codeep 1.2.17 → 1.2.18

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 (62) hide show
  1. package/README.md +20 -7
  2. package/dist/api/index.d.ts +7 -0
  3. package/dist/api/index.js +21 -17
  4. package/dist/renderer/App.d.ts +1 -5
  5. package/dist/renderer/App.js +106 -486
  6. package/dist/renderer/agentExecution.d.ts +36 -0
  7. package/dist/renderer/agentExecution.js +394 -0
  8. package/dist/renderer/commands.d.ts +16 -0
  9. package/dist/renderer/commands.js +838 -0
  10. package/dist/renderer/handlers.d.ts +87 -0
  11. package/dist/renderer/handlers.js +260 -0
  12. package/dist/renderer/highlight.d.ts +18 -0
  13. package/dist/renderer/highlight.js +130 -0
  14. package/dist/renderer/main.d.ts +4 -2
  15. package/dist/renderer/main.js +103 -1550
  16. package/dist/utils/agent.d.ts +5 -15
  17. package/dist/utils/agent.js +9 -693
  18. package/dist/utils/agentChat.d.ts +46 -0
  19. package/dist/utils/agentChat.js +343 -0
  20. package/dist/utils/agentStream.d.ts +23 -0
  21. package/dist/utils/agentStream.js +216 -0
  22. package/dist/utils/keychain.js +3 -2
  23. package/dist/utils/learning.js +9 -3
  24. package/dist/utils/mcpIntegration.d.ts +61 -0
  25. package/dist/utils/mcpIntegration.js +154 -0
  26. package/dist/utils/project.js +8 -3
  27. package/dist/utils/skills.js +21 -11
  28. package/dist/utils/smartContext.d.ts +4 -0
  29. package/dist/utils/smartContext.js +51 -14
  30. package/dist/utils/toolExecution.d.ts +27 -0
  31. package/dist/utils/toolExecution.js +525 -0
  32. package/dist/utils/toolParsing.d.ts +18 -0
  33. package/dist/utils/toolParsing.js +302 -0
  34. package/dist/utils/tools.d.ts +11 -24
  35. package/dist/utils/tools.js +22 -1187
  36. package/package.json +3 -1
  37. package/dist/config/config.test.d.ts +0 -1
  38. package/dist/config/config.test.js +0 -157
  39. package/dist/config/providers.test.d.ts +0 -1
  40. package/dist/config/providers.test.js +0 -187
  41. package/dist/hooks/index.d.ts +0 -4
  42. package/dist/hooks/index.js +0 -4
  43. package/dist/hooks/useAgent.d.ts +0 -29
  44. package/dist/hooks/useAgent.js +0 -148
  45. package/dist/utils/agent.test.d.ts +0 -1
  46. package/dist/utils/agent.test.js +0 -315
  47. package/dist/utils/git.test.d.ts +0 -1
  48. package/dist/utils/git.test.js +0 -193
  49. package/dist/utils/gitignore.test.d.ts +0 -1
  50. package/dist/utils/gitignore.test.js +0 -167
  51. package/dist/utils/project.test.d.ts +0 -1
  52. package/dist/utils/project.test.js +0 -212
  53. package/dist/utils/ratelimit.test.d.ts +0 -1
  54. package/dist/utils/ratelimit.test.js +0 -131
  55. package/dist/utils/retry.test.d.ts +0 -1
  56. package/dist/utils/retry.test.js +0 -163
  57. package/dist/utils/smartContext.test.d.ts +0 -1
  58. package/dist/utils/smartContext.test.js +0 -382
  59. package/dist/utils/tools.test.d.ts +0 -1
  60. package/dist/utils/tools.test.js +0 -681
  61. package/dist/utils/validation.test.d.ts +0 -1
  62. package/dist/utils/validation.test.js +0 -164
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Key event handlers for inline UI panels.
3
+ *
4
+ * Each handler receives a context object that exposes only the state slices
5
+ * and callbacks it needs, keeping the handlers decoupled from App internals.
6
+ */
7
+ import { KeyEvent } from './Input';
8
+ import { SelectItem } from './components/SelectScreen';
9
+ import { ConfirmOptions } from './App';
10
+ export interface StatusHandlerContext {
11
+ close(): void;
12
+ render(): void;
13
+ }
14
+ export declare function handleInlineStatusKey(event: KeyEvent, ctx: StatusHandlerContext): void;
15
+ export interface HelpHandlerContext {
16
+ scrollIndex: number;
17
+ setScrollIndex(v: number): void;
18
+ close(): void;
19
+ render(): void;
20
+ }
21
+ export declare function handleInlineHelpKey(event: KeyEvent, ctx: HelpHandlerContext): void;
22
+ export interface MenuHandlerContext {
23
+ index: number;
24
+ items: SelectItem[];
25
+ setIndex(v: number): void;
26
+ close(callback: ((item: SelectItem) => void) | null, selected: SelectItem | null): void;
27
+ render(): void;
28
+ }
29
+ export declare function handleMenuKey(event: KeyEvent, ctx: MenuHandlerContext): void;
30
+ declare const PERMISSION_OPTIONS: readonly ["read", "write", "none"];
31
+ type PermissionLevel = typeof PERMISSION_OPTIONS[number];
32
+ export interface PermissionHandlerContext {
33
+ index: number;
34
+ setIndex(v: number): void;
35
+ close(level: PermissionLevel): void;
36
+ render(): void;
37
+ }
38
+ export declare function handleInlinePermissionKey(event: KeyEvent, ctx: PermissionHandlerContext): void;
39
+ export interface SessionItem {
40
+ name: string;
41
+ messageCount: number;
42
+ createdAt: string;
43
+ }
44
+ export interface SessionPickerHandlerContext {
45
+ index: number;
46
+ items: SessionItem[];
47
+ deleteMode: boolean;
48
+ hasDeleteCallback: boolean;
49
+ setIndex(v: number): void;
50
+ setItems(items: SessionItem[]): void;
51
+ setDeleteMode(v: boolean): void;
52
+ close(sessionName: string | null): void;
53
+ onDelete(sessionName: string): void;
54
+ notify(msg: string): void;
55
+ render(): void;
56
+ }
57
+ export declare function handleInlineSessionPickerKey(event: KeyEvent, ctx: SessionPickerHandlerContext): void;
58
+ export interface ConfirmHandlerContext {
59
+ options: ConfirmOptions;
60
+ selection: 'yes' | 'no';
61
+ setSelection(v: 'yes' | 'no'): void;
62
+ close(confirmed: boolean): void;
63
+ render(): void;
64
+ }
65
+ export declare function handleInlineConfirmKey(event: KeyEvent, ctx: ConfirmHandlerContext): void;
66
+ export interface LoginProvider {
67
+ id: string;
68
+ name: string;
69
+ subscribeUrl?: string;
70
+ }
71
+ export interface LoginHandlerContext {
72
+ step: 'provider' | 'apikey';
73
+ providerIndex: number;
74
+ providers: LoginProvider[];
75
+ apiKey: string;
76
+ setStep(v: 'provider' | 'apikey'): void;
77
+ setProviderIndex(v: number): void;
78
+ setApiKey(v: string): void;
79
+ setError(msg: string): void;
80
+ close(result: {
81
+ providerId: string;
82
+ apiKey: string;
83
+ } | null): void;
84
+ render(): void;
85
+ }
86
+ export declare function handleLoginKey(event: KeyEvent, ctx: LoginHandlerContext): void;
87
+ export {};
@@ -0,0 +1,260 @@
1
+ /**
2
+ * Key event handlers for inline UI panels.
3
+ *
4
+ * Each handler receives a context object that exposes only the state slices
5
+ * and callbacks it needs, keeping the handlers decoupled from App internals.
6
+ */
7
+ import { helpCategories, keyboardShortcuts } from './components/Help.js';
8
+ import { spawn } from 'child_process';
9
+ import clipboardy from 'clipboardy';
10
+ export function handleInlineStatusKey(event, ctx) {
11
+ if (event.key === 'escape' || event.key === 'q') {
12
+ ctx.close();
13
+ ctx.render();
14
+ }
15
+ }
16
+ export function handleInlineHelpKey(event, ctx) {
17
+ if (event.key === 'escape' || event.key === 'q') {
18
+ ctx.close();
19
+ ctx.render();
20
+ return;
21
+ }
22
+ let totalItems = 0;
23
+ for (const cat of helpCategories) {
24
+ totalItems += 1 + cat.items.length;
25
+ }
26
+ totalItems += 1 + keyboardShortcuts.length;
27
+ if (event.key === 'down') {
28
+ ctx.setScrollIndex(Math.min(ctx.scrollIndex + 1, Math.max(0, totalItems - 5)));
29
+ ctx.render();
30
+ }
31
+ else if (event.key === 'up') {
32
+ ctx.setScrollIndex(Math.max(0, ctx.scrollIndex - 1));
33
+ ctx.render();
34
+ }
35
+ else if (event.key === 'pagedown') {
36
+ ctx.setScrollIndex(Math.min(ctx.scrollIndex + 5, Math.max(0, totalItems - 5)));
37
+ ctx.render();
38
+ }
39
+ else if (event.key === 'pageup') {
40
+ ctx.setScrollIndex(Math.max(0, ctx.scrollIndex - 5));
41
+ ctx.render();
42
+ }
43
+ }
44
+ export function handleMenuKey(event, ctx) {
45
+ if (event.key === 'escape') {
46
+ ctx.close(null, null);
47
+ ctx.render();
48
+ return;
49
+ }
50
+ if (event.key === 'up') {
51
+ ctx.setIndex(Math.max(0, ctx.index - 1));
52
+ ctx.render();
53
+ return;
54
+ }
55
+ if (event.key === 'down') {
56
+ ctx.setIndex(Math.min(ctx.items.length - 1, ctx.index + 1));
57
+ ctx.render();
58
+ return;
59
+ }
60
+ if (event.key === 'pageup') {
61
+ ctx.setIndex(Math.max(0, ctx.index - 5));
62
+ ctx.render();
63
+ return;
64
+ }
65
+ if (event.key === 'pagedown') {
66
+ ctx.setIndex(Math.min(ctx.items.length - 1, ctx.index + 5));
67
+ ctx.render();
68
+ return;
69
+ }
70
+ if (event.key === 'enter') {
71
+ const selected = ctx.items[ctx.index];
72
+ ctx.close(null, selected);
73
+ ctx.render();
74
+ }
75
+ }
76
+ // ─── Permission ──────────────────────────────────────────────────────────────
77
+ const PERMISSION_OPTIONS = ['read', 'write', 'none'];
78
+ export function handleInlinePermissionKey(event, ctx) {
79
+ if (event.key === 'escape') {
80
+ ctx.close('none');
81
+ ctx.render();
82
+ return;
83
+ }
84
+ if (event.key === 'up') {
85
+ ctx.setIndex(Math.max(0, ctx.index - 1));
86
+ ctx.render();
87
+ return;
88
+ }
89
+ if (event.key === 'down') {
90
+ ctx.setIndex(Math.min(PERMISSION_OPTIONS.length - 1, ctx.index + 1));
91
+ ctx.render();
92
+ return;
93
+ }
94
+ if (event.key === 'enter') {
95
+ ctx.close(PERMISSION_OPTIONS[ctx.index]);
96
+ ctx.render();
97
+ }
98
+ }
99
+ export function handleInlineSessionPickerKey(event, ctx) {
100
+ if (event.key === 'n' && !ctx.deleteMode) {
101
+ ctx.close(null);
102
+ ctx.render();
103
+ return;
104
+ }
105
+ if (event.key === 'd' && ctx.hasDeleteCallback && ctx.items.length > 0) {
106
+ ctx.setDeleteMode(!ctx.deleteMode);
107
+ ctx.render();
108
+ return;
109
+ }
110
+ if (event.key === 'escape') {
111
+ if (ctx.deleteMode) {
112
+ ctx.setDeleteMode(false);
113
+ ctx.render();
114
+ return;
115
+ }
116
+ ctx.close(null);
117
+ ctx.render();
118
+ return;
119
+ }
120
+ if (event.key === 'up') {
121
+ ctx.setIndex(Math.max(0, ctx.index - 1));
122
+ ctx.render();
123
+ return;
124
+ }
125
+ if (event.key === 'down') {
126
+ ctx.setIndex(Math.min(ctx.items.length - 1, ctx.index + 1));
127
+ ctx.render();
128
+ return;
129
+ }
130
+ if (event.key === 'enter' && ctx.items.length > 0) {
131
+ const selected = ctx.items[ctx.index];
132
+ if (ctx.deleteMode) {
133
+ ctx.onDelete(selected.name);
134
+ const newItems = ctx.items.filter(s => s.name !== selected.name);
135
+ ctx.setItems(newItems);
136
+ ctx.setIndex(Math.min(ctx.index, Math.max(0, newItems.length - 1)));
137
+ if (newItems.length === 0)
138
+ ctx.setDeleteMode(false);
139
+ ctx.notify(`Deleted: ${selected.name}`);
140
+ ctx.render();
141
+ return;
142
+ }
143
+ ctx.close(selected.name);
144
+ ctx.render();
145
+ }
146
+ }
147
+ export function handleInlineConfirmKey(event, ctx) {
148
+ if (event.key === 'escape') {
149
+ ctx.close(false);
150
+ ctx.render();
151
+ return;
152
+ }
153
+ if (event.key === 'left' || event.key === 'right' || event.key === 'tab') {
154
+ ctx.setSelection(ctx.selection === 'yes' ? 'no' : 'yes');
155
+ ctx.render();
156
+ return;
157
+ }
158
+ if (event.key === 'y') {
159
+ ctx.setSelection('yes');
160
+ ctx.render();
161
+ return;
162
+ }
163
+ if (event.key === 'n') {
164
+ ctx.setSelection('no');
165
+ ctx.render();
166
+ return;
167
+ }
168
+ if (event.key === 'enter') {
169
+ ctx.close(ctx.selection === 'yes');
170
+ ctx.render();
171
+ }
172
+ }
173
+ export function handleLoginKey(event, ctx) {
174
+ if (ctx.step === 'provider') {
175
+ if (event.key === 'escape') {
176
+ ctx.close(null);
177
+ ctx.render();
178
+ return;
179
+ }
180
+ if (event.key === 'up') {
181
+ ctx.setProviderIndex(Math.max(0, ctx.providerIndex - 1));
182
+ ctx.render();
183
+ return;
184
+ }
185
+ if (event.key === 'down') {
186
+ ctx.setProviderIndex(Math.min(ctx.providers.length - 1, ctx.providerIndex + 1));
187
+ ctx.render();
188
+ return;
189
+ }
190
+ if (event.key === 'enter') {
191
+ ctx.setStep('apikey');
192
+ ctx.setApiKey('');
193
+ ctx.setError('');
194
+ ctx.render();
195
+ }
196
+ return;
197
+ }
198
+ // apikey step
199
+ if (event.key === 'escape') {
200
+ ctx.setStep('provider');
201
+ ctx.setApiKey('');
202
+ ctx.setError('');
203
+ ctx.render();
204
+ return;
205
+ }
206
+ if (event.key === 'enter') {
207
+ if (ctx.apiKey.length < 10) {
208
+ ctx.setError('API key too short (min 10 characters)');
209
+ ctx.render();
210
+ return;
211
+ }
212
+ ctx.close({ providerId: ctx.providers[ctx.providerIndex].id, apiKey: ctx.apiKey });
213
+ ctx.render();
214
+ return;
215
+ }
216
+ if (event.key === 'backspace') {
217
+ ctx.setApiKey(ctx.apiKey.slice(0, -1));
218
+ ctx.setError('');
219
+ ctx.render();
220
+ return;
221
+ }
222
+ if (event.ctrl && event.key === 'v') {
223
+ clipboardy.read().then(text => {
224
+ if (text) {
225
+ ctx.setApiKey(text.trim());
226
+ ctx.setError('');
227
+ ctx.render();
228
+ }
229
+ }).catch(() => {
230
+ ctx.setError('Could not read clipboard');
231
+ ctx.render();
232
+ });
233
+ return;
234
+ }
235
+ if (event.ctrl && event.key === 'b') {
236
+ const provider = ctx.providers[ctx.providerIndex];
237
+ if (provider.subscribeUrl) {
238
+ try {
239
+ const cmd = process.platform === 'darwin' ? 'open'
240
+ : process.platform === 'win32' ? 'start'
241
+ : 'xdg-open';
242
+ const child = spawn(cmd, [provider.subscribeUrl], { detached: true, stdio: 'ignore' });
243
+ child.unref();
244
+ }
245
+ catch { /* ignore */ }
246
+ }
247
+ return;
248
+ }
249
+ if (event.isPaste && event.key.length > 1) {
250
+ ctx.setApiKey(ctx.apiKey + event.key.trim());
251
+ ctx.setError('');
252
+ ctx.render();
253
+ return;
254
+ }
255
+ if (event.key.length === 1 && !event.ctrl) {
256
+ ctx.setApiKey(ctx.apiKey + event.key);
257
+ ctx.setError('');
258
+ ctx.render();
259
+ }
260
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Syntax highlighting for the terminal renderer.
3
+ * Supports 12+ languages with One Dark theme colors.
4
+ */
5
+ export declare const SYNTAX: {
6
+ keyword: string;
7
+ string: string;
8
+ number: string;
9
+ comment: string;
10
+ function: string;
11
+ type: string;
12
+ operator: string;
13
+ variable: string;
14
+ punctuation: string;
15
+ codeFrame: string;
16
+ codeLang: string;
17
+ };
18
+ export declare function highlightCode(code: string, lang: string): string;
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Syntax highlighting for the terminal renderer.
3
+ * Supports 12+ languages with One Dark theme colors.
4
+ */
5
+ import { fg } from './ansi.js';
6
+ export const SYNTAX = {
7
+ keyword: fg.rgb(198, 120, 221),
8
+ string: fg.rgb(152, 195, 121),
9
+ number: fg.rgb(209, 154, 102),
10
+ comment: fg.rgb(92, 99, 112),
11
+ function: fg.rgb(97, 175, 239),
12
+ type: fg.rgb(229, 192, 123),
13
+ operator: fg.rgb(86, 182, 194),
14
+ variable: fg.white,
15
+ punctuation: fg.gray,
16
+ codeFrame: fg.rgb(100, 105, 115),
17
+ codeLang: fg.rgb(150, 155, 165),
18
+ };
19
+ const KEYWORDS = {
20
+ js: ['const', 'let', 'var', 'function', 'return', 'if', 'else', 'for', 'while', 'do', 'switch', 'case', 'break', 'continue', 'try', 'catch', 'throw', 'finally', 'new', 'class', 'extends', 'import', 'export', 'from', 'default', 'async', 'await', 'yield', 'typeof', 'instanceof', 'in', 'of', 'delete', 'void', 'this', 'super', 'null', 'undefined', 'true', 'false', 'NaN', 'Infinity'],
21
+ ts: ['const', 'let', 'var', 'function', 'return', 'if', 'else', 'for', 'while', 'do', 'switch', 'case', 'break', 'continue', 'try', 'catch', 'throw', 'finally', 'new', 'class', 'extends', 'import', 'export', 'from', 'default', 'async', 'await', 'yield', 'typeof', 'instanceof', 'in', 'of', 'delete', 'void', 'this', 'super', 'null', 'undefined', 'true', 'false', 'type', 'interface', 'enum', 'namespace', 'module', 'declare', 'abstract', 'implements', 'private', 'public', 'protected', 'readonly', 'static', 'as', 'is', 'keyof', 'infer', 'never', 'unknown', 'any'],
22
+ py: ['def', 'class', 'return', 'if', 'elif', 'else', 'for', 'while', 'try', 'except', 'finally', 'raise', 'import', 'from', 'as', 'with', 'yield', 'lambda', 'pass', 'break', 'continue', 'and', 'or', 'not', 'in', 'is', 'None', 'True', 'False', 'global', 'nonlocal', 'assert', 'del', 'async', 'await'],
23
+ go: ['func', 'return', 'if', 'else', 'for', 'range', 'switch', 'case', 'break', 'continue', 'fallthrough', 'default', 'go', 'select', 'chan', 'defer', 'panic', 'recover', 'type', 'struct', 'interface', 'map', 'package', 'import', 'const', 'var', 'nil', 'true', 'false', 'iota', 'make', 'new', 'append', 'len', 'cap', 'copy', 'delete'],
24
+ rust: ['fn', 'let', 'mut', 'const', 'static', 'return', 'if', 'else', 'match', 'for', 'while', 'loop', 'break', 'continue', 'struct', 'enum', 'trait', 'impl', 'type', 'where', 'use', 'mod', 'pub', 'crate', 'self', 'super', 'async', 'await', 'move', 'ref', 'true', 'false', 'Some', 'None', 'Ok', 'Err', 'Self', 'dyn', 'unsafe', 'extern'],
25
+ sh: ['if', 'then', 'else', 'elif', 'fi', 'case', 'esac', 'for', 'while', 'until', 'do', 'done', 'in', 'function', 'return', 'local', 'export', 'readonly', 'declare', 'typeset', 'unset', 'shift', 'exit', 'break', 'continue', 'source', 'alias', 'echo', 'printf', 'read', 'test', 'true', 'false'],
26
+ html: ['html', 'head', 'body', 'div', 'span', 'p', 'a', 'img', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'table', 'tr', 'td', 'th', 'form', 'input', 'button', 'select', 'option', 'textarea', 'label', 'section', 'article', 'nav', 'header', 'footer', 'main', 'aside', 'meta', 'link', 'script', 'style', 'title', 'DOCTYPE'],
27
+ css: ['import', 'media', 'keyframes', 'font-face', 'supports', 'charset', 'namespace', 'page', 'inherit', 'initial', 'unset', 'none', 'auto', 'block', 'inline', 'flex', 'grid', 'absolute', 'relative', 'fixed', 'sticky', 'static', 'hidden', 'visible', 'solid', 'dashed', 'dotted', 'transparent', 'important'],
28
+ };
29
+ const LANG_ALIASES = {
30
+ javascript: 'js', typescript: 'ts', python: 'py', golang: 'go',
31
+ bash: 'sh', shell: 'sh', zsh: 'sh', tsx: 'ts', jsx: 'js',
32
+ htm: 'html', scss: 'css', sass: 'css', less: 'css',
33
+ };
34
+ export function highlightCode(code, lang) {
35
+ const normalizedLang = LANG_ALIASES[lang.toLowerCase()] || lang.toLowerCase();
36
+ const keywords = KEYWORDS[normalizedLang] || KEYWORDS['js'] || [];
37
+ if (normalizedLang === 'html' || normalizedLang === 'xml' || normalizedLang === 'svg') {
38
+ return code.replace(/(<\/?)(\w[\w-]*)((?:\s+[\w-]+(?:=(?:"[^"]*"|'[^']*'|\S+))?)*)(\s*\/?>)/g, (_match, open, tag, attrs, close) => {
39
+ const highlightedAttrs = attrs.replace(/([\w-]+)(=)("[^"]*"|'[^']*')/g, (_m, attr, eq, val) => SYNTAX.function + attr + '\x1b[0m' + SYNTAX.operator + eq + '\x1b[0m' + SYNTAX.string + val + '\x1b[0m');
40
+ return SYNTAX.punctuation + open + '\x1b[0m' + SYNTAX.keyword + tag + '\x1b[0m' + highlightedAttrs + SYNTAX.punctuation + close + '\x1b[0m';
41
+ }).replace(/<!--[\s\S]*?-->/g, (comment) => SYNTAX.comment + comment + '\x1b[0m');
42
+ }
43
+ if (normalizedLang === 'css') {
44
+ return code
45
+ .replace(/\/\*[\s\S]*?\*\//g, (comment) => SYNTAX.comment + comment + '\x1b[0m')
46
+ .replace(/([\w-]+)(\s*:\s*)([^;{}]+)/g, (_m, prop, colon, val) => SYNTAX.function + prop + '\x1b[0m' + colon + SYNTAX.string + val + '\x1b[0m')
47
+ .replace(/([.#]?[\w-]+(?:\s*[,>+~]\s*[.#]?[\w-]+)*)\s*\{/g, (match, selector) => SYNTAX.keyword + selector + '\x1b[0m' + ' {');
48
+ }
49
+ let result = '';
50
+ let i = 0;
51
+ while (i < code.length) {
52
+ if (code.slice(i, i + 2) === '//' || (normalizedLang === 'py' && code[i] === '#') ||
53
+ (normalizedLang === 'sh' && code[i] === '#')) {
54
+ let end = code.indexOf('\n', i);
55
+ if (end === -1)
56
+ end = code.length;
57
+ result += SYNTAX.comment + code.slice(i, end) + '\x1b[0m';
58
+ i = end;
59
+ continue;
60
+ }
61
+ if (code.slice(i, i + 2) === '/*') {
62
+ let end = code.indexOf('*/', i + 2);
63
+ if (end === -1)
64
+ end = code.length;
65
+ else
66
+ end += 2;
67
+ result += SYNTAX.comment + code.slice(i, end) + '\x1b[0m';
68
+ i = end;
69
+ continue;
70
+ }
71
+ if (code[i] === '"' || code[i] === "'" || code[i] === '`') {
72
+ const quote = code[i];
73
+ let end = i + 1;
74
+ while (end < code.length) {
75
+ if (code[end] === '\\') {
76
+ end += 2;
77
+ }
78
+ else if (code[end] === quote) {
79
+ end++;
80
+ break;
81
+ }
82
+ else {
83
+ end++;
84
+ }
85
+ }
86
+ result += SYNTAX.string + code.slice(i, end) + '\x1b[0m';
87
+ i = end;
88
+ continue;
89
+ }
90
+ const numMatch = code.slice(i).match(/^(0x[0-9a-fA-F]+|0b[01]+|0o[0-7]+|\d+\.?\d*(?:e[+-]?\d+)?)/);
91
+ if (numMatch && (i === 0 || !/[a-zA-Z_]/.test(code[i - 1]))) {
92
+ result += SYNTAX.number + numMatch[1] + '\x1b[0m';
93
+ i += numMatch[1].length;
94
+ continue;
95
+ }
96
+ const identMatch = code.slice(i).match(/^[a-zA-Z_][a-zA-Z0-9_]*/);
97
+ if (identMatch) {
98
+ const ident = identMatch[0];
99
+ const nextChar = code[i + ident.length];
100
+ if (keywords.includes(ident)) {
101
+ result += SYNTAX.keyword + ident + '\x1b[0m';
102
+ }
103
+ else if (nextChar === '(') {
104
+ result += SYNTAX.function + ident + '\x1b[0m';
105
+ }
106
+ else if (/^[A-Z]/.test(ident)) {
107
+ result += SYNTAX.type + ident + '\x1b[0m';
108
+ }
109
+ else {
110
+ result += ident;
111
+ }
112
+ i += ident.length;
113
+ continue;
114
+ }
115
+ const opMatch = code.slice(i).match(/^(===|!==|==|!=|<=|>=|=>|->|\+\+|--|&&|\|\||<<|>>|\+=|-=|\*=|\/=|[+\-*/%=<>!&|^~?:])/);
116
+ if (opMatch) {
117
+ result += SYNTAX.operator + opMatch[1] + '\x1b[0m';
118
+ i += opMatch[1].length;
119
+ continue;
120
+ }
121
+ if ('{}[]();,.'.includes(code[i])) {
122
+ result += SYNTAX.punctuation + code[i] + '\x1b[0m';
123
+ i++;
124
+ continue;
125
+ }
126
+ result += code[i];
127
+ i++;
128
+ }
129
+ return result;
130
+ }
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Codeep with Custom Renderer
4
- * Main entry point using the new ANSI-based renderer instead of Ink
3
+ * Codeep entry point.
4
+ *
5
+ * This file contains only startup/init logic. Command dispatch lives in
6
+ * commands.ts and agent execution in agentExecution.ts.
5
7
  */
6
8
  export {};