@kolisachint/hoocode-agent 0.5.30 → 0.5.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +234 -0
- package/dist/core/agent-selection-eval.d.ts +91 -0
- package/dist/core/agent-selection-eval.d.ts.map +1 -0
- package/dist/core/agent-selection-eval.js +186 -0
- package/dist/core/agent-selection-eval.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts +28 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +61 -2
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/builtin-skills.d.ts +61 -0
- package/dist/core/builtin-skills.d.ts.map +1 -0
- package/dist/core/builtin-skills.js +106 -0
- package/dist/core/builtin-skills.js.map +1 -0
- package/dist/core/extensions/plugins/default-marketplace/.agents-plugin/marketplace.json +5 -1
- package/dist/core/extensions/plugins/trigger-judge.d.ts +42 -0
- package/dist/core/extensions/plugins/trigger-judge.d.ts.map +1 -0
- package/dist/core/extensions/plugins/trigger-judge.js +121 -0
- package/dist/core/extensions/plugins/trigger-judge.js.map +1 -0
- package/dist/core/external-tools.d.ts +67 -0
- package/dist/core/external-tools.d.ts.map +1 -0
- package/dist/core/external-tools.js +120 -0
- package/dist/core/external-tools.js.map +1 -0
- package/dist/core/keybindings.d.ts +102 -30
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +123 -29
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/mode-prompts.d.ts +15 -3
- package/dist/core/mode-prompts.d.ts.map +1 -1
- package/dist/core/mode-prompts.js +17 -29
- package/dist/core/mode-prompts.js.map +1 -1
- package/dist/core/settings-defaults.d.ts +1 -1
- package/dist/core/settings-defaults.d.ts.map +1 -1
- package/dist/core/settings-defaults.js +1 -1
- package/dist/core/settings-defaults.js.map +1 -1
- package/dist/core/settings-manager.d.ts +10 -3
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +19 -8
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-types.d.ts +1 -1
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +5 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tool-output-view.d.ts +33 -0
- package/dist/core/tool-output-view.d.ts.map +1 -0
- package/dist/core/tool-output-view.js +31 -0
- package/dist/core/tool-output-view.js.map +1 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +4 -0
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/propose-plugin.d.ts.map +1 -1
- package/dist/core/tools/propose-plugin.js +7 -7
- package/dist/core/tools/propose-plugin.js.map +1 -1
- package/dist/core/tools/subagent.d.ts +7 -1
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +12 -24
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/extensions/core/modes.d.ts.map +1 -1
- package/dist/extensions/core/modes.js +21 -23
- package/dist/extensions/core/modes.js.map +1 -1
- package/dist/extensions/core/scaffold.d.ts.map +1 -1
- package/dist/extensions/core/scaffold.js +28 -24
- package/dist/extensions/core/scaffold.js.map +1 -1
- package/dist/init-templates.generated.d.ts +3 -0
- package/dist/init-templates.generated.d.ts.map +1 -1
- package/dist/init-templates.generated.js +12 -0
- package/dist/init-templates.generated.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +14 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/command-executor.d.ts +20 -0
- package/dist/modes/interactive/command-executor.d.ts.map +1 -1
- package/dist/modes/interactive/command-executor.js +138 -9
- package/dist/modes/interactive/command-executor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +4 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +31 -2
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +2 -2
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +2 -2
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +10 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +165 -23
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-chain-summary.d.ts +65 -0
- package/dist/modes/interactive/components/tool-chain-summary.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-chain-summary.js +216 -0
- package/dist/modes/interactive/components/tool-chain-summary.js.map +1 -0
- package/dist/modes/interactive/components/tool-chain.d.ts +61 -0
- package/dist/modes/interactive/components/tool-chain.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-chain.js +156 -0
- package/dist/modes/interactive/components/tool-chain.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +55 -9
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +173 -33
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-signal.d.ts +50 -0
- package/dist/modes/interactive/components/tool-signal.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-signal.js +151 -0
- package/dist/modes/interactive/components/tool-signal.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +50 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +244 -29
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/resource-display.d.ts +9 -0
- package/dist/modes/interactive/resource-display.d.ts.map +1 -1
- package/dist/modes/interactive/resource-display.js +13 -0
- package/dist/modes/interactive/resource-display.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +30 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +35 -0
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/modes.md +4 -0
- package/docs/plugins.md +10 -0
- package/docs/settings.md +42 -0
- package/docs/skills.md +30 -0
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +5 -4
- package/templates/prompts/grill-bridge.md +1 -0
- package/templates/prompts/grill-me.md +7 -0
- package/templates/prompts/grill-plan.md +9 -0
- package/templates/prompts/task-background-agents.md +2 -0
- package/templates/prompts/task-background-none.md +1 -0
- package/templates/prompts/task-main.md +19 -0
- package/templates/skills/plugin-authoring/SKILL.md +81 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../../src/core/tools/subagent.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Task tool: delegate a focused task to a specialized subagent.\n *\n * Mirrors the Claude Code `Task` tool. The parent agent decides *when* to\n * delegate based on each agent's `description` (there is no deterministic gate)\n * and selects *which* agent via `subagent_type`. The chosen agent runs in a\n * fresh, isolated child process (SubagentPool) and only its final answer is\n * returned to the parent.\n *\n * Enabled by default (the `enableSubagent` setting defaults to true); disable\n * with `enableSubagent: false`. The `--enable-subagents` flag still force-enables\n * it. Nesting is bounded by the tree-wide depth cap (maxSubagentDepth, default 2:\n * a spawned subagent may itself delegate one more level, and depth-2 grandchildren\n * cannot). See buildSessionOptions in main.ts.\n */\n\nimport { Text } from \"@kolisachint/hoocode-tui\";\nimport { type Static, Type } from \"typebox\";\nimport { agentColorFor } from \"../../modes/interactive/theme/theme.js\";\nimport { type AgentDefinition, TASK_TOOL_NAME } from \"../agent-frontmatter.js\";\nimport { agentLog } from \"../agent-log.js\";\nimport { loadAgentRegistry } from \"../agent-registry.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport { defineTool } from \"../extensions/types.js\";\nimport { formatDurationSecs } from \"../format-duration.js\";\nimport { formatTokens } from \"../format-tokens.js\";\nimport { getProviderExhaustion } from \"../provider-health.js\";\nimport { SessionManager } from \"../session-manager.js\";\nimport { delegateAllowList, isDelegateAllowed } from \"../subagent-depth.js\";\nimport { type InboxRecord, subagentInbox } from \"../subagent-inbox.js\";\nimport type { SubagentResult, TaskResult } from \"../subagent-pool.js\";\nimport { getSubagentPool } from \"../subagent-pool-instance.js\";\nimport type { SubagentResultFile, SubagentTaskNode } from \"../subagent-result.js\";\nimport { taskStore } from \"../task-store.js\";\nimport { type WarmRunResult, WarmWorkerError } from \"../warm-subagent-pool.js\";\nimport { getWarmSubagentPool, warmSubagentsEnabled } from \"../warm-subagent-pool-instance.js\";\n\n// Re-exported from its home in agent-registry (where formatAgentsForPrompt uses\n// it to render the roster) so existing importers keep working without creating a\n// tools -> registry -> tools cycle.\nexport { summarizeAgentDescription } from \"../agent-registry.js\";\n\n/** System prompt appendix for the main session when the Task tool is enabled.\n * Instructs the parent agent on when and how to delegate effectively. The\n * available agents themselves are listed once, authoritatively, in the\n * `<available_agents>` block the system prompt emits whenever the Task tool is\n * active (see agent-session `_rebuildSystemPrompt`); this appendix references\n * that list rather than re-rendering the roster and paying for it twice. */\n/**\n * Build the main-session subagent instructions appended to the system prompt.\n *\n * The detailed background/barrier guidance (the three heaviest bullets) is only\n * emitted when the project actually has background-capable agents; otherwise a\n * single concise line covers the per-call `background: true` escape hatch. This\n * keeps the always-on cost down for the common case where nothing runs in the\n * background. `cwd` is used only to detect those agents.\n */\nexport function buildTaskMainPrompt(cwd: string = process.cwd()): string {\n\tconst hasBackgroundAgents = collectBackgroundAgentNames(cwd).size > 0;\n\n\tconst backgroundGuidance = hasBackgroundAgents\n\t\t? `- Background agents run non-blocking (or force per call with \\`background: true\\`): you get a short \"explore#1 finished\" notification and pull the full result with \\`TaskOutput\\` (e.g. \\`TaskOutput(\"explore#1\")\\`); \\`TaskOutput(list: true)\\` shows what's running.\n- After dispatching, don't idle — keep doing independent work (read/edit unrelated files, draft, dispatch more); barrier with \\`TaskOutput(wait: true)\\` (a named task, or all outstanding when no id) only when you genuinely can't proceed.`\n\t\t: `- You can force any task to run in the background with \\`background: true\\` (non-blocking): keep working, then pull its result with \\`TaskOutput\\` (e.g. \\`TaskOutput(\"explore#1\")\\`) or block on it with \\`TaskOutput(wait: true)\\`.`;\n\n\treturn `You have access to the **Task** tool. Use it to delegate self-contained tasks to specialized subagents that run in their own isolated context and return only their final answer. Pick an agent by name from the <available_agents> list in this prompt and pass it as \\`subagent_type\\`.\n\nWhen to delegate:\n1. The work is self-contained and you only need the final result, not intermediate steps.\n2. You want to investigate or edit something in parallel without losing your current context or reasoning chain.\n3. The task is a discrete unit (explore one module, run one test file, review one PR, fix one isolated bug).\n4. You need to run a long command or test suite and wait for its output without blocking your own reasoning.\n\nModel tier (optional \\`complexity\\`): set \\`fast\\` for quick reads/lookups, \\`standard\\` for multi-file edits, \\`capable\\` for deep architecture work. It maps to a model from \\`settings.modelCategories\\`. Omit it to use the agent's default; an agent that pins its own model ignores \\`complexity\\`.\n\nGuidelines:\n- Choose the agent whose description best matches the task.\n- Make every task specific and self-contained. The subagent cannot see this conversation; pass all necessary context (files, constraints, prior findings) in \\`prompt\\`.\n- Do NOT delegate tasks that require tight back-and-forth with your current reasoning, or edits to files you are actively reasoning about.\n- The subagent returns ONLY its final answer. Its intermediate reasoning, tool calls, and output are hidden from you.\n- Delegate proactively when work is self-contained or parallelizable: multi-step investigation, read-only exploration (use \\`explore\\`), research before changes (use \\`plan\\`), drafting a standalone file/section, or running a long command/test suite. Dispatch independent subtasks in the same turn. Handle only trivial single-step edits or tightly interactive back-and-forth inline.\n${backgroundGuidance}\n- When working through a TodoWrite plan, mark the plan item in_progress BEFORE dispatching subagents for it: each dispatch is attributed to the current in_progress item in the user's task panel, so dispatching first (or with several items in_progress) leaves the run unattributed.\n- To continue a previous subagent (for example one that returned partial results), call Task again with \\`resume_task_id\\` set to its task_id; it resumes with its full prior transcript and \\`prompt\\` is your follow-up.`;\n}\n\nconst taskParams = Type.Object({\n\tdescription: Type.String({\n\t\tdescription: \"A short (3-5 word) description of the task, shown in the task panel.\",\n\t}),\n\tprompt: Type.String({\n\t\tdescription:\n\t\t\t\"The full, self-contained task for the subagent. It cannot see this conversation, so include all needed context, files, and constraints.\",\n\t}),\n\tsubagent_type: Type.String({\n\t\tdescription: \"The name of the specialized agent to delegate to. Must be one of the available agents.\",\n\t}),\n\tcomplexity: Type.Optional(\n\t\tType.Union([Type.Literal(\"fast\"), Type.Literal(\"standard\"), Type.Literal(\"capable\")], {\n\t\t\tdescription:\n\t\t\t\t\"Model tier for this dispatch: fast (quick reads/lookups), standard (multi-file edits), capable (deep architecture). Maps to settings.modelCategories. Ignored if the chosen agent pins its own model; omit to use the agent's default.\",\n\t\t}),\n\t),\n\tbackground: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Set true to run non-blocking: you get a short notification when it finishes and pull the full result with TaskOutput; set false to wait and get the answer inline. Defaults to the agent's own background setting.\",\n\t\t}),\n\t),\n\tresume_task_id: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Optional. To continue a previous subagent run, pass its task_id (returned by an earlier Task or TaskOutput call). The subagent resumes with its full prior transcript and `prompt` is your follow-up instruction.\",\n\t\t}),\n\t),\n});\n\ntype TaskParams = Static<typeof taskParams>;\n\nexport interface TaskToolDetails {\n\tsubagent_type: string;\n\tok: boolean;\n\terror?: string;\n\ttaskId: number;\n\t/** Pool-level task id usable for resume/polling. */\n\tpoolTaskId?: string;\n\t/** True when dispatched as a non-blocking background task. */\n\tbackground?: boolean;\n}\n\nexport interface TaskOutputDetails {\n\t/** The handle queried, when a specific task was named. */\n\ttask_id?: string;\n\t/** running | done | collected | failed | stalled | timeout | cancelled | list | empty | unknown */\n\tstatus: string;\n\tok: boolean;\n\t/** Number of subagents still running, included on roster/list responses. */\n\toutstanding?: number;\n}\n\n/**\n * A short, human-readable task name for the task panel: the first line limited\n * to ~8 words so it stays glanceable. A character cap guards a single long word.\n */\nfunction summarize(task: string): string {\n\tconst firstLine = (task.trim().split(\"\\n\")[0] ?? \"\").trim();\n\tif (!firstLine) return \"(task)\";\n\tconst words = firstLine.split(/\\s+/);\n\tlet name = words.length > 8 ? `${words.slice(0, 8).join(\" \")}…` : firstLine;\n\tif (name.length > 60) name = `${name.slice(0, 59)}…`;\n\treturn name;\n}\n\n/** Create the Task tool definition. Registered as a customTool when enabled. */\nexport function createTaskToolDefinition(cwd: string = process.cwd()): ToolDefinition {\n\t// Agents whose definitions opt into background execution. The agent loop reads\n\t// the tool's `background` flag per call and, for these, runs the dispatch\n\t// detached: the parent keeps reasoning and the subagent's answer is injected as\n\t// a follow-up message when it finishes (no polling needed). A per-call\n\t// `background` argument overrides the agent's default in either direction.\n\tconst backgroundAgents = collectBackgroundAgentNames(cwd);\n\treturn defineTool<typeof taskParams, TaskToolDetails>({\n\t\tname: TASK_TOOL_NAME,\n\t\tlabel: TASK_TOOL_NAME,\n\t\tbackground: (toolCall) => {\n\t\t\tconst override = toolCall.arguments?.background;\n\t\t\tif (typeof override === \"boolean\") return override;\n\t\t\treturn backgroundAgents.has(String(toolCall.arguments?.subagent_type ?? \"\"));\n\t\t},\n\t\t// Kept to mechanics only: the when-to-use / when-not-to guidance lives once in\n\t\t// the system-prompt block (buildTaskMainPrompt), the available agents are\n\t\t// listed there too, and the `complexity`/`background`/`resume_task_id`\n\t\t// semantics live in their parameter descriptions. Repeating any of that here\n\t\t// would re-spend those tokens on every turn.\n\t\tdescription:\n\t\t\t\"Delegate a focused task to a specialized subagent that runs in a fresh, isolated context (it cannot see this conversation). Choose one of the available agents (listed in the system prompt) via `subagent_type` and pass everything it needs via `prompt`; the subagent returns only its final answer.\",\n\t\tpromptSnippet: \"delegate a self-contained task to a specialized subagent (choose via subagent_type)\",\n\t\tparameters: taskParams,\n\n\t\tasync execute(_toolCallId, params: TaskParams, signal, _onUpdate, ctx) {\n\t\t\t// Snapshot the caller's available models so unconfigured model-category\n\t\t\t// tiers (fast/standard/capable) resolve to a derived default instead of a\n\t\t\t// no-op. Explicit settings.modelCategories still win inside the pool. The\n\t\t\t// registry can be absent in some tool contexts; an empty list just keeps\n\t\t\t// category derivation a no-op (inherit parent), so guard the access.\n\t\t\tconst availableModels = ctx.modelRegistry?.getAvailable() ?? [];\n\t\t\tconst pool = getSubagentPool(ctx.cwd, availableModels);\n\n\t\t\t// User-initiated cancel (Esc/abort): kill the dispatched run's whole\n\t\t\t// process tree and let the dispatch settle with status \"cancelled\" —\n\t\t\t// distinct from \"failed\" everywhere it surfaces (panel, inbox, result).\n\t\t\t// Cold dispatches only: a warm worker has no cancel surface (it is\n\t\t\t// reused), so warm runs still complete server-side and are discarded.\n\t\t\tconst cancelOnAbort = async (poolRunId: string, run: () => Promise<TaskResult>): Promise<TaskResult> => {\n\t\t\t\tif (!signal) return run();\n\t\t\t\tconst onAbort = () => {\n\t\t\t\t\tpool.cancel?.(poolRunId);\n\t\t\t\t};\n\t\t\t\tif (signal.aborted) onAbort();\n\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\ttry {\n\t\t\t\t\treturn await run();\n\t\t\t\t} finally {\n\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Pre-flight: if the inherited provider recently exhausted its quota (the\n\t\t\t// parent's own turn failed with a usage/rate-limit error that did not\n\t\t\t// recover), skip the spawn. Subagents run on the same provider, so this\n\t\t\t// would only burn another failed attempt. The signal self-expires and is\n\t\t\t// cleared on the next successful response.\n\t\t\tconst provider = ctx.model?.provider;\n\t\t\tconst exhaustion = provider ? getProviderExhaustion(provider) : undefined;\n\t\t\tif (exhaustion) {\n\t\t\t\tconst skippedRunId = newDispatchTaskId();\n\t\t\t\tconst skipped = taskStore.create(params.description?.trim() || summarize(params.prompt), {\n\t\t\t\t\tsource: \"subagent\",\n\t\t\t\t\tsubagentMode: params.subagent_type,\n\t\t\t\t\tagent: skippedRunId,\n\t\t\t\t\tlinkedTaskId: linkedTodoId(),\n\t\t\t\t});\n\t\t\t\tregisterSubagentDispatch(skippedRunId, subagentInbox.nextLabel(params.subagent_type));\n\t\t\t\ttaskStore.update(skipped.id, { status: \"failed\", note: `${provider} exhausted` });\n\t\t\t\ttaskStore.patchAgent(skippedRunId, { state: \"failed\" });\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext:\n\t\t\t\t\t\t\t\t`Did not dispatch subagent \"${params.subagent_type}\": the \"${provider}\" provider appears ` +\n\t\t\t\t\t\t\t\t`exhausted or rate-limited (this session just failed with: ${exhaustion.message}). ` +\n\t\t\t\t\t\t\t\t`Subagents run on the same provider, so dispatching would fail too. Wait for the quota to ` +\n\t\t\t\t\t\t\t\t`reset or switch model/provider, then retry — or complete the work directly in this session.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { subagent_type: params.subagent_type, ok: false, taskId: skipped.id },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Scoped delegation: a delegating agent may be restricted to certain subagent\n\t\t\t// types (its `delegate: <types>` frontmatter). The root is unrestricted.\n\t\t\tif (!isDelegateAllowed(params.subagent_type)) {\n\t\t\t\tconst allowed = delegateAllowList()?.join(\", \") ?? \"\";\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`This agent may not delegate to \"${params.subagent_type}\". Allowed subagent types: ${allowed || \"(none)\"}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Resume path: continue a previously dispatched subagent with a follow-up\n\t\t\t// prompt, reusing its persisted session (full prior transcript).\n\t\t\tconst resumeId = params.resume_task_id?.trim();\n\t\t\tif (resumeId) {\n\t\t\t\tconst summary = params.description?.trim() || summarize(params.prompt);\n\t\t\t\tconst runId = newDispatchTaskId();\n\t\t\t\tconst label = subagentInbox.nextLabel(params.subagent_type);\n\t\t\t\tconst task = taskStore.create(summary, {\n\t\t\t\t\tsource: \"subagent\",\n\t\t\t\t\tsubagentMode: params.subagent_type,\n\t\t\t\t\tagent: runId,\n\t\t\t\t\tlinkedTaskId: linkedTodoId(),\n\t\t\t\t});\n\t\t\t\tregisterSubagentDispatch(runId, label);\n\t\t\t\ttaskStore.update(task.id, { status: \"in_progress\" });\n\t\t\t\ttry {\n\t\t\t\t\tconst dispatchResult = await cancelOnAbort(runId, () =>\n\t\t\t\t\t\tpool.resume(resumeId, params.prompt, {\n\t\t\t\t\t\t\tmodel: ctx.model?.id,\n\t\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\t\ttaskId: runId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\t// The session lives under the original task id; keep it as the resume handle.\n\t\t\t\t\treturn finalizeDispatchResult(dispatchResult, params.subagent_type, runId, task.id, resumeId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tmarkDispatchFailed(task.id, runId);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The model has already decided to delegate and which agent to use; honor\n\t\t\t// it. Validate the requested agent against the registry (no routing gate).\n\t\t\tconst registry = loadAgentRegistry({ cwd: ctx.cwd });\n\t\t\tconst def = registry.get(params.subagent_type);\n\t\t\tif (!def) {\n\t\t\t\tconst available = registry\n\t\t\t\t\t.list()\n\t\t\t\t\t.map((a) => a.name)\n\t\t\t\t\t.join(\", \");\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unknown subagent_type: \"${params.subagent_type}\". Available agents: ${available || \"(none)\"}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst summary = params.description?.trim() || summarize(params.prompt);\n\t\t\t// One roster row per dispatch, keyed by the (pre-allocated) pool task id.\n\t\t\t// Keying by agent TYPE made concurrent same-type runs share a single row:\n\t\t\t// their activity, state, and stats collided last-writer-wins. The inbox\n\t\t\t// already keys by task id; this aligns the panel to the same model. The\n\t\t\t// pool's task_progress events carry the task id, so patching by this id\n\t\t\t// routes live activity to the right row.\n\t\t\tconst poolTaskId = newDispatchTaskId();\n\t\t\tconst label = subagentInbox.nextLabel(params.subagent_type);\n\t\t\tconst task = taskStore.create(summary, {\n\t\t\t\tsource: \"subagent\",\n\t\t\t\tsubagentMode: params.subagent_type,\n\t\t\t\tagent: poolTaskId,\n\t\t\t\t// Tie this run to the plan item it executes (the single in_progress\n\t\t\t\t// TodoWrite task, when unambiguous) so the panel can nest it there.\n\t\t\t\tlinkedTaskId: linkedTodoId(),\n\t\t\t});\n\t\t\tregisterSubagentDispatch(poolTaskId, label);\n\t\t\ttaskStore.update(task.id, { status: \"in_progress\" });\n\t\t\t// Fork agents inherit the parent's conversation via a forked session.\n\t\t\tconst forkSessionFile = def.fork\n\t\t\t\t? resolveForkSessionFile(def, ctx.sessionManager?.getSessionFile(), ctx.cwd)\n\t\t\t\t: undefined;\n\n\t\t\t// `complexity` is passed as the model: the pool's spawn() already lets a\n\t\t\t// non-`inherit` agent model win, then resolves a category string (fast/\n\t\t\t// standard/capable) via settings.modelCategories. So a pinned-model agent\n\t\t\t// ignores complexity, and an `inherit` agent picks up the requested tier —\n\t\t\t// no settings lookup needed here.\n\t\t\tconst dispatchModel = params.complexity ?? ctx.model?.id;\n\n\t\t\t// Whether this call runs detached. The agent loop reads the tool's\n\t\t\t// `background` flag (the same predicate) to run execute() detached; we\n\t\t\t// recompute it here to choose the notify-and-pull return shape.\n\t\t\tconst isBackground = params.background ?? backgroundAgents.has(params.subagent_type);\n\n\t\t\tif (isBackground) {\n\t\t\t\t// Notify-and-pull: register the dispatch in the inbox under the\n\t\t\t\t// pre-allocated id, await it, retain the body in the inbox, and return a\n\t\t\t\t// compact notification (not the body). The model pulls it with TaskOutput.\n\t\t\t\tsubagentInbox.observe(pool);\n\t\t\t\tsubagentInbox.start(poolTaskId, label, params.subagent_type);\n\n\t\t\t\t// Warm path (opt-in): run on a reused RPC worker, retain the body in the\n\t\t\t\t// inbox, and return the same notify-and-pull shape as the cold path. An\n\t\t\t\t// infra failure falls through to the cold dispatch below.\n\t\t\t\tif (warmSubagentsEnabled() && !forkSessionFile) {\n\t\t\t\t\tconst warm = getWarmSubagentPool(ctx.cwd, availableModels);\n\t\t\t\t\tif (warm.isPoolable(params.subagent_type)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst warmResult = await warm.dispatch(\n\t\t\t\t\t\t\t\tparams.prompt,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tagentType: params.subagent_type,\n\t\t\t\t\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\t\t\t\t\tmodel: dispatchModel,\n\t\t\t\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t(activity) => taskStore.patchAgent(poolTaskId, { activity }),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst dispatchResult = warmResultToTaskResult(warmResult, params.subagent_type, task.id);\n\t\t\t\t\t\t\tsubagentInbox.finish(poolTaskId, dispatchResult);\n\t\t\t\t\t\t\treturn finalizeDispatchResult(\n\t\t\t\t\t\t\t\tdispatchResult,\n\t\t\t\t\t\t\t\tparams.subagent_type,\n\t\t\t\t\t\t\t\tpoolTaskId,\n\t\t\t\t\t\t\t\ttask.id,\n\t\t\t\t\t\t\t\tpoolTaskId,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttaskId: poolTaskId,\n\t\t\t\t\t\t\t\t\tlabel,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (!(error instanceof WarmWorkerError)) throw error;\n\t\t\t\t\t\t\tagentLog(`[WARM] ${params.subagent_type} fell back to cold spawn: ${error.message}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst dispatchResult = await cancelOnAbort(poolTaskId, () =>\n\t\t\t\t\t\tpool.dispatch(params.prompt, {\n\t\t\t\t\t\t\tforceAgent: params.subagent_type,\n\t\t\t\t\t\t\tcontext: \"\",\n\t\t\t\t\t\t\tmodel: dispatchModel,\n\t\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\t\tsessionFile: forkSessionFile,\n\t\t\t\t\t\t\ttaskId: poolTaskId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tsubagentInbox.finish(poolTaskId, dispatchResult);\n\t\t\t\t\treturn finalizeDispatchResult(dispatchResult, params.subagent_type, poolTaskId, task.id, poolTaskId, {\n\t\t\t\t\t\ttaskId: poolTaskId,\n\t\t\t\t\t\tlabel,\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tmarkDispatchFailed(task.id, poolTaskId);\n\t\t\t\t\tsubagentInbox.fail(poolTaskId, reason);\n\t\t\t\t\t// A background dispatch reports failure as a compact notification, not a\n\t\t\t\t\t// thrown tool error — the call was already answered by a placeholder.\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: `${label} failed ✗ — ${reason}` }],\n\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\tsubagent_type: params.subagent_type,\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\terror: reason,\n\t\t\t\t\t\t\ttaskId: task.id,\n\t\t\t\t\t\t\tpoolTaskId,\n\t\t\t\t\t\t\tbackground: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Warm path (opt-in): for an eligible foreground dispatch, run on a reused\n\t\t\t// RPC worker to skip the cold-boot. Fork agents (forkSessionFile set) and\n\t\t\t// non-poolable types are excluded. Any infra failure falls through to the\n\t\t\t// cold pool below, so enabling this can only change latency, never whether\n\t\t\t// the task can run.\n\t\t\tif (warmSubagentsEnabled() && !forkSessionFile) {\n\t\t\t\tconst warm = getWarmSubagentPool(ctx.cwd, availableModels);\n\t\t\t\tif (warm.isPoolable(params.subagent_type)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst warmResult = await warm.dispatch(\n\t\t\t\t\t\t\tparams.prompt,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tagentType: params.subagent_type,\n\t\t\t\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\t\t\t\tmodel: dispatchModel,\n\t\t\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t// Mirror the cold pool's live progress on the task panel roster so a\n\t\t\t\t\t\t\t// warm dispatch reads as busy (⋯ grep), not stuck.\n\t\t\t\t\t\t\t(activity) => taskStore.patchAgent(poolTaskId, { activity }),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst dispatchResult = warmResultToTaskResult(warmResult, params.subagent_type, task.id);\n\t\t\t\t\t\treturn finalizeDispatchResult(dispatchResult, params.subagent_type, poolTaskId, task.id, undefined);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// A genuine infra failure (worker crash/timeout) retries cold; any other\n\t\t\t\t\t\t// error is a real dispatch failure and propagates.\n\t\t\t\t\t\tif (!(error instanceof WarmWorkerError)) {\n\t\t\t\t\t\t\ttaskStore.update(task.id, { status: \"failed\" });\n\t\t\t\t\t\t\ttaskStore.patchAgent(poolTaskId, { state: \"failed\", activity: \"\" });\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tagentLog(`[WARM] ${params.subagent_type} fell back to cold spawn: ${error.message}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Foreground: block the turn and return the subagent's full answer inline.\n\t\t\ttry {\n\t\t\t\tconst dispatchResult = await cancelOnAbort(poolTaskId, () =>\n\t\t\t\t\tpool.dispatch(params.prompt, {\n\t\t\t\t\t\tforceAgent: params.subagent_type,\n\t\t\t\t\t\tcontext: \"\",\n\t\t\t\t\t\tmodel: dispatchModel,\n\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\tsessionFile: forkSessionFile,\n\t\t\t\t\t\ttaskId: poolTaskId,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn finalizeDispatchResult(\n\t\t\t\t\tdispatchResult,\n\t\t\t\t\tparams.subagent_type,\n\t\t\t\t\tpoolTaskId,\n\t\t\t\t\ttask.id,\n\t\t\t\t\tdispatchResult.task_id,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tmarkDispatchFailed(task.id, poolTaskId);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\n\t\trenderCall(args, theme) {\n\t\t\tconst type = args.subagent_type ?? \"agent\";\n\t\t\t// The [type] tag carries the agent's identity color — the same hue this\n\t\t\t// agent has in the task panel and TaskOutput — so a transcript full of\n\t\t\t// concurrent dispatches is scannable by color.\n\t\t\tconst text = theme.fg(\"toolTitle\", theme.bold(\"Agent \")) + theme.fg(agentColorFor(type), `[${type}]`);\n\t\t\treturn new Text(text, 0, 0);\n\t\t},\n\t});\n}\n\n/**\n * For a `fork: true` agent, fork the parent's session so the subagent inherits the\n * full parent conversation (and its prompt cache) instead of starting fresh. Returns\n * the forked session file to dispatch the child with, or undefined to fall back to a\n * fresh session (non-fork agent, no parent session, or an empty/invalid source).\n */\nexport function resolveForkSessionFile(\n\tdef: Pick<AgentDefinition, \"fork\">,\n\tparentSessionPath: string | undefined,\n\tcwd: string,\n): string | undefined {\n\tif (!def.fork || !parentSessionPath) return undefined;\n\ttry {\n\t\treturn SessionManager.forkFrom(parentSessionPath, cwd).getSessionFile();\n\t} catch {\n\t\t// Empty/invalid parent session: fall back to a fresh subagent session.\n\t\treturn undefined;\n\t}\n}\n\n/** Pre-allocated pool task id for a dispatch (matches the pool's own format). */\nfunction newDispatchTaskId(): string {\n\treturn `dispatch-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/**\n * The TodoWrite plan item this dispatch is (most plausibly) working on: the\n * single in_progress main-agent task. TodoWrite discipline keeps exactly one\n * item in_progress, so when that holds the link is unambiguous; with zero or\n * several in_progress items no link is recorded rather than guessing. Used to\n * nest the run under its plan item in the task panel's flat lens.\n */\nfunction linkedTodoId(): number | undefined {\n\tconst inProgress = taskStore\n\t\t.list()\n\t\t.filter(\n\t\t\t(t) =>\n\t\t\t\tt.source === undefined &&\n\t\t\t\tt.agent === undefined &&\n\t\t\t\tt.parentTaskId === undefined &&\n\t\t\t\tt.status === \"in_progress\",\n\t\t);\n\treturn inProgress.length === 1 ? inProgress[0]?.id : undefined;\n}\n\n/**\n * Register this dispatch in the task store's roster, keyed by its run id (the\n * pool task id) so concurrent runs of the same agent type each get their own\n * row, state, activity, and stats. The friendly label (\"explore#1\") names the\n * row the same way the inbox names background tasks.\n */\nfunction registerSubagentDispatch(runId: string, label: string): void {\n\ttaskStore.upsertAgent({ id: runId, name: label, role: \"subagent\", kind: \"subagent\", state: \"running\" });\n}\n\n/**\n * Catch-path bookkeeping: mark the dispatch failed unless it already settled.\n * finalizeDispatchResult records a terminal status (failed/cancelled) *before*\n * throwing, so a blanket \"failed\" here would clobber a cancellation with a\n * failure the moment the thrown error passed through.\n */\nfunction markDispatchFailed(taskStoreId: number, runId: string): void {\n\tconst current = taskStore.list().find((t) => t.id === taskStoreId);\n\tif (current && current.status !== \"pending\" && current.status !== \"in_progress\") return;\n\ttaskStore.update(taskStoreId, { status: \"failed\" });\n\ttaskStore.patchAgent(runId, { state: \"failed\", activity: \"\" });\n}\n\n/** Names of agents configured to run in the background (non-blocking). */\nfunction collectBackgroundAgentNames(cwd: string): Set<string> {\n\tconst names = new Set<string>();\n\tfor (const agent of loadAgentRegistry({ cwd }).list()) {\n\t\tif (agent.background) names.add(agent.name);\n\t}\n\treturn names;\n}\n\n/**\n * Merge a child subagent's task subtree into the parent's task store, rooting\n * each top-level node under the dispatching task (`parentTaskId`). Recurses so a\n * subagent that itself delegated shows its nested work — the subtree the child\n * could not surface across the process boundary on its own. Each node is its own\n * task (no key-by-type collapse), preserving the order the child created them.\n */\nfunction mergeChildTaskTree(nodes: readonly SubagentTaskNode[] | undefined, parentTaskId: number): void {\n\tif (!nodes) return;\n\ttaskStore.batch(() => {\n\t\tfor (const node of nodes) {\n\t\t\tconst created = taskStore.create(node.title, {\n\t\t\t\tsource: node.source,\n\t\t\t\tsubagentMode: node.subagentMode,\n\t\t\t\tparentTaskId,\n\t\t\t});\n\t\t\ttaskStore.update(created.id, { status: node.status, usage: node.usage });\n\t\t\tmergeChildTaskTree(node.children, created.id);\n\t\t}\n\t});\n}\n\n/**\n * Adapt a warm-worker run into the TaskResult shape finalizeDispatchResult\n * consumes, so the warm and cold paths share one finish/render path. A warm run\n * returns its answer inline (no result.json), so we synthesize an equivalent\n * SubagentResult with the answer as the summary and the pulled usage. The warm\n * path is clean (no persisted session), so there is no task_tree to merge and no\n * resume handle.\n */\nfunction warmResultToTaskResult(warm: WarmRunResult, agentType: string, taskStoreId: number): TaskResult {\n\tconst resultData: SubagentResultFile = {\n\t\tsummary: warm.summary || \"(subagent returned no output)\",\n\t\tfiles_changed: [],\n\t\tconfidence: warm.ok ? 1 : 0,\n\t\tstatus: warm.status,\n\t\tusage: warm.usage,\n\t};\n\tconst result: SubagentResult = {\n\t\ttask_id: String(taskStoreId),\n\t\tok: warm.ok,\n\t\tstdout: \"\",\n\t\tstderr: \"\",\n\t\texit_code: warm.ok ? 0 : 1,\n\t\tstatus: warm.status,\n\t\terror: warm.error,\n\t\tresult_data: resultData as unknown as Record<string, unknown>,\n\t};\n\treturn { handled_inline: false, agent_type: agentType, result };\n}\n\n/**\n * Update the task panel from a finished dispatch and shape the tool result.\n *\n * Foreground calls return the subagent's full answer inline and signal a hard\n * failure by throwing (the agent loop derives a tool's error state from a thrown\n * error). A background call passes `background`: the body already lives in the\n * inbox, so it returns a compact, self-contained notification (success or\n * failure) and never throws — the call was already answered by a placeholder.\n */\nfunction finalizeDispatchResult(\n\tdispatchResult: TaskResult,\n\tsubagentType: string,\n\trunAgentId: string,\n\ttaskStoreId: number,\n\tresumeHandle: string | undefined,\n\tbackground?: { taskId: string; label: string },\n): { content: Array<{ type: \"text\"; text: string }>; details: TaskToolDetails } {\n\tconst result = dispatchResult.result;\n\tconst resultData = result?.result_data as SubagentResultFile | undefined;\n\tconst usage = resultData?.usage;\n\n\t// Merge the child's own task subtree under the dispatching task so nested\n\t// delegation (depth >= 2) is visible in the subagents lens's task tree.\n\tmergeChildTaskTree(resultData?.task_tree, taskStoreId);\n\n\t// Roll this run's usage into its own roster row (rows are per-dispatch).\n\tif (usage) {\n\t\ttaskStore.addAgentStats(runAgentId, { input: usage.input, output: usage.output, cost: usage.cost });\n\t}\n\n\tif (!result || !result.ok) {\n\t\t// A user-initiated cancel is not a failure: it gets its own terminal\n\t\t// status so the panel shows ⊘ cancelled (dim) instead of ✗ failed (red).\n\t\tconst cancelled = result?.status === \"cancelled\";\n\t\tconst failNote = result?.usedInheritedModelFallback ? \"inherited-model retry failed\" : undefined;\n\t\ttaskStore.update(taskStoreId, { status: cancelled ? \"cancelled\" : \"failed\", usage, note: failNote });\n\t\ttaskStore.patchAgent(runAgentId, { state: cancelled ? \"cancelled\" : \"failed\", activity: \"\" });\n\t\tconst reason = result?.error ?? (result?.status ? `subagent ${result.status}` : \"unknown error\");\n\t\tif (background) {\n\t\t\tconst verdict = cancelled ? \"cancelled ⊘\" : \"failed ✗\";\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `${background.label} ${verdict} — ${reason}` }],\n\t\t\t\tdetails: {\n\t\t\t\t\tsubagent_type: subagentType,\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: reason,\n\t\t\t\t\ttaskId: taskStoreId,\n\t\t\t\t\tpoolTaskId: background.taskId,\n\t\t\t\t\tbackground: true,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (cancelled) {\n\t\t\tthrow new Error(`Subagent (${subagentType}) cancelled by user.`);\n\t\t}\n\t\tconst stderr = result?.stderr?.trim();\n\t\tthrow new Error(`Subagent (${subagentType}) failed: ${reason}${stderr ? `\\nstderr: ${stderr.slice(-500)}` : \"\"}`);\n\t}\n\n\t// Leave the task in the store with its final status; it stays visible in the\n\t// task panel until the next user message arrives. Surface a ⚠ cue when the run\n\t// fell back to the inherited model rather than emitting a chat message — and\n\t// clear any stale note otherwise (note is clearable via an explicit undefined).\n\tconst fallbackNote = dispatchResult.result?.usedInheritedModelFallback ? \"ran on inherited model\" : undefined;\n\ttaskStore.update(taskStoreId, { status: \"done\", usage, note: fallbackNote });\n\t// Rows are per-run, so this run settles to done regardless of siblings.\n\ttaskStore.patchAgent(runAgentId, { state: \"done\", activity: \"\" });\n\tlet answer = resultData?.summary || \"(subagent returned no output)\";\n\t// Partial results are resumable; surface the handle so the parent can continue.\n\tif (result.status === \"partial\" && resumeHandle) {\n\t\tanswer += `\\n\\n[Partial result. To continue this subagent, call Task again with resume_task_id=\"${resumeHandle}\".]`;\n\t}\n\n\tif (background) {\n\t\t// Compact notification: the body is retained in the inbox; the model pulls it\n\t\t// with TaskOutput. Keeps a wide swarm from flooding the parent's context.\n\t\tconst partial = result.status === \"partial\" ? \" (partial — resume to continue)\" : \"\";\n\t\tconst outstanding = subagentInbox.outstanding().length;\n\t\tconst tail = outstanding > 0 ? ` ${outstanding} still running.` : \"\";\n\t\tconst text =\n\t\t\t`${background.label} finished ✓${partial} — ${summarize(answer)}.${tail}\\n` +\n\t\t\t`Read the full result with TaskOutput(\"${background.label}\").`;\n\t\treturn {\n\t\t\tcontent: [{ type: \"text\", text }],\n\t\t\tdetails: {\n\t\t\t\tsubagent_type: subagentType,\n\t\t\t\tok: true,\n\t\t\t\ttaskId: taskStoreId,\n\t\t\t\tpoolTaskId: background.taskId,\n\t\t\t\tbackground: true,\n\t\t\t},\n\t\t};\n\t}\n\n\treturn {\n\t\tcontent: [{ type: \"text\", text: answer }],\n\t\tdetails: { subagent_type: subagentType, ok: true, taskId: taskStoreId, poolTaskId: resumeHandle },\n\t};\n}\n\nconst taskOutputParams = Type.Object({\n\ttask_id: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t'Handle of a background subagent — its task_id or friendly label (e.g. \"explore#1\") from a Task notification. Omit (or set list:true) to see every background task.',\n\t\t}),\n\t),\n\tlist: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"List all background subagents with their status (running/done/failed/cancelled) and current activity. No result bodies are returned.\",\n\t\t}),\n\t),\n\twait: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Block until the named task finishes — or, with no task_id, until all outstanding subagents finish (a swarm barrier) — before returning. Bounded by timeout_ms.\",\n\t\t}),\n\t),\n\ttimeout_ms: Type.Optional(\n\t\tType.Number({ description: \"Maximum time to block in wait mode, in milliseconds (default 120000).\" }),\n\t),\n});\n\ntype TaskOutputParams = Static<typeof taskOutputParams>;\n\nconst TASK_OUTPUT_DEFAULT_TIMEOUT_MS = 120_000;\n\n/**\n * Elapsed time a record has run (so far, or until it settled), in the same\n * format the task panel uses so the two surfaces always agree.\n */\nfunction recordElapsed(rec: InboxRecord): string {\n\tconst end = rec.endedAt ?? Date.now();\n\treturn formatDurationSecs((end - rec.startedAt) / 1000);\n}\n\n/** A compact roster of every known background subagent — status + activity, no bodies. */\nfunction formatTaskRoster(): { content: Array<{ type: \"text\"; text: string }>; details: TaskOutputDetails } {\n\tconst all = subagentInbox.list();\n\tconst outstanding = subagentInbox.outstanding().length;\n\tif (all.length === 0) {\n\t\treturn {\n\t\t\tcontent: [{ type: \"text\", text: \"No background subagents have been dispatched.\" }],\n\t\t\tdetails: { status: \"empty\", ok: true, outstanding: 0 },\n\t\t};\n\t}\n\tconst lines = all.map((r) => {\n\t\tconst when = recordElapsed(r);\n\t\tswitch (r.lifecycle) {\n\t\t\tcase \"running\":\n\t\t\t\treturn `- ${r.label} running ${when}${r.lastActivity ? ` · ${r.lastActivity}` : \"\"}`;\n\t\t\tcase \"done\":\n\t\t\t\treturn `- ${r.label} done (uncollected) ${when} — ${r.summaryLine ?? \"\"}`;\n\t\t\tcase \"collected\":\n\t\t\t\treturn `- ${r.label} collected ${when} — ${r.summaryLine ?? \"\"}`;\n\t\t\tcase \"cancelled\":\n\t\t\t\treturn `- ${r.label} cancelled ⊘ — ${r.error ?? \"cancelled by user\"}`;\n\t\t\tdefault:\n\t\t\t\treturn `- ${r.label} ${r.lifecycle} ✗ — ${r.error ?? \"unknown error\"}`;\n\t\t}\n\t});\n\tconst header = `${all.length} background subagent${all.length === 1 ? \"\" : \"s\"} (${outstanding} running):`;\n\tconst hint = all.some((r) => r.lifecycle === \"done\") ? '\\nRead a finished one with TaskOutput(\"<label>\").' : \"\";\n\treturn {\n\t\tcontent: [{ type: \"text\", text: `${header}\\n${lines.join(\"\\n\")}${hint}` }],\n\t\tdetails: { status: \"list\", ok: true, outstanding },\n\t};\n}\n\n/**\n * TaskOutput tool: check on background subagents and pull their results.\n *\n * Background `Task` calls don't push their body into the conversation — they\n * leave it in the inbox and post a compact notification. TaskOutput is how the\n * model pulls a body, checks liveness, or waits. It never throws on a valid\n * handle (an error tool result would only confuse the loop): it reports status\n * instead. Modes: `list` (roster), a `task_id` to read/check one, and `wait` to\n * block until one task — or all outstanding tasks — finish.\n */\nexport function createTaskOutputToolDefinition(): ToolDefinition {\n\treturn defineTool<typeof taskOutputParams, TaskOutputDetails>({\n\t\tname: \"TaskOutput\",\n\t\tlabel: \"TaskOutput\",\n\t\tdescription: [\n\t\t\t\"Check on background subagents dispatched via Task, and pull their results.\",\n\t\t\t'Pass a task_id/label (e.g. \"explore#1\") to read a finished subagent\\'s full result, or to see its status while it runs.',\n\t\t\t\"Set list:true (or omit task_id) to list every background subagent with its status and current activity.\",\n\t\t\t\"Set wait:true to block until that task finishes — or, with no task_id, until all outstanding subagents finish (a swarm barrier).\",\n\t\t\t\"It never errors on a valid handle: a running task reports status, a finished one returns its result, an already-read one says so.\",\n\t\t].join(\"\\n\"),\n\t\tpromptSnippet: \"check status / list / collect the results of background subagents\",\n\t\tparameters: taskOutputParams,\n\n\t\tasync execute(_toolCallId, params: TaskOutputParams, _signal, _onUpdate, ctx) {\n\t\t\t// Touch the pool so the inbox is wired to its progress stream for activity.\n\t\t\t// The pool is normally already created by a prior dispatch; pass available\n\t\t\t// models so a first-touch here still seeds category derivation.\n\t\t\tsubagentInbox.observe(getSubagentPool(ctx.cwd, ctx.modelRegistry?.getAvailable() ?? []));\n\t\t\tconst handle = params.task_id?.trim();\n\n\t\t\t// Barrier: wait for the target (or all outstanding) to settle first.\n\t\t\tif (params.wait) {\n\t\t\t\tconst timeout = params.timeout_ms ?? TASK_OUTPUT_DEFAULT_TIMEOUT_MS;\n\t\t\t\tif (handle) await subagentInbox.waitFor(handle, timeout);\n\t\t\t\telse await subagentInbox.waitForAll(timeout);\n\t\t\t}\n\n\t\t\t// Roster when asked, or when no specific task was named.\n\t\t\tif (params.list || !handle) {\n\t\t\t\treturn formatTaskRoster();\n\t\t\t}\n\n\t\t\tconst rec = subagentInbox.get(handle);\n\t\t\tif (!rec) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `No background task \"${handle}\". Call TaskOutput with list:true to see active tasks.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { task_id: handle, status: \"unknown\", ok: false },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (rec.lifecycle === \"running\") {\n\t\t\t\tconst activity = rec.lastActivity ? ` (currently: ${rec.lastActivity})` : \"\";\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `${rec.label} is still running — ${recordElapsed(rec)} elapsed${activity}. Call TaskOutput again, or with wait:true to block until it finishes.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { task_id: handle, status: \"running\", ok: true },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (rec.lifecycle === \"done\") {\n\t\t\t\tconst collected = subagentInbox.collect(handle);\n\t\t\t\tconst body = collected?.body ?? rec.summaryLine ?? \"(subagent returned no output)\";\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: body }],\n\t\t\t\t\tdetails: { task_id: handle, status: \"done\", ok: true },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (rec.lifecycle === \"collected\") {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `${rec.label} was already delivered — ${rec.summaryLine ?? \"(no summary kept)\"}.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { task_id: handle, status: \"collected\", ok: true },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// failed / stalled / timeout / cancelled\n\t\t\tconst glyph = rec.lifecycle === \"cancelled\" ? \"⊘\" : \"✗\";\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: `${rec.label} ${rec.lifecycle} ${glyph} — ${rec.error ?? \"unknown error\"}.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { task_id: handle, status: rec.lifecycle, ok: false },\n\t\t\t};\n\t\t},\n\n\t\trenderCall(args, theme) {\n\t\t\tconst target = args.list ? \"list\" : String(args.task_id ?? \"\");\n\t\t\t// A friendly label (\"explore#1\") gets its agent's identity color so the\n\t\t\t// pull visually pairs with the dispatch that produced it; raw ids and\n\t\t\t// \"list\" stay dim.\n\t\t\tconst hashIdx = target.indexOf(\"#\");\n\t\t\tconst styledTarget =\n\t\t\t\thashIdx > 0 ? theme.fg(agentColorFor(target.slice(0, hashIdx)), target) : theme.fg(\"dim\", target);\n\t\t\tconst text =\n\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(\"TaskOutput \")) +\n\t\t\t\tstyledTarget +\n\t\t\t\t(args.wait ? theme.fg(\"dim\", \" (wait)\") : \"\");\n\t\t\treturn new Text(text, 0, 0);\n\t\t},\n\n\t\trenderResult(result, _options, theme) {\n\t\t\t// Display-only framing/colorization (the text sent to the model stays\n\t\t\t// plain). A single-task pull renders as a result CARD — a status-stamped\n\t\t\t// header, a left spine down the body, and a closing corner — so a\n\t\t\t// collected result reads as a discrete artifact instead of blending into\n\t\t\t// the surrounding tool chatter. Roster/list responses keep the line\n\t\t\t// colorization.\n\t\t\tconst text = result.content\n\t\t\t\t.map((c) => (c.type === \"text\" ? c.text : \"\"))\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (!text) return new Text(\"\", 0, 0);\n\n\t\t\tconst details = result.details as TaskOutputDetails | undefined;\n\t\t\tconst cardStatus = details?.task_id ? details.status : undefined;\n\t\t\tif (cardStatus && cardStatus !== \"list\" && cardStatus !== \"empty\") {\n\t\t\t\tconst presentation: Record<\n\t\t\t\t\tstring,\n\t\t\t\t\t{ glyph: string; color: \"success\" | \"warning\" | \"error\" | \"muted\" | \"dim\" }\n\t\t\t\t> = {\n\t\t\t\t\tdone: { glyph: \"✓\", color: \"success\" },\n\t\t\t\t\trunning: { glyph: \"◐\", color: \"warning\" },\n\t\t\t\t\tcollected: { glyph: \"✓\", color: \"muted\" },\n\t\t\t\t\tcancelled: { glyph: \"⊘\", color: \"dim\" },\n\t\t\t\t\tunknown: { glyph: \"?\", color: \"dim\" },\n\t\t\t\t};\n\t\t\t\tconst { glyph, color } = presentation[cardStatus] ?? { glyph: \"✗\", color: \"error\" as const };\n\t\t\t\tconst label = details?.task_id ?? \"\";\n\t\t\t\tconst hashIdx = label.indexOf(\"#\");\n\t\t\t\tconst labelColor = hashIdx > 0 ? agentColorFor(label.slice(0, hashIdx)) : \"accent\";\n\n\t\t\t\t// Look up inbox record for elapsed time\n\t\t\t\tconst inboxRecord = subagentInbox.get(label);\n\t\t\t\tconst elapsed = inboxRecord ? (inboxRecord.endedAt ?? Date.now()) - inboxRecord.startedAt : undefined;\n\t\t\t\tconst elapsedText = elapsed ? ` ${formatDurationSecs(elapsed / 1000)}` : \"\";\n\n\t\t\t\t// Look up task for token count\n\t\t\t\tconst task = inboxRecord ? taskStore.list().find((t) => t.agent === inboxRecord.taskId) : undefined;\n\t\t\t\tconst totalTokens = task?.usage ? task.usage.input + task.usage.output : undefined;\n\t\t\t\tconst tokenText = totalTokens !== undefined ? ` ${formatTokens(totalTokens)}` : \"\";\n\n\t\t\t\tconst spine = (s: string) => theme.fg(\"borderMuted\", s);\n\t\t\t\tconst header =\n\t\t\t\t\t`${spine(\"╭\")} ${theme.fg(color, glyph)} ` +\n\t\t\t\t\t`${theme.bold(theme.fg(color, cardStatus))} ${theme.fg(labelColor, label)}${tokenText}${elapsedText}`;\n\t\t\t\tconst body = text\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.map((line) => `${spine(\"│\")} ${theme.fg(\"toolOutput\", line)}`)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\treturn new Text(`${header}\\n${body}\\n${spine(\"╰\")}`, 0, 0);\n\t\t\t}\n\n\t\t\tconst rosterLine =\n\t\t\t\t/^- (\\S+)\\s{2}(running|done \\(uncollected\\)|collected|failed|stalled|timeout|cancelled)(.*)$/;\n\t\t\tconst styled = text\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((line) => {\n\t\t\t\t\tconst match = rosterLine.exec(line);\n\t\t\t\t\tif (!match) return theme.fg(\"toolOutput\", line);\n\t\t\t\t\tconst [, label, status, rest] = match as unknown as [string, string, string, string];\n\t\t\t\t\tconst hashIdx = label.indexOf(\"#\");\n\t\t\t\t\tconst labelColor = hashIdx > 0 ? agentColorFor(label.slice(0, hashIdx)) : \"accent\";\n\t\t\t\t\tconst statusColor =\n\t\t\t\t\t\tstatus === \"running\"\n\t\t\t\t\t\t\t? \"warning\"\n\t\t\t\t\t\t\t: status.startsWith(\"done\")\n\t\t\t\t\t\t\t\t? \"success\"\n\t\t\t\t\t\t\t\t: status === \"collected\" || status === \"cancelled\"\n\t\t\t\t\t\t\t\t\t? \"muted\"\n\t\t\t\t\t\t\t\t\t: \"error\";\n\t\t\t\t\treturn `- ${theme.fg(labelColor, label)} ${theme.fg(statusColor, status)}${theme.fg(\"dim\", rest)}`;\n\t\t\t\t})\n\t\t\t\t.join(\"\\n\");\n\t\t\treturn new Text(styled, 0, 0);\n\t\t},\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../../src/core/tools/subagent.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Task tool: delegate a focused task to a specialized subagent.\n *\n * Mirrors the Claude Code `Task` tool. The parent agent decides *when* to\n * delegate based on each agent's `description` (there is no deterministic gate)\n * and selects *which* agent via `subagent_type`. The chosen agent runs in a\n * fresh, isolated child process (SubagentPool) and only its final answer is\n * returned to the parent.\n *\n * Enabled by default (the `enableSubagent` setting defaults to true); disable\n * with `enableSubagent: false`. The `--enable-subagents` flag still force-enables\n * it. Nesting is bounded by the tree-wide depth cap (maxSubagentDepth, default 2:\n * a spawned subagent may itself delegate one more level, and depth-2 grandchildren\n * cannot). See buildSessionOptions in main.ts.\n */\n\nimport { Text } from \"@kolisachint/hoocode-tui\";\nimport { type Static, Type } from \"typebox\";\nimport { EMBEDDED_PROMPTS } from \"../../init-templates.generated.js\";\nimport { agentColorFor } from \"../../modes/interactive/theme/theme.js\";\nimport { type AgentDefinition, TASK_TOOL_NAME } from \"../agent-frontmatter.js\";\nimport { agentLog } from \"../agent-log.js\";\nimport { loadAgentRegistry } from \"../agent-registry.js\";\nimport type { ToolDefinition } from \"../extensions/types.js\";\nimport { defineTool } from \"../extensions/types.js\";\nimport { formatDurationSecs } from \"../format-duration.js\";\nimport { formatTokens } from \"../format-tokens.js\";\nimport { getProviderExhaustion } from \"../provider-health.js\";\nimport { SessionManager } from \"../session-manager.js\";\nimport { delegateAllowList, isDelegateAllowed } from \"../subagent-depth.js\";\nimport { type InboxRecord, subagentInbox } from \"../subagent-inbox.js\";\nimport type { SubagentResult, TaskResult } from \"../subagent-pool.js\";\nimport { getSubagentPool } from \"../subagent-pool-instance.js\";\nimport type { SubagentResultFile, SubagentTaskNode } from \"../subagent-result.js\";\nimport { taskStore } from \"../task-store.js\";\nimport { type WarmRunResult, WarmWorkerError } from \"../warm-subagent-pool.js\";\nimport { getWarmSubagentPool, warmSubagentsEnabled } from \"../warm-subagent-pool-instance.js\";\n\n// Re-exported from its home in agent-registry (where formatAgentsForPrompt uses\n// it to render the roster) so existing importers keep working without creating a\n// tools -> registry -> tools cycle.\nexport { summarizeAgentDescription } from \"../agent-registry.js\";\n\n/** System prompt appendix for the main session when the Task tool is enabled.\n * Instructs the parent agent on when and how to delegate effectively. The\n * available agents themselves are listed once, authoritatively, in the\n * `<available_agents>` block the system prompt emits whenever the Task tool is\n * active (see agent-session `_rebuildSystemPrompt`); this appendix references\n * that list rather than re-rendering the roster and paying for it twice. */\n/**\n * Build the main-session subagent instructions appended to the system prompt.\n *\n * The prose lives in `templates/prompts/task-*.md` and reaches here through the\n * build-time embed. It is the largest block of always-on text hoocode emits\n * (~600 tok/turn once the Task tool is on) and it had no interpolation beyond\n * the single background slot, so keeping it as a TypeScript string constant\n * bought nothing and made it awkward to edit as the prose it is.\n *\n * The detailed background/barrier guidance (the two heaviest bullets) is only\n * emitted when the project actually has background-capable agents; otherwise a\n * single concise line covers the per-call `background: true` escape hatch. This\n * keeps the always-on cost down for the common case where nothing runs in the\n * background. `cwd` is used only to detect those agents.\n */\nexport function buildTaskMainPrompt(cwd: string = process.cwd()): string {\n\tconst hasBackgroundAgents = collectBackgroundAgentNames(cwd).size > 0;\n\tconst backgroundGuidance = (\n\t\tEMBEDDED_PROMPTS[hasBackgroundAgents ? \"task-background-agents\" : \"task-background-none\"] ?? \"\"\n\t).trim();\n\n\t// Trimmed at both ends: the template file ends with a newline, and this is\n\t// appended to a system prompt that manages its own separators.\n\treturn (EMBEDDED_PROMPTS[\"task-main\"] ?? \"\").replace(\"{{BACKGROUND_GUIDANCE}}\", backgroundGuidance).trim();\n}\n\nconst taskParams = Type.Object({\n\tdescription: Type.String({\n\t\tdescription: \"A short (3-5 word) description of the task, shown in the task panel.\",\n\t}),\n\tprompt: Type.String({\n\t\tdescription:\n\t\t\t\"The full, self-contained task for the subagent. It cannot see this conversation, so include all needed context, files, and constraints.\",\n\t}),\n\tsubagent_type: Type.String({\n\t\tdescription: \"The name of the specialized agent to delegate to. Must be one of the available agents.\",\n\t}),\n\tcomplexity: Type.Optional(\n\t\tType.Union([Type.Literal(\"fast\"), Type.Literal(\"standard\"), Type.Literal(\"capable\")], {\n\t\t\tdescription:\n\t\t\t\t\"Model tier for this dispatch: fast (quick reads/lookups), standard (multi-file edits), capable (deep architecture). Maps to settings.modelCategories. Ignored if the chosen agent pins its own model; omit to use the agent's default.\",\n\t\t}),\n\t),\n\tbackground: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Set true to run non-blocking: you get a short notification when it finishes and pull the full result with TaskOutput; set false to wait and get the answer inline. Defaults to the agent's own background setting.\",\n\t\t}),\n\t),\n\tresume_task_id: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Optional. To continue a previous subagent run, pass its task_id (returned by an earlier Task or TaskOutput call). The subagent resumes with its full prior transcript and `prompt` is your follow-up instruction.\",\n\t\t}),\n\t),\n});\n\ntype TaskParams = Static<typeof taskParams>;\n\nexport interface TaskToolDetails {\n\tsubagent_type: string;\n\tok: boolean;\n\terror?: string;\n\ttaskId: number;\n\t/** Pool-level task id usable for resume/polling. */\n\tpoolTaskId?: string;\n\t/** True when dispatched as a non-blocking background task. */\n\tbackground?: boolean;\n}\n\nexport interface TaskOutputDetails {\n\t/** The handle queried, when a specific task was named. */\n\ttask_id?: string;\n\t/** running | done | collected | failed | stalled | timeout | cancelled | list | empty | unknown */\n\tstatus: string;\n\tok: boolean;\n\t/** Number of subagents still running, included on roster/list responses. */\n\toutstanding?: number;\n}\n\n/**\n * A short, human-readable task name for the task panel: the first line limited\n * to ~8 words so it stays glanceable. A character cap guards a single long word.\n */\nfunction summarize(task: string): string {\n\tconst firstLine = (task.trim().split(\"\\n\")[0] ?? \"\").trim();\n\tif (!firstLine) return \"(task)\";\n\tconst words = firstLine.split(/\\s+/);\n\tlet name = words.length > 8 ? `${words.slice(0, 8).join(\" \")}…` : firstLine;\n\tif (name.length > 60) name = `${name.slice(0, 59)}…`;\n\treturn name;\n}\n\n/** Create the Task tool definition. Registered as a customTool when enabled. */\nexport function createTaskToolDefinition(cwd: string = process.cwd()): ToolDefinition {\n\t// Agents whose definitions opt into background execution. The agent loop reads\n\t// the tool's `background` flag per call and, for these, runs the dispatch\n\t// detached: the parent keeps reasoning and the subagent's answer is injected as\n\t// a follow-up message when it finishes (no polling needed). A per-call\n\t// `background` argument overrides the agent's default in either direction.\n\tconst backgroundAgents = collectBackgroundAgentNames(cwd);\n\treturn defineTool<typeof taskParams, TaskToolDetails>({\n\t\tname: TASK_TOOL_NAME,\n\t\tlabel: TASK_TOOL_NAME,\n\t\tbackground: (toolCall) => {\n\t\t\tconst override = toolCall.arguments?.background;\n\t\t\tif (typeof override === \"boolean\") return override;\n\t\t\treturn backgroundAgents.has(String(toolCall.arguments?.subagent_type ?? \"\"));\n\t\t},\n\t\t// Kept to mechanics only: the when-to-use / when-not-to guidance lives once in\n\t\t// the system-prompt block (buildTaskMainPrompt), the available agents are\n\t\t// listed there too, and the `complexity`/`background`/`resume_task_id`\n\t\t// semantics live in their parameter descriptions. Repeating any of that here\n\t\t// would re-spend those tokens on every turn.\n\t\tdescription:\n\t\t\t\"Delegate a focused task to a specialized subagent that runs in a fresh, isolated context (it cannot see this conversation). Choose one of the available agents (listed in the system prompt) via `subagent_type` and pass everything it needs via `prompt`; the subagent returns only its final answer.\",\n\t\tpromptSnippet: \"delegate a self-contained task to a specialized subagent (choose via subagent_type)\",\n\t\tparameters: taskParams,\n\n\t\tasync execute(_toolCallId, params: TaskParams, signal, _onUpdate, ctx) {\n\t\t\t// Snapshot the caller's available models so unconfigured model-category\n\t\t\t// tiers (fast/standard/capable) resolve to a derived default instead of a\n\t\t\t// no-op. Explicit settings.modelCategories still win inside the pool. The\n\t\t\t// registry can be absent in some tool contexts; an empty list just keeps\n\t\t\t// category derivation a no-op (inherit parent), so guard the access.\n\t\t\tconst availableModels = ctx.modelRegistry?.getAvailable() ?? [];\n\t\t\tconst pool = getSubagentPool(ctx.cwd, availableModels);\n\n\t\t\t// User-initiated cancel (Esc/abort): kill the dispatched run's whole\n\t\t\t// process tree and let the dispatch settle with status \"cancelled\" —\n\t\t\t// distinct from \"failed\" everywhere it surfaces (panel, inbox, result).\n\t\t\t// Cold dispatches only: a warm worker has no cancel surface (it is\n\t\t\t// reused), so warm runs still complete server-side and are discarded.\n\t\t\tconst cancelOnAbort = async (poolRunId: string, run: () => Promise<TaskResult>): Promise<TaskResult> => {\n\t\t\t\tif (!signal) return run();\n\t\t\t\tconst onAbort = () => {\n\t\t\t\t\tpool.cancel?.(poolRunId);\n\t\t\t\t};\n\t\t\t\tif (signal.aborted) onAbort();\n\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\ttry {\n\t\t\t\t\treturn await run();\n\t\t\t\t} finally {\n\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Pre-flight: if the inherited provider recently exhausted its quota (the\n\t\t\t// parent's own turn failed with a usage/rate-limit error that did not\n\t\t\t// recover), skip the spawn. Subagents run on the same provider, so this\n\t\t\t// would only burn another failed attempt. The signal self-expires and is\n\t\t\t// cleared on the next successful response.\n\t\t\tconst provider = ctx.model?.provider;\n\t\t\tconst exhaustion = provider ? getProviderExhaustion(provider) : undefined;\n\t\t\tif (exhaustion) {\n\t\t\t\tconst skippedRunId = newDispatchTaskId();\n\t\t\t\tconst skipped = taskStore.create(params.description?.trim() || summarize(params.prompt), {\n\t\t\t\t\tsource: \"subagent\",\n\t\t\t\t\tsubagentMode: params.subagent_type,\n\t\t\t\t\tagent: skippedRunId,\n\t\t\t\t\tlinkedTaskId: linkedTodoId(),\n\t\t\t\t});\n\t\t\t\tregisterSubagentDispatch(skippedRunId, subagentInbox.nextLabel(params.subagent_type));\n\t\t\t\ttaskStore.update(skipped.id, { status: \"failed\", note: `${provider} exhausted` });\n\t\t\t\ttaskStore.patchAgent(skippedRunId, { state: \"failed\" });\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext:\n\t\t\t\t\t\t\t\t`Did not dispatch subagent \"${params.subagent_type}\": the \"${provider}\" provider appears ` +\n\t\t\t\t\t\t\t\t`exhausted or rate-limited (this session just failed with: ${exhaustion.message}). ` +\n\t\t\t\t\t\t\t\t`Subagents run on the same provider, so dispatching would fail too. Wait for the quota to ` +\n\t\t\t\t\t\t\t\t`reset or switch model/provider, then retry — or complete the work directly in this session.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { subagent_type: params.subagent_type, ok: false, taskId: skipped.id },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Scoped delegation: a delegating agent may be restricted to certain subagent\n\t\t\t// types (its `delegate: <types>` frontmatter). The root is unrestricted.\n\t\t\tif (!isDelegateAllowed(params.subagent_type)) {\n\t\t\t\tconst allowed = delegateAllowList()?.join(\", \") ?? \"\";\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`This agent may not delegate to \"${params.subagent_type}\". Allowed subagent types: ${allowed || \"(none)\"}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Resume path: continue a previously dispatched subagent with a follow-up\n\t\t\t// prompt, reusing its persisted session (full prior transcript).\n\t\t\tconst resumeId = params.resume_task_id?.trim();\n\t\t\tif (resumeId) {\n\t\t\t\tconst summary = params.description?.trim() || summarize(params.prompt);\n\t\t\t\tconst runId = newDispatchTaskId();\n\t\t\t\tconst label = subagentInbox.nextLabel(params.subagent_type);\n\t\t\t\tconst task = taskStore.create(summary, {\n\t\t\t\t\tsource: \"subagent\",\n\t\t\t\t\tsubagentMode: params.subagent_type,\n\t\t\t\t\tagent: runId,\n\t\t\t\t\tlinkedTaskId: linkedTodoId(),\n\t\t\t\t});\n\t\t\t\tregisterSubagentDispatch(runId, label);\n\t\t\t\ttaskStore.update(task.id, { status: \"in_progress\" });\n\t\t\t\ttry {\n\t\t\t\t\tconst dispatchResult = await cancelOnAbort(runId, () =>\n\t\t\t\t\t\tpool.resume(resumeId, params.prompt, {\n\t\t\t\t\t\t\tmodel: ctx.model?.id,\n\t\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\t\ttaskId: runId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\t// The session lives under the original task id; keep it as the resume handle.\n\t\t\t\t\treturn finalizeDispatchResult(dispatchResult, params.subagent_type, runId, task.id, resumeId);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tmarkDispatchFailed(task.id, runId);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The model has already decided to delegate and which agent to use; honor\n\t\t\t// it. Validate the requested agent against the registry (no routing gate).\n\t\t\tconst registry = loadAgentRegistry({ cwd: ctx.cwd });\n\t\t\tconst def = registry.get(params.subagent_type);\n\t\t\tif (!def) {\n\t\t\t\tconst available = registry\n\t\t\t\t\t.list()\n\t\t\t\t\t.map((a) => a.name)\n\t\t\t\t\t.join(\", \");\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unknown subagent_type: \"${params.subagent_type}\". Available agents: ${available || \"(none)\"}.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst summary = params.description?.trim() || summarize(params.prompt);\n\t\t\t// One roster row per dispatch, keyed by the (pre-allocated) pool task id.\n\t\t\t// Keying by agent TYPE made concurrent same-type runs share a single row:\n\t\t\t// their activity, state, and stats collided last-writer-wins. The inbox\n\t\t\t// already keys by task id; this aligns the panel to the same model. The\n\t\t\t// pool's task_progress events carry the task id, so patching by this id\n\t\t\t// routes live activity to the right row.\n\t\t\tconst poolTaskId = newDispatchTaskId();\n\t\t\tconst label = subagentInbox.nextLabel(params.subagent_type);\n\t\t\tconst task = taskStore.create(summary, {\n\t\t\t\tsource: \"subagent\",\n\t\t\t\tsubagentMode: params.subagent_type,\n\t\t\t\tagent: poolTaskId,\n\t\t\t\t// Tie this run to the plan item it executes (the single in_progress\n\t\t\t\t// TodoWrite task, when unambiguous) so the panel can nest it there.\n\t\t\t\tlinkedTaskId: linkedTodoId(),\n\t\t\t});\n\t\t\tregisterSubagentDispatch(poolTaskId, label);\n\t\t\ttaskStore.update(task.id, { status: \"in_progress\" });\n\t\t\t// Fork agents inherit the parent's conversation via a forked session.\n\t\t\tconst forkSessionFile = def.fork\n\t\t\t\t? resolveForkSessionFile(def, ctx.sessionManager?.getSessionFile(), ctx.cwd)\n\t\t\t\t: undefined;\n\n\t\t\t// `complexity` is passed as the model: the pool's spawn() already lets a\n\t\t\t// non-`inherit` agent model win, then resolves a category string (fast/\n\t\t\t// standard/capable) via settings.modelCategories. So a pinned-model agent\n\t\t\t// ignores complexity, and an `inherit` agent picks up the requested tier —\n\t\t\t// no settings lookup needed here.\n\t\t\tconst dispatchModel = params.complexity ?? ctx.model?.id;\n\n\t\t\t// Whether this call runs detached. The agent loop reads the tool's\n\t\t\t// `background` flag (the same predicate) to run execute() detached; we\n\t\t\t// recompute it here to choose the notify-and-pull return shape.\n\t\t\tconst isBackground = params.background ?? backgroundAgents.has(params.subagent_type);\n\n\t\t\tif (isBackground) {\n\t\t\t\t// Notify-and-pull: register the dispatch in the inbox under the\n\t\t\t\t// pre-allocated id, await it, retain the body in the inbox, and return a\n\t\t\t\t// compact notification (not the body). The model pulls it with TaskOutput.\n\t\t\t\tsubagentInbox.observe(pool);\n\t\t\t\tsubagentInbox.start(poolTaskId, label, params.subagent_type);\n\n\t\t\t\t// Warm path (opt-in): run on a reused RPC worker, retain the body in the\n\t\t\t\t// inbox, and return the same notify-and-pull shape as the cold path. An\n\t\t\t\t// infra failure falls through to the cold dispatch below.\n\t\t\t\tif (warmSubagentsEnabled() && !forkSessionFile) {\n\t\t\t\t\tconst warm = getWarmSubagentPool(ctx.cwd, availableModels);\n\t\t\t\t\tif (warm.isPoolable(params.subagent_type)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst warmResult = await warm.dispatch(\n\t\t\t\t\t\t\t\tparams.prompt,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tagentType: params.subagent_type,\n\t\t\t\t\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\t\t\t\t\tmodel: dispatchModel,\n\t\t\t\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t(activity) => taskStore.patchAgent(poolTaskId, { activity }),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst dispatchResult = warmResultToTaskResult(warmResult, params.subagent_type, task.id);\n\t\t\t\t\t\t\tsubagentInbox.finish(poolTaskId, dispatchResult);\n\t\t\t\t\t\t\treturn finalizeDispatchResult(\n\t\t\t\t\t\t\t\tdispatchResult,\n\t\t\t\t\t\t\t\tparams.subagent_type,\n\t\t\t\t\t\t\t\tpoolTaskId,\n\t\t\t\t\t\t\t\ttask.id,\n\t\t\t\t\t\t\t\tpoolTaskId,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttaskId: poolTaskId,\n\t\t\t\t\t\t\t\t\tlabel,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (!(error instanceof WarmWorkerError)) throw error;\n\t\t\t\t\t\t\tagentLog(`[WARM] ${params.subagent_type} fell back to cold spawn: ${error.message}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst dispatchResult = await cancelOnAbort(poolTaskId, () =>\n\t\t\t\t\t\tpool.dispatch(params.prompt, {\n\t\t\t\t\t\t\tforceAgent: params.subagent_type,\n\t\t\t\t\t\t\tcontext: \"\",\n\t\t\t\t\t\t\tmodel: dispatchModel,\n\t\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\t\tsessionFile: forkSessionFile,\n\t\t\t\t\t\t\ttaskId: poolTaskId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tsubagentInbox.finish(poolTaskId, dispatchResult);\n\t\t\t\t\treturn finalizeDispatchResult(dispatchResult, params.subagent_type, poolTaskId, task.id, poolTaskId, {\n\t\t\t\t\t\ttaskId: poolTaskId,\n\t\t\t\t\t\tlabel,\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\t\t\tmarkDispatchFailed(task.id, poolTaskId);\n\t\t\t\t\tsubagentInbox.fail(poolTaskId, reason);\n\t\t\t\t\t// A background dispatch reports failure as a compact notification, not a\n\t\t\t\t\t// thrown tool error — the call was already answered by a placeholder.\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: `${label} failed ✗ — ${reason}` }],\n\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\tsubagent_type: params.subagent_type,\n\t\t\t\t\t\t\tok: false,\n\t\t\t\t\t\t\terror: reason,\n\t\t\t\t\t\t\ttaskId: task.id,\n\t\t\t\t\t\t\tpoolTaskId,\n\t\t\t\t\t\t\tbackground: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Warm path (opt-in): for an eligible foreground dispatch, run on a reused\n\t\t\t// RPC worker to skip the cold-boot. Fork agents (forkSessionFile set) and\n\t\t\t// non-poolable types are excluded. Any infra failure falls through to the\n\t\t\t// cold pool below, so enabling this can only change latency, never whether\n\t\t\t// the task can run.\n\t\t\tif (warmSubagentsEnabled() && !forkSessionFile) {\n\t\t\t\tconst warm = getWarmSubagentPool(ctx.cwd, availableModels);\n\t\t\t\tif (warm.isPoolable(params.subagent_type)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst warmResult = await warm.dispatch(\n\t\t\t\t\t\t\tparams.prompt,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tagentType: params.subagent_type,\n\t\t\t\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\t\t\t\tmodel: dispatchModel,\n\t\t\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t// Mirror the cold pool's live progress on the task panel roster so a\n\t\t\t\t\t\t\t// warm dispatch reads as busy (⋯ grep), not stuck.\n\t\t\t\t\t\t\t(activity) => taskStore.patchAgent(poolTaskId, { activity }),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst dispatchResult = warmResultToTaskResult(warmResult, params.subagent_type, task.id);\n\t\t\t\t\t\treturn finalizeDispatchResult(dispatchResult, params.subagent_type, poolTaskId, task.id, undefined);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// A genuine infra failure (worker crash/timeout) retries cold; any other\n\t\t\t\t\t\t// error is a real dispatch failure and propagates.\n\t\t\t\t\t\tif (!(error instanceof WarmWorkerError)) {\n\t\t\t\t\t\t\ttaskStore.update(task.id, { status: \"failed\" });\n\t\t\t\t\t\t\ttaskStore.patchAgent(poolTaskId, { state: \"failed\", activity: \"\" });\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tagentLog(`[WARM] ${params.subagent_type} fell back to cold spawn: ${error.message}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Foreground: block the turn and return the subagent's full answer inline.\n\t\t\ttry {\n\t\t\t\tconst dispatchResult = await cancelOnAbort(poolTaskId, () =>\n\t\t\t\t\tpool.dispatch(params.prompt, {\n\t\t\t\t\t\tforceAgent: params.subagent_type,\n\t\t\t\t\t\tcontext: \"\",\n\t\t\t\t\t\tmodel: dispatchModel,\n\t\t\t\t\t\tprovider: ctx.model?.provider,\n\t\t\t\t\t\tsessionFile: forkSessionFile,\n\t\t\t\t\t\ttaskId: poolTaskId,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn finalizeDispatchResult(\n\t\t\t\t\tdispatchResult,\n\t\t\t\t\tparams.subagent_type,\n\t\t\t\t\tpoolTaskId,\n\t\t\t\t\ttask.id,\n\t\t\t\t\tdispatchResult.task_id,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tmarkDispatchFailed(task.id, poolTaskId);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\n\t\trenderCall(args, theme) {\n\t\t\tconst type = args.subagent_type ?? \"agent\";\n\t\t\t// The [type] tag carries the agent's identity color — the same hue this\n\t\t\t// agent has in the task panel and TaskOutput — so a transcript full of\n\t\t\t// concurrent dispatches is scannable by color.\n\t\t\tconst text = theme.fg(\"toolTitle\", theme.bold(\"Agent \")) + theme.fg(agentColorFor(type), `[${type}]`);\n\t\t\treturn new Text(text, 0, 0);\n\t\t},\n\t});\n}\n\n/**\n * For a `fork: true` agent, fork the parent's session so the subagent inherits the\n * full parent conversation (and its prompt cache) instead of starting fresh. Returns\n * the forked session file to dispatch the child with, or undefined to fall back to a\n * fresh session (non-fork agent, no parent session, or an empty/invalid source).\n */\nexport function resolveForkSessionFile(\n\tdef: Pick<AgentDefinition, \"fork\">,\n\tparentSessionPath: string | undefined,\n\tcwd: string,\n): string | undefined {\n\tif (!def.fork || !parentSessionPath) return undefined;\n\ttry {\n\t\treturn SessionManager.forkFrom(parentSessionPath, cwd).getSessionFile();\n\t} catch {\n\t\t// Empty/invalid parent session: fall back to a fresh subagent session.\n\t\treturn undefined;\n\t}\n}\n\n/** Pre-allocated pool task id for a dispatch (matches the pool's own format). */\nfunction newDispatchTaskId(): string {\n\treturn `dispatch-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/**\n * The TodoWrite plan item this dispatch is (most plausibly) working on: the\n * single in_progress main-agent task. TodoWrite discipline keeps exactly one\n * item in_progress, so when that holds the link is unambiguous; with zero or\n * several in_progress items no link is recorded rather than guessing. Used to\n * nest the run under its plan item in the task panel's flat lens.\n */\nfunction linkedTodoId(): number | undefined {\n\tconst inProgress = taskStore\n\t\t.list()\n\t\t.filter(\n\t\t\t(t) =>\n\t\t\t\tt.source === undefined &&\n\t\t\t\tt.agent === undefined &&\n\t\t\t\tt.parentTaskId === undefined &&\n\t\t\t\tt.status === \"in_progress\",\n\t\t);\n\treturn inProgress.length === 1 ? inProgress[0]?.id : undefined;\n}\n\n/**\n * Register this dispatch in the task store's roster, keyed by its run id (the\n * pool task id) so concurrent runs of the same agent type each get their own\n * row, state, activity, and stats. The friendly label (\"explore#1\") names the\n * row the same way the inbox names background tasks.\n */\nfunction registerSubagentDispatch(runId: string, label: string): void {\n\ttaskStore.upsertAgent({ id: runId, name: label, role: \"subagent\", kind: \"subagent\", state: \"running\" });\n}\n\n/**\n * Catch-path bookkeeping: mark the dispatch failed unless it already settled.\n * finalizeDispatchResult records a terminal status (failed/cancelled) *before*\n * throwing, so a blanket \"failed\" here would clobber a cancellation with a\n * failure the moment the thrown error passed through.\n */\nfunction markDispatchFailed(taskStoreId: number, runId: string): void {\n\tconst current = taskStore.list().find((t) => t.id === taskStoreId);\n\tif (current && current.status !== \"pending\" && current.status !== \"in_progress\") return;\n\ttaskStore.update(taskStoreId, { status: \"failed\" });\n\ttaskStore.patchAgent(runId, { state: \"failed\", activity: \"\" });\n}\n\n/** Names of agents configured to run in the background (non-blocking). */\nfunction collectBackgroundAgentNames(cwd: string): Set<string> {\n\tconst names = new Set<string>();\n\tfor (const agent of loadAgentRegistry({ cwd }).list()) {\n\t\tif (agent.background) names.add(agent.name);\n\t}\n\treturn names;\n}\n\n/**\n * Merge a child subagent's task subtree into the parent's task store, rooting\n * each top-level node under the dispatching task (`parentTaskId`). Recurses so a\n * subagent that itself delegated shows its nested work — the subtree the child\n * could not surface across the process boundary on its own. Each node is its own\n * task (no key-by-type collapse), preserving the order the child created them.\n */\nfunction mergeChildTaskTree(nodes: readonly SubagentTaskNode[] | undefined, parentTaskId: number): void {\n\tif (!nodes) return;\n\ttaskStore.batch(() => {\n\t\tfor (const node of nodes) {\n\t\t\tconst created = taskStore.create(node.title, {\n\t\t\t\tsource: node.source,\n\t\t\t\tsubagentMode: node.subagentMode,\n\t\t\t\tparentTaskId,\n\t\t\t});\n\t\t\ttaskStore.update(created.id, { status: node.status, usage: node.usage });\n\t\t\tmergeChildTaskTree(node.children, created.id);\n\t\t}\n\t});\n}\n\n/**\n * Adapt a warm-worker run into the TaskResult shape finalizeDispatchResult\n * consumes, so the warm and cold paths share one finish/render path. A warm run\n * returns its answer inline (no result.json), so we synthesize an equivalent\n * SubagentResult with the answer as the summary and the pulled usage. The warm\n * path is clean (no persisted session), so there is no task_tree to merge and no\n * resume handle.\n */\nfunction warmResultToTaskResult(warm: WarmRunResult, agentType: string, taskStoreId: number): TaskResult {\n\tconst resultData: SubagentResultFile = {\n\t\tsummary: warm.summary || \"(subagent returned no output)\",\n\t\tfiles_changed: [],\n\t\tconfidence: warm.ok ? 1 : 0,\n\t\tstatus: warm.status,\n\t\tusage: warm.usage,\n\t};\n\tconst result: SubagentResult = {\n\t\ttask_id: String(taskStoreId),\n\t\tok: warm.ok,\n\t\tstdout: \"\",\n\t\tstderr: \"\",\n\t\texit_code: warm.ok ? 0 : 1,\n\t\tstatus: warm.status,\n\t\terror: warm.error,\n\t\tresult_data: resultData as unknown as Record<string, unknown>,\n\t};\n\treturn { handled_inline: false, agent_type: agentType, result };\n}\n\n/**\n * Update the task panel from a finished dispatch and shape the tool result.\n *\n * Foreground calls return the subagent's full answer inline and signal a hard\n * failure by throwing (the agent loop derives a tool's error state from a thrown\n * error). A background call passes `background`: the body already lives in the\n * inbox, so it returns a compact, self-contained notification (success or\n * failure) and never throws — the call was already answered by a placeholder.\n */\nfunction finalizeDispatchResult(\n\tdispatchResult: TaskResult,\n\tsubagentType: string,\n\trunAgentId: string,\n\ttaskStoreId: number,\n\tresumeHandle: string | undefined,\n\tbackground?: { taskId: string; label: string },\n): { content: Array<{ type: \"text\"; text: string }>; details: TaskToolDetails } {\n\tconst result = dispatchResult.result;\n\tconst resultData = result?.result_data as SubagentResultFile | undefined;\n\tconst usage = resultData?.usage;\n\n\t// Merge the child's own task subtree under the dispatching task so nested\n\t// delegation (depth >= 2) is visible in the subagents lens's task tree.\n\tmergeChildTaskTree(resultData?.task_tree, taskStoreId);\n\n\t// Roll this run's usage into its own roster row (rows are per-dispatch).\n\tif (usage) {\n\t\ttaskStore.addAgentStats(runAgentId, { input: usage.input, output: usage.output, cost: usage.cost });\n\t}\n\n\tif (!result || !result.ok) {\n\t\t// A user-initiated cancel is not a failure: it gets its own terminal\n\t\t// status so the panel shows ⊘ cancelled (dim) instead of ✗ failed (red).\n\t\tconst cancelled = result?.status === \"cancelled\";\n\t\tconst failNote = result?.usedInheritedModelFallback ? \"inherited-model retry failed\" : undefined;\n\t\ttaskStore.update(taskStoreId, { status: cancelled ? \"cancelled\" : \"failed\", usage, note: failNote });\n\t\ttaskStore.patchAgent(runAgentId, { state: cancelled ? \"cancelled\" : \"failed\", activity: \"\" });\n\t\tconst reason = result?.error ?? (result?.status ? `subagent ${result.status}` : \"unknown error\");\n\t\tif (background) {\n\t\t\tconst verdict = cancelled ? \"cancelled ⊘\" : \"failed ✗\";\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: `${background.label} ${verdict} — ${reason}` }],\n\t\t\t\tdetails: {\n\t\t\t\t\tsubagent_type: subagentType,\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: reason,\n\t\t\t\t\ttaskId: taskStoreId,\n\t\t\t\t\tpoolTaskId: background.taskId,\n\t\t\t\t\tbackground: true,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (cancelled) {\n\t\t\tthrow new Error(`Subagent (${subagentType}) cancelled by user.`);\n\t\t}\n\t\tconst stderr = result?.stderr?.trim();\n\t\tthrow new Error(`Subagent (${subagentType}) failed: ${reason}${stderr ? `\\nstderr: ${stderr.slice(-500)}` : \"\"}`);\n\t}\n\n\t// Leave the task in the store with its final status; it stays visible in the\n\t// task panel until the next user message arrives. Surface a ⚠ cue when the run\n\t// fell back to the inherited model rather than emitting a chat message — and\n\t// clear any stale note otherwise (note is clearable via an explicit undefined).\n\tconst fallbackNote = dispatchResult.result?.usedInheritedModelFallback ? \"ran on inherited model\" : undefined;\n\ttaskStore.update(taskStoreId, { status: \"done\", usage, note: fallbackNote });\n\t// Rows are per-run, so this run settles to done regardless of siblings.\n\ttaskStore.patchAgent(runAgentId, { state: \"done\", activity: \"\" });\n\tlet answer = resultData?.summary || \"(subagent returned no output)\";\n\t// Partial results are resumable; surface the handle so the parent can continue.\n\tif (result.status === \"partial\" && resumeHandle) {\n\t\tanswer += `\\n\\n[Partial result. To continue this subagent, call Task again with resume_task_id=\"${resumeHandle}\".]`;\n\t}\n\n\tif (background) {\n\t\t// Compact notification: the body is retained in the inbox; the model pulls it\n\t\t// with TaskOutput. Keeps a wide swarm from flooding the parent's context.\n\t\tconst partial = result.status === \"partial\" ? \" (partial — resume to continue)\" : \"\";\n\t\tconst outstanding = subagentInbox.outstanding().length;\n\t\tconst tail = outstanding > 0 ? ` ${outstanding} still running.` : \"\";\n\t\tconst text =\n\t\t\t`${background.label} finished ✓${partial} — ${summarize(answer)}.${tail}\\n` +\n\t\t\t`Read the full result with TaskOutput(\"${background.label}\").`;\n\t\treturn {\n\t\t\tcontent: [{ type: \"text\", text }],\n\t\t\tdetails: {\n\t\t\t\tsubagent_type: subagentType,\n\t\t\t\tok: true,\n\t\t\t\ttaskId: taskStoreId,\n\t\t\t\tpoolTaskId: background.taskId,\n\t\t\t\tbackground: true,\n\t\t\t},\n\t\t};\n\t}\n\n\treturn {\n\t\tcontent: [{ type: \"text\", text: answer }],\n\t\tdetails: { subagent_type: subagentType, ok: true, taskId: taskStoreId, poolTaskId: resumeHandle },\n\t};\n}\n\nconst taskOutputParams = Type.Object({\n\ttask_id: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t'Handle of a background subagent — its task_id or friendly label (e.g. \"explore#1\") from a Task notification. Omit (or set list:true) to see every background task.',\n\t\t}),\n\t),\n\tlist: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"List all background subagents with their status (running/done/failed/cancelled) and current activity. No result bodies are returned.\",\n\t\t}),\n\t),\n\twait: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Block until the named task finishes — or, with no task_id, until all outstanding subagents finish (a swarm barrier) — before returning. Bounded by timeout_ms.\",\n\t\t}),\n\t),\n\ttimeout_ms: Type.Optional(\n\t\tType.Number({ description: \"Maximum time to block in wait mode, in milliseconds (default 120000).\" }),\n\t),\n});\n\ntype TaskOutputParams = Static<typeof taskOutputParams>;\n\nconst TASK_OUTPUT_DEFAULT_TIMEOUT_MS = 120_000;\n\n/**\n * Elapsed time a record has run (so far, or until it settled), in the same\n * format the task panel uses so the two surfaces always agree.\n */\nfunction recordElapsed(rec: InboxRecord): string {\n\tconst end = rec.endedAt ?? Date.now();\n\treturn formatDurationSecs((end - rec.startedAt) / 1000);\n}\n\n/** A compact roster of every known background subagent — status + activity, no bodies. */\nfunction formatTaskRoster(): { content: Array<{ type: \"text\"; text: string }>; details: TaskOutputDetails } {\n\tconst all = subagentInbox.list();\n\tconst outstanding = subagentInbox.outstanding().length;\n\tif (all.length === 0) {\n\t\treturn {\n\t\t\tcontent: [{ type: \"text\", text: \"No background subagents have been dispatched.\" }],\n\t\t\tdetails: { status: \"empty\", ok: true, outstanding: 0 },\n\t\t};\n\t}\n\tconst lines = all.map((r) => {\n\t\tconst when = recordElapsed(r);\n\t\tswitch (r.lifecycle) {\n\t\t\tcase \"running\":\n\t\t\t\treturn `- ${r.label} running ${when}${r.lastActivity ? ` · ${r.lastActivity}` : \"\"}`;\n\t\t\tcase \"done\":\n\t\t\t\treturn `- ${r.label} done (uncollected) ${when} — ${r.summaryLine ?? \"\"}`;\n\t\t\tcase \"collected\":\n\t\t\t\treturn `- ${r.label} collected ${when} — ${r.summaryLine ?? \"\"}`;\n\t\t\tcase \"cancelled\":\n\t\t\t\treturn `- ${r.label} cancelled ⊘ — ${r.error ?? \"cancelled by user\"}`;\n\t\t\tdefault:\n\t\t\t\treturn `- ${r.label} ${r.lifecycle} ✗ — ${r.error ?? \"unknown error\"}`;\n\t\t}\n\t});\n\tconst header = `${all.length} background subagent${all.length === 1 ? \"\" : \"s\"} (${outstanding} running):`;\n\tconst hint = all.some((r) => r.lifecycle === \"done\") ? '\\nRead a finished one with TaskOutput(\"<label>\").' : \"\";\n\treturn {\n\t\tcontent: [{ type: \"text\", text: `${header}\\n${lines.join(\"\\n\")}${hint}` }],\n\t\tdetails: { status: \"list\", ok: true, outstanding },\n\t};\n}\n\n/**\n * TaskOutput tool: check on background subagents and pull their results.\n *\n * Background `Task` calls don't push their body into the conversation — they\n * leave it in the inbox and post a compact notification. TaskOutput is how the\n * model pulls a body, checks liveness, or waits. It never throws on a valid\n * handle (an error tool result would only confuse the loop): it reports status\n * instead. Modes: `list` (roster), a `task_id` to read/check one, and `wait` to\n * block until one task — or all outstanding tasks — finish.\n */\nexport function createTaskOutputToolDefinition(): ToolDefinition {\n\treturn defineTool<typeof taskOutputParams, TaskOutputDetails>({\n\t\tname: \"TaskOutput\",\n\t\tlabel: \"TaskOutput\",\n\t\tdescription: [\n\t\t\t\"Check on background subagents dispatched via Task, and pull their results.\",\n\t\t\t'Pass a task_id/label (e.g. \"explore#1\") to read a finished subagent\\'s full result, or to see its status while it runs.',\n\t\t\t\"Set list:true (or omit task_id) to list every background subagent with its status and current activity.\",\n\t\t\t\"Set wait:true to block until that task finishes — or, with no task_id, until all outstanding subagents finish (a swarm barrier).\",\n\t\t\t\"It never errors on a valid handle: a running task reports status, a finished one returns its result, an already-read one says so.\",\n\t\t].join(\"\\n\"),\n\t\tpromptSnippet: \"check status / list / collect the results of background subagents\",\n\t\tparameters: taskOutputParams,\n\n\t\tasync execute(_toolCallId, params: TaskOutputParams, _signal, _onUpdate, ctx) {\n\t\t\t// Touch the pool so the inbox is wired to its progress stream for activity.\n\t\t\t// The pool is normally already created by a prior dispatch; pass available\n\t\t\t// models so a first-touch here still seeds category derivation.\n\t\t\tsubagentInbox.observe(getSubagentPool(ctx.cwd, ctx.modelRegistry?.getAvailable() ?? []));\n\t\t\tconst handle = params.task_id?.trim();\n\n\t\t\t// Barrier: wait for the target (or all outstanding) to settle first.\n\t\t\tif (params.wait) {\n\t\t\t\tconst timeout = params.timeout_ms ?? TASK_OUTPUT_DEFAULT_TIMEOUT_MS;\n\t\t\t\tif (handle) await subagentInbox.waitFor(handle, timeout);\n\t\t\t\telse await subagentInbox.waitForAll(timeout);\n\t\t\t}\n\n\t\t\t// Roster when asked, or when no specific task was named.\n\t\t\tif (params.list || !handle) {\n\t\t\t\treturn formatTaskRoster();\n\t\t\t}\n\n\t\t\tconst rec = subagentInbox.get(handle);\n\t\t\tif (!rec) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `No background task \"${handle}\". Call TaskOutput with list:true to see active tasks.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { task_id: handle, status: \"unknown\", ok: false },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (rec.lifecycle === \"running\") {\n\t\t\t\tconst activity = rec.lastActivity ? ` (currently: ${rec.lastActivity})` : \"\";\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `${rec.label} is still running — ${recordElapsed(rec)} elapsed${activity}. Call TaskOutput again, or with wait:true to block until it finishes.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { task_id: handle, status: \"running\", ok: true },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (rec.lifecycle === \"done\") {\n\t\t\t\tconst collected = subagentInbox.collect(handle);\n\t\t\t\tconst body = collected?.body ?? rec.summaryLine ?? \"(subagent returned no output)\";\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: body }],\n\t\t\t\t\tdetails: { task_id: handle, status: \"done\", ok: true },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (rec.lifecycle === \"collected\") {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: `${rec.label} was already delivered — ${rec.summaryLine ?? \"(no summary kept)\"}.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: { task_id: handle, status: \"collected\", ok: true },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// failed / stalled / timeout / cancelled\n\t\t\tconst glyph = rec.lifecycle === \"cancelled\" ? \"⊘\" : \"✗\";\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: `${rec.label} ${rec.lifecycle} ${glyph} — ${rec.error ?? \"unknown error\"}.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { task_id: handle, status: rec.lifecycle, ok: false },\n\t\t\t};\n\t\t},\n\n\t\trenderCall(args, theme) {\n\t\t\tconst target = args.list ? \"list\" : String(args.task_id ?? \"\");\n\t\t\t// A friendly label (\"explore#1\") gets its agent's identity color so the\n\t\t\t// pull visually pairs with the dispatch that produced it; raw ids and\n\t\t\t// \"list\" stay dim.\n\t\t\tconst hashIdx = target.indexOf(\"#\");\n\t\t\tconst styledTarget =\n\t\t\t\thashIdx > 0 ? theme.fg(agentColorFor(target.slice(0, hashIdx)), target) : theme.fg(\"dim\", target);\n\t\t\tconst text =\n\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(\"TaskOutput \")) +\n\t\t\t\tstyledTarget +\n\t\t\t\t(args.wait ? theme.fg(\"dim\", \" (wait)\") : \"\");\n\t\t\treturn new Text(text, 0, 0);\n\t\t},\n\n\t\trenderResult(result, _options, theme) {\n\t\t\t// Display-only framing/colorization (the text sent to the model stays\n\t\t\t// plain). A single-task pull renders as a result CARD — a status-stamped\n\t\t\t// header, a left spine down the body, and a closing corner — so a\n\t\t\t// collected result reads as a discrete artifact instead of blending into\n\t\t\t// the surrounding tool chatter. Roster/list responses keep the line\n\t\t\t// colorization.\n\t\t\tconst text = result.content\n\t\t\t\t.map((c) => (c.type === \"text\" ? c.text : \"\"))\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (!text) return new Text(\"\", 0, 0);\n\n\t\t\tconst details = result.details as TaskOutputDetails | undefined;\n\t\t\tconst cardStatus = details?.task_id ? details.status : undefined;\n\t\t\tif (cardStatus && cardStatus !== \"list\" && cardStatus !== \"empty\") {\n\t\t\t\tconst presentation: Record<\n\t\t\t\t\tstring,\n\t\t\t\t\t{ glyph: string; color: \"success\" | \"warning\" | \"error\" | \"muted\" | \"dim\" }\n\t\t\t\t> = {\n\t\t\t\t\tdone: { glyph: \"✓\", color: \"success\" },\n\t\t\t\t\trunning: { glyph: \"◐\", color: \"warning\" },\n\t\t\t\t\tcollected: { glyph: \"✓\", color: \"muted\" },\n\t\t\t\t\tcancelled: { glyph: \"⊘\", color: \"dim\" },\n\t\t\t\t\tunknown: { glyph: \"?\", color: \"dim\" },\n\t\t\t\t};\n\t\t\t\tconst { glyph, color } = presentation[cardStatus] ?? { glyph: \"✗\", color: \"error\" as const };\n\t\t\t\tconst label = details?.task_id ?? \"\";\n\t\t\t\tconst hashIdx = label.indexOf(\"#\");\n\t\t\t\tconst labelColor = hashIdx > 0 ? agentColorFor(label.slice(0, hashIdx)) : \"accent\";\n\n\t\t\t\t// Look up inbox record for elapsed time\n\t\t\t\tconst inboxRecord = subagentInbox.get(label);\n\t\t\t\tconst elapsed = inboxRecord ? (inboxRecord.endedAt ?? Date.now()) - inboxRecord.startedAt : undefined;\n\t\t\t\tconst elapsedText = elapsed ? ` ${formatDurationSecs(elapsed / 1000)}` : \"\";\n\n\t\t\t\t// Look up task for token count\n\t\t\t\tconst task = inboxRecord ? taskStore.list().find((t) => t.agent === inboxRecord.taskId) : undefined;\n\t\t\t\tconst totalTokens = task?.usage ? task.usage.input + task.usage.output : undefined;\n\t\t\t\tconst tokenText = totalTokens !== undefined ? ` ${formatTokens(totalTokens)}` : \"\";\n\n\t\t\t\tconst spine = (s: string) => theme.fg(\"borderMuted\", s);\n\t\t\t\tconst header =\n\t\t\t\t\t`${spine(\"╭\")} ${theme.fg(color, glyph)} ` +\n\t\t\t\t\t`${theme.bold(theme.fg(color, cardStatus))} ${theme.fg(labelColor, label)}${tokenText}${elapsedText}`;\n\t\t\t\tconst body = text\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.map((line) => `${spine(\"│\")} ${theme.fg(\"toolOutput\", line)}`)\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t\treturn new Text(`${header}\\n${body}\\n${spine(\"╰\")}`, 0, 0);\n\t\t\t}\n\n\t\t\tconst rosterLine =\n\t\t\t\t/^- (\\S+)\\s{2}(running|done \\(uncollected\\)|collected|failed|stalled|timeout|cancelled)(.*)$/;\n\t\t\tconst styled = text\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((line) => {\n\t\t\t\t\tconst match = rosterLine.exec(line);\n\t\t\t\t\tif (!match) return theme.fg(\"toolOutput\", line);\n\t\t\t\t\tconst [, label, status, rest] = match as unknown as [string, string, string, string];\n\t\t\t\t\tconst hashIdx = label.indexOf(\"#\");\n\t\t\t\t\tconst labelColor = hashIdx > 0 ? agentColorFor(label.slice(0, hashIdx)) : \"accent\";\n\t\t\t\t\tconst statusColor =\n\t\t\t\t\t\tstatus === \"running\"\n\t\t\t\t\t\t\t? \"warning\"\n\t\t\t\t\t\t\t: status.startsWith(\"done\")\n\t\t\t\t\t\t\t\t? \"success\"\n\t\t\t\t\t\t\t\t: status === \"collected\" || status === \"cancelled\"\n\t\t\t\t\t\t\t\t\t? \"muted\"\n\t\t\t\t\t\t\t\t\t: \"error\";\n\t\t\t\t\treturn `- ${theme.fg(labelColor, label)} ${theme.fg(statusColor, status)}${theme.fg(\"dim\", rest)}`;\n\t\t\t\t})\n\t\t\t\t.join(\"\\n\");\n\t\t\treturn new Text(styled, 0, 0);\n\t\t},\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../../../src/extensions/core/modes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAGX,YAAY,EAIZ,MAAM,gCAAgC,CAAC;AAwExC;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,MAAM,GAAG,SAAS,CAGnH;AAMD,MAAM,WAAW,YAAY;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CA2BnE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAwBlE;AAMD,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAEjD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAKtE;AAqCD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CASrF;AAMD,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC9B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAatE;AAED,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC5B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,CAWxF;AAMD,wBAAgB,SAAS,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA6OhD","sourcesContent":["/**\n * Mode system — resolves the active mode (ask/plan/build/debug), loads the\n * mode's system prompt, filters active tools, and exposes the /mode, /plan,\n * /grill, /goal, and /approve commands.\n *\n * Mode prompt search order (first hit wins):\n * - `./.hoocode/modes/{mode}/system.md`\n * - `~/.hoocode/modes/{mode}/system.md`\n * - each configured/contributed external dir in declared order\n * - built-in MODE_DEFAULTS for the four known modes\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { getHooCodeDir } from \"../../config.js\";\nimport type {\n\tBeforeAgentStartEvent,\n\tBeforeAgentStartEventResult,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tSessionStartEvent,\n} from \"../../core/extensions/types.js\";\nimport { isLightModeEnv } from \"../../core/light.js\";\nimport { DEFAULT_MODE, DEFAULT_MODE_PROMPTS as MODE_DEFAULTS } from \"../../core/mode-prompts.js\";\nimport { mergeSearchPaths, readConfig, readMergedConfig, writeConfig } from \"./config.js\";\nimport { AUTO_LOOP_DONE_TOKEN, LOOP_AUTO_CHANGED, LOOP_AUTO_START, type LoopAutoStartPayload } from \"./loop.js\";\n\nconst HOOCODE_DIR = getHooCodeDir();\n\n/**\n * Per-session plan file path. Keying on sessionId lets concurrent or resumed\n * plan sessions keep distinct plans instead of clobbering each other.\n */\nfunction getPlanPath(cwd: string, sessionId: string): string {\n\treturn join(cwd, \".hoocode\", \"plans\", `${sessionId}.md`);\n}\n\n/** Legacy single-file plan location, retained as a read-only fallback for /approve. */\nfunction getLegacyPlanPath(cwd: string): string {\n\treturn join(cwd, \".hoocode\", \"plan.md\");\n}\n\nfunction tryReadFile(path: string): string | undefined {\n\tif (!existsSync(path)) return undefined;\n\ttry {\n\t\tconst text = readFileSync(path, \"utf8\").trim();\n\t\treturn text || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Outcome of reading the first usable plan file out of a candidate list. */\ntype PlanLoadResult =\n\t| { status: \"loaded\"; sections: PlanSections }\n\t| { status: \"missing\" }\n\t| { status: \"error\"; path: string };\n\n/**\n * Reads the first candidate plan file that exists and is non-empty, parsed into\n * sections. Missing and blank files fall through to the next candidate; an\n * unreadable one stops the walk so the caller can report the specific path.\n */\nfunction loadPlanSections(candidatePaths: string[]): PlanLoadResult {\n\tfor (const planPath of candidatePaths) {\n\t\tif (!existsSync(planPath)) continue;\n\t\ttry {\n\t\t\tconst raw = readFileSync(planPath, \"utf8\").trim();\n\t\t\tif (raw) return { status: \"loaded\", sections: parsePlanSections(raw) };\n\t\t} catch {\n\t\t\treturn { status: \"error\", path: planPath };\n\t\t}\n\t}\n\treturn { status: \"missing\" };\n}\n\n/**\n * Walks search dirs in precedence order and returns the first existing\n * `modes/{name}/system.md` content. Order: project → user → externalDirs.\n */\nfunction resolveModeFile(name: string, cwd: string, externalDirs: string[]): string | undefined {\n\tconst candidates: string[] = [\n\t\tjoin(cwd, \".hoocode\", \"modes\", name, \"system.md\"),\n\t\tjoin(HOOCODE_DIR, \"modes\", name, \"system.md\"),\n\t\t...externalDirs.map((dir) => join(dir, name, \"system.md\")),\n\t];\n\tfor (const candidate of candidates) {\n\t\tconst content = tryReadFile(candidate);\n\t\tif (content !== undefined) return content;\n\t}\n\treturn undefined;\n}\n\n/**\n * Returns the system prompt for the active mode.\n *\n * Search order (first hit wins):\n * - `./.hoocode/modes/{mode}/system.md`\n * - `~/.hoocode/modes/{mode}/system.md`\n * - each of `externalDirs` in declared order (config + CLI + extension contributions)\n * - built-in MODE_DEFAULTS for the four known modes\n */\nexport function buildSystemPrompt(mode: string, cwd: string, options?: { modePaths?: string[] }): string | undefined {\n\tconst modePaths = options?.modePaths ?? [];\n\treturn resolveModeFile(mode, cwd, modePaths) ?? MODE_DEFAULTS[mode];\n}\n\n// ============================================================================\n// Plan file: section parsing and step-by-step execution message\n// ============================================================================\n\nexport interface PlanSections {\n\tgoal?: string;\n\tfilesToModify?: string;\n\tnewFiles?: string;\n\ttests?: string;\n\tverification?: string;\n\t/** Original full text, used as fallback if no sections parsed */\n\traw: string;\n}\n\n/**\n * Parses `.hoocode/plan.md` into named sections.\n *\n * Recognises both ATX headings (`## Goal`) and bold labels (`**Goal**`).\n * Section names matched (case-insensitive): Goal, Files to modify, New files,\n * Tests, Verification.\n */\nexport function parsePlanSections(planContent: string): PlanSections {\n\tconst result: PlanSections = { raw: planContent };\n\n\t// Match `## Heading text` or `**Heading text**` followed by content until\n\t// the next heading of the same style.\n\tconst sectionPattern =\n\t\t/^(?:#{1,3}\\s+(.+?)|(?:\\*\\*(.+?)\\*\\*))\\s*\\n([\\s\\S]*?)(?=(?:^#{1,3}\\s+|\\*\\*[^*\\n]+\\*\\*\\s*\\n)|$)/gm;\n\n\tfor (const match of planContent.matchAll(sectionPattern)) {\n\t\tconst heading = (match[1] ?? match[2] ?? \"\").toLowerCase().trim();\n\t\tconst content = match[3].trim();\n\t\tif (!content) continue;\n\n\t\tif (/^goal/.test(heading)) {\n\t\t\tresult.goal = content;\n\t\t} else if (/files?\\s+to\\s+modif|^modif/.test(heading)) {\n\t\t\tresult.filesToModify = content;\n\t\t} else if (/new\\s+files?/.test(heading)) {\n\t\t\tresult.newFiles = content;\n\t\t} else if (/^tests?/.test(heading)) {\n\t\t\tresult.tests = content;\n\t\t} else if (/^verif/.test(heading)) {\n\t\t\tresult.verification = content;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Builds the user message sent to the agent when `/approve` is run.\n *\n * If the plan has recognisable sections, each is presented as a numbered step\n * so the agent works through them sequentially. Otherwise the raw plan is used.\n *\n * Execution order:\n * 1. Modify existing files\n * 2. Create new files\n * 3. Update / add tests\n * 4. Run verification commands\n */\nexport function buildApproveMessage(sections: PlanSections): string {\n\tconst steps: string[] = [];\n\n\tif (sections.goal) {\n\t\tsteps.push(`**Goal:** ${sections.goal}`);\n\t}\n\tif (sections.filesToModify) {\n\t\tsteps.push(`**Step 1 — Modify existing files:**\\n${sections.filesToModify}`);\n\t}\n\tif (sections.newFiles) {\n\t\tsteps.push(`**Step 2 — Create new files:**\\n${sections.newFiles}`);\n\t}\n\tif (sections.tests) {\n\t\tsteps.push(`**Step 3 — Update tests:**\\n${sections.tests}`);\n\t}\n\tif (sections.verification) {\n\t\tsteps.push(`**Step 4 — Verify:**\\n${sections.verification}`);\n\t}\n\n\tif (steps.length === 0) {\n\t\treturn `Execute the following plan:\\n\\n${sections.raw}`;\n\t}\n\n\treturn `Execute this plan step by step. Complete each step fully before moving to the next.\\n\\n${steps.join(\"\\n\\n\")}`;\n}\n\n// ============================================================================\n// Grill: plan interrogation\n// ============================================================================\n\n/** Which half (or both) of the grill flow to run. */\nexport type GrillTarget = \"both\" | \"me\" | \"plan\";\n\n/**\n * Parses the `/grill` argument into a target.\n *\n * Bare `/grill` runs both phases, `/grill me` only questions the user, and\n * `/grill plan` only critiques the plan. Anything else returns undefined so the\n * caller shows usage rather than guessing at intent.\n */\nexport function parseGrillTarget(args: string): GrillTarget | undefined {\n\tconst arg = args.trim().toLowerCase();\n\tif (!arg) return \"both\";\n\tif (arg === \"me\" || arg === \"plan\") return arg;\n\treturn undefined;\n}\n\n/**\n * Renders the parsed plan back into the message so the agent reviews a concrete\n * artifact rather than whatever it remembers writing. Falls back to the raw plan\n * text when no sections were recognised.\n */\nfunction renderPlanForReview(sections: PlanSections): string {\n\tconst parts: string[] = [];\n\tif (sections.goal) parts.push(`**Goal**\\n${sections.goal}`);\n\tif (sections.filesToModify) parts.push(`**Files to modify**\\n${sections.filesToModify}`);\n\tif (sections.newFiles) parts.push(`**New files**\\n${sections.newFiles}`);\n\tif (sections.tests) parts.push(`**Tests**\\n${sections.tests}`);\n\tif (sections.verification) parts.push(`**Verification**\\n${sections.verification}`);\n\treturn parts.length > 0 ? parts.join(\"\\n\\n\") : sections.raw;\n}\n\n/** Phase 1 — interrogate the request, surfacing unknowns as ask_options questions. */\nconst GRILL_ME_PROMPT = `You are interrogating the *request*, not writing code.\n\nRe-read the plan below and find where it rests on assumptions nobody confirmed: ambiguous requirements, unstated constraints, decisions you made silently because the request did not specify them, and places where a different reasonable reading of the request would produce a materially different plan.\n\nPut the most consequential of those to the user with the ask_options tool. Ask only what would actually change the plan — settle anything you can from the codebase or from convention yourself. Prefer two to four sharp questions over an exhaustive list, and mark a recommended option wherever you have a genuine preference.\n\nDo not edit files and do not revise the plan yet.`;\n\n/** Phase 2 — adversarial self-critique of the plan file. */\nconst GRILL_PLAN_PROMPT = `You are attacking the plan below, not executing it.\n\nReview it as a skeptical reviewer would:\n- Which steps rest on assumptions you have not verified in the codebase? Read the relevant files and verify them now.\n- Where could this fail silently — wrong-but-plausible behaviour rather than a loud error?\n- What does the goal require that the plan does not cover? What does the plan cover that the goal does not need?\n- Does the verification section prove the goal is met, or only that the code runs?\n\nReport what you find. Where a weakness is real, revise the plan file and state what changed. Where the plan holds up, say so plainly rather than inventing criticism. Do not implement anything.`;\n\n/**\n * Builds the follow-up message injected by `/grill`.\n *\n * The two phases are ordered rather than alternative: underspecification sits\n * upstream of plan weakness, so critiquing a plan built on a misread request\n * produces a well-reviewed plan for the wrong job. Bare `/grill` therefore asks\n * first and folds the answers into the critique.\n */\nexport function buildGrillMessage(sections: PlanSections, target: GrillTarget): string {\n\tconst plan = renderPlanForReview(sections);\n\tif (target === \"me\") return `${GRILL_ME_PROMPT}\\n\\n---\\n\\n${plan}`;\n\tif (target === \"plan\") return `${GRILL_PLAN_PROMPT}\\n\\n---\\n\\n${plan}`;\n\treturn (\n\t\t`${GRILL_ME_PROMPT}\\n\\n` +\n\t\t`Once the user has answered, fold their answers into the plan and immediately continue with this review:\\n\\n` +\n\t\t`${GRILL_PLAN_PROMPT}\\n\\n---\\n\\n${plan}`\n\t);\n}\n\n// ============================================================================\n// Goal: autonomous execution toward a completion condition\n// ============================================================================\n\n/** A parsed `/goal` invocation. */\nexport interface GoalInvocation {\n\t/** Explicit objective; falls back to the plan's Goal section when absent. */\n\tobjective?: string;\n\t/** Turn budget passed through to the autonomous loop. */\n\tmaxTurns?: number;\n}\n\n/**\n * Parses `/goal [--max-turns N] [objective]`.\n *\n * Returns undefined when `--max-turns` is present but not followed by a\n * non-negative integer, so the caller shows usage instead of silently running\n * with the default budget.\n */\nexport function parseGoalArgs(args: string): GoalInvocation | undefined {\n\tlet rest = args.trim();\n\tlet maxTurns: number | undefined;\n\n\tconst flag = /^--max-turns(?:\\s+(\\S+))?([\\s\\S]*)$/.exec(rest);\n\tif (flag) {\n\t\tconst raw = flag[1];\n\t\tif (!raw || !/^\\d+$/.test(raw)) return undefined;\n\t\tmaxTurns = Number(raw);\n\t\trest = flag[2].trim();\n\t}\n\n\treturn { objective: rest || undefined, maxTurns };\n}\n\n/** The two messages `/goal` hands to the autonomous loop. */\nexport interface GoalMessages {\n\t/** Delivered once, to start the run. */\n\ttask: string;\n\t/** Re-sent on each continuation to keep the target in view. */\n\tcontinuePrompt: string;\n}\n\n/**\n * Builds the messages for a `/goal` run.\n *\n * When the plan carries a Verification section it becomes the completion\n * condition, which is the difference between a loop that stops when it feels\n * finished and one that stops when something it can run says so. Both messages\n * restate the objective, because the loop's continuation prompt is all that\n * holds the target in place as the transcript grows.\n */\nexport function buildGoalMessages(objective: string, verification?: string): GoalMessages {\n\tconst condition = verification\n\t\t? `\\n\\nThe goal counts as complete only once this verification passes. Run it, and if it fails, fix what it reports and run it again:\\n\\n${verification}`\n\t\t: \"\";\n\n\treturn {\n\t\ttask: `Work autonomously toward this goal:\\n\\n${objective}${condition}`,\n\t\tcontinuePrompt:\n\t\t\t`Keep working toward the goal:\\n\\n${objective}${condition}\\n\\n` +\n\t\t\t`Reply with ${AUTO_LOOP_DONE_TOKEN} only when it is genuinely complete — not when it is merely close.`,\n\t};\n}\n\n// ============================================================================\n// setupMode\n// ============================================================================\n\nexport function setupMode(pi: ExtensionAPI): void {\n\tlet cachedMode = DEFAULT_MODE;\n\tlet cachedSystemPrompt: string | undefined;\n\tlet cachedPlanPath: string | undefined;\n\n\t// `/grill me` asks the user a question via ask_options, which an unattended\n\t// `/loop auto` run has nobody to answer. Track the loop's broadcast state so\n\t// the command can drop its interrogation phase instead of stalling the run.\n\tlet autoLoopActive = false;\n\tpi.events.on(LOOP_AUTO_CHANGED, (data) => {\n\t\tautoLoopActive = (data as { active?: boolean } | undefined)?.active === true;\n\t});\n\n\t// ── session_start ─────────────────────────────────────────────────────────\n\t// Config resolution order:\n\t// 1. Read global config (~/.hoocode/hoo-config.json)\n\t// 2. Read project config (./.hoocode/hoo-config.json) if present\n\t// 3. Merge — project scalars win; arrays are unioned\n\t// 4. Re-resolve active_mode from the merged result\n\n\tpi.on(\"session_start\", (_event: SessionStartEvent, ctx: ExtensionContext) => {\n\t\t// Light mode strips every fixed prompt appendix. Leaving\n\t\t// cachedSystemPrompt unset makes before_agent_start a no-op, so no\n\t\t// `<!-- hoo-core: mode= -->` block is appended.\n\t\tif (isLightModeEnv()) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Steps 1–3: merge global + project configs\n\t\tconst config = readMergedConfig(ctx.cwd);\n\n\t\t// Step 4: resolve mode from the merged config\n\t\tcachedMode = config.active_mode ?? DEFAULT_MODE;\n\t\t// External search dirs come from two channels:\n\t\t// - HooConfig.mode_paths (config-declared)\n\t\t// - pi.addModeSearchPath (CLI flags + extension contributions)\n\t\tconst modePaths = mergeSearchPaths(config.mode_paths, pi.getModeSearchPaths());\n\t\tconst rawSystemPrompt = buildSystemPrompt(cachedMode, ctx.cwd, { modePaths });\n\n\t\t// Per-session plan path so concurrent sessions don't overwrite each other.\n\t\t// The `{{PLAN_PATH}}` token in plan-mode templates is substituted here.\n\t\tcachedPlanPath = getPlanPath(ctx.cwd, ctx.sessionManager.getSessionId());\n\t\tconst relPlanPath = relative(ctx.cwd, cachedPlanPath) || cachedPlanPath;\n\t\tcachedSystemPrompt = rawSystemPrompt?.replace(/\\{\\{PLAN_PATH\\}\\}/g, relPlanPath);\n\n\t\t// Update footer with active mode\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.setMode(cachedMode);\n\t\t}\n\n\t\t// Apply tool filter from mode enabled_tools\n\t\tconst modeCfg = config.modes?.[cachedMode];\n\t\tif (modeCfg?.enabled_tools && modeCfg.enabled_tools.length > 0) {\n\t\t\tpi.setActiveTools(modeCfg.enabled_tools);\n\t\t}\n\t});\n\n\t// ── before_agent_start ────────────────────────────────────────────────────\n\n\tpi.on(\"before_agent_start\", (event: BeforeAgentStartEvent): BeforeAgentStartEventResult | undefined => {\n\t\tif (!cachedSystemPrompt) return;\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n\\n<!-- hoo-core: mode=${cachedMode} -->\\n${cachedSystemPrompt}`,\n\t\t};\n\t});\n\n\t// ── /mode command ─────────────────────────────────────────────────────────\n\n\tconst KNOWN_MODES = [\"ask\", \"plan\", \"build\", \"debug\"];\n\n\tpi.registerCommand(\"mode\", {\n\t\tdescription: \"Switch active mode. Usage: /mode <ask|plan|build|debug>\",\n\t\tgetArgumentCompletions: (prefix: string) =>\n\t\t\tKNOWN_MODES.filter((m) => m.startsWith(prefix)).map((m) => ({ value: m, label: m })),\n\t\thandler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst name = args.trim();\n\t\t\tif (!name) {\n\t\t\t\tctx.ui.notify(`Active mode: ${cachedMode}`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst config = readConfig();\n\t\t\tconfig.active_mode = name === DEFAULT_MODE ? undefined : name;\n\t\t\twriteConfig(config);\n\t\t\tctx.ui.notify(`Mode set to \"${name}\" — reloading…`, \"info\");\n\t\t\tawait ctx.reload();\n\t\t},\n\t});\n\n\t// ── /plan command (shorthand for /mode plan) ──────────────────────────────\n\n\tpi.registerCommand(\"plan\", {\n\t\tdescription: \"Switch to plan mode. Shorthand for /mode plan.\",\n\t\tgetArgumentCompletions: () => [],\n\t\thandler: async (_args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst config = readConfig();\n\t\t\tconfig.active_mode = \"plan\";\n\t\t\twriteConfig(config);\n\t\t\tctx.ui.notify(`Mode set to \"plan\" — reloading…`, \"info\");\n\t\t\tawait ctx.reload();\n\t\t},\n\t});\n\n\t// ── /grill command ────────────────────────────────────────────────────────\n\t// Stress-tests the current plan in two phases: `me` surfaces the request's\n\t// unconfirmed assumptions as ask_options questions, `plan` critiques the plan\n\t// file itself. Unlike /approve this only injects a follow-up message — no\n\t// session switch, no mode change, no config write.\n\n\tpi.registerCommand(\"grill\", {\n\t\tdescription: \"Stress-test the current plan. Usage: /grill [me|plan]\",\n\t\tgetArgumentCompletions: (prefix: string) =>\n\t\t\t[\"me\", \"plan\"].filter((s) => s.startsWith(prefix)).map((s) => ({ value: s, label: s })),\n\t\thandler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst requested = parseGrillTarget(args);\n\t\t\tif (!requested) {\n\t\t\t\tctx.ui.notify(\"Usage: /grill [me|plan]\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Same lookup as /approve: per-session plan first, legacy file second.\n\t\t\tconst sessionPlanPath = cachedPlanPath ?? getPlanPath(ctx.cwd, ctx.sessionManager.getSessionId());\n\t\t\tconst loaded = loadPlanSections([sessionPlanPath, getLegacyPlanPath(ctx.cwd)]);\n\t\t\tif (loaded.status === \"error\") {\n\t\t\t\tctx.ui.notify(`Could not read ${relative(ctx.cwd, loaded.path) || loaded.path}`, \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (loaded.status === \"missing\") {\n\t\t\t\tconst relPlan = relative(ctx.cwd, sessionPlanPath) || sessionPlanPath;\n\t\t\t\tctx.ui.notify(`No plan to grill — ${relPlan} not found. Run /plan first.`, \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Nobody is present to answer during an autonomous loop, so keep the\n\t\t\t// half of the flow that still works rather than blocking on a question.\n\t\t\tlet target = requested;\n\t\t\tif (autoLoopActive && target !== \"plan\") {\n\t\t\t\ttarget = \"plan\";\n\t\t\t\tctx.ui.notify(\"Autonomous loop active — grilling the plan only, skipping questions.\", \"info\");\n\t\t\t}\n\n\t\t\tpi.sendUserMessage(buildGrillMessage(loaded.sections, target), { deliverAs: \"followUp\" });\n\t\t},\n\t});\n\n\t// ── /goal command ─────────────────────────────────────────────────────────\n\t// Works autonomously toward a completion condition by driving the loop in\n\t// loop.ts over the LOOP_AUTO_START channel. Linear by design: a single thread\n\t// of execution that iterates until it reports done or exhausts its budget —\n\t// there is no task graph here, and no subtask fan-out.\n\t//\n\t// The run inherits whatever the active mode already permits (enabled_tools,\n\t// allowed_bash_commands, allowed_write_paths, auto_allow), so how much rope\n\t// an unattended goal gets is a mode-config decision, not one made here.\n\n\tpi.registerCommand(\"goal\", {\n\t\tdescription: \"Work autonomously toward a goal. Usage: /goal [--max-turns N] [objective]\",\n\t\tgetArgumentCompletions: () => [],\n\t\thandler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst parsed = parseGoalArgs(args);\n\t\t\tif (!parsed) {\n\t\t\t\tctx.ui.notify(\"Usage: /goal [--max-turns N] [objective]\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The plan supplies the objective when none was typed, and its\n\t\t\t// verification section becomes the completion condition either way.\n\t\t\tconst sessionPlanPath = cachedPlanPath ?? getPlanPath(ctx.cwd, ctx.sessionManager.getSessionId());\n\t\t\tconst loaded = loadPlanSections([sessionPlanPath, getLegacyPlanPath(ctx.cwd)]);\n\t\t\tif (loaded.status === \"error\") {\n\t\t\t\tctx.ui.notify(`Could not read ${relative(ctx.cwd, loaded.path) || loaded.path}`, \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst sections = loaded.status === \"loaded\" ? loaded.sections : undefined;\n\n\t\t\tconst objective = parsed.objective ?? sections?.goal;\n\t\t\tif (!objective) {\n\t\t\t\tconst relPlan = relative(ctx.cwd, sessionPlanPath) || sessionPlanPath;\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`No objective — pass one as /goal <objective>, or write a Goal section in ${relPlan}.`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { task, continuePrompt } = buildGoalMessages(objective, sections?.verification);\n\t\t\t// The loop announces itself on start, so nothing to notify here.\n\t\t\tpi.events.emit(LOOP_AUTO_START, {\n\t\t\t\ttask,\n\t\t\t\tmaxTurns: parsed.maxTurns,\n\t\t\t\tcontinuePrompt,\n\t\t\t} satisfies LoopAutoStartPayload);\n\t\t},\n\t});\n\n\t// ── /approve command ──────────────────────────────────────────────────────\n\t// Reads .hoocode/plan.md, parses it into named sections (Goal, Files to\n\t// modify, New files, Tests, Verification), switches to build mode, then\n\t// injects a step-by-step execution message into the new session.\n\n\tpi.registerCommand(\"approve\", {\n\t\tdescription: \"Approve the current plan and switch to build mode to execute it.\",\n\t\tgetArgumentCompletions: () => [],\n\t\thandler: async (_args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tif (cachedMode !== \"plan\") {\n\t\t\t\tctx.ui.notify(`/approve is only available in plan mode (current mode: \"${cachedMode}\")`, \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Prefer the per-session plan file, fall back to the legacy single file.\n\t\t\tconst sessionPlanPath = cachedPlanPath ?? getPlanPath(ctx.cwd, ctx.sessionManager.getSessionId());\n\t\t\tconst loaded = loadPlanSections([sessionPlanPath, getLegacyPlanPath(ctx.cwd)]);\n\t\t\tif (loaded.status === \"error\") {\n\t\t\t\tctx.ui.notify(`Could not read ${relative(ctx.cwd, loaded.path) || loaded.path}`, \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst approveMessage = loaded.status === \"loaded\" ? buildApproveMessage(loaded.sections) : undefined;\n\n\t\t\t// Switch global config to build mode\n\t\t\tconst config = readConfig();\n\t\t\tconfig.active_mode = \"build\";\n\t\t\twriteConfig(config);\n\n\t\t\tif (approveMessage) {\n\t\t\t\t// Open a new build-mode session and deliver the parsed plan as the\n\t\t\t\t// first user message so the agent starts executing immediately\n\t\t\t\tawait ctx.newSession({\n\t\t\t\t\twithSession: async (replacedCtx) => {\n\t\t\t\t\t\tawait replacedCtx.sendUserMessage(approveMessage!, { deliverAs: \"followUp\" });\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst relPlan = relative(ctx.cwd, sessionPlanPath) || sessionPlanPath;\n\t\t\t\tctx.ui.notify(`Switched to build mode. No ${relPlan} found — describe what to build.`, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../../../src/extensions/core/modes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAGX,YAAY,EAIZ,MAAM,gCAAgC,CAAC;AAyExC;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,MAAM,GAAG,SAAS,CAGnH;AAMD,MAAM,WAAW,YAAY;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CA2BnE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAwBlE;AAMD,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAEjD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAKtE;AAiCD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAOrF;AAMD,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC9B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAatE;AAED,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC5B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,CAWxF;AAMD,wBAAgB,SAAS,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA6OhD","sourcesContent":["/**\n * Mode system — resolves the active mode (ask/plan/build/debug), loads the\n * mode's system prompt, filters active tools, and exposes the /mode, /plan,\n * /grill, /goal, and /approve commands.\n *\n * Mode prompt search order (first hit wins):\n * - `./.hoocode/modes/{mode}/system.md`\n * - `~/.hoocode/modes/{mode}/system.md`\n * - each configured/contributed external dir in declared order\n * - built-in MODE_DEFAULTS for the four known modes\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { getHooCodeDir } from \"../../config.js\";\nimport type {\n\tBeforeAgentStartEvent,\n\tBeforeAgentStartEventResult,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tSessionStartEvent,\n} from \"../../core/extensions/types.js\";\nimport { isLightModeEnv } from \"../../core/light.js\";\nimport { DEFAULT_MODE, DEFAULT_MODE_PROMPTS as MODE_DEFAULTS } from \"../../core/mode-prompts.js\";\nimport { EMBEDDED_PROMPTS } from \"../../init-templates.generated.js\";\nimport { mergeSearchPaths, readConfig, readMergedConfig, writeConfig } from \"./config.js\";\nimport { AUTO_LOOP_DONE_TOKEN, LOOP_AUTO_CHANGED, LOOP_AUTO_START, type LoopAutoStartPayload } from \"./loop.js\";\n\nconst HOOCODE_DIR = getHooCodeDir();\n\n/**\n * Per-session plan file path. Keying on sessionId lets concurrent or resumed\n * plan sessions keep distinct plans instead of clobbering each other.\n */\nfunction getPlanPath(cwd: string, sessionId: string): string {\n\treturn join(cwd, \".hoocode\", \"plans\", `${sessionId}.md`);\n}\n\n/** Legacy single-file plan location, retained as a read-only fallback for /approve. */\nfunction getLegacyPlanPath(cwd: string): string {\n\treturn join(cwd, \".hoocode\", \"plan.md\");\n}\n\nfunction tryReadFile(path: string): string | undefined {\n\tif (!existsSync(path)) return undefined;\n\ttry {\n\t\tconst text = readFileSync(path, \"utf8\").trim();\n\t\treturn text || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Outcome of reading the first usable plan file out of a candidate list. */\ntype PlanLoadResult =\n\t| { status: \"loaded\"; sections: PlanSections }\n\t| { status: \"missing\" }\n\t| { status: \"error\"; path: string };\n\n/**\n * Reads the first candidate plan file that exists and is non-empty, parsed into\n * sections. Missing and blank files fall through to the next candidate; an\n * unreadable one stops the walk so the caller can report the specific path.\n */\nfunction loadPlanSections(candidatePaths: string[]): PlanLoadResult {\n\tfor (const planPath of candidatePaths) {\n\t\tif (!existsSync(planPath)) continue;\n\t\ttry {\n\t\t\tconst raw = readFileSync(planPath, \"utf8\").trim();\n\t\t\tif (raw) return { status: \"loaded\", sections: parsePlanSections(raw) };\n\t\t} catch {\n\t\t\treturn { status: \"error\", path: planPath };\n\t\t}\n\t}\n\treturn { status: \"missing\" };\n}\n\n/**\n * Walks search dirs in precedence order and returns the first existing\n * `modes/{name}/system.md` content. Order: project → user → externalDirs.\n */\nfunction resolveModeFile(name: string, cwd: string, externalDirs: string[]): string | undefined {\n\tconst candidates: string[] = [\n\t\tjoin(cwd, \".hoocode\", \"modes\", name, \"system.md\"),\n\t\tjoin(HOOCODE_DIR, \"modes\", name, \"system.md\"),\n\t\t...externalDirs.map((dir) => join(dir, name, \"system.md\")),\n\t];\n\tfor (const candidate of candidates) {\n\t\tconst content = tryReadFile(candidate);\n\t\tif (content !== undefined) return content;\n\t}\n\treturn undefined;\n}\n\n/**\n * Returns the system prompt for the active mode.\n *\n * Search order (first hit wins):\n * - `./.hoocode/modes/{mode}/system.md`\n * - `~/.hoocode/modes/{mode}/system.md`\n * - each of `externalDirs` in declared order (config + CLI + extension contributions)\n * - built-in MODE_DEFAULTS for the four known modes\n */\nexport function buildSystemPrompt(mode: string, cwd: string, options?: { modePaths?: string[] }): string | undefined {\n\tconst modePaths = options?.modePaths ?? [];\n\treturn resolveModeFile(mode, cwd, modePaths) ?? MODE_DEFAULTS[mode];\n}\n\n// ============================================================================\n// Plan file: section parsing and step-by-step execution message\n// ============================================================================\n\nexport interface PlanSections {\n\tgoal?: string;\n\tfilesToModify?: string;\n\tnewFiles?: string;\n\ttests?: string;\n\tverification?: string;\n\t/** Original full text, used as fallback if no sections parsed */\n\traw: string;\n}\n\n/**\n * Parses `.hoocode/plan.md` into named sections.\n *\n * Recognises both ATX headings (`## Goal`) and bold labels (`**Goal**`).\n * Section names matched (case-insensitive): Goal, Files to modify, New files,\n * Tests, Verification.\n */\nexport function parsePlanSections(planContent: string): PlanSections {\n\tconst result: PlanSections = { raw: planContent };\n\n\t// Match `## Heading text` or `**Heading text**` followed by content until\n\t// the next heading of the same style.\n\tconst sectionPattern =\n\t\t/^(?:#{1,3}\\s+(.+?)|(?:\\*\\*(.+?)\\*\\*))\\s*\\n([\\s\\S]*?)(?=(?:^#{1,3}\\s+|\\*\\*[^*\\n]+\\*\\*\\s*\\n)|$)/gm;\n\n\tfor (const match of planContent.matchAll(sectionPattern)) {\n\t\tconst heading = (match[1] ?? match[2] ?? \"\").toLowerCase().trim();\n\t\tconst content = match[3].trim();\n\t\tif (!content) continue;\n\n\t\tif (/^goal/.test(heading)) {\n\t\t\tresult.goal = content;\n\t\t} else if (/files?\\s+to\\s+modif|^modif/.test(heading)) {\n\t\t\tresult.filesToModify = content;\n\t\t} else if (/new\\s+files?/.test(heading)) {\n\t\t\tresult.newFiles = content;\n\t\t} else if (/^tests?/.test(heading)) {\n\t\t\tresult.tests = content;\n\t\t} else if (/^verif/.test(heading)) {\n\t\t\tresult.verification = content;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Builds the user message sent to the agent when `/approve` is run.\n *\n * If the plan has recognisable sections, each is presented as a numbered step\n * so the agent works through them sequentially. Otherwise the raw plan is used.\n *\n * Execution order:\n * 1. Modify existing files\n * 2. Create new files\n * 3. Update / add tests\n * 4. Run verification commands\n */\nexport function buildApproveMessage(sections: PlanSections): string {\n\tconst steps: string[] = [];\n\n\tif (sections.goal) {\n\t\tsteps.push(`**Goal:** ${sections.goal}`);\n\t}\n\tif (sections.filesToModify) {\n\t\tsteps.push(`**Step 1 — Modify existing files:**\\n${sections.filesToModify}`);\n\t}\n\tif (sections.newFiles) {\n\t\tsteps.push(`**Step 2 — Create new files:**\\n${sections.newFiles}`);\n\t}\n\tif (sections.tests) {\n\t\tsteps.push(`**Step 3 — Update tests:**\\n${sections.tests}`);\n\t}\n\tif (sections.verification) {\n\t\tsteps.push(`**Step 4 — Verify:**\\n${sections.verification}`);\n\t}\n\n\tif (steps.length === 0) {\n\t\treturn `Execute the following plan:\\n\\n${sections.raw}`;\n\t}\n\n\treturn `Execute this plan step by step. Complete each step fully before moving to the next.\\n\\n${steps.join(\"\\n\\n\")}`;\n}\n\n// ============================================================================\n// Grill: plan interrogation\n// ============================================================================\n\n/** Which half (or both) of the grill flow to run. */\nexport type GrillTarget = \"both\" | \"me\" | \"plan\";\n\n/**\n * Parses the `/grill` argument into a target.\n *\n * Bare `/grill` runs both phases, `/grill me` only questions the user, and\n * `/grill plan` only critiques the plan. Anything else returns undefined so the\n * caller shows usage rather than guessing at intent.\n */\nexport function parseGrillTarget(args: string): GrillTarget | undefined {\n\tconst arg = args.trim().toLowerCase();\n\tif (!arg) return \"both\";\n\tif (arg === \"me\" || arg === \"plan\") return arg;\n\treturn undefined;\n}\n\n/**\n * Renders the parsed plan back into the message so the agent reviews a concrete\n * artifact rather than whatever it remembers writing. Falls back to the raw plan\n * text when no sections were recognised.\n */\nfunction renderPlanForReview(sections: PlanSections): string {\n\tconst parts: string[] = [];\n\tif (sections.goal) parts.push(`**Goal**\\n${sections.goal}`);\n\tif (sections.filesToModify) parts.push(`**Files to modify**\\n${sections.filesToModify}`);\n\tif (sections.newFiles) parts.push(`**New files**\\n${sections.newFiles}`);\n\tif (sections.tests) parts.push(`**Tests**\\n${sections.tests}`);\n\tif (sections.verification) parts.push(`**Verification**\\n${sections.verification}`);\n\treturn parts.length > 0 ? parts.join(\"\\n\\n\") : sections.raw;\n}\n\n/**\n * The `/grill` phases, read from the shipped prompt templates.\n *\n * These were two ~200-word string constants in this file. They are prose the\n * runtime injects verbatim - no interpolation, no branching, nothing a compiler\n * checks - so a `.md` under `templates/prompts/` is their right home, and the\n * existing build-time embed carries them in. Editing a prompt is now editing\n * prose rather than editing TypeScript that happens to contain prose.\n *\n * Each is trimmed: the files end with a newline and the phases are joined with\n * explicit separators below.\n */\nfunction grillPrompt(name: \"grill-me\" | \"grill-plan\" | \"grill-bridge\"): string {\n\treturn (EMBEDDED_PROMPTS[name] ?? \"\").trim();\n}\n\n/**\n * Builds the follow-up message injected by `/grill`.\n *\n * The two phases are ordered rather than alternative: underspecification sits\n * upstream of plan weakness, so critiquing a plan built on a misread request\n * produces a well-reviewed plan for the wrong job. Bare `/grill` therefore asks\n * first and folds the answers into the critique.\n */\nexport function buildGrillMessage(sections: PlanSections, target: GrillTarget): string {\n\tconst plan = renderPlanForReview(sections);\n\tconst me = grillPrompt(\"grill-me\");\n\tconst critique = grillPrompt(\"grill-plan\");\n\tif (target === \"me\") return `${me}\\n\\n---\\n\\n${plan}`;\n\tif (target === \"plan\") return `${critique}\\n\\n---\\n\\n${plan}`;\n\treturn `${me}\\n\\n${grillPrompt(\"grill-bridge\")}\\n\\n${critique}\\n\\n---\\n\\n${plan}`;\n}\n\n// ============================================================================\n// Goal: autonomous execution toward a completion condition\n// ============================================================================\n\n/** A parsed `/goal` invocation. */\nexport interface GoalInvocation {\n\t/** Explicit objective; falls back to the plan's Goal section when absent. */\n\tobjective?: string;\n\t/** Turn budget passed through to the autonomous loop. */\n\tmaxTurns?: number;\n}\n\n/**\n * Parses `/goal [--max-turns N] [objective]`.\n *\n * Returns undefined when `--max-turns` is present but not followed by a\n * non-negative integer, so the caller shows usage instead of silently running\n * with the default budget.\n */\nexport function parseGoalArgs(args: string): GoalInvocation | undefined {\n\tlet rest = args.trim();\n\tlet maxTurns: number | undefined;\n\n\tconst flag = /^--max-turns(?:\\s+(\\S+))?([\\s\\S]*)$/.exec(rest);\n\tif (flag) {\n\t\tconst raw = flag[1];\n\t\tif (!raw || !/^\\d+$/.test(raw)) return undefined;\n\t\tmaxTurns = Number(raw);\n\t\trest = flag[2].trim();\n\t}\n\n\treturn { objective: rest || undefined, maxTurns };\n}\n\n/** The two messages `/goal` hands to the autonomous loop. */\nexport interface GoalMessages {\n\t/** Delivered once, to start the run. */\n\ttask: string;\n\t/** Re-sent on each continuation to keep the target in view. */\n\tcontinuePrompt: string;\n}\n\n/**\n * Builds the messages for a `/goal` run.\n *\n * When the plan carries a Verification section it becomes the completion\n * condition, which is the difference between a loop that stops when it feels\n * finished and one that stops when something it can run says so. Both messages\n * restate the objective, because the loop's continuation prompt is all that\n * holds the target in place as the transcript grows.\n */\nexport function buildGoalMessages(objective: string, verification?: string): GoalMessages {\n\tconst condition = verification\n\t\t? `\\n\\nThe goal counts as complete only once this verification passes. Run it, and if it fails, fix what it reports and run it again:\\n\\n${verification}`\n\t\t: \"\";\n\n\treturn {\n\t\ttask: `Work autonomously toward this goal:\\n\\n${objective}${condition}`,\n\t\tcontinuePrompt:\n\t\t\t`Keep working toward the goal:\\n\\n${objective}${condition}\\n\\n` +\n\t\t\t`Reply with ${AUTO_LOOP_DONE_TOKEN} only when it is genuinely complete — not when it is merely close.`,\n\t};\n}\n\n// ============================================================================\n// setupMode\n// ============================================================================\n\nexport function setupMode(pi: ExtensionAPI): void {\n\tlet cachedMode = DEFAULT_MODE;\n\tlet cachedSystemPrompt: string | undefined;\n\tlet cachedPlanPath: string | undefined;\n\n\t// `/grill me` asks the user a question via ask_options, which an unattended\n\t// `/loop auto` run has nobody to answer. Track the loop's broadcast state so\n\t// the command can drop its interrogation phase instead of stalling the run.\n\tlet autoLoopActive = false;\n\tpi.events.on(LOOP_AUTO_CHANGED, (data) => {\n\t\tautoLoopActive = (data as { active?: boolean } | undefined)?.active === true;\n\t});\n\n\t// ── session_start ─────────────────────────────────────────────────────────\n\t// Config resolution order:\n\t// 1. Read global config (~/.hoocode/hoo-config.json)\n\t// 2. Read project config (./.hoocode/hoo-config.json) if present\n\t// 3. Merge — project scalars win; arrays are unioned\n\t// 4. Re-resolve active_mode from the merged result\n\n\tpi.on(\"session_start\", (_event: SessionStartEvent, ctx: ExtensionContext) => {\n\t\t// Light mode strips every fixed prompt appendix. Leaving\n\t\t// cachedSystemPrompt unset makes before_agent_start a no-op, so no\n\t\t// `<!-- hoo-core: mode= -->` block is appended.\n\t\tif (isLightModeEnv()) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Steps 1–3: merge global + project configs\n\t\tconst config = readMergedConfig(ctx.cwd);\n\n\t\t// Step 4: resolve mode from the merged config\n\t\tcachedMode = config.active_mode ?? DEFAULT_MODE;\n\t\t// External search dirs come from two channels:\n\t\t// - HooConfig.mode_paths (config-declared)\n\t\t// - pi.addModeSearchPath (CLI flags + extension contributions)\n\t\tconst modePaths = mergeSearchPaths(config.mode_paths, pi.getModeSearchPaths());\n\t\tconst rawSystemPrompt = buildSystemPrompt(cachedMode, ctx.cwd, { modePaths });\n\n\t\t// Per-session plan path so concurrent sessions don't overwrite each other.\n\t\t// The `{{PLAN_PATH}}` token in plan-mode templates is substituted here.\n\t\tcachedPlanPath = getPlanPath(ctx.cwd, ctx.sessionManager.getSessionId());\n\t\tconst relPlanPath = relative(ctx.cwd, cachedPlanPath) || cachedPlanPath;\n\t\tcachedSystemPrompt = rawSystemPrompt?.replace(/\\{\\{PLAN_PATH\\}\\}/g, relPlanPath);\n\n\t\t// Update footer with active mode\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.setMode(cachedMode);\n\t\t}\n\n\t\t// Apply tool filter from mode enabled_tools\n\t\tconst modeCfg = config.modes?.[cachedMode];\n\t\tif (modeCfg?.enabled_tools && modeCfg.enabled_tools.length > 0) {\n\t\t\tpi.setActiveTools(modeCfg.enabled_tools);\n\t\t}\n\t});\n\n\t// ── before_agent_start ────────────────────────────────────────────────────\n\n\tpi.on(\"before_agent_start\", (event: BeforeAgentStartEvent): BeforeAgentStartEventResult | undefined => {\n\t\tif (!cachedSystemPrompt) return;\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n\\n<!-- hoo-core: mode=${cachedMode} -->\\n${cachedSystemPrompt}`,\n\t\t};\n\t});\n\n\t// ── /mode command ─────────────────────────────────────────────────────────\n\n\tconst KNOWN_MODES = [\"ask\", \"plan\", \"build\", \"debug\"];\n\n\tpi.registerCommand(\"mode\", {\n\t\tdescription: \"Switch active mode. Usage: /mode <ask|plan|build|debug>\",\n\t\tgetArgumentCompletions: (prefix: string) =>\n\t\t\tKNOWN_MODES.filter((m) => m.startsWith(prefix)).map((m) => ({ value: m, label: m })),\n\t\thandler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst name = args.trim();\n\t\t\tif (!name) {\n\t\t\t\tctx.ui.notify(`Active mode: ${cachedMode}`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst config = readConfig();\n\t\t\tconfig.active_mode = name === DEFAULT_MODE ? undefined : name;\n\t\t\twriteConfig(config);\n\t\t\tctx.ui.notify(`Mode set to \"${name}\" — reloading…`, \"info\");\n\t\t\tawait ctx.reload();\n\t\t},\n\t});\n\n\t// ── /plan command (shorthand for /mode plan) ──────────────────────────────\n\n\tpi.registerCommand(\"plan\", {\n\t\tdescription: \"Switch to plan mode. Shorthand for /mode plan.\",\n\t\tgetArgumentCompletions: () => [],\n\t\thandler: async (_args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst config = readConfig();\n\t\t\tconfig.active_mode = \"plan\";\n\t\t\twriteConfig(config);\n\t\t\tctx.ui.notify(`Mode set to \"plan\" — reloading…`, \"info\");\n\t\t\tawait ctx.reload();\n\t\t},\n\t});\n\n\t// ── /grill command ────────────────────────────────────────────────────────\n\t// Stress-tests the current plan in two phases: `me` surfaces the request's\n\t// unconfirmed assumptions as ask_options questions, `plan` critiques the plan\n\t// file itself. Unlike /approve this only injects a follow-up message — no\n\t// session switch, no mode change, no config write.\n\n\tpi.registerCommand(\"grill\", {\n\t\tdescription: \"Stress-test the current plan. Usage: /grill [me|plan]\",\n\t\tgetArgumentCompletions: (prefix: string) =>\n\t\t\t[\"me\", \"plan\"].filter((s) => s.startsWith(prefix)).map((s) => ({ value: s, label: s })),\n\t\thandler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst requested = parseGrillTarget(args);\n\t\t\tif (!requested) {\n\t\t\t\tctx.ui.notify(\"Usage: /grill [me|plan]\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Same lookup as /approve: per-session plan first, legacy file second.\n\t\t\tconst sessionPlanPath = cachedPlanPath ?? getPlanPath(ctx.cwd, ctx.sessionManager.getSessionId());\n\t\t\tconst loaded = loadPlanSections([sessionPlanPath, getLegacyPlanPath(ctx.cwd)]);\n\t\t\tif (loaded.status === \"error\") {\n\t\t\t\tctx.ui.notify(`Could not read ${relative(ctx.cwd, loaded.path) || loaded.path}`, \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (loaded.status === \"missing\") {\n\t\t\t\tconst relPlan = relative(ctx.cwd, sessionPlanPath) || sessionPlanPath;\n\t\t\t\tctx.ui.notify(`No plan to grill — ${relPlan} not found. Run /plan first.`, \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Nobody is present to answer during an autonomous loop, so keep the\n\t\t\t// half of the flow that still works rather than blocking on a question.\n\t\t\tlet target = requested;\n\t\t\tif (autoLoopActive && target !== \"plan\") {\n\t\t\t\ttarget = \"plan\";\n\t\t\t\tctx.ui.notify(\"Autonomous loop active — grilling the plan only, skipping questions.\", \"info\");\n\t\t\t}\n\n\t\t\tpi.sendUserMessage(buildGrillMessage(loaded.sections, target), { deliverAs: \"followUp\" });\n\t\t},\n\t});\n\n\t// ── /goal command ─────────────────────────────────────────────────────────\n\t// Works autonomously toward a completion condition by driving the loop in\n\t// loop.ts over the LOOP_AUTO_START channel. Linear by design: a single thread\n\t// of execution that iterates until it reports done or exhausts its budget —\n\t// there is no task graph here, and no subtask fan-out.\n\t//\n\t// The run inherits whatever the active mode already permits (enabled_tools,\n\t// allowed_bash_commands, allowed_write_paths, auto_allow), so how much rope\n\t// an unattended goal gets is a mode-config decision, not one made here.\n\n\tpi.registerCommand(\"goal\", {\n\t\tdescription: \"Work autonomously toward a goal. Usage: /goal [--max-turns N] [objective]\",\n\t\tgetArgumentCompletions: () => [],\n\t\thandler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst parsed = parseGoalArgs(args);\n\t\t\tif (!parsed) {\n\t\t\t\tctx.ui.notify(\"Usage: /goal [--max-turns N] [objective]\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The plan supplies the objective when none was typed, and its\n\t\t\t// verification section becomes the completion condition either way.\n\t\t\tconst sessionPlanPath = cachedPlanPath ?? getPlanPath(ctx.cwd, ctx.sessionManager.getSessionId());\n\t\t\tconst loaded = loadPlanSections([sessionPlanPath, getLegacyPlanPath(ctx.cwd)]);\n\t\t\tif (loaded.status === \"error\") {\n\t\t\t\tctx.ui.notify(`Could not read ${relative(ctx.cwd, loaded.path) || loaded.path}`, \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst sections = loaded.status === \"loaded\" ? loaded.sections : undefined;\n\n\t\t\tconst objective = parsed.objective ?? sections?.goal;\n\t\t\tif (!objective) {\n\t\t\t\tconst relPlan = relative(ctx.cwd, sessionPlanPath) || sessionPlanPath;\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`No objective — pass one as /goal <objective>, or write a Goal section in ${relPlan}.`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { task, continuePrompt } = buildGoalMessages(objective, sections?.verification);\n\t\t\t// The loop announces itself on start, so nothing to notify here.\n\t\t\tpi.events.emit(LOOP_AUTO_START, {\n\t\t\t\ttask,\n\t\t\t\tmaxTurns: parsed.maxTurns,\n\t\t\t\tcontinuePrompt,\n\t\t\t} satisfies LoopAutoStartPayload);\n\t\t},\n\t});\n\n\t// ── /approve command ──────────────────────────────────────────────────────\n\t// Reads .hoocode/plan.md, parses it into named sections (Goal, Files to\n\t// modify, New files, Tests, Verification), switches to build mode, then\n\t// injects a step-by-step execution message into the new session.\n\n\tpi.registerCommand(\"approve\", {\n\t\tdescription: \"Approve the current plan and switch to build mode to execute it.\",\n\t\tgetArgumentCompletions: () => [],\n\t\thandler: async (_args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tif (cachedMode !== \"plan\") {\n\t\t\t\tctx.ui.notify(`/approve is only available in plan mode (current mode: \"${cachedMode}\")`, \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Prefer the per-session plan file, fall back to the legacy single file.\n\t\t\tconst sessionPlanPath = cachedPlanPath ?? getPlanPath(ctx.cwd, ctx.sessionManager.getSessionId());\n\t\t\tconst loaded = loadPlanSections([sessionPlanPath, getLegacyPlanPath(ctx.cwd)]);\n\t\t\tif (loaded.status === \"error\") {\n\t\t\t\tctx.ui.notify(`Could not read ${relative(ctx.cwd, loaded.path) || loaded.path}`, \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst approveMessage = loaded.status === \"loaded\" ? buildApproveMessage(loaded.sections) : undefined;\n\n\t\t\t// Switch global config to build mode\n\t\t\tconst config = readConfig();\n\t\t\tconfig.active_mode = \"build\";\n\t\t\twriteConfig(config);\n\n\t\t\tif (approveMessage) {\n\t\t\t\t// Open a new build-mode session and deliver the parsed plan as the\n\t\t\t\t// first user message so the agent starts executing immediately\n\t\t\t\tawait ctx.newSession({\n\t\t\t\t\twithSession: async (replacedCtx) => {\n\t\t\t\t\t\tawait replacedCtx.sendUserMessage(approveMessage!, { deliverAs: \"followUp\" });\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst relPlan = relative(ctx.cwd, sessionPlanPath) || sessionPlanPath;\n\t\t\t\tctx.ui.notify(`Switched to build mode. No ${relPlan} found — describe what to build.`, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|
|
@@ -14,6 +14,7 @@ import { join, relative } from "node:path";
|
|
|
14
14
|
import { getHooCodeDir } from "../../config.js";
|
|
15
15
|
import { isLightModeEnv } from "../../core/light.js";
|
|
16
16
|
import { DEFAULT_MODE, DEFAULT_MODE_PROMPTS as MODE_DEFAULTS } from "../../core/mode-prompts.js";
|
|
17
|
+
import { EMBEDDED_PROMPTS } from "../../init-templates.generated.js";
|
|
17
18
|
import { mergeSearchPaths, readConfig, readMergedConfig, writeConfig } from "./config.js";
|
|
18
19
|
import { AUTO_LOOP_DONE_TOKEN, LOOP_AUTO_CHANGED, LOOP_AUTO_START } from "./loop.js";
|
|
19
20
|
const HOOCODE_DIR = getHooCodeDir();
|
|
@@ -192,24 +193,21 @@ function renderPlanForReview(sections) {
|
|
|
192
193
|
parts.push(`**Verification**\n${sections.verification}`);
|
|
193
194
|
return parts.length > 0 ? parts.join("\n\n") : sections.raw;
|
|
194
195
|
}
|
|
195
|
-
/**
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
- Does the verification section prove the goal is met, or only that the code runs?
|
|
211
|
-
|
|
212
|
-
Report what you find. Where a weakness is real, revise the plan file and state what changed. Where the plan holds up, say so plainly rather than inventing criticism. Do not implement anything.`;
|
|
196
|
+
/**
|
|
197
|
+
* The `/grill` phases, read from the shipped prompt templates.
|
|
198
|
+
*
|
|
199
|
+
* These were two ~200-word string constants in this file. They are prose the
|
|
200
|
+
* runtime injects verbatim - no interpolation, no branching, nothing a compiler
|
|
201
|
+
* checks - so a `.md` under `templates/prompts/` is their right home, and the
|
|
202
|
+
* existing build-time embed carries them in. Editing a prompt is now editing
|
|
203
|
+
* prose rather than editing TypeScript that happens to contain prose.
|
|
204
|
+
*
|
|
205
|
+
* Each is trimmed: the files end with a newline and the phases are joined with
|
|
206
|
+
* explicit separators below.
|
|
207
|
+
*/
|
|
208
|
+
function grillPrompt(name) {
|
|
209
|
+
return (EMBEDDED_PROMPTS[name] ?? "").trim();
|
|
210
|
+
}
|
|
213
211
|
/**
|
|
214
212
|
* Builds the follow-up message injected by `/grill`.
|
|
215
213
|
*
|
|
@@ -220,13 +218,13 @@ Report what you find. Where a weakness is real, revise the plan file and state w
|
|
|
220
218
|
*/
|
|
221
219
|
export function buildGrillMessage(sections, target) {
|
|
222
220
|
const plan = renderPlanForReview(sections);
|
|
221
|
+
const me = grillPrompt("grill-me");
|
|
222
|
+
const critique = grillPrompt("grill-plan");
|
|
223
223
|
if (target === "me")
|
|
224
|
-
return `${
|
|
224
|
+
return `${me}\n\n---\n\n${plan}`;
|
|
225
225
|
if (target === "plan")
|
|
226
|
-
return `${
|
|
227
|
-
return
|
|
228
|
-
`Once the user has answered, fold their answers into the plan and immediately continue with this review:\n\n` +
|
|
229
|
-
`${GRILL_PLAN_PROMPT}\n\n---\n\n${plan}`);
|
|
226
|
+
return `${critique}\n\n---\n\n${plan}`;
|
|
227
|
+
return `${me}\n\n${grillPrompt("grill-bridge")}\n\n${critique}\n\n---\n\n${plan}`;
|
|
230
228
|
}
|
|
231
229
|
/**
|
|
232
230
|
* Parses `/goal [--max-turns N] [objective]`.
|