@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,441 @@
1
+ /**
2
+ * Commands Overlay V2
3
+ *
4
+ * Modal overlay for viewing and managing custom command definitions.
5
+ * Uses TabbedListOverlayV2 for consistent navigation patterns.
6
+ *
7
+ * Features:
8
+ * - Tabs: All, Project, Personal
9
+ * - Search with / toggle
10
+ * - Detail view for command information
11
+ * - Wizard for creating new commands
12
+ */
13
+ import chalk from 'chalk';
14
+ import * as terminal from '../../terminal.js';
15
+ import { getCustomCommandRegistry, } from '../../../commands/index.js';
16
+ import { TabbedListOverlayV2, BaseScreen, stay, popScreen, closeOverlay, isEscape, isEnter, isCtrlC, isNavigateUp, isNavigateDown, isBackspace, renderBorder, wrapText, } from '../../base/index.js';
17
+ import { InputFeature } from '../../features/index.js';
18
+ // =============================================================================
19
+ // Constants
20
+ // =============================================================================
21
+ const TABS = [
22
+ { id: 'all', label: 'All' },
23
+ { id: 'project', label: 'Project' },
24
+ { id: 'personal', label: 'Personal' },
25
+ ];
26
+ const PAGE_SIZE = 10;
27
+ // =============================================================================
28
+ // Helpers
29
+ // =============================================================================
30
+ function isCreateItem(item) {
31
+ return 'type' in item;
32
+ }
33
+ function buildItemsList(registry) {
34
+ const commands = registry.getAll();
35
+ return [...commands, { type: 'create' }];
36
+ }
37
+ function defaultWizardState() {
38
+ return {
39
+ step: 'location',
40
+ location: 'project',
41
+ name: '',
42
+ description: '',
43
+ prompt: '',
44
+ selectedOption: 0,
45
+ error: null,
46
+ };
47
+ }
48
+ // =============================================================================
49
+ // Detail Screen
50
+ // =============================================================================
51
+ class CommandDetailScreen extends BaseScreen {
52
+ command;
53
+ registry;
54
+ styles;
55
+ constructor(command, registry, styles) {
56
+ super();
57
+ this.command = command;
58
+ this.registry = registry;
59
+ this.styles = styles;
60
+ }
61
+ render() {
62
+ const s = this.styles;
63
+ const lines = [];
64
+ const cols = terminal.getTerminalWidth();
65
+ const border = renderBorder(cols, s);
66
+ const cmd = this.command;
67
+ // Header
68
+ lines.push(border);
69
+ lines.push(' ' + s.primaryBold('Command Details'));
70
+ lines.push('');
71
+ // Command name
72
+ lines.push(chalk.bold(` /${cmd.name}`));
73
+ lines.push('');
74
+ // Location
75
+ lines.push(' ' + s.primary('LOCATION'));
76
+ lines.push(` ${cmd.location === 'project' ? 'Project' : 'Personal'} (${cmd.location})`);
77
+ lines.push('');
78
+ // File path
79
+ lines.push(' ' + s.primary('FILE'));
80
+ const basePath = cmd.location === 'project'
81
+ ? this.registry.getProjectDir()
82
+ : this.registry.getUserDir();
83
+ lines.push(s.muted(` ${basePath}/${cmd.name}.md`));
84
+ lines.push('');
85
+ // Description
86
+ lines.push(' ' + s.primary('DESCRIPTION'));
87
+ const descLines = wrapText(cmd.description, cols - 6, ' ');
88
+ lines.push(...descLines);
89
+ lines.push('');
90
+ // Prompt
91
+ lines.push(' ' + s.primary('PROMPT TEMPLATE'));
92
+ const promptLines = wrapText(cmd.prompt, cols - 6, ' ');
93
+ lines.push(...promptLines);
94
+ lines.push('');
95
+ // Footer
96
+ lines.push(border);
97
+ lines.push(` ${s.muted('q/Esc Back')}`);
98
+ lines.push(border);
99
+ return lines;
100
+ }
101
+ handleKey(data) {
102
+ if (isCtrlC(data)) {
103
+ return closeOverlay(undefined);
104
+ }
105
+ if (isEscape(data) || data.toString() === 'q') {
106
+ return popScreen();
107
+ }
108
+ return stay(false);
109
+ }
110
+ /**
111
+ * Minimum height for stable rendering.
112
+ * Covers: header(3) + name(2) + location(3) + file(3) + desc(5) + prompt(5) + footer(3) = 24
113
+ */
114
+ getMinHeight() {
115
+ return 24;
116
+ }
117
+ }
118
+ // =============================================================================
119
+ // Wizard Screen
120
+ // =============================================================================
121
+ class WizardScreen extends BaseScreen {
122
+ registry;
123
+ styles;
124
+ state;
125
+ input;
126
+ constructor(registry, styles) {
127
+ super();
128
+ this.registry = registry;
129
+ this.styles = styles;
130
+ this.state = defaultWizardState();
131
+ this.input = new InputFeature({ placeholder: '' });
132
+ }
133
+ render() {
134
+ const s = this.styles;
135
+ const lines = [];
136
+ const cols = terminal.getTerminalWidth();
137
+ const border = renderBorder(cols, s);
138
+ lines.push(border);
139
+ lines.push(' ' + s.primaryBold('Create New Command'));
140
+ lines.push('');
141
+ switch (this.state.step) {
142
+ case 'location':
143
+ lines.push(chalk.bold(' Choose location'));
144
+ lines.push('');
145
+ lines.push(this.state.selectedOption === 0
146
+ ? s.primary(' ❯ 1. Project (.compilr-dev/commands/)')
147
+ : s.muted(' 1. Project (.compilr-dev/commands/)'));
148
+ lines.push(this.state.selectedOption === 1
149
+ ? s.primary(' ❯ 2. Personal (~/.compilr-dev/commands/)')
150
+ : s.muted(' 2. Personal (~/.compilr-dev/commands/)'));
151
+ lines.push('');
152
+ lines.push(s.muted(' Project commands are shared with your team.'));
153
+ lines.push(s.muted(' Personal commands apply to all your projects.'));
154
+ break;
155
+ case 'name':
156
+ lines.push(chalk.bold(' Command name'));
157
+ lines.push('');
158
+ lines.push(' Enter a unique name:');
159
+ lines.push(` > ${this.input.render(s)}`);
160
+ lines.push('');
161
+ if (this.state.error) {
162
+ lines.push(s.error(` ${this.state.error}`));
163
+ }
164
+ else {
165
+ lines.push(s.muted(' Use lowercase letters, numbers, hyphens (e.g., code-review)'));
166
+ lines.push(s.muted(' This becomes the command: /{name}'));
167
+ }
168
+ break;
169
+ case 'description':
170
+ lines.push(chalk.bold(' Description'));
171
+ lines.push('');
172
+ lines.push(' Enter a short description:');
173
+ lines.push(` > ${this.input.render(s)}`);
174
+ lines.push('');
175
+ lines.push(s.muted(' This is shown in the help menu.'));
176
+ break;
177
+ case 'prompt':
178
+ lines.push(chalk.bold(' Prompt template'));
179
+ lines.push('');
180
+ lines.push(' Enter the prompt to send:');
181
+ lines.push(` > ${this.input.render(s)}`);
182
+ lines.push('');
183
+ lines.push(s.muted(' Use $1, $2 for positional args, $ARGUMENTS for all args.'));
184
+ lines.push(s.muted(' Example: "Review $1 for bugs and security issues"'));
185
+ break;
186
+ case 'confirm': {
187
+ lines.push(chalk.bold(' Confirm'));
188
+ lines.push('');
189
+ lines.push(` Command: ${s.primary('/' + this.state.name)}`);
190
+ const locationPath = this.state.location === 'project'
191
+ ? '.compilr-dev/commands/'
192
+ : '~/.compilr-dev/commands/';
193
+ lines.push(` Location: ${s.primary(locationPath)}${this.state.name}.md`);
194
+ lines.push('');
195
+ lines.push(chalk.bold(' Description:'));
196
+ const descPreview = this.state.description.slice(0, 60) +
197
+ (this.state.description.length > 60 ? '...' : '');
198
+ lines.push(s.muted(` ${descPreview}`));
199
+ lines.push('');
200
+ lines.push(chalk.bold(' Prompt template:'));
201
+ const promptPreview = this.state.prompt.slice(0, 60) +
202
+ (this.state.prompt.length > 60 ? '...' : '');
203
+ lines.push(s.muted(` ${promptPreview}`));
204
+ lines.push('');
205
+ lines.push(this.state.selectedOption === 0
206
+ ? s.primary(' ❯ Save')
207
+ : s.muted(' Save'));
208
+ lines.push(this.state.selectedOption === 1
209
+ ? s.primary(' ❯ Cancel')
210
+ : s.muted(' Cancel'));
211
+ if (this.state.error) {
212
+ lines.push('');
213
+ lines.push(s.error(` ${this.state.error}`));
214
+ }
215
+ break;
216
+ }
217
+ }
218
+ lines.push('');
219
+ lines.push(border);
220
+ lines.push(` ${s.muted('Esc to go back')}`);
221
+ lines.push(border);
222
+ return lines;
223
+ }
224
+ handleKey(data) {
225
+ // Ctrl+C always closes
226
+ if (isCtrlC(data)) {
227
+ return closeOverlay(undefined);
228
+ }
229
+ // Escape goes back one step (or exits wizard)
230
+ if (isEscape(data)) {
231
+ return this.handleBack();
232
+ }
233
+ // Input steps: name, description, prompt
234
+ if (['name', 'description', 'prompt'].includes(this.state.step)) {
235
+ return this.handleInputStep(data);
236
+ }
237
+ // Selection steps: location, confirm
238
+ if (['location', 'confirm'].includes(this.state.step)) {
239
+ return this.handleSelectionStep(data);
240
+ }
241
+ return stay();
242
+ }
243
+ handleBack() {
244
+ switch (this.state.step) {
245
+ case 'location':
246
+ return popScreen();
247
+ case 'name':
248
+ this.state.step = 'location';
249
+ this.state.selectedOption = this.state.location === 'project' ? 0 : 1;
250
+ break;
251
+ case 'description':
252
+ this.state.step = 'name';
253
+ this.input.value = this.state.name;
254
+ break;
255
+ case 'prompt':
256
+ this.state.step = 'description';
257
+ this.input.value = this.state.description;
258
+ break;
259
+ case 'confirm':
260
+ this.state.step = 'prompt';
261
+ this.input.value = this.state.prompt;
262
+ break;
263
+ }
264
+ this.state.error = null;
265
+ return stay();
266
+ }
267
+ handleInputStep(data) {
268
+ if (isEnter(data)) {
269
+ const value = this.input.trimmedValue;
270
+ if (value) {
271
+ // Validate name
272
+ if (this.state.step === 'name') {
273
+ if (!/^[a-z][a-z0-9-]{1,29}$/.test(value)) {
274
+ this.state.error = 'Invalid name. Use lowercase letters, numbers, hyphens (2-30 chars).';
275
+ return stay();
276
+ }
277
+ if (this.registry.has(value)) {
278
+ this.state.error = `Command "${value}" already exists.`;
279
+ return stay();
280
+ }
281
+ }
282
+ this.advanceStep();
283
+ }
284
+ return stay();
285
+ }
286
+ if (isBackspace(data)) {
287
+ const result = this.input.handleKey(data);
288
+ if (result.handled) {
289
+ this.state.error = null;
290
+ return stay(result.render);
291
+ }
292
+ return stay(false);
293
+ }
294
+ // Regular character input
295
+ const result = this.input.handleKey(data);
296
+ if (result.handled) {
297
+ this.state.error = null;
298
+ return stay(result.render);
299
+ }
300
+ return stay(false);
301
+ }
302
+ handleSelectionStep(data) {
303
+ const maxOptions = 2;
304
+ if (isNavigateUp(data) && this.state.selectedOption > 0) {
305
+ this.state.selectedOption--;
306
+ return stay();
307
+ }
308
+ if (isNavigateDown(data) && this.state.selectedOption < maxOptions - 1) {
309
+ this.state.selectedOption++;
310
+ return stay();
311
+ }
312
+ if (isEnter(data)) {
313
+ if (this.state.step === 'confirm') {
314
+ if (this.state.selectedOption === 0) {
315
+ // Save
316
+ try {
317
+ this.registry.save({
318
+ name: this.state.name,
319
+ description: this.state.description,
320
+ prompt: this.state.prompt,
321
+ }, this.state.location);
322
+ this.registry.load();
323
+ return closeOverlay({ created: this.state.name });
324
+ }
325
+ catch (error) {
326
+ this.state.error = error.message;
327
+ return stay();
328
+ }
329
+ }
330
+ else {
331
+ return popScreen();
332
+ }
333
+ }
334
+ else {
335
+ this.advanceStep();
336
+ }
337
+ }
338
+ return stay(false);
339
+ }
340
+ advanceStep() {
341
+ switch (this.state.step) {
342
+ case 'location':
343
+ this.state.location = this.state.selectedOption === 0 ? 'project' : 'personal';
344
+ this.state.step = 'name';
345
+ this.input.clear();
346
+ break;
347
+ case 'name':
348
+ this.state.name = this.input.trimmedValue;
349
+ this.state.step = 'description';
350
+ this.input.clear();
351
+ break;
352
+ case 'description':
353
+ this.state.description = this.input.trimmedValue;
354
+ this.state.step = 'prompt';
355
+ this.input.clear();
356
+ break;
357
+ case 'prompt':
358
+ this.state.prompt = this.input.trimmedValue;
359
+ this.state.step = 'confirm';
360
+ this.state.selectedOption = 0;
361
+ break;
362
+ }
363
+ this.state.error = null;
364
+ }
365
+ /**
366
+ * Minimum height for stable rendering.
367
+ * Covers: header(3) + form fields (up to 12) + options(4) + footer(3) = 22
368
+ */
369
+ getMinHeight() {
370
+ return 22;
371
+ }
372
+ }
373
+ // =============================================================================
374
+ // Commands Overlay V2
375
+ // =============================================================================
376
+ /**
377
+ * Commands overlay using TabbedListOverlayV2.
378
+ * Displays custom commands in a searchable, tabbed list.
379
+ */
380
+ export class CommandsOverlayV2 extends TabbedListOverlayV2 {
381
+ type = 'inline';
382
+ id = 'commands-overlay-v2';
383
+ registry;
384
+ constructor() {
385
+ const registry = getCustomCommandRegistry();
386
+ registry.load();
387
+ const items = buildItemsList(registry);
388
+ super({
389
+ title: 'Custom Commands',
390
+ tabs: TABS,
391
+ items,
392
+ pageSize: PAGE_SIZE,
393
+ filterByTab: (item, tabId) => {
394
+ // "Create new command" always shows
395
+ if (isCreateItem(item))
396
+ return true;
397
+ // Filter by location
398
+ if (tabId === 'all')
399
+ return true;
400
+ return item.location === tabId;
401
+ },
402
+ getSearchText: (item) => {
403
+ if (isCreateItem(item))
404
+ return 'create new';
405
+ return `${item.name} ${item.description}`;
406
+ },
407
+ renderItem: (item, isSelected, styles) => {
408
+ const cols = terminal.getTerminalWidth();
409
+ if (isCreateItem(item)) {
410
+ return isSelected
411
+ ? styles.primary(' ❯ Create new command')
412
+ : styles.muted(' Create new command');
413
+ }
414
+ const cmd = item;
415
+ const prefix = isSelected ? styles.primary(' ❯ ') : ' ';
416
+ const name = `/${cmd.name}`;
417
+ const nameStyled = isSelected ? styles.primary(name.padEnd(25)) : name.padEnd(25);
418
+ const maxDesc = Math.max(20, cols - 45);
419
+ const desc = cmd.description.slice(0, maxDesc) + (cmd.description.length > maxDesc ? '...' : '');
420
+ const descStyled = styles.muted(desc);
421
+ const location = styles.muted(` (${cmd.location})`);
422
+ return prefix + nameStyled + descStyled + location;
423
+ },
424
+ footerHints: (searchMode) => {
425
+ if (searchMode) {
426
+ return 'Type to filter · ↑↓/jk Navigate · Enter Select · Esc Exit search';
427
+ }
428
+ return 'Tab Filter · ↑↓/jk · / Search · Enter Select · q/Esc Close';
429
+ },
430
+ emptyMessage: 'No custom commands found.',
431
+ noResultsMessage: 'No commands match the search.',
432
+ });
433
+ this.registry = registry;
434
+ }
435
+ createDetailScreen(item) {
436
+ if (isCreateItem(item)) {
437
+ return new WizardScreen(this.registry, this.getStyles());
438
+ }
439
+ return new CommandDetailScreen(item, this.registry, this.getStyles());
440
+ }
441
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Config Overlay V2
3
+ *
4
+ * Claude Code-style settings overlay with 4 tabs:
5
+ * - Status: Read-only info (version, model, provider, cwd, session)
6
+ * - Config: Interactive settings (toggle/cycle with Enter/Space)
7
+ * - Paths: Path configuration and safety settings
8
+ * - Usage: Usage statistics with progress bars
9
+ *
10
+ * Theme, Model, and Mascot selection are delegated to standalone overlays.
11
+ * Uses BaseOverlayV2 for the new Overlay interface.
12
+ */
13
+ import { BaseOverlayV2 } from '../../base/index.js';
14
+ import type { RenderContext, OverlayAction, KeyEvent } from '../../overlay/index.js';
15
+ type ConfigItemType = 'boolean' | 'cycle' | 'submenu';
16
+ interface ConfigItem {
17
+ id: string;
18
+ label: string;
19
+ type: ConfigItemType;
20
+ value: boolean | string;
21
+ options?: string[];
22
+ }
23
+ interface StatusInfo {
24
+ version: string;
25
+ sessionId: string;
26
+ cwd: string;
27
+ model: string;
28
+ provider: string;
29
+ memoryFile: string | null;
30
+ toolCount: number;
31
+ startTime: Date;
32
+ }
33
+ interface UsageStats {
34
+ inputTokens: number;
35
+ outputTokens: number;
36
+ requests: number;
37
+ contextUsed: number;
38
+ contextMax: number;
39
+ messageCount: number;
40
+ }
41
+ interface ConfigState {
42
+ currentTab: number;
43
+ selectedItem: number;
44
+ scrollOffset: number;
45
+ configItems: ConfigItem[];
46
+ pathSelectedItem: number;
47
+ pathEditMode: boolean;
48
+ pathEditInput: string;
49
+ statusInfo: StatusInfo;
50
+ usageStats: UsageStats;
51
+ }
52
+ export interface ConfigOverlayV2Options {
53
+ version?: string;
54
+ sessionId?: string;
55
+ cwd?: string;
56
+ model?: string;
57
+ provider?: string;
58
+ toolCount?: number;
59
+ startTime?: Date;
60
+ inputTokens?: number;
61
+ outputTokens?: number;
62
+ requests?: number;
63
+ contextUsed?: number;
64
+ contextMax?: number;
65
+ messageCount?: number;
66
+ }
67
+ export interface ConfigOverlayV2Result {
68
+ /** Settings were changed */
69
+ settingsChanged?: boolean;
70
+ }
71
+ export declare class ConfigOverlayV2 extends BaseOverlayV2<ConfigState, ConfigOverlayV2Result> {
72
+ readonly type: "inline";
73
+ readonly id = "config-overlay-v2";
74
+ protected minHeight: number;
75
+ private settingsChanged;
76
+ constructor(options?: ConfigOverlayV2Options);
77
+ protected renderContent(context: RenderContext): string[];
78
+ private renderTabHeader;
79
+ private renderStatusTab;
80
+ private renderConfigTab;
81
+ private renderPathsTab;
82
+ private renderUsageTab;
83
+ private renderProgressBar;
84
+ private renderTabFooter;
85
+ handleKey(key: KeyEvent): OverlayAction<ConfigOverlayV2Result>;
86
+ private handleConfigTabKey;
87
+ private handlePathsTabKey;
88
+ private handlePathEditKey;
89
+ /**
90
+ * Toggle/cycle a config item, or return a sub-overlay for submenus.
91
+ * Returns the sub-overlay to push, or null if handled internally.
92
+ */
93
+ private toggleOrCycleItem;
94
+ private isQuit;
95
+ /**
96
+ * When overlay closes, refresh config items to reflect any changes from sub-overlays.
97
+ */
98
+ onUnmount(): void;
99
+ }
100
+ export {};