@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
@@ -0,0 +1,44 @@
1
+ export type RigConnection = {
2
+ kind: "local";
3
+ mode: "auto";
4
+ } | {
5
+ kind: "remote";
6
+ baseUrl: string;
7
+ };
8
+ export type GlobalConnectionState = {
9
+ connections: Record<string, RigConnection>;
10
+ };
11
+ export type RepoConnectionState = {
12
+ selected: string;
13
+ project?: string;
14
+ linkedAt?: string;
15
+ /**
16
+ * The server-host project root this repo scopes to (multi-root serving).
17
+ * Sent as the x-rig-project-root header on every remote request.
18
+ */
19
+ serverProjectRoot?: string;
20
+ };
21
+ export declare function resolveGlobalConnectionsPath(env?: NodeJS.ProcessEnv): string;
22
+ export declare function resolveRepoConnectionPath(projectRoot: string): string;
23
+ export declare function readGlobalConnections(options?: {
24
+ env?: NodeJS.ProcessEnv;
25
+ }): GlobalConnectionState;
26
+ export declare function writeGlobalConnections(state: GlobalConnectionState, options?: {
27
+ env?: NodeJS.ProcessEnv;
28
+ }): void;
29
+ export declare function upsertGlobalConnection(alias: string, connection: RigConnection, options?: {
30
+ env?: NodeJS.ProcessEnv;
31
+ }): GlobalConnectionState;
32
+ export declare function readRepoConnection(projectRoot: string): RepoConnectionState | null;
33
+ export declare function writeRepoConnection(projectRoot: string, state: RepoConnectionState): void;
34
+ export declare function resolveSelectedConnection(projectRoot: string, options?: {
35
+ env?: NodeJS.ProcessEnv;
36
+ }): {
37
+ alias: string;
38
+ connection: RigConnection;
39
+ serverProjectRoot?: string;
40
+ } | null;
41
+ /** Persist the server-host project root this repo scopes to (multi-root serving). */
42
+ export declare function writeRepoServerProjectRoot(projectRoot: string, serverProjectRoot: string): void;
43
+ /** Whether this repo's selected connection targets a remote Rig server. */
44
+ export declare function isRemoteConnectionSelected(projectRoot: string): boolean;
@@ -0,0 +1,52 @@
1
+ type DoctorConfig = {
2
+ readonly project?: Record<string, unknown>;
3
+ readonly taskSource?: {
4
+ readonly kind?: string;
5
+ readonly owner?: string;
6
+ readonly repo?: string;
7
+ };
8
+ readonly github?: {
9
+ readonly projects?: {
10
+ readonly enabled?: boolean;
11
+ readonly projectId?: string;
12
+ readonly statusFieldId?: string;
13
+ };
14
+ };
15
+ readonly pr?: {
16
+ readonly mode?: string;
17
+ };
18
+ readonly merge?: {
19
+ readonly mode?: string;
20
+ readonly method?: string;
21
+ };
22
+ };
23
+ import { type PiInstallCheck } from "./_pi-install";
24
+ export type DoctorStatus = "pass" | "warn" | "fail";
25
+ export type RigDoctorCheck = {
26
+ readonly id: string;
27
+ readonly label: string;
28
+ readonly status: DoctorStatus;
29
+ readonly detail?: string;
30
+ readonly remediation?: string;
31
+ };
32
+ export type RigDoctorServer = {
33
+ readonly baseUrl: string;
34
+ readonly authToken: string | null;
35
+ readonly connectionKind: "local" | "remote";
36
+ };
37
+ export type RunRigDoctorChecksOptions = {
38
+ readonly projectRoot: string;
39
+ readonly resolveServer?: (projectRoot: string) => Promise<RigDoctorServer>;
40
+ readonly requestJson?: (pathname: string, init?: RequestInit) => Promise<unknown>;
41
+ readonly piChecks?: () => Promise<readonly PiInstallCheck[]>;
42
+ readonly which?: (binary: string) => string | null;
43
+ readonly bunVersion?: string;
44
+ readonly loadConfig?: (projectRoot: string) => Promise<DoctorConfig | null>;
45
+ /** Per-check status narration ("Checking GitHub auth…") for wait spinners. */
46
+ readonly onProgress?: (label: string) => void;
47
+ };
48
+ export declare function runRigDoctorChecks(options: RunRigDoctorChecksOptions): Promise<RigDoctorCheck[]>;
49
+ export declare function formatDoctorChecks(checks: readonly RigDoctorCheck[]): string;
50
+ export declare function countDoctorFailures(checks: readonly RigDoctorCheck[]): number;
51
+ export declare function throwIfDoctorFailed(checks: readonly RigDoctorCheck[]): void;
52
+ export {};
@@ -311,7 +311,9 @@ ${failure.contextLine}`, 1, { hint: failure.hint });
311
311
  })() : null;
312
312
  if (!response.ok) {
313
313
  const diagnostics = diagnosticMessage(payload);
314
- const detail = diagnostics ?? (text || response.statusText);
314
+ const rawDetail = diagnostics ?? (text || response.statusText);
315
+ const detail = diagnostics ? rawDetail : rawDetail.split(`
316
+ `).map((line) => line.trim()).find((line) => line.length > 0)?.slice(0, 200) ?? response.statusText;
315
317
  const failure = await buildServerFailureContext(context.projectRoot, server);
316
318
  throw new CliError(`Rig server request failed (${response.status}): ${detail}
