@netlify/axis 0.2.0 → 0.3.1

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.
Files changed (54) hide show
  1. package/README.md +24 -916
  2. package/dist/cli.js +6 -5
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config/validator.d.ts.map +1 -1
  5. package/dist/config/validator.js +2 -20
  6. package/dist/config/validator.js.map +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/report-ui/index.html +51 -45
  12. package/dist/reports/writer.d.ts +1 -1
  13. package/dist/reports/writer.d.ts.map +1 -1
  14. package/dist/reports/writer.js +2 -1
  15. package/dist/reports/writer.js.map +1 -1
  16. package/dist/runner/runner.d.ts.map +1 -1
  17. package/dist/runner/runner.js +18 -29
  18. package/dist/runner/runner.js.map +1 -1
  19. package/dist/scoring/index.d.ts +1 -7
  20. package/dist/scoring/index.d.ts.map +1 -1
  21. package/dist/scoring/index.js +1 -16
  22. package/dist/scoring/index.js.map +1 -1
  23. package/dist/scoring/sparse-index.d.ts +2 -2
  24. package/dist/scoring/sparse-index.d.ts.map +1 -1
  25. package/dist/scoring/sparse-index.js +8 -9
  26. package/dist/scoring/sparse-index.js.map +1 -1
  27. package/dist/skills/resolver.d.ts +2 -4
  28. package/dist/skills/resolver.d.ts.map +1 -1
  29. package/dist/skills/resolver.js +4 -10
  30. package/dist/skills/resolver.js.map +1 -1
  31. package/dist/transcript/categorize.d.ts +1 -3
  32. package/dist/transcript/categorize.d.ts.map +1 -1
  33. package/dist/transcript/categorize.js +0 -27
  34. package/dist/transcript/categorize.js.map +1 -1
  35. package/dist/types/config.d.ts +4 -17
  36. package/dist/types/config.d.ts.map +1 -1
  37. package/dist/types/report.d.ts +2 -0
  38. package/dist/types/report.d.ts.map +1 -1
  39. package/dist/types/scenario.d.ts +1 -2
  40. package/dist/types/scenario.d.ts.map +1 -1
  41. package/dist/types/scoring.d.ts +0 -4
  42. package/dist/types/scoring.d.ts.map +1 -1
  43. package/package.json +6 -3
  44. package/dist/docs-site/_astro/cli.DDWZtG0-.css +0 -1
  45. package/dist/docs-site/cli/index.html +0 -18
  46. package/dist/docs-site/configuration/index.html +0 -121
  47. package/dist/docs-site/content-assets.mjs +0 -1
  48. package/dist/docs-site/content-modules.mjs +0 -1
  49. package/dist/docs-site/data-store.json +0 -9
  50. package/dist/docs-site/index.html +0 -69
  51. package/dist/docs-site/quickstart/index.html +0 -59
  52. package/dist/docs-site/running/index.html +0 -87
  53. package/dist/docs-site/scoring/index.html +0 -135
  54. package/dist/report-ui/mock-data.json +0 -298
