@kb-labs/agent-cli 0.5.0

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 (136) hide show
  1. package/README.md +56 -0
  2. package/dist/cli/commands/diff.d.ts +17 -0
  3. package/dist/cli/commands/diff.js +182 -0
  4. package/dist/cli/commands/diff.js.map +1 -0
  5. package/dist/cli/commands/history.d.ts +16 -0
  6. package/dist/cli/commands/history.js +216 -0
  7. package/dist/cli/commands/history.js.map +1 -0
  8. package/dist/cli/commands/quality-report.d.ts +21 -0
  9. package/dist/cli/commands/quality-report.js +457 -0
  10. package/dist/cli/commands/quality-report.js.map +1 -0
  11. package/dist/cli/commands/rollback.d.ts +27 -0
  12. package/dist/cli/commands/rollback.js +109 -0
  13. package/dist/cli/commands/rollback.js.map +1 -0
  14. package/dist/cli/commands/run.d.ts +42 -0
  15. package/dist/cli/commands/run.js +923 -0
  16. package/dist/cli/commands/run.js.map +1 -0
  17. package/dist/cli/commands/trace-context.d.ts +22 -0
  18. package/dist/cli/commands/trace-context.js +131 -0
  19. package/dist/cli/commands/trace-context.js.map +1 -0
  20. package/dist/cli/commands/trace-diagnose.d.ts +20 -0
  21. package/dist/cli/commands/trace-diagnose.js +434 -0
  22. package/dist/cli/commands/trace-diagnose.js.map +1 -0
  23. package/dist/cli/commands/trace-event-normalizer.d.ts +13 -0
  24. package/dist/cli/commands/trace-event-normalizer.js +39 -0
  25. package/dist/cli/commands/trace-event-normalizer.js.map +1 -0
  26. package/dist/cli/commands/trace-filter.d.ts +19 -0
  27. package/dist/cli/commands/trace-filter.js +153 -0
  28. package/dist/cli/commands/trace-filter.js.map +1 -0
  29. package/dist/cli/commands/trace-iteration.d.ts +18 -0
  30. package/dist/cli/commands/trace-iteration.js +192 -0
  31. package/dist/cli/commands/trace-iteration.js.map +1 -0
  32. package/dist/cli/commands/trace-stats.d.ts +17 -0
  33. package/dist/cli/commands/trace-stats.js +247 -0
  34. package/dist/cli/commands/trace-stats.js.map +1 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +473 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/manifest.d.ts +184 -0
  39. package/dist/manifest.js +473 -0
  40. package/dist/manifest.js.map +1 -0
  41. package/dist/rest/handlers/approve-handler.d.ts +15 -0
  42. package/dist/rest/handlers/approve-handler.js +60 -0
  43. package/dist/rest/handlers/approve-handler.js.map +1 -0
  44. package/dist/rest/handlers/approve-session-plan-handler.d.ts +10 -0
  45. package/dist/rest/handlers/approve-session-plan-handler.js +52 -0
  46. package/dist/rest/handlers/approve-session-plan-handler.js.map +1 -0
  47. package/dist/rest/handlers/correct-handler.d.ts +7 -0
  48. package/dist/rest/handlers/correct-handler.js +326 -0
  49. package/dist/rest/handlers/correct-handler.js.map +1 -0
  50. package/dist/rest/handlers/create-session-handler.d.ts +7 -0
  51. package/dist/rest/handlers/create-session-handler.js +25 -0
  52. package/dist/rest/handlers/create-session-handler.js.map +1 -0
  53. package/dist/rest/handlers/execute-session-plan-handler.d.ts +10 -0
  54. package/dist/rest/handlers/execute-session-plan-handler.js +635 -0
  55. package/dist/rest/handlers/execute-session-plan-handler.js.map +1 -0
  56. package/dist/rest/handlers/generate-spec-handler.d.ts +10 -0
  57. package/dist/rest/handlers/generate-spec-handler.js +389 -0
  58. package/dist/rest/handlers/generate-spec-handler.js.map +1 -0
  59. package/dist/rest/handlers/get-file-diff-handler.d.ts +24 -0
  60. package/dist/rest/handlers/get-file-diff-handler.js +44 -0
  61. package/dist/rest/handlers/get-file-diff-handler.js.map +1 -0
  62. package/dist/rest/handlers/get-session-handler.d.ts +10 -0
  63. package/dist/rest/handlers/get-session-handler.js +23 -0
  64. package/dist/rest/handlers/get-session-handler.js.map +1 -0
  65. package/dist/rest/handlers/get-session-plan-handler.d.ts +10 -0
  66. package/dist/rest/handlers/get-session-plan-handler.js +53 -0
  67. package/dist/rest/handlers/get-session-plan-handler.js.map +1 -0
  68. package/dist/rest/handlers/get-session-turns-handler.d.ts +16 -0
  69. package/dist/rest/handlers/get-session-turns-handler.js +35 -0
  70. package/dist/rest/handlers/get-session-turns-handler.js.map +1 -0
  71. package/dist/rest/handlers/get-spec-handler.d.ts +10 -0
  72. package/dist/rest/handlers/get-spec-handler.js +39 -0
  73. package/dist/rest/handlers/get-spec-handler.js.map +1 -0
  74. package/dist/rest/handlers/list-file-changes-handler.d.ts +13 -0
  75. package/dist/rest/handlers/list-file-changes-handler.js +34 -0
  76. package/dist/rest/handlers/list-file-changes-handler.js.map +1 -0
  77. package/dist/rest/handlers/list-sessions-handler.d.ts +7 -0
  78. package/dist/rest/handlers/list-sessions-handler.js +23 -0
  79. package/dist/rest/handlers/list-sessions-handler.js.map +1 -0
  80. package/dist/rest/handlers/rollback-handler.d.ts +22 -0
  81. package/dist/rest/handlers/rollback-handler.js +91 -0
  82. package/dist/rest/handlers/rollback-handler.js.map +1 -0
  83. package/dist/rest/handlers/run-handler.d.ts +7 -0
  84. package/dist/rest/handlers/run-handler.js +516 -0
  85. package/dist/rest/handlers/run-handler.js.map +1 -0
  86. package/dist/rest/handlers/sessions-handler.d.ts +18 -0
  87. package/dist/rest/handlers/sessions-handler.js +56 -0
  88. package/dist/rest/handlers/sessions-handler.js.map +1 -0
  89. package/dist/rest/handlers/status-handler.d.ts +7 -0
  90. package/dist/rest/handlers/status-handler.js +313 -0
  91. package/dist/rest/handlers/status-handler.js.map +1 -0
  92. package/dist/rest/handlers/stop-handler.d.ts +7 -0
  93. package/dist/rest/handlers/stop-handler.js +317 -0
  94. package/dist/rest/handlers/stop-handler.js.map +1 -0
  95. package/dist/widgets/220.js +446 -0
  96. package/dist/widgets/220.js.map +1 -0
  97. package/dist/widgets/331.js +2 -0
  98. package/dist/widgets/331.js.map +1 -0
  99. package/dist/widgets/403.js +2 -0
  100. package/dist/widgets/403.js.map +1 -0
  101. package/dist/widgets/406.js +35 -0
  102. package/dist/widgets/406.js.map +1 -0
  103. package/dist/widgets/455.js +2 -0
  104. package/dist/widgets/455.js.map +1 -0
  105. package/dist/widgets/482.js +2 -0
  106. package/dist/widgets/482.js.map +1 -0
  107. package/dist/widgets/485.js +2 -0
  108. package/dist/widgets/485.js.map +1 -0
  109. package/dist/widgets/527.js +2 -0
  110. package/dist/widgets/527.js.map +1 -0
  111. package/dist/widgets/628.js +2 -0
  112. package/dist/widgets/628.js.map +1 -0
  113. package/dist/widgets/694.js +2 -0
  114. package/dist/widgets/694.js.map +1 -0
  115. package/dist/widgets/712.js +2 -0
  116. package/dist/widgets/712.js.map +1 -0
  117. package/dist/widgets/866.js +2 -0
  118. package/dist/widgets/866.js.map +1 -0
  119. package/dist/widgets/915.js +39 -0
  120. package/dist/widgets/915.js.map +1 -0
  121. package/dist/widgets/957.js +10 -0
  122. package/dist/widgets/957.js.map +1 -0
  123. package/dist/widgets/983.js +2 -0
  124. package/dist/widgets/983.js.map +1 -0
  125. package/dist/widgets/@mf-types.d.ts +3 -0
  126. package/dist/widgets/@mf-types.zip +0 -0
  127. package/dist/widgets/__federation_expose_AgentsPage.js +2 -0
  128. package/dist/widgets/__federation_expose_AgentsPage.js.map +1 -0
  129. package/dist/widgets/mf-manifest.json +260 -0
  130. package/dist/widgets/mf-stats.json +305 -0
  131. package/dist/widgets/remoteEntry.js +7 -0
  132. package/dist/widgets/remoteEntry.js.map +1 -0
  133. package/dist/ws/session-stream-handler.d.ts +8 -0
  134. package/dist/ws/session-stream-handler.js +409 -0
  135. package/dist/ws/session-stream-handler.js.map +1 -0
  136. package/package.json +83 -0
