@compilr-dev/cli 0.4.0 → 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 (315) hide show
  1. package/README.md +30 -12
  2. package/dist/agent.d.ts +74 -1
  3. package/dist/agent.js +259 -76
  4. package/dist/anchors/index.d.ts +9 -0
  5. package/dist/anchors/index.js +9 -0
  6. package/dist/anchors/project-anchors.d.ts +79 -0
  7. package/dist/anchors/project-anchors.js +202 -0
  8. package/dist/commands/handler-types.d.ts +68 -0
  9. package/dist/commands/handler-types.js +8 -0
  10. package/dist/commands/handlers/agent-commands.d.ts +13 -0
  11. package/dist/commands/handlers/agent-commands.js +305 -0
  12. package/dist/commands/handlers/design-commands.d.ts +15 -0
  13. package/dist/commands/handlers/design-commands.js +334 -0
  14. package/dist/commands/handlers/index.d.ts +20 -0
  15. package/dist/commands/handlers/index.js +43 -0
  16. package/dist/commands/handlers/overlay-commands.d.ts +21 -0
  17. package/dist/commands/handlers/overlay-commands.js +287 -0
  18. package/dist/commands/handlers/project-commands.d.ts +11 -0
  19. package/dist/commands/handlers/project-commands.js +167 -0
  20. package/dist/commands/handlers/simple-commands.d.ts +19 -0
  21. package/dist/commands/handlers/simple-commands.js +144 -0
  22. package/dist/commands/index.d.ts +2 -1
  23. package/dist/commands/registry.d.ts +50 -0
  24. package/dist/commands/registry.js +75 -0
  25. package/dist/commands-v2/handlers/context.d.ts +13 -0
  26. package/dist/commands-v2/handlers/context.js +348 -0
  27. package/dist/commands-v2/handlers/core.d.ts +13 -0
  28. package/dist/commands-v2/handlers/core.js +165 -0
  29. package/dist/commands-v2/handlers/debug.d.ts +11 -0
  30. package/dist/commands-v2/handlers/debug.js +159 -0
  31. package/dist/commands-v2/handlers/index.d.ts +12 -0
  32. package/dist/commands-v2/handlers/index.js +24 -0
  33. package/dist/commands-v2/handlers/project.d.ts +22 -0
  34. package/dist/commands-v2/handlers/project.js +814 -0
  35. package/dist/commands-v2/handlers/settings.d.ts +15 -0
  36. package/dist/commands-v2/handlers/settings.js +235 -0
  37. package/dist/commands-v2/index.d.ts +13 -0
  38. package/dist/commands-v2/index.js +15 -0
  39. package/dist/commands-v2/registry.d.ts +37 -0
  40. package/dist/commands-v2/registry.js +80 -0
  41. package/dist/commands-v2/types.d.ts +75 -0
  42. package/dist/commands-v2/types.js +7 -0
  43. package/dist/commands.js +110 -7
  44. package/dist/index.js +288 -29
  45. package/dist/input-handlers/index.d.ts +7 -0
  46. package/dist/input-handlers/index.js +7 -0
  47. package/dist/input-handlers/memory-handler.d.ts +26 -0
  48. package/dist/input-handlers/memory-handler.js +68 -0
  49. package/dist/repl-helpers.d.ts +63 -0
  50. package/dist/repl-helpers.js +318 -0
  51. package/dist/repl-v2.d.ts +155 -0
  52. package/dist/repl-v2.js +774 -0
  53. package/dist/repl.d.ts +32 -4
  54. package/dist/repl.js +250 -977
  55. package/dist/settings/index.d.ts +23 -0
  56. package/dist/settings/index.js +48 -0
  57. package/dist/settings/paths.d.ts +110 -0
  58. package/dist/settings/paths.js +264 -0
  59. package/dist/templates/compilr-md.js +7 -4
  60. package/dist/templates/index.js +3 -4
  61. package/dist/themes/colors.js +3 -1
  62. package/dist/themes/registry.d.ts +5 -36
  63. package/dist/themes/registry.js +11 -95
  64. package/dist/themes/types.d.ts +3 -38
  65. package/dist/themes/types.js +2 -2
  66. package/dist/tools/anchor-tools.d.ts +31 -0
  67. package/dist/tools/anchor-tools.js +255 -0
  68. package/dist/tools/backlog-wrappers.d.ts +54 -0
  69. package/dist/tools/backlog-wrappers.js +338 -0
  70. package/dist/tools/backlog.js +1 -1
  71. package/dist/tools/db-tools.d.ts +65 -0
  72. package/dist/tools/db-tools.js +19 -0
  73. package/dist/tools/document-db.d.ts +43 -0
  74. package/dist/tools/document-db.js +220 -0
  75. package/dist/tools/project-db.d.ts +102 -0
  76. package/dist/tools/project-db.js +370 -0
  77. package/dist/tools/workitem-db.d.ts +103 -0
  78. package/dist/tools/workitem-db.js +549 -0
  79. package/dist/tools.js +13 -3
  80. package/dist/ui/agents-overlay-v2.d.ts +43 -0
  81. package/dist/ui/agents-overlay-v2.js +809 -0
  82. package/dist/ui/agents-overlay.d.ts +5 -5
  83. package/dist/ui/agents-overlay.js +782 -420
  84. package/dist/ui/anchors-overlay.d.ts +12 -0
  85. package/dist/ui/anchors-overlay.js +775 -0
  86. package/dist/ui/arch-type-overlay.d.ts +1 -6
  87. package/dist/ui/arch-type-overlay.js +175 -203
  88. package/dist/ui/ask-user-overlay-v2.d.ts +26 -0
  89. package/dist/ui/ask-user-overlay-v2.js +555 -0
  90. package/dist/ui/ask-user-overlay.d.ts +2 -2
  91. package/dist/ui/ask-user-overlay.js +443 -535
  92. package/dist/ui/ask-user-simple-overlay-v2.d.ts +25 -0
  93. package/dist/ui/ask-user-simple-overlay-v2.js +215 -0
  94. package/dist/ui/ask-user-simple-overlay.d.ts +2 -2
  95. package/dist/ui/ask-user-simple-overlay.js +182 -209
  96. package/dist/ui/backlog-overlay.d.ts +16 -1
  97. package/dist/ui/backlog-overlay.js +525 -659
  98. package/dist/ui/base/index.d.ts +26 -0
  99. package/dist/ui/base/index.js +33 -0
  100. package/dist/ui/base/inline-overlay-utils.d.ts +217 -0
  101. package/dist/ui/base/inline-overlay-utils.js +320 -0
  102. package/dist/ui/base/inline-overlay.d.ts +159 -0
  103. package/dist/ui/base/inline-overlay.js +257 -0
  104. package/dist/ui/base/key-utils.d.ts +15 -0
  105. package/dist/ui/base/key-utils.js +30 -0
  106. package/dist/ui/base/overlay-base-v2.d.ts +193 -0
  107. package/dist/ui/base/overlay-base-v2.js +246 -0
  108. package/dist/ui/base/overlay-base.d.ts +156 -0
  109. package/dist/ui/base/overlay-base.js +238 -0
  110. package/dist/ui/base/overlay-lifecycle.d.ts +65 -0
  111. package/dist/ui/base/overlay-lifecycle.js +159 -0
  112. package/dist/ui/base/overlay-types.d.ts +185 -0
  113. package/dist/ui/base/overlay-types.js +7 -0
  114. package/dist/ui/base/render-utils.d.ts +8 -0
  115. package/dist/ui/base/render-utils.js +11 -0
  116. package/dist/ui/base/screen-stack.d.ts +148 -0
  117. package/dist/ui/base/screen-stack.js +184 -0
  118. package/dist/ui/base/tabbed-list-overlay-v2.d.ts +103 -0
  119. package/dist/ui/base/tabbed-list-overlay-v2.js +317 -0
  120. package/dist/ui/base/tabbed-list-overlay.d.ts +153 -0
  121. package/dist/ui/base/tabbed-list-overlay.js +369 -0
  122. package/dist/ui/commands-overlay-v2.d.ts +33 -0
  123. package/dist/ui/commands-overlay-v2.js +441 -0
  124. package/dist/ui/commands-overlay.d.ts +7 -2
  125. package/dist/ui/commands-overlay.js +384 -355
  126. package/dist/ui/config-overlay.d.ts +5 -4
  127. package/dist/ui/config-overlay.js +243 -513
  128. package/dist/ui/conversation.d.ts +75 -4
  129. package/dist/ui/conversation.js +374 -161
  130. package/dist/ui/docs-overlay.d.ts +17 -0
  131. package/dist/ui/docs-overlay.js +303 -0
  132. package/dist/ui/ephemeral.d.ts +1 -1
  133. package/dist/ui/ephemeral.js +1 -1
  134. package/dist/ui/features/index.d.ts +34 -0
  135. package/dist/ui/features/index.js +34 -0
  136. package/dist/ui/features/input-feature.d.ts +85 -0
  137. package/dist/ui/features/input-feature.js +238 -0
  138. package/dist/ui/features/list-feature.d.ts +155 -0
  139. package/dist/ui/features/list-feature.js +244 -0
  140. package/dist/ui/features/pagination-feature.d.ts +154 -0
  141. package/dist/ui/features/pagination-feature.js +238 -0
  142. package/dist/ui/features/search-feature.d.ts +148 -0
  143. package/dist/ui/features/search-feature.js +185 -0
  144. package/dist/ui/features/tab-feature.d.ts +194 -0
  145. package/dist/ui/features/tab-feature.js +307 -0
  146. package/dist/ui/footer-v2.d.ts +222 -0
  147. package/dist/ui/footer-v2.js +1349 -0
  148. package/dist/ui/footer.d.ts +107 -0
  149. package/dist/ui/footer.js +359 -67
  150. package/dist/ui/guardrail-overlay.d.ts +29 -0
  151. package/dist/ui/guardrail-overlay.js +145 -0
  152. package/dist/ui/help-overlay-v2.d.ts +34 -0
  153. package/dist/ui/help-overlay-v2.js +309 -0
  154. package/dist/ui/help-overlay.d.ts +16 -0
  155. package/dist/ui/help-overlay.js +316 -0
  156. package/dist/ui/index.d.ts +1 -1
  157. package/dist/ui/index.js +1 -3
  158. package/dist/ui/init-overlay-v2.d.ts +34 -0
  159. package/dist/ui/init-overlay-v2.js +600 -0
  160. package/dist/ui/init-overlay.d.ts +12 -2
  161. package/dist/ui/init-overlay.js +349 -270
  162. package/dist/ui/input-prompt-v2.d.ts +1 -0
  163. package/dist/ui/input-prompt-v2.js +14 -6
  164. package/dist/ui/input-prompt.d.ts +116 -33
  165. package/dist/ui/input-prompt.js +536 -337
  166. package/dist/ui/iteration-limit-overlay-v2.d.ts +21 -0
  167. package/dist/ui/iteration-limit-overlay-v2.js +114 -0
  168. package/dist/ui/iteration-limit-overlay.d.ts +2 -2
  169. package/dist/ui/iteration-limit-overlay.js +92 -128
  170. package/dist/ui/keys-overlay-v2.d.ts +41 -0
  171. package/dist/ui/keys-overlay-v2.js +248 -0
  172. package/dist/ui/keys-overlay.d.ts +1 -0
  173. package/dist/ui/keys-overlay.js +203 -141
  174. package/dist/ui/line-utils.d.ts +88 -0
  175. package/dist/ui/line-utils.js +150 -0
  176. package/dist/ui/live-region.d.ts +161 -0
  177. package/dist/ui/live-region.js +387 -0
  178. package/dist/ui/mascot/expressions.d.ts +32 -0
  179. package/dist/ui/mascot/expressions.js +213 -0
  180. package/dist/ui/mascot/index.d.ts +8 -0
  181. package/dist/ui/mascot/index.js +8 -0
  182. package/dist/ui/mascot/renderer.d.ts +19 -0
  183. package/dist/ui/mascot/renderer.js +97 -0
  184. package/dist/ui/mascot-overlay-v2.d.ts +41 -0
  185. package/dist/ui/mascot-overlay-v2.js +138 -0
  186. package/dist/ui/mascot-overlay.d.ts +21 -0
  187. package/dist/ui/mascot-overlay.js +146 -0
  188. package/dist/ui/model-overlay-v2.d.ts +49 -0
  189. package/dist/ui/model-overlay-v2.js +118 -0
  190. package/dist/ui/model-overlay.d.ts +27 -0
  191. package/dist/ui/model-overlay.js +221 -0
  192. package/dist/ui/model-warning-overlay.js +3 -5
  193. package/dist/ui/new-overlay.d.ts +34 -0
  194. package/dist/ui/new-overlay.js +604 -0
  195. package/dist/ui/overlay/impl/agents-overlay-v2.d.ts +45 -0
  196. package/dist/ui/overlay/impl/agents-overlay-v2.js +825 -0
  197. package/dist/ui/overlay/impl/anchors-overlay-v2.d.ts +47 -0
  198. package/dist/ui/overlay/impl/anchors-overlay-v2.js +783 -0
  199. package/dist/ui/overlay/impl/arch-type-overlay-v2.d.ts +37 -0
  200. package/dist/ui/overlay/impl/arch-type-overlay-v2.js +240 -0
  201. package/dist/ui/overlay/impl/ask-user-overlay-v2.d.ts +72 -0
  202. package/dist/ui/overlay/impl/ask-user-overlay-v2.js +584 -0
  203. package/dist/ui/overlay/impl/ask-user-simple-overlay-v2.d.ts +46 -0
  204. package/dist/ui/overlay/impl/ask-user-simple-overlay-v2.js +204 -0
  205. package/dist/ui/overlay/impl/backlog-overlay-v2.d.ts +49 -0
  206. package/dist/ui/overlay/impl/backlog-overlay-v2.js +642 -0
  207. package/dist/ui/overlay/impl/commands-overlay-v2.d.ts +33 -0
  208. package/dist/ui/overlay/impl/commands-overlay-v2.js +441 -0
  209. package/dist/ui/overlay/impl/config-overlay-v2.d.ts +100 -0
  210. package/dist/ui/overlay/impl/config-overlay-v2.js +654 -0
  211. package/dist/ui/overlay/impl/dashboard-overlay-v2.d.ts +55 -0
  212. package/dist/ui/overlay/impl/dashboard-overlay-v2.js +359 -0
  213. package/dist/ui/overlay/impl/docs-overlay-v2.d.ts +45 -0
  214. package/dist/ui/overlay/impl/docs-overlay-v2.js +114 -0
  215. package/dist/ui/overlay/impl/document-detail-overlay-v2.d.ts +77 -0
  216. package/dist/ui/overlay/impl/document-detail-overlay-v2.js +1071 -0
  217. package/dist/ui/overlay/impl/guardrail-overlay-v2.d.ts +43 -0
  218. package/dist/ui/overlay/impl/guardrail-overlay-v2.js +114 -0
  219. package/dist/ui/overlay/impl/help-overlay-v2.d.ts +34 -0
  220. package/dist/ui/overlay/impl/help-overlay-v2.js +309 -0
  221. package/dist/ui/overlay/impl/init-overlay-v2.d.ts +77 -0
  222. package/dist/ui/overlay/impl/init-overlay-v2.js +593 -0
  223. package/dist/ui/overlay/impl/init-setup-overlay-v2.d.ts +25 -0
  224. package/dist/ui/overlay/impl/init-setup-overlay-v2.js +97 -0
  225. package/dist/ui/overlay/impl/iteration-limit-overlay-v2.d.ts +35 -0
  226. package/dist/ui/overlay/impl/iteration-limit-overlay-v2.js +105 -0
  227. package/dist/ui/overlay/impl/keys-overlay-v2.d.ts +41 -0
  228. package/dist/ui/overlay/impl/keys-overlay-v2.js +248 -0
  229. package/dist/ui/overlay/impl/mascot-overlay-v2.d.ts +41 -0
  230. package/dist/ui/overlay/impl/mascot-overlay-v2.js +138 -0
  231. package/dist/ui/overlay/impl/model-overlay-v2.d.ts +49 -0
  232. package/dist/ui/overlay/impl/model-overlay-v2.js +118 -0
  233. package/dist/ui/overlay/impl/model-warning-overlay-v2.d.ts +46 -0
  234. package/dist/ui/overlay/impl/model-warning-overlay-v2.js +132 -0
  235. package/dist/ui/overlay/impl/new-overlay-v2.d.ts +77 -0
  236. package/dist/ui/overlay/impl/new-overlay-v2.js +593 -0
  237. package/dist/ui/overlay/impl/permission-overlay-v2.d.ts +36 -0
  238. package/dist/ui/overlay/impl/permission-overlay-v2.js +380 -0
  239. package/dist/ui/overlay/impl/projects-overlay-v2.d.ts +36 -0
  240. package/dist/ui/overlay/impl/projects-overlay-v2.js +499 -0
  241. package/dist/ui/overlay/impl/theme-overlay-v2.d.ts +42 -0
  242. package/dist/ui/overlay/impl/theme-overlay-v2.js +135 -0
  243. package/dist/ui/overlay/impl/tools-overlay-v2.d.ts +47 -0
  244. package/dist/ui/overlay/impl/tools-overlay-v2.js +218 -0
  245. package/dist/ui/overlay/impl/tutorial-overlay-v2.d.ts +31 -0
  246. package/dist/ui/overlay/impl/tutorial-overlay-v2.js +1035 -0
  247. package/dist/ui/overlay/impl/workflow-overlay-v2.d.ts +80 -0
  248. package/dist/ui/overlay/impl/workflow-overlay-v2.js +637 -0
  249. package/dist/ui/overlay/index.d.ts +33 -0
  250. package/dist/ui/overlay/index.js +35 -0
  251. package/dist/ui/overlay/key-utils.d.ts +6 -0
  252. package/dist/ui/overlay/key-utils.js +6 -0
  253. package/dist/ui/overlay/overlay-types.d.ts +128 -0
  254. package/dist/ui/overlay/overlay-types.js +22 -0
  255. package/dist/ui/overlay/types.d.ts +135 -0
  256. package/dist/ui/overlay/types.js +22 -0
  257. package/dist/ui/overlays/help-overlay-v2.d.ts +28 -0
  258. package/dist/ui/overlays/help-overlay-v2.js +198 -0
  259. package/dist/ui/overlays/index.d.ts +11 -0
  260. package/dist/ui/overlays/index.js +11 -0
  261. package/dist/ui/overlays.d.ts +0 -4
  262. package/dist/ui/overlays.js +0 -444
  263. package/dist/ui/permission-overlay-v2.d.ts +36 -0
  264. package/dist/ui/permission-overlay-v2.js +380 -0
  265. package/dist/ui/permission-overlay.d.ts +1 -1
  266. package/dist/ui/permission-overlay.js +186 -298
  267. package/dist/ui/projects-overlay.d.ts +19 -0
  268. package/dist/ui/projects-overlay.js +484 -0
  269. package/dist/ui/providers/types.d.ts +178 -0
  270. package/dist/ui/providers/types.js +9 -0
  271. package/dist/ui/render-modes.d.ts +36 -0
  272. package/dist/ui/render-modes.js +44 -0
  273. package/dist/ui/startup-menu.d.ts +36 -0
  274. package/dist/ui/startup-menu.js +236 -0
  275. package/dist/ui/subagent-renderer.d.ts +117 -0
  276. package/dist/ui/subagent-renderer.js +334 -0
  277. package/dist/ui/terminal-codes.d.ts +94 -0
  278. package/dist/ui/terminal-codes.js +124 -0
  279. package/dist/ui/terminal-renderer.d.ts +221 -0
  280. package/dist/ui/terminal-renderer.js +751 -0
  281. package/dist/ui/terminal-ui.d.ts +463 -0
  282. package/dist/ui/terminal-ui.js +2296 -0
  283. package/dist/ui/terminal.d.ts +20 -0
  284. package/dist/ui/terminal.js +72 -0
  285. package/dist/ui/theme-overlay-v2.d.ts +42 -0
  286. package/dist/ui/theme-overlay-v2.js +135 -0
  287. package/dist/ui/theme-overlay.d.ts +24 -0
  288. package/dist/ui/theme-overlay.js +127 -0
  289. package/dist/ui/todo-zone.js +53 -25
  290. package/dist/ui/tool-formatters.d.ts +16 -0
  291. package/dist/ui/tool-formatters.js +516 -0
  292. package/dist/ui/tools-overlay-v2.d.ts +47 -0
  293. package/dist/ui/tools-overlay-v2.js +218 -0
  294. package/dist/ui/tools-overlay.d.ts +10 -2
  295. package/dist/ui/tools-overlay.js +172 -220
  296. package/dist/ui/tutorial-overlay-v2.d.ts +31 -0
  297. package/dist/ui/tutorial-overlay-v2.js +1035 -0
  298. package/dist/ui/tutorial-overlay.d.ts +1 -0
  299. package/dist/ui/tutorial-overlay.js +400 -302
  300. package/dist/ui/workflow-overlay.d.ts +22 -0
  301. package/dist/ui/workflow-overlay.js +636 -0
  302. package/dist/utils/debug-log.d.ts +28 -0
  303. package/dist/utils/debug-log.js +57 -0
  304. package/dist/utils/model-tiers.js +1 -1
  305. package/dist/utils/path-safety.d.ts +56 -0
  306. package/dist/utils/path-safety.js +239 -0
  307. package/dist/workflow/guided-mode-injector.d.ts +42 -0
  308. package/dist/workflow/guided-mode-injector.js +191 -0
  309. package/dist/workflow/index.d.ts +8 -0
  310. package/dist/workflow/index.js +8 -0
  311. package/dist/workflow/step-criteria.d.ts +62 -0
  312. package/dist/workflow/step-criteria.js +150 -0
  313. package/dist/workflow/step-tracker.d.ts +92 -0
  314. package/dist/workflow/step-tracker.js +141 -0
  315. package/package.json +12 -5
