@compilr-dev/cli 0.4.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 (152) hide show
  1. package/README.md +110 -0
  2. package/dist/agent.d.ts +62 -0
  3. package/dist/agent.js +317 -0
  4. package/dist/agents/registry.d.ts +66 -0
  5. package/dist/agents/registry.js +238 -0
  6. package/dist/agents/types.d.ts +40 -0
  7. package/dist/agents/types.js +94 -0
  8. package/dist/commands/custom-registry.d.ts +69 -0
  9. package/dist/commands/custom-registry.js +246 -0
  10. package/dist/commands/index.d.ts +7 -0
  11. package/dist/commands/index.js +7 -0
  12. package/dist/commands/types.d.ts +31 -0
  13. package/dist/commands/types.js +26 -0
  14. package/dist/commands.d.ts +63 -0
  15. package/dist/commands.js +324 -0
  16. package/dist/db/index.d.ts +42 -0
  17. package/dist/db/index.js +146 -0
  18. package/dist/db/repositories/document-repository.d.ts +63 -0
  19. package/dist/db/repositories/document-repository.js +184 -0
  20. package/dist/db/repositories/index.d.ts +9 -0
  21. package/dist/db/repositories/index.js +6 -0
  22. package/dist/db/repositories/project-repository.d.ts +132 -0
  23. package/dist/db/repositories/project-repository.js +337 -0
  24. package/dist/db/repositories/work-item-repository.d.ts +115 -0
  25. package/dist/db/repositories/work-item-repository.js +389 -0
  26. package/dist/db/schema.d.ts +83 -0
  27. package/dist/db/schema.js +143 -0
  28. package/dist/debug.d.ts +8 -0
  29. package/dist/debug.js +48 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.js +348 -0
  32. package/dist/index.old.d.ts +7 -0
  33. package/dist/index.old.js +1014 -0
  34. package/dist/repl.d.ts +121 -0
  35. package/dist/repl.js +1878 -0
  36. package/dist/settings/index.d.ts +80 -0
  37. package/dist/settings/index.js +195 -0
  38. package/dist/shared-handlers.d.ts +63 -0
  39. package/dist/shared-handlers.js +57 -0
  40. package/dist/slash-autocomplete.d.ts +41 -0
  41. package/dist/slash-autocomplete.js +638 -0
  42. package/dist/state.d.ts +75 -0
  43. package/dist/state.js +130 -0
  44. package/dist/tabbed-menu.d.ts +11 -0
  45. package/dist/tabbed-menu.js +328 -0
  46. package/dist/templates/backlog-md.d.ts +7 -0
  47. package/dist/templates/backlog-md.js +94 -0
  48. package/dist/templates/claude-md.d.ts +7 -0
  49. package/dist/templates/claude-md.js +189 -0
  50. package/dist/templates/coding-standards.d.ts +7 -0
  51. package/dist/templates/coding-standards.js +299 -0
  52. package/dist/templates/compilr-md.d.ts +7 -0
  53. package/dist/templates/compilr-md.js +189 -0
  54. package/dist/templates/config-json.d.ts +38 -0
  55. package/dist/templates/config-json.js +39 -0
  56. package/dist/templates/gitignore.d.ts +7 -0
  57. package/dist/templates/gitignore.js +85 -0
  58. package/dist/templates/index.d.ts +19 -0
  59. package/dist/templates/index.js +302 -0
  60. package/dist/templates/package-json.d.ts +7 -0
  61. package/dist/templates/package-json.js +111 -0
  62. package/dist/templates/readme-md.d.ts +7 -0
  63. package/dist/templates/readme-md.js +161 -0
  64. package/dist/templates/tsconfig.d.ts +7 -0
  65. package/dist/templates/tsconfig.js +61 -0
  66. package/dist/templates/types.d.ts +33 -0
  67. package/dist/templates/types.js +24 -0
  68. package/dist/test-autocomplete.d.ts +7 -0
  69. package/dist/test-autocomplete.js +85 -0
  70. package/dist/test-tabbed-menu.d.ts +7 -0
  71. package/dist/test-tabbed-menu.js +25 -0
  72. package/dist/themes/colors.d.ts +49 -0
  73. package/dist/themes/colors.js +135 -0
  74. package/dist/themes/index.d.ts +23 -0
  75. package/dist/themes/index.js +24 -0
  76. package/dist/themes/registry.d.ts +60 -0
  77. package/dist/themes/registry.js +195 -0
  78. package/dist/themes/types.d.ts +82 -0
  79. package/dist/themes/types.js +7 -0
  80. package/dist/tool-selector.d.ts +71 -0
  81. package/dist/tool-selector.js +184 -0
  82. package/dist/tools/ask-user-simple.d.ts +19 -0
  83. package/dist/tools/ask-user-simple.js +86 -0
  84. package/dist/tools/ask-user.d.ts +32 -0
  85. package/dist/tools/ask-user.js +113 -0
  86. package/dist/tools/backlog.d.ts +53 -0
  87. package/dist/tools/backlog.js +709 -0
  88. package/dist/tools.d.ts +15 -0
  89. package/dist/tools.js +121 -0
  90. package/dist/ui/agents-overlay.d.ts +12 -0
  91. package/dist/ui/agents-overlay.js +501 -0
  92. package/dist/ui/arch-type-overlay.d.ts +20 -0
  93. package/dist/ui/arch-type-overlay.js +229 -0
  94. package/dist/ui/ask-user-overlay.d.ts +26 -0
  95. package/dist/ui/ask-user-overlay.js +647 -0
  96. package/dist/ui/ask-user-simple-overlay.d.ts +25 -0
  97. package/dist/ui/ask-user-simple-overlay.js +242 -0
  98. package/dist/ui/backlog-overlay.d.ts +17 -0
  99. package/dist/ui/backlog-overlay.js +786 -0
  100. package/dist/ui/commands-overlay.d.ts +11 -0
  101. package/dist/ui/commands-overlay.js +410 -0
  102. package/dist/ui/config-overlay.d.ts +34 -0
  103. package/dist/ui/config-overlay.js +977 -0
  104. package/dist/ui/conversation.d.ts +82 -0
  105. package/dist/ui/conversation.js +508 -0
  106. package/dist/ui/diff.d.ts +38 -0
  107. package/dist/ui/diff.js +182 -0
  108. package/dist/ui/ephemeral.d.ts +111 -0
  109. package/dist/ui/ephemeral.js +413 -0
  110. package/dist/ui/file-autocomplete.d.ts +45 -0
  111. package/dist/ui/file-autocomplete.js +237 -0
  112. package/dist/ui/footer.d.ts +153 -0
  113. package/dist/ui/footer.js +422 -0
  114. package/dist/ui/index.d.ts +12 -0
  115. package/dist/ui/index.js +15 -0
  116. package/dist/ui/init-overlay.d.ts +24 -0
  117. package/dist/ui/init-overlay.js +525 -0
  118. package/dist/ui/input-prompt-v2.d.ts +179 -0
  119. package/dist/ui/input-prompt-v2.js +991 -0
  120. package/dist/ui/input-prompt.d.ts +97 -0
  121. package/dist/ui/input-prompt.js +800 -0
  122. package/dist/ui/iteration-limit-overlay.d.ts +21 -0
  123. package/dist/ui/iteration-limit-overlay.js +150 -0
  124. package/dist/ui/keys-overlay.d.ts +14 -0
  125. package/dist/ui/keys-overlay.js +181 -0
  126. package/dist/ui/model-warning-overlay.d.ts +30 -0
  127. package/dist/ui/model-warning-overlay.js +171 -0
  128. package/dist/ui/overlay-controller.d.ts +25 -0
  129. package/dist/ui/overlay-controller.js +35 -0
  130. package/dist/ui/overlays.d.ts +47 -0
  131. package/dist/ui/overlays.js +627 -0
  132. package/dist/ui/permission-overlay.d.ts +16 -0
  133. package/dist/ui/permission-overlay.js +494 -0
  134. package/dist/ui/terminal.d.ts +117 -0
  135. package/dist/ui/terminal.js +237 -0
  136. package/dist/ui/todo-zone.d.ts +112 -0
  137. package/dist/ui/todo-zone.js +353 -0
  138. package/dist/ui/tools-overlay.d.ts +26 -0
  139. package/dist/ui/tools-overlay.js +278 -0
  140. package/dist/ui/tutorial-overlay.d.ts +10 -0
  141. package/dist/ui/tutorial-overlay.js +936 -0
  142. package/dist/ui/types.d.ts +103 -0
  143. package/dist/ui/types.js +33 -0
  144. package/dist/utils/credentials.d.ts +55 -0
  145. package/dist/utils/credentials.js +268 -0
  146. package/dist/utils/model-tiers.d.ts +37 -0
  147. package/dist/utils/model-tiers.js +118 -0
  148. package/dist/utils/project-memory.d.ts +47 -0
  149. package/dist/utils/project-memory.js +117 -0
  150. package/dist/utils/project-status.d.ts +56 -0
  151. package/dist/utils/project-status.js +237 -0
  152. package/package.json +66 -0