@@ -1,22 +1,25 @@
1
- <!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AXIS Report</title><style>:root{--bg: #faf9f5;--bg-card: #ffffff;--text: #141413;--text-secondary: #6b6962;--text-muted: #9a958d;--mid-gray: #b0aea5;--light-gray: #e8e6dc;--border: #e0ddd4;--accent: #d97757;--accent-hover: #c4654a;--accent-blue: #6a9bcc;--success: #788c5d;--success-light: #e8eddf;--yellow: #c9a227;--yellow-light: #faf3d8;--warning: #d97757;--warning-light: #fceee8;--danger: #c0392b;--danger-light: #fce4e1;--radius: 6px;--radius-lg: 10px;--shadow: 0 1px 3px rgba(20, 20, 19, .06), 0 2px 8px rgba(20, 20, 19, .04);--shadow-lg: 0 4px 16px rgba(20, 20, 19, .08);--font: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, sans-serif;--font-mono: "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;--transition: .2s ease}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{font-size:15px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{font-family:var(--font);color:var(--text);background:var(--bg);line-height:1.6;min-height:100vh}.container{max-width:1120px;margin:0 auto;padding:32px 24px 64px}h1{font-size:1.75rem;font-weight:600;letter-spacing:-.02em;color:var(--text)}h2{font-size:1.25rem;font-weight:600;letter-spacing:-.01em;color:var(--text)}h3{font-size:1rem;font-weight:600;color:var(--text)}.report-header{margin-bottom:32px}.report-title{display:flex;align-items:baseline;gap:12px;margin-bottom:4px}.report-title h1{flex-shrink:0}.report-id{font-family:var(--font-mono);font-size:.875rem;color:var(--text-secondary);font-weight:400}.report-timestamp{font-size:.8125rem;color:var(--text-muted);margin-bottom:24px;display:block}.summary-cards{display:flex;gap:12px;flex-wrap:wrap}.summary-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px;min-width:120px;flex:1;box-shadow:var(--shadow)}.summary-card .card-value{font-size:1.5rem;font-weight:700;color:var(--text);line-height:1.2;margin-bottom:2px}.summary-card .card-label{font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);font-weight:500}.summary-card.card-failed .card-value{color:var(--danger)}.score-badge{display:inline-flex;align-items:center;justify-content:center;min-width:36px;height:28px;padding:0 8px;border-radius:14px;font-size:.8125rem;font-weight:700;color:#fff;line-height:1}.score-badge.score-green{background:var(--success)}.score-badge.score-yellow{background:var(--yellow)}.score-badge.score-orange{background:var(--warning)}.score-badge.score-red{background:var(--danger)}.score-badge.score-na{background:var(--mid-gray);font-weight:500}.score-badge-lg{min-width:64px;height:64px;border-radius:32px;font-size:1.5rem;padding:0 16px}.results-section{margin-top:32px}.results-table{width:100%;border-collapse:collapse;font-size:.875rem}.results-table thead th{text-align:left;padding:10px 12px;font-size:.6875rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:600;border-bottom:2px solid var(--light-gray);white-space:nowrap}.results-table thead th.col-score{text-align:center;width:60px}.results-table thead th.col-right{text-align:right}.result-row{cursor:pointer;transition:background var(--transition)}.result-row:hover,.result-row.expanded{background:#00000005}.result-row td{padding:12px;border-bottom:1px solid var(--light-gray);vertical-align:middle}.result-row td.col-score{text-align:center}.result-row td.col-right{text-align:right;font-family:var(--font-mono);font-size:.8125rem;color:var(--text-secondary)}.result-row td.col-scenario{font-weight:500;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.result-row td.col-agent{color:var(--text-secondary);font-family:var(--font-mono);font-size:.8125rem}.result-row .expand-icon{display:inline-block;width:16px;color:var(--text-muted);transition:transform var(--transition);font-size:.75rem}.result-row.expanded .expand-icon{transform:rotate(90deg)}.result-row .error-hint{display:block;font-size:.75rem;color:var(--danger);margin-top:2px}.detail-row{display:none}.detail-row.visible{display:table-row}.detail-row td{padding:0;border-bottom:2px solid var(--light-gray)}.detail-panel{padding:24px;background:var(--bg)}.score-overview{display:flex;align-items:flex-start;gap:32px;margin-bottom:32px;padding-bottom:24px;border-bottom:1px solid var(--light-gray)}.score-overview .big-score{flex-shrink:0}.category-bars{flex:1;display:flex;flex-direction:column;gap:8px;padding-top:4px}.category-bar-row{display:flex;align-items:center;gap:12px}.category-bar-label{width:120px;font-size:.8125rem;font-weight:500;color:var(--text-secondary);flex-shrink:0}.category-bar-value{font-size:.8125rem;font-weight:600;width:32px;text-align:right;flex-shrink:0}.progress-bar{flex:1;height:8px;background:var(--light-gray);border-radius:4px;overflow:hidden;min-width:80px}.progress-bar .fill{height:100%;border-radius:4px;transition:width .4s ease}.progress-bar .fill.fill-green{background:var(--success)}.progress-bar .fill.fill-yellow{background:var(--yellow)}.progress-bar .fill.fill-orange{background:var(--warning)}.progress-bar .fill.fill-red{background:var(--danger)}.detail-sections{display:flex;flex-direction:column;gap:20px}.detail-section{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:20px;box-shadow:var(--shadow)}.section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.section-header h3{display:flex;align-items:center;gap:8px}.section-score{font-size:.875rem;font-weight:600;color:var(--text-secondary)}.criteria-list{display:flex;flex-direction:column;gap:12px}.criterion-item{padding:12px;background:var(--bg);border-radius:var(--radius);border:1px solid var(--light-gray)}.criterion-top{display:flex;align-items:center;gap:8px;margin-bottom:6px}.criterion-icon{font-size:.875rem;width:20px;text-align:center;flex-shrink:0}.criterion-icon.high{color:var(--success)}.criterion-icon.good{color:var(--yellow)}.criterion-icon.medium{color:var(--warning)}.criterion-icon.low{color:var(--danger)}.criterion-name{flex:1;font-size:.8125rem;font-weight:500}.criterion-score{font-size:.8125rem;font-weight:600;color:var(--text-secondary);flex-shrink:0}.criterion-weight{font-size:.6875rem;color:var(--text-muted);background:var(--light-gray);padding:1px 6px;border-radius:3px;flex-shrink:0}.criterion-bar{margin-bottom:8px}.criterion-rationale{font-size:.8125rem;color:var(--text-secondary);line-height:1.5;font-style:italic}.criterion-perfect{padding:8px 12px;background:var(--success-light);border-left:3px solid var(--success)}.criterion-perfect .criterion-bar{display:none}.criterion-imperfect{border-left:3px solid var(--warning)}.deductions-summary{background:var(--warning-light);border:1px solid var(--warning);border-radius:var(--radius);padding:14px 16px;margin-bottom:16px}.deductions-header{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--warning);margin-bottom:10px}.deduction-item{display:grid;grid-template-columns:1fr auto;gap:4px 12px;padding:6px 0;border-bottom:1px solid rgba(217,119,87,.15)}.deduction-item:last-child{border-bottom:none;padding-bottom:0}.deduction-criterion{font-size:.8125rem;font-weight:500;color:var(--text)}.deduction-lost{font-size:.75rem;font-weight:600;font-family:var(--font-mono);color:var(--warning);white-space:nowrap}.deduction-rationale{grid-column:1 / -1;font-size:.75rem;color:var(--text-secondary);line-height:1.5;font-style:italic}.dim-tags{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}.dim-tag{font-size:.6875rem;font-weight:600;font-family:var(--font-mono);padding:2px 8px;border-radius:10px;color:#fff}.dim-tag.fill-green{background:var(--success)}.dim-tag.fill-yellow{background:var(--yellow)}.dim-tag.fill-orange{background:var(--warning)}.dim-tag.fill-red{background:var(--danger)}.cat-deduction-item{padding:8px 0;border-bottom:1px solid rgba(217,119,87,.15)}.cat-deduction-item:last-child{border-bottom:none;padding-bottom:0}.cat-deduction-id{font-family:var(--font-mono);font-size:.75rem;font-weight:600;color:var(--text);margin-right:8px}.cat-deduction-scores{display:inline-flex;gap:4px}.dim-score-tag{font-size:.625rem;font-family:var(--font-mono);background:var(--light-gray);padding:1px 5px;border-radius:3px;color:var(--text-secondary)}.cat-deduction-rationale{display:block;font-size:.75rem;color:var(--text-secondary);line-height:1.5;font-style:italic;margin-top:4px}.cat-deduction-note{font-size:.75rem;color:var(--text-muted);font-style:italic}.deductions-baseline{background:var(--bg);border-color:var(--light-gray)}.deductions-baseline .deductions-header{color:var(--text-muted)}.dimensions-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px;margin-bottom:16px}.dimension-item{display:flex;align-items:center;gap:8px}.dimension-label{width:72px;font-size:.75rem;font-weight:500;color:var(--text-secondary);flex-shrink:0}.dimension-value{font-size:.75rem;font-weight:600;width:28px;text-align:right;flex-shrink:0}.interaction-meta{font-size:.75rem;color:var(--text-muted);margin-bottom:12px}.audits-section{margin-top:12px}.audits-toggle{font-size:.75rem;color:var(--accent-blue);background:none;border:none;cursor:pointer;font-family:var(--font);padding:4px 0;font-weight:500}.audits-toggle:hover{color:var(--accent)}.audits-list{display:none;margin-top:8px}.audits-list.visible{display:block}.audit-item{padding:10px 12px;background:var(--bg);border-radius:var(--radius);margin-bottom:6px;border-left:3px solid var(--mid-gray)}.audit-header{display:flex;align-items:center;gap:8px;margin-bottom:4px;flex-wrap:wrap}.audit-id{font-family:var(--font-mono);font-size:.75rem;font-weight:600;color:var(--text)}.audit-scores{font-family:var(--font-mono);font-size:.6875rem;color:var(--text-muted)}.audit-rationale{font-size:.8125rem;color:var(--text-secondary);line-height:1.5}.necessity-section{margin-top:12px;padding-top:12px;border-top:1px solid var(--light-gray)}.necessity-header{display:flex;align-items:center;gap:8px;margin-bottom:4px}.necessity-label{font-size:.75rem;font-weight:600;color:var(--text-secondary)}.necessity-score{font-size:.75rem;font-weight:600}.necessity-rationale{font-size:.8125rem;color:var(--text-secondary);font-style:italic}.waterfall{font-size:.8125rem}.waterfall-header{display:flex;align-items:flex-end;border-bottom:1px solid var(--light-gray);padding-bottom:6px;margin-bottom:2px}.wf-label-col{width:200px;flex-shrink:0;display:flex;align-items:center;gap:6px;overflow:hidden}.waterfall-header .wf-label-col,.waterfall-header .wf-dur-col{font-size:.6875rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:600}.wf-timeline-col{flex:1;min-width:0;position:relative}.wf-dur-col{width:64px;flex-shrink:0;text-align:right;font-family:var(--font-mono);font-size:.75rem;color:var(--text-secondary)}.wf-ticks{position:relative;height:18px}.wf-tick{position:absolute;transform:translate(-50%);font-family:var(--font-mono);font-size:.625rem;color:var(--text-muted);white-space:nowrap;top:0}.wf-tick:after{content:"";position:absolute;left:50%;top:100%;width:1px;height:4px;background:var(--light-gray)}.waterfall-body{position:relative}.wf-row{display:flex;align-items:center;height:26px;border-bottom:1px solid rgba(0,0,0,.03)}.wf-row:hover{background:#00000005}.wf-id{font-family:var(--font-mono);font-size:.6875rem;color:var(--text-muted);width:28px;flex-shrink:0}.wf-cat{font-size:.625rem;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);width:36px;flex-shrink:0}.wf-tool{font-size:.75rem;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wf-track{position:relative;height:14px;background:#00000004;border-radius:2px}.wf-bar{position:absolute;top:2px;height:10px;border-radius:2px;min-width:3px;cursor:default;transition:opacity var(--transition)}.wf-row:hover .wf-bar{opacity:.8}.wf-env .wf-bar{background:var(--success)}.wf-svc .wf-bar{background:var(--accent-blue)}.wf-agent .wf-bar{background:var(--mid-gray)}.wf-bar-error{background:var(--danger)!important}.wf-show-all{display:block;width:100%;margin-top:4px;padding:6px;font-size:.75rem;color:var(--accent-blue);background:none;border:1px dashed var(--light-gray);border-radius:var(--radius);cursor:pointer;font-family:var(--font);font-weight:500}.wf-show-all:hover{background:#6a9bcc0d;border-color:var(--accent-blue)}.wf-legend{display:flex;gap:16px;margin-top:10px;padding-top:8px;border-top:1px solid var(--light-gray)}.wf-legend-item{display:flex;align-items:center;gap:5px;font-size:.6875rem;color:var(--text-muted)}.wf-legend-dot{width:10px;height:10px;border-radius:2px}.wf-legend-dot.wf-env{background:var(--success)}.wf-legend-dot.wf-svc{background:var(--accent-blue)}.wf-legend-dot.wf-agent{background:var(--mid-gray)}.sparse-index-section{margin-top:16px}.sparse-index-toggle{font-size:.75rem;color:var(--accent-blue);background:none;border:none;cursor:pointer;font-family:var(--font);padding:4px 0;font-weight:500}.sparse-index-content{display:none;margin-top:8px}.sparse-index-content.visible{display:block}.sparse-line{font-family:var(--font-mono);font-size:.75rem;line-height:1.8;padding:3px 10px;border-left:3px solid var(--mid-gray);white-space:pre;overflow-x:auto}.sparse-line.cat-env{border-left-color:var(--success);background:#788c5d0a}.sparse-line.cat-svc{border-left-color:var(--accent-blue);background:#6a9bcc0a}.sparse-line.cat-agent{border-left-color:var(--mid-gray)}.sparse-line-expandable{cursor:pointer;position:relative}.sparse-line-expandable:after{content:"▶";position:absolute;right:8px;top:4px;font-size:.6rem;color:var(--text-secondary);transition:transform .15s ease}.sparse-line-expandable.expanded:after{transform:rotate(90deg)}.sparse-line-expandable:hover{background:#00000005}.sparse-line-content{display:none;margin:4px 0 8px 12px;padding:8px 12px;background:var(--bg-alt);border-radius:4px;border:1px solid var(--border)}.sparse-line-expandable.expanded .sparse-line-content{display:block}.sparse-line-content pre{margin:0;font-family:var(--font-mono);font-size:.7rem;line-height:1.5;white-space:pre-wrap;word-break:break-word;color:var(--text)}.sparse-expand-all{font-size:.75rem;color:var(--accent-blue);background:none;border:none;cursor:pointer;font-family:var(--font);padding:4px 0;font-weight:500;margin-left:12px}.info-btn{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;margin-left:6px;border:1px solid var(--light-gray);border-radius:50%;background:var(--bg-card);color:var(--accent-blue);font-size:.75rem;font-weight:600;cursor:pointer;vertical-align:middle;line-height:1;transition:background var(--transition),border-color var(--transition)}.info-btn:hover{background:#6a9bcc14;border-color:var(--accent-blue)}.modal-backdrop{display:none;position:fixed;inset:0;z-index:100;background:#14141373;align-items:center;justify-content:center;padding:24px}.modal-backdrop.visible{display:flex}.modal{background:var(--bg-card);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg),0 8px 32px #1414131f;max-width:640px;width:100%;max-height:80vh;overflow-y:auto;animation:modal-in .15s ease}@keyframes modal-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:20px 24px 16px;border-bottom:1px solid var(--light-gray)}.modal-header h3{font-size:1.0625rem;font-weight:600;margin-bottom:2px}.modal-subtitle{font-size:.75rem;font-family:var(--font-mono);color:var(--text-muted)}.modal-close{background:none;border:none;font-size:1.5rem;line-height:1;color:var(--text-muted);cursor:pointer;padding:0 4px;flex-shrink:0;transition:color var(--transition)}.modal-close:hover{color:var(--text)}.modal-body{padding:20px 24px 24px}.modal-section{margin-bottom:20px}.modal-section:last-child{margin-bottom:0}.modal-section h4{font-size:.6875rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:600;margin-bottom:8px}.modal-prompt{font-family:var(--font-mono);font-size:.8125rem;line-height:1.6;background:var(--bg);border:1px solid var(--light-gray);border-radius:var(--radius);padding:12px 16px;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow-y:auto}.modal-rubric-table{width:100%;border-collapse:collapse;font-size:.8125rem}.modal-rubric-table thead th{text-align:left;padding:6px 10px;font-size:.6875rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--light-gray)}.modal-rubric-table tbody td{padding:8px 10px;border-bottom:1px solid var(--light-gray);color:var(--text-secondary)}.modal-rubric-weight{width:60px;text-align:right;font-family:var(--font-mono);font-weight:600;color:var(--text)!important}.modal-config{display:flex;flex-direction:column;gap:6px}.modal-config-item{display:flex;align-items:baseline;gap:12px;font-size:.8125rem;padding:6px 10px;background:var(--bg);border-radius:var(--radius)}.modal-config-key{font-family:var(--font-mono);font-weight:600;color:var(--text);flex-shrink:0}.modal-config-val{font-family:var(--font-mono);color:var(--text-secondary);word-break:break-all}.error-banner{background:var(--danger-light);border:1px solid var(--danger);border-radius:var(--radius);padding:12px 16px;color:var(--danger);font-size:.875rem;font-weight:500;margin-bottom:16px}.loading{text-align:center;padding:80px 24px;color:var(--text-muted);font-size:1.125rem}.empty-state{text-align:center;padding:60px 24px;color:var(--text-muted)}.report-footer{margin-top:48px;padding-top:16px;border-top:1px solid var(--light-gray);text-align:center;font-size:.6875rem;color:var(--text-muted);letter-spacing:.02em}@media(max-width:768px){.container{padding:16px 12px 48px}.summary-cards{flex-direction:column}.summary-card{min-width:0}.score-overview{flex-direction:column;align-items:center;gap:16px}.dimensions-grid{grid-template-columns:1fr}.wf-label-col{width:120px}.wf-dur-col{width:48px}.wf-tool{font-size:.6875rem}.results-table{font-size:.8125rem}.results-table thead th.hide-mobile,.results-table tbody td.hide-mobile{display:none}.detail-panel{padding:16px 12px}}@media print{.detail-row{display:table-row!important}.audits-list,.sparse-index-content{display:block!important}.result-row{cursor:default}.wf-overflow{display:block!important}.wf-show-all,.expand-icon,.audits-toggle,.sparse-index-toggle,.info-btn,.modal-backdrop{display:none!important}}
2
- </style></head> <body> <div id="app"> <div class="loading">Loading report&hellip;</div> </div> <script id="axis-data" type="application/json">__AXIS_REPORT_DATA__</script> <script type="module">function x(e){return"averageAxisScore"in e}function o(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function u(e){return!Number.isFinite(e)||e<0?"—":e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`}function f(e){return e===void 0||e<=0?"—":`$${e.toFixed(4)}`}function A(e){try{return new Date(e).toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}catch{return e}}function y(e){return e>=90?"score-green":e>=80?"score-yellow":e>=70?"score-orange":"score-red"}function E(e){return e>=90?"fill-green":e>=80?"fill-yellow":e>=70?"fill-orange":"fill-red"}function v(e,s=!1){return e===void 0?`<span class="score-badge score-na${s?" score-badge-lg":""}">—</span>`:`<span class="score-badge ${y(e)}${s?" score-badge-lg":""}">${e}</span>`}function b(e,s=100){const t=Math.max(0,Math.min(100,e/s*100));return`<div class="progress-bar"><div class="fill ${E(t)}" style="width: ${t}%"></div></div>`}function k(e,s){return`
1
+ <!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AXIS Report</title><style>:root{--bg: #fafbf9;--bg-card: #ffffff;--bg-alt: #f3f4f6;--text: #1a1a2e;--text-secondary: #4a5568;--text-muted: #637083;--mid-gray: #6b7280;--light-gray: #e5e7eb;--border: #e5e7eb;--accent: #016867;--accent-hover: #015554;--accent-bright: #2dd4bf;--accent-light: rgba(1, 104, 103, .07);--success: #059669;--success-light: #ecfdf5;--yellow: #d97706;--yellow-light: #fffbeb;--warning: #d97706;--warning-light: #fffbeb;--danger: #dc2626;--danger-light: #fef2f2;--cat-env: #059669;--cat-svc: #2563eb;--cat-agent: #6b7280;--radius: 8px;--radius-lg: 12px;--shadow: 0 1px 3px rgba(0, 0, 0, .04), 0 2px 8px rgba(0, 0, 0, .03);--shadow-lg: 0 4px 16px rgba(0, 0, 0, .06), 0 0 40px rgba(1, 104, 103, .04);--font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, sans-serif;--font-mono: "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;--transition: .15s ease}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html{font-size:15px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{font-family:var(--font);color:var(--text);background:var(--bg);line-height:1.6;min-height:100vh}.container{max-width:1120px;margin:0 auto;padding:32px 24px 64px}h1{font-size:2rem;font-weight:800;letter-spacing:-.02em;background:linear-gradient(135deg,var(--text) 0%,var(--accent) 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}h2{font-size:1.375rem;font-weight:700;letter-spacing:-.01em;color:var(--text)}h3{font-size:1.0625rem;font-weight:600;color:var(--text)}.report-header{margin-bottom:32px}.report-branding{display:flex;align-items:baseline;gap:12px;margin-bottom:16px}.site-logo-mark{font-size:2.0625rem;font-weight:800;letter-spacing:.12em;color:var(--accent)}.logo-ax{letter-spacing:-.06em}.logo-i{display:inline-block;font-style:italic;transform:skew(-20deg);margin-left:2px;margin-right:-2px}.report-badge{font-size:.8125rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted)}.report-meta{margin-bottom:24px}.report-meta-row{font-size:.875rem;line-height:1.8;color:var(--text-secondary)}.report-meta-label{font-weight:600;color:var(--text)}.report-meta-value{color:var(--text-secondary)}.report-meta-id{font-family:var(--font-mono);font-size:.8125rem}.summary-cards{display:flex;gap:12px;flex-wrap:wrap}.summary-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px;min-width:120px;flex:1;box-shadow:var(--shadow);transition:box-shadow var(--transition)}.summary-card:hover{box-shadow:var(--shadow-lg)}.summary-card .card-value{font-size:1.5rem;font-weight:700;color:var(--text);line-height:1.2;margin-bottom:2px}.summary-card .card-label{font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);font-weight:500}.summary-card.card-failed .card-value{color:var(--danger)}.score-badge{display:inline-flex;align-items:center;justify-content:center;min-width:36px;height:28px;padding:0 8px;border-radius:14px;font-size:.8125rem;font-weight:700;color:#fff;line-height:1}.score-badge.score-green{background:var(--success)}.score-badge.score-yellow{background:var(--yellow)}.score-badge.score-orange{background:#ea580c}.score-badge.score-red{background:var(--danger)}.score-badge.score-na{background:var(--mid-gray);font-weight:500}.score-badge-lg{min-width:64px;height:64px;border-radius:32px;font-size:1.5rem;padding:0 16px}.results-section{margin-top:32px}.results-table{width:100%;border-collapse:collapse;font-size:.875rem}.results-table thead th{text-align:left;padding:10px 12px;font-size:.6875rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:600;border-bottom:2px solid var(--light-gray);white-space:nowrap}.results-table thead th.col-score{text-align:center;width:60px}.results-table thead th.col-right{text-align:right}.result-row{cursor:pointer;transition:background var(--transition)}.result-row:hover,.result-row.expanded{background:var(--accent-light)}.result-row td{padding:12px;border-bottom:1px solid var(--light-gray);vertical-align:middle}.result-row td.col-score{text-align:center}.result-row td.col-right{text-align:right;font-family:var(--font-mono);font-size:.8125rem;color:var(--text-secondary)}.result-row td.col-scenario{font-weight:500;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.result-row td.col-agent{color:var(--text-secondary);font-family:var(--font-mono);font-size:.8125rem}.result-row .expand-icon{display:inline-block;width:16px;color:var(--text-muted);transition:transform var(--transition);font-size:.75rem}.result-row.expanded .expand-icon{transform:rotate(90deg)}.result-row .error-hint{display:block;font-size:.75rem;color:var(--danger);margin-top:2px}.detail-row{display:none}.detail-row.visible{display:table-row}.detail-row td{padding:0;border-bottom:2px solid var(--light-gray)}.detail-panel{padding:24px;background:var(--bg)}.score-overview{display:flex;align-items:flex-start;gap:32px;margin-bottom:32px;padding-bottom:24px;border-bottom:1px solid var(--light-gray)}.score-overview .big-score{flex-shrink:0}.category-bars{flex:1;display:flex;flex-direction:column;gap:8px;padding-top:4px}.category-bar-row{display:flex;align-items:center;gap:12px}.category-bar-label{width:120px;font-size:.8125rem;font-weight:500;color:var(--text-secondary);flex-shrink:0}.category-bar-value{font-size:.8125rem;font-weight:600;width:32px;text-align:right;flex-shrink:0}.progress-bar{flex:1;height:8px;background:var(--light-gray);border-radius:4px;overflow:hidden;min-width:80px}.progress-bar .fill{height:100%;border-radius:4px;transition:width .4s ease}.progress-bar .fill.fill-green{background:var(--success)}.progress-bar .fill.fill-yellow{background:var(--yellow)}.progress-bar .fill.fill-orange{background:#ea580c}.progress-bar .fill.fill-red{background:var(--danger)}.detail-sections{display:flex;flex-direction:column;gap:20px}.detail-section{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:20px;box-shadow:var(--shadow)}.section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.section-header h3{display:flex;align-items:center;gap:8px}.section-score{font-size:.875rem;font-weight:600;color:var(--text-secondary)}.criteria-list{display:flex;flex-direction:column;gap:12px}.criterion-item{padding:12px;background:var(--bg);border-radius:var(--radius);border:1px solid var(--light-gray)}.criterion-top{display:flex;align-items:center;gap:8px;margin-bottom:6px}.criterion-icon{font-size:.875rem;width:20px;text-align:center;flex-shrink:0}.criterion-icon.high{color:var(--success)}.criterion-icon.good{color:var(--yellow)}.criterion-icon.medium{color:#ea580c}.criterion-icon.low{color:var(--danger)}.criterion-name{flex:1;font-size:.8125rem;font-weight:500}.criterion-score{font-size:.8125rem;font-weight:600;color:var(--text-secondary);flex-shrink:0}.criterion-weight{font-size:.6875rem;color:var(--text-muted);background:var(--light-gray);padding:1px 6px;border-radius:3px;flex-shrink:0}.criterion-bar{margin-bottom:8px}.criterion-rationale{font-size:.8125rem;color:var(--text-secondary);line-height:1.5;font-style:italic}.criterion-perfect{padding:8px 12px;background:var(--success-light);border-left:3px solid var(--success)}.criterion-perfect .criterion-bar{display:none}.criterion-imperfect{border-left:3px solid var(--warning)}.deductions-summary{background:var(--warning-light);border:1px solid var(--warning);border-radius:var(--radius);padding:14px 16px;margin-bottom:16px}.deductions-header{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--warning);margin-bottom:10px}.deduction-item{display:grid;grid-template-columns:1fr auto;gap:4px 12px;padding:6px 0;border-bottom:1px solid rgba(217,119,6,.15)}.deduction-item:last-child{border-bottom:none;padding-bottom:0}.deduction-criterion{font-size:.8125rem;font-weight:500;color:var(--text)}.deduction-lost{font-size:.75rem;font-weight:600;font-family:var(--font-mono);color:var(--warning);white-space:nowrap}.deduction-rationale{grid-column:1 / -1;font-size:.75rem;color:var(--text-secondary);line-height:1.5;font-style:italic}.dim-tags{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}.dim-tag{font-size:.6875rem;font-weight:600;font-family:var(--font-mono);padding:2px 8px;border-radius:10px;color:#fff}.dim-tag.fill-green{background:var(--success)}.dim-tag.fill-yellow{background:var(--yellow)}.dim-tag.fill-orange{background:#ea580c}.dim-tag.fill-red{background:var(--danger)}.cat-deduction-item{padding:8px 0;border-bottom:1px solid rgba(217,119,6,.15)}.cat-deduction-item:last-child{border-bottom:none;padding-bottom:0}.cat-deduction-id{font-family:var(--font-mono);font-size:.75rem;font-weight:600;color:var(--text);margin-right:8px}.cat-deduction-scores{display:inline-flex;gap:4px}.dim-score-tag{font-size:.625rem;font-family:var(--font-mono);background:var(--light-gray);padding:1px 5px;border-radius:3px;color:var(--text-secondary)}.cat-deduction-rationale{display:block;font-size:.75rem;color:var(--text-secondary);line-height:1.5;font-style:italic;margin-top:4px}.cat-deduction-note{font-size:.75rem;color:var(--text-muted);font-style:italic}.deductions-baseline{background:var(--bg);border-color:var(--light-gray)}.deductions-baseline .deductions-header{color:var(--text-muted)}.dimensions-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px;margin-bottom:16px}.dimension-item{display:flex;align-items:center;gap:8px}.dimension-label{width:72px;font-size:.75rem;font-weight:500;color:var(--text-secondary);flex-shrink:0}.dimension-value{font-size:.75rem;font-weight:600;width:28px;text-align:right;flex-shrink:0}.interaction-meta{font-size:.75rem;color:var(--text-muted);margin-bottom:12px}.audits-section{margin-top:12px}.audits-toggle{font-size:.75rem;color:var(--accent);background:none;border:none;cursor:pointer;font-family:var(--font);padding:4px 0;font-weight:500}.audits-toggle:hover{color:var(--accent-hover)}.audits-list{display:none;margin-top:8px}.audits-list.visible{display:block}.audit-item{padding:10px 12px;background:var(--bg);border-radius:var(--radius);margin-bottom:6px;border-left:3px solid var(--mid-gray)}.audit-header{display:flex;align-items:center;gap:8px;margin-bottom:4px;flex-wrap:wrap}.audit-id{font-family:var(--font-mono);font-size:.75rem;font-weight:600;color:var(--text)}.audit-scores{font-family:var(--font-mono);font-size:.6875rem;color:var(--text-muted)}.audit-rationale{font-size:.8125rem;color:var(--text-secondary);line-height:1.5}.necessity-section{margin-top:12px;padding-top:12px;border-top:1px solid var(--light-gray)}.necessity-header{display:flex;align-items:center;gap:8px;margin-bottom:4px}.necessity-label{font-size:.75rem;font-weight:600;color:var(--text-secondary)}.necessity-score{font-size:.75rem;font-weight:600}.necessity-rationale{font-size:.8125rem;color:var(--text-secondary);font-style:italic}.waterfall{font-size:.8125rem}.waterfall-header{display:flex;align-items:flex-end;border-bottom:1px solid var(--light-gray);padding-bottom:6px;margin-bottom:2px}.wf-label-col{width:200px;flex-shrink:0;display:flex;align-items:center;gap:6px;overflow:hidden}.waterfall-header .wf-label-col,.waterfall-header .wf-dur-col{font-size:.6875rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:600}.wf-timeline-col{flex:1;min-width:0;position:relative}.wf-dur-col{width:64px;flex-shrink:0;text-align:right;font-family:var(--font-mono);font-size:.75rem;color:var(--text-secondary)}.wf-ticks{position:relative;height:18px}.wf-tick{position:absolute;transform:translate(-50%);font-family:var(--font-mono);font-size:.625rem;color:var(--text-muted);white-space:nowrap;top:0}.wf-tick:after{content:"";position:absolute;left:50%;top:100%;width:1px;height:4px;background:var(--light-gray)}.waterfall-body{position:relative}.wf-row{display:flex;align-items:center;height:26px;border-bottom:1px solid rgba(0,0,0,.03)}.wf-row:hover{background:var(--accent-light)}.wf-id{font-family:var(--font-mono);font-size:.6875rem;color:var(--text-muted);width:28px;flex-shrink:0}.wf-cat{font-size:.625rem;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);width:36px;flex-shrink:0}.wf-tool{font-size:.75rem;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wf-track{position:relative;height:14px;background:#00000004;border-radius:2px}.wf-bar{position:absolute;top:2px;height:10px;border-radius:2px;min-width:3px;cursor:default;transition:opacity var(--transition)}.wf-row:hover .wf-bar{opacity:.8}.wf-env .wf-bar{background:var(--cat-env)}.wf-svc .wf-bar{background:var(--cat-svc)}.wf-agent .wf-bar{background:var(--cat-agent)}.wf-bar-error{background:var(--danger)!important}.wf-show-all{display:block;width:100%;margin-top:4px;padding:6px;font-size:.75rem;color:var(--accent);background:none;border:1px dashed var(--light-gray);border-radius:var(--radius);cursor:pointer;font-family:var(--font);font-weight:500}.wf-show-all:hover{background:var(--accent-light);border-color:var(--accent)}.wf-legend{display:flex;gap:16px;margin-top:10px;padding-top:8px;border-top:1px solid var(--light-gray)}.wf-legend-item{display:flex;align-items:center;gap:5px;font-size:.6875rem;color:var(--text-muted)}.wf-legend-dot{width:10px;height:10px;border-radius:2px}.wf-legend-dot.wf-env{background:var(--cat-env)}.wf-legend-dot.wf-svc{background:var(--cat-svc)}.wf-legend-dot.wf-agent{background:var(--cat-agent)}.sparse-index-section{margin-top:16px}.sparse-index-toggle{font-size:.75rem;color:var(--accent);background:none;border:none;cursor:pointer;font-family:var(--font);padding:4px 0;font-weight:500}.sparse-index-content{display:none;margin-top:8px}.sparse-index-content.visible{display:block}.sparse-line{font-family:var(--font-mono);font-size:.75rem;line-height:1.8;padding:3px 10px;border-left:3px solid var(--cat-agent);white-space:pre;overflow-x:auto}.sparse-line.cat-env{border-left-color:var(--cat-env);background:#0596690a}.sparse-line.cat-svc{border-left-color:var(--cat-svc);background:#2563eb0a}.sparse-line.cat-agent{border-left-color:var(--cat-agent)}.sparse-line-expandable{cursor:pointer;position:relative}.sparse-line-expandable:after{content:"▶";position:absolute;right:8px;top:4px;font-size:.6rem;color:var(--text-secondary);transition:transform .15s ease}.sparse-line-expandable.expanded:after{transform:rotate(90deg)}.sparse-line-expandable:hover{background:var(--accent-light)}.sparse-line-content{display:none;margin:4px 0 8px 12px;padding:8px 12px;background:var(--bg-alt);border-radius:4px;border:1px solid var(--border)}.sparse-line-expandable.expanded .sparse-line-content{display:block}.sparse-line-content pre{margin:0;font-family:var(--font-mono);font-size:.7rem;line-height:1.5;white-space:pre-wrap;word-break:break-word;color:var(--text)}.sparse-expand-all{font-size:.75rem;color:var(--accent);background:none;border:none;cursor:pointer;font-family:var(--font);padding:4px 0;font-weight:500;margin-left:12px}.info-btn{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;margin-left:6px;border:1px solid var(--light-gray);border-radius:50%;background:var(--bg-card);color:var(--accent);font-size:.75rem;font-weight:600;cursor:pointer;vertical-align:middle;line-height:1;transition:background var(--transition),border-color var(--transition)}.info-btn:hover{background:var(--accent-light);border-color:var(--accent)}.modal-backdrop{display:none;position:fixed;inset:0;z-index:100;background:#1a1a2e73;align-items:center;justify-content:center;padding:24px}.modal-backdrop.visible{display:flex}.modal{background:var(--bg-card);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg),0 8px 32px #0000001f;max-width:640px;width:100%;max-height:80vh;overflow-y:auto;animation:modal-in .15s ease}@keyframes modal-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:20px 24px 16px;border-bottom:1px solid var(--light-gray)}.modal-header h3{font-size:1.0625rem;font-weight:600;margin-bottom:2px}.modal-subtitle{font-size:.75rem;font-family:var(--font-mono);color:var(--text-muted)}.modal-close{background:none;border:none;font-size:1.5rem;line-height:1;color:var(--text-muted);cursor:pointer;padding:0 4px;flex-shrink:0;transition:color var(--transition)}.modal-close:hover{color:var(--text)}.modal-body{padding:20px 24px 24px}.modal-section{margin-bottom:20px}.modal-section:last-child{margin-bottom:0}.modal-section h4{font-size:.6875rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:600;margin-bottom:8px}.modal-prompt{font-family:var(--font-mono);font-size:.8125rem;line-height:1.6;background:var(--bg);border:1px solid var(--light-gray);border-radius:var(--radius);padding:12px 16px;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow-y:auto}.modal-rubric-table{width:100%;border-collapse:collapse;font-size:.8125rem}.modal-rubric-table thead th{text-align:left;padding:6px 10px;font-size:.6875rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--light-gray)}.modal-rubric-table tbody td{padding:8px 10px;border-bottom:1px solid var(--light-gray);color:var(--text-secondary)}.modal-rubric-weight{width:60px;text-align:right;font-family:var(--font-mono);font-weight:600;color:var(--text)!important}.modal-config{display:flex;flex-direction:column;gap:6px}.modal-config-item{display:flex;align-items:baseline;gap:12px;font-size:.8125rem;padding:6px 10px;background:var(--bg);border-radius:var(--radius)}.modal-config-key{font-family:var(--font-mono);font-weight:600;color:var(--text);flex-shrink:0}.modal-config-val{font-family:var(--font-mono);color:var(--text-secondary);word-break:break-all}.error-banner{background:var(--danger-light);border:1px solid var(--danger);border-radius:var(--radius);padding:12px 16px;color:var(--danger);font-size:.875rem;font-weight:500;margin-bottom:16px}.loading{text-align:center;padding:80px 24px;color:var(--text-muted);font-size:1.125rem}.empty-state{text-align:center;padding:60px 24px;color:var(--text-muted)}@media(max-width:768px){.container{padding:16px 12px 48px}.summary-cards{flex-direction:column}.summary-card{min-width:0}.score-overview{flex-direction:column;align-items:center;gap:16px}.dimensions-grid{grid-template-columns:1fr}.wf-label-col{width:120px}.wf-dur-col{width:48px}.wf-tool{font-size:.6875rem}.results-table{font-size:.8125rem}.results-table thead th.hide-mobile,.results-table tbody td.hide-mobile{display:none}.detail-panel{padding:16px 12px}}@media print{.detail-row{display:table-row!important}.audits-list,.sparse-index-content{display:block!important}.result-row{cursor:default}.wf-overflow{display:block!important}.wf-show-all,.expand-icon,.audits-toggle,.sparse-index-toggle,.info-btn,.modal-backdrop{display:none!important}}
2
+ </style></head> <body> <div id="app"> <div class="loading">Loading report&hellip;</div> </div> <script id="axis-data" type="application/json">__AXIS_REPORT_DATA__</script> <script type="module">function C(e){return"averageAxisScore"in e}function o(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function u(e){return!Number.isFinite(e)||e<0?"—":e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`}function f(e){return e===void 0||e<=0?"—":`$${e.toFixed(4)}`}function w(e){if(!e)return"—";const s=e.input+e.output+(e.cacheReadInput??0);return s===0?"—":s>=1e6?`${(s/1e6).toFixed(1)}M`:s>=1e3?`${(s/1e3).toFixed(1)}k`:s.toLocaleString()}function A(e){try{return new Date(e).toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}catch{return e}}function E(e){return e>=90?"score-green":e>=80?"score-yellow":e>=70?"score-orange":"score-red"}function x(e){return e>=90?"fill-green":e>=80?"fill-yellow":e>=70?"fill-orange":"fill-red"}function v(e,s=!1){return e===void 0?`<span class="score-badge score-na${s?" score-badge-lg":""}">—</span>`:`<span class="score-badge ${E(e)}${s?" score-badge-lg":""}">${e}</span>`}function b(e,s=100){const t=Math.max(0,Math.min(100,e/s*100));return`<div class="progress-bar"><div class="fill ${x(t)}" style="width: ${t}%"></div></div>`}function L(e,s){return`
3
3
  <div class="dimension-item">
4
4
  <span class="dimension-label">${o(e)}</span>
5
5
  ${b(s)}
6
6
  <span class="dimension-value">${s}</span>
7
- </div>`}function L(e){return`
7
+ </div>`}function R(e){return`
8
8
  <div class="container">
9
- ${R(e)}
10
9
  ${M(e)}
11
- <footer class="report-footer">AXIS — Agent eXperience Index Score</footer>
10
+ ${I(e)}
12
11
  </div>
13
- ${J(e.results)}`}function R(e){const s=x(e.summary),t=e.results.reduce((a,n)=>a+(n.totalCostUsd??0),0);return`
12
+ ${K(e.results)}`}function M(e){const s=C(e.summary),t=e.results.reduce((a,n)=>a+(n.totalCostUsd??0),0);return`
14
13
  <header class="report-header">
15
- <div class="report-title">
16
- <h1>AXIS Report</h1>
17
- <span class="report-id">${o(e.reportId)}</span>
14
+ <div class="report-branding">
15
+ <span class="site-logo-mark"><span class="logo-ax">AX</span><span class="logo-i">I</span>S</span>
16
+ <span class="report-badge">Report</span>
17
+ </div>
18
+ <div class="report-meta">
19
+ ${e.name?`<div class="report-meta-row"><span class="report-meta-label">Report name:</span> <span class="report-meta-value">${o(e.name)}</span></div>`:""}
20
+ <div class="report-meta-row"><span class="report-meta-label">Generated on:</span> <span class="report-meta-value">${A(e.timestamp)}</span></div>
21
+ <div class="report-meta-row"><span class="report-meta-label">ID:</span> <span class="report-meta-value report-meta-id">${o(e.reportId)}</span></div>
18
22
  </div>
19
- <span class="report-timestamp">${A(e.timestamp)}</span>
20
23
  <div class="summary-cards">
21
24
  <div class="summary-card">
22
25
  <div class="card-value">${e.summary.total}</div>
@@ -44,7 +47,7 @@
44
47
  <div class="card-label">Total Cost</div>
45
48
  </div>
46
49
  </div>
47
- </header>`}function M(e){if(e.results.length===0)return'<div class="empty-state">No results in this report.</div>';const s=e.results.some(a=>a.score!==void 0),t=e.results.map((a,n)=>I(a,n,s)+D(a,n)).join("");return`
50
+ </header>`}function I(e){if(e.results.length===0)return'<div class="empty-state">No results in this report.</div>';const s=e.results.some(a=>a.score!==void 0),t=e.results.map((a,n)=>D(a,n,s)+T(a,n)).join("");return`
48
51
  <section class="results-section">
49
52
  <table class="results-table">
50
53
  <thead>
@@ -59,13 +62,14 @@
59
62
  <th class="col-score hide-mobile">Svc</th>
60
63
  <th class="col-score hide-mobile">Agent</th>`:`
61
64
  <th class="col-score">Status</th>`}
65
+ <th class="col-right hide-mobile">Tokens</th>
62
66
  <th class="col-right hide-mobile">Duration</th>
63
67
  <th class="col-right hide-mobile">Cost</th>
64
68
  </tr>
65
69
  </thead>
66
70
  <tbody>${t}</tbody>
67
71
  </table>
68
- </section>`}function I(e,s,t){const a=e.score,n=e.exitCode!==0||!!e.error,i=e.error?`<span class="error-hint">${o(se(e.error))}</span>`:"",c=e.prompt?`<button class="info-btn" data-modal-index="${s}" title="View scenario settings">ℹ</button>`:"";if(t)return`
72
+ </section>`}function D(e,s,t){const a=e.score,n=e.exitCode!==0||!!e.error,i=e.error?`<span class="error-hint">${o(te(e.error))}</span>`:"",c=e.prompt?`<button class="info-btn" data-modal-index="${s}" title="View scenario settings">ℹ</button>`:"";if(t)return`
69
73
  <tr class="result-row" data-index="${s}">
70
74
  <td><span class="expand-icon">▶</span></td>
71
75
  <td class="col-scenario">${o(e.scenarioName)}${c}${i}</td>
@@ -75,6 +79,7 @@
75
79
  <td class="col-score hide-mobile">${v(a?.environment.score)}</td>
76
80
  <td class="col-score hide-mobile">${v(a?.service.score)}</td>
77
81
  <td class="col-score hide-mobile">${v(a?.agent.score)}</td>
82
+ <td class="col-right hide-mobile">${w(e.tokenUsage)}</td>
78
83
  <td class="col-right hide-mobile">${u(e.durationMs)}</td>
79
84
  <td class="col-right hide-mobile">${f(e.totalCostUsd)}</td>
80
85
  </tr>`;const l=n?'<span class="score-badge score-red">Fail</span>':'<span class="score-badge score-green">Pass</span>';return`
@@ -83,17 +88,18 @@
83
88
  <td class="col-scenario">${o(e.scenarioName)}${c}${i}</td>
84
89
  <td class="col-agent">${o(e.agentName)}</td>
85
90
  <td class="col-score">${l}</td>
91
+ <td class="col-right hide-mobile">${w(e.tokenUsage)}</td>
86
92
  <td class="col-right hide-mobile">${u(e.durationMs)}</td>
87
93
  <td class="col-right hide-mobile">${f(e.totalCostUsd)}</td>
88
- </tr>`}function D(e,s){const t=e.score?10:7;return`
94
+ </tr>`}function T(e,s){const t=e.score?11:8;return`
89
95
  <tr class="detail-row" id="detail-${s}">
90
96
  <td colspan="${t}">
91
97
  <div class="detail-panel">
92
98
  ${e.error?`<div class="error-banner">${o(e.error)}</div>`:""}
93
- ${e.score?N(e.score):T(e)}
99
+ ${e.score?j(e.score):N(e)}
94
100
  </div>
95
101
  </td>
96
- </tr>`}function T(e){const s=[];return e.tokenUsage&&(s.push(`Input: ${e.tokenUsage.input.toLocaleString()}`),s.push(`Output: ${e.tokenUsage.output.toLocaleString()}`),e.tokenUsage.cacheReadInput&&s.push(`Cache: ${e.tokenUsage.cacheReadInput.toLocaleString()}`)),`
102
+ </tr>`}function N(e){const s=[];return e.tokenUsage&&(s.push(`Input: ${e.tokenUsage.input.toLocaleString()}`),s.push(`Output: ${e.tokenUsage.output.toLocaleString()}`),e.tokenUsage.cacheReadInput&&s.push(`Cache: ${e.tokenUsage.cacheReadInput.toLocaleString()}`)),`
97
103
  <div class="detail-sections">
98
104
  <div class="detail-section">
99
105
  <div class="section-header"><h3>Run Details</h3></div>
@@ -103,7 +109,7 @@
103
109
  ${e.totalCostUsd?` &middot; Cost: ${f(e.totalCostUsd)}`:""}
104
110
  </p>
105
111
  </div>
106
- </div>`}function N(e){return`
112
+ </div>`}function j(e){return`
107
113
  <div class="score-overview">
108
114
  ${v(e.axisScore,!0)}
109
115
  <div class="category-bars">
@@ -114,18 +120,18 @@
114
120
  </div>
115
121
  </div>
116
122
  <div class="detail-sections">
117
- ${e.sparseIndex?_(e.sparseIndex):""}
118
- ${j(e.goalAchievement)}
123
+ ${e.sparseIndex?G(e.sparseIndex):""}
124
+ ${q(e.goalAchievement)}
119
125
  ${h("Environment",e.environment)}
120
126
  ${h("Service",e.service)}
121
127
  ${h("Agent",e.agent)}
122
- ${e.sparseIndex?V(e.sparseIndex):""}
128
+ ${e.sparseIndex?J(e.sparseIndex):""}
123
129
  </div>`}function p(e,s){return`
124
130
  <div class="category-bar-row">
125
131
  <span class="category-bar-label">${e}</span>
126
132
  ${b(s)}
127
133
  <span class="category-bar-value">${s}</span>
128
- </div>`}function j(e){const s=e.criteria.filter(n=>n.score<10),t=s.length>0?q(s):"",a=e.criteria.map(P).join("");return`
134
+ </div>`}function q(e){const s=e.criteria.filter(n=>n.score<10),t=s.length>0?P(s):"",a=e.criteria.map(F).join("");return`
129
135
  <div class="detail-section">
130
136
  <div class="section-header">
131
137
  <h3>Goal Achievement</h3>
@@ -133,7 +139,7 @@
133
139
  </div>
134
140
  ${t}
135
141
  <div class="criteria-list">${a}</div>
136
- </div>`}function q(e){return`
142
+ </div>`}function P(e){return`
137
143
  <div class="deductions-summary">
138
144
  <div class="deductions-header">Areas for improvement</div>
139
145
  ${e.map(t=>{const a=10-t.score;return`
@@ -142,7 +148,7 @@
142
148
  <span class="deduction-lost">-${a} pts</span>
143
149
  <span class="deduction-rationale">${o(t.rationale)}</span>
144
150
  </div>`}).join("")}
145
- </div>`}function P(e){const s=e.score===10,t=e.score*10,a=t>=90||t>=80?"✔":t>=70?"◐":"✗",n=t>=90?"high":t>=80?"good":t>=70?"medium":"low",i=Math.round(e.weight*100);return`
151
+ </div>`}function F(e){const s=e.score===10,t=e.score*10,a=t>=90||t>=80?"✔":t>=70?"◐":"✗",n=t>=90?"high":t>=80?"good":t>=70?"medium":"low",i=Math.round(e.weight*100);return`
146
152
  <div class="${s?"criterion-item criterion-perfect":"criterion-item criterion-imperfect"}">
147
153
  <div class="criterion-top">
148
154
  <span class="criterion-icon ${n}">${a}</span>
@@ -152,7 +158,7 @@
152
158
  </div>
153
159
  <div class="criterion-bar">${b(e.score,10)}</div>
154
160
  ${s?"":`<div class="criterion-rationale">${o(e.rationale)}</div>`}
155
- </div>`}function h(e,s){const t=s.dimensions,a=s.audits.filter(d=>d.rationale!=="default"),n=a.length>0,i=[{label:"Success",value:t.success},{label:"Speed",value:t.speed},{label:"Relevance",value:t.relevance},{label:"Necessity",value:t.necessity}],c=i.filter(d=>d.value<100),l=n?`<div class="dimensions-grid">${i.map(d=>k(d.label,d.value)).join("")}</div>`:"",r=c.length>0?B(c,a):"";return`
161
+ </div>`}function h(e,s){const t=s.dimensions,a=s.audits.filter(d=>d.rationale!=="default"),n=a.length>0,i=[{label:"Success",value:t.success},{label:"Speed",value:t.speed},{label:"Relevance",value:t.relevance},{label:"Necessity",value:t.necessity}],c=i.filter(d=>d.value<100),l=n?`<div class="dimensions-grid">${i.map(d=>L(d.label,d.value)).join("")}</div>`:"",r=c.length>0?U(c,a):"";return`
156
162
  <div class="detail-section">
157
163
  <div class="section-header">
158
164
  <h3>${o(e)}</h3>
@@ -164,23 +170,23 @@
164
170
  </div>
165
171
  ${l}
166
172
  ${r}
167
- ${n?U(a):""}
168
- ${H(s.necessity)}
169
- </div>`}function B(e,s,t){const a=e.map(i=>`<span class="dim-tag ${E(i.value)}">${i.label}: ${i.value}</span>`).join(""),n=s.map(i=>`
173
+ ${n?O(a):""}
174
+ ${_(s.necessity)}
175
+ </div>`}function U(e,s,t){const a=e.map(i=>`<span class="dim-tag ${x(i.value)}">${i.label}: ${i.value}</span>`).join(""),n=s.map(i=>`
170
176
  <div class="cat-deduction-item">
171
177
  <span class="cat-deduction-id">#${i.id}</span>
172
- <span class="cat-deduction-scores">${F(i)}</span>
178
+ <span class="cat-deduction-scores">${B(i)}</span>
173
179
  <span class="cat-deduction-rationale">${o(i.rationale)}</span>
174
180
  </div>`).join("");return`
175
181
  <div class="deductions-summary">
176
182
  <div class="deductions-header">Score breakdown</div>
177
183
  <div class="dim-tags">${a}</div>
178
184
  ${n}
179
- </div>`}function F(e){return[{label:"Success",value:e.success},{label:"Speed",value:e.speed},{label:"Relevance",value:e.contextRelevance}].filter(t=>t.value<1).map(t=>`<span class="dim-score-tag">${t.label}: ${m(t.value)}</span>`).join("")}function U(e){const s=e.map(O).join("");return`
185
+ </div>`}function B(e){return[{label:"Success",value:e.success},{label:"Speed",value:e.speed},{label:"Relevance",value:e.contextRelevance}].filter(t=>t.value<1).map(t=>`<span class="dim-score-tag">${t.label}: ${m(t.value)}</span>`).join("")}function O(e){const s=e.map(H).join("");return`
180
186
  <div class="audits-section">
181
187
  <button class="audits-toggle">Show audits (${e.length})</button>
182
188
  <div class="audits-list">${s}</div>
183
- </div>`}function O(e){return`
189
+ </div>`}function H(e){return`
184
190
  <div class="audit-item">
185
191
  <div class="audit-header">
186
192
  <span class="audit-id">#${e.id}</span>
@@ -189,15 +195,15 @@
189
195
  </span>
190
196
  </div>
191
197
  <div class="audit-rationale">${o(e.rationale)}</div>
192
- </div>`}function m(e){return(e*100).toFixed(0)}function H(e){if(e.rationale==="default")return"";const s=Math.round(e.score*100),t=e.unnecessaryIds.length>0?` &middot; Unnecessary: #${e.unnecessaryIds.join(", #")}`:"";return`
198
+ </div>`}function m(e){return(e*100).toFixed(0)}function _(e){if(e.rationale==="default")return"";const s=Math.round(e.score*100),t=e.unnecessaryIds.length>0?` &middot; Unnecessary: #${e.unnecessaryIds.join(", #")}`:"";return`
193
199
  <div class="necessity-section">
194
200
  <div class="necessity-header">
195
201
  <span class="necessity-label">Necessity</span>
196
- <span class="necessity-score ${y(s)}">${s}/100</span>
202
+ <span class="necessity-score ${E(s)}">${s}/100</span>
197
203
  ${t}
198
204
  </div>
199
205
  <div class="necessity-rationale">${o(e.rationale)}</div>
200
- </div>`}const $=30;function _(e){const{interactions:s}=e;if(!s.some(r=>r.startMs!==null)||s.length===0)return"";const a=e.stats.wallClockMs||G(s);if(a<=0)return"";const n=z(a),i=s.length>$,c=i?s.slice(0,$):s,l=i?s.slice($):[];return`
206
+ </div>`}const $=30;function G(e){const{interactions:s}=e;if(!s.some(r=>r.startMs!==null)||s.length===0)return"";const a=e.stats.wallClockMs||z(s);if(a<=0)return"";const n=V(a),i=s.length>$,c=i?s.slice(0,$):s,l=i?s.slice($):[];return`
201
207
  <div class="detail-section">
202
208
  <div class="section-header">
203
209
  <h3>Timeline</h3>
@@ -214,8 +220,8 @@
214
220
  <div class="wf-dur-col">Duration</div>
215
221
  </div>
216
222
  <div class="waterfall-body">
217
- ${c.map(r=>w(r,a)).join("")}
218
- ${i?`<div class="wf-overflow" style="display:none">${l.map(r=>w(r,a)).join("")}</div>`:""}
223
+ ${c.map(r=>S(r,a)).join("")}
224
+ ${i?`<div class="wf-overflow" style="display:none">${l.map(r=>S(r,a)).join("")}</div>`:""}
219
225
  </div>
220
226
  ${i?`<button class="wf-show-all">Show all ${s.length} interactions</button>`:""}
221
227
  <div class="wf-legend">
@@ -224,7 +230,7 @@
224
230
  <span class="wf-legend-item"><span class="wf-legend-dot wf-agent"></span>Agent</span>
225
231
  </div>
226
232
  </div>
227
- </div>`}function w(e,s){const t=e.startMs??0,a=e.durationMs??0,n=t/s*100,i=Math.max(.4,a/s*100),c=X(e),l=e.hasError?" wf-bar-error":"",r=e.toolName??"thinking",d=e.categories.includes("environment")?"env":e.categories.includes("service")?"svc":"agent",C=[`#${e.id} ${r} (${d})`,e.durationMs!==null?`Duration: ${u(e.durationMs)}`:null,`Context: ${W(e.contextBytes)}`,e.hasError?"ERROR":null].filter(Boolean).join(`
233
+ </div>`}function S(e,s){const t=e.startMs??0,a=e.durationMs??0,n=t/s*100,i=Math.max(.4,a/s*100),c=W(e),l=e.hasError?" wf-bar-error":"",r=e.toolName??"thinking",d=e.categories.includes("environment")?"env":e.categories.includes("service")?"svc":"agent",k=[`#${e.id} ${r} (${d})`,e.durationMs!==null?`Duration: ${u(e.durationMs)}`:null,`Context: ${X(e.contextBytes)}`,e.hasError?"ERROR":null].filter(Boolean).join(`
228
234
  `);return`
229
235
  <div class="wf-row ${c}">
230
236
  <div class="wf-label-col">
@@ -234,11 +240,11 @@
234
240
  </div>
235
241
  <div class="wf-timeline-col">
236
242
  <div class="wf-track">
237
- <div class="wf-bar${l}" style="left:${n.toFixed(2)}%;width:${i.toFixed(2)}%" title="${o(C)}"></div>
243
+ <div class="wf-bar${l}" style="left:${n.toFixed(2)}%;width:${i.toFixed(2)}%" title="${o(k)}"></div>
238
244
  </div>
239
245
  </div>
240
246
  <div class="wf-dur-col">${e.durationMs!==null?u(e.durationMs):"—"}</div>
241
- </div>`}function X(e){return e.categories.includes("environment")?"wf-env":e.categories.includes("service")?"wf-svc":"wf-agent"}function W(e){return e<1024?`${e}B`:`${(e/1024).toFixed(1)}KB`}function G(e){let s=0;for(const t of e)if(t.startMs!==null){const a=t.startMs+(t.durationMs??0);a>s&&(s=a)}return s}function z(e){const s=[50,100,200,250,500,1e3,2e3,2500,5e3,1e4,15e3,3e4,6e4,12e4,3e5];let t=s[s.length-1];for(const n of s){const i=Math.floor(e/n);if(i>=3&&i<=8){t=n;break}}const a=[];for(let n=0;n<=e;n+=t)a.push({pct:n/e*100,label:u(n)});return a.length===0&&a.push({pct:0,label:"0s"}),a}function V(e){const s=e.interactions.some(a=>a.content),t=e.lines.map((a,n)=>{const i=e.interactions[n];let c="cat-agent";i?i.categories.includes("environment")?c="cat-env":i.categories.includes("service")&&(c="cat-svc"):a.includes(" env ")?c="cat-env":(a.includes(" service ")||a.includes(" svc "))&&(c="cat-svc");const l=i?.content?" sparse-line-expandable":"",r=i?.content?`<div class="sparse-line-content"><pre>${o(i.content)}</pre></div>`:"";return`<div class="sparse-line ${c}${l}">${o(a)}${r}</div>`}).join("");return`
247
+ </div>`}function W(e){return e.categories.includes("environment")?"wf-env":e.categories.includes("service")?"wf-svc":"wf-agent"}function X(e){return e<1024?`${e}B`:`${(e/1024).toFixed(1)}KB`}function z(e){let s=0;for(const t of e)if(t.startMs!==null){const a=t.startMs+(t.durationMs??0);a>s&&(s=a)}return s}function V(e){const s=[50,100,200,250,500,1e3,2e3,2500,5e3,1e4,15e3,3e4,6e4,12e4,3e5];let t=s[s.length-1];for(const n of s){const i=Math.floor(e/n);if(i>=3&&i<=8){t=n;break}}const a=[];for(let n=0;n<=e;n+=t)a.push({pct:n/e*100,label:u(n)});return a.length===0&&a.push({pct:0,label:"0s"}),a}function J(e){const s=e.interactions.some(a=>a.content),t=e.lines.map((a,n)=>{const i=e.interactions[n];let c="cat-agent";i?i.categories.includes("environment")?c="cat-env":i.categories.includes("service")&&(c="cat-svc"):a.includes(" env ")?c="cat-env":(a.includes(" service ")||a.includes(" svc "))&&(c="cat-svc");const l=i?.content?" sparse-line-expandable":"",r=i?.content?`<div class="sparse-line-content"><pre>${o(i.content)}</pre></div>`:"";return`<div class="sparse-line ${c}${l}">${o(a)}${r}</div>`}).join("");return`
242
248
  <div class="detail-section">
243
249
  <div class="section-header">
244
250
  <h3>Transcript</h3>
@@ -249,7 +255,7 @@
249
255
  ${s?'<button class="sparse-expand-all">Expand all</button>':""}
250
256
  <div class="sparse-index-content">${t}</div>
251
257
  </div>
252
- </div>`}function J(e){return e.map((s,t)=>s.prompt?K(s,t):"").join("")}function K(e,s){return`
258
+ </div>`}function K(e){return e.map((s,t)=>s.prompt?Q(s,t):"").join("")}function Q(e,s){return`
253
259
  <div class="modal-backdrop" data-modal-index="${s}">
254
260
  <div class="modal">
255
261
  <div class="modal-header">
@@ -260,16 +266,16 @@
260
266
  <button class="modal-close">&times;</button>
261
267
  </div>
262
268
  <div class="modal-body">
263
- ${Q(e.prompt)}
264
- ${e.rubric?Y(e.rubric):""}
265
- ${e.agentConfig?Z(e.agentConfig):""}
269
+ ${Y(e.prompt)}
270
+ ${e.rubric?Z(e.rubric):""}
271
+ ${e.agentConfig?ee(e.agentConfig):""}
266
272
  </div>
267
273
  </div>
268
- </div>`}function Q(e){return`
274
+ </div>`}function Y(e){return`
269
275
  <div class="modal-section">
270
276
  <h4>Prompt</h4>
271
277
  <pre class="modal-prompt">${o(e)}</pre>
272
- </div>`}function Y(e){return typeof e=="string"?`
278
+ </div>`}function Z(e){return typeof e=="string"?`
273
279
  <div class="modal-section">
274
280
  <h4>Rubric</h4>
275
281
  <pre class="modal-prompt">${o(e)}</pre>
@@ -284,8 +290,8 @@
284
290
  <td class="modal-rubric-weight">${Math.round(t.weight*100)}%</td>
285
291
  </tr>`).join("")}</tbody>
286
292
  </table>
287
- </div>`}function Z(e){const s=Object.entries(e);return s.length===0?"":`
293
+ </div>`}function ee(e){const s=Object.entries(e);return s.length===0?"":`
288
294
  <div class="modal-section">
289
295
  <h4>Agent Configuration</h4>
290
296
  <div class="modal-config">${s.map(([a,n])=>{const i=typeof n=="string"?n:JSON.stringify(n);return`<div class="modal-config-item"><span class="modal-config-key">${o(a)}</span><span class="modal-config-val">${o(String(i))}</span></div>`}).join("")}</div>
291
- </div>`}const ee=[[/quota|rate.?limit|429|too many requests/i,"Rate limit / quota exceeded"],[/auth|unauthorized|401|403|api.?key|token/i,"Authentication error"],[/timeout|timed?\s*out|ETIMEDOUT/i,"Timeout"],[/ECONNREFUSED|ENOTFOUND|network|socket/i,"Network error"],[/not found|command not found|ENOENT/i,"CLI not found"],[/spawn|EPERM|EACCES/i,"Permission error"]];function se(e){for(const[s,t]of ee)if(s.test(e))return t;return e.length>80?e.slice(0,77)+"...":e}function te(){document.querySelectorAll(".result-row").forEach(e=>{e.addEventListener("click",()=>{const s=e.dataset.index;if(s===void 0)return;const t=document.getElementById(`detail-${s}`);if(!t)return;const a=e.classList.contains("expanded");document.querySelectorAll(".result-row").forEach(n=>{n.classList.remove("expanded")}),document.querySelectorAll(".detail-row").forEach(n=>{n.classList.remove("visible")}),a||(e.classList.add("expanded"),t.classList.add("visible"))})}),document.querySelectorAll(".audits-toggle").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.closest(".audits-section");if(!t)return;const a=t.querySelector(".audits-list");if(!a)return;const n=a.classList.contains("visible");a.classList.toggle("visible"),e.textContent=n?e.textContent.replace("Hide","Show"):e.textContent.replace("Show","Hide")})}),document.querySelectorAll(".wf-show-all").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.closest(".waterfall");if(!t)return;const a=t.querySelector(".wf-overflow");a&&(a.style.display="block",e.style.display="none")})}),document.querySelectorAll(".info-btn").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.dataset.modalIndex;if(t===void 0)return;const a=document.querySelector(`.modal-backdrop[data-modal-index="${t}"]`);a&&a.classList.add("visible")})}),document.querySelectorAll(".modal-backdrop").forEach(e=>{e.addEventListener("click",t=>{t.target===e&&e.classList.remove("visible")});const s=e.querySelector(".modal-close");s&&s.addEventListener("click",()=>e.classList.remove("visible"))}),document.addEventListener("keydown",e=>{e.key==="Escape"&&document.querySelectorAll(".modal-backdrop.visible").forEach(s=>s.classList.remove("visible"))}),document.querySelectorAll(".sparse-index-toggle").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.closest(".sparse-index-section");if(!t)return;const a=t.querySelector(".sparse-index-content");if(!a)return;const n=a.classList.contains("visible");a.classList.toggle("visible"),e.textContent=n?"Show transcript":"Hide transcript"})}),document.querySelectorAll(".sparse-line-expandable").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation(),e.classList.toggle("expanded")})}),document.querySelectorAll(".sparse-expand-all").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.closest(".sparse-index-section");if(!t)return;const a=t.querySelectorAll(".sparse-line-expandable"),n=Array.from(a).every(i=>i.classList.contains("expanded"));a.forEach(i=>{n?i.classList.remove("expanded"):i.classList.add("expanded")}),e.textContent=n?"Expand all":"Collapse all"})})}function S(e){const s=document.getElementById("app");s&&(s.innerHTML=L(e),document.title=`AXIS Report — ${o(e.reportId)}`,te())}const ae=document.getElementById("axis-data"),g=ae?.textContent?.trim();if(g&&g!=="__AXIS_REPORT_DATA__")try{S(JSON.parse(g))}catch{const s=document.getElementById("app");s&&(s.innerHTML='<div class="error-banner">Failed to parse report data.</div>')}else fetch("/mock-data.json").then(e=>e.json()).then(e=>S(e)).catch(e=>{const s=document.getElementById("app");s&&(s.innerHTML=`<div class="error-banner">Failed to load mock data: ${e.message}</div>`)});</script> </body> </html>
297
+ </div>`}const se=[[/quota|rate.?limit|429|too many requests/i,"Rate limit / quota exceeded"],[/auth|unauthorized|401|403|api.?key|token/i,"Authentication error"],[/timeout|timed?\s*out|ETIMEDOUT/i,"Timeout"],[/ECONNREFUSED|ENOTFOUND|network|socket/i,"Network error"],[/not found|command not found|ENOENT/i,"CLI not found"],[/spawn|EPERM|EACCES/i,"Permission error"]];function te(e){for(const[s,t]of se)if(s.test(e))return t;return e.length>80?e.slice(0,77)+"...":e}function ae(){document.querySelectorAll(".result-row").forEach(e=>{e.addEventListener("click",()=>{const s=e.dataset.index;if(s===void 0)return;const t=document.getElementById(`detail-${s}`);if(!t)return;const a=e.classList.contains("expanded");document.querySelectorAll(".result-row").forEach(n=>{n.classList.remove("expanded")}),document.querySelectorAll(".detail-row").forEach(n=>{n.classList.remove("visible")}),a||(e.classList.add("expanded"),t.classList.add("visible"))})}),document.querySelectorAll(".audits-toggle").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.closest(".audits-section");if(!t)return;const a=t.querySelector(".audits-list");if(!a)return;const n=a.classList.contains("visible");a.classList.toggle("visible"),e.textContent=n?e.textContent.replace("Hide","Show"):e.textContent.replace("Show","Hide")})}),document.querySelectorAll(".wf-show-all").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.closest(".waterfall");if(!t)return;const a=t.querySelector(".wf-overflow");a&&(a.style.display="block",e.style.display="none")})}),document.querySelectorAll(".info-btn").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.dataset.modalIndex;if(t===void 0)return;const a=document.querySelector(`.modal-backdrop[data-modal-index="${t}"]`);a&&a.classList.add("visible")})}),document.querySelectorAll(".modal-backdrop").forEach(e=>{e.addEventListener("click",t=>{t.target===e&&e.classList.remove("visible")});const s=e.querySelector(".modal-close");s&&s.addEventListener("click",()=>e.classList.remove("visible"))}),document.addEventListener("keydown",e=>{e.key==="Escape"&&document.querySelectorAll(".modal-backdrop.visible").forEach(s=>s.classList.remove("visible"))}),document.querySelectorAll(".sparse-index-toggle").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.closest(".sparse-index-section");if(!t)return;const a=t.querySelector(".sparse-index-content");if(!a)return;const n=a.classList.contains("visible");a.classList.toggle("visible"),e.textContent=n?"Show transcript":"Hide transcript"})}),document.querySelectorAll(".sparse-line-expandable").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation(),e.classList.toggle("expanded")})}),document.querySelectorAll(".sparse-expand-all").forEach(e=>{e.addEventListener("click",s=>{s.stopPropagation();const t=e.closest(".sparse-index-section");if(!t)return;const a=t.querySelectorAll(".sparse-line-expandable"),n=Array.from(a).every(i=>i.classList.contains("expanded"));a.forEach(i=>{n?i.classList.remove("expanded"):i.classList.add("expanded")}),e.textContent=n?"Expand all":"Collapse all"})})}function y(e){const s=document.getElementById("app");s&&(s.innerHTML=R(e),document.title=`AXIS Report — ${o(e.reportId)}`,ae())}const ne=document.getElementById("axis-data"),g=ne?.textContent?.trim();if(g&&g!=="__AXIS_REPORT_DATA__")try{y(JSON.parse(g))}catch{const s=document.getElementById("app");s&&(s.innerHTML='<div class="error-banner">Failed to parse report data.</div>')}else fetch("/mock-data.json").then(e=>e.json()).then(e=>y(e)).catch(e=>{const s=document.getElementById("app");s&&(s.innerHTML=`<div class="error-banner">Failed to load mock data: ${e.message}</div>`)});</script> </body> </html>
@@ -8,7 +8,7 @@ import type { ScoredOutput } from "../types/scoring.js";
8
8
  * .axis/reports/{reportId}/report.json
