@draht/coding-agent 2026.3.3 → 2026.3.5

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.
Files changed (201) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/README.md +1 -0
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +1 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +5 -0
  8. package/dist/cli.js.map +1 -1
  9. package/dist/config.d.ts +0 -7
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +0 -12
  12. package/dist/config.js.map +1 -1
  13. package/dist/core/agent-session.d.ts +14 -4
  14. package/dist/core/agent-session.d.ts.map +1 -1
  15. package/dist/core/agent-session.js +167 -49
  16. package/dist/core/agent-session.js.map +1 -1
  17. package/dist/core/auth-storage.d.ts +1 -1
  18. package/dist/core/auth-storage.d.ts.map +1 -1
  19. package/dist/core/auth-storage.js +2 -1
  20. package/dist/core/auth-storage.js.map +1 -1
  21. package/dist/core/builtins/subagent.d.ts +14 -0
  22. package/dist/core/builtins/subagent.d.ts.map +1 -0
  23. package/dist/core/builtins/subagent.js +492 -0
  24. package/dist/core/builtins/subagent.js.map +1 -0
  25. package/dist/core/compaction/compaction.d.ts.map +1 -1
  26. package/dist/core/compaction/compaction.js +4 -1
  27. package/dist/core/compaction/compaction.js.map +1 -1
  28. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  29. package/dist/core/export-html/tool-renderer.js +6 -0
  30. package/dist/core/export-html/tool-renderer.js.map +1 -1
  31. package/dist/core/extensions/loader.d.ts.map +1 -1
  32. package/dist/core/extensions/loader.js +19 -8
  33. package/dist/core/extensions/loader.js.map +1 -1
  34. package/dist/core/extensions/runner.d.ts.map +1 -1
  35. package/dist/core/extensions/runner.js +1 -0
  36. package/dist/core/extensions/runner.js.map +1 -1
  37. package/dist/core/extensions/types.d.ts +8 -2
  38. package/dist/core/extensions/types.d.ts.map +1 -1
  39. package/dist/core/extensions/types.js.map +1 -1
  40. package/dist/core/model-registry.d.ts +1 -0
  41. package/dist/core/model-registry.d.ts.map +1 -1
  42. package/dist/core/model-registry.js +9 -6
  43. package/dist/core/model-registry.js.map +1 -1
  44. package/dist/core/model-resolver.d.ts.map +1 -1
  45. package/dist/core/model-resolver.js +35 -5
  46. package/dist/core/model-resolver.js.map +1 -1
  47. package/dist/core/package-manager.d.ts.map +1 -1
  48. package/dist/core/package-manager.js +1 -10
  49. package/dist/core/package-manager.js.map +1 -1
  50. package/dist/core/prompt-templates.d.ts.map +1 -1
  51. package/dist/core/prompt-templates.js +4 -2
  52. package/dist/core/prompt-templates.js.map +1 -1
  53. package/dist/core/resource-loader.d.ts +2 -0
  54. package/dist/core/resource-loader.d.ts.map +1 -1
  55. package/dist/core/resource-loader.js +5 -1
  56. package/dist/core/resource-loader.js.map +1 -1
  57. package/dist/core/sdk.d.ts +1 -1
  58. package/dist/core/sdk.d.ts.map +1 -1
  59. package/dist/core/sdk.js.map +1 -1
  60. package/dist/core/session-manager.js.map +1 -1
  61. package/dist/core/settings-manager.d.ts +3 -0
  62. package/dist/core/settings-manager.d.ts.map +1 -1
  63. package/dist/core/settings-manager.js +4 -0
  64. package/dist/core/settings-manager.js.map +1 -1
  65. package/dist/core/system-prompt.d.ts +4 -0
  66. package/dist/core/system-prompt.d.ts.map +1 -1
  67. package/dist/core/system-prompt.js +34 -12
  68. package/dist/core/system-prompt.js.map +1 -1
  69. package/dist/core/tools/edit-diff.js.map +1 -1
  70. package/dist/core/tools/path-utils.js.map +1 -1
  71. package/dist/gsd/domain-validator.d.ts +18 -0
  72. package/dist/gsd/domain-validator.d.ts.map +1 -0
  73. package/dist/gsd/domain-validator.js +61 -0
  74. package/dist/gsd/domain-validator.js.map +1 -0
  75. package/dist/gsd/domain.d.ts +12 -0
  76. package/dist/gsd/domain.d.ts.map +1 -0
  77. package/dist/gsd/domain.js +113 -0
  78. package/dist/gsd/domain.js.map +1 -0
  79. package/dist/gsd/git.d.ts +20 -0
  80. package/dist/gsd/git.d.ts.map +1 -0
  81. package/dist/gsd/git.js +59 -0
  82. package/dist/gsd/git.js.map +1 -0
  83. package/dist/gsd/hook-utils.d.ts +22 -0
  84. package/dist/gsd/hook-utils.d.ts.map +1 -0
  85. package/dist/gsd/hook-utils.js +100 -0
  86. package/dist/gsd/hook-utils.js.map +1 -0
  87. package/dist/gsd/index.d.ts +9 -0
  88. package/dist/gsd/index.d.ts.map +1 -0
  89. package/dist/gsd/index.js +8 -0
  90. package/dist/gsd/index.js.map +1 -0
  91. package/dist/gsd/planning.d.ts +20 -0
  92. package/dist/gsd/planning.d.ts.map +1 -0
  93. package/dist/gsd/planning.js +167 -0
  94. package/dist/gsd/planning.js.map +1 -0
  95. package/dist/hooks/gsd/draht-post-task.js +44 -11
  96. package/dist/hooks/gsd/draht-quality-gate.js +99 -57
  97. package/dist/index.d.ts +2 -0
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +2 -0
  100. package/dist/index.js.map +1 -1
  101. package/dist/main.d.ts.map +1 -1
  102. package/dist/main.js +5 -5
  103. package/dist/main.js.map +1 -1
  104. package/dist/migrations.js.map +1 -1
  105. package/dist/modes/interactive/components/armin.js.map +1 -1
  106. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  107. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  108. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  109. package/dist/modes/interactive/components/extension-editor.d.ts +5 -2
  110. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/extension-editor.js +9 -1
  112. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  113. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  114. package/dist/modes/interactive/components/footer.js.map +1 -1
  115. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  116. package/dist/modes/interactive/components/login-dialog.js +1 -1
  117. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  118. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  119. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  120. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  121. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  122. package/dist/modes/interactive/components/oauth-selector.js +1 -1
  123. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  124. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  125. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  126. package/dist/modes/interactive/components/session-selector.js +1 -1
  127. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  128. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  129. package/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  130. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  131. package/dist/modes/interactive/components/tool-execution.js +28 -3
  132. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  133. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  134. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  135. package/dist/modes/interactive/components/user-message.d.ts +1 -0
  136. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  137. package/dist/modes/interactive/components/user-message.js +11 -0
  138. package/dist/modes/interactive/components/user-message.js.map +1 -1
  139. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  140. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  141. package/dist/modes/interactive/interactive-mode.js +29 -28
  142. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  143. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  144. package/dist/modes/interactive/theme/theme.js +5 -0
  145. package/dist/modes/interactive/theme/theme.js.map +1 -1
  146. package/dist/prompts/agents/build.md +5 -1
  147. package/dist/prompts/agents/plan.md +5 -1
  148. package/dist/prompts/agents/verify.md +5 -1
  149. package/dist/prompts/commands/atomic-commit.md +8 -16
  150. package/dist/prompts/commands/discuss-phase.md +9 -3
  151. package/dist/prompts/commands/execute-phase.md +15 -8
  152. package/dist/prompts/commands/fix.md +35 -0
  153. package/dist/prompts/commands/init-project.md +55 -0
  154. package/dist/prompts/commands/map-codebase.md +7 -1
  155. package/dist/prompts/commands/new-project.md +8 -2
  156. package/dist/prompts/commands/next-milestone.md +48 -0
  157. package/dist/prompts/commands/pause-work.md +4 -0
  158. package/dist/prompts/commands/plan-phase.md +11 -5
  159. package/dist/prompts/commands/progress.md +4 -0
  160. package/dist/prompts/commands/quick.md +8 -2
  161. package/dist/prompts/commands/resume-work.md +4 -0
  162. package/dist/prompts/commands/review.md +32 -0
  163. package/dist/prompts/commands/verify-work.md +10 -4
  164. package/docs/custom-provider.md +10 -2
  165. package/docs/extensions.md +20 -1
  166. package/docs/providers.md +3 -1
  167. package/docs/settings.md +1 -0
  168. package/examples/extensions/README.md +1 -0
  169. package/examples/extensions/antigravity-image-gen.ts +3 -1
  170. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  171. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  172. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  173. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  174. package/examples/extensions/dynamic-tools.ts +74 -0
  175. package/examples/extensions/with-deps/package-lock.json +2 -2
  176. package/examples/extensions/with-deps/package.json +1 -1
  177. package/hooks/gsd/draht-post-task.js +44 -11
  178. package/hooks/gsd/draht-quality-gate.js +99 -57
  179. package/package.json +9 -8
  180. package/prompts/agents/build.md +5 -1
  181. package/prompts/agents/plan.md +5 -1
  182. package/prompts/agents/verify.md +5 -1
  183. package/prompts/commands/atomic-commit.md +8 -16
  184. package/prompts/commands/discuss-phase.md +9 -3
  185. package/prompts/commands/execute-phase.md +15 -8
  186. package/prompts/commands/fix.md +35 -0
  187. package/prompts/commands/init-project.md +55 -0
  188. package/prompts/commands/map-codebase.md +7 -1
  189. package/prompts/commands/new-project.md +8 -2
  190. package/prompts/commands/next-milestone.md +48 -0
  191. package/prompts/commands/pause-work.md +4 -0
  192. package/prompts/commands/plan-phase.md +11 -5
  193. package/prompts/commands/progress.md +4 -0
  194. package/prompts/commands/quick.md +8 -2
  195. package/prompts/commands/resume-work.md +4 -0
  196. package/prompts/commands/review.md +32 -0
  197. package/prompts/commands/verify-work.md +10 -4
  198. package/dist/extensions/gsd-commands.ts +0 -403
  199. package/dist/extensions/subagent.ts +0 -515
  200. package/extensions/gsd-commands.ts +0 -403
  201. package/extensions/subagent.ts +0 -515