@@ -0,0 +1,923 @@
1
+ import { defineCommand, useCache, useConfig, useAnalytics } from '@kb-labs/sdk';
2
+ import { bootstrapAgentSDK, SessionManager, PlanDocumentService, createSessionMemoryBridge, SpecModeHandler, createCoreToolPack } from '@kb-labs/agent-core';
3
+ import { AgentSDK } from '@kb-labs/agent-sdk';
4
+ import { createDefaultResponseRequirementsSelector } from '@kb-labs/agent-runtime';
5
+ import { IncrementalTraceWriter } from '@kb-labs/agent-tracing';
6
+ import { createToolRegistry } from '@kb-labs/agent-tools';
7
+ import { promises } from 'fs';
8
+
9
+ // src/cli/commands/run.ts
10
+
11
+ // src/cli/ui/event-renderer.ts
12
+ var CSI = "\x1B[";
13
+ var RESET = "\x1B[0m";
14
+ var color = {
15
+ // Status colors
16
+ success: (t) => `${CSI}32m${t}${RESET}`,
17
+ error: (t) => `${CSI}31m${t}${RESET}`,
18
+ warning: (t) => `${CSI}33m${t}${RESET}`,
19
+ info: (t) => `${CSI}36m${t}${RESET}`,
20
+ // UI colors
21
+ dim: (t) => `${CSI}90m${t}${RESET}`,
22
+ bold: (t) => `${CSI}1m${t}${RESET}`,
23
+ accent: (t) => `${CSI}38;5;99m${t}${RESET}`,
24
+ // Purple - orchestrator
25
+ primary: (t) => `${CSI}38;5;39m${t}${RESET}`,
26
+ // Blue - agent
27
+ highlight: (t) => `${CSI}38;5;51m${t}${RESET}`,
28
+ // Cyan - tools
29
+ secondary: (t) => `${CSI}38;5;208m${t}${RESET}`
30
+ // Orange - subtask
31
+ };
32
+ var box = {
33
+ topLeft: "\u250C",
34
+ topRight: "\u2510",
35
+ bottomLeft: "\u2514",
36
+ bottomRight: "\u2518",
37
+ horizontal: "\u2500",
38
+ vertical: "\u2502",
39
+ leftT: "\u251C"};
40
+ var symbols = {
41
+ success: color.success("\u2713"),
42
+ error: color.error("\u2717"),
43
+ thinking: "\u25C6",
44
+ tool: "\u2699",
45
+ memory: "\u{1F4BE}",
46
+ subtask: "\u25C8",
47
+ agent: "\u25CF"
48
+ };
49
+ function formatDuration(ms) {
50
+ if (ms < 1e3) {
51
+ return `${ms}ms`;
52
+ }
53
+ if (ms < 6e4) {
54
+ return `${(ms / 1e3).toFixed(1)}s`;
55
+ }
56
+ return `${Math.floor(ms / 6e4)}m ${Math.floor(ms % 6e4 / 1e3)}s`;
57
+ }
58
+ function formatPath(path, maxLen = 40) {
59
+ if (path.length <= maxLen) {
60
+ return path;
61
+ }
62
+ const parts = path.split("/");
63
+ if (parts.length <= 2) {
64
+ return "..." + path.slice(-maxLen + 3);
65
+ }
66
+ return `.../${parts.slice(-2).join("/")}`;
67
+ }
68
+ function formatBudget(event) {
69
+ const data = event.data;
70
+ const used = typeof data.budgetUsedTokens === "number" ? data.budgetUsedTokens : null;
71
+ const remaining = typeof data.budgetRemainingTokens === "number" ? data.budgetRemainingTokens : null;
72
+ const total = typeof data.budgetTotalTokens === "number" ? data.budgetTotalTokens : null;
73
+ if (used === null && remaining === null && total === null) {
74
+ return null;
75
+ }
76
+ const fmt = (value) => value === null ? "?" : value.toLocaleString("en-US");
77
+ return `Budget ${fmt(used)} used / ${fmt(total)} total (${fmt(remaining)} left)`;
78
+ }
79
+ function renderBoxTop(title, colorFn, width = 60) {
80
+ const titleLen = title.length + 2;
81
+ const leftPad = 2;
82
+ const rightPad = width - leftPad - titleLen - 2;
83
+ return colorFn(
84
+ `${box.topLeft}${box.horizontal.repeat(leftPad)} ${title} ${box.horizontal.repeat(Math.max(0, rightPad))}${box.topRight}`
85
+ );
86
+ }
87
+ function renderBoxBottom(colorFn, width = 60) {
88
+ return colorFn(`${box.bottomLeft}${box.horizontal.repeat(width - 2)}${box.bottomRight}`);
89
+ }
90
+ function renderBoxLine(content, colorFn) {
91
+ return `${colorFn(box.vertical)} ${content}`;
92
+ }
93
+ function createEventRenderer(options) {
94
+ const { verbose = true, showToolOutput = true, showLLMContent = false, showDebug = false } = options;
95
+ const state = {
96
+ currentSubtask: null,
97
+ agentActive: false,
98
+ indentLevel: 0
99
+ };
100
+ return (event) => {
101
+ switch (event.type) {
102
+ // ═══════════════════════════════════════════════════════════════════
103
+ // SUBTASK LEVEL
104
+ // ═══════════════════════════════════════════════════════════════════
105
+ case "subtask:start": {
106
+ state.currentSubtask = {
107
+ id: event.data.subtaskId,
108
+ index: event.data.index,
109
+ total: event.data.total
110
+ };
111
+ state.indentLevel = 1;
112
+ const subtaskNum = `${event.data.index + 1}/${event.data.total}`;
113
+ console.log(color.accent(box.vertical));
114
+ console.log(
115
+ color.accent(`${box.leftT}${box.horizontal}`) + renderBoxTop(`SUBTASK ${subtaskNum}`, color.secondary, 50)
116
+ );
117
+ console.log(
118
+ color.accent(box.vertical) + " " + renderBoxLine(
119
+ `${symbols.subtask} ${event.data.description.slice(0, 45)}${event.data.description.length > 45 ? "..." : ""}`,
120
+ color.secondary
121
+ )
122
+ );
123
+ console.log(color.accent(box.vertical) + " " + color.secondary(box.vertical));
124
+ break;
125
+ }
126
+ case "subtask:end": {
127
+ const status = event.data.success ? color.success(`${symbols.success} Done`) : color.error(`${symbols.error} Failed`);
128
+ console.log(color.accent(box.vertical) + " " + color.secondary(box.vertical));
129
+ console.log(
130
+ color.accent(box.vertical) + " " + renderBoxLine(status, color.secondary)
131
+ );
132
+ console.log(
133
+ color.accent(box.vertical) + " " + renderBoxBottom(color.secondary, 50)
134
+ );
135
+ state.currentSubtask = null;
136
+ state.indentLevel = 0;
137
+ break;
138
+ }
139
+ // ═══════════════════════════════════════════════════════════════════
140
+ // AGENT LEVEL (nested under subtask or standalone)
141
+ // ═══════════════════════════════════════════════════════════════════
142
+ case "agent:start": {
143
+ state.agentActive = true;
144
+ const linePrefix = state.currentSubtask ? color.accent(box.vertical) + " " + color.secondary(box.vertical) + " " : "";
145
+ console.log(linePrefix);
146
+ console.log(linePrefix + renderBoxTop(`AGENT [${event.data.tier}]`, color.primary, 45));
147
+ console.log(linePrefix + renderBoxLine(
148
+ `${symbols.agent} ${event.data.task.slice(0, 40)}${event.data.task.length > 40 ? "..." : ""}`,
149
+ color.primary
150
+ ));
151
+ console.log(linePrefix + renderBoxLine(
152
+ color.dim(`Tools: ${event.data.toolCount} | Max iterations: ${event.data.maxIterations}`),
153
+ color.primary
154
+ ));
155
+ state.indentLevel = state.currentSubtask ? 3 : 1;
156
+ break;
157
+ }
158
+ case "agent:end": {
159
+ const linePrefix = state.currentSubtask ? color.accent(box.vertical) + " " + color.secondary(box.vertical) + " " : "";
160
+ const status = event.data.success ? color.success(`${symbols.success} Success`) : color.error(`${symbols.error} Failed`);
161
+ console.log(linePrefix + color.primary(box.vertical));
162
+ console.log(linePrefix + renderBoxLine(
163
+ `${status} ${color.dim(`(${formatDuration(event.data.durationMs)}, ${event.data.tokensUsed} tokens)`)}`,
164
+ color.primary
165
+ ));
166
+ if (event.data.summary) {
167
+ console.log(linePrefix + color.primary(box.vertical));
168
+ console.log(linePrefix + renderBoxLine(
169
+ color.bold("\u{1F4CB} Result:"),
170
+ color.primary
171
+ ));
172
+ const summaryLines = event.data.summary.split("\n");
173
+ for (const line of summaryLines) {
174
+ if (line.trim()) {
175
+ const words = line.split(" ");
176
+ let currentLine = "";
177
+ for (const word of words) {
178
+ if (currentLine.length + word.length > 75) {
179
+ if (currentLine) {
180
+ console.log(linePrefix + renderBoxLine(` ${currentLine}`, color.primary));
181
+ }
182
+ currentLine = word;
183
+ } else {
184
+ currentLine = currentLine ? `${currentLine} ${word}` : word;
185
+ }
186
+ }
187
+ if (currentLine) {
188
+ console.log(linePrefix + renderBoxLine(` ${currentLine}`, color.primary));
189
+ }
190
+ }
191
+ }
192
+ }
193
+ if (event.data.filesModified.length > 0 || event.data.filesCreated.length > 0) {
194
+ const files = [...event.data.filesCreated, ...event.data.filesModified];
195
+ console.log(linePrefix + renderBoxLine(
196
+ color.dim(`Files: ${files.slice(0, 3).map((f) => formatPath(f, 20)).join(", ")}${files.length > 3 ? ` +${files.length - 3}` : ""}`),
197
+ color.primary
198
+ ));
199
+ }
200
+ console.log(linePrefix + renderBoxBottom(color.primary, 45));
201
+ state.agentActive = false;
202
+ state.indentLevel = state.currentSubtask ? 1 : 0;
203
+ break;
204
+ }
205
+ case "agent:error": {
206
+ const linePrefix = getLinePrefix(state);
207
+ console.log(linePrefix + renderBoxLine(
208
+ `${symbols.error} ${color.error("Error:")} ${event.data.error.slice(0, 50)}`,
209
+ color.primary
210
+ ));
211
+ break;
212
+ }
213
+ // ═══════════════════════════════════════════════════════════════════
214
+ // ITERATION & LLM (inside agent box)
215
+ // ═══════════════════════════════════════════════════════════════════
216
+ case "iteration:start": {
217
+ const linePrefix = getLinePrefix(state);
218
+ if (verbose) {
219
+ console.log(linePrefix + color.primary(box.vertical));
220
+ console.log(linePrefix + renderBoxLine(
221
+ color.dim(`\u2500\u2500\u2500 Iteration ${event.data.iteration}/${event.data.maxIterations} \u2500\u2500\u2500`),
222
+ color.primary
223
+ ));
224
+ }
225
+ break;
226
+ }
227
+ case "llm:start": {
228
+ const linePrefix = getLinePrefix(state);
229
+ if (verbose) {
230
+ const iterLabel = event.data.iteration !== void 0 ? color.dim(` #${event.data.iteration}`) : "";
231
+ const msgLabel = showDebug ? color.dim(` [${event.data.messageCount} msgs, ${event.data.toolCount ?? 0} tools, ${event.data.systemPromptChars ?? 0} sys chars]`) : "";
232
+ process.stdout.write(linePrefix + renderBoxLine(
233
+ `${color.accent(symbols.thinking)} ${color.dim("Thinking...")}${iterLabel}${msgLabel}`,
234
+ color.primary
235
+ ));
236
+ }
237
+ break;
238
+ }
239
+ case "llm:end": {
240
+ if (verbose) {
241
+ process.stdout.write(`\r`);
242
+ const linePrefix = getLinePrefix(state);
243
+ const stopLabel = event.data.stopReason ? `, stop=${event.data.stopReason}` : "";
244
+ console.log(linePrefix + renderBoxLine(
245
+ `${color.accent(symbols.thinking)} Thought ${color.dim(`(${formatDuration(event.data.durationMs)}, ${event.data.tokensUsed} tok${stopLabel})`)}`,
246
+ color.primary
247
+ ));
248
+ if (event.data.content) {
249
+ const maxLen = showDebug ? 2e3 : showLLMContent ? 500 : 150;
250
+ const content = event.data.content.slice(0, maxLen).replace(/\n/g, " ").trim();
251
+ if (content) {
252
+ console.log(linePrefix + renderBoxLine(
253
+ color.dim(` \u{1F4AD} "${content}${event.data.content.length > maxLen ? "..." : ""}"`),
254
+ color.primary
255
+ ));
256
+ }
257
+ }
258
+ }
259
+ break;
260
+ }
261
+ // ═══════════════════════════════════════════════════════════════════
262
+ // TOOL EXECUTION (inside agent, compact format)
263
+ // ═══════════════════════════════════════════════════════════════════
264
+ case "tool:start": {
265
+ const linePrefix = getLinePrefix(state);
266
+ const toolName = event.data.toolName;
267
+ const meta = event.data.metadata;
268
+ let details = "";
269
+ if (showDebug) {
270
+ const inputObj = event.data.input;
271
+ if (inputObj && Object.keys(inputObj).length > 0) {
272
+ const raw = JSON.stringify(inputObj);
273
+ const maxLen = 200;
274
+ details = ` ${color.dim(raw.slice(0, maxLen) + (raw.length > maxLen ? "..." : ""))}`;
275
+ }
276
+ } else if (meta?.filePath) {
277
+ details = ` ${color.dim(formatPath(meta.filePath, 30))}`;
278
+ } else if (meta?.query) {
279
+ details = ` ${color.dim(`"${meta.query.slice(0, 25)}${meta.query.length > 25 ? "..." : ""}"`)}`;
280
+ } else if (meta?.command) {
281
+ details = ` ${color.dim(`$ ${meta.command.slice(0, 25)}`)}`;
282
+ }
283
+ process.stdout.write(linePrefix + renderBoxLine(
284
+ `${color.highlight(symbols.tool)} ${color.highlight(toolName)}${details}`,
285
+ color.primary
286
+ ));
287
+ break;
288
+ }
289
+ case "tool:end": {
290
+ const status = event.data.success ? ` ${symbols.success}` : ` ${symbols.error}`;
291
+ process.stdout.write(`${status} ${color.dim(formatDuration(event.data.durationMs))}
292
+ `);
293
+ if (showToolOutput) {
294
+ const linePrefix = getLinePrefix(state);
295
+ const meta = event.data.metadata;
296
+ const output = event.data.output;
297
+ if (output && verbose) {
298
+ const maxOutputLen = showDebug ? 1e3 : 200;
299
+ if (showDebug) {
300
+ const truncated = output.slice(0, maxOutputLen);
301
+ const lines = truncated.split("\n");
302
+ for (const line of lines) {
303
+ if (line.trim()) {
304
+ console.log(linePrefix + renderBoxLine(
305
+ color.dim(` \u{1F4C4} ${line}`),
306
+ color.primary
307
+ ));
308
+ }
309
+ }
310
+ if (output.length > maxOutputLen) {
311
+ console.log(linePrefix + renderBoxLine(
312
+ color.dim(` \u{1F4C4} ... (${output.length - maxOutputLen} more chars)`),
313
+ color.primary
314
+ ));
315
+ }
316
+ } else {
317
+ const cleanOutput = output.slice(0, maxOutputLen).replace(/\n/g, " ").replace(/\s+/g, " ").trim();
318
+ if (cleanOutput && cleanOutput.length > 10) {
319
+ console.log(linePrefix + renderBoxLine(
320
+ color.dim(` \u{1F4C4} ${cleanOutput}${output.length > maxOutputLen ? "..." : ""}`),
321
+ color.primary
322
+ ));
323
+ }
324
+ }
325
+ }
326
+ if (meta?.summary && !output) {
327
+ console.log(linePrefix + renderBoxLine(
328
+ color.dim(` \u2514\u2500 ${meta.summary.slice(0, 80)}`),
329
+ color.primary
330
+ ));
331
+ }
332
+ }
333
+ break;
334
+ }
335
+ case "tool:error": {
336
+ process.stdout.write(` ${symbols.error}
337
+ `);
338
+ const linePrefix = getLinePrefix(state);
339
+ console.log(linePrefix + renderBoxLine(
340
+ color.error(` \u2514\u2500 ${event.data.error.slice(0, 50)}`),
341
+ color.primary
342
+ ));
343
+ break;
344
+ }
345
+ // ═══════════════════════════════════════════════════════════════════
346
+ // MEMORY & PROGRESS (compact notifications)
347
+ // ═══════════════════════════════════════════════════════════════════
348
+ case "memory:write": {
349
+ if (verbose) {
350
+ const linePrefix = getLinePrefix(state);
351
+ console.log(linePrefix + renderBoxLine(
352
+ color.dim(`${symbols.memory} Saved ${event.data.entryType} to ${event.data.target}`),
353
+ color.primary
354
+ ));
355
+ }
356
+ break;
357
+ }
358
+ case "progress:update": {
359
+ const budgetLine = formatBudget(event);
360
+ const phase = event.data.phase || "progress";
361
+ const progress = Math.max(0, Math.min(100, Math.round(event.data.progress || 0)));
362
+ const message = event.data.message || "";
363
+ if (verbose) {
364
+ const linePrefix = getLinePrefix(state);
365
+ const main = `[${phase}] ${progress}%${message ? ` - ${message}` : ""}`;
366
+ console.log(linePrefix + renderBoxLine(color.info(main), color.primary));
367
+ if (budgetLine) {
368
+ console.log(linePrefix + renderBoxLine(color.dim(` ${budgetLine}`), color.primary));
369
+ }
370
+ } else if (message && (phase === "plan" || phase === "spec") && (progress === 100 || progress === 5)) {
371
+ const budgetSuffix = budgetLine ? ` | ${budgetLine}` : "";
372
+ console.log(`${color.info(`[${phase}]`)} ${message}${budgetSuffix}`);
373
+ }
374
+ break;
375
+ }
376
+ case "status:change": {
377
+ const budgetLine = formatBudget(event);
378
+ if (verbose && event.data.message) {
379
+ const linePrefix = getLinePrefix(state);
380
+ console.log(linePrefix + renderBoxLine(
381
+ color.info(`Status: ${event.data.status}${event.data.message ? ` - ${event.data.message}` : ""}`),
382
+ color.primary
383
+ ));
384
+ if (budgetLine) {
385
+ console.log(linePrefix + renderBoxLine(color.dim(` ${budgetLine}`), color.primary));
386
+ }
387
+ if (event.data.status === "waiting" && event.sessionId) {
388
+ const sid = event.sessionId;
389
+ console.log(linePrefix + renderBoxLine(color.dim(` To approve: kb agent run --session-id=${sid} --approve`), color.primary));
390
+ console.log(linePrefix + renderBoxLine(color.dim(` To execute: kb agent run --session-id=${sid}`), color.primary));
391
+ }
392
+ }
393
+ if (!verbose && (event.data.status === "done" || event.data.status === "error")) {
394
+ const budgetSuffix = budgetLine ? ` (${budgetLine})` : "";
395
+ console.log(
396
+ event.data.status === "done" ? `${symbols.success} ${event.data.message}${budgetSuffix}` : `${symbols.error} ${event.data.message}${budgetSuffix}`
397
+ );
398
+ }
399
+ break;
400
+ }
401
+ case "middleware:decision": {
402
+ if (verbose) {
403
+ const linePrefix = getLinePrefix(state);
404
+ const decisionIcons = {
405
+ soft_warning: "\u26A0",
406
+ hard_stop: "\u{1F6D1}",
407
+ trimmed: "\u2702",
408
+ loop_detected: "\u{1F501}",
409
+ stuck: "\u23F8",
410
+ summarized: "\u{1F4DD}"
411
+ };
412
+ const icon = decisionIcons[event.data.decision] ?? "\xB7";
413
+ console.log(linePrefix + renderBoxLine(
414
+ color.dim(` ${icon} [${event.data.middleware}] ${event.data.decision}`),
415
+ color.primary
416
+ ));
417
+ }
418
+ break;
419
+ }
420
+ case "llm:debug": {
421
+ if (!showDebug) {
422
+ break;
423
+ }
424
+ const linePrefix = getLinePrefix(state);
425
+ const iterLabel = event.data.iteration !== void 0 ? ` (iter #${event.data.iteration})` : "";
426
+ console.log(linePrefix + renderBoxLine(
427
+ color.dim(` \u2500\u2500\u2500 System Prompt${iterLabel} \u2500\u2500\u2500`),
428
+ color.primary
429
+ ));
430
+ for (const line of event.data.systemPrompt.split("\n")) {
431
+ console.log(linePrefix + renderBoxLine(color.dim(` ${line}`), color.primary));
432
+ }
433
+ console.log(linePrefix + renderBoxLine(color.dim(" \u2500\u2500\u2500 Messages \u2500\u2500\u2500"), color.primary));
434
+ for (const m of event.data.messages) {
435
+ const roleLabel = `[${m.role}]`;
436
+ const content = m.content;
437
+ const lines = content.split("\n");
438
+ const firstLine = `${roleLabel} ${lines[0] ?? ""}`;
439
+ console.log(linePrefix + renderBoxLine(color.dim(` ${firstLine}`), color.primary));
440
+ for (const line of lines.slice(1)) {
441
+ console.log(linePrefix + renderBoxLine(color.dim(` ${line}`), color.primary));
442
+ }
443
+ }
444
+ console.log(linePrefix + renderBoxLine(color.dim(" \u2500\u2500\u2500 End Prompt \u2500\u2500\u2500"), color.primary));
445
+ break;
446
+ }
447
+ }
448
+ };
449
+ function getLinePrefix(state2) {
450
+ if (state2.currentSubtask && state2.agentActive) {
451
+ return color.accent(box.vertical) + " " + color.secondary(box.vertical) + " ";
452
+ }
453
+ if (state2.currentSubtask) {
454
+ return color.accent(box.vertical) + " " + color.secondary(box.vertical) + " ";
455
+ }
456
+ if (state2.agentActive) {
457
+ return "";
458
+ }
459
+ return "";
460
+ }
461
+ }
462
+ function createMinimalRenderer() {
463
+ return createEventRenderer({
464
+ verbose: false,
465
+ showToolOutput: false,
466
+ showLLMContent: false
467
+ });
468
+ }
469
+ function createDetailedRenderer() {
470
+ return createEventRenderer({
471
+ verbose: true,
472
+ showToolOutput: true,
473
+ showLLMContent: true
474
+ });
475
+ }
476
+ function createDebugRenderer() {
477
+ return createEventRenderer({
478
+ verbose: true,
479
+ showToolOutput: true,
480
+ showLLMContent: true,
481
+ showDebug: true
482
+ });
483
+ }
484
+
485
+ // src/cli/commands/run.ts
486
+ bootstrapAgentSDK();
487
+ function parseBooleanFlag(value, defaultValue) {
488
+ if (typeof value === "boolean") {
489
+ return value;
490
+ }
491
+ if (typeof value === "string") {
492
+ const normalized = value.trim().toLowerCase();
493
+ if (["true", "1", "yes", "y", "on"].includes(normalized)) {
494
+ return true;
495
+ }
496
+ if (["false", "0", "no", "n", "off"].includes(normalized)) {
497
+ return false;
498
+ }
499
+ }
500
+ if (typeof value === "number") {
501
+ return value !== 0;
502
+ }
503
+ return defaultValue;
504
+ }
505
+ var run_default = defineCommand({
506
+ id: "agent:run",
507
+ description: "Execute a task with autonomous agent (orchestrator + child agents)",
508
+ handler: {
509
+ async execute(ctx, input) {
510
+ const flags = input.flags ?? input;
511
+ const {
512
+ task,
513
+ workingDir = ctx.cwd || process.cwd(),
514
+ maxIterations = 200,
515
+ temperature = 0.1,
516
+ verbose: verboseRaw = true,
517
+ quiet: quietRaw = false,
518
+ detailed: detailedRaw = false,
519
+ sessionId,
520
+ tier = "medium",
521
+ mode = "execute",
522
+ complexity,
523
+ files,
524
+ trace,
525
+ approve: approveRaw = false,
526
+ execute: executeRaw = false,
527
+ spec: specRaw = false,
528
+ "dry-run": dryRunRaw = false,
529
+ debug: debugRaw = false,
530
+ timeout: timeoutSeconds,
531
+ budget: budgetOverride,
532
+ json: jsonOutput = false
533
+ } = flags;
534
+ const verbose = parseBooleanFlag(verboseRaw, true);
535
+ const quiet = parseBooleanFlag(quietRaw, false);
536
+ const detailed = parseBooleanFlag(detailedRaw, false);
537
+ const approve = parseBooleanFlag(approveRaw, false);
538
+ const executeAfterPlan = parseBooleanFlag(executeRaw, false);
539
+ const spec = parseBooleanFlag(specRaw, false);
540
+ const dryRun = parseBooleanFlag(dryRunRaw, false);
541
+ const debug = parseBooleanFlag(debugRaw, false);
542
+ const timeoutSecs = typeof timeoutSeconds === "number" && timeoutSeconds > 0 ? timeoutSeconds : void 0;
543
+ const abortController = timeoutSecs !== void 0 ? new AbortController() : void 0;
544
+ let timeoutHandle;
545
+ if (abortController && timeoutSecs !== void 0) {
546
+ timeoutHandle = setTimeout(() => {
547
+ abortController.abort(
548
+ new Error(`Agent execution timed out after ${timeoutSecs}s (--timeout=${timeoutSecs})`)
549
+ );
550
+ }, timeoutSecs * 1e3);
551
+ timeoutHandle.unref?.();
552
+ }
553
+ const clearTimeout_ = () => {
554
+ if (timeoutHandle !== void 0) {
555
+ clearTimeout(timeoutHandle);
556
+ timeoutHandle = void 0;
557
+ }
558
+ };
559
+ if (!task) {
560
+ if (approve && sessionId) {
561
+ const sessionManager = new SessionManager(workingDir || ctx.cwd || process.cwd());
562
+ const planPath = sessionManager.getSessionPlanPath(sessionId);
563
+ try {
564
+ const raw = await promises.readFile(planPath, "utf-8");
565
+ const plan = JSON.parse(raw);
566
+ if (plan.status !== "draft") {
567
+ ctx.ui?.warn?.(`Plan is not in draft state (current: ${plan.status}). Nothing to approve.`);
568
+ clearTimeout_();
569
+ return { exitCode: 1 };
570
+ }
571
+ const approvedAt = (/* @__PURE__ */ new Date()).toISOString();
572
+ const approvedPlan = { ...plan, status: "approved", approvedAt, approvalComment: "Approved via CLI --approve", updatedAt: approvedAt };
573
+ await promises.writeFile(planPath, JSON.stringify(approvedPlan, null, 2), "utf-8");
574
+ const planDocumentService = new PlanDocumentService(workingDir || ctx.cwd || process.cwd());
575
+ const planDocPath = planDocumentService.getPlanPath(plan);
576
+ await planDocumentService.appendExecutionLog(planDocPath, `- ${approvedAt}: Plan approved via CLI (--approve).`).catch(() => {
577
+ });
578
+ ctx.ui?.success?.(`Plan approved: ${approvedPlan.id} (session: ${sessionId})`);
579
+ ctx.ui?.info?.(`Ready to execute: kb agent run --session-id=${sessionId}`);
580
+ clearTimeout_();
581
+ return { exitCode: 0, sessionId };
582
+ } catch {
583
+ ctx.ui?.error?.(`No plan found for session: ${sessionId}`);
584
+ clearTimeout_();
585
+ return { exitCode: 1 };
586
+ }
587
+ }
588
+ ctx.ui?.error?.("Error: --task is required");
589
+ clearTimeout_();
590
+ return { exitCode: 1 };
591
+ }
592
+ let modeConfig;
593
+ if (mode !== "execute") {
594
+ modeConfig = { mode };
595
+ if (mode === "plan") {
596
+ modeConfig.context = { mode: "plan", task, complexity };
597
+ } else if (mode === "edit") {
598
+ modeConfig.context = { mode: "edit", task, targetFiles: files || [], dryRun };
599
+ } else if (mode === "debug") {
600
+ modeConfig.context = { mode: "debug", task, traceFile: trace, relevantFiles: files || [] };
601
+ }
602
+ }
603
+ let eventRenderer;
604
+ if (jsonOutput) {
605
+ eventRenderer = () => {
606
+ };
607
+ } else if (quiet) {
608
+ eventRenderer = createMinimalRenderer();
609
+ } else if (debug) {
610
+ eventRenderer = createDebugRenderer();
611
+ } else if (detailed) {
612
+ eventRenderer = createDetailedRenderer();
613
+ } else {
614
+ eventRenderer = createEventRenderer({
615
+ verbose,
616
+ showToolOutput: true,
617
+ showLLMContent: false
618
+ });
619
+ }
620
+ try {
621
+ const runId = `run-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
622
+ const sessionManager = new SessionManager(workingDir);
623
+ let effectiveSessionId = sessionId;
624
+ if (!effectiveSessionId) {
625
+ const createdSession = await sessionManager.createSession({
626
+ mode,
627
+ task,
628
+ agentId: "cli-agent"
629
+ });
630
+ effectiveSessionId = createdSession.id;
631
+ } else {
632
+ const existing = await sessionManager.loadSession(effectiveSessionId);
633
+ if (!existing) {
634
+ const createdSession = await sessionManager.createSession({
635
+ mode,
636
+ task,
637
+ agentId: "cli-agent",
638
+ sessionId: effectiveSessionId
639
+ });
640
+ effectiveSessionId = createdSession.id;
641
+ }
642
+ }
643
+ await sessionManager.createUserTurn(effectiveSessionId, task, runId);
644
+ const filesRead = /* @__PURE__ */ new Set();
645
+ const filesReadHash = /* @__PURE__ */ new Map();
646
+ const sessionMemory = createSessionMemoryBridge(workingDir, effectiveSessionId);
647
+ const responseRequirementsSelector = createDefaultResponseRequirementsSelector();
648
+ const toolRegistry = createToolRegistry({
649
+ workingDir,
650
+ currentTask: task,
651
+ sessionId: effectiveSessionId,
652
+ verbose: false,
653
+ // Disable tool registry verbose - we have event renderer
654
+ cache: useCache(),
655
+ filesRead,
656
+ filesReadHash,
657
+ sessionMemory,
658
+ responseRequirementsResolver: async ({ task: activeTask, kernel }) => responseRequirementsSelector.select({
659
+ state: kernel,
660
+ messages: [],
661
+ task: activeTask ?? task
662
+ })
663
+ });
664
+ const agentsConfig = await useConfig();
665
+ const effectiveBudget = typeof budgetOverride === "number" && budgetOverride > 0 ? { ...agentsConfig?.tokenBudget ?? {}, enabled: true, maxTokens: budgetOverride } : agentsConfig?.tokenBudget;
666
+ const analytics = useAnalytics() ?? null;
667
+ const taskId = `task-${Date.now()}`;
668
+ const tracer = new IncrementalTraceWriter(taskId);
669
+ if (spec && effectiveSessionId && sessionId) {
670
+ const planPath = sessionManager.getSessionPlanPath(effectiveSessionId);
671
+ try {
672
+ const planData = JSON.parse(await promises.readFile(planPath, "utf-8"));
673
+ if (planData.status === "approved" || planData.status === "spec_ready") {
674
+ ctx.ui?.info?.(`Found approved plan: ${planData.id} (${planData.phases.length} phases). Generating spec directly...`);
675
+ let pendingSessionWrite2 = Promise.resolve();
676
+ const specEventCallback = (event) => {
677
+ tracer.trace(event);
678
+ eventRenderer(event);
679
+ pendingSessionWrite2 = pendingSessionWrite2.then(async () => {
680
+ await sessionManager.addEvent(effectiveSessionId, {
681
+ ...event,
682
+ sessionId: effectiveSessionId,
683
+ runId,
684
+ metadata: {
685
+ ...event["metadata"],
686
+ sessionId: effectiveSessionId,
687
+ runId,
688
+ workingDir
689
+ }
690
+ });
691
+ }).catch((error) => {
692
+ const message = error instanceof Error ? error.message : String(error);
693
+ console.warn(`[agent:run] Failed to persist spec event: ${message}`);
694
+ });
695
+ };
696
+ const specConfig = {
697
+ workingDir,
698
+ maxIterations: 40,
699
+ temperature: 0.1,
700
+ sessionId: effectiveSessionId,
701
+ tier,
702
+ analytics,
703
+ tokenBudget: effectiveBudget,
704
+ onEvent: specEventCallback,
705
+ abortSignal: abortController?.signal
706
+ };
707
+ const specHandler = new SpecModeHandler();
708
+ const specResult = await specHandler.execute(planData, specConfig, toolRegistry);
709
+ await pendingSessionWrite2;
710
+ await tracer.finalize();
711
+ const detailedTrace2 = tracer.getEntries();
712
+ if (detailedTrace2.length > 0) {
713
+ await sessionManager.storeTraceArtifacts(effectiveSessionId, runId, detailedTrace2);
714
+ }
715
+ if (specResult.success) {
716
+ ctx.ui?.success?.(`Spec generated: ${specResult.spec?.id} (${specResult.spec?.sections.length || 0} sections, ${specResult.spec?.sections.reduce((s, sec) => s + sec.changes.length, 0) || 0} changes)`);
717
+ } else {
718
+ ctx.ui?.warn?.(`Spec generation failed: ${specResult.summary}`);
719
+ }
720
+ const specSucceeded = specResult.success;
721
+ clearTimeout_();
722
+ return {
723
+ exitCode: specSucceeded ? 0 : 1,
724
+ sessionId: effectiveSessionId,
725
+ result: {
726
+ success: specSucceeded,
727
+ summary: specResult.summary,
728
+ filesCreated: specResult.filesCreated,
729
+ filesModified: specResult.filesModified,
730
+ filesRead: specResult.filesRead,
731
+ iterations: specResult.iterations,
732
+ tokensUsed: specResult.tokensUsed
733
+ }
734
+ };
735
+ }
736
+ } catch {
737
+ }
738
+ }
739
+ let pendingSessionWrite = Promise.resolve();
740
+ let persistedEventCount = 0;
741
+ const compositeEventCallback = (event) => {
742
+ tracer.trace(event);
743
+ eventRenderer(event);
744
+ pendingSessionWrite = pendingSessionWrite.then(async () => {
745
+ await sessionManager.addEvent(effectiveSessionId, {
746
+ ...event,
747
+ sessionId: effectiveSessionId,
748
+ runId
749
+ });
750
+ persistedEventCount += 1;
751
+ }).catch((error) => {
752
+ const message = error instanceof Error ? error.message : String(error);
753
+ console.warn(`[agent:run] Failed to persist event: ${message}`);
754
+ });
755
+ };
756
+ const config = {
757
+ workingDir,
758
+ maxIterations,
759
+ temperature,
760
+ sessionId: effectiveSessionId,
761
+ tier,
762
+ analytics,
763
+ tokenBudget: agentsConfig?.tokenBudget,
764
+ mode: modeConfig,
765
+ onEvent: compositeEventCallback,
766
+ debug,
767
+ abortSignal: abortController?.signal
768
+ };
769
+ if (timeoutSecs !== void 0 && !quiet) {
770
+ ctx.ui?.info?.(`\u23F1 Timeout active: agent will abort after ${timeoutSecs}s (--timeout=${timeoutSecs})`);
771
+ }
772
+ const sdk = new AgentSDK();
773
+ sdk.register(createCoreToolPack(toolRegistry));
774
+ const runner = sdk.createRunner(config);
775
+ let result = await runner.execute(task);
776
+ clearTimeout_();
777
+ await pendingSessionWrite;
778
+ if (persistedEventCount === 0 && result.summary?.trim()) {
779
+ const now = (/* @__PURE__ */ new Date()).toISOString();
780
+ const agentId = `agent-${runId}`;
781
+ const baseMetadata = { sessionId: effectiveSessionId, runId, workingDir };
782
+ await sessionManager.addEvent(effectiveSessionId, {
783
+ type: "agent:start",
784
+ timestamp: now,
785
+ sessionId: effectiveSessionId,
786
+ agentId,
787
+ runId,
788
+ data: { task, tier, maxIterations, toolCount: 0 },
789
+ metadata: baseMetadata
790
+ });
791
+ await sessionManager.addEvent(effectiveSessionId, {
792
+ type: "llm:end",
793
+ timestamp: now,
794
+ sessionId: effectiveSessionId,
795
+ agentId,
796
+ runId,
797
+ data: {
798
+ content: result.summary,
799
+ hasToolCalls: false,
800
+ tokensUsed: 0,
801
+ durationMs: 0,
802
+ stopReason: "no_tool_calls"
803
+ },
804
+ metadata: baseMetadata
805
+ });
806
+ await sessionManager.addEvent(effectiveSessionId, {
807
+ type: "agent:end",
808
+ timestamp: now,
809
+ sessionId: effectiveSessionId,
810
+ agentId,
811
+ runId,
812
+ data: {
813
+ success: result.success,
814
+ summary: result.summary,
815
+ iterations: result.iterations,
816
+ tokensUsed: result.tokensUsed,
817
+ durationMs: 0,
818
+ filesCreated: result.filesCreated,
819
+ filesModified: result.filesModified,
820
+ stopReason: result.success ? "report_complete" : "unknown"
821
+ },
822
+ metadata: baseMetadata
823
+ });
824
+ }
825
+ const detailedTrace = tracer.getEntries();
826
+ if (detailedTrace.length > 0) {
827
+ await sessionManager.storeTraceArtifacts(effectiveSessionId, runId, detailedTrace);
828
+ }
829
+ if (result.fileChanges && result.fileChanges.length > 0) {
830
+ await sessionManager.attachFileChangesToTurn(effectiveSessionId, runId, result.fileChanges);
831
+ }
832
+ if (approve) {
833
+ if (mode !== "plan") {
834
+ ctx.ui?.warn?.("--approve is currently supported only with --mode=plan");
835
+ } else if (!result.plan) {
836
+ ctx.ui?.warn?.("No plan produced by plan mode, nothing to approve");
837
+ } else {
838
+ const approvedAt = (/* @__PURE__ */ new Date()).toISOString();
839
+ const approvedPlan = {
840
+ ...result.plan,
841
+ status: "approved",
842
+ approvedAt,
843
+ approvalComment: "Approved via CLI --approve",
844
+ updatedAt: approvedAt
845
+ };
846
+ const sessionPlanPath = sessionManager.getSessionPlanPath(effectiveSessionId);
847
+ await promises.writeFile(sessionPlanPath, JSON.stringify(approvedPlan, null, 2), "utf-8");
848
+ const planDocumentService = new PlanDocumentService(workingDir);
849
+ const planDocPath = planDocumentService.getPlanPath(result.plan);
850
+ await planDocumentService.appendExecutionLog(
851
+ planDocPath,
852
+ `- ${approvedAt}: Plan approved via CLI (--approve).`
853
+ );
854
+ ctx.ui?.success?.(`Plan approved: ${approvedPlan.id}`);
855
+ if (executeAfterPlan) {
856
+ ctx.ui?.info?.("Executing approved plan...");
857
+ const executeConfig = {
858
+ ...config,
859
+ mode: { mode: "execute" }
860
+ };
861
+ const executeSdk = new AgentSDK();
862
+ executeSdk.register(createCoreToolPack(toolRegistry));
863
+ const executeRunner = executeSdk.createRunner(executeConfig);
864
+ result = await executeRunner.execute(task);
865
+ } else {
866
+ ctx.ui?.info?.(`Execute: kb agent run --session-id=${effectiveSessionId}`);
867
+ }
868
+ if (spec && approvedPlan) {
869
+ ctx.ui?.info?.("Generating detailed specification from approved plan...");
870
+ const specHandler = new SpecModeHandler();
871
+ const specResult = await specHandler.execute(approvedPlan, config, toolRegistry);
872
+ if (specResult.success) {
873
+ ctx.ui?.success?.(`Spec generated: ${specResult.spec?.id} (${specResult.spec?.sections.length || 0} sections)`);
874
+ } else {
875
+ ctx.ui?.warn?.(`Spec generation failed: ${specResult.summary}`);
876
+ }
877
+ }
878
+ }
879
+ }
880
+ await tracer.finalize();
881
+ const runSucceeded = result.success;
882
+ const structuredResult = {
883
+ exitCode: runSucceeded ? 0 : 1,
884
+ sessionId: effectiveSessionId,
885
+ summary: result.summary,
886
+ data: {
887
+ sessionId: effectiveSessionId,
888
+ success: runSucceeded,
889
+ summary: result.summary,
890
+ filesCreated: result.filesCreated,
891
+ filesModified: result.filesModified,
892
+ filesRead: result.filesRead,
893
+ iterations: result.iterations,
894
+ tokensUsed: result.tokensUsed,
895
+ hasPlan: mode === "plan" && !!result.plan
896
+ }
897
+ };
898
+ if (jsonOutput) {
899
+ ctx.ui?.json?.(structuredResult);
900
+ }
901
+ return structuredResult;
902
+ } catch (error) {
903
+ clearTimeout_();
904
+ if (abortController?.signal.aborted) {
905
+ const reason = abortController.signal.reason instanceof Error ? abortController.signal.reason.message : `Agent execution timed out after ${timeoutSecs}s`;
906
+ console.error(`
907
+ \u23F1 ${reason}
908
+ `);
909
+ return { exitCode: 124 };
910
+ }
911
+ const errorMessage = error instanceof Error ? error.message : String(error);
912
+ console.error(`
913
+ \u274C Agent execution failed: ${errorMessage}
914
+ `);
915
+ return { exitCode: 1 };
916
+ }
917
+ }
918
+ }
919
+ });
920
+
921
+ export { run_default as default };
922
+ //# sourceMappingURL=run.js.map
923
+ //# sourceMappingURL=run.js.map