@zephyrdeng/pi-review 0.7.1 → 0.8.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.
- package/README.md +37 -8
- package/README.zh-CN.md +31 -5
- package/dist/args.d.ts +4 -0
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +61 -4
- package/dist/args.js.map +1 -1
- package/dist/args.test.js +62 -1
- package/dist/args.test.js.map +1 -1
- package/dist/child-process.d.ts +3 -0
- package/dist/child-process.d.ts.map +1 -1
- package/dist/child-process.js +27 -5
- package/dist/child-process.js.map +1 -1
- package/dist/child-process.test.js +42 -1
- package/dist/child-process.test.js.map +1 -1
- package/dist/cli-exit.test.js +14 -5
- package/dist/cli-exit.test.js.map +1 -1
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/install-args.test.js +1 -1
- package/dist/install-args.test.js.map +1 -1
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +2 -3
- package/dist/install.js.map +1 -1
- package/dist/json-events.d.ts +6 -0
- package/dist/json-events.d.ts.map +1 -1
- package/dist/json-events.js +48 -6
- package/dist/json-events.js.map +1 -1
- package/dist/json-events.test.js +20 -1
- package/dist/json-events.test.js.map +1 -1
- package/dist/loop.d.ts +28 -2
- package/dist/loop.d.ts.map +1 -1
- package/dist/loop.js +45 -3
- package/dist/loop.js.map +1 -1
- package/dist/loop.test.js +24 -1
- package/dist/loop.test.js.map +1 -1
- package/dist/matcher.test.js +1 -1
- package/dist/matcher.test.js.map +1 -1
- package/dist/meta-footer.d.ts +4 -8
- package/dist/meta-footer.d.ts.map +1 -1
- package/dist/meta-footer.js +19 -5
- package/dist/meta-footer.js.map +1 -1
- package/dist/meta-footer.test.js +11 -4
- package/dist/meta-footer.test.js.map +1 -1
- package/dist/panel-aggregate.test.js +1 -1
- package/dist/panel-aggregate.test.js.map +1 -1
- package/dist/panel-cancellation.test.js +33 -2
- package/dist/panel-cancellation.test.js.map +1 -1
- package/dist/panel-cli-ui.test.d.ts +2 -0
- package/dist/panel-cli-ui.test.d.ts.map +1 -0
- package/dist/panel-cli-ui.test.js +91 -0
- package/dist/panel-cli-ui.test.js.map +1 -0
- package/dist/panel-cli.test.js +37 -39
- package/dist/panel-cli.test.js.map +1 -1
- package/dist/panel-config.d.ts +38 -0
- package/dist/panel-config.d.ts.map +1 -1
- package/dist/panel-config.js +135 -2
- package/dist/panel-config.js.map +1 -1
- package/dist/panel-config.test.js +79 -2
- package/dist/panel-config.test.js.map +1 -1
- package/dist/panel-loop.test.js +1 -1
- package/dist/panel-loop.test.js.map +1 -1
- package/dist/panel-tools.test.js +1 -1
- package/dist/panel-tools.test.js.map +1 -1
- package/dist/panel-ui.d.ts +20 -0
- package/dist/panel-ui.d.ts.map +1 -0
- package/dist/panel-ui.js +84 -0
- package/dist/panel-ui.js.map +1 -0
- package/dist/panel-ui.test.d.ts +2 -0
- package/dist/panel-ui.test.d.ts.map +1 -0
- package/dist/panel-ui.test.js +122 -0
- package/dist/panel-ui.test.js.map +1 -0
- package/dist/panel-view.d.ts +1 -0
- package/dist/panel-view.d.ts.map +1 -1
- package/dist/panel-view.js +40 -6
- package/dist/panel-view.js.map +1 -1
- package/dist/panel-view.test.js +68 -1
- package/dist/panel-view.test.js.map +1 -1
- package/dist/panel.d.ts +11 -1
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +67 -21
- package/dist/panel.js.map +1 -1
- package/dist/prompt.d.ts +2 -0
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +34 -3
- package/dist/prompt.js.map +1 -1
- package/dist/prompt.test.js +21 -2
- package/dist/prompt.test.js.map +1 -1
- package/dist/review-events.test.js +1 -1
- package/dist/review-events.test.js.map +1 -1
- package/dist/review-result.test.js +1 -1
- package/dist/review-result.test.js.map +1 -1
- package/dist/review.js +3 -3
- package/dist/review.js.map +1 -1
- package/dist/review.meta.test.js +1 -1
- package/dist/review.meta.test.js.map +1 -1
- package/dist/skill-protocol.test.js +1 -1
- package/dist/skill-protocol.test.js.map +1 -1
- package/dist/skill-update.test.d.ts +2 -0
- package/dist/skill-update.test.d.ts.map +1 -0
- package/dist/skill-update.test.js +23 -0
- package/dist/skill-update.test.js.map +1 -0
- package/dist/skill.d.ts +22 -0
- package/dist/skill.d.ts.map +1 -1
- package/dist/skill.js +109 -22
- package/dist/skill.js.map +1 -1
- package/dist/types.d.ts +23 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui-client.d.ts +13 -0
- package/dist/ui-client.d.ts.map +1 -0
- package/dist/ui-client.js +161 -0
- package/dist/ui-client.js.map +1 -0
- package/dist/ui-client.test.d.ts +2 -0
- package/dist/ui-client.test.d.ts.map +1 -0
- package/dist/ui-client.test.js +48 -0
- package/dist/ui-client.test.js.map +1 -0
- package/dist/ui-html.d.ts +7 -0
- package/dist/ui-html.d.ts.map +1 -0
- package/dist/ui-html.js +52 -0
- package/dist/ui-html.js.map +1 -0
- package/dist/ui-html.test.d.ts +2 -0
- package/dist/ui-html.test.d.ts.map +1 -0
- package/dist/ui-html.test.js +26 -0
- package/dist/ui-html.test.js.map +1 -0
- package/dist/ui-server-main.d.ts +3 -0
- package/dist/ui-server-main.d.ts.map +1 -0
- package/dist/ui-server-main.js +128 -0
- package/dist/ui-server-main.js.map +1 -0
- package/dist/ui-server-main.test.d.ts +2 -0
- package/dist/ui-server-main.test.d.ts.map +1 -0
- package/dist/ui-server-main.test.js +123 -0
- package/dist/ui-server-main.test.js.map +1 -0
- package/dist/ui-server.d.ts +42 -0
- package/dist/ui-server.d.ts.map +1 -0
- package/dist/ui-server.js +233 -0
- package/dist/ui-server.js.map +1 -0
- package/dist/ui-server.test.d.ts +2 -0
- package/dist/ui-server.test.d.ts.map +1 -0
- package/dist/ui-server.test.js +236 -0
- package/dist/ui-server.test.js.map +1 -0
- package/dist/update.d.ts +2 -0
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +80 -20
- package/dist/update.js.map +1 -1
- package/dist/update.test.d.ts +2 -0
- package/dist/update.test.d.ts.map +1 -0
- package/dist/update.test.js +17 -0
- package/dist/update.test.js.map +1 -0
- package/extensions/panel-tool.test.ts +366 -8
- package/extensions/panel-tool.ts +289 -68
- package/extensions/review.test.ts +79 -0
- package/extensions/review.ts +188 -44
- package/extensions/rv-completions.test.ts +177 -18
- package/extensions/rv-completions.ts +490 -60
- package/extensions/rv-interactive.test.ts +562 -0
- package/extensions/rv-interactive.ts +616 -0
- package/extensions/rv-locale.test.ts +12 -4
- package/extensions/rv-locale.ts +44 -11
- package/extensions/rv-model-picker.test.ts +172 -0
- package/extensions/rv-model-picker.ts +313 -0
- package/extensions/rv-model-priorities.test.ts +29 -9
- package/extensions/rv-model-priorities.ts +23 -8
- package/extensions/rv-prompts.test.ts +274 -2
- package/extensions/rv-prompts.ts +479 -33
- package/extensions/rv-resolve.test.ts +189 -0
- package/extensions/rv-resolve.ts +313 -0
- package/extensions/rv-semantic.test.ts +1 -1
- package/extensions/rv-semantic.ts +38 -4
- package/package.json +7 -4
- package/resources/rv-model-priorities.json +18 -9
- package/skills/pi-review/SKILL.md +84 -60
- package/skills/pi-review/references/codex-tools.md +18 -11
- package/skills/pi-review/references/model-selection.md +49 -28
- package/dist/extensions/review.d.ts +0 -2
- package/dist/extensions/review.js +0 -22
- package/dist/extensions/rv-prompts.d.ts +0 -19
- package/dist/extensions/rv-prompts.js +0 -132
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,2EAA4E,CAAC;AAClG,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhD,eAAO,MAAM,eAAe,8DAA+D,CAAC;AAC5F,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,eAAe,GAAG,iBAAiB,GAAG,QAAQ,CAAC;IACnG,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,kGAAkG;IAClG,MAAM,EAAE,OAAO,CAAC;IAChB,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,SAAS,CAAU,CAAC;AAGlG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,SAAS,CAAU,CAAC;AAGlG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,CAAU,CAAC;AAoH5F,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AActF,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAE/B,yDAAyD;AACzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAU,CAAC;AAE7E,mEAAmE;AACnE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAG,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PanelReviewerView, PanelViewState, ReviewerViewStatus } from "./panel-view.js";
|
|
2
|
+
import type { FindingCluster, TokenUsage } from "./types.js";
|
|
3
|
+
export declare function formatDuration(ms: number | undefined): string;
|
|
4
|
+
export declare function formatUsage(usage: TokenUsage | undefined): string;
|
|
5
|
+
export declare function statusClass(status: ReviewerViewStatus): string;
|
|
6
|
+
/** Pure header summary line; kept separate from DOM writes so it is unit-testable. */
|
|
7
|
+
export declare function headerSummary(state: PanelViewState, now: number): string;
|
|
8
|
+
export declare function headerTitle(state: PanelViewState): string;
|
|
9
|
+
/** Pure reviewer detail line; excludes recent activity, which renders as its own block. */
|
|
10
|
+
export declare function reviewerDetailLine(reviewer: PanelReviewerView, now: number): string;
|
|
11
|
+
export declare function findingDetailLine(cluster: FindingCluster): string;
|
|
12
|
+
export declare function resultsSummary(meta: PanelViewState["meta"]): string;
|
|
13
|
+
//# sourceMappingURL=ui-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-client.d.ts","sourceRoot":"","sources":["../src/ui-client.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE7F,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7D,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAO7D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAGjE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAE9D;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAUxE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEzD;AAED,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAanF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAKjE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG,MAAM,CAGnE"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// Browser renderer for the loopback dashboard (issue #4). Loaded as a plain
|
|
2
|
+
// ES module; resolves its sibling reducer and events endpoint relative to its
|
|
3
|
+
// own script URL so the page needs no server-injected config. All dynamic
|
|
4
|
+
// content is written through textContent, never innerHTML.
|
|
5
|
+
import { createPanelViewState, reducePanelEvent } from "./panel-view.js";
|
|
6
|
+
export function formatDuration(ms) {
|
|
7
|
+
if (ms === undefined || ms < 0)
|
|
8
|
+
return "–";
|
|
9
|
+
const totalSeconds = Math.round(ms / 1000);
|
|
10
|
+
if (totalSeconds < 60)
|
|
11
|
+
return `${totalSeconds}s`;
|
|
12
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
13
|
+
const seconds = totalSeconds % 60;
|
|
14
|
+
return `${minutes}m ${seconds}s`;
|
|
15
|
+
}
|
|
16
|
+
export function formatUsage(usage) {
|
|
17
|
+
if (!usage)
|
|
18
|
+
return "– tokens";
|
|
19
|
+
return `${usage.totalTokens.toLocaleString("en-US")} tokens`;
|
|
20
|
+
}
|
|
21
|
+
export function statusClass(status) {
|
|
22
|
+
return `status status-${status}`;
|
|
23
|
+
}
|
|
24
|
+
/** Pure header summary line; kept separate from DOM writes so it is unit-testable. */
|
|
25
|
+
export function headerSummary(state, now) {
|
|
26
|
+
const elapsed = state.startedAt !== undefined ? formatDuration((state.completedAt ?? now) - state.startedAt) : "–";
|
|
27
|
+
const parts = [
|
|
28
|
+
state.mode,
|
|
29
|
+
state.phase,
|
|
30
|
+
`${state.aggregate.completed}/${state.aggregate.total} completed`,
|
|
31
|
+
elapsed,
|
|
32
|
+
formatUsage(state.aggregate.usage),
|
|
33
|
+
].filter((part) => Boolean(part));
|
|
34
|
+
return parts.join(" · ");
|
|
35
|
+
}
|
|
36
|
+
export function headerTitle(state) {
|
|
37
|
+
return state.target ? `pi-review panel — ${state.target}` : "pi-review panel";
|
|
38
|
+
}
|
|
39
|
+
/** Pure reviewer detail line; excludes recent activity, which renders as its own block. */
|
|
40
|
+
export function reviewerDetailLine(reviewer, now) {
|
|
41
|
+
const durationMs = reviewer.startedAt !== undefined ? (reviewer.completedAt ?? now) - reviewer.startedAt : undefined;
|
|
42
|
+
const activityAgeMs = reviewer.status === "running" && reviewer.activityAt !== undefined ? now - reviewer.activityAt : undefined;
|
|
43
|
+
return [
|
|
44
|
+
reviewer.model ?? "default model",
|
|
45
|
+
reviewer.thinking,
|
|
46
|
+
reviewer.activeTool ? `tool: ${reviewer.activeTool}` : undefined,
|
|
47
|
+
durationMs !== undefined ? formatDuration(durationMs) : undefined,
|
|
48
|
+
formatUsage(reviewer.usage),
|
|
49
|
+
activityAgeMs !== undefined ? `active ${formatDuration(activityAgeMs)} ago` : undefined,
|
|
50
|
+
]
|
|
51
|
+
.filter((part) => Boolean(part))
|
|
52
|
+
.join(" · ");
|
|
53
|
+
}
|
|
54
|
+
export function findingDetailLine(cluster) {
|
|
55
|
+
const support = cluster.supportingReviewerIds.length > 0
|
|
56
|
+
? `${cluster.supportCount} reviewer(s): ${cluster.supportingReviewerIds.join(", ")}`
|
|
57
|
+
: `${cluster.supportCount} reviewer(s)`;
|
|
58
|
+
return [cluster.severity, cluster.path, support].filter((part) => Boolean(part)).join(" · ");
|
|
59
|
+
}
|
|
60
|
+
export function resultsSummary(meta) {
|
|
61
|
+
if (!meta)
|
|
62
|
+
return "";
|
|
63
|
+
return `Result: ${meta.status} (${meta.panelHealth})`;
|
|
64
|
+
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// DOM glue — only executed inside a real browser.
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
function el(tag, opts = {}) {
|
|
69
|
+
const node = document.createElement(tag);
|
|
70
|
+
if (opts.className)
|
|
71
|
+
node.className = opts.className;
|
|
72
|
+
if (opts.text !== undefined)
|
|
73
|
+
node.textContent = opts.text;
|
|
74
|
+
return node;
|
|
75
|
+
}
|
|
76
|
+
function renderReviewerCard(reviewer, now) {
|
|
77
|
+
const card = el("article", { className: "reviewer-card" });
|
|
78
|
+
if (reviewer.status === "queued" || reviewer.status === "running") {
|
|
79
|
+
card.classList.add("is-loading");
|
|
80
|
+
}
|
|
81
|
+
const heading = el("h2");
|
|
82
|
+
const statusLabel = reviewer.status === "queued" ? "loading"
|
|
83
|
+
: reviewer.status === "running" ? "running"
|
|
84
|
+
: reviewer.status;
|
|
85
|
+
heading.append(`${reviewer.role} `, el("span", { className: statusClass(reviewer.status), text: statusLabel }));
|
|
86
|
+
card.append(heading, el("div", { className: "reviewer-detail", text: reviewerDetailLine(reviewer, now) }));
|
|
87
|
+
if (reviewer.recentActivity.length > 0) {
|
|
88
|
+
card.append(el("div", { className: "activity", text: reviewer.recentActivity.join("\n") }));
|
|
89
|
+
}
|
|
90
|
+
else if (reviewer.status === "queued") {
|
|
91
|
+
card.append(el("div", { className: "activity loading-line", text: "waiting to start…" }));
|
|
92
|
+
}
|
|
93
|
+
else if (reviewer.status === "running") {
|
|
94
|
+
card.append(el("div", { className: "activity loading-line", text: "working…" }));
|
|
95
|
+
}
|
|
96
|
+
if (reviewer.error) {
|
|
97
|
+
card.append(el("div", { className: "activity", text: `error: ${reviewer.error}` }));
|
|
98
|
+
}
|
|
99
|
+
return card;
|
|
100
|
+
}
|
|
101
|
+
function renderFindingCluster(cluster, advisory) {
|
|
102
|
+
const wrapper = el("div", { className: advisory ? "finding advisory" : "finding" });
|
|
103
|
+
wrapper.append(el("strong", { text: cluster.summary }), el("div", { text: findingDetailLine(cluster) }));
|
|
104
|
+
return wrapper;
|
|
105
|
+
}
|
|
106
|
+
function render(state) {
|
|
107
|
+
const now = Date.now();
|
|
108
|
+
const title = document.getElementById("run-title");
|
|
109
|
+
const meta = document.getElementById("run-meta");
|
|
110
|
+
if (title)
|
|
111
|
+
title.textContent = headerTitle(state);
|
|
112
|
+
if (meta)
|
|
113
|
+
meta.textContent = headerSummary(state, now);
|
|
114
|
+
const reviewers = document.getElementById("reviewers");
|
|
115
|
+
if (reviewers) {
|
|
116
|
+
reviewers.replaceChildren(...Object.values(state.reviewers).map((reviewer) => renderReviewerCard(reviewer, now)));
|
|
117
|
+
}
|
|
118
|
+
const results = document.getElementById("results");
|
|
119
|
+
if (results) {
|
|
120
|
+
results.replaceChildren();
|
|
121
|
+
if (state.meta) {
|
|
122
|
+
results.append(el("h2", { text: resultsSummary(state.meta) }));
|
|
123
|
+
if (state.meta.confirmedClusters.length > 0) {
|
|
124
|
+
results.append(el("h3", { text: "Confirmed findings" }));
|
|
125
|
+
results.append(...state.meta.confirmedClusters.map((cluster) => renderFindingCluster(cluster, false)));
|
|
126
|
+
}
|
|
127
|
+
if (state.meta.advisories.length > 0) {
|
|
128
|
+
results.append(el("h3", { text: "Advisories" }));
|
|
129
|
+
results.append(...state.meta.advisories.map((cluster) => renderFindingCluster(cluster, true)));
|
|
130
|
+
}
|
|
131
|
+
if (state.meta.confirmedClusters.length === 0 && state.meta.advisories.length === 0) {
|
|
132
|
+
results.append(el("p", { text: "No findings reported." }));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function bootstrap() {
|
|
138
|
+
let state = createPanelViewState();
|
|
139
|
+
render(state);
|
|
140
|
+
const eventsUrl = new URL("../events", import.meta.url).toString();
|
|
141
|
+
const source = new EventSource(eventsUrl);
|
|
142
|
+
source.onmessage = (message) => {
|
|
143
|
+
let event;
|
|
144
|
+
try {
|
|
145
|
+
event = JSON.parse(message.data);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
state = reducePanelEvent(state, event);
|
|
151
|
+
render(state);
|
|
152
|
+
};
|
|
153
|
+
source.onerror = () => {
|
|
154
|
+
const meta = document.getElementById("run-meta");
|
|
155
|
+
if (meta)
|
|
156
|
+
meta.textContent = "reconnecting…";
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (typeof document !== "undefined")
|
|
160
|
+
bootstrap();
|
|
161
|
+
//# sourceMappingURL=ui-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-client.js","sourceRoot":"","sources":["../src/ui-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-client.test.d.ts","sourceRoot":"","sources":["../src/ui-client.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "vitest";
|
|
3
|
+
import { createPanelViewState, reducePanelEvent } from "./panel-view.js";
|
|
4
|
+
import { findingDetailLine, formatDuration, formatUsage, headerSummary, headerTitle, resultsSummary, reviewerDetailLine, statusClass, } from "./ui-client.js";
|
|
5
|
+
test("formatDuration renders seconds and minutes", () => {
|
|
6
|
+
assert.equal(formatDuration(undefined), "–");
|
|
7
|
+
assert.equal(formatDuration(-5), "–");
|
|
8
|
+
assert.equal(formatDuration(4200), "4s");
|
|
9
|
+
assert.equal(formatDuration(65000), "1m 5s");
|
|
10
|
+
});
|
|
11
|
+
test("formatUsage renders total tokens or a placeholder", () => {
|
|
12
|
+
assert.equal(formatUsage(undefined), "– tokens");
|
|
13
|
+
assert.equal(formatUsage({ input: 1, output: 1, cacheRead: 0, cacheWrite: 0, reasoning: 0, totalTokens: 1234 }), "1,234 tokens");
|
|
14
|
+
});
|
|
15
|
+
test("statusClass maps every reviewer status to a CSS class", () => {
|
|
16
|
+
assert.equal(statusClass("queued"), "status status-queued");
|
|
17
|
+
assert.equal(statusClass("failed"), "status status-failed");
|
|
18
|
+
});
|
|
19
|
+
function event(type, seq, payload) {
|
|
20
|
+
return { v: 1, runId: "run-1", seq, at: 1000 + seq, type, ...payload };
|
|
21
|
+
}
|
|
22
|
+
test("headerTitle and headerSummary reflect live reducer state", () => {
|
|
23
|
+
let state = createPanelViewState();
|
|
24
|
+
state = reducePanelEvent(state, event("panel.started", 1, { target: "@src", mode: "code", reviewers: [{ reviewerId: "r1", role: "Reviewer", model: null }] }));
|
|
25
|
+
assert.equal(headerTitle(state), "pi-review panel — @src");
|
|
26
|
+
assert.match(headerSummary(state, 2000), /code · running · 0\/1 completed/);
|
|
27
|
+
state = reducePanelEvent(state, event("reviewer.started", 2, { reviewerId: "r1" }));
|
|
28
|
+
state = reducePanelEvent(state, event("reviewer.completed", 3, {
|
|
29
|
+
reviewerId: "r1",
|
|
30
|
+
submission: { reviewerId: "r1", role: "Reviewer", model: null, durationMs: 10, result: { status: "clean", verdict: "approve", verdictSource: "parsed", findings: [], actionableCount: 0 } },
|
|
31
|
+
}));
|
|
32
|
+
assert.match(headerSummary(state, 2000), /1\/1 completed/);
|
|
33
|
+
});
|
|
34
|
+
test("reviewerDetailLine joins model, thinking, active tool, duration, usage, and activity age", () => {
|
|
35
|
+
assert.equal(reviewerDetailLine({
|
|
36
|
+
reviewerId: "r1", role: "Reviewer", model: "openai/gpt", thinking: "high", status: "running",
|
|
37
|
+
activeTool: "read", turns: 1, recentActivity: [], startedAt: 1000, activityAt: 4000,
|
|
38
|
+
usage: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, reasoning: 0, totalTokens: 500 },
|
|
39
|
+
}, 5000), "openai/gpt · high · tool: read · 4s · 500 tokens · active 1s ago");
|
|
40
|
+
assert.equal(reviewerDetailLine({ reviewerId: "r1", role: "Reviewer", model: null, status: "queued", turns: 0, recentActivity: [] }, 5000), "default model · – tokens");
|
|
41
|
+
assert.equal(reviewerDetailLine({ reviewerId: "r1", role: "Reviewer", model: null, status: "completed", turns: 0, recentActivity: [], startedAt: 1000, completedAt: 3000, activityAt: 3000 }, 9000), "default model · 2s · – tokens", "a completed reviewer's duration is fixed and does not keep growing with wall-clock time");
|
|
42
|
+
});
|
|
43
|
+
test("findingDetailLine includes provenance and resultsSummary formats meta text", () => {
|
|
44
|
+
assert.equal(findingDetailLine({ id: "C1", summary: "x", confirmed: true, supportCount: 2, actionableSupportCount: 2, supportingReviewerIds: ["r1", "r2"], sourceFindingIds: [], severity: "high", path: "src/x.ts" }), "high · src/x.ts · 2 reviewer(s): r1, r2");
|
|
45
|
+
assert.equal(findingDetailLine({ id: "C2", summary: "y", confirmed: false, supportCount: 1, actionableSupportCount: 1, supportingReviewerIds: [], sourceFindingIds: [] }), "1 reviewer(s)");
|
|
46
|
+
assert.equal(resultsSummary(undefined), "");
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=ui-client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-client.test.js","sourceRoot":"","sources":["../src/ui-client.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface DashboardHtmlOptions {
|
|
2
|
+
/** The capability-token path, e.g. "/run/<token>". Used to build absolute asset URLs. */
|
|
3
|
+
runPath: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function renderDashboardHtml(opts: DashboardHtmlOptions): string;
|
|
7
|
+
//# sourceMappingURL=ui-html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-html.d.ts","sourceRoot":"","sources":["../src/ui-html.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,oBAAoB;IACnC,yFAAyF;IACzF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CA4CtE"}
|
package/dist/ui-html.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Pure HTML shell for the loopback dashboard (issue #4). No inline <script>;
|
|
2
|
+
// the page loads one CSP-safe module script that renders everything.
|
|
3
|
+
const HTML_ESCAPES = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
|
|
4
|
+
function escapeHtml(value) {
|
|
5
|
+
return value.replace(/[&<>"']/g, (ch) => HTML_ESCAPES[ch] ?? ch);
|
|
6
|
+
}
|
|
7
|
+
export function renderDashboardHtml(opts) {
|
|
8
|
+
const title = opts.title ?? "pi-review dashboard";
|
|
9
|
+
const scriptSrc = `${opts.runPath}/static/ui-client.js`;
|
|
10
|
+
return `<!doctype html>
|
|
11
|
+
<html lang="en">
|
|
12
|
+
<head>
|
|
13
|
+
<meta charset="utf-8" />
|
|
14
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
15
|
+
<title>${escapeHtml(title)}</title>
|
|
16
|
+
<style>
|
|
17
|
+
:root { color-scheme: light dark; }
|
|
18
|
+
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; margin: 0; padding: 1.5rem; background: Canvas; color: CanvasText; }
|
|
19
|
+
h1 { font-size: 1.15rem; margin: 0 0 0.25rem; }
|
|
20
|
+
header { margin-bottom: 1.25rem; }
|
|
21
|
+
#run-meta { opacity: 0.75; font-size: 0.85rem; }
|
|
22
|
+
.reviewer-card { border: 1px solid GrayText; border-radius: 8px; padding: 0.75rem 1rem; margin-bottom: 0.6rem; }
|
|
23
|
+
.reviewer-card h2 { margin: 0 0 0.35rem; font-size: 0.95rem; font-weight: 600; }
|
|
24
|
+
.status { display: inline-block; padding: 0.1rem 0.5rem; border-radius: 999px; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.02em; color: #fff; }
|
|
25
|
+
.status-queued { background: #6b7280; }
|
|
26
|
+
.status-running { background: #2563eb; animation: pulse 1.4s ease-in-out infinite; }
|
|
27
|
+
.status-completed { background: #16a34a; }
|
|
28
|
+
.status-failed, .status-cancelled { background: #dc2626; }
|
|
29
|
+
.reviewer-card.is-loading { border-color: #2563eb; }
|
|
30
|
+
.reviewer-detail { font-size: 0.85rem; opacity: 0.85; margin: 0.15rem 0; }
|
|
31
|
+
.activity { font-size: 0.8rem; opacity: 0.75; margin: 0.35rem 0 0; white-space: pre-wrap; }
|
|
32
|
+
.loading-line::before { content: "⏳ "; }
|
|
33
|
+
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
|
|
34
|
+
.finding { border-left: 3px solid #dc2626; padding-left: 0.6rem; margin-bottom: 0.6rem; }
|
|
35
|
+
.finding.advisory { border-left-color: #d97706; }
|
|
36
|
+
section h2 { font-size: 1rem; margin: 1.25rem 0 0.5rem; }
|
|
37
|
+
section h3 { font-size: 0.9rem; margin: 0.75rem 0 0.4rem; }
|
|
38
|
+
</style>
|
|
39
|
+
</head>
|
|
40
|
+
<body>
|
|
41
|
+
<header>
|
|
42
|
+
<h1 id="run-title">pi-review panel</h1>
|
|
43
|
+
<div id="run-meta">connecting…</div>
|
|
44
|
+
</header>
|
|
45
|
+
<section id="reviewers" aria-label="Reviewers"></section>
|
|
46
|
+
<section id="results" aria-label="Results"></section>
|
|
47
|
+
<script type="module" src="${scriptSrc}"></script>
|
|
48
|
+
</body>
|
|
49
|
+
</html>
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ui-html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-html.js","sourceRoot":"","sources":["../src/ui-html.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,qEAAqE;AAErE,MAAM,YAAY,GAA2B,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AAErH,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC;AAQD,MAAM,UAAU,mBAAmB,CAAC,IAA0B;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,qBAAqB,CAAC;IAClD,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,OAAO,sBAAsB,CAAC;IACxD,OAAO;;;;;SAKA,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAgCG,SAAS;;;CAGrC,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-html.test.d.ts","sourceRoot":"","sources":["../src/ui-html.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "vitest";
|
|
3
|
+
import { renderDashboardHtml } from "./ui-html.js";
|
|
4
|
+
test("dashboard HTML references the client script under the run's own token path", () => {
|
|
5
|
+
const html = renderDashboardHtml({ runPath: "/run/abc123" });
|
|
6
|
+
assert.match(html, /<script type="module" src="\/run\/abc123\/static\/ui-client\.js"><\/script>/);
|
|
7
|
+
});
|
|
8
|
+
test("dashboard HTML has exactly one script tag and no inline event handlers", () => {
|
|
9
|
+
const html = renderDashboardHtml({ runPath: "/run/abc123" });
|
|
10
|
+
const scriptTags = html.match(/<script/g) ?? [];
|
|
11
|
+
assert.equal(scriptTags.length, 1);
|
|
12
|
+
assert.doesNotMatch(html, /\son\w+\s*=/i);
|
|
13
|
+
});
|
|
14
|
+
test("dashboard HTML escapes an untrusted title", () => {
|
|
15
|
+
const html = renderDashboardHtml({ runPath: "/run/abc123", title: '<img src=x onerror=alert(1)>' });
|
|
16
|
+
assert.doesNotMatch(html, /<img/);
|
|
17
|
+
assert.match(html, /<img src=x onerror=alert\(1\)>/);
|
|
18
|
+
});
|
|
19
|
+
test("dashboard HTML declares the render containers", () => {
|
|
20
|
+
const html = renderDashboardHtml({ runPath: "/run/abc123" });
|
|
21
|
+
assert.match(html, /id="run-title"/);
|
|
22
|
+
assert.match(html, /id="run-meta"/);
|
|
23
|
+
assert.match(html, /id="reviewers"/);
|
|
24
|
+
assert.match(html, /id="results"/);
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=ui-html.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-html.test.js","sourceRoot":"","sources":["../src/ui-html.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,IAAI,CAAC,4EAA4E,EAAE,GAAG,EAAE;IACtF,MAAM,IAAI,GAAG,mBAAmB,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IAC7D,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,6EAA6E,CAAC,CAAC;AACpG,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wEAAwE,EAAE,GAAG,EAAE;IAClF,MAAM,IAAI,GAAG,mBAAmB,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACnC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACrD,MAAM,IAAI,GAAG,mBAAmB,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;IACpG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;IACzD,MAAM,IAAI,GAAG,mBAAmB,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IAC7D,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-server-main.d.ts","sourceRoot":"","sources":["../src/ui-server-main.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Detached loopback dashboard server process (issue #4). panel-ui.ts spawns
|
|
3
|
+
// this via child_process.fork with a temporary IPC channel for the initial
|
|
4
|
+
// ready handshake, then fully detaches it: this process outlives the review
|
|
5
|
+
// process so a browser can reconnect/replay for the configured idle TTL.
|
|
6
|
+
// It never talks back to the parent after the handshake — it only tails the
|
|
7
|
+
// shared events.jsonl artifact on disk.
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import http from "node:http";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
import { createDashboardRequestListener, MAX_RUN_LIFETIME_MS } from "./ui-server.js";
|
|
13
|
+
import { renderDashboardHtml } from "./ui-html.js";
|
|
14
|
+
const TTL_CHECK_INTERVAL_MS = 30_000;
|
|
15
|
+
function readTextAsset(name) {
|
|
16
|
+
return fs.readFileSync(fileURLToPath(new URL(`./${name}`, import.meta.url)), "utf8");
|
|
17
|
+
}
|
|
18
|
+
function isRunComplete(eventsPath) {
|
|
19
|
+
let content;
|
|
20
|
+
try {
|
|
21
|
+
content = fs.readFileSync(eventsPath, "utf8");
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
for (const line of content.split("\n")) {
|
|
27
|
+
if (!line.includes("panel.completed"))
|
|
28
|
+
continue;
|
|
29
|
+
try {
|
|
30
|
+
if (JSON.parse(line).type === "panel.completed")
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
/* malformed/partial line; ignore */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
function main() {
|
|
40
|
+
const [runDir, token, ttlMsArg, ttlCheckIntervalArg] = process.argv.slice(2);
|
|
41
|
+
if (!runDir || !token || !ttlMsArg || !Number.isFinite(Number(ttlMsArg))) {
|
|
42
|
+
process.stderr.write("pi-review-ui-server: expected <runDir> <token> <ttlMs> [ttlCheckIntervalMs]\n");
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const ttlMs = Number(ttlMsArg);
|
|
47
|
+
// Test-only override; production always uses the default 30s cadence.
|
|
48
|
+
const ttlCheckIntervalMs = ttlCheckIntervalArg && Number.isFinite(Number(ttlCheckIntervalArg))
|
|
49
|
+
? Number(ttlCheckIntervalArg)
|
|
50
|
+
: TTL_CHECK_INTERVAL_MS;
|
|
51
|
+
const eventsPath = path.join(runDir, "events.jsonl");
|
|
52
|
+
let staticAssets;
|
|
53
|
+
let html;
|
|
54
|
+
try {
|
|
55
|
+
staticAssets = {
|
|
56
|
+
// panel-view.js's transitive runtime import (panel-usage.js) must be
|
|
57
|
+
// served too, or the browser's ES module graph fails to resolve it.
|
|
58
|
+
"panel-view.js": { contentType: "text/javascript; charset=utf-8", body: readTextAsset("panel-view.js") },
|
|
59
|
+
"panel-usage.js": { contentType: "text/javascript; charset=utf-8", body: readTextAsset("panel-usage.js") },
|
|
60
|
+
"ui-client.js": { contentType: "text/javascript; charset=utf-8", body: readTextAsset("ui-client.js") },
|
|
61
|
+
};
|
|
62
|
+
html = renderDashboardHtml({ runPath: `/run/${token}` });
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
process.send?.({ ready: false, error: error.message });
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const startedAt = Date.now();
|
|
70
|
+
let completedAt;
|
|
71
|
+
let shuttingDown = false;
|
|
72
|
+
const server4 = http.createServer();
|
|
73
|
+
const server6 = http.createServer();
|
|
74
|
+
const ttlTimer = setInterval(() => {
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
if (completedAt === undefined && isRunComplete(eventsPath))
|
|
77
|
+
completedAt = now;
|
|
78
|
+
if (completedAt !== undefined && now - completedAt > ttlMs) {
|
|
79
|
+
shutdown(0);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (now - startedAt > MAX_RUN_LIFETIME_MS)
|
|
83
|
+
shutdown(0);
|
|
84
|
+
}, ttlCheckIntervalMs);
|
|
85
|
+
function shutdown(exitCode) {
|
|
86
|
+
if (shuttingDown)
|
|
87
|
+
return;
|
|
88
|
+
shuttingDown = true;
|
|
89
|
+
clearInterval(ttlTimer);
|
|
90
|
+
for (const server of [server4, server6]) {
|
|
91
|
+
try {
|
|
92
|
+
server.closeAllConnections();
|
|
93
|
+
server.close();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
/* already closed */
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
fs.rmSync(runDir, { recursive: true, force: true });
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* best-effort cleanup */
|
|
104
|
+
}
|
|
105
|
+
process.exit(exitCode);
|
|
106
|
+
}
|
|
107
|
+
process.on("SIGTERM", () => shutdown(0));
|
|
108
|
+
process.on("SIGINT", () => shutdown(0));
|
|
109
|
+
server4.once("error", (error) => {
|
|
110
|
+
process.send?.({ ready: false, error: error.message });
|
|
111
|
+
shutdown(1);
|
|
112
|
+
});
|
|
113
|
+
server4.listen(0, "127.0.0.1", () => {
|
|
114
|
+
const address = server4.address();
|
|
115
|
+
const port = typeof address === "object" && address ? address.port : 0;
|
|
116
|
+
const ctx = { token, port, eventsPath, html, staticAssets };
|
|
117
|
+
const listener = createDashboardRequestListener(ctx);
|
|
118
|
+
server4.on("request", listener);
|
|
119
|
+
// Best-effort IPv6 loopback: never widen to 0.0.0.0, and a bind failure
|
|
120
|
+
// here (dual-stack quirks, IPv6 disabled) must not affect the IPv4 path.
|
|
121
|
+
server6.on("error", () => { });
|
|
122
|
+
server6.on("request", listener);
|
|
123
|
+
server6.listen(port, "::1");
|
|
124
|
+
process.send?.({ ready: true, port });
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
main();
|
|
128
|
+
//# sourceMappingURL=ui-server-main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-server-main.js","sourceRoot":"","sources":["../src/ui-server-main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-server-main.test.d.ts","sourceRoot":"","sources":["../src/ui-server-main.test.ts"],"names":[],"mappings":""}
|