@zibby/core 0.1.15 → 0.1.17

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/core",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Core test automation engine with multi-agent and multi-MCP support",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -26,14 +26,13 @@
26
26
  "./package.json": "./package.json"
27
27
  },
28
28
  "scripts": {
29
- "test": "vitest run",
29
+ "test": "vitest run --exclude '**/memory/**'",
30
30
  "test:watch": "vitest",
31
31
  "test:state-schema": "vitest run src/framework/__tests__/state-schema.test.js",
32
32
  "test:state-schema:e2e": "node src/framework/__tests__/state-schema.e2e.test.js",
33
33
  "export:workflows": "node scripts/export-default-workflows.js",
34
34
  "lint": "eslint .",
35
- "lint:fix": "eslint --fix .",
36
- "prepublishOnly": "npm run lint && npm test"
35
+ "lint:fix": "eslint --fix ."
37
36
  },
38
37
  "keywords": [
39
38
  "testing",
@@ -169,9 +169,13 @@ export class CursorAgentStrategy extends AgentStrategy {
169
169
  logger.debug(`[Agent] Executing: ${fullCmd.slice(0, 200)}`);
170
170
  logger.debug(`[Agent] Workspace: ${workspace}`);
171
171
  if (process.env.LOG_LEVEL === 'debug' || process.env.ZIBBY_LOG_CURSOR_CLI === '1') {
172
- console.log(`\nšŸ”§ Cursor CLI --model ${model || 'auto'} (from .zibby.config.js agent.cursor.model)\n`);
173
- if (process.env.ZIBBY_LOG_CURSOR_CLI === '1') {
174
- console.log(` Full command: ${fullCmd}\n`);
172
+ try {
173
+ console.log(`\nšŸ”§ Cursor CLI --model ${model || 'auto'} (from .zibby.config.js agent.cursor.model)\n`);
174
+ if (process.env.ZIBBY_LOG_CURSOR_CLI === '1') {
175
+ console.log(` Full command: ${fullCmd}\n`);
176
+ }
177
+ } catch (err) {
178
+ // Ignore EPIPE errors from console.log
175
179
  }
176
180
  }
177
181
 
@@ -327,6 +331,7 @@ export class CursorAgentStrategy extends AgentStrategy {
327
331
  let lineCount = 0;
328
332
  let killed = false;
329
333
  let processStarted = false;
334
+ let processClosed = false;
330
335
 
331
336
  const proc = spawn(bin, args, {
332
337
  cwd,
@@ -336,58 +341,21 @@ export class CursorAgentStrategy extends AgentStrategy {
336
341
 
337
342
  logger.debug(`[Agent] PID: ${proc.pid}`);
338
343
 
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
-
344
+ // Handle stdin write errors gracefully
385
345
  if (stdinPrompt) {
386
- proc.stdin.write(stdinPrompt);
387
- proc.stdin.end();
388
- logger.debug(`[Agent] Prompt also piped to stdin (${stdinPrompt.length} chars)`);
346
+ try {
347
+ proc.stdin.write(stdinPrompt);
348
+ proc.stdin.end();
349
+ logger.debug(`[Agent] Prompt also piped to stdin (${stdinPrompt.length} chars)`);
350
+ } catch (err) {
351
+ logger.warn(`[Agent] Failed to write to stdin: ${err.message}`);
352
+ }
389
353
  } else {
390
- proc.stdin.end();
354
+ try {
355
+ proc.stdin.end();
356
+ } catch (err) {
357
+ // Process may have already closed
358
+ }
391
359
  }
392
360
 
393
361
  const modifiedFiles = new Set();
@@ -473,10 +441,16 @@ export class CursorAgentStrategy extends AgentStrategy {
473
441
  } else {
474
442
  timeline.stepTool(`Tool: ${displayName}`);
475
443
  }
476
- if (displayInput != null && typeof displayInput === 'object' && Object.keys(displayInput).length > 0) {
444
+ if (displayInput != null && typeof displayInput === 'object' && Object.keys(displayInput).length > 0 && !processClosed) {
477
445
  const raw = JSON.stringify(displayInput);
478
446
  const preview = raw.length > 100 ? `${raw.substring(0, 100)}...` : raw;
479
- console.log(` Input: ${preview}`);
447
+ try {
448
+ console.log(` Input: ${preview}`);
449
+ } catch (err) {
450
+ if (err.code !== 'EPIPE') {
451
+ logger.warn(`[Agent] console.log error: ${err.message}`);
452
+ }
453
+ }
480
454
  }
481
455
  };
482
456
 
@@ -487,12 +461,18 @@ export class CursorAgentStrategy extends AgentStrategy {
487
461
 
488
462
  if (!processStarted) {
489
463
  processStarted = true;
490
- clearTimeout(startupTimer);
491
464
  }
492
465
 
493
466
  const displayText = streamParser.processChunk(chunk);
494
- if (displayText) {
495
- process.stdout.write(displayText);
467
+ if (displayText && !processClosed) {
468
+ try {
469
+ process.stdout.write(displayText);
470
+ } catch (err) {
471
+ // Handle EPIPE gracefully - parent process stdout may be closed
472
+ if (err.code !== 'EPIPE') {
473
+ logger.warn(`[Agent] stdout write error: ${err.message}`);
474
+ }
475
+ }
496
476
  }
497
477
 
498
478
  const lines = chunk.split('\n').filter(l => l.trim());
@@ -506,7 +486,6 @@ export class CursorAgentStrategy extends AgentStrategy {
506
486
 
507
487
  if (!processStarted) {
508
488
  processStarted = true;
509
- clearTimeout(startupTimer);
510
489
  }
511
490
 
512
491
  const lines = chunk.split('\n').filter(l => l.trim());
@@ -516,8 +495,8 @@ export class CursorAgentStrategy extends AgentStrategy {
516
495
  });
517
496
 
518
497
  proc.on('close', (code, signal) => {
498
+ processClosed = true;
519
499
  clearTimeout(timer);
520
- clearTimeout(startupTimer);
521
500
  clearInterval(heartbeat);
522
501
  streamParser.flush();
523
502
  const elapsed = Math.round((Date.now() - startTime) / 1000);
@@ -551,7 +530,6 @@ export class CursorAgentStrategy extends AgentStrategy {
551
530
 
552
531
  proc.on('error', (err) => {
553
532
  clearTimeout(timer);
554
- clearTimeout(startupTimer);
555
533
  clearInterval(heartbeat);
556
534
  reject(new Error(
557
535
  `Cursor Agent spawn error: ${err.message}\n` +