317
319
  ${failure.contextLine}`, 1, { hint: failure.hint });
@@ -0,0 +1,51 @@
1
+ export type HelpCommand = {
2
+ command: string;
3
+ description: string;
4
+ primary?: boolean;
5
+ };
6
+ export type HelpGroup = {
7
+ name: string;
8
+ summary: string;
9
+ usage: string[];
10
+ commands: HelpCommand[];
11
+ examples?: string[];
12
+ next?: string[];
13
+ advanced?: string[];
14
+ };
15
+ export type TopLevelSection = {
16
+ title: string;
17
+ subtitle: string;
18
+ commands: HelpCommand[];
19
+ };
20
+ /** Catalog DATA for the app's help view — the view builds its own layout
21
+ * from these; the render* functions below remain for plain/script output. */
22
+ export declare function helpCatalog(): {
23
+ sections: readonly TopLevelSection[];
24
+ groups: readonly HelpGroup[];
25
+ };
26
+ /**
27
+ * Night City boot screen. Rendered only on interactive TTY launches — plain
28
+ * mode and --json never see it.
29
+ */
30
+ export declare function renderRigBanner(version?: string): string;
31
+ export declare function renderTopLevelHelp(): string;
32
+ export declare function renderAdvancedHelp(): string;
33
+ export declare function renderGroupHelp(groupName: string): string | null;
34
+ export declare function listHelpGroups(): string[];
35
+ /**
36
+ * Fuzzy-match a bare word against known group subcommand names so the
37
+ * unknown-command error can suggest the canonical `rig <group> <cmd>`
38
+ * spelling. Primary groups win ties (ALL_GROUPS is primary-first).
39
+ */
40
+ export declare function suggestGroupCommandForWord(word: string): string | null;
41
+ export type TopLevelLaunchState = {
42
+ /** True when the cwd resolves to an initialized Rig project. */
43
+ projectInitialized?: boolean;
44
+ /** Short description of the selected server connection, if known. */
45
+ selectedServer?: string | null;
46
+ /** CLI version for the banner footer. */
47
+ version?: string;
48
+ };
49
+ export declare function printTopLevelHelp(state?: TopLevelLaunchState): void;
50
+ export declare function printAdvancedHelp(): void;
51
+ export declare function printGroupHelpDocument(groupName: string): void;
@@ -1,7 +1,9 @@
1
1
  // @bun
2
2
  // packages/cli/src/commands/_help-catalog.ts
3
- import { intro, log, note, outro } from "@clack/prompts";
4
3
  import pc from "picocolors";
4
+ function helpCatalog() {
5
+ return { sections: TOP_LEVEL_SECTIONS, groups: ALL_GROUPS };
6
+ }
5
7
  var TOP_LEVEL_SECTIONS = [
6
8
  {
7
9
  title: "Pi console",
@@ -92,6 +94,7 @@ var PRIMARY_GROUPS = [
92
94
  { command: "next [filters]", description: "Render the next matching task as a selected-task card.", primary: true },
93
95
  { command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
94
96
  { command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
97
+ { command: "ready", description: "List task IDs that are runnable now." },
95
98
  { command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
96
99
  { command: "details --task <id>", description: "Show full task info from the configured source." },
97
100
  { command: "reopen [--task <id> | --all] [--reason <text>]", description: "Reopen closed task(s) in the configured source." },
@@ -416,79 +419,14 @@ function suggestGroupCommandForWord(word) {
416
419
  }
417
420
  return null;
418
421
  }
419
- function shouldUseClackOutput() {
420
- return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
421
- }
422
422
  function printTopLevelHelp(state = {}) {
423
- if (!shouldUseClackOutput()) {
424
- console.log(renderTopLevelHelp());
425
- return;
426
- }
427
- console.log(renderRigBanner(state.version));
428
- console.log("");
429
- if (state.projectInitialized === false) {
430
- intro("no rig project in this directory");
431
- note([
432
- commandLine("rig init", "Set this repo up: config, GitHub auth, task source, server, Pi."),
433
- commandLine("rig init --yes", "Same, non-interactive, sensible defaults."),
434
- commandLine("rig doctor", "Already initialized somewhere else? Check the wiring.")
435
- ].join(`
436
- `), "Get started");
437
- outro("After init: rig task run --next puts an agent on your next task.");
438
- return;
439
- }
440
- intro(state.selectedServer ? `server: ${state.selectedServer}` : "rig");
441
- for (const section of TOP_LEVEL_SECTIONS) {
442
- note(renderCommandBlock(section.commands), `${section.title} \u2014 ${section.subtitle}`);
443
- }
444
- log.info("More: rig help --advanced \xB7 rig <group> --help \xB7 rig --version");
445
- note([
446
- commandLine("--project <path>", "Use a project root instead of auto-discovery."),
447
- commandLine("--json", "Emit structured output for scripts/agents."),
448
- commandLine("--dry-run", "Print the command plan without mutating state.")
449
- ].join(`
450
- `), "Global options");
451
- outro("init \u2192 task run \u2192 attach (Pi console: watch + steer live) \u2192 inbox \u2192 merged.");
423
+ console.log(renderTopLevelHelp());
452
424
  }
453
425
  function printAdvancedHelp() {
454
- if (!shouldUseClackOutput()) {
455
- console.log(renderAdvancedHelp());
456
- return;
457
- }
458
- intro("rig advanced");
459
- note(ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)).join(`
460
- `), "Advanced commands");
461
- note(ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)).join(`
462
- `), "Advanced groups");
463
- outro("Primary daily flow: rig server \xB7 rig task \xB7 rig run \xB7 rig inbox.");
426
+ console.log(renderAdvancedHelp());
464
427
  }
465
428
  function printGroupHelpDocument(groupName) {
466
- const rendered = renderGroupHelp(groupName) ?? renderTopLevelHelp();
467
- if (!shouldUseClackOutput()) {
468
- console.log(rendered);
469
- return;
470
- }
471
- const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
472
- if (!group) {
473
- printTopLevelHelp();
474
- return;
475
- }
476
- intro(`rig ${group.name}`);
477
- note(group.summary, "Purpose");
478
- note(group.usage.join(`
479
- `), "Usage");
480
- note(group.commands.map((entry) => commandLine(entry.command, entry.description)).join(`
481
- `), "Commands");
482
- if (group.examples?.length)
483
- note(group.examples.map((line) => `$ ${line}`).join(`
484
- `), "Examples");
485
- if (group.next?.length)
486
- note(group.next.map((line) => `\u203A ${line}`).join(`
487
- `), "Next steps");
488
- if (group.advanced?.length)
489
- log.info(group.advanced.join(`
490
- `));
491
- outro("Run with --json when scripts need structured output.");
429
+ console.log(renderGroupHelp(groupName) ?? renderTopLevelHelp());
492
430
  }
493
431
  export {
494
432
  suggestGroupCommandForWord,
@@ -499,5 +437,6 @@ export {
499
437
  printTopLevelHelp,
500
438
  printGroupHelpDocument,
501
439
  printAdvancedHelp,
502
- listHelpGroups
440
+ listHelpGroups,
441
+ helpCatalog
503
442
  };
@@ -0,0 +1,11 @@
1
+ import { type RigCliOutputEnvelope } from "@rig/contracts";
2
+ /**
3
+ * Build the versioned `{ v: 1, command, data }` envelope for a command
4
+ * outcome, or null when the command has no output schema (legacy payload)
5
+ * or the details fail validation (warned on stderr, legacy payload).
6
+ */
7
+ export declare function buildCliJsonEnvelope(outcome: unknown, options?: {
8
+ warn?: (message: string) => void;
9
+ }): RigCliOutputEnvelope | null;
10
+ /** Commands with a versioned --json envelope (for help/docs/tests). */
11
+ export declare function listSchematizedCliCommands(): string[];
@@ -0,0 +1,34 @@
1
+ import type { WorkspaceTaskRecord } from "./_server-client";
2
+ export type OperatorSnapshot = {
3
+ readonly run: Record<string, unknown>;
4
+ readonly logs?: readonly Record<string, unknown>[];
5
+ readonly timeline?: readonly Record<string, unknown>[];
6
+ };
7
+ export declare function renderOperatorSnapshot(snapshot: OperatorSnapshot): string;
8
+ export type PiRunStreamRenderer = {
9
+ renderSnapshot(snapshot: OperatorSnapshot): void;
10
+ renderTimeline(entries: readonly Record<string, unknown>[]): void;
11
+ renderLogs(entries: readonly Record<string, unknown>[]): void;
12
+ };
13
+ export declare function createPiRunStreamRenderer(output?: Pick<NodeJS.WriteStream, "write">): PiRunStreamRenderer;
14
+ export type OperatorSurface = PiRunStreamRenderer & {
15
+ readonly mode: "text" | "pi-compatible-text";
16
+ info(message: string): void;
17
+ error(message: string): void;
18
+ attachCommandInput(handler: (line: string) => void | Promise<void>): {
19
+ close(): void;
20
+ } | null;
21
+ };
22
+ export declare function createOperatorSurface(options?: {
23
+ readonly input?: NodeJS.ReadStream;
24
+ readonly output?: Pick<NodeJS.WriteStream, "write"> & {
25
+ readonly isTTY?: boolean;
26
+ };
27
+ readonly errorOutput?: Pick<NodeJS.WriteStream, "write">;
28
+ readonly interactive?: boolean;
29
+ }): OperatorSurface;
30
+ export type TaskPickerRenderer = {
31
+ readonly writeLine: (line: string) => void;
32
+ };
33
+ export declare function renderTaskPickerRows(tasks: readonly WorkspaceTaskRecord[]): string[];
34
+ export declare function promptForTaskSelection(question: string): Promise<string>;
@@ -0,0 +1,30 @@
1
+ import { steerRunViaServer, stopRunViaServer } from "./_server-client";
2
+ import { createPiRunStreamRenderer, renderOperatorSnapshot } from "./_operator-surface";
3
+ import type { RunnerContext } from "../runner";
4
+ export { createPiRunStreamRenderer, renderOperatorSnapshot };
5
+ export declare function applyOperatorCommand(context: Pick<RunnerContext, "projectRoot">, input: {
6
+ readonly runId: string;
7
+ readonly line: string;
8
+ }, deps?: {
9
+ readonly steer?: typeof steerRunViaServer;
10
+ readonly stop?: typeof stopRunViaServer;
11
+ }): Promise<{
12
+ action: "continue" | "detach" | "stopped" | "ignored";
13
+ message?: string;
14
+ }>;
15
+ export declare function attachRunOperatorView(context: Pick<RunnerContext, "projectRoot" | "outputMode">, input: {
16
+ readonly runId: string;
17
+ readonly message?: string | null;
18
+ readonly once?: boolean;
19
+ readonly follow?: boolean;
20
+ readonly pollMs?: number;
21
+ readonly interactive?: boolean;
22
+ }): Promise<{
23
+ run: Record<string, unknown>;
24
+ logs: Record<string, unknown>[];
25
+ timeline: Record<string, unknown>[];
26
+ timelineCursor: string | null;
27
+ steered: boolean;
28
+ rendered: string;
29
+ detached?: boolean;
30
+ }>;
@@ -311,7 +311,9 @@ ${failure.contextLine}`, 1, { hint: failure.hint });
311
311
  })() : null;
