From 3692fc9f0013a19ea083c561a59f2fb4291277d8 Mon Sep 17 00:00:00 2001 From: malevrigns <99654957+malevrigns@users.noreply.github.com> Date: Sun, 8 Nov 2026 20:47:54 +0800 Subject: [PATCH 1/8] feat(acp): add DeepSeek Harness and ZCode to the registry Search can install DeepSeek Harness and the unofficial ZCode ACP bridge through the existing registry driver. An official entry with the same id replaces the supplemental record. Local ACP commands use the same sign-in step. On Windows, a standard npm cmd shim such as dsh.cmd launches through node instead of a shell. --- .../SettingsProviderAccountsRouteScreen.tsx | 5 +- ...nstanceDialog.environment.browser.test.tsx | 8 +- .../AddProviderInstanceDialog.logic.ts | 1 - .../settings/AddProviderInstanceDialog.tsx | 26 ++----- .../ProviderAuthenticationSection.tsx | 7 +- docs/user/providers-acp.md | 29 +++++++- .../src/server/AcpRegistrySupport.test.ts | 70 ++++++++++++++++++ .../src/server/AcpRegistrySupport.ts | 56 ++++++++++++-- .../src/server/driver.test.ts | 51 +++++++++++++ .../src/server/driver.ts | 6 +- .../src/server/supplementalAgents.test.ts | 30 ++++++++ .../src/server/supplementalAgents.ts | 74 +++++++++++++++++++ packages/shared/src/shell.test.ts | 37 ++++++++++ packages/shared/src/shell.ts | 40 ++++++++++ 14 files changed, 403 insertions(+), 37 deletions(-) create mode 100644 packages/provider-acp-registry/src/server/supplementalAgents.test.ts create mode 100644 packages/provider-acp-registry/src/server/supplementalAgents.ts diff --git a/apps/mobile/src/features/settings/SettingsProviderAccountsRouteScreen.tsx b/apps/mobile/src/features/settings/SettingsProviderAccountsRouteScreen.tsx index a3b698dd9aff8..a368873f41578 100644 --- a/apps/mobile/src/features/settings/SettingsProviderAccountsRouteScreen.tsx +++ b/apps/mobile/src/features/settings/SettingsProviderAccountsRouteScreen.tsx @@ -174,9 +174,12 @@ function ProviderAccount({ !signedIn && !auth.error && state?.methods === undefined; + const hasAdvertisedSignIn = (state?.methods?.length ?? 0) > 0; const needsExternalSetup = !active && !signedIn && + !isDiscovering && + !hasAdvertisedSignIn && (provider.setup?.canAuthenticate === false || (provider.driver === "acpRegistry" && state?.methods?.length === 0)); const url = @@ -232,7 +235,7 @@ function ProviderAccount({ const canSignIn = !active && !needsExternalSetup && - provider.setup?.canAuthenticate !== false && + (provider.setup?.canAuthenticate !== false || hasAdvertisedSignIn) && provider.enabled && provider.installed; const signInDisabled = disabled || state === null; diff --git a/apps/web/src/components/settings/AddProviderInstanceDialog.environment.browser.test.tsx b/apps/web/src/components/settings/AddProviderInstanceDialog.environment.browser.test.tsx index 568c6a953ffc7..e25eb79083268 100644 --- a/apps/web/src/components/settings/AddProviderInstanceDialog.environment.browser.test.tsx +++ b/apps/web/src/components/settings/AddProviderInstanceDialog.environment.browser.test.tsx @@ -244,7 +244,7 @@ describe("AddProviderInstanceDialog environment routing", () => { expect(actions.onOpenChange).toHaveBeenCalledWith(false); }); - it("creates a local command in the selected environment without a sign-in step", async () => { + it("creates a local command in the selected environment and opens sign-in", async () => { setup(); await using _screen = await render(dialog()); await click("Show more"); @@ -271,7 +271,7 @@ describe("AddProviderInstanceDialog environment routing", () => { await type('input[aria-label="Environment variable value 1"]', "work"); await click("Next"); await type("#add-provider-label", "Deepseek Harness"); - await click("Add instance"); + await click("Continue to sign-in"); expect(settingsHooks.useMutation).toHaveBeenCalledWith(remoteEnvironmentId); expect(settingsHooks.mutate).toHaveBeenCalledWith({ @@ -287,8 +287,8 @@ describe("AddProviderInstanceDialog environment routing", () => { ], }, }); - expect(actions.onOpenChange).toHaveBeenCalledWith(false); - expect(signInStep()).toBeNull(); + expect(actions.onOpenChange).not.toHaveBeenCalled(); + expect(signInStep()?.textContent).toContain("remote-device/acpRegistry_deepseek_harness"); }); it("rejects a queued save after the provider grant is revoked", async () => { diff --git a/apps/web/src/components/settings/AddProviderInstanceDialog.logic.ts b/apps/web/src/components/settings/AddProviderInstanceDialog.logic.ts index 1263c675e05b7..29e3ccac5daad 100644 --- a/apps/web/src/components/settings/AddProviderInstanceDialog.logic.ts +++ b/apps/web/src/components/settings/AddProviderInstanceDialog.logic.ts @@ -7,7 +7,6 @@ const ACP_REGISTRY_IDENTITY_STEP = 1; export const ADD_PROVIDER_WIZARD_STEPS = ["Provider", "Identity", "Config"] as const; export const ACP_REGISTRY_WIZARD_STEPS = ["Provider", "Identity", "Sign in"] as const; -export const LOCAL_ACP_WIZARD_STEPS = ["Provider", "Identity"] as const; export interface ProviderIdentityDraft { readonly label: string; diff --git a/apps/web/src/components/settings/AddProviderInstanceDialog.tsx b/apps/web/src/components/settings/AddProviderInstanceDialog.tsx index e5074e4a9bfd1..0da2fbe9f94ce 100644 --- a/apps/web/src/components/settings/AddProviderInstanceDialog.tsx +++ b/apps/web/src/components/settings/AddProviderInstanceDialog.tsx @@ -46,7 +46,6 @@ import { WizardPanel, WizardPopup, WizardHeader, WizardFooter } from "../ui/wiza import { ADD_PROVIDER_WIZARD_STEPS, ACP_REGISTRY_WIZARD_STEPS, - LOCAL_ACP_WIZARD_STEPS, resolveAcpRegistryWizardNavigation, resolveWizardNavigation, updateProviderIdentityDraft, @@ -277,7 +276,7 @@ export function AddProviderInstanceDialog({ if (navigation.kind === "blocked") { setHasAttemptedSubmit(true); } - if (isAcpRegistry && !isLocalAcp && navigation.kind === "navigate" && navigation.step === 2) { + if (isAcpRegistry && navigation.kind === "navigate" && navigation.step === 2) { void handleSave(); return; } @@ -287,15 +286,10 @@ export function AddProviderInstanceDialog({ const navigateToStep = (requestedStep: number) => { applyWizardNavigation( isAcpRegistry - ? isLocalAcp - ? resolveWizardNavigation(wizardStep, requestedStep, LOCAL_ACP_WIZARD_STEPS.length, { - instanceIdError, - prerequisite: { step: 0, error: acpSelectionError }, - }) - : resolveAcpRegistryWizardNavigation(wizardStep, requestedStep, { - instanceIdError, - selectionError: acpSelectionError, - }) + ? resolveAcpRegistryWizardNavigation(wizardStep, requestedStep, { + instanceIdError, + selectionError: acpSelectionError, + }) : resolveWizardNavigation(wizardStep, requestedStep, ADD_PROVIDER_WIZARD_STEPS.length, { instanceIdError, }), @@ -409,7 +403,7 @@ export function AddProviderInstanceDialog({ return; } onCreated?.(brandedId, driver); - if (isAcpRegistry && !isLocalAcp) { + if (isAcpRegistry) { setCreatedInstanceId(brandedId); setIsSaving(false); setWizardStep(2); @@ -445,7 +439,7 @@ export function AddProviderInstanceDialog({ currentStep={wizardStep} summaries={wizardStepSummaries} instanceIdError={instanceIdError} - steps={isLocalAcp ? LOCAL_ACP_WIZARD_STEPS : ACP_REGISTRY_WIZARD_STEPS} + steps={ACP_REGISTRY_WIZARD_STEPS} disabled={isSaving || isPreparingRegistryAgent || createdInstanceId !== null} identityStep={1} prerequisite={{ step: 0, error: acpSelectionError }} @@ -752,11 +746,7 @@ export function AddProviderInstanceDialog({ disabled={isSaving || !canManageProviders} onClick={() => void handleSave()} > - {isSaving - ? "Adding..." - : isAcpRegistry && !isLocalAcp - ? "Continue to sign-in" - : "Add instance"} + {isSaving ? "Adding..." : isAcpRegistry ? "Continue to sign-in" : "Add instance"} )} diff --git a/apps/web/src/components/settings/ProviderAuthenticationSection.tsx b/apps/web/src/components/settings/ProviderAuthenticationSection.tsx index f5c4ee146db2a..0582cb1224cfc 100644 --- a/apps/web/src/components/settings/ProviderAuthenticationSection.tsx +++ b/apps/web/src/components/settings/ProviderAuthenticationSection.tsx @@ -68,9 +68,12 @@ export function ProviderAuthenticationSection({ !signedIn && !query.error && auth?.methods === undefined; + const hasAdvertisedSignIn = (auth?.methods?.length ?? 0) > 0; const needsExternalSetup = !active && !signedIn && + !isDiscovering && + !hasAdvertisedSignIn && (provider.setup?.canAuthenticate === false || (provider.driver === "acpRegistry" && auth?.methods?.length === 0)); const usesCredentials = @@ -276,7 +279,9 @@ export function ProviderAuthenticationSection({ > Cancel - ) : !active && !needsExternalSetup && provider.setup?.canAuthenticate !== false ? ( + ) : !active && + !needsExternalSetup && + (provider.setup?.canAuthenticate !== false || hasAdvertisedSignIn) ? (