@zhuxixi/pi-agent-board 0.3.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/IMPLEMENTATION_PLAN.md +920 -0
- package/LICENSE +21 -0
- package/PRD.md +484 -0
- package/PROGRESS.md +127 -0
- package/README.md +131 -0
- package/VERIFY.md +113 -0
- package/docs/BATCH_SELECTION_READ_FLOW.md +277 -0
- package/docs/EXPLORATION.md +187 -0
- package/docs/PTY_ATTACH_IMPLEMENTATION_PLAN.md +579 -0
- package/docs/superpowers/plans/2026-08-15-screenlog-gc.md +704 -0
- package/docs/superpowers/plans/2026-08-16-attach-double-cursor-jiggle-retry.md +499 -0
- package/docs/superpowers/plans/2026-08-21-dashboard-keypress-lag.md +366 -0
- package/docs/superpowers/specs/2026-08-15-screenlog-gc-design.md +105 -0
- package/docs/superpowers/specs/2026-08-16-attach-double-cursor-jiggle-retry-design.md +142 -0
- package/docs/superpowers/specs/2026-08-21-dashboard-keypress-lag-design.md +59 -0
- package/index.ts +6 -0
- package/package.json +81 -0
- package/runner/job-runner.mjs +420 -0
- package/runner/pty-runner.mjs +310 -0
- package/runner/state-runner.mjs +120 -0
- package/runner/title-runner.mjs +80 -0
- package/scripts/patch-vulns.mjs +59 -0
- package/src/commands/agent-board.ts +318 -0
- package/src/commands/attach-flow.ts +231 -0
- package/src/commands/bg.ts +70 -0
- package/src/core/atomic.mjs +145 -0
- package/src/core/auto-state.mjs +320 -0
- package/src/core/dashboard-render.mjs +10 -0
- package/src/core/derive.mjs +114 -0
- package/src/core/diagnostics.mjs +109 -0
- package/src/core/events.mjs +268 -0
- package/src/core/evidence.mjs +242 -0
- package/src/core/follow-up-queue.mjs +193 -0
- package/src/core/heuristics.mjs +240 -0
- package/src/core/ids.mjs +35 -0
- package/src/core/invocation.mjs +43 -0
- package/src/core/launch-options.mjs +317 -0
- package/src/core/launch.mjs +116 -0
- package/src/core/locks.mjs +80 -0
- package/src/core/paths.mjs +86 -0
- package/src/core/pid.mjs +42 -0
- package/src/core/prewarm-schedule.mjs +41 -0
- package/src/core/prompt-transport.mjs +13 -0
- package/src/core/pty-attach-jiggle-retry.mjs +90 -0
- package/src/core/pty-attach-render.mjs +51 -0
- package/src/core/pty-input.mjs +15 -0
- package/src/core/pty-links.mjs +71 -0
- package/src/core/pty-scroll.mjs +155 -0
- package/src/core/pty-support.mjs +327 -0
- package/src/core/repo.mjs +47 -0
- package/src/core/rows.mjs +290 -0
- package/src/core/screen-log-gc.mjs +198 -0
- package/src/core/screen-log.mjs +160 -0
- package/src/core/session-view.mjs +174 -0
- package/src/core/steering-prompts.mjs +34 -0
- package/src/core/steering.mjs +133 -0
- package/src/core/store.mjs +308 -0
- package/src/core/title.mjs +43 -0
- package/src/core/types.mjs +380 -0
- package/src/core/worktree.mjs +64 -0
- package/src/index.ts +109 -0
- package/src/runtime/service.mjs +1194 -0
- package/src/ui/dashboard-evidence.mjs +85 -0
- package/src/ui/dashboard.ts +1952 -0
- package/src/ui/pty-attach.ts +1378 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** Pure evidence panel rendering helpers for dashboard evidence mode. */
|
|
2
|
+
import { relativeTime, truncate } from "../core/heuristics.mjs";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {{ row:any, evidence:any, diagnostics:any[], paths?:Record<string,string>, width:number, now?:number }} opts
|
|
6
|
+
* @returns {string[]}
|
|
7
|
+
*/
|
|
8
|
+
export function buildEvidencePanel(opts) {
|
|
9
|
+
const width = opts.width ?? 80;
|
|
10
|
+
const now = opts.now ?? Date.now();
|
|
11
|
+
const evidence = opts.evidence ?? {};
|
|
12
|
+
const diagnostics = Array.isArray(opts.diagnostics) ? opts.diagnostics : [];
|
|
13
|
+
const paths = opts.paths ?? {};
|
|
14
|
+
const lines = [];
|
|
15
|
+
lines.push(`Evidence / diagnostics for ${opts.row?.meta?.name ?? "session"}`);
|
|
16
|
+
lines.push(`State: ${opts.row?.state?.semanticState ?? "unknown"} · Outcome: ${evidence.outcome ?? "unknown"}${evidence.ready ? " · ready" : ""}`);
|
|
17
|
+
if (evidence.summary) lines.push(...wrap(`Summary: ${evidence.summary}`, width));
|
|
18
|
+
lines.push("");
|
|
19
|
+
lines.push(`Changed files (${evidence.fileChanges?.length ?? 0})`);
|
|
20
|
+
if (evidence.fileChanges?.length) {
|
|
21
|
+
for (const f of evidence.fileChanges.slice(-12)) lines.push(` ${f.action ?? "changed"} ${f.path}${f.count > 1 ? ` ×${f.count}` : ""}`);
|
|
22
|
+
} else lines.push(" —");
|
|
23
|
+
lines.push("");
|
|
24
|
+
lines.push(`Commands (${evidence.commands?.length ?? 0})`);
|
|
25
|
+
if (evidence.commands?.length) {
|
|
26
|
+
for (const c of evidence.commands.slice(-12)) {
|
|
27
|
+
const status = c.status === "failed" ? "✗" : c.status === "passed" ? "✓" : c.status === "started" ? "…" : "?";
|
|
28
|
+
lines.push(...wrap(` ${status} [${c.kind ?? "other"}] ${c.command || "command"}`, width, 2));
|
|
29
|
+
if (c.outputPreview) lines.push(...wrap(` ${c.outputPreview}`, width, 2));
|
|
30
|
+
}
|
|
31
|
+
} else lines.push(" —");
|
|
32
|
+
lines.push("");
|
|
33
|
+
lines.push(`Errors (${evidence.errors?.length ?? 0})`);
|
|
34
|
+
if (evidence.errors?.length) {
|
|
35
|
+
for (const e of evidence.errors.slice(-8)) lines.push(...wrap(` ${e.source ?? "error"}: ${e.message}`, width, 2));
|
|
36
|
+
} else lines.push(" —");
|
|
37
|
+
lines.push("");
|
|
38
|
+
lines.push("Latest assistant evidence");
|
|
39
|
+
const latest = evidence.assistantEvidence?.[evidence.assistantEvidence.length - 1]?.text;
|
|
40
|
+
lines.push(...wrap(` ${latest || "—"}`, width, 8));
|
|
41
|
+
lines.push("");
|
|
42
|
+
lines.push(`Diagnostics (${diagnostics.length} shown)`);
|
|
43
|
+
if (diagnostics.length) {
|
|
44
|
+
for (const d of diagnostics.slice(-12)) {
|
|
45
|
+
const age = d.at ? relativeTime(d.at, now) : "?";
|
|
46
|
+
lines.push(...wrap(` ${age} ${String(d.level ?? "info").toUpperCase()} ${d.code ?? "event"}: ${d.message ?? ""}`, width, 2));
|
|
47
|
+
}
|
|
48
|
+
} else lines.push(" —");
|
|
49
|
+
lines.push("");
|
|
50
|
+
lines.push("Artifacts");
|
|
51
|
+
for (const [name, value] of Object.entries(paths)) {
|
|
52
|
+
if (value) lines.push(...wrap(` ${name}: ${value}`, width, 2));
|
|
53
|
+
}
|
|
54
|
+
if (Object.keys(paths).length === 0) lines.push(" —");
|
|
55
|
+
return lines.map((line) => clip(line, width));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @param {string} text @param {number} width @param {number} [maxLines] */
|
|
59
|
+
function wrap(text, width, maxLines = 10) {
|
|
60
|
+
const words = String(text ?? "").split(/\s+/);
|
|
61
|
+
const out = [];
|
|
62
|
+
let line = "";
|
|
63
|
+
for (const word of words) {
|
|
64
|
+
if (!word) continue;
|
|
65
|
+
const next = line ? `${line} ${word}` : word;
|
|
66
|
+
if (visibleLength(next) > width && line) {
|
|
67
|
+
out.push(line);
|
|
68
|
+
line = word;
|
|
69
|
+
} else line = next;
|
|
70
|
+
if (out.length >= maxLines) break;
|
|
71
|
+
}
|
|
72
|
+
if (line && out.length < maxLines) out.push(line);
|
|
73
|
+
if (out.length === maxLines && words.length > 0) out[out.length - 1] = truncate(out[out.length - 1], Math.max(1, width - 1));
|
|
74
|
+
return out.length ? out : [""];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @param {string} line @param {number} width */
|
|
78
|
+
function clip(line, width) {
|
|
79
|
+
return truncate(line, Math.max(1, width));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** @param {string} s */
|
|
83
|
+
function visibleLength(s) {
|
|
84
|
+
return String(s || "").replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
85
|
+
}
|