Skip to content

Commit e6affc7

Browse files
2228293026HitMargincoderabbitai[bot]
authored
1. 修复 src/commands/fork/index.ts — 将空 stub 改为有效的 Command 定义 2. 新增 src/commands/fork/fork.tsx — 完整实现 /fork 命令,复用了 AgentTool 的 fork 子 agent 逻辑 (#221)
* 1. 修复 src/commands/fork/index.ts — 将空 stub 改为有效的 Command 定义 2. 新增 src/commands/fork/fork.tsx — 完整实现 /fork 命令,复用了 AgentTool 的 fork 子 agent 逻辑 * Update src/commands/fork/fork.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix --------- Co-authored-by: HitMargin <hitmargin@qq.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent bb07836 commit e6affc7

2 files changed

Lines changed: 84 additions & 3 deletions

File tree

src/commands/fork/fork.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { feature } from 'bun:bundle'
2+
import React from 'react'
3+
import { AgentTool } from '../../tools/AgentTool/AgentTool.js'
4+
import { isInForkChild } from '../../tools/AgentTool/forkSubagent.js'
5+
import { logForDebugging } from '../../utils/debug.js'
6+
import type { LocalJSXCommandOnDone, LocalJSXCommandContext } from '../../types/command.js'
7+
8+
export async function call(
9+
onDone: LocalJSXCommandOnDone,
10+
context: LocalJSXCommandContext,
11+
args: string,
12+
): Promise<React.ReactNode> {
13+
// Check feature flag
14+
if (!feature('FORK_SUBAGENT')) {
15+
onDone('Fork subagent feature is not enabled. Set FEATURE_FORK_SUBAGENT=1 to enable.', { display: 'system' })
16+
return null
17+
}
18+
19+
// Recursive fork guard
20+
if (isInForkChild(context.messages)) {
21+
onDone('Fork is not available inside a forked worker. Complete your task directly using your tools.', { display: 'system' })
22+
return null
23+
}
24+
25+
const directive = args.trim()
26+
if (!directive) {
27+
onDone('Usage: /fork <directive>\nExample: /fork Fix the null check in validate.ts', { display: 'system' })
28+
return null
29+
}
30+
31+
// Find the last assistant message to fork from
32+
const lastAssistantMessage = [...context.messages].reverse().find(
33+
m => m.type === 'assistant'
34+
) as any // Type assertion to avoid complex type import
35+
36+
if (!lastAssistantMessage) {
37+
onDone('Cannot fork: no assistant response in conversation history.', { display: 'system' })
38+
return null
39+
}
40+
41+
try {
42+
// Reuse AgentTool logic for fork path.
43+
// Omitting subagent_type triggers implicit fork.
44+
const input = {
45+
prompt: directive,
46+
run_in_background: true, // fork always runs async
47+
description: `Fork: ${directive.slice(0, 30)}${directive.length > 30 ? '...' : ''}`,
48+
}
49+
50+
// Call AgentTool with proper parameters:
51+
// - input: the agent parameters (no subagent_type => fork path)
52+
// - toolUseContext: the current context (ToolUseContext)
53+
// - canUseTool: permission-check function from context
54+
// - assistantMessage: the last assistant message to fork from
55+
AgentTool.call(
56+
input,
57+
context,
58+
context.canUseTool,
59+
lastAssistantMessage
60+
).catch(error => {
61+
logForDebugging(`Fork subagent async error: ${error}`, { level: 'error' })
62+
})
63+
64+
// Notify user that fork has been started
65+
onDone(`Forked subagent started with directive: "${directive}"`, { display: 'system' })
66+
return null
67+
} catch (error) {
68+
// Catches synchronous setup errors only
69+
logForDebugging(`Fork command setup error: ${error}`, { level: 'error' })
70+
onDone(`Fork failed: ${error instanceof Error ? error.message : String(error)}`, { display: 'system' })
71+
return null
72+
}
73+
}

src/commands/fork/index.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1-
// Auto-generated stub — replace with real implementation
2-
const _default: Record<string, unknown> = {};
3-
export default _default;
1+
import type { Command } from '../../commands.js'
2+
3+
const fork = {
4+
type: 'local-jsx',
5+
name: 'fork',
6+
description: 'Fork the current session into a new sub-agent',
7+
argumentHint: '<prompt>',
8+
load: () => import('./fork.js'),
9+
} satisfies Command
10+
11+
export default fork

0 commit comments

Comments
 (0)