-
Notifications
You must be signed in to change notification settings - Fork 15.6k
feat: fork-agent-redesign — 新增 AgentTool fork 参数与 spec 设计文档 #405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| import { describe, expect, test } from 'bun:test' | ||
| import { readFileSync } from 'fs' | ||
| import { join, dirname } from 'path' | ||
| import { fileURLToPath } from 'url' | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)) | ||
| const promptSource = readFileSync(join(__dirname, '..', 'prompt.ts'), 'utf-8') | ||
|
|
||
| describe('prompt.ts fork-related text verification', () => { | ||
| test('does not contain "omit `subagent_type`" guidance', () => { | ||
| expect(promptSource).not.toMatch(/omit.*subagent_type/) | ||
| }) | ||
|
|
||
| test('contains `fork: true` in at least 3 locations (shared + whenToFork + forkExamples)', () => { | ||
| const matches = promptSource.match(/fork: true/g) | ||
| expect(matches).not.toBeNull() | ||
| expect(matches!.length).toBeGreaterThanOrEqual(3) | ||
| }) | ||
|
|
||
| test('all forkEnabled references are ternary conditions, not negated', () => { | ||
| const lines = promptSource.split('\n') | ||
| for (const line of lines) { | ||
| if ( | ||
| line.includes('forkEnabled') && | ||
| !line.includes('const forkEnabled') && | ||
| !line.includes('forkEnabled =') | ||
| ) { | ||
| expect(line).not.toContain('!forkEnabled') | ||
| } | ||
| } | ||
| }) | ||
|
|
||
| test('uses "non-fork" terminology instead of "fresh agent"', () => { | ||
| expect(promptSource).toContain('non-fork') | ||
| // "fresh agent" should not appear in fork-aware conditional text | ||
| const freshAgentMatches = promptSource.match(/fresh agent/g) | ||
| if (freshAgentMatches) { | ||
| // Only allowed in comments explaining behavior, not in prompt text | ||
| const linesWithFreshAgent = promptSource | ||
| .split('\n') | ||
| .filter(line => line.includes('fresh agent')) | ||
| .map(line => line.trim()) | ||
| for (const line of linesWithFreshAgent) { | ||
| // "fresh agent" in the context of "starts fresh" (not fork-aware) is ok | ||
| // but "fresh agent" in forkEnabled conditional should not appear | ||
| expect(line).not.toMatch(/fresh agent.*subagent_type/) | ||
| } | ||
| } | ||
| }) | ||
|
|
||
| test('background task condition does not include !forkEnabled', () => { | ||
| // The condition for showing background task instructions should not exclude fork | ||
| const bgCondition = promptSource.match( | ||
| /!isEnvTruthy.*isInProcessTeammate[\s\S]*?run_in_background/, | ||
| ) | ||
| if (bgCondition) { | ||
| expect(bgCondition[0]).not.toContain('!forkEnabled') | ||
| } | ||
| }) | ||
|
Comment on lines
+51
to
+59
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fail if the background-note block disappears. If Suggested fix test('background task condition does not include !forkEnabled', () => {
// The condition for showing background task instructions should not exclude fork
const bgCondition = promptSource.match(
/!isEnvTruthy.*isInProcessTeammate[\s\S]*?run_in_background/,
)
- if (bgCondition) {
- expect(bgCondition[0]).not.toContain('!forkEnabled')
- }
+ expect(bgCondition).not.toBeNull()
+ expect(bgCondition![0]).not.toContain('!forkEnabled')
})🤖 Prompt for AI Agents |
||
|
|
||
| test('fork example includes fork: true parameter', () => { | ||
| // The first fork example should have fork: true | ||
| const forkExampleBlock = promptSource.match( | ||
| /name: "ship-audit"[\s\S]*?Under 200 words/, | ||
| ) | ||
| expect(forkExampleBlock).not.toBeNull() | ||
| expect(forkExampleBlock![0]).toContain('fork: true') | ||
| }) | ||
| }) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: claude-code-best/claude-code
Length of output: 1544
🏁 Script executed:
Repository: claude-code-best/claude-code
Length of output: 99
🏁 Script executed:
Repository: claude-code-best/claude-code
Length of output: 2893
🏁 Script executed:
Repository: claude-code-best/claude-code
Length of output: 3289
🏁 Script executed:
Repository: claude-code-best/claude-code
Length of output: 1801
Add
fork: trueto the fork command's AgentTool invocation.The routing logic in AgentTool.tsx changed from implicit (omit
subagent_typeto trigger fork) to explicit (fork: trueparameter). The/forkcommand insrc/commands/fork/fork.tsx(lines 42–48) has not been updated and still relies on the old implicit behavior. Withoutfork: true, the fork command will spawn a general-purpose agent instead of a fork, silently producing incorrect behavior.Required fix
const input = { prompt: directive, + fork: true, run_in_background: true, description: `Fork: ${directive.slice(0, 30)}${directive.length > 30 ? '...' : ''}`, };🤖 Prompt for AI Agents