@h-rig/cli 0.0.6-alpha.7 → 0.0.6-alpha.71
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 +1 -1
- package/dist/bin/rig.js +4507 -1506
- package/dist/src/commands/_async-ui.js +152 -0
- package/dist/src/commands/_authority-runs.js +2 -3
- package/dist/src/commands/_cli-format.js +369 -0
- package/dist/src/commands/_connection-state.js +30 -11
- package/dist/src/commands/_doctor-checks.js +177 -43
- package/dist/src/commands/_help-catalog.js +485 -0
- package/dist/src/commands/_json-output.js +56 -0
- package/dist/src/commands/_operator-surface.js +220 -0
- package/dist/src/commands/_operator-view.js +595 -72
- package/dist/src/commands/_parsers.js +18 -11
- package/dist/src/commands/_pi-frontend.js +411 -0
- package/dist/src/commands/_pi-install.js +4 -3
- package/dist/src/commands/_policy.js +12 -5
- package/dist/src/commands/_preflight.js +187 -127
- package/dist/src/commands/_run-driver-helpers.js +75 -22
- package/dist/src/commands/_run-replay.js +142 -0
- package/dist/src/commands/_server-client.js +343 -60
- package/dist/src/commands/_snapshot-upload.js +160 -38
- package/dist/src/commands/_spinner.js +65 -0
- package/dist/src/commands/_task-picker.js +44 -16
- package/dist/src/commands/agent.js +39 -20
- package/dist/src/commands/browser.js +28 -21
- package/dist/src/commands/connect.js +146 -33
- package/dist/src/commands/dist.js +19 -12
- package/dist/src/commands/doctor.js +304 -44
- package/dist/src/commands/github.js +301 -52
- package/dist/src/commands/inbox.js +679 -72
- package/dist/src/commands/init.js +622 -118
- package/dist/src/commands/inspect.js +515 -32
- package/dist/src/commands/inspector.js +20 -13
- package/dist/src/commands/pi.js +177 -0
- package/dist/src/commands/plugin.js +95 -27
- package/dist/src/commands/profile-and-review.js +26 -19
- package/dist/src/commands/queue.js +32 -12
- package/dist/src/commands/remote.js +43 -36
- package/dist/src/commands/repo-git-harness.js +22 -15
- package/dist/src/commands/run.js +1162 -158
- package/dist/src/commands/server.js +373 -56
- package/dist/src/commands/setup.js +316 -62
- package/dist/src/commands/stats.js +1030 -0
- package/dist/src/commands/task-report-bug.js +29 -22
- package/dist/src/commands/task-run-driver.js +862 -129
- package/dist/src/commands/task.js +1423 -311
- package/dist/src/commands/test.js +15 -8
- package/dist/src/commands/workspace.js +18 -11
- package/dist/src/commands.js +4446 -1499
- package/dist/src/index.js +4502 -1504
- package/dist/src/launcher.js +77 -13
- package/dist/src/report-bug.js +3 -3
- package/dist/src/runner.js +16 -22
- package/package.json +10 -5
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/cli/src/commands/_run-replay.ts
|
|
3
|
+
import { existsSync, readdirSync } from "fs";
|
|
4
|
+
import { join, resolve } from "path";
|
|
5
|
+
import {
|
|
6
|
+
readAuthorityRun,
|
|
7
|
+
readJsonlFile,
|
|
8
|
+
runJournalPath
|
|
9
|
+
} from "@rig/runtime/control-plane/authority-files";
|
|
10
|
+
function asRecord(value) {
|
|
11
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
12
|
+
}
|
|
13
|
+
function text(value) {
|
|
14
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
15
|
+
}
|
|
16
|
+
function snippet(value, max = 120) {
|
|
17
|
+
const raw = text(value);
|
|
18
|
+
if (!raw)
|
|
19
|
+
return null;
|
|
20
|
+
const flat = raw.replace(/\s+/g, " ");
|
|
21
|
+
return flat.length > max ? `${flat.slice(0, max - 1)}\u2026` : flat;
|
|
22
|
+
}
|
|
23
|
+
function summarizeLifecycleEntry(entry) {
|
|
24
|
+
const type = text(entry.type) ?? "event";
|
|
25
|
+
switch (type) {
|
|
26
|
+
case "status": {
|
|
27
|
+
const anchor = text(entry.sessionId);
|
|
28
|
+
return [
|
|
29
|
+
`status \u2192 ${text(entry.status) ?? "(unknown)"}`,
|
|
30
|
+
snippet(entry.detail) ? `\u2014 ${snippet(entry.detail)}` : null,
|
|
31
|
+
anchor ? `[session ${anchor}]` : null
|
|
32
|
+
].filter(Boolean).join(" ");
|
|
33
|
+
}
|
|
34
|
+
case "timeline-entry": {
|
|
35
|
+
const payload = asRecord(entry.payload) ?? {};
|
|
36
|
+
const kind = text(payload.type) ?? "entry";
|
|
37
|
+
const body = snippet(payload.title) ?? snippet(payload.text) ?? snippet(payload.detail);
|
|
38
|
+
const state = text(payload.state);
|
|
39
|
+
return [`timeline ${kind}`, body ? `\u2014 ${body}` : null, state ? `(${state})` : null].filter(Boolean).join(" ");
|
|
40
|
+
}
|
|
41
|
+
case "log-entry": {
|
|
42
|
+
const payload = asRecord(entry.payload) ?? {};
|
|
43
|
+
const title = snippet(payload.title) ?? "log";
|
|
44
|
+
const detail = snippet(payload.detail);
|
|
45
|
+
return [`log ${title}`, detail ? `\u2014 ${detail}` : null].filter(Boolean).join(" ");
|
|
46
|
+
}
|
|
47
|
+
case "record-patch": {
|
|
48
|
+
const patch = asRecord(entry.patch) ?? {};
|
|
49
|
+
const keys = Object.keys(patch);
|
|
50
|
+
const shown = keys.slice(0, 8).join(", ");
|
|
51
|
+
return `record-patch {${shown}${keys.length > 8 ? `, +${keys.length - 8} more` : ""}}`;
|
|
52
|
+
}
|
|
53
|
+
case "timeline":
|
|
54
|
+
return "timeline updated (signal)";
|
|
55
|
+
case "log":
|
|
56
|
+
return `log signal${snippet(entry.title) ? ` \u2014 ${snippet(entry.title)}` : ""}`;
|
|
57
|
+
case "completed":
|
|
58
|
+
return "run completed";
|
|
59
|
+
case "failed":
|
|
60
|
+
return `run failed${snippet(entry.error) ? ` \u2014 ${snippet(entry.error)}` : ""}`;
|
|
61
|
+
default:
|
|
62
|
+
return type;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function summarizeSessionEntry(entry) {
|
|
66
|
+
const type = text(entry.type) ?? "entry";
|
|
67
|
+
const message = asRecord(entry.message);
|
|
68
|
+
const role = text(message?.role);
|
|
69
|
+
const content = message?.content;
|
|
70
|
+
let body = null;
|
|
71
|
+
if (typeof content === "string") {
|
|
72
|
+
body = snippet(content);
|
|
73
|
+
} else if (Array.isArray(content)) {
|
|
74
|
+
body = snippet(content.map((part) => text(asRecord(part)?.text) ?? "").filter(Boolean).join(" "));
|
|
75
|
+
}
|
|
76
|
+
return [
|
|
77
|
+
`pi ${type}`,
|
|
78
|
+
role ? `(${role})` : null,
|
|
79
|
+
body ? `\u2014 ${body}` : null
|
|
80
|
+
].filter(Boolean).join(" ");
|
|
81
|
+
}
|
|
82
|
+
function sessionEntryTimestamp(entry) {
|
|
83
|
+
return text(entry.timestamp) ?? text(entry.at) ?? text(entry.createdAt) ?? null;
|
|
84
|
+
}
|
|
85
|
+
function resolveRunSessionFile(record) {
|
|
86
|
+
const piSession = record?.piSession ?? null;
|
|
87
|
+
if (!piSession)
|
|
88
|
+
return null;
|
|
89
|
+
const recorded = text(piSession.sessionFile);
|
|
90
|
+
if (recorded && existsSync(recorded)) {
|
|
91
|
+
return recorded;
|
|
92
|
+
}
|
|
93
|
+
const cwd = text(piSession.cwd);
|
|
94
|
+
const sessionId = text(piSession.sessionId);
|
|
95
|
+
if (!cwd || !sessionId)
|
|
96
|
+
return null;
|
|
97
|
+
const sessionDir = resolve(cwd, ".rig", "session");
|
|
98
|
+
try {
|
|
99
|
+
const match = readdirSync(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
|
|
100
|
+
return match ? join(sessionDir, match) : null;
|
|
101
|
+
} catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function buildRunReplay(projectRoot, runId, options = {}) {
|
|
106
|
+
const logPath = runJournalPath(projectRoot, runId);
|
|
107
|
+
const record = readAuthorityRun(projectRoot, runId);
|
|
108
|
+
const lifecycleEntries = readJsonlFile(logPath).map((entry) => asRecord(entry)).filter((entry) => entry !== null);
|
|
109
|
+
const merged = lifecycleEntries.map((entry) => ({
|
|
110
|
+
at: text(entry.at),
|
|
111
|
+
source: "run",
|
|
112
|
+
summary: summarizeLifecycleEntry(entry)
|
|
113
|
+
}));
|
|
114
|
+
let sessionFile = null;
|
|
115
|
+
let sessionEntryCount = 0;
|
|
116
|
+
if (options.withSession) {
|
|
117
|
+
sessionFile = resolveRunSessionFile(record);
|
|
118
|
+
if (sessionFile) {
|
|
119
|
+
let lastSeenAt = null;
|
|
120
|
+
const sessionLines = readJsonlFile(sessionFile).map((entry) => asRecord(entry)).filter((entry) => entry !== null).map((entry) => {
|
|
121
|
+
lastSeenAt = sessionEntryTimestamp(entry) ?? lastSeenAt;
|
|
122
|
+
return { at: lastSeenAt, source: "session", summary: summarizeSessionEntry(entry) };
|
|
123
|
+
});
|
|
124
|
+
sessionEntryCount = sessionLines.length;
|
|
125
|
+
merged.push(...sessionLines);
|
|
126
|
+
merged.sort((left, right) => (left.at ?? "").localeCompare(right.at ?? ""));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const lines = merged.map((line) => `${line.at ?? "(no timestamp) "} ${line.source === "run" ? "run " : "session"} ${line.summary}`);
|
|
130
|
+
return {
|
|
131
|
+
runId,
|
|
132
|
+
logPath,
|
|
133
|
+
sessionFile,
|
|
134
|
+
entryCount: lifecycleEntries.length,
|
|
135
|
+
sessionEntryCount,
|
|
136
|
+
lines
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export {
|
|
140
|
+
resolveRunSessionFile,
|
|
141
|
+
buildRunReplay
|
|
142
|
+
};
|