@h-rig/cli 0.0.6-alpha.34 → 0.0.6-alpha.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/rig.js CHANGED
@@ -531,9 +531,9 @@ import { loadPolicy as loadPolicy3 } from "@rig/runtime/control-plane/runtime/gu
531
531
  // packages/cli/src/commands.ts
532
532
  init_runner();
533
533
  import {
534
- existsSync as existsSync15
534
+ existsSync as existsSync16
535
535
  } from "fs";
536
- import { resolve as resolve24 } from "path";
536
+ import { resolve as resolve25 } from "path";
537
537
  import { readBuildConfig } from "@rig/runtime/build-time-config";
538
538
 
539
539
  // packages/cli/src/commands/browser.ts
@@ -2644,6 +2644,157 @@ async function executeHarness(context, args) {
2644
2644
  // packages/cli/src/commands.ts
2645
2645
  init_plugin();
2646
2646
 
2647
+ // packages/cli/src/commands/pi.ts
2648
+ init_runner();
2649
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
2650
+ import { homedir as homedir2 } from "os";
2651
+ import { dirname, resolve as resolve9 } from "path";
2652
+ function settingsPath(root) {
2653
+ return resolve9(root, ".pi", "settings.json");
2654
+ }
2655
+ function userSettingsPath() {
2656
+ return resolve9(homedir2(), ".pi", "agent", "settings.json");
2657
+ }
2658
+ function readJson(path, fallback) {
2659
+ if (!existsSync5(path))
2660
+ return fallback;
2661
+ try {
2662
+ return JSON.parse(readFileSync2(path, "utf-8"));
2663
+ } catch {
2664
+ return fallback;
2665
+ }
2666
+ }
2667
+ function packageKey(entry) {
2668
+ if (typeof entry === "string")
2669
+ return entry;
2670
+ if (entry && typeof entry === "object" && typeof entry.source === "string") {
2671
+ return entry.source;
2672
+ }
2673
+ return JSON.stringify(entry);
2674
+ }
2675
+ function writeSettings(path, settings) {
2676
+ mkdirSync5(dirname(path), { recursive: true });
2677
+ writeFileSync3(path, `${JSON.stringify(settings, null, 2)}
2678
+ `, "utf-8");
2679
+ }
2680
+ async function searchNpmForPiExtensions(term) {
2681
+ const query = encodeURIComponent(term ? `${term} pi extension` : "pi extension");
2682
+ const url = `https://registry.npmjs.org/-/v1/search?text=${query}&size=20`;
2683
+ const response = await fetch(url);
2684
+ if (!response.ok) {
2685
+ throw new CliError2(`npm registry search failed (${response.status}).`, 2);
2686
+ }
2687
+ const payload = await response.json();
2688
+ const results = [];
2689
+ for (const entry of payload.objects ?? []) {
2690
+ const pkg = entry.package;
2691
+ if (!pkg?.name)
2692
+ continue;
2693
+ const keywords = (pkg.keywords ?? []).map((k) => k.toLowerCase());
2694
+ const piLike = pkg.name.startsWith("pi-") || pkg.name.includes("-pi") || keywords.includes("pi") || keywords.includes("pi-extension") || (pkg.description ?? "").toLowerCase().includes("pi extension") || (pkg.description ?? "").toLowerCase().includes("pi coding agent");
2695
+ if (!piLike)
2696
+ continue;
2697
+ results.push({ name: pkg.name, version: pkg.version ?? "", description: pkg.description ?? "" });
2698
+ }
2699
+ return results;
2700
+ }
2701
+ async function executePi(context, args) {
2702
+ const [command = "list", ...rest] = args;
2703
+ const projectSettingsPath = settingsPath(context.projectRoot);
2704
+ const managedRecordPath = resolve9(context.projectRoot, ".rig", "state", "pi-managed-packages.json");
2705
+ switch (command) {
2706
+ case "list": {
2707
+ requireNoExtraArgs(rest, "rig pi list");
2708
+ const project = readJson(projectSettingsPath, {});
2709
+ const managed = new Set(readJson(managedRecordPath, []));
2710
+ const user = readJson(userSettingsPath(), {});
2711
+ const projectPackages = (Array.isArray(project.packages) ? project.packages : []).map((entry) => ({
2712
+ source: packageKey(entry),
2713
+ managedByRigConfig: managed.has(packageKey(entry))
2714
+ }));
2715
+ const userPackages = (Array.isArray(user.packages) ? user.packages : []).map(packageKey);
2716
+ if (context.outputMode === "text") {
2717
+ console.log("Project Pi packages (.pi/settings.json):");
2718
+ if (projectPackages.length === 0)
2719
+ console.log(" (none)");
2720
+ for (const pkg of projectPackages) {
2721
+ console.log(` ${pkg.source}${pkg.managedByRigConfig ? " [from rig.config runtime.pi.packages]" : ""}`);
2722
+ }
2723
+ console.log("User Pi packages (~/.pi/agent/settings.json):");
2724
+ if (userPackages.length === 0)
2725
+ console.log(" (none)");
2726
+ for (const pkg of userPackages)
2727
+ console.log(` ${pkg}`);
2728
+ console.log("Add more: `rig pi add <npm-package>` \xB7 discover: `rig pi search <term>`");
2729
+ }
2730
+ return { ok: true, group: "pi", command, details: { projectPackages, userPackages } };
2731
+ }
2732
+ case "add": {
2733
+ const [source, ...extra] = rest;
2734
+ requireNoExtraArgs(extra, "rig pi add <package-source>");
2735
+ if (!source) {
2736
+ throw new CliError2("Usage: rig pi add <package-source> (npm name, name@version, or git URL)", 2);
2737
+ }
2738
+ const settings = readJson(projectSettingsPath, {});
2739
+ const packages = Array.isArray(settings.packages) ? settings.packages : [];
2740
+ if (packages.some((entry) => packageKey(entry) === source)) {
2741
+ throw new CliError2(`"${source}" is already in ${projectSettingsPath}.`, 2);
2742
+ }
2743
+ writeSettings(projectSettingsPath, { ...settings, packages: [...packages, source] });
2744
+ if (context.outputMode === "text") {
2745
+ console.log(`Added ${source} to ${projectSettingsPath}.`);
2746
+ console.log("Pi installs missing packages automatically at the next session start (local and worker).");
2747
+ }
2748
+ return { ok: true, group: "pi", command, details: { source, settingsPath: projectSettingsPath } };
2749
+ }
2750
+ case "remove": {
2751
+ const [source, ...extra] = rest;
2752
+ requireNoExtraArgs(extra, "rig pi remove <package-source>");
2753
+ if (!source) {
2754
+ throw new CliError2("Usage: rig pi remove <package-source>", 2);
2755
+ }
2756
+ const managed = new Set(readJson(managedRecordPath, []));
2757
+ if (managed.has(source)) {
2758
+ throw new CliError2(`"${source}" is managed by rig.config.ts (runtime.pi.packages); remove it there instead.`, 2);
2759
+ }
2760
+ const settings = readJson(projectSettingsPath, {});
2761
+ const packages = Array.isArray(settings.packages) ? settings.packages : [];
2762
+ const next = packages.filter((entry) => packageKey(entry) !== source);
2763
+ if (next.length === packages.length) {
2764
+ throw new CliError2(`"${source}" is not in ${projectSettingsPath}.`, 2);
2765
+ }
2766
+ const nextSettings = { ...settings };
2767
+ if (next.length > 0)
2768
+ nextSettings.packages = next;
2769
+ else
2770
+ delete nextSettings.packages;
2771
+ writeSettings(projectSettingsPath, nextSettings);
2772
+ if (context.outputMode === "text") {
2773
+ console.log(`Removed ${source} from ${projectSettingsPath}.`);
2774
+ }
2775
+ return { ok: true, group: "pi", command, details: { source } };
2776
+ }
2777
+ case "search": {
2778
+ const term = rest.join(" ").trim();
2779
+ const results = await searchNpmForPiExtensions(term);
2780
+ if (context.outputMode === "text") {
2781
+ if (results.length === 0) {
2782
+ console.log(`No Pi extension packages found on npm${term ? ` for "${term}"` : ""}.`);
2783
+ } else {
2784
+ console.log(`Pi extension packages on npm${term ? ` matching "${term}"` : ""}:`);
2785
+ for (const pkg of results) {
2786
+ console.log(` ${pkg.name}@${pkg.version} ${pkg.description.slice(0, 80)}`);
2787
+ }
2788
+ console.log("Install one: `rig pi add <name>`");
2789
+ }
2790
+ }
2791
+ return { ok: true, group: "pi", command, details: { term, results } };
2792
+ }
2793
+ default:
2794
+ throw new CliError2(`Unknown pi command: ${command}. Use list|add|remove|search.`);
2795
+ }
2796
+ }
2797
+
2647
2798
  // packages/cli/src/commands/queue.ts
2648
2799
  init_runner();
2649
2800
  init__parsers();
@@ -2655,33 +2806,33 @@ import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/proj
2655
2806
 
2656
2807
  // packages/cli/src/commands/_connection-state.ts
2657
2808
  init_runner();
2658
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
2659
- import { homedir as homedir2 } from "os";
2660
- import { dirname, resolve as resolve9 } from "path";
2809
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
2810
+ import { homedir as homedir3 } from "os";
2811
+ import { dirname as dirname2, resolve as resolve10 } from "path";
2661
2812
  function resolveGlobalConnectionsPath(env = process.env) {
2662
2813
  const explicit = env.RIG_CONNECTIONS_FILE?.trim();
2663
2814
  if (explicit)
2664
- return resolve9(explicit);
2815
+ return resolve10(explicit);
2665
2816
  const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
2666
2817
  if (stateDir)
2667
- return resolve9(stateDir, "connections.json");
2668
- return resolve9(homedir2(), ".rig", "connections.json");
2818
+ return resolve10(stateDir, "connections.json");
2819
+ return resolve10(homedir3(), ".rig", "connections.json");
2669
2820
  }
2670
2821
  function resolveRepoConnectionPath(projectRoot) {
2671
- return resolve9(projectRoot, ".rig", "state", "connection.json");
2822
+ return resolve10(projectRoot, ".rig", "state", "connection.json");
2672
2823
  }
2673
2824
  function readJsonFile2(path) {
2674
- if (!existsSync5(path))
2825
+ if (!existsSync6(path))
2675
2826
  return null;
2676
2827
  try {
2677
- return JSON.parse(readFileSync2(path, "utf8"));
2828
+ return JSON.parse(readFileSync3(path, "utf8"));
2678
2829
  } catch (error) {
2679
2830
  throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
2680
2831
  }
2681
2832
  }
2682
2833
  function writeJsonFile2(path, value) {
2683
- mkdirSync5(dirname(path), { recursive: true });
2684
- writeFileSync3(path, `${JSON.stringify(value, null, 2)}
2834
+ mkdirSync6(dirname2(path), { recursive: true });
2835
+ writeFileSync4(path, `${JSON.stringify(value, null, 2)}
2685
2836
  `, "utf8");
2686
2837
  }
2687
2838
  function normalizeConnection(value) {
@@ -2758,8 +2909,8 @@ function resolveSelectedConnection(projectRoot, options = {}) {
2758
2909
 
2759
2910
  // packages/cli/src/commands/_server-client.ts
2760
2911
  init_runner();
2761
- import { existsSync as existsSync6, readFileSync as readFileSync3 } from "fs";
2762
- import { resolve as resolve10 } from "path";
2912
+ import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
2913
+ import { resolve as resolve11 } from "path";
2763
2914
  import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
2764
2915
  var scopedGitHubBearerTokens = new Map;
2765
2916
  function cleanToken(value) {
@@ -2767,22 +2918,22 @@ function cleanToken(value) {
2767
2918
  return trimmed ? trimmed : null;
2768
2919
  }
2769
2920
  function setGitHubBearerTokenForCurrentProcess(token, projectRoot) {
2770
- const scopedKey = resolve10(projectRoot ?? process.cwd());
2921
+ const scopedKey = resolve11(projectRoot ?? process.cwd());
2771
2922
  scopedGitHubBearerTokens.set(scopedKey, cleanToken(token ?? undefined));
2772
2923
  }
2773
2924
  function readPrivateRemoteSessionToken(projectRoot) {
2774
- const path = resolve10(projectRoot, ".rig", "state", "github-auth.json");
2775
- if (!existsSync6(path))
2925
+ const path = resolve11(projectRoot, ".rig", "state", "github-auth.json");
2926
+ if (!existsSync7(path))
2776
2927
  return null;
2777
2928
  try {
2778
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
2929
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
2779
2930
  return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
2780
2931
  } catch {
2781
2932
  return null;
2782
2933
  }
2783
2934
  }
2784
2935
  function readGitHubBearerTokenForRemote(projectRoot) {
2785
- const scopedKey = resolve10(projectRoot);
2936
+ const scopedKey = resolve11(projectRoot);
2786
2937
  if (scopedGitHubBearerTokens.has(scopedKey))
2787
2938
  return scopedGitHubBearerTokens.get(scopedKey) ?? null;
2788
2939
  const privateSession = readPrivateRemoteSessionToken(projectRoot);
@@ -2924,7 +3075,7 @@ async function registerProjectViaServer(context, input) {
2924
3075
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
2925
3076
  }
2926
3077
  function sleep(ms) {
2927
- return new Promise((resolve11) => setTimeout(resolve11, ms));
3078
+ return new Promise((resolve12) => setTimeout(resolve12, ms));
2928
3079
  }
2929
3080
  function isRetryableProjectRootSwitchError(error) {
2930
3081
  if (!(error instanceof Error))
@@ -3407,7 +3558,7 @@ async function executeQueue(context, args) {
3407
3558
 
3408
3559
  // packages/cli/src/commands/agent.ts
3409
3560
  init_runner();
3410
- import { resolve as resolve12 } from "path";
3561
+ import { resolve as resolve13 } from "path";
3411
3562
  import {
3412
3563
  agentId,
3413
3564
  cleanupAgentRuntime,
@@ -3417,8 +3568,8 @@ import {
3417
3568
  } from "@rig/runtime/control-plane/runtime/isolation";
3418
3569
 
3419
3570
  // packages/cli/src/commands/_authority-runs.ts
3420
- import { existsSync as existsSync7 } from "fs";
3421
- import { resolve as resolve11 } from "path";
3571
+ import { existsSync as existsSync8 } from "fs";
3572
+ import { resolve as resolve12 } from "path";
3422
3573
  import {
3423
3574
  readAuthorityRun,
3424
3575
  readJsonlFile as readJsonlFile2,
@@ -3440,8 +3591,8 @@ function normalizeRuntimeAdapter(value) {
3440
3591
  return "claude-code";
3441
3592
  }
3442
3593
  function readLatestBeadRecord(projectRoot, taskId) {
3443
- const issuesPath = resolve11(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
3444
- if (!existsSync7(issuesPath)) {
3594
+ const issuesPath = resolve12(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
3595
+ if (!existsSync8(issuesPath)) {
3445
3596
  return null;
3446
3597
  }
3447
3598
  let latest = null;
@@ -3509,7 +3660,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
3509
3660
  } else if ("errorText" in next) {
3510
3661
  delete next.errorText;
3511
3662
  }
3512
- writeJsonFile3(resolve11(resolveAuthorityRunDir(projectRoot, input.runId), "run.json"), next);
3663
+ writeJsonFile3(resolve12(resolveAuthorityRunDir(projectRoot, input.runId), "run.json"), next);
3513
3664
  return next;
3514
3665
  }
3515
3666
 
@@ -3631,10 +3782,10 @@ async function executeAgent(context, args) {
3631
3782
  status: "running",
3632
3783
  startedAt: createdAt,
3633
3784
  worktreePath: runtime.workspaceDir,
3634
- artifactRoot: resolve12(runtime.workspaceDir, "artifacts", taskId),
3785
+ artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
3635
3786
  logRoot: runtime.logsDir,
3636
- sessionPath: resolve12(runtime.sessionDir, "session.json"),
3637
- sessionLogPath: resolve12(runtime.logsDir, "agent-stdout.log"),
3787
+ sessionPath: resolve13(runtime.sessionDir, "session.json"),
3788
+ sessionLogPath: resolve13(runtime.logsDir, "agent-stdout.log"),
3638
3789
  pid: process.pid
3639
3790
  });
3640
3791
  const result = await runInAgentRuntime({
@@ -3654,10 +3805,10 @@ async function executeAgent(context, args) {
3654
3805
  startedAt: createdAt,
3655
3806
  completedAt: failedAt,
3656
3807
  worktreePath: runtime.workspaceDir,
3657
- artifactRoot: resolve12(runtime.workspaceDir, "artifacts", taskId),
3808
+ artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
3658
3809
  logRoot: runtime.logsDir,
3659
- sessionPath: resolve12(runtime.sessionDir, "session.json"),
3660
- sessionLogPath: resolve12(runtime.logsDir, "agent-stdout.log"),
3810
+ sessionPath: resolve13(runtime.sessionDir, "session.json"),
3811
+ sessionLogPath: resolve13(runtime.logsDir, "agent-stdout.log"),
3661
3812
  pid: process.pid,
3662
3813
  errorText: result.stderr ? result.stderr.trim() : `Agent runtime command failed (${result.exitCode})`
3663
3814
  });
@@ -3674,10 +3825,10 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
3674
3825
  startedAt: createdAt,
3675
3826
  completedAt,
3676
3827
  worktreePath: runtime.workspaceDir,
3677
- artifactRoot: resolve12(runtime.workspaceDir, "artifacts", taskId),
3828
+ artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
3678
3829
  logRoot: runtime.logsDir,
3679
- sessionPath: resolve12(runtime.sessionDir, "session.json"),
3680
- sessionLogPath: resolve12(runtime.logsDir, "agent-stdout.log"),
3830
+ sessionPath: resolve13(runtime.sessionDir, "session.json"),
3831
+ sessionLogPath: resolve13(runtime.logsDir, "agent-stdout.log"),
3681
3832
  pid: process.pid
3682
3833
  });
3683
3834
  return {
@@ -3753,8 +3904,8 @@ init__parsers();
3753
3904
  import {
3754
3905
  chmodSync,
3755
3906
  copyFileSync as copyFileSync2,
3756
- existsSync as existsSync8,
3757
- mkdirSync as mkdirSync6,
3907
+ existsSync as existsSync9,
3908
+ mkdirSync as mkdirSync7,
3758
3909
  readdirSync,
3759
3910
  readlinkSync,
3760
3911
  rmSync as rmSync3,
@@ -3762,8 +3913,8 @@ import {
3762
3913
  symlinkSync,
3763
3914
  unlinkSync
3764
3915
  } from "fs";
3765
- import { homedir as homedir3 } from "os";
3766
- import { resolve as resolve13 } from "path";
3916
+ import { homedir as homedir4 } from "os";
3917
+ import { resolve as resolve14 } from "path";
3767
3918
  import { buildBinary as buildBinary2 } from "@rig/runtime/control-plane/runtime/isolation";
3768
3919
  import {
3769
3920
  computeRuntimeImageFingerprint,
@@ -3782,13 +3933,13 @@ async function runQuietBinaryProbe(binaryPath, args, cwd) {
3782
3933
 
3783
3934
  // packages/cli/src/commands/dist.ts
3784
3935
  function collectRigValidatorBuildTargets(input) {
3785
- const validatorsRoot = resolve13(input.hostProjectRoot, "packages/runtime/src/control-plane/validators");
3786
- if (!existsSync8(validatorsRoot))
3936
+ const validatorsRoot = resolve14(input.hostProjectRoot, "packages/runtime/src/control-plane/validators");
3937
+ if (!existsSync9(validatorsRoot))
3787
3938
  return [];
3788
3939
  const targets = [];
3789
3940
  const categories = readdirSync(validatorsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
3790
3941
  for (const category of categories) {
3791
- const categoryDir = resolve13(validatorsRoot, category.name);
3942
+ const categoryDir = resolve14(validatorsRoot, category.name);
3792
3943
  for (const entry of readdirSync(categoryDir, { withFileTypes: true })) {
3793
3944
  if (!entry.isFile() || !entry.name.endsWith(".ts"))
3794
3945
  continue;
@@ -3797,7 +3948,7 @@ function collectRigValidatorBuildTargets(input) {
3797
3948
  continue;
3798
3949
  targets.push({
3799
3950
  source: `packages/runtime/src/control-plane/validators/${category.name}/${entry.name}`,
3800
- dest: resolve13(input.imageDir, `bin/validators/${category.name}-${check}`),
3951
+ dest: resolve14(input.imageDir, `bin/validators/${category.name}-${check}`),
3801
3952
  cwd: input.hostProjectRoot
3802
3953
  });
3803
3954
  }
@@ -3806,16 +3957,16 @@ function collectRigValidatorBuildTargets(input) {
3806
3957
  }
3807
3958
  async function findLatestDistBinary(projectRoot) {
3808
3959
  const distRoot = resolveControlPlaneHostDistDir(projectRoot);
3809
- if (!existsSync8(distRoot)) {
3960
+ if (!existsSync9(distRoot)) {
3810
3961
  return null;
3811
3962
  }
3812
3963
  const entries = readdirSync(distRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.startsWith("rig-")).map((entry) => ({
3813
3964
  name: entry.name,
3814
- mtimeMs: statSync(resolve13(distRoot, entry.name)).mtimeMs
3965
+ mtimeMs: statSync(resolve14(distRoot, entry.name)).mtimeMs
3815
3966
  })).sort((a, b) => b.mtimeMs - a.mtimeMs || b.name.localeCompare(a.name));
3816
3967
  for (const { name } of entries) {
3817
- const candidate = resolve13(distRoot, name, "bin", "rig");
3818
- if (existsSync8(candidate) && await isRunnableRigBinary(candidate, projectRoot)) {
3968
+ const candidate = resolve14(distRoot, name, "bin", "rig");
3969
+ if (existsSync9(candidate) && await isRunnableRigBinary(candidate, projectRoot)) {
3819
3970
  return candidate;
3820
3971
  }
3821
3972
  }
@@ -3827,7 +3978,7 @@ async function isRunnableRigBinary(binaryPath, projectRoot) {
3827
3978
  async function runDistDoctor(projectRoot) {
3828
3979
  const bunPath = Bun.which("bun");
3829
3980
  const rigPath = Bun.which("rig");
3830
- const userBinDir = resolve13(homedir3(), ".local/bin");
3981
+ const userBinDir = resolve14(homedir4(), ".local/bin");
3831
3982
  const userBinInPath = (process.env.PATH || "").split(":").filter(Boolean).includes(userBinDir);
3832
3983
  let rigRunnable = false;
3833
3984
  if (rigPath) {
@@ -3871,19 +4022,19 @@ async function executeDist(context, args) {
3871
4022
  requireNoExtraArgs(pending, "rig dist install [--scope user|system] [--path <dir>]");
3872
4023
  const scope = parseInstallScope(scopeResult.value);
3873
4024
  const installDir = resolveInstallDir(scope, pathResult.value);
3874
- mkdirSync6(installDir, { recursive: true });
4025
+ mkdirSync7(installDir, { recursive: true });
3875
4026
  let source = await findLatestDistBinary(context.projectRoot);
3876
4027
  let buildDir = null;
3877
4028
  if (!source) {
3878
- buildDir = resolve13(resolveControlPlaneHostDistDir(context.projectRoot), `rig-install-${Date.now()}`);
4029
+ buildDir = resolve14(resolveControlPlaneHostDistDir(context.projectRoot), `rig-install-${Date.now()}`);
3879
4030
  await context.runCommand(["bun", "run", "packages/cli/bin/build-rig-binaries.ts", "--output-dir", buildDir]);
3880
- source = resolve13(buildDir, "bin", "rig");
4031
+ source = resolve14(buildDir, "bin", "rig");
3881
4032
  }
3882
- if (!existsSync8(source)) {
4033
+ if (!existsSync9(source)) {
3883
4034
  throw new CliError2(`Unable to locate rig binary at ${source}.`, 2);
3884
4035
  }
3885
- const installedPath = resolve13(installDir, "rig");
3886
- if (existsSync8(installedPath)) {
4036
+ const installedPath = resolve14(installDir, "rig");
4037
+ if (existsSync9(installedPath)) {
3887
4038
  unlinkSync(installedPath);
3888
4039
  }
3889
4040
  copyFileSync2(source, installedPath);
@@ -3925,22 +4076,22 @@ async function executeDist(context, args) {
3925
4076
  requireNoExtraArgs(rest, "rig dist rebuild-agent");
3926
4077
  const fp = await computeRuntimeImageFingerprint(context.projectRoot);
3927
4078
  const currentId = computeRuntimeImageId(fp);
3928
- const imagesDir = resolve13(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
3929
- mkdirSync6(imagesDir, { recursive: true });
4079
+ const imagesDir = resolve14(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
4080
+ mkdirSync7(imagesDir, { recursive: true });
3930
4081
  let pruned = 0;
3931
4082
  for (const entry of readdirSync(imagesDir, { withFileTypes: true })) {
3932
4083
  if (entry.isDirectory() && entry.name !== currentId) {
3933
- rmSync3(resolve13(imagesDir, entry.name), { recursive: true, force: true });
4084
+ rmSync3(resolve14(imagesDir, entry.name), { recursive: true, force: true });
3934
4085
  pruned++;
3935
4086
  }
3936
4087
  }
3937
4088
  if (pruned > 0 && context.outputMode === "text") {
3938
4089
  console.log(`Pruned ${pruned} stale image(s).`);
3939
4090
  }
3940
- const imageDir = resolve13(imagesDir, currentId);
3941
- mkdirSync6(resolve13(imageDir, "bin/hooks"), { recursive: true });
3942
- mkdirSync6(resolve13(imageDir, "bin/plugins"), { recursive: true });
3943
- mkdirSync6(resolve13(imageDir, "bin/validators"), { recursive: true });
4091
+ const imageDir = resolve14(imagesDir, currentId);
4092
+ mkdirSync7(resolve14(imageDir, "bin/hooks"), { recursive: true });
4093
+ mkdirSync7(resolve14(imageDir, "bin/plugins"), { recursive: true });
4094
+ mkdirSync7(resolve14(imageDir, "bin/validators"), { recursive: true });
3944
4095
  const hookNames = [
3945
4096
  "scope-guard",
3946
4097
  "import-guard",
@@ -3954,25 +4105,25 @@ async function executeDist(context, args) {
3954
4105
  ];
3955
4106
  const targets = [];
3956
4107
  const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || context.projectRoot;
3957
- targets.push({ source: "packages/runtime/bin/rig-agent.ts", dest: resolve13(imageDir, "bin/rig-agent"), cwd: hostProjectRoot });
3958
- targets.push({ source: "packages/runtime/bin/rig-agent-dispatch.ts", dest: resolve13(resolveControlPlaneHostBinDir(context.projectRoot), "rig-agent"), cwd: hostProjectRoot });
4108
+ targets.push({ source: "packages/runtime/bin/rig-agent.ts", dest: resolve14(imageDir, "bin/rig-agent"), cwd: hostProjectRoot });
4109
+ targets.push({ source: "packages/runtime/bin/rig-agent-dispatch.ts", dest: resolve14(resolveControlPlaneHostBinDir(context.projectRoot), "rig-agent"), cwd: hostProjectRoot });
3959
4110
  for (const hookName of hookNames) {
3960
4111
  const src = `packages/runtime/src/control-plane/hooks/${hookName}.ts`;
3961
- targets.push({ source: src, dest: resolve13(imageDir, `bin/hooks/${hookName}`), cwd: hostProjectRoot });
3962
- targets.push({ source: src, dest: resolve13(resolveControlPlaneHostBinDir(context.projectRoot), `hooks/${hookName}`), cwd: hostProjectRoot });
3963
- }
3964
- const pluginsDir = resolve13(context.projectRoot, "rig/plugins");
3965
- const binPluginsDir = resolve13(resolveControlPlaneHostBinDir(context.projectRoot), "plugins");
3966
- const validatorsRoot = resolve13(hostProjectRoot, "packages/runtime/src/control-plane/validators");
3967
- const binValidatorsDir = resolve13(resolveControlPlaneHostBinDir(context.projectRoot), "validators");
3968
- mkdirSync6(binPluginsDir, { recursive: true });
3969
- mkdirSync6(binValidatorsDir, { recursive: true });
3970
- if (existsSync8(pluginsDir)) {
4112
+ targets.push({ source: src, dest: resolve14(imageDir, `bin/hooks/${hookName}`), cwd: hostProjectRoot });
4113
+ targets.push({ source: src, dest: resolve14(resolveControlPlaneHostBinDir(context.projectRoot), `hooks/${hookName}`), cwd: hostProjectRoot });
4114
+ }
4115
+ const pluginsDir = resolve14(context.projectRoot, "rig/plugins");
4116
+ const binPluginsDir = resolve14(resolveControlPlaneHostBinDir(context.projectRoot), "plugins");
4117
+ const validatorsRoot = resolve14(hostProjectRoot, "packages/runtime/src/control-plane/validators");
4118
+ const binValidatorsDir = resolve14(resolveControlPlaneHostBinDir(context.projectRoot), "validators");
4119
+ mkdirSync7(binPluginsDir, { recursive: true });
4120
+ mkdirSync7(binValidatorsDir, { recursive: true });
4121
+ if (existsSync9(pluginsDir)) {
3971
4122
  for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
3972
4123
  const m = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
3973
4124
  if (!m)
3974
4125
  continue;
3975
- targets.push({ source: `rig/plugins/${entry.name}`, dest: resolve13(imageDir, `bin/plugins/${m[1]}`), cwd: context.projectRoot });
4126
+ targets.push({ source: `rig/plugins/${entry.name}`, dest: resolve14(imageDir, `bin/plugins/${m[1]}`), cwd: context.projectRoot });
3976
4127
  }
3977
4128
  }
3978
4129
  targets.push(...collectRigValidatorBuildTargets({ contextProjectRoot: context.projectRoot, hostProjectRoot, imageDir }));
@@ -3983,17 +4134,17 @@ async function executeDist(context, args) {
3983
4134
  const isValidator = dest.includes("/bin/validators/");
3984
4135
  await buildBinary2(source, dest, cwd, isValidator ? { AGENT_BUN_PATH: Bun.which("bun") || "bun" } : { AGENT_PROJECT_ROOT: context.projectRoot });
3985
4136
  }
3986
- if (existsSync8(pluginsDir)) {
4137
+ if (existsSync9(pluginsDir)) {
3987
4138
  for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
3988
4139
  const m = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
3989
4140
  if (!m)
3990
4141
  continue;
3991
4142
  const pluginName = m[1];
3992
- const imageBin = resolve13(imageDir, `bin/plugins/${pluginName}`);
4143
+ const imageBin = resolve14(imageDir, `bin/plugins/${pluginName}`);
3993
4144
  if (!pluginName)
3994
4145
  continue;
3995
- const symlinkPath = resolve13(binPluginsDir, pluginName);
3996
- if (existsSync8(imageBin)) {
4146
+ const symlinkPath = resolve14(binPluginsDir, pluginName);
4147
+ if (existsSync9(imageBin)) {
3997
4148
  try {
3998
4149
  unlinkSync(symlinkPath);
3999
4150
  } catch {}
@@ -4001,10 +4152,10 @@ async function executeDist(context, args) {
4001
4152
  }
4002
4153
  }
4003
4154
  }
4004
- if (existsSync8(validatorsRoot)) {
4155
+ if (existsSync9(validatorsRoot)) {
4005
4156
  const categories = readdirSync(validatorsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
4006
4157
  for (const category of categories) {
4007
- const categoryDir = resolve13(validatorsRoot, category.name);
4158
+ const categoryDir = resolve14(validatorsRoot, category.name);
4008
4159
  for (const entry of readdirSync(categoryDir, { withFileTypes: true })) {
4009
4160
  if (!entry.isFile() || !entry.name.endsWith(".ts"))
4010
4161
  continue;
@@ -4012,9 +4163,9 @@ async function executeDist(context, args) {
4012
4163
  if (!check || check === "index" || check === "shared")
4013
4164
  continue;
4014
4165
  const validatorName = `${category.name}-${check}`;
4015
- const imageBin = resolve13(imageDir, `bin/validators/${validatorName}`);
4016
- const symlinkPath = resolve13(binValidatorsDir, validatorName);
4017
- if (existsSync8(imageBin)) {
4166
+ const imageBin = resolve14(imageDir, `bin/validators/${validatorName}`);
4167
+ const symlinkPath = resolve14(binValidatorsDir, validatorName);
4168
+ if (existsSync9(imageBin)) {
4018
4169
  try {
4019
4170
  unlinkSync(symlinkPath);
4020
4171
  } catch {}
@@ -4023,18 +4174,18 @@ async function executeDist(context, args) {
4023
4174
  }
4024
4175
  }
4025
4176
  }
4026
- const agentsDir = resolve13(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "agents");
4027
- if (existsSync8(agentsDir)) {
4177
+ const agentsDir = resolve14(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "agents");
4178
+ if (existsSync9(agentsDir)) {
4028
4179
  let relinkCount = 0;
4029
4180
  for (const agentEntry of readdirSync(agentsDir, { withFileTypes: true })) {
4030
4181
  if (!agentEntry.isDirectory())
4031
4182
  continue;
4032
- const agentBinDir = resolve13(agentsDir, agentEntry.name, "worktree", ".rig", "bin");
4033
- if (!existsSync8(agentBinDir))
4183
+ const agentBinDir = resolve14(agentsDir, agentEntry.name, "worktree", ".rig", "bin");
4184
+ if (!existsSync9(agentBinDir))
4034
4185
  continue;
4035
4186
  const walkDir = (dir) => {
4036
4187
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
4037
- const fullPath = resolve13(dir, entry.name);
4188
+ const fullPath = resolve14(dir, entry.name);
4038
4189
  if (entry.isDirectory()) {
4039
4190
  walkDir(fullPath);
4040
4191
  } else if (entry.isSymbolicLink()) {
@@ -4068,8 +4219,8 @@ async function executeDist(context, args) {
4068
4219
 
4069
4220
  // packages/cli/src/commands/inbox.ts
4070
4221
  init_runner();
4071
- import { writeFileSync as writeFileSync4 } from "fs";
4072
- import { resolve as resolve14 } from "path";
4222
+ import { writeFileSync as writeFileSync5 } from "fs";
4223
+ import { resolve as resolve15 } from "path";
4073
4224
  import {
4074
4225
  listAuthorityRuns,
4075
4226
  readJsonlFile as readJsonlFile3,
@@ -4471,7 +4622,7 @@ async function listRemoteInboxRecords(context, kind, filters) {
4471
4622
  function listLocalInboxRecords(context, kind, filters) {
4472
4623
  const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
4473
4624
  const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
4474
- return runs.flatMap((entry) => readJsonlFile3(resolve14(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
4625
+ return runs.flatMap((entry) => readJsonlFile3(resolve15(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
4475
4626
  runId: entry.runId,
4476
4627
  taskId: entry.taskId ?? undefined,
4477
4628
  record
@@ -4519,11 +4670,11 @@ async function executeInbox(context, args) {
4519
4670
  if (isRemoteConnectionSelected(context.projectRoot)) {
4520
4671
  throw new CliError2("Remote approval resolution is not available from this CLI yet; use the server UI/API or switch to local state for direct JSONL edits.", 2);
4521
4672
  }
4522
- const approvalsPath = resolve14(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
4673
+ const approvalsPath = resolve15(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
4523
4674
  const approvals = readJsonlFile3(approvalsPath);
4524
4675
  const resolvedAt = new Date().toISOString();
4525
4676
  const next = approvals.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", decision: decision.value, note: note4.value ?? null, resolvedAt } : entry);
4526
- writeFileSync4(approvalsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
4677
+ writeFileSync5(approvalsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
4527
4678
  `)}
4528
4679
  `, "utf8");
4529
4680
  return { ok: true, group: "inbox", command, details: { runId: run.value, requestId: request.value, decision: decision.value } };
@@ -4575,11 +4726,11 @@ async function executeInbox(context, args) {
4575
4726
  const [key, ...restValue] = entry.split("=");
4576
4727
  return [key, restValue.join("=")];
4577
4728
  }));
4578
- const requestsPath = resolve14(resolveAuthorityRunDir2(context.projectRoot, run.value), "user-input.jsonl");
4729
+ const requestsPath = resolve15(resolveAuthorityRunDir2(context.projectRoot, run.value), "user-input.jsonl");
4579
4730
  const requests = readJsonlFile3(requestsPath);
4580
4731
  const resolvedAt = new Date().toISOString();
4581
4732
  const next = requests.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", answers: parsedAnswers, respondedAt: resolvedAt, resolvedAt } : entry);
4582
- writeFileSync4(requestsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
4733
+ writeFileSync5(requestsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
4583
4734
  `)}
