Selaa lähdekoodia

fix(subagent): tighten named Claude instance evidence

pku-xht 3 viikkoa sitten
vanhempi
sitoutus
044f65e46b

+ 1 - 1
.agents/notes/implemented/architecture/2026-08-10-product-subagent-providers-in-shared-host.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-product-subagent-providers-in-shared-host.md
-2026-08-10-product-subagent-providers-in-shared-host.md: 2798431709307e50a1ee16c7fc595bcead223f59
+2026-08-10-product-subagent-providers-in-shared-host.md: 34c286821a245a659b668a8ba6676c4e3b1ba5e9
 2026-08-10-product-subagent-providers-in-shared-host.zh.md: 981b1e2cd305c1410dcd744e3aea5028eb283806

+ 1 - 1
.agents/notes/implemented/architecture/2026-08-10-product-subagent-providers-in-shared-host.md

@@ -26,7 +26,7 @@ The base bundle test proves production `dsh-base` contains neither product provi
 
 ## Alternatives considered
 
-**Keep product providers opt-in at the Profile layer.** This preserves a smaller default dependency closure but requires the user to edit both a Profile and a Preset. The production-install exclusion decision accepts that installation trade-off; this note retains the requirement that any selected provider is mounted once on the host plane rather than inside the preset.
+**Keep product providers opt-in at the Profile layer.** This preserves a smaller default dependency closure but requires the user to edit both a Profile and a Preset. The production-install exclusion decision accepts that installation trade-off; this note retains the requirement that selected provider instances are mounted on the host plane rather than inside the preset.
 
 **Store global or per-Profile product enable switches.** A process switch competes with the Preset as owner of model-visible tools and cannot express two sessions using different combinations. Availability and authentication are deployment facts, not another persisted product state.
 

+ 10 - 16
examples/acp-agent/tests/fixtures/subagent/subagent-claude-code/cordis.yml

@@ -12,21 +12,15 @@
 - id: subagent-codex
   name: '@deepseek-ai/dsh-subagent-codex'
 
-- id: subagent-claude-safe
+- id: subagent-claude-primary
   name: '@deepseek-ai/dsh-subagent-claude-code'
   config:
-    providerName: claude-safe
-    permissionMode: dontAsk
-    env:
-      DSH_CLAUDE_INSTANCE: safe
+    providerName: claude-primary
 
-- id: subagent-claude-bypass
+- id: subagent-claude-secondary
   name: '@deepseek-ai/dsh-subagent-claude-code'
   config:
-    providerName: claude-bypass
-    permissionMode: bypassPermissions
-    env:
-      DSH_CLAUDE_INSTANCE: bypass
+    providerName: claude-secondary
 
 - id: tool-subagent-codex
   name: '@deepseek-ai/dsh-tool-subagent'
@@ -36,19 +30,19 @@
     backgroundMode: one-shot
     maxDepth: 'provider-managed'
 
-- id: tool-subagent-claude-safe
+- id: tool-subagent-claude-primary
   name: '@deepseek-ai/dsh-tool-subagent'
   config:
-    provider: claude-safe
-    toolName: subagent_claude_safe
+    provider: claude-primary
+    toolName: subagent_claude_primary
     backgroundMode: one-shot
     maxDepth: 'provider-managed'
 
-- id: tool-subagent-claude-bypass
+- id: tool-subagent-claude-secondary
   name: '@deepseek-ai/dsh-tool-subagent'
   config:
-    provider: claude-bypass
-    toolName: subagent_claude_bypass
+    provider: claude-secondary
+    toolName: subagent_claude_secondary
     backgroundMode: one-shot
     maxDepth: 'provider-managed'
 

+ 3 - 3
examples/acp-agent/tests/fixtures/subagent/subagent-claude-code/driver.ts

@@ -23,11 +23,11 @@ const ctx = await boot(
 )
 
 try {
-  const providerNames = ['codex', 'claude-safe', 'claude-bypass'] as const
+  const providerNames = ['codex', 'claude-primary', 'claude-secondary'] as const
   const toolNames = [
     'subagent_codex',
-    'subagent_claude_safe',
-    'subagent_claude_bypass',
+    'subagent_claude_primary',
+    'subagent_claude_secondary',
   ] as const
   const providers = providerNames.map((providerName) => {
     const provider = ctx.subagents.getProvider(providerName)

+ 0 - 3
packages/subagent/subagent-claude-code/src/index.ts

@@ -131,9 +131,6 @@ export function apply(ctx: Context, config: Config): void {
       `subagent-claude-code: disposeGraceMs must be no greater than ${MAX_TIMER_DELAY_MS}`,
     )
   }
-  if (resolved.providerName.length === 0) {
-    throw new TypeError('subagent-claude-code providerName must be non-empty')
-  }
   ctx.subagents.registerProvider(new ClaudeCodeProvider(
     resolved.providerName,
     ctx,

+ 5 - 5
packages/subagent/subagent-claude-code/tests/loader-composition.e2e.ts

@@ -31,7 +31,7 @@ describe('product-provider public Loader composition', () => {
 
     expect(stderr).toBe('')
     expect(JSON.parse(stdout)).toEqual({
-      registeredProviders: ['codex', 'claude-safe', 'claude-bypass'],
+      registeredProviders: ['codex', 'claude-primary', 'claude-secondary'],
       providers: [
         {
           name: 'codex',
@@ -44,7 +44,7 @@ describe('product-provider public Loader composition', () => {
           inheritsParentContext: false,
         },
         {
-          name: 'claude-safe',
+          name: 'claude-primary',
           capabilities: {
             outputSchema: false,
             depthLimit: false,
@@ -54,7 +54,7 @@ describe('product-provider public Loader composition', () => {
           inheritsParentContext: false,
         },
         {
-          name: 'claude-bypass',
+          name: 'claude-secondary',
           capabilities: {
             outputSchema: false,
             depthLimit: false,
@@ -71,12 +71,12 @@ describe('product-provider public Loader composition', () => {
           required: ['description', 'prompt'],
         },
         {
-          name: 'subagent_claude_safe',
+          name: 'subagent_claude_primary',
           parameterNames: ['description', 'prompt', 'run_in_background'],
           required: ['description', 'prompt'],
         },
         {
-          name: 'subagent_claude_bypass',
+          name: 'subagent_claude_secondary',
           parameterNames: ['description', 'prompt', 'run_in_background'],
           required: ['description', 'prompt'],
         },

+ 0 - 7
packages/subagent/subagent-claude-code/tests/subagent-claude-code.spec.ts

@@ -480,13 +480,6 @@ describe('task admission and package contracts', () => {
     await ctx.plugin(LocalSubprocessRuntime)
     claudeCode.apply(ctx, { env: {}, disposeGraceMs: 3_000 })
     expect(ctx.subagents.getProvider('claude-code')).toBeDefined()
-    expect(() => {
-      claudeCode.apply(ctx, {
-        providerName: '',
-        env: {},
-        disposeGraceMs: 3_000,
-      })
-    }).toThrow('providerName must be non-empty')
     await ctx.fiber.dispose()
   })