@@ -2,81 +2,160 @@
2
2
  * Conversation Renderer
3
3
  *
4
4
  * Handles the scrolling zone - prints conversation messages.
5
- * Uses console.log() which naturally scrolls content up.
5
+ * When TerminalRenderer is connected (scroll region mode), uses appendToScrollZone().
6
+ * Otherwise falls back to console.log() for legacy mode.
6
7
  */
7
- import chalk, { Chalk } from 'chalk';
8
+ import { Chalk } from 'chalk';
8
9
  import { marked } from 'marked';
9
10
  import { markedTerminal } from 'marked-terminal';
10
11
  import { highlight } from 'cli-highlight';
11
12
  import { getStyles } from '../themes/index.js';
13
+ import { getThemeColors } from '../themes/index.js';
12
14
  import * as terminal from './terminal.js';
13
- import { isVerboseEnabled } from '../settings/index.js';
15
+ import { isVerboseEnabled, getMascotSetting } from '../settings/index.js';
14
16
  import { detectProjectStatus, getWorkflowStage } from '../utils/project-status.js';
17
+ import { renderMascotWithLogo } from './mascot/index.js';
18
+ // =============================================================================
19
+ // Renderer Integration
20
+ // =============================================================================
21
+ /** Module-level renderer reference for scroll region mode */
22
+ let rendererInstance = null;
23
+ /**
24
+ * Set the TerminalRenderer instance for scroll region output
25
+ * When set, output goes through renderer.appendToScrollZone()
26
+ * When null, falls back to console.log (legacy mode)
27
+ */
28
+ export function setRenderer(renderer) {
29
+ rendererInstance = renderer;
30
+ }
31
+ /**
32
+ * Get the current renderer instance
33
+ */
34
+ export function getRenderer() {
35
+ return rendererInstance;
36
+ }
37
+ /**
38
+ * Output lines to the scroll zone
39
+ * Uses renderer if connected (scroll region mode), otherwise console.log
40
+ */
41
+ function outputLines(lines) {
42
+ if (rendererInstance) {
43
+ rendererInstance.appendToScrollZone(lines);
44
+ }
45
+ else {
46
+ for (const line of lines) {
47
+ console.log(line);
48
+ }
49
+ }
50
+ }
51
+ /**
52
+ * Output a single line to the scroll zone
53
+ */
54
+ function outputLine(line) {
55
+ outputLines([line]);
56
+ }
15
57
  // Create chalk instance with colors forced on for our direct usage
