@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.
- package/README.md +110 -0
- package/dist/agent.d.ts +62 -0
- package/dist/agent.js +317 -0
- package/dist/agents/registry.d.ts +66 -0
- package/dist/agents/registry.js +238 -0
- package/dist/agents/types.d.ts +40 -0
- package/dist/agents/types.js +94 -0
- package/dist/commands/custom-registry.d.ts +69 -0
- package/dist/commands/custom-registry.js +246 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/types.d.ts +31 -0
- package/dist/commands/types.js +26 -0
- package/dist/commands.d.ts +63 -0
- package/dist/commands.js +324 -0
- package/dist/db/index.d.ts +42 -0
- package/dist/db/index.js +146 -0
- package/dist/db/repositories/document-repository.d.ts +63 -0
- package/dist/db/repositories/document-repository.js +184 -0
- package/dist/db/repositories/index.d.ts +9 -0
- package/dist/db/repositories/index.js +6 -0
- package/dist/db/repositories/project-repository.d.ts +132 -0
- package/dist/db/repositories/project-repository.js +337 -0
- package/dist/db/repositories/work-item-repository.d.ts +115 -0
- package/dist/db/repositories/work-item-repository.js +389 -0
- package/dist/db/schema.d.ts +83 -0
- package/dist/db/schema.js +143 -0
- package/dist/debug.d.ts +8 -0
- package/dist/debug.js +48 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +348 -0
- package/dist/index.old.d.ts +7 -0
- package/dist/index.old.js +1014 -0
- package/dist/repl.d.ts +121 -0
- package/dist/repl.js +1878 -0
- package/dist/settings/index.d.ts +80 -0
- package/dist/settings/index.js +195 -0
- package/dist/shared-handlers.d.ts +63 -0
- package/dist/shared-handlers.js +57 -0
- package/dist/slash-autocomplete.d.ts +41 -0
- package/dist/slash-autocomplete.js +638 -0
- package/dist/state.d.ts +75 -0
- package/dist/state.js +130 -0
- package/dist/tabbed-menu.d.ts +11 -0
- package/dist/tabbed-menu.js +328 -0
- package/dist/templates/backlog-md.d.ts +7 -0
- package/dist/templates/backlog-md.js +94 -0
- package/dist/templates/claude-md.d.ts +7 -0
- package/dist/templates/claude-md.js +189 -0
- package/dist/templates/coding-standards.d.ts +7 -0
- package/dist/templates/coding-standards.js +299 -0
- package/dist/templates/compilr-md.d.ts +7 -0
- package/dist/templates/compilr-md.js +189 -0
- package/dist/templates/config-json.d.ts +38 -0
- package/dist/templates/config-json.js +39 -0
- package/dist/templates/gitignore.d.ts +7 -0
- package/dist/templates/gitignore.js +85 -0
- package/dist/templates/index.d.ts +19 -0
- package/dist/templates/index.js +302 -0
- package/dist/templates/package-json.d.ts +7 -0
- package/dist/templates/package-json.js +111 -0
- package/dist/templates/readme-md.d.ts +7 -0
- package/dist/templates/readme-md.js +161 -0
- package/dist/templates/tsconfig.d.ts +7 -0
- package/dist/templates/tsconfig.js +61 -0
- package/dist/templates/types.d.ts +33 -0
- package/dist/templates/types.js +24 -0
- package/dist/test-autocomplete.d.ts +7 -0
- package/dist/test-autocomplete.js +85 -0
- package/dist/test-tabbed-menu.d.ts +7 -0
- package/dist/test-tabbed-menu.js +25 -0
- package/dist/themes/colors.d.ts +49 -0
- package/dist/themes/colors.js +135 -0
- package/dist/themes/index.d.ts +23 -0
- package/dist/themes/index.js +24 -0
- package/dist/themes/registry.d.ts +60 -0
- package/dist/themes/registry.js +195 -0
- package/dist/themes/types.d.ts +82 -0
- package/dist/themes/types.js +7 -0
- package/dist/tool-selector.d.ts +71 -0
- package/dist/tool-selector.js +184 -0
- package/dist/tools/ask-user-simple.d.ts +19 -0
- package/dist/tools/ask-user-simple.js +86 -0
- package/dist/tools/ask-user.d.ts +32 -0
- package/dist/tools/ask-user.js +113 -0
- package/dist/tools/backlog.d.ts +53 -0
- package/dist/tools/backlog.js +709 -0
- package/dist/tools.d.ts +15 -0
- package/dist/tools.js +121 -0
- package/dist/ui/agents-overlay.d.ts +12 -0
- package/dist/ui/agents-overlay.js +501 -0
- package/dist/ui/arch-type-overlay.d.ts +20 -0
- package/dist/ui/arch-type-overlay.js +229 -0
- package/dist/ui/ask-user-overlay.d.ts +26 -0
- package/dist/ui/ask-user-overlay.js +647 -0
- package/dist/ui/ask-user-simple-overlay.d.ts +25 -0
- package/dist/ui/ask-user-simple-overlay.js +242 -0
- package/dist/ui/backlog-overlay.d.ts +17 -0
- package/dist/ui/backlog-overlay.js +786 -0
- package/dist/ui/commands-overlay.d.ts +11 -0
- package/dist/ui/commands-overlay.js +410 -0
- package/dist/ui/config-overlay.d.ts +34 -0
- package/dist/ui/config-overlay.js +977 -0
- package/dist/ui/conversation.d.ts +82 -0
- package/dist/ui/conversation.js +508 -0
- package/dist/ui/diff.d.ts +38 -0
- package/dist/ui/diff.js +182 -0
- package/dist/ui/ephemeral.d.ts +111 -0
- package/dist/ui/ephemeral.js +413 -0
- package/dist/ui/file-autocomplete.d.ts +45 -0
- package/dist/ui/file-autocomplete.js +237 -0
- package/dist/ui/footer.d.ts +153 -0
- package/dist/ui/footer.js +422 -0
- package/dist/ui/index.d.ts +12 -0
- package/dist/ui/index.js +15 -0
- package/dist/ui/init-overlay.d.ts +24 -0
- package/dist/ui/init-overlay.js +525 -0
- package/dist/ui/input-prompt-v2.d.ts +179 -0
- package/dist/ui/input-prompt-v2.js +991 -0
- package/dist/ui/input-prompt.d.ts +97 -0
- package/dist/ui/input-prompt.js +800 -0
- package/dist/ui/iteration-limit-overlay.d.ts +21 -0
- package/dist/ui/iteration-limit-overlay.js +150 -0
- package/dist/ui/keys-overlay.d.ts +14 -0
- package/dist/ui/keys-overlay.js +181 -0
- package/dist/ui/model-warning-overlay.d.ts +30 -0
- package/dist/ui/model-warning-overlay.js +171 -0
- package/dist/ui/overlay-controller.d.ts +25 -0
- package/dist/ui/overlay-controller.js +35 -0
- package/dist/ui/overlays.d.ts +47 -0
- package/dist/ui/overlays.js +627 -0
- package/dist/ui/permission-overlay.d.ts +16 -0
- package/dist/ui/permission-overlay.js +494 -0
- package/dist/ui/terminal.d.ts +117 -0
- package/dist/ui/terminal.js +237 -0
- package/dist/ui/todo-zone.d.ts +112 -0
- package/dist/ui/todo-zone.js +353 -0
- package/dist/ui/tools-overlay.d.ts +26 -0
- package/dist/ui/tools-overlay.js +278 -0
- package/dist/ui/tutorial-overlay.d.ts +10 -0
- package/dist/ui/tutorial-overlay.js +936 -0
- package/dist/ui/types.d.ts +103 -0
- package/dist/ui/types.js +33 -0
- package/dist/utils/credentials.d.ts +55 -0
- package/dist/utils/credentials.js +268 -0
- package/dist/utils/model-tiers.d.ts +37 -0
- package/dist/utils/model-tiers.js +118 -0
- package/dist/utils/project-memory.d.ts +47 -0
- package/dist/utils/project-memory.js +117 -0
- package/dist/utils/project-status.d.ts +56 -0
- package/dist/utils/project-status.js +237 -0
- package/package.json +66 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tools Overlay
|
|
3
|
+
*
|
|
4
|
+
* Displays available agent tools in a scrollable list with descriptions.
|
|
5
|
+
* Supports detail view for full tool information.
|
|
6
|
+
*/
|
|
7
|
+
export interface ToolParameter {
|
|
8
|
+
name: string;
|
|
9
|
+
type: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
required: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface ToolPermissionInfo {
|
|
14
|
+
level: 'once' | 'always' | 'session';
|
|
15
|
+
description: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ToolInfo {
|
|
18
|
+
name: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
parameters?: ToolParameter[];
|
|
21
|
+
permission?: ToolPermissionInfo;
|
|
22
|
+
}
|
|
23
|
+
export interface ToolsOverlayResult {
|
|
24
|
+
dismissed: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function showToolsOverlay(tools: ToolInfo[]): Promise<ToolsOverlayResult>;
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tools Overlay
|
|
3
|
+
*
|
|
4
|
+
* Displays available agent tools in a scrollable list with descriptions.
|
|
5
|
+
* Supports detail view for full tool information.
|
|
6
|
+
*/
|
|
7
|
+
import * as terminal from './terminal.js';
|
|
8
|
+
import { getStyles } from '../themes/index.js';
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Constants
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/** Number of tools visible at once */
|
|
13
|
+
const VISIBLE_ROWS = 12;
|
|
14
|
+
/** Width for tool name column */
|
|
15
|
+
const NAME_WIDTH = 18;
|
|
16
|
+
/** Max description length in detail view */
|
|
17
|
+
const MAX_DESCRIPTION_LENGTH = 300;
|
|
18
|
+
/** Max parameters to show in detail view */
|
|
19
|
+
const MAX_PARAMETERS_SHOWN = 5;
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// Main Function
|
|
22
|
+
// =============================================================================
|
|
23
|
+
export async function showToolsOverlay(tools) {
|
|
24
|
+
const s = getStyles();
|
|
25
|
+
const stdin = process.stdin;
|
|
26
|
+
// Sort tools alphabetically
|
|
27
|
+
const sortedTools = [...tools].sort((a, b) => a.name.localeCompare(b.name));
|
|
28
|
+
// State
|
|
29
|
+
let selectedIndex = 0;
|
|
30
|
+
let scrollOffset = 0;
|
|
31
|
+
let lineCount = 0;
|
|
32
|
+
let mode = 'list';
|
|
33
|
+
// Get terminal width for layout
|
|
34
|
+
const termWidth = terminal.getTerminalWidth();
|
|
35
|
+
const descWidth = Math.max(20, termWidth - NAME_WIDTH - 10); // 10 for padding/cursor
|
|
36
|
+
// Helper to truncate text
|
|
37
|
+
const truncate = (text, maxLen) => {
|
|
38
|
+
if (text.length <= maxLen)
|
|
39
|
+
return text;
|
|
40
|
+
return text.slice(0, maxLen - 1) + '…';
|
|
41
|
+
};
|
|
42
|
+
// Helper to get border
|
|
43
|
+
const getBorder = () => {
|
|
44
|
+
return s.muted('─'.repeat(Math.max(1, termWidth - 1)));
|
|
45
|
+
};
|
|
46
|
+
// Helper to wrap text to multiple lines
|
|
47
|
+
const wrapText = (text, maxWidth) => {
|
|
48
|
+
const words = text.split(' ');
|
|
49
|
+
const lines = [];
|
|
50
|
+
let currentLine = '';
|
|
51
|
+
for (const word of words) {
|
|
52
|
+
if (currentLine.length + word.length + 1 <= maxWidth) {
|
|
53
|
+
currentLine += (currentLine ? ' ' : '') + word;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (currentLine)
|
|
57
|
+
lines.push(currentLine);
|
|
58
|
+
currentLine = word;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (currentLine)
|
|
62
|
+
lines.push(currentLine);
|
|
63
|
+
return lines;
|
|
64
|
+
};
|
|
65
|
+
// Render list view
|
|
66
|
+
const renderList = () => {
|
|
67
|
+
// Clear previous render
|
|
68
|
+
if (lineCount > 0) {
|
|
69
|
+
terminal.clearLinesAbove(lineCount);
|
|
70
|
+
}
|
|
71
|
+
const lines = [];
|
|
72
|
+
// Header
|
|
73
|
+
lines.push(getBorder());
|
|
74
|
+
const title = `Available Tools`;
|
|
75
|
+
const countBadge = s.muted(`[${String(sortedTools.length)} tools]`);
|
|
76
|
+
lines.push(` ${s.primaryBold(title)} ${countBadge}`);
|
|
77
|
+
lines.push('');
|
|
78
|
+
// Column headers
|
|
79
|
+
const nameHeader = s.muted('Tool'.padEnd(NAME_WIDTH));
|
|
80
|
+
const descHeader = s.muted('Description');
|
|
81
|
+
lines.push(` ${nameHeader} ${descHeader}`);
|
|
82
|
+
lines.push(` ${s.muted('─'.repeat(NAME_WIDTH))} ${s.muted('─'.repeat(Math.min(descWidth, 40)))}`);
|
|
83
|
+
// Visible tools
|
|
84
|
+
const visibleTools = sortedTools.slice(scrollOffset, scrollOffset + VISIBLE_ROWS);
|
|
85
|
+
for (let i = 0; i < visibleTools.length; i++) {
|
|
86
|
+
const tool = visibleTools[i];
|
|
87
|
+
const absoluteIndex = scrollOffset + i;
|
|
88
|
+
const isSelected = absoluteIndex === selectedIndex;
|
|
89
|
+
const cursor = isSelected ? s.primary('❯ ') : ' ';
|
|
90
|
+
const name = isSelected
|
|
91
|
+
? s.primaryBold(tool.name.padEnd(NAME_WIDTH))
|
|
92
|
+
: s.secondary(tool.name.padEnd(NAME_WIDTH));
|
|
93
|
+
const desc = truncate(tool.description ?? '', descWidth);
|
|
94
|
+
const descColor = isSelected ? s.secondary(desc) : s.muted(desc);
|
|
95
|
+
lines.push(` ${cursor}${name} ${descColor}`);
|
|
96
|
+
}
|
|
97
|
+
// Padding if fewer tools than VISIBLE_ROWS
|
|
98
|
+
const emptyRows = VISIBLE_ROWS - visibleTools.length;
|
|
99
|
+
for (let i = 0; i < emptyRows; i++) {
|
|
100
|
+
lines.push('');
|
|
101
|
+
}
|
|
102
|
+
// Scroll indicator
|
|
103
|
+
lines.push('');
|
|
104
|
+
if (sortedTools.length > VISIBLE_ROWS) {
|
|
105
|
+
const scrollInfo = `${String(scrollOffset + 1)}-${String(Math.min(scrollOffset + VISIBLE_ROWS, sortedTools.length))} of ${String(sortedTools.length)}`;
|
|
106
|
+
const canUp = scrollOffset > 0;
|
|
107
|
+
const canDown = scrollOffset + VISIBLE_ROWS < sortedTools.length;
|
|
108
|
+
const arrows = (canUp ? '↑' : ' ') + (canDown ? '↓' : ' ');
|
|
109
|
+
lines.push(` ${s.muted(scrollInfo)} ${s.muted(arrows)}`);
|
|
110
|
+
}
|
|
111
|
+
// Footer
|
|
112
|
+
lines.push(getBorder());
|
|
113
|
+
lines.push(` ${s.muted('↑↓ Navigate · Enter Details · Esc Close')}`);
|
|
114
|
+
lines.push(getBorder());
|
|
115
|
+
// Print all lines
|
|
116
|
+
terminal.write(lines.join('\n'));
|
|
117
|
+
return lines.length;
|
|
118
|
+
};
|
|
119
|
+
// Render detail view
|
|
120
|
+
const renderDetail = () => {
|
|
121
|
+
// Clear previous render
|
|
122
|
+
if (lineCount > 0) {
|
|
123
|
+
terminal.clearLinesAbove(lineCount);
|
|
124
|
+
}
|
|
125
|
+
const tool = sortedTools[selectedIndex];
|
|
126
|
+
const lines = [];
|
|
127
|
+
// Header
|
|
128
|
+
lines.push(getBorder());
|
|
129
|
+
lines.push(` ${s.primaryBold('Tool Details')}`);
|
|
130
|
+
lines.push('');
|
|
131
|
+
// Tool name
|
|
132
|
+
lines.push(` ${s.muted('Name:')} ${s.primaryBold(tool.name)}`);
|
|
133
|
+
lines.push('');
|
|
134
|
+
// Permission info (if any)
|
|
135
|
+
if (tool.permission) {
|
|
136
|
+
const levelColor = tool.permission.level === 'once' ? s.warning : s.muted;
|
|
137
|
+
lines.push(` ${s.muted('Permission:')} ${levelColor(tool.permission.level)} ${s.muted(`(${tool.permission.description})`)}`);
|
|
138
|
+
lines.push('');
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
lines.push(` ${s.muted('Permission:')} ${s.success('always')} ${s.muted('(no approval required)')}`);
|
|
142
|
+
lines.push('');
|
|
143
|
+
}
|
|
144
|
+
// Description (truncated if too long)
|
|
145
|
+
lines.push(` ${s.muted('Description:')}`);
|
|
146
|
+
let description = tool.description ?? 'No description available.';
|
|
147
|
+
if (description.length > MAX_DESCRIPTION_LENGTH) {
|
|
148
|
+
description = description.slice(0, MAX_DESCRIPTION_LENGTH).trim() + '...';
|
|
149
|
+
}
|
|
150
|
+
const wrappedDesc = wrapText(description, termWidth - 6);
|
|
151
|
+
for (const line of wrappedDesc) {
|
|
152
|
+
lines.push(` ${s.secondary(line)}`);
|
|
153
|
+
}
|
|
154
|
+
lines.push('');
|
|
155
|
+
// Parameters (limited to avoid verbose displays)
|
|
156
|
+
if (tool.parameters && tool.parameters.length > 0) {
|
|
157
|
+
// Sort: required first, then optional
|
|
158
|
+
const sorted = [...tool.parameters].sort((a, b) => {
|
|
159
|
+
if (a.required && !b.required)
|
|
160
|
+
return -1;
|
|
161
|
+
if (!a.required && b.required)
|
|
162
|
+
return 1;
|
|
163
|
+
return 0;
|
|
164
|
+
});
|
|
165
|
+
const shown = sorted.slice(0, MAX_PARAMETERS_SHOWN);
|
|
166
|
+
const hidden = sorted.length - shown.length;
|
|
167
|
+
lines.push(` ${s.muted('Parameters:')}`);
|
|
168
|
+
for (const param of shown) {
|
|
169
|
+
const requiredBadge = param.required ? s.warning('*') : ' ';
|
|
170
|
+
const typeStr = s.muted(`(${param.type})`);
|
|
171
|
+
lines.push(` ${requiredBadge} ${s.secondary(param.name)} ${typeStr}`);
|
|
172
|
+
}
|
|
173
|
+
if (hidden > 0) {
|
|
174
|
+
lines.push(` ${s.muted(` + ${String(hidden)} more optional parameters`)}`);
|
|
175
|
+
}
|
|
176
|
+
lines.push('');
|
|
177
|
+
lines.push(` ${s.muted('* = required')}`);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
lines.push(` ${s.muted('Parameters:')} ${s.muted('None')}`);
|
|
181
|
+
}
|
|
182
|
+
// Footer
|
|
183
|
+
lines.push(getBorder());
|
|
184
|
+
lines.push(` ${s.muted('Esc Back to list')}`);
|
|
185
|
+
lines.push(getBorder());
|
|
186
|
+
// Print all lines
|
|
187
|
+
terminal.write(lines.join('\n'));
|
|
188
|
+
return lines.length;
|
|
189
|
+
};
|
|
190
|
+
// Render based on mode
|
|
191
|
+
const render = () => {
|
|
192
|
+
if (mode === 'detail') {
|
|
193
|
+
return renderDetail();
|
|
194
|
+
}
|
|
195
|
+
return renderList();
|
|
196
|
+
};
|
|
197
|
+
// Ensure selected item is visible
|
|
198
|
+
const ensureVisible = () => {
|
|
199
|
+
if (selectedIndex < scrollOffset) {
|
|
200
|
+
scrollOffset = selectedIndex;
|
|
201
|
+
}
|
|
202
|
+
else if (selectedIndex >= scrollOffset + VISIBLE_ROWS) {
|
|
203
|
+
scrollOffset = selectedIndex - VISIBLE_ROWS + 1;
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
// Initial render
|
|
207
|
+
lineCount = render();
|
|
208
|
+
// Set up raw mode for keyboard input
|
|
209
|
+
const wasRaw = stdin.isRaw;
|
|
210
|
+
stdin.setRawMode(true);
|
|
211
|
+
stdin.resume();
|
|
212
|
+
return new Promise((resolve) => {
|
|
213
|
+
const cleanup = () => {
|
|
214
|
+
stdin.removeListener('data', handleKey);
|
|
215
|
+
stdin.setRawMode(wasRaw);
|
|
216
|
+
// Clear the overlay
|
|
217
|
+
terminal.clearLinesAbove(lineCount);
|
|
218
|
+
};
|
|
219
|
+
const handleKey = (data) => {
|
|
220
|
+
const key = data.toString();
|
|
221
|
+
// Handle key presses
|
|
222
|
+
const isEscape = key === '\x1B' && data.length === 1;
|
|
223
|
+
const isEnter = key === '\r' || key === '\n';
|
|
224
|
+
const isUpArrow = key === '\x1B[A';
|
|
225
|
+
const isDownArrow = key === '\x1B[B';
|
|
226
|
+
const isPageUp = key === '\x1B[5~';
|
|
227
|
+
const isPageDown = key === '\x1B[6~';
|
|
228
|
+
const isCtrlC = key === '\x03';
|
|
229
|
+
const isQ = key === 'q' || key === 'Q';
|
|
230
|
+
if (isCtrlC) {
|
|
231
|
+
cleanup();
|
|
232
|
+
resolve({ dismissed: true });
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (mode === 'detail') {
|
|
236
|
+
// Detail view: Esc goes back to list
|
|
237
|
+
if (isEscape || isQ) {
|
|
238
|
+
mode = 'list';
|
|
239
|
+
lineCount = render();
|
|
240
|
+
}
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
// List view
|
|
244
|
+
if (isEscape || isQ) {
|
|
245
|
+
cleanup();
|
|
246
|
+
resolve({ dismissed: true });
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if (isEnter) {
|
|
250
|
+
mode = 'detail';
|
|
251
|
+
lineCount = render();
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
// Navigation
|
|
255
|
+
if (isUpArrow && selectedIndex > 0) {
|
|
256
|
+
selectedIndex--;
|
|
257
|
+
ensureVisible();
|
|
258
|
+
lineCount = render();
|
|
259
|
+
}
|
|
260
|
+
else if (isDownArrow && selectedIndex < sortedTools.length - 1) {
|
|
261
|
+
selectedIndex++;
|
|
262
|
+
ensureVisible();
|
|
263
|
+
lineCount = render();
|
|
264
|
+
}
|
|
265
|
+
else if (isPageUp) {
|
|
266
|
+
selectedIndex = Math.max(0, selectedIndex - VISIBLE_ROWS);
|
|
267
|
+
ensureVisible();
|
|
268
|
+
lineCount = render();
|
|
269
|
+
}
|
|
270
|
+
else if (isPageDown) {
|
|
271
|
+
selectedIndex = Math.min(sortedTools.length - 1, selectedIndex + VISIBLE_ROWS);
|
|
272
|
+
ensureVisible();
|
|
273
|
+
lineCount = render();
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
stdin.on('data', handleKey);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tutorial Overlay
|
|
3
|
+
*
|
|
4
|
+
* Interactive tutorial that guides users through the compilr.dev workflow.
|
|
5
|
+
* Supports guided sequential tour and topic-based navigation.
|
|
6
|
+
*/
|
|
7
|
+
export interface TutorialOverlayResult {
|
|
8
|
+
completed: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function showTutorialOverlay(): Promise<TutorialOverlayResult>;
|