@zibby/core 0.1.18 → 0.1.21

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.21",
4
4
  "description": "Core test automation engine with multi-agent and multi-MCP support",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -6,7 +6,7 @@ import { tmpdir, homedir } from 'os';
6
6
  import { logger } from '../../utils/logger.js';
7
7
  import { DEFAULT_MODELS, TIMEOUTS } from '../../constants.js';
8
8
  import { DEFAULT_OUTPUT_BASE, SESSION_INFO_FILE } from '../constants.js';
9
- import { getAllSkills } from '../skill-registry.js';
9
+ import { getAllSkills, getSkill } from '../skill-registry.js';
10
10
  import { StreamingParser } from '../../utils/streaming-parser.js';
11
11
  import { CursorOutputFormatter } from './utils/cursor-output-formatter.js';
12
12
  import { formatWithOpenAIProxy } from './utils/openai-proxy-formatter.js';
@@ -83,7 +83,7 @@ export class CursorAgentStrategy extends AgentStrategy {
83
83
 
84
84
  logger.debug(`[Cursor] Invoking (model: ${model}, timeout: ${timeout / 1000}s, skills: ${JSON.stringify(skills)})`);
85
85
 
86
- this._setupMcpConfig(sessionPath, workspace, config);
86
+ this._setupMcpConfig(sessionPath, workspace, config, skills);
87
87
 
88
88
  const possibleBins = [
89
89
  // Try absolute paths first (most reliable)
@@ -174,7 +174,7 @@ export class CursorAgentStrategy extends AgentStrategy {
174
174
  if (process.env.ZIBBY_LOG_CURSOR_CLI === '1') {
175
175
  console.log(` Full command: ${fullCmd}\n`);
176
176
  }
177
- } catch (err) {
177
+ } catch (_err) {
178
178
  // Ignore EPIPE errors from console.log
179
179
  }
180
180
  }
@@ -252,7 +252,7 @@ export class CursorAgentStrategy extends AgentStrategy {
252
252
  return rawOutput;
253
253
  }
254
254
 
255
- _setupMcpConfig(sessionPath, workspace, config) {
255
+ _setupMcpConfig(sessionPath, workspace, config, skills = null) {
256
256
  const cursorDir = join(homedir(), '.cursor');
257
257
  const mcpConfigPath = join(cursorDir, 'mcp.json');
258
258
 
@@ -267,8 +267,12 @@ export class CursorAgentStrategy extends AgentStrategy {
267
267
  const outputBase = config?.paths?.output || DEFAULT_OUTPUT_BASE;
268
268
  const sessionInfoPath = join(workspace || process.cwd(), outputBase, SESSION_INFO_FILE);
269
269
 
270
+ const skillsToResolve = Array.isArray(skills)
271
+ ? skills.map(id => getSkill(id)).filter(Boolean)
272
+ : [...getAllSkills()].map(([, skill]) => skill);
273
+
270
274
  const configured = new Set();
271
- for (const [, skill] of getAllSkills()) {
275
+ for (const skill of skillsToResolve) {
272
276
  if (typeof skill.resolve !== 'function') continue;
273
277
  if (configured.has(skill.serverName)) continue;
274
278
  configured.add(skill.serverName);
@@ -341,21 +345,31 @@ export class CursorAgentStrategy extends AgentStrategy {
341
345
 
342
346
  logger.debug(`[Agent] PID: ${proc.pid}`);
343
347
 
344
- // Handle stdin write errors gracefully
348
+ // Register error handlers on ALL child stdio streams to prevent
349
+ // unhandled EPIPE crashes (Node v23+ throws these as uncaught exceptions)
350
+ proc.stdin.on('error', (err) => {
351
+ if (err.code === 'EPIPE') return;
352
+ logger.warn(`[Agent] stdin error: ${err.message}`);
353
+ });
354
+ proc.stdout.on('error', (err) => {
355
+ if (err.code === 'EPIPE') return;
356
+ logger.warn(`[Agent] stdout error: ${err.message}`);
357
+ });
358
+ proc.stderr.on('error', (err) => {
359
+ if (err.code === 'EPIPE') return;
360
+ logger.warn(`[Agent] stderr error: ${err.message}`);
361
+ });
362
+
345
363
  if (stdinPrompt) {
346
- try {
347
- proc.stdin.write(stdinPrompt);
364
+ proc.stdin.write(stdinPrompt, (err) => {
365
+ if (err && err.code !== 'EPIPE') {
366
+ logger.warn(`[Agent] Failed to write to stdin: ${err.message}`);
367
+ }
348
368
  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
- }
369
+ });
370
+ logger.debug(`[Agent] Prompt also piped to stdin (${stdinPrompt.length} chars)`);
353
371
  } else {
354
- try {
355
- proc.stdin.end();
356
- } catch (err) {
357
- // Process may have already closed
358
- }
372
+ proc.stdin.end();
359
373
  }
360
374
 
361
375
  const modifiedFiles = new Set();
@@ -444,13 +458,7 @@ export class CursorAgentStrategy extends AgentStrategy {
444
458
  if (displayInput != null && typeof displayInput === 'object' && Object.keys(displayInput).length > 0 && !processClosed) {
445
459
  const raw = JSON.stringify(displayInput);
446
460
  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
- }
461
+ console.log(` Input: ${preview}`);
454
462
  }
455
463
  };
456
464
 
@@ -465,14 +473,7 @@ export class CursorAgentStrategy extends AgentStrategy {
465
473
 
466
474
  const displayText = streamParser.processChunk(chunk);
467
475
  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
- }
476
+ process.stdout.write(displayText);
476
477
  }
477
478
 
478
479
  const lines = chunk.split('\n').filter(l => l.trim());
@@ -70,7 +70,7 @@ export async function invokeAgent(prompt, context = {}, options = {}) {
70
70
  workspace: context.state?.workspace || options.workspace,
71
71
  schema: options.schema || context.schema,
72
72
  images: options.images || context.images || [],
73
- skills: options.skills || context.skills || null,
73
+ skills: options.skills || context.skills || [],
74
74
  config,
75
75
  ...options
76
76
  };
@@ -167,7 +167,7 @@ export class Node {
167
167
  model,
168
168
  workspace: cwd,
169
169
  schema: this.isZodSchema ? this.outputSchema : null,
170
- skills: this.config.skills || null,
170
+ skills: this.config.skills || [],
171
171
  sessionPath,
172
172
  config: zibbyConfig
173
173
  };