@h-rig/cli 0.0.6-alpha.87 → 0.0.6-alpha.89

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.
Files changed (78) hide show
  1. package/dist/bin/rig.js +1380 -865
  2. package/dist/src/app/board.js +462 -48
  3. package/dist/src/app-opentui/adapters/common.d.ts +3 -0
  4. package/dist/src/app-opentui/adapters/common.js +4 -0
  5. package/dist/src/app-opentui/adapters/doctor.js +458 -46
  6. package/dist/src/app-opentui/adapters/family.js +701 -151
  7. package/dist/src/app-opentui/adapters/fleet.js +477 -46
  8. package/dist/src/app-opentui/adapters/inbox.js +477 -46
  9. package/dist/src/app-opentui/adapters/init.js +497 -74
  10. package/dist/src/app-opentui/adapters/inspect.js +477 -46
  11. package/dist/src/app-opentui/adapters/pi-attach.d.ts +7 -0
  12. package/dist/src/app-opentui/adapters/pi-attach.js +1004 -519
  13. package/dist/src/app-opentui/adapters/run-detail.js +477 -46
  14. package/dist/src/app-opentui/adapters/server.d.ts +26 -0
  15. package/dist/src/app-opentui/adapters/server.js +676 -59
  16. package/dist/src/app-opentui/adapters/tasks.js +621 -549
  17. package/dist/src/app-opentui/autocomplete.js +4 -2
  18. package/dist/src/app-opentui/bootstrap.js +1376 -861
  19. package/dist/src/app-opentui/command-palette.js +37 -10
  20. package/dist/src/app-opentui/index.js +632 -528
  21. package/dist/src/app-opentui/intent.js +33 -8
  22. package/dist/src/app-opentui/keymap.js +43 -414
  23. package/dist/src/app-opentui/pi-host-child.js +496 -57
  24. package/dist/src/app-opentui/pi-pty-host.d.ts +14 -64
  25. package/dist/src/app-opentui/pi-pty-host.js +3 -397
  26. package/dist/src/app-opentui/react/App.js +144 -469
  27. package/dist/src/app-opentui/react/ChromeHost.js +44 -415
  28. package/dist/src/app-opentui/react/launch.js +659 -552
  29. package/dist/src/app-opentui/react/nav.js +1 -1
  30. package/dist/src/app-opentui/registry.js +1181 -742
  31. package/dist/src/app-opentui/remote-link.d.ts +10 -0
  32. package/dist/src/app-opentui/remote-link.js +47 -0
  33. package/dist/src/app-opentui/render/terminal-handoff.d.ts +16 -0
  34. package/dist/src/app-opentui/render/terminal-handoff.js +14 -0
  35. package/dist/src/app-opentui/runtime.js +632 -528
  36. package/dist/src/app-opentui/scenes/doctor.js +1 -1
  37. package/dist/src/app-opentui/scenes/error.js +50 -4
  38. package/dist/src/app-opentui/scenes/family.js +60 -6
  39. package/dist/src/app-opentui/scenes/fleet.js +65 -13
  40. package/dist/src/app-opentui/scenes/help.js +4 -2
  41. package/dist/src/app-opentui/scenes/init.js +12 -12
  42. package/dist/src/app-opentui/scenes/main.js +7 -7
  43. package/dist/src/app-opentui/scenes/server.js +83 -11
  44. package/dist/src/app-opentui/scenes/tasks.js +79 -16
  45. package/dist/src/app-opentui/state.js +25 -5
  46. package/dist/src/app-opentui/surface-catalog.js +4 -2
  47. package/dist/src/app-opentui/types.d.ts +1 -1
  48. package/dist/src/commands/_cli-format.d.ts +10 -1
  49. package/dist/src/commands/_cli-format.js +5 -2
  50. package/dist/src/commands/_connection-state.d.ts +11 -1
  51. package/dist/src/commands/_connection-state.js +50 -5
  52. package/dist/src/commands/_doctor-checks.js +458 -46
  53. package/dist/src/commands/_help-catalog.js +4 -2
  54. package/dist/src/commands/_json-output.js +4 -0
  55. package/dist/src/commands/_operator-view.js +496 -57
  56. package/dist/src/commands/_pi-frontend.d.ts +25 -0
  57. package/dist/src/commands/_pi-frontend.js +497 -57
  58. package/dist/src/commands/_preflight.js +509 -72
  59. package/dist/src/commands/_server-client.d.ts +33 -0
  60. package/dist/src/commands/_server-client.js +477 -46
  61. package/dist/src/commands/_server-events.js +446 -41
  62. package/dist/src/commands/_snapshot-upload.js +460 -48
  63. package/dist/src/commands/connect.js +620 -15
  64. package/dist/src/commands/doctor.js +458 -46
  65. package/dist/src/commands/github.js +462 -50
  66. package/dist/src/commands/inbox.js +458 -46
  67. package/dist/src/commands/init.js +497 -74
  68. package/dist/src/commands/inspect.js +458 -46
  69. package/dist/src/commands/run.js +496 -57
  70. package/dist/src/commands/server.js +647 -163
  71. package/dist/src/commands/setup.js +463 -51
  72. package/dist/src/commands/stats.js +462 -48
  73. package/dist/src/commands/task-run-driver.js +464 -52
  74. package/dist/src/commands/task.js +551 -85
  75. package/dist/src/commands.js +701 -151
  76. package/dist/src/index.js +705 -151
  77. package/dist/src/launcher.js +4 -0
  78. package/package.json +8 -8
