@redplanethq/corebrain 2.5.3 → 2.5.5

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 (55) hide show
  1. package/dist/cli.js +10 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/browser/close.js +4 -4
  4. package/dist/commands/browser/close.js.map +1 -1
  5. package/dist/commands/browser/command.js +4 -4
  6. package/dist/commands/browser/command.js.map +1 -1
  7. package/dist/commands/browser/create-session.d.ts +10 -0
  8. package/dist/commands/browser/create-session.d.ts.map +1 -0
  9. package/dist/commands/browser/create-session.js +36 -0
  10. package/dist/commands/browser/create-session.js.map +1 -0
  11. package/dist/commands/browser/delete-session.d.ts.map +1 -1
  12. package/dist/commands/browser/delete-session.js +20 -14
  13. package/dist/commands/browser/delete-session.js.map +1 -1
  14. package/dist/commands/browser/install.d.ts.map +1 -1
  15. package/dist/commands/browser/install.js +38 -36
  16. package/dist/commands/browser/install.js.map +1 -1
  17. package/dist/commands/browser/list-sessions.d.ts.map +1 -1
  18. package/dist/commands/browser/list-sessions.js +7 -15
  19. package/dist/commands/browser/list-sessions.js.map +1 -1
  20. package/dist/commands/browser/open-head.d.ts.map +1 -1
  21. package/dist/commands/browser/open-head.js +9 -15
  22. package/dist/commands/browser/open-head.js.map +1 -1
  23. package/dist/commands/browser/open.js +4 -4
  24. package/dist/commands/browser/open.js.map +1 -1
  25. package/dist/commands/browser/set-browser.d.ts +15 -0
  26. package/dist/commands/browser/set-browser.d.ts.map +1 -0
  27. package/dist/commands/browser/set-browser.js +111 -0
  28. package/dist/commands/browser/set-browser.js.map +1 -0
  29. package/dist/commands/browser/status.d.ts.map +1 -1
  30. package/dist/commands/browser/status.js +9 -8
  31. package/dist/commands/browser/status.js.map +1 -1
  32. package/dist/commands/coding/start.d.ts.map +1 -1
  33. package/dist/commands/coding/start.js.map +1 -1
  34. package/dist/commands/gateway/config.js +9 -9
  35. package/dist/commands/gateway/config.js.map +1 -1
  36. package/dist/server/gateway-client.js +2 -2
  37. package/dist/server/gateway-client.js.map +1 -1
  38. package/dist/server/tools/browser-tools.d.ts.map +1 -1
  39. package/dist/server/tools/browser-tools.js +14 -12
  40. package/dist/server/tools/browser-tools.js.map +1 -1
  41. package/dist/server/tools/coding-tools.d.ts +2 -1
  42. package/dist/server/tools/coding-tools.d.ts.map +1 -1
  43. package/dist/server/tools/coding-tools.js +19 -7
  44. package/dist/server/tools/coding-tools.js.map +1 -1
  45. package/dist/types/config.d.ts +7 -0
  46. package/dist/types/config.d.ts.map +1 -1
  47. package/dist/utils/agent-browser.d.ts +135 -0
  48. package/dist/utils/agent-browser.d.ts.map +1 -0
  49. package/dist/utils/agent-browser.js +549 -0
  50. package/dist/utils/agent-browser.js.map +1 -0
  51. package/dist/utils/coding-runner.d.ts +3 -1
  52. package/dist/utils/coding-runner.d.ts.map +1 -1
  53. package/dist/utils/coding-runner.js +35 -7
  54. package/dist/utils/coding-runner.js.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,549 @@
