@h-rig/cli 0.0.6-alpha.78 → 0.0.6-alpha.79

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 (69) hide show
  1. package/dist/bin/build-rig-binaries.d.ts +2 -0
  2. package/dist/bin/rig.d.ts +2 -0
  3. package/dist/bin/rig.js +37 -13
  4. package/dist/src/app/board.d.ts +23 -0
  5. package/dist/src/app/board.js +11 -8
  6. package/dist/src/app/drone-ui.d.ts +37 -0
  7. package/dist/src/app/theme.d.ts +47 -0
  8. package/dist/src/commands/_async-ui.d.ts +13 -0
  9. package/dist/src/commands/_authority-runs.d.ts +22 -0
  10. package/dist/src/commands/_cli-format.d.ts +49 -0
  11. package/dist/src/commands/_connection-state.d.ts +44 -0
  12. package/dist/src/commands/_doctor-checks.d.ts +52 -0
  13. package/dist/src/commands/_help-catalog.d.ts +51 -0
  14. package/dist/src/commands/_help-catalog.js +1 -0
  15. package/dist/src/commands/_json-output.d.ts +11 -0
  16. package/dist/src/commands/_operator-surface.d.ts +34 -0
  17. package/dist/src/commands/_operator-view.d.ts +30 -0
  18. package/dist/src/commands/_parsers.d.ts +15 -0
  19. package/dist/src/commands/_paths.d.ts +11 -0
  20. package/dist/src/commands/_pi-frontend.d.ts +27 -0
  21. package/dist/src/commands/_pi-install.d.ts +42 -0
  22. package/dist/src/commands/_pi-install.js +1 -1
  23. package/dist/src/commands/_policy.d.ts +8 -0
  24. package/dist/src/commands/_preflight.d.ts +22 -0
  25. package/dist/src/commands/_probes.d.ts +1 -0
  26. package/dist/src/commands/_run-driver-helpers.d.ts +99 -0
  27. package/dist/src/commands/_run-replay.d.ts +24 -0
  28. package/dist/src/commands/_server-client.d.ts +186 -0
  29. package/dist/src/commands/_snapshot-upload.d.ts +39 -0
  30. package/dist/src/commands/_spinner.d.ts +25 -0
  31. package/dist/src/commands/_task-picker.d.ts +9 -0
  32. package/dist/src/commands/agent.d.ts +3 -0
  33. package/dist/src/commands/browser.d.ts +65 -0
  34. package/dist/src/commands/connect.d.ts +7 -0
  35. package/dist/src/commands/dist.d.ts +28 -0
  36. package/dist/src/commands/doctor.d.ts +3 -0
  37. package/dist/src/commands/github.d.ts +3 -0
  38. package/dist/src/commands/inbox.d.ts +30 -0
  39. package/dist/src/commands/init.d.ts +74 -0
  40. package/dist/src/commands/init.js +1 -1
  41. package/dist/src/commands/inspect.d.ts +3 -0
  42. package/dist/src/commands/inspector.d.ts +3 -0
  43. package/dist/src/commands/pi.d.ts +3 -0
  44. package/dist/src/commands/plugin.d.ts +16 -0
  45. package/dist/src/commands/profile-and-review.d.ts +4 -0
  46. package/dist/src/commands/queue.d.ts +3 -0
  47. package/dist/src/commands/remote.d.ts +3 -0
  48. package/dist/src/commands/repo-git-harness.d.ts +5 -0
  49. package/dist/src/commands/run.d.ts +3 -0
  50. package/dist/src/commands/server.d.ts +7 -0
  51. package/dist/src/commands/setup.d.ts +16 -0
  52. package/dist/src/commands/stats.d.ts +12 -0
  53. package/dist/src/commands/stats.js +1 -0
  54. package/dist/src/commands/task-report-bug.d.ts +19 -0
  55. package/dist/src/commands/task-run-driver.d.ts +132 -0
  56. package/dist/src/commands/task-run-driver.js +23 -2
  57. package/dist/src/commands/task.d.ts +14 -0
  58. package/dist/src/commands/task.js +1 -0
  59. package/dist/src/commands/test.d.ts +3 -0
  60. package/dist/src/commands/workspace.d.ts +3 -0
  61. package/dist/src/commands.d.ts +29 -0
  62. package/dist/src/commands.js +37 -13
  63. package/dist/src/index.d.ts +4 -0
  64. package/dist/src/index.js +37 -13
  65. package/dist/src/launcher.d.ts +61 -0
  66. package/dist/src/report-bug.d.ts +44 -0
  67. package/dist/src/runner.d.ts +47 -0
  68. package/dist/src/withMutedConsole.d.ts +2 -0
  69. package/package.json +10 -8