@@ -187,16 +187,31 @@ function taskViewIntent(argv, command = "", rest = [], raw) {
187
187
  const { payload, label } = taskViewPayload(command, rest);
188
188
  return intent("tasks", argv, "refresh", payload, label, raw);
189
189
  }
190
- function routeServer(argv, command, raw, checkingLabel) {
191
- if (!command || command === "status") {
190
+ function routeServer(argv, command, rest, raw, checkingLabel) {
191
+ if (!command || command === "status" || command === "list") {
192
192
  return intent("server", argv, "refresh", undefined, command ? checkingLabel : "Loading server", raw);
193
193
  }
194
+ if (command === "use") {
195
+ const alias = firstNonOption(rest);
196
+ if (alias === "local")
197
+ return intent("server", argv, "server-use-local", undefined, "Use local server", raw);
198
+ if (alias)
199
+ return intent("server", argv, "server-use-remote", { alias }, `Use ${alias}`, raw);
200
+ return intent("server", argv, "refresh", undefined, "Select a remote alias in Server", raw);
201
+ }
202
+ if (command === "add")
203
+ return intent("server", argv, "server-add-remote", { argv: [...argv] }, "Add remote server", raw);
204
+ if (command === "repair-link")
205
+ return intent("server", argv, "remote-link-repair", undefined, "Repair remote link", raw);
194
206
  return commandRunIntent(argv, raw);
195
207
  }
196
208
  function routeGithub(argv, command, rest, raw) {
197
209
  if (command === "auth" && (rest[0]?.toLowerCase() ?? "status") === "status" && rest.length <= 1) {
198
210
  return intent("server", argv, "refresh", undefined, "Checking GitHub auth", raw);
199
211
  }
212
+ if (command === "auth" && rest[0]?.toLowerCase() === "import-gh" && rest.length <= 1) {
213
+ return intent("server", argv, "github-auth-import", undefined, "Import GitHub auth", raw);
214
+ }
200
215
  return commandRunIntent(argv, raw);
201
216
  }
202
217
  function routeDoctor(argv, command, raw) {
@@ -245,11 +260,16 @@ function intentFromArgv(argv) {
245
260
  return commandRunIntent(argv);
246
261
  }
247
262
  if (normalizedGroup === "server")
248
- return routeServer(argv, normalizedCommand, undefined, "Checking server");
263
+ return routeServer(argv, normalizedCommand, rest, undefined, "Checking server");
249
264
  if (normalizedGroup === "github")
250
265
  return routeGithub(argv, normalizedCommand, rest);
251
- if (normalizedGroup === "init")
252
- return commandRunIntent(argv);
266
+ if (normalizedGroup === "init") {
267
+ if (!normalizedCommand)
268
+ return intent("init", argv, "refresh", undefined, "Open init");
269
+ if (rest.includes("--yes") || normalizedCommand === "--yes")
270
+ return intent("init", argv, "init-start", undefined, "Run init");
271
+ return intent("init", argv, "refresh", undefined, "Open init");
272
+ }
253
273
  if (normalizedGroup === "doctor")
254
274
  return routeDoctor(argv, normalizedCommand);
255
275
  if (normalizedGroup === "inbox")
@@ -312,12 +332,17 @@ function intentFromTypeBar(value) {
312
332
  return commandRunIntent(parts, value);
313
333
  return intent("tasks", parts, "refresh", undefined, "Select a task, then press Enter; or use run next", value);
314
334
  }
315
- if (first === "init")
316
- return commandRunIntent(parts, value);
335
+ if (first === "init") {
336
+ if (!second)
337
+ return intent("init", parts, "refresh", undefined, "Open init", value);
338
+ if (parts.includes("--yes"))
339
+ return intent("init", parts, "init-start", undefined, "Run init", value);
340
+ return intent("init", parts, "refresh", undefined, "Open init", value);
341
+ }
317
342
  if (first === "doctor")
318
343
  return routeDoctor(parts, second, value);
319
344
  if (first === "server")
320
- return routeServer(parts, second, value, "Loading server");
345
+ return routeServer(parts, second, rest, value, "Loading server");
321
346
  if (first === "github")
322
347
  return routeGithub(parts, second, rest, value);
323
348
  if (first === "inbox")
@@ -67,12 +67,13 @@ var PRIMARY_GROUPS = [
67
67
  {
68
68
  name: "server",
69
69
  summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
70
- usage: ["rig server <status|list|add|use|start> [options]"],
70
+ usage: ["rig server <status|list|add|use|repair-link|start> [options]"],
71
71
  commands: [
72
- { command: "status", description: "Show the selected server for this repo.", primary: true },
72
+ { command: "status", description: "Show the selected server and remote project-root link for this repo.", primary: true },
73
73
  { command: "use local", description: "Switch this repo to the local Rig server.", primary: true },
74
74
  { command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
75
75
  { command: "use <alias>", description: "Select a saved remote server alias.", primary: true },
76
+ { command: "repair-link [--prepare|--backfill-only] [--repo owner/repo]", description: "Backfill or prepare the selected remote's server-host checkout link.", primary: true },
76
77
  { command: "list", description: "List saved local/remote server aliases.", primary: true },
77
78
  { command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process." }
78
79
  ],
@@ -80,6 +81,7 @@ var PRIMARY_GROUPS = [
80
81
  "rig server status",
81
82
  "rig server add prod https://where.rig-does.work",
82
83
  "rig server use prod",
84
+ "rig server repair-link --repo owner/repo",
83
85
  "rig server use local",
84
86
  "rig server start --port 3773"
85
87
  ],
@@ -976,16 +978,31 @@ function taskViewIntent(argv, command = "", rest = [], raw) {
976
978
  const { payload, label } = taskViewPayload(command, rest);
977
979
  return intent("tasks", argv, "refresh", payload, label, raw);
978
980
  }
979
- function routeServer(argv, command, raw, checkingLabel) {
980
- if (!command || command === "status") {
981
+ function routeServer(argv, command, rest, raw, checkingLabel) {
982
+ if (!command || command === "status" || command === "list") {
981
983
  return intent("server", argv, "refresh", undefined, command ? checkingLabel : "Loading server", raw);
982
984
  }
985
+ if (command === "use") {
986
+ const alias = firstNonOption(rest);
987
+ if (alias === "local")
988
+ return intent("server", argv, "server-use-local", undefined, "Use local server", raw);
989
+ if (alias)
990
+ return intent("server", argv, "server-use-remote", { alias }, `Use ${alias}`, raw);
991
+ return intent("server", argv, "refresh", undefined, "Select a remote alias in Server", raw);
992
+ }
993
+ if (command === "add")
994
+ return intent("server", argv, "server-add-remote", { argv: [...argv] }, "Add remote server", raw);
995
+ if (command === "repair-link")
996
+ return intent("server", argv, "remote-link-repair", undefined, "Repair remote link", raw);
983
997
  return commandRunIntent(argv, raw);
984
998
  }
985
999
  function routeGithub(argv, command, rest, raw) {
986
1000
  if (command === "auth" && (rest[0]?.toLowerCase() ?? "status") === "status" && rest.length <= 1) {
987
1001
  return intent("server", argv, "refresh", undefined, "Checking GitHub auth", raw);
988
1002
  }
1003
+ if (command === "auth" && rest[0]?.toLowerCase() === "import-gh" && rest.length <= 1) {
1004
+ return intent("server", argv, "github-auth-import", undefined, "Import GitHub auth", raw);
1005
+ }
989
1006
  return commandRunIntent(argv, raw);
990
1007
  }
991
1008
  function routeDoctor(argv, command, raw) {
@@ -1034,11 +1051,16 @@ function intentFromArgv(argv) {
1034
1051
  return commandRunIntent(argv);
1035
1052
  }
1036
1053
  if (normalizedGroup === "server")
1037
- return routeServer(argv, normalizedCommand, undefined, "Checking server");
1054
+ return routeServer(argv, normalizedCommand, rest, undefined, "Checking server");
1038
1055
  if (normalizedGroup === "github")
1039
1056
  return routeGithub(argv, normalizedCommand, rest);
1040
- if (normalizedGroup === "init")
1041
- return commandRunIntent(argv);
1057
+ if (normalizedGroup === "init") {
1058
+ if (!normalizedCommand)
1059
+ return intent("init", argv, "refresh", undefined, "Open init");
1060
+ if (rest.includes("--yes") || normalizedCommand === "--yes")
1061
+ return intent("init", argv, "init-start", undefined, "Run init");
1062
+ return intent("init", argv, "refresh", undefined, "Open init");
1063
+ }
1042
1064
  if (normalizedGroup === "doctor")
1043
1065
  return routeDoctor(argv, normalizedCommand);
1044
1066
  if (normalizedGroup === "inbox")
@@ -1101,12 +1123,17 @@ function intentFromTypeBar(value) {
1101
1123
  return commandRunIntent(parts, value);
1102
1124
  return intent("tasks", parts, "refresh", undefined, "Select a task, then press Enter; or use run next", value);
1103
1125
  }
1104
- if (first === "init")
1105
- return commandRunIntent(parts, value);
1126
+ if (first === "init") {
1127
+ if (!second)
1128
+ return intent("init", parts, "refresh", undefined, "Open init", value);
1129
+ if (parts.includes("--yes"))
1130
+ return intent("init", parts, "init-start", undefined, "Run init", value);
1131
+ return intent("init", parts, "refresh", undefined, "Open init", value);
1132
+ }
1106
1133
  if (first === "doctor")
1107
1134
  return routeDoctor(parts, second, value);
1108
1135
  if (first === "server")
1109
- return routeServer(parts, second, value, "Loading server");
1136
+ return routeServer(parts, second, rest, value, "Loading server");
1110
1137
  if (first === "github")
1111
1138
  return routeGithub(parts, second, rest, value);
1112
1139
  if (first === "inbox")
@@ -1124,397 +1151,6 @@ function intentFromTypeBar(value) {
1124
1151
  return intentFromArgv(parts);
1125
1152
  }
1126
1153
 
1127
- // packages/cli/src/app-opentui/pi-pty-host.ts
1128
- import { fileURLToPath as fileURLToPath2 } from "url";
1129
- import { basename as basename2 } from "path";
1130
- import { RGBA, StyledText, TextAttributes } from "@opentui/core";
1131
- import { Terminal as XtermTerminal2 } from "@xterm/headless";
1132
- var MIN_COLS2 = 40;
1133
- var MIN_ROWS2 = 12;
1134
- var MAX_ROWS2 = 300;
1135
- var MAX_SNAPSHOT_LINES2 = 360;
1136
- var STYLED_SNAPSHOT_MARGIN = 6;
1137
- var SNAPSHOT_DELAY_MS2 = 120;
1138
- var fallbackChildScriptPath = fileURLToPath2(new URL("./pi-host-child.ts", import.meta.url));
1139
- var activeHost2 = null;
1140
- function clampCols2(cols) {
1141
- return Math.max(MIN_COLS2, Math.trunc(cols || 100));
1142
- }
1143
- function clampRows2(rows) {
1144
- return Math.max(MIN_ROWS2, Math.min(MAX_ROWS2, Math.trunc(rows || 35)));
1145
- }
1146
- var XTERM_COLOR_MODE_INDEXED_16 = 16777216;
1147
- var XTERM_COLOR_MODE_INDEXED_256 = 33554432;
1148
- var XTERM_COLOR_MODE_RGB = 50331648;
1149
- function rgbaFromXtermColor(mode, value) {
1150
- if (mode === 1 || mode === 2 || mode === XTERM_COLOR_MODE_INDEXED_16 || mode === XTERM_COLOR_MODE_INDEXED_256) {
1151
- return RGBA.fromIndex(value);
1152
- }
1153
- if (mode === 3 || mode === XTERM_COLOR_MODE_RGB) {
1154
- return RGBA.fromInts(value >> 16 & 255, value >> 8 & 255, value & 255);
1155
- }
1156
- return;
1157
- }
1158
- function textAttributesFromCell(cell) {
1159
- let attributes = TextAttributes.NONE;
1160
- if (cell.isBold())
1161
- attributes |= TextAttributes.BOLD;
1162
- if (cell.isDim())
1163
- attributes |= TextAttributes.DIM;
1164
- if (cell.isItalic())
1165
- attributes |= TextAttributes.ITALIC;
1166
- if (cell.isUnderline())
1167
- attributes |= TextAttributes.UNDERLINE;
1168
- if (cell.isBlink())
1169
- attributes |= TextAttributes.BLINK;
1170
- if (cell.isInverse())
1171
- attributes |= TextAttributes.INVERSE;
1172
- if (cell.isInvisible())
1173
- attributes |= TextAttributes.HIDDEN;
1174
- if (cell.isStrikethrough())
1175
- attributes |= TextAttributes.STRIKETHROUGH;
1176
- return attributes;
1177
- }
1178
- function sameRgba(a, b) {
1179
- if (!a && !b)
1180
- return true;
1181
- return Boolean(a && b && a.equals(b));
1182
- }
1183
- function sameStyle(a, b) {
1184
- return sameRgba(a.fg, b.fg) && sameRgba(a.bg, b.bg) && (a.attributes ?? 0) === (b.attributes ?? 0);
1185
- }
1186
- function styleFromCell(cell) {
1187
- return {
1188
- fg: rgbaFromXtermColor(cell.getFgColorMode(), cell.getFgColor()),
1189
- bg: rgbaFromXtermColor(cell.getBgColorMode(), cell.getBgColor()),
1190
- attributes: textAttributesFromCell(cell)
1191
- };
1192
- }
1193
- function lineToStyledText(line, cols) {
1194
- if (!line)
1195
- return new StyledText([{ __isChunk: true, text: "" }]);
1196
- const chunks = [];
1197
- let run = "";
1198
- let runStyle = null;
1199
- const flush = () => {
1200
- if (!run)
1201
- return;
1202
- chunks.push({
1203
- __isChunk: true,
1204
- text: run,
1205
- ...runStyle?.fg ? { fg: runStyle.fg } : {},
1206
- ...runStyle?.bg ? { bg: runStyle.bg } : {},
1207
- ...(runStyle?.attributes ?? 0) !== 0 ? { attributes: runStyle.attributes } : {}
1208
- });
1209
- run = "";
1210
- };
1211
- for (let index = 0;index < cols; index += 1) {
1212
- const cell = line.getCell(index);
1213
- if (!cell) {
1214
- if (runStyle !== null)
1215
- flush();
1216
- runStyle = null;
1217
- run += " ";
1218
- continue;
1219
- }
1220
- if (cell.getWidth() === 0)
1221
- continue;
1222
- const style = styleFromCell(cell);
1223
- if (!runStyle || !sameStyle(runStyle, style)) {
1224
- flush();
1225
- runStyle = style;
1226
- }
1227
- run += cell.getChars() || " ";
1228
- }
1229
- flush();
1230
- return new StyledText(chunks.length > 0 ? chunks : [{ __isChunk: true, text: "" }]);
1231
- }
1232
- function childCommandPrefix2() {
1233
- const execName = basename2(process.execPath).toLowerCase();
1234
- const currentEntry = process.argv[1];
1235
- if (execName === "bun" || execName === "bun.exe") {
1236
- return currentEntry ? [process.execPath, currentEntry, "__opentui-pi-host"] : [process.execPath, fallbackChildScriptPath];
1237
- }
1238
- return [process.execPath, "__opentui-pi-host"];
1239
- }
1240
- function withEnv2(base) {
1241
- const env = {};
1242
- for (const [key, value] of Object.entries(base ?? process.env)) {
1243
- if (key === "RIG_PLAIN" || key === "RIG_CLI_PLAIN_HELP" || key === "NO_COLOR")
1244
- continue;
1245
- if (typeof value === "string")
1246
- env[key] = value;
1247
- }
1248
- return {
1249
- ...env,
1250
- TERM: "xterm-256color",
1251
- COLORTERM: "truecolor",
1252
- FORCE_COLOR: env.FORCE_COLOR ?? "1",
1253
- RIG_OPENTUI_PI_HOST: "1"
1254
- };
1255
- }
1256
- function getActivePiHost() {
1257
- return activeHost2 && !activeHost2.disposed ? activeHost2 : null;
1258
- }
1259
- function stopActivePiHost(reason = "detach") {
1260
- activeHost2?.dispose(reason);
1261
- activeHost2 = null;
1262
- }
1263
-
1264
- class PiPtyHost {
1265
- runId;
1266
- projectRoot;
1267
- onSnapshot;
1268
- onExit;
1269
- onError;
1270
- terminal;
1271
- disposables = [];
1272
- decoder = new TextDecoder("utf-8");
1273
- proc = null;
1274
- pty = null;
1275
- status = "starting";
1276
- cols;
1277
- rows;
1278
- message = "starting bundled Pi";
1279
- lastResizeError = null;
1280
- exitCode;
1281
- signal;
1282
- notifyTimer = null;
1283
- lastStreamKey = "";
1284
- _disposed = false;
1285
- constructor(options) {
1286
- this.runId = options.runId;
1287
- this.projectRoot = options.projectRoot;
1288
- this.cols = clampCols2(options.cols);
1289
- this.rows = clampRows2(options.rows);
1290
- this.onSnapshot = options.onSnapshot;
1291
- this.onExit = options.onExit;
1292
- this.onError = options.onError;
1293
- this.terminal = new XtermTerminal2({
1294
- allowProposedApi: true,
1295
- cols: this.cols,
1296
- rows: this.rows,
1297
- scrollback: 1000
1298
- });
1299
- this.registerTerminalResponders();
1300
- this.disposables.push(this.terminal.onWriteParsed(() => {
1301
- if (this._disposed)
1302
- return;
1303
- const snapshot = this.createSnapshot();
1304
- const key = snapshot.lines.join(`
1305
- `);
1306
- if (key === this.lastStreamKey)
1307
- return;
1308
- this.lastStreamKey = key;
1309
- this.onSnapshot?.(snapshot);
1310
- }));
1311
- }
1312
- get disposed() {
1313
- return this._disposed;
1314
- }
1315
- get snapshot() {
1316
- return this.createSnapshot();
1317
- }
1318
- async start() {
1319
- if (this._disposed)
1320
- throw new Error("Pi PTY host is disposed.");
1321
- if (typeof Bun.Terminal !== "function") {
1322
- throw new Error("Bun native PTY is unavailable in this runtime. Pi host requires Bun.Terminal.");
1323
- }
1324
- const spawnOptions = {
1325
- cwd: this.projectRoot,
1326
- env: withEnv2(process.env),
1327
- terminal: {
1328
- cols: this.cols,
1329
- rows: this.rows,
1330
- name: "xterm-256color",
1331
- data: (_terminal, data) => this.handlePtyData(data)
1332
- }
1333
- };
1334
- const proc = Bun.spawn([
1335
- ...childCommandPrefix2(),
1336
- "--run-id",
1337
- this.runId,
1338
- "--project-root",
1339
- this.projectRoot
1340
- ], spawnOptions);
1341
- if (!proc.terminal)
1342
- throw new Error("Bun did not attach a terminal to the bundled Pi child process.");
1343
- this.proc = proc;
1344
- this.pty = proc.terminal;
1345
- this.status = "running";
1346
- this.message = "bundled Pi running inside this app";
1347
- this.emitSnapshotSoon(0);
1348
- proc.exited.then((exitCode) => {
1349
- if (this._disposed)
1350
- return;
1351
- this.status = exitCode === 0 ? "exited" : "failed";
1352
- this.exitCode = exitCode;
1353
- this.signal = null;
1354
- this.message = exitCode === 0 ? "bundled Pi exited" : `bundled Pi exited with code ${exitCode}`;
1355
- const snapshot = this.createSnapshot();
1356
- this.onSnapshot?.(snapshot);
1357
- this.onExit?.(snapshot);
1358
- if (activeHost2 === this)
1359
- activeHost2 = null;
1360
- this.dispose("exit", { kill: false, notify: false });
1361
- }).catch((error) => {
1362
- if (this._disposed)
1363
- return;
1364
- this.status = "failed";
1365
- this.message = error instanceof Error ? error.message : String(error);
1366
- const snapshot = this.createSnapshot();
1367
- this.onSnapshot?.(snapshot);
1368
- this.onError?.(error, snapshot);
1369
- if (activeHost2 === this)
1370
- activeHost2 = null;
1371
- this.dispose("error", { kill: false, notify: false });
1372
- });
1373
- }
1374
- write(data) {
1375
- if (this._disposed || !this.pty)
1376
- return;
1377
- try {
1378
- this.pty.write(data);
1379
- } catch (error) {
1380
- this.status = "failed";
1381
- this.message = error instanceof Error ? error.message : String(error);
1382
- const snapshot = this.createSnapshot();
1383
- this.onSnapshot?.(snapshot);
1384
- this.onError?.(error, snapshot);
1385
- }
1386
- }
1387
- resize(cols, rows) {
1388
- const nextCols = clampCols2(cols);
1389
- const nextRows = clampRows2(rows);
1390
- if (nextCols === this.cols && nextRows === this.rows)
1391
- return;
1392
- this.cols = nextCols;
1393
- this.rows = nextRows;
1394
- this.terminal.resize(nextCols, nextRows);
1395
- try {
1396
- this.pty?.resize(nextCols, nextRows);
1397
- this.lastResizeError = null;
1398
- } catch (error) {
1399
- this.lastResizeError = error instanceof Error ? error.message : String(error);
1400
- }
1401
- this.emitSnapshotSoon(0);
1402
- }
1403
- detach() {
1404
- this.dispose("detach");
1405
- return this.createSnapshot("detached from bundled Pi");
1406
- }
1407
- dispose(reason = "dispose", options = {}) {
1408
- if (this._disposed)
1409
- return;
1410
- this._disposed = true;
1411
- if (this.notifyTimer)
1412
- clearTimeout(this.notifyTimer);
1413
- this.notifyTimer = null;
1414
- for (const disposable of this.disposables.splice(0)) {
1415
- try {
1416
- disposable.dispose();
1417
- } catch {}
1418
- }
1419
- if (options.kill !== false) {
1420
- try {
1421
- this.proc?.kill("SIGTERM");
1422
- } catch {}
1423
- }
1424
- try {
1425
- this.pty?.close();
1426
- } catch {}
1427
- try {
1428
- this.terminal.dispose();
1429
- } catch {}
1430
- if (activeHost2 === this)
1431
- activeHost2 = null;
1432
- if (options.notify) {
1433
- this.message = reason;
1434
- this.onSnapshot?.(this.createSnapshot(reason));
1435
- }
1436
- }
1437
- handlePtyData(data) {
1438
- if (this._disposed)
1439
- return;
1440
- const text = this.decoder.decode(data, { stream: true });
1441
- this.respondToRawTerminalQueries(text);
1442
- this.terminal.write(data);
1443
- }
1444
- emitSnapshotSoon(delayMs = SNAPSHOT_DELAY_MS2) {
1445
- if (this._disposed || this.notifyTimer)
1446
- return;
1447
- this.notifyTimer = setTimeout(() => {
1448
- this.notifyTimer = null;
1449
- if (this._disposed)
1450
- return;
1451
- this.onSnapshot?.(this.createSnapshot());
1452
- }, delayMs);
1453
- }
1454
- createSnapshot(message = this.message) {
1455
- const buffer = this.terminal.buffer.active;
1456
- const end = buffer.length;
1457
- const start = Math.max(0, end - MAX_SNAPSHOT_LINES2);
1458
- const styledStart = Math.max(start, end - this.rows - STYLED_SNAPSHOT_MARGIN);
1459
- const lines = [];
1460
- const styledLines = [];
1461
- for (let row = start;row < end; row += 1) {
1462
- const line = buffer.getLine(row);
1463
- lines.push((line?.translateToString(false) ?? "").slice(0, this.cols));
1464
- if (row >= styledStart)
1465
- styledLines[lines.length - 1] = lineToStyledText(line, this.cols);
1466
- }
1467
- while (lines.length < this.rows) {
1468
- lines.push("");
1469
- styledLines[lines.length - 1] = new StyledText([{ __isChunk: true, text: "" }]);
1470
- }
1471
- const resolvedMessage = this.lastResizeError ? `resize degraded: ${this.lastResizeError}` : message;
1472
- return {
1473
- runId: this.runId,
1474
- status: this.status,
1475
- cols: this.cols,
1476
- rows: this.rows,
1477
- lines,
1478
- styledLines,
1479
- message: resolvedMessage,
1480
- ...this.lastResizeError ? { resizeError: this.lastResizeError } : {},
1481
- ...this.exitCode !== undefined ? { exitCode: this.exitCode } : {},
1482
- ...this.signal !== undefined ? { signal: this.signal } : {}
1483
- };
1484
- }
1485
- registerTerminalResponders() {
1486
- this.disposables.push(this.terminal.parser.registerCsiHandler({ final: "c" }, (params) => {
1487
- if (params.length === 0 || params[0] === 0)
1488
- this.write("\x1B[?62;22c");
1489
- return false;
1490
- }));
1491
- this.disposables.push(this.terminal.parser.registerCsiHandler({ prefix: ">", final: "c" }, (params) => {
1492
- if (params.length === 0 || params[0] === 0)
1493
- this.write("\x1B[>0;0;0c");
1494
- return false;
1495
- }));
1496
- this.disposables.push(this.terminal.parser.registerCsiHandler({ final: "n" }, (params) => {
1497
- if (params[0] === 5) {
1498
- this.write("\x1B[0n");
1499
- } else if (params[0] === 6) {
1500
- const row = this.terminal.buffer.active.cursorY + 1;
1501
- const col = this.terminal.buffer.active.cursorX + 1;
1502
- this.write(`\x1B[${row};${col}R`);
1503
- }
1504
- return false;
1505
- }));
1506
- }
1507
- respondToRawTerminalQueries(text) {
1508
- if (!text)
1509
- return;
1510
- const decrqm = /\x1b\[\?(\d+)\$p/g;
1511
- let match;
1512
- while ((match = decrqm.exec(text)) !== null) {
1513
- this.write(`\x1B[?${match[1]};2$y`);
1514
- }
1515
- }
1516
- }
1517
-
1518
1154
  // packages/cli/src/app-opentui/keymap.ts
1519
1155
  var autocompleteState;
1520
1156
  function clearTypeBar(context, message) {
@@ -1524,22 +1160,15 @@ function clearTypeBar(context, message) {
1524
1160
  context.emitTypeBarPatch({ value: "", mode: "nav", prompt: undefined, message });
1525
1161
  }
1526
1162
  function handleEmbeddedTerminalKey(context, key) {
1527
- const state = context.getState();
1528
- const piHost = getActivePiHost();
1529
- const commandHost = getActiveCommandHost();
1530
- const host = state.scene === "handoff" ? piHost : state.scene === "command" ? commandHost : null;
1163
+ if (context.getState().scene !== "command")
1164
+ return false;
1165
+ const host = getActiveCommandHost();
1531
1166
  if (!host)
1532
1167
  return false;
1533
1168
  if (key.ctrl && key.name === "]") {
1534
- if (state.scene === "handoff") {
1535
- stopActivePiHost("operator detach");
1536
- clearTypeBar(context, "detached from Pi");
1537
- context.runAppAction("Opening runs", () => context.runtime.runIntent({ scene: "fleet", argv: ["runs"], action: { kind: "refresh", label: "Opening runs" } }));
1538
- } else {
1539
- stopActiveCommandHost("operator detach");
1540
- clearTypeBar(context, "closed command");
1541
- context.runAppAction("Project menu", () => context.runtime.runIntent({ scene: "main", argv: ["main"], action: { kind: "none", label: "Project menu" } }));
1542
- }
1169
+ stopActiveCommandHost("operator detach");
1170
+ clearTypeBar(context, "closed command");
1171
+ context.runAppAction("Project menu", () => context.runtime.runIntent({ scene: "main", argv: ["main"], action: { kind: "none", label: "Project menu" } }));
1543
1172
  return true;
1544
1173
  }
1545
1174
  const sequence = key.raw || key.sequence;