@h-rig/cli 0.0.6-alpha.77 → 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 (91) 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 +10214 -9309
  4. package/dist/src/app/board.d.ts +23 -0
  5. package/dist/src/app/board.js +1786 -0
  6. package/dist/src/app/drone-ui.d.ts +37 -0
  7. package/dist/src/app/drone-ui.js +294 -0
  8. package/dist/src/app/theme.d.ts +47 -0
  9. package/dist/src/{commands/_tui-theme.js → app/theme.js} +16 -1
  10. package/dist/src/commands/_async-ui.d.ts +13 -0
  11. package/dist/src/commands/_async-ui.js +74 -3
  12. package/dist/src/commands/_authority-runs.d.ts +22 -0
  13. package/dist/src/commands/_cli-format.d.ts +49 -0
  14. package/dist/src/commands/_cli-format.js +26 -8
  15. package/dist/src/commands/_connection-state.d.ts +44 -0
  16. package/dist/src/commands/_doctor-checks.d.ts +52 -0
  17. package/dist/src/commands/_doctor-checks.js +3 -1
  18. package/dist/src/commands/_help-catalog.d.ts +51 -0
  19. package/dist/src/commands/_help-catalog.js +9 -70
  20. package/dist/src/commands/_json-output.d.ts +11 -0
  21. package/dist/src/commands/_operator-surface.d.ts +34 -0
  22. package/dist/src/commands/_operator-view.d.ts +30 -0
  23. package/dist/src/commands/_operator-view.js +184 -7
  24. package/dist/src/commands/_parsers.d.ts +15 -0
  25. package/dist/src/commands/_paths.d.ts +11 -0
  26. package/dist/src/commands/_pi-frontend.d.ts +27 -0
  27. package/dist/src/commands/_pi-frontend.js +184 -7
  28. package/dist/src/commands/_pi-install.d.ts +42 -0
  29. package/dist/src/commands/_pi-install.js +1 -1
  30. package/dist/src/commands/_policy.d.ts +8 -0
  31. package/dist/src/commands/_preflight.d.ts +22 -0
  32. package/dist/src/commands/_preflight.js +3 -1
  33. package/dist/src/commands/_probes.d.ts +1 -0
  34. package/dist/src/commands/_run-driver-helpers.d.ts +99 -0
  35. package/dist/src/commands/_run-replay.d.ts +24 -0
  36. package/dist/src/commands/_server-client.d.ts +186 -0
  37. package/dist/src/commands/_server-client.js +3 -1
  38. package/dist/src/commands/_snapshot-upload.d.ts +39 -0
  39. package/dist/src/commands/_snapshot-upload.js +3 -1
  40. package/dist/src/commands/_spinner.d.ts +25 -0
  41. package/dist/src/commands/_task-picker.d.ts +9 -0
  42. package/dist/src/commands/_task-picker.js +132 -7
  43. package/dist/src/commands/agent.d.ts +3 -0
  44. package/dist/src/commands/browser.d.ts +65 -0
  45. package/dist/src/commands/browser.js +306 -30
  46. package/dist/src/commands/connect.d.ts +7 -0
  47. package/dist/src/commands/connect.js +130 -64
  48. package/dist/src/commands/dist.d.ts +28 -0
  49. package/dist/src/commands/doctor.d.ts +3 -0
  50. package/dist/src/commands/doctor.js +77 -4
  51. package/dist/src/commands/github.d.ts +3 -0
  52. package/dist/src/commands/github.js +77 -4
  53. package/dist/src/commands/inbox.d.ts +30 -0
  54. package/dist/src/commands/inbox.js +101 -78
  55. package/dist/src/commands/init.d.ts +74 -0
  56. package/dist/src/commands/init.js +350 -10
  57. package/dist/src/commands/inspect.d.ts +3 -0
  58. package/dist/src/commands/inspect.js +77 -4
  59. package/dist/src/commands/inspector.d.ts +3 -0
  60. package/dist/src/commands/pi.d.ts +3 -0
  61. package/dist/src/commands/plugin.d.ts +16 -0
  62. package/dist/src/commands/profile-and-review.d.ts +4 -0
  63. package/dist/src/commands/queue.d.ts +3 -0
  64. package/dist/src/commands/remote.d.ts +3 -0
  65. package/dist/src/commands/repo-git-harness.d.ts +5 -0
  66. package/dist/src/commands/run.d.ts +3 -0
  67. package/dist/src/commands/run.js +195 -69
  68. package/dist/src/commands/server.d.ts +7 -0
  69. package/dist/src/commands/server.js +133 -65
  70. package/dist/src/commands/setup.d.ts +16 -0
  71. package/dist/src/commands/setup.js +77 -4
  72. package/dist/src/commands/stats.d.ts +12 -0
  73. package/dist/src/commands/stats.js +57 -113
  74. package/dist/src/commands/task-report-bug.d.ts +19 -0
  75. package/dist/src/commands/task-report-bug.js +231 -40
  76. package/dist/src/commands/task-run-driver.d.ts +132 -0
  77. package/dist/src/commands/task-run-driver.js +26 -3
  78. package/dist/src/commands/task.d.ts +14 -0
  79. package/dist/src/commands/task.js +341 -229
  80. package/dist/src/commands/test.d.ts +3 -0
  81. package/dist/src/commands/workspace.d.ts +3 -0
  82. package/dist/src/commands.d.ts +29 -0
  83. package/dist/src/commands.js +10194 -9289
  84. package/dist/src/index.d.ts +4 -0
  85. package/dist/src/index.js +10200 -9295
  86. package/dist/src/launcher.d.ts +61 -0
  87. package/dist/src/report-bug.d.ts +44 -0
  88. package/dist/src/runner.d.ts +47 -0
  89. package/dist/src/withMutedConsole.d.ts +2 -0
  90. package/package.json +10 -9
  91. package/dist/src/commands/_operator-board.js +0 -730