16
58
  // Note: FORCE_COLOR=3 is set in index.ts for global chalk-based libraries
17
59
  const chalkWithColors = new Chalk({ level: 3 });
18
- // Configure marked for terminal output
19
- // Type assertion is needed because markedTerminal returns a type incompatible with marked's extension type
20
- // but it works correctly at runtime. This is a known issue with the marked-terminal types.
21
- marked.use(markedTerminal({
22
- reflowText: true,
23
- width: process.stdout.columns || 80,
24
- // Enable styling options
25
- showSectionPrefix: false,
26
- tab: 2,
27
- // Use our chalk instance with colors forced on
28
- // marked-terminal uses these for inline formatting
29
- strong: chalkWithColors.bold,
30
- em: chalkWithColors.italic,
31
- codespan: chalkWithColors.cyan,
32
- }));
60
+ // =============================================================================
61
+ // Theme-Aware Markdown Options (using markedTerminal)
62
+ // =============================================================================
63
+ /**
64
+ * Get markedTerminal options configured with current theme colors.
65
+ */
66
+ function getThemedMarkedOptions() {
67
+ const colors = getThemeColors();
68
+ const chalk = new Chalk({ level: 3 });
69
+ // Create chalk instances with theme colors
70
+ const primaryColor = chalk.hex(colors.primary);
71
+ const secondaryColor = chalk.hex(colors.secondary || colors.primary);
72
+ const fgColor = chalk.hex(colors.foreground);
73
+ const mutedColor = chalk.hex(colors.muted);
74
+ const borderColor = chalk.hex(colors.border);
75
+ return {
76
+ reflowText: true,
77
+ width: Math.min(100, terminal.getTerminalWidth() - 4),
78
+ unescape: true,
79
+ tab: 2,
80
+ showSectionPrefix: false,
81
+ // Theme-aware styling
82
+ heading: primaryColor.bold,
83
+ firstHeading: primaryColor.bold,
84
+ strong: fgColor.bold,
85
+ em: fgColor.italic,
86
+ link: secondaryColor,
87
+ href: secondaryColor.underline,
88
+ blockquote: mutedColor.italic,
89
+ del: mutedColor.strikethrough,
90
+ hr: borderColor,
91
+ codespan: primaryColor,
92
+ code: secondaryColor,
93
+ html: mutedColor,
94
+ table: fgColor,
95
+ listitem: fgColor,
96
+ paragraph: fgColor,
97
+ tableOptions: {
98
+ style: { head: ['bold'], border: [] },
99
+ chars: {
100
+ 'top': '─', 'top-mid': '─', 'top-left': '─', 'top-right': '─',
101
+ 'bottom': '─', 'bottom-mid': '─', 'bottom-left': '─', 'bottom-right': '─',
102
+ 'left': ' ', 'left-mid': ' ', 'mid': '─', 'mid-mid': '─',
103
+ 'right': ' ', 'right-mid': ' ', 'middle': ' ',
104
+ },
105
+ },
106
+ };
107
+ }
108
+ /**
109
+ * Preprocess markdown before parsing.
110
+ */
111
+ function preprocessMarkdown(content) {
112
+ const lines = content.split('\n');
113
+ return lines.map((line) => {
114
+ // Normalize bullet lists: "* " -> "- "
115
+ if (/^\s*\* /.test(line)) {
116
+ return line.replace(/^(\s*)\* /, '$1- ');
117
+ }
118
+ return line;
119
+ }).join('\n');
120
+ }
121
+ /**
122
+ * Post-process to catch formatting that markedTerminal missed.
123
+ * Handles: **bold**, `code`, and **`bold code`** patterns.
124
+ */
125
+ function postProcessFormatting(text) {
126
+ const chalk = new Chalk({ level: 3 });
127
+ const colors = getThemeColors();
128
+ const primary = chalk.hex(colors.primary);
129
+ let result = text;
130
+ // Handle **`code`** (bold code) - common pattern in tool docs
131
+ result = result.replace(/\*\*`([^`]+)`\*\*/g, (_match, code) => chalk.bold(primary(code)));
132
+ // Handle remaining `code` spans
133
+ result = result.replace(/`([^`]+)`/g, (_match, code) => primary(code));
134
+ // Handle remaining **bold**
135
+ result = result.replace(/\*\*([^*]+)\*\*/g, (_match, content) => chalk.bold(content));
136
+ return result;
137
+ }
33
138
  // =============================================================================
