@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
@@ -0,0 +1,814 @@
1
+ /**
2
+ * Project Commands for REPL V2
3
+ *
4
+ * Commands for project management: init, backlog, workflow, anchors, design, sketch, refine
5
+ */
6
+ import { executeCommand } from '../registry.js';
7
+ import { BacklogOverlayV2, WorkflowOverlayV2, DocsOverlayV2, DocumentDetailOverlayV2, AnchorsOverlayV2, ProjectsOverlayV2, NewProjectOverlayV2, InitSetupOverlayV2, ArchTypeOverlayV2, ModelWarningOverlayV2 } from '../../ui/overlay/index.js';
8
+ import { projectRepository, workItemRepository } from '../../db/repositories/index.js';
9
+ import { setCurrentProject, getCurrentProject } from '../../tools/project-db.js';
10
+ import { getSkillPrompt } from '../../repl-helpers.js';
11
+ import { getModelTier, modelMeetsTier } from '../../utils/model-tiers.js';
12
+ // =============================================================================
13
+ // Helper Functions
14
+ // =============================================================================
15
+ /**
16
+ * Sync the footer project name with the current project.
17
+ * Call after any overlay that might change the current project.
18
+ */
19
+ function syncFooterWithCurrentProject(ctx) {
20
+ const current = getCurrentProject();
21
+ ctx.ui.setProjectName(current?.displayName ?? null);
22
+ }
23
+ // =============================================================================
24
+ // New Command
25
+ // =============================================================================
26
+ export const newCommand = {
27
+ name: 'new',
28
+ description: 'Create a new project',
29
+ async execute(_args, ctx) {
30
+ const newProjectOverlay = new NewProjectOverlayV2();
31
+ const result = await ctx.ui.showOverlay(newProjectOverlay);
32
+ // User cancelled
33
+ if (!result?.created) {
34
+ return true;
35
+ }
36
+ // Project was created - show success messages
37
+ ctx.ui.print({ type: 'success', message: `Project created: ${result.projectPath ?? ''}` });
38
+ if (result.docsPath) {
39
+ ctx.ui.print({ type: 'success', message: `Docs repo created: ${result.docsPath}` });
40
+ }
41
+ // Register project in database if tracking is enabled
42
+ if (result.trackInDatabase && result.projectName && result.projectPath) {
43
+ try {
44
+ const project = projectRepository.create({
45
+ name: result.projectName,
46
+ display_name: result.projectName.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()),
47
+ description: result.description,
48
+ path: result.projectPath,
49
+ type: 'general',
50
+ workflow_mode: result.workflowMode ?? 'flexible',
51
+ });
52
+ setCurrentProject({ id: project.id, name: project.name, displayName: project.displayName, path: project.path });
53
+ ctx.ui.setProjectName(project.displayName);
54
+ ctx.ui.print({ type: 'success', message: `Project tracked in database (${result.workflowMode ?? 'flexible'} mode)` });
55
+ ctx.ui.print({ type: 'success', message: `"${project.displayName}" is now the current project` });
56
+ }
57
+ catch (dbError) {
58
+ ctx.ui.print({ type: 'warning', message: `Could not register in database: ${dbError.message}` });
59
+ }
60
+ }
61
+ // Show next steps
62
+ ctx.ui.print({ type: 'info', message: '' });
63
+ ctx.ui.print({ type: 'info', message: 'Next steps:' });
64
+ ctx.ui.print({ type: 'info', message: ` cd ${result.projectPath?.split('/').pop() ?? 'project'}` });
65
+ ctx.ui.print({ type: 'info', message: ' npm install' });
66
+ ctx.ui.print({ type: 'info', message: ' npm run dev' });
67
+ ctx.ui.print({ type: 'info', message: '' });
68
+ // Hint for agent interaction
69
+ const compilrMdPath = result.docsPath
70
+ ? `${result.docsPath}/COMPILR.md`
71
+ : `${result.projectPath ?? '.'}/COMPILR.md`;
72
+ ctx.ui.print({ type: 'info', message: `Tip: Ask the agent to read ${compilrMdPath} to get started!` });
73
+ ctx.ui.print({ type: 'info', message: 'When ready to define requirements, type /design' });
74
+ return true;
75
+ },
76
+ };
77
+ // =============================================================================
78
+ // Init Command (Setup Status Placeholder)
79
+ // =============================================================================
80
+ export const initCommand = {
81
+ name: 'init',
82
+ description: 'View CLI setup status',
83
+ async execute(_args, ctx) {
84
+ const initSetupOverlay = new InitSetupOverlayV2();
85
+ await ctx.ui.showOverlay(initSetupOverlay);
86
+ return true;
87
+ },
88
+ };
89
+ // =============================================================================
90
+ // Backlog Command
91
+ // =============================================================================
92
+ export const backlogCommand = {
93
+ name: 'backlog',
94
+ description: 'View and manage project backlog',
95
+ async execute(_args, ctx) {
96
+ const backlogOverlay = new BacklogOverlayV2();
97
+ const result = await ctx.ui.showOverlay(backlogOverlay);
98
+ if (result?.modified) {
99
+ ctx.ui.print({ type: 'success', message: 'Backlog updated.' });
100
+ }
101
+ return true;
102
+ },
103
+ };
104
+ // =============================================================================
105
+ // Workflow Command
106
+ // =============================================================================
107
+ export const workflowCommand = {
108
+ name: 'workflow',
109
+ description: 'View project workflow dashboard',
110
+ async execute(_args, ctx) {
111
+ const workflowOverlay = new WorkflowOverlayV2();
112
+ const result = await ctx.ui.showOverlay(workflowOverlay);
113
+ // Handle workflow result - execute command if returned
114
+ if (result?.command) {
115
+ // Strip leading slash and execute the command
116
+ const cmd = result.command.replace(/^\//, '');
117
+ await executeCommand(cmd, '', ctx);
118
+ }
119
+ // Sync footer with current project (may have changed during overlay)
120
+ syncFooterWithCurrentProject(ctx);
121
+ return true;
122
+ },
123
+ };
124
+ // =============================================================================
125
+ // Anchors Command
126
+ // =============================================================================
127
+ export const anchorsCommand = {
128
+ name: 'anchors',
129
+ description: 'View and manage anchors (persistent context)',
130
+ async execute(_args, ctx) {
131
+ const anchorsOverlay = new AnchorsOverlayV2();
132
+ const result = await ctx.ui.showOverlay(anchorsOverlay);
133
+ if (result?.modified) {
134
+ ctx.ui.print({ type: 'success', message: 'Anchors updated.' });
135
+ }
136
+ return true;
137
+ },
138
+ };
139
+ // =============================================================================
140
+ // Design Command
141
+ // =============================================================================
142
+ export const designCommand = {
143
+ name: 'design',
144
+ description: 'Agent-driven requirements gathering',
145
+ async execute(_args, ctx) {
146
+ // Check if a project is set
147
+ const currentProject = getCurrentProject();
148
+ if (!currentProject) {
149
+ ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
150
+ return true;
151
+ }
152
+ // Check model tier - /design works best with large models
153
+ const currentModel = ctx.model ?? 'unknown';
154
+ if (!modelMeetsTier(currentModel, '/design')) {
155
+ const modelTier = getModelTier(currentModel);
156
+ const warningOverlay = new ModelWarningOverlayV2({
157
+ command: '/design',
158
+ currentModel,
159
+ currentTier: modelTier.tier,
160
+ suggestedModel: modelTier.suggestedUpgrade,
161
+ alternativeCommand: '/sketch',
162
+ });
163
+ const choice = await ctx.ui.showOverlay(warningOverlay);
164
+ switch (choice) {
165
+ case 'cancel':
166
+ return true;
167
+ case 'alternative':
168
+ // Run /sketch instead
169
+ await executeCommand('sketch', '', ctx);
170
+ return true;
171
+ case 'switch':
172
+ // TODO: Hot-switch model when setModel is available in ctx
173
+ ctx.ui.print({ type: 'info', message: `Continuing with ${currentModel} (model switching not yet available in V2)` });
174
+ break;
175
+ case 'continue':
176
+ // Proceed with current model
177
+ break;
178
+ }
179
+ }
180
+ // Get design skill prompt
181
+ const designPrompt = getSkillPrompt('design');
182
+ if (!designPrompt) {
183
+ ctx.ui.print({ type: 'error', message: 'Design skill not found.' });
184
+ return true;
185
+ }
186
+ // Build full message for agent with project context
187
+ const fullMessage = `I want to design my project and create the backlog.
188
+
189
+ ## PROJECT CONTEXT (IMPORTANT)
190
+ - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
191
+ - This is a NEW project being designed from scratch
192
+ - Do NOT scan the filesystem - the current directory is NOT the project
193
+ - Do NOT use detect_project, glob, read_file, or ls tools
194
+ - Focus ONLY on gathering requirements via ask_user questions
195
+
196
+ ## DOCUMENT STORAGE (CRITICAL)
197
+ Save all documents and backlog items using the database - do NOT write files directly.
198
+ - For backlog items: \`workitem_add({ type: "feature", title: "...", description: "...", priority: "high" })\`
199
+ - For documents: \`project_document_add({ doc_type: "prd", title: "...", content: "..." })\`
200
+ - The database is the source of truth for all project documents
201
+ - Do NOT use write_file or edit tools for documentation
202
+
203
+ ${designPrompt}
204
+
205
+ Please start by using todo_write to track the design phases, then begin with Phase 1: Vision. Use the ask_user tool to gather information efficiently.`;
206
+ // Queue message for agent
207
+ ctx.queueAgentMessage({
208
+ message: fullMessage,
209
+ displayMessage: 'Start the design process for my project.',
210
+ });
211
+ return true;
212
+ },
213
+ };
214
+ // =============================================================================
215
+ // Sketch Command
216
+ // =============================================================================
217
+ export const sketchCommand = {
218
+ name: 'sketch',
219
+ description: 'Quick 6-question project outline',
220
+ execute(_args, ctx) {
221
+ // Check if a project is set
222
+ const currentProject = getCurrentProject();
223
+ if (!currentProject) {
224
+ ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
225
+ return Promise.resolve(true);
226
+ }
227
+ // Get sketch skill prompt
228
+ const sketchPrompt = getSkillPrompt('sketch');
229
+ if (!sketchPrompt) {
230
+ ctx.ui.print({ type: 'error', message: 'Sketch skill not found.' });
231
+ return Promise.resolve(true);
232
+ }
233
+ // Build full message for agent with project context
234
+ const fullMessage = `I want to quickly outline my project.
235
+
236
+ ## PROJECT CONTEXT (IMPORTANT)
237
+ - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
238
+ - This is a NEW project being designed from scratch
239
+ - Do NOT scan the filesystem - the current directory is NOT the project
240
+ - Do NOT use detect_project, glob, read_file, or ls tools
241
+ - Focus ONLY on gathering requirements via ask_user questions
242
+
243
+ ## DOCUMENT STORAGE (CRITICAL)
244
+ Save all documents and backlog items using the database - do NOT write files directly.
245
+ - For backlog items: \`workitem_add({ type: "feature", title: "...", description: "..." })\`
246
+ - For documents: \`project_document_add({ doc_type: "prd", title: "...", content: "..." })\`
247
+ - Do NOT use write_file or edit tools for documentation
248
+
249
+ ${sketchPrompt}
250
+
251
+ Please start by asking me about the type of application I'm building using the ask_user_simple tool.`;
252
+ // Queue message for agent
253
+ ctx.queueAgentMessage({
254
+ message: fullMessage,
255
+ displayMessage: 'Quick project outline.',
256
+ });
257
+ return Promise.resolve(true);
258
+ },
259
+ };
260
+ // =============================================================================
261
+ // Refine Command
262
+ // =============================================================================
263
+ export const refineCommand = {
264
+ name: 'refine',
265
+ description: 'Iterative refinement of requirements',
266
+ async execute(args, ctx) {
267
+ // Check if a project is set
268
+ const currentProject = getCurrentProject();
269
+ if (!currentProject) {
270
+ ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
271
+ return true;
272
+ }
273
+ // Check if project has work items in database
274
+ const counts = workItemRepository.getStatusCounts(currentProject.id);
275
+ const totalItems = counts.backlog + counts.in_progress + counts.completed + counts.skipped;
276
+ if (totalItems === 0) {
277
+ ctx.ui.print({ type: 'error', message: 'No backlog items found. Run /design first to create initial requirements.' });
278
+ return true;
279
+ }
280
+ // Check if a specific item ID was provided (e.g., /refine REQ-001)
281
+ const itemId = args.trim().toUpperCase();
282
+ const isFocusedRefine = itemId && /^[A-Z]+-\d{3}$/.test(itemId);
283
+ // For full refine mode (no item ID), check model tier and warn
284
+ if (!isFocusedRefine) {
285
+ const currentModel = ctx.model ?? 'unknown';
286
+ if (!modelMeetsTier(currentModel, '/refine')) {
287
+ const modelTier = getModelTier(currentModel);
288
+ const warningOverlay = new ModelWarningOverlayV2({
289
+ command: '/refine',
290
+ currentModel,
291
+ currentTier: modelTier.tier,
292
+ suggestedModel: modelTier.suggestedUpgrade,
293
+ alternativeCommand: '/refine <ITEM-ID>',
294
+ });
295
+ const choice = await ctx.ui.showOverlay(warningOverlay);
296
+ switch (choice) {
297
+ case 'cancel':
298
+ return true;
299
+ case 'alternative':
300
+ ctx.ui.print({ type: 'info', message: 'Tip: Use /refine <ITEM-ID> for focused refinement with smaller models.' });
301
+ ctx.ui.print({ type: 'info', message: ' Example: /refine REQ-001' });
302
+ return true;
303
+ case 'switch':
304
+ // TODO: Hot-switch model when setModel is available in ctx
305
+ ctx.ui.print({ type: 'info', message: `Continuing with ${currentModel} (model switching not yet available in V2)` });
306
+ break;
307
+ case 'continue':
308
+ break;
309
+ }
310
+ }
311
+ }
312
+ // Get appropriate skill prompt
313
+ const skillName = isFocusedRefine ? 'refine-item' : 'refine';
314
+ const refinePrompt = getSkillPrompt(skillName);
315
+ if (!refinePrompt) {
316
+ ctx.ui.print({ type: 'error', message: `${skillName} skill not found.` });
317
+ return true;
318
+ }
319
+ // Build message based on mode
320
+ const userIntent = isFocusedRefine
321
+ ? `I want to refine backlog item ${itemId}.`
322
+ : 'I want to refine my project requirements.';
323
+ const agentInstructions = isFocusedRefine
324
+ ? `Please use workitem_query to find item "${itemId}", then guide me through refining it using workitem_update.`
325
+ : 'Please start by using workitem_query with limit:10 to get an overview, then ask me what I\'d like to focus on using ask_user_simple.';
326
+ const fullMessage = `${userIntent}
327
+
328
+ ## PROJECT CONTEXT (IMPORTANT)
329
+ - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
330
+ - Do NOT scan the filesystem - the current directory is NOT the project
331
+ - Do NOT use detect_project, glob, read_file, or ls tools
332
+ - Use ONLY database tools to access project data
333
+
334
+ ## DOCUMENT STORAGE (CRITICAL)
335
+ Use database tools for all updates - do NOT write files directly.
336
+ - Use \`workitem_query\` to read items
337
+ - Use \`workitem_update\` to modify items
338
+ - Do NOT use write_file or edit tools
339
+
340
+ ${refinePrompt}
341
+
342
+ ${agentInstructions}`;
343
+ // Queue message for agent
344
+ ctx.queueAgentMessage({
345
+ message: fullMessage,
346
+ displayMessage: userIntent,
347
+ });
348
+ return true;
349
+ },
350
+ };
351
+ // =============================================================================
352
+ // Build Command
353
+ // =============================================================================
354
+ export const buildCommand = {
355
+ name: 'build',
356
+ description: 'Build a backlog item',
357
+ async execute(args, ctx) {
358
+ const argTrimmed = args.trim();
359
+ // Handle `/build scaffold` - redirect to scaffold command
360
+ if (argTrimmed.toLowerCase() === 'scaffold') {
361
+ await executeCommand('scaffold', '', ctx);
362
+ return true;
363
+ }
364
+ // Check if a project is set
365
+ const currentProject = getCurrentProject();
366
+ if (!currentProject) {
367
+ ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
368
+ return true;
369
+ }
370
+ // Check if project has a path set (REQUIRED for building)
371
+ if (!currentProject.path) {
372
+ ctx.ui.print({ type: 'error', message: 'Project path not set. Cannot build without a target directory.' });
373
+ ctx.ui.print({ type: 'info', message: 'Tip: Update the project path in /projects to specify where files should be created.' });
374
+ return true;
375
+ }
376
+ // Warn if cwd doesn't match project path (common source of confusion)
377
+ const buildCwd = process.cwd();
378
+ if (buildCwd !== currentProject.path) {
379
+ ctx.ui.print({ type: 'warning', message: `Working directory differs from project path!` });
380
+ ctx.ui.print({ type: 'info', message: ` cwd: ${buildCwd}` });
381
+ ctx.ui.print({ type: 'info', message: ` project: ${currentProject.path}` });
382
+ ctx.ui.print({ type: 'info', message: `Files will be created/modified in the project path, not cwd.` });
383
+ }
384
+ // Parse item ID argument (e.g., "REQ-001")
385
+ const requestedItemId = argTrimmed.toUpperCase();
386
+ const isSpecificItem = requestedItemId && /^[A-Z]+-\d{3}$/.test(requestedItemId);
387
+ // Find the item to build
388
+ let selectedItem;
389
+ if (isSpecificItem) {
390
+ // Get specific item by ID
391
+ selectedItem = workItemRepository.getByItemId(currentProject.id, requestedItemId);
392
+ if (!selectedItem) {
393
+ ctx.ui.print({ type: 'error', message: `Work item "${requestedItemId}" not found.` });
394
+ return true;
395
+ }
396
+ if (selectedItem.status !== 'backlog') {
397
+ ctx.ui.print({ type: 'warning', message: `Work item "${requestedItemId}" is already ${selectedItem.status}. Use /backlog to view status.` });
398
+ return true;
399
+ }
400
+ }
401
+ else {
402
+ // Auto-select highest priority backlog item
403
+ selectedItem = workItemRepository.getNext(currentProject.id);
404
+ if (!selectedItem) {
405
+ ctx.ui.print({ type: 'info', message: 'No backlog items found. Create items with /design or /backlog first.' });
406
+ ctx.ui.print({ type: 'info', message: 'Or run /build scaffold to create the project foundation.' });
407
+ return true;
408
+ }
409
+ }
410
+ // Check model tier for full builds (not targeted item)
411
+ if (!isSpecificItem) {
412
+ const currentModel = ctx.model ?? 'unknown';
413
+ if (!modelMeetsTier(currentModel, '/build')) {
414
+ const modelTier = getModelTier(currentModel);
415
+ const warningOverlay = new ModelWarningOverlayV2({
416
+ command: '/build',
417
+ currentModel,
418
+ currentTier: modelTier.tier,
419
+ suggestedModel: modelTier.suggestedUpgrade,
420
+ alternativeCommand: `/build ${selectedItem.itemId}`,
421
+ });
422
+ const choice = await ctx.ui.showOverlay(warningOverlay);
423
+ switch (choice) {
424
+ case 'cancel':
425
+ return true;
426
+ case 'alternative':
427
+ ctx.ui.print({ type: 'info', message: `Tip: Use /build ${selectedItem.itemId} to build a specific item with smaller models.` });
428
+ return true;
429
+ case 'switch':
430
+ ctx.ui.print({ type: 'info', message: `Continuing with ${currentModel} (model switching not yet available in V2)` });
431
+ break;
432
+ case 'continue':
433
+ break;
434
+ }
435
+ }
436
+ }
437
+ // Get build skill prompt and replace placeholders
438
+ let buildPrompt = getSkillPrompt('build');
439
+ if (!buildPrompt) {
440
+ ctx.ui.print({ type: 'error', message: 'Build skill not found.' });
441
+ return true;
442
+ }
443
+ // Replace {{projectPath}} and item placeholders with actual values
444
+ buildPrompt = buildPrompt
445
+ .replace(/\{\{projectPath\}\}/g, currentProject.path)
446
+ .replace(/\{\{item_id\}\}/g, selectedItem.itemId)
447
+ .replace(/\{\{item_title\}\}/g, selectedItem.title)
448
+ .replace(/\{\{item_type\}\}/g, selectedItem.type)
449
+ .replace(/\{\{item_priority\}\}/g, selectedItem.priority)
450
+ .replace(/\{\{item_description\}\}/g, selectedItem.description ?? 'No description provided');
451
+ // Build full message for agent with explicit project path context
452
+ const fullMessage = `I want to implement backlog item ${selectedItem.itemId}: "${selectedItem.title}".
453
+
454
+ ## PROJECT CONTEXT (CRITICAL)
455
+ - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
456
+ - **Project Directory: ${currentProject.path}**
457
+ - ALL files MUST be created/modified in this directory
458
+
459
+ ## WORK ITEM DETAILS
460
+ - Item ID: ${selectedItem.itemId}
461
+ - Type: ${selectedItem.type}
462
+ - Priority: ${selectedItem.priority}
463
+ - Description: ${selectedItem.description ?? 'No description provided'}
464
+
465
+ ## TOOL RESTRICTIONS (CRITICAL)
466
+ - Do NOT use detect_project or find_project_root
467
+ - Do NOT scan filesystem to detect project type
468
+ - The project path above is the ONLY source of truth for where to create/modify files
469
+ - Use \`project_document_get\` to read PRD and architecture docs from the database
470
+ - Use \`workitem_query\` to read related backlog items from the database
471
+ - Use \`workitem_update\` to update the item status when done
472
+
473
+ ## FILE OPERATIONS (CRITICAL)
474
+ When creating or modifying files:
475
+ - Use absolute paths starting with: ${currentProject.path}/
476
+ - Example: write_file({ path: "${currentProject.path}/src/index.ts", ... })
477
+ - NEVER use relative paths
478
+ - IGNORE the current working directory (cwd) - it may be different from the project!
479
+ - The user may have started the CLI from a different folder
480
+
481
+ ${buildPrompt}
482
+
483
+ Please start by:
484
+ 1. Using todo_write to plan the implementation steps
485
+ 2. Reading project documents from the database (project_document_list, project_document_get)
486
+ 3. Updating the work item status to 'in_progress' using workitem_update
487
+ 4. Implementing the feature
488
+ 5. Updating the work item status to 'completed' when done`;
489
+ // Queue message for agent
490
+ ctx.queueAgentMessage({
491
+ message: fullMessage,
492
+ displayMessage: `Build ${selectedItem.itemId}: ${selectedItem.title}`,
493
+ });
494
+ return true;
495
+ },
496
+ };
497
+ // =============================================================================
498
+ // Note Command
499
+ // =============================================================================
500
+ export const noteCommand = {
501
+ name: 'note',
502
+ description: 'Create a session note',
503
+ execute(args, ctx) {
504
+ // Check if a project is set
505
+ const currentProject = getCurrentProject();
506
+ if (!currentProject) {
507
+ ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
508
+ return Promise.resolve(true);
509
+ }
510
+ // Get session-notes skill prompt
511
+ const notePrompt = getSkillPrompt('session-notes');
512
+ if (!notePrompt) {
513
+ ctx.ui.print({ type: 'error', message: 'Session-notes skill not found.' });
514
+ return Promise.resolve(true);
515
+ }
516
+ // Check for optional title argument
517
+ const noteTitle = args.trim();
518
+ // Build title instruction based on whether title was provided
519
+ const titleInstruction = noteTitle
520
+ ? `The session title is: "${noteTitle}"`
521
+ : 'Please ask me for a title using ask_user_simple, or generate one from the session summary.';
522
+ // Build full message for agent
523
+ const fullMessage = `I want to create a session note capturing what we've done.
524
+
525
+ ## PROJECT CONTEXT
526
+ - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
527
+
528
+ ## DOCUMENT STORAGE (CRITICAL)
529
+ Save session notes using the database - do NOT write files directly.
530
+ - Tool: \`project_document_add({ doc_type: "session-note", title: "...", content: "..." })\`
531
+ - The database is the source of truth for all project documents
532
+ - Do NOT use write_file or edit tools for documentation
533
+
534
+ ${notePrompt}
535
+
536
+ ${titleInstruction}
537
+
538
+ Review the conversation context to understand what was accomplished, then create the session note.`;
539
+ // Queue message for agent
540
+ ctx.queueAgentMessage({
541
+ message: fullMessage,
542
+ displayMessage: noteTitle
543
+ ? `Create session note: "${noteTitle}"`
544
+ : 'Create a session note for this session.',
545
+ });
546
+ return Promise.resolve(true);
547
+ },
548
+ };
549
+ // =============================================================================
550
+ // PRD Command
551
+ // =============================================================================
552
+ export const prdCommand = {
553
+ name: 'prd',
554
+ description: 'Update the Product Requirements Document',
555
+ execute(args, ctx) {
556
+ // Check if a project is set
557
+ const currentProject = getCurrentProject();
558
+ if (!currentProject) {
559
+ ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
560
+ return Promise.resolve(true);
561
+ }
562
+ // Get PRD skill prompt
563
+ const prdPrompt = getSkillPrompt('prd');
564
+ if (!prdPrompt) {
565
+ ctx.ui.print({ type: 'error', message: 'PRD skill not found.' });
566
+ return Promise.resolve(true);
567
+ }
568
+ // Check for optional section argument
569
+ const section = args.trim().toLowerCase();
570
+ const validSections = ['vision', 'scope', 'technical', 'success'];
571
+ const sectionInstruction = validSections.includes(section)
572
+ ? `The user wants to update the "${section}" section specifically.`
573
+ : 'Ask the user which section they want to update using ask_user_simple.';
574
+ // Build full message for agent with project context
575
+ const fullMessage = `I want to update the Product Requirements Document.
576
+
577
+ ## DOCUMENT STORAGE (CRITICAL)
578
+ Save PRD updates using the database - do NOT write files directly.
579
+ - Project: ${currentProject.name} (ID: ${String(currentProject.id)})
580
+ - Tool: \`project_document_add({ doc_type: "prd", title: "Product Requirements Document", content: "..." })\`
581
+ - The database is the source of truth for all project documents
582
+ - Do NOT use write_file or edit tools for documentation
583
+
584
+ ${prdPrompt}
585
+
586
+ ${sectionInstruction}
587
+
588
+ Start by reading the existing PRD.md file to understand current state.`;
589
+ // Queue message for agent
590
+ ctx.queueAgentMessage({
591
+ message: fullMessage,
592
+ displayMessage: section
593
+ ? `Update PRD: ${section} section`
594
+ : 'Update the Product Requirements Document',
595
+ });
596
+ return Promise.resolve(true);
597
+ },
598
+ };
599
+ // =============================================================================
600
+ // Scaffold Command
601
+ // =============================================================================
602
+ export const scaffoldCommand = {
603
+ name: 'scaffold',
604
+ description: 'Create project scaffold/foundation',
605
+ async execute(_args, ctx) {
606
+ // Check if a project is set
607
+ const currentProject = getCurrentProject();
608
+ if (!currentProject) {
609
+ ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
610
+ return true;
611
+ }
612
+ // Check if project has a path set (REQUIRED for scaffolding)
613
+ if (!currentProject.path) {
614
+ ctx.ui.print({ type: 'error', message: 'Project path not set. Cannot scaffold without a target directory.' });
615
+ ctx.ui.print({ type: 'info', message: 'Tip: Update the project path in /projects to specify where files should be created.' });
616
+ return true;
617
+ }
618
+ // Warn if cwd doesn't match project path (common source of confusion)
619
+ const cwd = process.cwd();
620
+ if (cwd !== currentProject.path) {
621
+ ctx.ui.print({ type: 'warning', message: `Working directory differs from project path!` });
622
+ ctx.ui.print({ type: 'info', message: ` cwd: ${cwd}` });
623
+ ctx.ui.print({ type: 'info', message: ` project: ${currentProject.path}` });
624
+ ctx.ui.print({ type: 'info', message: `Files will be created in the project path, not cwd.` });
625
+ }
626
+ // Check model tier - /scaffold works best with large models
627
+ const currentModel = ctx.model ?? 'unknown';
628
+ if (!modelMeetsTier(currentModel, '/scaffold')) {
629
+ const modelTier = getModelTier(currentModel);
630
+ const warningOverlay = new ModelWarningOverlayV2({
631
+ command: '/scaffold',
632
+ currentModel,
633
+ currentTier: modelTier.tier,
634
+ suggestedModel: modelTier.suggestedUpgrade,
635
+ });
636
+ const choice = await ctx.ui.showOverlay(warningOverlay);
637
+ switch (choice) {
638
+ case 'cancel':
639
+ return true;
640
+ case 'switch':
641
+ ctx.ui.print({ type: 'info', message: `Continuing with ${currentModel} (model switching not yet available in V2)` });
642
+ break;
643
+ case 'continue':
644
+ // Proceed with current model
645
+ break;
646
+ }
647
+ }
648
+ // Get scaffold skill prompt and replace path placeholder
649
+ let scaffoldPrompt = getSkillPrompt('scaffold');
650
+ if (!scaffoldPrompt) {
651
+ ctx.ui.print({ type: 'error', message: 'Scaffold skill not found.' });
652
+ return true;
653
+ }
654
+ // Replace {{projectPath}} placeholder with actual path
655
+ scaffoldPrompt = scaffoldPrompt.replace(/\{\{projectPath\}\}/g, currentProject.path);
656
+ // Build full message for agent with explicit project path context
657
+ const fullMessage = `I want to create the project scaffold/foundation.
658
+
659
+ ## PROJECT CONTEXT (CRITICAL)
660
+ - Project Name: ${currentProject.name} (ID: ${String(currentProject.id)})
661
+ - **Project Directory: ${currentProject.path}**
662
+ - ALL files MUST be created in this directory
663
+
664
+ ## TOOL RESTRICTIONS (CRITICAL)
665
+ - Do NOT use detect_project or find_project_root
666
+ - Do NOT scan filesystem to detect project type
667
+ - The project path above is the ONLY source of truth for where to create files
668
+ - Use \`project_document_get\` to read PRD and architecture docs from the database
669
+ - Use \`workitem_query\` to read backlog items from the database
670
+
671
+ ## FILE CREATION (CRITICAL)
672
+ When creating files:
673
+ - Use absolute paths starting with: ${currentProject.path}/
674
+ - Example: write_file({ path: "${currentProject.path}/package.json", ... })
675
+ - NEVER use relative paths
676
+ - IGNORE the current working directory (cwd) - it may be different from the project!
677
+ - The user may have started the CLI from a different folder
678
+
679
+ ${scaffoldPrompt}
680
+
681
+ Please start by reading the project documents from the database using project_document_list and project_document_get. Then create a plan with todo_write before generating files.`;
682
+ // Queue message for agent
683
+ ctx.queueAgentMessage({
684
+ message: fullMessage,
685
+ displayMessage: 'Create project scaffold.',
686
+ });
687
+ return true;
688
+ },
689
+ };
690
+ // =============================================================================
691
+ // Arch Command
692
+ // =============================================================================
693
+ export const archCommand = {
694
+ name: 'arch',
695
+ description: 'Create architecture documentation',
696
+ async execute(_args, ctx) {
697
+ // Check if a project is set (use database, not filesystem)
698
+ const currentProject = getCurrentProject();
699
+ if (!currentProject) {
700
+ ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
701
+ return true;
702
+ }
703
+ // TODO: Check model tier and show warning if too small (like legacy)
704
+ // Show type selection overlay
705
+ const archOverlay = new ArchTypeOverlayV2();
706
+ const archChoice = await ctx.ui.showOverlay(archOverlay);
707
+ if (!archChoice) {
708
+ // User cancelled
709
+ return true;
710
+ }
711
+ // Get architecture skill prompt
712
+ const archPrompt = getSkillPrompt('architecture');
713
+ if (!archPrompt) {
714
+ ctx.ui.print({ type: 'error', message: 'Architecture skill not found.' });
715
+ return true;
716
+ }
717
+ // Build the document type description for display
718
+ const docTypeLabels = {
719
+ 'adr': 'Architecture Decision Record',
720
+ 'diagram': 'System Diagram',
721
+ 'data-model': 'Data Model',
722
+ 'api': 'API Design',
723
+ 'custom': 'Custom Documentation',
724
+ };
725
+ const displayType = archChoice.customTopic
726
+ ? `Custom: ${archChoice.customTopic}`
727
+ : docTypeLabels[archChoice.type];
728
+ // Replace placeholders in skill prompt
729
+ const finalPrompt = archPrompt
730
+ .replace('{{doc_type}}', archChoice.type)
731
+ .replace('{{#if custom_topic}}Custom Topic: {{custom_topic}}{{/if}}', archChoice.customTopic ? `Custom Topic: ${archChoice.customTopic}` : '');
732
+ // Build full message for agent with project context
733
+ const fullMessage = `I want to create architecture documentation.
734
+
735
+ ## DOCUMENT STORAGE (CRITICAL)
736
+ Save architecture documentation using the database - do NOT write files directly.
737
+ - Project: ${currentProject.name} (ID: ${String(currentProject.id)})
738
+ - Tool: \`project_document_add({ doc_type: "architecture", title: "...", content: "..." })\`
739
+ - The database is the source of truth for all project documents
740
+ - Do NOT use write_file or edit tools for documentation
741
+
742
+ ${finalPrompt}
743
+
744
+ Please start by using project_document_list to find any existing PRD, and workitem_query to understand the project backlog. Then use ask_user to gather the information needed for this ${archChoice.type} document.`;
745
+ // Queue message for agent
746
+ ctx.queueAgentMessage({
747
+ message: fullMessage,
748
+ displayMessage: `Create ${displayType} documentation.`,
749
+ });
750
+ return true;
751
+ },
752
+ };
753
+ // =============================================================================
754
+ // Docs Command
755
+ // =============================================================================
756
+ export const docsCommand = {
757
+ name: 'docs',
758
+ description: 'View project documents (PRD, architecture, design, notes)',
759
+ async execute(_args, ctx) {
760
+ // Loop: show list → detail → back to list (until user cancels list or Ctrl+C from detail)
761
+ let showList = true;
762
+ while (showList) {
763
+ // Show document list (inline overlay)
764
+ const docsOverlay = new DocsOverlayV2();
765
+ const listResult = await ctx.ui.showOverlay(docsOverlay);
766
+ // User cancelled the list (Esc/Ctrl+C) - exit
767
+ if (!listResult?.selectedDocument || listResult.cancelled) {
768
+ showList = false;
769
+ continue;
770
+ }
771
+ // Show selected document in fullscreen detail overlay
772
+ const detailOverlay = new DocumentDetailOverlayV2(listResult.selectedDocument);
773
+ const detailResult = await ctx.ui.showOverlay(detailOverlay);
774
+ // Ctrl+C from detail - exit completely
775
+ // Esc/q from detail (goBack=true) - loop back to show list again
776
+ showList = detailResult?.goBack === true;
777
+ }
778
+ return true;
779
+ },
780
+ };
781
+ // =============================================================================
782
+ // Projects Command
783
+ // =============================================================================
784
+ export const projectsCommand = {
785
+ name: 'projects',
786
+ description: 'View and manage all projects',
787
+ async execute(_args, ctx) {
788
+ const projectsOverlay = new ProjectsOverlayV2();
789
+ await ctx.ui.showOverlay(projectsOverlay);
790
+ // Sync footer with current project (may have changed during overlay)
791
+ syncFooterWithCurrentProject(ctx);
792
+ return true;
793
+ },
794
+ };
795
+ // =============================================================================
796
+ // Export All Project Commands
797
+ // =============================================================================
798
+ export const projectCommands = [
799
+ newCommand,
800
+ initCommand,
801
+ backlogCommand,
802
+ workflowCommand,
803
+ anchorsCommand,
804
+ designCommand,
805
+ sketchCommand,
806
+ refineCommand,
807
+ buildCommand,
808
+ noteCommand,
809
+ prdCommand,
810
+ scaffoldCommand,
811
+ archCommand,
812
+ docsCommand,
813
+ projectsCommand,
814
+ ];