@yasserkhanorg/e2e-agents 0.7.4 โ†’ 0.7.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"plan_builder.d.ts","sourceRoot":"","sources":["../../src/engine/plan_builder.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAC,YAAY,EAAkB,MAAM,oBAAoB,CAAC;AAEtE,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAG3D,OAAO,KAAK,EACR,UAAU,EACV,SAAS,EACT,kBAAkB,EAIrB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAC,UAAU,EAAE,SAAS,EAAE,kBAAkB,EAAC,CAAC;AAqOxD,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,YAAY,EACpB,cAAc,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,EACtC,YAAY,CAAC,EAAE,kBAAkB,GAClC,UAAU,CA0IZ;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAMzE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAsEhE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,SAAiC,GAAG,MAAM,CAMvH"}
1
+ {"version":3,"file":"plan_builder.d.ts","sourceRoot":"","sources":["../../src/engine/plan_builder.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAC,YAAY,EAAkB,MAAM,oBAAoB,CAAC;AAEtE,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAG3D,OAAO,KAAK,EACR,UAAU,EACV,SAAS,EACT,kBAAkB,EAIrB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAC,UAAU,EAAE,SAAS,EAAE,kBAAkB,EAAC,CAAC;AAqOxD,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,YAAY,EACpB,cAAc,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,EACtC,YAAY,CAAC,EAAE,kBAAkB,GAClC,UAAU,CA0IZ;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAMzE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAuGhE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,SAAiC,GAAG,MAAM,CAMvH"}
@@ -335,16 +335,21 @@ function renderCiSummaryMarkdown(plan) {
335
335
  const lines = [];
336
336
  const { uncoveredP0P1Flows, changedFiles, impactedFlows, coveredFlows: coveredCount, partialFlows: partialCount } = plan.metrics;
337
337
  const mustAddTests = plan.decision.action === 'must-add-tests';
338
+ const flowsWithAdvisory = plan.coveredFlows.filter((f) => f.advisoryScenarios && f.advisoryScenarios.length > 0);
339
+ const cleanFlows = plan.coveredFlows.filter((f) => !f.advisoryScenarios || f.advisoryScenarios.length === 0);
338
340
  const statusEmoji = mustAddTests ? '๐Ÿ”ด' : plan.decision.action === 'safe-to-merge' ? '๐ŸŸข' : '๐ŸŸก';
339
341
  lines.push(`## ${statusEmoji} E2E Coverage: ${plan.decision.title}`);
340
342
  lines.push('');
341
343
  lines.push(`${plan.decision.summary}`);
342
344
  lines.push('');
343
- // Build a readable coverage breakdown instead of raw P0/P1 counts
345
+ // Coverage breakdown: "3 covered ยท 2 new ยท 1 gap ยท 1 partial"
344
346
  const parts = [];
345
347
  if ((coveredCount ?? 0) > 0) {
346
348
  parts.push(`${coveredCount} covered`);
347
349
  }
350
+ if (flowsWithAdvisory.length > 0) {
351
+ parts.push(`${flowsWithAdvisory.length} new behavior`);
352
+ }
348
353
  if (uncoveredP0P1Flows > 0) {
349
354
  parts.push(`${uncoveredP0P1Flows} gap${uncoveredP0P1Flows !== 1 ? 's' : ''}`);
350
355
  }
@@ -353,6 +358,7 @@ function renderCiSummaryMarkdown(plan) {
353
358
  }
354
359
  const breakdown = parts.length > 0 ? ` (${parts.join(' ยท ')})` : '';
355
360
  lines.push(`**${changedFiles}** files changed โ†’ **${impactedFlows}** features impacted${breakdown}`);
361
+ // โ”€โ”€ Blocking gaps โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
356
362
  if (mustAddTests && plan.requiredNewTests.length > 0) {
357
363
  lines.push('');
358
364
  lines.push('### โš ๏ธ Add E2E tests for these uncovered P0/P1 features');
@@ -361,32 +367,57 @@ function renderCiSummaryMarkdown(plan) {
361
367
  lines.push('');
362
368
  for (const gap of plan.gapDetails.filter((g) => !g.name.includes('(partial)'))) {
363
369
  const aiLabel = gap.source === 'ai+deterministic' ? ' โœฆ AI-enriched' : '';
364
- lines.push(`- **${gap.name}** [${gap.priority}]${aiLabel}`);
370
+ lines.push(`> [!WARNING]`);
371
+ lines.push(`> **${gap.name}** ยท ${gap.priority}${aiLabel}`);
372
+ // AI-provided reasons (skip the first generic deterministic reason)
373
+ const aiReasons = gap.reasons.slice(1);
374
+ if (aiReasons.length > 0) {
375
+ lines.push(`> ${aiReasons.join(' ')}`);
376
+ }
365
377
  if (gap.missingScenarios && gap.missingScenarios.length > 0) {
378
+ lines.push(`>`);
379
+ lines.push(`> **Suggested test scenarios:**`);
366
380
  for (const scenario of gap.missingScenarios) {
367
- lines.push(` - ${scenario}`);
381
+ lines.push(`> - [ ] ${scenario}`);
368
382
  }
369
383
  }
370
- // Show AI-provided reasons (skip the first deterministic reason which is always included)
371
- const aiReasons = gap.reasons.slice(1);
372
- if (aiReasons.length > 0) {
373
- lines.push(` - *AI insight*: ${aiReasons.join('; ')}`);
384
+ lines.push('');
385
+ }
386
+ }
387
+ // โ”€โ”€ Advisory: covered flows with new behavior detected โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
388
+ if (flowsWithAdvisory.length > 0) {
389
+ lines.push('');
390
+ lines.push(`### ๐Ÿ’ก New behavior detected in ${flowsWithAdvisory.length} covered feature${flowsWithAdvisory.length !== 1 ? 's' : ''}`);
391
+ lines.push('');
392
+ lines.push('These features already have E2E tests, but this PR introduces new behavior worth covering:');
393
+ lines.push('');
394
+ for (const flow of flowsWithAdvisory) {
395
+ lines.push(`> [!TIP]`);
396
+ lines.push(`> **${flow.name}** ยท ${flow.priority} โ€” ${flow.coveredBy.join(', ')}`);
397
+ lines.push(`>`);
398
+ lines.push(`> Consider adding tests for:`);
399
+ for (const s of flow.advisoryScenarios) {
400
+ lines.push(`> - [ ] ${s}`);
374
401
  }
402
+ lines.push('');
375
403
  }
376
404
  }
377
- if (plan.coveredFlows.length > 0) {
405
+ // โ”€โ”€ Clean covered flows (collapsed) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
406
+ if (cleanFlows.length > 0 || flowsWithAdvisory.length > 0) {
378
407
  lines.push('');
379
- lines.push('### โœ… Covered features');
408
+ const label = cleanFlows.length > 0
409
+ ? `โœ… Covered flows (${cleanFlows.length})`
410
+ : `โœ… All covered flows have advisory notes above`;
411
+ lines.push(`<details><summary>${label}</summary>`);
380
412
  lines.push('');
381
- for (const flow of plan.coveredFlows) {
413
+ for (const flow of cleanFlows) {
382
414
  lines.push(`- **${flow.name}** [${flow.priority}] โ€” ${flow.coveredBy.join(', ')}`);
383
- if (flow.advisoryScenarios && flow.advisoryScenarios.length > 0) {
384
- lines.push(` ๐Ÿ’ก New behavior in this PR โ€” consider adding:`);
385
- for (const s of flow.advisoryScenarios) {
386
- lines.push(` - [ ] ${s}`);
387
- }
388
- }
389
415
  }
416
+ for (const flow of flowsWithAdvisory) {
417
+ lines.push(`- **${flow.name}** [${flow.priority}] โ€” ${flow.coveredBy.join(', ')} ๐Ÿ’ก`);
418
+ }
419
+ lines.push('');
420
+ lines.push('</details>');
390
421
  }
391
422
  if (plan.confidence < 100) {
392
423
  lines.push('');
@@ -329,16 +329,21 @@ export function renderCiSummaryMarkdown(plan) {
329
329
  const lines = [];
330
330
  const { uncoveredP0P1Flows, changedFiles, impactedFlows, coveredFlows: coveredCount, partialFlows: partialCount } = plan.metrics;
331
331
  const mustAddTests = plan.decision.action === 'must-add-tests';
332
+ const flowsWithAdvisory = plan.coveredFlows.filter((f) => f.advisoryScenarios && f.advisoryScenarios.length > 0);
333
+ const cleanFlows = plan.coveredFlows.filter((f) => !f.advisoryScenarios || f.advisoryScenarios.length === 0);
332
334
  const statusEmoji = mustAddTests ? '๐Ÿ”ด' : plan.decision.action === 'safe-to-merge' ? '๐ŸŸข' : '๐ŸŸก';
333
335
  lines.push(`## ${statusEmoji} E2E Coverage: ${plan.decision.title}`);
334
336
  lines.push('');
335
337
  lines.push(`${plan.decision.summary}`);
336
338
  lines.push('');
337
- // Build a readable coverage breakdown instead of raw P0/P1 counts
339
+ // Coverage breakdown: "3 covered ยท 2 new ยท 1 gap ยท 1 partial"
338
340
  const parts = [];
339
341
  if ((coveredCount ?? 0) > 0) {
340
342
  parts.push(`${coveredCount} covered`);
341
343
  }
344
+ if (flowsWithAdvisory.length > 0) {
345
+ parts.push(`${flowsWithAdvisory.length} new behavior`);
346
+ }
342
347
  if (uncoveredP0P1Flows > 0) {
343
348
  parts.push(`${uncoveredP0P1Flows} gap${uncoveredP0P1Flows !== 1 ? 's' : ''}`);
344
349
  }
@@ -347,6 +352,7 @@ export function renderCiSummaryMarkdown(plan) {
347
352
  }
348
353
  const breakdown = parts.length > 0 ? ` (${parts.join(' ยท ')})` : '';
349
354
  lines.push(`**${changedFiles}** files changed โ†’ **${impactedFlows}** features impacted${breakdown}`);
355
+ // โ”€โ”€ Blocking gaps โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
350
356
  if (mustAddTests && plan.requiredNewTests.length > 0) {
351
357
  lines.push('');
352
358
  lines.push('### โš ๏ธ Add E2E tests for these uncovered P0/P1 features');
@@ -355,32 +361,57 @@ export function renderCiSummaryMarkdown(plan) {
355
361
  lines.push('');
356
362
  for (const gap of plan.gapDetails.filter((g) => !g.name.includes('(partial)'))) {
357
363
  const aiLabel = gap.source === 'ai+deterministic' ? ' โœฆ AI-enriched' : '';
358
- lines.push(`- **${gap.name}** [${gap.priority}]${aiLabel}`);
364
+ lines.push(`> [!WARNING]`);
365
+ lines.push(`> **${gap.name}** ยท ${gap.priority}${aiLabel}`);
366
+ // AI-provided reasons (skip the first generic deterministic reason)
367
+ const aiReasons = gap.reasons.slice(1);
368
+ if (aiReasons.length > 0) {
369
+ lines.push(`> ${aiReasons.join(' ')}`);
370
+ }
359
371
  if (gap.missingScenarios && gap.missingScenarios.length > 0) {
372
+ lines.push(`>`);
373
+ lines.push(`> **Suggested test scenarios:**`);
360
374
  for (const scenario of gap.missingScenarios) {
361
- lines.push(` - ${scenario}`);
375
+ lines.push(`> - [ ] ${scenario}`);
362
376
  }
363
377
  }
364
- // Show AI-provided reasons (skip the first deterministic reason which is always included)
365
- const aiReasons = gap.reasons.slice(1);
366
- if (aiReasons.length > 0) {
367
- lines.push(` - *AI insight*: ${aiReasons.join('; ')}`);
378
+ lines.push('');
379
+ }
380
+ }
381
+ // โ”€โ”€ Advisory: covered flows with new behavior detected โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
382
+ if (flowsWithAdvisory.length > 0) {
383
+ lines.push('');
384
+ lines.push(`### ๐Ÿ’ก New behavior detected in ${flowsWithAdvisory.length} covered feature${flowsWithAdvisory.length !== 1 ? 's' : ''}`);
385
+ lines.push('');
386
+ lines.push('These features already have E2E tests, but this PR introduces new behavior worth covering:');
387
+ lines.push('');
388
+ for (const flow of flowsWithAdvisory) {
389
+ lines.push(`> [!TIP]`);
390
+ lines.push(`> **${flow.name}** ยท ${flow.priority} โ€” ${flow.coveredBy.join(', ')}`);
391
+ lines.push(`>`);
392
+ lines.push(`> Consider adding tests for:`);
393
+ for (const s of flow.advisoryScenarios) {
394
+ lines.push(`> - [ ] ${s}`);
368
395
  }
396
+ lines.push('');
369
397
  }
370
398
  }
371
- if (plan.coveredFlows.length > 0) {
399
+ // โ”€โ”€ Clean covered flows (collapsed) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
400
+ if (cleanFlows.length > 0 || flowsWithAdvisory.length > 0) {
372
401
  lines.push('');
373
- lines.push('### โœ… Covered features');
402
+ const label = cleanFlows.length > 0
403
+ ? `โœ… Covered flows (${cleanFlows.length})`
404
+ : `โœ… All covered flows have advisory notes above`;
405
+ lines.push(`<details><summary>${label}</summary>`);
374
406
  lines.push('');
375
- for (const flow of plan.coveredFlows) {
407
+ for (const flow of cleanFlows) {
376
408
  lines.push(`- **${flow.name}** [${flow.priority}] โ€” ${flow.coveredBy.join(', ')}`);
377
- if (flow.advisoryScenarios && flow.advisoryScenarios.length > 0) {
378
- lines.push(` ๐Ÿ’ก New behavior in this PR โ€” consider adding:`);
379
- for (const s of flow.advisoryScenarios) {
380
- lines.push(` - [ ] ${s}`);
381
- }
382
- }
383
409
  }
410
+ for (const flow of flowsWithAdvisory) {
411
+ lines.push(`- **${flow.name}** [${flow.priority}] โ€” ${flow.coveredBy.join(', ')} ๐Ÿ’ก`);
412
+ }
413
+ lines.push('');
414
+ lines.push('</details>');
384
415
  }
385
416
  if (plan.confidence < 100) {
386
417
  lines.push('');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yasserkhanorg/e2e-agents",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "Pluggable LLM provider library for AI-powered test automation. Use Claude, Ollama, or your own LLM. Integrate with Playwright, Jest, or any test framework. MCP server for test agents, cost tracking, and hybrid provider mode.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",