@compilr-dev/cli 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/README.md +30 -12
  2. package/dist/agent.d.ts +74 -1
  3. package/dist/agent.js +259 -76
  4. package/dist/anchors/index.d.ts +9 -0
  5. package/dist/anchors/index.js +9 -0
  6. package/dist/anchors/project-anchors.d.ts +79 -0
  7. package/dist/anchors/project-anchors.js +202 -0
  8. package/dist/commands/handler-types.d.ts +68 -0
  9. package/dist/commands/handler-types.js +8 -0
  10. package/dist/commands/handlers/agent-commands.d.ts +13 -0
  11. package/dist/commands/handlers/agent-commands.js +305 -0
  12. package/dist/commands/handlers/design-commands.d.ts +15 -0
  13. package/dist/commands/handlers/design-commands.js +334 -0
  14. package/dist/commands/handlers/index.d.ts +20 -0
  15. package/dist/commands/handlers/index.js +43 -0
  16. package/dist/commands/handlers/overlay-commands.d.ts +21 -0
  17. package/dist/commands/handlers/overlay-commands.js +287 -0
  18. package/dist/commands/handlers/project-commands.d.ts +11 -0
  19. package/dist/commands/handlers/project-commands.js +167 -0
  20. package/dist/commands/handlers/simple-commands.d.ts +19 -0
  21. package/dist/commands/handlers/simple-commands.js +144 -0
  22. package/dist/commands/index.d.ts +2 -1
  23. package/dist/commands/registry.d.ts +50 -0
  24. package/dist/commands/registry.js +75 -0
  25. package/dist/commands-v2/handlers/context.d.ts +13 -0
  26. package/dist/commands-v2/handlers/context.js +348 -0
  27. package/dist/commands-v2/handlers/core.d.ts +13 -0
  28. package/dist/commands-v2/handlers/core.js +165 -0
  29. package/dist/commands-v2/handlers/debug.d.ts +11 -0
  30. package/dist/commands-v2/handlers/debug.js +159 -0
  31. package/dist/commands-v2/handlers/index.d.ts +12 -0
  32. package/dist/commands-v2/handlers/index.js +24 -0
  33. package/dist/commands-v2/handlers/project.d.ts +22 -0
  34. package/dist/commands-v2/handlers/project.js +814 -0
  35. package/dist/commands-v2/handlers/settings.d.ts +15 -0
  36. package/dist/commands-v2/handlers/settings.js +235 -0
  37. package/dist/commands-v2/index.d.ts +13 -0
  38. package/dist/commands-v2/index.js +15 -0
  39. package/dist/commands-v2/registry.d.ts +37 -0
  40. package/dist/commands-v2/registry.js +80 -0
  41. package/dist/commands-v2/types.d.ts +75 -0
  42. package/dist/commands-v2/types.js +7 -0
  43. package/dist/commands.js +110 -7
  44. package/dist/index.js +288 -29
  45. package/dist/input-handlers/index.d.ts +7 -0
  46. package/dist/input-handlers/index.js +7 -0
  47. package/dist/input-handlers/memory-handler.d.ts +26 -0
  48. package/dist/input-handlers/memory-handler.js +68 -0
  49. package/dist/repl-helpers.d.ts +63 -0
  50. package/dist/repl-helpers.js +318 -0
  51. package/dist/repl-v2.d.ts +155 -0
  52. package/dist/repl-v2.js +774 -0
  53. package/dist/repl.d.ts +32 -4
  54. package/dist/repl.js +250 -977
  55. package/dist/settings/index.d.ts +23 -0
  56. package/dist/settings/index.js +48 -0
  57. package/dist/settings/paths.d.ts +110 -0
  58. package/dist/settings/paths.js +264 -0
  59. package/dist/templates/compilr-md.js +7 -4
  60. package/dist/templates/index.js +3 -4
  61. package/dist/themes/colors.js +3 -1
  62. package/dist/themes/registry.d.ts +5 -36
  63. package/dist/themes/registry.js +11 -95
  64. package/dist/themes/types.d.ts +3 -38
  65. package/dist/themes/types.js +2 -2
  66. package/dist/tools/anchor-tools.d.ts +31 -0
  67. package/dist/tools/anchor-tools.js +255 -0
  68. package/dist/tools/backlog-wrappers.d.ts +54 -0
  69. package/dist/tools/backlog-wrappers.js +338 -0
  70. package/dist/tools/backlog.js +1 -1
  71. package/dist/tools/db-tools.d.ts +65 -0
  72. package/dist/tools/db-tools.js +19 -0
  73. package/dist/tools/document-db.d.ts +43 -0
  74. package/dist/tools/document-db.js +220 -0
  75. package/dist/tools/project-db.d.ts +102 -0
  76. package/dist/tools/project-db.js +370 -0
  77. package/dist/tools/workitem-db.d.ts +103 -0
  78. package/dist/tools/workitem-db.js +549 -0
  79. package/dist/tools.js +13 -3
  80. package/dist/ui/agents-overlay-v2.d.ts +43 -0
  81. package/dist/ui/agents-overlay-v2.js +809 -0
  82. package/dist/ui/agents-overlay.d.ts +5 -5
  83. package/dist/ui/agents-overlay.js +782 -420
  84. package/dist/ui/anchors-overlay.d.ts +12 -0
  85. package/dist/ui/anchors-overlay.js +775 -0
  86. package/dist/ui/arch-type-overlay.d.ts +1 -6
  87. package/dist/ui/arch-type-overlay.js +175 -203
  88. package/dist/ui/ask-user-overlay-v2.d.ts +26 -0
  89. package/dist/ui/ask-user-overlay-v2.js +555 -0
  90. package/dist/ui/ask-user-overlay.d.ts +2 -2
  91. package/dist/ui/ask-user-overlay.js +443 -535
  92. package/dist/ui/ask-user-simple-overlay-v2.d.ts +25 -0
  93. package/dist/ui/ask-user-simple-overlay-v2.js +215 -0
  94. package/dist/ui/ask-user-simple-overlay.d.ts +2 -2
  95. package/dist/ui/ask-user-simple-overlay.js +182 -209
  96. package/dist/ui/backlog-overlay.d.ts +16 -1
  97. package/dist/ui/backlog-overlay.js +525 -659
  98. package/dist/ui/base/index.d.ts +26 -0
  99. package/dist/ui/base/index.js +33 -0
  100. package/dist/ui/base/inline-overlay-utils.d.ts +217 -0
  101. package/dist/ui/base/inline-overlay-utils.js +320 -0
  102. package/dist/ui/base/inline-overlay.d.ts +159 -0
  103. package/dist/ui/base/inline-overlay.js +257 -0
  104. package/dist/ui/base/key-utils.d.ts +15 -0
  105. package/dist/ui/base/key-utils.js +30 -0
  106. package/dist/ui/base/overlay-base-v2.d.ts +193 -0
  107. package/dist/ui/base/overlay-base-v2.js +246 -0
  108. package/dist/ui/base/overlay-base.d.ts +156 -0
  109. package/dist/ui/base/overlay-base.js +238 -0
  110. package/dist/ui/base/overlay-lifecycle.d.ts +65 -0
  111. package/dist/ui/base/overlay-lifecycle.js +159 -0
  112. package/dist/ui/base/overlay-types.d.ts +185 -0
  113. package/dist/ui/base/overlay-types.js +7 -0
  114. package/dist/ui/base/render-utils.d.ts +8 -0
  115. package/dist/ui/base/render-utils.js +11 -0
  116. package/dist/ui/base/screen-stack.d.ts +148 -0
  117. package/dist/ui/base/screen-stack.js +184 -0
  118. package/dist/ui/base/tabbed-list-overlay-v2.d.ts +103 -0
  119. package/dist/ui/base/tabbed-list-overlay-v2.js +317 -0
  120. package/dist/ui/base/tabbed-list-overlay.d.ts +153 -0
  121. package/dist/ui/base/tabbed-list-overlay.js +369 -0
  122. package/dist/ui/commands-overlay-v2.d.ts +33 -0
  123. package/dist/ui/commands-overlay-v2.js +441 -0
  124. package/dist/ui/commands-overlay.d.ts +7 -2
  125. package/dist/ui/commands-overlay.js +384 -355
  126. package/dist/ui/config-overlay.d.ts +5 -4
  127. package/dist/ui/config-overlay.js +243 -513
  128. package/dist/ui/conversation.d.ts +75 -4
  129. package/dist/ui/conversation.js +374 -161
  130. package/dist/ui/docs-overlay.d.ts +17 -0
  131. package/dist/ui/docs-overlay.js +303 -0
  132. package/dist/ui/ephemeral.d.ts +1 -1
  133. package/dist/ui/ephemeral.js +1 -1
  134. package/dist/ui/features/index.d.ts +34 -0
  135. package/dist/ui/features/index.js +34 -0
  136. package/dist/ui/features/input-feature.d.ts +85 -0
  137. package/dist/ui/features/input-feature.js +238 -0
  138. package/dist/ui/features/list-feature.d.ts +155 -0
  139. package/dist/ui/features/list-feature.js +244 -0
  140. package/dist/ui/features/pagination-feature.d.ts +154 -0
  141. package/dist/ui/features/pagination-feature.js +238 -0
  142. package/dist/ui/features/search-feature.d.ts +148 -0
  143. package/dist/ui/features/search-feature.js +185 -0
  144. package/dist/ui/features/tab-feature.d.ts +194 -0
  145. package/dist/ui/features/tab-feature.js +307 -0
  146. package/dist/ui/footer-v2.d.ts +222 -0
  147. package/dist/ui/footer-v2.js +1349 -0
  148. package/dist/ui/footer.d.ts +107 -0
  149. package/dist/ui/footer.js +359 -67
  150. package/dist/ui/guardrail-overlay.d.ts +29 -0
  151. package/dist/ui/guardrail-overlay.js +145 -0
  152. package/dist/ui/help-overlay-v2.d.ts +34 -0
  153. package/dist/ui/help-overlay-v2.js +309 -0
  154. package/dist/ui/help-overlay.d.ts +16 -0
  155. package/dist/ui/help-overlay.js +316 -0
  156. package/dist/ui/index.d.ts +1 -1
  157. package/dist/ui/index.js +1 -3
  158. package/dist/ui/init-overlay-v2.d.ts +34 -0
  159. package/dist/ui/init-overlay-v2.js +600 -0
  160. package/dist/ui/init-overlay.d.ts +12 -2
  161. package/dist/ui/init-overlay.js +349 -270
  162. package/dist/ui/input-prompt-v2.d.ts +1 -0
  163. package/dist/ui/input-prompt-v2.js +14 -6
  164. package/dist/ui/input-prompt.d.ts +116 -33
  165. package/dist/ui/input-prompt.js +536 -337
  166. package/dist/ui/iteration-limit-overlay-v2.d.ts +21 -0
  167. package/dist/ui/iteration-limit-overlay-v2.js +114 -0
  168. package/dist/ui/iteration-limit-overlay.d.ts +2 -2
  169. package/dist/ui/iteration-limit-overlay.js +92 -128
  170. package/dist/ui/keys-overlay-v2.d.ts +41 -0
  171. package/dist/ui/keys-overlay-v2.js +248 -0
  172. package/dist/ui/keys-overlay.d.ts +1 -0
  173. package/dist/ui/keys-overlay.js +203 -141
  174. package/dist/ui/line-utils.d.ts +88 -0
  175. package/dist/ui/line-utils.js +150 -0
  176. package/dist/ui/live-region.d.ts +161 -0
  177. package/dist/ui/live-region.js +387 -0
  178. package/dist/ui/mascot/expressions.d.ts +32 -0
  179. package/dist/ui/mascot/expressions.js +213 -0
  180. package/dist/ui/mascot/index.d.ts +8 -0
  181. package/dist/ui/mascot/index.js +8 -0
  182. package/dist/ui/mascot/renderer.d.ts +19 -0
  183. package/dist/ui/mascot/renderer.js +97 -0
  184. package/dist/ui/mascot-overlay-v2.d.ts +41 -0
  185. package/dist/ui/mascot-overlay-v2.js +138 -0
  186. package/dist/ui/mascot-overlay.d.ts +21 -0
  187. package/dist/ui/mascot-overlay.js +146 -0
  188. package/dist/ui/model-overlay-v2.d.ts +49 -0
  189. package/dist/ui/model-overlay-v2.js +118 -0
  190. package/dist/ui/model-overlay.d.ts +27 -0
  191. package/dist/ui/model-overlay.js +221 -0
  192. package/dist/ui/model-warning-overlay.js +3 -5
  193. package/dist/ui/new-overlay.d.ts +34 -0
  194. package/dist/ui/new-overlay.js +604 -0
  195. package/dist/ui/overlay/impl/agents-overlay-v2.d.ts +45 -0
  196. package/dist/ui/overlay/impl/agents-overlay-v2.js +825 -0
  197. package/dist/ui/overlay/impl/anchors-overlay-v2.d.ts +47 -0
  198. package/dist/ui/overlay/impl/anchors-overlay-v2.js +783 -0
  199. package/dist/ui/overlay/impl/arch-type-overlay-v2.d.ts +37 -0
  200. package/dist/ui/overlay/impl/arch-type-overlay-v2.js +240 -0
  201. package/dist/ui/overlay/impl/ask-user-overlay-v2.d.ts +72 -0
  202. package/dist/ui/overlay/impl/ask-user-overlay-v2.js +584 -0
  203. package/dist/ui/overlay/impl/ask-user-simple-overlay-v2.d.ts +46 -0
  204. package/dist/ui/overlay/impl/ask-user-simple-overlay-v2.js +204 -0
  205. package/dist/ui/overlay/impl/backlog-overlay-v2.d.ts +49 -0
  206. package/dist/ui/overlay/impl/backlog-overlay-v2.js +642 -0
  207. package/dist/ui/overlay/impl/commands-overlay-v2.d.ts +33 -0
  208. package/dist/ui/overlay/impl/commands-overlay-v2.js +441 -0
  209. package/dist/ui/overlay/impl/config-overlay-v2.d.ts +100 -0
  210. package/dist/ui/overlay/impl/config-overlay-v2.js +654 -0
  211. package/dist/ui/overlay/impl/dashboard-overlay-v2.d.ts +55 -0
  212. package/dist/ui/overlay/impl/dashboard-overlay-v2.js +359 -0
  213. package/dist/ui/overlay/impl/docs-overlay-v2.d.ts +45 -0
  214. package/dist/ui/overlay/impl/docs-overlay-v2.js +114 -0
  215. package/dist/ui/overlay/impl/document-detail-overlay-v2.d.ts +77 -0
  216. package/dist/ui/overlay/impl/document-detail-overlay-v2.js +1071 -0
  217. package/dist/ui/overlay/impl/guardrail-overlay-v2.d.ts +43 -0
  218. package/dist/ui/overlay/impl/guardrail-overlay-v2.js +114 -0
  219. package/dist/ui/overlay/impl/help-overlay-v2.d.ts +34 -0
  220. package/dist/ui/overlay/impl/help-overlay-v2.js +309 -0
  221. package/dist/ui/overlay/impl/init-overlay-v2.d.ts +77 -0
  222. package/dist/ui/overlay/impl/init-overlay-v2.js +593 -0
  223. package/dist/ui/overlay/impl/init-setup-overlay-v2.d.ts +25 -0
  224. package/dist/ui/overlay/impl/init-setup-overlay-v2.js +97 -0
  225. package/dist/ui/overlay/impl/iteration-limit-overlay-v2.d.ts +35 -0
  226. package/dist/ui/overlay/impl/iteration-limit-overlay-v2.js +105 -0
  227. package/dist/ui/overlay/impl/keys-overlay-v2.d.ts +41 -0
  228. package/dist/ui/overlay/impl/keys-overlay-v2.js +248 -0
  229. package/dist/ui/overlay/impl/mascot-overlay-v2.d.ts +41 -0
  230. package/dist/ui/overlay/impl/mascot-overlay-v2.js +138 -0
  231. package/dist/ui/overlay/impl/model-overlay-v2.d.ts +49 -0
  232. package/dist/ui/overlay/impl/model-overlay-v2.js +118 -0
  233. package/dist/ui/overlay/impl/model-warning-overlay-v2.d.ts +46 -0
  234. package/dist/ui/overlay/impl/model-warning-overlay-v2.js +132 -0
  235. package/dist/ui/overlay/impl/new-overlay-v2.d.ts +77 -0
  236. package/dist/ui/overlay/impl/new-overlay-v2.js +593 -0
  237. package/dist/ui/overlay/impl/permission-overlay-v2.d.ts +36 -0
  238. package/dist/ui/overlay/impl/permission-overlay-v2.js +380 -0
  239. package/dist/ui/overlay/impl/projects-overlay-v2.d.ts +36 -0
  240. package/dist/ui/overlay/impl/projects-overlay-v2.js +499 -0
  241. package/dist/ui/overlay/impl/theme-overlay-v2.d.ts +42 -0
  242. package/dist/ui/overlay/impl/theme-overlay-v2.js +135 -0
  243. package/dist/ui/overlay/impl/tools-overlay-v2.d.ts +47 -0
  244. package/dist/ui/overlay/impl/tools-overlay-v2.js +218 -0
  245. package/dist/ui/overlay/impl/tutorial-overlay-v2.d.ts +31 -0
  246. package/dist/ui/overlay/impl/tutorial-overlay-v2.js +1035 -0
  247. package/dist/ui/overlay/impl/workflow-overlay-v2.d.ts +80 -0
  248. package/dist/ui/overlay/impl/workflow-overlay-v2.js +637 -0
  249. package/dist/ui/overlay/index.d.ts +33 -0
  250. package/dist/ui/overlay/index.js +35 -0
  251. package/dist/ui/overlay/key-utils.d.ts +6 -0
  252. package/dist/ui/overlay/key-utils.js +6 -0
  253. package/dist/ui/overlay/overlay-types.d.ts +128 -0
  254. package/dist/ui/overlay/overlay-types.js +22 -0
  255. package/dist/ui/overlay/types.d.ts +135 -0
  256. package/dist/ui/overlay/types.js +22 -0
  257. package/dist/ui/overlays/help-overlay-v2.d.ts +28 -0
  258. package/dist/ui/overlays/help-overlay-v2.js +198 -0
  259. package/dist/ui/overlays/index.d.ts +11 -0
  260. package/dist/ui/overlays/index.js +11 -0
  261. package/dist/ui/overlays.d.ts +0 -4
  262. package/dist/ui/overlays.js +0 -444
  263. package/dist/ui/permission-overlay-v2.d.ts +36 -0
  264. package/dist/ui/permission-overlay-v2.js +380 -0
  265. package/dist/ui/permission-overlay.d.ts +1 -1
  266. package/dist/ui/permission-overlay.js +186 -298
  267. package/dist/ui/projects-overlay.d.ts +19 -0
  268. package/dist/ui/projects-overlay.js +484 -0
  269. package/dist/ui/providers/types.d.ts +178 -0
  270. package/dist/ui/providers/types.js +9 -0
  271. package/dist/ui/render-modes.d.ts +36 -0
  272. package/dist/ui/render-modes.js +44 -0
  273. package/dist/ui/startup-menu.d.ts +36 -0
  274. package/dist/ui/startup-menu.js +236 -0
  275. package/dist/ui/subagent-renderer.d.ts +117 -0
  276. package/dist/ui/subagent-renderer.js +334 -0
  277. package/dist/ui/terminal-codes.d.ts +94 -0
  278. package/dist/ui/terminal-codes.js +124 -0
  279. package/dist/ui/terminal-renderer.d.ts +221 -0
  280. package/dist/ui/terminal-renderer.js +751 -0
  281. package/dist/ui/terminal-ui.d.ts +463 -0
  282. package/dist/ui/terminal-ui.js +2296 -0
  283. package/dist/ui/terminal.d.ts +20 -0
  284. package/dist/ui/terminal.js +72 -0
  285. package/dist/ui/theme-overlay-v2.d.ts +42 -0
  286. package/dist/ui/theme-overlay-v2.js +135 -0
  287. package/dist/ui/theme-overlay.d.ts +24 -0
  288. package/dist/ui/theme-overlay.js +127 -0
  289. package/dist/ui/todo-zone.js +53 -25
  290. package/dist/ui/tool-formatters.d.ts +16 -0
  291. package/dist/ui/tool-formatters.js +516 -0
  292. package/dist/ui/tools-overlay-v2.d.ts +47 -0
  293. package/dist/ui/tools-overlay-v2.js +218 -0
  294. package/dist/ui/tools-overlay.d.ts +10 -2
  295. package/dist/ui/tools-overlay.js +172 -220
  296. package/dist/ui/tutorial-overlay-v2.d.ts +31 -0
  297. package/dist/ui/tutorial-overlay-v2.js +1035 -0
  298. package/dist/ui/tutorial-overlay.d.ts +1 -0
  299. package/dist/ui/tutorial-overlay.js +400 -302
  300. package/dist/ui/workflow-overlay.d.ts +22 -0
  301. package/dist/ui/workflow-overlay.js +636 -0
  302. package/dist/utils/debug-log.d.ts +28 -0
  303. package/dist/utils/debug-log.js +57 -0
  304. package/dist/utils/model-tiers.js +1 -1
  305. package/dist/utils/path-safety.d.ts +56 -0
  306. package/dist/utils/path-safety.js +239 -0
  307. package/dist/workflow/guided-mode-injector.d.ts +42 -0
  308. package/dist/workflow/guided-mode-injector.js +191 -0
  309. package/dist/workflow/index.d.ts +8 -0
  310. package/dist/workflow/index.js +8 -0
  311. package/dist/workflow/step-criteria.d.ts +62 -0
  312. package/dist/workflow/step-criteria.js +150 -0
  313. package/dist/workflow/step-tracker.d.ts +92 -0
  314. package/dist/workflow/step-tracker.js +141 -0
  315. package/package.json +12 -5
