@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,55 @@
1
+ /**
2
+ * Dashboard Overlay V2
3
+ *
4
+ * Main entry point for the CLI when startup mode is 'dashboard'.
5
+ * Shows current project info, recent projects, and quick actions.
6
+ *
7
+ * Two tabs:
8
+ * - Dashboard: Current project, recent projects, actions
9
+ * - More: Help links, about information
10
+ */
11
+ import { BaseOverlayV2 } from '../../base/index.js';
12
+ import type { RenderContext, OverlayAction, KeyEvent } from '../types.js';
13
+ import { type Project } from '../../../db/repositories/index.js';
14
+ type DashboardTab = 'dashboard' | 'more';
15
+ type DashboardAction = 'continue' | 'new' | 'projects' | 'chat' | 'workflow' | 'exit' | 'help' | 'config' | 'about';
16
+ interface DashboardState {
17
+ currentTab: DashboardTab;
18
+ selectedIndex: number;
19
+ currentProject: {
20
+ id: number;
21
+ name: string;
22
+ displayName: string;
23
+ path: string;
24
+ } | null;
25
+ recentProjects: Project[];
26
+ progress: {
27
+ completed: number;
28
+ total: number;
29
+ } | null;
30
+ }
31
+ export interface DashboardOverlayV2Result {
32
+ /** The action to take after closing the overlay */
33
+ action: DashboardAction;
34
+ /** The selected project ID (for 'continue' action) */
35
+ projectId?: number;
36
+ }
37
+ export declare class DashboardOverlayV2 extends BaseOverlayV2<DashboardState, DashboardOverlayV2Result> {
38
+ readonly type: "inline";
39
+ readonly id = "dashboard-overlay-v2";
40
+ protected minHeight: number;
41
+ constructor();
42
+ private getDashboardItems;
43
+ private getMoreItems;
44
+ private getItems;
45
+ private formatProjectStatus;
46
+ private formatTimeAgo;
47
+ protected renderContent(context: RenderContext): string[];
48
+ private renderTabBar;
49
+ private renderDashboardTab;
50
+ private renderMoreTab;
51
+ private renderDashboardFooter;
52
+ private shortenPath;
53
+ handleKey(key: KeyEvent): OverlayAction<DashboardOverlayV2Result>;
54
+ }
55
+ export {};
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Dashboard Overlay V2
3
+ *
4
+ * Main entry point for the CLI when startup mode is 'dashboard'.
5
+ * Shows current project info, recent projects, and quick actions.
6
+ *
7
+ * Two tabs:
8
+ * - Dashboard: Current project, recent projects, actions
9
+ * - More: Help links, about information
10
+ */
11
+ import { BaseOverlayV2, isEscape, isEnter, isNavigateUp, isNavigateDown, isNavigateLeft, isNavigateRight, isTab, isShiftTab, isCtrlC, renderBorder, } from '../../base/index.js';
12
+ import { getCurrentProject } from '../../../tools/project-db.js';
13
+ import { projectRepository } from '../../../db/repositories/index.js';
14
+ import { workItemRepository } from '../../../db/repositories/work-item-repository.js';
15
+ // =============================================================================
16
+ // Constants
17
+ // =============================================================================
18
+ const VERSION = '0.4.0';
19
+ const TARGET_HEIGHT = 20; // Without logo (logo is printed to scrolling area)
20
+ const MAX_RECENT_PROJECTS = 3;
21
+ // =============================================================================
22
+ // Dashboard Overlay V2
23
+ // =============================================================================
24
+ export class DashboardOverlayV2 extends BaseOverlayV2 {
25
+ type = 'inline';
26
+ id = 'dashboard-overlay-v2';
27
+ minHeight = TARGET_HEIGHT;
28
+ constructor() {
29
+ // Load current project and recent projects
30
+ const current = getCurrentProject();
31
+ const { projects: recentProjects } = projectRepository.list({
32
+ status: 'all',
33
+ limit: MAX_RECENT_PROJECTS + 1, // Get one extra to exclude current
34
+ });
35
+ // Filter out current project from recent list
36
+ const filteredRecent = current
37
+ ? recentProjects.filter(p => p.id !== current.id).slice(0, MAX_RECENT_PROJECTS)
38
+ : recentProjects.slice(0, MAX_RECENT_PROJECTS);
39
+ // Get progress for current project
40
+ let progress = null;
41
+ if (current) {
42
+ const allItems = workItemRepository.query({ project_id: current.id });
43
+ const completedItems = workItemRepository.query({ project_id: current.id, status: 'completed' });
44
+ progress = {
45
+ completed: completedItems.total,
46
+ total: allItems.total,
47
+ };
48
+ }
49
+ super({
50
+ currentTab: 'dashboard',
51
+ selectedIndex: 0,
52
+ currentProject: current,
53
+ recentProjects: filteredRecent,
54
+ progress,
55
+ });
56
+ }
57
+ // ===========================================================================
58
+ // Get Items for Current Tab
59
+ // ===========================================================================
60
+ getDashboardItems() {
61
+ const items = [];
62
+ if (this.state.currentProject) {
63
+ // First item: Continue with current project
64
+ items.push({
65
+ key: '',
66
+ label: `Continue with ${this.state.currentProject.displayName}`,
67
+ description: 'Resume working on current project',
68
+ action: 'continue',
69
+ });
70
+ }
71
+ // Show recent projects as switch options (always, if any exist)
72
+ for (const project of this.state.recentProjects) {
73
+ items.push({
74
+ key: '',
75
+ label: `Switch to ${project.displayName}`,
76
+ description: this.formatProjectStatus(project),
77
+ action: 'continue',
78
+ });
79
+ }
80
+ // If no projects at all, show create/chat options
81
+ if (items.length === 0) {
82
+ items.push({
83
+ key: 'n',
84
+ label: '/new Project',
85
+ description: 'Create new or import existing project',
86
+ action: 'new',
87
+ });
88
+ items.push({
89
+ key: 'c',
90
+ label: 'Quick Chat',
91
+ description: 'Chat without project context',
92
+ action: 'chat',
93
+ });
94
+ }
95
+ return items;
96
+ }
97
+ getMoreItems() {
98
+ return [
99
+ { key: '?', label: 'Help', description: 'Show help and available commands', action: 'help' },
100
+ { key: '', label: 'Settings', description: 'Open configuration panel', action: 'config' },
101
+ { key: '', label: 'About', description: `compilr-dev-cli v${VERSION}`, action: 'about' },
102
+ ];
103
+ }
104
+ getItems() {
105
+ return this.state.currentTab === 'dashboard' ? this.getDashboardItems() : this.getMoreItems();
106
+ }
107
+ formatProjectStatus(project) {
108
+ const status = project.status.charAt(0).toUpperCase() + project.status.slice(1);
109
+ const ago = this.formatTimeAgo(project.lastActivityAt ?? project.updatedAt);
110
+ return `${status} • ${ago}`;
111
+ }
112
+ formatTimeAgo(date) {
113
+ const now = new Date();
114
+ const diffMs = now.getTime() - date.getTime();
115
+ const diffMins = Math.floor(diffMs / 60000);
116
+ const diffHours = Math.floor(diffMins / 60);
117
+ const diffDays = Math.floor(diffHours / 24);
118
+ const diffWeeks = Math.floor(diffDays / 7);
119
+ if (diffMins < 1)
120
+ return 'just now';
121
+ if (diffMins < 60)
122
+ return `${String(diffMins)}m ago`;
123
+ if (diffHours < 24)
124
+ return `${String(diffHours)}h ago`;
125
+ if (diffDays === 1)
126
+ return 'yesterday';
127
+ if (diffDays < 7)
128
+ return `${String(diffDays)} days ago`;
129
+ if (diffWeeks === 1)
130
+ return '1 week ago';
131
+ return `${String(diffWeeks)} weeks ago`;
132
+ }
133
+ // ===========================================================================
134
+ // Rendering
135
+ // ===========================================================================
136
+ renderContent(context) {
137
+ const lines = [];
138
+ const s = context.styles;
139
+ const cols = context.width;
140
+ // 1. Tab bar (logo is printed to scrolling area by menuCommand)
141
+ lines.push(renderBorder(cols, s));
142
+ lines.push(this.renderTabBar(s));
143
+ lines.push(renderBorder(cols, s));
144
+ lines.push('');
145
+ // 3. Content based on current tab
146
+ if (this.state.currentTab === 'dashboard') {
147
+ lines.push(...this.renderDashboardTab(context));
148
+ }
149
+ else {
150
+ lines.push(...this.renderMoreTab(context));
151
+ }
152
+ // 4. Footer with keyboard hints
153
+ lines.push('');
154
+ lines.push(...this.renderDashboardFooter(context));
155
+ // Pad to target height
156
+ while (lines.length < TARGET_HEIGHT) {
157
+ lines.push('');
158
+ }
159
+ return lines;
160
+ }
161
+ renderTabBar(s) {
162
+ const dashLabel = this.state.currentTab === 'dashboard' ? s.selected(' Dashboard ') : s.muted(' Dashboard ');
163
+ const moreLabel = this.state.currentTab === 'more' ? s.selected(' More ') : s.muted(' More ');
164
+ const hint = s.muted('(Tab Switch · 1-2 Jump)');
165
+ return ` ${dashLabel} │ ${moreLabel} ${hint}`;
166
+ }
167
+ renderDashboardTab(context) {
168
+ const lines = [];
169
+ const s = context.styles;
170
+ const items = this.getDashboardItems();
171
+ const hasProjects = this.state.currentProject || this.state.recentProjects.length > 0;
172
+ if (this.state.currentProject) {
173
+ // Current project section (display info)
174
+ lines.push(` ${s.primaryBold('CURRENT PROJECT')}`);
175
+ lines.push(` ${s.primary('★')} ${s.primaryBold(this.state.currentProject.displayName)}`);
176
+ // Path, status, mode
177
+ const project = projectRepository.getById(this.state.currentProject.id);
178
+ if (project) {
179
+ const pathShort = this.shortenPath(project.path);
180
+ lines.push(` ${s.muted(pathShort)} │ ${s.muted(project.status)} │ ${s.muted(project.workflowMode)}`);
181
+ }
182
+ // Progress bar
183
+ if (this.state.progress && this.state.progress.total > 0) {
184
+ const pct = Math.round((this.state.progress.completed / this.state.progress.total) * 100);
185
+ const barWidth = 20;
186
+ const filled = Math.round((pct / 100) * barWidth);
187
+ const empty = barWidth - filled;
188
+ const bar = s.success('█'.repeat(filled)) + s.muted('░'.repeat(empty));
189
+ lines.push(` Progress: ${bar} ${String(pct)}% (${String(this.state.progress.completed)}/${String(this.state.progress.total)} items)`);
190
+ }
191
+ lines.push('');
192
+ }
193
+ else if (hasProjects) {
194
+ // No current project but have recent projects - show select prompt
195
+ lines.push(` ${s.primaryBold('SELECT A PROJECT')}`);
196
+ lines.push(` ${s.muted('No project currently selected. Choose a project to continue.')}`);
197
+ lines.push('');
198
+ }
199
+ else {
200
+ // No projects at all - welcome screen
201
+ lines.push(` ${s.primaryBold('WELCOME TO COMPILR DEV CLI')}`);
202
+ lines.push('');
203
+ lines.push(` ${s.muted('Get started by creating a new project or importing an existing')}`);
204
+ lines.push(` ${s.muted('repository. Or use Quick Chat for general assistance.')}`);
205
+ lines.push('');
206
+ }
207
+ // Actions list
208
+ lines.push(` ${s.secondary('ACTIONS')}`);
209
+ for (let i = 0; i < items.length; i++) {
210
+ const item = items[i];
211
+ const isSelected = i === this.state.selectedIndex;
212
+ const prefix = isSelected ? s.primary(' ❯ ') : ' ';
213
+ const label = isSelected ? s.primary(item.label.padEnd(35)) : item.label.padEnd(35);
214
+ lines.push(`${prefix}${label}${s.muted(item.description)}`);
215
+ }
216
+ // Shortcut hints (only if we have projects)
217
+ if (hasProjects) {
218
+ lines.push('');
219
+ lines.push(` ${s.muted('[n] /new [p] Projects [c] Chat [w] Workflow')}`);
220
+ }
221
+ return lines;
222
+ }
223
+ renderMoreTab(context) {
224
+ const lines = [];
225
+ const s = context.styles;
226
+ lines.push(` ${s.primaryBold('HELP & DOCUMENTATION')}`);
227
+ lines.push('');
228
+ const items = this.getMoreItems();
229
+ for (let i = 0; i < items.length; i++) {
230
+ const item = items[i];
231
+ const isSelected = i === this.state.selectedIndex;
232
+ const prefix = isSelected ? s.primary(' ❯ ') : ' ';
233
+ const label = isSelected ? s.primary(item.label.padEnd(25)) : item.label.padEnd(25);
234
+ lines.push(`${prefix}${label}${s.muted(item.description)}`);
235
+ }
236
+ lines.push('');
237
+ lines.push(` ${s.muted('For more options, use /config to open settings.')}`);
238
+ return lines;
239
+ }
240
+ renderDashboardFooter(context) {
241
+ const s = context.styles;
242
+ return [
243
+ s.muted(' ↑↓/jk Navigate Enter Select q Quit'),
244
+ ];
245
+ }
246
+ shortenPath(fullPath) {
247
+ const home = process.env.HOME || process.env.USERPROFILE || '';
248
+ if (home && fullPath.startsWith(home)) {
249
+ return '~' + fullPath.slice(home.length);
250
+ }
251
+ return fullPath;
252
+ }
253
+ // ===========================================================================
254
+ // Key Handling
255
+ // ===========================================================================
256
+ handleKey(key) {
257
+ const data = key.raw;
258
+ const char = data.toString();
259
+ const items = this.getItems();
260
+ // Only q exits - Escape does nothing on dashboard (it's the home screen)
261
+ if (char === 'q') {
262
+ return this.close({ action: 'exit' });
263
+ }
264
+ // Escape and Ctrl+C just do nothing on dashboard
265
+ if (isEscape(data) || isCtrlC(data)) {
266
+ return this.noAction();
267
+ }
268
+ // Tab switching
269
+ if (isTab(data) || isNavigateRight(data) || char === 'l') {
270
+ this.state.currentTab = this.state.currentTab === 'dashboard' ? 'more' : 'dashboard';
271
+ this.state.selectedIndex = 0;
272
+ return this.rerender();
273
+ }
274
+ if (isShiftTab(data) || isNavigateLeft(data) || char === 'h') {
275
+ this.state.currentTab = this.state.currentTab === 'dashboard' ? 'more' : 'dashboard';
276
+ this.state.selectedIndex = 0;
277
+ return this.rerender();
278
+ }
279
+ // Number keys for tab jump (1 = Dashboard, 2 = More)
280
+ if (char === '1') {
281
+ this.state.currentTab = 'dashboard';
282
+ this.state.selectedIndex = 0;
283
+ return this.rerender();
284
+ }
285
+ if (char === '2') {
286
+ this.state.currentTab = 'more';
287
+ this.state.selectedIndex = 0;
288
+ return this.rerender();
289
+ }
290
+ // Navigation
291
+ if (isNavigateUp(data) || char === 'k') {
292
+ if (this.state.selectedIndex > 0) {
293
+ this.state.selectedIndex--;
294
+ return this.rerender();
295
+ }
296
+ return this.noAction();
297
+ }
298
+ if (isNavigateDown(data) || char === 'j') {
299
+ if (this.state.selectedIndex < items.length - 1) {
300
+ this.state.selectedIndex++;
301
+ return this.rerender();
302
+ }
303
+ return this.noAction();
304
+ }
305
+ // Enter selects current item
306
+ if (isEnter(data)) {
307
+ const selectedItem = items[this.state.selectedIndex];
308
+ if (selectedItem) {
309
+ if (selectedItem.action === 'continue') {
310
+ // For continue action, determine which project
311
+ if (this.state.currentProject && this.state.selectedIndex === 0) {
312
+ // First item = current project (only if we have a current project)
313
+ return this.close({
314
+ action: 'continue',
315
+ projectId: this.state.currentProject.id,
316
+ });
317
+ }
318
+ else {
319
+ // Recent projects - offset by 1 if we have a current project
320
+ const recentIndex = this.state.currentProject
321
+ ? this.state.selectedIndex - 1
322
+ : this.state.selectedIndex;
323
+ const recentProject = this.state.recentProjects[recentIndex];
324
+ if (recentProject) {
325
+ return this.close({
326
+ action: 'continue',
327
+ projectId: recentProject.id,
328
+ });
329
+ }
330
+ }
331
+ }
332
+ // For other actions (new, chat, help, config, about)
333
+ return this.close({ action: selectedItem.action });
334
+ }
335
+ return this.noAction();
336
+ }
337
+ // Quick action shortcuts (Dashboard tab only)
338
+ if (this.state.currentTab === 'dashboard') {
339
+ switch (char) {
340
+ case 'n':
341
+ return this.close({ action: 'new' });
342
+ case 'p':
343
+ return this.close({ action: 'projects' });
344
+ case 'c':
345
+ return this.close({ action: 'chat' });
346
+ case 'w':
347
+ if (this.state.currentProject) {
348
+ return this.close({ action: 'workflow' });
349
+ }
350
+ return this.noAction();
351
+ }
352
+ }
353
+ // More tab shortcuts
354
+ if (this.state.currentTab === 'more' && char === '?') {
355
+ return this.close({ action: 'help' });
356
+ }
357
+ return this.noAction();
358
+ }
359
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Docs Overlay V2
3
+ *
4
+ * Document browser for project documents (PRD, architecture, design, notes).
5
+ * Uses TabbedListOverlayV2 for consistent list/tab/search behavior.
6
+ *
7
+ * Features:
8
+ * - Tabbed filtering by document type
9
+ * - Search with / toggle
10
+ * - Paginated list
11
+ * - Returns selected document for viewing in separate fullscreen overlay
12
+ */
13
+ import { TabbedListOverlayV2 } from '../../base/tabbed-list-overlay-v2.js';
14
+ import type { OverlayAction, KeyEvent } from '../types.js';
15
+ import { type ProjectDocument } from '../../../db/repositories/document-repository.js';
16
+ export interface DocsOverlayV2Result {
17
+ /** Selected document to view (if any) */
18
+ selectedDocument?: ProjectDocument;
19
+ /** Whether user cancelled (Ctrl+C or Esc) */
20
+ cancelled: boolean;
21
+ }
22
+ export declare class DocsOverlayV2 extends TabbedListOverlayV2<ProjectDocument, DocsOverlayV2Result> {
23
+ readonly type: "inline";
24
+ readonly id = "docs-overlay-v2";
25
+ private readonly projectName;
26
+ /**
27
+ * @param projectId - Optional project ID to view documents for.
28
+ * If not provided, uses the active project.
29
+ * Pass this when opening from workflow overlay for a specific project.
30
+ */
31
+ constructor(projectId?: number);
32
+ /**
33
+ * Override to render project name in header
34
+ */
35
+ protected renderHeader(title: string, subtitle?: string): string[];
36
+ /**
37
+ * Override to handle item selection.
38
+ * Returns the selected document so the command handler can show it in a fullscreen overlay.
39
+ */
40
+ protected onItemSelected(doc: ProjectDocument): DocsOverlayV2Result | undefined;
41
+ /**
42
+ * Override to return result on close
43
+ */
44
+ handleKey(key: KeyEvent): OverlayAction<DocsOverlayV2Result>;
45
+ }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Docs Overlay V2
3
+ *
4
+ * Document browser for project documents (PRD, architecture, design, notes).
5
+ * Uses TabbedListOverlayV2 for consistent list/tab/search behavior.
6
+ *
7
+ * Features:
8
+ * - Tabbed filtering by document type
9
+ * - Search with / toggle
10
+ * - Paginated list
11
+ * - Returns selected document for viewing in separate fullscreen overlay
12
+ */
13
+ import { TabbedListOverlayV2 } from '../../base/tabbed-list-overlay-v2.js';
14
+ import { documentRepository } from '../../../db/repositories/document-repository.js';
15
+ import { getActiveProject } from '../../../tools/project-db.js';
16
+ // =============================================================================
17
+ // Constants
18
+ // =============================================================================
19
+ const PAGE_SIZE = 10;
20
+ const DOC_TYPE_LABELS = {
21
+ 'prd': 'PRD',
22
+ 'architecture': 'ARCH',
23
+ 'design': 'DESIGN',
24
+ 'notes': 'NOTES',
25
+ };
26
+ const TABS = [
27
+ { id: 'all', label: 'All' },
28
+ { id: 'prd', label: 'PRD' },
29
+ { id: 'architecture', label: 'ARCH' },
30
+ { id: 'design', label: 'DESIGN' },
31
+ { id: 'notes', label: 'NOTES' },
32
+ ];
33
+ // =============================================================================
34
+ // Docs Overlay V2
35
+ // =============================================================================
36
+ export class DocsOverlayV2 extends TabbedListOverlayV2 {
37
+ type = 'inline';
38
+ id = 'docs-overlay-v2';
39
+ projectName;
40
+ /**
41
+ * @param projectId - Optional project ID to view documents for.
42
+ * If not provided, uses the active project.
43
+ * Pass this when opening from workflow overlay for a specific project.
44
+ */
45
+ constructor(projectId) {
46
+ // Use provided projectId, or fall back to active project
47
+ const activeProject = getActiveProject();
48
+ const resolvedProjectId = projectId ?? activeProject?.id ?? null;
49
+ const projectName = projectId
50
+ ? null // Will be loaded if needed, but we don't have it here
51
+ : activeProject?.displayName ?? null;
52
+ // Load documents
53
+ const documents = resolvedProjectId !== null
54
+ ? documentRepository.listByProject(resolvedProjectId)
55
+ : [];
56
+ super({
57
+ title: 'Documents',
58
+ tabs: TABS,
59
+ items: documents,
60
+ pageSize: PAGE_SIZE,
61
+ filterByTab: (doc, tabId) => {
62
+ if (tabId === 'all')
63
+ return true;
64
+ return doc.docType === tabId;
65
+ },
66
+ getSearchText: (doc) => `${doc.title} ${doc.docType}`,
67
+ renderItem: (doc, isSelected, styles) => {
68
+ const prefix = isSelected ? styles.primary('❯ ') : ' ';
69
+ const typeLabel = (DOC_TYPE_LABELS[doc.docType] || doc.docType).padEnd(8);
70
+ const title = doc.title.slice(0, 50);
71
+ if (isSelected) {
72
+ return `${prefix}${styles.primaryBold(typeLabel)} ${styles.primary(title)}`;
73
+ }
74
+ return `${prefix}${styles.muted(typeLabel)} ${styles.secondary(title)}`;
75
+ },
76
+ showCount: true,
77
+ emptyMessage: resolvedProjectId === null
78
+ ? 'No active project. Use /projects to select one.'
79
+ : 'No documents found. Use /design or /arch to create documents.',
80
+ noResultsMessage: 'No documents match the search.',
81
+ });
82
+ this.projectName = projectName;
83
+ this.minHeight = 20;
84
+ }
85
+ /**
86
+ * Override to render project name in header
87
+ */
88
+ renderHeader(title, subtitle) {
89
+ const displaySubtitle = this.projectName || subtitle;
90
+ return super.renderHeader(title, displaySubtitle);
91
+ }
92
+ /**
93
+ * Override to handle item selection.
94
+ * Returns the selected document so the command handler can show it in a fullscreen overlay.
95
+ */
96
+ onItemSelected(doc) {
97
+ return { selectedDocument: doc, cancelled: false };
98
+ }
99
+ /**
100
+ * Override to return result on close
101
+ */
102
+ handleKey(key) {
103
+ // Check for close keys first
104
+ if (this.isInterruptKey(key)) {
105
+ return this.close({ cancelled: true });
106
+ }
107
+ if (this.isCloseKey(key) && !this.state.searchMode) {
108
+ return this.close({ cancelled: true });
109
+ }
110
+ // Let parent handle everything else (including Enter → onItemSelected)
111
+ // Parent will return the result from onItemSelected, so pass it through
112
+ return super.handleKey(key);
113
+ }
114
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Document Detail Overlay V2
3
+ *
4
+ * Fullscreen markdown document viewer AND editor with vim-style navigation.
5
+ * Separate from DocsOverlayV2 (inline list) to allow proper fullscreen rendering.
6
+ *
7
+ * Features:
8
+ * - Full-screen document viewing with markdown rendering
9
+ * - Vim-style navigation (j/k, g/G, PgUp/PgDn)
10
+ * - Edit mode with raw markdown editing
11
+ * - Save to database (Ctrl+S)
12
+ * - Dirty check with save prompt on exit
13
+ */
14
+ import { BaseOverlayV2 } from '../../base/overlay-base-v2.js';
15
+ import type { RenderContext, OverlayAction, KeyEvent } from '../types.js';
16
+ import { type ProjectDocument } from '../../../db/repositories/document-repository.js';
17
+ export interface DocumentDetailResult {
18
+ /** Whether to go back to the document list */
19
+ goBack: boolean;
20
+ }
21
+ interface DocumentDetailState {
22
+ contentLines: string[];
23
+ scrollOffset: number;
24
+ isEditMode: boolean;
25
+ rawLines: string[];
26
+ cursorLine: number;
27
+ cursorColumn: number;
28
+ editScrollOffset: number;
29
+ isDirty: boolean;
30
+ originalContent: string;
31
+ showSavePrompt: boolean;
32
+ saveMessage: string | null;
33
+ }
34
+ /**
35
+ * Fullscreen document viewer and editor overlay.
36
+ * Shows a single document with vim-style scrolling navigation.
37
+ * Supports edit mode for modifying raw markdown content.
38
+ */
39
+ export declare class DocumentDetailOverlayV2 extends BaseOverlayV2<DocumentDetailState, DocumentDetailResult> {
40
+ private readonly document;
41
+ readonly type: "inline";
42
+ readonly id = "document-detail-overlay-v2";
43
+ readonly usesAlternateScreen = true;
44
+ constructor(document: ProjectDocument);
45
+ /**
46
+ * Enter alternate screen buffer when overlay mounts.
47
+ * This preserves the main screen content.
48
+ */
49
+ onMount(): void;
50
+ /**
51
+ * Exit alternate screen buffer when overlay unmounts.
52
+ * This restores the main screen content.
53
+ */
54
+ onUnmount(): void;
55
+ protected renderContent(context: RenderContext): string[];
56
+ private renderViewMode;
57
+ private renderEditMode;
58
+ private renderLineWithCursor;
59
+ private ensureCursorVisible;
60
+ handleKey(key: KeyEvent): OverlayAction<DocumentDetailResult>;
61
+ private handleViewModeKey;
62
+ private handleEditModeKey;
63
+ private handleSavePromptKey;
64
+ private moveCursorUp;
65
+ private moveCursorDown;
66
+ private moveCursorLeft;
67
+ private moveCursorRight;
68
+ private clampCursorColumn;
69
+ private getCurrentLine;
70
+ private insertText;
71
+ private handleBackspace;
72
+ private handleDelete;
73
+ private handleEnter;
74
+ private saveDocument;
75
+ private exitEditMode;
76
+ }
77
+ export {};