agentic-forge 0.0.0 → 0.7.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 (209) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +31 -21
  3. package/dist/checkpoints/manager.d.ts +5 -0
  4. package/dist/checkpoints/manager.js +87 -0
  5. package/dist/checkpoints/manager.js.map +1 -0
  6. package/{src → dist}/claude/.claude/skills/analyze/SKILL.md +1 -1
  7. package/{src → dist}/claude/.claude/skills/create-checkpoint/SKILL.md +1 -1
  8. package/{src → dist}/claude/.claude/skills/create-log/SKILL.md +1 -1
  9. package/{src → dist}/claude/.claude/skills/fix-analyze/SKILL.md +1 -1
  10. package/{src → dist}/claude/.claude/skills/git-branch/SKILL.md +1 -1
  11. package/{src → dist}/claude/.claude/skills/git-commit/SKILL.md +1 -1
  12. package/{src → dist}/claude/.claude/skills/git-pr/SKILL.md +1 -1
  13. package/{src → dist}/claude/.claude/skills/sdlc-plan/SKILL.md +1 -1
  14. package/{src → dist}/claude/.claude/skills/sdlc-review/SKILL.md +1 -1
  15. package/{src → dist}/claude/.claude/skills/workflow-builder/SKILL.md +1 -1
  16. package/dist/cli.d.ts +3 -0
  17. package/dist/cli.js +155 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/commands/config-cmd.d.ts +2 -0
  20. package/dist/commands/config-cmd.js +30 -0
  21. package/dist/commands/config-cmd.js.map +1 -0
  22. package/{src/commands/index.ts → dist/commands/index.d.ts} +1 -10
  23. package/dist/commands/index.js +13 -0
  24. package/dist/commands/index.js.map +1 -0
  25. package/dist/commands/init.d.ts +6 -0
  26. package/dist/commands/init.js +83 -0
  27. package/dist/commands/init.js.map +1 -0
  28. package/dist/commands/release-notes.d.ts +5 -0
  29. package/dist/commands/release-notes.js +68 -0
  30. package/dist/commands/release-notes.js.map +1 -0
  31. package/dist/commands/resume.d.ts +5 -0
  32. package/dist/commands/resume.js +79 -0
  33. package/dist/commands/resume.js.map +1 -0
  34. package/dist/commands/run.d.ts +14 -0
  35. package/dist/commands/run.js +193 -0
  36. package/dist/commands/run.js.map +1 -0
  37. package/dist/commands/shortcuts.d.ts +2 -0
  38. package/dist/commands/shortcuts.js +11 -0
  39. package/dist/commands/shortcuts.js.map +1 -0
  40. package/dist/commands/skills-dir.d.ts +2 -0
  41. package/dist/commands/skills-dir.js +9 -0
  42. package/dist/commands/skills-dir.js.map +1 -0
  43. package/dist/commands/status.d.ts +4 -0
  44. package/dist/commands/status.js +99 -0
  45. package/dist/commands/status.js.map +1 -0
  46. package/dist/commands/update.d.ts +4 -0
  47. package/dist/commands/update.js +65 -0
  48. package/dist/commands/update.js.map +1 -0
  49. package/dist/commands/version.d.ts +3 -0
  50. package/dist/commands/version.js +26 -0
  51. package/dist/commands/version.js.map +1 -0
  52. package/dist/commands/workflows.d.ts +4 -0
  53. package/dist/commands/workflows.js +109 -0
  54. package/dist/commands/workflows.js.map +1 -0
  55. package/dist/config.d.ts +8 -0
  56. package/dist/config.js +110 -0
  57. package/dist/config.js.map +1 -0
  58. package/dist/console.d.ts +103 -0
  59. package/dist/console.js +670 -0
  60. package/dist/console.js.map +1 -0
  61. package/dist/executor.d.ts +27 -0
  62. package/dist/executor.js +236 -0
  63. package/dist/executor.js.map +1 -0
  64. package/dist/git/worktree.d.ts +23 -0
  65. package/dist/git/worktree.js +170 -0
  66. package/dist/git/worktree.js.map +1 -0
  67. package/dist/logging/logger.d.ts +27 -0
  68. package/dist/logging/logger.js +69 -0
  69. package/dist/logging/logger.js.map +1 -0
  70. package/dist/orchestrator.d.ts +44 -0
  71. package/dist/orchestrator.js +587 -0
  72. package/dist/orchestrator.js.map +1 -0
  73. package/dist/parser.d.ts +17 -0
  74. package/dist/parser.js +184 -0
  75. package/dist/parser.js.map +1 -0
  76. package/dist/progress.d.ts +29 -0
  77. package/dist/progress.js +275 -0
  78. package/dist/progress.js.map +1 -0
  79. package/dist/ralph-loop.d.ts +26 -0
  80. package/dist/ralph-loop.js +194 -0
  81. package/dist/ralph-loop.js.map +1 -0
  82. package/dist/renderer.d.ts +15 -0
  83. package/dist/renderer.js +123 -0
  84. package/dist/renderer.js.map +1 -0
  85. package/dist/runner.d.ts +84 -0
  86. package/dist/runner.js +529 -0
  87. package/dist/runner.js.map +1 -0
  88. package/dist/signal-manager.d.ts +16 -0
  89. package/dist/signal-manager.js +50 -0
  90. package/dist/signal-manager.js.map +1 -0
  91. package/dist/steps/base.d.ts +28 -0
  92. package/dist/steps/base.js +23 -0
  93. package/dist/steps/base.js.map +1 -0
  94. package/dist/steps/conditional-step.d.ts +12 -0
  95. package/dist/steps/conditional-step.js +106 -0
  96. package/dist/steps/conditional-step.js.map +1 -0
  97. package/{src/steps/index.ts → dist/steps/index.d.ts} +1 -9
  98. package/dist/steps/index.js +8 -0
  99. package/dist/steps/index.js.map +1 -0
  100. package/dist/steps/parallel-step.d.ts +11 -0
  101. package/dist/steps/parallel-step.js +166 -0
  102. package/dist/steps/parallel-step.js.map +1 -0
  103. package/dist/steps/prompt-step.d.ts +8 -0
  104. package/dist/steps/prompt-step.js +94 -0
  105. package/dist/steps/prompt-step.js.map +1 -0
  106. package/dist/steps/ralph-loop-step.d.ts +8 -0
  107. package/dist/steps/ralph-loop-step.js +132 -0
  108. package/dist/steps/ralph-loop-step.js.map +1 -0
  109. package/dist/steps/serial-step.d.ts +10 -0
  110. package/dist/steps/serial-step.js +57 -0
  111. package/dist/steps/serial-step.js.map +1 -0
  112. package/dist/types.d.ts +118 -0
  113. package/dist/types.js +10 -0
  114. package/dist/types.js.map +1 -0
  115. package/package.json +56 -2
  116. package/.gitattributes +0 -24
  117. package/.github/workflows/ci.yml +0 -70
  118. package/.markdownlint-cli2.jsonc +0 -16
  119. package/.prettierignore +0 -3
  120. package/.prettierrc +0 -6
  121. package/.vscode/agentic-forge.code-workspace +0 -26
  122. package/CHANGELOG.md +0 -100
  123. package/CLAUDE.md +0 -158
  124. package/CONTRIBUTING.md +0 -152
  125. package/biome.json +0 -21
  126. package/scripts/copy-assets.js +0 -21
  127. package/src/checkpoints/manager.ts +0 -119
  128. package/src/cli.ts +0 -182
  129. package/src/commands/config-cmd.ts +0 -28
  130. package/src/commands/init.ts +0 -96
  131. package/src/commands/release-notes.ts +0 -85
  132. package/src/commands/resume.ts +0 -103
  133. package/src/commands/run.ts +0 -234
  134. package/src/commands/shortcuts.ts +0 -11
  135. package/src/commands/skills-dir.ts +0 -11
  136. package/src/commands/status.ts +0 -112
  137. package/src/commands/update.ts +0 -64
  138. package/src/commands/version.ts +0 -27
  139. package/src/commands/workflows.ts +0 -129
  140. package/src/config.ts +0 -129
  141. package/src/console.ts +0 -790
  142. package/src/executor.ts +0 -354
  143. package/src/git/worktree.ts +0 -236
  144. package/src/logging/logger.ts +0 -95
  145. package/src/orchestrator.ts +0 -815
  146. package/src/parser.ts +0 -225
  147. package/src/progress.ts +0 -306
  148. package/src/ralph-loop.ts +0 -260
  149. package/src/renderer.ts +0 -164
  150. package/src/runner.ts +0 -634
  151. package/src/signal-manager.ts +0 -55
  152. package/src/steps/base.ts +0 -71
  153. package/src/steps/conditional-step.ts +0 -144
  154. package/src/steps/parallel-step.ts +0 -213
  155. package/src/steps/prompt-step.ts +0 -121
  156. package/src/steps/ralph-loop-step.ts +0 -186
  157. package/src/steps/serial-step.ts +0 -84
  158. package/src/types.ts +0 -141
  159. package/tests/config.test.ts +0 -219
  160. package/tests/console.test.ts +0 -506
  161. package/tests/executor.test.ts +0 -339
  162. package/tests/init.test.ts +0 -86
  163. package/tests/logger.test.ts +0 -110
  164. package/tests/parser.test.ts +0 -290
  165. package/tests/progress.test.ts +0 -345
  166. package/tests/ralph-loop.test.ts +0 -418
  167. package/tests/renderer.test.ts +0 -350
  168. package/tests/runner.test.ts +0 -497
  169. package/tests/setup.test.ts +0 -7
  170. package/tests/signal-manager.test.ts +0 -26
  171. package/tests/steps.test.ts +0 -412
  172. package/tests/worktree.test.ts +0 -411
  173. package/tsconfig.json +0 -18
  174. package/vitest.config.ts +0 -8
  175. /package/{src → dist}/agents/explorer.md +0 -0
  176. /package/{src → dist}/agents/reviewer.md +0 -0
  177. /package/{src → dist}/claude/.claude/skills/analyze/references/bug.md +0 -0
  178. /package/{src → dist}/claude/.claude/skills/analyze/references/debt.md +0 -0
  179. /package/{src → dist}/claude/.claude/skills/analyze/references/doc.md +0 -0
  180. /package/{src → dist}/claude/.claude/skills/analyze/references/security.md +0 -0
  181. /package/{src → dist}/claude/.claude/skills/analyze/references/style.md +0 -0
  182. /package/{src → dist}/claude/.claude/skills/orchestrate/SKILL.md +0 -0
  183. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/bug.md +0 -0
  184. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/chore.md +0 -0
  185. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/feature.md +0 -0
  186. /package/{src → dist}/claude/.claude/skills/workflow-builder/references/REFERENCE.md +0 -0
  187. /package/{src → dist}/claude/.claude/skills/workflow-builder/references/workflow-example.yaml +0 -0
  188. /package/{src → dist}/prompts/agentic-system.md +0 -0
  189. /package/{src → dist}/templates/analysis/bug.md.j2 +0 -0
  190. /package/{src → dist}/templates/analysis/debt.md.j2 +0 -0
  191. /package/{src → dist}/templates/analysis/doc.md.j2 +0 -0
  192. /package/{src → dist}/templates/analysis/security.md.j2 +0 -0
  193. /package/{src → dist}/templates/analysis/style.md.j2 +0 -0
  194. /package/{src → dist}/templates/analysis-summary.md.j2 +0 -0
  195. /package/{src → dist}/templates/checkpoint.md.j2 +0 -0
  196. /package/{src → dist}/templates/implementation-report.md.j2 +0 -0
  197. /package/{src → dist}/templates/memory.md.j2 +0 -0
  198. /package/{src → dist}/templates/plan-bug.md.j2 +0 -0
  199. /package/{src → dist}/templates/plan-chore.md.j2 +0 -0
  200. /package/{src → dist}/templates/plan-feature.md.j2 +0 -0
  201. /package/{src → dist}/templates/progress.json.j2 +0 -0
  202. /package/{src → dist}/templates/ralph-report.md.j2 +0 -0
  203. /package/{src → dist}/workflows/analyze-codebase-merge.yaml +0 -0
  204. /package/{src → dist}/workflows/analyze-codebase.yaml +0 -0
  205. /package/{src → dist}/workflows/analyze-single.yaml +0 -0
  206. /package/{src → dist}/workflows/demo.yaml +0 -0
  207. /package/{src → dist}/workflows/one-shot.yaml +0 -0
  208. /package/{src → dist}/workflows/plan-build-review.yaml +0 -0
  209. /package/{src → dist}/workflows/ralph-loop.yaml +0 -0
