@redplanethq/corebrain 2.5.3 → 2.5.4
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/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/browser/close.js +4 -4
- package/dist/commands/browser/close.js.map +1 -1
- package/dist/commands/browser/command.js +4 -4
- package/dist/commands/browser/command.js.map +1 -1
- package/dist/commands/browser/create-session.d.ts +10 -0
- package/dist/commands/browser/create-session.d.ts.map +1 -0
- package/dist/commands/browser/create-session.js +36 -0
- package/dist/commands/browser/create-session.js.map +1 -0
- package/dist/commands/browser/delete-session.d.ts.map +1 -1
- package/dist/commands/browser/delete-session.js +20 -14
- package/dist/commands/browser/delete-session.js.map +1 -1
- package/dist/commands/browser/install.d.ts.map +1 -1
- package/dist/commands/browser/install.js +38 -36
- package/dist/commands/browser/install.js.map +1 -1
- package/dist/commands/browser/list-sessions.d.ts.map +1 -1
- package/dist/commands/browser/list-sessions.js +7 -15
- package/dist/commands/browser/list-sessions.js.map +1 -1
- package/dist/commands/browser/open-head.d.ts.map +1 -1
- package/dist/commands/browser/open-head.js +9 -15
- package/dist/commands/browser/open-head.js.map +1 -1
- package/dist/commands/browser/open.js +4 -4
- package/dist/commands/browser/open.js.map +1 -1
- package/dist/commands/browser/set-browser.d.ts +15 -0
- package/dist/commands/browser/set-browser.d.ts.map +1 -0
- package/dist/commands/browser/set-browser.js +111 -0
- package/dist/commands/browser/set-browser.js.map +1 -0
- package/dist/commands/browser/status.d.ts.map +1 -1
- package/dist/commands/browser/status.js +9 -8
- package/dist/commands/browser/status.js.map +1 -1
- package/dist/commands/coding/start.d.ts.map +1 -1
- package/dist/commands/coding/start.js.map +1 -1
- package/dist/commands/gateway/config.js +9 -9
- package/dist/commands/gateway/config.js.map +1 -1
- package/dist/server/gateway-client.js +2 -2
- package/dist/server/gateway-client.js.map +1 -1
- package/dist/server/tools/browser-tools.d.ts +6 -0
- package/dist/server/tools/browser-tools.d.ts.map +1 -1
- package/dist/server/tools/browser-tools.js +87 -12
- package/dist/server/tools/browser-tools.js.map +1 -1
- package/dist/server/tools/coding-tools.d.ts +2 -1
- package/dist/server/tools/coding-tools.d.ts.map +1 -1
- package/dist/server/tools/coding-tools.js +19 -7
- package/dist/server/tools/coding-tools.js.map +1 -1
- package/dist/types/config.d.ts +7 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/agent-browser.d.ts +135 -0
- package/dist/utils/agent-browser.d.ts.map +1 -0
- package/dist/utils/agent-browser.js +549 -0
- package/dist/utils/agent-browser.js.map +1 -0
- package/dist/utils/coding-runner.d.ts +3 -1
- package/dist/utils/coding-runner.d.ts.map +1 -1
- package/dist/utils/coding-runner.js +35 -7
- package/dist/utils/coding-runner.js.map +1 -1
- 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,
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
/**
|