@h-rig/cli 0.0.6-alpha.83 → 0.0.6-alpha.84
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/dist/bin/rig.js +22085 -14618
- package/dist/src/app/board.js +155 -28
- package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
- package/dist/src/app-opentui/adapters/doctor.js +1 -25
- package/dist/src/app-opentui/adapters/family.d.ts +62 -0
- package/dist/src/app-opentui/adapters/family.js +14305 -0
- package/dist/src/app-opentui/adapters/fleet.d.ts +0 -2
- package/dist/src/app-opentui/adapters/fleet.js +6 -40
- package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
- package/dist/src/app-opentui/adapters/inbox.js +54 -59
- package/dist/src/app-opentui/adapters/init.d.ts +0 -2
- package/dist/src/app-opentui/adapters/init.js +0 -26
- package/dist/src/app-opentui/adapters/inspect.d.ts +52 -0
- package/dist/src/app-opentui/adapters/inspect.js +1024 -0
- package/dist/src/app-opentui/adapters/pi-attach.d.ts +15 -6
- package/dist/src/app-opentui/adapters/pi-attach.js +348 -93
- package/dist/src/app-opentui/adapters/pi.d.ts +23 -0
- package/dist/src/app-opentui/adapters/pi.js +363 -0
- package/dist/src/app-opentui/adapters/plugin.d.ts +84 -0
- package/dist/src/app-opentui/adapters/plugin.js +544 -0
- package/dist/src/app-opentui/adapters/repo.d.ts +37 -0
- package/dist/src/app-opentui/adapters/repo.js +186 -0
- package/dist/src/app-opentui/adapters/run-detail.d.ts +9 -2
- package/dist/src/app-opentui/adapters/run-detail.js +97 -44
- package/dist/src/app-opentui/adapters/server.d.ts +10 -2
- package/dist/src/app-opentui/adapters/server.js +96 -27
- package/dist/src/app-opentui/adapters/tasks.d.ts +0 -2
- package/dist/src/app-opentui/adapters/tasks.js +437 -105
- package/dist/src/app-opentui/adapters/workspace.d.ts +49 -0
- package/dist/src/app-opentui/adapters/workspace.js +333 -0
- package/dist/src/app-opentui/autocomplete.d.ts +20 -0
- package/dist/src/app-opentui/autocomplete.js +576 -0
- package/dist/src/app-opentui/bootstrap.js +24296 -16919
- package/dist/src/app-opentui/command-palette.d.ts +3 -0
- package/dist/src/app-opentui/command-palette.js +1010 -0
- package/dist/src/app-opentui/drone.js +8 -6
- package/dist/src/app-opentui/fleet-stats.d.ts +32 -0
- package/dist/src/app-opentui/fleet-stats.js +114 -0
- package/dist/src/app-opentui/index.js +3438 -1724
- package/dist/src/app-opentui/intent.js +71 -48
- package/dist/src/app-opentui/keymap.d.ts +6 -5
- package/dist/src/app-opentui/keymap.js +1064 -23
- package/dist/src/app-opentui/layout.d.ts +7 -0
- package/dist/src/app-opentui/layout.js +13 -6
- package/dist/src/app-opentui/list-search.d.ts +24 -0
- package/dist/src/app-opentui/list-search.js +88 -1
- package/dist/src/app-opentui/pi-host-child.js +33 -1
- package/dist/src/app-opentui/pi-pty-host.d.ts +5 -0
- package/dist/src/app-opentui/pi-pty-host.js +21 -3
- package/dist/src/app-opentui/react/App.d.ts +9 -0
- package/dist/src/app-opentui/react/App.js +5144 -0
- package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
- package/dist/src/app-opentui/react/Backdrop.js +1834 -0
- package/dist/src/app-opentui/react/ChromeHost.d.ts +5 -0
- package/dist/src/app-opentui/react/ChromeHost.js +2942 -0
- package/dist/src/app-opentui/react/SceneFrameView.d.ts +7 -0
- package/dist/src/app-opentui/react/SceneFrameView.js +529 -0
- package/dist/src/app-opentui/react/context.d.ts +17 -0
- package/dist/src/app-opentui/react/context.js +37 -0
- package/dist/src/app-opentui/react/launch.d.ts +2 -0
- package/dist/src/app-opentui/react/launch.js +5743 -0
- package/dist/src/app-opentui/react/nav.d.ts +18 -0
- package/dist/src/app-opentui/react/nav.js +54 -0
- package/dist/src/app-opentui/react/scroll.d.ts +12 -0
- package/dist/src/app-opentui/react/scroll.js +21 -0
- package/dist/src/app-opentui/react/syntax.d.ts +2 -0
- package/dist/src/app-opentui/react/syntax.js +64 -0
- package/dist/src/app-opentui/registry.js +19923 -5151
- package/dist/src/app-opentui/render/constants.d.ts +31 -0
- package/dist/src/app-opentui/render/constants.js +66 -0
- package/dist/src/app-opentui/render/graphics.d.ts +2 -1
- package/dist/src/app-opentui/render/graphics.js +106 -39
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +108 -20
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +7 -0
- package/dist/src/app-opentui/render/image-visual-layer.js +109 -20
- package/dist/src/app-opentui/render/native-host.d.ts +37 -0
- package/dist/src/app-opentui/render/native-host.js +179 -0
- package/dist/src/app-opentui/render/panels.js +18 -11
- package/dist/src/app-opentui/render/preloader.js +8 -6
- package/dist/src/app-opentui/render/scene.d.ts +50 -1
- package/dist/src/app-opentui/render/scene.js +183 -6
- package/dist/src/app-opentui/render/text.d.ts +7 -1
- package/dist/src/app-opentui/render/text.js +10 -7
- package/dist/src/app-opentui/render/type-bar.js +69 -30
- package/dist/src/app-opentui/runtime.d.ts +44 -1
- package/dist/src/app-opentui/runtime.js +3231 -1363
- package/dist/src/app-opentui/scenes/command.js +20 -6
- package/dist/src/app-opentui/scenes/doctor.js +176 -11
- package/dist/src/app-opentui/scenes/error.js +20 -10
- package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/agent.js +348 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.js +195 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.js +243 -0
- package/dist/src/app-opentui/scenes/family-domains/git.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/git.js +195 -0
- package/dist/src/app-opentui/scenes/family-domains/github.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/github.js +274 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.js +152 -0
- package/dist/src/app-opentui/scenes/family-domains/index.d.ts +4 -0
- package/dist/src/app-opentui/scenes/family-domains/index.js +1679 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +76 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.js +305 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.js +212 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.js +146 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.js +518 -0
- package/dist/src/app-opentui/scenes/family-domains/review.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/review.js +280 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.js +267 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.js +370 -0
- package/dist/src/app-opentui/scenes/family.d.ts +3 -0
- package/dist/src/app-opentui/scenes/family.js +2144 -0
- package/dist/src/app-opentui/scenes/fleet.js +521 -31
- package/dist/src/app-opentui/scenes/handoff.js +204 -12
- package/dist/src/app-opentui/scenes/help.js +609 -40
- package/dist/src/app-opentui/scenes/inbox.js +278 -17
- package/dist/src/app-opentui/scenes/init.js +84 -39
- package/dist/src/app-opentui/scenes/inspect.d.ts +3 -0
- package/dist/src/app-opentui/scenes/inspect.js +793 -0
- package/dist/src/app-opentui/scenes/main.js +218 -39
- package/dist/src/app-opentui/scenes/pi.d.ts +3 -0
- package/dist/src/app-opentui/scenes/pi.js +508 -0
- package/dist/src/app-opentui/scenes/plugin.d.ts +3 -0
- package/dist/src/app-opentui/scenes/plugin.js +486 -0
- package/dist/src/app-opentui/scenes/repo.d.ts +3 -0
- package/dist/src/app-opentui/scenes/repo.js +424 -0
- package/dist/src/app-opentui/scenes/run-detail.js +333 -20
- package/dist/src/app-opentui/scenes/server.js +181 -15
- package/dist/src/app-opentui/scenes/tasks.js +486 -31
- package/dist/src/app-opentui/scenes/workspace.d.ts +3 -0
- package/dist/src/app-opentui/scenes/workspace.js +426 -0
- package/dist/src/app-opentui/selectable.d.ts +19 -0
- package/dist/src/app-opentui/selectable.js +79 -0
- package/dist/src/app-opentui/state.js +83 -30
- package/dist/src/app-opentui/surface-catalog.d.ts +20 -0
- package/dist/src/app-opentui/surface-catalog.js +540 -0
- package/dist/src/app-opentui/theme.d.ts +28 -6
- package/dist/src/app-opentui/theme.js +61 -8
- package/dist/src/app-opentui/types.d.ts +121 -4
- package/dist/src/commands/_authority-runs.d.ts +1 -1
- package/dist/src/commands/_authority-runs.js +2 -12
- package/dist/src/commands/_help-catalog.js +95 -15
- package/dist/src/commands/_operator-view.js +34 -2
- package/dist/src/commands/_pi-frontend.d.ts +2 -0
- package/dist/src/commands/_pi-frontend.js +34 -0
- package/dist/src/commands/_server-events.d.ts +26 -0
- package/dist/src/commands/_server-events.js +310 -0
- package/dist/src/commands/agent.js +2 -12
- package/dist/src/commands/run.js +34 -2
- package/dist/src/commands/server.js +2 -12
- package/dist/src/commands/stats.js +95 -15
- package/dist/src/commands/task-run-driver.js +2 -12
- package/dist/src/commands/task.js +131 -29
- package/dist/src/commands.js +192 -31
- package/dist/src/index.js +192 -31
- package/package.json +11 -9
|
@@ -16,15 +16,6 @@ var __export = (target, all) => {
|
|
|
16
16
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
17
|
|
|
18
18
|
// packages/cli/src/app-opentui/adapters/common.ts
|
|
19
|
-
function adapterContextFromRuntime(runtime, renderer) {
|
|
20
|
-
return {
|
|
21
|
-
projectRoot: runtime.getState().projectRoot,
|
|
22
|
-
renderer,
|
|
23
|
-
ensureRuntime: () => runtime.getRunnerContext(),
|
|
24
|
-
emit: (event) => runtime.emit(event),
|
|
25
|
-
getState: () => runtime.getState()
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
19
|
function projectRootOf(ctx) {
|
|
29
20
|
const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
|
|
30
21
|
if (typeof root === "string" && root.trim())
|
|
@@ -74,6 +65,17 @@ function patchData(ctx, data) {
|
|
|
74
65
|
function patchFooter(ctx, footer) {
|
|
75
66
|
ctx.emit({ type: "footer.patch", footer });
|
|
76
67
|
}
|
|
68
|
+
function arrayFromPayload(value) {
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
return value.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry)));
|
|
71
|
+
}
|
|
72
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
73
|
+
const entries = value.entries;
|
|
74
|
+
if (Array.isArray(entries))
|
|
75
|
+
return arrayFromPayload(entries);
|
|
76
|
+
}
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
77
79
|
function stringField(record, keys, fallback = "") {
|
|
78
80
|
for (const key of keys) {
|
|
79
81
|
const value = record[key];
|
|
@@ -93,10 +95,6 @@ function compactRecord(record, keys) {
|
|
|
93
95
|
}
|
|
94
96
|
return out;
|
|
95
97
|
}
|
|
96
|
-
function payloadString(intent, key) {
|
|
97
|
-
const value = intent.action.payload?.[key];
|
|
98
|
-
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
99
|
-
}
|
|
100
98
|
|
|
101
99
|
// packages/cli/src/runner.ts
|
|
102
100
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
@@ -1125,18 +1123,8 @@ import {
|
|
|
1125
1123
|
readJsonlFile,
|
|
1126
1124
|
writeAuthorityRunRecord
|
|
1127
1125
|
} from "@rig/runtime/control-plane/authority-files";
|
|
1128
|
-
function normalizeRuntimeAdapter(
|
|
1129
|
-
|
|
1130
|
-
if (!normalized) {
|
|
1131
|
-
return "pi";
|
|
1132
|
-
}
|
|
1133
|
-
if (normalized === "codex" || normalized === "codex-cli" || normalized === "codex-app-server" || normalized === "gpt-codex") {
|
|
1134
|
-
return "codex";
|
|
1135
|
-
}
|
|
1136
|
-
if (normalized === "pi" || normalized === "rig-pi" || normalized === "@rig/pi") {
|
|
1137
|
-
return "pi";
|
|
1138
|
-
}
|
|
1139
|
-
return "claude-code";
|
|
1126
|
+
function normalizeRuntimeAdapter(_value) {
|
|
1127
|
+
return "pi";
|
|
1140
1128
|
}
|
|
1141
1129
|
var init__authority_runs = __esm(() => {
|
|
1142
1130
|
init__paths();
|
|
@@ -1758,6 +1746,23 @@ function buildOperatorPiEnv(input) {
|
|
|
1758
1746
|
...input.serverProjectRoot ? { RIG_PROJECT_ROOT: input.serverProjectRoot } : {}
|
|
1759
1747
|
};
|
|
1760
1748
|
}
|
|
1749
|
+
function shouldRequireOperatorTranscript(status) {
|
|
1750
|
+
return typeof status === "string" && TERMINAL_RUN_STATUSES.has(status.trim().toLowerCase());
|
|
1751
|
+
}
|
|
1752
|
+
function missingOperatorTranscriptMessage(runId, status) {
|
|
1753
|
+
const shortRun = runId.trim().slice(0, 8) || "unknown";
|
|
1754
|
+
const statusText = typeof status === "string" && status.trim() ? status.trim() : "terminal";
|
|
1755
|
+
return `Run ${shortRun} is ${statusText}, but no worker Pi session transcript is recorded for this run. It likely failed before Pi started or predates full-session capture. Use \`rig run show ${runId}\` and \`rig run logs ${runId}\` for the lifecycle details.`;
|
|
1756
|
+
}
|
|
1757
|
+
function statusFromRunDetails(run) {
|
|
1758
|
+
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
1759
|
+
return;
|
|
1760
|
+
const record = run;
|
|
1761
|
+
if (typeof record.status === "string")
|
|
1762
|
+
return record.status;
|
|
1763
|
+
const nested = record.run;
|
|
1764
|
+
return nested && typeof nested === "object" && !Array.isArray(nested) ? nested.status : undefined;
|
|
1765
|
+
}
|
|
1761
1766
|
async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
1762
1767
|
const server = await ensureServerForCli(context.projectRoot);
|
|
1763
1768
|
const localCwd = join(homedir2(), ".rig", "drones", runId.slice(0, 8));
|
|
@@ -1787,6 +1792,13 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
|
1787
1792
|
sessionFileArg = ["--session", localSessionPath];
|
|
1788
1793
|
}
|
|
1789
1794
|
} catch {}
|
|
1795
|
+
if (sessionFileArg.length === 0) {
|
|
1796
|
+
const run = await getRunDetailsViaServer(context, runId).catch(() => null);
|
|
1797
|
+
const status = statusFromRunDetails(run);
|
|
1798
|
+
if (shouldRequireOperatorTranscript(status)) {
|
|
1799
|
+
throw new OperatorTranscriptUnavailableError(missingOperatorTranscriptMessage(runId, status));
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1790
1802
|
return { server, sessionFileArg };
|
|
1791
1803
|
}
|
|
1792
1804
|
function trustDroneCwd(localCwd) {
|
|
@@ -1858,10 +1870,17 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
1858
1870
|
rendered: "stock Pi operator console with the pi-rig extension"
|
|
1859
1871
|
};
|
|
1860
1872
|
}
|
|
1861
|
-
var RIG_PI_THEME;
|
|
1873
|
+
var TERMINAL_RUN_STATUSES, OperatorTranscriptUnavailableError, RIG_PI_THEME;
|
|
1862
1874
|
var init__pi_frontend = __esm(() => {
|
|
1863
1875
|
init__server_client();
|
|
1864
1876
|
init__async_ui();
|
|
1877
|
+
TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
|
|
1878
|
+
OperatorTranscriptUnavailableError = class OperatorTranscriptUnavailableError extends Error {
|
|
1879
|
+
constructor(message2) {
|
|
1880
|
+
super(message2);
|
|
1881
|
+
this.name = "OperatorTranscriptUnavailableError";
|
|
1882
|
+
}
|
|
1883
|
+
};
|
|
1865
1884
|
RIG_PI_THEME = {
|
|
1866
1885
|
$schema: "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
1867
1886
|
name: "rig",
|
|
@@ -2016,7 +2035,7 @@ async function attachRunOperatorView(context, input) {
|
|
|
2016
2035
|
}
|
|
2017
2036
|
const pollMs = Math.max(250, Math.trunc(input.pollMs ?? 2000));
|
|
2018
2037
|
let timelineCursor = snapshot.timelineCursor;
|
|
2019
|
-
while (!detached && !
|
|
2038
|
+
while (!detached && !TERMINAL_RUN_STATUSES2.has(runStatusFromPayload(snapshot.run))) {
|
|
2020
2039
|
await Bun.sleep(pollMs);
|
|
2021
2040
|
snapshot = await readOperatorSnapshot(context, input.runId, { timelineCursor });
|
|
2022
2041
|
timelineCursor = snapshot.timelineCursor;
|
|
@@ -2028,13 +2047,13 @@ async function attachRunOperatorView(context, input) {
|
|
|
2028
2047
|
}
|
|
2029
2048
|
return { ...snapshot, steered, detached };
|
|
2030
2049
|
}
|
|
2031
|
-
var
|
|
2050
|
+
var TERMINAL_RUN_STATUSES2;
|
|
2032
2051
|
var init__operator_view = __esm(() => {
|
|
2033
2052
|
init__server_client();
|
|
2034
2053
|
init__operator_surface();
|
|
2035
2054
|
init__pi_frontend();
|
|
2036
2055
|
init__async_ui();
|
|
2037
|
-
|
|
2056
|
+
TERMINAL_RUN_STATUSES2 = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
|
|
2038
2057
|
});
|
|
2039
2058
|
|
|
2040
2059
|
// packages/cli/src/commands/_cli-format.ts
|
|
@@ -2564,30 +2583,62 @@ var init__help_catalog = __esm(() => {
|
|
|
2564
2583
|
}
|
|
2565
2584
|
];
|
|
2566
2585
|
ADVANCED_GROUPS = [
|
|
2567
|
-
{
|
|
2568
|
-
|
|
2586
|
+
{
|
|
2587
|
+
name: "setup",
|
|
2588
|
+
summary: "Bootstrap/check local setup.",
|
|
2589
|
+
usage: ["rig setup <bootstrap|check|preflight>"],
|
|
2590
|
+
commands: [
|
|
2591
|
+
{ command: "bootstrap", description: "Bootstrap local setup dependencies.", primary: true },
|
|
2592
|
+
{ command: "check", description: "Check local setup state (toolchain, deps, config).", primary: true },
|
|
2593
|
+
{ command: "preflight", description: "Run preflight checks before a run.", primary: true }
|
|
2594
|
+
]
|
|
2595
|
+
},
|
|
2596
|
+
{
|
|
2597
|
+
name: "profile",
|
|
2598
|
+
summary: "Runtime profile/model defaults.",
|
|
2599
|
+
usage: ["rig profile <show|set>"],
|
|
2600
|
+
commands: [
|
|
2601
|
+
{ command: "show", description: "Show the active execution profile.", primary: true },
|
|
2602
|
+
{ command: "set [--model <model>] [--runtime <runtime>] [--plugin <plugin>]", description: "Set model/runtime/plugin profile defaults.", primary: true }
|
|
2603
|
+
]
|
|
2604
|
+
},
|
|
2569
2605
|
{
|
|
2570
2606
|
name: "review",
|
|
2571
2607
|
summary: "Inspect or change completion review gate policy.",
|
|
2572
2608
|
usage: ["rig review <show|set>"],
|
|
2573
2609
|
commands: [
|
|
2574
2610
|
{ command: "show", description: "Show current review gate settings." },
|
|
2575
|
-
{ command: "set <off|advisory|required> [--provider
|
|
2611
|
+
{ command: "set <off|advisory|required> [--provider <provider>]", description: "Change review strictness/provider (e.g. --provider greptile)." }
|
|
2576
2612
|
],
|
|
2577
2613
|
examples: ["rig review show", "rig review set required --provider greptile"],
|
|
2578
2614
|
next: ["Use `rig inbox approvals` for blocked run handoffs."]
|
|
2579
2615
|
},
|
|
2580
2616
|
{
|
|
2581
2617
|
name: "browser",
|
|
2582
|
-
summary: "Browser
|
|
2583
|
-
usage: ["rig browser <help|explain|demo|
|
|
2618
|
+
summary: "Browser workstation actions for browser-required tasks: launch, check, CDP probe, profile reset, and app-specific smokes.",
|
|
2619
|
+
usage: ["rig browser <help|explain|demo|hp-next|cdp-probe|profile-persistence|profile-lock-check|smoke-test> [options]"],
|
|
2584
2620
|
commands: [
|
|
2585
|
-
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
|
|
2586
|
-
{ command: "explain", description: "Explain the browser-required task contract." },
|
|
2587
|
-
{ command: "demo", description: "Run
|
|
2588
|
-
{ command: "
|
|
2589
|
-
{ command: "hp-next
|
|
2590
|
-
|
|
2621
|
+
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`).", primary: true },
|
|
2622
|
+
{ command: "explain", description: "Explain the browser-required task contract and runtime helper commands.", primary: true },
|
|
2623
|
+
{ command: "demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]", description: "Run a guided real browser/agent demo flow.", primary: true },
|
|
2624
|
+
{ command: "hp-next dev", description: "Start hp-next Rig Browser in dev/watch mode.", primary: true },
|
|
2625
|
+
{ command: "hp-next start", description: "Build/start the hp-next browser workstation without watch mode.", primary: true },
|
|
2626
|
+
{ command: "hp-next check", description: "Validate the hp-next CDP endpoint on the configured port.", primary: true },
|
|
2627
|
+
{ command: "hp-next e2e", description: "Run hp-next browser e2e smoke checks through Rig Browser.", primary: true },
|
|
2628
|
+
{ command: "hp-next reset", description: "Reset the hp-next browser profile when stale browser state is suspected.", primary: true },
|
|
2629
|
+
{ command: "cdp-probe", description: "Run an isolated CDP attach/evaluate/layout probe." },
|
|
2630
|
+
{ command: "profile-persistence", description: "Verify a named browser profile persists browser state." },
|
|
2631
|
+
{ command: "profile-lock-check", description: "Verify concurrent launches reject the same profile." },
|
|
2632
|
+
{ command: "smoke-test", description: "Run the browser package smoke test." }
|
|
2633
|
+
],
|
|
2634
|
+
examples: [
|
|
2635
|
+
"rig browser help",
|
|
2636
|
+
"rig browser hp-next check",
|
|
2637
|
+
"rig browser hp-next e2e",
|
|
2638
|
+
"rig browser cdp-probe",
|
|
2639
|
+
"rig browser profile-lock-check"
|
|
2640
|
+
],
|
|
2641
|
+
next: ["Inside a task run, use rig-browser-launch, rig-browser-check, and rig-browser-attach-info from the worker PATH."]
|
|
2591
2642
|
},
|
|
2592
2643
|
{
|
|
2593
2644
|
name: "pi",
|
|
@@ -2602,12 +2653,60 @@ var init__help_catalog = __esm(() => {
|
|
|
2602
2653
|
examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
|
|
2603
2654
|
next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
|
|
2604
2655
|
},
|
|
2605
|
-
{
|
|
2606
|
-
|
|
2656
|
+
{
|
|
2657
|
+
name: "queue",
|
|
2658
|
+
summary: "Run task queues locally.",
|
|
2659
|
+
usage: ["rig queue run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]"],
|
|
2660
|
+
commands: [
|
|
2661
|
+
{ command: "run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]", description: "Process queue work: drain matching tasks with N workers, optional per-task action and isolation.", primary: true }
|
|
2662
|
+
]
|
|
2663
|
+
},
|
|
2664
|
+
{
|
|
2665
|
+
name: "agent",
|
|
2666
|
+
summary: "Runtime agent workspace helpers.",
|
|
2667
|
+
usage: ["rig agent <list|prepare|run|cleanup>"],
|
|
2668
|
+
commands: [
|
|
2669
|
+
{ command: "list", description: "List prepared agent runtimes.", primary: true },
|
|
2670
|
+
{ command: "prepare [--id <id>] [--mode <mode>] [--task <task>]", description: "Prepare an isolated agent runtime workspace.", primary: true },
|
|
2671
|
+
{ command: "run [--id <id>] [--mode <mode>] [--task <task>] [--skip-project-sync]", description: "Prepare (if needed) and run an agent in its workspace.", primary: true },
|
|
2672
|
+
{ command: "cleanup [--all] [--id <id>]", description: "Remove prepared agent workspaces.", primary: true }
|
|
2673
|
+
]
|
|
2674
|
+
},
|
|
2607
2675
|
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
2608
|
-
{
|
|
2676
|
+
{
|
|
2677
|
+
name: "dist",
|
|
2678
|
+
summary: "Build/install packaged Rig CLI.",
|
|
2679
|
+
usage: ["rig dist <build|install|doctor|rebuild-agent>"],
|
|
2680
|
+
commands: [
|
|
2681
|
+
{ command: "build [--output-dir <dir>]", description: "Build the distributable Rig CLI.", primary: true },
|
|
2682
|
+
{ command: "install [--scope <scope>] [--path <path>]", description: "Install the built CLI to a scope/path.", primary: true },
|
|
2683
|
+
{ command: "doctor", description: "Diagnose the dist toolchain and install state.", primary: true },
|
|
2684
|
+
{ command: "rebuild-agent", description: "Rebuild the agent runtime image, pruning stale images.", primary: true }
|
|
2685
|
+
]
|
|
2686
|
+
},
|
|
2609
2687
|
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
2610
|
-
{
|
|
2688
|
+
{
|
|
2689
|
+
name: "remote",
|
|
2690
|
+
summary: "Compatibility remote orchestration controls.",
|
|
2691
|
+
usage: ["rig remote <status|tasks|watch|pause|resume|continue|stop|refresh|add-iterations|remove-iterations|endpoint ...>"],
|
|
2692
|
+
commands: [
|
|
2693
|
+
{ command: "status [--remote <alias>]", description: "Show the remote orchestration state.", primary: true },
|
|
2694
|
+
{ command: "tasks [--remote <alias>]", description: "List the remote's tracked tasks.", primary: true },
|
|
2695
|
+
{ command: "watch [--remote <alias>] [--seconds <n>] [--event <type>]", description: "Stream remote orchestration events.", primary: true },
|
|
2696
|
+
{ command: "pause [--remote <alias>]", description: "Pause the running remote orchestration.", primary: true },
|
|
2697
|
+
{ command: "resume [--remote <alias>] [--max-workers <n>] [--max-iterations <n>] [--direct-merge]", description: "Resume the remote with optional tuning.", primary: true },
|
|
2698
|
+
{ command: "continue [--remote <alias>]", description: "Continue a paused remote orchestration.", primary: true },
|
|
2699
|
+
{ command: "stop [--remote <alias>]", description: "Stop the remote orchestration.", primary: true },
|
|
2700
|
+
{ command: "refresh [--remote <alias>]", description: "Refresh remote state.", primary: true },
|
|
2701
|
+
{ command: "add-iterations [--count <n>] [--remote <alias>]", description: "Grant the remote more iterations.", primary: true },
|
|
2702
|
+
{ command: "remove-iterations [--count <n>] [--remote <alias>]", description: "Reduce the remote's iteration budget.", primary: true },
|
|
2703
|
+
{ command: "endpoint list", description: "List configured remote endpoints.", primary: true },
|
|
2704
|
+
{ command: "endpoint add --alias <alias> --host <host> --port <n> [--token <token>]", description: "Register a remote endpoint.", primary: true },
|
|
2705
|
+
{ command: "endpoint remove --alias <alias>", description: "Remove a remote endpoint.", primary: true },
|
|
2706
|
+
{ command: "endpoint test [--alias <alias>]", description: "Test connectivity to a remote endpoint.", primary: true },
|
|
2707
|
+
{ command: "endpoint doctor", description: "Diagnose remote endpoint configuration.", primary: true }
|
|
2708
|
+
]
|
|
2709
|
+
},
|
|
2611
2710
|
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
2612
2711
|
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
2613
2712
|
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
@@ -3280,9 +3379,11 @@ class PiPtyHost {
|
|
|
3280
3379
|
cols;
|
|
3281
3380
|
rows;
|
|
3282
3381
|
message = "starting bundled Pi";
|
|
3382
|
+
lastResizeError = null;
|
|
3283
3383
|
exitCode;
|
|
3284
3384
|
signal;
|
|
3285
3385
|
notifyTimer = null;
|
|
3386
|
+
lastStreamKey = "";
|
|
3286
3387
|
_disposed = false;
|
|
3287
3388
|
constructor(options) {
|
|
3288
3389
|
this.runId = options.runId;
|
|
@@ -3299,6 +3400,17 @@ class PiPtyHost {
|
|
|
3299
3400
|
scrollback: 1000
|
|
3300
3401
|
});
|
|
3301
3402
|
this.registerTerminalResponders();
|
|
3403
|
+
this.disposables.push(this.terminal.onWriteParsed(() => {
|
|
3404
|
+
if (this._disposed)
|
|
3405
|
+
return;
|
|
3406
|
+
const snapshot = this.createSnapshot();
|
|
3407
|
+
const key = snapshot.lines.join(`
|
|
3408
|
+
`);
|
|
3409
|
+
if (key === this.lastStreamKey)
|
|
3410
|
+
return;
|
|
3411
|
+
this.lastStreamKey = key;
|
|
3412
|
+
this.onSnapshot?.(snapshot);
|
|
3413
|
+
}));
|
|
3302
3414
|
}
|
|
3303
3415
|
get disposed() {
|
|
3304
3416
|
return this._disposed;
|
|
@@ -3385,7 +3497,10 @@ class PiPtyHost {
|
|
|
3385
3497
|
this.terminal.resize(nextCols, nextRows);
|
|
3386
3498
|
try {
|
|
3387
3499
|
this.pty?.resize(nextCols, nextRows);
|
|
3388
|
-
|
|
3500
|
+
this.lastResizeError = null;
|
|
3501
|
+
} catch (error) {
|
|
3502
|
+
this.lastResizeError = error instanceof Error ? error.message : String(error);
|
|
3503
|
+
}
|
|
3389
3504
|
this.emitSnapshotSoon(0);
|
|
3390
3505
|
}
|
|
3391
3506
|
detach() {
|
|
@@ -3427,7 +3542,7 @@ class PiPtyHost {
|
|
|
3427
3542
|
return;
|
|
3428
3543
|
const text = this.decoder.decode(data, { stream: true });
|
|
3429
3544
|
this.respondToRawTerminalQueries(text);
|
|
3430
|
-
this.terminal.write(data
|
|
3545
|
+
this.terminal.write(data);
|
|
3431
3546
|
}
|
|
3432
3547
|
emitSnapshotSoon(delayMs = SNAPSHOT_DELAY_MS) {
|
|
3433
3548
|
if (this._disposed || this.notifyTimer)
|
|
@@ -3456,6 +3571,7 @@ class PiPtyHost {
|
|
|
3456
3571
|
lines.push("");
|
|
3457
3572
|
styledLines[lines.length - 1] = new StyledText([{ __isChunk: true, text: "" }]);
|
|
3458
3573
|
}
|
|
3574
|
+
const resolvedMessage = this.lastResizeError ? `resize degraded: ${this.lastResizeError}` : message2;
|
|
3459
3575
|
return {
|
|
3460
3576
|
runId: this.runId,
|
|
3461
3577
|
status: this.status,
|
|
@@ -3463,7 +3579,8 @@ class PiPtyHost {
|
|
|
3463
3579
|
rows: this.rows,
|
|
3464
3580
|
lines,
|
|
3465
3581
|
styledLines,
|
|
3466
|
-
message:
|
|
3582
|
+
message: resolvedMessage,
|
|
3583
|
+
...this.lastResizeError ? { resizeError: this.lastResizeError } : {},
|
|
3467
3584
|
...this.exitCode !== undefined ? { exitCode: this.exitCode } : {},
|
|
3468
3585
|
...this.signal !== undefined ? { signal: this.signal } : {}
|
|
3469
3586
|
};
|
|
@@ -3537,7 +3654,7 @@ async function refreshFleet(ctx, options = {}) {
|
|
|
3537
3654
|
const entry = normalizeRunRecord(run);
|
|
3538
3655
|
return entry ? [entry] : [];
|
|
3539
3656
|
});
|
|
3540
|
-
patchData(ctx, { fleet: { runs: normalized, refreshedAt: new Date().toISOString() } });
|
|
3657
|
+
patchData(ctx, { fleet: { runs: normalized, refreshedAt: new Date().toISOString() }, lastRefreshError: undefined });
|
|
3541
3658
|
patchFooter(ctx, { server: serverLabel, runs: String(normalized.length) });
|
|
3542
3659
|
emitCompleted(ctx, label, { count: normalized.length });
|
|
3543
3660
|
return normalized;
|
|
@@ -3548,32 +3665,235 @@ async function refreshFleet(ctx, options = {}) {
|
|
|
3548
3665
|
}
|
|
3549
3666
|
var init_fleet = () => {};
|
|
3550
3667
|
|
|
3668
|
+
// packages/cli/src/app-opentui/adapters/inspect.ts
|
|
3669
|
+
var exports_inspect = {};
|
|
3670
|
+
__export(exports_inspect, {
|
|
3671
|
+
loadInspectRuns: () => loadInspectRuns,
|
|
3672
|
+
loadInspect: () => loadInspect,
|
|
3673
|
+
INSPECT_VIEWS: () => INSPECT_VIEWS
|
|
3674
|
+
});
|
|
3675
|
+
import { execFile } from "child_process";
|
|
3676
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5, readdirSync, statSync } from "fs";
|
|
3677
|
+
import { resolve as resolve4 } from "path";
|
|
3678
|
+
import { promisify } from "util";
|
|
3679
|
+
import { resolveTaskArtifactDirs } from "@rig/runtime/control-plane/authority-files";
|
|
3680
|
+
import { readTaskArtifactPreview } from "@rig/runtime/control-plane/native/workspace-ops";
|
|
3681
|
+
import { resolveHarnessPaths, resolveMonorepoRoot as resolveMonorepoRoot2, runCapture } from "@rig/runtime/control-plane/native/utils";
|
|
3682
|
+
function isFailureEntry(entry) {
|
|
3683
|
+
const status = `${entry.status ?? entry.level ?? entry.type ?? ""}`.toLowerCase();
|
|
3684
|
+
return status.includes("fail") || status.includes("error");
|
|
3685
|
+
}
|
|
3686
|
+
async function gitDiff(projectRoot) {
|
|
3687
|
+
try {
|
|
3688
|
+
const { stdout } = await execFileAsync("git", ["diff", "--no-color"], { cwd: projectRoot, maxBuffer: 8 * 1024 * 1024 });
|
|
3689
|
+
return { diff: stdout };
|
|
3690
|
+
} catch (error) {
|
|
3691
|
+
return { diff: "", error: normalizeAppError(error).message };
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
function listArtifacts(projectRoot, taskId3) {
|
|
3695
|
+
if (!taskId3)
|
|
3696
|
+
return { artifacts: [], error: "run has no task id \u2014 artifacts are resolved per task" };
|
|
3697
|
+
try {
|
|
3698
|
+
const dirs = resolveTaskArtifactDirs(projectRoot, taskId3).filter((dir) => existsSync4(dir));
|
|
3699
|
+
const out = [];
|
|
3700
|
+
const seen = new Set;
|
|
3701
|
+
for (const dir of dirs) {
|
|
3702
|
+
for (const name of readdirSync(dir)) {
|
|
3703
|
+
if (seen.has(name))
|
|
3704
|
+
continue;
|
|
3705
|
+
seen.add(name);
|
|
3706
|
+
const path = resolve4(dir, name);
|
|
3707
|
+
try {
|
|
3708
|
+
const stat = statSync(path);
|
|
3709
|
+
out.push({ name, path, sizeBytes: stat.size, isDir: stat.isDirectory() });
|
|
3710
|
+
} catch {
|
|
3711
|
+
out.push({ name, path, sizeBytes: 0, isDir: false });
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3715
|
+
out.sort((left, right) => left.name.localeCompare(right.name));
|
|
3716
|
+
return { artifacts: out };
|
|
3717
|
+
} catch (error) {
|
|
3718
|
+
return { artifacts: [], error: normalizeAppError(error).message };
|
|
3719
|
+
}
|
|
3720
|
+
}
|
|
3721
|
+
function readArtifact(projectRoot, taskId3, fileName) {
|
|
3722
|
+
if (!taskId3)
|
|
3723
|
+
return;
|
|
3724
|
+
try {
|
|
3725
|
+
const preview = readTaskArtifactPreview(projectRoot, taskId3, fileName);
|
|
3726
|
+
return { name: fileName, contents: preview.contents, truncated: preview.truncated, sizeBytes: preview.sizeBytes };
|
|
3727
|
+
} catch (error) {
|
|
3728
|
+
return { name: fileName, contents: `Failed to read artifact: ${normalizeAppError(error).message}`, truncated: false, sizeBytes: 0 };
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
function loadGraph(projectRoot) {
|
|
3732
|
+
try {
|
|
3733
|
+
const result = runCapture(["br", "--no-db", "list", "--pretty"], resolveMonorepoRoot2(projectRoot));
|
|
3734
|
+
if (result.exitCode !== 0)
|
|
3735
|
+
return { graph: "", error: result.stderr || result.stdout || "failed to inspect graph" };
|
|
3736
|
+
return { graph: result.stdout };
|
|
3737
|
+
} catch (error) {
|
|
3738
|
+
return { graph: "", error: normalizeAppError(error).message };
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
function loadAudit(projectRoot) {
|
|
3742
|
+
try {
|
|
3743
|
+
const auditPath = resolve4(resolveHarnessPaths(projectRoot).logsDir, "audit.jsonl");
|
|
3744
|
+
if (!existsSync4(auditPath))
|
|
3745
|
+
return [];
|
|
3746
|
+
return readFileSync5(auditPath, "utf-8").split(/\r?\n/).filter(Boolean).slice(-50).flatMap((raw) => {
|
|
3747
|
+
try {
|
|
3748
|
+
const parsed = JSON.parse(raw);
|
|
3749
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? [parsed] : [{ detail: raw }];
|
|
3750
|
+
} catch {
|
|
3751
|
+
return [{ detail: raw }];
|
|
3752
|
+
}
|
|
3753
|
+
});
|
|
3754
|
+
} catch {
|
|
3755
|
+
return [];
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
async function loadInspectRuns(ctx, options = {}) {
|
|
3759
|
+
const label = "Loading runs to inspect";
|
|
3760
|
+
emitStarted(ctx, label);
|
|
3761
|
+
try {
|
|
3762
|
+
const projectRoot = projectRootOf(ctx);
|
|
3763
|
+
const { listRunsViaServer: listRunsViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
|
|
3764
|
+
emitProgress(ctx, label, "listing recent runs");
|
|
3765
|
+
const runs = await listRunsViaServer2({ projectRoot }, { limit: options.limit ?? 50 });
|
|
3766
|
+
const options_ = runs.flatMap((record) => {
|
|
3767
|
+
const runId = stringField(record, ["runId", "id"]);
|
|
3768
|
+
if (!runId)
|
|
3769
|
+
return [];
|
|
3770
|
+
const taskId3 = stringField(record, ["taskId"]);
|
|
3771
|
+
const updatedAt = stringField(record, ["updatedAt", "createdAt"]);
|
|
3772
|
+
return [{
|
|
3773
|
+
runId,
|
|
3774
|
+
status: stringField(record, ["status", "state"], "unknown"),
|
|
3775
|
+
title: stringField(record, ["title", "taskTitle", "taskId"], "untitled run"),
|
|
3776
|
+
...taskId3 ? { taskId: taskId3 } : {},
|
|
3777
|
+
...updatedAt ? { updatedAt } : {}
|
|
3778
|
+
}];
|
|
3779
|
+
});
|
|
3780
|
+
patchData(ctx, { inspectRuns: options_, lastRefreshError: undefined });
|
|
3781
|
+
emitCompleted(ctx, label, { count: options_.length });
|
|
3782
|
+
return options_;
|
|
3783
|
+
} catch (error) {
|
|
3784
|
+
emitFailed(ctx, label, error);
|
|
3785
|
+
throw error;
|
|
3786
|
+
}
|
|
3787
|
+
}
|
|
3788
|
+
async function loadInspect(ctx, runId) {
|
|
3789
|
+
const cleanRunId = runId.trim();
|
|
3790
|
+
const label = `Inspecting run ${cleanRunId.slice(0, 8)}`;
|
|
3791
|
+
if (!cleanRunId) {
|
|
3792
|
+
await loadInspectRuns(ctx).catch(() => []);
|
|
3793
|
+
const error = new Error("Inspect requires a run id.");
|
|
3794
|
+
throw error;
|
|
3795
|
+
}
|
|
3796
|
+
emitStarted(ctx, label);
|
|
3797
|
+
try {
|
|
3798
|
+
const projectRoot = projectRootOf(ctx);
|
|
3799
|
+
const { getRunDetailsViaServer: getRunDetailsViaServer2, getRunLogsViaServer: getRunLogsViaServer2, getRunTimelineViaServer: getRunTimelineViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
|
|
3800
|
+
const context = { projectRoot };
|
|
3801
|
+
emitProgress(ctx, label, "loading logs, timeline, diff, artifacts, graph, and audit");
|
|
3802
|
+
const [runPayload, logsPayload, timelinePayload, diffResult] = await Promise.all([
|
|
3803
|
+
getRunDetailsViaServer2(context, cleanRunId).catch((error) => ({ error: normalizeAppError(error).message })),
|
|
3804
|
+
getRunLogsViaServer2(context, cleanRunId, { limit: 500 }).catch(() => []),
|
|
3805
|
+
getRunTimelineViaServer2(context, cleanRunId, { limit: 500 }).catch(() => []),
|
|
3806
|
+
gitDiff(projectRoot)
|
|
3807
|
+
]);
|
|
3808
|
+
const run = runPayload && typeof runPayload === "object" && "run" in runPayload && runPayload.run && typeof runPayload.run === "object" ? runPayload.run : runPayload;
|
|
3809
|
+
const logs = arrayFromPayload(logsPayload);
|
|
3810
|
+
const timeline = arrayFromPayload(timelinePayload);
|
|
3811
|
+
const taskId3 = stringField(run, ["taskId"]) || undefined;
|
|
3812
|
+
const { artifacts, error: artifactsError } = listArtifacts(projectRoot, taskId3);
|
|
3813
|
+
const { graph, error: graphError } = loadGraph(projectRoot);
|
|
3814
|
+
const audit = loadAudit(projectRoot);
|
|
3815
|
+
const state = ctx.getState();
|
|
3816
|
+
const selectedArtifact = typeof state.data?.inspectArtifact === "string" ? state.data.inspectArtifact : undefined;
|
|
3817
|
+
const artifactView = selectedArtifact ? readArtifact(projectRoot, taskId3, selectedArtifact) : undefined;
|
|
3818
|
+
const snapshot = {
|
|
3819
|
+
runId: cleanRunId,
|
|
3820
|
+
status: stringField(run, ["status", "state"], "unknown"),
|
|
3821
|
+
title: stringField(run, ["title", "taskId", "id"], "untitled run"),
|
|
3822
|
+
logs,
|
|
3823
|
+
timeline,
|
|
3824
|
+
diff: diffResult.diff,
|
|
3825
|
+
failures: [...logs, ...timeline].filter(isFailureEntry),
|
|
3826
|
+
artifacts,
|
|
3827
|
+
graph,
|
|
3828
|
+
audit,
|
|
3829
|
+
refreshedAt: Date.now(),
|
|
3830
|
+
...taskId3 ? { taskId: taskId3 } : {},
|
|
3831
|
+
...artifactView ? { artifactView } : {},
|
|
3832
|
+
...diffResult.error ? { diffError: diffResult.error } : {},
|
|
3833
|
+
...graphError ? { graphError } : {},
|
|
3834
|
+
...artifactsError ? { artifactsError } : {}
|
|
3835
|
+
};
|
|
3836
|
+
patchData(ctx, { inspect: snapshot, lastRefreshError: undefined });
|
|
3837
|
+
emitCompleted(ctx, label, {
|
|
3838
|
+
runId: cleanRunId,
|
|
3839
|
+
logs: logs.length,
|
|
3840
|
+
timeline: timeline.length,
|
|
3841
|
+
diffBytes: snapshot.diff.length,
|
|
3842
|
+
artifacts: artifacts.length,
|
|
3843
|
+
audit: audit.length
|
|
3844
|
+
});
|
|
3845
|
+
return snapshot;
|
|
3846
|
+
} catch (error) {
|
|
3847
|
+
emitFailed(ctx, label, error, { runId: cleanRunId });
|
|
3848
|
+
throw error;
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
var execFileAsync, INSPECT_VIEWS;
|
|
3852
|
+
var init_inspect = __esm(() => {
|
|
3853
|
+
execFileAsync = promisify(execFile);
|
|
3854
|
+
INSPECT_VIEWS = [
|
|
3855
|
+
"logs",
|
|
3856
|
+
"timeline",
|
|
3857
|
+
"artifacts",
|
|
3858
|
+
"artifact",
|
|
3859
|
+
"diff",
|
|
3860
|
+
"failures",
|
|
3861
|
+
"graph",
|
|
3862
|
+
"audit"
|
|
3863
|
+
];
|
|
3864
|
+
});
|
|
3865
|
+
|
|
3551
3866
|
// packages/cli/src/app-opentui/adapters/pi-attach.ts
|
|
3552
3867
|
var exports_pi_attach = {};
|
|
3553
3868
|
__export(exports_pi_attach, {
|
|
3554
3869
|
preparePiAttachHandoff: () => preparePiAttachHandoff,
|
|
3555
|
-
createPiAttachAdapter: () => createPiAttachAdapter,
|
|
3556
3870
|
attachRunWithBundledPi: () => attachRunWithBundledPi
|
|
3557
3871
|
});
|
|
3558
|
-
function
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3872
|
+
function currentAttachState(ctx, runId) {
|
|
3873
|
+
const value = ctx.getState().data?.piAttach;
|
|
3874
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3875
|
+
return null;
|
|
3876
|
+
const state = value;
|
|
3877
|
+
return state.runId === runId ? state : null;
|
|
3878
|
+
}
|
|
3879
|
+
function recordStep(ctx, runId, label, emitLabel) {
|
|
3880
|
+
const now = Date.now();
|
|
3881
|
+
const previous = currentAttachState(ctx, runId);
|
|
3882
|
+
const priorSteps = previous?.steps ?? [];
|
|
3883
|
+
const settled = priorSteps.map((step) => step.status === "running" ? { ...step, status: "done", endedAtMs: step.endedAtMs ?? now } : step);
|
|
3884
|
+
const steps = [...settled, { label, startedAtMs: now, status: "running" }];
|
|
3885
|
+
patchData(ctx, {
|
|
3886
|
+
piAttach: { ...previous ?? { runId, status: "preparing", message: label }, runId, steps }
|
|
3887
|
+
});
|
|
3888
|
+
emitProgress(ctx, emitLabel, label);
|
|
3889
|
+
}
|
|
3890
|
+
function settleSteps(ctx, runId) {
|
|
3891
|
+
const now = Date.now();
|
|
3892
|
+
const previous = currentAttachState(ctx, runId);
|
|
3893
|
+
if (!previous?.steps)
|
|
3894
|
+
return;
|
|
3895
|
+
const steps = previous.steps.map((step) => step.status === "running" ? { ...step, status: "done", endedAtMs: step.endedAtMs ?? now } : step);
|
|
3896
|
+
patchData(ctx, { piAttach: { ...previous, steps } });
|
|
3577
3897
|
}
|
|
3578
3898
|
async function preparePiAttachHandoff(ctx, runId) {
|
|
3579
3899
|
const cleanRunId = runId.trim();
|
|
@@ -3582,7 +3902,7 @@ async function preparePiAttachHandoff(ctx, runId) {
|
|
|
3582
3902
|
try {
|
|
3583
3903
|
const { getRunDetailsViaServer: getRunDetailsViaServer2, getRunPiStatusViaServer: getRunPiStatusViaServer2, resolveServerConnectionLabel: resolveServerConnectionLabel2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
|
|
3584
3904
|
const projectRoot = projectRootOf(ctx);
|
|
3585
|
-
|
|
3905
|
+
recordStep(ctx, cleanRunId, "connecting to server \xB7 checking run and Pi session readiness", label);
|
|
3586
3906
|
const [run, piStatus, server] = await Promise.all([
|
|
3587
3907
|
getRunDetailsViaServer2({ projectRoot }, cleanRunId).catch((error) => ({ error: error instanceof Error ? error.message : String(error) })),
|
|
3588
3908
|
getRunPiStatusViaServer2({ projectRoot }, cleanRunId).catch((error) => ({ error: error instanceof Error ? error.message : String(error) })),
|
|
@@ -3593,13 +3913,21 @@ async function preparePiAttachHandoff(ctx, runId) {
|
|
|
3593
3913
|
status: "preparing",
|
|
3594
3914
|
message: "ready to enter worker Pi",
|
|
3595
3915
|
result: { run, piStatus, server },
|
|
3596
|
-
ready: true
|
|
3916
|
+
ready: true,
|
|
3917
|
+
...currentAttachState(ctx, cleanRunId)?.steps ? { steps: currentAttachState(ctx, cleanRunId).steps } : {}
|
|
3597
3918
|
};
|
|
3598
|
-
patchData(ctx, { piAttach: state });
|
|
3919
|
+
patchData(ctx, { piAttach: state, lastRefreshError: undefined });
|
|
3599
3920
|
emitCompleted(ctx, label, { runId: cleanRunId, server });
|
|
3600
3921
|
return state;
|
|
3601
3922
|
} catch (error) {
|
|
3602
|
-
const
|
|
3923
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
3924
|
+
const state = {
|
|
3925
|
+
runId: cleanRunId,
|
|
3926
|
+
status: "failed",
|
|
3927
|
+
message: reason,
|
|
3928
|
+
failureReason: reason,
|
|
3929
|
+
...currentAttachState(ctx, cleanRunId)?.steps ? { steps: currentAttachState(ctx, cleanRunId).steps } : {}
|
|
3930
|
+
};
|
|
3603
3931
|
patchData(ctx, { piAttach: state });
|
|
3604
3932
|
emitFailed(ctx, label, error, { runId: cleanRunId });
|
|
3605
3933
|
throw error;
|
|
@@ -3614,32 +3942,52 @@ async function attachRunWithBundledPi(ctx, runId) {
|
|
|
3614
3942
|
throw error;
|
|
3615
3943
|
}
|
|
3616
3944
|
emitStarted(ctx, label, { piAttach: { runId: cleanRunId, status: "entering-pi" } });
|
|
3617
|
-
patchData(ctx, { piAttach: { runId: cleanRunId, status: "entering-pi", message: "starting bundled Pi" } });
|
|
3945
|
+
patchData(ctx, { piAttach: { runId: cleanRunId, status: "entering-pi", message: "starting bundled Pi", steps: [] } });
|
|
3618
3946
|
try {
|
|
3619
|
-
|
|
3620
|
-
|
|
3947
|
+
recordStep(ctx, cleanRunId, "connecting to server and fetching run transcript", label);
|
|
3948
|
+
await preparePiAttachHandoff(ctx, cleanRunId).catch((error) => {
|
|
3949
|
+
patchData(ctx, { lastRefreshError: normalizeAppError(error).message });
|
|
3950
|
+
return null;
|
|
3951
|
+
});
|
|
3952
|
+
recordStep(ctx, cleanRunId, "spawning Bun PTY host for bundled Pi", label);
|
|
3621
3953
|
const projectRoot = projectRootOf(ctx);
|
|
3622
3954
|
const cols = typeof process.stdout.columns === "number" ? process.stdout.columns : 100;
|
|
3623
3955
|
const rows = Math.max(1, (typeof process.stdout.rows === "number" ? process.stdout.rows : 35) - 1);
|
|
3624
3956
|
const patchTerminal = (snapshot) => {
|
|
3957
|
+
const previousSteps = currentAttachState(ctx, cleanRunId)?.steps;
|
|
3958
|
+
const failed = snapshot.status === "failed";
|
|
3959
|
+
const reason = failed ? snapshot.message ?? `bundled Pi exited with code ${snapshot.exitCode ?? "unknown"}` : undefined;
|
|
3625
3960
|
patchData(ctx, {
|
|
3626
3961
|
piTerminal: snapshot,
|
|
3627
3962
|
piAttach: {
|
|
3628
3963
|
runId: cleanRunId,
|
|
3629
|
-
status:
|
|
3964
|
+
status: failed ? "failed" : snapshot.status === "exited" ? "returned" : "entering-pi",
|
|
3630
3965
|
message: snapshot.message ?? "bundled Pi running",
|
|
3631
|
-
result: { runId: cleanRunId, status: snapshot.status, exitCode: snapshot.exitCode }
|
|
3966
|
+
result: { runId: cleanRunId, status: snapshot.status, exitCode: snapshot.exitCode },
|
|
3967
|
+
...previousSteps ? { steps: previousSteps } : {},
|
|
3968
|
+
...reason ? { failureReason: reason } : {}
|
|
3632
3969
|
}
|
|
3633
3970
|
});
|
|
3634
3971
|
};
|
|
3972
|
+
recordStep(ctx, cleanRunId, "starting bundled Pi", label);
|
|
3635
3973
|
await startPiPtyHost({
|
|
3636
3974
|
runId: cleanRunId,
|
|
3637
3975
|
projectRoot,
|
|
3638
3976
|
cols,
|
|
3639
3977
|
rows,
|
|
3640
|
-
onSnapshot:
|
|
3978
|
+
onSnapshot: (snapshot) => {
|
|
3979
|
+
if (snapshot.status === "running" && snapshot.lines.some((entry) => entry.trim().length > 0)) {
|
|
3980
|
+
settleSteps(ctx, cleanRunId);
|
|
3981
|
+
}
|
|
3982
|
+
patchTerminal(snapshot);
|
|
3983
|
+
},
|
|
3641
3984
|
onExit: (snapshot) => {
|
|
3642
3985
|
patchTerminal(snapshot);
|
|
3986
|
+
if (snapshot.status === "failed") {
|
|
3987
|
+
Promise.resolve().then(() => (init_inspect(), exports_inspect)).then(({ loadInspect: loadInspect2 }) => loadInspect2(ctx, cleanRunId)).catch(() => null);
|
|
3988
|
+
emitFailed(ctx, label, new Error(snapshot.message ?? `bundled Pi exited with code ${snapshot.exitCode ?? "unknown"}`), { runId: cleanRunId, result: { status: snapshot.status, exitCode: snapshot.exitCode } });
|
|
3989
|
+
return;
|
|
3990
|
+
}
|
|
3643
3991
|
emitCompleted(ctx, label, { runId: cleanRunId, result: { status: snapshot.status, exitCode: snapshot.exitCode } });
|
|
3644
3992
|
ctx.emit({ type: "scene.change", scene: "fleet", intent: { scene: "fleet", argv: ["runs"], action: { kind: "refresh", label: "Opening runs" } } });
|
|
3645
3993
|
refreshFleet(ctx).catch((error) => emitFailed(ctx, "Refresh runs", error));
|
|
@@ -3657,7 +4005,16 @@ async function attachRunWithBundledPi(ctx, runId) {
|
|
|
3657
4005
|
emitProgress(ctx, label, "bundled Pi is running", { piAttach: { runId: cleanRunId, status: "entering-pi", message: "bundled Pi running", result: record } });
|
|
3658
4006
|
return record;
|
|
3659
4007
|
} catch (error) {
|
|
3660
|
-
|
|
4008
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
4009
|
+
patchData(ctx, {
|
|
4010
|
+
piAttach: {
|
|
4011
|
+
runId: cleanRunId,
|
|
4012
|
+
status: "failed",
|
|
4013
|
+
message: reason,
|
|
4014
|
+
failureReason: reason,
|
|
4015
|
+
...currentAttachState(ctx, cleanRunId)?.steps ? { steps: currentAttachState(ctx, cleanRunId).steps } : {}
|
|
4016
|
+
}
|
|
4017
|
+
});
|
|
3661
4018
|
emitFailed(ctx, label, error, { runId: cleanRunId });
|
|
3662
4019
|
throw error;
|
|
3663
4020
|
}
|
|
@@ -3669,30 +4026,6 @@ var init_pi_attach = __esm(() => {
|
|
|
3669
4026
|
|
|
3670
4027
|
// packages/cli/src/app-opentui/adapters/tasks.ts
|
|
3671
4028
|
import { randomUUID } from "crypto";
|
|
3672
|
-
function createTasksAdapter() {
|
|
3673
|
-
return {
|
|
3674
|
-
id: "tasks",
|
|
3675
|
-
async handleIntent(runtime, intent) {
|
|
3676
|
-
if (intent.scene !== "tasks" && intent.action.kind !== "task-run-next" && intent.action.kind !== "task-run-id")
|
|
3677
|
-
return false;
|
|
3678
|
-
const ctx = adapterContextFromRuntime(runtime);
|
|
3679
|
-
const detach = intent.action.payload?.detach === true;
|
|
3680
|
-
if (intent.action.kind === "task-run-next") {
|
|
3681
|
-
await submitNextTaskRun(ctx, {}, { detach });
|
|
3682
|
-
return true;
|
|
3683
|
-
}
|
|
3684
|
-
if (intent.action.kind === "task-run-id") {
|
|
3685
|
-
await submitTaskRun(ctx, { taskId: payloadString(intent, "task"), detach });
|
|
3686
|
-
return true;
|
|
3687
|
-
}
|
|
3688
|
-
if (intent.action.kind === "refresh" || intent.action.kind === "navigate") {
|
|
3689
|
-
await refreshTasks(ctx, { limit: 20 });
|
|
3690
|
-
return true;
|
|
3691
|
-
}
|
|
3692
|
-
return false;
|
|
3693
|
-
}
|
|
3694
|
-
};
|
|
3695
|
-
}
|
|
3696
4029
|
function rawRecord(record, key) {
|
|
3697
4030
|
const direct = record[key];
|
|
3698
4031
|
if (direct !== undefined && direct !== null)
|
|
@@ -4096,7 +4429,7 @@ async function loadTaskPreview(ctx, taskId3) {
|
|
|
4096
4429
|
const { getWorkspaceTaskViaServer: getWorkspaceTaskViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
|
|
4097
4430
|
const task = await getWorkspaceTaskViaServer2({ projectRoot: projectRootOf(ctx) }, taskId3);
|
|
4098
4431
|
const normalized = task ? normalizeTaskRecord(task) : null;
|
|
4099
|
-
patchData(ctx, { selectedTaskId: taskId3, taskPreview: normalized, taskPreviewRaw: task ? compactRecord(task, ["id", "title", "status", "body", "url"]) : null });
|
|
4432
|
+
patchData(ctx, { selectedTaskId: taskId3, taskDetailId: taskId3, taskPreview: normalized, taskPreviewRaw: task ? compactRecord(task, ["id", "title", "status", "body", "url"]) : null });
|
|
4100
4433
|
emitCompleted(ctx, label, { taskId: taskId3, found: Boolean(normalized) });
|
|
4101
4434
|
return normalized;
|
|
4102
4435
|
} catch (error) {
|
|
@@ -4114,7 +4447,6 @@ export {
|
|
|
4114
4447
|
normalizeTaskRecord,
|
|
4115
4448
|
loadTaskPreview,
|
|
4116
4449
|
ensureTaskRuntime,
|
|
4117
|
-
createTasksAdapter,
|
|
4118
4450
|
activeRunIdFromTaskRunError,
|
|
4119
4451
|
activeRunIdFromTaskLike
|
|
4120
4452
|
};
|