@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,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Path Autocomplete
|
|
3
|
+
*
|
|
4
|
+
* Uses ripgrep to provide fast file/folder suggestions when user types @path
|
|
5
|
+
*/
|
|
6
|
+
export interface FileMatch {
|
|
7
|
+
/** Display name (filename or dirname/) */
|
|
8
|
+
name: string;
|
|
9
|
+
/** Full path from cwd */
|
|
10
|
+
path: string;
|
|
11
|
+
/** Is this a directory? */
|
|
12
|
+
isDirectory: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get file/folder matches for a partial path
|
|
16
|
+
*
|
|
17
|
+
* @param partial - The partial path after @ (e.g., "src/comp" or "package")
|
|
18
|
+
* @param cwd - Current working directory
|
|
19
|
+
* @returns Array of matching files/folders
|
|
20
|
+
*/
|
|
21
|
+
export declare function getFileMatches(partial: string, cwd?: string): FileMatch[];
|
|
22
|
+
/**
|
|
23
|
+
* Extract the @ mention from input text
|
|
24
|
+
*
|
|
25
|
+
* @param input - Full input text
|
|
26
|
+
* @param cursorPos - Current cursor position
|
|
27
|
+
* @returns The partial path after @ or null if not in @ context
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractAtMention(input: string, cursorPos: number): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Replace the @ mention with completed path
|
|
32
|
+
*
|
|
33
|
+
* @param input - Full input text
|
|
34
|
+
* @param cursorPos - Current cursor position
|
|
35
|
+
* @param completedPath - The completed path to insert
|
|
36
|
+
* @returns New input text and new cursor position
|
|
37
|
+
*/
|
|
38
|
+
export declare function replaceAtMention(input: string, cursorPos: number, completedPath: string): {
|
|
39
|
+
input: string;
|
|
40
|
+
cursorPos: number;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Clear the file cache (call when cwd changes)
|
|
44
|
+
*/
|
|
45
|
+
export declare function clearFileCache(): void;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Path Autocomplete
|
|
3
|
+
*
|
|
4
|
+
* Uses ripgrep to provide fast file/folder suggestions when user types @path
|
|
5
|
+
*/
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Constants
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/** Max results to return */
|
|
12
|
+
const MAX_RESULTS = 15;
|
|
13
|
+
/** Cache for file list (refreshed periodically) */
|
|
14
|
+
let fileCache = [];
|
|
15
|
+
let lastCacheTime = 0;
|
|
16
|
+
const CACHE_TTL_MS = 5000; // 5 seconds
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// Ripgrep File Listing
|
|
19
|
+
// =============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Get all files using ripgrep
|
|
22
|
+
* Results are cached for performance
|
|
23
|
+
*/
|
|
24
|
+
function getAllFiles(cwd) {
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
// Return cached results if fresh
|
|
27
|
+
if (fileCache.length > 0 && now - lastCacheTime < CACHE_TTL_MS) {
|
|
28
|
+
return fileCache;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
// Use ripgrep to list all files
|
|
32
|
+
// --files: list files instead of searching
|
|
33
|
+
// Respects .gitignore by default
|
|
34
|
+
const result = execSync('rg --files 2>/dev/null', {
|
|
35
|
+
cwd,
|
|
36
|
+
encoding: 'utf-8',
|
|
37
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
|
|
38
|
+
timeout: 3000, // 3 second timeout
|
|
39
|
+
});
|
|
40
|
+
fileCache = result
|
|
41
|
+
.split('\n')
|
|
42
|
+
.filter((line) => line.trim())
|
|
43
|
+
.map((line) => line.replace(/\\/g, '/')); // Normalize paths
|
|
44
|
+
lastCacheTime = now;
|
|
45
|
+
return fileCache;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Ripgrep failed or not available, return empty
|
|
49
|
+
return fileCache; // Return stale cache if available
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract unique directories from file paths
|
|
54
|
+
*/
|
|
55
|
+
function extractDirectories(files) {
|
|
56
|
+
const dirs = new Set();
|
|
57
|
+
for (const file of files) {
|
|
58
|
+
const parts = file.split('/');
|
|
59
|
+
let current = '';
|
|
60
|
+
// Add all parent directories
|
|
61
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
62
|
+
current = current ? `${current}/${parts[i]}` : parts[i];
|
|
63
|
+
dirs.add(current);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return dirs;
|
|
67
|
+
}
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// File Matching
|
|
70
|
+
// =============================================================================
|
|
71
|
+
/**
|
|
72
|
+
* Get file/folder matches for a partial path
|
|
73
|
+
*
|
|
74
|
+
* @param partial - The partial path after @ (e.g., "src/comp" or "package")
|
|
75
|
+
* @param cwd - Current working directory
|
|
76
|
+
* @returns Array of matching files/folders
|
|
77
|
+
*/
|
|
78
|
+
export function getFileMatches(partial, cwd = process.cwd()) {
|
|
79
|
+
const files = getAllFiles(cwd);
|
|
80
|
+
const dirs = extractDirectories(files);
|
|
81
|
+
const matches = [];
|
|
82
|
+
const seen = new Set();
|
|
83
|
+
const normalizedPartial = partial.toLowerCase().replace(/\\/g, '/');
|
|
84
|
+
// If partial has a directory component, filter by that
|
|
85
|
+
const lastSlash = normalizedPartial.lastIndexOf('/');
|
|
86
|
+
const dirPrefix = lastSlash >= 0 ? normalizedPartial.slice(0, lastSlash + 1) : '';
|
|
87
|
+
const namePrefix = lastSlash >= 0 ? normalizedPartial.slice(lastSlash + 1) : normalizedPartial;
|
|
88
|
+
// Match directories first
|
|
89
|
+
for (const dir of dirs) {
|
|
90
|
+
const dirLower = dir.toLowerCase();
|
|
91
|
+
const dirWithSlash = `${dir}/`;
|
|
92
|
+
// Check if this directory matches
|
|
93
|
+
if (dirPrefix) {
|
|
94
|
+
// Has directory prefix - match directories under that path
|
|
95
|
+
if (dirLower.startsWith(dirPrefix.slice(0, -1))) {
|
|
96
|
+
const remaining = dir.slice(dirPrefix.length - 1);
|
|
97
|
+
if (remaining && !remaining.includes('/')) {
|
|
98
|
+
// Direct child directory
|
|
99
|
+
if (!namePrefix || remaining.toLowerCase().startsWith(namePrefix)) {
|
|
100
|
+
if (!seen.has(dirWithSlash)) {
|
|
101
|
+
seen.add(dirWithSlash);
|
|
102
|
+
matches.push({
|
|
103
|
+
name: `${remaining}/`,
|
|
104
|
+
path: dirWithSlash,
|
|
105
|
+
isDirectory: true,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// No directory prefix - match top-level directories
|
|
114
|
+
if (!dir.includes('/')) {
|
|
115
|
+
if (!namePrefix || dirLower.startsWith(namePrefix)) {
|
|
116
|
+
if (!seen.has(dirWithSlash)) {
|
|
117
|
+
seen.add(dirWithSlash);
|
|
118
|
+
matches.push({
|
|
119
|
+
name: `${dir}/`,
|
|
120
|
+
path: dirWithSlash,
|
|
121
|
+
isDirectory: true,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (matches.length >= MAX_RESULTS)
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
// Then match files
|
|
131
|
+
for (const file of files) {
|
|
132
|
+
if (matches.length >= MAX_RESULTS)
|
|
133
|
+
break;
|
|
134
|
+
const fileLower = file.toLowerCase();
|
|
135
|
+
if (dirPrefix) {
|
|
136
|
+
// Has directory prefix - match files under that path
|
|
137
|
+
if (fileLower.startsWith(dirPrefix)) {
|
|
138
|
+
const remaining = file.slice(dirPrefix.length);
|
|
139
|
+
if (!remaining.includes('/')) {
|
|
140
|
+
// Direct child file
|
|
141
|
+
if (!namePrefix || remaining.toLowerCase().startsWith(namePrefix)) {
|
|
142
|
+
if (!seen.has(file)) {
|
|
143
|
+
seen.add(file);
|
|
144
|
+
matches.push({
|
|
145
|
+
name: remaining,
|
|
146
|
+
path: file,
|
|
147
|
+
isDirectory: false,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// No directory prefix - match top-level files or by filename anywhere
|
|
156
|
+
const fileName = path.basename(file);
|
|
157
|
+
if (!namePrefix || fileName.toLowerCase().startsWith(namePrefix) || fileLower.startsWith(namePrefix)) {
|
|
158
|
+
if (!seen.has(file)) {
|
|
159
|
+
seen.add(file);
|
|
160
|
+
matches.push({
|
|
161
|
+
name: file.includes('/') ? file : fileName,
|
|
162
|
+
path: file,
|
|
163
|
+
isDirectory: false,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Sort: directories first, then alphabetically
|
|
170
|
+
matches.sort((a, b) => {
|
|
171
|
+
if (a.isDirectory && !b.isDirectory)
|
|
172
|
+
return -1;
|
|
173
|
+
if (!a.isDirectory && b.isDirectory)
|
|
174
|
+
return 1;
|
|
175
|
+
return a.name.localeCompare(b.name);
|
|
176
|
+
});
|
|
177
|
+
return matches.slice(0, MAX_RESULTS);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Extract the @ mention from input text
|
|
181
|
+
*
|
|
182
|
+
* @param input - Full input text
|
|
183
|
+
* @param cursorPos - Current cursor position
|
|
184
|
+
* @returns The partial path after @ or null if not in @ context
|
|
185
|
+
*/
|
|
186
|
+
export function extractAtMention(input, cursorPos) {
|
|
187
|
+
// Look backwards from cursor to find @
|
|
188
|
+
let start = cursorPos - 1;
|
|
189
|
+
while (start >= 0) {
|
|
190
|
+
const char = input[start];
|
|
191
|
+
// Found @
|
|
192
|
+
if (char === '@') {
|
|
193
|
+
// Make sure it's at start or after whitespace
|
|
194
|
+
if (start === 0 || /\s/.test(input[start - 1])) {
|
|
195
|
+
return input.slice(start + 1, cursorPos);
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
// Hit whitespace without finding @ - not in @ context
|
|
200
|
+
if (/\s/.test(char)) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
start--;
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Replace the @ mention with completed path
|
|
209
|
+
*
|
|
210
|
+
* @param input - Full input text
|
|
211
|
+
* @param cursorPos - Current cursor position
|
|
212
|
+
* @param completedPath - The completed path to insert
|
|
213
|
+
* @returns New input text and new cursor position
|
|
214
|
+
*/
|
|
215
|
+
export function replaceAtMention(input, cursorPos, completedPath) {
|
|
216
|
+
// Find the @ position
|
|
217
|
+
let atPos = cursorPos - 1;
|
|
218
|
+
while (atPos >= 0 && input[atPos] !== '@') {
|
|
219
|
+
atPos--;
|
|
220
|
+
}
|
|
221
|
+
if (atPos < 0) {
|
|
222
|
+
return { input, cursorPos };
|
|
223
|
+
}
|
|
224
|
+
// Replace from @ to cursor with the completed path
|
|
225
|
+
const before = input.slice(0, atPos);
|
|
226
|
+
const after = input.slice(cursorPos);
|
|
227
|
+
const newInput = `${before}@${completedPath}${after}`;
|
|
228
|
+
const newCursorPos = atPos + 1 + completedPath.length;
|
|
229
|
+
return { input: newInput, cursorPos: newCursorPos };
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Clear the file cache (call when cwd changes)
|
|
233
|
+
*/
|
|
234
|
+
export function clearFileCache() {
|
|
235
|
+
fileCache = [];
|
|
236
|
+
lastCacheTime = 0;
|
|
237
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
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 type { TodoItem, AgentMode } from './types.js';
|
|
17
|
+
export interface FooterEvents {
|
|
18
|
+
submit: (input: string) => void;
|
|
19
|
+
command: (command: string, args: string) => void;
|
|
20
|
+
cancel: () => void;
|
|
21
|
+
escape: () => void;
|
|
22
|
+
modeChange: () => void;
|
|
23
|
+
}
|
|
24
|
+
export interface FooterOptions {
|
|
25
|
+
prompt?: string;
|
|
26
|
+
showSeparators?: boolean;
|
|
27
|
+
renderInterval?: number;
|
|
28
|
+
initialMode?: AgentMode;
|
|
29
|
+
}
|
|
30
|
+
export declare class Footer extends EventEmitter {
|
|
31
|
+
private readonly todoZone;
|
|
32
|
+
private readonly inputPrompt;
|
|
33
|
+
private agentRunning;
|
|
34
|
+
private mode;
|
|
35
|
+
private lastRenderHeight;
|
|
36
|
+
private isRunning;
|
|
37
|
+
private isPaused;
|
|
38
|
+
private cursorLineFromBottom;
|
|
39
|
+
private readonly renderInterval;
|
|
40
|
+
private renderTimer;
|
|
41
|
+
private needsRender;
|
|
42
|
+
constructor(options?: FooterOptions);
|
|
43
|
+
/**
|
|
44
|
+
* Start the footer (begins render loop and input capture)
|
|
45
|
+
*/
|
|
46
|
+
start(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Stop the footer
|
|
49
|
+
*/
|
|
50
|
+
stop(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Set whether agent is running
|
|
53
|
+
* Enables/disables queue mode and spinner
|
|
54
|
+
*/
|
|
55
|
+
setAgentRunning(running: boolean): void;
|
|
56
|
+
/**
|
|
57
|
+
* Check if agent is running
|
|
58
|
+
*/
|
|
59
|
+
isAgentRunning(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Set the current mode
|
|
62
|
+
*/
|
|
63
|
+
setMode(mode: AgentMode): void;
|
|
64
|
+
/**
|
|
65
|
+
* Get the current mode
|
|
66
|
+
*/
|
|
67
|
+
getMode(): AgentMode;
|
|
68
|
+
/**
|
|
69
|
+
* Update the todo list
|
|
70
|
+
*/
|
|
71
|
+
setTodos(todos: TodoItem[]): void;
|
|
72
|
+
/**
|
|
73
|
+
* Set the current tool being executed
|
|
74
|
+
*/
|
|
75
|
+
setCurrentTool(tool: string | null): void;
|
|
76
|
+
/**
|
|
77
|
+
* Set a suggestion for the next action (ghost text in input prompt)
|
|
78
|
+
*/
|
|
79
|
+
setSuggestion(action: string | null): void;
|
|
80
|
+
/**
|
|
81
|
+
* Set custom spinner text (overrides todo activeForm and random thinking word)
|
|
82
|
+
* Pass null to clear and use default behavior.
|
|
83
|
+
*/
|
|
84
|
+
setSpinnerText(text: string | null): void;
|
|
85
|
+
/**
|
|
86
|
+
* Add tokens to the spinner counter
|
|
87
|
+
*/
|
|
88
|
+
addTokens(count: number): void;
|
|
89
|
+
/**
|
|
90
|
+
* Get queued inputs
|
|
91
|
+
*/
|
|
92
|
+
getQueuedInputs(): string[];
|
|
93
|
+
/**
|
|
94
|
+
* Pop the first queued input
|
|
95
|
+
*/
|
|
96
|
+
popQueuedInput(): string | null;
|
|
97
|
+
/**
|
|
98
|
+
* Check if there are queued inputs
|
|
99
|
+
*/
|
|
100
|
+
hasQueuedInput(): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Clear the queue
|
|
103
|
+
*/
|
|
104
|
+
clearQueue(): void;
|
|
105
|
+
/**
|
|
106
|
+
* Clear footer before scrolling output
|
|
107
|
+
* Call this before writing to the scrolling zone
|
|
108
|
+
*/
|
|
109
|
+
clearForOutput(): void;
|
|
110
|
+
/**
|
|
111
|
+
* Force an immediate render
|
|
112
|
+
*/
|
|
113
|
+
forceRender(): void;
|
|
114
|
+
/**
|
|
115
|
+
* Pause footer completely (for overlays)
|
|
116
|
+
* Stops render loop, input capture, and animation
|
|
117
|
+
*/
|
|
118
|
+
pauseAnimation(): void;
|
|
119
|
+
/**
|
|
120
|
+
* Resume footer after pause
|
|
121
|
+
* Restarts render loop, input capture, and animation
|
|
122
|
+
*/
|
|
123
|
+
resumeAnimation(): void;
|
|
124
|
+
/**
|
|
125
|
+
* Get the height of last render
|
|
126
|
+
*/
|
|
127
|
+
getLastRenderHeight(): number;
|
|
128
|
+
/**
|
|
129
|
+
* Refresh the prompt with current theme colors
|
|
130
|
+
* Call after theme changes to apply new colors immediately
|
|
131
|
+
*/
|
|
132
|
+
refreshPrompt(): void;
|
|
133
|
+
/**
|
|
134
|
+
* Clear the footer area
|
|
135
|
+
*/
|
|
136
|
+
private clear;
|
|
137
|
+
/**
|
|
138
|
+
* Render the entire footer
|
|
139
|
+
*/
|
|
140
|
+
private render;
|
|
141
|
+
/**
|
|
142
|
+
* Render mode indicator line
|
|
143
|
+
*/
|
|
144
|
+
private renderModeIndicator;
|
|
145
|
+
/**
|
|
146
|
+
* Calculate how many terminal rows a line takes (accounting for wrapping)
|
|
147
|
+
*/
|
|
148
|
+
private getTerminalRowsForLine;
|
|
149
|
+
/**
|
|
150
|
+
* Position cursor correctly within the input prompt
|
|
151
|
+
*/
|
|
152
|
+
private positionCursor;
|
|
153
|
+
}
|