312
312
  if (!response.ok) {
313
313
  const diagnostics = diagnosticMessage(payload);
314
- const detail = diagnostics ?? (text || response.statusText);
314
+ const rawDetail = diagnostics ?? (text || response.statusText);
315
+ const detail = diagnostics ? rawDetail : rawDetail.split(`
316
+ `).map((line) => line.trim()).find((line) => line.length > 0)?.slice(0, 200) ?? response.statusText;
315
317
  const failure = await buildServerFailureContext(context.projectRoot, server);
316
318
  throw new CliError(`Rig server request failed (${response.status}): ${detail}
317
319
  ${failure.contextLine}`, 1, { hint: failure.hint });
@@ -569,8 +571,8 @@ function createOperatorSurface(options = {}) {
569
571
  }
570
572
 
571
573
  // packages/cli/src/commands/_pi-frontend.ts
572
- import { mkdtempSync, rmSync, writeFileSync as writeFileSync2 } from "fs";
573
- import { tmpdir } from "os";
574
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, mkdtempSync, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync2 } from "fs";
575
+ import { homedir as homedir2, tmpdir } from "os";
574
576
  import { join } from "path";
575
577
  import { main as runPiMain } from "@earendil-works/pi-coding-agent";
576
578
  import createPiRigExtension from "@rig/pi-rig";
