@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,11 @@
1
+ /**
2
+ * Commands Overlay
3
+ *
4
+ * Modal overlay for viewing and managing custom command definitions.
5
+ * - List tab: Shows existing custom commands
6
+ * - Wizard mode: Step-by-step command creation
7
+ */
8
+ /**
9
+ * Show the commands overlay
10
+ */
11
+ export declare function showCommandsOverlay(): Promise<void>;
@@ -0,0 +1,410 @@
1
+ /**
2
+ * Commands Overlay
3
+ *
4
+ * Modal overlay for viewing and managing custom command definitions.
5
+ * - List tab: Shows existing custom commands
6
+ * - Wizard mode: Step-by-step command creation
7
+ */
8
+ import chalk from 'chalk';
9
+ import * as terminal from './terminal.js';
10
+ import { getCustomCommandRegistry, } from '../commands/index.js';
11
+ import { getStyles } from '../themes/index.js';
12
+ // =============================================================================
13
+ // Rendering - List Mode
14
+ // =============================================================================
15
+ function renderListHeader() {
16
+ const s = getStyles();
17
+ const lines = [];
18
+ const cols = terminal.getTerminalWidth();
19
+ lines.push(s.muted('─'.repeat(Math.max(1, cols - 1))));
20
+ lines.push(' ' + s.primaryBold('Custom Commands'));
21
+ lines.push('');
22
+ return lines;
23
+ }
24
+ function renderCommandsList(state) {
25
+ const s = getStyles();
26
+ const lines = [];
27
+ const commands = state.registry.getAll();
28
+ if (commands.length === 0) {
29
+ lines.push(s.muted(' No custom commands found'));
30
+ lines.push('');
31
+ lines.push(state.selectedIndex === 0
32
+ ? s.primary(' ❯ Create new command')
33
+ : s.muted(' Create new command'));
34
+ lines.push('');
35
+ lines.push(s.muted(' Custom commands are stored in:'));
36
+ lines.push(s.muted(` ${state.registry.getProjectDir()}/ (project)`));
37
+ lines.push(s.muted(` ${state.registry.getUserDir()}/ (personal)`));
38
+ }
39
+ else {
40
+ lines.push(chalk.bold(' Available commands:'));
41
+ lines.push('');
42
+ for (let i = 0; i < commands.length; i++) {
43
+ const cmd = commands[i];
44
+ const isSelected = i === state.selectedIndex;
45
+ const prefix = isSelected ? s.primary(' ❯ ') : ' ';
46
+ const name = `/${cmd.name}`;
47
+ const nameStyled = isSelected ? s.primary(name.padEnd(25)) : name.padEnd(25);
48
+ const desc = s.muted(cmd.description.slice(0, 45) + (cmd.description.length > 45 ? '...' : ''));
49
+ const location = s.muted(` (${cmd.location})`);
50
+ lines.push(prefix + nameStyled + desc + location);
51
+ }
52
+ lines.push(s.muted(' ──────────────────────────────────'));
53
+ const createIdx = commands.length;
54
+ const isCreateSelected = state.selectedIndex === createIdx;
55
+ lines.push(isCreateSelected
56
+ ? s.primary(' ❯ Create new command')
57
+ : s.muted(' Create new command'));
58
+ }
59
+ return lines;
60
+ }
61
+ function renderListFooter() {
62
+ const s = getStyles();
63
+ const lines = [];
64
+ lines.push('');
65
+ lines.push(s.muted(' ↑↓ Navigate · Enter Select · Esc Close'));
66
+ return lines;
67
+ }
68
+ function buildListLines(state) {
69
+ const allLines = [];
70
+ allLines.push(...renderListHeader());
71
+ allLines.push(...renderCommandsList(state));
72
+ allLines.push(...renderListFooter());
73
+ return allLines;
74
+ }
75
+ // =============================================================================
76
+ // Rendering - Wizard Mode
77
+ // =============================================================================
78
+ function buildWizardLines(state) {
79
+ const s = getStyles();
80
+ const lines = [];
81
+ const cols = terminal.getTerminalWidth();
82
+ lines.push(s.muted('─'.repeat(Math.max(1, cols - 1))));
83
+ lines.push(' ' + s.primaryBold('Create new command'));
84
+ lines.push('');
85
+ switch (state.wizardStep) {
86
+ case 'location':
87
+ lines.push(chalk.bold(' Choose location'));
88
+ lines.push('');
89
+ lines.push(state.wizardSelectedOption === 0
90
+ ? s.primary(' ❯ 1. Project (.compilr-dev/commands/)')
91
+ : s.muted(' 1. Project (.compilr-dev/commands/)'));
92
+ lines.push(state.wizardSelectedOption === 1
93
+ ? s.primary(' ❯ 2. Personal (~/.compilr-dev/commands/)')
94
+ : s.muted(' 2. Personal (~/.compilr-dev/commands/)'));
95
+ lines.push('');
96
+ lines.push(s.muted(' Project commands are shared with your team.'));
97
+ lines.push(s.muted(' Personal commands apply to all your projects.'));
98
+ break;
99
+ case 'name':
100
+ lines.push(chalk.bold(' Command name'));
101
+ lines.push('');
102
+ lines.push(' Enter a unique name:');
103
+ lines.push(` > ${state.wizardInputBuffer}█`);
104
+ lines.push('');
105
+ if (state.wizardError) {
106
+ lines.push(s.error(` ${state.wizardError}`));
107
+ }
108
+ else {
109
+ lines.push(s.muted(' Use lowercase letters, numbers, hyphens (e.g., code-review)'));
110
+ lines.push(s.muted(' This becomes the command: /{name}'));
111
+ }
112
+ break;
113
+ case 'description':
114
+ lines.push(chalk.bold(' Description'));
115
+ lines.push('');
116
+ lines.push(' Enter a short description:');
117
+ lines.push(` > ${state.wizardInputBuffer}█`);
118
+ lines.push('');
119
+ lines.push(s.muted(' This is shown in the help menu.'));
120
+ break;
121
+ case 'prompt':
122
+ lines.push(chalk.bold(' Prompt template'));
123
+ lines.push('');
124
+ lines.push(' Enter the prompt to send:');
125
+ lines.push(` > ${state.wizardInputBuffer}█`);
126
+ lines.push('');
127
+ lines.push(s.muted(' Use $1, $2 for positional args, $ARGUMENTS for all args.'));
128
+ lines.push(s.muted(' Example: "Review $1 for bugs and security issues"'));
129
+ break;
130
+ case 'confirm':
131
+ lines.push(chalk.bold(' Confirm'));
132
+ lines.push('');
133
+ lines.push(` Command: ${s.primary('/' + state.wizardName)}`);
134
+ lines.push(` Location: ${s.primary(state.wizardLocation === 'project' ? '.compilr-dev/commands/' : '~/.compilr-dev/commands/')}${state.wizardName}.md`);
135
+ lines.push('');
136
+ lines.push(chalk.bold(' Description:'));
137
+ lines.push(s.muted(` ${state.wizardDescription.slice(0, 60)}${state.wizardDescription.length > 60 ? '...' : ''}`));
138
+ lines.push('');
139
+ lines.push(chalk.bold(' Prompt template:'));
140
+ lines.push(s.muted(` ${state.wizardPrompt.slice(0, 60)}${state.wizardPrompt.length > 60 ? '...' : ''}`));
141
+ lines.push('');
142
+ lines.push(state.wizardSelectedOption === 0
143
+ ? s.primary(' ❯ Save')
144
+ : s.muted(' Save'));
145
+ lines.push(state.wizardSelectedOption === 1
146
+ ? s.primary(' ❯ Cancel')
147
+ : s.muted(' Cancel'));
148
+ break;
149
+ }
150
+ lines.push('');
151
+ lines.push(s.muted(' Esc to go back'));
152
+ return lines;
153
+ }
154
+ // =============================================================================
155
+ // Unified Rendering
156
+ // =============================================================================
157
+ function buildLines(state) {
158
+ if (state.mode === 'wizard') {
159
+ return buildWizardLines(state);
160
+ }
161
+ return buildListLines(state);
162
+ }
163
+ function render(state, prevLineCount) {
164
+ const lines = buildLines(state);
165
+ // Clear previous content
166
+ terminal.clearLinesAbove(prevLineCount);
167
+ // Write new content
168
+ terminal.write(lines.join('\n'));
169
+ return lines.length;
170
+ }
171
+ // =============================================================================
172
+ // Main Export
173
+ // =============================================================================
174
+ /**
175
+ * Show the commands overlay
176
+ */
177
+ export async function showCommandsOverlay() {
178
+ const registry = getCustomCommandRegistry();
179
+ registry.load();
180
+ const state = {
181
+ mode: 'list',
182
+ selectedIndex: 0,
183
+ wizardStep: 'location',
184
+ wizardLocation: 'project',
185
+ wizardName: '',
186
+ wizardDescription: '',
187
+ wizardPrompt: '',
188
+ wizardSelectedOption: 0,
189
+ wizardInputBuffer: '',
190
+ wizardError: null,
191
+ registry,
192
+ };
193
+ let lineCount = 0;
194
+ terminal.writeLine('');
195
+ terminal.hideCursor();
196
+ const wasRawMode = process.stdin.isRaw;
197
+ terminal.enableRawMode();
198
+ lineCount = render(state, 0);
199
+ const getMaxIndex = () => {
200
+ return state.registry.getAll().length; // includes "Create new"
201
+ };
202
+ // Reset wizard state for a new creation
203
+ const resetWizard = () => {
204
+ state.wizardStep = 'location';
205
+ state.wizardLocation = 'project';
206
+ state.wizardName = '';
207
+ state.wizardDescription = '';
208
+ state.wizardPrompt = '';
209
+ state.wizardSelectedOption = 0;
210
+ state.wizardInputBuffer = '';
211
+ state.wizardError = null;
212
+ };
213
+ // Wizard: advance to next step
214
+ const wizardNextStep = () => {
215
+ switch (state.wizardStep) {
216
+ case 'location':
217
+ state.wizardLocation = state.wizardSelectedOption === 0 ? 'project' : 'personal';
218
+ state.wizardStep = 'name';
219
+ state.wizardInputBuffer = '';
220
+ break;
221
+ case 'name':
222
+ state.wizardName = state.wizardInputBuffer.trim();
223
+ state.wizardStep = 'description';
224
+ state.wizardInputBuffer = '';
225
+ break;
226
+ case 'description':
227
+ state.wizardDescription = state.wizardInputBuffer.trim();
228
+ state.wizardStep = 'prompt';
229
+ state.wizardInputBuffer = '';
230
+ break;
231
+ case 'prompt':
232
+ state.wizardPrompt = state.wizardInputBuffer.trim();
233
+ state.wizardStep = 'confirm';
234
+ state.wizardSelectedOption = 0;
235
+ break;
236
+ case 'confirm':
237
+ if (state.wizardSelectedOption === 0) {
238
+ // Save
239
+ try {
240
+ registry.save({
241
+ name: state.wizardName,
242
+ description: state.wizardDescription,
243
+ prompt: state.wizardPrompt,
244
+ }, state.wizardLocation);
245
+ // Success - go back to list
246
+ registry.load();
247
+ state.mode = 'list';
248
+ state.selectedIndex = 0;
249
+ return true; // Created successfully
250
+ }
251
+ catch (error) {
252
+ state.wizardError = error.message;
253
+ }
254
+ }
255
+ else {
256
+ // Cancel - go back to list
257
+ state.mode = 'list';
258
+ }
259
+ break;
260
+ }
261
+ state.wizardError = null;
262
+ return false;
263
+ };
264
+ // Wizard: go back to previous step (or exit wizard)
265
+ const wizardPrevStep = () => {
266
+ switch (state.wizardStep) {
267
+ case 'location':
268
+ // Exit wizard, go back to list
269
+ state.mode = 'list';
270
+ break;
271
+ case 'name':
272
+ state.wizardStep = 'location';
273
+ state.wizardSelectedOption = state.wizardLocation === 'project' ? 0 : 1;
274
+ break;
275
+ case 'description':
276
+ state.wizardStep = 'name';
277
+ state.wizardInputBuffer = state.wizardName;
278
+ break;
279
+ case 'prompt':
280
+ state.wizardStep = 'description';
281
+ state.wizardInputBuffer = state.wizardDescription;
282
+ break;
283
+ case 'confirm':
284
+ state.wizardStep = 'prompt';
285
+ state.wizardInputBuffer = state.wizardPrompt;
286
+ break;
287
+ }
288
+ state.wizardError = null;
289
+ };
290
+ return new Promise((resolve) => {
291
+ const cleanup = () => {
292
+ terminal.clearLinesAbove(lineCount);
293
+ terminal.writeLine('');
294
+ terminal.showCursor();
295
+ if (!wasRawMode) {
296
+ terminal.disableRawMode();
297
+ }
298
+ process.stdin.removeListener('data', onData);
299
+ };
300
+ const onData = (data) => {
301
+ const isEscape = data.length === 1 && data[0] === 0x1b;
302
+ const isUpArrow = data.length === 3 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x41;
303
+ const isDownArrow = data.length === 3 && data[0] === 0x1b && data[1] === 0x5b && data[2] === 0x42;
304
+ const isCtrlC = data.length === 1 && data[0] === 0x03;
305
+ const isEnter = data.length === 1 && (data[0] === 0x0d || data[0] === 0x0a);
306
+ const isBackspace = data.length === 1 && (data[0] === 0x7f || data[0] === 0x08);
307
+ // ===== LIST MODE =====
308
+ if (state.mode === 'list') {
309
+ if (isEscape || isCtrlC) {
310
+ cleanup();
311
+ resolve();
312
+ return;
313
+ }
314
+ if (isUpArrow && state.selectedIndex > 0) {
315
+ state.selectedIndex--;
316
+ lineCount = render(state, lineCount);
317
+ return;
318
+ }
319
+ if (isDownArrow && state.selectedIndex < getMaxIndex()) {
320
+ state.selectedIndex++;
321
+ lineCount = render(state, lineCount);
322
+ return;
323
+ }
324
+ if (isEnter) {
325
+ const commands = state.registry.getAll();
326
+ if (state.selectedIndex === commands.length) {
327
+ // "Create new command" selected - enter wizard mode
328
+ resetWizard();
329
+ state.mode = 'wizard';
330
+ lineCount = render(state, lineCount);
331
+ }
332
+ return;
333
+ }
334
+ return;
335
+ }
336
+ // ===== WIZARD MODE =====
337
+ // At this point, mode must be 'wizard' since we handled 'list' above
338
+ {
339
+ if (isCtrlC) {
340
+ cleanup();
341
+ resolve();
342
+ return;
343
+ }
344
+ if (isEscape) {
345
+ wizardPrevStep();
346
+ lineCount = render(state, lineCount);
347
+ return;
348
+ }
349
+ // Input steps: name, description, prompt
350
+ if (['name', 'description', 'prompt'].includes(state.wizardStep)) {
351
+ if (isEnter) {
352
+ if (state.wizardInputBuffer.trim()) {
353
+ // Validate name
354
+ if (state.wizardStep === 'name') {
355
+ const name = state.wizardInputBuffer.trim();
356
+ if (!/^[a-z][a-z0-9-]{1,29}$/.test(name)) {
357
+ state.wizardError = 'Invalid name. Use lowercase letters, numbers, hyphens (2-30 chars).';
358
+ lineCount = render(state, lineCount);
359
+ return;
360
+ }
361
+ if (registry.has(name)) {
362
+ state.wizardError = `Command "${name}" already exists.`;
363
+ lineCount = render(state, lineCount);
364
+ return;
365
+ }
366
+ }
367
+ wizardNextStep();
368
+ lineCount = render(state, lineCount);
369
+ }
370
+ return;
371
+ }
372
+ if (isBackspace) {
373
+ state.wizardInputBuffer = state.wizardInputBuffer.slice(0, -1);
374
+ state.wizardError = null;
375
+ lineCount = render(state, lineCount);
376
+ return;
377
+ }
378
+ // Regular character input
379
+ const char = data.toString('utf-8');
380
+ if (char.length === 1 && char.charCodeAt(0) >= 32) {
381
+ state.wizardInputBuffer += char;
382
+ state.wizardError = null;
383
+ lineCount = render(state, lineCount);
384
+ }
385
+ return;
386
+ }
387
+ // Selection steps: location, confirm
388
+ if (['location', 'confirm'].includes(state.wizardStep)) {
389
+ const maxOptions = 2;
390
+ if (isUpArrow && state.wizardSelectedOption > 0) {
391
+ state.wizardSelectedOption--;
392
+ lineCount = render(state, lineCount);
393
+ return;
394
+ }
395
+ if (isDownArrow && state.wizardSelectedOption < maxOptions - 1) {
396
+ state.wizardSelectedOption++;
397
+ lineCount = render(state, lineCount);
398
+ return;
399
+ }
400
+ if (isEnter) {
401
+ wizardNextStep();
402
+ lineCount = render(state, lineCount);
403
+ return;
404
+ }
405
+ }
406
+ }
407
+ };
408
+ process.stdin.on('data', onData);
409
+ });
410
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Config Overlay
3
+ *
4
+ * Claude Code-style settings overlay with 3 tabs:
5
+ * - Status: Read-only info (version, model, provider, cwd, session)
6
+ * - Config: Interactive settings (toggle/cycle with Enter/Space)
7
+ * - Usage: Usage statistics with progress bars (mocked)
8
+ *
9
+ * Includes theme selector sub-screen with 418 themes.
10
+ */
11
+ export interface ConfigOverlayOptions {
12
+ version?: string;
13
+ sessionId?: string;
14
+ cwd?: string;
15
+ model?: string;
16
+ provider?: string;
17
+ toolCount?: number;
18
+ startTime?: Date;
19
+ inputTokens?: number;
20
+ outputTokens?: number;
21
+ requests?: number;
22
+ contextUsed?: number;
23
+ contextMax?: number;
24
+ messageCount?: number;
25
+ onModelChange?: (model: string) => void;
26
+ initialMode?: 'tabs' | 'model-selector';
27
+ }
28
+ export interface ConfigOverlayResult {
29
+ modelChanged?: string;
30
+ }
31
+ /**
32
+ * Show the config overlay
33
+ */
34
+ export declare function showConfigOverlay(options?: ConfigOverlayOptions): Promise<ConfigOverlayResult>;