@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
|
@@ -91,6 +91,21 @@ async function captureConsole(fn) {
|
|
|
91
91
|
console.error = original.error;
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
+
async function releaseRendererForExternalTui(ctx) {
|
|
95
|
+
const renderer = ctx.renderer;
|
|
96
|
+
if (!renderer)
|
|
97
|
+
return;
|
|
98
|
+
if (renderer.suspend) {
|
|
99
|
+
await renderer.suspend();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (renderer.destroy) {
|
|
103
|
+
await renderer.destroy();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function resumeRendererAfterExternalTui(ctx) {
|
|
107
|
+
await ctx.renderer?.resume?.();
|
|
108
|
+
}
|
|
94
109
|
function arrayFromPayload(value) {
|
|
95
110
|
if (Array.isArray(value)) {
|
|
96
111
|
return value.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry)));
|
|
@@ -8882,6 +8897,14 @@ var init__operator_surface = __esm(() => {
|
|
|
8882
8897
|
});
|
|
8883
8898
|
|
|
8884
8899
|
// packages/cli/src/commands/_pi-frontend.ts
|
|
8900
|
+
var exports__pi_frontend = {};
|
|
8901
|
+
__export(exports__pi_frontend, {
|
|
8902
|
+
shouldRequireOperatorTranscript: () => shouldRequireOperatorTranscript,
|
|
8903
|
+
runWithProcessExitGuard: () => runWithProcessExitGuard,
|
|
8904
|
+
missingOperatorTranscriptMessage: () => missingOperatorTranscriptMessage,
|
|
8905
|
+
buildOperatorPiEnv: () => buildOperatorPiEnv,
|
|
8906
|
+
attachRunBundledPiFrontend: () => attachRunBundledPiFrontend
|
|
8907
|
+
});
|
|
8885
8908
|
import { existsSync as existsSync14, mkdirSync as mkdirSync9, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
8886
8909
|
import { homedir as homedir6, tmpdir } from "os";
|
|
8887
8910
|
import { join as join3 } from "path";
|
|
@@ -8994,6 +9017,29 @@ function installRigPiTheme() {
|
|
|
8994
9017
|
}
|
|
8995
9018
|
} catch {}
|
|
8996
9019
|
}
|
|
9020
|
+
async function runWithProcessExitGuard(body) {
|
|
9021
|
+
const realExit = process.exit;
|
|
9022
|
+
let exitCode = 0;
|
|
9023
|
+
let signalQuit = () => {};
|
|
9024
|
+
const quit = new Promise((resolve22) => {
|
|
9025
|
+
signalQuit = resolve22;
|
|
9026
|
+
});
|
|
9027
|
+
const guardedExit = (code) => {
|
|
9028
|
+
exitCode = typeof code === "number" ? code : 0;
|
|
9029
|
+
signalQuit();
|
|
9030
|
+
return;
|
|
9031
|
+
};
|
|
9032
|
+
process.exit = guardedExit;
|
|
9033
|
+
try {
|
|
9034
|
+
await Promise.race([Promise.resolve().then(body), quit]);
|
|
9035
|
+
} finally {
|
|
9036
|
+
process.exit = realExit;
|
|
9037
|
+
}
|
|
9038
|
+
return exitCode;
|
|
9039
|
+
}
|
|
9040
|
+
function runPiMainReturningOnQuit(args, options) {
|
|
9041
|
+
return runWithProcessExitGuard(() => runPiMain(args, options));
|
|
9042
|
+
}
|
|
8997
9043
|
async function attachRunBundledPiFrontend(context, input) {
|
|
8998
9044
|
const tempSessionDir = mkdtempSync(join3(tmpdir(), "rig-pi-frontend-sessions-"));
|
|
8999
9045
|
const { server, sessionFileArg } = await withSpinner(`Opening Pi console for run ${input.runId}\u2026`, () => prepareOperatorConsole(context, input.runId, tempSessionDir), { outputMode: context.outputMode });
|
|
@@ -9009,16 +9055,20 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
9009
9055
|
};
|
|
9010
9056
|
let detached = false;
|
|
9011
9057
|
try {
|
|
9012
|
-
|
|
9058
|
+
const piArgs = [
|
|
9013
9059
|
"--offline",
|
|
9014
9060
|
"--no-extensions",
|
|
9015
9061
|
"--no-skills",
|
|
9016
9062
|
"--no-prompt-templates",
|
|
9017
9063
|
"--no-context-files",
|
|
9018
9064
|
...sessionFileArg
|
|
9019
|
-
]
|
|
9020
|
-
|
|
9021
|
-
|
|
9065
|
+
];
|
|
9066
|
+
const piOptions = { extensionFactories: [piRigExtensionFactory] };
|
|
9067
|
+
if (input.returnOnQuit) {
|
|
9068
|
+
await runPiMainReturningOnQuit(piArgs, piOptions);
|
|
9069
|
+
} else {
|
|
9070
|
+
await runPiMain(piArgs, piOptions);
|
|
9071
|
+
}
|
|
9022
9072
|
detached = true;
|
|
9023
9073
|
} finally {
|
|
9024
9074
|
restoreEnv();
|
|
@@ -14284,390 +14334,6 @@ async function stopFleetRun(ctx, runId) {
|
|
|
14284
14334
|
}
|
|
14285
14335
|
var init_fleet = () => {};
|
|
14286
14336
|
|
|
14287
|
-
// packages/cli/src/app-opentui/pi-pty-host.ts
|
|
14288
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
14289
|
-
import { basename as basename4 } from "path";
|
|
14290
|
-
import { RGBA, StyledText, TextAttributes } from "@opentui/core";
|
|
14291
|
-
import { Terminal as XtermTerminal2 } from "@xterm/headless";
|
|
14292
|
-
function clampCols2(cols) {
|
|
14293
|
-
return Math.max(MIN_COLS2, Math.trunc(cols || 100));
|
|
14294
|
-
}
|
|
14295
|
-
function clampRows2(rows) {
|
|
14296
|
-
return Math.max(MIN_ROWS2, Math.min(MAX_ROWS2, Math.trunc(rows || 35)));
|
|
14297
|
-
}
|
|
14298
|
-
function rgbaFromXtermColor(mode, value) {
|
|
14299
|
-
if (mode === 1 || mode === 2 || mode === XTERM_COLOR_MODE_INDEXED_16 || mode === XTERM_COLOR_MODE_INDEXED_256) {
|
|
14300
|
-
return RGBA.fromIndex(value);
|
|
14301
|
-
}
|
|
14302
|
-
if (mode === 3 || mode === XTERM_COLOR_MODE_RGB) {
|
|
14303
|
-
return RGBA.fromInts(value >> 16 & 255, value >> 8 & 255, value & 255);
|
|
14304
|
-
}
|
|
14305
|
-
return;
|
|
14306
|
-
}
|
|
14307
|
-
function textAttributesFromCell(cell) {
|
|
14308
|
-
let attributes = TextAttributes.NONE;
|
|
14309
|
-
if (cell.isBold())
|
|
14310
|
-
attributes |= TextAttributes.BOLD;
|
|
14311
|
-
if (cell.isDim())
|
|
14312
|
-
attributes |= TextAttributes.DIM;
|
|
14313
|
-
if (cell.isItalic())
|
|
14314
|
-
attributes |= TextAttributes.ITALIC;
|
|
14315
|
-
if (cell.isUnderline())
|
|
14316
|
-
attributes |= TextAttributes.UNDERLINE;
|
|
14317
|
-
if (cell.isBlink())
|
|
14318
|
-
attributes |= TextAttributes.BLINK;
|
|
14319
|
-
if (cell.isInverse())
|
|
14320
|
-
attributes |= TextAttributes.INVERSE;
|
|
14321
|
-
if (cell.isInvisible())
|
|
14322
|
-
attributes |= TextAttributes.HIDDEN;
|
|
14323
|
-
if (cell.isStrikethrough())
|
|
14324
|
-
attributes |= TextAttributes.STRIKETHROUGH;
|
|
14325
|
-
return attributes;
|
|
14326
|
-
}
|
|
14327
|
-
function sameRgba(a, b) {
|
|
14328
|
-
if (!a && !b)
|
|
14329
|
-
return true;
|
|
14330
|
-
return Boolean(a && b && a.equals(b));
|
|
14331
|
-
}
|
|
14332
|
-
function sameStyle(a, b) {
|
|
14333
|
-
return sameRgba(a.fg, b.fg) && sameRgba(a.bg, b.bg) && (a.attributes ?? 0) === (b.attributes ?? 0);
|
|
14334
|
-
}
|
|
14335
|
-
function styleFromCell(cell) {
|
|
14336
|
-
return {
|
|
14337
|
-
fg: rgbaFromXtermColor(cell.getFgColorMode(), cell.getFgColor()),
|
|
14338
|
-
bg: rgbaFromXtermColor(cell.getBgColorMode(), cell.getBgColor()),
|
|
14339
|
-
attributes: textAttributesFromCell(cell)
|
|
14340
|
-
};
|
|
14341
|
-
}
|
|
14342
|
-
function lineToStyledText(line, cols) {
|
|
14343
|
-
if (!line)
|
|
14344
|
-
return new StyledText([{ __isChunk: true, text: "" }]);
|
|
14345
|
-
const chunks = [];
|
|
14346
|
-
let run = "";
|
|
14347
|
-
let runStyle = null;
|
|
14348
|
-
const flush = () => {
|
|
14349
|
-
if (!run)
|
|
14350
|
-
return;
|
|
14351
|
-
chunks.push({
|
|
14352
|
-
__isChunk: true,
|
|
14353
|
-
text: run,
|
|
14354
|
-
...runStyle?.fg ? { fg: runStyle.fg } : {},
|
|
14355
|
-
...runStyle?.bg ? { bg: runStyle.bg } : {},
|
|
14356
|
-
...(runStyle?.attributes ?? 0) !== 0 ? { attributes: runStyle.attributes } : {}
|
|
14357
|
-
});
|
|
14358
|
-
run = "";
|
|
14359
|
-
};
|
|
14360
|
-
for (let index = 0;index < cols; index += 1) {
|
|
14361
|
-
const cell = line.getCell(index);
|
|
14362
|
-
if (!cell) {
|
|
14363
|
-
if (runStyle !== null)
|
|
14364
|
-
flush();
|
|
14365
|
-
runStyle = null;
|
|
14366
|
-
run += " ";
|
|
14367
|
-
continue;
|
|
14368
|
-
}
|
|
14369
|
-
if (cell.getWidth() === 0)
|
|
14370
|
-
continue;
|
|
14371
|
-
const style = styleFromCell(cell);
|
|
14372
|
-
if (!runStyle || !sameStyle(runStyle, style)) {
|
|
14373
|
-
flush();
|
|
14374
|
-
runStyle = style;
|
|
14375
|
-
}
|
|
14376
|
-
run += cell.getChars() || " ";
|
|
14377
|
-
}
|
|
14378
|
-
flush();
|
|
14379
|
-
return new StyledText(chunks.length > 0 ? chunks : [{ __isChunk: true, text: "" }]);
|
|
14380
|
-
}
|
|
14381
|
-
function childCommandPrefix2() {
|
|
14382
|
-
const execName = basename4(process.execPath).toLowerCase();
|
|
14383
|
-
const currentEntry = process.argv[1];
|
|
14384
|
-
if (execName === "bun" || execName === "bun.exe") {
|
|
14385
|
-
return currentEntry ? [process.execPath, currentEntry, "__opentui-pi-host"] : [process.execPath, fallbackChildScriptPath];
|
|
14386
|
-
}
|
|
14387
|
-
return [process.execPath, "__opentui-pi-host"];
|
|
14388
|
-
}
|
|
14389
|
-
function withEnv2(base) {
|
|
14390
|
-
const env = {};
|
|
14391
|
-
for (const [key, value] of Object.entries(base ?? process.env)) {
|
|
14392
|
-
if (key === "RIG_PLAIN" || key === "RIG_CLI_PLAIN_HELP" || key === "NO_COLOR")
|
|
14393
|
-
continue;
|
|
14394
|
-
if (typeof value === "string")
|
|
14395
|
-
env[key] = value;
|
|
14396
|
-
}
|
|
14397
|
-
return {
|
|
14398
|
-
...env,
|
|
14399
|
-
TERM: "xterm-256color",
|
|
14400
|
-
COLORTERM: "truecolor",
|
|
14401
|
-
FORCE_COLOR: env.FORCE_COLOR ?? "1",
|
|
14402
|
-
RIG_OPENTUI_PI_HOST: "1"
|
|
14403
|
-
};
|
|
14404
|
-
}
|
|
14405
|
-
async function startPiPtyHost(options) {
|
|
14406
|
-
activeHost2?.dispose("replace");
|
|
14407
|
-
const host = new PiPtyHost(options);
|
|
14408
|
-
activeHost2 = host;
|
|
14409
|
-
await host.start();
|
|
14410
|
-
return host;
|
|
14411
|
-
}
|
|
14412
|
-
|
|
14413
|
-
class PiPtyHost {
|
|
14414
|
-
runId;
|
|
14415
|
-
projectRoot;
|
|
14416
|
-
onSnapshot;
|
|
14417
|
-
onExit;
|
|
14418
|
-
onError;
|
|
14419
|
-
terminal;
|
|
14420
|
-
disposables = [];
|
|
14421
|
-
decoder = new TextDecoder("utf-8");
|
|
14422
|
-
proc = null;
|
|
14423
|
-
pty = null;
|
|
14424
|
-
status = "starting";
|
|
14425
|
-
cols;
|
|
14426
|
-
rows;
|
|
14427
|
-
message = "starting bundled Pi";
|
|
14428
|
-
lastResizeError = null;
|
|
14429
|
-
exitCode;
|
|
14430
|
-
signal;
|
|
14431
|
-
notifyTimer = null;
|
|
14432
|
-
lastStreamKey = "";
|
|
14433
|
-
_disposed = false;
|
|
14434
|
-
constructor(options) {
|
|
14435
|
-
this.runId = options.runId;
|
|
14436
|
-
this.projectRoot = options.projectRoot;
|
|
14437
|
-
this.cols = clampCols2(options.cols);
|
|
14438
|
-
this.rows = clampRows2(options.rows);
|
|
14439
|
-
this.onSnapshot = options.onSnapshot;
|
|
14440
|
-
this.onExit = options.onExit;
|
|
14441
|
-
this.onError = options.onError;
|
|
14442
|
-
this.terminal = new XtermTerminal2({
|
|
14443
|
-
allowProposedApi: true,
|
|
14444
|
-
cols: this.cols,
|
|
14445
|
-
rows: this.rows,
|
|
14446
|
-
scrollback: 1000
|
|
14447
|
-
});
|
|
14448
|
-
this.registerTerminalResponders();
|
|
14449
|
-
this.disposables.push(this.terminal.onWriteParsed(() => {
|
|
14450
|
-
if (this._disposed)
|
|
14451
|
-
return;
|
|
14452
|
-
const snapshot = this.createSnapshot();
|
|
14453
|
-
const key = snapshot.lines.join(`
|
|
14454
|
-
`);
|
|
14455
|
-
if (key === this.lastStreamKey)
|
|
14456
|
-
return;
|
|
14457
|
-
this.lastStreamKey = key;
|
|
14458
|
-
this.onSnapshot?.(snapshot);
|
|
14459
|
-
}));
|
|
14460
|
-
}
|
|
14461
|
-
get disposed() {
|
|
14462
|
-
return this._disposed;
|
|
14463
|
-
}
|
|
14464
|
-
get snapshot() {
|
|
14465
|
-
return this.createSnapshot();
|
|
14466
|
-
}
|
|
14467
|
-
async start() {
|
|
14468
|
-
if (this._disposed)
|
|
14469
|
-
throw new Error("Pi PTY host is disposed.");
|
|
14470
|
-
if (typeof Bun.Terminal !== "function") {
|
|
14471
|
-
throw new Error("Bun native PTY is unavailable in this runtime. Pi host requires Bun.Terminal.");
|
|
14472
|
-
}
|
|
14473
|
-
const spawnOptions = {
|
|
14474
|
-
cwd: this.projectRoot,
|
|
14475
|
-
env: withEnv2(process.env),
|
|
14476
|
-
terminal: {
|
|
14477
|
-
cols: this.cols,
|
|
14478
|
-
rows: this.rows,
|
|
14479
|
-
name: "xterm-256color",
|
|
14480
|
-
data: (_terminal, data) => this.handlePtyData(data)
|
|
14481
|
-
}
|
|
14482
|
-
};
|
|
14483
|
-
const proc = Bun.spawn([
|
|
14484
|
-
...childCommandPrefix2(),
|
|
14485
|
-
"--run-id",
|
|
14486
|
-
this.runId,
|
|
14487
|
-
"--project-root",
|
|
14488
|
-
this.projectRoot
|
|
14489
|
-
], spawnOptions);
|
|
14490
|
-
if (!proc.terminal)
|
|
14491
|
-
throw new Error("Bun did not attach a terminal to the bundled Pi child process.");
|
|
14492
|
-
this.proc = proc;
|
|
14493
|
-
this.pty = proc.terminal;
|
|
14494
|
-
this.status = "running";
|
|
14495
|
-
this.message = "bundled Pi running inside this app";
|
|
14496
|
-
this.emitSnapshotSoon(0);
|
|
14497
|
-
proc.exited.then((exitCode) => {
|
|
14498
|
-
if (this._disposed)
|
|
14499
|
-
return;
|
|
14500
|
-
this.status = exitCode === 0 ? "exited" : "failed";
|
|
14501
|
-
this.exitCode = exitCode;
|
|
14502
|
-
this.signal = null;
|
|
14503
|
-
this.message = exitCode === 0 ? "bundled Pi exited" : `bundled Pi exited with code ${exitCode}`;
|
|
14504
|
-
const snapshot = this.createSnapshot();
|
|
14505
|
-
this.onSnapshot?.(snapshot);
|
|
14506
|
-
this.onExit?.(snapshot);
|
|
14507
|
-
if (activeHost2 === this)
|
|
14508
|
-
activeHost2 = null;
|
|
14509
|
-
this.dispose("exit", { kill: false, notify: false });
|
|
14510
|
-
}).catch((error) => {
|
|
14511
|
-
if (this._disposed)
|
|
14512
|
-
return;
|
|
14513
|
-
this.status = "failed";
|
|
14514
|
-
this.message = error instanceof Error ? error.message : String(error);
|
|
14515
|
-
const snapshot = this.createSnapshot();
|
|
14516
|
-
this.onSnapshot?.(snapshot);
|
|
14517
|
-
this.onError?.(error, snapshot);
|
|
14518
|
-
if (activeHost2 === this)
|
|
14519
|
-
activeHost2 = null;
|
|
14520
|
-
this.dispose("error", { kill: false, notify: false });
|
|
14521
|
-
});
|
|
14522
|
-
}
|
|
14523
|
-
write(data) {
|
|
14524
|
-
if (this._disposed || !this.pty)
|
|
14525
|
-
return;
|
|
14526
|
-
try {
|
|
14527
|
-
this.pty.write(data);
|
|
14528
|
-
} catch (error) {
|
|
14529
|
-
this.status = "failed";
|
|
14530
|
-
this.message = error instanceof Error ? error.message : String(error);
|
|
14531
|
-
const snapshot = this.createSnapshot();
|
|
14532
|
-
this.onSnapshot?.(snapshot);
|
|
14533
|
-
this.onError?.(error, snapshot);
|
|
14534
|
-
}
|
|
14535
|
-
}
|
|
14536
|
-
resize(cols, rows) {
|
|
14537
|
-
const nextCols = clampCols2(cols);
|
|
14538
|
-
const nextRows = clampRows2(rows);
|
|
14539
|
-
if (nextCols === this.cols && nextRows === this.rows)
|
|
14540
|
-
return;
|
|
14541
|
-
this.cols = nextCols;
|
|
14542
|
-
this.rows = nextRows;
|
|
14543
|
-
this.terminal.resize(nextCols, nextRows);
|
|
14544
|
-
try {
|
|
14545
|
-
this.pty?.resize(nextCols, nextRows);
|
|
14546
|
-
this.lastResizeError = null;
|
|
14547
|
-
} catch (error) {
|
|
14548
|
-
this.lastResizeError = error instanceof Error ? error.message : String(error);
|
|
14549
|
-
}
|
|
14550
|
-
this.emitSnapshotSoon(0);
|
|
14551
|
-
}
|
|
14552
|
-
detach() {
|
|
14553
|
-
this.dispose("detach");
|
|
14554
|
-
return this.createSnapshot("detached from bundled Pi");
|
|
14555
|
-
}
|
|
14556
|
-
dispose(reason = "dispose", options = {}) {
|
|
14557
|
-
if (this._disposed)
|
|
14558
|
-
return;
|
|
14559
|
-
this._disposed = true;
|
|
14560
|
-
if (this.notifyTimer)
|
|
14561
|
-
clearTimeout(this.notifyTimer);
|
|
14562
|
-
this.notifyTimer = null;
|
|
14563
|
-
for (const disposable of this.disposables.splice(0)) {
|
|
14564
|
-
try {
|
|
14565
|
-
disposable.dispose();
|
|
14566
|
-
} catch {}
|
|
14567
|
-
}
|
|
14568
|
-
if (options.kill !== false) {
|
|
14569
|
-
try {
|
|
14570
|
-
this.proc?.kill("SIGTERM");
|
|
14571
|
-
} catch {}
|
|
14572
|
-
}
|
|
14573
|
-
try {
|
|
14574
|
-
this.pty?.close();
|
|
14575
|
-
} catch {}
|
|
14576
|
-
try {
|
|
14577
|
-
this.terminal.dispose();
|
|
14578
|
-
} catch {}
|
|
14579
|
-
if (activeHost2 === this)
|
|
14580
|
-
activeHost2 = null;
|
|
14581
|
-
if (options.notify) {
|
|
14582
|
-
this.message = reason;
|
|
14583
|
-
this.onSnapshot?.(this.createSnapshot(reason));
|
|
14584
|
-
}
|
|
14585
|
-
}
|
|
14586
|
-
handlePtyData(data) {
|
|
14587
|
-
if (this._disposed)
|
|
14588
|
-
return;
|
|
14589
|
-
const text2 = this.decoder.decode(data, { stream: true });
|
|
14590
|
-
this.respondToRawTerminalQueries(text2);
|
|
14591
|
-
this.terminal.write(data);
|
|
14592
|
-
}
|
|
14593
|
-
emitSnapshotSoon(delayMs = SNAPSHOT_DELAY_MS2) {
|
|
14594
|
-
if (this._disposed || this.notifyTimer)
|
|
14595
|
-
return;
|
|
14596
|
-
this.notifyTimer = setTimeout(() => {
|
|
14597
|
-
this.notifyTimer = null;
|
|
14598
|
-
if (this._disposed)
|
|
14599
|
-
return;
|
|
14600
|
-
this.onSnapshot?.(this.createSnapshot());
|
|
14601
|
-
}, delayMs);
|
|
14602
|
-
}
|
|
14603
|
-
createSnapshot(message2 = this.message) {
|
|
14604
|
-
const buffer = this.terminal.buffer.active;
|
|
14605
|
-
const end = buffer.length;
|
|
14606
|
-
const start = Math.max(0, end - MAX_SNAPSHOT_LINES2);
|
|
14607
|
-
const styledStart = Math.max(start, end - this.rows - STYLED_SNAPSHOT_MARGIN);
|
|
14608
|
-
const lines = [];
|
|
14609
|
-
const styledLines = [];
|
|
14610
|
-
for (let row = start;row < end; row += 1) {
|
|
14611
|
-
const line = buffer.getLine(row);
|
|
14612
|
-
lines.push((line?.translateToString(false) ?? "").slice(0, this.cols));
|
|
14613
|
-
if (row >= styledStart)
|
|
14614
|
-
styledLines[lines.length - 1] = lineToStyledText(line, this.cols);
|
|
14615
|
-
}
|
|
14616
|
-
while (lines.length < this.rows) {
|
|
14617
|
-
lines.push("");
|
|
14618
|
-
styledLines[lines.length - 1] = new StyledText([{ __isChunk: true, text: "" }]);
|
|
14619
|
-
}
|
|
14620
|
-
const resolvedMessage = this.lastResizeError ? `resize degraded: ${this.lastResizeError}` : message2;
|
|
14621
|
-
return {
|
|
14622
|
-
runId: this.runId,
|
|
14623
|
-
status: this.status,
|
|
14624
|
-
cols: this.cols,
|
|
14625
|
-
rows: this.rows,
|
|
14626
|
-
lines,
|
|
14627
|
-
styledLines,
|
|
14628
|
-
message: resolvedMessage,
|
|
14629
|
-
...this.lastResizeError ? { resizeError: this.lastResizeError } : {},
|
|
14630
|
-
...this.exitCode !== undefined ? { exitCode: this.exitCode } : {},
|
|
14631
|
-
...this.signal !== undefined ? { signal: this.signal } : {}
|
|
14632
|
-
};
|
|
14633
|
-
}
|
|
14634
|
-
registerTerminalResponders() {
|
|
14635
|
-
this.disposables.push(this.terminal.parser.registerCsiHandler({ final: "c" }, (params) => {
|
|
14636
|
-
if (params.length === 0 || params[0] === 0)
|
|
14637
|
-
this.write("\x1B[?62;22c");
|
|
14638
|
-
return false;
|
|
14639
|
-
}));
|
|
14640
|
-
this.disposables.push(this.terminal.parser.registerCsiHandler({ prefix: ">", final: "c" }, (params) => {
|
|
14641
|
-
if (params.length === 0 || params[0] === 0)
|
|
14642
|
-
this.write("\x1B[>0;0;0c");
|
|
14643
|
-
return false;
|
|
14644
|
-
}));
|
|
14645
|
-
this.disposables.push(this.terminal.parser.registerCsiHandler({ final: "n" }, (params) => {
|
|
14646
|
-
if (params[0] === 5) {
|
|
14647
|
-
this.write("\x1B[0n");
|
|
14648
|
-
} else if (params[0] === 6) {
|
|
14649
|
-
const row = this.terminal.buffer.active.cursorY + 1;
|
|
14650
|
-
const col = this.terminal.buffer.active.cursorX + 1;
|
|
14651
|
-
this.write(`\x1B[${row};${col}R`);
|
|
14652
|
-
}
|
|
14653
|
-
return false;
|
|
14654
|
-
}));
|
|
14655
|
-
}
|
|
14656
|
-
respondToRawTerminalQueries(text2) {
|
|
14657
|
-
if (!text2)
|
|
14658
|
-
return;
|
|
14659
|
-
const decrqm = /\x1b\[\?(\d+)\$p/g;
|
|
14660
|
-
let match;
|
|
14661
|
-
while ((match = decrqm.exec(text2)) !== null) {
|
|
14662
|
-
this.write(`\x1B[?${match[1]};2$y`);
|
|
14663
|
-
}
|
|
14664
|
-
}
|
|
14665
|
-
}
|
|
14666
|
-
var MIN_COLS2 = 40, MIN_ROWS2 = 12, MAX_ROWS2 = 300, MAX_SNAPSHOT_LINES2 = 360, STYLED_SNAPSHOT_MARGIN = 6, SNAPSHOT_DELAY_MS2 = 120, fallbackChildScriptPath, activeHost2 = null, XTERM_COLOR_MODE_INDEXED_16 = 16777216, XTERM_COLOR_MODE_INDEXED_256 = 33554432, XTERM_COLOR_MODE_RGB = 50331648;
|
|
14667
|
-
var init_pi_pty_host = __esm(() => {
|
|
14668
|
-
fallbackChildScriptPath = fileURLToPath2(new URL("./pi-host-child.ts", import.meta.url));
|
|
14669
|
-
});
|
|
14670
|
-
|
|
14671
14337
|
// packages/cli/src/app-opentui/adapters/inspect.ts
|
|
14672
14338
|
var exports_inspect = {};
|
|
14673
14339
|
__export(exports_inspect, {
|
|
@@ -14890,14 +14556,6 @@ function recordStep(ctx, runId, label, emitLabel) {
|
|
|
14890
14556
|
});
|
|
14891
14557
|
emitProgress(ctx, emitLabel, label);
|
|
14892
14558
|
}
|
|
14893
|
-
function settleSteps(ctx, runId) {
|
|
14894
|
-
const now = Date.now();
|
|
14895
|
-
const previous = currentAttachState(ctx, runId);
|
|
14896
|
-
if (!previous?.steps)
|
|
14897
|
-
return;
|
|
14898
|
-
const steps = previous.steps.map((step) => step.status === "running" ? { ...step, status: "done", endedAtMs: step.endedAtMs ?? now } : step);
|
|
14899
|
-
patchData(ctx, { piAttach: { ...previous, steps } });
|
|
14900
|
-
}
|
|
14901
14559
|
async function preparePiAttachHandoff(ctx, runId) {
|
|
14902
14560
|
const cleanRunId = runId.trim();
|
|
14903
14561
|
const label = `Preparing Pi ${cleanRunId.slice(0, 8)}`;
|
|
@@ -14945,85 +14603,41 @@ async function attachRunWithBundledPi(ctx, runId) {
|
|
|
14945
14603
|
throw error;
|
|
14946
14604
|
}
|
|
14947
14605
|
emitStarted(ctx, label, { piAttach: { runId: cleanRunId, status: "entering-pi" } });
|
|
14948
|
-
patchData(ctx, { piAttach: { runId: cleanRunId, status: "entering-pi", message: "
|
|
14606
|
+
patchData(ctx, { piAttach: { runId: cleanRunId, status: "entering-pi", message: "handing the terminal to worker Pi\u2026" } });
|
|
14607
|
+
const projectRoot = projectRootOf(ctx);
|
|
14608
|
+
const outputMode = ctx.rig?.outputMode ?? "text";
|
|
14609
|
+
await releaseRendererForExternalTui(ctx);
|
|
14610
|
+
let outcome = null;
|
|
14611
|
+
let attachError = null;
|
|
14949
14612
|
try {
|
|
14950
|
-
|
|
14951
|
-
await
|
|
14952
|
-
patchData(ctx, { lastRefreshError: normalizeAppError(error).message });
|
|
14953
|
-
return null;
|
|
14954
|
-
});
|
|
14955
|
-
recordStep(ctx, cleanRunId, "spawning Bun PTY host for bundled Pi", label);
|
|
14956
|
-
const projectRoot = projectRootOf(ctx);
|
|
14957
|
-
const cols = typeof process.stdout.columns === "number" ? process.stdout.columns : 100;
|
|
14958
|
-
const rows = Math.max(1, (typeof process.stdout.rows === "number" ? process.stdout.rows : 35) - 1);
|
|
14959
|
-
const patchTerminal = (snapshot) => {
|
|
14960
|
-
const previousSteps = currentAttachState(ctx, cleanRunId)?.steps;
|
|
14961
|
-
const failed = snapshot.status === "failed";
|
|
14962
|
-
const reason = failed ? snapshot.message ?? `bundled Pi exited with code ${snapshot.exitCode ?? "unknown"}` : undefined;
|
|
14963
|
-
patchData(ctx, {
|
|
14964
|
-
piTerminal: snapshot,
|
|
14965
|
-
piAttach: {
|
|
14966
|
-
runId: cleanRunId,
|
|
14967
|
-
status: failed ? "failed" : snapshot.status === "exited" ? "returned" : "entering-pi",
|
|
14968
|
-
message: snapshot.message ?? "bundled Pi running",
|
|
14969
|
-
result: { runId: cleanRunId, status: snapshot.status, exitCode: snapshot.exitCode },
|
|
14970
|
-
...previousSteps ? { steps: previousSteps } : {},
|
|
14971
|
-
...reason ? { failureReason: reason } : {}
|
|
14972
|
-
}
|
|
14973
|
-
});
|
|
14974
|
-
};
|
|
14975
|
-
recordStep(ctx, cleanRunId, "starting bundled Pi", label);
|
|
14976
|
-
await startPiPtyHost({
|
|
14977
|
-
runId: cleanRunId,
|
|
14978
|
-
projectRoot,
|
|
14979
|
-
cols,
|
|
14980
|
-
rows,
|
|
14981
|
-
onSnapshot: (snapshot) => {
|
|
14982
|
-
if (snapshot.status === "running" && snapshot.lines.some((entry) => entry.trim().length > 0)) {
|
|
14983
|
-
settleSteps(ctx, cleanRunId);
|
|
14984
|
-
}
|
|
14985
|
-
patchTerminal(snapshot);
|
|
14986
|
-
},
|
|
14987
|
-
onExit: (snapshot) => {
|
|
14988
|
-
patchTerminal(snapshot);
|
|
14989
|
-
if (snapshot.status === "failed") {
|
|
14990
|
-
Promise.resolve().then(() => (init_inspect2(), exports_inspect)).then(({ loadInspect: loadInspect2 }) => loadInspect2(ctx, cleanRunId)).catch(() => null);
|
|
14991
|
-
emitFailed(ctx, label, new Error(snapshot.message ?? `bundled Pi exited with code ${snapshot.exitCode ?? "unknown"}`), { runId: cleanRunId, result: { status: snapshot.status, exitCode: snapshot.exitCode } });
|
|
14992
|
-
return;
|
|
14993
|
-
}
|
|
14994
|
-
emitCompleted(ctx, label, { runId: cleanRunId, result: { status: snapshot.status, exitCode: snapshot.exitCode } });
|
|
14995
|
-
ctx.emit({ type: "scene.change", scene: "fleet", intent: { scene: "fleet", argv: ["runs"], action: { kind: "refresh", label: "Opening runs" } } });
|
|
14996
|
-
refreshFleet(ctx).catch((error) => emitFailed(ctx, "Refresh runs", error));
|
|
14997
|
-
},
|
|
14998
|
-
onError: (error, snapshot) => {
|
|
14999
|
-
patchTerminal(snapshot);
|
|
15000
|
-
emitFailed(ctx, label, error, { runId: cleanRunId });
|
|
15001
|
-
}
|
|
15002
|
-
});
|
|
15003
|
-
const record = {
|
|
15004
|
-
runId: cleanRunId,
|
|
15005
|
-
status: "running",
|
|
15006
|
-
rendered: "bundled Pi embedded via Bun.Terminal + @xterm/headless"
|
|
15007
|
-
};
|
|
15008
|
-
emitProgress(ctx, label, "bundled Pi is running", { piAttach: { runId: cleanRunId, status: "entering-pi", message: "bundled Pi running", result: record } });
|
|
15009
|
-
return record;
|
|
14613
|
+
const { attachRunBundledPiFrontend: attachRunBundledPiFrontend2 } = await Promise.resolve().then(() => (init__pi_frontend(), exports__pi_frontend));
|
|
14614
|
+
outcome = await attachRunBundledPiFrontend2({ projectRoot, outputMode }, { runId: cleanRunId, returnOnQuit: true });
|
|
15010
14615
|
} catch (error) {
|
|
15011
|
-
|
|
14616
|
+
attachError = error;
|
|
14617
|
+
} finally {
|
|
14618
|
+
await resumeRendererAfterExternalTui(ctx);
|
|
14619
|
+
}
|
|
14620
|
+
if (attachError) {
|
|
14621
|
+
const reason = normalizeAppError(attachError).message;
|
|
15012
14622
|
patchData(ctx, {
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
status: "failed",
|
|
15016
|
-
message: reason,
|
|
15017
|
-
failureReason: reason,
|
|
15018
|
-
...currentAttachState(ctx, cleanRunId)?.steps ? { steps: currentAttachState(ctx, cleanRunId).steps } : {}
|
|
15019
|
-
}
|
|
14623
|
+
piTerminal: undefined,
|
|
14624
|
+
piAttach: { runId: cleanRunId, status: "failed", message: reason, failureReason: reason }
|
|
15020
14625
|
});
|
|
15021
|
-
|
|
15022
|
-
|
|
14626
|
+
Promise.resolve().then(() => (init_inspect2(), exports_inspect)).then(({ loadInspect: loadInspect2 }) => loadInspect2(ctx, cleanRunId)).catch(() => null);
|
|
14627
|
+
emitFailed(ctx, label, attachError, { runId: cleanRunId });
|
|
14628
|
+
throw attachError;
|
|
15023
14629
|
}
|
|
14630
|
+
const detached = outcome?.detached === true;
|
|
14631
|
+
patchData(ctx, {
|
|
14632
|
+
piTerminal: undefined,
|
|
14633
|
+
piAttach: { runId: cleanRunId, status: "returned", message: detached ? "detached from worker Pi" : "returned from worker Pi" }
|
|
14634
|
+
});
|
|
14635
|
+
emitCompleted(ctx, label, { runId: cleanRunId, result: { runId: cleanRunId, detached } });
|
|
14636
|
+
ctx.emit({ type: "scene.change", scene: "fleet", intent: { scene: "fleet", argv: ["runs"], action: { kind: "refresh", label: "Opening runs" } } });
|
|
14637
|
+
refreshFleet(ctx).catch((error) => emitFailed(ctx, "Refresh runs", error));
|
|
14638
|
+
return { runId: cleanRunId, status: "returned", detached };
|
|
15024
14639
|
}
|
|
15025
14640
|
var init_pi_attach = __esm(() => {
|
|
15026
|
-
init_pi_pty_host();
|
|
15027
14641
|
init_fleet();
|
|
15028
14642
|
});
|
|
15029
14643
|
// packages/cli/src/app-opentui/command-pty-host.ts
|
|
@@ -17038,13 +16652,14 @@ import {
|
|
|
17038
16652
|
dim as otuiDim,
|
|
17039
16653
|
fg as otuiFg,
|
|
17040
16654
|
t,
|
|
17041
|
-
TextAttributes
|
|
16655
|
+
TextAttributes
|
|
17042
16656
|
} from "@opentui/core";
|
|
17043
16657
|
var RIG_UI = {
|
|
17044
16658
|
bg: "#070809",
|
|
17045
16659
|
bg2: "#0b0c0e",
|
|
17046
16660
|
panel: "#101115",
|
|
17047
16661
|
panel2: "#14161b",
|
|
16662
|
+
hover: "#181b24",
|
|
17048
16663
|
glass: "#1e2230",
|
|
17049
16664
|
border: "#2a2e3a",
|
|
17050
16665
|
ink: "#f4f5f8",
|
|
@@ -17139,7 +16754,7 @@ function statusLabel(status) {
|
|
|
17139
16754
|
}
|
|
17140
16755
|
|
|
17141
16756
|
// packages/cli/src/app-opentui/drone.ts
|
|
17142
|
-
import { RGBA
|
|
16757
|
+
import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
|
|
17143
16758
|
var MINI_DRONE = [
|
|
17144
16759
|
"(!!!) (!!!)",
|
|
17145
16760
|
" \\%==%/ ",
|
|
@@ -17155,13 +16770,13 @@ var LEAD_MARK = [
|
|
|
17155
16770
|
var BLADE_FRAMES2 = ["---", "\\\\\\", "|||", "///"];
|
|
17156
16771
|
var EYE_FRAMES2 = ["o", "@", "\u2022", "."];
|
|
17157
16772
|
var COLOR = {
|
|
17158
|
-
body:
|
|
17159
|
-
mini:
|
|
17160
|
-
rotor:
|
|
17161
|
-
path:
|
|
17162
|
-
eye:
|
|
17163
|
-
dim:
|
|
17164
|
-
ink:
|
|
16773
|
+
body: RGBA.fromHex(RIG_UI.lime),
|
|
16774
|
+
mini: RGBA.fromHex(RIG_UI.limeDim),
|
|
16775
|
+
rotor: RGBA.fromHex(RIG_UI.cyan),
|
|
16776
|
+
path: RGBA.fromHex(RIG_UI.cyan),
|
|
16777
|
+
eye: RGBA.fromHex(RIG_UI.ink),
|
|
16778
|
+
dim: RGBA.fromHex(RIG_UI.ink4),
|
|
16779
|
+
ink: RGBA.fromHex(RIG_UI.ink2)
|
|
17165
16780
|
};
|
|
17166
16781
|
function bladeForTick(tick, phase = 0) {
|
|
17167
16782
|
return BLADE_FRAMES2[(Math.floor(tick / 3) + phase) % BLADE_FRAMES2.length];
|
|
@@ -17171,12 +16786,12 @@ function eyeForTick(tick, phase = 0) {
|
|
|
17171
16786
|
return pulse > 0.55 ? EYE_FRAMES2[1] : pulse > 0.1 ? EYE_FRAMES2[0] : pulse > -0.45 ? EYE_FRAMES2[2] : EYE_FRAMES2[3];
|
|
17172
16787
|
}
|
|
17173
16788
|
function chunk(text2, fg2, bold2 = false, dim = false) {
|
|
17174
|
-
let attributes =
|
|
16789
|
+
let attributes = TextAttributes2.NONE;
|
|
17175
16790
|
if (bold2)
|
|
17176
|
-
attributes |=
|
|
16791
|
+
attributes |= TextAttributes2.BOLD;
|
|
17177
16792
|
if (dim)
|
|
17178
|
-
attributes |=
|
|
17179
|
-
return { __isChunk: true, text: text2, fg: fg2, ...attributes !==
|
|
16793
|
+
attributes |= TextAttributes2.DIM;
|
|
16794
|
+
return { __isChunk: true, text: text2, fg: fg2, ...attributes !== TextAttributes2.NONE ? { attributes } : {} };
|
|
17180
16795
|
}
|
|
17181
16796
|
function styledLine(text2, colorFor) {
|
|
17182
16797
|
const chunks = [];
|
|
@@ -17197,7 +16812,7 @@ function styledLine(text2, colorFor) {
|
|
|
17197
16812
|
run += char;
|
|
17198
16813
|
}
|
|
17199
16814
|
flush();
|
|
17200
|
-
return new
|
|
16815
|
+
return new StyledText(chunks.length > 0 ? chunks : [chunk("", COLOR.ink)]);
|
|
17201
16816
|
}
|
|
17202
16817
|
function droneColor(char) {
|
|
17203
16818
|
if (char === "?" || char === "o" || char === "@" || char === "\u2022")
|
|
@@ -19347,11 +18962,8 @@ function renderFamilyScene(state, layout) {
|
|
|
19347
18962
|
}
|
|
19348
18963
|
|
|
19349
18964
|
// packages/cli/src/app-opentui/list-search.ts
|
|
19350
|
-
function
|
|
19351
|
-
return
|
|
19352
|
-
}
|
|
19353
|
-
function listSearchQuery(state) {
|
|
19354
|
-
return isListSearchScene(state.scene) ? state.typeBar.value.trim() : "";
|
|
18965
|
+
function listSearchQuery(_state) {
|
|
18966
|
+
return "";
|
|
19355
18967
|
}
|
|
19356
18968
|
function valueText(value) {
|
|
19357
18969
|
if (value === undefined || value === null)
|