1
+ import { spawn, execSync } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import { getPreferences, updatePreferences } from '../config/preferences.js';
4
+ // Constants
5
+ const BINARY_NAME = 'agent-browser';
6
+ const MAX_SESSIONS = 5;
7
+ const DEFAULT_SESSIONS = ['corebrain', 'personal', 'work'];
8
+ // ============ Browser Executable Paths ============
9
+ // Known browser paths for auto-detection
10
+ const BRAVE_PATHS = {
11
+ darwin: [
12
+ '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser',
13
+ ],
14
+ linux: [
15
+ '/usr/bin/brave-browser',
16
+ '/usr/bin/brave',
17
+ '/snap/bin/brave',
18
+ ],
19
+ win32: [
20
+ 'C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
21
+ 'C:\\Program Files (x86)\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
22
+ ],
23
+ };
24
+ const CHROME_PATHS = {
25
+ darwin: [
26
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
27
+ ],
28
+ linux: [
29
+ '/usr/bin/google-chrome',
30
+ '/usr/bin/google-chrome-stable',
31
+ ],
32
+ win32: [
33
+ 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
34
+ 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
35
+ ],
36
+ };
37
+ // ============ Browser Config Management (stored in preferences.browser) ============
38
+ /**
39
+ * Get all configured session names from preferences
40
+ */
41
+ export function getConfiguredSessions() {
42
+ const prefs = getPreferences();
43
+ return prefs.browser?.sessions || [];
44
+ }
45
+ /**
46
+ * Check if a session name is configured
47
+ */
48
+ export function isSessionConfigured(name) {
49
+ const sessions = getConfiguredSessions();
50
+ return sessions.includes(name);
51
+ }
52
+ /**
53
+ * Create a new session (add to preferences.browser.sessions)
54
+ */
55
+ export function createSession(name) {
56
+ // Validate name
57
+ if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
58
+ return { success: false, error: 'Session name must contain only alphanumeric characters, hyphens, and underscores' };
59
+ }
60
+ const prefs = getPreferences();
61
+ const currentSessions = prefs.browser?.sessions || [];
62
+ if (currentSessions.includes(name)) {
63
+ return { success: false, error: `Session "${name}" already exists` };
64
+ }
65
+ if (currentSessions.length >= MAX_SESSIONS) {
66
+ return { success: false, error: `Maximum ${MAX_SESSIONS} sessions allowed. Current: ${currentSessions.join(', ')}` };
67
+ }
68
+ updatePreferences({
69
+ browser: {
70
+ ...prefs.browser,
71
+ sessions: [...currentSessions, name],
72
+ },
73
+ });
74
+ return { success: true };
75
+ }
76
+ /**
77
+ * Delete a session from preferences
78
+ */
79
+ export function deleteSession(name) {
80
+ const prefs = getPreferences();
81
+ const currentSessions = prefs.browser?.sessions || [];
82
+ if (!currentSessions.includes(name)) {
83
+ return { success: false, error: `Session "${name}" does not exist` };
84
+ }
85
+ updatePreferences({
86
+ browser: {
87
+ ...prefs.browser,
88
+ sessions: currentSessions.filter(s => s !== name),
89
+ },
90
+ });
91
+ return { success: true };
92
+ }
93
+ /**
94
+ * Initialize default sessions (called on install)
95
+ */
96
+ export function initializeDefaultSessions() {
97
+ const prefs = getPreferences();
98
+ const currentSessions = prefs.browser?.sessions || [];
99
+ // Only add defaults if no sessions exist
100
+ if (currentSessions.length === 0) {
101
+ updatePreferences({
102
+ browser: {
103
+ ...prefs.browser,
104
+ sessions: [...DEFAULT_SESSIONS],
105
+ },
106
+ });
107
+ }
108
+ }
109
+ // ============ Browser Executable Management ============
110
+ /**
111
+ * Auto-detect Brave browser path
112
+ */
113
+ export function detectBravePath() {
114
+ const platform = process.platform;
115
+ const paths = BRAVE_PATHS[platform] || [];
116
+ for (const p of paths) {
117
+ if (fs.existsSync(p)) {
118
+ return p;
119
+ }
120
+ }
121
+ return null;
122
+ }
123
+ /**
124
+ * Auto-detect Chrome browser path
125
+ */
126
+ export function detectChromePath() {
127
+ const platform = process.platform;
128
+ const paths = CHROME_PATHS[platform] || [];
129
+ for (const p of paths) {
130
+ if (fs.existsSync(p)) {
131
+ return p;
132
+ }
133
+ }
134
+ return null;
135
+ }
136
+ /**
137
+ * Detect all available browsers
138
+ */
139
+ export function detectAvailableBrowsers() {
140
+ const browsers = [];
141
+ const bravePath = detectBravePath();
142
+ if (bravePath) {
143
+ browsers.push({ type: 'brave', path: bravePath });
144
+ }
145
+ const chromePath = detectChromePath();
146
+ if (chromePath) {
147
+ browsers.push({ type: 'chrome', path: chromePath });
148
+ }
149
+ return browsers;
150
+ }
151
+ /**
152
+ * Get configured browser executable from preferences.browser
153
+ */
154
+ export function getBrowserExecutable() {
155
+ const prefs = getPreferences();
156
+ return {
157
+ type: prefs.browser?.browserType || 'default',
158
+ path: prefs.browser?.browserExecutable,
159
+ };
160
+ }
161
+ /**
162
+ * Set browser executable in preferences.browser
163
+ */
164
+ export function setBrowserExecutable(type, customPath) {
165
+ const prefs = getPreferences();
166
+ let browserExecutable;
167
+ if (type === 'default') {
168
+ // No executable path for default
169
+ browserExecutable = undefined;
170
+ }
171
+ else if (type === 'brave') {
172
+ const bravePath = detectBravePath();
173
+ if (!bravePath) {
174
+ return { success: false, error: 'Brave browser not found. Install it or use custom path.' };
175
+ }
176
+ browserExecutable = bravePath;
177
+ }
178
+ else if (type === 'chrome') {
179
+ const chromePath = detectChromePath();
180
+ if (!chromePath) {
181
+ return { success: false, error: 'Chrome browser not found. Install it or use custom path.' };
182
+ }
183
+ browserExecutable = chromePath;
184
+ }
185
+ else if (type === 'custom') {
186
+ if (!customPath) {
187
+ return { success: false, error: 'Custom path is required' };
188
+ }
189
+ if (!fs.existsSync(customPath)) {
190
+ return { success: false, error: `Browser not found at: ${customPath}` };
191
+ }
192
+ browserExecutable = customPath;
193
+ }
194
+ updatePreferences({
195
+ browser: {
196
+ ...prefs.browser,
197
+ browserType: type,
198
+ browserExecutable,
199
+ },
200
+ });
201
+ return { success: true };
202
+ }
203
+ // Blocked commands that cannot be run via browser_command
204
+ const BLOCKED_COMMANDS = [
205
+ 'open',
206
+ 'close',
207
+ 'cookies',
208
+ 'storage',
209
+ 'network',
210
+ 'download',
211
+ 'run',
212
+ 'session',
213
+ 'task',
214
+ 'tunnel',
215
+ 'state',
216
+ ];
217
+ // ============ Installation ============
218
+ /**
219
+ * Get the agent-browser binary path (cross-platform)
220
+ */
221
+ function getAgentBrowserPath() {
222
+ try {
223
+ const command = process.platform === 'win32'
224
+ ? `where ${BINARY_NAME}`
225
+ : `which ${BINARY_NAME}`;
226
+ const result = execSync(command, { stdio: 'pipe', encoding: 'utf-8' });
227
+ const binaryPath = result.trim().split('\n')[0]; // Take first result on Windows (where can return multiple)
228
+ return binaryPath || null;
229
+ }
230
+ catch {
231
+ return null;
232
+ }
233
+ }
234
+ // Cache the binary path
235
+ let cachedBinaryPath;
236
+ function getBinaryPath() {
237
+ if (cachedBinaryPath === undefined) {
238
+ cachedBinaryPath = getAgentBrowserPath();
239
+ }
240
+ return cachedBinaryPath;
241
+ }
242
+ // Clear cache (useful after installation)
243
+ export function clearBinaryPathCache() {
244
+ cachedBinaryPath = undefined;
245
+ }
246
+ export async function isAgentBrowserInstalled() {
247
+ return getBinaryPath() !== null;
248
+ }
249
+ /**
250
+ * Install agent-browser via npm
251
+ */
252
+ export async function installAgentBrowser() {
253
+ const result = await runShellCommand('npm install -g agent-browser');
254
+ // Clear cache so next check finds the newly installed binary
255
+ clearBinaryPathCache();
256
+ if (result.code === 0) {
257
+ // Initialize default sessions after successful installation
258
+ initializeDefaultSessions();
259
+ }
260
+ return result;
261
+ }
262
+ /**
263
+ * Run agent-browser doctor to validate installation
264
+ */
265
+ export async function runAgentBrowserDoctor() {
266
+ // agent-browser doesn't have a doctor command, so check version instead
267
+ return runAgentBrowserRawCommand(['--version']);
268
+ }
269
+ function runShellCommand(command) {
270
+ return new Promise(resolve => {
271
+ const proc = spawn(command, [], {
272
+ stdio: ['pipe', 'pipe', 'pipe'],
273
+ shell: true,
274
+ });
275
+ let stdout = '';
276
+ let stderr = '';
277
+ proc.stdout?.on('data', data => {
278
+ stdout += data.toString();
279
+ });
280
+ proc.stderr?.on('data', data => {
281
+ stderr += data.toString();
282
+ });
283
+ proc.on('close', code => {
284
+ resolve({ stdout, stderr, code: code ?? 0 });
285
+ });
286
+ proc.on('error', err => {
287
+ resolve({ stdout, stderr: err.message, code: 1 });
288
+ });
289
+ });
290
+ }
291
+ // ============ Core Browser Command Runner ============
292
+ /**
293
+ * Run a raw agent-browser command without session
294
+ */
295
+ async function runAgentBrowserRawCommand(args) {
296
+ const binaryPath = getBinaryPath();
297
+ if (!binaryPath) {
298
+ return {
299
+ stdout: '',
300
+ stderr: 'agent-browser not found. Run: corebrain browser install',
301
+ code: 1,
302
+ };
303
+ }
304
+ return new Promise(resolve => {
305
+ const proc = spawn(binaryPath, args, {
306
+ stdio: ['pipe', 'pipe', 'pipe'],
307
+ });
308
+ let stdout = '';
309
+ let stderr = '';
310
+ proc.stdout?.on('data', data => {
311
+ stdout += data.toString();
312
+ });
313
+ proc.stderr?.on('data', data => {
314
+ stderr += data.toString();
315
+ });
316
+ proc.on('close', code => {
317
+ resolve({ stdout, stderr, code: code ?? 0 });
318
+ });
319
+ proc.on('error', err => {
320
+ resolve({ stdout, stderr: err.message, code: 1 });
321
+ });
322
+ });
323
+ }
324
+ /**
325
+ * Run an agent-browser command with session
326
+ * agent-browser [--executable-path <path>] --session <name> --session-name <name> <command> <args>
327
+ */
328
+ async function runAgentBrowserCommand(sessionName, args) {
329
+ const fullArgs = [];
330
+ // Add executable path if configured (not default)
331
+ const browserConfig = getBrowserExecutable();
332
+ if (browserConfig.type !== 'default' && browserConfig.path) {
333
+ fullArgs.push('--executable-path', browserConfig.path);
334
+ }
335
+ // Use both --session and --session-name with the same value
336
+ fullArgs.push('--session', sessionName, '--session-name', sessionName, ...args);
337
+ return runAgentBrowserRawCommand(fullArgs);
338
+ }
339
+ /**
340
+ * List all available sessions using agent-browser session list command
341
+ */
342
+ export async function listSessions() {
343
+ const result = await runAgentBrowserRawCommand(['session', 'list']);
344
+ if (result.code !== 0) {
345
+ return [];
346
+ }
347
+ // Parse output - each line after "Active sessions:" is a session name
348
+ // Lines starting with "->" or just session names
349
+ const lines = result.stdout.trim().split('\n');
350
+ const sessions = [];
351
+ for (const line of lines) {
352
+ const trimmed = line.trim();
353
+ // Skip header lines
354
+ if (trimmed.startsWith('Active sessions:') || trimmed.length === 0) {
355
+ continue;
356
+ }
357
+ // Handle "-> default" or " agent1" formats
358
+ const sessionName = trimmed.replace(/^->\s*/, '').trim();
359
+ if (sessionName && !sessionName.startsWith('No ')) {
360
+ sessions.push(sessionName);
361
+ }
362
+ }
363
+ return sessions;
364
+ }
365
+ /**
366
+ * Check if a session exists
367
+ */
368
+ export async function sessionExists(name) {
369
+ const sessions = await listSessions();
370
+ return sessions.includes(name);
371
+ }
372
+ /**
373
+ * Check if max sessions limit is reached
374
+ */
375
+ export async function isSessionLimitReached() {
376
+ const sessions = await listSessions();
377
+ return sessions.length >= MAX_SESSIONS;
378
+ }
379
+ /**
380
+ * Get current session count
381
+ */
382
+ export async function getSessionCount() {
383
+ const sessions = await listSessions();
384
+ return sessions.length;
385
+ }
386
+ // ============ Browser Operations ============
387
+ /**
388
+ * Open a browser with URL using the specified session
389
+ */
390
+ export async function browserOpen(url, sessionName = 'corebrain', headed = false) {
391
+ // Validate session is configured
392
+ if (!isSessionConfigured(sessionName)) {
393
+ const configured = getConfiguredSessions();
394
+ if (configured.length === 0) {
395
+ return {
396
+ stdout: '',
397
+ stderr: `No sessions configured. Run: corebrain browser create-session <name>`,
398
+ code: 1,
399
+ };
400
+ }
401
+ return {
402
+ stdout: '',
403
+ stderr: `Session "${sessionName}" is not configured. Available sessions: ${configured.join(', ')}. Create with: corebrain browser create-session <name>`,
404
+ code: 1,
405
+ };
406
+ }
407
+ const args = headed ? ['--headed', 'open', url] : ['open', url];
408
+ return runAgentBrowserCommand(sessionName, args);
409
+ }
410
+ /**
411
+ * Close a browser for the specified session
412
+ */
413
+ export async function browserClose(sessionName) {
414
+ // Validate session is configured
415
+ if (!isSessionConfigured(sessionName)) {
416
+ const configured = getConfiguredSessions();
417
+ return {
418
+ stdout: '',
419
+ stderr: `Session "${sessionName}" is not configured. Available sessions: ${configured.join(', ')}`,
420
+ code: 1,
421
+ };
422
+ }
423
+ // Use close --session <name> format
424
+ return runAgentBrowserRawCommand(['close', '--session', sessionName]);
425
+ }
426
+ /**
427
+ * Close all browser sessions by closing each configured session
428
+ */
429
+ export async function browserCloseAll() {
430
+ // Get all configured sessions and close each
431
+ const configuredSessions = getConfiguredSessions();
432
+ if (configuredSessions.length === 0) {
433
+ return {
434
+ stdout: 'No sessions configured',
435
+ stderr: '',
436
+ code: 0,
437
+ };
438
+ }
439
+ const results = [];
440
+ let hasError = false;
441
+ // Close each configured session
442
+ for (const session of configuredSessions) {
443
+ const result = await runAgentBrowserRawCommand(['close', '--session', session]);
444
+ if (result.code !== 0 && !result.stderr.includes('not running')) {
445
+ hasError = true;
446
+ results.push(`Failed to close ${session}: ${result.stderr}`);
447
+ }
448
+ else {
449
+ results.push(`Closed session: ${session}`);
450
+ }
451
+ }
452
+ return {
453
+ stdout: results.join('\n'),
454
+ stderr: hasError ? 'Some sessions failed to close' : '',
455
+ code: hasError ? 1 : 0,
456
+ };
457
+ }
458
+ /**
459
+ * Check if a command is blocked
460
+ */
461
+ export function isBlockedCommand(command) {
462
+ const cmd = command.toLowerCase().trim();
463
+ return BLOCKED_COMMANDS.includes(cmd);
464
+ }
465
+ // Args that are controlled internally and should be stripped from user input
466
+ const INTERNAL_ARGS = ['--session', '--session-name', '--executable-path'];
467
+ /**
468
+ * Filter out internal args that we control (session, session-name, executable-path)
469
+ */
470
+ function filterInternalArgs(args) {
471
+ const filtered = [];
472
+ let skipNext = false;
473
+ for (let i = 0; i < args.length; i++) {
474
+ if (skipNext) {
475
+ skipNext = false;
476
+ continue;
477
+ }
478
+ const arg = args[i];
479
+ // Check if this arg is an internal arg we should filter
480
+ const isInternal = INTERNAL_ARGS.some(internal => arg === internal || arg.startsWith(`${internal}=`));
481
+ if (isInternal) {
482
+ // If it's --flag value format (not --flag=value), skip the next arg too
483
+ if (!arg.includes('=')) {
484
+ skipNext = true;
485
+ }
486
+ continue;
487
+ }
488
+ filtered.push(arg);
489
+ }
490
+ return filtered;
491
+ }
492
+ /**
493
+ * Execute a generic browser command on a session
494
+ * Blocks: open, close, cookies, storage, network, download, run, session, task, tunnel, state
495
+ * Filters: --session, --session-name, --executable-path (controlled internally)
496
+ */
497
+ export async function browserCommand(sessionName, command, args = []) {
498
+ // Validate session is configured
499
+ if (!isSessionConfigured(sessionName)) {
500
+ const configured = getConfiguredSessions();
501
+ return {
502
+ stdout: '',
503
+ stderr: `Session "${sessionName}" is not configured. Available sessions: ${configured.join(', ')}`,
504
+ code: 1,
505
+ };
506
+ }
507
+ // Check if command is blocked
508
+ if (isBlockedCommand(command)) {
509
+ return {
510
+ stdout: '',
511
+ stderr: `Command "${command}" is blocked. Blocked commands: ${BLOCKED_COMMANDS.join(', ')}`,
512
+ code: 1,
513
+ };
514
+ }
515
+ // Filter out internal args that could override our session/executable settings
516
+ const filteredArgs = filterInternalArgs(args);
517
+ return runAgentBrowserCommand(sessionName, [command, ...filteredArgs]);
518
+ }
519
+ /**
520
+ * Get all configured sessions (sync)
521
+ */
522
+ export function browserGetSessions() {
523
+ return getConfiguredSessions();
524
+ }
525
+ /**
526
+ * Get running sessions from agent-browser
527
+ */
528
+ export async function getActiveSessions() {
529
+ return listSessions();
530
+ }
531
+ /**
532
+ * Get server status
533
+ */
534
+ export async function getServerStatus() {
535
+ return runAgentBrowserRawCommand(['session', 'list']);
536
+ }
537
+ /**
538
+ * Get max sessions limit
539
+ */
540
+ export function getMaxSessions() {
541
+ return MAX_SESSIONS;
542
+ }
543
+ /**
544
+ * Get default sessions list
545
+ */
546
+ export function getDefaultSessions() {
547
+ return DEFAULT_SESSIONS;
548
+ }
549
+ //# sourceMappingURL=agent-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-browser.js","sourceRoot":"","sources":["../../src/utils/agent-browser.ts"],"names":[],"mappings":"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"}
@@ -19,13 +19,15 @@ export declare function buildResumeArgs(config: CliBackendConfig, params: {
19
19
  prompt: string;
20
20
  sessionId: string;
21
21
  }): string[];