@@ -0,0 +1,492 @@
1
+ /**
2
+ * Subagent Tool for Draht — adapted from the pi subagent example
3
+ *
4
+ * Spawns isolated draht processes for delegated tasks.
5
+ * Agents are defined in .draht/agents/*.md (project) or ~/.draht/agent/agents/*.md (global).
6
+ *
7
+ * Modes:
8
+ * single — { agent, task }
9
+ * parallel — { tasks: [{ agent, task }] } (max 8, concurrency 4)
10
+ * chain — { chain: [{ agent, task }] } (sequential, {previous} placeholder)
11
+ */
12
+ import { spawn } from "node:child_process";
13
+ import * as fs from "node:fs";
14
+ import * as os from "node:os";
15
+ import * as path from "node:path";
16
+ import { StringEnum } from "@draht/ai";
17
+ import { Text } from "@draht/tui";
18
+ import { Type } from "@sinclair/typebox";
19
+ import { getAgentDir, getPackageDir, isBunBinary } from "../../config.js";
20
+ import { parseFrontmatter } from "../../utils/frontmatter.js";
21
+ const MAX_PARALLEL = 8;
22
+ const MAX_CONCURRENCY = 4;
23
+ // Build the command to spawn a subagent process.
24
+ // Compiled Bun binary: process.execPath IS the CLI binary, args go directly.
25
+ // Source/dev mode: process.execPath is the runtime (bun/node), process.argv[1] is the CLI script.
26
+ const DRAHT_BIN = process.execPath;
27
+ const DRAHT_ARGS_PREFIX = isBunBinary ? [] : [process.argv[1]];
28
+ function loadAgentsFromDir(dir, source) {
29
+ if (!fs.existsSync(dir))
30
+ return [];
31
+ let entries;
32
+ try {
33
+ entries = fs.readdirSync(dir, { withFileTypes: true });
34
+ }
35
+ catch {
36
+ return [];
37
+ }
38
+ const agents = [];
39
+ for (const entry of entries) {
40
+ if (!entry.isFile() || !entry.name.endsWith(".md"))
41
+ continue;
42
+ try {
43
+ const content = fs.readFileSync(path.join(dir, entry.name), "utf-8");
44
+ const { frontmatter, body } = parseFrontmatter(content);
45
+ if (!frontmatter.name || !frontmatter.description)
46
+ continue;
47
+ const tools = frontmatter.tools
48
+ ?.split(",")
49
+ .map((t) => t.trim())
50
+ .filter(Boolean);
51
+ agents.push({
52
+ name: frontmatter.name,
53
+ description: frontmatter.description,
54
+ tools: tools?.length ? tools : undefined,
55
+ model: frontmatter.model,
56
+ systemPrompt: body,
57
+ source,
58
+ });
59
+ }
60
+ catch { }
61
+ }
62
+ return agents;
63
+ }
64
+ function findProjectAgentsDir(cwd) {
65
+ let dir = cwd;
66
+ while (true) {
67
+ const candidate = path.join(dir, ".draht", "agents");
68
+ try {
69
+ if (fs.statSync(candidate).isDirectory())
70
+ return candidate;
71
+ }
72
+ catch { }
73
+ const parent = path.dirname(dir);
74
+ if (parent === dir)
75
+ return null;
76
+ dir = parent;
77
+ }
78
+ }
79
+ function discoverAgents(cwd, scope) {
80
+ // Shipped agents (bundled with the package) — lowest priority
81
+ const shippedDir = path.join(getPackageDir(), "agents");
82
+ const shippedAgents = loadAgentsFromDir(shippedDir, "user");
83
+ const userDir = path.join(getAgentDir(), "agents");
84
+ const projectDir = findProjectAgentsDir(cwd);
85
+ const userAgents = scope !== "project" ? loadAgentsFromDir(userDir, "user") : [];
86
+ const projectAgents = scope !== "user" && projectDir ? loadAgentsFromDir(projectDir, "project") : [];
87
+ // Priority: shipped < user < project
88
+ const map = new Map();
89
+ for (const a of shippedAgents)
90
+ map.set(a.name, a);
91
+ for (const a of userAgents)
92
+ map.set(a.name, a);
93
+ for (const a of projectAgents)
94
+ map.set(a.name, a);
95
+ return Array.from(map.values());
96
+ }
97
+ function writeTemp(name, content) {
98
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "draht-subagent-"));
99
+ const file = path.join(dir, `${name.replace(/[^\w.-]/g, "_")}.md`);
100
+ fs.writeFileSync(file, content, { encoding: "utf-8", mode: 0o600 });
101
+ return { file, dir };
102
+ }
103
+ function cleanTemp(file, dir) {
104
+ try {
105
+ fs.unlinkSync(file);
106
+ }
107
+ catch { }
108
+ try {
109
+ fs.rmdirSync(dir);
110
+ }
111
+ catch { }
112
+ }
113
+ function getFinalText(messages) {
114
+ for (let i = messages.length - 1; i >= 0; i--) {
115
+ const msg = messages[i];
116
+ if (msg.role === "assistant") {
117
+ for (const part of msg.content) {
118
+ if (part.type === "text")
119
+ return part.text;
120
+ }
121
+ }
122
+ }
123
+ return "";
124
+ }
125
+ async function runAgent(cwd, agent, task, signal, step, onProgress) {
126
+ const args = ["--mode", "json", "-p", "--no-session"];
127
+ if (agent.model)
128
+ args.push("--model", agent.model);
129
+ if (agent.tools?.length)
130
+ args.push("--tools", agent.tools.join(","));
131
+ let tmpFile = null;
132
+ let tmpDir = null;
133
+ if (agent.systemPrompt.trim()) {
134
+ const tmp = writeTemp(agent.name, agent.systemPrompt);
135
+ tmpFile = tmp.file;
136
+ tmpDir = tmp.dir;
137
+ args.push("--append-system-prompt", tmpFile);
138
+ }
139
+ args.push(`Task: ${task}`);
140
+ const messages = [];
141
+ let stderr = "";
142
+ try {
143
+ const exitCode = await new Promise((resolve) => {
144
+ const proc = spawn(DRAHT_BIN, [...DRAHT_ARGS_PREFIX, ...args], {
145
+ cwd,
146
+ shell: false,
147
+ stdio: ["ignore", "pipe", "pipe"],
148
+ });
149
+ let buf = "";
150
+ const processLine = (line) => {
151
+ if (!line.trim())
152
+ return;
153
+ try {
154
+ const event = JSON.parse(line);
155
+ if ((event.type === "message_end" || event.type === "tool_result_end") && event.message) {
156
+ messages.push(event.message);
157
+ }
158
+ // Stream activity updates to the parent
159
+ if (onProgress) {
160
+ if (event.type === "tool_execution_start") {
161
+ const toolArgs = event.args ?? {};
162
+ const detail = toolArgs.command || toolArgs.path || toolArgs.file_path || toolArgs.pattern || "";
163
+ const short = typeof detail === "string" && detail.length > 60 ? `${detail.slice(0, 60)}...` : detail;
164
+ onProgress(short ? `${event.toolName} ${short}` : event.toolName);
165
+ }
166
+ else if (event.type === "text_delta") {
167
+ // Show first line of streaming text as activity
168
+ const text = event.text?.trim();
169
+ if (text) {
170
+ const firstLine = text.split("\n")[0];
171
+ const short = firstLine.length > 80 ? `${firstLine.slice(0, 80)}...` : firstLine;
172
+ onProgress(short);
173
+ }
174
+ }
175
+ }
176
+ }
177
+ catch { }
178
+ };
179
+ proc.stdout.on("data", (d) => {
180
+ buf += d.toString();
181
+ const lines = buf.split("\n");
182
+ buf = lines.pop() || "";
183
+ for (const l of lines)
184
+ processLine(l);
185
+ });
186
+ proc.stderr.on("data", (d) => {
187
+ stderr += d.toString();
188
+ });
189
+ proc.on("close", (code) => {
190
+ if (buf.trim())
191
+ processLine(buf);
192
+ resolve(code ?? 0);
193
+ });
194
+ proc.on("error", () => resolve(1));
195
+ if (signal) {
196
+ const kill = () => {
197
+ proc.kill("SIGTERM");
198
+ setTimeout(() => {
199
+ if (!proc.killed)
200
+ proc.kill("SIGKILL");
201
+ }, 5000);
202
+ };
203
+ if (signal.aborted)
204
+ kill();
205
+ else
206
+ signal.addEventListener("abort", kill, { once: true });
207
+ }
208
+ });
209
+ return { agent: agent.name, task, exitCode, output: getFinalText(messages), stderr, step };
210
+ }
211
+ finally {
212
+ if (tmpFile && tmpDir)
213
+ cleanTemp(tmpFile, tmpDir);
214
+ }
215
+ }
216
+ async function runParallel(items, concurrency, fn) {
217
+ const results = new Array(items.length);
218
+ let next = 0;
219
+ await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, async () => {
220
+ while (true) {
221
+ const i = next++;
222
+ if (i >= items.length)
223
+ return;
224
+ results[i] = await fn(items[i], i);
225
+ }
226
+ }));
227
+ return results;
228
+ }
229
+ // ─── Extension ──────────────────────────────────────────────────────────────
230
+ const TaskItem = Type.Object({
231
+ agent: Type.String({ description: "Agent name" }),
232
+ task: Type.String({ description: "Task description" }),
233
+ });
234
+ const ChainItem = Type.Object({
235
+ agent: Type.String({ description: "Agent name" }),
236
+ task: Type.String({ description: "Task, optionally using {previous} placeholder" }),
237
+ });
238
+ const Params = Type.Object({
239
+ agent: Type.Optional(Type.String()),
240
+ task: Type.Optional(Type.String()),
241
+ tasks: Type.Optional(Type.Array(TaskItem, { description: "Parallel tasks" })),
242
+ chain: Type.Optional(Type.Array(ChainItem, { description: "Chained tasks" })),
243
+ agentScope: Type.Optional(StringEnum(["user", "project", "both"], { default: "both" })),
244
+ });
245
+ // ─── Rendering helpers ──────────────────────────────────────────────────────
246
+ function truncateTask(task, maxLen = 120) {
247
+ const oneLine = task.replace(/\n/g, " ").trim();
248
+ return oneLine.length > maxLen ? `${oneLine.slice(0, maxLen)}...` : oneLine;
249
+ }
250
+ export default function (pi) {
251
+ pi.registerTool({
252
+ name: "subagent",
253
+ label: "Subagent",
254
+ description: "Delegate to specialized agents. single: {agent,task} | parallel: {tasks:[]} | chain: {chain:[]} with {previous} placeholder. agentScope: 'both' (default) uses project .draht/agents/ + global.",
255
+ parameters: Params,
256
+ renderCall(args, theme) {
257
+ const lines = [];
258
+ if (args.chain?.length) {
259
+ const agents = args.chain.map((s) => s.agent).join(" -> ");
260
+ lines.push(`${theme.fg("toolTitle", theme.bold(`subagent chain`))} ${theme.fg("accent", agents)}`);
261
+ for (let i = 0; i < args.chain.length; i++) {
262
+ const step = args.chain[i];
263
+ const prefix = theme.fg("muted", ` ${i + 1}.`);
264
+ lines.push(`${prefix} ${theme.fg("accent", step.agent)} ${theme.fg("toolOutput", truncateTask(step.task))}`);
265
+ }
266
+ }
267
+ else if (args.tasks?.length) {
268
+ lines.push(theme.fg("toolTitle", theme.bold(`subagent parallel`)) +
269
+ theme.fg("muted", ` (${args.tasks.length} tasks)`));
270
+ for (const t of args.tasks) {
271
+ lines.push(` ${theme.fg("accent", t.agent)} ${theme.fg("toolOutput", truncateTask(t.task))}`);
272
+ }
273
+ }
274
+ else if (args.agent) {
275
+ lines.push(theme.fg("toolTitle", theme.bold("subagent")) +
276
+ " " +
277
+ theme.fg("accent", args.agent) +
278
+ (args.task ? ` ${theme.fg("toolOutput", truncateTask(args.task))}` : ""));
279
+ }
280
+ else {
281
+ lines.push(theme.fg("toolTitle", theme.bold("subagent")));
282
+ }
283
+ return new Text(lines.join("\n"), 0, 0);
284
+ },
285
+ renderResult(result, options, theme) {
286
+ const status = result.details?.status;
287
+ const output = result.content
288
+ ?.filter((c) => c.type === "text")
289
+ .map((c) => ("text" in c ? c.text : ""))
290
+ .join("\n") || "";
291
+ const lines = [];
292
+ if (status) {
293
+ lines.push(theme.fg("muted", status));
294
+ }
295
+ if (output.trim()) {
296
+ const trimmed = output.trim();
297
+ if (options.expanded || options.isPartial) {
298
+ // When expanded or during execution, show full activity log
299
+ for (const line of trimmed.split("\n")) {
300
+ lines.push(theme.fg("toolOutput", line));
301
+ }
302
+ }
303
+ else {
304
+ // Collapsed final result — show preview
305
+ const allLines = trimmed.split("\n");
306
+ const previewLines = allLines.slice(0, 8);
307
+ lines.push(theme.fg("toolOutput", previewLines.join("\n")));
308
+ if (allLines.length > 8) {
309
+ lines.push(theme.fg("muted", `... (${allLines.length - 8} more lines)`));
310
+ }
311
+ }
312
+ }
313
+ if (lines.length === 0)
314
+ return new Text("", 0, 0);
315
+ return new Text(lines.join("\n"), 0, 0);
316
+ },
317
+ async execute(_id, params, signal, onUpdate, ctx) {
318
+ const scope = params.agentScope ?? "both";
319
+ const agents = discoverAgents(ctx.cwd, scope);
320
+ const available = agents.map((a) => a.name).join(", ") || "none";
321
+ const find = (name) => agents.find((a) => a.name === name);
322
+ const notFound = (name) => ({
323
+ content: [{ type: "text", text: `Unknown agent "${name}". Available: ${available}` }],
324
+ isError: true,
325
+ details: {},
326
+ });
327
+ // Stream live activity from the subagent process
328
+ const activityLines = [];
329
+ const emitProgress = (agentName, activity) => {
330
+ const status = activity ? `${agentName}: ${activity}` : `${agentName} working...`;
331
+ onUpdate?.({
332
+ content: [{ type: "text", text: activityLines.join("\n") }],
333
+ details: { status },
334
+ });
335
+ };
336
+ const makeProgressFn = (agentName) => (activity) => {
337
+ // Keep a rolling log of recent activities
338
+ activityLines.push(`${agentName}: ${activity}`);
339
+ if (activityLines.length > 50)
340
+ activityLines.splice(0, activityLines.length - 50);
341
+ emitProgress(agentName, activity);
342
+ };
343
+ // ── Chain mode ──
344
+ if (params.chain?.length) {
345
+ let previous = "";
346
+ const results = [];
347
+ for (let i = 0; i < params.chain.length; i++) {
348
+ const step = params.chain[i];
349
+ const agent = find(step.agent);
350
+ if (!agent)
351
+ return notFound(step.agent);
352
+ activityLines.length = 0;
353
+ emitProgress(step.agent, `step ${i + 1}/${params.chain.length}`);
354
+ const task = step.task.replace(/\{previous\}/g, previous);
355
+ const result = await runAgent(ctx.cwd, agent, task, signal, i + 1, makeProgressFn(step.agent));
356
+ results.push(result);
357
+ if (result.exitCode !== 0) {
358
+ return {
359
+ content: [
360
+ {
361
+ type: "text",
362
+ text: `Chain failed at step ${i + 1} (${step.agent}):\n${result.output || result.stderr}`,
363
+ },
364
+ ],
365
+ isError: true,
366
+ details: {},
367
+ };
368
+ }
369
+ previous = result.output;
370
+ }
371
+ return {
372
+ content: [{ type: "text", text: results[results.length - 1].output || "(no output)" }],
373
+ details: {},
374
+ };
375
+ }
376
+ // ── Parallel mode ──
377
+ if (params.tasks?.length) {
378
+ if (params.tasks.length > MAX_PARALLEL) {
379
+ return {
380
+ content: [{ type: "text", text: `Too many tasks (max ${MAX_PARALLEL})` }],
381
+ isError: true,
382
+ details: {},
383
+ };
384
+ }
385
+ for (const t of params.tasks) {
386
+ if (!find(t.agent))
387
+ return notFound(t.agent);
388
+ }
389
+ const agentNames = params.tasks.map((t) => t.agent).join(", ");
390
+ emitProgress(agentNames);
391
+ const results = await runParallel(params.tasks, MAX_CONCURRENCY, async (t, _i) => {
392
+ return runAgent(ctx.cwd, find(t.agent), t.task, signal, undefined, makeProgressFn(t.agent));
393
+ });
394
+ const ok = results.filter((r) => r.exitCode === 0).length;
395
+ const summary = results
396
+ .map((r) => `[${r.agent}] ${r.exitCode === 0 ? "ok" : "fail"} ${r.output.slice(0, 200)}`)
397
+ .join("\n\n");
398
+ return {
399
+ content: [{ type: "text", text: `Parallel: ${ok}/${results.length} succeeded\n\n${summary}` }],
400
+ details: {},
401
+ };
402
+ }
403
+ // ── Single mode ──
404
+ if (params.agent && params.task) {
405
+ const agent = find(params.agent);
406
+ if (!agent)
407
+ return notFound(params.agent);
408
+ emitProgress(params.agent);
409
+ const result = await runAgent(ctx.cwd, agent, params.task, signal, undefined, makeProgressFn(params.agent));
410
+ const isError = result.exitCode !== 0;
411
+ return {
412
+ content: [{ type: "text", text: result.output || result.stderr || "(no output)" }],
413
+ ...(isError ? { isError: true } : {}),
414
+ details: {},
415
+ };
416
+ }
417
+ return {
418
+ content: [{ type: "text", text: `Provide exactly one mode. Available agents: ${available}` }],
419
+ isError: true,
420
+ details: {},
421
+ };
422
+ },
423
+ });
424
+ // ── Agent selection for user prompts ─────────────────────────────────────
425
+ let selectedAgent;
426
+ function updateAgentStatus(ctx) {
427
+ ctx.ui.setStatus("agent", selectedAgent ? `agent: ${selectedAgent}` : undefined);
428
+ }
429
+ // /agent command — select an agent or clear selection
430
+ pi.registerCommand("agent", {
431
+ description: "Select an agent to handle your next prompts, or clear selection. Usage: /agent [name]",
432
+ handler: async (args, ctx) => {
433
+ const agents = discoverAgents(ctx.cwd, "both");
434
+ if (args.trim()) {
435
+ // Direct selection: /agent architect
436
+ const name = args.trim();
437
+ if (name === "none" || name === "off" || name === "clear") {
438
+ selectedAgent = undefined;
439
+ updateAgentStatus(ctx);
440
+ ctx.ui.notify("Agent cleared — prompts go to default model", "info");
441
+ return;
442
+ }
443
+ const agent = agents.find((a) => a.name === name);
444
+ if (!agent) {
445
+ const available = agents.map((a) => a.name).join(", ") || "none";
446
+ ctx.ui.notify(`Unknown agent "${name}". Available: ${available}`, "warning");
447
+ return;
448
+ }
449
+ selectedAgent = name;
450
+ updateAgentStatus(ctx);
451
+ ctx.ui.notify(`Agent set to "${name}" — your prompts will be handled by this agent`, "info");
452
+ return;
453
+ }
454
+ // Interactive selection
455
+ if (!ctx.hasUI) {
456
+ ctx.ui.notify("Usage: /agent <name> or /agent none", "warning");
457
+ return;
458
+ }
459
+ const options = ["(none — default model)", ...agents.map((a) => `${a.name} — ${a.description}`)];
460
+ const choice = await ctx.ui.select("Select agent for your prompts", options);
461
+ if (choice === undefined)
462
+ return; // cancelled
463
+ if (choice === options[0]) {
464
+ selectedAgent = undefined;
465
+ updateAgentStatus(ctx);
466
+ ctx.ui.notify("Agent cleared", "info");
467
+ }
468
+ else {
469
+ const name = choice.split(" — ")[0];
470
+ selectedAgent = name;
471
+ updateAgentStatus(ctx);
472
+ ctx.ui.notify(`Agent set to "${name}"`, "info");
473
+ }
474
+ },
475
+ getArgumentCompletions: (partial) => {
476
+ const agents = discoverAgents(process.cwd(), "both");
477
+ const names = ["none", ...agents.map((a) => a.name)];
478
+ return names.filter((n) => n.startsWith(partial)).map((n) => ({ value: n, label: n }));
479
+ },
480
+ });
481
+ // Intercept user input when an agent is selected
482
+ pi.on("input", (event) => {
483
+ if (!selectedAgent)
484
+ return { action: "continue" };
485
+ // Don't intercept slash commands
486
+ if (event.text.startsWith("/") || event.text.startsWith("!"))
487
+ return { action: "continue" };
488
+ const wrapped = `Use the subagent tool to delegate to the "${selectedAgent}" agent with this task:\n\n"${event.text}"\n\nSet agentScope to "both".`;
489
+ return { action: "transform", text: wrapped, images: event.images };
490
+ });
491
+ }
492
+ //# sourceMappingURL=subagent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../../src/core/builtins/subagent.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Subagent Tool for Draht — adapted from the pi subagent example\n *\n * Spawns isolated draht processes for delegated tasks.\n * Agents are defined in .draht/agents/*.md (project) or ~/.draht/agent/agents/*.md (global).\n *\n * Modes:\n * single — { agent, task }\n * parallel — { tasks: [{ agent, task }] } (max 8, concurrency 4)\n * chain — { chain: [{ agent, task }] } (sequential, {previous} placeholder)\n */\n\nimport { spawn } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { Message } from \"@draht/ai\";\nimport { StringEnum } from \"@draht/ai\";\nimport { Text } from \"@draht/tui\";\nimport { Type } from \"@sinclair/typebox\";\nimport { getAgentDir, getPackageDir, isBunBinary } from \"../../config.js\";\nimport { parseFrontmatter } from \"../../utils/frontmatter.js\";\nimport type { ExtensionAPI } from \"../extensions/types.js\";\n\nconst MAX_PARALLEL = 8;\nconst MAX_CONCURRENCY = 4;\n\n// Build the command to spawn a subagent process.\n// Compiled Bun binary: process.execPath IS the CLI binary, args go directly.\n// Source/dev mode: process.execPath is the runtime (bun/node), process.argv[1] is the CLI script.\nconst DRAHT_BIN = process.execPath;\nconst DRAHT_ARGS_PREFIX: string[] = isBunBinary ? [] : [process.argv[1]];\n\n// ─── Agent discovery ────────────────────────────────────────────────────────\n\ninterface AgentConfig {\n\tname: string;\n\tdescription: string;\n\ttools?: string[];\n\tmodel?: string;\n\tsystemPrompt: string;\n\tsource: \"user\" | \"project\";\n}\n\nfunction loadAgentsFromDir(dir: string, source: \"user\" | \"project\"): AgentConfig[] {\n\tif (!fs.existsSync(dir)) return [];\n\tlet entries: fs.Dirent[];\n\ttry {\n\t\tentries = fs.readdirSync(dir, { withFileTypes: true });\n\t} catch {\n\t\treturn [];\n\t}\n\tconst agents: AgentConfig[] = [];\n\tfor (const entry of entries) {\n\t\tif (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n\t\ttry {\n\t\t\tconst content = fs.readFileSync(path.join(dir, entry.name), \"utf-8\");\n\t\t\tconst { frontmatter, body } = parseFrontmatter<Record<string, string>>(content);\n\t\t\tif (!frontmatter.name || !frontmatter.description) continue;\n\t\t\tconst tools = frontmatter.tools\n\t\t\t\t?.split(\",\")\n\t\t\t\t.map((t: string) => t.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\tagents.push({\n\t\t\t\tname: frontmatter.name,\n\t\t\t\tdescription: frontmatter.description,\n\t\t\t\ttools: tools?.length ? tools : undefined,\n\t\t\t\tmodel: frontmatter.model,\n\t\t\t\tsystemPrompt: body,\n\t\t\t\tsource,\n\t\t\t});\n\t\t} catch {}\n\t}\n\treturn agents;\n}\n\nfunction findProjectAgentsDir(cwd: string): string | null {\n\tlet dir = cwd;\n\twhile (true) {\n\t\tconst candidate = path.join(dir, \".draht\", \"agents\");\n\t\ttry {\n\t\t\tif (fs.statSync(candidate).isDirectory()) return candidate;\n\t\t} catch {}\n\t\tconst parent = path.dirname(dir);\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n}\n\ntype AgentScope = \"user\" | \"project\" | \"both\";\n\nfunction discoverAgents(cwd: string, scope: AgentScope): AgentConfig[] {\n\t// Shipped agents (bundled with the package) — lowest priority\n\tconst shippedDir = path.join(getPackageDir(), \"agents\");\n\tconst shippedAgents = loadAgentsFromDir(shippedDir, \"user\");\n\n\tconst userDir = path.join(getAgentDir(), \"agents\");\n\tconst projectDir = findProjectAgentsDir(cwd);\n\tconst userAgents = scope !== \"project\" ? loadAgentsFromDir(userDir, \"user\") : [];\n\tconst projectAgents = scope !== \"user\" && projectDir ? loadAgentsFromDir(projectDir, \"project\") : [];\n\n\t// Priority: shipped < user < project\n\tconst map = new Map<string, AgentConfig>();\n\tfor (const a of shippedAgents) map.set(a.name, a);\n\tfor (const a of userAgents) map.set(a.name, a);\n\tfor (const a of projectAgents) map.set(a.name, a);\n\treturn Array.from(map.values());\n}\n\n// ─── Runner ─────────────────────────────────────────────────────────────────\n\ninterface RunResult {\n\tagent: string;\n\ttask: string;\n\texitCode: number;\n\toutput: string;\n\tstderr: string;\n\tstep?: number;\n}\n\nfunction writeTemp(name: string, content: string): { file: string; dir: string } {\n\tconst dir = fs.mkdtempSync(path.join(os.tmpdir(), \"draht-subagent-\"));\n\tconst file = path.join(dir, `${name.replace(/[^\\w.-]/g, \"_\")}.md`);\n\tfs.writeFileSync(file, content, { encoding: \"utf-8\", mode: 0o600 });\n\treturn { file, dir };\n}\n\nfunction cleanTemp(file: string, dir: string) {\n\ttry {\n\t\tfs.unlinkSync(file);\n\t} catch {}\n\ttry {\n\t\tfs.rmdirSync(dir);\n\t} catch {}\n}\n\nfunction getFinalText(messages: Message[]): string {\n\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"assistant\") {\n\t\t\tfor (const part of msg.content) {\n\t\t\t\tif (part.type === \"text\") return part.text;\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\";\n}\n\ntype ProgressFn = (activity: string) => void;\n\nasync function runAgent(\n\tcwd: string,\n\tagent: AgentConfig,\n\ttask: string,\n\tsignal?: AbortSignal,\n\tstep?: number,\n\tonProgress?: ProgressFn,\n): Promise<RunResult> {\n\tconst args: string[] = [\"--mode\", \"json\", \"-p\", \"--no-session\"];\n\tif (agent.model) args.push(\"--model\", agent.model);\n\tif (agent.tools?.length) args.push(\"--tools\", agent.tools.join(\",\"));\n\n\tlet tmpFile: string | null = null;\n\tlet tmpDir: string | null = null;\n\n\tif (agent.systemPrompt.trim()) {\n\t\tconst tmp = writeTemp(agent.name, agent.systemPrompt);\n\t\ttmpFile = tmp.file;\n\t\ttmpDir = tmp.dir;\n\t\targs.push(\"--append-system-prompt\", tmpFile);\n\t}\n\n\targs.push(`Task: ${task}`);\n\n\tconst messages: Message[] = [];\n\tlet stderr = \"\";\n\n\ttry {\n\t\tconst exitCode = await new Promise<number>((resolve) => {\n\t\t\tconst proc = spawn(DRAHT_BIN, [...DRAHT_ARGS_PREFIX, ...args], {\n\t\t\t\tcwd,\n\t\t\t\tshell: false,\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t});\n\t\t\tlet buf = \"\";\n\n\t\t\tconst processLine = (line: string) => {\n\t\t\t\tif (!line.trim()) return;\n\t\t\t\ttry {\n\t\t\t\t\tconst event = JSON.parse(line);\n\t\t\t\t\tif ((event.type === \"message_end\" || event.type === \"tool_result_end\") && event.message) {\n\t\t\t\t\t\tmessages.push(event.message as Message);\n\t\t\t\t\t}\n\t\t\t\t\t// Stream activity updates to the parent\n\t\t\t\t\tif (onProgress) {\n\t\t\t\t\t\tif (event.type === \"tool_execution_start\") {\n\t\t\t\t\t\t\tconst toolArgs = event.args ?? {};\n\t\t\t\t\t\t\tconst detail = toolArgs.command || toolArgs.path || toolArgs.file_path || toolArgs.pattern || \"\";\n\t\t\t\t\t\t\tconst short =\n\t\t\t\t\t\t\t\ttypeof detail === \"string\" && detail.length > 60 ? `${detail.slice(0, 60)}...` : detail;\n\t\t\t\t\t\t\tonProgress(short ? `${event.toolName} ${short}` : event.toolName);\n\t\t\t\t\t\t} else if (event.type === \"text_delta\") {\n\t\t\t\t\t\t\t// Show first line of streaming text as activity\n\t\t\t\t\t\t\tconst text = event.text?.trim();\n\t\t\t\t\t\t\tif (text) {\n\t\t\t\t\t\t\t\tconst firstLine = text.split(\"\\n\")[0];\n\t\t\t\t\t\t\t\tconst short = firstLine.length > 80 ? `${firstLine.slice(0, 80)}...` : firstLine;\n\t\t\t\t\t\t\t\tonProgress(short);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {}\n\t\t\t};\n\n\t\t\tproc.stdout.on(\"data\", (d) => {\n\t\t\t\tbuf += d.toString();\n\t\t\t\tconst lines = buf.split(\"\\n\");\n\t\t\t\tbuf = lines.pop() || \"\";\n\t\t\t\tfor (const l of lines) processLine(l);\n\t\t\t});\n\t\t\tproc.stderr.on(\"data\", (d) => {\n\t\t\t\tstderr += d.toString();\n\t\t\t});\n\t\t\tproc.on(\"close\", (code) => {\n\t\t\t\tif (buf.trim()) processLine(buf);\n\t\t\t\tresolve(code ?? 0);\n\t\t\t});\n\t\t\tproc.on(\"error\", () => resolve(1));\n\n\t\t\tif (signal) {\n\t\t\t\tconst kill = () => {\n\t\t\t\t\tproc.kill(\"SIGTERM\");\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tif (!proc.killed) proc.kill(\"SIGKILL\");\n\t\t\t\t\t}, 5000);\n\t\t\t\t};\n\t\t\t\tif (signal.aborted) kill();\n\t\t\t\telse signal.addEventListener(\"abort\", kill, { once: true });\n\t\t\t}\n\t\t});\n\n\t\treturn { agent: agent.name, task, exitCode, output: getFinalText(messages), stderr, step };\n\t} finally {\n\t\tif (tmpFile && tmpDir) cleanTemp(tmpFile, tmpDir);\n\t}\n}\n\nasync function runParallel<T>(\n\titems: T[],\n\tconcurrency: number,\n\tfn: (item: T, i: number) => Promise<T extends unknown ? RunResult : never>,\n): Promise<RunResult[]> {\n\tconst results: RunResult[] = new Array(items.length);\n\tlet next = 0;\n\tawait Promise.all(\n\t\tArray.from({ length: Math.min(concurrency, items.length) }, async () => {\n\t\t\twhile (true) {\n\t\t\t\tconst i = next++;\n\t\t\t\tif (i >= items.length) return;\n\t\t\t\tresults[i] = await (fn as (item: T, i: number) => Promise<RunResult>)(items[i], i);\n\t\t\t}\n\t\t}),\n\t);\n\treturn results;\n}\n\n// ─── Extension ──────────────────────────────────────────────────────────────\n\nconst TaskItem = Type.Object({\n\tagent: Type.String({ description: \"Agent name\" }),\n\ttask: Type.String({ description: \"Task description\" }),\n});\n\nconst ChainItem = Type.Object({\n\tagent: Type.String({ description: \"Agent name\" }),\n\ttask: Type.String({ description: \"Task, optionally using {previous} placeholder\" }),\n});\n\nconst Params = Type.Object({\n\tagent: Type.Optional(Type.String()),\n\ttask: Type.Optional(Type.String()),\n\ttasks: Type.Optional(Type.Array(TaskItem, { description: \"Parallel tasks\" })),\n\tchain: Type.Optional(Type.Array(ChainItem, { description: \"Chained tasks\" })),\n\tagentScope: Type.Optional(StringEnum([\"user\", \"project\", \"both\"] as const, { default: \"both\" })),\n});\n\n// ─── Rendering helpers ──────────────────────────────────────────────────────\n\nfunction truncateTask(task: string, maxLen = 120): string {\n\tconst oneLine = task.replace(/\\n/g, \" \").trim();\n\treturn oneLine.length > maxLen ? `${oneLine.slice(0, maxLen)}...` : oneLine;\n}\n\nexport default function (pi: ExtensionAPI) {\n\tpi.registerTool({\n\t\tname: \"subagent\",\n\t\tlabel: \"Subagent\",\n\t\tdescription:\n\t\t\t\"Delegate to specialized agents. single: {agent,task} | parallel: {tasks:[]} | chain: {chain:[]} with {previous} placeholder. agentScope: 'both' (default) uses project .draht/agents/ + global.\",\n\t\tparameters: Params,\n\n\t\trenderCall(args, theme) {\n\t\t\tconst lines: string[] = [];\n\n\t\t\tif (args.chain?.length) {\n\t\t\t\tconst agents = args.chain.map((s: { agent: string }) => s.agent).join(\" -> \");\n\t\t\t\tlines.push(`${theme.fg(\"toolTitle\", theme.bold(`subagent chain`))} ${theme.fg(\"accent\", agents)}`);\n\t\t\t\tfor (let i = 0; i < args.chain.length; i++) {\n\t\t\t\t\tconst step = args.chain[i];\n\t\t\t\t\tconst prefix = theme.fg(\"muted\", ` ${i + 1}.`);\n\t\t\t\t\tlines.push(\n\t\t\t\t\t\t`${prefix} ${theme.fg(\"accent\", step.agent)} ${theme.fg(\"toolOutput\", truncateTask(step.task))}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (args.tasks?.length) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(`subagent parallel`)) +\n\t\t\t\t\t\ttheme.fg(\"muted\", ` (${args.tasks.length} tasks)`),\n\t\t\t\t);\n\t\t\t\tfor (const t of args.tasks) {\n\t\t\t\t\tlines.push(` ${theme.fg(\"accent\", t.agent)} ${theme.fg(\"toolOutput\", truncateTask(t.task))}`);\n\t\t\t\t}\n\t\t\t} else if (args.agent) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\"toolTitle\", theme.bold(\"subagent\")) +\n\t\t\t\t\t\t\" \" +\n\t\t\t\t\t\ttheme.fg(\"accent\", args.agent) +\n\t\t\t\t\t\t(args.task ? ` ${theme.fg(\"toolOutput\", truncateTask(args.task))}` : \"\"),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tlines.push(theme.fg(\"toolTitle\", theme.bold(\"subagent\")));\n\t\t\t}\n\n\t\t\treturn new Text(lines.join(\"\\n\"), 0, 0);\n\t\t},\n\n\t\trenderResult(result, options, theme) {\n\t\t\tconst status = (result.details as { status?: string } | undefined)?.status;\n\t\t\tconst output =\n\t\t\t\tresult.content\n\t\t\t\t\t?.filter((c) => c.type === \"text\")\n\t\t\t\t\t.map((c) => (\"text\" in c ? c.text : \"\"))\n\t\t\t\t\t.join(\"\\n\") || \"\";\n\n\t\t\tconst lines: string[] = [];\n\n\t\t\tif (status) {\n\t\t\t\tlines.push(theme.fg(\"muted\", status));\n\t\t\t}\n\n\t\t\tif (output.trim()) {\n\t\t\t\tconst trimmed = output.trim();\n\t\t\t\tif (options.expanded || options.isPartial) {\n\t\t\t\t\t// When expanded or during execution, show full activity log\n\t\t\t\t\tfor (const line of trimmed.split(\"\\n\")) {\n\t\t\t\t\t\tlines.push(theme.fg(\"toolOutput\", line));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Collapsed final result — show preview\n\t\t\t\t\tconst allLines = trimmed.split(\"\\n\");\n\t\t\t\t\tconst previewLines = allLines.slice(0, 8);\n\t\t\t\t\tlines.push(theme.fg(\"toolOutput\", previewLines.join(\"\\n\")));\n\t\t\t\t\tif (allLines.length > 8) {\n\t\t\t\t\t\tlines.push(theme.fg(\"muted\", `... (${allLines.length - 8} more lines)`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (lines.length === 0) return new Text(\"\", 0, 0);\n\t\t\treturn new Text(lines.join(\"\\n\"), 0, 0);\n\t\t},\n\n\t\tasync execute(_id, params, signal, onUpdate, ctx) {\n\t\t\tconst scope: AgentScope = (params.agentScope as AgentScope) ?? \"both\";\n\t\t\tconst agents = discoverAgents(ctx.cwd, scope);\n\t\t\tconst available = agents.map((a) => a.name).join(\", \") || \"none\";\n\n\t\t\tconst find = (name: string) => agents.find((a) => a.name === name);\n\t\t\tconst notFound = (name: string) => ({\n\t\t\t\tcontent: [{ type: \"text\" as const, text: `Unknown agent \"${name}\". Available: ${available}` }],\n\t\t\t\tisError: true,\n\t\t\t\tdetails: {},\n\t\t\t});\n\n\t\t\t// Stream live activity from the subagent process\n\t\t\tconst activityLines: string[] = [];\n\t\t\tconst emitProgress = (agentName: string, activity?: string) => {\n\t\t\t\tconst status = activity ? `${agentName}: ${activity}` : `${agentName} working...`;\n\t\t\t\tonUpdate?.({\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: activityLines.join(\"\\n\") }],\n\t\t\t\t\tdetails: { status },\n\t\t\t\t});\n\t\t\t};\n\t\t\tconst makeProgressFn =\n\t\t\t\t(agentName: string): ProgressFn =>\n\t\t\t\t(activity) => {\n\t\t\t\t\t// Keep a rolling log of recent activities\n\t\t\t\t\tactivityLines.push(`${agentName}: ${activity}`);\n\t\t\t\t\tif (activityLines.length > 50) activityLines.splice(0, activityLines.length - 50);\n\t\t\t\t\temitProgress(agentName, activity);\n\t\t\t\t};\n\n\t\t\t// ── Chain mode ──\n\t\t\tif (params.chain?.length) {\n\t\t\t\tlet previous = \"\";\n\t\t\t\tconst results: RunResult[] = [];\n\t\t\t\tfor (let i = 0; i < params.chain.length; i++) {\n\t\t\t\t\tconst step = params.chain[i];\n\t\t\t\t\tconst agent = find(step.agent);\n\t\t\t\t\tif (!agent) return notFound(step.agent);\n\t\t\t\t\tactivityLines.length = 0;\n\t\t\t\t\temitProgress(step.agent, `step ${i + 1}/${params.chain.length}`);\n\t\t\t\t\tconst task = step.task.replace(/\\{previous\\}/g, previous);\n\t\t\t\t\tconst result = await runAgent(ctx.cwd, agent, task, signal, i + 1, makeProgressFn(step.agent));\n\t\t\t\t\tresults.push(result);\n\t\t\t\t\tif (result.exitCode !== 0) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\t\t\ttext: `Chain failed at step ${i + 1} (${step.agent}):\\n${result.output || result.stderr}`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tprevious = result.output;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: results[results.length - 1].output || \"(no output)\" }],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// ── Parallel mode ──\n\t\t\tif (params.tasks?.length) {\n\t\t\t\tif (params.tasks.length > MAX_PARALLEL) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: `Too many tasks (max ${MAX_PARALLEL})` }],\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tfor (const t of params.tasks) {\n\t\t\t\t\tif (!find(t.agent)) return notFound(t.agent);\n\t\t\t\t}\n\n\t\t\t\tconst agentNames = params.tasks.map((t: { agent: string }) => t.agent).join(\", \");\n\t\t\t\temitProgress(agentNames);\n\n\t\t\t\tconst results = await runParallel(params.tasks, MAX_CONCURRENCY, async (t, _i) => {\n\t\t\t\t\treturn runAgent(ctx.cwd, find(t.agent)!, t.task, signal, undefined, makeProgressFn(t.agent));\n\t\t\t\t});\n\n\t\t\t\tconst ok = results.filter((r) => r.exitCode === 0).length;\n\t\t\t\tconst summary = results\n\t\t\t\t\t.map((r) => `[${r.agent}] ${r.exitCode === 0 ? \"ok\" : \"fail\"} ${r.output.slice(0, 200)}`)\n\t\t\t\t\t.join(\"\\n\\n\");\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: `Parallel: ${ok}/${results.length} succeeded\\n\\n${summary}` }],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// ── Single mode ──\n\t\t\tif (params.agent && params.task) {\n\t\t\t\tconst agent = find(params.agent);\n\t\t\t\tif (!agent) return notFound(params.agent);\n\t\t\t\temitProgress(params.agent);\n\t\t\t\tconst result = await runAgent(ctx.cwd, agent, params.task, signal, undefined, makeProgressFn(params.agent));\n\t\t\t\tconst isError = result.exitCode !== 0;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: result.output || result.stderr || \"(no output)\" }],\n\t\t\t\t\t...(isError ? { isError: true } : {}),\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\" as const, text: `Provide exactly one mode. Available agents: ${available}` }],\n\t\t\t\tisError: true,\n\t\t\t\tdetails: {},\n\t\t\t};\n\t\t},\n\t});\n\n\t// ── Agent selection for user prompts ─────────────────────────────────────\n\n\tlet selectedAgent: string | undefined;\n\n\tfunction updateAgentStatus(ctx: { ui: { setStatus: (key: string, text: string | undefined) => void } }) {\n\t\tctx.ui.setStatus(\"agent\", selectedAgent ? `agent: ${selectedAgent}` : undefined);\n\t}\n\n\t// /agent command — select an agent or clear selection\n\tpi.registerCommand(\"agent\", {\n\t\tdescription: \"Select an agent to handle your next prompts, or clear selection. Usage: /agent [name]\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst agents = discoverAgents(ctx.cwd, \"both\");\n\n\t\t\tif (args.trim()) {\n\t\t\t\t// Direct selection: /agent architect\n\t\t\t\tconst name = args.trim();\n\t\t\t\tif (name === \"none\" || name === \"off\" || name === \"clear\") {\n\t\t\t\t\tselectedAgent = undefined;\n\t\t\t\t\tupdateAgentStatus(ctx);\n\t\t\t\t\tctx.ui.notify(\"Agent cleared — prompts go to default model\", \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst agent = agents.find((a) => a.name === name);\n\t\t\t\tif (!agent) {\n\t\t\t\t\tconst available = agents.map((a) => a.name).join(\", \") || \"none\";\n\t\t\t\t\tctx.ui.notify(`Unknown agent \"${name}\". Available: ${available}`, \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tselectedAgent = name;\n\t\t\t\tupdateAgentStatus(ctx);\n\t\t\t\tctx.ui.notify(`Agent set to \"${name}\" — your prompts will be handled by this agent`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Interactive selection\n\t\t\tif (!ctx.hasUI) {\n\t\t\t\tctx.ui.notify(\"Usage: /agent <name> or /agent none\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst options = [\"(none — default model)\", ...agents.map((a) => `${a.name} — ${a.description}`)];\n\t\t\tconst choice = await ctx.ui.select(\"Select agent for your prompts\", options);\n\t\t\tif (choice === undefined) return; // cancelled\n\n\t\t\tif (choice === options[0]) {\n\t\t\t\tselectedAgent = undefined;\n\t\t\t\tupdateAgentStatus(ctx);\n\t\t\t\tctx.ui.notify(\"Agent cleared\", \"info\");\n\t\t\t} else {\n\t\t\t\tconst name = choice.split(\" — \")[0];\n\t\t\t\tselectedAgent = name;\n\t\t\t\tupdateAgentStatus(ctx);\n\t\t\t\tctx.ui.notify(`Agent set to \"${name}\"`, \"info\");\n\t\t\t}\n\t\t},\n\t\tgetArgumentCompletions: (partial) => {\n\t\t\tconst agents = discoverAgents(process.cwd(), \"both\");\n\t\t\tconst names = [\"none\", ...agents.map((a) => a.name)];\n\t\t\treturn names.filter((n) => n.startsWith(partial)).map((n) => ({ value: n, label: n }));\n\t\t},\n\t});\n\n\t// Intercept user input when an agent is selected\n\tpi.on(\"input\", (event) => {\n\t\tif (!selectedAgent) return { action: \"continue\" as const };\n\t\t// Don't intercept slash commands\n\t\tif (event.text.startsWith(\"/\") || event.text.startsWith(\"!\")) return { action: \"continue\" as const };\n\n\t\tconst wrapped = `Use the subagent tool to delegate to the \"${selectedAgent}\" agent with this task:\\n\\n\"${event.text}\"\\n\\nSet agentScope to \"both\".`;\n\t\treturn { action: \"transform\" as const, text: wrapped, images: event.images };\n\t});\n}\n"]}