@@ -639,8 +641,79 @@ function createTtySpinner(input) {
639
641
  };
640
642
  }
641
643
 
644
+ // packages/cli/src/app/theme.ts
645
+ var RIG_PALETTE = {
646
+ ink: "#f2f3f6",
647
+ ink2: "#aeb0ba",
648
+ ink3: "#6c6e79",
649
+ ink4: "#44464f",
650
+ accent: "#ccff4d",
651
+ accentDim: "#a9d63f",
652
+ cyan: "#56d8ff",
653
+ red: "#ff5d5d",
654
+ yellow: "#ffd24d"
655
+ };
656
+ function hexToRgb(hex) {
657
+ const value = hex.replace("#", "");
658
+ return [
659
+ Number.parseInt(value.slice(0, 2), 16),
660
+ Number.parseInt(value.slice(2, 4), 16),
661
+ Number.parseInt(value.slice(4, 6), 16)
662
+ ];
663
+ }
664
+ function fg(hex) {
665
+ const [r, g, b] = hexToRgb(hex);
666
+ return (text) => `\x1B[38;2;${r};${g};${b}m${text}\x1B[39m`;
667
+ }
668
+ var ink = fg(RIG_PALETTE.ink);
669
+ var ink2 = fg(RIG_PALETTE.ink2);
670
+ var ink3 = fg(RIG_PALETTE.ink3);
671
+ var ink4 = fg(RIG_PALETTE.ink4);
672
+ var accent = fg(RIG_PALETTE.accent);
673
+ var accentDim = fg(RIG_PALETTE.accentDim);
674
+ var cyan = fg(RIG_PALETTE.cyan);
675
+ var red = fg(RIG_PALETTE.red);
676
+ var yellow = fg(RIG_PALETTE.yellow);
677
+ function bold(text) {
678
+ return `\x1B[1m${text}\x1B[22m`;
679
+ }
680
+ var DRONE_ART = [
681
+ " .-=-. .-=-. ",
682
+ " ( !!! ) ( !!! ) ",
683
+ " '-=-'._ _.'-=-' ",
684
+ " '._ _.' ",
685
+ " '=$$$$$$$=.' ",
686
+ " =$$$$$$$$$$$= ",
687
+ " $$$@@@@@@@@@@$$$ ",
688
+ " $$$@@ @@$$$ ",
689
+ " $$@ ? @$$$ ",
690
+ " $$$@ '-' @$$$ ",
691
+ " $$$@@ @@$$$ ",
692
+ " $$$@@@@@@@@@@$$$ ",
693
+ " =$$$$$$$$$$$= ",
694
+ " '=$$$$$$$=.' ",
695
+ " _.' '._ ",
696
+ " .-=-.' '.-=-. ",
697
+ " ( !!! ) ( !!! ) ",
698
+ " '-=-' '-=-' "
699
+ ];
700
+ var EYE_FRAMES = ["@", "o", "."];
701
+ var DRONE_WIDTH = DRONE_ART[0].length;
702
+ var DRONE_HEIGHT = DRONE_ART.length;
703
+ var MICRO_BLADES = ["---", "\\\\\\", "|||", "///"];
704
+ function microDroneFrame(tick) {
705
+ const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
706
+ const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
707
+ return `(${blade})${eye}(${blade})`;
708
+ }
709
+ var MICRO_DRONE_FRAMES = Array.from({ length: 12 }, (_, index) => microDroneFrame(index));
710
+ function renderMicroDroneFrame(tick) {
711
+ const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
712
+ const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
713
+ return `${ink4("(")}${cyan(blade)}${ink4(")")}${bold(accent(eye))}${ink4("(")}${cyan(blade)}${ink4(")")}`;
714
+ }
715
+
642
716
  // packages/cli/src/commands/_async-ui.ts
