@zibby/core 0.1.18 → 0.1.20

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.18",
3
+ "version": "0.1.20",
4
4
  "description": "Core test automation engine with multi-agent and multi-MCP support",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -341,21 +341,31 @@ export class CursorAgentStrategy extends AgentStrategy {
341
341
 
342
342
  logger.debug(`[Agent] PID: ${proc.pid}`);
343
343
 
344
- // Handle stdin write errors gracefully
344
+ // Register error handlers on ALL child stdio streams to prevent
345
+ // unhandled EPIPE crashes (Node v23+ throws these as uncaught exceptions)
346
+ proc.stdin.on('error', (err) => {
347
+ if (err.code === 'EPIPE') return;
348
+ logger.warn(`[Agent] stdin error: ${err.message}`);
349
+ });
350
+ proc.stdout.on('error', (err) => {
351
+ if (err.code === 'EPIPE') return;
352
+ logger.warn(`[Agent] stdout error: ${err.message}`);
353
+ });
354
+ proc.stderr.on('error', (err) => {
355
+ if (err.code === 'EPIPE') return;
356
+ logger.warn(`[Agent] stderr error: ${err.message}`);
357
+ });
358
+
345
359
  if (stdinPrompt) {
346
- try {
347
- proc.stdin.write(stdinPrompt);
360
+ proc.stdin.write(stdinPrompt, (err) => {
361
+ if (err && err.code !== 'EPIPE') {
362
+ logger.warn(`[Agent] Failed to write to stdin: ${err.message}`);
363
+ }
348
364
  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
- }
365
+ });
366
+ logger.debug(`[Agent] Prompt also piped to stdin (${stdinPrompt.length} chars)`);
353
367
  } else {
354
- try {
355
- proc.stdin.end();
356
- } catch (err) {
357
- // Process may have already closed
358
- }
368
+ proc.stdin.end();
359
369
  }
360
370
 
361
371
  const modifiedFiles = new Set();
@@ -444,13 +454,7 @@ export class CursorAgentStrategy extends AgentStrategy {
444
454
  if (displayInput != null && typeof displayInput === 'object' && Object.keys(displayInput).length > 0 && !processClosed) {
445
455
  const raw = JSON.stringify(displayInput);
446
456
  const preview = raw.length > 100 ? `${raw.substring(0, 100)}...` : raw;
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
- }
457
+ console.log(` Input: ${preview}`);
454
458
  }
455
459
  };
456
460
 
@@ -465,14 +469,7 @@ export class CursorAgentStrategy extends AgentStrategy {
465
469
 
466
470
  const displayText = streamParser.processChunk(chunk);
467
471
  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
- }
472
+ process.stdout.write(displayText);
476
473
  }
477
474
 
478
475
  const lines = chunk.split('\n').filter(l => l.trim());