4584
4735
  `, "utf8");
4585
4736
  return { ok: true, group: "inbox", command, details: { runId: run.value, requestId: request.value, answers: parsedAnswers } };
@@ -4591,16 +4742,16 @@ async function executeInbox(context, args) {
4591
4742
 
4592
4743
  // packages/cli/src/commands/init.ts
4593
4744
  init_runner();
4594
- import { appendFileSync as appendFileSync2, existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
4745
+ import { appendFileSync as appendFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4595
4746
  import { spawnSync } from "child_process";
4596
- import { resolve as resolve18 } from "path";
4747
+ import { resolve as resolve19 } from "path";
4597
4748
  import { buildRigInitConfigSource } from "@rig/core";
4598
4749
  import { listGitHubProjects as listGitHubProjectsDirect, resolveProjectStatusField as resolveProjectStatusFieldDirect } from "@rig/server";
4599
4750
 
4600
4751
  // packages/cli/src/commands/_pi-install.ts
4601
- import { existsSync as existsSync9, readFileSync as readFileSync4, rmSync as rmSync4 } from "fs";
4602
- import { homedir as homedir4 } from "os";
4603
- import { resolve as resolve15 } from "path";
4752
+ import { existsSync as existsSync10, readFileSync as readFileSync5, rmSync as rmSync4 } from "fs";
4753
+ import { homedir as homedir5 } from "os";
4754
+ import { resolve as resolve16 } from "path";
4604
4755
  var PI_RIG_PACKAGE_NAME = "@h-rig/pi-rig";
4605
4756
  var LEGACY_PI_RIG_PACKAGE_NAME = "@rig/pi-rig";
4606
4757
  var LEGACY_PI_RIG_MARKER = `// Managed by Rig. Source package: @rig/pi-rig.
