codeep 1.2.17 → 1.2.19

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 (64) 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/config/providers.d.ts +6 -0
  5. package/dist/config/providers.js +11 -0
  6. package/dist/renderer/App.d.ts +1 -5
  7. package/dist/renderer/App.js +106 -486
  8. package/dist/renderer/agentExecution.d.ts +36 -0
  9. package/dist/renderer/agentExecution.js +394 -0
  10. package/dist/renderer/commands.d.ts +16 -0
  11. package/dist/renderer/commands.js +838 -0
  12. package/dist/renderer/handlers.d.ts +87 -0
  13. package/dist/renderer/handlers.js +260 -0
  14. package/dist/renderer/highlight.d.ts +18 -0
  15. package/dist/renderer/highlight.js +130 -0
  16. package/dist/renderer/main.d.ts +4 -2
  17. package/dist/renderer/main.js +103 -1550
  18. package/dist/utils/agent.d.ts +5 -15
  19. package/dist/utils/agent.js +9 -693
  20. package/dist/utils/agentChat.d.ts +46 -0
  21. package/dist/utils/agentChat.js +343 -0
  22. package/dist/utils/agentStream.d.ts +23 -0
  23. package/dist/utils/agentStream.js +216 -0
  24. package/dist/utils/keychain.js +3 -2
  25. package/dist/utils/learning.js +9 -3
  26. package/dist/utils/mcpIntegration.d.ts +61 -0
  27. package/dist/utils/mcpIntegration.js +154 -0
  28. package/dist/utils/project.js +8 -3
  29. package/dist/utils/skills.js +21 -11
  30. package/dist/utils/smartContext.d.ts +4 -0
  31. package/dist/utils/smartContext.js +51 -14
  32. package/dist/utils/toolExecution.d.ts +27 -0
  33. package/dist/utils/toolExecution.js +525 -0
  34. package/dist/utils/toolParsing.d.ts +18 -0
  35. package/dist/utils/toolParsing.js +302 -0
  36. package/dist/utils/tools.d.ts +11 -24
  37. package/dist/utils/tools.js +22 -1187
  38. package/package.json +3 -1
  39. package/dist/config/config.test.d.ts +0 -1
  40. package/dist/config/config.test.js +0 -157
  41. package/dist/config/providers.test.d.ts +0 -1
  42. package/dist/config/providers.test.js +0 -187
  43. package/dist/hooks/index.d.ts +0 -4
  44. package/dist/hooks/index.js +0 -4
  45. package/dist/hooks/useAgent.d.ts +0 -29
  46. package/dist/hooks/useAgent.js +0 -148
  47. package/dist/utils/agent.test.d.ts +0 -1
  48. package/dist/utils/agent.test.js +0 -315
  49. package/dist/utils/git.test.d.ts +0 -1
  50. package/dist/utils/git.test.js +0 -193
  51. package/dist/utils/gitignore.test.d.ts +0 -1
  52. package/dist/utils/gitignore.test.js +0 -167
  53. package/dist/utils/project.test.d.ts +0 -1
  54. package/dist/utils/project.test.js +0 -212
  55. package/dist/utils/ratelimit.test.d.ts +0 -1
  56. package/dist/utils/ratelimit.test.js +0 -131
  57. package/dist/utils/retry.test.d.ts +0 -1
  58. package/dist/utils/retry.test.js +0 -163
  59. package/dist/utils/smartContext.test.d.ts +0 -1
  60. package/dist/utils/smartContext.test.js +0 -382
  61. package/dist/utils/tools.test.d.ts +0 -1
  62. package/dist/utils/tools.test.js +0 -681
  63. package/dist/utils/validation.test.d.ts +0 -1
  64. 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 {};