@@ -0,0 +1,670 @@
1
+ /** Console output utilities for workflow execution. */
2
+ // --- Enums and constants ---
3
+ export const OutputLevel = {
4
+ BASE: "base",
5
+ ALL: "all",
6
+ };
7
+ export const Color = {
8
+ RESET: "\x1b[0m",
9
+ BOLD: "\x1b[1m",
10
+ DIM: "\x1b[2m",
11
+ RED: "\x1b[31m",
12
+ GREEN: "\x1b[32m",
13
+ YELLOW: "\x1b[33m",
14
+ BLUE: "\x1b[34m",
15
+ MAGENTA: "\x1b[35m",
16
+ CYAN: "\x1b[36m",
17
+ WHITE: "\x1b[37m",
18
+ BRIGHT_RED: "\x1b[91m",
19
+ BRIGHT_GREEN: "\x1b[92m",
20
+ BRIGHT_YELLOW: "\x1b[93m",
21
+ BRIGHT_BLUE: "\x1b[94m",
22
+ BRIGHT_CYAN: "\x1b[96m",
23
+ };
24
+ /** Maximum characters to accumulate in BASE mode before truncating (1MB). */
25
+ const MAX_ACCUMULATED_TEXT = 1024 * 1024;
26
+ // --- Utility functions ---
27
+ export function supportsColor() {
28
+ if (typeof process.stdout.isTTY !== "boolean") {
29
+ return false;
30
+ }
31
+ return process.stdout.isTTY;
32
+ }
33
+ export function colorize(text, ...colors) {
34
+ if (!supportsColor()) {
35
+ return text;
36
+ }
37
+ const colorCodes = colors.join("");
38
+ return `${colorCodes}${text}${Color.RESET}`;
39
+ }
40
+ // --- ParallelOutputHandler ---
41
+ export class ParallelOutputHandler {
42
+ stream;
43
+ level;
44
+ printFn;
45
+ branches = [];
46
+ branchIndex = new Map();
47
+ branchDone = new Map();
48
+ deferredMessages = [];
49
+ linesPerBranch = 4;
50
+ active = false;
51
+ // Per-branch accumulation (single-threaded, so we use maps instead of thread-local)
52
+ currentBranch = null;
53
+ accumulatedText = "";
54
+ accumulatedRole = "";
55
+ accumulatedModel = null;
56
+ baseAccumulatedText = "";
57
+ // Message queue for ALL mode parallel
58
+ messageQueue = [];
59
+ constructor(stream = process.stdout, level = OutputLevel.BASE, printFn) {
60
+ this.stream = stream;
61
+ this.level = level;
62
+ this.printFn = printFn ?? null;
63
+ }
64
+ print(message) {
65
+ if (this.printFn) {
66
+ this.printFn(message);
67
+ }
68
+ else {
69
+ this.stream.write(`${message}\n`);
70
+ }
71
+ }
72
+ get isActive() {
73
+ return this.active;
74
+ }
75
+ get hasBranches() {
76
+ return this.branches.length > 0;
77
+ }
78
+ registerBranches(branches) {
79
+ this.branches = [...branches];
80
+ this.branchIndex = new Map(branches.map((name, idx) => [name, idx]));
81
+ this.branchDone = new Map(branches.map((name) => [name, false]));
82
+ this.deferredMessages = [];
83
+ if (this.level === OutputLevel.BASE && supportsColor()) {
84
+ for (const branch of branches) {
85
+ const prefix = colorize(`[${branch}]`, Color.CYAN, Color.BOLD);
86
+ this.print(prefix);
87
+ const waiting = colorize("waiting...", Color.DIM);
88
+ this.print(` ${waiting}`);
89
+ this.print(""); // Message line 2
90
+ this.print(""); // Blank line
91
+ }
92
+ }
93
+ }
94
+ updateBranchLine(branch, text, maxWidth = 100) {
95
+ if (!supportsColor() || !this.branchIndex.has(branch))
96
+ return;
97
+ if (this.branchDone.get(branch))
98
+ return;
99
+ const idx = this.branchIndex.get(branch) ?? 0;
100
+ const totalBranches = this.branches.length;
101
+ const totalLines = totalBranches * this.linesPerBranch;
102
+ const branchStartLine = idx * this.linesPerBranch;
103
+ const messageLine1 = branchStartLine + 1;
104
+ const messageLine2 = branchStartLine + 2;
105
+ const linesUpToMsg1 = totalLines - messageLine1;
106
+ const linesUpToMsg2 = totalLines - messageLine2;
107
+ const trimmed = text.trim();
108
+ let line1;
109
+ let line2 = "";
110
+ if (trimmed.length <= maxWidth) {
111
+ line1 = trimmed;
112
+ }
113
+ else {
114
+ let breakPoint = trimmed.lastIndexOf(" ", maxWidth);
115
+ if (breakPoint === -1)
116
+ breakPoint = maxWidth;
117
+ line1 = trimmed.slice(0, breakPoint).trim();
118
+ line2 = trimmed.slice(breakPoint).trim();
119
+ if (line2.length > maxWidth) {
120
+ line2 = `${line2.slice(0, maxWidth - 3)}...`;
121
+ }
122
+ }
123
+ const prefix = colorize("...", Color.DIM);
124
+ const w = this.stream;
125
+ w.write("\x1b[s"); // Save cursor
126
+ w.write(`\x1b[${linesUpToMsg1}A`); // Move up
127
+ w.write("\x1b[K"); // Clear line
128
+ w.write(` ${prefix} ${line1}`);
129
+ w.write(`\x1b[${linesUpToMsg1 - linesUpToMsg2}B`); // Move down to line 2
130
+ w.write("\r\x1b[K"); // Clear line
131
+ if (line2) {
132
+ w.write(` ${prefix} ${line2}`);
133
+ }
134
+ w.write("\x1b[u"); // Restore cursor
135
+ }
136
+ markBranchDone(branch, success = true) {
137
+ if (!supportsColor() || !this.branchIndex.has(branch))
138
+ return;
139
+ this.branchDone.set(branch, true);
140
+ const idx = this.branchIndex.get(branch) ?? 0;
141
+ const totalBranches = this.branches.length;
142
+ const totalLines = totalBranches * this.linesPerBranch;
143
+ const branchStartLine = idx * this.linesPerBranch;
144
+ const linesUpToHeader = totalLines - branchStartLine;
145
+ const messageLine1 = branchStartLine + 1;
146
+ const messageLine2 = branchStartLine + 2;
147
+ const linesUpToMsg1 = totalLines - messageLine1;
148
+ const linesUpToMsg2 = totalLines - messageLine2;
149
+ const branchPrefix = colorize(`[${branch}]`, Color.CYAN, Color.BOLD);
150
+ const status = success
151
+ ? colorize("[Done]", Color.BRIGHT_GREEN, Color.BOLD)
152
+ : colorize("[Failed]", Color.BRIGHT_RED, Color.BOLD);
153
+ const w = this.stream;
154
+ w.write("\x1b[s");
155
+ w.write(`\x1b[${linesUpToHeader}A`);
156
+ w.write("\x1b[K");
157
+ w.write(`${branchPrefix} ${status}`);
158
+ w.write(`\x1b[${linesUpToHeader - linesUpToMsg1}B`);
159
+ w.write("\r\x1b[K");
160
+ w.write(`\x1b[${linesUpToMsg1 - linesUpToMsg2}B`);
161
+ w.write("\r\x1b[K");
162
+ w.write("\x1b[u");
163
+ }
164
+ clearDisplay() {
165
+ if (this.branches.length === 0 || !supportsColor()) {
166
+ this.branches = [];
167
+ this.branchIndex = new Map();
168
+ this.branchDone = new Map();
169
+ return;
170
+ }
171
+ const totalLines = this.branches.length * this.linesPerBranch;
172
+ for (let i = 0; i < totalLines; i++) {
173
+ this.stream.write("\x1b[A\x1b[2K");
174
+ }
175
+ this.branches = [];
176
+ this.branchIndex = new Map();
177
+ this.branchDone = new Map();
178
+ }
179
+ enter() {
180
+ this.active = true;
181
+ if (this.level === OutputLevel.ALL) {
182
+ this.messageQueue = [];
183
+ }
184
+ }
185
+ exit() {
186
+ if (this.level === OutputLevel.BASE) {
187
+ if (this.branches.length > 0) {
188
+ this.clearDisplay();
189
+ }
190
+ for (const msg of this.deferredMessages) {
191
+ this.print(msg);
192
+ }
193
+ this.deferredMessages = [];
194
+ }
195
+ // Flush remaining messages in ALL mode
196
+ if (this.level === OutputLevel.ALL) {
197
+ for (const [branch, role, text, model] of this.messageQueue) {
198
+ this.printBranchMessage(branch, role, text, model);
199
+ }
200
+ this.messageQueue = [];
201
+ }
202
+ this.active = false;
203
+ }
204
+ deferMessage(message) {
205
+ this.deferredMessages.push(message);
206
+ }
207
+ setBranch(branchName) {
208
+ this.currentBranch = branchName;
209
+ this.accumulatedText = "";
210
+ this.accumulatedRole = "";
211
+ this.accumulatedModel = null;
212
+ this.baseAccumulatedText = "";
213
+ }
214
+ getCurrentBranch() {
215
+ return this.currentBranch;
216
+ }
217
+ enqueueCurrentMessage() {
218
+ if (this.level === OutputLevel.ALL &&
219
+ this.active &&
220
+ this.accumulatedText.trim() &&
221
+ this.accumulatedRole &&
222
+ this.currentBranch) {
223
+ this.messageQueue.push([
224
+ this.currentBranch,
225
+ this.accumulatedRole,
226
+ this.accumulatedText.trim(),
227
+ this.accumulatedModel,
228
+ ]);
229
+ }
230
+ this.accumulatedText = "";
231
+ this.accumulatedRole = "";
232
+ this.accumulatedModel = null;
233
+ }
234
+ printBranchMessage(branch, role, text, model, formatModelName) {
235
+ const formattedModel = formatModelName && model ? formatModelName(model) : null;
236
+ const branchPrefix = colorize(`[${branch}] `, Color.CYAN, Color.BOLD);
237
+ if (role === "user") {
238
+ const prefix = colorize(">", Color.BRIGHT_CYAN, Color.BOLD);
239
+ const label = colorize(" [user]", Color.DIM);
240
+ this.print(`\n${branchPrefix}${prefix}${label}`);
241
+ for (const line of text.split("\n")) {
242
+ const coloredLine = colorize(line, Color.GREEN);
243
+ this.print(` ${coloredLine}`);
244
+ }
245
+ }
246
+ else {
247
+ const bullet = colorize("*", Color.BRIGHT_GREEN, Color.BOLD);
248
+ let modelLabel = "";
249
+ if (formattedModel) {
250
+ modelLabel = ` ${colorize(`[${formattedModel}]`, Color.DIM)}`;
251
+ }
252
+ const lines = text.split("\n");
253
+ this.print(`\n${branchPrefix}${bullet}${modelLabel} ${lines[0]}`);
254
+ for (const line of lines.slice(1)) {
255
+ this.print(` ${line}`);
256
+ }
257
+ }
258
+ }
259
+ accumulateText(text, role, model) {
260
+ if (this.accumulatedRole && this.accumulatedRole !== role && this.accumulatedText.trim()) {
261
+ this.enqueueCurrentMessage();
262
+ }
263
+ this.accumulatedText += text;
264
+ this.accumulatedRole = role;
265
+ if (model) {
266
+ this.accumulatedModel = model;
267
+ }
268
+ }
269
+ accumulateBaseText(text) {
270
+ this.baseAccumulatedText += text;
271
+ const accumulated = this.baseAccumulatedText.trim();
272
+ if (accumulated) {
273
+ const lines = accumulated.split("\n");
274
+ return lines[lines.length - 1];
275
+ }
276
+ return "";
277
+ }
278
+ }
279
+ // --- ConsoleOutput ---
280
+ export class ConsoleOutput {
281
+ level;
282
+ stream;
283
+ _baseAccumulatedText = "";
284
+ baseLastDisplayLines = 0;
285
+ _parallelHandler;
286
+ formatModelName = null;
287
+ constructor(level = OutputLevel.BASE, stream = process.stdout) {
288
+ this.level = level;
289
+ this.stream = stream;
290
+ this._parallelHandler = new ParallelOutputHandler(stream, level, (msg) => this.printLine(msg));
291
+ }
292
+ /** Set model name formatter to avoid circular imports with runner. */
293
+ setModelFormatter(fn) {
294
+ this.formatModelName = fn;
295
+ }
296
+ printLine(message, end = "\n") {
297
+ this.stream.write(`${message}${end}`);
298
+ }
299
+ printInplace(message) {
300
+ const lines = message.trim().split("\n");
301
+ const numLines = lines.length;
302
+ if (supportsColor()) {
303
+ if (this.baseLastDisplayLines > 0) {
304
+ this.stream.write(`\x1b[${this.baseLastDisplayLines}A`);
305
+ this.stream.write("\x1b[J");
306
+ }
307
+ const content = `${lines.join("\n")}\n`;
308
+ this.stream.write(content);
309
+ }
310
+ else {
311
+ const lastLine = lines[lines.length - 1] ?? "";
312
+ const truncated = lastLine.length > 80 ? `${lastLine.slice(0, 80)}...` : lastLine;
313
+ this.printLine(` ... ${truncated}`);
314
+ }
315
+ this.baseLastDisplayLines = numLines;
316
+ }
317
+ clearInplace() {
318
+ if (this.baseLastDisplayLines > 0 && supportsColor()) {
319
+ this.stream.write(`\x1b[${this.baseLastDisplayLines}A\x1b[J`);
320
+ }
321
+ this.baseLastDisplayLines = 0;
322
+ }
323
+ // --- Parallel mode delegation ---
324
+ registerParallelBranches(branches) {
325
+ this._parallelHandler.registerBranches(branches);
326
+ }
327
+ enterParallelMode() {
328
+ this._parallelHandler.enter();
329
+ }
330
+ exitParallelMode() {
331
+ this._parallelHandler.exit();
332
+ }
333
+ setParallelBranch(branchName) {
334
+ this._parallelHandler.setBranch(branchName);
335
+ }
336
+ markParallelBranchDone(branch, success = true) {
337
+ this._parallelHandler.markBranchDone(branch, success);
338
+ }
339
+ isParallelMode() {
340
+ return this._parallelHandler.isActive;
341
+ }
342
+ shouldDeferMessage() {
343
+ return (this._parallelHandler.isActive &&
344
+ this.level === OutputLevel.BASE &&
345
+ this._parallelHandler.hasBranches);
346
+ }
347
+ deferMessage(message) {
348
+ this._parallelHandler.deferMessage(message);
349
+ }
350
+ // --- Workflow-level messages ---
351
+ workflowStart(workflowName, workflowId) {
352
+ const header = colorize(`Workflow: ${workflowName}`, Color.BOLD, Color.BRIGHT_CYAN);
353
+ const idStr = colorize(`[${workflowId}]`, Color.DIM);
354
+ this.printLine(`\n${header} ${idStr}`);
355
+ this.printLine(colorize("-".repeat(50), Color.DIM));
356
+ }
357
+ workflowComplete(workflowName, status) {
358
+ this.printLine(colorize("-".repeat(50), Color.DIM));
359
+ const statusStr = status === "completed"
360
+ ? colorize("COMPLETED", Color.BOLD, Color.BRIGHT_GREEN)
361
+ : colorize(status.toUpperCase(), Color.BOLD, Color.BRIGHT_RED);
362
+ this.printLine(`Workflow ${workflowName}: ${statusStr}\n`);
363
+ }
364
+ // --- Step-level messages ---
365
+ stepStart(stepName, stepType, model) {
366
+ let modelStr = "";
367
+ if (this.level === OutputLevel.BASE && model) {
368
+ const formattedModel = this.formatModelName ? this.formatModelName(model) : model;
369
+ if (formattedModel) {
370
+ modelStr = `${colorize(`[${formattedModel}] `, Color.DIM)}`;
371
+ }
372
+ }
373
+ const stepStr = colorize(`Step: ${stepName}`, Color.BOLD);
374
+ const typeStr = stepType ? colorize(`[${stepType}]`, Color.DIM) : "";
375
+ const formatted = `\n${modelStr}${stepStr} ${typeStr}`;
376
+ if (this.shouldDeferMessage()) {
377
+ this.deferMessage(formatted);
378
+ }
379
+ else {
380
+ this.printLine(formatted);
381
+ }
382
+ }
383
+ stepComplete(stepName, summary) {
384
+ if (this.level === OutputLevel.BASE && !this.isParallelMode()) {
385
+ this.baseLastDisplayLines = 0;
386
+ this._baseAccumulatedText = "";
387
+ }
388
+ const check = colorize("[OK]", Color.BRIGHT_GREEN);
389
+ const name = colorize(stepName, Color.GREEN);
390
+ const mainLine = `${check} ${name} completed`;
391
+ const lines = [mainLine];
392
+ if (summary && this.level === OutputLevel.BASE) {
393
+ const summaryLines = summary.trim().split("\n");
394
+ for (const line of summaryLines.slice(0, 5)) {
395
+ const truncated = line.length > 200 ? `${line.slice(0, 200)}...` : line;
396
+ lines.push(colorize(` ${truncated}`, Color.DIM));
397
+ }
398
+ if (summaryLines.length > 5) {
399
+ lines.push(colorize(` ... (${summaryLines.length - 5} more lines)`, Color.DIM));
400
+ }
401
+ }
402
+ if (this.shouldDeferMessage()) {
403
+ const branch = this._parallelHandler.getCurrentBranch();
404
+ if (branch) {
405
+ this.markParallelBranchDone(branch);
406
+ }
407
+ for (const line of lines) {
408
+ this.deferMessage(line);
409
+ }
410
+ }
411
+ else {
412
+ for (const line of lines) {
413
+ this.printLine(line);
414
+ }
415
+ }
416
+ }
417
+ stepFailed(stepName, error) {
418
+ if (this.level === OutputLevel.BASE && !this.isParallelMode()) {
419
+ this.baseLastDisplayLines = 0;
420
+ this._baseAccumulatedText = "";
421
+ }
422
+ const cross = colorize("[FAIL]", Color.BRIGHT_RED);
423
+ const name = colorize(stepName, Color.RED);
424
+ const mainLine = `${cross} ${name} failed`;
425
+ const lines = [mainLine];
426
+ if (error) {
427
+ const errorLines = error.trim().split("\n");
428
+ for (const line of errorLines.slice(0, 10)) {
429
+ const truncated = line.length > 200 ? `${line.slice(0, 200)}...` : line;
430
+ lines.push(colorize(` ${truncated}`, Color.RED));
431
+ }
432
+ if (errorLines.length > 10) {
433
+ lines.push(colorize(` ... (${errorLines.length - 10} more lines)`, Color.DIM));
434
+ }
435
+ }
436
+ if (this.shouldDeferMessage()) {
437
+ const branch = this._parallelHandler.getCurrentBranch();
438
+ if (branch) {
439
+ this.markParallelBranchDone(branch, false);
440
+ }
441
+ for (const line of lines) {
442
+ this.deferMessage(line);
443
+ }
444
+ }
445
+ else {
446
+ for (const line of lines) {
447
+ this.printLine(line);
448
+ }
449
+ }
450
+ }
451
+ stepRetry(stepName, attempt, maxAttempts, error) {
452
+ const retry = colorize(`[RETRY ${attempt}/${maxAttempts}]`, Color.YELLOW);
453
+ const name = colorize(stepName, Color.YELLOW);
454
+ const mainLine = `${retry} ${name}`;
455
+ const lines = [mainLine];
456
+ if (error) {
457
+ const firstLine = error.trim().split("\n")[0].slice(0, 100);
458
+ lines.push(colorize(` Reason: ${firstLine}`, Color.DIM));
459
+ }
460
+ if (this.shouldDeferMessage()) {
461
+ for (const line of lines) {
462
+ this.deferMessage(line);
463
+ }
464
+ }
465
+ else {
466
+ for (const line of lines) {
467
+ this.printLine(line);
468
+ }
469
+ }
470
+ }
471
+ // --- Ralph loop messages ---
472
+ ralphIterationStart(stepName, iteration, maxIterations) {
473
+ if (this.level === OutputLevel.BASE && !this.isParallelMode()) {
474
+ this.baseLastDisplayLines = 0;
475
+ this._baseAccumulatedText = "";
476
+ }
477
+ const progress = colorize(`[${iteration}/${maxIterations}]`, Color.CYAN);
478
+ const name = colorize(stepName, Color.CYAN);
479
+ this.printLine(`${progress} ${name} iteration`);
480
+ }
481
+ ralphIteration(_stepName, _iteration, _maxIterations, summary) {
482
+ if (this.level === OutputLevel.BASE && !this.isParallelMode()) {
483
+ return;
484
+ }
485
+ if (summary && this.level === OutputLevel.ALL) {
486
+ const summaryLines = summary.trim().split("\n");
487
+ for (const line of summaryLines.slice(0, 3)) {
488
+ const truncated = line.length > 150 ? `${line.slice(0, 150)}...` : line;
489
+ this.printLine(colorize(` ${truncated}`, Color.DIM));
490
+ }
491
+ }
492
+ }
493
+ ralphComplete(stepName, iteration, maxIterations) {
494
+ if (this.level === OutputLevel.BASE && !this.isParallelMode()) {
495
+ this.baseLastDisplayLines = 0;
496
+ this._baseAccumulatedText = "";
497
+ }
498
+ const check = colorize("[OK]", Color.BRIGHT_GREEN);
499
+ const name = colorize(stepName, Color.GREEN);
500
+ this.printLine(`${check} ${name} completed at iteration ${iteration}/${maxIterations}`);
501
+ }
502
+ ralphMaxIterations(stepName, maxIterations) {
503
+ if (this.level === OutputLevel.BASE && !this.isParallelMode()) {
504
+ this.baseLastDisplayLines = 0;
505
+ this._baseAccumulatedText = "";
506
+ }
507
+ const warn = colorize("[WARN]", Color.YELLOW);
508
+ const name = colorize(stepName, Color.YELLOW);
509
+ this.printLine(`${warn} ${name} reached max iterations (${maxIterations})`);
510
+ }
511
+ // --- Generic messages ---
512
+ info(message) {
513
+ const infoPrefix = colorize("[INFO]", Color.BLUE);
514
+ const formatted = `${infoPrefix} ${message}`;
515
+ if (this.shouldDeferMessage()) {
516
+ this.deferMessage(formatted);
517
+ }
518
+ else {
519
+ this.printLine(formatted);
520
+ }
521
+ }
522
+ warning(message) {
523
+ const warn = colorize("[WARN]", Color.YELLOW);
524
+ const formatted = `${warn} ${message}`;
525
+ if (this.shouldDeferMessage()) {
526
+ this.deferMessage(formatted);
527
+ }
528
+ else {
529
+ this.printLine(formatted);
530
+ }
531
+ }
532
+ error(message) {
533
+ const err = colorize("[ERROR]", Color.BRIGHT_RED);
534
+ const formatted = `${err} ${message}`;
535
+ if (this.shouldDeferMessage()) {
536
+ this.deferMessage(formatted);
537
+ }
538
+ else {
539
+ this.printLine(formatted);
540
+ }
541
+ }
542
+ // --- Streaming ---
543
+ streamText(text, role = "assistant", model) {
544
+ const formattedModel = this.formatModelName && model ? this.formatModelName(model) : null;
545
+ if (this.level === OutputLevel.ALL) {
546
+ if (!text || !text.trim())
547
+ return;
548
+ if (this.isParallelMode()) {
549
+ this._parallelHandler.accumulateText(text, role, model);
550
+ return;
551
+ }
552
+ if (role === "user") {
553
+ const prefix = colorize(">", Color.BRIGHT_CYAN, Color.BOLD);
554
+ const label = colorize(" [user]", Color.DIM);
555
+ this.printLine("");
556
+ this.printLine(`${prefix}${label}`);
557
+ for (const line of text.split("\n")) {
558
+ const coloredLine = colorize(line, Color.GREEN);
559
+ this.printLine(` ${coloredLine}`);
560
+ }
561
+ }
562
+ else {
563
+ const bullet = colorize("*", Color.BRIGHT_GREEN, Color.BOLD);
564
+ let modelLabel = "";
565
+ if (formattedModel) {
566
+ modelLabel = ` ${colorize(`[${formattedModel}]`, Color.DIM)}`;
567
+ }
568
+ const lines = text.split("\n");
569
+ this.printLine("");
570
+ this.printLine(`${bullet}${modelLabel} ${lines[0]}`);
571
+ for (const line of lines.slice(1)) {
572
+ this.printLine(` ${line}`);
573
+ }
574
+ }
575
+ }
576
+ else if (this.level === OutputLevel.BASE) {
577
+ if (role === "user")
578
+ return;
579
+ if (this.isParallelMode()) {
580
+ const branch = this._parallelHandler.getCurrentBranch();
581
+ if (branch && this._parallelHandler.hasBranches) {
582
+ const lastLine = this._parallelHandler.accumulateBaseText(text);
583
+ if (lastLine) {
584
+ this._parallelHandler.updateBranchLine(branch, lastLine);
585
+ }
586
+ }
587
+ return;
588
+ }
589
+ this._baseAccumulatedText += text;
590
+ if (this._baseAccumulatedText.length > MAX_ACCUMULATED_TEXT) {
591
+ this._baseAccumulatedText = this._baseAccumulatedText.slice(-MAX_ACCUMULATED_TEXT);
592
+ }
593
+ if (this._baseAccumulatedText.trim()) {
594
+ const prefix = colorize("...", Color.DIM);
595
+ const lines = this._baseAccumulatedText.trim().split("\n");
596
+ const formattedLines = [`${prefix} ${lines[0]}`];
597
+ for (const line of lines.slice(1)) {
598
+ formattedLines.push(` ${line}`);
599
+ }
600
+ const displayText = formattedLines.join("\n");
601
+ this.printInplace(displayText);
602
+ }
603
+ }
604
+ }
605
+ streamComplete() {
606
+ if (this.level === OutputLevel.ALL && this.isParallelMode()) {
607
+ this._parallelHandler.enqueueCurrentMessage();
608
+ }
609
+ this._baseAccumulatedText = "";
610
+ }
611
+ }
612
+ // --- Standalone utility functions ---
613
+ export function extractJson(output) {
614
+ if (!output || !output.trim())
615
+ return null;
616
+ const pattern = /```json\s*([\s\S]*?)```/g;
617
+ const matches = [...output.matchAll(pattern)];
618
+ if (matches.length === 0)
619
+ return null;
620
+ const jsonStr = matches[matches.length - 1][1].trim();
621
+ try {
622
+ return JSON.parse(jsonStr);
623
+ }
624
+ catch (e) {
625
+ const msg = e instanceof Error ? e.message : String(e);
626
+ process.stderr.write(`[WARN] Failed to parse JSON from output: ${msg}\n`);
627
+ return null;
628
+ }
629
+ }
630
+ export function extractSummary(output, maxLines = 5, maxChars = 500) {
631
+ if (!output || !output.trim())
632
+ return "";
633
+ const trimmed = output.trim();
634
+ const summaryMarkers = [
635
+ "## Summary",
636
+ "### Summary",
637
+ "Summary:",
638
+ "Result:",
639
+ "Completed:",
640
+ "Done:",
641
+ ];
642
+ for (const marker of summaryMarkers) {
643
+ if (trimmed.includes(marker)) {
644
+ const idx = trimmed.indexOf(marker);
645
+ const summarySection = trimmed.slice(idx);
646
+ const lines = summarySection.split("\n");
647
+ const resultLines = [];
648
+ for (let i = 1; i < lines.length; i++) {
649
+ if (i > maxLines)
650
+ break;
651
+ if (lines[i].startsWith("#") && i > 1)
652
+ break;
653
+ resultLines.push(lines[i]);
654
+ }
655
+ if (resultLines.length > 0) {
656
+ return resultLines.join("\n").trim().slice(0, maxChars);
657
+ }
658
+ }
659
+ }
660
+ const nonEmptyLines = trimmed.split("\n").filter((line) => line.trim());
661
+ if (nonEmptyLines.length === 0)
662
+ return "";
663
+ const lastLines = nonEmptyLines.slice(-maxLines);
664
+ let summary = lastLines.join("\n");
665
+ if (summary.length > maxChars) {
666
+ summary = `${summary.slice(0, maxChars)}...`;
667
+ }
668
+ return summary;
669
+ }
670
+ //# sourceMappingURL=console.js.map