@@ -4616,16 +4767,16 @@ async function defaultCommandRunner(command, options = {}) {
4616
4767
  return { exitCode, stdout, stderr };
4617
4768
  }
4618
4769
  function resolvePiRigExtensionPath(homeDir) {
4619
- return resolve15(homeDir, ".pi", "agent", "extensions", "pi-rig");
4770
+ return resolve16(homeDir, ".pi", "agent", "extensions", "pi-rig");
4620
4771
  }
4621
- function resolvePiRigPackageSource(projectRoot, exists = existsSync9) {
4622
- const localPackage = resolve15(projectRoot, "packages", "pi-rig");
4623
- if (exists(resolve15(localPackage, "package.json")))
4772
+ function resolvePiRigPackageSource(projectRoot, exists = existsSync10) {
4773
+ const localPackage = resolve16(projectRoot, "packages", "pi-rig");
4774
+ if (exists(resolve16(localPackage, "package.json")))
4624
4775
  return localPackage;
4625
4776
  return `npm:${PI_RIG_PACKAGE_NAME}`;
4626
4777
  }
4627
4778
  function resolvePiHomeDir(inputHomeDir) {
4628
- return inputHomeDir ?? process.env.RIG_PI_HOME_DIR?.trim() ?? homedir4();
4779
+ return inputHomeDir ?? process.env.RIG_PI_HOME_DIR?.trim() ?? homedir5();
4629
4780
  }
4630
4781
  function piListContainsPiRig(output) {
4631
4782
  return output.split(/\r?\n/).some((line) => {
@@ -4671,13 +4822,13 @@ async function ensurePiBinaryAvailable(input) {
4671
4822
  ...next.exitCode === 0 ? {} : { error: (next.stderr || next.stdout).trim() || "pi --version failed after install" }
4672
4823
  };
4673
4824
  }
4674
- function removeManagedLegacyPiRigBridge(homeDir, exists = existsSync9) {
4825
+ function removeManagedLegacyPiRigBridge(homeDir, exists = existsSync10) {
4675
4826
  const extensionPath = resolvePiRigExtensionPath(homeDir);
4676
- const indexPath = resolve15(extensionPath, "index.ts");
4827
+ const indexPath = resolve16(extensionPath, "index.ts");
4677
4828
  if (!exists(indexPath))
4678
4829
  return;
4679
4830
  try {
4680
- const content = readFileSync4(indexPath, "utf8");
4831
+ const content = readFileSync5(indexPath, "utf8");
4681
4832
  if (content === LEGACY_PI_RIG_MARKER || content.includes("Managed by Rig. Source package: @rig/pi-rig")) {
4682
4833
  rmSync4(extensionPath, { recursive: true, force: true });
4683
4834
  }
@@ -4693,13 +4844,13 @@ async function checkPiRigInstall(input = {}) {
4693
4844
  piRig: { ok: true, label: "pi-rig global extension", detail: extensionPath }
4694
4845
  };
4695
4846
  }
4696
- const exists = input.exists ?? existsSync9;
4847
+ const exists = input.exists ?? existsSync10;
4697
4848
  const runner = input.commandRunner ?? defaultCommandRunner;
4698
4849
  const piResult = await safeRun(runner, ["pi", "--version"]);
4699
4850
  const piListResult = piResult.exitCode === 0 ? await safeRun(runner, ["pi", "list"]) : { exitCode: 1, stdout: "", stderr: "" };
4700
4851
  const listedPiRig = piListResult.exitCode === 0 && piListContainsPiRig(`${piListResult.stdout}
4701
4852
  ${piListResult.stderr}`);
4702
- const legacyBridge = exists(resolve15(extensionPath, "index.ts"));
4853
+ const legacyBridge = exists(resolve16(extensionPath, "index.ts"));
4703
4854
  const hasPiRig = listedPiRig;
4704
4855
  return {
4705
4856
  extensionPath,
@@ -4776,7 +4927,7 @@ async function buildPiSetupChecks(input = {}) {
4776
4927
 
4777
4928
  // packages/cli/src/commands/_snapshot-upload.ts
4778
4929
  import { mkdir, readdir, readFile, writeFile } from "fs/promises";
4779
- import { dirname as dirname2, resolve as resolve16, relative, sep } from "path";
4930
+ import { dirname as dirname3, resolve as resolve17, relative, sep } from "path";
4780
4931
  var SNAPSHOT_ARCHIVE_VERSION = 1;
4781
4932
  var SNAPSHOT_ARCHIVE_CONTENT_TYPE = "application/vnd.rig.snapshot+json";
4782
4933
  var DEFAULT_EXCLUDED_DIRECTORIES = new Set([
@@ -4798,15 +4949,15 @@ function assertManifestPath(root, relativePath) {
4798
4949
  if (!relativePath || relativePath.startsWith("/") || relativePath.includes("\x00")) {
4799
4950
  throw new Error(`Invalid snapshot path: ${relativePath}`);
4800
4951
  }
4801
- const resolved = resolve16(root, relativePath);
4952
+ const resolved = resolve17(root, relativePath);
4802
4953
  const relativeToRoot = relative(root, resolved);
4803
- if (relativeToRoot.startsWith("..") || relativeToRoot === ".." || resolve16(relativeToRoot) === resolved) {
4954
+ if (relativeToRoot.startsWith("..") || relativeToRoot === ".." || resolve17(relativeToRoot) === resolved) {
4804
4955
  throw new Error(`Snapshot path escapes project root: ${relativePath}`);
4805
4956
  }
4806
4957
  return resolved;
4807
4958
  }
4808
4959
  async function buildSnapshotUploadManifest(projectRoot, options = {}) {
4809
- const root = resolve16(projectRoot);
4960
+ const root = resolve17(projectRoot);
4810
4961
  const excludedDirectories = [...new Set([
4811
4962
  ...DEFAULT_EXCLUDED_DIRECTORIES,
4812
4963
  ...options.excludedDirectories ?? []
@@ -4818,7 +4969,7 @@ async function buildSnapshotUploadManifest(projectRoot, options = {}) {
4818
4969
  for (const entry of entries) {
4819
4970
  if (entry.isDirectory() && excludedSet.has(entry.name))
4820
4971
  continue;
4821
- const fullPath = resolve16(dir, entry.name);
4972
+ const fullPath = resolve17(dir, entry.name);
4822
4973
  if (entry.isDirectory()) {
4823
4974
  await visit(fullPath);
4824
4975
  continue;
@@ -4867,8 +5018,8 @@ async function uploadSnapshotArchiveViaServer(context, input) {
4867
5018
 
4868
5019
  // packages/cli/src/commands/_doctor-checks.ts
4869
5020
  init_runner();
4870
- import { existsSync as existsSync10, readFileSync as readFileSync5 } from "fs";
4871
- import { resolve as resolve17 } from "path";
5021
+ import { existsSync as existsSync11, readFileSync as readFileSync6 } from "fs";
5022
+ import { resolve as resolve18 } from "path";
4872
5023
  import { isSupportedBunVersion, MIN_SUPPORTED_BUN_VERSION } from "@rig/runtime/control-plane/setup-version";
4873
5024
  init__parsers();
4874
5025
  function check(id, label, status, detail, remediation) {
@@ -4909,11 +5060,11 @@ function repoSlugFromConfig(config) {
4909
5060
  function loadFallbackConfig(projectRoot) {
4910
5061
  const candidates = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
4911
5062
  for (const name of candidates) {
4912
- const path = resolve17(projectRoot, name);
4913
- if (!existsSync10(path))
5063
+ const path = resolve18(projectRoot, name);
5064
+ if (!existsSync11(path))
4914
5065
  continue;
4915
5066
  try {
4916
- const source = readFileSync5(path, "utf8");
5067
+ const source = readFileSync6(path, "utf8");
4917
5068
  if (name.endsWith(".json"))
4918
5069
  return JSON.parse(source);
4919
5070
  const owner = source.match(/owner\s*:\s*["']([^"']+)["']/)?.[1];
@@ -4992,7 +5143,7 @@ async function runRigDoctorChecks(options) {
4992
5143
  checks.push(check("bun", `bun >= ${MIN_SUPPORTED_BUN_VERSION}`, isSupportedBunVersion(bunVersion) ? "pass" : "fail", `found ${bunVersion}`, `Install Bun ${MIN_SUPPORTED_BUN_VERSION} or newer.`), check("git", "git", which("git") ? "pass" : "fail", which("git") ?? undefined, "Install git and ensure it is on PATH."), check("jq", "jq", which("jq") ? "pass" : "warn", which("jq") ?? undefined, "Install jq (for example `brew install jq`)."));
4993
5144
  const loadedConfig = await loadConfig(projectRoot).catch(() => null);
4994
5145
  const config = loadedConfig ?? loadFallbackConfig(projectRoot);
4995
- const hasConfigFile = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) => existsSync10(resolve17(projectRoot, name)));
5146
+ const hasConfigFile = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) => existsSync11(resolve18(projectRoot, name)));
4996
5147
  checks.push(config ? check("config", "rig.config loadable", "pass") : check("config", "rig.config loadable", hasConfigFile ? "fail" : "fail", hasConfigFile ? "config file exists but failed to load" : "missing rig.config.ts/json", "Run `rig init` or fix the config error."));
4997
5148
  const taskSourceKind = config?.taskSource?.kind;
4998
5149
  checks.push(taskSourceKind ? check("task-source", "task source configured", "pass", taskSourceKind) : check("task-source", "task source configured", "fail", "missing taskSource", "Configure taskSource in rig.config.ts."));
@@ -5111,20 +5262,20 @@ function parseRepoSlug(value) {
5111
5262
  return { owner: match[1], repo: match[2], slug: `${match[1]}/${match[2]}` };
5112
5263
  }
5113
5264
  function ensureRigPrivateDirs(projectRoot) {
5114
- const rigDir = resolve18(projectRoot, ".rig");
5115
- mkdirSync7(resolve18(rigDir, "state"), { recursive: true });
5116
- mkdirSync7(resolve18(rigDir, "logs"), { recursive: true });
5117
- mkdirSync7(resolve18(rigDir, "runs"), { recursive: true });
5118
- mkdirSync7(resolve18(rigDir, "tmp"), { recursive: true });
5119
- mkdirSync7(resolve18(projectRoot, "artifacts"), { recursive: true });
5120
- const taskConfigPath = resolve18(rigDir, "task-config.json");
5121
- if (!existsSync11(taskConfigPath))
5122
- writeFileSync5(taskConfigPath, `{}
5265
+ const rigDir = resolve19(projectRoot, ".rig");
5266
+ mkdirSync8(resolve19(rigDir, "state"), { recursive: true });
5267
+ mkdirSync8(resolve19(rigDir, "logs"), { recursive: true });
5268
+ mkdirSync8(resolve19(rigDir, "runs"), { recursive: true });
5269
+ mkdirSync8(resolve19(rigDir, "tmp"), { recursive: true });
5270
+ mkdirSync8(resolve19(projectRoot, "artifacts"), { recursive: true });
5271
+ const taskConfigPath = resolve19(rigDir, "task-config.json");
5272
+ if (!existsSync12(taskConfigPath))
5273
+ writeFileSync6(taskConfigPath, `{}
5123
5274
  `, "utf-8");
5124
5275
  }
5125
5276
  function ensureGitignoreEntries(projectRoot) {
5126
- const path = resolve18(projectRoot, ".gitignore");
5127
- const existing = existsSync11(path) ? readFileSync6(path, "utf8") : "";
5277
+ const path = resolve19(projectRoot, ".gitignore");
5278
+ const existing = existsSync12(path) ? readFileSync7(path, "utf8") : "";
5128
5279
  const entries = [".rig/state/", ".rig/logs/", ".rig/runs/", ".rig/tmp/"];
5129
5280
  const missing = entries.filter((entry) => !existing.split(/\r?\n/).includes(entry));
5130
5281
  if (missing.length === 0)
@@ -5137,17 +5288,17 @@ function ensureGitignoreEntries(projectRoot) {
5137
5288
  `, "utf8");
5138
5289
  }
5139
5290
  function ensureRigConfigPackageDependencies(projectRoot) {
5140
- const path = resolve18(projectRoot, "package.json");
5141
- const existing = existsSync11(path) ? JSON.parse(readFileSync6(path, "utf8")) : {};
5291
+ const path = resolve19(projectRoot, "package.json");
5292
+ const existing = existsSync12(path) ? JSON.parse(readFileSync7(path, "utf8")) : {};
5142
5293
  const devDependencies = existing.devDependencies && typeof existing.devDependencies === "object" && !Array.isArray(existing.devDependencies) ? { ...existing.devDependencies } : {};
5143
5294
  for (const [name, spec] of Object.entries(RIG_CONFIG_DEV_DEPENDENCIES)) {
5144
5295
  devDependencies[name] = spec;
5145
5296
  }
5146
5297
  const next = {
5147
- ...existsSync11(path) ? existing : { name: "rig-project", private: true },
5298
+ ...existsSync12(path) ? existing : { name: "rig-project", private: true },
5148
5299
  devDependencies
5149
5300
  };
5150
- writeFileSync5(path, `${JSON.stringify(next, null, 2)}
5301
+ writeFileSync6(path, `${JSON.stringify(next, null, 2)}
5151
5302
  `, "utf8");
5152
5303
  }
5153
5304
  function applyGitHubProjectConfig(source, options) {
@@ -5396,7 +5547,7 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
5396
5547
  };
5397
5548
  }
5398
5549
  function sleep2(ms) {
5399
- return new Promise((resolve19) => setTimeout(resolve19, ms));
5550
+ return new Promise((resolve20) => setTimeout(resolve20, ms));
5400
5551
  }
5401
5552
  function positiveIntFromEnv(name, fallback) {
5402
5553
  const value = Number.parseInt(process.env[name] ?? "", 10);
@@ -5425,7 +5576,7 @@ function remoteGitHubAuthMetadata(payload) {
5425
5576
  };
5426
5577
  }
5427
5578
  function writeRemoteGitHubAuthState(projectRoot, input) {
5428
- writeFileSync5(resolve18(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
5579
+ writeFileSync6(resolve19(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
5429
5580
  authenticated: true,
5430
5581
  source: input.source,
5431
5582
  storedOnServer: true,
@@ -5482,9 +5633,9 @@ async function runControlPlaneInit(context, options) {
5482
5633
  });
5483
5634
  ensureRigPrivateDirs(projectRoot);
5484
5635
  ensureGitignoreEntries(projectRoot);
5485
- const configTsPath = resolve18(projectRoot, "rig.config.ts");
5486
- const configJsonPath = resolve18(projectRoot, "rig.config.json");
5487
- const configExists = existsSync11(configTsPath) || existsSync11(configJsonPath);
5636
+ const configTsPath = resolve19(projectRoot, "rig.config.ts");
5637
+ const configJsonPath = resolve19(projectRoot, "rig.config.json");
5638
+ const configExists = existsSync12(configTsPath) || existsSync12(configJsonPath);
5488
5639
  if (!options.privateStateOnly) {
5489
5640
  if (configExists && !options.repair) {
5490
5641
  if (context.outputMode !== "json")
@@ -5496,11 +5647,11 @@ async function runControlPlaneInit(context, options) {
5496
5647
  taskSource: { kind: "github-issues", owner: repo.owner, repo: repo.repo },
5497
5648
  useStandardPlugin: true
5498
5649
  }), options);
5499
- writeFileSync5(configTsPath, source, "utf-8");
5650
+ writeFileSync6(configTsPath, source, "utf-8");
5500
5651
  }
5501
5652
  ensureRigConfigPackageDependencies(projectRoot);
5502
5653
  }
5503
- writeFileSync5(resolve18(projectRoot, ".rig", "state", "project-link.json"), `${JSON.stringify({ repoSlug: repo.slug, connection: connectionAlias, linkedAt: new Date().toISOString() }, null, 2)}
5654
+ writeFileSync6(resolve19(projectRoot, ".rig", "state", "project-link.json"), `${JSON.stringify({ repoSlug: repo.slug, connection: connectionAlias, linkedAt: new Date().toISOString() }, null, 2)}
5504
5655
  `, "utf8");
5505
5656
  const checkout = checkoutForInit(projectRoot, serverKind, options.remoteCheckout);
5506
5657
  let uploadedSnapshot = null;
@@ -5696,7 +5847,7 @@ function parseInitOptions(args) {
5696
5847
  async function runInteractiveControlPlaneInit(context, prompts) {
5697
5848
  prompts.intro?.("Initialize a Rig control-plane project");
5698
5849
  const projectRoot = context.projectRoot;
5699
- const existingConfig = existsSync11(resolve18(projectRoot, "rig.config.ts")) || existsSync11(resolve18(projectRoot, "rig.config.json"));
5850
+ const existingConfig = existsSync12(resolve19(projectRoot, "rig.config.ts")) || existsSync12(resolve19(projectRoot, "rig.config.json"));
5700
5851
  let repair = false;
5701
5852
  let privateStateOnly = false;
5702
5853
  if (existingConfig) {
@@ -5999,8 +6150,8 @@ async function executeDoctor(context, args) {
5999
6150
 
6000
6151
  // packages/cli/src/commands/_run-driver-helpers.ts
6001
6152
  init_runner();
6002
- import { readFileSync as readFileSync7 } from "fs";
6003
- import { resolve as resolve19 } from "path";
6153
+ import { readFileSync as readFileSync8 } from "fs";
6154
+ import { resolve as resolve20 } from "path";
6004
6155
  import {
6005
6156
  appendJsonlRecord as appendJsonlRecord2,
6006
6157
  readAuthorityRun as readAuthorityRun2,
@@ -6020,7 +6171,7 @@ function patchAuthorityRun(projectRoot, runId, patch) {
6020
6171
  ...patch,
6021
6172
  updatedAt: new Date().toISOString()
6022
6173
  };
6023
- writeJsonFile4(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), next);
6174
+ writeJsonFile4(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), next);
6024
6175
  return next;
6025
6176
  }
6026
6177
  function touchAuthorityRun(projectRoot, runId) {
@@ -6028,21 +6179,21 @@ function touchAuthorityRun(projectRoot, runId) {
6028
6179
  if (!current) {
6029
6180
  return;
6030
6181
  }
6031
- writeJsonFile4(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), {
6182
+ writeJsonFile4(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), {
6032
6183
  ...current,
6033
6184
  updatedAt: new Date().toISOString()
6034
6185
  });
6035
6186
  }
6036
6187
  function appendRunTimeline(projectRoot, runId, value) {
6037
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), value);
6188
+ appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), value);
6038
6189
  touchAuthorityRun(projectRoot, runId);
6039
6190
  }
6040
6191
  function appendRunLog(projectRoot, runId, value) {
6041
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "logs.jsonl"), value);
6192
+ appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "logs.jsonl"), value);
6042
6193
  touchAuthorityRun(projectRoot, runId);
6043
6194
  }
6044
6195
  function appendRunAction(projectRoot, runId, value) {
6045
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), {
6196
+ appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), {
6046
6197
  id: value.id,
6047
6198
  type: "action",
6048
6199
  actionType: value.actionType,
@@ -6113,7 +6264,7 @@ function buildRunPrompt(input) {
6113
6264
  })();
6114
6265
  const scopeText = (() => {
6115
6266
  try {
6116
- const parsed = JSON.parse(readFileSync7(resolveControlPlaneTaskConfigPath(input.projectRoot), "utf8"));
6267
+ const parsed = JSON.parse(readFileSync8(resolveControlPlaneTaskConfigPath(input.projectRoot), "utf8"));
6117
6268
  const entry = parsed[input.taskId] ?? {};
6118
6269
  const scope = Array.isArray(entry.scope) ? entry.scope.filter((item) => typeof item === "string") : [];
6119
6270
  const validation = Array.isArray(entry.validation) ? entry.validation.filter((item) => typeof item === "string") : [];
@@ -6227,8 +6378,8 @@ function renderSourceScopeValidation(task, validation) {
6227
6378
 
6228
6379
  // packages/cli/src/commands/inspect.ts
6229
6380
  init_runner();
6230
- import { existsSync as existsSync12, readFileSync as readFileSync8 } from "fs";
6231
- import { resolve as resolve20 } from "path";
6381
+ import { existsSync as existsSync13, readFileSync as readFileSync9 } from "fs";
6382
+ import { resolve as resolve21 } from "path";
6232
6383
  import {
6233
6384
  listAuthorityRuns as listAuthorityRuns2,
6234
6385
  readAuthorityRun as readAuthorityRun3,
@@ -6247,10 +6398,27 @@ async function executeInspect(context, args) {
6247
6398
  const requiredTask = requireTask(task, "rig inspect logs --task <task-id>");
6248
6399
  const latestRun = listAuthorityRuns2(context.projectRoot).map((entry) => readAuthorityRun3(context.projectRoot, entry.runId)).filter((run) => Boolean(run)).filter((run) => run.taskId === requiredTask).sort((left, right) => String(right.updatedAt ?? "").localeCompare(String(left.updatedAt ?? "")))[0];
6249
6400
  if (!latestRun) {
6250
- throw new CliError2(`No runs found for ${requiredTask}.`);
6401
+ const serverRuns = await listRunsViaServer(context, { limit: 200 }).catch(() => []);
6402
+ const serverRun = serverRuns.filter((run) => String(run.taskId ?? "") === requiredTask).sort((left, right) => String(right.updatedAt ?? "").localeCompare(String(left.updatedAt ?? "")))[0];
6403
+ if (!serverRun || typeof serverRun.runId !== "string") {
6404
+ throw new CliError2(`No runs found for ${requiredTask} (local or on the selected server).`);
6405
+ }
6406
+ const page = await getRunLogsViaServer(context, serverRun.runId, { limit: 500 });
6407
+ const entries = Array.isArray(page.entries) ? page.entries : [];
6408
+ if (context.outputMode === "text") {
6409
+ for (const entry of entries) {
6410
+ const record = entry && typeof entry === "object" ? entry : {};
6411
+ const title = String(record.title ?? "");
6412
+ const detail = String(record.detail ?? "");
6413
+ console.log([title, detail].filter(Boolean).join(" \u2014 "));
6414
+ }
6415
+ if (entries.length === 0)
6416
+ console.log(`(no log entries for run ${serverRun.runId})`);
6417
+ }
6418
+ return { ok: true, group: "inspect", command, details: { task: requiredTask, runId: serverRun.runId, source: "server", entries } };
6251
6419
  }
6252
- const logsPath = resolve20(resolveAuthorityRunDir4(context.projectRoot, latestRun.runId), "logs.jsonl");
6253
- if (!existsSync12(logsPath)) {
6420
+ const logsPath = resolve21(resolveAuthorityRunDir4(context.projectRoot, latestRun.runId), "logs.jsonl");
6421
+ if (!existsSync13(logsPath)) {
6254
6422
  throw new CliError2(`No logs found for run ${latestRun.runId}.`);
6255
6423
  }
6256
6424
  await context.runCommand(["cat", logsPath]);
@@ -6260,7 +6428,7 @@ async function executeInspect(context, args) {
6260
6428
  const { value: task, rest: remaining } = takeOption(rest, "--task");
6261
6429
  requireNoExtraArgs(remaining, "rig inspect artifacts --task <task-id>");
6262
6430
  const requiredTask = requireTask(task, "rig inspect artifacts --task <task-id>");
6263
- const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync12(path));
6431
+ const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync13(path));
6264
6432
  if (!artifactRoot) {
6265
6433
  throw new CliError2(`No artifacts found for ${requiredTask}.`);
6266
6434
  }
@@ -6317,10 +6485,10 @@ async function executeInspect(context, args) {
6317
6485
  case "failures": {
6318
6486
  requireNoExtraArgs(rest, "rig inspect failures");
6319
6487
  const failed = resolveHarnessPaths2(context.projectRoot).failedApproachesPath;
6320
- if (!existsSync12(failed)) {
6488
+ if (!existsSync13(failed)) {
6321
6489
  console.log("No failures recorded.");
6322
6490
  } else {
6323
- process.stdout.write(readFileSync8(failed, "utf-8"));
6491
+ process.stdout.write(readFileSync9(failed, "utf-8"));
6324
6492
  }
6325
6493
  return { ok: true, group: "inspect", command };
6326
6494
  }
@@ -6337,11 +6505,11 @@ async function executeInspect(context, args) {
6337
6505
  return { ok: true, group: "inspect", command };
6338
6506
  case "audit": {
6339
6507
  requireNoExtraArgs(rest, "rig inspect audit");
6340
- const auditPath = resolve20(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
6341
- if (!existsSync12(auditPath)) {
6508
+ const auditPath = resolve21(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
6509
+ if (!existsSync13(auditPath)) {
6342
6510
  console.log("No audit log found.");
6343
6511
  } else {
6344
- const lines = readFileSync8(auditPath, "utf-8").split(/\r?\n/).filter(Boolean).slice(-20);
6512
+ const lines = readFileSync9(auditPath, "utf-8").split(/\r?\n/).filter(Boolean).slice(-20);
6345
6513
  for (const line of lines) {
6346
6514
  console.log(line);
6347
6515
  }
@@ -7532,7 +7700,38 @@ function parseWsPayload(message2) {
7532
7700
  return JSON.parse(message2.data);
7533
7701
  return JSON.parse(Buffer.from(message2.data).toString("utf8"));
7534
7702
  }
7535
- async function connectWorkerStream(options, ctx, state) {
7703
+ var BRIDGE_LOCAL_COMMANDS = new Set(["detach", "quit", "q", "stop"]);
7704
+ function registerDaemonCommandsNatively(pi, options, ctx, state, commands, registered) {
7705
+ for (const command of commands) {
7706
+ const record = recordOf(command);
7707
+ const name = typeof record?.name === "string" ? record.name : "";
7708
+ if (!name || registered.has(name) || BRIDGE_LOCAL_COMMANDS.has(name))
7709
+ continue;
7710
+ registered.add(name);
7711
+ const description = typeof record?.description === "string" ? record.description : undefined;
7712
+ const source = typeof record?.source === "string" ? record.source : "worker";
7713
+ try {
7714
+ pi.registerCommand(name, {
7715
+ description: `[worker ${source}] ${description ?? ""}`.trim(),
7716
+ handler: async (args) => {
7717
+ const text2 = `/${name}${args ? ` ${args}` : ""}`;
7718
+ appendTranscript(state, "You", text2);
7719
+ try {
7720
+ const result = await runRunPiCommandViaServer(options.context, options.runId, text2);
7721
+ const message2 = typeof result.message === "string" ? result.message : "worker command accepted";
7722
+ appendTranscript(state, "System", message2);
7723
+ if (state.nativeStream)
7724
+ ctx.ui.notify(message2, "info");
7725
+ } catch (error) {
7726
+ reportBridgeError(ctx, state, error instanceof Error ? error.message : String(error));
7727
+ }
7728
+ updatePiUi(ctx, state);
7729
+ }
7730
+ });
7731
+ } catch {}
7732
+ }
7733
+ }
7734
+ async function connectWorkerStream(options, pi, ctx, state, registeredDaemonCommands) {
7536
7735
  const ready = await waitForWorkerReady(options, ctx, state);
7537
7736
  if (!ready)
7538
7737
  return;
@@ -7540,7 +7739,7 @@ async function connectWorkerStream(options, ctx, state) {
7540
7739
  const buffered = [];
7541
7740
  const wsUrl = await buildRunPiEventsWebSocketUrl(options.context, options.runId);
7542
7741
  const socket = new WebSocket(wsUrl);
7543
- const closePromise = new Promise((resolve21) => {
7742
+ const closePromise = new Promise((resolve22) => {
7544
7743
  socket.onopen = () => {
7545
7744
  state.wsConnected = true;
7546
7745
  state.status = "live worker Pi WebSocket connected";
@@ -7565,7 +7764,7 @@ async function connectWorkerStream(options, ctx, state) {
7565
7764
  state.wsConnected = false;
7566
7765
  state.status = "worker Pi WebSocket disconnected";
7567
7766
  updatePiUi(ctx, state);
7568
- resolve21();
7767
+ resolve22();
7569
7768
  };
7570
7769
  });
7571
7770
  try {
@@ -7587,6 +7786,7 @@ async function connectWorkerStream(options, ctx, state) {
7587
7786
  const record = recordOf(command);
7588
7787
  return typeof record?.name === "string" ? [`/${record.name}`] : [];
7589
7788
  });
7789
+ registerDaemonCommandsNatively(pi, options, ctx, state, commands, registeredDaemonCommands);
7590
7790
  catchupDone = true;
7591
7791
  for (const payload of buffered.splice(0))
7592
7792
  applyEnvelope(ctx, state, payload);
@@ -7601,11 +7801,11 @@ async function connectWorkerStream(options, ctx, state) {
7601
7801
  function createRemoteBashOperations(options, state, excludeFromContext) {
7602
7802
  return {
7603
7803
  exec(command, _cwd, execOptions) {
7604
- return new Promise((resolve21, reject) => {
7804
+ return new Promise((resolve22, reject) => {
7605
7805
  const pending = {
7606
7806
  command,
7607
7807
  onData: execOptions.onData,
7608
- resolve: resolve21,
7808
+ resolve: resolve22,
7609
7809
  reject,
7610
7810
  sawChunk: false
7611
7811
  };
@@ -7714,6 +7914,7 @@ function createRigWorkerPiBridgeExtension(options) {
7714
7914
  };
7715
7915
  if (options.initialMessageSent)
7716
7916
  appendTranscript(state, "System", "Initial message sent to worker Pi daemon.");
7917
+ const registeredDaemonCommands = new Set;
7717
7918
  let nativePiUiContextAvailable = false;
7718
7919
  pi.on("user_bash", (event) => {
7719
7920
  state.nativeStream = Boolean(state.nativeStream || nativePiUiContextAvailable);
@@ -7746,7 +7947,7 @@ function createRigWorkerPiBridgeExtension(options) {
7746
7947
  });
7747
7948
  return { consume: true };
7748
7949
  });
7749
- connectWorkerStream(options, ctx, state).catch((error) => {
7950
+ connectWorkerStream(options, pi, ctx, state, registeredDaemonCommands).catch((error) => {
7750
7951
  appendTranscript(state, "Error", error instanceof Error ? error.message : String(error));
7751
7952
  updatePiUi(ctx, state);
7752
7953
  });
@@ -7793,8 +7994,6 @@ async function attachRunBundledPiFrontend(context, input) {
7793
7994
  "--no-tools",
7794
7995
  "--no-builtin-tools",
7795
7996
  "--no-skills",
7796
- "--no-prompt-templates",
7797
- "--no-themes",
7798
7997
  "--no-context-files",
7799
7998
  "--no-approve"
7800
7999
  ], {
@@ -8268,6 +8467,33 @@ async function executeRun(context, args) {
8268
8467
  }
8269
8468
  return { ok: true, group: "run", command, details: restarted };
8270
8469
  }
8470
+ case "steer": {
8471
+ const runOption = takeOption(rest, "--run");
8472
+ const messageOption = takeOption(runOption.rest, "--message");
8473
+ const shortMessageOption = takeOption(messageOption.rest, "-m");
8474
+ const positionalRunId = shortMessageOption.rest.length > 0 ? shortMessageOption.rest[0] : undefined;
8475
+ const extra = positionalRunId ? shortMessageOption.rest.slice(1) : shortMessageOption.rest;
8476
+ requireNoExtraArgs(extra, "rig run steer [<run-id>|--run <id>] --message <text>");
8477
+ const runId = runOption.value ?? positionalRunId;
8478
+ const message2 = messageOption.value ?? shortMessageOption.value;
8479
+ if (!runId) {
8480
+ throw new CliError2("run steer requires a run id (positional or --run <id>).", 2);
8481
+ }
8482
+ if (!message2?.trim()) {
8483
+ throw new CliError2("run steer requires --message <text>.", 2);
8484
+ }
8485
+ if (context.dryRun) {
8486
+ if (context.outputMode === "text") {
8487
+ console.log(`[dry-run] rig run steer ${runId} --message ${JSON.stringify(message2)}`);
8488
+ }
8489
+ return { ok: true, group: "run", command, details: { runId, dryRun: true } };
8490
+ }
8491
+ await steerRunViaServer(context, runId, message2.trim());
8492
+ if (context.outputMode === "text") {
8493
+ console.log(`Steering message queued for ${runId}.`);
8494
+ }
8495
+ return { ok: true, group: "run", command, details: { runId, queued: true } };
8496
+ }
8271
8497
  case "stop": {
8272
8498
  const runOption = takeOption(rest, "--run");
8273
8499
  const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
@@ -8312,6 +8538,7 @@ async function executeRun(context, args) {
8312
8538
 
8313
8539
  // packages/cli/src/commands/server.ts
8314
8540
  init_runner();
8541
+ import { resolveRigServerCommand } from "@rig/runtime/local-server";
8315
8542
  async function executeServer(context, args, options) {
8316
8543
  const [command = "status", ...rest] = args;
8317
8544
  if (["status", "list", "add", "use"].includes(command)) {
@@ -8329,7 +8556,8 @@ async function executeServer(context, args, options) {
8329
8556
  const authTokenResult = takeOption(pending, "--auth-token");
8330
8557
  pending = authTokenResult.rest;
8331
8558
  requireNoExtraArgs(pending, "rig server start [--host <host>] [--port <n>] [--poll-ms <n>] [--auth-token <token>]");
8332
- const commandParts = ["rig-server", "start"];
8559
+ const serverCommand = resolveRigServerCommand(context.projectRoot);
8560
+ const commandParts = [serverCommand.command, ...serverCommand.commandArgs, "start"];
8333
8561
  if (hostResult.value) {
8334
8562
  commandParts.push("--host", hostResult.value);
8335
8563
  }
@@ -8352,7 +8580,8 @@ async function executeServer(context, args, options) {
8352
8580
  const eventResult = takeOption(pending, "--event");
8353
8581
  pending = eventResult.rest;
8354
8582
  requireNoExtraArgs(pending, "rig server notify-test [--event <type>]");
8355
- const commandParts = ["rig-server", "notify-test"];
8583
+ const serverCommand = resolveRigServerCommand(context.projectRoot);
8584
+ const commandParts = [serverCommand.command, ...serverCommand.commandArgs, "notify-test"];
8356
8585
  if (eventResult.value) {
8357
8586
  commandParts.push("--event", eventResult.value);
8358
8587
  }
@@ -8414,9 +8643,9 @@ async function executeServer(context, args, options) {
8414
8643
 
8415
8644
  // packages/cli/src/commands/task.ts
8416
8645
  init_runner();
8417
- import { readFileSync as readFileSync9 } from "fs";
8646
+ import { readFileSync as readFileSync10 } from "fs";
8418
8647
  import { spawnSync as spawnSync3 } from "child_process";
8419
- import { resolve as resolve21 } from "path";
8648
+ import { resolve as resolve22 } from "path";
8420
8649
  import { cancel as cancel4, confirm as confirm2, isCancel as isCancel4 } from "@clack/prompts";
8421
8650
  import {
8422
8651
  taskArtifactDir,
@@ -8594,6 +8823,7 @@ var PRIMARY_GROUPS = [
8594
8823
  { command: "show <id>|--run <id> [--raw]", description: "Show a human run summary; --raw prints the full payload.", primary: true },
8595
8824
  { command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; --follow launches native bundled Pi for live Pi runs.", primary: true },
8596
8825
  { command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
8826
+ { command: "steer <run-id> --message <text>", description: "Queue a steering message into a live worker without attaching." },
8597
8827
  { command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
8598
8828
  { command: "resume", description: "Resume the most recent interrupted local run." },
8599
8829
  { command: "restart", description: "Restart the most recent local run from a clean runtime." },
@@ -8695,6 +8925,19 @@ var ADVANCED_GROUPS = [
8695
8925
  { command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
8696
8926
  ]
8697
8927
  },
8928
+ {
8929
+ name: "pi",
8930
+ summary: "Manage Pi extension packages for this project (community extensions from npm/git).",
8931
+ usage: ["rig pi <list|add|remove|search> [args]"],
8932
+ commands: [
8933
+ { command: "list", description: "Show project and user Pi extension packages." },
8934
+ { command: "add <source>", description: "Add an npm/git Pi extension to .pi/settings.json (auto-installs at next session)." },
8935
+ { command: "remove <source>", description: "Remove an operator-added Pi extension." },
8936
+ { command: "search [term]", description: "Discover Pi extension packages on the npm registry." }
8937
+ ],
8938
+ examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
8939
+ next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
8940
+ },
8698
8941
  {
8699
8942
  name: "plugin",
8700
8943
  summary: "Plugin listing, validation, and plugin-contributed commands.",
@@ -9125,7 +9368,7 @@ async function executeTask(context, args, options) {
9125
9368
  const fileFlag = takeOption(rest.slice(1), "--file");
9126
9369
  let content;
9127
9370
  if (fileFlag.value) {
9128
- content = readFileSync9(resolve21(context.projectRoot, fileFlag.value), "utf-8");
9371
+ content = readFileSync10(resolve22(context.projectRoot, fileFlag.value), "utf-8");
9129
9372
  } else {
9130
9373
  content = await readStdin();
9131
9374
  }
@@ -9359,8 +9602,8 @@ async function executeTask(context, args, options) {
9359
9602
 
9360
9603
  // packages/cli/src/commands/task-run-driver.ts
9361
9604
  init_runner();
9362
- import { copyFileSync as copyFileSync3, existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
9363
- import { resolve as resolve22 } from "path";
9605
+ import { copyFileSync as copyFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
9606
+ import { resolve as resolve23 } from "path";
9364
9607
  import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
9365
9608
  import { createInterface as createLineInterface } from "readline";
9366
9609
  import { loadConfig as loadConfig2 } from "@rig/core/load-config";
@@ -9443,12 +9686,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
9443
9686
  return 0;
9444
9687
  let copied = 0;
9445
9688
  for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
9446
- const sourcePath = resolve22(sourceRoot, relativePath);
9447
- const targetPath = resolve22(targetRoot, relativePath);
9689
+ const sourcePath = resolve23(sourceRoot, relativePath);
9690
+ const targetPath = resolve23(targetRoot, relativePath);
9448
9691
  try {
9449
9692
  if (!statSync2(sourcePath).isFile())
9450
9693
  continue;
9451
- mkdirSync8(resolve22(targetPath, ".."), { recursive: true });
9694
+ mkdirSync9(resolve23(targetPath, ".."), { recursive: true });
9452
9695
  copyFileSync3(sourcePath, targetPath);
9453
9696
  copied += 1;
9454
9697
  } catch {}
@@ -9487,7 +9730,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
9487
9730
  return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
9488
9731
  return {
9489
9732
  RIG_BASELINE_MODE: "dirty-snapshot",
9490
- RIG_DIRTY_BASELINE_READY_FILE: resolve22(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
9733
+ RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
9491
9734
  };
9492
9735
  }
9493
9736
  function positiveInt(value, fallback) {
@@ -9598,9 +9841,9 @@ function createCommandRunner(binary) {
9598
9841
  const stderrChunks = [];
9599
9842
  child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
9600
9843
  child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
9601
- return await new Promise((resolve23) => {
9602
- child.once("error", (error) => resolve23({ exitCode: 1, stderr: error.message }));
9603
- child.once("close", (code) => resolve23({
9844
+ return await new Promise((resolve24) => {
9845
+ child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
9846
+ child.once("close", (code) => resolve24({
9604
9847
  exitCode: code ?? 1,
9605
9848
  stdout: Buffer.concat(stdoutChunks).toString("utf8"),
9606
9849
  stderr: Buffer.concat(stderrChunks).toString("utf8")
@@ -9674,7 +9917,7 @@ async function runTaskRunPostValidationLifecycle(input) {
9674
9917
  config,
9675
9918
  sourceTask: input.sourceTask,
9676
9919
  uploadedSnapshot: input.uploadedSnapshot,
9677
- artifactRoot: resolve22(input.projectRoot, "artifacts", taskId3),
9920
+ artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
9678
9921
  command: ghCommand,
9679
9922
  gitCommand,
9680
9923
  steerPi,
@@ -9804,7 +10047,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
9804
10047
  return null;
9805
10048
  }
9806
10049
  for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
9807
- const summary = readJsonFile3(resolve22(artifactDir, "validation-summary.json"), null);
10050
+ const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
9808
10051
  if (!summary || summary.status !== "fail") {
9809
10052
  continue;
9810
10053
  }
@@ -9885,9 +10128,9 @@ function readTaskRunAcceptedArtifactState(input) {
9885
10128
  if (!input.taskId || !input.workspaceDir) {
9886
10129
  return { accepted: false, reason: null };
9887
10130
  }
9888
- const artifactDir = resolve22(input.workspaceDir, "artifacts", input.taskId);
9889
- const reviewStatusPath = resolve22(artifactDir, "review-status.txt");
9890
- const taskResultPath = resolve22(artifactDir, "task-result.json");
10131
+ const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10132
+ const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10133
+ const taskResultPath = resolve23(artifactDir, "task-result.json");
9891
10134
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
9892
10135
  if (reviewStatus !== "APPROVED") {
9893
10136
  return { accepted: false, reason: null };
@@ -9924,12 +10167,12 @@ function resolveTaskRunRetryContext(input) {
9924
10167
  if (!input.taskId || !input.workspaceDir) {
9925
10168
  return { shouldRetry: false, failureDetail: null, nextPrompt: null };
9926
10169
  }
9927
- const artifactDir = resolve22(input.workspaceDir, "artifacts", input.taskId);
9928
- const reviewStatePath = resolve22(artifactDir, "review-state.json");
9929
- const reviewFeedbackPath = resolve22(artifactDir, "review-feedback.md");
9930
- const reviewStatusPath = resolve22(artifactDir, "review-status.txt");
9931
- const failedApproachesPath = resolve22(input.workspaceDir, ".rig", "state", "failed_approaches.md");
9932
- const validationSummaryPath = resolve22(artifactDir, "validation-summary.json");
10170
+ const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10171
+ const reviewStatePath = resolve23(artifactDir, "review-state.json");
10172
+ const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
10173
+ const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10174
+ const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
10175
+ const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
9933
10176
  const reviewState = readJsonFile3(reviewStatePath, null);
9934
10177
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
9935
10178
  const reviewRejected = isTaskRunReviewRejected(reviewState);
@@ -10115,11 +10358,11 @@ function appendToolTimelineFromLog(input) {
10115
10358
  });
10116
10359
  }
10117
10360
  function readTaskRunReviewStatus(reviewStatusPath) {
10118
- if (!existsSync13(reviewStatusPath)) {
10361
+ if (!existsSync14(reviewStatusPath)) {
10119
10362
  return null;
10120
10363
  }
10121
10364
  try {
10122
- const status = readFileSync10(reviewStatusPath, "utf8").trim().toUpperCase();
10365
+ const status = readFileSync11(reviewStatusPath, "utf8").trim().toUpperCase();
10123
10366
  return status === "APPROVED" || status === "REJECTED" ? status : null;
10124
10367
  } catch {
10125
10368
  return null;
@@ -10333,15 +10576,15 @@ async function executeRigOwnedTaskRun(context, input) {
10333
10576
  const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
10334
10577
  const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
10335
10578
  const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
10336
- const planningArtifactPath = resolve22("artifacts", runtimeTaskId, "implementation-plan.md");
10579
+ const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
10337
10580
  const persistedPlanning = {
10338
10581
  ...planningClassification,
10339
10582
  classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
10340
10583
  artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
10341
10584
  classifiedAt: new Date().toISOString()
10342
10585
  };
10343
- mkdirSync8(resolve22(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
10344
- writeFileSync6(resolve22(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
10586
+ mkdirSync9(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
10587
+ writeFileSync7(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
10345
10588
  `, "utf8");
10346
10589
  patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
10347
10590
  prompt = `${prompt}
@@ -10391,7 +10634,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10391
10634
  let verificationStarted = false;
10392
10635
  let reviewStarted = false;
10393
10636
  let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
10394
- let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve22(existingRunRecord.sessionPath, "..") : null;
10637
+ let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
10395
10638
  let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
10396
10639
  let latestProviderCommand = null;
10397
10640
  let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
@@ -10477,10 +10720,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10477
10720
  patchAuthorityRun(context.projectRoot, input.runId, {
10478
10721
  status: "running",
10479
10722
  worktreePath: latestRuntimeWorkspace,
10480
- artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve22(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
10723
+ artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
10481
10724
  logRoot: latestLogsDir,
10482
- sessionPath: latestSessionDir ? resolve22(latestSessionDir, "session.json") : null,
10483
- sessionLogPath: latestLogsDir ? resolve22(latestLogsDir, "agent-stdout.log") : null,
10725
+ sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
10726
+ sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
10484
10727
  branch: runtimeId
10485
10728
  });
10486
10729
  if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
@@ -10488,8 +10731,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10488
10731
  const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
10489
10732
  const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
10490
10733
  if (readyFile) {
10491
- mkdirSync8(resolve22(readyFile, ".."), { recursive: true });
10492
- writeFileSync6(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
10734
+ mkdirSync9(resolve23(readyFile, ".."), { recursive: true });
10735
+ writeFileSync7(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
10493
10736
  `, "utf8");
10494
10737
  }
10495
10738
  appendRunLog(context.projectRoot, input.runId, {
@@ -10873,7 +11116,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10873
11116
  let acceptedArtifactObservedAt = null;
10874
11117
  let acceptedArtifactPollTimer = null;
10875
11118
  let acceptedArtifactKillTimer = null;
10876
- const attemptExit = await new Promise((resolve23) => {
11119
+ const attemptExit = await new Promise((resolve24) => {
10877
11120
  let settled = false;
10878
11121
  const settle = (result) => {
10879
11122
  if (settled)
@@ -10881,7 +11124,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10881
11124
  settled = true;
10882
11125
  if (acceptedArtifactPollTimer)
10883
11126
  clearInterval(acceptedArtifactPollTimer);
10884
- resolve23(result);
11127
+ resolve24(result);
10885
11128
  };
10886
11129
  const pollAcceptedArtifacts = () => {
10887
11130
  const artifactState = readTaskRunAcceptedArtifactState({
@@ -11083,8 +11326,8 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11083
11326
  }
11084
11327
  if (planningClassification.planningRequired) {
11085
11328
  const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
11086
- const expectedPlanPath = resolve22(planWorkspace, planningArtifactPath);
11087
- if (!existsSync13(expectedPlanPath)) {
11329
+ const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
11330
+ if (!existsSync14(expectedPlanPath)) {
11088
11331
  const failedAt = new Date().toISOString();
11089
11332
  const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
11090
11333
  patchAuthorityRun(context.projectRoot, input.runId, {
@@ -11254,9 +11497,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11254
11497
  });
11255
11498
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
11256
11499
  });
11257
- const exitCode = await new Promise((resolve23) => {
11258
- child.once("error", () => resolve23(1));
11259
- child.once("close", (code) => resolve23(code ?? 1));
11500
+ const exitCode = await new Promise((resolve24) => {
11501
+ child.once("error", () => resolve24(1));
11502
+ child.once("close", (code) => resolve24(code ?? 1));
11260
11503
  });
11261
11504
  for (const pendingLog of flushPendingClaudeToolUseLogs({
11262
11505
  runId: input.runId,
@@ -11398,8 +11641,8 @@ async function executeTest(context, args) {
11398
11641
 
11399
11642
  // packages/cli/src/commands/setup.ts
11400
11643
  init_runner();
11401
- import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync7 } from "fs";
11402
- import { resolve as resolve23 } from "path";
11644
+ import { existsSync as existsSync15, mkdirSync as mkdirSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync8 } from "fs";
11645
+ import { resolve as resolve24 } from "path";
11403
11646
  import { createPluginHost } from "@rig/core";
11404
11647
  import {
11405
11648
  isSupportedBunVersion as isSupportedBunVersion2,
@@ -11454,12 +11697,12 @@ function runSetupInit(projectRoot) {
11454
11697
  const stateDir = resolveControlPlaneHostStateDir(projectRoot);
11455
11698
  const logsDir = resolveControlPlaneHostLogsDir(projectRoot);
11456
11699
  const artifactsDir = resolveControlPlaneArtifactsDir(projectRoot);
11457
- mkdirSync9(stateDir, { recursive: true });
11458
- mkdirSync9(logsDir, { recursive: true });
11459
- mkdirSync9(artifactsDir, { recursive: true });
11460
- const failuresPath = resolve23(stateDir, "failed_approaches.md");
11461
- if (!existsSync14(failuresPath)) {
11462
- writeFileSync7(failuresPath, `# Failed Approaches
11700
+ mkdirSync10(stateDir, { recursive: true });
11701
+ mkdirSync10(logsDir, { recursive: true });
11702
+ mkdirSync10(artifactsDir, { recursive: true });
11703
+ const failuresPath = resolve24(stateDir, "failed_approaches.md");
11704
+ if (!existsSync15(failuresPath)) {
11705
+ writeFileSync8(failuresPath, `# Failed Approaches
11463
11706
 
11464
11707
  `, "utf-8");
11465
11708
  }
@@ -11476,18 +11719,18 @@ async function runSetupCheck(projectRoot) {
11476
11719
  }
11477
11720
  async function runSetupPreflight(projectRoot) {
11478
11721
  await runSetupCheck(projectRoot);
11479
- const validationRoot = resolve23(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
11480
- if (existsSync14(validationRoot)) {
11722
+ const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
11723
+ if (existsSync15(validationRoot)) {
11481
11724
  const validators = readdirSync2(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
11482
11725
  for (const validator of validators) {
11483
- const script = resolve23(validationRoot, validator.name, "validate.sh");
11484
- if (existsSync14(script)) {
11726
+ const script = resolve24(validationRoot, validator.name, "validate.sh");
11727
+ if (existsSync15(script)) {
11485
11728
  console.log(`OK: validator script ${script}`);
11486
11729
  }
11487
11730
  }
11488
11731
  }
11489
- const hooksRoot = resolve23(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
11490
- if (existsSync14(hooksRoot)) {
11732
+ const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
11733
+ if (existsSync15(hooksRoot)) {
11491
11734
  const hooks = readdirSync2(hooksRoot).filter((name) => name.endsWith(".sh"));
11492
11735
  for (const hook of hooks) {
11493
11736
  console.log(`OK: hook ${hook}`);
@@ -11632,7 +11875,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
11632
11875
  ]);
11633
11876
  var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
11634
11877
  function hasInitializedRigProject(projectRoot) {
11635
- return RIG_CONFIG_FILENAMES.some((name) => existsSync15(resolve24(projectRoot, name))) || existsSync15(resolve24(projectRoot, ".rig"));
11878
+ return RIG_CONFIG_FILENAMES.some((name) => existsSync16(resolve25(projectRoot, name))) || existsSync16(resolve25(projectRoot, ".rig"));
11636
11879
  }
11637
11880
  function requireInitializedRigProject(context, group) {
11638
11881
  if (hasInitializedRigProject(context.projectRoot)) {
@@ -11658,6 +11901,7 @@ var GROUPS = new Set([
11658
11901
  "review",
11659
11902
  "git",
11660
11903
  "harness",
11904
+ "pi",
11661
11905
  "plugin",
11662
11906
  "queue",
11663
11907
  "agent",
@@ -11803,6 +12047,8 @@ async function executeGroup(context, group, args) {
11803
12047
  return executeGit(context, args);
11804
12048
  case "harness":
11805
12049
  return executeHarness(context, args);
12050
+ case "pi":
12051
+ return executePi(context, args);
11806
12052
  case "plugin":
11807
12053
  return executePlugin(context, args);
11808
12054
  case "queue":
@@ -11832,8 +12078,8 @@ async function executeGroup(context, group, args) {
11832
12078
  }
11833
12079
  }
11834
12080
  // packages/cli/src/launcher.ts
11835
- import { existsSync as existsSync16 } from "fs";
11836
- import { basename as basename2, resolve as resolve25 } from "path";
12081
+ import { existsSync as existsSync17 } from "fs";
12082
+ import { basename as basename2, resolve as resolve26 } from "path";
11837
12083
  import { loadDotEnvSecrets } from "@rig/runtime/baked-secrets";
11838
12084
  import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, resolveNearestRigProjectRoot } from "@rig/runtime/layout";
11839
12085
  function parsePolicyMode(value) {
@@ -11846,7 +12092,7 @@ function parsePolicyMode(value) {
11846
12092
  throw new Error(`Invalid --policy-mode value: ${value}. Use off|observe|enforce.`);
11847
12093
  }
11848
12094
  function hasRigProjectMarker(candidate) {
11849
- return existsSync16(resolve25(candidate, RIG_DEFINITION_DIRNAME)) || existsSync16(resolve25(candidate, RIG_STATE_DIRNAME)) || existsSync16(resolve25(candidate, "rig.config.ts")) || existsSync16(resolve25(candidate, "rig.config.json")) || existsSync16(resolve25(candidate, ".git"));
12095
+ return existsSync17(resolve26(candidate, RIG_DEFINITION_DIRNAME)) || existsSync17(resolve26(candidate, RIG_STATE_DIRNAME)) || existsSync17(resolve26(candidate, "rig.config.ts")) || existsSync17(resolve26(candidate, "rig.config.json")) || existsSync17(resolve26(candidate, ".git"));
11850
12096
  }
11851
12097
  function resolveProjectRoot({
11852
12098
  envProjectRoot,
@@ -11855,19 +12101,19 @@ function resolveProjectRoot({
11855
12101
  cwd = process.cwd()
11856
12102
  }) {
11857
12103
  if (envProjectRoot) {
11858
- return resolve25(cwd, envProjectRoot);
12104
+ return resolve26(cwd, envProjectRoot);
11859
12105
  }
11860
12106
  const fallbackImportDir = importDir ?? cwd;
11861
12107
  const execName = basename2(execPath).toLowerCase();
11862
- const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve25(execPath, "..", "..")] : [];
11863
- const candidates = [cwd, ...execCandidates, resolve25(fallbackImportDir, "..")];
12108
+ const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve26(execPath, "..", "..")] : [];
12109
+ const candidates = [cwd, ...execCandidates, resolve26(fallbackImportDir, "..")];
11864
12110
  for (const candidate of candidates) {
11865
12111
  const nearest = resolveNearestRigProjectRoot(candidate);
11866
12112
  if (hasRigProjectMarker(nearest)) {
11867
12113
  return nearest;
11868
12114
  }
11869
12115
  }
11870
- return resolve25(cwd);
12116
+ return resolve26(cwd);
11871
12117
  }
11872
12118
  function normalizeCliErrorCode(message2, isCliError) {
11873
12119
  if (message2.startsWith("Invalid --policy-mode value:")) {
@@ -11934,7 +12180,7 @@ async function runRigCli(module, options = {}) {
11934
12180
  runId: context.runId,
11935
12181
  outcome,
11936
12182
  eventsFile: context.eventBus.getEventsFile(),
11937
- policyFile: resolve25(projectRoot, "rig", "policy", "policy.json"),
12183
+ policyFile: resolve26(projectRoot, "rig", "policy", "policy.json"),
11938
12184
  policyMode: context.policyMode ?? policyMode ?? module.loadPolicy(projectRoot).mode
11939
12185
  }, null, 2));
11940
12186
  }