@h-rig/cli 0.0.6-alpha.86 → 0.0.6-alpha.88
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 +287 -578
- package/dist/src/app-opentui/adapters/common.d.ts +3 -0
- package/dist/src/app-opentui/adapters/common.js +4 -0
- package/dist/src/app-opentui/adapters/family.js +31 -4
- package/dist/src/app-opentui/adapters/pi-attach.d.ts +7 -0
- package/dist/src/app-opentui/adapters/pi-attach.js +527 -473
- package/dist/src/app-opentui/adapters/tasks.js +82 -468
- package/dist/src/app-opentui/bootstrap.js +287 -578
- package/dist/src/app-opentui/command-palette.js +1 -0
- package/dist/src/app-opentui/drone.js +1 -0
- package/dist/src/app-opentui/index.js +127 -446
- package/dist/src/app-opentui/keymap.js +2 -387
- package/dist/src/app-opentui/list-search.d.ts +5 -1
- package/dist/src/app-opentui/list-search.js +2 -2
- package/dist/src/app-opentui/pi-host-child.js +31 -4
- package/dist/src/app-opentui/pi-pty-host.d.ts +14 -64
- package/dist/src/app-opentui/pi-pty-host.js +3 -397
- package/dist/src/app-opentui/react/App.js +107 -433
- package/dist/src/app-opentui/react/Backdrop.js +1 -0
- package/dist/src/app-opentui/react/ChromeHost.js +34 -410
- package/dist/src/app-opentui/react/SceneFrameView.js +55 -5
- package/dist/src/app-opentui/react/launch.js +171 -472
- package/dist/src/app-opentui/react/syntax.js +1 -0
- package/dist/src/app-opentui/registry.js +99 -487
- package/dist/src/app-opentui/render/graphics.js +1 -0
- package/dist/src/app-opentui/render/hover.d.ts +11 -0
- package/dist/src/app-opentui/render/hover.js +34 -0
- package/dist/src/app-opentui/render/native-host.js +1 -0
- package/dist/src/app-opentui/render/panels.js +50 -3
- package/dist/src/app-opentui/render/preloader.js +1 -0
- package/dist/src/app-opentui/render/scene.js +1 -0
- package/dist/src/app-opentui/render/terminal-handoff.d.ts +16 -0
- package/dist/src/app-opentui/render/terminal-handoff.js +14 -0
- package/dist/src/app-opentui/render/text.d.ts +13 -0
- package/dist/src/app-opentui/render/text.js +54 -5
- package/dist/src/app-opentui/render/type-bar.js +1 -0
- package/dist/src/app-opentui/runtime.js +127 -446
- package/dist/src/app-opentui/scenes/command.js +1 -0
- package/dist/src/app-opentui/scenes/doctor.js +1 -0
- package/dist/src/app-opentui/scenes/error.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/agent.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/git.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/github.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/index.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/review.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.js +1 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.js +1 -0
- package/dist/src/app-opentui/scenes/family.js +1 -0
- package/dist/src/app-opentui/scenes/fleet.js +3 -5
- package/dist/src/app-opentui/scenes/handoff.js +1 -0
- package/dist/src/app-opentui/scenes/help.js +1 -0
- package/dist/src/app-opentui/scenes/inbox.js +1 -0
- package/dist/src/app-opentui/scenes/init.js +1 -0
- package/dist/src/app-opentui/scenes/inspect.js +1 -0
- package/dist/src/app-opentui/scenes/main.js +1 -0
- package/dist/src/app-opentui/scenes/pi.js +1 -0
- package/dist/src/app-opentui/scenes/plugin.js +1 -0
- package/dist/src/app-opentui/scenes/repo.js +1 -0
- package/dist/src/app-opentui/scenes/run-detail.js +1 -0
- package/dist/src/app-opentui/scenes/server.js +1 -0
- package/dist/src/app-opentui/scenes/tasks.js +3 -5
- package/dist/src/app-opentui/scenes/workspace.js +1 -0
- package/dist/src/app-opentui/selectable.js +1 -0
- package/dist/src/app-opentui/theme.d.ts +1 -0
- package/dist/src/app-opentui/theme.js +1 -0
- package/dist/src/commands/_operator-view.js +31 -4
- package/dist/src/commands/_pi-frontend.d.ts +25 -0
- package/dist/src/commands/_pi-frontend.js +32 -4
- package/dist/src/commands/run.js +31 -4
- package/dist/src/commands/task.js +31 -4
- package/dist/src/commands.js +31 -4
- package/dist/src/index.js +31 -4
- package/package.json +8 -8
|
@@ -12,6 +12,7 @@ var RIG_UI = {
|
|
|
12
12
|
bg2: "#0b0c0e",
|
|
13
13
|
panel: "#101115",
|
|
14
14
|
panel2: "#14161b",
|
|
15
|
+
hover: "#181b24",
|
|
15
16
|
glass: "#1e2230",
|
|
16
17
|
border: "#2a2e3a",
|
|
17
18
|
ink: "#f4f5f8",
|
|
@@ -284,11 +285,8 @@ function withSelectable(line2, item) {
|
|
|
284
285
|
}
|
|
285
286
|
|
|
286
287
|
// packages/cli/src/app-opentui/list-search.ts
|
|
287
|
-
function
|
|
288
|
-
return
|
|
289
|
-
}
|
|
290
|
-
function listSearchQuery(state) {
|
|
291
|
-
return isListSearchScene(state.scene) ? state.typeBar.value.trim() : "";
|
|
288
|
+
function listSearchQuery(_state) {
|
|
289
|
+
return "";
|
|
292
290
|
}
|
|
293
291
|
function valueText(value) {
|
|
294
292
|
if (value === undefined || value === null)
|
|
@@ -12,6 +12,7 @@ var RIG_UI = {
|
|
|
12
12
|
bg2: "#0b0c0e",
|
|
13
13
|
panel: "#101115",
|
|
14
14
|
panel2: "#14161b",
|
|
15
|
+
hover: "#181b24",
|
|
15
16
|
glass: "#1e2230",
|
|
16
17
|
border: "#2a2e3a",
|
|
17
18
|
ink: "#f4f5f8",
|
|
@@ -284,11 +285,8 @@ function withSelectable(line2, item) {
|
|
|
284
285
|
}
|
|
285
286
|
|
|
286
287
|
// packages/cli/src/app-opentui/list-search.ts
|
|
287
|
-
function
|
|
288
|
-
return
|
|
289
|
-
}
|
|
290
|
-
function listSearchQuery(state) {
|
|
291
|
-
return isListSearchScene(state.scene) ? state.typeBar.value.trim() : "";
|
|
288
|
+
function listSearchQuery(_state) {
|
|
289
|
+
return "";
|
|
292
290
|
}
|
|
293
291
|
function valueText(value) {
|
|
294
292
|
if (value === undefined || value === null)
|
|
@@ -1008,6 +1008,29 @@ function installRigPiTheme() {
|
|
|
1008
1008
|
}
|
|
1009
1009
|
} catch {}
|
|
1010
1010
|
}
|
|
1011
|
+
async function runWithProcessExitGuard(body) {
|
|
1012
|
+
const realExit = process.exit;
|
|
1013
|
+
let exitCode = 0;
|
|
1014
|
+
let signalQuit = () => {};
|
|
1015
|
+
const quit = new Promise((resolve3) => {
|
|
1016
|
+
signalQuit = resolve3;
|
|
1017
|
+
});
|
|
1018
|
+
const guardedExit = (code) => {
|
|
1019
|
+
exitCode = typeof code === "number" ? code : 0;
|
|
1020
|
+
signalQuit();
|
|
1021
|
+
return;
|
|
1022
|
+
};
|
|
1023
|
+
process.exit = guardedExit;
|
|
1024
|
+
try {
|
|
1025
|
+
await Promise.race([Promise.resolve().then(body), quit]);
|
|
1026
|
+
} finally {
|
|
1027
|
+
process.exit = realExit;
|
|
1028
|
+
}
|
|
1029
|
+
return exitCode;
|
|
1030
|
+
}
|
|
1031
|
+
function runPiMainReturningOnQuit(args, options) {
|
|
1032
|
+
return runWithProcessExitGuard(() => runPiMain(args, options));
|
|
1033
|
+
}
|
|
1011
1034
|
async function attachRunBundledPiFrontend(context, input) {
|
|
1012
1035
|
const tempSessionDir = mkdtempSync(join(tmpdir(), "rig-pi-frontend-sessions-"));
|
|
1013
1036
|
const { server, sessionFileArg } = await withSpinner(`Opening Pi console for run ${input.runId}\u2026`, () => prepareOperatorConsole(context, input.runId, tempSessionDir), { outputMode: context.outputMode });
|
|
@@ -1023,16 +1046,20 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
1023
1046
|
};
|
|
1024
1047
|
let detached = false;
|
|
1025
1048
|
try {
|
|
1026
|
-
|
|
1049
|
+
const piArgs = [
|
|
1027
1050
|
"--offline",
|
|
1028
1051
|
"--no-extensions",
|
|
1029
1052
|
"--no-skills",
|
|
1030
1053
|
"--no-prompt-templates",
|
|
1031
1054
|
"--no-context-files",
|
|
1032
1055
|
...sessionFileArg
|
|
1033
|
-
]
|
|
1034
|
-
|
|
1035
|
-
|
|
1056
|
+
];
|
|
1057
|
+
const piOptions = { extensionFactories: [piRigExtensionFactory] };
|
|
1058
|
+
if (input.returnOnQuit) {
|
|
1059
|
+
await runPiMainReturningOnQuit(piArgs, piOptions);
|
|
1060
|
+
} else {
|
|
1061
|
+
await runPiMain(piArgs, piOptions);
|
|
1062
|
+
}
|
|
1036
1063
|
detached = true;
|
|
1037
1064
|
} finally {
|
|
1038
1065
|
restoreEnv();
|
|
@@ -22,8 +22,33 @@ export declare function buildOperatorPiEnv(input: {
|
|
|
22
22
|
}): Record<string, string>;
|
|
23
23
|
export declare function shouldRequireOperatorTranscript(status: unknown): boolean;
|
|
24
24
|
export declare function missingOperatorTranscriptMessage(runId: string, status: unknown): string;
|
|
25
|
+
/** Run Pi's `main()` in-process but RETURN to the caller when Pi quits, instead
|
|
26
|
+
* of letting it terminate the process. Pi's interactive quit calls
|
|
27
|
+
* `process.exit(...)` (interactive-mode.js); when the OpenTUI shell hands Pi the
|
|
28
|
+
* terminal IN-PROCESS (the eject), that would kill the whole rig process. We
|
|
29
|
+
* temporarily intercept `process.exit` for the duration of the Pi session,
|
|
30
|
+
* convert the exit into a thrown sentinel that unwinds back here, then restore
|
|
31
|
+
* the real `process.exit`. The OpenTUI store + React tree are still alive (the
|
|
32
|
+
* renderer was only suspended), so the caller resumes the shell at the same
|
|
33
|
+
* state/screen. Returns Pi's intended exit code. */
|
|
34
|
+
/** Run `body` in-process while RETURNING (instead of terminating) when it calls
|
|
35
|
+
* `process.exit`. Used to run Pi's `main()` from the OpenTUI shell so Pi's
|
|
36
|
+
* interactive quit (which calls `process.exit`, interactive-mode.js) returns
|
|
37
|
+
* control to the shell rather than killing the whole rig process.
|
|
38
|
+
*
|
|
39
|
+
* We replace `process.exit` with a guard that resolves a `quit` promise — raced
|
|
40
|
+
* against `body` — instead of terminating, then restore the real `process.exit`.
|
|
41
|
+
* We deliberately do NOT throw from the guard: Pi's `process.exit` calls are
|
|
42
|
+
* terminal (the last statement of their quit path, after Pi has already stopped
|
|
43
|
+
* its render loop and disposed), and Pi often calls exit from a detached input
|
|
44
|
+
* callback where a throw would escape to the event loop (the bug that first
|
|
45
|
+
* shipped — the shell hung). Resolving `quit` synchronously returns control
|
|
46
|
+
* whichever path the exit takes. Returns the intended exit code. Exported for
|
|
47
|
+
* unit testing both exit paths. */
|
|
48
|
+
export declare function runWithProcessExitGuard(body: () => Promise<unknown>): Promise<number>;
|
|
25
49
|
export declare function attachRunBundledPiFrontend(context: Pick<RunnerContext, "projectRoot" | "outputMode">, input: {
|
|
26
50
|
readonly runId: string;
|
|
27
51
|
readonly steered?: boolean;
|
|
52
|
+
readonly returnOnQuit?: boolean;
|
|
28
53
|
}): Promise<AttachResult>;
|
|
29
54
|
export {};
|
|
@@ -774,6 +774,29 @@ function installRigPiTheme() {
|
|
|
774
774
|
}
|
|
775
775
|
} catch {}
|
|
776
776
|
}
|
|
777
|
+
async function runWithProcessExitGuard(body) {
|
|
778
|
+
const realExit = process.exit;
|
|
779
|
+
let exitCode = 0;
|
|
780
|
+
let signalQuit = () => {};
|
|
781
|
+
const quit = new Promise((resolve3) => {
|
|
782
|
+
signalQuit = resolve3;
|
|
783
|
+
});
|
|
784
|
+
const guardedExit = (code) => {
|
|
785
|
+
exitCode = typeof code === "number" ? code : 0;
|
|
786
|
+
signalQuit();
|
|
787
|
+
return;
|
|
788
|
+
};
|
|
789
|
+
process.exit = guardedExit;
|
|
790
|
+
try {
|
|
791
|
+
await Promise.race([Promise.resolve().then(body), quit]);
|
|
792
|
+
} finally {
|
|
793
|
+
process.exit = realExit;
|
|
794
|
+
}
|
|
795
|
+
return exitCode;
|
|
796
|
+
}
|
|
797
|
+
function runPiMainReturningOnQuit(args, options) {
|
|
798
|
+
return runWithProcessExitGuard(() => runPiMain(args, options));
|
|
799
|
+
}
|
|
777
800
|
async function attachRunBundledPiFrontend(context, input) {
|
|
778
801
|
const tempSessionDir = mkdtempSync(join(tmpdir(), "rig-pi-frontend-sessions-"));
|
|
779
802
|
const { server, sessionFileArg } = await withSpinner(`Opening Pi console for run ${input.runId}\u2026`, () => prepareOperatorConsole(context, input.runId, tempSessionDir), { outputMode: context.outputMode });
|
|
@@ -789,16 +812,20 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
789
812
|
};
|
|
790
813
|
let detached = false;
|
|
791
814
|
try {
|
|
792
|
-
|
|
815
|
+
const piArgs = [
|
|
793
816
|
"--offline",
|
|
794
817
|
"--no-extensions",
|
|
795
818
|
"--no-skills",
|
|
796
819
|
"--no-prompt-templates",
|
|
797
820
|
"--no-context-files",
|
|
798
821
|
...sessionFileArg
|
|
799
|
-
]
|
|
800
|
-
|
|
801
|
-
|
|
822
|
+
];
|
|
823
|
+
const piOptions = { extensionFactories: [piRigExtensionFactory] };
|
|
824
|
+
if (input.returnOnQuit) {
|
|
825
|
+
await runPiMainReturningOnQuit(piArgs, piOptions);
|
|
826
|
+
} else {
|
|
827
|
+
await runPiMain(piArgs, piOptions);
|
|
828
|
+
}
|
|
802
829
|
detached = true;
|
|
803
830
|
} finally {
|
|
804
831
|
restoreEnv();
|
|
@@ -820,6 +847,7 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
820
847
|
}
|
|
821
848
|
export {
|
|
822
849
|
shouldRequireOperatorTranscript,
|
|
850
|
+
runWithProcessExitGuard,
|
|
823
851
|
missingOperatorTranscriptMessage,
|
|
824
852
|
buildOperatorPiEnv,
|
|
825
853
|
attachRunBundledPiFrontend
|
package/dist/src/commands/run.js
CHANGED
|
@@ -1246,6 +1246,29 @@ function installRigPiTheme() {
|
|
|
1246
1246
|
}
|
|
1247
1247
|
} catch {}
|
|
1248
1248
|
}
|
|
1249
|
+
async function runWithProcessExitGuard(body) {
|
|
1250
|
+
const realExit = process.exit;
|
|
1251
|
+
let exitCode = 0;
|
|
1252
|
+
let signalQuit = () => {};
|
|
1253
|
+
const quit = new Promise((resolve4) => {
|
|
1254
|
+
signalQuit = resolve4;
|
|
1255
|
+
});
|
|
1256
|
+
const guardedExit = (code) => {
|
|
1257
|
+
exitCode = typeof code === "number" ? code : 0;
|
|
1258
|
+
signalQuit();
|
|
1259
|
+
return;
|
|
1260
|
+
};
|
|
1261
|
+
process.exit = guardedExit;
|
|
1262
|
+
try {
|
|
1263
|
+
await Promise.race([Promise.resolve().then(body), quit]);
|
|
1264
|
+
} finally {
|
|
1265
|
+
process.exit = realExit;
|
|
1266
|
+
}
|
|
1267
|
+
return exitCode;
|
|
1268
|
+
}
|
|
1269
|
+
function runPiMainReturningOnQuit(args, options) {
|
|
1270
|
+
return runWithProcessExitGuard(() => runPiMain(args, options));
|
|
1271
|
+
}
|
|
1249
1272
|
async function attachRunBundledPiFrontend(context, input) {
|
|
1250
1273
|
const tempSessionDir = mkdtempSync(join2(tmpdir(), "rig-pi-frontend-sessions-"));
|
|
1251
1274
|
const { server, sessionFileArg } = await withSpinner(`Opening Pi console for run ${input.runId}\u2026`, () => prepareOperatorConsole(context, input.runId, tempSessionDir), { outputMode: context.outputMode });
|
|
@@ -1261,16 +1284,20 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
1261
1284
|
};
|
|
1262
1285
|
let detached = false;
|
|
1263
1286
|
try {
|
|
1264
|
-
|
|
1287
|
+
const piArgs = [
|
|
1265
1288
|
"--offline",
|
|
1266
1289
|
"--no-extensions",
|
|
1267
1290
|
"--no-skills",
|
|
1268
1291
|
"--no-prompt-templates",
|
|
1269
1292
|
"--no-context-files",
|
|
1270
1293
|
...sessionFileArg
|
|
1271
|
-
]
|
|
1272
|
-
|
|
1273
|
-
|
|
1294
|
+
];
|
|
1295
|
+
const piOptions = { extensionFactories: [piRigExtensionFactory] };
|
|
1296
|
+
if (input.returnOnQuit) {
|
|
1297
|
+
await runPiMainReturningOnQuit(piArgs, piOptions);
|
|
1298
|
+
} else {
|
|
1299
|
+
await runPiMain(piArgs, piOptions);
|
|
1300
|
+
}
|
|
1274
1301
|
detached = true;
|
|
1275
1302
|
} finally {
|
|
1276
1303
|
restoreEnv();
|
|
@@ -1551,6 +1551,29 @@ function installRigPiTheme() {
|
|
|
1551
1551
|
}
|
|
1552
1552
|
} catch {}
|
|
1553
1553
|
}
|
|
1554
|
+
async function runWithProcessExitGuard(body) {
|
|
1555
|
+
const realExit = process.exit;
|
|
1556
|
+
let exitCode = 0;
|
|
1557
|
+
let signalQuit = () => {};
|
|
1558
|
+
const quit = new Promise((resolve3) => {
|
|
1559
|
+
signalQuit = resolve3;
|
|
1560
|
+
});
|
|
1561
|
+
const guardedExit = (code) => {
|
|
1562
|
+
exitCode = typeof code === "number" ? code : 0;
|
|
1563
|
+
signalQuit();
|
|
1564
|
+
return;
|
|
1565
|
+
};
|
|
1566
|
+
process.exit = guardedExit;
|
|
1567
|
+
try {
|
|
1568
|
+
await Promise.race([Promise.resolve().then(body), quit]);
|
|
1569
|
+
} finally {
|
|
1570
|
+
process.exit = realExit;
|
|
1571
|
+
}
|
|
1572
|
+
return exitCode;
|
|
1573
|
+
}
|
|
1574
|
+
function runPiMainReturningOnQuit(args, options) {
|
|
1575
|
+
return runWithProcessExitGuard(() => runPiMain(args, options));
|
|
1576
|
+
}
|
|
1554
1577
|
async function attachRunBundledPiFrontend(context, input) {
|
|
1555
1578
|
const tempSessionDir = mkdtempSync(join(tmpdir(), "rig-pi-frontend-sessions-"));
|
|
1556
1579
|
const { server, sessionFileArg } = await withSpinner(`Opening Pi console for run ${input.runId}\u2026`, () => prepareOperatorConsole(context, input.runId, tempSessionDir), { outputMode: context.outputMode });
|
|
@@ -1566,16 +1589,20 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
1566
1589
|
};
|
|
1567
1590
|
let detached = false;
|
|
1568
1591
|
try {
|
|
1569
|
-
|
|
1592
|
+
const piArgs = [
|
|
1570
1593
|
"--offline",
|
|
1571
1594
|
"--no-extensions",
|
|
1572
1595
|
"--no-skills",
|
|
1573
1596
|
"--no-prompt-templates",
|
|
1574
1597
|
"--no-context-files",
|
|
1575
1598
|
...sessionFileArg
|
|
1576
|
-
]
|
|
1577
|
-
|
|
1578
|
-
|
|
1599
|
+
];
|
|
1600
|
+
const piOptions = { extensionFactories: [piRigExtensionFactory] };
|
|
1601
|
+
if (input.returnOnQuit) {
|
|
1602
|
+
await runPiMainReturningOnQuit(piArgs, piOptions);
|
|
1603
|
+
} else {
|
|
1604
|
+
await runPiMain(piArgs, piOptions);
|
|
1605
|
+
}
|
|
1579
1606
|
detached = true;
|
|
1580
1607
|
} finally {
|
|
1581
1608
|
restoreEnv();
|