@@ -2,12 +2,7 @@
2
2
  * Architecture Type Selection Overlay
3
3
  *
4
4
  * Shows options for what type of architecture documentation to create.
5
- * User selects from:
6
- * - ADR (Architecture Decision Record)
7
- * - System Diagram
8
- * - Data Model
9
- * - API Design
10
- * - Custom topic
5
+ * Refactored to use BaseOverlay + ScreenStack + InputFeature.
11
6
  */
12
7
  export type ArchDocType = 'adr' | 'diagram' | 'data-model' | 'api' | 'custom';
13
8
  export interface ArchTypeChoice {
@@ -2,228 +2,200 @@
2
2
  * Architecture Type Selection Overlay
3
3
  *
4
4
  * Shows options for what type of architecture documentation to create.
5
- * User selects from:
6
- * - ADR (Architecture Decision Record)
7
- * - System Diagram
8
- * - Data Model
9
- * - API Design
10
- * - Custom topic
5
+ * Refactored to use BaseOverlay + ScreenStack + InputFeature.
11
6
  */
12
7
  import * as terminal from './terminal.js';
13
- import { getStyles } from '../themes/index.js';
14
- import { pauseForOverlay, resumeAfterOverlay } from './overlay-controller.js';
8
+ import { BaseOverlay, BaseScreen, ScreenStack, stay, pushScreen, popScreen, closeOverlay, isEscape, isEnter, isCtrlC, isNavigateUp, isNavigateDown, isClose, } from './base/index.js';
9
+ import { InputFeature } from './features/index.js';
15
10
  const ARCH_OPTIONS = [
16
- { key: '1', type: 'adr', label: 'Decision Record (ADR)', description: '"Why we chose X over Y"' },
17
- { key: '2', type: 'diagram', label: 'System Diagram', description: 'Mermaid component diagram' },
18
- { key: '3', type: 'data-model', label: 'Data Model', description: 'Entities and relationships' },
19
- { key: '4', type: 'api', label: 'API Design', description: 'Endpoints and contracts' },
20
- { key: '5', type: 'custom', label: 'Custom topic...', description: 'Specify your own' },
11
+ { type: 'adr', label: 'Decision Record (ADR)', description: '"Why we chose X over Y"' },
12
+ { type: 'diagram', label: 'System Diagram', description: 'Mermaid component diagram' },
13
+ { type: 'data-model', label: 'Data Model', description: 'Entities and relationships' },
14
+ { type: 'api', label: 'API Design', description: 'Endpoints and contracts' },
15
+ { type: 'custom', label: 'Custom topic...', description: 'Specify your own' },
21
16
  ];
22
- // =============================================================================
23
- // Rendering
24
- // =============================================================================
25
- function render(selectedIndex, previousLineCount = 0, targetLineCount = 0) {
26
- const s = getStyles();
27
- const lines = [];
28
- const cols = terminal.getTerminalWidth();
29
- const border = s.muted('─'.repeat(Math.max(1, cols - 1)));
30
- // Clear previous render
31
- if (previousLineCount > 0) {
32
- terminal.clearLinesAbove(previousLineCount);
17
+ /**
18
+ * Select screen - shows list of architecture doc types
19
+ */
20
+ class SelectScreen extends BaseScreen {
21
+ state;
22
+ styles;
23
+ constructor(state, styles) {
24
+ super();
25
+ this.state = state;
26
+ this.styles = styles;
33
27
  }
34
- // Header
35
- lines.push(border);
36
- lines.push(' ' + s.primary('Architecture Documentation'));
37
- lines.push('');
38
- // Question
39
- lines.push(' What would you like to document?');
40
- lines.push('');
41
- // Options
42
- for (let i = 0; i < ARCH_OPTIONS.length; i++) {
43
- const opt = ARCH_OPTIONS[i];
44
- const isCursor = selectedIndex === i;
45
- const prefix = isCursor ? '' : ' ';
46
- // Calculate max label width for alignment
28
+ render() {
29
+ const s = this.styles;
30
+ const cols = terminal.getTerminalWidth();
31
+ const border = s.muted(''.repeat(Math.max(1, cols - 1)));
32
+ const lines = [];
33
+ // Header
34
+ lines.push(border);
35
+ lines.push(' ' + s.primary('Architecture Documentation'));
36
+ lines.push('');
37
+ // Question
38
+ lines.push(' What would you like to document?');
39
+ lines.push('');
40
+ // Options
47
41
  const maxLabelLen = Math.max(...ARCH_OPTIONS.map((o) => o.label.length));
48
- const paddedLabel = opt.label.padEnd(maxLabelLen + 2);
49
- if (isCursor) {
50
- lines.push(s.primary(`${prefix}${opt.key}. ${paddedLabel}`) + s.muted(opt.description));
42
+ for (let i = 0; i < ARCH_OPTIONS.length; i++) {
43
+ const opt = ARCH_OPTIONS[i];
44
+ const isCursor = this.state.selectedIndex === i;
45
+ const prefix = isCursor ? ' ❯ ' : ' ';
46
+ const paddedLabel = opt.label.padEnd(maxLabelLen + 2);
47
+ if (isCursor) {
48
+ lines.push(s.primary(`${prefix}${paddedLabel}`) + s.muted(opt.description));
49
+ }
50
+ else {
51
+ lines.push(s.muted(`${prefix}${paddedLabel}${opt.description}`));
52
+ }
53
+ }
54
+ // Footer
55
+ lines.push('');
56
+ lines.push(s.muted(' ↑↓/jk Navigate · Enter Select · q/Esc Cancel'));
57
+ lines.push(border);
58
+ return lines;
59
+ }
60
+ handleKey(data) {
61
+ // Close keys
62
+ if (isCtrlC(data) || isClose(data)) {
63
+ return closeOverlay(null);
64
+ }
65
+ // Navigation up
66
+ if (isNavigateUp(data)) {
67
+ this.state.selectedIndex = Math.max(0, this.state.selectedIndex - 1);
68
+ return stay();
51
69
  }
52
- else {
53
- lines.push(s.muted(`${prefix}${opt.key}. ${paddedLabel}${opt.description}`));
70
+ // Navigation down
71
+ if (isNavigateDown(data)) {
72
+ this.state.selectedIndex = Math.min(ARCH_OPTIONS.length - 1, this.state.selectedIndex + 1);
73
+ return stay();
54
74
  }
75
+ // Enter - select option
76
+ if (isEnter(data)) {
77
+ const selected = ARCH_OPTIONS[this.state.selectedIndex];
78
+ if (selected.type === 'custom') {
79
+ // Switch to custom input screen
80
+ return pushScreen(new CustomInputScreen(this.styles));
81
+ }
82
+ return closeOverlay({ type: selected.type });
83
+ }
84
+ return stay();
85
+ }
86
+ }
87
+ /**
88
+ * Custom input screen - text input for custom topic using InputFeature
89
+ */
90
+ class CustomInputScreen extends BaseScreen {
91
+ styles;
92
+ input;
93
+ constructor(styles) {
94
+ super();
95
+ this.styles = styles;
96
+ this.input = new InputFeature({ placeholder: 'e.g., Security Architecture' });
55
97
  }
56
- // Footer
57
- lines.push('');
58
- lines.push(s.muted(' ↑↓ Navigate · Enter Select · Esc Cancel'));
59
- lines.push(border);
60
- // Pad with empty lines to maintain consistent height
61
- while (lines.length < targetLineCount) {
98
+ onEnter() {
99
+ terminal.showCursor();
100
+ }
101
+ onExit() {
102
+ terminal.hideCursor();
103
+ }
104
+ render() {
105
+ const s = this.styles;
106
+ const cols = terminal.getTerminalWidth();
107
+ const border = s.muted('─'.repeat(Math.max(1, cols - 1)));
108
+ const lines = [];
109
+ // Header
110
+ lines.push(border);
111
+ lines.push(' ' + s.primary('Custom Architecture Topic'));
112
+ lines.push('');
113
+ // Input field
114
+ lines.push(' Enter the topic you want to document:');
62
115
  lines.push('');
116
+ lines.push(' ' + this.input.render(s));
117
+ lines.push('');
118
+ // Footer
119
+ lines.push(s.muted(' Enter Confirm · Esc Back · ←→ Move cursor'));
120
+ lines.push(border);
121
+ return lines;
122
+ }
123
+ handleKey(data) {
124
+ // Ctrl+C closes overlay
125
+ if (isCtrlC(data)) {
126
+ return closeOverlay(null);
127
+ }
128
+ // Escape goes back to select screen
129
+ if (isEscape(data)) {
130
+ return popScreen();
131
+ }
132
+ // Enter confirms input
133
+ if (isEnter(data)) {
134
+ const value = this.input.trimmedValue;
135
+ if (value) {
136
+ return closeOverlay({ type: 'custom', customTopic: value });
137
+ }
138
+ return stay(false); // Don't allow empty
139
+ }
140
+ // Let InputFeature handle the key
141
+ const result = this.input.handleKey(data);
142
+ if (result.handled) {
143
+ return stay(result.render);
144
+ }
145
+ return stay(false);
63
146
  }
64
- // Render all lines
65
- terminal.write(lines.join('\n'));
66
- return lines.length;
67
147
  }
68
- function renderCustomInput(inputValue, previousLineCount = 0, targetLineCount = 0) {
69
- const s = getStyles();
70
- const lines = [];
71
- const cols = terminal.getTerminalWidth();
72
- const border = s.muted('─'.repeat(Math.max(1, cols - 1)));
73
- // Clear previous render
74
- if (previousLineCount > 0) {
75
- terminal.clearLinesAbove(previousLineCount);
148
+ // =============================================================================
149
+ // Overlay Class
150
+ // =============================================================================
151
+ class ArchTypeOverlay extends BaseOverlay {
152
+ screenStack;
153
+ constructor() {
154
+ super({
155
+ lineCount: 0,
156
+ maxLineCount: 0,
157
+ selectedIndex: 0,
158
+ });
159
+ this.screenStack = new ScreenStack();
160
+ this.screenStack.push(new SelectScreen(this.state, this.styles));
76
161
  }
77
- // Header
78
- lines.push(border);
79
- lines.push(' ' + s.primary('Custom Architecture Topic'));
80
- lines.push('');
81
- // Input field
82
- lines.push(' Enter the topic you want to document:');
83
- lines.push('');
84
- lines.push(' ' + s.primary('> ') + inputValue + s.primary('_'));
85
- lines.push('');
86
- // Footer
87
- lines.push(s.muted(' Enter to confirm · Esc to go back'));
88
- lines.push(border);
89
- // Pad with empty lines to maintain consistent height
90
- while (lines.length < targetLineCount) {
91
- lines.push('');
162
+ render() {
163
+ const screen = this.screenStack.current();
164
+ return screen?.render() ?? [];
165
+ }
166
+ handleKey(data) {
167
+ const screen = this.screenStack.current();
168
+ if (!screen) {
169
+ this.close(null);
170
+ return;
171
+ }
172
+ const result = screen.handleKey(data);
173
+ switch (result.action) {
174
+ case 'stay':
175
+ if (result.render) {
176
+ this.update();
177
+ }
178
+ break;
179
+ case 'push':
180
+ this.screenStack.push(result.screen);
181
+ this.update();
182
+ break;
183
+ case 'pop':
184
+ this.screenStack.pop();
185
+ this.update();
186
+ break;
187
+ case 'close':
188
+ this.close(result.result);
189
+ break;
190
+ }
92
191
  }
93
- // Render all lines
94
- terminal.write(lines.join('\n'));
95
- return lines.length;
96
192
  }
97
193
  // =============================================================================
98
- // Main Export
194
+ // Export Function (Backward Compatible)
99
195
  // =============================================================================
100
196
  /**
101
197
  * Show the architecture type selection overlay and return the user's choice.
102
198
  */
103
199
  export async function showArchTypeOverlay() {
104
- let selectedIndex = 0;
105
- let lineCount = 0;
106
- let maxLineCount = 0;
107
- let mode = 'select';
108
- let customInput = '';
109
- // Pause footer animation
110
- pauseForOverlay();
111
- // Clear and prepare
112
- terminal.clearToEndOfScreen();
113
- terminal.writeLine('');
114
- terminal.hideCursor();
115
- const wasRawMode = process.stdin.isRaw;
116
- terminal.enableRawMode();
117
- // Initial render
118
- lineCount = render(selectedIndex, 0);
119
- maxLineCount = Math.max(maxLineCount, lineCount);
120
- // Re-render to stabilize
121
- lineCount = render(selectedIndex, lineCount, lineCount);
122
- return new Promise((resolve) => {
123
- const cleanup = () => {
124
- terminal.clearLinesAbove(maxLineCount);
125
- terminal.writeLine('');
126
- terminal.showCursor();
127
- if (!wasRawMode) {
128
- terminal.disableRawMode();
129
- }
130
- process.stdin.removeListener('data', handleData);
131
- resumeAfterOverlay();
132
- };
133
- const handleData = (data) => {
134
- const isEscape = data.length === 1 && data[0] === 0x1b;
135
- const isUpArrow = data.length === 3 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x41;
136
- const isDownArrow = data.length === 3 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x42;
137
- const isCtrlC = data.length === 1 && data[0] === 0x03;
138
- const isEnter = data.length === 1 && (data[0] === 0x0d || data[0] === 0x0a);
139
- const isBackspace = data.length === 1 && (data[0] === 0x7f || data[0] === 0x08);
140
- if (mode === 'select') {
141
- // Ctrl+C or Escape cancels
142
- if (isCtrlC || isEscape) {
143
- cleanup();
144
- resolve(null);
145
- return;
146
- }
147
- // Navigation
148
- if (isUpArrow) {
149
- selectedIndex = Math.max(0, selectedIndex - 1);
150
- }
151
- else if (isDownArrow) {
152
- selectedIndex = Math.min(ARCH_OPTIONS.length - 1, selectedIndex + 1);
153
- }
154
- else if (isEnter) {
155
- const selected = ARCH_OPTIONS[selectedIndex];
156
- if (selected.type === 'custom') {
157
- // Switch to custom input mode
158
- mode = 'custom-input';
159
- customInput = '';
160
- terminal.showCursor();
161
- lineCount = renderCustomInput(customInput, maxLineCount, maxLineCount);
162
- maxLineCount = Math.max(maxLineCount, lineCount);
163
- return;
164
- }
165
- cleanup();
166
- resolve({ type: selected.type });
167
- return;
168
- }
169
- else if (data.length === 1 && data[0] >= 0x31 && data[0] <= 0x35) {
170
- // Number keys 1-5
171
- const numIndex = data[0] - 0x31; // 0-indexed
172
- if (numIndex < ARCH_OPTIONS.length) {
173
- const selected = ARCH_OPTIONS[numIndex];
174
- if (selected.type === 'custom') {
175
- mode = 'custom-input';
176
- customInput = '';
177
- terminal.showCursor();
178
- lineCount = renderCustomInput(customInput, maxLineCount, maxLineCount);
179
- maxLineCount = Math.max(maxLineCount, lineCount);
180
- return;
181
- }
182
- cleanup();
183
- resolve({ type: selected.type });
184
- return;
185
- }
186
- }
187
- // Re-render
188
- lineCount = render(selectedIndex, maxLineCount, maxLineCount);
189
- maxLineCount = Math.max(maxLineCount, lineCount);
190
- }
191
- else {
192
- // Custom input mode
193
- if (isCtrlC) {
194
- cleanup();
195
- resolve(null);
196
- return;
197
- }
198
- if (isEscape) {
199
- // Go back to select mode
200
- mode = 'select';
201
- terminal.hideCursor();
202
- lineCount = render(selectedIndex, maxLineCount, maxLineCount);
203
- maxLineCount = Math.max(maxLineCount, lineCount);
204
- return;
205
- }
206
- if (isEnter) {
207
- if (customInput.trim()) {
208
- cleanup();
209
- resolve({ type: 'custom', customTopic: customInput.trim() });
210
- return;
211
- }
212
- // Don't allow empty custom topic
213
- return;
214
- }
215
- if (isBackspace) {
216
- customInput = customInput.slice(0, -1);
217
- }
218
- else if (data.length === 1 && data[0] >= 0x20 && data[0] <= 0x7e) {
219
- // Printable ASCII
220
- customInput += String.fromCharCode(data[0]);
221
- }
222
- // Re-render
223
- lineCount = renderCustomInput(customInput, maxLineCount, maxLineCount);
224
- maxLineCount = Math.max(maxLineCount, lineCount);
225
- }
226
- };
227
- process.stdin.on('data', handleData);
228
- });
200
+ return new ArchTypeOverlay().show();
229
201
  }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Ask User Overlay (Refactored)
3
+ *
4
+ * Modal overlay for presenting multi-question forms to the user.
5
+ * Uses InlineOverlay base class for consistent lifecycle management.
6
+ *
7
+ * Features:
8
+ * - Multiple questions with navigation (←/→ or Tab)
9
+ * - Options to select from with arrow keys
10
+ * - Custom text input option
11
+ * - Multi-select support
12
+ * - Progress indicator showing answered questions
13
+ */
14
+ import type { AskUserQuestion } from '../tools/ask-user.js';
15
+ export interface AskUserOptions {
16
+ questions: AskUserQuestion[];
17
+ context?: string;
18
+ }
19
+ export interface AskUserResult {
20
+ answers: Record<string, string | string[]>;
21
+ skipped: string[];
22
+ }
23
+ /**
24
+ * Show the ask user overlay
25
+ */
26
+ export declare function showAskUserOverlay(options: AskUserOptions): Promise<AskUserResult>;