@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,22 @@
1
+ /**
2
+ * Workflow Overlay
3
+ *
4
+ * Unified project dashboard with tabbed interface:
5
+ * [Actions] - Quick actions based on workflow state
6
+ * [Details] - Project metadata (read-only)
7
+ * [Dashboard] - Overview of project status (placeholder)
8
+ * [Manage] - Project management actions
9
+ *
10
+ * Access paths:
11
+ * /workflow - Opens workflow for active project
12
+ * /projects → Enter - Opens workflow for selected project
13
+ *
14
+ * Workflow phases:
15
+ * /new → /design|/sketch → /backlog → /build → /scaffold → done
16
+ */
17
+ export interface WorkflowOverlayResult {
18
+ command: string | null;
19
+ action?: 'set-active' | 'archive' | 'restore' | 'delete' | 'edit';
20
+ projectId?: number;
21
+ }
22
+ export declare function showWorkflowOverlay(projectId?: number): Promise<WorkflowOverlayResult>;
@@ -0,0 +1,636 @@
1
+ /**
2
+ * Workflow Overlay
3
+ *
4
+ * Unified project dashboard with tabbed interface:
5
+ * [Actions] - Quick actions based on workflow state
6
+ * [Details] - Project metadata (read-only)
7
+ * [Dashboard] - Overview of project status (placeholder)
8
+ * [Manage] - Project management actions
9
+ *
10
+ * Access paths:
11
+ * /workflow - Opens workflow for active project
12
+ * /projects → Enter - Opens workflow for selected project
13
+ *
14
+ * Workflow phases:
15
+ * /new → /design|/sketch → /backlog → /build → /scaffold → done
16
+ */
17
+ import * as terminal from './terminal.js';
18
+ import { getActiveProject, setActiveProject, clearActiveProject } from '../tools/project-db.js';
19
+ import { BaseOverlay, isEscape, isTab, isShiftTab, isEnter, isCtrlC, isNavigateUp, isNavigateDown, isLeftArrow, isRightArrow, isClose, extractPrintable, renderBorder, } from './base/index.js';
20
+ import { TabFeature } from './features/tab-feature.js';
21
+ import { projectRepository, workItemRepository, documentRepository } from '../db/repositories/index.js';
22
+ // =============================================================================
23
+ // Constants
24
+ // =============================================================================
25
+ const PHASES = [
26
+ {
27
+ id: 'init',
28
+ name: 'Initialize',
29
+ command: '/new',
30
+ description: 'Create project structure',
31
+ isComplete: (project) => !!project,
32
+ isActive: (project) => !project,
33
+ },
34
+ {
35
+ id: 'design',
36
+ name: 'Design',
37
+ command: '/design',
38
+ description: 'Define requirements and PRD',
39
+ isComplete: (_project, stats) => stats.hasPrd,
40
+ isActive: (_project, stats) => !stats.hasPrd && stats.totalItems === 0,
41
+ },
42
+ {
43
+ id: 'backlog',
44
+ name: 'Backlog',
45
+ command: '/backlog',
46
+ description: 'Plan and prioritize work items',
47
+ isComplete: (_project, stats) => stats.totalItems >= 3,
48
+ isActive: (_project, stats) => stats.hasPrd && stats.totalItems < 3,
49
+ },
50
+ {
51
+ id: 'scaffold',
52
+ name: 'Scaffold',
53
+ command: '/scaffold',
54
+ description: 'Create project foundation',
55
+ isComplete: (_project, stats) => stats.hasScaffold,
56
+ isActive: (_project, stats) => stats.totalItems >= 3 && !stats.hasScaffold,
57
+ },
58
+ {
59
+ id: 'build',
60
+ name: 'Build',
61
+ command: '/build',
62
+ description: 'Implement backlog items',
63
+ isComplete: (_project, stats) => stats.completedItems >= stats.totalItems && stats.totalItems > 0,
64
+ isActive: (_project, stats) => stats.hasScaffold && stats.completedItems < stats.totalItems,
65
+ },
66
+ ];
67
+ const TABS = [
68
+ { id: 'actions', label: 'Actions' },
69
+ { id: 'details', label: 'Details' },
70
+ { id: 'dashboard', label: 'Dashboard' },
71
+ { id: 'manage', label: 'Manage' },
72
+ ];
73
+ const MAX_ACTIONS = 6;
74
+ // =============================================================================
75
+ // Helper Functions
76
+ // =============================================================================
77
+ function getProjectStats(project) {
78
+ const itemsResult = workItemRepository.query({
79
+ project_id: project.id,
80
+ limit: 1000,
81
+ });
82
+ const items = itemsResult.items;
83
+ const completedItems = items.filter(i => i.status === 'completed').length;
84
+ const inProgressItems = items.filter(i => i.status === 'in_progress').length;
85
+ const docs = documentRepository.listByProject(project.id);
86
+ const hasPrd = docs.some(d => d.docType === 'prd');
87
+ const hasArchDocs = docs.some(d => d.docType === 'architecture');
88
+ const hasScaffold = items.some(i => i.title.toLowerCase().includes('scaffold') && i.status === 'completed') || project.metadata?.scaffolded === true;
89
+ return {
90
+ totalItems: items.length,
91
+ completedItems,
92
+ inProgressItems,
93
+ hasPrd,
94
+ hasArchDocs,
95
+ hasScaffold,
96
+ };
97
+ }
98
+ function buildActionsItems(project, stats) {
99
+ const actions = [];
100
+ if (!project) {
101
+ actions.push({
102
+ label: 'Initialize Project',
103
+ command: '/new',
104
+ description: 'Create a new project',
105
+ enabled: true,
106
+ });
107
+ return actions;
108
+ }
109
+ if (!stats) {
110
+ return actions;
111
+ }
112
+ if (!stats.hasPrd) {
113
+ actions.push({
114
+ label: 'Design Project',
115
+ command: '/design',
116
+ description: 'Create PRD and requirements',
117
+ enabled: true,
118
+ });
119
+ actions.push({
120
+ label: 'Quick Sketch',
121
+ command: '/sketch',
122
+ description: 'Lightweight project outline',
123
+ enabled: true,
124
+ });
125
+ }
126
+ if (stats.hasPrd || stats.totalItems > 0) {
127
+ actions.push({
128
+ label: 'View Backlog',
129
+ command: '/backlog',
130
+ description: `${String(stats.totalItems)} items, ${String(stats.completedItems)} done`,
131
+ enabled: true,
132
+ });
133
+ }
134
+ if (stats.totalItems > 0 && !stats.hasScaffold) {
135
+ actions.push({
136
+ label: 'Scaffold Project',
137
+ command: '/scaffold',
138
+ description: 'Create project foundation',
139
+ enabled: true,
140
+ });
141
+ }
142
+ if (stats.hasScaffold && stats.totalItems > stats.completedItems) {
143
+ actions.push({
144
+ label: 'Build Next Item',
145
+ command: '/build',
146
+ description: `${String(stats.totalItems - stats.completedItems)} items remaining`,
147
+ enabled: true,
148
+ });
149
+ }
150
+ actions.push({
151
+ label: 'View Documents',
152
+ command: '/docs',
153
+ description: 'Browse project documents',
154
+ enabled: stats.hasPrd || stats.hasArchDocs,
155
+ });
156
+ actions.push({
157
+ label: 'View Anchors',
158
+ command: '/anchors',
159
+ description: 'Manage persistent context',
160
+ enabled: true,
161
+ });
162
+ return actions;
163
+ }
164
+ function buildManageActions(project) {
165
+ const actions = [];
166
+ if (!project) {
167
+ return actions;
168
+ }
169
+ actions.push({
170
+ id: 'edit',
171
+ label: 'Edit Project',
172
+ command: '',
173
+ description: 'Change name, description',
174
+ enabled: true,
175
+ style: 'normal',
176
+ });
177
+ const activeProject = getActiveProject();
178
+ if (!activeProject || activeProject.id !== project.id) {
179
+ actions.push({
180
+ id: 'set-active',
181
+ label: 'Set as Active',
182
+ command: '',
183
+ description: 'Make this the active project',
184
+ enabled: true,
185
+ style: 'normal',
186
+ });
187
+ }
188
+ if (project.status === 'archived') {
189
+ actions.push({
190
+ id: 'restore',
191
+ label: 'Restore Project',
192
+ command: '',
193
+ description: 'Restore from archive',
194
+ enabled: true,
195
+ style: 'normal',
196
+ });
197
+ }
198
+ else {
199
+ actions.push({
200
+ id: 'archive',
201
+ label: 'Archive Project',
202
+ command: '',
203
+ description: 'Hide from active list',
204
+ enabled: true,
205
+ style: 'warning',
206
+ });
207
+ }
208
+ actions.push({
209
+ id: 'delete',
210
+ label: 'Delete Project',
211
+ command: '',
212
+ description: 'Permanently remove',
213
+ enabled: true,
214
+ style: 'danger',
215
+ });
216
+ return actions;
217
+ }
218
+ function formatRelativeTime(date) {
219
+ if (!date)
220
+ return 'never';
221
+ const now = new Date();
222
+ const diffMs = now.getTime() - date.getTime();
223
+ const diffMins = Math.floor(diffMs / 60000);
224
+ const diffHours = Math.floor(diffMs / 3600000);
225
+ const diffDays = Math.floor(diffMs / 86400000);
226
+ if (diffMins < 1)
227
+ return 'just now';
228
+ if (diffMins < 60)
229
+ return `${String(diffMins)}m ago`;
230
+ if (diffHours < 24)
231
+ return `${String(diffHours)}h ago`;
232
+ if (diffDays < 7)
233
+ return `${String(diffDays)}d ago`;
234
+ return date.toLocaleDateString();
235
+ }
236
+ function formatStatus(status, s) {
237
+ switch (status) {
238
+ case 'active':
239
+ return s.success('active');
240
+ case 'paused':
241
+ return s.warning('paused');
242
+ case 'completed':
243
+ return s.info('completed');
244
+ case 'archived':
245
+ return s.muted('archived');
246
+ default:
247
+ return s.muted(status);
248
+ }
249
+ }
250
+ // =============================================================================
251
+ // Workflow Overlay Class
252
+ // =============================================================================
253
+ class WorkflowOverlay extends BaseOverlay {
254
+ tabFeature;
255
+ constructor(projectId) {
256
+ // Load project data
257
+ let project = null;
258
+ let stats = null;
259
+ if (projectId) {
260
+ try {
261
+ project = projectRepository.getById(projectId);
262
+ if (project) {
263
+ stats = getProjectStats(project);
264
+ }
265
+ }
266
+ catch {
267
+ // Project not found
268
+ }
269
+ }
270
+ else {
271
+ const activeProject = getActiveProject();
272
+ if (activeProject) {
273
+ try {
274
+ project = projectRepository.getById(activeProject.id);
275
+ if (project) {
276
+ stats = getProjectStats(project);
277
+ }
278
+ }
279
+ catch {
280
+ // Project not found
281
+ }
282
+ }
283
+ }
284
+ const initialState = {
285
+ lineCount: 0,
286
+ maxLineCount: 0,
287
+ currentTab: 0,
288
+ project,
289
+ stats,
290
+ actionsIndex: 0,
291
+ manageActionIndex: 0,
292
+ actionsItems: buildActionsItems(project, stats),
293
+ manageActions: buildManageActions(project),
294
+ };
295
+ super(initialState, { minHeight: 18 });
296
+ this.tabFeature = new TabFeature(TABS, () => {
297
+ // Tab changed - no special handling needed
298
+ });
299
+ }
300
+ render() {
301
+ const s = this.styles;
302
+ const cols = terminal.getTerminalWidth();
303
+ const border = renderBorder(cols, s);
304
+ const lines = [];
305
+ // Header with project name
306
+ const projectName = this.state.project ? this.state.project.displayName : 'No Project';
307
+ lines.push(border);
308
+ lines.push(` ${s.primaryBold('Workflow:')} ${s.primary(projectName)}`);
309
+ lines.push('');
310
+ // Tab bar
311
+ const tabBar = this.tabFeature.renderTabs(this.state, s);
312
+ const tabHint = s.muted(`(${this.tabFeature.renderHints()} · 1-4)`);
313
+ lines.push(` ${tabBar} ${tabHint}`);
314
+ lines.push('');
315
+ // Project info + Progress row
316
+ if (this.state.project && this.state.stats) {
317
+ const progress = this.state.stats.totalItems > 0
318
+ ? Math.round((this.state.stats.completedItems / this.state.stats.totalItems) * 100)
319
+ : 0;
320
+ const barWidth = 20;
321
+ const filledWidth = Math.round((progress / 100) * barWidth);
322
+ const bar = '█'.repeat(filledWidth) + '░'.repeat(barWidth - filledWidth);
323
+ lines.push(` ${s.muted('Status:')} ${formatStatus(this.state.project.status, s)} ${s.muted('Mode:')} ${this.state.project.workflowMode}`);
324
+ lines.push(` ${s.muted('Progress:')} ${String(this.state.stats.completedItems)}/${String(this.state.stats.totalItems)} [${s.primary(bar)}] ${String(progress)}%`);
325
+ }
326
+ else {
327
+ lines.push(` ${s.warning('No active project')} ${s.muted('Run /new to create')}`);
328
+ lines.push('');
329
+ }
330
+ lines.push('');
331
+ // Workflow phases (horizontal)
332
+ if (this.state.project && this.state.stats) {
333
+ let phaseLine = ' ';
334
+ for (const phase of PHASES) {
335
+ const isComplete = phase.isComplete(this.state.project, this.state.stats);
336
+ const isActive = phase.isActive(this.state.project, this.state.stats);
337
+ let icon;
338
+ let label;
339
+ if (isComplete) {
340
+ icon = s.success('✓');
341
+ label = s.muted(phase.name);
342
+ }
343
+ else if (isActive) {
344
+ icon = s.primary('►');
345
+ label = s.primary(phase.name);
346
+ }
347
+ else {
348
+ icon = s.muted('○');
349
+ label = s.muted(phase.name);
350
+ }
351
+ phaseLine += `${icon} ${label} `;
352
+ }
353
+ lines.push(phaseLine);
354
+ }
355
+ else {
356
+ lines.push(` ${s.muted('○ Init ○ Design ○ Backlog ○ Scaffold ○ Build')}`);
357
+ }
358
+ lines.push('');
359
+ lines.push(border);
360
+ // Tab content
361
+ const tabId = TABS[this.state.currentTab]?.id ?? 'actions';
362
+ switch (tabId) {
363
+ case 'actions':
364
+ this.renderActionsTab(lines);
365
+ break;
366
+ case 'details':
367
+ this.renderDetailsTab(lines);
368
+ break;
369
+ case 'dashboard':
370
+ this.renderDashboardTab(lines);
371
+ break;
372
+ case 'manage':
373
+ this.renderManageTab(lines);
374
+ break;
375
+ }
376
+ // Footer
377
+ lines.push('');
378
+ lines.push(border);
379
+ lines.push(` ${s.muted('↑↓/jk Navigate · ←→/hl Tabs · Enter Action · q/Esc Close')}`);
380
+ lines.push(border);
381
+ return lines;
382
+ }
383
+ renderActionsTab(lines) {
384
+ const s = this.styles;
385
+ lines.push(` ${s.muted('Quick Actions:')}`);
386
+ lines.push('');
387
+ if (this.state.actionsItems.length > 0) {
388
+ const displayActions = this.state.actionsItems.slice(0, MAX_ACTIONS);
389
+ for (let i = 0; i < displayActions.length; i++) {
390
+ const action = displayActions[i];
391
+ const isSelected = i === this.state.actionsIndex;
392
+ const prefix = isSelected ? s.primary('❯ ') : ' ';
393
+ const labelWidth = 20;
394
+ const paddedLabel = action.label.padEnd(labelWidth);
395
+ if (action.enabled) {
396
+ const label = isSelected ? s.primary(paddedLabel) : paddedLabel;
397
+ const desc = s.muted(action.description);
398
+ lines.push(` ${prefix}${label} ${desc}`);
399
+ }
400
+ else {
401
+ lines.push(` ${prefix}${s.muted(paddedLabel)} ${s.muted(action.description)}`);
402
+ }
403
+ }
404
+ }
405
+ else {
406
+ lines.push(` ${s.muted(' No actions available')}`);
407
+ }
408
+ }
409
+ renderDetailsTab(lines) {
410
+ const s = this.styles;
411
+ if (!this.state.project) {
412
+ lines.push(` ${s.muted('No project selected')}`);
413
+ return;
414
+ }
415
+ const project = this.state.project;
416
+ lines.push(` ${s.muted('Project Details:')}`);
417
+ lines.push('');
418
+ const infoRows = [
419
+ ['Name', project.name],
420
+ ['Display Name', project.displayName],
421
+ ['Type', project.type],
422
+ ['Path', project.path],
423
+ ['Created', project.createdAt.toLocaleDateString()],
424
+ ['Last Activity', formatRelativeTime(project.lastActivityAt)],
425
+ ['Lifecycle', project.lifecycleState],
426
+ ];
427
+ for (const [label, value] of infoRows) {
428
+ lines.push(` ${s.muted(label.padEnd(15))} ${value}`);
429
+ }
430
+ if (project.description) {
431
+ lines.push('');
432
+ lines.push(` ${s.muted('Description:')}`);
433
+ lines.push(` ${project.description}`);
434
+ }
435
+ }
436
+ renderDashboardTab(lines) {
437
+ const s = this.styles;
438
+ if (!this.state.project) {
439
+ lines.push(` ${s.muted('No project selected')}`);
440
+ return;
441
+ }
442
+ lines.push(` ${s.muted('Dashboard:')}`);
443
+ lines.push('');
444
+ lines.push(` ${s.warning('Coming soon...')}`);
445
+ lines.push('');
446
+ lines.push(` ${s.muted('This tab will show:')}`);
447
+ lines.push(` ${s.muted('• Current in-progress work item')}`);
448
+ lines.push(` ${s.muted('• Recent activity')}`);
449
+ lines.push(` ${s.muted('• Project health indicators')}`);
450
+ }
451
+ renderManageTab(lines) {
452
+ const s = this.styles;
453
+ if (!this.state.project) {
454
+ lines.push(` ${s.muted('No project selected')}`);
455
+ return;
456
+ }
457
+ lines.push(` ${s.muted('Management Actions:')}`);
458
+ lines.push('');
459
+ const actions = this.state.manageActions;
460
+ if (actions.length > 0) {
461
+ for (let i = 0; i < actions.length; i++) {
462
+ const action = actions[i];
463
+ const isSelected = i === this.state.manageActionIndex;
464
+ const prefix = isSelected ? s.primary('❯ ') : ' ';
465
+ const labelWidth = 20;
466
+ const paddedLabel = action.label.padEnd(labelWidth);
467
+ let labelStyle;
468
+ if (isSelected) {
469
+ labelStyle = action.style === 'danger' ? s.error :
470
+ action.style === 'warning' ? s.warning : s.primary;
471
+ }
472
+ else {
473
+ labelStyle = action.style === 'danger' ? s.error :
474
+ action.style === 'warning' ? s.warning : (text) => text;
475
+ }
476
+ lines.push(` ${prefix}${labelStyle(paddedLabel)} ${s.muted(action.description)}`);
477
+ }
478
+ }
479
+ }
480
+ handleKey(data) {
481
+ // Ctrl+C always closes
482
+ if (isCtrlC(data)) {
483
+ this.close({ command: null });
484
+ return;
485
+ }
486
+ // q or Esc closes
487
+ if (isEscape(data) || isClose(data)) {
488
+ this.close({ command: null });
489
+ return;
490
+ }
491
+ // Tab switching: Tab/→/l for next, Shift+Tab/←/h for previous
492
+ if (isTab(data) || isRightArrow(data)) {
493
+ this.state.currentTab = (this.state.currentTab + 1) % TABS.length;
494
+ this.update();
495
+ return;
496
+ }
497
+ if (isShiftTab(data) || isLeftArrow(data)) {
498
+ this.state.currentTab = (this.state.currentTab - 1 + TABS.length) % TABS.length;
499
+ this.update();
500
+ return;
501
+ }
502
+ // Vim-style tab navigation (h/l)
503
+ const char = extractPrintable(data);
504
+ if (char === 'l') {
505
+ this.state.currentTab = (this.state.currentTab + 1) % TABS.length;
506
+ this.update();
507
+ return;
508
+ }
509
+ if (char === 'h') {
510
+ this.state.currentTab = (this.state.currentTab - 1 + TABS.length) % TABS.length;
511
+ this.update();
512
+ return;
513
+ }
514
+ // Number keys to jump to tab (1-4)
515
+ if (char && char >= '1' && char <= '4') {
516
+ const tabNum = parseInt(char, 10) - 1;
517
+ if (tabNum < TABS.length) {
518
+ this.state.currentTab = tabNum;
519
+ this.update();
520
+ }
521
+ return;
522
+ }
523
+ // Tab-specific key handling
524
+ const tabId = TABS[this.state.currentTab]?.id ?? 'actions';
525
+ if (tabId === 'actions') {
526
+ this.handleActionsTabKey(data);
527
+ }
528
+ else if (tabId === 'manage') {
529
+ this.handleManageTabKey(data);
530
+ }
531
+ // Details and Dashboard tabs are read-only
532
+ }
533
+ handleActionsTabKey(data) {
534
+ if (isNavigateUp(data)) {
535
+ if (this.state.actionsItems.length > 0) {
536
+ this.state.actionsIndex = (this.state.actionsIndex - 1 + this.state.actionsItems.length) % this.state.actionsItems.length;
537
+ this.update();
538
+ }
539
+ return;
540
+ }
541
+ if (isNavigateDown(data)) {
542
+ if (this.state.actionsItems.length > 0) {
543
+ this.state.actionsIndex = (this.state.actionsIndex + 1) % this.state.actionsItems.length;
544
+ this.update();
545
+ }
546
+ return;
547
+ }
548
+ if (isEnter(data)) {
549
+ if (this.state.actionsItems.length > 0) {
550
+ const action = this.state.actionsItems[this.state.actionsIndex];
551
+ if (action.enabled) {
552
+ this.close({ command: action.command });
553
+ }
554
+ }
555
+ return;
556
+ }
557
+ }
558
+ handleManageTabKey(data) {
559
+ if (isNavigateUp(data)) {
560
+ if (this.state.manageActions.length > 0) {
561
+ this.state.manageActionIndex = (this.state.manageActionIndex - 1 + this.state.manageActions.length) % this.state.manageActions.length;
562
+ this.update();
563
+ }
564
+ return;
565
+ }
566
+ if (isNavigateDown(data)) {
567
+ if (this.state.manageActions.length > 0) {
568
+ this.state.manageActionIndex = (this.state.manageActionIndex + 1) % this.state.manageActions.length;
569
+ this.update();
570
+ }
571
+ return;
572
+ }
573
+ if (isEnter(data)) {
574
+ if (this.state.manageActions.length > 0 && this.state.project) {
575
+ const action = this.state.manageActions[this.state.manageActionIndex];
576
+ this.executeManageAction(action);
577
+ }
578
+ return;
579
+ }
580
+ }
581
+ executeManageAction(action) {
582
+ if (!this.state.project)
583
+ return;
584
+ switch (action.id) {
585
+ case 'set-active':
586
+ setActiveProject({
587
+ id: this.state.project.id,
588
+ name: this.state.project.name,
589
+ displayName: this.state.project.displayName,
590
+ path: this.state.project.path,
591
+ });
592
+ projectRepository.touch(this.state.project.id);
593
+ this.state.manageActions = buildManageActions(this.state.project);
594
+ this.update();
595
+ break;
596
+ case 'archive': {
597
+ projectRepository.update(this.state.project.id, { status: 'archived' });
598
+ const activeProject = getActiveProject();
599
+ if (activeProject?.id === this.state.project.id) {
600
+ clearActiveProject();
601
+ }
602
+ this.refreshProject();
603
+ break;
604
+ }
605
+ case 'restore':
606
+ projectRepository.update(this.state.project.id, { status: 'active' });
607
+ this.refreshProject();
608
+ break;
609
+ case 'edit':
610
+ case 'delete':
611
+ this.close({
612
+ command: null,
613
+ action: action.id,
614
+ projectId: this.state.project.id,
615
+ });
616
+ break;
617
+ }
618
+ }
619
+ refreshProject() {
620
+ if (!this.state.project)
621
+ return;
622
+ this.state.project = projectRepository.getById(this.state.project.id);
623
+ if (this.state.project) {
624
+ this.state.stats = getProjectStats(this.state.project);
625
+ this.state.actionsItems = buildActionsItems(this.state.project, this.state.stats);
626
+ this.state.manageActions = buildManageActions(this.state.project);
627
+ }
628
+ this.update();
629
+ }
630
+ }
631
+ // =============================================================================
632
+ // Export Function (Backward Compatible)
633
+ // =============================================================================
634
+ export function showWorkflowOverlay(projectId) {
635
+ return new WorkflowOverlay(projectId).show();
636
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Debug Logger
3
+ *
4
+ * Writes timestamped logs to a file for debugging timing issues.
5
+ * Usage: import { debugLog } from './utils/debug-log.js';
6
+ * debugLog('event-name', 'description');
7
+ *
8
+ * For rendering debug: set DEBUG_RENDERING=1 environment variable
9
+ * Usage: DEBUG_RENDERING=1 compilr
10
+ * Then: tail -f /tmp/compilr-debug.log
11
+ */
12
+ export declare const DEBUG_RENDERING: boolean;
13
+ /**
14
+ * Log a debug message with timestamp
15
+ */
16
+ export declare function debugLog(event: string, details?: string): void;
17
+ /**
18
+ * Clear the log file
19
+ */
20
+ export declare function clearDebugLog(): void;
21
+ /**
22
+ * Get the log file path
23
+ */
24
+ export declare function getDebugLogPath(): string;
25
+ /**
26
+ * Log rendering-specific debug info (only if DEBUG_RENDERING=1)
27
+ */
28
+ export declare function debugRender(component: string, details: string): void;