34
139
  // Markdown Rendering
35
140
  // =============================================================================
36
141
  /**
37
- * Render markdown text for terminal display
142
+ * Render markdown text for terminal display with theme colors.
143
+ * Uses markedTerminal with theme-aware options.
38
144
  */
39
145
  export function renderMarkdown(text) {
40
146
  try {
41
- // Preprocess: normalize list markers and indentation
42
- const lines = text.split('\n');
43
- const processedLines = lines.map((line) => {
44
- // Normalize bullet lists: "* " or "- " -> "- "
45
- // This prevents the asterisk from being confused with italic
46
- if (/^\*\s{2,}/.test(line)) {
47
- return line.replace(/^\*\s{2,}/, '- ');
48
- }
49
- // Remove leading 4 spaces that would make it a code block
50
- // But preserve intentional code blocks (``` fenced)
51
- if (line.startsWith(' ') && !line.startsWith(' ```')) {
52
- return line.slice(4);
53
- }
54
- return line;
55
- });
56
- const processed = processedLines.join('\n');
57
- // marked.parse returns string synchronously with these options
58
- let rendered = marked.parse(processed, { async: false });
59
- // Post-process: marked-terminal doesn't always render bold/italic inside list items
60
- // Convert remaining **bold** and *italic* to ANSI codes
61
- // Use chalkWithColors to ensure ANSI codes are always generated
62
- const s = getStyles();
63
- // Handle **`code`** (bold code) - common pattern
64
- rendered = rendered.replace(/\*\*`([^`]+)`\*\*/g, (_match, code) => chalkWithColors.bold(s.primary(code)));
65
- // Handle `code` inside **bold** - e.g., **some `code` here**
66
- rendered = rendered.replace(/\*\*([^*]*)`([^`]+)`([^*]*)\*\*/g, (_match, before, code, after) => chalkWithColors.bold(`${before}${s.primary(code)}${after}`));
67
- // Handle **bold** (not already processed)
68
- rendered = rendered.replace(/\*\*([^*]+)\*\*/g, (_match, boldText) => chalkWithColors.bold(boldText));
69
- // Handle *italic* - must not be at start of line (bullet) and not part of **
70
- // Match *text* but not * (bullet with spaces) and not **
71
- rendered = rendered.replace(/(?<![*\n])\*([^*\s][^*]*[^*\s])\*(?!\*)/g, (_match, italicText) => chalkWithColors.italic(italicText));
72
- // Also handle single-word italic: *word*
73
- rendered = rendered.replace(/(?<![*\n])\*(\S+)\*(?!\*)/g, (_match, word) => chalkWithColors.italic(word));
74
- // Handle `code` (inline code) - use theme primary color
75
- rendered = rendered.replace(/`([^`]+)`/g, (_match, code) => s.primary(code));
76
- // Handle numbered lists that weren't processed (e.g., "1. text")
77
- rendered = rendered.replace(/^(\d+)\.\s{2,}/gm, (_match, num) => chalkWithColors.bold(`${num}. `));
78
- // Remove trailing newlines that marked adds
79
- return rendered.replace(/\n+$/, '');
147
+ // Preprocess markdown
148
+ const preprocessed = preprocessMarkdown(text);
149
+ // Configure marked with theme-aware options
150
+ const options = getThemedMarkedOptions();
151
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
152
+ marked.use(markedTerminal(options));
153
+ // Parse
154
+ const rendered = marked.parse(preprocessed, { async: false });
155
+ // Post-process for any remaining formatting that markedTerminal missed
156
+ const postProcessed = postProcessFormatting(rendered);
157
+ // Remove excessive trailing newlines
158
+ return postProcessed.replace(/\n{3,}/g, '\n\n').replace(/\n+$/, '');
80
159
  }
81
160
  catch {
82
161
  return text; // Fallback to raw text
@@ -132,6 +211,20 @@ export function formatToolResult(result) {
132
211
  if (result === null || result === undefined) {
133
212
  return '';
134
213
  }
214
+ // DEBUG: Log type to understand what's coming in (uncomment if needed)
215
+ // console.error(`[DEBUG formatToolResult] type=${typeof result}, isArray=${Array.isArray(result)}, preview=${String(result).slice(0, 100)}`);
216
+ // Handle JSON strings - parse and format as object
217
+ if (typeof result === 'string' && (result.startsWith('{') || result.startsWith('['))) {
218
+ try {
219
+ const parsed = JSON.parse(result);
220
+ if (typeof parsed === 'object' && parsed !== null) {
221
+ return formatToolResult(parsed); // Recursively format the parsed object
222
+ }
223
+ }
224
+ catch {
225
+ // Not valid JSON, continue with string handling
226
+ }
227
+ }
135
228
  // String result - count lines or truncate
136
229
  if (typeof result === 'string') {
137
230
  const allLines = result.split('\n');
@@ -214,6 +307,40 @@ export function formatToolResult(result) {
214
307
  const branches = obj.branches;
215
308
  return s.muted(`${String(branches?.length ?? 0)} branches`);
216
309
  }
310
+ // Backlog/workitem pattern - { items: [...], total: N, filtered: N }
311
+ if ('items' in obj && Array.isArray(obj.items) && 'total' in obj) {
312
+ const items = obj.items;
313
+ const total = obj.total;
314
+ const filtered = 'filtered' in obj ? obj.filtered : items.length;
315
+ if (items.length === 0) {
316
+ return s.muted('no items');
317
+ }
318
+ if (verbose) {
319
+ // Verbose mode: show item summaries
320
+ const lines = [];
321
+ const maxItems = Math.min(items.length, 10);
322
+ for (let i = 0; i < maxItems; i++) {
323
+ const item = items[i];
324
+ const id = item.id || '?';
325
+ const title = (item.title || 'Untitled').slice(0, 50);
326
+ const status = item.status || '?';
327
+ const priority = item.priority ? `[${item.priority}]` : '';
328
+ lines.push(` ${id}: ${title} (${status}) ${priority}`);
329
+ }
330
+ if (items.length > maxItems) {
331
+ lines.push(` ... and ${String(items.length - maxItems)} more`);
332
+ }
333
+ const summary = filtered < total
334
+ ? `${String(filtered)} of ${String(total)} items:`
335
+ : `${String(total)} items:`;
336
+ return s.muted(summary + '\n' + lines.join('\n'));
337
+ }
338
+ // Non-verbose: show count summary
339
+ const summary = filtered < total
340
+ ? `${String(filtered)} of ${String(total)} items`
341
+ : `${String(total)} items`;
342
+ return s.muted(summary);
343
+ }
217
344
  // File read pattern
218
345
  if ('content' in obj) {
219
346
  const content = String(obj.content);
@@ -281,28 +408,122 @@ export function formatToolResult(result) {
281
408
  return s.muted(resultStr.slice(0, 60));
282
409
  }
283
410
  // =============================================================================
284
- // Message Printing
411
+ // Message Formatting (return string[] for TerminalRenderer)
412
+ // =============================================================================
413
+ /**
414
+ * Format user message for display
415
+ * Returns: [primary "❯ " + message content, ""]
416
+ */
417
+ export function formatUserMessage(content) {
418
+ const s = getStyles();
419
+ return [s.primary('❯ ') + content, ''];
420
+ }
421
+ /**
422
+ * Format assistant message for display
423
+ * Renders markdown (code blocks, bold, etc.)
424
+ */
425
+ export function formatAssistantMessage(content) {
426
+ if (!content.trim())
427
+ return [];
428
+ const s = getStyles();
429
+ const lines = [];
430
+ lines.push(s.success('Agent: '));
431
+ lines.push(renderMarkdown(content));
432
+ lines.push('');
433
+ return lines;
434
+ }
435
+ /**
436
+ * Format assistant response (event-based rendering)
437
+ * Used when text is accumulated between tool calls.
438
+ */
439
+ export function formatAssistantResponse(content) {
440
+ if (!content.trim())
441
+ return [];
442
+ const s = getStyles();
443
+ const rendered = renderInlineMarkdown(content);
444
+ return [s.primary('● ') + rendered];
445
+ }
446
+ /**
447
+ * Format tool execution for display
448
+ */
449
+ export function formatToolExecution(name, args, result) {
450
+ const s = getStyles();
451
+ const verbose = isVerboseEnabled();
452
+ const lines = [];
453
+ let displayArgs = args;
454
+ if (args && !verbose && args.length > 60) {
455
+ displayArgs = args.slice(0, 57) + '...';
456
+ }
457
+ const toolHeader = displayArgs
458
+ ? s.warning(`● ${name}`) + s.secondary(`(${displayArgs})`)
459
+ : s.warning(`● ${name}`);
460
+ lines.push(toolHeader);
461
+ if (result) {
462
+ lines.push(s.muted(' ⎿ ') + result);
463
+ }
464
+ lines.push('');
465
+ return lines;
466
+ }
467
+ /**
468
+ * Format sub-agent completion summary
469
+ */
470
+ export function formatSubagentResponse(stats) {
471
+ const s = getStyles();
472
+ const lines = [];
473
+ const typeLabel = stats.type.charAt(0).toUpperCase() + stats.type.slice(1);
474
+ lines.push(s.primary(`● ${typeLabel}(${stats.description})`));
475
+ const duration = formatDuration(stats.durationMs);
476
+ const tokens = formatTokens(stats.tokenCount);
477
+ const toolUses = stats.toolCount === 1 ? '1 tool use' : `${String(stats.toolCount)} tool uses`;
478
+ const statsLine = `${toolUses} · ${tokens} tokens · ${duration}`;
479
+ lines.push(s.muted(` ⎿ Done (${statsLine})`));
480
+ lines.push('');
481
+ return lines;
482
+ }
483
+ /**
484
+ * Format error message
485
+ */
486
+ export function formatError(message) {
487
+ const s = getStyles();
488
+ return [s.error('✖ ') + message, ''];
489
+ }
490
+ /**
491
+ * Format info message
492
+ */
493
+ export function formatInfo(message) {
494
+ const s = getStyles();
495
+ return [s.muted(message)];
496
+ }
497
+ /**
498
+ * Format success message
499
+ */
500
+ export function formatSuccess(message) {
501
+ const s = getStyles();
502
+ return [s.success('✔ ') + message, ''];
503
+ }
504
+ /**
505
+ * Format warning message
506
+ */
507
+ export function formatWarning(message) {
508
+ const s = getStyles();
509
+ return [s.warning('⚠ ') + message, ''];
510
+ }
511
+ // =============================================================================
512
+ // Message Printing (wrappers for backward compatibility)
285
513
  // =============================================================================
286
514
  /**
287
515
  * Print user message to conversation
288
516
  * Format: primary "❯ " + message content
289
517
  */
290
518
  export function printUserMessage(content) {
291
- const s = getStyles();
292
- console.log(s.primary('❯ ') + content);
293
- console.log(''); // Blank line after
519
+ outputLines(formatUserMessage(content));
294
520
  }
295
521
  /**
296
522
  * Print assistant message to conversation
297
523
  * Renders markdown (code blocks, bold, etc.)
298
524
  */
299
525
  export function printAssistantMessage(content) {
300
- if (!content.trim())
301
- return;
302
- const s = getStyles();
303
- console.log(s.success('Agent: '));
304
- console.log(renderMarkdown(content));
305
- console.log(''); // Blank line after
526
+ outputLines(formatAssistantMessage(content));
306
527
  }
307
528
  /**
308
529
  * Print assistant response (event-based rendering)
@@ -310,13 +531,7 @@ export function printAssistantMessage(content) {
310
531
  * Format: "● " prefix + rendered markdown with syntax highlighting
311
532
  */
312
533
  export function printAssistantResponse(content) {
313
- if (!content.trim())
314
- return;
315
- const s = getStyles();
316
- // Use bullet prefix (consistent with tool output style)
317
- // Apply renderInlineMarkdown which handles code blocks with syntax highlighting
318
- const rendered = renderInlineMarkdown(content);
319
- console.log(s.primary('● ') + rendered);
534
+ outputLines(formatAssistantResponse(content));
320
535
  }
321
536
  /**
322
537
  * Print tool execution log
@@ -324,75 +539,72 @@ export function printAssistantResponse(content) {
324
539
  * When verbose mode is enabled, shows full args
325
540
  */
326
541
  export function printToolLog(tool) {
327
- const s = getStyles();
328
- const verbose = isVerboseEnabled();
329
- // In verbose mode, show full args; otherwise truncate
330
- let displayArgs = tool.args;
331
- if (tool.args && !verbose && tool.args.length > 60) {
332
- displayArgs = tool.args.slice(0, 57) + '...';
333
- }
334
- const toolHeader = displayArgs
335
- ? s.warning(`● ${tool.name}`) + s.secondary(`(${displayArgs})`)
336
- : s.warning(`● ${tool.name}`);
337
- console.log(toolHeader);
338
- if (tool.result) {
339
- console.log(s.muted(' ⎿ ') + tool.result);
340
- }
341
- console.log(''); // Blank line after
542
+ outputLines(formatToolExecution(tool.name, tool.args, tool.result));
342
543
  }
343
544
  /**
344
545
  * Print tool execution inline (without creating ToolMessage)
345
546
  * When verbose mode is enabled, shows full args instead of truncated
346
547
  */
347
548
  export function printToolExecution(name, args, result) {
348
- const s = getStyles();
349
- const verbose = isVerboseEnabled();
350
- // In verbose mode, show full args; otherwise truncate
351
- let displayArgs = args;
352
- if (args && !verbose && args.length > 60) {
353
- displayArgs = args.slice(0, 57) + '...';
549
+ outputLines(formatToolExecution(name, args, result));
550
+ }
551
+ /**
552
+ * Format duration in human-readable format (e.g., "1m 23s", "45s", "19.2s")
553
+ */
554
+ function formatDuration(ms) {
555
+ const seconds = ms / 1000;
556
+ if (seconds < 60) {
557
+ return seconds < 10 ? `${seconds.toFixed(1)}s` : `${String(Math.floor(seconds))}s`;
354
558
  }
355
- const toolHeader = displayArgs
356
- ? s.warning(`● ${name}`) + s.secondary(`(${displayArgs})`)
357
- : s.warning(`● ${name}`);
358
- console.log(toolHeader);
359
- if (result) {
360
- console.log(s.muted(' ⎿ ') + result);
559
+ const minutes = Math.floor(seconds / 60);
560
+ const remainingSeconds = Math.floor(seconds % 60);
561
+ return `${String(minutes)}m ${String(remainingSeconds)}s`;
562
+ }
563
+ /**
564
+ * Format token count (e.g., "18.1k", "500")
565
+ */
566
+ function formatTokens(tokens) {
567
+ if (tokens >= 1000) {
568
+ return `${(tokens / 1000).toFixed(1)}k`;
361
569
  }
362
- console.log(''); // Blank line after
570
+ return tokens.toString();
571
+ }
572
+ /**
573
+ * Print sub-agent completion summary
574
+ * Format matches the footer's subagent zone when done:
575
+ * ● Explore(Find CLI entry points)
576
+ * ⎿ Done (6 tool uses · 38.8k tokens · 19s)
577
+ */
578
+ export function printSubagentResponse(stats) {
579
+ outputLines(formatSubagentResponse(stats));
363
580
  }
364
581
  /**
365
582
  * Print error message
366
583
  * Format: error "✖ " + message
367
584
  */
368
585
  export function printError(message) {
369
- const s = getStyles();
370
- console.log(s.error('✖ ') + message);
371
- console.log('');
586
+ outputLines(formatError(message));
372
587
  }
373
588
  /**
374
589
  * Print info message
375
590
  * Format: muted text
376
591
  */
377
592
  export function printInfo(message) {
378
- const s = getStyles();
379
- console.log(s.muted(message));
593
+ outputLines(formatInfo(message));
380
594
  }
381
595
  /**
382
596
  * Print success message
383
597
  * Format: success "✔ " + message
384
598
  */
385
599
  export function printSuccess(message) {
386
- const s = getStyles();
387
- console.log(s.success('✔ ') + message);
600
+ outputLines(formatSuccess(message));
388
601
  }
389
602
  /**
390
603
  * Print warning message
391
604
  * Format: warning "⚠ " + message
392
605
  */
393
606
  export function printWarning(message) {
394
- const s = getStyles();
395
- console.log(s.warning('⚠ ') + message);
607
+ outputLines(formatWarning(message));
396
608
  }
397
609
  // =============================================================================
398
610
  // Welcome Banner
@@ -400,43 +612,34 @@ export function printWarning(message) {
400
612
  /**
401
613
  * Print just the ASCII logo (for startup before full welcome)
402
614
  */
403
- export function printLogo(version) {
404
- const s = getStyles();
615
+ export function printLogo(version, projectName) {
405
616
  terminal.clearScreen();
406
- console.log('');
407
- console.log(s.primary(" ___ ___ _ __ ___ _ __ (_) |_ __"));
408
- console.log(s.primary(" / __|/ _ \\| '_ ` _ \\| '_ \\| | | '__|"));
409
- console.log(s.primary(" | (__| (_) | | | | | | |_) | | | |"));
410
- console.log(s.primary(" \\___|\\___/|_| |_| |_| .__/|_|_|_|"));
411
- console.log(s.primary(' | |') + s.secondary(' .dev'));
412
- console.log(s.primary(' |_|') + s.muted(` v${version}`));
413
- console.log('');
414
- console.log(chalk.bold('@compilr-dev/cli') + s.muted(' - AI-powered coding assistant'));
415
- console.log('');
617
+ outputLine('');
618
+ // Get mascot setting and render mascot + logo
619
+ const mascotSetting = getMascotSetting();
620
+ const lines = renderMascotWithLogo(mascotSetting, version, projectName);
621
+ outputLines(lines);
622
+ outputLine('');
416
623
  }
