@h-rig/cli 0.0.6-alpha.33 → 0.0.6-alpha.35

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/src/index.js CHANGED
@@ -527,9 +527,9 @@ var init_plugin = __esm(() => {
527
527
  // packages/cli/src/commands.ts
528
528
  init_runner();
529
529
  import {
530
- existsSync as existsSync15
530
+ existsSync as existsSync16
531
531
  } from "fs";
532
- import { resolve as resolve24 } from "path";
532
+ import { resolve as resolve25 } from "path";
533
533
  import { readBuildConfig } from "@rig/runtime/build-time-config";
534
534
 
535
535
  // packages/cli/src/commands/browser.ts
@@ -2640,6 +2640,157 @@ async function executeHarness(context, args) {
2640
2640
  // packages/cli/src/commands.ts
2641
2641
  init_plugin();
2642
2642
 
2643
+ // packages/cli/src/commands/pi.ts
2644
+ init_runner();
2645
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
2646
+ import { homedir as homedir2 } from "os";
2647
+ import { dirname, resolve as resolve9 } from "path";
2648
+ function settingsPath(root) {
2649
+ return resolve9(root, ".pi", "settings.json");
2650
+ }
2651
+ function userSettingsPath() {
2652
+ return resolve9(homedir2(), ".pi", "agent", "settings.json");
2653
+ }
2654
+ function readJson(path, fallback) {
2655
+ if (!existsSync5(path))
2656
+ return fallback;
2657
+ try {
2658
+ return JSON.parse(readFileSync2(path, "utf-8"));
2659
+ } catch {
2660
+ return fallback;
2661
+ }
2662
+ }
2663
+ function packageKey(entry) {
2664
+ if (typeof entry === "string")
2665
+ return entry;
2666
+ if (entry && typeof entry === "object" && typeof entry.source === "string") {
2667
+ return entry.source;
2668
+ }
2669
+ return JSON.stringify(entry);
2670
+ }
2671
+ function writeSettings(path, settings) {
2672
+ mkdirSync5(dirname(path), { recursive: true });
2673
+ writeFileSync3(path, `${JSON.stringify(settings, null, 2)}
2674
+ `, "utf-8");
2675
+ }
2676
+ async function searchNpmForPiExtensions(term) {
2677
+ const query = encodeURIComponent(term ? `${term} pi extension` : "pi extension");
2678
+ const url = `https://registry.npmjs.org/-/v1/search?text=${query}&size=20`;
2679
+ const response = await fetch(url);
2680
+ if (!response.ok) {
2681
+ throw new CliError2(`npm registry search failed (${response.status}).`, 2);
2682
+ }
2683
+ const payload = await response.json();
2684
+ const results = [];
2685
+ for (const entry of payload.objects ?? []) {
2686
+ const pkg = entry.package;
2687
+ if (!pkg?.name)
2688
+ continue;
2689
+ const keywords = (pkg.keywords ?? []).map((k) => k.toLowerCase());
2690
+ 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");
2691
+ if (!piLike)
2692
+ continue;
2693
+ results.push({ name: pkg.name, version: pkg.version ?? "", description: pkg.description ?? "" });
2694
+ }
2695
+ return results;
2696
+ }
2697
+ async function executePi(context, args) {
2698
+ const [command = "list", ...rest] = args;
2699
+ const projectSettingsPath = settingsPath(context.projectRoot);
2700
+ const managedRecordPath = resolve9(context.projectRoot, ".rig", "state", "pi-managed-packages.json");
2701
+ switch (command) {
2702
+ case "list": {
2703
+ requireNoExtraArgs(rest, "rig pi list");
2704
+ const project = readJson(projectSettingsPath, {});
2705
+ const managed = new Set(readJson(managedRecordPath, []));
2706
+ const user = readJson(userSettingsPath(), {});
2707
+ const projectPackages = (Array.isArray(project.packages) ? project.packages : []).map((entry) => ({
2708
+ source: packageKey(entry),
2709
+ managedByRigConfig: managed.has(packageKey(entry))
2710
+ }));
2711
+ const userPackages = (Array.isArray(user.packages) ? user.packages : []).map(packageKey);
2712
+ if (context.outputMode === "text") {
2713
+ console.log("Project Pi packages (.pi/settings.json):");
2714
+ if (projectPackages.length === 0)
2715
+ console.log(" (none)");
2716
+ for (const pkg of projectPackages) {
2717
+ console.log(` ${pkg.source}${pkg.managedByRigConfig ? " [from rig.config runtime.pi.packages]" : ""}`);
2718
+ }
2719
+ console.log("User Pi packages (~/.pi/agent/settings.json):");
2720
+ if (userPackages.length === 0)
2721
+ console.log(" (none)");
2722
+ for (const pkg of userPackages)
2723
+ console.log(` ${pkg}`);
2724
+ console.log("Add more: `rig pi add <npm-package>` \xB7 discover: `rig pi search <term>`");
2725
+ }
2726
+ return { ok: true, group: "pi", command, details: { projectPackages, userPackages } };
2727
+ }
2728
+ case "add": {
2729
+ const [source, ...extra] = rest;
2730
+ requireNoExtraArgs(extra, "rig pi add <package-source>");
2731
+ if (!source) {
2732
+ throw new CliError2("Usage: rig pi add <package-source> (npm name, name@version, or git URL)", 2);
2733
+ }
2734
+ const settings = readJson(projectSettingsPath, {});
2735
+ const packages = Array.isArray(settings.packages) ? settings.packages : [];
2736
+ if (packages.some((entry) => packageKey(entry) === source)) {
2737
+ throw new CliError2(`"${source}" is already in ${projectSettingsPath}.`, 2);
2738
+ }
2739
+ writeSettings(projectSettingsPath, { ...settings, packages: [...packages, source] });
2740
+ if (context.outputMode === "text") {
2741
+ console.log(`Added ${source} to ${projectSettingsPath}.`);
2742
+ console.log("Pi installs missing packages automatically at the next session start (local and worker).");
2743
+ }
2744
+ return { ok: true, group: "pi", command, details: { source, settingsPath: projectSettingsPath } };
2745
+ }
2746
+ case "remove": {
2747
+ const [source, ...extra] = rest;
2748
+ requireNoExtraArgs(extra, "rig pi remove <package-source>");
2749
+ if (!source) {
2750
+ throw new CliError2("Usage: rig pi remove <package-source>", 2);
2751
+ }
2752
+ const managed = new Set(readJson(managedRecordPath, []));
2753
+ if (managed.has(source)) {
2754
+ throw new CliError2(`"${source}" is managed by rig.config.ts (runtime.pi.packages); remove it there instead.`, 2);
2755
+ }
2756
+ const settings = readJson(projectSettingsPath, {});
2757
+ const packages = Array.isArray(settings.packages) ? settings.packages : [];
2758
+ const next = packages.filter((entry) => packageKey(entry) !== source);
2759
+ if (next.length === packages.length) {
2760
+ throw new CliError2(`"${source}" is not in ${projectSettingsPath}.`, 2);
2761
+ }
2762
+ const nextSettings = { ...settings };
2763
+ if (next.length > 0)
2764
+ nextSettings.packages = next;
2765
+ else
2766
+ delete nextSettings.packages;
2767
+ writeSettings(projectSettingsPath, nextSettings);
2768
+ if (context.outputMode === "text") {
2769
+ console.log(`Removed ${source} from ${projectSettingsPath}.`);
2770
+ }
2771
+ return { ok: true, group: "pi", command, details: { source } };
2772
+ }
2773
+ case "search": {
2774
+ const term = rest.join(" ").trim();
2775
+ const results = await searchNpmForPiExtensions(term);
2776
+ if (context.outputMode === "text") {
2777
+ if (results.length === 0) {
2778
+ console.log(`No Pi extension packages found on npm${term ? ` for "${term}"` : ""}.`);
2779
+ } else {
2780
+ console.log(`Pi extension packages on npm${term ? ` matching "${term}"` : ""}:`);
2781
+ for (const pkg of results) {
2782
+ console.log(` ${pkg.name}@${pkg.version} ${pkg.description.slice(0, 80)}`);
2783
+ }
2784
+ console.log("Install one: `rig pi add <name>`");
2785
+ }
2786
+ }
2787
+ return { ok: true, group: "pi", command, details: { term, results } };
2788
+ }
2789
+ default:
2790
+ throw new CliError2(`Unknown pi command: ${command}. Use list|add|remove|search.`);
2791
+ }
2792
+ }
2793
+
2643
2794
  // packages/cli/src/commands/queue.ts
2644
2795
  init_runner();
2645
2796
  init__parsers();
@@ -2651,33 +2802,33 @@ import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/proj
2651
2802
 
2652
2803
  // packages/cli/src/commands/_connection-state.ts
2653
2804
  init_runner();
2654
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
2655
- import { homedir as homedir2 } from "os";
2656
- import { dirname, resolve as resolve9 } from "path";
2805
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
2806
+ import { homedir as homedir3 } from "os";
2807
+ import { dirname as dirname2, resolve as resolve10 } from "path";
2657
2808
  function resolveGlobalConnectionsPath(env = process.env) {
2658
2809
  const explicit = env.RIG_CONNECTIONS_FILE?.trim();
2659
2810
  if (explicit)
2660
- return resolve9(explicit);
2811
+ return resolve10(explicit);
2661
2812
  const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
2662
2813
  if (stateDir)
2663
- return resolve9(stateDir, "connections.json");
2664
- return resolve9(homedir2(), ".rig", "connections.json");
2814
+ return resolve10(stateDir, "connections.json");
2815
+ return resolve10(homedir3(), ".rig", "connections.json");
2665
2816
  }
2666
2817
  function resolveRepoConnectionPath(projectRoot) {
2667
- return resolve9(projectRoot, ".rig", "state", "connection.json");
2818
+ return resolve10(projectRoot, ".rig", "state", "connection.json");
2668
2819
  }
2669
2820
  function readJsonFile2(path) {
2670
- if (!existsSync5(path))
2821
+ if (!existsSync6(path))
2671
2822
  return null;
2672
2823
  try {
2673
- return JSON.parse(readFileSync2(path, "utf8"));
2824
+ return JSON.parse(readFileSync3(path, "utf8"));
2674
2825
  } catch (error) {
2675
2826
  throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
2676
2827
  }
2677
2828
  }
2678
2829
  function writeJsonFile2(path, value) {
2679
- mkdirSync5(dirname(path), { recursive: true });
2680
- writeFileSync3(path, `${JSON.stringify(value, null, 2)}
2830
+ mkdirSync6(dirname2(path), { recursive: true });
2831
+ writeFileSync4(path, `${JSON.stringify(value, null, 2)}
2681
2832
  `, "utf8");
2682
2833
  }
2683
2834
  function normalizeConnection(value) {
@@ -2754,8 +2905,8 @@ function resolveSelectedConnection(projectRoot, options = {}) {
2754
2905
 
2755
2906
  // packages/cli/src/commands/_server-client.ts
2756
2907
  init_runner();
2757
- import { existsSync as existsSync6, readFileSync as readFileSync3 } from "fs";
2758
- import { resolve as resolve10 } from "path";
2908
+ import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
2909
+ import { resolve as resolve11 } from "path";
2759
2910
  import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
2760
2911
  var scopedGitHubBearerTokens = new Map;
2761
2912
  function cleanToken(value) {
@@ -2763,22 +2914,22 @@ function cleanToken(value) {
2763
2914
  return trimmed ? trimmed : null;
2764
2915
  }
2765
2916
  function setGitHubBearerTokenForCurrentProcess(token, projectRoot) {
2766
- const scopedKey = resolve10(projectRoot ?? process.cwd());
2917
+ const scopedKey = resolve11(projectRoot ?? process.cwd());
2767
2918
  scopedGitHubBearerTokens.set(scopedKey, cleanToken(token ?? undefined));
2768
2919
  }
2769
2920
  function readPrivateRemoteSessionToken(projectRoot) {
2770
- const path = resolve10(projectRoot, ".rig", "state", "github-auth.json");
2771
- if (!existsSync6(path))
2921
+ const path = resolve11(projectRoot, ".rig", "state", "github-auth.json");
2922
+ if (!existsSync7(path))
2772
2923
  return null;
2773
2924
  try {
2774
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
2925
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
2775
2926
  return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
2776
2927
  } catch {
2777
2928
  return null;
2778
2929
  }
2779
2930
  }
2780
2931
  function readGitHubBearerTokenForRemote(projectRoot) {
2781
- const scopedKey = resolve10(projectRoot);
2932
+ const scopedKey = resolve11(projectRoot);
2782
2933
  if (scopedGitHubBearerTokens.has(scopedKey))
2783
2934
  return scopedGitHubBearerTokens.get(scopedKey) ?? null;
2784
2935
  const privateSession = readPrivateRemoteSessionToken(projectRoot);
@@ -2920,7 +3071,7 @@ async function registerProjectViaServer(context, input) {
2920
3071
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
2921
3072
  }
2922
3073
  function sleep(ms) {
2923
- return new Promise((resolve11) => setTimeout(resolve11, ms));
3074
+ return new Promise((resolve12) => setTimeout(resolve12, ms));
2924
3075
  }
2925
3076
  function isRetryableProjectRootSwitchError(error) {
2926
3077
  if (!(error instanceof Error))
@@ -3403,7 +3554,7 @@ async function executeQueue(context, args) {
3403
3554
 
3404
3555
  // packages/cli/src/commands/agent.ts
3405
3556
  init_runner();
3406
- import { resolve as resolve12 } from "path";
3557
+ import { resolve as resolve13 } from "path";
3407
3558
  import {
3408
3559
  agentId,
3409
3560
  cleanupAgentRuntime,
@@ -3413,8 +3564,8 @@ import {
3413
3564
  } from "@rig/runtime/control-plane/runtime/isolation";
3414
3565
 
3415
3566
  // packages/cli/src/commands/_authority-runs.ts
3416
- import { existsSync as existsSync7 } from "fs";
3417
- import { resolve as resolve11 } from "path";
3567
+ import { existsSync as existsSync8 } from "fs";
3568
+ import { resolve as resolve12 } from "path";
3418
3569
  import {
3419
3570
  readAuthorityRun,
3420
3571
  readJsonlFile as readJsonlFile2,
@@ -3436,8 +3587,8 @@ function normalizeRuntimeAdapter(value) {
3436
3587
  return "claude-code";
3437
3588
  }
3438
3589
  function readLatestBeadRecord(projectRoot, taskId) {
3439
- const issuesPath = resolve11(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
3440
- if (!existsSync7(issuesPath)) {
3590
+ const issuesPath = resolve12(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
3591
+ if (!existsSync8(issuesPath)) {
3441
3592
  return null;
3442
3593
  }
3443
3594
  let latest = null;
@@ -3505,7 +3656,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
3505
3656
  } else if ("errorText" in next) {
3506
3657
  delete next.errorText;
3507
3658
  }
3508
- writeJsonFile3(resolve11(resolveAuthorityRunDir(projectRoot, input.runId), "run.json"), next);
3659
+ writeJsonFile3(resolve12(resolveAuthorityRunDir(projectRoot, input.runId), "run.json"), next);
3509
3660
  return next;
3510
3661
  }
3511
3662
 
@@ -3627,10 +3778,10 @@ async function executeAgent(context, args) {
3627
3778
  status: "running",
3628
3779
  startedAt: createdAt,
3629
3780
  worktreePath: runtime.workspaceDir,
3630
- artifactRoot: resolve12(runtime.workspaceDir, "artifacts", taskId),
3781
+ artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
3631
3782
  logRoot: runtime.logsDir,
3632
- sessionPath: resolve12(runtime.sessionDir, "session.json"),
3633
- sessionLogPath: resolve12(runtime.logsDir, "agent-stdout.log"),
3783
+ sessionPath: resolve13(runtime.sessionDir, "session.json"),
3784
+ sessionLogPath: resolve13(runtime.logsDir, "agent-stdout.log"),
3634
3785
  pid: process.pid
3635
3786
  });
3636
3787
  const result = await runInAgentRuntime({
@@ -3650,10 +3801,10 @@ async function executeAgent(context, args) {
3650
3801
  startedAt: createdAt,
3651
3802
  completedAt: failedAt,
3652
3803
  worktreePath: runtime.workspaceDir,
3653
- artifactRoot: resolve12(runtime.workspaceDir, "artifacts", taskId),
3804
+ artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
3654
3805
  logRoot: runtime.logsDir,
3655
- sessionPath: resolve12(runtime.sessionDir, "session.json"),
3656
- sessionLogPath: resolve12(runtime.logsDir, "agent-stdout.log"),
3806
+ sessionPath: resolve13(runtime.sessionDir, "session.json"),
3807
+ sessionLogPath: resolve13(runtime.logsDir, "agent-stdout.log"),
3657
3808
  pid: process.pid,
3658
3809
  errorText: result.stderr ? result.stderr.trim() : `Agent runtime command failed (${result.exitCode})`
3659
3810
  });
@@ -3670,10 +3821,10 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
3670
3821
  startedAt: createdAt,
3671
3822
  completedAt,
3672
3823
  worktreePath: runtime.workspaceDir,
3673
- artifactRoot: resolve12(runtime.workspaceDir, "artifacts", taskId),
3824
+ artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
3674
3825
  logRoot: runtime.logsDir,
3675
- sessionPath: resolve12(runtime.sessionDir, "session.json"),
3676
- sessionLogPath: resolve12(runtime.logsDir, "agent-stdout.log"),
3826
+ sessionPath: resolve13(runtime.sessionDir, "session.json"),
3827
+ sessionLogPath: resolve13(runtime.logsDir, "agent-stdout.log"),
3677
3828
  pid: process.pid
3678
3829
  });
3679
3830
  return {
@@ -3749,8 +3900,8 @@ init__parsers();
3749
3900
  import {
3750
3901
  chmodSync,
3751
3902
  copyFileSync as copyFileSync2,
3752
- existsSync as existsSync8,
3753
- mkdirSync as mkdirSync6,
3903
+ existsSync as existsSync9,
3904
+ mkdirSync as mkdirSync7,
3754
3905
  readdirSync,
3755
3906
  readlinkSync,
3756
3907
  rmSync as rmSync3,
@@ -3758,8 +3909,8 @@ import {
3758
3909
  symlinkSync,
3759
3910
  unlinkSync
3760
3911
  } from "fs";
3761
- import { homedir as homedir3 } from "os";
3762
- import { resolve as resolve13 } from "path";
3912
+ import { homedir as homedir4 } from "os";
3913
+ import { resolve as resolve14 } from "path";
3763
3914
  import { buildBinary as buildBinary2 } from "@rig/runtime/control-plane/runtime/isolation";
3764
3915
  import {
3765
3916
  computeRuntimeImageFingerprint,
@@ -3778,13 +3929,13 @@ async function runQuietBinaryProbe(binaryPath, args, cwd) {
3778
3929
 
3779
3930
  // packages/cli/src/commands/dist.ts
3780
3931
  function collectRigValidatorBuildTargets(input) {
3781
- const validatorsRoot = resolve13(input.hostProjectRoot, "packages/runtime/src/control-plane/validators");
3782
- if (!existsSync8(validatorsRoot))
3932
+ const validatorsRoot = resolve14(input.hostProjectRoot, "packages/runtime/src/control-plane/validators");
3933
+ if (!existsSync9(validatorsRoot))
3783
3934
  return [];
3784
3935
  const targets = [];
3785
3936
  const categories = readdirSync(validatorsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
3786
3937
  for (const category of categories) {
3787
- const categoryDir = resolve13(validatorsRoot, category.name);
3938
+ const categoryDir = resolve14(validatorsRoot, category.name);
3788
3939
  for (const entry of readdirSync(categoryDir, { withFileTypes: true })) {
3789
3940
  if (!entry.isFile() || !entry.name.endsWith(".ts"))
3790
3941
  continue;
@@ -3793,7 +3944,7 @@ function collectRigValidatorBuildTargets(input) {
3793
3944
  continue;
3794
3945
  targets.push({
3795
3946
  source: `packages/runtime/src/control-plane/validators/${category.name}/${entry.name}`,
3796
- dest: resolve13(input.imageDir, `bin/validators/${category.name}-${check}`),
3947
+ dest: resolve14(input.imageDir, `bin/validators/${category.name}-${check}`),
3797
3948
  cwd: input.hostProjectRoot
3798
3949
  });
3799
3950
  }
@@ -3802,16 +3953,16 @@ function collectRigValidatorBuildTargets(input) {
3802
3953
  }
3803
3954
  async function findLatestDistBinary(projectRoot) {
3804
3955
  const distRoot = resolveControlPlaneHostDistDir(projectRoot);
3805
- if (!existsSync8(distRoot)) {
3956
+ if (!existsSync9(distRoot)) {
3806
3957
  return null;
3807
3958
  }
3808
3959
  const entries = readdirSync(distRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.startsWith("rig-")).map((entry) => ({
3809
3960
  name: entry.name,
3810
- mtimeMs: statSync(resolve13(distRoot, entry.name)).mtimeMs
3961
+ mtimeMs: statSync(resolve14(distRoot, entry.name)).mtimeMs
3811
3962
  })).sort((a, b) => b.mtimeMs - a.mtimeMs || b.name.localeCompare(a.name));
3812
3963
  for (const { name } of entries) {
3813
- const candidate = resolve13(distRoot, name, "bin", "rig");
3814
- if (existsSync8(candidate) && await isRunnableRigBinary(candidate, projectRoot)) {
3964
+ const candidate = resolve14(distRoot, name, "bin", "rig");
3965
+ if (existsSync9(candidate) && await isRunnableRigBinary(candidate, projectRoot)) {
3815
3966
  return candidate;
3816
3967
  }
3817
3968
  }
@@ -3823,7 +3974,7 @@ async function isRunnableRigBinary(binaryPath, projectRoot) {
3823
3974
  async function runDistDoctor(projectRoot) {
3824
3975
  const bunPath = Bun.which("bun");
3825
3976
  const rigPath = Bun.which("rig");
3826
- const userBinDir = resolve13(homedir3(), ".local/bin");
3977
+ const userBinDir = resolve14(homedir4(), ".local/bin");
3827
3978
  const userBinInPath = (process.env.PATH || "").split(":").filter(Boolean).includes(userBinDir);
3828
3979
  let rigRunnable = false;
3829
3980
  if (rigPath) {
@@ -3867,19 +4018,19 @@ async function executeDist(context, args) {
3867
4018
  requireNoExtraArgs(pending, "rig dist install [--scope user|system] [--path <dir>]");
3868
4019
  const scope = parseInstallScope(scopeResult.value);
3869
4020
  const installDir = resolveInstallDir(scope, pathResult.value);
3870
- mkdirSync6(installDir, { recursive: true });
4021
+ mkdirSync7(installDir, { recursive: true });
3871
4022
  let source = await findLatestDistBinary(context.projectRoot);
3872
4023
  let buildDir = null;
3873
4024
  if (!source) {
3874
- buildDir = resolve13(resolveControlPlaneHostDistDir(context.projectRoot), `rig-install-${Date.now()}`);
4025
+ buildDir = resolve14(resolveControlPlaneHostDistDir(context.projectRoot), `rig-install-${Date.now()}`);
3875
4026
  await context.runCommand(["bun", "run", "packages/cli/bin/build-rig-binaries.ts", "--output-dir", buildDir]);
3876
- source = resolve13(buildDir, "bin", "rig");
4027
+ source = resolve14(buildDir, "bin", "rig");
3877
4028
  }
3878
- if (!existsSync8(source)) {
4029
+ if (!existsSync9(source)) {
3879
4030
  throw new CliError2(`Unable to locate rig binary at ${source}.`, 2);
3880
4031
  }
3881
- const installedPath = resolve13(installDir, "rig");
3882
- if (existsSync8(installedPath)) {
4032
+ const installedPath = resolve14(installDir, "rig");
4033
+ if (existsSync9(installedPath)) {
3883
4034
  unlinkSync(installedPath);
3884
4035
  }
3885
4036
  copyFileSync2(source, installedPath);
@@ -3921,22 +4072,22 @@ async function executeDist(context, args) {
3921
4072
  requireNoExtraArgs(rest, "rig dist rebuild-agent");
3922
4073
  const fp = await computeRuntimeImageFingerprint(context.projectRoot);
3923
4074
  const currentId = computeRuntimeImageId(fp);
3924
- const imagesDir = resolve13(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
3925
- mkdirSync6(imagesDir, { recursive: true });
4075
+ const imagesDir = resolve14(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
4076
+ mkdirSync7(imagesDir, { recursive: true });
3926
4077
  let pruned = 0;
3927
4078
  for (const entry of readdirSync(imagesDir, { withFileTypes: true })) {
3928
4079
  if (entry.isDirectory() && entry.name !== currentId) {
3929
- rmSync3(resolve13(imagesDir, entry.name), { recursive: true, force: true });
4080
+ rmSync3(resolve14(imagesDir, entry.name), { recursive: true, force: true });
3930
4081
  pruned++;
3931
4082
  }
3932
4083
  }
3933
4084
  if (pruned > 0 && context.outputMode === "text") {
3934
4085
  console.log(`Pruned ${pruned} stale image(s).`);
3935
4086
  }
3936
- const imageDir = resolve13(imagesDir, currentId);
3937
- mkdirSync6(resolve13(imageDir, "bin/hooks"), { recursive: true });
3938
- mkdirSync6(resolve13(imageDir, "bin/plugins"), { recursive: true });
3939
- mkdirSync6(resolve13(imageDir, "bin/validators"), { recursive: true });
4087
+ const imageDir = resolve14(imagesDir, currentId);
4088
+ mkdirSync7(resolve14(imageDir, "bin/hooks"), { recursive: true });
4089
+ mkdirSync7(resolve14(imageDir, "bin/plugins"), { recursive: true });
4090
+ mkdirSync7(resolve14(imageDir, "bin/validators"), { recursive: true });
3940
4091
  const hookNames = [
3941
4092
  "scope-guard",
3942
4093
  "import-guard",
@@ -3950,25 +4101,25 @@ async function executeDist(context, args) {
3950
4101
  ];
3951
4102
  const targets = [];
3952
4103
  const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || context.projectRoot;
3953
- targets.push({ source: "packages/runtime/bin/rig-agent.ts", dest: resolve13(imageDir, "bin/rig-agent"), cwd: hostProjectRoot });
3954
- targets.push({ source: "packages/runtime/bin/rig-agent-dispatch.ts", dest: resolve13(resolveControlPlaneHostBinDir(context.projectRoot), "rig-agent"), cwd: hostProjectRoot });
4104
+ targets.push({ source: "packages/runtime/bin/rig-agent.ts", dest: resolve14(imageDir, "bin/rig-agent"), cwd: hostProjectRoot });
4105
+ targets.push({ source: "packages/runtime/bin/rig-agent-dispatch.ts", dest: resolve14(resolveControlPlaneHostBinDir(context.projectRoot), "rig-agent"), cwd: hostProjectRoot });
3955
4106
  for (const hookName of hookNames) {
3956
4107
  const src = `packages/runtime/src/control-plane/hooks/${hookName}.ts`;
3957
- targets.push({ source: src, dest: resolve13(imageDir, `bin/hooks/${hookName}`), cwd: hostProjectRoot });
3958
- targets.push({ source: src, dest: resolve13(resolveControlPlaneHostBinDir(context.projectRoot), `hooks/${hookName}`), cwd: hostProjectRoot });
3959
- }
3960
- const pluginsDir = resolve13(context.projectRoot, "rig/plugins");
3961
- const binPluginsDir = resolve13(resolveControlPlaneHostBinDir(context.projectRoot), "plugins");
3962
- const validatorsRoot = resolve13(hostProjectRoot, "packages/runtime/src/control-plane/validators");
3963
- const binValidatorsDir = resolve13(resolveControlPlaneHostBinDir(context.projectRoot), "validators");
3964
- mkdirSync6(binPluginsDir, { recursive: true });
3965
- mkdirSync6(binValidatorsDir, { recursive: true });
3966
- if (existsSync8(pluginsDir)) {
4108
+ targets.push({ source: src, dest: resolve14(imageDir, `bin/hooks/${hookName}`), cwd: hostProjectRoot });
4109
+ targets.push({ source: src, dest: resolve14(resolveControlPlaneHostBinDir(context.projectRoot), `hooks/${hookName}`), cwd: hostProjectRoot });
4110
+ }
4111
+ const pluginsDir = resolve14(context.projectRoot, "rig/plugins");
4112
+ const binPluginsDir = resolve14(resolveControlPlaneHostBinDir(context.projectRoot), "plugins");
4113
+ const validatorsRoot = resolve14(hostProjectRoot, "packages/runtime/src/control-plane/validators");
4114
+ const binValidatorsDir = resolve14(resolveControlPlaneHostBinDir(context.projectRoot), "validators");
4115
+ mkdirSync7(binPluginsDir, { recursive: true });
4116
+ mkdirSync7(binValidatorsDir, { recursive: true });
4117
+ if (existsSync9(pluginsDir)) {
3967
4118
  for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
3968
4119
  const m = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
3969
4120
  if (!m)
3970
4121
  continue;
3971
- targets.push({ source: `rig/plugins/${entry.name}`, dest: resolve13(imageDir, `bin/plugins/${m[1]}`), cwd: context.projectRoot });
4122
+ targets.push({ source: `rig/plugins/${entry.name}`, dest: resolve14(imageDir, `bin/plugins/${m[1]}`), cwd: context.projectRoot });
3972
4123
  }
3973
4124
  }
3974
4125
  targets.push(...collectRigValidatorBuildTargets({ contextProjectRoot: context.projectRoot, hostProjectRoot, imageDir }));
@@ -3979,17 +4130,17 @@ async function executeDist(context, args) {
3979
4130
  const isValidator = dest.includes("/bin/validators/");
3980
4131
  await buildBinary2(source, dest, cwd, isValidator ? { AGENT_BUN_PATH: Bun.which("bun") || "bun" } : { AGENT_PROJECT_ROOT: context.projectRoot });
3981
4132
  }
3982
- if (existsSync8(pluginsDir)) {
4133
+ if (existsSync9(pluginsDir)) {
3983
4134
  for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
3984
4135
  const m = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
3985
4136
  if (!m)
3986
4137
  continue;
3987
4138
  const pluginName = m[1];
3988
- const imageBin = resolve13(imageDir, `bin/plugins/${pluginName}`);
4139
+ const imageBin = resolve14(imageDir, `bin/plugins/${pluginName}`);
3989
4140
  if (!pluginName)
3990
4141
  continue;
3991
- const symlinkPath = resolve13(binPluginsDir, pluginName);
3992
- if (existsSync8(imageBin)) {
4142
+ const symlinkPath = resolve14(binPluginsDir, pluginName);
4143
+ if (existsSync9(imageBin)) {
3993
4144
  try {
3994
4145
  unlinkSync(symlinkPath);
3995
4146
  } catch {}
@@ -3997,10 +4148,10 @@ async function executeDist(context, args) {
3997
4148
  }
3998
4149
  }
3999
4150
  }
4000
- if (existsSync8(validatorsRoot)) {
4151
+ if (existsSync9(validatorsRoot)) {
4001
4152
  const categories = readdirSync(validatorsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
4002
4153
  for (const category of categories) {
4003
- const categoryDir = resolve13(validatorsRoot, category.name);
4154
+ const categoryDir = resolve14(validatorsRoot, category.name);
4004
4155
  for (const entry of readdirSync(categoryDir, { withFileTypes: true })) {
4005
4156
  if (!entry.isFile() || !entry.name.endsWith(".ts"))
4006
4157
  continue;
@@ -4008,9 +4159,9 @@ async function executeDist(context, args) {
4008
4159
  if (!check || check === "index" || check === "shared")
4009
4160
  continue;
4010
4161
  const validatorName = `${category.name}-${check}`;
4011
- const imageBin = resolve13(imageDir, `bin/validators/${validatorName}`);
4012
- const symlinkPath = resolve13(binValidatorsDir, validatorName);
4013
- if (existsSync8(imageBin)) {
4162
+ const imageBin = resolve14(imageDir, `bin/validators/${validatorName}`);
4163
+ const symlinkPath = resolve14(binValidatorsDir, validatorName);
4164
+ if (existsSync9(imageBin)) {
4014
4165
  try {
4015
4166
  unlinkSync(symlinkPath);
4016
4167
  } catch {}
@@ -4019,18 +4170,18 @@ async function executeDist(context, args) {
4019
4170
  }
4020
4171
  }
4021
4172
  }
4022
- const agentsDir = resolve13(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "agents");
4023
- if (existsSync8(agentsDir)) {
4173
+ const agentsDir = resolve14(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "agents");
4174
+ if (existsSync9(agentsDir)) {
4024
4175
  let relinkCount = 0;
4025
4176
  for (const agentEntry of readdirSync(agentsDir, { withFileTypes: true })) {
4026
4177
  if (!agentEntry.isDirectory())
4027
4178
  continue;
4028
- const agentBinDir = resolve13(agentsDir, agentEntry.name, "worktree", ".rig", "bin");
4029
- if (!existsSync8(agentBinDir))
4179
+ const agentBinDir = resolve14(agentsDir, agentEntry.name, "worktree", ".rig", "bin");
4180
+ if (!existsSync9(agentBinDir))
4030
4181
  continue;
4031
4182
  const walkDir = (dir) => {
4032
4183
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
4033
- const fullPath = resolve13(dir, entry.name);
4184
+ const fullPath = resolve14(dir, entry.name);
4034
4185
  if (entry.isDirectory()) {
4035
4186
  walkDir(fullPath);
4036
4187
  } else if (entry.isSymbolicLink()) {
@@ -4064,8 +4215,8 @@ async function executeDist(context, args) {
4064
4215
 
4065
4216
  // packages/cli/src/commands/inbox.ts
4066
4217
  init_runner();
4067
- import { writeFileSync as writeFileSync4 } from "fs";
4068
- import { resolve as resolve14 } from "path";
4218
+ import { writeFileSync as writeFileSync5 } from "fs";
4219
+ import { resolve as resolve15 } from "path";
4069
4220
  import {
4070
4221
  listAuthorityRuns,
4071
4222
  readJsonlFile as readJsonlFile3,
@@ -4467,7 +4618,7 @@ async function listRemoteInboxRecords(context, kind, filters) {
4467
4618
  function listLocalInboxRecords(context, kind, filters) {
4468
4619
  const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
4469
4620
  const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
4470
- return runs.flatMap((entry) => readJsonlFile3(resolve14(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
4621
+ return runs.flatMap((entry) => readJsonlFile3(resolve15(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
4471
4622
  runId: entry.runId,
4472
4623
  taskId: entry.taskId ?? undefined,
4473
4624
  record
@@ -4515,11 +4666,11 @@ async function executeInbox(context, args) {
4515
4666
  if (isRemoteConnectionSelected(context.projectRoot)) {
4516
4667
  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);
4517
4668
  }
4518
- const approvalsPath = resolve14(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
4669
+ const approvalsPath = resolve15(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
4519
4670
  const approvals = readJsonlFile3(approvalsPath);
4520
4671
  const resolvedAt = new Date().toISOString();
4521
4672
  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);
4522
- writeFileSync4(approvalsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
4673
+ writeFileSync5(approvalsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
4523
4674
  `)}
4524
4675
  `, "utf8");
4525
4676
  return { ok: true, group: "inbox", command, details: { runId: run.value, requestId: request.value, decision: decision.value } };
@@ -4571,11 +4722,11 @@ async function executeInbox(context, args) {
4571
4722
  const [key, ...restValue] = entry.split("=");
4572
4723
  return [key, restValue.join("=")];
4573
4724
  }));
4574
- const requestsPath = resolve14(resolveAuthorityRunDir2(context.projectRoot, run.value), "user-input.jsonl");
4725
+ const requestsPath = resolve15(resolveAuthorityRunDir2(context.projectRoot, run.value), "user-input.jsonl");
4575
4726
  const requests = readJsonlFile3(requestsPath);
4576
4727
  const resolvedAt = new Date().toISOString();
4577
4728
  const next = requests.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", answers: parsedAnswers, respondedAt: resolvedAt, resolvedAt } : entry);
4578
- writeFileSync4(requestsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
4729
+ writeFileSync5(requestsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
4579
4730
  `)}
4580
4731
  `, "utf8");
4581
4732
  return { ok: true, group: "inbox", command, details: { runId: run.value, requestId: request.value, answers: parsedAnswers } };
@@ -4587,16 +4738,16 @@ async function executeInbox(context, args) {
4587
4738
 
4588
4739
  // packages/cli/src/commands/init.ts
4589
4740
  init_runner();
4590
- import { appendFileSync as appendFileSync2, existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
4741
+ import { appendFileSync as appendFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4591
4742
  import { spawnSync } from "child_process";
4592
- import { resolve as resolve18 } from "path";
4743
+ import { resolve as resolve19 } from "path";
4593
4744
  import { buildRigInitConfigSource } from "@rig/core";
4594
4745
  import { listGitHubProjects as listGitHubProjectsDirect, resolveProjectStatusField as resolveProjectStatusFieldDirect } from "@rig/server";
4595
4746
 
4596
4747
  // packages/cli/src/commands/_pi-install.ts
4597
- import { existsSync as existsSync9, readFileSync as readFileSync4, rmSync as rmSync4 } from "fs";
4598
- import { homedir as homedir4 } from "os";
4599
- import { resolve as resolve15 } from "path";
4748
+ import { existsSync as existsSync10, readFileSync as readFileSync5, rmSync as rmSync4 } from "fs";
4749
+ import { homedir as homedir5 } from "os";
4750
+ import { resolve as resolve16 } from "path";
4600
4751
  var PI_RIG_PACKAGE_NAME = "@h-rig/pi-rig";
4601
4752
  var LEGACY_PI_RIG_PACKAGE_NAME = "@rig/pi-rig";
4602
4753
  var LEGACY_PI_RIG_MARKER = `// Managed by Rig. Source package: @rig/pi-rig.
@@ -4612,16 +4763,16 @@ async function defaultCommandRunner(command, options = {}) {
4612
4763
  return { exitCode, stdout, stderr };
4613
4764
  }
4614
4765
  function resolvePiRigExtensionPath(homeDir) {
4615
- return resolve15(homeDir, ".pi", "agent", "extensions", "pi-rig");
4766
+ return resolve16(homeDir, ".pi", "agent", "extensions", "pi-rig");
4616
4767
  }
4617
- function resolvePiRigPackageSource(projectRoot, exists = existsSync9) {
4618
- const localPackage = resolve15(projectRoot, "packages", "pi-rig");
4619
- if (exists(resolve15(localPackage, "package.json")))
4768
+ function resolvePiRigPackageSource(projectRoot, exists = existsSync10) {
4769
+ const localPackage = resolve16(projectRoot, "packages", "pi-rig");
4770
+ if (exists(resolve16(localPackage, "package.json")))
4620
4771
  return localPackage;
4621
4772
  return `npm:${PI_RIG_PACKAGE_NAME}`;
4622
4773
  }
4623
4774
  function resolvePiHomeDir(inputHomeDir) {
4624
- return inputHomeDir ?? process.env.RIG_PI_HOME_DIR?.trim() ?? homedir4();
4775
+ return inputHomeDir ?? process.env.RIG_PI_HOME_DIR?.trim() ?? homedir5();
4625
4776
  }
4626
4777
  function piListContainsPiRig(output) {
4627
4778
  return output.split(/\r?\n/).some((line) => {
@@ -4667,13 +4818,13 @@ async function ensurePiBinaryAvailable(input) {
4667
4818
  ...next.exitCode === 0 ? {} : { error: (next.stderr || next.stdout).trim() || "pi --version failed after install" }
4668
4819
  };
4669
4820
  }
4670
- function removeManagedLegacyPiRigBridge(homeDir, exists = existsSync9) {
4821
+ function removeManagedLegacyPiRigBridge(homeDir, exists = existsSync10) {
4671
4822
  const extensionPath = resolvePiRigExtensionPath(homeDir);
4672
- const indexPath = resolve15(extensionPath, "index.ts");
4823
+ const indexPath = resolve16(extensionPath, "index.ts");
4673
4824
  if (!exists(indexPath))
4674
4825
  return;
4675
4826
  try {
4676
- const content = readFileSync4(indexPath, "utf8");
4827
+ const content = readFileSync5(indexPath, "utf8");
4677
4828
  if (content === LEGACY_PI_RIG_MARKER || content.includes("Managed by Rig. Source package: @rig/pi-rig")) {
4678
4829
  rmSync4(extensionPath, { recursive: true, force: true });
4679
4830
  }
@@ -4689,13 +4840,13 @@ async function checkPiRigInstall(input = {}) {
4689
4840
  piRig: { ok: true, label: "pi-rig global extension", detail: extensionPath }
4690
4841
  };
4691
4842
  }
4692
- const exists = input.exists ?? existsSync9;
4843
+ const exists = input.exists ?? existsSync10;
4693
4844
  const runner = input.commandRunner ?? defaultCommandRunner;
4694
4845
  const piResult = await safeRun(runner, ["pi", "--version"]);
4695
4846
  const piListResult = piResult.exitCode === 0 ? await safeRun(runner, ["pi", "list"]) : { exitCode: 1, stdout: "", stderr: "" };
4696
4847
  const listedPiRig = piListResult.exitCode === 0 && piListContainsPiRig(`${piListResult.stdout}
4697
4848
  ${piListResult.stderr}`);
4698
- const legacyBridge = exists(resolve15(extensionPath, "index.ts"));
4849
+ const legacyBridge = exists(resolve16(extensionPath, "index.ts"));
4699
4850
  const hasPiRig = listedPiRig;
4700
4851
  return {
4701
4852
  extensionPath,
@@ -4772,7 +4923,7 @@ async function buildPiSetupChecks(input = {}) {
4772
4923
 
4773
4924
  // packages/cli/src/commands/_snapshot-upload.ts
4774
4925
  import { mkdir, readdir, readFile, writeFile } from "fs/promises";
4775
- import { dirname as dirname2, resolve as resolve16, relative, sep } from "path";
4926
+ import { dirname as dirname3, resolve as resolve17, relative, sep } from "path";
4776
4927
  var SNAPSHOT_ARCHIVE_VERSION = 1;
4777
4928
  var SNAPSHOT_ARCHIVE_CONTENT_TYPE = "application/vnd.rig.snapshot+json";
4778
4929
  var DEFAULT_EXCLUDED_DIRECTORIES = new Set([
@@ -4794,15 +4945,15 @@ function assertManifestPath(root, relativePath) {
4794
4945
  if (!relativePath || relativePath.startsWith("/") || relativePath.includes("\x00")) {
4795
4946
  throw new Error(`Invalid snapshot path: ${relativePath}`);
4796
4947
  }
4797
- const resolved = resolve16(root, relativePath);
4948
+ const resolved = resolve17(root, relativePath);
4798
4949
  const relativeToRoot = relative(root, resolved);
4799
- if (relativeToRoot.startsWith("..") || relativeToRoot === ".." || resolve16(relativeToRoot) === resolved) {
4950
+ if (relativeToRoot.startsWith("..") || relativeToRoot === ".." || resolve17(relativeToRoot) === resolved) {
4800
4951
  throw new Error(`Snapshot path escapes project root: ${relativePath}`);
4801
4952
  }
4802
4953
  return resolved;
4803
4954
  }
4804
4955
  async function buildSnapshotUploadManifest(projectRoot, options = {}) {
4805
- const root = resolve16(projectRoot);
4956
+ const root = resolve17(projectRoot);
4806
4957
  const excludedDirectories = [...new Set([
4807
4958
  ...DEFAULT_EXCLUDED_DIRECTORIES,
4808
4959
  ...options.excludedDirectories ?? []
@@ -4814,7 +4965,7 @@ async function buildSnapshotUploadManifest(projectRoot, options = {}) {
4814
4965
  for (const entry of entries) {
4815
4966
  if (entry.isDirectory() && excludedSet.has(entry.name))
4816
4967
  continue;
4817
- const fullPath = resolve16(dir, entry.name);
4968
+ const fullPath = resolve17(dir, entry.name);
4818
4969
  if (entry.isDirectory()) {
4819
4970
  await visit(fullPath);
4820
4971
  continue;
@@ -4863,8 +5014,8 @@ async function uploadSnapshotArchiveViaServer(context, input) {
4863
5014
 
4864
5015
  // packages/cli/src/commands/_doctor-checks.ts
4865
5016
  init_runner();
4866
- import { existsSync as existsSync10, readFileSync as readFileSync5 } from "fs";
4867
- import { resolve as resolve17 } from "path";
5017
+ import { existsSync as existsSync11, readFileSync as readFileSync6 } from "fs";
5018
+ import { resolve as resolve18 } from "path";
4868
5019
  import { isSupportedBunVersion, MIN_SUPPORTED_BUN_VERSION } from "@rig/runtime/control-plane/setup-version";
4869
5020
  init__parsers();
4870
5021
  function check(id, label, status, detail, remediation) {
@@ -4905,11 +5056,11 @@ function repoSlugFromConfig(config) {
4905
5056
  function loadFallbackConfig(projectRoot) {
4906
5057
  const candidates = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
4907
5058
  for (const name of candidates) {
4908
- const path = resolve17(projectRoot, name);
4909
- if (!existsSync10(path))
5059
+ const path = resolve18(projectRoot, name);
5060
+ if (!existsSync11(path))
4910
5061
  continue;
4911
5062
  try {
4912
- const source = readFileSync5(path, "utf8");
5063
+ const source = readFileSync6(path, "utf8");
4913
5064
  if (name.endsWith(".json"))
4914
5065
  return JSON.parse(source);
4915
5066
  const owner = source.match(/owner\s*:\s*["']([^"']+)["']/)?.[1];
@@ -4988,7 +5139,7 @@ async function runRigDoctorChecks(options) {
4988
5139
  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`)."));
4989
5140
  const loadedConfig = await loadConfig(projectRoot).catch(() => null);
4990
5141
  const config = loadedConfig ?? loadFallbackConfig(projectRoot);
4991
- const hasConfigFile = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) => existsSync10(resolve17(projectRoot, name)));
5142
+ const hasConfigFile = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) => existsSync11(resolve18(projectRoot, name)));
4992
5143
  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."));
4993
5144
  const taskSourceKind = config?.taskSource?.kind;
4994
5145
  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."));
@@ -5107,20 +5258,20 @@ function parseRepoSlug(value) {
5107
5258
  return { owner: match[1], repo: match[2], slug: `${match[1]}/${match[2]}` };
5108
5259
  }
5109
5260
  function ensureRigPrivateDirs(projectRoot) {
5110
- const rigDir = resolve18(projectRoot, ".rig");
5111
- mkdirSync7(resolve18(rigDir, "state"), { recursive: true });
5112
- mkdirSync7(resolve18(rigDir, "logs"), { recursive: true });
5113
- mkdirSync7(resolve18(rigDir, "runs"), { recursive: true });
5114
- mkdirSync7(resolve18(rigDir, "tmp"), { recursive: true });
5115
- mkdirSync7(resolve18(projectRoot, "artifacts"), { recursive: true });
5116
- const taskConfigPath = resolve18(rigDir, "task-config.json");
5117
- if (!existsSync11(taskConfigPath))
5118
- writeFileSync5(taskConfigPath, `{}
5261
+ const rigDir = resolve19(projectRoot, ".rig");
5262
+ mkdirSync8(resolve19(rigDir, "state"), { recursive: true });
5263
+ mkdirSync8(resolve19(rigDir, "logs"), { recursive: true });
5264
+ mkdirSync8(resolve19(rigDir, "runs"), { recursive: true });
5265
+ mkdirSync8(resolve19(rigDir, "tmp"), { recursive: true });
5266
+ mkdirSync8(resolve19(projectRoot, "artifacts"), { recursive: true });
5267
+ const taskConfigPath = resolve19(rigDir, "task-config.json");
5268
+ if (!existsSync12(taskConfigPath))
5269
+ writeFileSync6(taskConfigPath, `{}
5119
5270
  `, "utf-8");
5120
5271
  }
5121
5272
  function ensureGitignoreEntries(projectRoot) {
5122
- const path = resolve18(projectRoot, ".gitignore");
5123
- const existing = existsSync11(path) ? readFileSync6(path, "utf8") : "";
5273
+ const path = resolve19(projectRoot, ".gitignore");
5274
+ const existing = existsSync12(path) ? readFileSync7(path, "utf8") : "";
5124
5275
  const entries = [".rig/state/", ".rig/logs/", ".rig/runs/", ".rig/tmp/"];
5125
5276
  const missing = entries.filter((entry) => !existing.split(/\r?\n/).includes(entry));
5126
5277
  if (missing.length === 0)
@@ -5133,17 +5284,17 @@ function ensureGitignoreEntries(projectRoot) {
5133
5284
  `, "utf8");
5134
5285
  }
5135
5286
  function ensureRigConfigPackageDependencies(projectRoot) {
5136
- const path = resolve18(projectRoot, "package.json");
5137
- const existing = existsSync11(path) ? JSON.parse(readFileSync6(path, "utf8")) : {};
5287
+ const path = resolve19(projectRoot, "package.json");
5288
+ const existing = existsSync12(path) ? JSON.parse(readFileSync7(path, "utf8")) : {};
5138
5289
  const devDependencies = existing.devDependencies && typeof existing.devDependencies === "object" && !Array.isArray(existing.devDependencies) ? { ...existing.devDependencies } : {};
5139
5290
  for (const [name, spec] of Object.entries(RIG_CONFIG_DEV_DEPENDENCIES)) {
5140
5291
  devDependencies[name] = spec;
5141
5292
  }
5142
5293
  const next = {
5143
- ...existsSync11(path) ? existing : { name: "rig-project", private: true },
5294
+ ...existsSync12(path) ? existing : { name: "rig-project", private: true },
5144
5295
  devDependencies
5145
5296
  };
5146
- writeFileSync5(path, `${JSON.stringify(next, null, 2)}
5297
+ writeFileSync6(path, `${JSON.stringify(next, null, 2)}
5147
5298
  `, "utf8");
5148
5299
  }
5149
5300
  function applyGitHubProjectConfig(source, options) {
@@ -5392,7 +5543,7 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
5392
5543
  };
5393
5544
  }
5394
5545
  function sleep2(ms) {
5395
- return new Promise((resolve19) => setTimeout(resolve19, ms));
5546
+ return new Promise((resolve20) => setTimeout(resolve20, ms));
5396
5547
  }
5397
5548
  function positiveIntFromEnv(name, fallback) {
5398
5549
  const value = Number.parseInt(process.env[name] ?? "", 10);
@@ -5421,7 +5572,7 @@ function remoteGitHubAuthMetadata(payload) {
5421
5572
  };
5422
5573
  }
5423
5574
  function writeRemoteGitHubAuthState(projectRoot, input) {
5424
- writeFileSync5(resolve18(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
5575
+ writeFileSync6(resolve19(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
5425
5576
  authenticated: true,
5426
5577
  source: input.source,
5427
5578
  storedOnServer: true,
@@ -5478,9 +5629,9 @@ async function runControlPlaneInit(context, options) {
5478
5629
  });
5479
5630
  ensureRigPrivateDirs(projectRoot);
5480
5631
  ensureGitignoreEntries(projectRoot);
5481
- const configTsPath = resolve18(projectRoot, "rig.config.ts");
5482
- const configJsonPath = resolve18(projectRoot, "rig.config.json");
5483
- const configExists = existsSync11(configTsPath) || existsSync11(configJsonPath);
5632
+ const configTsPath = resolve19(projectRoot, "rig.config.ts");
5633
+ const configJsonPath = resolve19(projectRoot, "rig.config.json");
5634
+ const configExists = existsSync12(configTsPath) || existsSync12(configJsonPath);
5484
5635
  if (!options.privateStateOnly) {
5485
5636
  if (configExists && !options.repair) {
5486
5637
  if (context.outputMode !== "json")
@@ -5492,11 +5643,11 @@ async function runControlPlaneInit(context, options) {
5492
5643
  taskSource: { kind: "github-issues", owner: repo.owner, repo: repo.repo },
5493
5644
  useStandardPlugin: true
5494
5645
  }), options);
5495
- writeFileSync5(configTsPath, source, "utf-8");
5646
+ writeFileSync6(configTsPath, source, "utf-8");
5496
5647
  }
5497
5648
  ensureRigConfigPackageDependencies(projectRoot);
5498
5649
  }
5499
- writeFileSync5(resolve18(projectRoot, ".rig", "state", "project-link.json"), `${JSON.stringify({ repoSlug: repo.slug, connection: connectionAlias, linkedAt: new Date().toISOString() }, null, 2)}
5650
+ writeFileSync6(resolve19(projectRoot, ".rig", "state", "project-link.json"), `${JSON.stringify({ repoSlug: repo.slug, connection: connectionAlias, linkedAt: new Date().toISOString() }, null, 2)}
5500
5651
  `, "utf8");
5501
5652
  const checkout = checkoutForInit(projectRoot, serverKind, options.remoteCheckout);
5502
5653
  let uploadedSnapshot = null;
@@ -5692,7 +5843,7 @@ function parseInitOptions(args) {
5692
5843
  async function runInteractiveControlPlaneInit(context, prompts) {
5693
5844
  prompts.intro?.("Initialize a Rig control-plane project");
5694
5845
  const projectRoot = context.projectRoot;
5695
- const existingConfig = existsSync11(resolve18(projectRoot, "rig.config.ts")) || existsSync11(resolve18(projectRoot, "rig.config.json"));
5846
+ const existingConfig = existsSync12(resolve19(projectRoot, "rig.config.ts")) || existsSync12(resolve19(projectRoot, "rig.config.json"));
5696
5847
  let repair = false;
5697
5848
  let privateStateOnly = false;
5698
5849
  if (existingConfig) {
@@ -5995,8 +6146,8 @@ async function executeDoctor(context, args) {
5995
6146
 
5996
6147
  // packages/cli/src/commands/_run-driver-helpers.ts
5997
6148
  init_runner();
5998
- import { readFileSync as readFileSync7 } from "fs";
5999
- import { resolve as resolve19 } from "path";
6149
+ import { readFileSync as readFileSync8 } from "fs";
6150
+ import { resolve as resolve20 } from "path";
6000
6151
  import {
6001
6152
  appendJsonlRecord as appendJsonlRecord2,
6002
6153
  readAuthorityRun as readAuthorityRun2,
@@ -6016,7 +6167,7 @@ function patchAuthorityRun(projectRoot, runId, patch) {
6016
6167
  ...patch,
6017
6168
  updatedAt: new Date().toISOString()
6018
6169
  };
6019
- writeJsonFile4(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), next);
6170
+ writeJsonFile4(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), next);
6020
6171
  return next;
6021
6172
  }
6022
6173
  function touchAuthorityRun(projectRoot, runId) {
@@ -6024,21 +6175,21 @@ function touchAuthorityRun(projectRoot, runId) {
6024
6175
  if (!current) {
6025
6176
  return;
6026
6177
  }
6027
- writeJsonFile4(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), {
6178
+ writeJsonFile4(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "run.json"), {
6028
6179
  ...current,
6029
6180
  updatedAt: new Date().toISOString()
6030
6181
  });
6031
6182
  }
6032
6183
  function appendRunTimeline(projectRoot, runId, value) {
6033
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), value);
6184
+ appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), value);
6034
6185
  touchAuthorityRun(projectRoot, runId);
6035
6186
  }
6036
6187
  function appendRunLog(projectRoot, runId, value) {
6037
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "logs.jsonl"), value);
6188
+ appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "logs.jsonl"), value);
6038
6189
  touchAuthorityRun(projectRoot, runId);
6039
6190
  }
6040
6191
  function appendRunAction(projectRoot, runId, value) {
6041
- appendJsonlRecord2(resolve19(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), {
6192
+ appendJsonlRecord2(resolve20(resolveAuthorityRunDir3(projectRoot, runId), "timeline.jsonl"), {
6042
6193
  id: value.id,
6043
6194
  type: "action",
6044
6195
  actionType: value.actionType,
@@ -6109,7 +6260,7 @@ function buildRunPrompt(input) {
6109
6260
  })();
6110
6261
  const scopeText = (() => {
6111
6262
  try {
6112
- const parsed = JSON.parse(readFileSync7(resolveControlPlaneTaskConfigPath(input.projectRoot), "utf8"));
6263
+ const parsed = JSON.parse(readFileSync8(resolveControlPlaneTaskConfigPath(input.projectRoot), "utf8"));
6113
6264
  const entry = parsed[input.taskId] ?? {};
6114
6265
  const scope = Array.isArray(entry.scope) ? entry.scope.filter((item) => typeof item === "string") : [];
6115
6266
  const validation = Array.isArray(entry.validation) ? entry.validation.filter((item) => typeof item === "string") : [];
@@ -6223,8 +6374,8 @@ function renderSourceScopeValidation(task, validation) {
6223
6374
 
6224
6375
  // packages/cli/src/commands/inspect.ts
6225
6376
  init_runner();
6226
- import { existsSync as existsSync12, readFileSync as readFileSync8 } from "fs";
6227
- import { resolve as resolve20 } from "path";
6377
+ import { existsSync as existsSync13, readFileSync as readFileSync9 } from "fs";
6378
+ import { resolve as resolve21 } from "path";
6228
6379
  import {
6229
6380
  listAuthorityRuns as listAuthorityRuns2,
6230
6381
  readAuthorityRun as readAuthorityRun3,
@@ -6245,8 +6396,8 @@ async function executeInspect(context, args) {
6245
6396
  if (!latestRun) {
6246
6397
  throw new CliError2(`No runs found for ${requiredTask}.`);
6247
6398
  }
6248
- const logsPath = resolve20(resolveAuthorityRunDir4(context.projectRoot, latestRun.runId), "logs.jsonl");
6249
- if (!existsSync12(logsPath)) {
6399
+ const logsPath = resolve21(resolveAuthorityRunDir4(context.projectRoot, latestRun.runId), "logs.jsonl");
6400
+ if (!existsSync13(logsPath)) {
6250
6401
  throw new CliError2(`No logs found for run ${latestRun.runId}.`);
6251
6402
  }
6252
6403
  await context.runCommand(["cat", logsPath]);
@@ -6256,7 +6407,7 @@ async function executeInspect(context, args) {
6256
6407
  const { value: task, rest: remaining } = takeOption(rest, "--task");
6257
6408
  requireNoExtraArgs(remaining, "rig inspect artifacts --task <task-id>");
6258
6409
  const requiredTask = requireTask(task, "rig inspect artifacts --task <task-id>");
6259
- const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync12(path));
6410
+ const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync13(path));
6260
6411
  if (!artifactRoot) {
6261
6412
  throw new CliError2(`No artifacts found for ${requiredTask}.`);
6262
6413
  }
@@ -6313,10 +6464,10 @@ async function executeInspect(context, args) {
6313
6464
  case "failures": {
6314
6465
  requireNoExtraArgs(rest, "rig inspect failures");
6315
6466
  const failed = resolveHarnessPaths2(context.projectRoot).failedApproachesPath;
6316
- if (!existsSync12(failed)) {
6467
+ if (!existsSync13(failed)) {
6317
6468
  console.log("No failures recorded.");
6318
6469
  } else {
6319
- process.stdout.write(readFileSync8(failed, "utf-8"));
6470
+ process.stdout.write(readFileSync9(failed, "utf-8"));
6320
6471
  }
6321
6472
  return { ok: true, group: "inspect", command };
6322
6473
  }
@@ -6333,11 +6484,11 @@ async function executeInspect(context, args) {
6333
6484
  return { ok: true, group: "inspect", command };
6334
6485
  case "audit": {
6335
6486
  requireNoExtraArgs(rest, "rig inspect audit");
6336
- const auditPath = resolve20(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
6337
- if (!existsSync12(auditPath)) {
6487
+ const auditPath = resolve21(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
6488
+ if (!existsSync13(auditPath)) {
6338
6489
  console.log("No audit log found.");
6339
6490
  } else {
6340
- const lines = readFileSync8(auditPath, "utf-8").split(/\r?\n/).filter(Boolean).slice(-20);
6491
+ const lines = readFileSync9(auditPath, "utf-8").split(/\r?\n/).filter(Boolean).slice(-20);
6341
6492
  for (const line of lines) {
6342
6493
  console.log(line);
6343
6494
  }
@@ -7116,7 +7267,23 @@ function createPiRunStreamRenderer(output = process.stdout) {
7116
7267
  }
7117
7268
  if (entry.type === "timeline_warning") {
7118
7269
  writeLine(`[Rig timeline] ${String(entry.detail ?? entry.message ?? "timeline unavailable")}`);
7270
+ continue;
7271
+ }
7272
+ if (entry.type === "action") {
7273
+ const text2 = String(entry.detail ?? entry.message ?? entry.title ?? "").trim();
7274
+ if (text2)
7275
+ writeLine(`[Rig action] ${text2}`);
7276
+ continue;
7119
7277
  }
7278
+ if (entry.type === "user_message") {
7279
+ const text2 = String(entry.text ?? entry.message ?? entry.detail ?? "").trim();
7280
+ if (text2)
7281
+ writeLine(`[Operator] ${text2}`);
7282
+ continue;
7283
+ }
7284
+ const fallback = String(entry.detail ?? entry.message ?? entry.text ?? entry.title ?? "").trim();
7285
+ if (fallback)
7286
+ writeLine(`[${String(entry.type ?? "timeline")}] ${fallback}`);
7120
7287
  }
7121
7288
  },
7122
7289
  renderLogs(entries) {
@@ -7520,7 +7687,7 @@ async function connectWorkerStream(options, ctx, state) {
7520
7687
  const buffered = [];
7521
7688
  const wsUrl = await buildRunPiEventsWebSocketUrl(options.context, options.runId);
7522
7689
  const socket = new WebSocket(wsUrl);
7523
- const closePromise = new Promise((resolve21) => {
7690
+ const closePromise = new Promise((resolve22) => {
7524
7691
  socket.onopen = () => {
7525
7692
  state.wsConnected = true;
7526
7693
  state.status = "live worker Pi WebSocket connected";
@@ -7545,7 +7712,7 @@ async function connectWorkerStream(options, ctx, state) {
7545
7712
  state.wsConnected = false;
7546
7713
  state.status = "worker Pi WebSocket disconnected";
7547
7714
  updatePiUi(ctx, state);
7548
- resolve21();
7715
+ resolve22();
7549
7716
  };
7550
7717
  });
7551
7718
  try {
@@ -7581,11 +7748,11 @@ async function connectWorkerStream(options, ctx, state) {
7581
7748
  function createRemoteBashOperations(options, state, excludeFromContext) {
7582
7749
  return {
7583
7750
  exec(command, _cwd, execOptions) {
7584
- return new Promise((resolve21, reject) => {
7751
+ return new Promise((resolve22, reject) => {
7585
7752
  const pending = {
7586
7753
  command,
7587
7754
  onData: execOptions.onData,
7588
- resolve: resolve21,
7755
+ resolve: resolve22,
7589
7756
  reject,
7590
7757
  sawChunk: false
7591
7758
  };
@@ -8248,6 +8415,33 @@ async function executeRun(context, args) {
8248
8415
  }
8249
8416
  return { ok: true, group: "run", command, details: restarted };
8250
8417
  }
8418
+ case "steer": {
8419
+ const runOption = takeOption(rest, "--run");
8420
+ const messageOption = takeOption(runOption.rest, "--message");
8421
+ const shortMessageOption = takeOption(messageOption.rest, "-m");
8422
+ const positionalRunId = shortMessageOption.rest.length > 0 ? shortMessageOption.rest[0] : undefined;
8423
+ const extra = positionalRunId ? shortMessageOption.rest.slice(1) : shortMessageOption.rest;
8424
+ requireNoExtraArgs(extra, "rig run steer [<run-id>|--run <id>] --message <text>");
8425
+ const runId = runOption.value ?? positionalRunId;
8426
+ const message2 = messageOption.value ?? shortMessageOption.value;
8427
+ if (!runId) {
8428
+ throw new CliError2("run steer requires a run id (positional or --run <id>).", 2);
8429
+ }
8430
+ if (!message2?.trim()) {
8431
+ throw new CliError2("run steer requires --message <text>.", 2);
8432
+ }
8433
+ if (context.dryRun) {
8434
+ if (context.outputMode === "text") {
8435
+ console.log(`[dry-run] rig run steer ${runId} --message ${JSON.stringify(message2)}`);
8436
+ }
8437
+ return { ok: true, group: "run", command, details: { runId, dryRun: true } };
8438
+ }
8439
+ await steerRunViaServer(context, runId, message2.trim());
8440
+ if (context.outputMode === "text") {
8441
+ console.log(`Steering message queued for ${runId}.`);
8442
+ }
8443
+ return { ok: true, group: "run", command, details: { runId, queued: true } };
8444
+ }
8251
8445
  case "stop": {
8252
8446
  const runOption = takeOption(rest, "--run");
8253
8447
  const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
@@ -8394,9 +8588,9 @@ async function executeServer(context, args, options) {
8394
8588
 
8395
8589
  // packages/cli/src/commands/task.ts
8396
8590
  init_runner();
8397
- import { readFileSync as readFileSync9 } from "fs";
8591
+ import { readFileSync as readFileSync10 } from "fs";
8398
8592
  import { spawnSync as spawnSync3 } from "child_process";
8399
- import { resolve as resolve21 } from "path";
8593
+ import { resolve as resolve22 } from "path";
8400
8594
  import { cancel as cancel4, confirm as confirm2, isCancel as isCancel4 } from "@clack/prompts";
8401
8595
  import {
8402
8596
  taskArtifactDir,
@@ -8574,6 +8768,7 @@ var PRIMARY_GROUPS = [
8574
8768
  { command: "show <id>|--run <id> [--raw]", description: "Show a human run summary; --raw prints the full payload.", primary: true },
8575
8769
  { command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; --follow launches native bundled Pi for live Pi runs.", primary: true },
8576
8770
  { command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
8771
+ { command: "steer <run-id> --message <text>", description: "Queue a steering message into a live worker without attaching." },
8577
8772
  { command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
8578
8773
  { command: "resume", description: "Resume the most recent interrupted local run." },
8579
8774
  { command: "restart", description: "Restart the most recent local run from a clean runtime." },
@@ -8675,6 +8870,19 @@ var ADVANCED_GROUPS = [
8675
8870
  { command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
8676
8871
  ]
8677
8872
  },
8873
+ {
8874
+ name: "pi",
8875
+ summary: "Manage Pi extension packages for this project (community extensions from npm/git).",
8876
+ usage: ["rig pi <list|add|remove|search> [args]"],
8877
+ commands: [
8878
+ { command: "list", description: "Show project and user Pi extension packages." },
8879
+ { command: "add <source>", description: "Add an npm/git Pi extension to .pi/settings.json (auto-installs at next session)." },
8880
+ { command: "remove <source>", description: "Remove an operator-added Pi extension." },
8881
+ { command: "search [term]", description: "Discover Pi extension packages on the npm registry." }
8882
+ ],
8883
+ examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
8884
+ next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
8885
+ },
8678
8886
  {
8679
8887
  name: "plugin",
8680
8888
  summary: "Plugin listing, validation, and plugin-contributed commands.",
@@ -9105,7 +9313,7 @@ async function executeTask(context, args, options) {
9105
9313
  const fileFlag = takeOption(rest.slice(1), "--file");
9106
9314
  let content;
9107
9315
  if (fileFlag.value) {
9108
- content = readFileSync9(resolve21(context.projectRoot, fileFlag.value), "utf-8");
9316
+ content = readFileSync10(resolve22(context.projectRoot, fileFlag.value), "utf-8");
9109
9317
  } else {
9110
9318
  content = await readStdin();
9111
9319
  }
@@ -9339,8 +9547,8 @@ async function executeTask(context, args, options) {
9339
9547
 
9340
9548
  // packages/cli/src/commands/task-run-driver.ts
9341
9549
  init_runner();
9342
- import { copyFileSync as copyFileSync3, existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
9343
- import { resolve as resolve22 } from "path";
9550
+ import { copyFileSync as copyFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
9551
+ import { resolve as resolve23 } from "path";
9344
9552
  import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
9345
9553
  import { createInterface as createLineInterface } from "readline";
9346
9554
  import { loadConfig as loadConfig2 } from "@rig/core/load-config";
@@ -9423,12 +9631,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
9423
9631
  return 0;
9424
9632
  let copied = 0;
9425
9633
  for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
9426
- const sourcePath = resolve22(sourceRoot, relativePath);
9427
- const targetPath = resolve22(targetRoot, relativePath);
9634
+ const sourcePath = resolve23(sourceRoot, relativePath);
9635
+ const targetPath = resolve23(targetRoot, relativePath);
9428
9636
  try {
9429
9637
  if (!statSync2(sourcePath).isFile())
9430
9638
  continue;
9431
- mkdirSync8(resolve22(targetPath, ".."), { recursive: true });
9639
+ mkdirSync9(resolve23(targetPath, ".."), { recursive: true });
9432
9640
  copyFileSync3(sourcePath, targetPath);
9433
9641
  copied += 1;
9434
9642
  } catch {}
@@ -9467,7 +9675,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
9467
9675
  return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
9468
9676
  return {
9469
9677
  RIG_BASELINE_MODE: "dirty-snapshot",
9470
- RIG_DIRTY_BASELINE_READY_FILE: resolve22(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
9678
+ RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
9471
9679
  };
9472
9680
  }
9473
9681
  function positiveInt(value, fallback) {
@@ -9578,9 +9786,9 @@ function createCommandRunner(binary) {
9578
9786
  const stderrChunks = [];
9579
9787
  child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
9580
9788
  child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
9581
- return await new Promise((resolve23) => {
9582
- child.once("error", (error) => resolve23({ exitCode: 1, stderr: error.message }));
9583
- child.once("close", (code) => resolve23({
9789
+ return await new Promise((resolve24) => {
9790
+ child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
9791
+ child.once("close", (code) => resolve24({
9584
9792
  exitCode: code ?? 1,
9585
9793
  stdout: Buffer.concat(stdoutChunks).toString("utf8"),
9586
9794
  stderr: Buffer.concat(stderrChunks).toString("utf8")
@@ -9654,7 +9862,7 @@ async function runTaskRunPostValidationLifecycle(input) {
9654
9862
  config,
9655
9863
  sourceTask: input.sourceTask,
9656
9864
  uploadedSnapshot: input.uploadedSnapshot,
9657
- artifactRoot: resolve22(input.projectRoot, "artifacts", taskId3),
9865
+ artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
9658
9866
  command: ghCommand,
9659
9867
  gitCommand,
9660
9868
  steerPi,
@@ -9784,7 +9992,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
9784
9992
  return null;
9785
9993
  }
9786
9994
  for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
9787
- const summary = readJsonFile3(resolve22(artifactDir, "validation-summary.json"), null);
9995
+ const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
9788
9996
  if (!summary || summary.status !== "fail") {
9789
9997
  continue;
9790
9998
  }
@@ -9865,9 +10073,9 @@ function readTaskRunAcceptedArtifactState(input) {
9865
10073
  if (!input.taskId || !input.workspaceDir) {
9866
10074
  return { accepted: false, reason: null };
9867
10075
  }
9868
- const artifactDir = resolve22(input.workspaceDir, "artifacts", input.taskId);
9869
- const reviewStatusPath = resolve22(artifactDir, "review-status.txt");
9870
- const taskResultPath = resolve22(artifactDir, "task-result.json");
10076
+ const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10077
+ const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10078
+ const taskResultPath = resolve23(artifactDir, "task-result.json");
9871
10079
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
9872
10080
  if (reviewStatus !== "APPROVED") {
9873
10081
  return { accepted: false, reason: null };
@@ -9904,12 +10112,12 @@ function resolveTaskRunRetryContext(input) {
9904
10112
  if (!input.taskId || !input.workspaceDir) {
9905
10113
  return { shouldRetry: false, failureDetail: null, nextPrompt: null };
9906
10114
  }
9907
- const artifactDir = resolve22(input.workspaceDir, "artifacts", input.taskId);
9908
- const reviewStatePath = resolve22(artifactDir, "review-state.json");
9909
- const reviewFeedbackPath = resolve22(artifactDir, "review-feedback.md");
9910
- const reviewStatusPath = resolve22(artifactDir, "review-status.txt");
9911
- const failedApproachesPath = resolve22(input.workspaceDir, ".rig", "state", "failed_approaches.md");
9912
- const validationSummaryPath = resolve22(artifactDir, "validation-summary.json");
10115
+ const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
10116
+ const reviewStatePath = resolve23(artifactDir, "review-state.json");
10117
+ const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
10118
+ const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
10119
+ const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
10120
+ const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
9913
10121
  const reviewState = readJsonFile3(reviewStatePath, null);
9914
10122
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
9915
10123
  const reviewRejected = isTaskRunReviewRejected(reviewState);
@@ -10095,11 +10303,11 @@ function appendToolTimelineFromLog(input) {
10095
10303
  });
10096
10304
  }
10097
10305
  function readTaskRunReviewStatus(reviewStatusPath) {
10098
- if (!existsSync13(reviewStatusPath)) {
10306
+ if (!existsSync14(reviewStatusPath)) {
10099
10307
  return null;
10100
10308
  }
10101
10309
  try {
10102
- const status = readFileSync10(reviewStatusPath, "utf8").trim().toUpperCase();
10310
+ const status = readFileSync11(reviewStatusPath, "utf8").trim().toUpperCase();
10103
10311
  return status === "APPROVED" || status === "REJECTED" ? status : null;
10104
10312
  } catch {
10105
10313
  return null;
@@ -10313,15 +10521,15 @@ async function executeRigOwnedTaskRun(context, input) {
10313
10521
  const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
10314
10522
  const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
10315
10523
  const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
10316
- const planningArtifactPath = resolve22("artifacts", runtimeTaskId, "implementation-plan.md");
10524
+ const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
10317
10525
  const persistedPlanning = {
10318
10526
  ...planningClassification,
10319
10527
  classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
10320
10528
  artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
10321
10529
  classifiedAt: new Date().toISOString()
10322
10530
  };
10323
- mkdirSync8(resolve22(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
10324
- writeFileSync6(resolve22(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
10531
+ mkdirSync9(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
10532
+ writeFileSync7(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
10325
10533
  `, "utf8");
10326
10534
  patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
10327
10535
  prompt = `${prompt}
@@ -10371,7 +10579,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10371
10579
  let verificationStarted = false;
10372
10580
  let reviewStarted = false;
10373
10581
  let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
10374
- let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve22(existingRunRecord.sessionPath, "..") : null;
10582
+ let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
10375
10583
  let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
10376
10584
  let latestProviderCommand = null;
10377
10585
  let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
@@ -10457,10 +10665,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10457
10665
  patchAuthorityRun(context.projectRoot, input.runId, {
10458
10666
  status: "running",
10459
10667
  worktreePath: latestRuntimeWorkspace,
10460
- artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve22(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
10668
+ artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
10461
10669
  logRoot: latestLogsDir,
10462
- sessionPath: latestSessionDir ? resolve22(latestSessionDir, "session.json") : null,
10463
- sessionLogPath: latestLogsDir ? resolve22(latestLogsDir, "agent-stdout.log") : null,
10670
+ sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
10671
+ sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
10464
10672
  branch: runtimeId
10465
10673
  });
10466
10674
  if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
@@ -10468,8 +10676,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10468
10676
  const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
10469
10677
  const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
10470
10678
  if (readyFile) {
10471
- mkdirSync8(resolve22(readyFile, ".."), { recursive: true });
10472
- writeFileSync6(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
10679
+ mkdirSync9(resolve23(readyFile, ".."), { recursive: true });
10680
+ writeFileSync7(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
10473
10681
  `, "utf8");
10474
10682
  }
10475
10683
  appendRunLog(context.projectRoot, input.runId, {
@@ -10853,7 +11061,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10853
11061
  let acceptedArtifactObservedAt = null;
10854
11062
  let acceptedArtifactPollTimer = null;
10855
11063
  let acceptedArtifactKillTimer = null;
10856
- const attemptExit = await new Promise((resolve23) => {
11064
+ const attemptExit = await new Promise((resolve24) => {
10857
11065
  let settled = false;
10858
11066
  const settle = (result) => {
10859
11067
  if (settled)
@@ -10861,7 +11069,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
10861
11069
  settled = true;
10862
11070
  if (acceptedArtifactPollTimer)
10863
11071
  clearInterval(acceptedArtifactPollTimer);
10864
- resolve23(result);
11072
+ resolve24(result);
10865
11073
  };
10866
11074
  const pollAcceptedArtifacts = () => {
10867
11075
  const artifactState = readTaskRunAcceptedArtifactState({
@@ -11063,8 +11271,8 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11063
11271
  }
11064
11272
  if (planningClassification.planningRequired) {
11065
11273
  const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
11066
- const expectedPlanPath = resolve22(planWorkspace, planningArtifactPath);
11067
- if (!existsSync13(expectedPlanPath)) {
11274
+ const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
11275
+ if (!existsSync14(expectedPlanPath)) {
11068
11276
  const failedAt = new Date().toISOString();
11069
11277
  const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
11070
11278
  patchAuthorityRun(context.projectRoot, input.runId, {
@@ -11234,9 +11442,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
11234
11442
  });
11235
11443
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
11236
11444
  });
11237
- const exitCode = await new Promise((resolve23) => {
11238
- child.once("error", () => resolve23(1));
11239
- child.once("close", (code) => resolve23(code ?? 1));
11445
+ const exitCode = await new Promise((resolve24) => {
11446
+ child.once("error", () => resolve24(1));
11447
+ child.once("close", (code) => resolve24(code ?? 1));
11240
11448
  });
11241
11449
  for (const pendingLog of flushPendingClaudeToolUseLogs({
11242
11450
  runId: input.runId,
@@ -11378,8 +11586,8 @@ async function executeTest(context, args) {
11378
11586
 
11379
11587
  // packages/cli/src/commands/setup.ts
11380
11588
  init_runner();
11381
- import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync7 } from "fs";
11382
- import { resolve as resolve23 } from "path";
11589
+ import { existsSync as existsSync15, mkdirSync as mkdirSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync8 } from "fs";
11590
+ import { resolve as resolve24 } from "path";
11383
11591
  import { createPluginHost } from "@rig/core";
11384
11592
  import {
11385
11593
  isSupportedBunVersion as isSupportedBunVersion2,
@@ -11434,12 +11642,12 @@ function runSetupInit(projectRoot) {
11434
11642
  const stateDir = resolveControlPlaneHostStateDir(projectRoot);
11435
11643
  const logsDir = resolveControlPlaneHostLogsDir(projectRoot);
11436
11644
  const artifactsDir = resolveControlPlaneArtifactsDir(projectRoot);
11437
- mkdirSync9(stateDir, { recursive: true });
11438
- mkdirSync9(logsDir, { recursive: true });
11439
- mkdirSync9(artifactsDir, { recursive: true });
11440
- const failuresPath = resolve23(stateDir, "failed_approaches.md");
11441
- if (!existsSync14(failuresPath)) {
11442
- writeFileSync7(failuresPath, `# Failed Approaches
11645
+ mkdirSync10(stateDir, { recursive: true });
11646
+ mkdirSync10(logsDir, { recursive: true });
11647
+ mkdirSync10(artifactsDir, { recursive: true });
11648
+ const failuresPath = resolve24(stateDir, "failed_approaches.md");
11649
+ if (!existsSync15(failuresPath)) {
11650
+ writeFileSync8(failuresPath, `# Failed Approaches
11443
11651
 
11444
11652
  `, "utf-8");
11445
11653
  }
@@ -11456,18 +11664,18 @@ async function runSetupCheck(projectRoot) {
11456
11664
  }
11457
11665
  async function runSetupPreflight(projectRoot) {
11458
11666
  await runSetupCheck(projectRoot);
11459
- const validationRoot = resolve23(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
11460
- if (existsSync14(validationRoot)) {
11667
+ const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
11668
+ if (existsSync15(validationRoot)) {
11461
11669
  const validators = readdirSync2(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
11462
11670
  for (const validator of validators) {
11463
- const script = resolve23(validationRoot, validator.name, "validate.sh");
11464
- if (existsSync14(script)) {
11671
+ const script = resolve24(validationRoot, validator.name, "validate.sh");
11672
+ if (existsSync15(script)) {
11465
11673
  console.log(`OK: validator script ${script}`);
11466
11674
  }
11467
11675
  }
11468
11676
  }
11469
- const hooksRoot = resolve23(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
11470
- if (existsSync14(hooksRoot)) {
11677
+ const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
11678
+ if (existsSync15(hooksRoot)) {
11471
11679
  const hooks = readdirSync2(hooksRoot).filter((name) => name.endsWith(".sh"));
11472
11680
  for (const hook of hooks) {
11473
11681
  console.log(`OK: hook ${hook}`);
@@ -11612,7 +11820,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
11612
11820
  ]);
11613
11821
  var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
11614
11822
  function hasInitializedRigProject(projectRoot) {
11615
- return RIG_CONFIG_FILENAMES.some((name) => existsSync15(resolve24(projectRoot, name))) || existsSync15(resolve24(projectRoot, ".rig"));
11823
+ return RIG_CONFIG_FILENAMES.some((name) => existsSync16(resolve25(projectRoot, name))) || existsSync16(resolve25(projectRoot, ".rig"));
11616
11824
  }
11617
11825
  function requireInitializedRigProject(context, group) {
11618
11826
  if (hasInitializedRigProject(context.projectRoot)) {
@@ -11638,6 +11846,7 @@ var GROUPS = new Set([
11638
11846
  "review",
11639
11847
  "git",
11640
11848
  "harness",
11849
+ "pi",
11641
11850
  "plugin",
11642
11851
  "queue",
11643
11852
  "agent",
@@ -11783,6 +11992,8 @@ async function executeGroup(context, group, args) {
11783
11992
  return executeGit(context, args);
11784
11993
  case "harness":
11785
11994
  return executeHarness(context, args);
11995
+ case "pi":
11996
+ return executePi(context, args);
11786
11997
  case "plugin":
11787
11998
  return executePlugin(context, args);
11788
11999
  case "queue":
@@ -11829,8 +12040,8 @@ var __testOnly = {
11829
12040
  validateRequiredBugPromptValue
11830
12041
  };
11831
12042
  // packages/cli/src/launcher.ts
11832
- import { existsSync as existsSync16 } from "fs";
11833
- import { basename as basename2, resolve as resolve25 } from "path";
12043
+ import { existsSync as existsSync17 } from "fs";
12044
+ import { basename as basename2, resolve as resolve26 } from "path";
11834
12045
  import { loadDotEnvSecrets } from "@rig/runtime/baked-secrets";
11835
12046
  import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, resolveNearestRigProjectRoot } from "@rig/runtime/layout";
11836
12047
  function parsePolicyMode(value) {
@@ -11843,7 +12054,7 @@ function parsePolicyMode(value) {
11843
12054
  throw new Error(`Invalid --policy-mode value: ${value}. Use off|observe|enforce.`);
11844
12055
  }
11845
12056
  function hasRigProjectMarker(candidate) {
11846
- 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"));
12057
+ 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"));
11847
12058
  }
11848
12059
  function resolveProjectRoot({
11849
12060
  envProjectRoot,
@@ -11852,19 +12063,19 @@ function resolveProjectRoot({
11852
12063
  cwd = process.cwd()
11853
12064
  }) {
11854
12065
  if (envProjectRoot) {
11855
- return resolve25(cwd, envProjectRoot);
12066
+ return resolve26(cwd, envProjectRoot);
11856
12067
  }
11857
12068
  const fallbackImportDir = importDir ?? cwd;
11858
12069
  const execName = basename2(execPath).toLowerCase();
11859
- const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve25(execPath, "..", "..")] : [];
11860
- const candidates = [cwd, ...execCandidates, resolve25(fallbackImportDir, "..")];
12070
+ const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve26(execPath, "..", "..")] : [];
12071
+ const candidates = [cwd, ...execCandidates, resolve26(fallbackImportDir, "..")];
11861
12072
  for (const candidate of candidates) {
11862
12073
  const nearest = resolveNearestRigProjectRoot(candidate);
11863
12074
  if (hasRigProjectMarker(nearest)) {
11864
12075
  return nearest;
11865
12076
  }
11866
12077
  }
11867
- return resolve25(cwd);
12078
+ return resolve26(cwd);
11868
12079
  }
11869
12080
  function normalizeCliErrorCode(message2, isCliError) {
11870
12081
  if (message2.startsWith("Invalid --policy-mode value:")) {
@@ -11931,7 +12142,7 @@ async function runRigCli(module, options = {}) {
11931
12142
  runId: context.runId,
11932
12143
  outcome,
11933
12144
  eventsFile: context.eventBus.getEventsFile(),
11934
- policyFile: resolve25(projectRoot, "rig", "policy", "policy.json"),
12145
+ policyFile: resolve26(projectRoot, "rig", "policy", "policy.json"),
11935
12146
  policyMode: context.policyMode ?? policyMode ?? module.loadPolicy(projectRoot).mode
11936
12147
  }, null, 2));
11937
12148
  }