@@ -320,7 +320,9 @@ ${failure.contextLine}`, 1, { hint: failure.hint });
320
320
  })() : null;
321
321
  if (!response.ok) {
322
322
  const diagnostics = diagnosticMessage(payload);
323
- const detail = diagnostics ?? (text || response.statusText);
323
+ const rawDetail = diagnostics ?? (text || response.statusText);
324
+ const detail = diagnostics ? rawDetail : rawDetail.split(`
325
+ `).map((line) => line.trim()).find((line) => line.length > 0)?.slice(0, 200) ?? response.statusText;
324
326
  const failure = await buildServerFailureContext(context.projectRoot, server);
325
327
  throw new CliError(`Rig server request failed (${response.status}): ${detail}
326
328
  ${failure.contextLine}`, 1, { hint: failure.hint });
@@ -713,8 +715,79 @@ function createTtySpinner(input) {
713
715
  };
714
716
  }
715
717
 
718
+ // packages/cli/src/app/theme.ts
719
+ var RIG_PALETTE = {
720
+ ink: "#f2f3f6",
721
+ ink2: "#aeb0ba",
722
+ ink3: "#6c6e79",
723
+ ink4: "#44464f",
724
+ accent: "#ccff4d",
725
+ accentDim: "#a9d63f",
726
+ cyan: "#56d8ff",
727
+ red: "#ff5d5d",
728
+ yellow: "#ffd24d"
729
+ };
730
+ function hexToRgb(hex) {
731
+ const value = hex.replace("#", "");
732
+ return [
733
+ Number.parseInt(value.slice(0, 2), 16),
734
+ Number.parseInt(value.slice(2, 4), 16),
735
+ Number.parseInt(value.slice(4, 6), 16)
736
+ ];
737
+ }
738
+ function fg(hex) {
739
+ const [r, g, b] = hexToRgb(hex);
740
+ return (text) => `\x1B[38;2;${r};${g};${b}m${text}\x1B[39m`;
741
+ }
742
+ var ink = fg(RIG_PALETTE.ink);
743
+ var ink2 = fg(RIG_PALETTE.ink2);
744
+ var ink3 = fg(RIG_PALETTE.ink3);
745
+ var ink4 = fg(RIG_PALETTE.ink4);
746
+ var accent = fg(RIG_PALETTE.accent);
747
+ var accentDim = fg(RIG_PALETTE.accentDim);
748
+ var cyan = fg(RIG_PALETTE.cyan);
749
+ var red = fg(RIG_PALETTE.red);
750
+ var yellow = fg(RIG_PALETTE.yellow);
751
+ function bold(text) {
752
+ return `\x1B[1m${text}\x1B[22m`;
753
+ }
754
+ var DRONE_ART = [
755
+ " .-=-. .-=-. ",
756
+ " ( !!! ) ( !!! ) ",
757
+ " '-=-'._ _.'-=-' ",
758
+ " '._ _.' ",
759
+ " '=$$$$$$$=.' ",
760
+ " =$$$$$$$$$$$= ",
761
+ " $$$@@@@@@@@@@$$$ ",
762
+ " $$$@@ @@$$$ ",
763
+ " $$@ ? @$$$ ",
764
+ " $$$@ '-' @$$$ ",
765
+ " $$$@@ @@$$$ ",
766
+ " $$$@@@@@@@@@@$$$ ",
767
+ " =$$$$$$$$$$$= ",
768
+ " '=$$$$$$$=.' ",
769
+ " _.' '._ ",
770
+ " .-=-.' '.-=-. ",
771
+ " ( !!! ) ( !!! ) ",
772
+ " '-=-' '-=-' "
773
+ ];
774
+ var EYE_FRAMES = ["@", "o", "."];
775
+ var DRONE_WIDTH = DRONE_ART[0].length;
776
+ var DRONE_HEIGHT = DRONE_ART.length;
777
+ var MICRO_BLADES = ["---", "\\\\\\", "|||", "///"];
778
+ function microDroneFrame(tick) {
779
+ const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
780
+ const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
781
+ return `(${blade})${eye}(${blade})`;
782
+ }
783
+ var MICRO_DRONE_FRAMES = Array.from({ length: 12 }, (_, index) => microDroneFrame(index));
784
+ function renderMicroDroneFrame(tick) {
785
+ const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
786
+ const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
787
+ return `${ink4("(")}${cyan(blade)}${ink4(")")}${bold(accent(eye))}${ink4("(")}${cyan(blade)}${ink4(")")}`;
788
+ }
789
+
716
790
  // packages/cli/src/commands/_async-ui.ts
717
- var CLACK_SPINNER_FRAMES = ["\u25D2", "\u25D0", "\u25D3", "\u25D1"];
718
791
  var DONE_SYMBOL = pc.green("\u25C7");
719
792
  var FAIL_SYMBOL = pc.red("\u25A0");
720
793
  var activeUpdate = null;
@@ -748,8 +821,8 @@ async function withSpinner(label, work, options = {}) {
748
821
  const spinner = createTtySpinner({
749
822
  label,
750
823
  output,
751
- frames: CLACK_SPINNER_FRAMES,
752
- styleFrame: (frame) => pc.magenta(frame)
824
+ frames: MICRO_DRONE_FRAMES,
825
+ styleFrame: (frame) => renderMicroDroneFrame(Math.max(0, MICRO_DRONE_FRAMES.indexOf(frame)))
753
826
  });
754
827
  const update = (next) => {
755
828
  lastLabel = next;
@@ -0,0 +1,3 @@
1
+ import { type RunnerContext } from "../runner";
2
+ import type { CommandOutcome } from "@rig/runtime/control-plane/runtime/types";
3
+ export declare function executeGithub(context: RunnerContext, args: string[]): Promise<CommandOutcome>;
@@ -332,7 +332,9 @@ ${failure.contextLine}`, 1, { hint: failure.hint });
332
332
  })() : null;
333
333
  if (!response.ok) {
334
334
  const diagnostics = diagnosticMessage(payload);
335
- const detail = diagnostics ?? (text || response.statusText);
335
+ const rawDetail = diagnostics ?? (text || response.statusText);
336
+ const detail = diagnostics ? rawDetail : rawDetail.split(`
337
+ `).map((line) => line.trim()).find((line) => line.length > 0)?.slice(0, 200) ?? response.statusText;
336
338
  const failure = await buildServerFailureContext(context.projectRoot, server);
337
339
  throw new CliError(`Rig server request failed (${response.status}): ${detail}
338
340
  ${failure.contextLine}`, 1, { hint: failure.hint });
@@ -427,8 +429,79 @@ function createTtySpinner(input) {
427
429
  };
428
430
  }
429
431
 
432
+ // packages/cli/src/app/theme.ts
433
+ var RIG_PALETTE = {
434
+ ink: "#f2f3f6",
435
+ ink2: "#aeb0ba",
436
+ ink3: "#6c6e79",
437
+ ink4: "#44464f",
438
+ accent: "#ccff4d",
439
+ accentDim: "#a9d63f",
440
+ cyan: "#56d8ff",
441
+ red: "#ff5d5d",
442
+ yellow: "#ffd24d"
443
+ };
444
+ function hexToRgb(hex) {
445
+ const value = hex.replace("#", "");
446
+ return [
447
+ Number.parseInt(value.slice(0, 2), 16),
448
+ Number.parseInt(value.slice(2, 4), 16),
449
+ Number.parseInt(value.slice(4, 6), 16)
450
+ ];
451
+ }
452
+ function fg(hex) {
453
+ const [r, g, b] = hexToRgb(hex);
454
+ return (text) => `\x1B[38;2;${r};${g};${b}m${text}\x1B[39m`;
455
+ }
456
+ var ink = fg(RIG_PALETTE.ink);
457
+ var ink2 = fg(RIG_PALETTE.ink2);
458
+ var ink3 = fg(RIG_PALETTE.ink3);
459
+ var ink4 = fg(RIG_PALETTE.ink4);
460
+ var accent = fg(RIG_PALETTE.accent);
461
+ var accentDim = fg(RIG_PALETTE.accentDim);
462
+ var cyan = fg(RIG_PALETTE.cyan);
463
+ var red = fg(RIG_PALETTE.red);
464
+ var yellow = fg(RIG_PALETTE.yellow);
465
+ function bold(text) {
466
+ return `\x1B[1m${text}\x1B[22m`;
467
+ }
468
+ var DRONE_ART = [
469
+ " .-=-. .-=-. ",
470
+ " ( !!! ) ( !!! ) ",
471
+ " '-=-'._ _.'-=-' ",
472
+ " '._ _.' ",
473
+ " '=$$$$$$$=.' ",
474
+ " =$$$$$$$$$$$= ",
475
+ " $$$@@@@@@@@@@$$$ ",
476
+ " $$$@@ @@$$$ ",
477
+ " $$@ ? @$$$ ",
478
+ " $$$@ '-' @$$$ ",
479
+ " $$$@@ @@$$$ ",
480
+ " $$$@@@@@@@@@@$$$ ",
481
+ " =$$$$$$$$$$$= ",
482
+ " '=$$$$$$$=.' ",
483
+ " _.' '._ ",
484
+ " .-=-.' '.-=-. ",
485
+ " ( !!! ) ( !!! ) ",
486
+ " '-=-' '-=-' "
487
+ ];
488
+ var EYE_FRAMES = ["@", "o", "."];
489
+ var DRONE_WIDTH = DRONE_ART[0].length;
490
+ var DRONE_HEIGHT = DRONE_ART.length;
491
+ var MICRO_BLADES = ["---", "\\\\\\", "|||", "///"];
492
+ function microDroneFrame(tick) {
493
+ const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
494
+ const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
495
+ return `(${blade})${eye}(${blade})`;
496
+ }
497
+ var MICRO_DRONE_FRAMES = Array.from({ length: 12 }, (_, index) => microDroneFrame(index));
498
+ function renderMicroDroneFrame(tick) {
499
+ const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
500
+ const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
501
+ return `${ink4("(")}${cyan(blade)}${ink4(")")}${bold(accent(eye))}${ink4("(")}${cyan(blade)}${ink4(")")}`;
502
+ }
503
+
430
504
  // packages/cli/src/commands/_async-ui.ts
431
- var CLACK_SPINNER_FRAMES = ["\u25D2", "\u25D0", "\u25D3", "\u25D1"];
432
505
  var DONE_SYMBOL = pc.green("\u25C7");
433
506
  var FAIL_SYMBOL = pc.red("\u25A0");
434
507
  var activeUpdate = null;
@@ -462,8 +535,8 @@ async function withSpinner(label, work, options = {}) {
462
535
  const spinner = createTtySpinner({
463
536
  label,
464
537
  output,
465
- frames: CLACK_SPINNER_FRAMES,
466
- styleFrame: (frame) => pc.magenta(frame)
538
+ frames: MICRO_DRONE_FRAMES,
539
+ styleFrame: (frame) => renderMicroDroneFrame(Math.max(0, MICRO_DRONE_FRAMES.indexOf(frame)))
467
540
  });
468
541
  const update = (next) => {
469
542
  lastLabel = next;
@@ -0,0 +1,30 @@
1
+ import { type RunnerContext } from "../runner";
2
+ import type { CommandOutcome } from "@rig/runtime/control-plane/runtime/types";
3
+ export type InboxKind = "approvals" | "inputs";
4
+ export type InboxRecord = {
5
+ runId?: string;
6
+ taskId?: string | null;
7
+ requestId?: string | null;
8
+ status?: string | null;
9
+ record?: Record<string, unknown>;
10
+ };
11
+ /** Exported for the board's inbox view — same records `rig inbox` renders. */
12
+ export declare function listInboxRecords(context: Pick<RunnerContext, "projectRoot">, kind: InboxKind, filters: {
13
+ run?: string;
14
+ task?: string;
15
+ pendingOnly?: boolean;
16
+ }): Promise<InboxRecord[]>;
17
+ /**
18
+ * Pending-gate counts for proactive surfacing. Returns null when the server
19
+ * is unreachable — footer callers must never break the primary command.
20
+ */
21
+ export declare function readPendingInboxCounts(context: Pick<RunnerContext, "projectRoot">): Promise<{
22
+ approvals: number;
23
+ inputs: number;
24
+ } | null>;
25
+ /**
26
+ * One-line warning under task/run command output when human gates are
27
+ * waiting. Silent when there is nothing pending or the server is down.
28
+ */
29
+ export declare function printPendingInboxFooter(context: RunnerContext): Promise<void>;
30
+ export declare function executeInbox(context: RunnerContext, args: string[]): Promise<CommandOutcome>;
@@ -41,11 +41,10 @@ Usage: ${usage}`);
41
41
  }
42
42
  }
43
43
 
44
- // packages/cli/src/commands/_cli-format.ts
45
- import { log, note } from "@clack/prompts";
46
- import pc from "picocolors";
44
+ // packages/cli/src/app/drone-ui.ts
45
+ import { ProcessTerminal, TUI, Text, Input, SelectList, matchesKey } from "@earendil-works/pi-tui";
47
46
 
48
- // packages/cli/src/commands/_tui-theme.ts
47
+ // packages/cli/src/app/theme.ts
49
48
  var RIG_PALETTE = {
50
49
  ink: "#f2f3f6",
51
50
  ink2: "#aeb0ba",
@@ -78,6 +77,9 @@ var accentDim = fg(RIG_PALETTE.accentDim);
78
77
  var cyan = fg(RIG_PALETTE.cyan);
79
78
  var red = fg(RIG_PALETTE.red);
80
79
  var yellow = fg(RIG_PALETTE.yellow);
80
+ function bold(text) {
81
+ return `\x1B[1m${text}\x1B[22m`;
82
+ }
81
83
  var DRONE_ART = [
82
84
  " .-=-. .-=-. ",
83
85
  " ( !!! ) ( !!! ) ",
@@ -98,10 +100,95 @@ var DRONE_ART = [
98
100
  " ( !!! ) ( !!! ) ",
99
101
  " '-=-' '-=-' "
100
102
  ];
103
+ var EYE_FRAMES = ["@", "o", "."];
101
104
  var DRONE_WIDTH = DRONE_ART[0].length;
102
105
  var DRONE_HEIGHT = DRONE_ART.length;
106
+ var MICRO_BLADES = ["---", "\\\\\\", "|||", "///"];
107
+ function microDroneFrame(tick) {
108
+ const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
109
+ const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
110
+ return `(${blade})${eye}(${blade})`;
111
+ }
112
+ var MICRO_DRONE_FRAMES = Array.from({ length: 12 }, (_, index) => microDroneFrame(index));
113
+ function renderMicroDroneFrame(tick) {
114
+ const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
115
+ const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
116
+ return `${ink4("(")}${cyan(blade)}${ink4(")")}${bold(accent(eye))}${ink4("(")}${cyan(blade)}${ink4(")")}`;
117
+ }
118
+
119
+ // packages/cli/src/commands/_spinner.ts
120
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
121
+ function createTtySpinner(input) {
122
+ const output = input.output ?? process.stdout;
123
+ const isTty = output.isTTY === true;
124
+ const frames = input.frames && input.frames.length > 0 ? input.frames : SPINNER_FRAMES;
125
+ let label = input.label;
126
+ let frame = 0;
127
+ let paused = false;
128
+ let stopped = false;
129
+ let lastPrintedLabel = "";
130
+ const render = () => {
131
+ if (stopped || paused)
132
+ return;
133
+ if (!isTty) {
134
+ if (label !== lastPrintedLabel) {
135
+ output.write(`${label}
136
+ `);
137
+ lastPrintedLabel = label;
138
+ }
139
+ return;
140
+ }
141
+ frame = (frame + 1) % frames.length;
142
+ const glyph = frames[frame] ?? frames[0] ?? "";
143
+ output.write(`\r\x1B[2K${input.styleFrame ? input.styleFrame(glyph) : glyph} ${label}`);
144
+ };
145
+ const clearLine = () => {
146
+ if (isTty)
147
+ output.write("\r\x1B[2K");
148
+ };
149
+ render();
150
+ const timer = isTty ? setInterval(render, input.intervalMs ?? 120) : null;
151
+ return {
152
+ setLabel(next) {
153
+ label = next;
154
+ render();
155
+ },
156
+ pause() {
157
+ paused = true;
158
+ clearLine();
159
+ },
160
+ resume() {
161
+ if (stopped)
162
+ return;
163
+ paused = false;
164
+ render();
165
+ },
166
+ stop(finalLine) {
167
+ if (stopped)
168
+ return;
169
+ stopped = true;
170
+ if (timer)
171
+ clearInterval(timer);
172
+ clearLine();
173
+ if (finalLine)
174
+ output.write(`${finalLine}
175
+ `);
176
+ }
177
+ };
178
+ }
179
+
180
+ // packages/cli/src/app/drone-ui.ts
181
+ function droneNote(message, title) {
182
+ if (title)
183
+ console.log(` ${accentDim("\u25C7")} ${bold(ink2(title))}`);
184
+ for (const line of message.split(`
185
+ `)) {
186
+ console.log(` ${ink4("\u2502")} ${line}`);
187
+ }
188
+ }
103
189
 
104
190
  // packages/cli/src/commands/_cli-format.ts
191
+ import pc from "picocolors";
105
192
  var themeDim = (value) => ink3(value);
106
193
  var themeFaint = (value) => ink4(value);
107
194
  function stringField(record, key, fallback = "") {
@@ -139,10 +226,7 @@ function printFormattedOutput(message, options = {}) {
139
226
  console.log(message);
140
227
  return;
141
228
  }
142
- if (options.title)
143
- note(message, options.title);
144
- else
145
- log.message(message);
229
+ droneNote(message, options.title);
146
230
  }
147
231
  function formatStatusPill(status) {
148
232
  const label = status || "unknown";
@@ -477,7 +561,9 @@ ${failure.contextLine}`, 1, { hint: failure.hint });
477
561
  })() : null;
478
562
  if (!response.ok) {
479
563
  const diagnostics = diagnosticMessage(payload);
480
- const detail = diagnostics ?? (text || response.statusText);
564
+ const rawDetail = diagnostics ?? (text || response.statusText);
565
+ const detail = diagnostics ? rawDetail : rawDetail.split(`
566
+ `).map((line) => line.trim()).find((line) => line.length > 0)?.slice(0, 200) ?? response.statusText;
481
567
  const failure = await buildServerFailureContext(context.projectRoot, server);
482
568
  throw new CliError(`Rig server request failed (${response.status}): ${detail}
483
569
  ${failure.contextLine}`, 1, { hint: failure.hint });
@@ -498,70 +584,6 @@ var RESUMABLE_RUN_STATUSES = new Set([
498
584
 
499
585
  // packages/cli/src/commands/_async-ui.ts
500
586
  import pc2 from "picocolors";
501
-
502
- // packages/cli/src/commands/_spinner.ts
503
- var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
504
- function createTtySpinner(input) {
505
- const output = input.output ?? process.stdout;
506
- const isTty = output.isTTY === true;
507
- const frames = input.frames && input.frames.length > 0 ? input.frames : SPINNER_FRAMES;
508
- let label = input.label;
509
- let frame = 0;
510
- let paused = false;
511
- let stopped = false;
512
- let lastPrintedLabel = "";
513
- const render = () => {
514
- if (stopped || paused)
515
- return;
516
- if (!isTty) {
517
- if (label !== lastPrintedLabel) {
518
- output.write(`${label}
519
- `);
520
- lastPrintedLabel = label;
521
- }
522
- return;
523
- }
524
- frame = (frame + 1) % frames.length;
525
- const glyph = frames[frame] ?? frames[0] ?? "";
526
- output.write(`\r\x1B[2K${input.styleFrame ? input.styleFrame(glyph) : glyph} ${label}`);
527
- };
528
- const clearLine = () => {
529
- if (isTty)
530
- output.write("\r\x1B[2K");
531
- };
532
- render();
533
- const timer = isTty ? setInterval(render, input.intervalMs ?? 120) : null;
534
- return {
535
- setLabel(next) {
536
- label = next;
537
- render();
538
- },
539
- pause() {
540
- paused = true;
541
- clearLine();
542
- },
543
- resume() {
544
- if (stopped)
545
- return;
546
- paused = false;
547
- render();
548
- },
549
- stop(finalLine) {
550
- if (stopped)
551
- return;
552
- stopped = true;
553
- if (timer)
554
- clearInterval(timer);
555
- clearLine();
556
- if (finalLine)
557
- output.write(`${finalLine}
558
- `);
559
- }
560
- };
561
- }
562
-
563
- // packages/cli/src/commands/_async-ui.ts
564
- var CLACK_SPINNER_FRAMES = ["\u25D2", "\u25D0", "\u25D3", "\u25D1"];
565
587
  var DONE_SYMBOL = pc2.green("\u25C7");
566
588
  var FAIL_SYMBOL = pc2.red("\u25A0");
567
589
  var activeUpdate = null;
@@ -595,8 +617,8 @@ async function withSpinner(label, work, options = {}) {
595
617
  const spinner = createTtySpinner({
596
618
  label,
597
619
  output,
598
- frames: CLACK_SPINNER_FRAMES,
599
- styleFrame: (frame) => pc2.magenta(frame)
620
+ frames: MICRO_DRONE_FRAMES,
621
+ styleFrame: (frame) => renderMicroDroneFrame(Math.max(0, MICRO_DRONE_FRAMES.indexOf(frame)))
600
622
  });
601
623
  const update = (next) => {
602
624
  lastLabel = next;
@@ -744,8 +766,8 @@ async function executeInbox(context, args) {
744
766
  pending = request.rest;
745
767
  const decision = takeOption(pending, "--decision");
746
768
  pending = decision.rest;
747
- const note2 = takeOption(pending, "--note");
748
- pending = note2.rest;
769
+ const note = takeOption(pending, "--note");
770
+ pending = note.rest;
749
771
  requireNoExtraArgs(pending, "rig inbox approve --run <id> --request <id> --decision approve|reject [--note <text>]");
750
772
  if (!run.value || !request.value || !decision.value) {
751
773
  throw new CliError("approve requires --run, --request, and --decision. List pending requests with `rig inbox approvals`.");
@@ -760,7 +782,7 @@ async function executeInbox(context, args) {
760
782
  runId: run.value,
761
783
  requestId: request.value,
762
784
  decision: decision.value,
763
- note: note2.value ?? null
785
+ note: note.value ?? null
764
786
  })
765
787
  }), { outputMode: context.outputMode });
766
788
  return { ok: true, group: "inbox", command, details: { result } };
@@ -823,5 +845,6 @@ async function executeInbox(context, args) {
823
845
  export {
824
846
  readPendingInboxCounts,
825
847
  printPendingInboxFooter,
848
+ listInboxRecords,
826
849
  executeInbox
827
850
  };
@@ -0,0 +1,74 @@
1
+ import { type RunnerContext } from "../runner";
2
+ import { buildRigInitConfigSource, type RigInitConfigInput } from "@rig/core";
3
+ import type { CommandOutcome } from "@rig/runtime/control-plane/runtime/types";
4
+ export { buildRigInitConfigSource };
5
+ export type { RigInitConfigInput };
6
+ type InitAuthMethod = "gh" | "token" | "device" | "skip";
7
+ type RemoteCheckoutStrategy = {
8
+ kind: "managed-clone";
9
+ } | {
10
+ kind: "current-ref";
11
+ ref?: string;
12
+ } | {
13
+ kind: "uploaded-snapshot";
14
+ } | {
15
+ kind: "existing-path";
16
+ path: string;
17
+ };
18
+ type InitControlPlaneOptions = {
19
+ demo?: boolean;
20
+ server?: "local" | "remote";
21
+ remoteUrl?: string;
22
+ connectionAlias?: string;
23
+ repoSlug?: string;
24
+ githubToken?: string;
25
+ githubAuthMethod?: InitAuthMethod;
26
+ githubProject?: "off" | string;
27
+ githubProjectStatusField?: string;
28
+ githubProjectStatuses?: Record<string, string>;
29
+ remoteCheckout?: RemoteCheckoutStrategy;
30
+ yes?: boolean;
31
+ repair?: boolean;
32
+ privateStateOnly?: boolean;
33
+ };
34
+ type InitPromptAdapter = {
35
+ intro?: (message: string) => void;
36
+ outro?: (message: string) => void;
37
+ cancel?: (message: string) => void;
38
+ isCancel: (value: unknown) => boolean;
39
+ text: (options: {
40
+ message: string;
41
+ placeholder?: string;
42
+ initialValue?: string;
43
+ defaultValue?: string;
44
+ }) => Promise<unknown>;
45
+ select: (options: {
46
+ message: string;
47
+ options: Array<{
48
+ value: string;
49
+ label: string;
50
+ hint?: string;
51
+ }>;
52
+ initialValue?: string;
53
+ }) => Promise<unknown>;
54
+ confirm?: (options: {
55
+ message: string;
56
+ initialValue?: boolean;
57
+ }) => Promise<unknown>;
58
+ };
59
+ export declare const DEMO_TASKS_RELATIVE_DIR = ".rig/demo-tasks";
60
+ /**
61
+ * The three sample tasks `rig init --demo` seeds. Shapes match what the
62
+ * standard plugin's files task source reads: one JSON object per file with
63
+ * id/title/body/status/labels (see packages/standard-plugin/src/files-source.ts).
64
+ */
65
+ export declare const DEMO_TASKS: ReadonlyArray<Record<string, unknown>>;
66
+ /**
67
+ * `rig init --demo` — zero-GitHub, offline demo project: files task source
68
+ * pointing at .rig/demo-tasks/ with three seeded sample tasks, so an
69
+ * operator can see the full run lifecycle in minutes. Non-interactive and
70
+ * idempotent: an existing rig.config is left untouched unless --repair.
71
+ */
72
+ export declare function runDemoInit(context: RunnerContext, options: InitControlPlaneOptions): CommandOutcome;
73
+ export declare function runInteractiveControlPlaneInit(context: RunnerContext, prompts: InitPromptAdapter): Promise<CommandOutcome>;
74
+ export declare function executeInit(context: RunnerContext, args: string[]): Promise<CommandOutcome>;