9
9
  * .axis/reports/{reportId}/scenarios/{scenarioKey}/{agentName}.json
10
10
  */
11
- export declare function writeReportToStore(output: ScoredOutput | RunOutput, configDir: string): string;
11
+ export declare function writeReportToStore(output: ScoredOutput | RunOutput, configDir: string, name?: string): string;
12
12
  /** Resolve the reports directory for a given config directory. */
13
13
  export declare function getReportsDir(configDir: string): string;
14
14
  //# sourceMappingURL=writer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/reports/writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,oBAAoB,CAAC;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,qBAAqB,CAAC;AAMzE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAoE9F;AAyCD,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD"}
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/reports/writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,oBAAoB,CAAC;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,qBAAqB,CAAC;AAMzE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAqE7G;AAyCD,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD"}
@@ -11,7 +11,7 @@ const REPORTS_DIR = ".axis/reports";
11
11
  * .axis/reports/{reportId}/report.json
12
12
  * .axis/reports/{reportId}/scenarios/{scenarioKey}/{agentName}.json
13
13
  */
14
- export function writeReportToStore(output, configDir) {
14
+ export function writeReportToStore(output, configDir, name) {
15
15
  const reportId = generateReportId(output.timestamp);
16
16
  const reportDir = path.join(configDir, REPORTS_DIR, reportId);
17
17
  fs.mkdirSync(reportDir, { recursive: true });
@@ -53,6 +53,7 @@ export function writeReportToStore(output, configDir) {
53
53
  const manifest = {
54
54
  version: output.version,
55
55
  reportId,
56
+ ...(name ? { name } : {}),
56
57
  timestamp: output.timestamp,
57
58
  durationMs: output.durationMs,
58
59
  summary: output.summary,
@@ -1 +1 @@
1
- {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/reports/writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/reports/writer.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAuB,MAAM,oBAAoB,CAAC;AAM5F,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC3C;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kDAAkD;IAClD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAiBD,wBAAsB,GAAG,CAAC,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAoLtE"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAuB,MAAM,oBAAoB,CAAC;AAM5F,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC3C;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kDAAkD;IAClD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAiBD,wBAAsB,GAAG,CAAC,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CA6KtE"}
@@ -5,7 +5,7 @@ import { loadConfig, discoverScenarios } from "../config/loader.js";
5
5
  import { getAdapter, registerAdapter } from "../adapters/registry.js";
6
6
  import { executeLifecycleActions } from "./lifecycle.js";
7
7
  import { silentLogger as defaultLogger, formatError } from "../types/output.js";
8
- import { resolveSkills, skillSourceString } from "../skills/resolver.js";
8
+ import { resolveSkills } from "../skills/resolver.js";
9
9
  /** System vars always passed through to isolated environments. */
10
10
  const SYSTEM_VARS = ["PATH", "USER", "SHELL", "LANG", "TERM", "TMPDIR"];
11
11
  /** Default env when not specified in config. */
@@ -109,37 +109,27 @@ export async function run(options = {}) {
109
109
  }
110
110
  }
111
111
  // --- Resolve skills (once, before any jobs start) ---
112
- const allSkillEntries = new Map();
113
- for (const entry of config.skills ?? []) {
114
- const key = skillSourceString(entry);
115
- if (!allSkillEntries.has(key))
116
- allSkillEntries.set(key, entry);
117
- }
112
+ const allSkillSources = new Set(config.skills ?? []);
118
113
  for (const job of jobs) {
119
- for (const entry of job.agentConfig.skills ?? []) {
120
- const key = skillSourceString(entry);
121
- if (!allSkillEntries.has(key))
122
- allSkillEntries.set(key, entry);
114
+ for (const s of job.agentConfig.skills ?? []) {
115
+ allSkillSources.add(s);
123
116
  }
124
- for (const entry of job.scenario.skills ?? []) {
125
- const key = skillSourceString(entry);
126
- if (!allSkillEntries.has(key))
127
- allSkillEntries.set(key, entry);
117
+ for (const s of job.scenario.skills ?? []) {
118
+ allSkillSources.add(s);
128
119
  }
129
120
  }
130
121
  const resolvedSkillMap = new Map();
131
- if (allSkillEntries.size > 0) {
132
- const entries = [...allSkillEntries.values()];
122
+ if (allSkillSources.size > 0) {
133
123
  const resolved = await resolveSkills({
134
- sources: entries,
124
+ sources: [...allSkillSources],
135
125
  configDir,
136
126
  cacheDir: path.join(configDir, ".axis", "skills-cache"),
137
127
  logger,
138
128
  refresh: options.refreshSkills,
139
129
  });
140
- const keys = [...allSkillEntries.keys()];
141
- for (let i = 0; i < keys.length; i++) {
142
- resolvedSkillMap.set(keys[i], resolved[i]);
130
+ const sources = [...allSkillSources];
131
+ for (let i = 0; i < sources.length; i++) {
132
+ resolvedSkillMap.set(sources[i], resolved[i]);
143
133
  }
144
134
  }
145
135
  // Emit initial state after pre-flight so ink's first render is clean
@@ -164,7 +154,7 @@ export async function run(options = {}) {
164
154
  const results = await runWithConcurrency(tasks, concurrency);
165
155
  return buildOutput(runStart, results);
166
156
  }
167
- async function executeJob(job, env, logger, updateStatus, updateTokens, resolvedSkillMap, registerCleanup, debug) {
157
+ async function executeJob(job, env, logger, updateStatus, updateTokens, resolvedSkillMap, registerCleanup, _debug) {
168
158
  const { index, agentName, agentConfig, scenario, axisConfig } = job;
169
159
  const label = `${scenario.key} (${agentName})`;
170
160
  const jobStart = Date.now();
@@ -209,15 +199,14 @@ async function executeJob(job, env, logger, updateStatus, updateTokens, resolved
209
199
  updateStatus(index, "running");
210
200
  logger.verbose?.(`[${label}] Executing agent...`);
211
201
  // Merge top-level + per-agent + per-scenario skills, deduplicate by source
212
- const skillEntries = [...(axisConfig.skills ?? []), ...(agentConfig.skills ?? []), ...(scenario.skills ?? [])];
202
+ const skillSources = [...(axisConfig.skills ?? []), ...(agentConfig.skills ?? []), ...(scenario.skills ?? [])];
213
203
  const seenSkills = new Set();
214
204
  const agentSkills = [];
215
- for (const entry of skillEntries) {
216
- const key = skillSourceString(entry);
217
- if (seenSkills.has(key))
205
+ for (const source of skillSources) {
206
+ if (seenSkills.has(source))
218
207
  continue;
219
- seenSkills.add(key);
220
- const resolved = resolvedSkillMap.get(key);
208
+ seenSkills.add(source);
209
+ const resolved = resolvedSkillMap.get(source);
221
210
  if (resolved)
222
211
  agentSkills.push(resolved);
223
212
  }
@@ -228,7 +217,7 @@ async function executeJob(job, env, logger, updateStatus, updateTokens, resolved
228
217
  workingDirectory: workspace,
229
218
  env: jobEnv,
230
219
  registerCleanup,
231
- captureRawOutput: !!debug,
220
+ captureRawOutput: true,
232
221
  mcpServers: axisConfig.mcp_servers,
233
222
  resolvedSkills: agentSkills.length > 0 ? agentSkills : undefined,
234
223
  onTokenProgress: (tokens) => updateTokens(index, tokens),