643
- var CLACK_SPINNER_FRAMES = ["\u25D2", "\u25D0", "\u25D3", "\u25D1"];
644
717
  var DONE_SYMBOL = pc.green("\u25C7");
645
718
  var FAIL_SYMBOL = pc.red("\u25A0");
646
719
  var activeUpdate = null;
@@ -674,8 +747,8 @@ async function withSpinner(label, work, options = {}) {
674
747
  const spinner = createTtySpinner({
675
748
  label,
676
749
  output,
677
- frames: CLACK_SPINNER_FRAMES,
678
- styleFrame: (frame) => pc.magenta(frame)
750
+ frames: MICRO_DRONE_FRAMES,
751
+ styleFrame: (frame) => renderMicroDroneFrame(Math.max(0, MICRO_DRONE_FRAMES.indexOf(frame)))
679
752
  });
680
753
  const update = (next) => {
681
754
  lastLabel = next;
@@ -716,6 +789,7 @@ function buildOperatorPiEnv(input) {
716
789
  return {
717
790
  PI_CODING_AGENT_SESSION_DIR: input.sessionDir,
718
791
  PI_SKIP_VERSION_CHECK: "1",
792
+ PI_HIDDEN_COMMANDS: "import,fork,clone,tree,new,resume,trust",
719
793
  RIG_PI_OPERATOR_SESSION: "1",
720
794
  RIG_RUN_ID: input.runId,
721
795
  RIG_SERVER_URL: input.serverUrl,
@@ -725,6 +799,10 @@ function buildOperatorPiEnv(input) {
725
799
  }
726
800
  async function prepareOperatorConsole(context, runId, tempSessionDir) {
727
801
  const server = await ensureServerForCli(context.projectRoot);
802
+ const localCwd = join(homedir2(), ".rig", "drones", runId.slice(0, 8));
803
+ mkdirSync2(localCwd, { recursive: true });
804
+ trustDroneCwd(localCwd);
805
+ installRigPiTheme();
728
806
  let sessionFileArg = [];
729
807
  try {
730
808
  const payload = await requestServerJson(context, `/api/runs/${encodeURIComponent(runId)}/session-file`);
@@ -738,7 +816,7 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
738
816
  try {
739
817
  const header = JSON.parse(line);
740
818
  if (header.type === "session" && typeof header.cwd === "string") {
741
- return JSON.stringify({ ...header, cwd: process.cwd() });
819
+ return JSON.stringify({ ...header, cwd: localCwd });
742
820
  }
743
821
  } catch {}
744
822
  return line;
@@ -750,6 +828,105 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
750
828
  } catch {}
751
829
  return { server, sessionFileArg };
752
830
  }
831
+ var RIG_PI_THEME = {
832
+ $schema: "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
833
+ name: "rig",
834
+ vars: {
835
+ acid: "#ccff4d",
836
+ acidDim: "#a9d63f",
837
+ cyan: "#56d8ff",
838
+ red: "#ff5d5d",
839
+ yellow: "#ffd24d",
840
+ ink: "#f2f3f6",
841
+ ink2: "#aeb0ba",
842
+ ink3: "#6c6e79",
843
+ ink4: "#44464f",
844
+ panel: "#101115",
845
+ panelUser: "#14161b",
846
+ toolPending: "#0e1013",
847
+ toolSuccess: "#10150c",
848
+ toolError: "#1a0f0f",
849
+ customMsg: "#0f1410"
850
+ },
851
+ colors: {
852
+ accent: "acid",
853
+ border: "ink4",
854
+ borderAccent: "acid",
855
+ borderMuted: "ink4",
856
+ success: "acid",
857
+ error: "red",
858
+ warning: "yellow",
859
+ muted: "ink3",
860
+ dim: "ink4",
861
+ text: "ink",
862
+ thinkingText: "ink3",
863
+ selectedBg: "panel",
864
+ userMessageBg: "panelUser",
865
+ userMessageText: "ink",
866
+ customMessageBg: "customMsg",
867
+ customMessageText: "ink2",
868
+ customMessageLabel: "acidDim",
869
+ toolPendingBg: "toolPending",
870
+ toolSuccessBg: "toolSuccess",
871
+ toolErrorBg: "toolError",
872
+ toolTitle: "ink",
873
+ toolOutput: "ink3",
874
+ mdHeading: "acid",
875
+ mdLink: "cyan",
876
+ mdLinkUrl: "ink4",
877
+ mdCode: "acidDim",
878
+ mdCodeBlock: "ink2",
879
+ mdCodeBlockBorder: "ink4",
880
+ mdQuote: "ink3",
881
+ mdQuoteBorder: "ink4",
882
+ mdHr: "ink4",
883
+ mdListBullet: "acid",
884
+ toolDiffAdded: "acid",
885
+ toolDiffRemoved: "red",
886
+ toolDiffContext: "ink3",
887
+ syntaxComment: "ink3",
888
+ syntaxKeyword: "cyan",
889
+ syntaxFunction: "acid",
890
+ syntaxVariable: "ink",
891
+ syntaxString: "acidDim",
892
+ syntaxNumber: "yellow",
893
+ syntaxType: "cyan",
894
+ syntaxOperator: "ink2",
895
+ syntaxPunctuation: "ink3",
896
+ thinkingOff: "ink4",
897
+ thinkingMinimal: "ink3",
898
+ thinkingLow: "ink2",
899
+ thinkingMedium: "cyan",
900
+ thinkingHigh: "acidDim",
901
+ thinkingXhigh: "acid",
902
+ bashMode: "cyan"
903
+ }
904
+ };
905
+ function trustDroneCwd(localCwd) {
906
+ try {
907
+ const agentDir = join(homedir2(), ".pi", "agent");
908
+ mkdirSync2(agentDir, { recursive: true });
909
+ const trustPath = join(agentDir, "trust.json");
910
+ const store = existsSync3(trustPath) ? JSON.parse(readFileSync3(trustPath, "utf8")) : {};
911
+ if (store[localCwd] !== true) {
912
+ store[localCwd] = true;
913
+ writeFileSync2(trustPath, `${JSON.stringify(store, null, "\t")}
914
+ `);
915
+ }
916
+ } catch {}
917
+ }
918
+ function installRigPiTheme() {
919
+ try {
920
+ const themesDir = join(homedir2(), ".pi", "agent", "themes");
921
+ mkdirSync2(themesDir, { recursive: true });
922
+ const themePath = join(themesDir, "rig.json");
923
+ const next = `${JSON.stringify(RIG_PI_THEME, null, "\t")}
924
+ `;
925
+ if (!existsSync3(themePath) || readFileSync3(themePath, "utf8") !== next) {
926
+ writeFileSync2(themePath, next);
927
+ }
928
+ } catch {}
929
+ }
753
930
  async function attachRunBundledPiFrontend(context, input) {
754
931
  const tempSessionDir = mkdtempSync(join(tmpdir(), "rig-pi-frontend-sessions-"));
755
932
  const { server, sessionFileArg } = await withSpinner(`Opening Pi console for run ${input.runId}\u2026`, () => prepareOperatorConsole(context, input.runId, tempSessionDir), { outputMode: context.outputMode });
@@ -0,0 +1,15 @@
1
+ import type { TaskSourceConfig } from "@rig/contracts";
2
+ import type { RigPluginWithRuntime } from "@rig/core";
3
+ export declare function parsePositiveInt(value: string | undefined, option: string, fallback: number): number;
4
+ export declare function parseOptionalPositiveInt(value: string | undefined, option: string): number | undefined;
5
+ export declare function parseRequiredPositiveInt(value: string | undefined, option: string): number;
6
+ export declare function parseAction(value: string | undefined): "validate" | "verify" | "pipeline";
7
+ export declare function parseIsolationMode(value: string | undefined, allowOff: true): "off" | "worktree";
8
+ export declare function parseIsolationMode(value: string | undefined, allowOff: false): "worktree";
9
+ export declare function parseInstallScope(value: string | undefined): "user" | "system";
10
+ export declare function resolveInstallDir(scope: "user" | "system", explicitPath: string | undefined): string;
11
+ export type CliRigConfig = {
12
+ plugins?: readonly RigPluginWithRuntime[];
13
+ taskSource?: TaskSourceConfig;
14
+ };
15
+ export declare function loadRigConfigOrNull(projectRoot: string): Promise<CliRigConfig | null>;
@@ -0,0 +1,11 @@
1
+ export declare function resolveControlPlaneMonorepoRoot(projectRoot: string): string;
2
+ export declare function resolveControlPlaneTaskConfigPath(projectRoot: string): string;
3
+ export declare function resolveControlPlaneHostStateRoot(projectRoot: string): string;
4
+ export declare function resolveControlPlaneHostStateDir(projectRoot: string): string;
5
+ export declare function resolveControlPlaneHostLogsDir(projectRoot: string): string;
6
+ export declare function resolveControlPlaneHostBinDir(projectRoot: string): string;
7
+ export declare function resolveControlPlaneHostDistDir(projectRoot: string): string;
8
+ export declare function resolveControlPlaneMonorepoStateRoot(projectRoot: string): string;
9
+ export declare function resolveControlPlaneMonorepoRuntimeDir(projectRoot: string): string;
10
+ export declare function resolveControlPlaneArtifactsDir(projectRoot: string): string;
11
+ export declare function resolveControlPlaneDefinitionRoot(projectRoot: string): string;
@@ -0,0 +1,27 @@
1
+ import type { RunnerContext } from "../runner";
2
+ type AttachResult = {
3
+ run: Record<string, unknown>;
4
+ logs: Record<string, unknown>[];
5
+ timeline: Record<string, unknown>[];
6
+ timelineCursor: string | null;
7
+ steered: boolean;
8
+ rendered: string;
9
+ detached?: boolean;
10
+ };
11
+ /**
12
+ * Compose the operator-session environment for the attached Pi console.
13
+ * Exported for tests: this is the contract between `rig run attach` and the
14
+ * pi-rig extension's context discovery (see packages/pi-rig/src/client.ts).
15
+ */
16
+ export declare function buildOperatorPiEnv(input: {
17
+ readonly runId: string;
18
+ readonly serverUrl: string;
19
+ readonly authToken?: string | null;
20
+ readonly serverProjectRoot?: string | null;
21
+ readonly sessionDir: string;
22
+ }): Record<string, string>;
23
+ export declare function attachRunBundledPiFrontend(context: Pick<RunnerContext, "projectRoot" | "outputMode">, input: {
24
+ readonly runId: string;
25
+ readonly steered?: boolean;
26
+ }): Promise<AttachResult>;
27
+ export {};