@@ -3027,6 +3027,7 @@ var init__help_catalog = __esm(() => {
3027
3027
  { command: "next [filters]", description: "Render the next matching task as a selected-task card.", primary: true },
3028
3028
  { command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
3029
3029
  { command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
3030
+ { command: "ready", description: "List task IDs that are runnable now." },
3030
3031
  { command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
3031
3032
  { command: "details --task <id>", description: "Show full task info from the configured source." },
3032
3033
  { command: "reopen [--task <id> | --all] [--reason <text>]", description: "Reopen closed task(s) in the configured source." },
@@ -3821,7 +3822,7 @@ __export(exports_board, {
3821
3822
  import { randomUUID } from "crypto";
3822
3823
  import { existsSync as existsSync17 } from "fs";
3823
3824
  import { resolve as resolvePath } from "path";
3824
- import { ProcessTerminal as ProcessTerminal2, TUI as TUI2, Text as Text2, matchesKey as matchesKey2, truncateToWidth } from "@earendil-works/pi-tui";
3825
+ import { ProcessTerminal as ProcessTerminal2, TUI as TUI2, Text as Text2, isKeyRelease, matchesKey as matchesKey2, truncateToWidth } from "@earendil-works/pi-tui";
3825
3826
  function oneLine(message2) {
3826
3827
  return message2.split(`
3827
3828
  `).map((line) => line.trim()).find((line) => line.length > 0)?.slice(0, 200) ?? "unknown error";
@@ -4273,13 +4274,13 @@ async function runOperatorBoard(context, options = {}) {
4273
4274
  return;
4274
4275
  }
4275
4276
  if (view === "help") {
4276
- footer.setText(` ${accent("\u2191\u2193")}${ink3(" scroll")} ${accent("esc")}${ink3(" board")} ${accent("q")}${ink3(" quit")}`);
4277
+ footer.setText(` ${accent("\u2190")}${ink3(" back")} ${accent("\u2191\u2193")}${ink3(" scroll")} ${accent("esc")}${ink3(" board")} ${accent("q")}${ink3(" quit")}`);
4277
4278
  return;
4278
4279
  }
4279
4280
  if (view === "tasks") {
4280
4281
  footer.setText([
4281
4282
  ` ${notice ? accentDim(notice) : ink4("pick a task \u2014 a drone launches with project defaults")}`,
4282
- ` ${accent("enter")}${ink3(" dispatch")} ${accent("r")}${ink3(" reload")} ${accent("esc")}${ink3(" board")} ${accent("q")}${ink3(" quit")}`
4283
+ ` ${accent("\u2190")}${ink3(" back")} ${accent("enter")}${ink3(" dispatch")} ${accent("r")}${ink3(" reload")} ${accent("esc")}${ink3(" board")} ${accent("q")}${ink3(" quit")}`
4283
4284
  ].join(`
4284
4285
  `));
4285
4286
  return;
@@ -4287,7 +4288,7 @@ async function runOperatorBoard(context, options = {}) {
4287
4288
  if (view === "inbox") {
4288
4289
  footer.setText([
4289
4290
  ` ${notice ? accentDim(notice) : ink4("gates the fleet is waiting on \u2014 resolve them here")}`,
4290
- ` ${accent("a")}${ink3(" approve")} ${accent("d")}${ink3(" reject")} ${accent("enter")}${ink3(" answer input")} ${accent("r")}${ink3(" reload")} ${accent("esc")}${ink3(" board")}`
4291
+ ` ${accent("\u2190")}${ink3(" back")} ${accent("a")}${ink3(" approve")} ${accent("d")}${ink3(" reject")} ${accent("enter")}${ink3(" answer input")} ${accent("r")}${ink3(" reload")} ${accent("esc")}${ink3(" board")}`
4291
4292
  ].join(`
4292
4293
  `));
4293
4294
  return;
@@ -4454,6 +4455,8 @@ async function runOperatorBoard(context, options = {}) {
4454
4455
  tui.requestRender();
4455
4456
  }).catch(() => {});
4456
4457
  tui.addInputListener((data) => {
4458
+ if (isKeyRelease(data))
4459
+ return { consume: true };
4457
4460
  if (inputLine) {
4458
4461
  if (matchesKey2(data, "escape")) {
4459
4462
  if (inputLine.kind === "search")
@@ -4490,7 +4493,7 @@ async function runOperatorBoard(context, options = {}) {
4490
4493
  helpView.scroll(-15);
4491
4494
  else if (matchesKey2(data, "pageDown") || data === " ")
4492
4495
  helpView.scroll(15);
4493
- else if (matchesKey2(data, "escape") || data === "?") {
4496
+ else if (matchesKey2(data, "left") || matchesKey2(data, "escape") || data === "?") {
4494
4497
  setView("board");
4495
4498
  return { consume: true };
4496
4499
  }
@@ -4508,7 +4511,7 @@ async function runOperatorBoard(context, options = {}) {
4508
4511
  dispatchTask(task);
4509
4512
  } else if (data === "r")
4510
4513
  refreshTasks();
4511
- else if (matchesKey2(data, "escape"))
4514
+ else if (matchesKey2(data, "left") || matchesKey2(data, "escape"))
4512
4515
  setView("board");
4513
4516
  tui.requestRender();
4514
4517
  return { consume: true };
@@ -4536,7 +4539,7 @@ async function runOperatorBoard(context, options = {}) {
4536
4539
  }
4537
4540
  } else if (data === "r")
4538
4541
  refreshInbox();
4539
- else if (matchesKey2(data, "escape"))
4542
+ else if (matchesKey2(data, "left") || matchesKey2(data, "escape"))
4540
4543
  setView("board");
4541
4544
  tui.requestRender();
4542
4545
  return { consume: true };
@@ -4647,7 +4650,7 @@ async function runOperatorBoardLoop(context, attach, options = {}) {
4647
4650
  await attach(outcome.runId);
4648
4651
  }
4649
4652
  }
4650
- var BOARD_REFRESH_MS = 5000, BOARD_TICK_MS = 120, BOARD_TASK_PAGE = 20;
4653
+ var BOARD_REFRESH_MS = 5000, BOARD_TICK_MS = 250, BOARD_TASK_PAGE = 20;
4651
4654
  var init_board = __esm(() => {
4652
4655
  init_theme();
4653
4656
  init__help_catalog();
@@ -7552,7 +7555,7 @@ async function ensurePiBinaryAvailable(input) {
7552
7555
  }
7553
7556
  return { ok: true, detail: (current.stdout || current.stderr).trim() || undefined };
7554
7557
  }
7555
- const installCommand = process.env.RIG_PI_INSTALL_COMMAND?.trim() || "bunx @earendil-works/pi@latest install";
7558
+ const installCommand = process.env.RIG_PI_INSTALL_COMMAND?.trim() || "bunx @earendil-works/pi-coding-agent@latest install";
7556
7559
  const parts = splitInstallCommand(installCommand);
7557
7560
  if (parts.length === 0) {
7558
7561
  return { ok: false, error: (current.stderr || current.stdout).trim() || "pi --version failed" };
@@ -11020,6 +11023,19 @@ function looksLikeGitHubToken(value) {
11020
11023
  return false;
11021
11024
  return /^(gh[opusr]_|github_pat_)/.test(token);
11022
11025
  }
11026
+ function isSensitivePayloadKey(key) {
11027
+ return /token|secret|password|authorization|credential/i.test(key);
11028
+ }
11029
+ function redactSensitivePayload(value) {
11030
+ if (Array.isArray(value))
11031
+ return value.map(redactSensitivePayload);
11032
+ if (!value || typeof value !== "object")
11033
+ return value;
11034
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [
11035
+ key,
11036
+ isSensitivePayloadKey(key) && typeof child === "string" && child.trim() ? "[redacted]" : redactSensitivePayload(child)
11037
+ ]));
11038
+ }
11023
11039
  function githubBridgeEnv(token) {
11024
11040
  const clean = token?.trim();
11025
11041
  if (!clean)
@@ -11710,7 +11726,7 @@ function appendPiToolTimelineFromRecord(input) {
11710
11726
  }
11711
11727
  function isNonRenderablePiProtocolRecord(record) {
11712
11728
  const type = typeof record.type === "string" ? record.type : "";
11713
- return type === "agent_start" || type === "agent_end" || type === "message_start" || type === "message_end" || type === "turn_start" || type === "turn_end" || type === "tool_result" || type === "message_update" && (!record.assistantMessageEvent || typeof record.assistantMessageEvent !== "object" || Array.isArray(record.assistantMessageEvent) || record.assistantMessageEvent.type !== "text_delta");
11729
+ return type === "pi.event" || type === "status.update" || type === "activity.update" || type === "ready" || type === "agent_start" || type === "agent_end" || type === "message_start" || type === "message_end" || type === "turn_start" || type === "turn_end" || type === "tool_result" || type === "message_update" && (!record.assistantMessageEvent || typeof record.assistantMessageEvent !== "object" || Array.isArray(record.assistantMessageEvent) || record.assistantMessageEvent.type !== "text_delta");
11714
11730
  }
11715
11731
  function appendToolTimelineFromLog(input) {
11716
11732
  const title = typeof input.log.title === "string" ? input.log.title : "";
@@ -12270,7 +12286,15 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
12270
12286
  emitServerRunEvent({ type: "log", runId: input.runId, title });
12271
12287
  return true;
12272
12288
  }
12273
- return false;
12289
+ appendRunTimeline(context.projectRoot, input.runId, {
12290
+ id: `timeline:${input.runId}:${Date.now()}:wrapper:${event.type}`,
12291
+ type: "wrapper-event",
12292
+ eventType: event.type,
12293
+ payload: redactSensitivePayload(payload),
12294
+ createdAt: new Date().toISOString()
12295
+ });
12296
+ emitServerRunEvent({ type: "timeline", runId: input.runId });
12297
+ return true;
12274
12298
  };
12275
12299
  const handleAgentStdoutLine = (line) => {
12276
12300
  const trimmed = line.trim();
@@ -13327,9 +13351,9 @@ async function openApp(context, options = {}) {
13327
13351
  const { runOperatorBoardLoop: runOperatorBoardLoop2 } = await Promise.resolve().then(() => (init_board(), exports_board));
13328
13352
  await runOperatorBoardLoop2(context, async (runId) => {
13329
13353
  const scriptArg = typeof process.argv[1] === "string" && /\.(ts|js|mjs)$/.test(process.argv[1]) ? [process.argv[1]] : [];
13330
- const child = Bun.spawn([process.execPath, ...scriptArg, "run", "attach", runId], {
13354
+ const child = Bun.spawn([process.execPath, ...scriptArg, "--project", context.projectRoot, "run", "attach", runId], {
13331
13355
  stdio: ["inherit", "inherit", "inherit"],
13332
- env: process.env
13356
+ env: { ...process.env, PROJECT_RIG_ROOT: context.projectRoot }
13333
13357
  });
13334
13358
  await child.exited;
13335
13359
  }, options);
@@ -0,0 +1,4 @@
1
+ export declare const RIG_CLI_PACKAGE = "@rig/cli";
2
+ export { execute, __testOnly } from "./commands";
3
+ export { parsePolicyMode, resolveProjectRoot, runRigCli, type CliIo, type PolicyModeValue, type ResolveProjectRootOptions, type RigCliModule, type RigCliRunOptions, } from "./launcher";
4
+ export { CliError, formatCommand, initializeRuntime, requireNoExtraArgs, requireTask, takeFlag, takeOption, withProjectRoot, type RunnerContext, } from "./runner";
package/dist/src/index.js CHANGED
@@ -3216,6 +3216,7 @@ var init__help_catalog = __esm(() => {
3216
3216
  { command: "next [filters]", description: "Render the next matching task as a selected-task card.", primary: true },
3217
3217
  { command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
3218
3218
  { command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
3219
+ { command: "ready", description: "List task IDs that are runnable now." },
3219
3220
  { command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
3220
3221
  { command: "details --task <id>", description: "Show full task info from the configured source." },
3221
3222
  { command: "reopen [--task <id> | --all] [--reason <text>]", description: "Reopen closed task(s) in the configured source." },
@@ -4010,7 +4011,7 @@ __export(exports_board, {
4010
4011
  import { randomUUID } from "crypto";
4011
4012
  import { existsSync as existsSync18 } from "fs";
4012
4013
  import { resolve as resolvePath } from "path";
4013
- import { ProcessTerminal as ProcessTerminal2, TUI as TUI2, Text as Text2, matchesKey as matchesKey2, truncateToWidth } from "@earendil-works/pi-tui";
4014
+ import { ProcessTerminal as ProcessTerminal2, TUI as TUI2, Text as Text2, isKeyRelease, matchesKey as matchesKey2, truncateToWidth } from "@earendil-works/pi-tui";
4014
4015
  function oneLine(message2) {
4015
4016
  return message2.split(`
4016
4017
  `).map((line) => line.trim()).find((line) => line.length > 0)?.slice(0, 200) ?? "unknown error";
@@ -4462,13 +4463,13 @@ async function runOperatorBoard(context, options = {}) {
4462
4463
  return;
4463
4464
  }
4464
4465
  if (view === "help") {
4465
- footer.setText(` ${accent("\u2191\u2193")}${ink3(" scroll")} ${accent("esc")}${ink3(" board")} ${accent("q")}${ink3(" quit")}`);
4466
+ footer.setText(` ${accent("\u2190")}${ink3(" back")} ${accent("\u2191\u2193")}${ink3(" scroll")} ${accent("esc")}${ink3(" board")} ${accent("q")}${ink3(" quit")}`);
4466
4467
  return;
4467
4468
  }
4468
4469
  if (view === "tasks") {
4469
4470
  footer.setText([
4470
4471
  ` ${notice ? accentDim(notice) : ink4("pick a task \u2014 a drone launches with project defaults")}`,
4471
- ` ${accent("enter")}${ink3(" dispatch")} ${accent("r")}${ink3(" reload")} ${accent("esc")}${ink3(" board")} ${accent("q")}${ink3(" quit")}`
4472
+ ` ${accent("\u2190")}${ink3(" back")} ${accent("enter")}${ink3(" dispatch")} ${accent("r")}${ink3(" reload")} ${accent("esc")}${ink3(" board")} ${accent("q")}${ink3(" quit")}`
4472
4473
  ].join(`
4473
4474
  `));
4474
4475
  return;
@@ -4476,7 +4477,7 @@ async function runOperatorBoard(context, options = {}) {
4476
4477
  if (view === "inbox") {
4477
4478
  footer.setText([
4478
4479
  ` ${notice ? accentDim(notice) : ink4("gates the fleet is waiting on \u2014 resolve them here")}`,
4479
- ` ${accent("a")}${ink3(" approve")} ${accent("d")}${ink3(" reject")} ${accent("enter")}${ink3(" answer input")} ${accent("r")}${ink3(" reload")} ${accent("esc")}${ink3(" board")}`
4480
+ ` ${accent("\u2190")}${ink3(" back")} ${accent("a")}${ink3(" approve")} ${accent("d")}${ink3(" reject")} ${accent("enter")}${ink3(" answer input")} ${accent("r")}${ink3(" reload")} ${accent("esc")}${ink3(" board")}`
4480
4481
  ].join(`
4481
4482
  `));
4482
4483
  return;
@@ -4643,6 +4644,8 @@ async function runOperatorBoard(context, options = {}) {
4643
4644
  tui.requestRender();
4644
4645
  }).catch(() => {});
4645
4646
  tui.addInputListener((data) => {
4647
+ if (isKeyRelease(data))
4648
+ return { consume: true };
4646
4649
  if (inputLine) {
4647
4650
  if (matchesKey2(data, "escape")) {
4648
4651
  if (inputLine.kind === "search")
@@ -4679,7 +4682,7 @@ async function runOperatorBoard(context, options = {}) {
4679
4682
  helpView.scroll(-15);
4680
4683
  else if (matchesKey2(data, "pageDown") || data === " ")
4681
4684
  helpView.scroll(15);
4682
- else if (matchesKey2(data, "escape") || data === "?") {
4685
+ else if (matchesKey2(data, "left") || matchesKey2(data, "escape") || data === "?") {
4683
4686
  setView("board");
4684
4687
  return { consume: true };
4685
4688
  }
@@ -4697,7 +4700,7 @@ async function runOperatorBoard(context, options = {}) {
4697
4700
  dispatchTask(task);
4698
4701
  } else if (data === "r")
4699
4702
  refreshTasks();
4700
- else if (matchesKey2(data, "escape"))
4703
+ else if (matchesKey2(data, "left") || matchesKey2(data, "escape"))
4701
4704
  setView("board");
4702
4705
  tui.requestRender();
4703
4706
  return { consume: true };
@@ -4725,7 +4728,7 @@ async function runOperatorBoard(context, options = {}) {
4725
4728
  }
4726
4729
  } else if (data === "r")
4727
4730
  refreshInbox();
4728
- else if (matchesKey2(data, "escape"))
4731
+ else if (matchesKey2(data, "left") || matchesKey2(data, "escape"))
4729
4732
  setView("board");
4730
4733
  tui.requestRender();
4731
4734
  return { consume: true };
@@ -4836,7 +4839,7 @@ async function runOperatorBoardLoop(context, attach, options = {}) {
4836
4839
  await attach(outcome.runId);
4837
4840
  }
4838
4841
  }
4839
- var BOARD_REFRESH_MS = 5000, BOARD_TICK_MS = 120, BOARD_TASK_PAGE = 20;
4842
+ var BOARD_REFRESH_MS = 5000, BOARD_TICK_MS = 250, BOARD_TASK_PAGE = 20;
4840
4843
  var init_board = __esm(() => {
4841
4844
  init_theme();
4842
4845
  init__help_catalog();
@@ -7741,7 +7744,7 @@ async function ensurePiBinaryAvailable(input) {
7741
7744
  }
7742
7745
  return { ok: true, detail: (current.stdout || current.stderr).trim() || undefined };
7743
7746
  }
7744
- const installCommand = process.env.RIG_PI_INSTALL_COMMAND?.trim() || "bunx @earendil-works/pi@latest install";
7747
+ const installCommand = process.env.RIG_PI_INSTALL_COMMAND?.trim() || "bunx @earendil-works/pi-coding-agent@latest install";
7745
7748
  const parts = splitInstallCommand(installCommand);
7746
7749
  if (parts.length === 0) {
7747
7750
  return { ok: false, error: (current.stderr || current.stdout).trim() || "pi --version failed" };
@@ -11209,6 +11212,19 @@ function looksLikeGitHubToken(value) {
11209
11212
  return false;
11210
11213
  return /^(gh[opusr]_|github_pat_)/.test(token);
11211
11214
  }
11215
+ function isSensitivePayloadKey(key) {
11216
+ return /token|secret|password|authorization|credential/i.test(key);
11217
+ }
11218
+ function redactSensitivePayload(value) {
11219
+ if (Array.isArray(value))
11220
+ return value.map(redactSensitivePayload);
11221
+ if (!value || typeof value !== "object")
11222
+ return value;
11223
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [
11224
+ key,
11225
+ isSensitivePayloadKey(key) && typeof child === "string" && child.trim() ? "[redacted]" : redactSensitivePayload(child)
11226
+ ]));
11227
+ }
11212
11228
  function githubBridgeEnv(token) {
11213
11229
  const clean = token?.trim();
11214
11230
  if (!clean)
@@ -11899,7 +11915,7 @@ function appendPiToolTimelineFromRecord(input) {
11899
11915
  }
11900
11916
  function isNonRenderablePiProtocolRecord(record) {
11901
11917
  const type = typeof record.type === "string" ? record.type : "";
11902
- return type === "agent_start" || type === "agent_end" || type === "message_start" || type === "message_end" || type === "turn_start" || type === "turn_end" || type === "tool_result" || type === "message_update" && (!record.assistantMessageEvent || typeof record.assistantMessageEvent !== "object" || Array.isArray(record.assistantMessageEvent) || record.assistantMessageEvent.type !== "text_delta");
11918
+ return type === "pi.event" || type === "status.update" || type === "activity.update" || type === "ready" || type === "agent_start" || type === "agent_end" || type === "message_start" || type === "message_end" || type === "turn_start" || type === "turn_end" || type === "tool_result" || type === "message_update" && (!record.assistantMessageEvent || typeof record.assistantMessageEvent !== "object" || Array.isArray(record.assistantMessageEvent) || record.assistantMessageEvent.type !== "text_delta");
11903
11919
  }
11904
11920
  function appendToolTimelineFromLog(input) {
11905
11921
  const title = typeof input.log.title === "string" ? input.log.title : "";
@@ -12459,7 +12475,15 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
12459
12475
  emitServerRunEvent({ type: "log", runId: input.runId, title });
12460
12476
  return true;
12461
12477
  }
12462
- return false;
12478
+ appendRunTimeline(context.projectRoot, input.runId, {
12479
+ id: `timeline:${input.runId}:${Date.now()}:wrapper:${event.type}`,
12480
+ type: "wrapper-event",
12481
+ eventType: event.type,
12482
+ payload: redactSensitivePayload(payload),
12483
+ createdAt: new Date().toISOString()
12484
+ });
12485
+ emitServerRunEvent({ type: "timeline", runId: input.runId });
12486
+ return true;
12463
12487
  };
12464
12488
  const handleAgentStdoutLine = (line) => {
12465
12489
  const trimmed = line.trim();
@@ -13516,9 +13540,9 @@ async function openApp(context, options = {}) {
13516
13540
  const { runOperatorBoardLoop: runOperatorBoardLoop2 } = await Promise.resolve().then(() => (init_board(), exports_board));
13517
13541
  await runOperatorBoardLoop2(context, async (runId) => {
13518
13542
  const scriptArg = typeof process.argv[1] === "string" && /\.(ts|js|mjs)$/.test(process.argv[1]) ? [process.argv[1]] : [];
13519
- const child = Bun.spawn([process.execPath, ...scriptArg, "run", "attach", runId], {
13543
+ const child = Bun.spawn([process.execPath, ...scriptArg, "--project", context.projectRoot, "run", "attach", runId], {
13520
13544
  stdio: ["inherit", "inherit", "inherit"],
13521
- env: process.env
13545
+ env: { ...process.env, PROJECT_RIG_ROOT: context.projectRoot }
13522
13546
  });
13523
13547
  await child.exited;
13524
13548
  }, options);
@@ -0,0 +1,61 @@
1
+ import type { RunnerContext } from "./runner";
2
+ export type PolicyModeValue = "off" | "observe" | "enforce";
3
+ export interface ResolveProjectRootOptions {
4
+ readonly envProjectRoot?: string;
5
+ readonly execPath?: string;
6
+ readonly importDir?: string;
7
+ readonly cwd?: string;
8
+ }
9
+ export interface CliIo {
10
+ readonly log: (message: string) => void;
11
+ readonly error: (message: string) => void;
12
+ }
13
+ export interface RigCliRunOptions {
14
+ readonly argv?: readonly string[];
15
+ readonly io?: CliIo;
16
+ readonly envProjectRoot?: string;
17
+ readonly execPath?: string;
18
+ readonly importDir?: string;
19
+ readonly cwd?: string;
20
+ }
21
+ export interface RigCliModule {
22
+ readonly CliError: new (message: string, exitCode?: number) => Error & {
23
+ exitCode: number;
24
+ };
25
+ execute: (context: RunnerContext, args: string[]) => Promise<unknown>;
26
+ initializeRuntime: (options: {
27
+ projectRoot: string;
28
+ dryRun: boolean;
29
+ outputMode: "json" | "text";
30
+ runId?: string | undefined;
31
+ policyMode?: PolicyModeValue | undefined;
32
+ }) => Promise<RunnerContext>;
33
+ loadPolicy(projectRoot: string): {
34
+ mode: PolicyModeValue;
35
+ };
36
+ takeFlag(args: string[], flag: string): {
37
+ value: boolean;
38
+ rest: string[];
39
+ };
40
+ takeOption(args: string[], option: string): {
41
+ value?: string;
42
+ rest: string[];
43
+ };
44
+ withProjectRoot(projectRoot: string): void;
45
+ }
46
+ export declare function parsePolicyMode(value: string | undefined): PolicyModeValue | undefined;
47
+ export declare function resolveProjectRoot({ envProjectRoot, execPath, importDir, cwd, }: ResolveProjectRootOptions): string;
48
+ export interface CliErrorPayload {
49
+ readonly ok: false;
50
+ readonly code: string;
51
+ readonly message: string;
52
+ readonly exitCode: number;
53
+ /** Remediation hint (next command to run); rendered as `Next: <hint>`. */
54
+ readonly hint?: string;
55
+ readonly stack?: string;
56
+ }
57
+ export declare function normalizeCliErrorPayload(error: unknown, CliErrorClass: RigCliModule["CliError"], options?: {
58
+ readonly debug?: boolean;
59
+ }): CliErrorPayload;
60
+ export declare function runRigCli(module: RigCliModule, options?: RigCliRunOptions): Promise<void>;
61
+ export declare function hydrateProcessEnvFromDotEnv(projectRoot: string): void;
@@ -0,0 +1,44 @@
1
+ export type BrowserBugEnvironment = "local" | "shared-dev" | "staging" | "production" | "custom";
2
+ export type BrowserBugReportInput = {
3
+ projectRoot: string;
4
+ outputRoot: string;
5
+ title: string;
6
+ url: string;
7
+ browserRequired?: boolean;
8
+ environment: BrowserBugEnvironment | string;
9
+ preset: string;
10
+ profile: string;
11
+ attachUrl: string;
12
+ stateDir: string;
13
+ mode: string;
14
+ viewport: string;
15
+ summary: string;
16
+ steps: string[];
17
+ expected: string;
18
+ actual: string;
19
+ evidence: string[];
20
+ screenshots?: string[];
21
+ assets?: string[];
22
+ issueId?: string;
23
+ slug?: string;
24
+ overwrite: boolean;
25
+ };
26
+ export type BrowserBugReportResult = {
27
+ slug: string;
28
+ reportDir: string;
29
+ taskPath: string;
30
+ browserPath: string | null;
31
+ manifestPath: string;
32
+ assetDir: string;
33
+ screenshotDir: string;
34
+ copiedAssets: string[];
35
+ copiedScreenshots: string[];
36
+ };
37
+ export declare function slugifyBugTitle(value: string): string;
38
+ export declare function defaultBrowserBugProfile(title: string): string;
39
+ export declare function defaultBrowserBugOptions(environment: string): {
40
+ preset: string;
41
+ attachUrl: string;
42
+ stateDir: string;
43
+ };
44
+ export declare function createBugReportFiles(input: BrowserBugReportInput): BrowserBugReportResult;
@@ -0,0 +1,47 @@
1
+ import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
2
+ import type { PolicyMode } from "@rig/runtime/control-plane/runtime/guard-types";
3
+ import type { RunnerContext } from "@rig/runtime/control-plane/runtime/runner-context";
4
+ import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
5
+ import type { CommandExecutionResult, OutputMode } from "@rig/runtime/control-plane/runtime/types";
6
+ export type { RunnerContext } from "@rig/runtime/control-plane/runtime/runner-context";
7
+ /**
8
+ * CLI-side error with an optional remediation hint. The hint is rendered on
9
+ * its own line as `Next: <hint>` (and carried in the --json error payload),
10
+ * so every failure names the next command to run. Extends the runtime
11
+ * CliError so `instanceof` checks against either class keep working.
12
+ */
13
+ export declare class CliError extends RuntimeCliError {
14
+ readonly hint?: string;
15
+ constructor(message: string, exitCode?: number, options?: {
16
+ readonly hint?: string;
17
+ });
18
+ }
19
+ export declare function withProjectRoot(projectRoot: string): void;
20
+ export declare function formatCommand(parts: string[]): string;
21
+ type AgentShellBuild = typeof buildBinary;
22
+ type AgentShellMaterializationOptions = {
23
+ readonly env?: Record<string, string | undefined>;
24
+ readonly cwd?: string;
25
+ readonly moduleDir?: string;
26
+ readonly build?: AgentShellBuild;
27
+ };
28
+ export declare function resolveAgentMaterializationSourceRoot(projectRoot: string, options?: AgentShellMaterializationOptions): string;
29
+ export declare function ensureAgentShellBinary(projectRoot: string, options?: AgentShellMaterializationOptions): Promise<string>;
30
+ export declare function initializeRuntime(options: {
31
+ projectRoot: string;
32
+ dryRun: boolean;
33
+ outputMode: OutputMode;
34
+ runId?: string;
35
+ policyMode?: PolicyMode;
36
+ }): Promise<RunnerContext>;
37
+ export declare function runCommand(context: RunnerContext, parts: string[]): Promise<CommandExecutionResult>;
38
+ export declare function takeFlag(args: string[], flag: string): {
39
+ value: boolean;
40
+ rest: string[];
41
+ };
42
+ export declare function takeOption(args: string[], option: string): {
43
+ value: string | undefined;
44
+ rest: string[];
45
+ };
46
+ export declare function requireNoExtraArgs(args: string[], usage: string): void;
47
+ export declare function requireTask(taskId: string | undefined, usage: string): string;
@@ -0,0 +1,2 @@
1
+ export declare function withMutedConsole<T>(mute: boolean, fn: () => Promise<T>): Promise<T>;
2
+ export declare function withMutedConsole<T>(mute: boolean, fn: () => T): T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h-rig/cli",
3
- "version": "0.0.6-alpha.78",
3
+ "version": "0.0.6-alpha.79",
4
4
  "type": "module",
5
5
  "description": "Rig package",
6
6
  "license": "UNLICENSED",
@@ -10,6 +10,7 @@
10
10
  ],
11
11
  "exports": {
12
12
  ".": {
13
+ "types": "./dist/src/index.d.ts",
13
14
  "import": "./dist/src/index.js"
14
15
  }
15
16
  },
@@ -18,19 +19,20 @@
18
19
  },
19
20
  "main": "./dist/src/index.js",
20
21
  "module": "./dist/src/index.js",
22
+ "types": "./dist/src/index.d.ts",
21
23
  "bin": {
22
24
  "rig": "./dist/bin/rig.js"
23
25
  },
24
26
  "dependencies": {
25
27
  "@earendil-works/pi-coding-agent": "0.79.0",
26
28
  "@earendil-works/pi-tui": "^0.79.0",
27
- "@rig/client": "npm:@h-rig/client@0.0.6-alpha.78",
28
- "@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.78",
29
- "@rig/core": "npm:@h-rig/core@0.0.6-alpha.78",
30
- "@rig/pi-rig": "npm:@h-rig/pi-rig@0.0.6-alpha.78",
31
- "@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.78",
32
- "@rig/server": "npm:@h-rig/server@0.0.6-alpha.78",
33
- "@rig/standard-plugin": "npm:@h-rig/standard-plugin@0.0.6-alpha.78",
29
+ "@rig/client": "npm:@h-rig/client@0.0.6-alpha.79",
30
+ "@rig/contracts": "npm:@h-rig/contracts@0.0.6-alpha.79",
31
+ "@rig/core": "npm:@h-rig/core@0.0.6-alpha.79",
32
+ "@rig/pi-rig": "npm:@h-rig/pi-rig@0.0.6-alpha.79",
33
+ "@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.79",
34
+ "@rig/server": "npm:@h-rig/server@0.0.6-alpha.79",
35
+ "@rig/standard-plugin": "npm:@h-rig/standard-plugin@0.0.6-alpha.79",
34
36
  "effect": "4.0.0-beta.78",
35
37
  "picocolors": "^1.1.1"
36
38
  }