@@ -0,0 +1,422 @@
1
+ /**
2
+ * Footer Orchestrator
3
+ *
4
+ * Manages all persistent UI elements below the scrolling zone:
5
+ * - TodoZone (spinner + todo list)
6
+ * - Queued input display
7
+ * - InputPrompt
8
+ *
9
+ * Handles:
10
+ * - Coordinated rendering via single render loop
11
+ * - Event forwarding from InputPrompt
12
+ * - Clearing for scrolling output
13
+ * - State management for agent running/idle modes
14
+ */
15
+ import { EventEmitter } from 'events';
16
+ import { MODE_INFO } from './types.js';
17
+ import { getStyles } from '../themes/index.js';
18
+ import * as terminal from './terminal.js';
19
+ import { TodoZone } from './todo-zone.js';
20
+ import { InputPrompt, DEFAULT_COMMANDS } from './input-prompt-v2.js';
21
+ // =============================================================================
22
+ // Footer Class
23
+ // =============================================================================
24
+ export class Footer extends EventEmitter {
25
+ // Child components
26
+ todoZone;
27
+ inputPrompt;
28
+ // State
29
+ agentRunning = false;
30
+ mode;
31
+ lastRenderHeight = 0;
32
+ isRunning = false;
33
+ isPaused = false; // Prevents rendering even if callback is queued
34
+ cursorLineFromBottom = 0; // Track cursor position for clear()
35
+ // Render loop
36
+ renderInterval;
37
+ renderTimer = null;
38
+ needsRender = false;
39
+ constructor(options = {}) {
40
+ super();
41
+ this.renderInterval = options.renderInterval ?? 60; // 60ms = ~16fps
42
+ this.mode = options.initialMode ?? 'normal';
43
+ // Create child components
44
+ const s = getStyles();
45
+ this.todoZone = new TodoZone();
46
+ this.inputPrompt = new InputPrompt({
47
+ prompt: options.prompt ?? s.primaryBold('compilr>') + ' ',
48
+ showSeparators: options.showSeparators ?? true,
49
+ commands: DEFAULT_COMMANDS,
50
+ });
51
+ // Wire up TodoZone animation callback
52
+ this.todoZone.setAnimationCallback(() => {
53
+ this.needsRender = true;
54
+ });
55
+ // Wire up InputPrompt events
56
+ this.inputPrompt.on('submit', (input) => {
57
+ this.emit('submit', input);
58
+ });
59
+ this.inputPrompt.on('command', (command, args) => {
60
+ this.emit('command', command, args);
61
+ });
62
+ this.inputPrompt.on('cancel', () => {
63
+ this.emit('cancel');
64
+ });
65
+ this.inputPrompt.on('escape', () => {
66
+ this.emit('escape');
67
+ });
68
+ this.inputPrompt.on('modeChange', () => {
69
+ this.emit('modeChange');
70
+ });
71
+ this.inputPrompt.on('change', () => {
72
+ this.needsRender = true;
73
+ });
74
+ }
75
+ // ===========================================================================
76
+ // Public API
77
+ // ===========================================================================
78
+ /**
79
+ * Start the footer (begins render loop and input capture)
80
+ */
81
+ start() {
82
+ if (this.isRunning)
83
+ return;
84
+ this.isRunning = true;
85
+ this.isPaused = false; // Ensure not paused when starting
86
+ // Start input capture
87
+ this.inputPrompt.start();
88
+ // Start render loop
89
+ this.render();
90
+ this.renderTimer = setInterval(() => {
91
+ if (this.needsRender && !this.isPaused) {
92
+ this.render();
93
+ this.needsRender = false;
94
+ }
95
+ }, this.renderInterval);
96
+ }
97
+ /**
98
+ * Stop the footer
99
+ */
100
+ stop() {
101
+ if (!this.isRunning)
102
+ return;
103
+ this.isRunning = false;
104
+ // Stop render loop
105
+ if (this.renderTimer) {
106
+ clearInterval(this.renderTimer);
107
+ this.renderTimer = null;
108
+ }
109
+ // Stop components
110
+ this.todoZone.dispose();
111
+ this.inputPrompt.stop();
112
+ // Clear rendered content
113
+ this.clear();
114
+ }
115
+ /**
116
+ * Set whether agent is running
117
+ * Enables/disables queue mode and spinner
118
+ */
119
+ setAgentRunning(running) {
120
+ const wasRunning = this.agentRunning;
121
+ this.agentRunning = running;
122
+ this.todoZone.setAgentRunning(running);
123
+ this.inputPrompt.setQueueMode(running);
124
+ // When stopping, immediately clear and re-render to remove spinner
125
+ // This prevents ghost spinner from render interval races
126
+ if (wasRunning && !running) {
127
+ this.clear();
128
+ this.render();
129
+ }
130
+ else {
131
+ this.needsRender = true;
132
+ }
133
+ }
134
+ /**
135
+ * Check if agent is running
136
+ */
137
+ isAgentRunning() {
138
+ return this.agentRunning;
139
+ }
140
+ /**
141
+ * Set the current mode
142
+ */
143
+ setMode(mode) {
144
+ this.mode = mode;
145
+ this.needsRender = true;
146
+ }
147
+ /**
148
+ * Get the current mode
149
+ */
150
+ getMode() {
151
+ return this.mode;
152
+ }
153
+ /**
154
+ * Update the todo list
155
+ */
156
+ setTodos(todos) {
157
+ this.todoZone.setTodos(todos);
158
+ this.needsRender = true;
159
+ }
160
+ /**
161
+ * Set the current tool being executed
162
+ */
163
+ setCurrentTool(tool) {
164
+ this.todoZone.setCurrentTool(tool);
165
+ this.needsRender = true;
166
+ }
167
+ /**
168
+ * Set a suggestion for the next action (ghost text in input prompt)
169
+ */
170
+ setSuggestion(action) {
171
+ this.inputPrompt.setSuggestion(action);
172
+ this.needsRender = true;
173
+ }
174
+ /**
175
+ * Set custom spinner text (overrides todo activeForm and random thinking word)
176
+ * Pass null to clear and use default behavior.
177
+ */
178
+ setSpinnerText(text) {
179
+ this.todoZone.setSpinnerText(text);
180
+ this.needsRender = true;
181
+ }
182
+ /**
183
+ * Add tokens to the spinner counter
184
+ */
185
+ addTokens(count) {
186
+ this.todoZone.addTokens(count);
187
+ }
188
+ /**
189
+ * Get queued inputs
190
+ */
191
+ getQueuedInputs() {
192
+ return this.inputPrompt.getQueuedInputs();
193
+ }
194
+ /**
195
+ * Pop the first queued input
196
+ */
197
+ popQueuedInput() {
198
+ const input = this.inputPrompt.popQueuedInput();
199
+ if (input !== null) {
200
+ this.needsRender = true;
201
+ }
202
+ return input;
203
+ }
204
+ /**
205
+ * Check if there are queued inputs
206
+ */
207
+ hasQueuedInput() {
208
+ return this.inputPrompt.hasQueuedInput();
209
+ }
210
+ /**
211
+ * Clear the queue
212
+ */
213
+ clearQueue() {
214
+ this.inputPrompt.clearQueue();
215
+ this.needsRender = true;
216
+ }
217
+ /**
218
+ * Clear footer before scrolling output
219
+ * Call this before writing to the scrolling zone
220
+ */
221
+ clearForOutput() {
222
+ this.clear();
223
+ }
224
+ /**
225
+ * Force an immediate render
226
+ */
227
+ forceRender() {
228
+ this.render();
229
+ this.needsRender = false;
230
+ }
231
+ /**
232
+ * Pause footer completely (for overlays)
233
+ * Stops render loop, input capture, and animation
234
+ */
235
+ pauseAnimation() {
236
+ // Set paused flag FIRST - this prevents any queued render callbacks from executing
237
+ this.isPaused = true;
238
+ // Stop render loop
239
+ if (this.renderTimer) {
240
+ clearInterval(this.renderTimer);
241
+ this.renderTimer = null;
242
+ }
243
+ // Stop input capture
244
+ this.inputPrompt.stop();
245
+ // Stop animation
246
+ this.todoZone.pauseAnimation();
247
+ // Clear footer from screen
248
+ this.clear();
249
+ }
250
+ /**
251
+ * Resume footer after pause
252
+ * Restarts render loop, input capture, and animation
253
+ */
254
+ resumeAnimation() {
255
+ // Clear paused flag FIRST
256
+ this.isPaused = false;
257
+ // Resume animation
258
+ this.todoZone.resumeAnimation();
259
+ // Restart input capture
260
+ this.inputPrompt.start();
261
+ // Restart render loop
262
+ this.render();
263
+ this.renderTimer = setInterval(() => {
264
+ if (this.needsRender && !this.isPaused) {
265
+ this.render();
266
+ this.needsRender = false;
267
+ }
268
+ }, this.renderInterval);
269
+ }
270
+ /**
271
+ * Get the height of last render
272
+ */
273
+ getLastRenderHeight() {
274
+ return this.lastRenderHeight;
275
+ }
276
+ /**
277
+ * Refresh the prompt with current theme colors
278
+ * Call after theme changes to apply new colors immediately
279
+ */
280
+ refreshPrompt() {
281
+ const s = getStyles();
282
+ this.inputPrompt.setPrompt(s.primaryBold('compilr>') + ' ');
283
+ this.needsRender = true;
284
+ }
285
+ // ===========================================================================
286
+ // Private: Rendering
287
+ // ===========================================================================
288
+ /**
289
+ * Clear the footer area
290
+ */
291
+ clear() {
292
+ if (this.lastRenderHeight > 0) {
293
+ // Move to start of current line
294
+ terminal.moveCursorToLineStart();
295
+ // First move DOWN to the last line of footer (cursor may be positioned in input area)
296
+ if (this.cursorLineFromBottom > 0) {
297
+ terminal.moveCursorDown(this.cursorLineFromBottom);
298
+ }
299
+ // Now move up to the first line of footer
300
+ terminal.moveCursorUp(this.lastRenderHeight - 1);
301
+ terminal.clearToEndOfScreen();
302
+ }
303
+ this.lastRenderHeight = 0;
304
+ this.cursorLineFromBottom = 0;
305
+ }
306
+ /**
307
+ * Render the entire footer
308
+ */
309
+ render() {
310
+ // Clear and redraw footer
311
+ this.clear();
312
+ const allLines = [];
313
+ // 1. Todo zone (spinner + todos)
314
+ const todoLines = this.todoZone.render();
315
+ allLines.push(...todoLines);
316
+ // 2. Queued inputs
317
+ const s = getStyles();
318
+ const queuedInputs = this.inputPrompt.getQueuedInputs();
319
+ for (const queued of queuedInputs) {
320
+ allLines.push(s.muted(`queued: "${queued}"`));
321
+ }
322
+ // 3. Input prompt
323
+ const inputLines = this.inputPrompt.render();
324
+ allLines.push(...inputLines);
325
+ // 4. Mode indicator (below input, before autocomplete)
326
+ allLines.push(this.renderModeIndicator());
327
+ // 5. Autocomplete dropdown (if active)
328
+ const autocompleteLines = this.inputPrompt.getAutocompleteLines();
329
+ allLines.push(...autocompleteLines);
330
+ // Write all lines
331
+ for (let i = 0; i < allLines.length; i++) {
332
+ terminal.write(allLines[i]);
333
+ if (i < allLines.length - 1) {
334
+ terminal.write('\n');
335
+ }
336
+ }
337
+ // Track height - account for line wrapping in terminal
338
+ const termWidth = process.stdout.columns || 80;
339
+ let actualTerminalRows = 0;
340
+ for (const line of allLines) {
341
+ // Strip ANSI codes to get visible length
342
+ // eslint-disable-next-line no-control-regex
343
+ const visibleLength = line.replace(/\x1b\[[0-9;]*m/g, '').length;
344
+ // Each line takes at least 1 row, plus extra rows if it wraps
345
+ actualTerminalRows += Math.max(1, Math.ceil(visibleLength / termWidth));
346
+ }
347
+ this.lastRenderHeight = actualTerminalRows;
348
+ // Position cursor within input prompt
349
+ // linesBeforeInput = todoLines + queuedInputs (mode indicator is now AFTER input)
350
+ this.positionCursor(allLines, todoLines.length + queuedInputs.length);
351
+ }
352
+ /**
353
+ * Render mode indicator line
354
+ */
355
+ renderModeIndicator() {
356
+ const s = getStyles();
357
+ const modeInfo = MODE_INFO[this.mode];
358
+ switch (this.mode) {
359
+ case 'normal':
360
+ // Subtle indicator in normal mode
361
+ return s.muted(`mode: ${modeInfo.label} (Shift+Tab to change)`);
362
+ case 'auto-accept':
363
+ // Warning color for auto-accept
364
+ return s.warning(`⚡ mode: ${modeInfo.label}`) + s.muted(' (Shift+Tab to change)');
365
+ case 'plan':
366
+ // Different color for plan mode
367
+ return s.info(`📋 mode: ${modeInfo.label}`) + s.muted(' (Shift+Tab to change)');
368
+ default:
369
+ return s.muted(`mode: ${modeInfo.label} (Shift+Tab to change)`);
370
+ }
371
+ }
372
+ /**
373
+ * Calculate how many terminal rows a line takes (accounting for wrapping)
374
+ */
375
+ getTerminalRowsForLine(line) {
376
+ const termWidth = process.stdout.columns || 80;
377
+ // Strip ANSI codes to get visible length
378
+ // eslint-disable-next-line no-control-regex
379
+ const visibleLength = line.replace(/\x1b\[[0-9;]*m/g, '').length;
380
+ // Each line takes at least 1 row, plus extra rows if it wraps
381
+ return Math.max(1, Math.ceil(visibleLength / termWidth));
382
+ }
383
+ /**
384
+ * Position cursor correctly within the input prompt
385
+ */
386
+ positionCursor(allLines, linesBeforeInput) {
387
+ const cursorInfo = this.inputPrompt.getCursorInfo();
388
+ // cursorInfo.row already accounts for:
389
+ // - Top separator (if enabled)
390
+ // - Wrapped lines within input
391
+ // cursorInfo.col is the column position within that terminal row
392
+ // Calculate terminal rows for lines BEFORE input (todo zone, queued inputs)
393
+ let rowsBeforeInput = 0;
394
+ for (let i = 0; i < linesBeforeInput; i++) {
395
+ rowsBeforeInput += this.getTerminalRowsForLine(allLines[i]);
396
+ }
397
+ // Calculate terminal rows for input section (including separators and wrapped lines)
398
+ const inputLines = this.inputPrompt.render();
399
+ let inputTotalRows = 0;
400
+ for (const line of inputLines) {
401
+ inputTotalRows += this.getTerminalRowsForLine(line);
402
+ }
403
+ // Calculate terminal rows for lines AFTER input (mode indicator, autocomplete)
404
+ let rowsAfterInput = 0;
405
+ const inputEndIndex = linesBeforeInput + inputLines.length;
406
+ for (let i = inputEndIndex; i < allLines.length; i++) {
407
+ rowsAfterInput += this.getTerminalRowsForLine(allLines[i]);
408
+ }
409
+ // Cursor target row from start of footer = rows before input + cursor row within input
410
+ const cursorRowFromStart = rowsBeforeInput + cursorInfo.row;
411
+ // Total rows to move up from end = total rows - cursor row - 1
412
+ const totalRows = rowsBeforeInput + inputTotalRows + rowsAfterInput;
413
+ const rowsToMoveUp = totalRows - cursorRowFromStart - 1;
414
+ if (rowsToMoveUp > 0) {
415
+ terminal.moveCursorUp(rowsToMoveUp);
416
+ }
417
+ // Track how far from bottom cursor is (for clear())
418
+ this.cursorLineFromBottom = rowsToMoveUp;
419
+ // Position cursor column (add 1 because terminal columns are 1-indexed)
420
+ terminal.moveCursorToColumn(cursorInfo.col + 1);
421
+ }
422
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * UI Module Exports
3
+ *
4
+ * Re-exports all UI components for easy importing.
5
+ */
6
+ export * from './types.js';
7
+ export * from './terminal.js';
8
+ export * from './conversation.js';
9
+ export * from './overlays.js';
10
+ export * from './todo-zone.js';
11
+ export * from './input-prompt-v2.js';
12
+ export * from './footer.js';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * UI Module Exports
3
+ *
4
+ * Re-exports all UI components for easy importing.
5
+ */
6
+ export * from './types.js';
7
+ export * from './terminal.js';
8
+ export * from './conversation.js';
9
+ export * from './overlays.js';
10
+ // Refactored components (event-driven, persistent footer)
11
+ export * from './todo-zone.js';
12
+ export * from './input-prompt-v2.js';
13
+ export * from './footer.js';
14
+ // Note: ephemeral.js and input-prompt.js are legacy and not re-exported
15
+ // to avoid naming conflicts. Import directly if needed.
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Init Overlay
3
+ *
4
+ * Modal overlay for the /init wizard - creates new projects with structured workflow.
5
+ * Steps:
6
+ * 0. Project type (new vs existing)
7
+ * 1. Project name
8
+ * 2. Description
9
+ * 3. Repo pattern (single vs two-repo)
10
+ * 4. Tech stack
11
+ * 5. Coding standards
12
+ * 6. Initialize git?
13
+ * 7. Confirmation
14
+ */
15
+ export interface InitResult {
16
+ created: boolean;
17
+ projectPath?: string;
18
+ docsPath?: string;
19
+ filesCreated?: string[];
20
+ }
21
+ /**
22
+ * Show the init wizard overlay
23
+ */
24
+ export declare function showInitOverlay(): Promise<InitResult>;