417
624
  /**
418
625
  * Print welcome banner with ASCII logo and contextual guidance
419
626
  */
420
- export function printWelcome(model, version) {
627
+ export function printWelcome(model, version, projectName) {
421
628
  const s = getStyles();
422
- console.log('');
423
- console.log(s.primary(" ___ ___ _ __ ___ _ __ (_) |_ __"));
424
- console.log(s.primary(" / __|/ _ \\| '_ ` _ \\| '_ \\| | | '__|"));
425
- console.log(s.primary(" | (__| (_) | | | | | | |_) | | | |"));
426
- console.log(s.primary(" \\___|\\___/|_| |_| |_| .__/|_|_|_|"));
427
- console.log(s.primary(' | |') + s.secondary(' .dev'));
428
- console.log(s.primary(' |_|') + s.muted(` v${version}`));
429
- console.log('');
430
- console.log(chalk.bold('@compilr-dev/cli') + s.muted(' - AI-powered coding assistant'));
431
- console.log('');
432
- console.log(s.muted(`Model: ${model}`));
433
- console.log('');
629
+ outputLine('');
630
+ // Get mascot setting and render mascot + logo
631
+ const mascotSetting = getMascotSetting();
632
+ const lines = renderMascotWithLogo(mascotSetting, version, projectName);
633
+ outputLines(lines);
634
+ outputLine('');
635
+ outputLine(s.muted(`Model: ${model}`));
636
+ outputLine('');
434
637
  // Detect project status and show contextual guidance
435
638
  const status = detectProjectStatus();
436
639
  const stage = getWorkflowStage(status);
437
640
  printWorkflowGuidance(status, stage);
438
- console.log(s.muted('Type /help for commands, /exit to quit'));
439
- console.log('');
641
+ outputLine(s.muted('Type /help for commands, /exit to quit'));
642
+ outputLine('');
440
643
  }
441
644
  /**
442
645
  * Print workflow guidance based on project status
@@ -446,28 +649,34 @@ function printWorkflowGuidance(status, stage) {
446
649
  switch (stage) {
447
650
  case 'new':
448
651
  // Brand new directory, nothing exists
449
- console.log(s.muted('Get started:'));
450
- console.log(s.muted(' /init ') + s.secondary('Create project structure'));
451
- console.log(s.muted(' /sketch ') + s.secondary('Quick 6-question outline'));
452
- console.log(s.muted(' /tutorial ') + s.secondary('Learn the workflow'));
453
- console.log('');
652
+ outputLines([
653
+ s.muted('Get started:'),
654
+ s.muted(' /new ') + s.secondary('Create project structure'),
655
+ s.muted(' /sketch ') + s.secondary('Quick 6-question outline'),
656
+ s.muted(' /tutorial ') + s.secondary('Learn the workflow'),
657
+ '',
658
+ ]);
454
659
  break;
455
660
  case 'initialized':
456
661
  // Existing project, but no compilr setup
457
662
  if (status.isExistingProject && !status.hasMemory) {
458
- console.log(s.muted(`Detected ${status.projectType || 'existing'} project. Define requirements:`));
459
- console.log(s.muted(' /design ') + s.secondary('Agent-driven requirements'));
460
- console.log(s.muted(' /sketch ') + s.secondary('Quick project outline'));
461
- console.log(s.muted(' /tutorial ') + s.secondary('Learn the workflow'));
462
- console.log('');
663
+ outputLines([
664
+ s.muted(`Detected ${status.projectType || 'existing'} project. Define requirements:`),
665
+ s.muted(' /design ') + s.secondary('Agent-driven requirements'),
666
+ s.muted(' /sketch ') + s.secondary('Quick project outline'),
667
+ s.muted(' /tutorial ') + s.secondary('Learn the workflow'),
668
+ '',
669
+ ]);
463
670
  }
464
671
  break;
465
672
  case 'designing':
466
673
  // Has PRD or initialized, but no backlog yet
467
- console.log(s.muted('Project initialized. Create your backlog:'));
468
- console.log(s.muted(' /design ') + s.secondary('Refine requirements'));
469
- console.log(s.muted(' /backlog ') + s.secondary('View/manage tasks'));
470
- console.log('');
674
+ outputLines([
675
+ s.muted('Project initialized. Create your backlog:'),
676
+ s.muted(' /design ') + s.secondary('Refine requirements'),
677
+ s.muted(' /backlog ') + s.secondary('View/manage tasks'),
678
+ '',
679
+ ]);
471
680
  break;
472
681
  case 'building':
473
682
  // Has backlog with pending items
@@ -476,20 +685,24 @@ function printWorkflowGuidance(status, stage) {
476
685
  const taskInfo = inProgress > 0
477
686
  ? `${String(inProgress)} in progress, ${String(pending)} pending`
478
687
  : `${String(pending)} tasks pending`;
479
- console.log(s.muted(`Backlog: ${taskInfo}`));
480
- console.log(s.muted(' /backlog ') + s.secondary('View tasks'));
481
- console.log(s.muted(' "build next item" ') + s.secondary('Start working'));
482
- console.log('');
688
+ outputLines([
689
+ s.muted(`Backlog: ${taskInfo}`),
690
+ s.muted(' /backlog ') + s.secondary('View tasks'),
691
+ s.muted(' "build next item" ') + s.secondary('Start working'),
692
+ '',
693
+ ]);
483
694
  }
484
695
  break;
485
696
  case 'maintaining':
486
697
  // Most items completed
487
698
  if (status.backlogStats) {
488
699
  const { total, completed } = status.backlogStats;
489
- console.log(s.muted(`Backlog: ${String(completed)}/${String(total)} completed`));
490
- console.log(s.muted(' /backlog ') + s.secondary('View tasks'));
491
- console.log(s.muted(' /refine ') + s.secondary('Add new requirements'));
492
- console.log('');
700
+ outputLines([
701
+ s.muted(`Backlog: ${String(completed)}/${String(total)} completed`),
702
+ s.muted(' /backlog ') + s.secondary('View tasks'),
703
+ s.muted(' /refine ') + s.secondary('Add new requirements'),
704
+ '',
705
+ ]);
493
706
  }
494
707
  break;
495
708
  }