@post-print/agent-test 0.3.12 → 1.0.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 +18 -4
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +53 -3
- package/dist/cli.js.map +1 -1
- package/dist/command-allowlist.d.ts +9 -0
- package/dist/command-allowlist.d.ts.map +1 -0
- package/dist/command-allowlist.js +29 -0
- package/dist/command-allowlist.js.map +1 -0
- package/dist/compare-scenario.d.ts +14 -18
- package/dist/compare-scenario.d.ts.map +1 -1
- package/dist/compare-scenario.js +146 -257
- package/dist/compare-scenario.js.map +1 -1
- package/dist/debug-bundle.d.ts.map +1 -1
- package/dist/debug-bundle.js +2 -0
- package/dist/debug-bundle.js.map +1 -1
- package/dist/expect.d.ts +3 -0
- package/dist/expect.d.ts.map +1 -1
- package/dist/expect.js +36 -0
- package/dist/expect.js.map +1 -1
- package/dist/html-report.d.ts +1 -0
- package/dist/html-report.d.ts.map +1 -1
- package/dist/html-report.js +194 -38
- package/dist/html-report.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/live-isolation.d.ts +8 -1
- package/dist/live-isolation.d.ts.map +1 -1
- package/dist/live-isolation.js +96 -8
- package/dist/live-isolation.js.map +1 -1
- package/dist/record-trace.d.ts +2 -2
- package/dist/record-trace.d.ts.map +1 -1
- package/dist/record-trace.js +6 -4
- package/dist/record-trace.js.map +1 -1
- package/dist/run-suite.d.ts +9 -1
- package/dist/run-suite.d.ts.map +1 -1
- package/dist/run-suite.js +190 -58
- package/dist/run-suite.js.map +1 -1
- package/dist/scenario-story.d.ts +4 -3
- package/dist/scenario-story.d.ts.map +1 -1
- package/dist/scenario-story.js +54 -71
- package/dist/scenario-story.js.map +1 -1
- package/dist/scenario-usage.d.ts.map +1 -1
- package/dist/scenario-usage.js +2 -3
- package/dist/scenario-usage.js.map +1 -1
- package/dist/types.d.ts +38 -22
- package/dist/types.d.ts.map +1 -1
- package/dist/validate-suite.d.ts.map +1 -1
- package/dist/validate-suite.js +65 -38
- package/dist/validate-suite.js.map +1 -1
- package/dist/viewer/catalog.d.ts +53 -0
- package/dist/viewer/catalog.d.ts.map +1 -0
- package/dist/viewer/catalog.js +116 -0
- package/dist/viewer/catalog.js.map +1 -0
- package/dist/viewer/cli.d.ts +17 -0
- package/dist/viewer/cli.d.ts.map +1 -0
- package/dist/viewer/cli.js +38 -0
- package/dist/viewer/cli.js.map +1 -0
- package/dist/viewer/compare-metrics.d.ts +30 -0
- package/dist/viewer/compare-metrics.d.ts.map +1 -0
- package/dist/viewer/compare-metrics.js +102 -0
- package/dist/viewer/compare-metrics.js.map +1 -0
- package/dist/viewer/context-files.d.ts +8 -0
- package/dist/viewer/context-files.d.ts.map +1 -0
- package/dist/viewer/context-files.js +56 -0
- package/dist/viewer/context-files.js.map +1 -0
- package/dist/viewer/emit.d.ts +7 -0
- package/dist/viewer/emit.d.ts.map +1 -0
- package/dist/viewer/emit.js +25 -0
- package/dist/viewer/emit.js.map +1 -0
- package/dist/viewer/events.d.ts +75 -0
- package/dist/viewer/events.d.ts.map +1 -0
- package/dist/viewer/events.js +47 -0
- package/dist/viewer/events.js.map +1 -0
- package/dist/viewer/live-runner.d.ts +20 -0
- package/dist/viewer/live-runner.d.ts.map +1 -0
- package/dist/viewer/live-runner.js +102 -0
- package/dist/viewer/live-runner.js.map +1 -0
- package/dist/viewer/page.d.ts +3 -0
- package/dist/viewer/page.d.ts.map +1 -0
- package/dist/viewer/page.js +1664 -0
- package/dist/viewer/page.js.map +1 -0
- package/dist/viewer/run-controller.d.ts +27 -0
- package/dist/viewer/run-controller.d.ts.map +1 -0
- package/dist/viewer/run-controller.js +154 -0
- package/dist/viewer/run-controller.js.map +1 -0
- package/dist/viewer/server.d.ts +16 -0
- package/dist/viewer/server.d.ts.map +1 -0
- package/dist/viewer/server.js +154 -0
- package/dist/viewer/server.js.map +1 -0
- package/dist/worker-pool.d.ts +8 -0
- package/dist/worker-pool.d.ts.map +1 -0
- package/dist/worker-pool.js +26 -0
- package/dist/worker-pool.js.map +1 -0
- package/package.json +7 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/viewer/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgB3C,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAyB;IAC7D,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC;QACvC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;KAC9B,CAAC,CAAC;IACH,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,sBAAsB,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QACjC,OAAO;QACP,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,IAAI,EAAE,OAAO,CAAC,UAAU;QACxB,OAAO;KACP,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,oCAAoC,CAAC,CAAC;IAC5D,MAAM,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,EAAE;QACxC,MAAM,IAAI,GAAG,GAAS,EAAE;YACvB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,CAAC;AACV,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CompareGateResult } from "../types.js";
|
|
2
|
+
export type ViewerCompareMetricId = "turns" | "tokens" | "tools" | "durationMs";
|
|
3
|
+
export interface ViewerArmMetricRow {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
turns?: number;
|
|
7
|
+
tokens?: number;
|
|
8
|
+
tools?: number;
|
|
9
|
+
durationMs?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ViewerMetricSummary {
|
|
12
|
+
id: ViewerCompareMetricId;
|
|
13
|
+
label: string;
|
|
14
|
+
winnerIds: string[];
|
|
15
|
+
line: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ViewerGateSummary {
|
|
18
|
+
metric: string;
|
|
19
|
+
passed: boolean;
|
|
20
|
+
line: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ViewerCompareSummary {
|
|
23
|
+
metrics: ViewerMetricSummary[];
|
|
24
|
+
gates: ViewerGateSummary[];
|
|
25
|
+
}
|
|
26
|
+
/** Lower turns, tokens, tool counts, and duration win. Named pairs do not pick one overall winner. */
|
|
27
|
+
export declare function summarizeViewerCompare(arms: ViewerArmMetricRow[], gates?: CompareGateResult[]): ViewerCompareSummary;
|
|
28
|
+
/** Markup for the winners list under a compare cell or report. */
|
|
29
|
+
export declare function renderViewerCompareBoard(summary: ViewerCompareSummary): string;
|
|
30
|
+
//# sourceMappingURL=compare-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare-metrics.d.ts","sourceRoot":"","sources":["../../src/viewer/compare-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,qBAAqB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC3B;AASD,sGAAsG;AACtG,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,kBAAkB,EAAE,EAC1B,KAAK,GAAE,iBAAiB,EAAO,GAC7B,oBAAoB,CAStB;AAED,kEAAkE;AAClE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAe9E"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const METRICS = [
|
|
2
|
+
{ id: "turns", label: "Turns" },
|
|
3
|
+
{ id: "tokens", label: "Tokens" },
|
|
4
|
+
{ id: "tools", label: "Tools" },
|
|
5
|
+
{ id: "durationMs", label: "Duration" },
|
|
6
|
+
];
|
|
7
|
+
/** Lower turns, tokens, tool counts, and duration win. Named pairs do not pick one overall winner. */
|
|
8
|
+
export function summarizeViewerCompare(arms, gates = []) {
|
|
9
|
+
return {
|
|
10
|
+
metrics: METRICS.map((metric) => summarizeMetric(arms, metric.id, metric.label)),
|
|
11
|
+
gates: gates.map((gate) => ({
|
|
12
|
+
metric: gate.gate.metric,
|
|
13
|
+
passed: gate.passed,
|
|
14
|
+
line: `${gate.message}. ${gate.passed ? "Pass." : "Fail."}`,
|
|
15
|
+
})),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Markup for the winners list under a compare cell or report. */
|
|
19
|
+
export function renderViewerCompareBoard(summary) {
|
|
20
|
+
if (summary.metrics.length === 0 && summary.gates.length === 0) {
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
const lines = [
|
|
24
|
+
...summary.metrics.map((metric) => `<li>${escapeHtml(metric.line)}</li>`),
|
|
25
|
+
...summary.gates.map((gate) => {
|
|
26
|
+
const status = gate.passed ? "compare-winner-pass" : "compare-winner-fail";
|
|
27
|
+
return `<li class="${status}">${escapeHtml(gate.line)}</li>`;
|
|
28
|
+
}),
|
|
29
|
+
];
|
|
30
|
+
return `<section class="compare-winners">
|
|
31
|
+
<h3>Winners</h3>
|
|
32
|
+
<ul>${lines.join("")}</ul>
|
|
33
|
+
</section>`;
|
|
34
|
+
}
|
|
35
|
+
function summarizeMetric(arms, id, label) {
|
|
36
|
+
const values = arms.map((arm) => arm[id]);
|
|
37
|
+
const numeric = values.filter((value) => typeof value === "number");
|
|
38
|
+
if (numeric.length < 2) {
|
|
39
|
+
return { id, label, winnerIds: [], line: `${label}: n/a.` };
|
|
40
|
+
}
|
|
41
|
+
const lowest = Math.min(...numeric);
|
|
42
|
+
const winners = arms.filter((arm) => arm[id] === lowest);
|
|
43
|
+
const shown = values
|
|
44
|
+
.map((value) => (typeof value === "number" ? String(value) : "n/a"))
|
|
45
|
+
.join(" vs ");
|
|
46
|
+
if (winners.length === 0) {
|
|
47
|
+
return { id, label, winnerIds: [], line: `${label}: n/a.` };
|
|
48
|
+
}
|
|
49
|
+
if (winners.length > 1) {
|
|
50
|
+
const names = joinLabels(winners.map((arm) => arm.label));
|
|
51
|
+
if (arms.length === 2) {
|
|
52
|
+
return {
|
|
53
|
+
id,
|
|
54
|
+
label,
|
|
55
|
+
winnerIds: winners.map((arm) => arm.id),
|
|
56
|
+
line: `${label}: tie (${shown}).`,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
id,
|
|
61
|
+
label,
|
|
62
|
+
winnerIds: winners.map((arm) => arm.id),
|
|
63
|
+
line: `${label}: lowest is a tie between ${names} (${shown}).`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const winner = winners[0];
|
|
67
|
+
if (!winner) {
|
|
68
|
+
return { id, label, winnerIds: [], line: `${label}: n/a.` };
|
|
69
|
+
}
|
|
70
|
+
if (arms.length === 2) {
|
|
71
|
+
return {
|
|
72
|
+
id,
|
|
73
|
+
label,
|
|
74
|
+
winnerIds: [winner.id],
|
|
75
|
+
line: `${label}: ${winner.label} wins (${shown}).`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
id,
|
|
80
|
+
label,
|
|
81
|
+
winnerIds: [winner.id],
|
|
82
|
+
line: `${label}: lowest is ${winner.label} (${shown}).`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function joinLabels(labels) {
|
|
86
|
+
if (labels.length <= 1) {
|
|
87
|
+
return labels[0] ?? "";
|
|
88
|
+
}
|
|
89
|
+
if (labels.length === 2) {
|
|
90
|
+
return `${labels[0]} and ${labels[1]}`;
|
|
91
|
+
}
|
|
92
|
+
return `${labels.slice(0, -1).join(", ")}, and ${labels[labels.length - 1]}`;
|
|
93
|
+
}
|
|
94
|
+
function escapeHtml(value) {
|
|
95
|
+
return value
|
|
96
|
+
.replaceAll("&", "&")
|
|
97
|
+
.replaceAll("<", "<")
|
|
98
|
+
.replaceAll(">", ">")
|
|
99
|
+
.replaceAll('"', """)
|
|
100
|
+
.replaceAll("'", "'");
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=compare-metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare-metrics.js","sourceRoot":"","sources":["../../src/viewer/compare-metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ViewerContextFile, ViewerContextReason } from "./events.js";
|
|
2
|
+
export declare const VIEWER_CONTEXT_FILE_CHARS = 4000;
|
|
3
|
+
export declare function truncateViewerText(text: string, max: number): string;
|
|
4
|
+
export declare function classifyContextReason(path: string, contextSources?: string[]): ViewerContextReason;
|
|
5
|
+
export declare function contextWhy(path: string, reason: ViewerContextReason): string;
|
|
6
|
+
/** Split a loaded preamble into path and text pairs for the viewer. */
|
|
7
|
+
export declare function viewerContextFiles(preamble: string, sources: string[], contextSources?: string[]): ViewerContextFile[];
|
|
8
|
+
//# sourceMappingURL=context-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-files.d.ts","sourceRoot":"","sources":["../../src/viewer/context-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE1E,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAE/C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKpE;AAED,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,MAAM,EACZ,cAAc,GAAE,MAAM,EAAO,GAC3B,mBAAmB,CAarB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAQ5E;AAYD,uEAAuE;AACvE,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,GAAE,MAAM,EAAO,GAC3B,iBAAiB,EAAE,CAgBrB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export const VIEWER_CONTEXT_FILE_CHARS = 4_000;
|
|
2
|
+
export function truncateViewerText(text, max) {
|
|
3
|
+
if (text.length <= max) {
|
|
4
|
+
return text;
|
|
5
|
+
}
|
|
6
|
+
return `${text.slice(0, max)}\n… (truncated)`;
|
|
7
|
+
}
|
|
8
|
+
export function classifyContextReason(path, contextSources = []) {
|
|
9
|
+
const needle = path.replace(/^\.\//, "");
|
|
10
|
+
if (contextSources.some((source) => source.replace(/^\.\//, "") === needle)) {
|
|
11
|
+
return "contextSources";
|
|
12
|
+
}
|
|
13
|
+
if (/(?:^|\/)SKILL\.md$/.test(needle) ||
|
|
14
|
+
/(?:^|\/)\.agents\/skills\//.test(needle) ||
|
|
15
|
+
/(?:^|\/)\.claude\/skills\//.test(needle)) {
|
|
16
|
+
return "skills";
|
|
17
|
+
}
|
|
18
|
+
return "profile";
|
|
19
|
+
}
|
|
20
|
+
export function contextWhy(path, reason) {
|
|
21
|
+
if (reason === "contextSources") {
|
|
22
|
+
return `The scenario lists ${path} in contextSources.`;
|
|
23
|
+
}
|
|
24
|
+
if (reason === "skills") {
|
|
25
|
+
return `The scenario skills setting loaded ${path}.`;
|
|
26
|
+
}
|
|
27
|
+
return `The host profile loaded ${path}.`;
|
|
28
|
+
}
|
|
29
|
+
function contextFile(path, text, contextSources) {
|
|
30
|
+
const reason = classifyContextReason(path, contextSources);
|
|
31
|
+
return {
|
|
32
|
+
path,
|
|
33
|
+
text: truncateViewerText(text, VIEWER_CONTEXT_FILE_CHARS),
|
|
34
|
+
reason,
|
|
35
|
+
why: contextWhy(path, reason),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Split a loaded preamble into path and text pairs for the viewer. */
|
|
39
|
+
export function viewerContextFiles(preamble, sources, contextSources = []) {
|
|
40
|
+
const chunks = preamble.split("\n\n---\n\n");
|
|
41
|
+
const files = [];
|
|
42
|
+
for (const chunk of chunks) {
|
|
43
|
+
const trimmed = chunk.trim();
|
|
44
|
+
if (!trimmed) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const match = trimmed.match(/^<!-- ([^\n]+) -->\n?([\s\S]*)$/);
|
|
48
|
+
if (match?.[1]) {
|
|
49
|
+
files.push(contextFile(match[1].trim(), match[2].trimEnd(), contextSources));
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
files.push(contextFile(sources[files.length] ?? "context", trimmed, contextSources));
|
|
53
|
+
}
|
|
54
|
+
return files;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=context-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-files.js","sourceRoot":"","sources":["../../src/viewer/context-files.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAE/C,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,GAAW;IAC3D,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,qBAAqB,CACpC,IAAY,EACZ,cAAc,GAAa,EAAE;IAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACzC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,EAAE,CAAC;QAC7E,OAAO,gBAAgB,CAAC;IACzB,CAAC;IACD,IACC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC;QACjC,4BAA4B,CAAC,IAAI,CAAC,MAAM,CAAC;QACzC,4BAA4B,CAAC,IAAI,CAAC,MAAM,CAAC,EACxC,CAAC;QACF,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,MAA2B;IACnE,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;QACjC,OAAO,sBAAsB,IAAI,qBAAqB,CAAC;IACxD,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO,sCAAsC,IAAI,GAAG,CAAC;IACtD,CAAC;IACD,OAAO,2BAA2B,IAAI,GAAG,CAAC;AAC3C,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,IAAY,EAAE,cAAwB;IACxE,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAC3D,OAAO;QACN,IAAI;QACJ,IAAI,EAAE,kBAAkB,CAAC,IAAI,EAAE,yBAAyB,CAAC;QACzD,MAAM;QACN,GAAG,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;KAC7B,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,kBAAkB,CACjC,QAAgB,EAChB,OAAiB,EACjB,cAAc,GAAa,EAAE;IAE7B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAwB,EAAE,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,SAAS;QACV,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAC/D,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;YAC7E,SAAS;QACV,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ViewerEvent } from "./events.js";
|
|
2
|
+
export declare const VIEWER_EVENTS_FD = 3;
|
|
3
|
+
export declare const VIEWER_EVENTS_FD_ENV = "AGENT_TEST_EVENTS_FD";
|
|
4
|
+
export declare function viewerEventsFd(env?: NodeJS.ProcessEnv): number | undefined;
|
|
5
|
+
/** Write one NDJSON event to the parent pipe. No-op when the fd is unset. */
|
|
6
|
+
export declare function emitViewerEvent(event: ViewerEvent, fd?: number | undefined): void;
|
|
7
|
+
//# sourceMappingURL=emit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/viewer/emit.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAElE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,SAAS,CAOvF;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,qBAAmB,GAAG,IAAI,CAS/E"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { writeSync } from "node:fs";
|
|
2
|
+
import { encodeViewerEvent } from "./events.js";
|
|
3
|
+
export const VIEWER_EVENTS_FD = 3;
|
|
4
|
+
export const VIEWER_EVENTS_FD_ENV = "AGENT_TEST_EVENTS_FD";
|
|
5
|
+
export function viewerEventsFd(env = process.env) {
|
|
6
|
+
const raw = env[VIEWER_EVENTS_FD_ENV]?.trim();
|
|
7
|
+
if (!raw) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
const fd = Number(raw);
|
|
11
|
+
return Number.isInteger(fd) && fd >= 3 ? fd : undefined;
|
|
12
|
+
}
|
|
13
|
+
/** Write one NDJSON event to the parent pipe. No-op when the fd is unset. */
|
|
14
|
+
export function emitViewerEvent(event, fd = viewerEventsFd()) {
|
|
15
|
+
if (fd === undefined) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
writeSync(fd, `${encodeViewerEvent(event)}\n`);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Parent closed the pipe.
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=emit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/viewer/emit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAoB,MAAM,aAAa,CAAC;AAElE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D,MAAM,UAAU,cAAc,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IAClE,MAAM,GAAG,GAAG,GAAG,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC;IAC9C,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAAC,KAAkB,EAAE,EAAE,GAAG,cAAc,EAAE;IACxE,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO;IACR,CAAC;IACD,IAAI,CAAC;QACJ,SAAS,CAAC,EAAE,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACR,0BAA0B;IAC3B,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export interface ViewerEventEnvelope {
|
|
2
|
+
suite: string;
|
|
3
|
+
scenario: string;
|
|
4
|
+
host: string;
|
|
5
|
+
arm?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ViewerFailureEvent {
|
|
8
|
+
matcher: string;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ViewerJudgeVerdictEvent {
|
|
12
|
+
id: string;
|
|
13
|
+
question: string;
|
|
14
|
+
pass: boolean;
|
|
15
|
+
rationale: string;
|
|
16
|
+
}
|
|
17
|
+
export type ViewerContextReason = "contextSources" | "profile" | "skills";
|
|
18
|
+
export interface ViewerContextFile {
|
|
19
|
+
path: string;
|
|
20
|
+
text: string;
|
|
21
|
+
reason: ViewerContextReason;
|
|
22
|
+
why: string;
|
|
23
|
+
}
|
|
24
|
+
export type ViewerEvent = {
|
|
25
|
+
type: "run_started";
|
|
26
|
+
runId: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: "run_finished";
|
|
29
|
+
runId: string;
|
|
30
|
+
passed: number;
|
|
31
|
+
failed: number;
|
|
32
|
+
skipped: number;
|
|
33
|
+
} | ({
|
|
34
|
+
type: "cell_started";
|
|
35
|
+
} & ViewerEventEnvelope) | ({
|
|
36
|
+
type: "status";
|
|
37
|
+
text: string;
|
|
38
|
+
} & ViewerEventEnvelope) | ({
|
|
39
|
+
type: "prompt";
|
|
40
|
+
text: string;
|
|
41
|
+
} & ViewerEventEnvelope) | ({
|
|
42
|
+
type: "context";
|
|
43
|
+
files: ViewerContextFile[];
|
|
44
|
+
} & ViewerEventEnvelope) | ({
|
|
45
|
+
type: "text";
|
|
46
|
+
text: string;
|
|
47
|
+
} & ViewerEventEnvelope) | ({
|
|
48
|
+
type: "tool";
|
|
49
|
+
name: string;
|
|
50
|
+
args?: Record<string, unknown>;
|
|
51
|
+
} & ViewerEventEnvelope) | ({
|
|
52
|
+
type: "cell_finished";
|
|
53
|
+
passed: boolean;
|
|
54
|
+
skipped?: boolean;
|
|
55
|
+
durationMs: number;
|
|
56
|
+
failures?: ViewerFailureEvent[];
|
|
57
|
+
metrics?: {
|
|
58
|
+
turns?: number;
|
|
59
|
+
tokens?: number;
|
|
60
|
+
tools?: number;
|
|
61
|
+
durationMs?: number;
|
|
62
|
+
passed?: boolean;
|
|
63
|
+
};
|
|
64
|
+
} & ViewerEventEnvelope) | ({
|
|
65
|
+
type: "judge";
|
|
66
|
+
verdicts: ViewerJudgeVerdictEvent[];
|
|
67
|
+
} & ViewerEventEnvelope) | ({
|
|
68
|
+
type: "error";
|
|
69
|
+
message: string;
|
|
70
|
+
} & Partial<ViewerEventEnvelope>);
|
|
71
|
+
/** One NDJSON object with no trailing newline. */
|
|
72
|
+
export declare function encodeViewerEvent(event: ViewerEvent): string;
|
|
73
|
+
export declare function parseViewerEvent(line: string): ViewerEvent | undefined;
|
|
74
|
+
export declare function parseViewerEventLines(chunk: string): ViewerEvent[];
|
|
75
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/viewer/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const EVENT_TYPES = new Set([
|
|
2
|
+
"run_started",
|
|
3
|
+
"run_finished",
|
|
4
|
+
"cell_started",
|
|
5
|
+
"status",
|
|
6
|
+
"prompt",
|
|
7
|
+
"context",
|
|
8
|
+
"text",
|
|
9
|
+
"tool",
|
|
10
|
+
"cell_finished",
|
|
11
|
+
"judge",
|
|
12
|
+
"error",
|
|
13
|
+
]);
|
|
14
|
+
/** One NDJSON object with no trailing newline. */
|
|
15
|
+
export function encodeViewerEvent(event) {
|
|
16
|
+
return JSON.stringify(event);
|
|
17
|
+
}
|
|
18
|
+
export function parseViewerEvent(line) {
|
|
19
|
+
const trimmed = line.trim();
|
|
20
|
+
if (!trimmed) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const parsed = JSON.parse(trimmed);
|
|
25
|
+
if (!isViewerEvent(parsed)) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function parseViewerEventLines(chunk) {
|
|
35
|
+
return chunk.split("\n").flatMap((line) => {
|
|
36
|
+
const event = parseViewerEvent(line);
|
|
37
|
+
return event ? [event] : [];
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function isViewerEvent(value) {
|
|
41
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const type = value.type;
|
|
45
|
+
return typeof type === "string" && EVENT_TYPES.has(type);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/viewer/events.ts"],"names":[],"mappings":"AAsDA,MAAM,WAAW,GAAG,IAAI,GAAG,CAAsB;IAChD,aAAa;IACb,cAAc;IACd,cAAc;IACd,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,MAAM;IACN,MAAM;IACN,eAAe;IACf,OAAO;IACP,OAAO;CACP,CAAC,CAAC;AAEH,kDAAkD;AAClD,MAAM,UAAU,iBAAiB,CAAC,KAAkB;IACnD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,CAAC;QACJ,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAa;IAClD,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAI,KAA4B,CAAC,IAAI,CAAC;IAChD,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,WAAW,CAAC,GAAG,CAAC,IAA2B,CAAC,CAAC;AACjF,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { HostAuthMode } from "@post-print/agent-harness";
|
|
2
|
+
import { type SpawnLiveScenarioOptions, type SpawnLiveScenarioResult } from "../live-isolation.js";
|
|
3
|
+
import type { ViewerJob } from "./catalog.js";
|
|
4
|
+
import type { ViewerRunner } from "./run-controller.js";
|
|
5
|
+
export interface LiveViewerRunnerOptions {
|
|
6
|
+
cwd: string;
|
|
7
|
+
suitesDir: string;
|
|
8
|
+
rubricsDir?: string;
|
|
9
|
+
judge?: boolean;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
authMode?: HostAuthMode;
|
|
12
|
+
adapterModules?: string[];
|
|
13
|
+
/** Override host auth probe. Tests inject this. */
|
|
14
|
+
missingAuth?: (host: ViewerJob["host"]) => string | undefined;
|
|
15
|
+
/** Override isolated spawn. Tests inject this. */
|
|
16
|
+
spawnLiveScenario?: (options: SpawnLiveScenarioOptions) => Promise<SpawnLiveScenarioResult>;
|
|
17
|
+
}
|
|
18
|
+
/** Spawn one isolated child per viewer job. Forward NDJSON events to the UI. */
|
|
19
|
+
export declare function createLiveViewerRunner(options: LiveViewerRunnerOptions): ViewerRunner;
|
|
20
|
+
//# sourceMappingURL=live-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-runner.d.ts","sourceRoot":"","sources":["../../src/viewer/live-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAEN,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAG5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,uBAAuB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,mDAAmD;IACnD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IAC9D,kDAAkD;IAClD,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC5F;AAWD,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,YAAY,CAsFrF"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { missingAgentAuth } from "../doctor.js";
|
|
2
|
+
import { killActiveLiveChildren, spawnLiveScenario, subprocessFailureMessage, } from "../live-isolation.js";
|
|
3
|
+
import { createLiveStagingSessionId } from "../record-trace.js";
|
|
4
|
+
function envelope(job) {
|
|
5
|
+
return {
|
|
6
|
+
suite: job.suite,
|
|
7
|
+
scenario: job.scenario,
|
|
8
|
+
host: job.host,
|
|
9
|
+
...(job.arm ? { arm: job.arm } : {}),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/** Spawn one isolated child per viewer job. Forward NDJSON events to the UI. */
|
|
13
|
+
export function createLiveViewerRunner(options) {
|
|
14
|
+
return {
|
|
15
|
+
async runJob(job, emit, signal) {
|
|
16
|
+
const cell = envelope(job);
|
|
17
|
+
emit({ type: "cell_started", ...cell });
|
|
18
|
+
emit({ type: "status", text: "Starting isolated child.", ...cell });
|
|
19
|
+
const missing = (options.missingAuth ?? missingAgentAuth)(job.host);
|
|
20
|
+
if (missing) {
|
|
21
|
+
emit({ type: "error", message: missing, ...cell });
|
|
22
|
+
emit({
|
|
23
|
+
type: "cell_finished",
|
|
24
|
+
...cell,
|
|
25
|
+
passed: false,
|
|
26
|
+
durationMs: 0,
|
|
27
|
+
failures: [{ matcher: "liveScenario", message: missing }],
|
|
28
|
+
});
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (signal.aborted) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const onAbort = () => {
|
|
35
|
+
killActiveLiveChildren();
|
|
36
|
+
};
|
|
37
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
38
|
+
const spawn = options.spawnLiveScenario ?? spawnLiveScenario;
|
|
39
|
+
let finished = false;
|
|
40
|
+
try {
|
|
41
|
+
const result = await spawn({
|
|
42
|
+
cwd: options.cwd,
|
|
43
|
+
suiteName: job.suite,
|
|
44
|
+
scenarioName: job.scenario,
|
|
45
|
+
suitesDir: options.suitesDir,
|
|
46
|
+
rubricsDir: options.rubricsDir,
|
|
47
|
+
suiteFilter: job.suite,
|
|
48
|
+
host: job.host,
|
|
49
|
+
compareArm: job.arm,
|
|
50
|
+
stagingSessionId: createLiveStagingSessionId(),
|
|
51
|
+
judge: options.judge,
|
|
52
|
+
timeoutMs: options.timeoutMs,
|
|
53
|
+
noTimeout: options.timeoutMs === 0,
|
|
54
|
+
authMode: options.authMode,
|
|
55
|
+
adapterModules: options.adapterModules,
|
|
56
|
+
signal,
|
|
57
|
+
onViewerEvent: (event) => {
|
|
58
|
+
if (event.type === "cell_finished") {
|
|
59
|
+
finished = true;
|
|
60
|
+
}
|
|
61
|
+
if (signal.aborted) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
emit(event);
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
if (signal.aborted) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (!finished && result.exitCode !== 0) {
|
|
71
|
+
const message = subprocessFailureMessage(result.exitCode, result.stderr);
|
|
72
|
+
emit({ type: "error", message, ...cell });
|
|
73
|
+
emit({
|
|
74
|
+
type: "cell_finished",
|
|
75
|
+
...cell,
|
|
76
|
+
passed: false,
|
|
77
|
+
durationMs: 0,
|
|
78
|
+
failures: [{ matcher: "liveScenario", message }],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (signal.aborted) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
87
|
+
emit({ type: "error", message, ...cell });
|
|
88
|
+
emit({
|
|
89
|
+
type: "cell_finished",
|
|
90
|
+
...cell,
|
|
91
|
+
passed: false,
|
|
92
|
+
durationMs: 0,
|
|
93
|
+
failures: [{ matcher: "liveScenario", message }],
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
signal.removeEventListener("abort", onAbort);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=live-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-runner.js","sourceRoot":"","sources":["../../src/viewer/live-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/viewer/page.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAA6C,MAAM,cAAc,CAAC;AAklD7F,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAiE/D"}
|