@netlify/axis 0.2.0
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/README.md +977 -0
- package/dist/adapters/base/acp-adapter.d.ts +44 -0
- package/dist/adapters/base/acp-adapter.d.ts.map +1 -0
- package/dist/adapters/base/acp-adapter.js +559 -0
- package/dist/adapters/base/acp-adapter.js.map +1 -0
- package/dist/adapters/base/agent-adapter.d.ts +132 -0
- package/dist/adapters/base/agent-adapter.d.ts.map +1 -0
- package/dist/adapters/base/agent-adapter.js +212 -0
- package/dist/adapters/base/agent-adapter.js.map +1 -0
- package/dist/adapters/claude-code.d.ts +3 -0
- package/dist/adapters/claude-code.d.ts.map +1 -0
- package/dist/adapters/claude-code.js +138 -0
- package/dist/adapters/claude-code.js.map +1 -0
- package/dist/adapters/claude-sdk.d.ts +11 -0
- package/dist/adapters/claude-sdk.d.ts.map +1 -0
- package/dist/adapters/claude-sdk.js +46 -0
- package/dist/adapters/claude-sdk.js.map +1 -0
- package/dist/adapters/codex.d.ts +3 -0
- package/dist/adapters/codex.d.ts.map +1 -0
- package/dist/adapters/codex.js +183 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/gemini-acp.d.ts +11 -0
- package/dist/adapters/gemini-acp.d.ts.map +1 -0
- package/dist/adapters/gemini-acp.js +60 -0
- package/dist/adapters/gemini-acp.js.map +1 -0
- package/dist/adapters/gemini.d.ts +3 -0
- package/dist/adapters/gemini.d.ts.map +1 -0
- package/dist/adapters/gemini.js +222 -0
- package/dist/adapters/gemini.js.map +1 -0
- package/dist/adapters/goose.d.ts +3 -0
- package/dist/adapters/goose.d.ts.map +1 -0
- package/dist/adapters/goose.js +9 -0
- package/dist/adapters/goose.js.map +1 -0
- package/dist/adapters/registry.d.ts +7 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +37 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/utils/mcp.d.ts +23 -0
- package/dist/adapters/utils/mcp.d.ts.map +1 -0
- package/dist/adapters/utils/mcp.js +114 -0
- package/dist/adapters/utils/mcp.js.map +1 -0
- package/dist/adapters/utils/resolve.d.ts +20 -0
- package/dist/adapters/utils/resolve.d.ts.map +1 -0
- package/dist/adapters/utils/resolve.js +48 -0
- package/dist/adapters/utils/resolve.js.map +1 -0
- package/dist/adapters/utils/skills.d.ts +17 -0
- package/dist/adapters/utils/skills.d.ts.map +1 -0
- package/dist/adapters/utils/skills.js +52 -0
- package/dist/adapters/utils/skills.js.map +1 -0
- package/dist/adapters/utils/token-estimator.d.ts +21 -0
- package/dist/adapters/utils/token-estimator.d.ts.map +1 -0
- package/dist/adapters/utils/token-estimator.js +37 -0
- package/dist/adapters/utils/token-estimator.js.map +1 -0
- package/dist/baselines/diff.d.ts +9 -0
- package/dist/baselines/diff.d.ts.map +1 -0
- package/dist/baselines/diff.js +83 -0
- package/dist/baselines/diff.js.map +1 -0
- package/dist/baselines/index.d.ts +3 -0
- package/dist/baselines/index.d.ts.map +1 -0
- package/dist/baselines/index.js +3 -0
- package/dist/baselines/index.js.map +1 -0
- package/dist/baselines/store.d.ts +19 -0
- package/dist/baselines/store.d.ts.map +1 -0
- package/dist/baselines/store.js +104 -0
- package/dist/baselines/store.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +487 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +99 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/validator.d.ts +11 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +203 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/docs-site/_astro/cli.DDWZtG0-.css +1 -0
- package/dist/docs-site/cli/index.html +18 -0
- package/dist/docs-site/configuration/index.html +121 -0
- package/dist/docs-site/content-assets.mjs +1 -0
- package/dist/docs-site/content-modules.mjs +1 -0
- package/dist/docs-site/data-store.json +9 -0
- package/dist/docs-site/index.html +69 -0
- package/dist/docs-site/quickstart/index.html +59 -0
- package/dist/docs-site/running/index.html +87 -0
- package/dist/docs-site/scoring/index.html +135 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/report-ui/index.html +291 -0
- package/dist/report-ui/mock-data.json +298 -0
- package/dist/reports/html.d.ts +7 -0
- package/dist/reports/html.d.ts.map +1 -0
- package/dist/reports/html.js +27 -0
- package/dist/reports/html.js.map +1 -0
- package/dist/reports/reader.d.ts +21 -0
- package/dist/reports/reader.d.ts.map +1 -0
- package/dist/reports/reader.js +110 -0
- package/dist/reports/reader.js.map +1 -0
- package/dist/reports/writer.d.ts +14 -0
- package/dist/reports/writer.d.ts.map +1 -0
- package/dist/reports/writer.js +106 -0
- package/dist/reports/writer.js.map +1 -0
- package/dist/runner/lifecycle.d.ts +10 -0
- package/dist/runner/lifecycle.d.ts.map +1 -0
- package/dist/runner/lifecycle.js +58 -0
- package/dist/runner/lifecycle.js.map +1 -0
- package/dist/runner/runner.d.ts +34 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +330 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/scoring/category-score.d.ts +52 -0
- package/dist/scoring/category-score.d.ts.map +1 -0
- package/dist/scoring/category-score.js +157 -0
- package/dist/scoring/category-score.js.map +1 -0
- package/dist/scoring/composite.d.ts +5 -0
- package/dist/scoring/composite.d.ts.map +1 -0
- package/dist/scoring/composite.js +24 -0
- package/dist/scoring/composite.js.map +1 -0
- package/dist/scoring/deep-eval.d.ts +25 -0
- package/dist/scoring/deep-eval.d.ts.map +1 -0
- package/dist/scoring/deep-eval.js +382 -0
- package/dist/scoring/deep-eval.js.map +1 -0
- package/dist/scoring/goal-achievement.d.ts +5 -0
- package/dist/scoring/goal-achievement.d.ts.map +1 -0
- package/dist/scoring/goal-achievement.js +241 -0
- package/dist/scoring/goal-achievement.js.map +1 -0
- package/dist/scoring/index.d.ts +22 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +115 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/scoring/parse-json.d.ts +6 -0
- package/dist/scoring/parse-json.d.ts.map +1 -0
- package/dist/scoring/parse-json.js +18 -0
- package/dist/scoring/parse-json.js.map +1 -0
- package/dist/scoring/sparse-index.d.ts +15 -0
- package/dist/scoring/sparse-index.d.ts.map +1 -0
- package/dist/scoring/sparse-index.js +338 -0
- package/dist/scoring/sparse-index.js.map +1 -0
- package/dist/scoring/triage.d.ts +15 -0
- package/dist/scoring/triage.d.ts.map +1 -0
- package/dist/scoring/triage.js +204 -0
- package/dist/scoring/triage.js.map +1 -0
- package/dist/skills/resolver.d.ts +19 -0
- package/dist/skills/resolver.d.ts.map +1 -0
- package/dist/skills/resolver.js +95 -0
- package/dist/skills/resolver.js.map +1 -0
- package/dist/transcript/categorize.d.ts +24 -0
- package/dist/transcript/categorize.d.ts.map +1 -0
- package/dist/transcript/categorize.js +233 -0
- package/dist/transcript/categorize.js.map +1 -0
- package/dist/transcript/classify.d.ts +7 -0
- package/dist/transcript/classify.d.ts.map +1 -0
- package/dist/transcript/classify.js +32 -0
- package/dist/transcript/classify.js.map +1 -0
- package/dist/transcript/extract.d.ts +24 -0
- package/dist/transcript/extract.d.ts.map +1 -0
- package/dist/transcript/extract.js +266 -0
- package/dist/transcript/extract.js.map +1 -0
- package/dist/transcript/index.d.ts +3 -0
- package/dist/transcript/index.d.ts.map +1 -0
- package/dist/transcript/index.js +2 -0
- package/dist/transcript/index.js.map +1 -0
- package/dist/transcript/normalize.d.ts +15 -0
- package/dist/transcript/normalize.d.ts.map +1 -0
- package/dist/transcript/normalize.js +160 -0
- package/dist/transcript/normalize.js.map +1 -0
- package/dist/transcript/types.d.ts +92 -0
- package/dist/transcript/types.d.ts.map +1 -0
- package/dist/transcript/types.js +2 -0
- package/dist/transcript/types.js.map +1 -0
- package/dist/transcript/urls.d.ts +10 -0
- package/dist/transcript/urls.d.ts.map +1 -0
- package/dist/transcript/urls.js +31 -0
- package/dist/transcript/urls.js.map +1 -0
- package/dist/types/agent.d.ts +80 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +2 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/baseline.d.ts +65 -0
- package/dist/types/baseline.d.ts.map +1 -0
- package/dist/types/baseline.js +2 -0
- package/dist/types/baseline.js.map +1 -0
- package/dist/types/config.d.ts +76 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/output.d.ts +70 -0
- package/dist/types/output.d.ts.map +1 -0
- package/dist/types/output.js +15 -0
- package/dist/types/output.js.map +1 -0
- package/dist/types/report.d.ts +37 -0
- package/dist/types/report.d.ts.map +1 -0
- package/dist/types/report.js +2 -0
- package/dist/types/report.js.map +1 -0
- package/dist/types/scenario.d.ts +23 -0
- package/dist/types/scenario.d.ts.map +1 -0
- package/dist/types/scenario.js +2 -0
- package/dist/types/scenario.js.map +1 -0
- package/dist/types/scoring.d.ts +176 -0
- package/dist/types/scoring.d.ts.map +1 -0
- package/dist/types/scoring.js +2 -0
- package/dist/types/scoring.js.map +1 -0
- package/dist/ui/AnimatedTokens.d.ts +29 -0
- package/dist/ui/AnimatedTokens.d.ts.map +1 -0
- package/dist/ui/AnimatedTokens.js +53 -0
- package/dist/ui/AnimatedTokens.js.map +1 -0
- package/dist/ui/App.d.ts +6 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +16 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/LiveDuration.d.ts +20 -0
- package/dist/ui/LiveDuration.d.ts.map +1 -0
- package/dist/ui/LiveDuration.js +31 -0
- package/dist/ui/LiveDuration.js.map +1 -0
- package/dist/ui/LiveStatus.d.ts +7 -0
- package/dist/ui/LiveStatus.d.ts.map +1 -0
- package/dist/ui/LiveStatus.js +52 -0
- package/dist/ui/LiveStatus.js.map +1 -0
- package/dist/ui/format.d.ts +29 -0
- package/dist/ui/format.d.ts.map +1 -0
- package/dist/ui/format.js +514 -0
- package/dist/ui/format.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/reports/html.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAezD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAKjE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
const DATA_PLACEHOLDER = "__AXIS_REPORT_DATA__";
|
|
6
|
+
function findTemplate() {
|
|
7
|
+
// From dist/reports/ → dist/report-ui/index.html (production)
|
|
8
|
+
const sibling = path.join(__dirname, "..", "report-ui", "index.html");
|
|
9
|
+
if (fs.existsSync(sibling))
|
|
10
|
+
return sibling;
|
|
11
|
+
// From src/reports/ → dist/report-ui/index.html (dev/test)
|
|
12
|
+
const fromRoot = path.join(__dirname, "..", "..", "dist", "report-ui", "index.html");
|
|
13
|
+
if (fs.existsSync(fromRoot))
|
|
14
|
+
return fromRoot;
|
|
15
|
+
throw new Error(`Report UI template not found. Run "npm run build:report-ui" first.`);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generate a self-contained HTML report page from a report manifest.
|
|
19
|
+
* Reads the pre-built Astro template and injects the report data as JSON.
|
|
20
|
+
*/
|
|
21
|
+
export function generateReportHtml(report) {
|
|
22
|
+
const template = fs.readFileSync(findTemplate(), "utf-8");
|
|
23
|
+
// Escape < and > in JSON to prevent </script> from closing the tag prematurely
|
|
24
|
+
const safeJson = JSON.stringify(report).replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
|
|
25
|
+
return template.replace(DATA_PLACEHOLDER, safeJson);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/reports/html.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;AAEhD,SAAS,YAAY;IACnB,8DAA8D;IAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IACtE,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC3C,2DAA2D;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IACrF,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7C,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;AACxF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1D,+EAA+E;IAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC1F,OAAO,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReportManifest } from "../types/report.js";
|
|
2
|
+
import type { RunResult } from "../types/output.js";
|
|
3
|
+
import type { ScoredRunResult } from "../types/scoring.js";
|
|
4
|
+
/**
|
|
5
|
+
* List all reports, sorted newest first.
|
|
6
|
+
*/
|
|
7
|
+
export declare function listReports(configDir: string): ReportManifest[];
|
|
8
|
+
/**
|
|
9
|
+
* Read a single report manifest by ID.
|
|
10
|
+
* Supports "latest" as a special ID.
|
|
11
|
+
*/
|
|
12
|
+
export declare function readReport(configDir: string, reportId: string): ReportManifest | null;
|
|
13
|
+
/**
|
|
14
|
+
* Read a full scenario result (with transcript) from a report.
|
|
15
|
+
*/
|
|
16
|
+
export declare function readScenarioResult(configDir: string, reportId: string, scenarioKey: string, agentName: string): ScoredRunResult | RunResult | null;
|
|
17
|
+
/**
|
|
18
|
+
* Read all agent results for a scenario within a report.
|
|
19
|
+
*/
|
|
20
|
+
export declare function readScenarioResults(configDir: string, reportId: string, scenarioKey: string): Array<ScoredRunResult | RunResult>;
|
|
21
|
+
//# sourceMappingURL=reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/reports/reader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAY3D;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE,CA0B/D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAcrF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,eAAe,GAAG,SAAS,GAAG,IAAI,CAgBpC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC,CAuBpC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { getReportsDir } from "./writer.js";
|
|
4
|
+
/** Ensure a resolved path stays within the expected root directory. */
|
|
5
|
+
function assertPathWithin(filePath, rootDir) {
|
|
6
|
+
const normalized = path.resolve(filePath);
|
|
7
|
+
const root = path.resolve(rootDir);
|
|
8
|
+
if (!normalized.startsWith(root + path.sep) && normalized !== root) {
|
|
9
|
+
throw new Error(`Path traversal detected: ${filePath} escapes ${rootDir}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* List all reports, sorted newest first.
|
|
14
|
+
*/
|
|
15
|
+
export function listReports(configDir) {
|
|
16
|
+
const reportsDir = getReportsDir(configDir);
|
|
17
|
+
if (!fs.existsSync(reportsDir))
|
|
18
|
+
return [];
|
|
19
|
+
const entries = fs.readdirSync(reportsDir, { withFileTypes: true });
|
|
20
|
+
const manifests = [];
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
if (!entry.isDirectory())
|
|
23
|
+
continue;
|
|
24
|
+
const manifestPath = path.join(reportsDir, entry.name, "report.json");
|
|
25
|
+
if (!fs.existsSync(manifestPath))
|
|
26
|
+
continue;
|
|
27
|
+
try {
|
|
28
|
+
const data = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
29
|
+
manifests.push(data);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Skip corrupted report files
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Sort by timestamp descending (newest first)
|
|
36
|
+
manifests.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
37
|
+
return manifests;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Read a single report manifest by ID.
|
|
41
|
+
* Supports "latest" as a special ID.
|
|
42
|
+
*/
|
|
43
|
+
export function readReport(configDir, reportId) {
|
|
44
|
+
if (reportId === "latest") {
|
|
45
|
+
const reports = listReports(configDir);
|
|
46
|
+
return reports[0] ?? null;
|
|
47
|
+
}
|
|
48
|
+
const manifestPath = path.join(getReportsDir(configDir), reportId, "report.json");
|
|
49
|
+
if (!fs.existsSync(manifestPath))
|
|
50
|
+
return null;
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Read a full scenario result (with transcript) from a report.
|
|
60
|
+
*/
|
|
61
|
+
export function readScenarioResult(configDir, reportId, scenarioKey, agentName) {
|
|
62
|
+
const resolvedId = resolveReportId(configDir, reportId);
|
|
63
|
+
if (!resolvedId)
|
|
64
|
+
return null;
|
|
65
|
+
const reportsRoot = getReportsDir(configDir);
|
|
66
|
+
const filePath = path.join(reportsRoot, resolvedId, "scenarios", scenarioKey, `${agentName}.json`);
|
|
67
|
+
assertPathWithin(filePath, reportsRoot);
|
|
68
|
+
if (!fs.existsSync(filePath))
|
|
69
|
+
return null;
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Read all agent results for a scenario within a report.
|
|
79
|
+
*/
|
|
80
|
+
export function readScenarioResults(configDir, reportId, scenarioKey) {
|
|
81
|
+
const resolvedId = resolveReportId(configDir, reportId);
|
|
82
|
+
if (!resolvedId)
|
|
83
|
+
return [];
|
|
84
|
+
const reportsRoot = getReportsDir(configDir);
|
|
85
|
+
const scenarioDir = path.join(reportsRoot, resolvedId, "scenarios", scenarioKey);
|
|
86
|
+
assertPathWithin(scenarioDir, reportsRoot);
|
|
87
|
+
if (!fs.existsSync(scenarioDir))
|
|
88
|
+
return [];
|
|
89
|
+
const results = [];
|
|
90
|
+
for (const entry of fs.readdirSync(scenarioDir)) {
|
|
91
|
+
if (!entry.endsWith(".json"))
|
|
92
|
+
continue;
|
|
93
|
+
const filePath = path.join(scenarioDir, entry);
|
|
94
|
+
try {
|
|
95
|
+
results.push(JSON.parse(fs.readFileSync(filePath, "utf-8")));
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// Skip corrupted files
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return results;
|
|
102
|
+
}
|
|
103
|
+
function resolveReportId(configDir, reportId) {
|
|
104
|
+
if (reportId === "latest") {
|
|
105
|
+
const reports = listReports(configDir);
|
|
106
|
+
return reports[0]?.reportId ?? null;
|
|
107
|
+
}
|
|
108
|
+
return reportId;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/reports/reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RunOutput } from "../types/output.js";
|
|
2
|
+
import type { ScoredOutput } from "../types/scoring.js";
|
|
3
|
+
/**
|
|
4
|
+
* Write a run's output to the persistent report store.
|
|
5
|
+
* Returns the reportId (used to recall the report later).
|
|
6
|
+
*
|
|
7
|
+
* Structure:
|
|
8
|
+
* .axis/reports/{reportId}/report.json
|
|
9
|
+
* .axis/reports/{reportId}/scenarios/{scenarioKey}/{agentName}.json
|
|
10
|
+
*/
|
|
11
|
+
export declare function writeReportToStore(output: ScoredOutput | RunOutput, configDir: string): string;
|
|
12
|
+
/** Resolve the reports directory for a given config directory. */
|
|
13
|
+
export declare function getReportsDir(configDir: string): string;
|
|
14
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { isScoredResult } from "../types/output.js";
|
|
4
|
+
import { generateReportHtml } from "./html.js";
|
|
5
|
+
const REPORTS_DIR = ".axis/reports";
|
|
6
|
+
/**
|
|
7
|
+
* Write a run's output to the persistent report store.
|
|
8
|
+
* Returns the reportId (used to recall the report later).
|
|
9
|
+
*
|
|
10
|
+
* Structure:
|
|
11
|
+
* .axis/reports/{reportId}/report.json
|
|
12
|
+
* .axis/reports/{reportId}/scenarios/{scenarioKey}/{agentName}.json
|
|
13
|
+
*/
|
|
14
|
+
export function writeReportToStore(output, configDir) {
|
|
15
|
+
const reportId = generateReportId(output.timestamp);
|
|
16
|
+
const reportDir = path.join(configDir, REPORTS_DIR, reportId);
|
|
17
|
+
fs.mkdirSync(reportDir, { recursive: true });
|
|
18
|
+
const entries = [];
|
|
19
|
+
for (const result of output.results) {
|
|
20
|
+
const relPath = `scenarios/${result.scenarioKey}/${result.agentName}.json`;
|
|
21
|
+
const absPath = path.join(reportDir, relPath);
|
|
22
|
+
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
|
23
|
+
// Strip rawOutput from scenario JSON — written as a separate file
|
|
24
|
+
const { rawOutput, ...outputWithoutRaw } = result.output;
|
|
25
|
+
// Strip sparseIndex from score — written as a separate file in debug mode
|
|
26
|
+
let resultToWrite = { ...result, output: outputWithoutRaw };
|
|
27
|
+
if (isScoredResult(result) && result.score.sparseIndex) {
|
|
28
|
+
const { sparseIndex: _sparseIndex, ...scoreWithoutIndex } = result.score;
|
|
29
|
+
resultToWrite = { ...resultToWrite, score: scoreWithoutIndex };
|
|
30
|
+
}
|
|
31
|
+
fs.writeFileSync(absPath, JSON.stringify(resultToWrite, null, 2));
|
|
32
|
+
if (rawOutput?.length) {
|
|
33
|
+
const rawPath = absPath.replace(/\.json$/, ".raw.ndjson");
|
|
34
|
+
fs.writeFileSync(rawPath, rawOutput.join("\n") + "\n");
|
|
35
|
+
}
|
|
36
|
+
// Write sparse index as a human-readable file in debug mode
|
|
37
|
+
if (rawOutput && isScoredResult(result) && result.score.sparseIndex) {
|
|
38
|
+
const indexPath = absPath.replace(/\.json$/, ".sparse-index.txt");
|
|
39
|
+
const { sparseIndex } = result.score;
|
|
40
|
+
const header = [
|
|
41
|
+
`# Sparse Index: ${result.scenarioKey} / ${result.agentName}`,
|
|
42
|
+
`# ${sparseIndex.stats.totalInteractions} interactions | ` +
|
|
43
|
+
`env: ${sparseIndex.stats.byCategory.environment} | ` +
|
|
44
|
+
`svc: ${sparseIndex.stats.byCategory.service} | ` +
|
|
45
|
+
`agent: ${sparseIndex.stats.byCategory.agent} | ` +
|
|
46
|
+
`errors: ${sparseIndex.stats.totalErrors}`,
|
|
47
|
+
"",
|
|
48
|
+
];
|
|
49
|
+
fs.writeFileSync(indexPath, header.join("\n") + sparseIndex.lines.join("\n") + "\n");
|
|
50
|
+
}
|
|
51
|
+
entries.push(buildResultEntry(result, relPath));
|
|
52
|
+
}
|
|
53
|
+
const manifest = {
|
|
54
|
+
version: output.version,
|
|
55
|
+
reportId,
|
|
56
|
+
timestamp: output.timestamp,
|
|
57
|
+
durationMs: output.durationMs,
|
|
58
|
+
summary: output.summary,
|
|
59
|
+
results: entries,
|
|
60
|
+
};
|
|
61
|
+
fs.writeFileSync(path.join(reportDir, "report.json"), JSON.stringify(manifest, null, 2));
|
|
62
|
+
try {
|
|
63
|
+
fs.writeFileSync(path.join(reportDir, "report.html"), generateReportHtml(manifest));
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
/* HTML generation is optional — template may not be built yet */
|
|
67
|
+
}
|
|
68
|
+
return reportId;
|
|
69
|
+
}
|
|
70
|
+
function buildResultEntry(result, relPath) {
|
|
71
|
+
const entry = {
|
|
72
|
+
scenarioKey: result.scenarioKey,
|
|
73
|
+
scenarioName: result.scenarioName,
|
|
74
|
+
agentName: result.agentName,
|
|
75
|
+
durationMs: result.output.metadata.durationMs,
|
|
76
|
+
exitCode: result.output.metadata.exitCode,
|
|
77
|
+
file: relPath,
|
|
78
|
+
};
|
|
79
|
+
if (result.output.metadata.tokenUsage) {
|
|
80
|
+
entry.tokenUsage = result.output.metadata.tokenUsage;
|
|
81
|
+
}
|
|
82
|
+
if (result.output.metadata.totalCostUsd !== undefined) {
|
|
83
|
+
entry.totalCostUsd = result.output.metadata.totalCostUsd;
|
|
84
|
+
}
|
|
85
|
+
if (result.output.metadata.error) {
|
|
86
|
+
entry.error = result.output.metadata.error;
|
|
87
|
+
}
|
|
88
|
+
if (isScoredResult(result)) {
|
|
89
|
+
entry.score = result.score;
|
|
90
|
+
}
|
|
91
|
+
entry.prompt = result.prompt;
|
|
92
|
+
entry.rubric = result.rubric;
|
|
93
|
+
entry.agentConfig = result.agentConfig;
|
|
94
|
+
return entry;
|
|
95
|
+
}
|
|
96
|
+
function generateReportId(timestamp) {
|
|
97
|
+
const d = new Date(timestamp);
|
|
98
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
99
|
+
return (`${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}` +
|
|
100
|
+
`-${pad(d.getUTCHours())}${pad(d.getUTCMinutes())}${pad(d.getUTCSeconds())}`);
|
|
101
|
+
}
|
|
102
|
+
/** Resolve the reports directory for a given config directory. */
|
|
103
|
+
export function getReportsDir(configDir) {
|
|
104
|
+
return path.join(configDir, REPORTS_DIR);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/reports/writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LifecycleAction } from "../types/scenario.js";
|
|
2
|
+
export interface LifecycleResult {
|
|
3
|
+
action: LifecycleAction;
|
|
4
|
+
exitCode: number;
|
|
5
|
+
stdout: string;
|
|
6
|
+
stderr: string;
|
|
7
|
+
durationMs: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function executeLifecycleActions(actions: LifecycleAction[], cwd: string, env?: Record<string, string>): Promise<LifecycleResult[]>;
|
|
10
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/runner/lifecycle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAK5D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,eAAe,EAAE,EAC1B,GAAG,EAAE,MAAM,EACX,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC,eAAe,EAAE,CAAC,CAe5B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
/** Default timeout for lifecycle scripts (30 seconds). */
|
|
3
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
|
+
export async function executeLifecycleActions(actions, cwd, env) {
|
|
5
|
+
const results = [];
|
|
6
|
+
for (const action of actions) {
|
|
7
|
+
const result = await runScript(action, cwd, env);
|
|
8
|
+
results.push(result);
|
|
9
|
+
if (result.exitCode !== 0) {
|
|
10
|
+
throw new Error(`Lifecycle action failed: "${action.command}" exited with code ${result.exitCode}\n${result.stderr}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return results;
|
|
14
|
+
}
|
|
15
|
+
function runScript(action, cwd, env) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const start = Date.now();
|
|
18
|
+
const child = spawn(action.command, {
|
|
19
|
+
cwd,
|
|
20
|
+
shell: true,
|
|
21
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
22
|
+
...(env && { env }),
|
|
23
|
+
});
|
|
24
|
+
let stdout = "";
|
|
25
|
+
let stderr = "";
|
|
26
|
+
let timedOut = false;
|
|
27
|
+
const timer = setTimeout(() => {
|
|
28
|
+
timedOut = true;
|
|
29
|
+
child.kill("SIGTERM");
|
|
30
|
+
setTimeout(() => child.kill("SIGKILL"), 5000);
|
|
31
|
+
}, DEFAULT_TIMEOUT_MS);
|
|
32
|
+
child.stdout.on("data", (data) => {
|
|
33
|
+
stdout += data.toString();
|
|
34
|
+
});
|
|
35
|
+
child.stderr.on("data", (data) => {
|
|
36
|
+
stderr += data.toString();
|
|
37
|
+
});
|
|
38
|
+
child.on("error", (err) => {
|
|
39
|
+
clearTimeout(timer);
|
|
40
|
+
reject(new Error(`Failed to execute "${action.command}": ${err.message}`));
|
|
41
|
+
});
|
|
42
|
+
child.on("close", (code) => {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
if (timedOut) {
|
|
45
|
+
reject(new Error(`Lifecycle action timed out after ${DEFAULT_TIMEOUT_MS / 1000}s: "${action.command}"`));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
resolve({
|
|
49
|
+
action,
|
|
50
|
+
exitCode: code ?? 1,
|
|
51
|
+
stdout,
|
|
52
|
+
stderr,
|
|
53
|
+
durationMs: Date.now() - start,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/runner/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { RunOutput, RunResult, Logger } from "../types/output.js";
|
|
2
|
+
export type { RunOutput, RunResult };
|
|
3
|
+
export interface RunOptions {
|
|
4
|
+
configPath?: string;
|
|
5
|
+
scenarioFilter?: string[];
|
|
6
|
+
agentFilter?: string[];
|
|
7
|
+
logger?: Logger;
|
|
8
|
+
/**
|
|
9
|
+
* Maximum number of jobs to run in parallel.
|
|
10
|
+
* Defaults to unlimited (all jobs start simultaneously).
|
|
11
|
+
*/
|
|
12
|
+
concurrency?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Called when an individual job completes (before all jobs finish).
|
|
15
|
+
* If a Promise is returned, the runner awaits it before running
|
|
16
|
+
* teardown — this allows scoring to verify results before cleanup.
|
|
17
|
+
*/
|
|
18
|
+
onResult?: (result: RunResult) => void | Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Register a cleanup function that will be called on process signals
|
|
21
|
+
* (SIGINT/SIGTERM). The runner uses this to register workspace cleanup
|
|
22
|
+
* and child process termination so Ctrl-C doesn't leave orphans.
|
|
23
|
+
*/
|
|
24
|
+
registerCleanup?: (fn: () => void) => void;
|
|
25
|
+
/**
|
|
26
|
+
* When true, adapters capture raw stdout lines in the output.
|
|
27
|
+
* Used by --debug mode to write .raw.ndjson files alongside reports.
|
|
28
|
+
*/
|
|
29
|
+
debug?: boolean;
|
|
30
|
+
/** Force re-clone of remote skills from cache. */
|
|
31
|
+
refreshSkills?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare function run(options?: RunOptions): Promise<RunOutput>;
|
|
34
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +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"}
|