codeep 1.1.12 → 1.1.13
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/bin/codeep.js +1 -1
- package/dist/config/index.js +10 -10
- package/dist/renderer/App.d.ts +430 -0
- package/dist/renderer/App.js +2712 -0
- package/dist/renderer/ChatUI.d.ts +71 -0
- package/dist/renderer/ChatUI.js +286 -0
- package/dist/renderer/Input.d.ts +72 -0
- package/dist/renderer/Input.js +371 -0
- package/dist/renderer/Screen.d.ts +79 -0
- package/dist/renderer/Screen.js +278 -0
- package/dist/renderer/ansi.d.ts +99 -0
- package/dist/renderer/ansi.js +176 -0
- package/dist/renderer/components/Box.d.ts +64 -0
- package/dist/renderer/components/Box.js +90 -0
- package/dist/renderer/components/Help.d.ts +30 -0
- package/dist/renderer/components/Help.js +195 -0
- package/dist/renderer/components/Intro.d.ts +12 -0
- package/dist/renderer/components/Intro.js +128 -0
- package/dist/renderer/components/Login.d.ts +42 -0
- package/dist/renderer/components/Login.js +178 -0
- package/dist/renderer/components/Modal.d.ts +43 -0
- package/dist/renderer/components/Modal.js +207 -0
- package/dist/renderer/components/Permission.d.ts +20 -0
- package/dist/renderer/components/Permission.js +113 -0
- package/dist/renderer/components/SelectScreen.d.ts +26 -0
- package/dist/renderer/components/SelectScreen.js +101 -0
- package/dist/renderer/components/Settings.d.ts +37 -0
- package/dist/renderer/components/Settings.js +333 -0
- package/dist/renderer/components/Status.d.ts +18 -0
- package/dist/renderer/components/Status.js +78 -0
- package/dist/renderer/demo-app.d.ts +6 -0
- package/dist/renderer/demo-app.js +85 -0
- package/dist/renderer/demo.d.ts +6 -0
- package/dist/renderer/demo.js +52 -0
- package/dist/renderer/index.d.ts +16 -0
- package/dist/renderer/index.js +17 -0
- package/dist/renderer/main.d.ts +6 -0
- package/dist/renderer/main.js +1634 -0
- package/dist/utils/agent.d.ts +21 -0
- package/dist/utils/agent.js +29 -0
- package/dist/utils/clipboard.d.ts +15 -0
- package/dist/utils/clipboard.js +95 -0
- package/package.json +7 -11
- package/dist/utils/console.d.ts +0 -55
- package/dist/utils/console.js +0 -188
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw input handling for terminal
|
|
3
|
+
* Handles keypresses, special keys, and line editing
|
|
4
|
+
*/
|
|
5
|
+
export class Input {
|
|
6
|
+
handlers = [];
|
|
7
|
+
rl = null;
|
|
8
|
+
/**
|
|
9
|
+
* Start listening for input
|
|
10
|
+
*/
|
|
11
|
+
start() {
|
|
12
|
+
// Enable raw mode for character-by-character input
|
|
13
|
+
if (process.stdin.isTTY) {
|
|
14
|
+
process.stdin.setRawMode(true);
|
|
15
|
+
}
|
|
16
|
+
process.stdin.resume();
|
|
17
|
+
process.stdin.setEncoding('utf8');
|
|
18
|
+
// Enable mouse tracking (SGR mode for better compatibility)
|
|
19
|
+
// \x1b[?1000h - enable basic mouse tracking
|
|
20
|
+
// \x1b[?1006h - enable SGR extended mouse mode
|
|
21
|
+
process.stdout.write('\x1b[?1000h\x1b[?1006h');
|
|
22
|
+
process.stdin.on('data', (data) => {
|
|
23
|
+
const event = this.parseKey(data);
|
|
24
|
+
this.emit(event);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Stop listening
|
|
29
|
+
*/
|
|
30
|
+
stop() {
|
|
31
|
+
// Disable mouse tracking
|
|
32
|
+
process.stdout.write('\x1b[?1006l\x1b[?1000l');
|
|
33
|
+
if (process.stdin.isTTY) {
|
|
34
|
+
process.stdin.setRawMode(false);
|
|
35
|
+
}
|
|
36
|
+
process.stdin.pause();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Add key handler
|
|
40
|
+
*/
|
|
41
|
+
onKey(handler) {
|
|
42
|
+
this.handlers.push(handler);
|
|
43
|
+
return () => {
|
|
44
|
+
const index = this.handlers.indexOf(handler);
|
|
45
|
+
if (index !== -1) {
|
|
46
|
+
this.handlers.splice(index, 1);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Emit key event to all handlers
|
|
52
|
+
*/
|
|
53
|
+
emit(event) {
|
|
54
|
+
for (const handler of this.handlers) {
|
|
55
|
+
handler(event);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Parse raw input into KeyEvent
|
|
60
|
+
*/
|
|
61
|
+
parseKey(data) {
|
|
62
|
+
const event = {
|
|
63
|
+
key: '',
|
|
64
|
+
ctrl: false,
|
|
65
|
+
alt: false,
|
|
66
|
+
shift: false,
|
|
67
|
+
raw: data,
|
|
68
|
+
isPaste: false,
|
|
69
|
+
};
|
|
70
|
+
// Check for mouse scroll events (SGR format: \x1b[<button;x;yM or \x1b[<button;x;ym)
|
|
71
|
+
// Button 64 = scroll up, Button 65 = scroll down
|
|
72
|
+
const mouseMatch = data.match(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/);
|
|
73
|
+
if (mouseMatch) {
|
|
74
|
+
const button = parseInt(mouseMatch[1], 10);
|
|
75
|
+
// const x = parseInt(mouseMatch[2], 10);
|
|
76
|
+
// const y = parseInt(mouseMatch[3], 10);
|
|
77
|
+
// const release = mouseMatch[4] === 'm';
|
|
78
|
+
if (button === 64) {
|
|
79
|
+
// Scroll up
|
|
80
|
+
event.key = 'scrollup';
|
|
81
|
+
return event;
|
|
82
|
+
}
|
|
83
|
+
else if (button === 65) {
|
|
84
|
+
// Scroll down
|
|
85
|
+
event.key = 'scrolldown';
|
|
86
|
+
return event;
|
|
87
|
+
}
|
|
88
|
+
// Ignore other mouse events (clicks, etc.)
|
|
89
|
+
event.key = 'mouse';
|
|
90
|
+
return event;
|
|
91
|
+
}
|
|
92
|
+
// Detect paste: multiple printable characters at once (not escape sequences)
|
|
93
|
+
if (data.length > 1 && !data.startsWith('\x1b')) {
|
|
94
|
+
// Check if it's all printable characters (paste event)
|
|
95
|
+
const isPrintable = /^[\x20-\x7E\n\r\t]+$/.test(data) ||
|
|
96
|
+
data.split('').every(c => c.charCodeAt(0) >= 32 || c === '\n' || c === '\r' || c === '\t');
|
|
97
|
+
if (isPrintable) {
|
|
98
|
+
event.key = data;
|
|
99
|
+
event.isPaste = true;
|
|
100
|
+
return event;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Ctrl+C
|
|
104
|
+
if (data === '\x03') {
|
|
105
|
+
event.key = 'c';
|
|
106
|
+
event.ctrl = true;
|
|
107
|
+
return event;
|
|
108
|
+
}
|
|
109
|
+
// Ctrl+D
|
|
110
|
+
if (data === '\x04') {
|
|
111
|
+
event.key = 'd';
|
|
112
|
+
event.ctrl = true;
|
|
113
|
+
return event;
|
|
114
|
+
}
|
|
115
|
+
// Ctrl+L
|
|
116
|
+
if (data === '\x0c') {
|
|
117
|
+
event.key = 'l';
|
|
118
|
+
event.ctrl = true;
|
|
119
|
+
return event;
|
|
120
|
+
}
|
|
121
|
+
// Ctrl+V (paste)
|
|
122
|
+
if (data === '\x16') {
|
|
123
|
+
event.key = 'v';
|
|
124
|
+
event.ctrl = true;
|
|
125
|
+
return event;
|
|
126
|
+
}
|
|
127
|
+
// Ctrl+A (go to beginning)
|
|
128
|
+
if (data === '\x01') {
|
|
129
|
+
event.key = 'a';
|
|
130
|
+
event.ctrl = true;
|
|
131
|
+
return event;
|
|
132
|
+
}
|
|
133
|
+
// Ctrl+E (go to end)
|
|
134
|
+
if (data === '\x05') {
|
|
135
|
+
event.key = 'e';
|
|
136
|
+
event.ctrl = true;
|
|
137
|
+
return event;
|
|
138
|
+
}
|
|
139
|
+
// Ctrl+U (clear line)
|
|
140
|
+
if (data === '\x15') {
|
|
141
|
+
event.key = 'u';
|
|
142
|
+
event.ctrl = true;
|
|
143
|
+
return event;
|
|
144
|
+
}
|
|
145
|
+
// Ctrl+W (delete word)
|
|
146
|
+
if (data === '\x17') {
|
|
147
|
+
event.key = 'w';
|
|
148
|
+
event.ctrl = true;
|
|
149
|
+
return event;
|
|
150
|
+
}
|
|
151
|
+
// Ctrl+K (delete to end of line)
|
|
152
|
+
if (data === '\x0b') {
|
|
153
|
+
event.key = 'k';
|
|
154
|
+
event.ctrl = true;
|
|
155
|
+
return event;
|
|
156
|
+
}
|
|
157
|
+
// Enter
|
|
158
|
+
if (data === '\r' || data === '\n') {
|
|
159
|
+
event.key = 'enter';
|
|
160
|
+
return event;
|
|
161
|
+
}
|
|
162
|
+
// Backspace
|
|
163
|
+
if (data === '\x7f' || data === '\b') {
|
|
164
|
+
event.key = 'backspace';
|
|
165
|
+
return event;
|
|
166
|
+
}
|
|
167
|
+
// Escape
|
|
168
|
+
if (data === '\x1b') {
|
|
169
|
+
event.key = 'escape';
|
|
170
|
+
return event;
|
|
171
|
+
}
|
|
172
|
+
// Tab
|
|
173
|
+
if (data === '\t') {
|
|
174
|
+
event.key = 'tab';
|
|
175
|
+
return event;
|
|
176
|
+
}
|
|
177
|
+
// Arrow keys and other escape sequences
|
|
178
|
+
if (data.startsWith('\x1b[')) {
|
|
179
|
+
const seq = data.slice(2);
|
|
180
|
+
switch (seq) {
|
|
181
|
+
case 'A':
|
|
182
|
+
event.key = 'up';
|
|
183
|
+
break;
|
|
184
|
+
case 'B':
|
|
185
|
+
event.key = 'down';
|
|
186
|
+
break;
|
|
187
|
+
case 'C':
|
|
188
|
+
event.key = 'right';
|
|
189
|
+
break;
|
|
190
|
+
case 'D':
|
|
191
|
+
event.key = 'left';
|
|
192
|
+
break;
|
|
193
|
+
case 'H':
|
|
194
|
+
event.key = 'home';
|
|
195
|
+
break;
|
|
196
|
+
case 'F':
|
|
197
|
+
event.key = 'end';
|
|
198
|
+
break;
|
|
199
|
+
case '3~':
|
|
200
|
+
event.key = 'delete';
|
|
201
|
+
break;
|
|
202
|
+
case '5~':
|
|
203
|
+
event.key = 'pageup';
|
|
204
|
+
break;
|
|
205
|
+
case '6~':
|
|
206
|
+
event.key = 'pagedown';
|
|
207
|
+
break;
|
|
208
|
+
default:
|
|
209
|
+
event.key = 'unknown';
|
|
210
|
+
}
|
|
211
|
+
return event;
|
|
212
|
+
}
|
|
213
|
+
// Alt+key (ESC followed by character)
|
|
214
|
+
if (data.startsWith('\x1b') && data.length === 2) {
|
|
215
|
+
event.key = data[1];
|
|
216
|
+
event.alt = true;
|
|
217
|
+
return event;
|
|
218
|
+
}
|
|
219
|
+
// Ctrl+letter (0x01-0x1a maps to a-z)
|
|
220
|
+
const code = data.charCodeAt(0);
|
|
221
|
+
if (code >= 1 && code <= 26) {
|
|
222
|
+
event.key = String.fromCharCode(code + 96); // 1 -> 'a', etc.
|
|
223
|
+
event.ctrl = true;
|
|
224
|
+
return event;
|
|
225
|
+
}
|
|
226
|
+
// Regular character
|
|
227
|
+
event.key = data;
|
|
228
|
+
return event;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Simple line editor with cursor support
|
|
233
|
+
*/
|
|
234
|
+
export class LineEditor {
|
|
235
|
+
value = '';
|
|
236
|
+
cursorPos = 0;
|
|
237
|
+
history = [];
|
|
238
|
+
historyIndex = -1;
|
|
239
|
+
tempValue = '';
|
|
240
|
+
getValue() {
|
|
241
|
+
return this.value;
|
|
242
|
+
}
|
|
243
|
+
getCursorPos() {
|
|
244
|
+
return this.cursorPos;
|
|
245
|
+
}
|
|
246
|
+
setValue(value) {
|
|
247
|
+
this.value = value;
|
|
248
|
+
this.cursorPos = value.length;
|
|
249
|
+
}
|
|
250
|
+
clear() {
|
|
251
|
+
this.value = '';
|
|
252
|
+
this.cursorPos = 0;
|
|
253
|
+
this.historyIndex = -1;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Insert text at cursor position
|
|
257
|
+
*/
|
|
258
|
+
insert(text) {
|
|
259
|
+
this.value = this.value.slice(0, this.cursorPos) + text + this.value.slice(this.cursorPos);
|
|
260
|
+
this.cursorPos += text.length;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Set cursor position
|
|
264
|
+
*/
|
|
265
|
+
setCursorPos(pos) {
|
|
266
|
+
this.cursorPos = Math.max(0, Math.min(pos, this.value.length));
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Delete word backward (Ctrl+W)
|
|
270
|
+
*/
|
|
271
|
+
deleteWordBackward() {
|
|
272
|
+
if (this.cursorPos === 0)
|
|
273
|
+
return;
|
|
274
|
+
const beforeCursor = this.value.slice(0, this.cursorPos);
|
|
275
|
+
const afterCursor = this.value.slice(this.cursorPos);
|
|
276
|
+
// Find last word boundary (skip trailing spaces, then find space)
|
|
277
|
+
let i = beforeCursor.length - 1;
|
|
278
|
+
while (i >= 0 && beforeCursor[i] === ' ')
|
|
279
|
+
i--;
|
|
280
|
+
while (i >= 0 && beforeCursor[i] !== ' ')
|
|
281
|
+
i--;
|
|
282
|
+
const newBefore = beforeCursor.slice(0, i + 1);
|
|
283
|
+
this.value = newBefore + afterCursor;
|
|
284
|
+
this.cursorPos = newBefore.length;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Delete to end of line (Ctrl+K)
|
|
288
|
+
*/
|
|
289
|
+
deleteToEnd() {
|
|
290
|
+
this.value = this.value.slice(0, this.cursorPos);
|
|
291
|
+
}
|
|
292
|
+
addToHistory(value) {
|
|
293
|
+
if (value.trim()) {
|
|
294
|
+
this.history.push(value);
|
|
295
|
+
// Keep last 100 entries
|
|
296
|
+
if (this.history.length > 100) {
|
|
297
|
+
this.history.shift();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
this.historyIndex = -1;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Handle key event, returns true if value changed
|
|
304
|
+
*/
|
|
305
|
+
handleKey(event) {
|
|
306
|
+
const oldValue = this.value;
|
|
307
|
+
const oldCursor = this.cursorPos;
|
|
308
|
+
switch (event.key) {
|
|
309
|
+
case 'backspace':
|
|
310
|
+
if (this.cursorPos > 0) {
|
|
311
|
+
this.value = this.value.slice(0, this.cursorPos - 1) + this.value.slice(this.cursorPos);
|
|
312
|
+
this.cursorPos--;
|
|
313
|
+
}
|
|
314
|
+
break;
|
|
315
|
+
case 'delete':
|
|
316
|
+
if (this.cursorPos < this.value.length) {
|
|
317
|
+
this.value = this.value.slice(0, this.cursorPos) + this.value.slice(this.cursorPos + 1);
|
|
318
|
+
}
|
|
319
|
+
break;
|
|
320
|
+
case 'left':
|
|
321
|
+
if (this.cursorPos > 0) {
|
|
322
|
+
this.cursorPos--;
|
|
323
|
+
}
|
|
324
|
+
break;
|
|
325
|
+
case 'right':
|
|
326
|
+
if (this.cursorPos < this.value.length) {
|
|
327
|
+
this.cursorPos++;
|
|
328
|
+
}
|
|
329
|
+
break;
|
|
330
|
+
case 'home':
|
|
331
|
+
this.cursorPos = 0;
|
|
332
|
+
break;
|
|
333
|
+
case 'end':
|
|
334
|
+
this.cursorPos = this.value.length;
|
|
335
|
+
break;
|
|
336
|
+
case 'up':
|
|
337
|
+
if (this.history.length > 0) {
|
|
338
|
+
if (this.historyIndex === -1) {
|
|
339
|
+
this.tempValue = this.value;
|
|
340
|
+
this.historyIndex = this.history.length - 1;
|
|
341
|
+
}
|
|
342
|
+
else if (this.historyIndex > 0) {
|
|
343
|
+
this.historyIndex--;
|
|
344
|
+
}
|
|
345
|
+
this.value = this.history[this.historyIndex];
|
|
346
|
+
this.cursorPos = this.value.length;
|
|
347
|
+
}
|
|
348
|
+
break;
|
|
349
|
+
case 'down':
|
|
350
|
+
if (this.historyIndex !== -1) {
|
|
351
|
+
if (this.historyIndex < this.history.length - 1) {
|
|
352
|
+
this.historyIndex++;
|
|
353
|
+
this.value = this.history[this.historyIndex];
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
this.historyIndex = -1;
|
|
357
|
+
this.value = this.tempValue;
|
|
358
|
+
}
|
|
359
|
+
this.cursorPos = this.value.length;
|
|
360
|
+
}
|
|
361
|
+
break;
|
|
362
|
+
default:
|
|
363
|
+
// Regular character (single char, not control)
|
|
364
|
+
if (event.key.length === 1 && !event.ctrl && !event.alt) {
|
|
365
|
+
this.value = this.value.slice(0, this.cursorPos) + event.key + this.value.slice(this.cursorPos);
|
|
366
|
+
this.cursorPos++;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return this.value !== oldValue || this.cursorPos !== oldCursor;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screen buffer with diff-based rendering
|
|
3
|
+
* Only writes changes to terminal - minimizes flickering
|
|
4
|
+
*/
|
|
5
|
+
export interface Cell {
|
|
6
|
+
char: string;
|
|
7
|
+
style: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class Screen {
|
|
10
|
+
private width;
|
|
11
|
+
private height;
|
|
12
|
+
private buffer;
|
|
13
|
+
private rendered;
|
|
14
|
+
private cursorX;
|
|
15
|
+
private cursorY;
|
|
16
|
+
private cursorVisible;
|
|
17
|
+
constructor();
|
|
18
|
+
private createEmptyBuffer;
|
|
19
|
+
/**
|
|
20
|
+
* Get terminal dimensions
|
|
21
|
+
*/
|
|
22
|
+
getSize(): {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Clear the buffer
|
|
28
|
+
*/
|
|
29
|
+
clear(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Write text at position
|
|
32
|
+
*/
|
|
33
|
+
write(x: number, y: number, text: string, textStyle?: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Write a line, clearing rest of line
|
|
36
|
+
*/
|
|
37
|
+
writeLine(y: number, text: string, textStyle?: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Write raw line with pre-formatted ANSI codes (for syntax highlighted content)
|
|
40
|
+
* This writes directly without parsing for styles since the text already contains ANSI escapes
|
|
41
|
+
*/
|
|
42
|
+
writeRaw(y: number, text: string, prefixStyle?: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Write multiple lines starting at y
|
|
45
|
+
*/
|
|
46
|
+
writeLines(startY: number, lines: string[], textStyle?: string): number;
|
|
47
|
+
/**
|
|
48
|
+
* Write text with word wrapping
|
|
49
|
+
*/
|
|
50
|
+
writeWrapped(x: number, y: number, text: string, maxWidth: number, textStyle?: string): number;
|
|
51
|
+
/**
|
|
52
|
+
* Draw a horizontal line
|
|
53
|
+
*/
|
|
54
|
+
horizontalLine(y: number, char?: string, textStyle?: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Set cursor position for input
|
|
57
|
+
*/
|
|
58
|
+
setCursor(x: number, y: number): void;
|
|
59
|
+
/**
|
|
60
|
+
* Show/hide cursor
|
|
61
|
+
*/
|
|
62
|
+
showCursor(visible: boolean): void;
|
|
63
|
+
/**
|
|
64
|
+
* Render only changed cells (diff render)
|
|
65
|
+
*/
|
|
66
|
+
render(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Full render (no diff, redraw everything)
|
|
69
|
+
*/
|
|
70
|
+
fullRender(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Initialize screen (hide cursor, clear)
|
|
73
|
+
*/
|
|
74
|
+
init(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Cleanup (show cursor, clear)
|
|
77
|
+
*/
|
|
78
|
+
cleanup(): void;
|
|
79
|
+
}
|