@zibby/core 0.1.11 → 0.1.15
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/package.json
CHANGED
|
@@ -23,10 +23,15 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
23
23
|
|
|
24
24
|
canHandle(_context) {
|
|
25
25
|
const paths = [
|
|
26
|
-
|
|
27
|
-
'
|
|
26
|
+
// Try absolute paths first (most reliable)
|
|
27
|
+
join(homedir(), '.local', 'bin', 'cursor-agent'),
|
|
28
|
+
join(homedir(), '.cursor', 'bin', 'cursor-agent'),
|
|
28
29
|
'/usr/local/bin/cursor-agent',
|
|
29
|
-
'/
|
|
30
|
+
'/usr/local/bin/agent',
|
|
31
|
+
'/Applications/Cursor.app/Contents/Resources/app/bin/cursor',
|
|
32
|
+
// Try PATH last (may have symlink issues)
|
|
33
|
+
'agent',
|
|
34
|
+
'cursor-agent'
|
|
30
35
|
];
|
|
31
36
|
|
|
32
37
|
for (const path of paths) {
|
|
@@ -81,10 +86,15 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
81
86
|
this._setupMcpConfig(sessionPath, workspace, config);
|
|
82
87
|
|
|
83
88
|
const possibleBins = [
|
|
84
|
-
|
|
85
|
-
'
|
|
89
|
+
// Try absolute paths first (most reliable)
|
|
90
|
+
join(homedir(), '.local', 'bin', 'cursor-agent'),
|
|
91
|
+
join(homedir(), '.cursor', 'bin', 'cursor-agent'),
|
|
86
92
|
'/usr/local/bin/cursor-agent',
|
|
87
|
-
'/
|
|
93
|
+
'/usr/local/bin/agent',
|
|
94
|
+
'/Applications/Cursor.app/Contents/Resources/app/bin/cursor',
|
|
95
|
+
// Try PATH last (may have symlink issues)
|
|
96
|
+
'agent',
|
|
97
|
+
'cursor-agent'
|
|
88
98
|
];
|
|
89
99
|
|
|
90
100
|
let cursorBin = null;
|
|
@@ -113,11 +123,14 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
113
123
|
|
|
114
124
|
if (!cursorBin) {
|
|
115
125
|
throw new Error(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
126
|
+
`Cursor Agent CLI not found or not working.\n\n` +
|
|
127
|
+
`Checked paths:\n` +
|
|
128
|
+
`${possibleBins.map(p => ` - ${p}`).join('\n')}\n\n` +
|
|
129
|
+
`Install cursor-agent:\n` +
|
|
130
|
+
` curl https://cursor.com/install -fsS | bash\n\n` +
|
|
131
|
+
`Then add to PATH:\n` +
|
|
132
|
+
` echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc\n\n` +
|
|
133
|
+
`Test with: agent --version`
|
|
121
134
|
);
|
|
122
135
|
}
|
|
123
136
|
|
|
@@ -138,28 +151,19 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
138
151
|
writeFileSync(promptFile, prompt, 'utf-8');
|
|
139
152
|
logger.debug(`📝 [Agent] Prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
140
153
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (process.env.CURSOR_API_KEY) {
|
|
153
|
-
args.push('--api-key', process.env.CURSOR_API_KEY);
|
|
154
|
-
}
|
|
155
|
-
args.push(`@${promptFile}`);
|
|
156
|
-
} else {
|
|
157
|
-
args = ['agent', '--print', '--force', '--trust', '--approve-mcps'];
|
|
158
|
-
if (process.env.CURSOR_API_KEY) {
|
|
159
|
-
args.push('--api-key', process.env.CURSOR_API_KEY);
|
|
160
|
-
}
|
|
161
|
-
args.push('--model', model || 'auto', `@${promptFile}`);
|
|
154
|
+
// All cursor-agent binaries use the same command structure (no subcommand needed)
|
|
155
|
+
const args = [
|
|
156
|
+
'--print',
|
|
157
|
+
'--force',
|
|
158
|
+
'--approve-mcps',
|
|
159
|
+
'--output-format', 'stream-json',
|
|
160
|
+
'--stream-partial-output',
|
|
161
|
+
'--model', model || 'auto',
|
|
162
|
+
];
|
|
163
|
+
if (process.env.CURSOR_API_KEY) {
|
|
164
|
+
args.push('--api-key', process.env.CURSOR_API_KEY);
|
|
162
165
|
}
|
|
166
|
+
args.push(`@${promptFile}`);
|
|
163
167
|
|
|
164
168
|
const fullCmd = [cursorBin, ...args].join(' ');
|
|
165
169
|
logger.debug(`[Agent] Executing: ${fullCmd.slice(0, 200)}`);
|
|
@@ -322,6 +326,7 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
322
326
|
let lastOutputTime = Date.now();
|
|
323
327
|
let lineCount = 0;
|
|
324
328
|
let killed = false;
|
|
329
|
+
let processStarted = false;
|
|
325
330
|
|
|
326
331
|
const proc = spawn(bin, args, {
|
|
327
332
|
cwd,
|
|
@@ -331,6 +336,52 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
331
336
|
|
|
332
337
|
logger.debug(`[Agent] PID: ${proc.pid}`);
|
|
333
338
|
|
|
339
|
+
const startupTimer = setTimeout(() => {
|
|
340
|
+
if (!processStarted && lineCount === 0) {
|
|
341
|
+
killed = true;
|
|
342
|
+
const binaryPath = bin.replace(/^"(.*)"$/, '$1');
|
|
343
|
+
const binaryExists = existsSync(binaryPath);
|
|
344
|
+
|
|
345
|
+
logger.error(`❌ [Agent] Process failed to start within 5 seconds.`);
|
|
346
|
+
logger.error(` Binary: ${bin}`);
|
|
347
|
+
logger.error(` File exists: ${binaryExists ? 'Yes (but not working - may be corrupted)' : 'No'}`);
|
|
348
|
+
logger.error(` PATH includes ~/.local/bin: ${process.env.PATH.includes('.local/bin') ? 'Yes' : 'No'}`);
|
|
349
|
+
|
|
350
|
+
if (binaryExists) {
|
|
351
|
+
logger.error(`\n ⚠️ Binary exists but won't start. Try reinstalling:`);
|
|
352
|
+
logger.error(` rm -f "${binaryPath}"`);
|
|
353
|
+
logger.error(` curl https://cursor.com/install -fsS | bash`);
|
|
354
|
+
logger.error(` echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`);
|
|
355
|
+
} else {
|
|
356
|
+
logger.error(`\n Install cursor-agent:`);
|
|
357
|
+
logger.error(` curl https://cursor.com/install -fsS | bash`);
|
|
358
|
+
logger.error(` echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
proc.kill('SIGTERM');
|
|
362
|
+
setTimeout(() => { if (!proc.killed) proc.kill('SIGKILL'); }, 2000);
|
|
363
|
+
reject(new Error(
|
|
364
|
+
`Cursor Agent failed to start. Binary '${binaryPath}' ${binaryExists ? 'exists but is not working (corrupted?)' : 'not found'}.\n\n` +
|
|
365
|
+
`${binaryExists
|
|
366
|
+
? '⚠️ The binary file exists but failed to start. It may be corrupted or incomplete.\n\n' +
|
|
367
|
+
'Try reinstalling cursor-agent:\n' +
|
|
368
|
+
` rm -f "${binaryPath}"\n` +
|
|
369
|
+
' curl https://cursor.com/install -fsS | bash\n\n' +
|
|
370
|
+
'Ensure ~/.local/bin is in your PATH:\n' +
|
|
371
|
+
' echo \'export PATH="$HOME/.local/bin:$PATH"\' >> ~/.zshrc\n' +
|
|
372
|
+
' source ~/.zshrc\n\n' +
|
|
373
|
+
'Test with: agent --version'
|
|
374
|
+
: 'Install cursor-agent:\n' +
|
|
375
|
+
' curl https://cursor.com/install -fsS | bash\n\n' +
|
|
376
|
+
'Add ~/.local/bin to your PATH:\n' +
|
|
377
|
+
' echo \'export PATH="$HOME/.local/bin:$PATH"\' >> ~/.zshrc\n' +
|
|
378
|
+
' source ~/.zshrc\n\n' +
|
|
379
|
+
'Test with: agent --version'
|
|
380
|
+
}`
|
|
381
|
+
));
|
|
382
|
+
}
|
|
383
|
+
}, 5000);
|
|
384
|
+
|
|
334
385
|
if (stdinPrompt) {
|
|
335
386
|
proc.stdin.write(stdinPrompt);
|
|
336
387
|
proc.stdin.end();
|
|
@@ -434,6 +485,11 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
434
485
|
stdout += chunk;
|
|
435
486
|
lastOutputTime = Date.now();
|
|
436
487
|
|
|
488
|
+
if (!processStarted) {
|
|
489
|
+
processStarted = true;
|
|
490
|
+
clearTimeout(startupTimer);
|
|
491
|
+
}
|
|
492
|
+
|
|
437
493
|
const displayText = streamParser.processChunk(chunk);
|
|
438
494
|
if (displayText) {
|
|
439
495
|
process.stdout.write(displayText);
|
|
@@ -448,6 +504,11 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
448
504
|
stderr += chunk;
|
|
449
505
|
lastOutputTime = Date.now();
|
|
450
506
|
|
|
507
|
+
if (!processStarted) {
|
|
508
|
+
processStarted = true;
|
|
509
|
+
clearTimeout(startupTimer);
|
|
510
|
+
}
|
|
511
|
+
|
|
451
512
|
const lines = chunk.split('\n').filter(l => l.trim());
|
|
452
513
|
for (const line of lines) {
|
|
453
514
|
logger.warn(`⚠️ [Agent stderr] ${line}`);
|
|
@@ -456,6 +517,7 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
456
517
|
|
|
457
518
|
proc.on('close', (code, signal) => {
|
|
458
519
|
clearTimeout(timer);
|
|
520
|
+
clearTimeout(startupTimer);
|
|
459
521
|
clearInterval(heartbeat);
|
|
460
522
|
streamParser.flush();
|
|
461
523
|
const elapsed = Math.round((Date.now() - startTime) / 1000);
|
|
@@ -489,8 +551,14 @@ export class CursorAgentStrategy extends AgentStrategy {
|
|
|
489
551
|
|
|
490
552
|
proc.on('error', (err) => {
|
|
491
553
|
clearTimeout(timer);
|
|
554
|
+
clearTimeout(startupTimer);
|
|
492
555
|
clearInterval(heartbeat);
|
|
493
|
-
reject(new Error(
|
|
556
|
+
reject(new Error(
|
|
557
|
+
`Cursor Agent spawn error: ${err.message}\n` +
|
|
558
|
+
`Binary: ${bin}\n` +
|
|
559
|
+
`This usually means the binary is not in PATH. Try:\n` +
|
|
560
|
+
` echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`
|
|
561
|
+
));
|
|
494
562
|
});
|
|
495
563
|
});
|
|
496
564
|
}
|
|
@@ -47,13 +47,12 @@ export class BrowserTestAutomationAgent extends WorkflowAgent {
|
|
|
47
47
|
BrowserTestResultHandler.saveTitle(result, cwd);
|
|
48
48
|
await BrowserTestResultHandler.saveExecutionData(result);
|
|
49
49
|
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
50
|
+
// Memory end-run hook (if @zibby/memory is installed)
|
|
51
|
+
try {
|
|
52
|
+
const { memoryEndRun, memorySyncPush } = await import('@zibby/memory');
|
|
53
|
+
const sessionId = result.state.sessionPath?.split('/').pop();
|
|
54
|
+
memoryEndRun(cwd, { sessionId, passed: result.success !== false });
|
|
55
|
+
memorySyncPush(cwd);
|
|
56
|
+
} catch { /* @zibby/memory not available */ }
|
|
58
57
|
}
|
|
59
58
|
}
|
|
@@ -14,7 +14,7 @@ import { formatAssertionChecklist } from './utils.mjs';
|
|
|
14
14
|
|
|
15
15
|
export const executeLiveNode = {
|
|
16
16
|
name: 'execute_live',
|
|
17
|
-
skills: [SKILLS.BROWSER,
|
|
17
|
+
skills: [SKILLS.BROWSER, SKILLS.MEMORY],
|
|
18
18
|
timeout: 600000,
|
|
19
19
|
|
|
20
20
|
prompt: (state) => {
|