22
+ export type Logger = (message: string) => void;
22
23
  /**
23
24
  * Start an agent process in the background (detached)
24
25
  * Returns immediately, CLI can exit while process continues
25
26
  * Output is written by the agent to its own session files (e.g., Claude Code writes to ~/.claude/projects/)
26
27
  */
27
- export declare function startAgentProcess(sessionId: string, config: CliBackendConfig, args: string[], workingDirectory: string): {
28
+ export declare function startAgentProcess(sessionId: string, config: CliBackendConfig, args: string[], workingDirectory: string, logger?: Logger): {
28
29
  pid: number | undefined;
30
+ error?: string;
29
31
  };
30
32
  /**
31
33
  * Check if a process is still running by session ID
@@ -1 +1 @@
1
- {"version":3,"file":"coding-runner.d.ts","sourceRoot":"","sources":["../../src/utils/coding-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,gBAAgB,CAAC;AAOrD;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAOzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,GACC,MAAM,EAAE,CAoCV;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CAClB,GACC,MAAM,EAAE,CAYV;AAwBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EAAE,EACd,gBAAgB,EAAE,MAAM,GACtB;IAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAC,CAgC3B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAetD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;IAClD,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAUP"}
1
+ {"version":3,"file":"coding-runner.d.ts","sourceRoot":"","sources":["../../src/utils/coding-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,gBAAgB,CAAC;AAOrD;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAOzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,GACC,MAAM,EAAE,CAoCV;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CAClB,GACC,MAAM,EAAE,CAYV;AAwBD,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EAAE,EACd,gBAAgB,EAAE,MAAM,EACxB,MAAM,CAAC,EAAE,MAAM,GACb;IAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAgE3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAetD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;IAClD,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAUP"}
@@ -82,31 +82,59 @@ function ensureLogsDir() {
82
82
  * Returns immediately, CLI can exit while process continues
83
83
  * Output is written by the agent to its own session files (e.g., Claude Code writes to ~/.claude/projects/)
84
84
  */
85
- export function startAgentProcess(sessionId, config, args, workingDirectory) {
85
+ export function startAgentProcess(sessionId, config, args, workingDirectory, logger) {
86
+ const log = logger || (() => { });
87
+ log(`SPAWN_START: sessionId=${sessionId}`);
88
+ log(`SPAWN_COMMAND: ${config.command}`);
89
+ log(`SPAWN_ARGS: ${JSON.stringify(args)}`);
90
+ log(`SPAWN_CWD: ${workingDirectory}`);
86
91
  // Ensure logs directory exists
87
92
  ensureLogsDir();
88
93
  // Open log files for stdout/stderr (so we can see any errors from the process itself)
89
94
  const stdoutPath = getSessionLogPath(sessionId, 'stdout');
90
95
  const stderrPath = getSessionLogPath(sessionId, 'stderr');
96
+ log(`SPAWN_STDOUT_LOG: ${stdoutPath}`);
97
+ log(`SPAWN_STDERR_LOG: ${stderrPath}`);
91
98
  const stdoutFd = openSync(stdoutPath, 'w');
92
99
  const stderrFd = openSync(stderrPath, 'w');
93
100
  // Spawn detached process
94
- const proc = spawn(config.command, args, {
95
- cwd: workingDirectory,
96
- shell: true,
97
- stdio: ['ignore', stdoutFd, stderrFd],
98
- detached: true,
99
- });
101
+ // Note: shell: false is required to avoid shell metacharacter issues in prompts
102
+ // (parentheses, quotes, etc. would otherwise be interpreted by the shell)
103
+ let proc;
104
+ try {
105
+ proc = spawn(config.command, args, {
106
+ cwd: workingDirectory,
107
+ shell: false,
108
+ stdio: ['ignore', stdoutFd, stderrFd],
109
+ detached: true,
110
+ });
111
+ }
112
+ catch (err) {
113
+ const errorMsg = err instanceof Error ? err.message : String(err);
114
+ log(`SPAWN_ERROR: Failed to spawn process: ${errorMsg}`);
115
+ return { pid: undefined, error: errorMsg };
116
+ }
100
117
  const pid = proc.pid;
118
+ log(`SPAWN_PID: ${pid}`);
119
+ // Handle spawn errors
120
+ proc.on('error', (err) => {
121
+ log(`SPAWN_PROCESS_ERROR: ${err.message}`);
122
+ });
123
+ // Log when process exits (useful for debugging quick failures)
124
+ proc.on('exit', (code, signal) => {
125
+ log(`SPAWN_EXIT: pid=${pid} code=${code} signal=${signal}`);
126
+ });
101
127
  // Store PID in session
102
128
  const session = getSession(sessionId);
103
129
  if (session && pid) {
104
130
  session.pid = pid;
105
131
  session.updatedAt = Date.now();
106
132
  updateSession(session);
133
+ log(`SPAWN_SESSION_UPDATED: pid stored in session`);
107
134
  }
108
135
  // Unref so parent can exit
109
136
  proc.unref();
137
+ log(`SPAWN_DETACHED: process detached and running`);
110
138
  return { pid };
111
139
  }
112
140
  /**