@h-rig/cli 0.0.6-alpha.34 → 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/bin/rig.js +426 -231
- package/dist/src/commands/_help-catalog.js +14 -0
- package/dist/src/commands/pi.js +168 -0
- package/dist/src/commands/run.js +27 -0
- package/dist/src/commands/task.js +14 -0
- package/dist/src/commands.js +418 -223
- package/dist/src/index.js +426 -231
- package/package.json +6 -6
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
|
|
534
|
+
existsSync as existsSync16
|
|
535
535
|
} from "fs";
|
|
536
|
-
import { resolve as
|
|
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
|
|
2659
|
-
import { homedir as
|
|
2660
|
-
import { dirname, resolve as
|
|
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
|
|
2815
|
+
return resolve10(explicit);
|
|
2665
2816
|
const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
|
|
2666
2817
|
if (stateDir)
|
|
2667
|
-
return
|
|
2668
|
-
return
|
|
2818
|
+
return resolve10(stateDir, "connections.json");
|
|
2819
|
+
return resolve10(homedir3(), ".rig", "connections.json");
|
|
2669
2820
|
}
|
|
2670
2821
|
function resolveRepoConnectionPath(projectRoot) {
|
|
2671
|
-
return
|
|
2822
|
+
return resolve10(projectRoot, ".rig", "state", "connection.json");
|
|
2672
2823
|
}
|
|
2673
2824
|
function readJsonFile2(path) {
|
|
2674
|
-
if (!
|
|
2825
|
+
if (!existsSync6(path))
|
|
2675
2826
|
return null;
|
|
2676
2827
|
try {
|
|
2677
|
-
return JSON.parse(
|
|
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
|
-
|
|
2684
|
-
|
|
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
|
|
2762
|
-
import { resolve as
|
|
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 =
|
|
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 =
|
|
2775
|
-
if (!
|
|
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(
|
|
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 =
|
|
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((
|
|
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
|
|
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
|
|
3421
|
-
import { resolve as
|
|
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 =
|
|
3444
|
-
if (!
|
|
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(
|
|
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:
|
|
3785
|
+
artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
|
|
3635
3786
|
logRoot: runtime.logsDir,
|
|
3636
|
-
sessionPath:
|
|
3637
|
-
sessionLogPath:
|
|
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:
|
|
3808
|
+
artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
|
|
3658
3809
|
logRoot: runtime.logsDir,
|
|
3659
|
-
sessionPath:
|
|
3660
|
-
sessionLogPath:
|
|
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:
|
|
3828
|
+
artifactRoot: resolve13(runtime.workspaceDir, "artifacts", taskId),
|
|
3678
3829
|
logRoot: runtime.logsDir,
|
|
3679
|
-
sessionPath:
|
|
3680
|
-
sessionLogPath:
|
|
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
|
|
3757
|
-
mkdirSync as
|
|
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
|
|
3766
|
-
import { resolve as
|
|
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 =
|
|
3786
|
-
if (!
|
|
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 =
|
|
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:
|
|
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 (!
|
|
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(
|
|
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 =
|
|
3818
|
-
if (
|
|
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 =
|
|
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
|
-
|
|
4025
|
+
mkdirSync7(installDir, { recursive: true });
|
|
3875
4026
|
let source = await findLatestDistBinary(context.projectRoot);
|
|
3876
4027
|
let buildDir = null;
|
|
3877
4028
|
if (!source) {
|
|
3878
|
-
buildDir =
|
|
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 =
|
|
4031
|
+
source = resolve14(buildDir, "bin", "rig");
|
|
3881
4032
|
}
|
|
3882
|
-
if (!
|
|
4033
|
+
if (!existsSync9(source)) {
|
|
3883
4034
|
throw new CliError2(`Unable to locate rig binary at ${source}.`, 2);
|
|
3884
4035
|
}
|
|
3885
|
-
const installedPath =
|
|
3886
|
-
if (
|
|
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 =
|
|
3929
|
-
|
|
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(
|
|
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 =
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
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:
|
|
3958
|
-
targets.push({ source: "packages/runtime/bin/rig-agent-dispatch.ts", dest:
|
|
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:
|
|
3962
|
-
targets.push({ source: src, dest:
|
|
3963
|
-
}
|
|
3964
|
-
const pluginsDir =
|
|
3965
|
-
const binPluginsDir =
|
|
3966
|
-
const validatorsRoot =
|
|
3967
|
-
const binValidatorsDir =
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
if (
|
|
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:
|
|
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 (
|
|
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 =
|
|
4143
|
+
const imageBin = resolve14(imageDir, `bin/plugins/${pluginName}`);
|
|
3993
4144
|
if (!pluginName)
|
|
3994
4145
|
continue;
|
|
3995
|
-
const symlinkPath =
|
|
3996
|
-
if (
|
|
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 (
|
|
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 =
|
|
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 =
|
|
4016
|
-
const symlinkPath =
|
|
4017
|
-
if (
|
|
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 =
|
|
4027
|
-
if (
|
|
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 =
|
|
4033
|
-
if (!
|
|
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 =
|
|
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
|
|
4072
|
-
import { resolve as
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
4602
|
-
import { homedir as
|
|
4603
|
-
import { resolve as
|
|
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
|
|
4770
|
+
return resolve16(homeDir, ".pi", "agent", "extensions", "pi-rig");
|
|
4620
4771
|
}
|
|
4621
|
-
function resolvePiRigPackageSource(projectRoot, exists =
|
|
4622
|
-
const localPackage =
|
|
4623
|
-
if (exists(
|
|
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() ??
|
|
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 =
|
|
4825
|
+
function removeManagedLegacyPiRigBridge(homeDir, exists = existsSync10) {
|
|
4675
4826
|
const extensionPath = resolvePiRigExtensionPath(homeDir);
|
|
4676
|
-
const indexPath =
|
|
4827
|
+
const indexPath = resolve16(extensionPath, "index.ts");
|
|
4677
4828
|
if (!exists(indexPath))
|
|
4678
4829
|
return;
|
|
4679
4830
|
try {
|
|
4680
|
-
const content =
|
|
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 ??
|
|
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(
|
|
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
|
|
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 =
|
|
4952
|
+
const resolved = resolve17(root, relativePath);
|
|
4802
4953
|
const relativeToRoot = relative(root, resolved);
|
|
4803
|
-
if (relativeToRoot.startsWith("..") || relativeToRoot === ".." ||
|
|
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 =
|
|
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 =
|
|
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
|
|
4871
|
-
import { resolve as
|
|
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 =
|
|
4913
|
-
if (!
|
|
5063
|
+
const path = resolve18(projectRoot, name);
|
|
5064
|
+
if (!existsSync11(path))
|
|
4914
5065
|
continue;
|
|
4915
5066
|
try {
|
|
4916
|
-
const source =
|
|
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) =>
|
|
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 =
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
const taskConfigPath =
|
|
5121
|
-
if (!
|
|
5122
|
-
|
|
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 =
|
|
5127
|
-
const existing =
|
|
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 =
|
|
5141
|
-
const existing =
|
|
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
|
-
...
|
|
5298
|
+
...existsSync12(path) ? existing : { name: "rig-project", private: true },
|
|
5148
5299
|
devDependencies
|
|
5149
5300
|
};
|
|
5150
|
-
|
|
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((
|
|
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
|
-
|
|
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 =
|
|
5486
|
-
const configJsonPath =
|
|
5487
|
-
const configExists =
|
|
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
|
-
|
|
5650
|
+
writeFileSync6(configTsPath, source, "utf-8");
|
|
5500
5651
|
}
|
|
5501
5652
|
ensureRigConfigPackageDependencies(projectRoot);
|
|
5502
5653
|
}
|
|
5503
|
-
|
|
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 =
|
|
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
|
|
6003
|
-
import { resolve as
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
6231
|
-
import { resolve as
|
|
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,
|
|
@@ -6249,8 +6400,8 @@ async function executeInspect(context, args) {
|
|
|
6249
6400
|
if (!latestRun) {
|
|
6250
6401
|
throw new CliError2(`No runs found for ${requiredTask}.`);
|
|
6251
6402
|
}
|
|
6252
|
-
const logsPath =
|
|
6253
|
-
if (!
|
|
6403
|
+
const logsPath = resolve21(resolveAuthorityRunDir4(context.projectRoot, latestRun.runId), "logs.jsonl");
|
|
6404
|
+
if (!existsSync13(logsPath)) {
|
|
6254
6405
|
throw new CliError2(`No logs found for run ${latestRun.runId}.`);
|
|
6255
6406
|
}
|
|
6256
6407
|
await context.runCommand(["cat", logsPath]);
|
|
@@ -6260,7 +6411,7 @@ async function executeInspect(context, args) {
|
|
|
6260
6411
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
6261
6412
|
requireNoExtraArgs(remaining, "rig inspect artifacts --task <task-id>");
|
|
6262
6413
|
const requiredTask = requireTask(task, "rig inspect artifacts --task <task-id>");
|
|
6263
|
-
const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) =>
|
|
6414
|
+
const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync13(path));
|
|
6264
6415
|
if (!artifactRoot) {
|
|
6265
6416
|
throw new CliError2(`No artifacts found for ${requiredTask}.`);
|
|
6266
6417
|
}
|
|
@@ -6317,10 +6468,10 @@ async function executeInspect(context, args) {
|
|
|
6317
6468
|
case "failures": {
|
|
6318
6469
|
requireNoExtraArgs(rest, "rig inspect failures");
|
|
6319
6470
|
const failed = resolveHarnessPaths2(context.projectRoot).failedApproachesPath;
|
|
6320
|
-
if (!
|
|
6471
|
+
if (!existsSync13(failed)) {
|
|
6321
6472
|
console.log("No failures recorded.");
|
|
6322
6473
|
} else {
|
|
6323
|
-
process.stdout.write(
|
|
6474
|
+
process.stdout.write(readFileSync9(failed, "utf-8"));
|
|
6324
6475
|
}
|
|
6325
6476
|
return { ok: true, group: "inspect", command };
|
|
6326
6477
|
}
|
|
@@ -6337,11 +6488,11 @@ async function executeInspect(context, args) {
|
|
|
6337
6488
|
return { ok: true, group: "inspect", command };
|
|
6338
6489
|
case "audit": {
|
|
6339
6490
|
requireNoExtraArgs(rest, "rig inspect audit");
|
|
6340
|
-
const auditPath =
|
|
6341
|
-
if (!
|
|
6491
|
+
const auditPath = resolve21(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
|
|
6492
|
+
if (!existsSync13(auditPath)) {
|
|
6342
6493
|
console.log("No audit log found.");
|
|
6343
6494
|
} else {
|
|
6344
|
-
const lines =
|
|
6495
|
+
const lines = readFileSync9(auditPath, "utf-8").split(/\r?\n/).filter(Boolean).slice(-20);
|
|
6345
6496
|
for (const line of lines) {
|
|
6346
6497
|
console.log(line);
|
|
6347
6498
|
}
|
|
@@ -7540,7 +7691,7 @@ async function connectWorkerStream(options, ctx, state) {
|
|
|
7540
7691
|
const buffered = [];
|
|
7541
7692
|
const wsUrl = await buildRunPiEventsWebSocketUrl(options.context, options.runId);
|
|
7542
7693
|
const socket = new WebSocket(wsUrl);
|
|
7543
|
-
const closePromise = new Promise((
|
|
7694
|
+
const closePromise = new Promise((resolve22) => {
|
|
7544
7695
|
socket.onopen = () => {
|
|
7545
7696
|
state.wsConnected = true;
|
|
7546
7697
|
state.status = "live worker Pi WebSocket connected";
|
|
@@ -7565,7 +7716,7 @@ async function connectWorkerStream(options, ctx, state) {
|
|
|
7565
7716
|
state.wsConnected = false;
|
|
7566
7717
|
state.status = "worker Pi WebSocket disconnected";
|
|
7567
7718
|
updatePiUi(ctx, state);
|
|
7568
|
-
|
|
7719
|
+
resolve22();
|
|
7569
7720
|
};
|
|
7570
7721
|
});
|
|
7571
7722
|
try {
|
|
@@ -7601,11 +7752,11 @@ async function connectWorkerStream(options, ctx, state) {
|
|
|
7601
7752
|
function createRemoteBashOperations(options, state, excludeFromContext) {
|
|
7602
7753
|
return {
|
|
7603
7754
|
exec(command, _cwd, execOptions) {
|
|
7604
|
-
return new Promise((
|
|
7755
|
+
return new Promise((resolve22, reject) => {
|
|
7605
7756
|
const pending = {
|
|
7606
7757
|
command,
|
|
7607
7758
|
onData: execOptions.onData,
|
|
7608
|
-
resolve:
|
|
7759
|
+
resolve: resolve22,
|
|
7609
7760
|
reject,
|
|
7610
7761
|
sawChunk: false
|
|
7611
7762
|
};
|
|
@@ -8268,6 +8419,33 @@ async function executeRun(context, args) {
|
|
|
8268
8419
|
}
|
|
8269
8420
|
return { ok: true, group: "run", command, details: restarted };
|
|
8270
8421
|
}
|
|
8422
|
+
case "steer": {
|
|
8423
|
+
const runOption = takeOption(rest, "--run");
|
|
8424
|
+
const messageOption = takeOption(runOption.rest, "--message");
|
|
8425
|
+
const shortMessageOption = takeOption(messageOption.rest, "-m");
|
|
8426
|
+
const positionalRunId = shortMessageOption.rest.length > 0 ? shortMessageOption.rest[0] : undefined;
|
|
8427
|
+
const extra = positionalRunId ? shortMessageOption.rest.slice(1) : shortMessageOption.rest;
|
|
8428
|
+
requireNoExtraArgs(extra, "rig run steer [<run-id>|--run <id>] --message <text>");
|
|
8429
|
+
const runId = runOption.value ?? positionalRunId;
|
|
8430
|
+
const message2 = messageOption.value ?? shortMessageOption.value;
|
|
8431
|
+
if (!runId) {
|
|
8432
|
+
throw new CliError2("run steer requires a run id (positional or --run <id>).", 2);
|
|
8433
|
+
}
|
|
8434
|
+
if (!message2?.trim()) {
|
|
8435
|
+
throw new CliError2("run steer requires --message <text>.", 2);
|
|
8436
|
+
}
|
|
8437
|
+
if (context.dryRun) {
|
|
8438
|
+
if (context.outputMode === "text") {
|
|
8439
|
+
console.log(`[dry-run] rig run steer ${runId} --message ${JSON.stringify(message2)}`);
|
|
8440
|
+
}
|
|
8441
|
+
return { ok: true, group: "run", command, details: { runId, dryRun: true } };
|
|
8442
|
+
}
|
|
8443
|
+
await steerRunViaServer(context, runId, message2.trim());
|
|
8444
|
+
if (context.outputMode === "text") {
|
|
8445
|
+
console.log(`Steering message queued for ${runId}.`);
|
|
8446
|
+
}
|
|
8447
|
+
return { ok: true, group: "run", command, details: { runId, queued: true } };
|
|
8448
|
+
}
|
|
8271
8449
|
case "stop": {
|
|
8272
8450
|
const runOption = takeOption(rest, "--run");
|
|
8273
8451
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
@@ -8414,9 +8592,9 @@ async function executeServer(context, args, options) {
|
|
|
8414
8592
|
|
|
8415
8593
|
// packages/cli/src/commands/task.ts
|
|
8416
8594
|
init_runner();
|
|
8417
|
-
import { readFileSync as
|
|
8595
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
8418
8596
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
8419
|
-
import { resolve as
|
|
8597
|
+
import { resolve as resolve22 } from "path";
|
|
8420
8598
|
import { cancel as cancel4, confirm as confirm2, isCancel as isCancel4 } from "@clack/prompts";
|
|
8421
8599
|
import {
|
|
8422
8600
|
taskArtifactDir,
|
|
@@ -8594,6 +8772,7 @@ var PRIMARY_GROUPS = [
|
|
|
8594
8772
|
{ command: "show <id>|--run <id> [--raw]", description: "Show a human run summary; --raw prints the full payload.", primary: true },
|
|
8595
8773
|
{ command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; --follow launches native bundled Pi for live Pi runs.", primary: true },
|
|
8596
8774
|
{ command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
|
|
8775
|
+
{ command: "steer <run-id> --message <text>", description: "Queue a steering message into a live worker without attaching." },
|
|
8597
8776
|
{ command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
|
|
8598
8777
|
{ command: "resume", description: "Resume the most recent interrupted local run." },
|
|
8599
8778
|
{ command: "restart", description: "Restart the most recent local run from a clean runtime." },
|
|
@@ -8695,6 +8874,19 @@ var ADVANCED_GROUPS = [
|
|
|
8695
8874
|
{ command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
|
|
8696
8875
|
]
|
|
8697
8876
|
},
|
|
8877
|
+
{
|
|
8878
|
+
name: "pi",
|
|
8879
|
+
summary: "Manage Pi extension packages for this project (community extensions from npm/git).",
|
|
8880
|
+
usage: ["rig pi <list|add|remove|search> [args]"],
|
|
8881
|
+
commands: [
|
|
8882
|
+
{ command: "list", description: "Show project and user Pi extension packages." },
|
|
8883
|
+
{ command: "add <source>", description: "Add an npm/git Pi extension to .pi/settings.json (auto-installs at next session)." },
|
|
8884
|
+
{ command: "remove <source>", description: "Remove an operator-added Pi extension." },
|
|
8885
|
+
{ command: "search [term]", description: "Discover Pi extension packages on the npm registry." }
|
|
8886
|
+
],
|
|
8887
|
+
examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
|
|
8888
|
+
next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
|
|
8889
|
+
},
|
|
8698
8890
|
{
|
|
8699
8891
|
name: "plugin",
|
|
8700
8892
|
summary: "Plugin listing, validation, and plugin-contributed commands.",
|
|
@@ -9125,7 +9317,7 @@ async function executeTask(context, args, options) {
|
|
|
9125
9317
|
const fileFlag = takeOption(rest.slice(1), "--file");
|
|
9126
9318
|
let content;
|
|
9127
9319
|
if (fileFlag.value) {
|
|
9128
|
-
content =
|
|
9320
|
+
content = readFileSync10(resolve22(context.projectRoot, fileFlag.value), "utf-8");
|
|
9129
9321
|
} else {
|
|
9130
9322
|
content = await readStdin();
|
|
9131
9323
|
}
|
|
@@ -9359,8 +9551,8 @@ async function executeTask(context, args, options) {
|
|
|
9359
9551
|
|
|
9360
9552
|
// packages/cli/src/commands/task-run-driver.ts
|
|
9361
9553
|
init_runner();
|
|
9362
|
-
import { copyFileSync as copyFileSync3, existsSync as
|
|
9363
|
-
import { resolve as
|
|
9554
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
9555
|
+
import { resolve as resolve23 } from "path";
|
|
9364
9556
|
import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
|
|
9365
9557
|
import { createInterface as createLineInterface } from "readline";
|
|
9366
9558
|
import { loadConfig as loadConfig2 } from "@rig/core/load-config";
|
|
@@ -9443,12 +9635,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
|
|
|
9443
9635
|
return 0;
|
|
9444
9636
|
let copied = 0;
|
|
9445
9637
|
for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
|
|
9446
|
-
const sourcePath =
|
|
9447
|
-
const targetPath =
|
|
9638
|
+
const sourcePath = resolve23(sourceRoot, relativePath);
|
|
9639
|
+
const targetPath = resolve23(targetRoot, relativePath);
|
|
9448
9640
|
try {
|
|
9449
9641
|
if (!statSync2(sourcePath).isFile())
|
|
9450
9642
|
continue;
|
|
9451
|
-
|
|
9643
|
+
mkdirSync9(resolve23(targetPath, ".."), { recursive: true });
|
|
9452
9644
|
copyFileSync3(sourcePath, targetPath);
|
|
9453
9645
|
copied += 1;
|
|
9454
9646
|
} catch {}
|
|
@@ -9487,7 +9679,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
|
|
|
9487
9679
|
return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
|
|
9488
9680
|
return {
|
|
9489
9681
|
RIG_BASELINE_MODE: "dirty-snapshot",
|
|
9490
|
-
RIG_DIRTY_BASELINE_READY_FILE:
|
|
9682
|
+
RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
|
|
9491
9683
|
};
|
|
9492
9684
|
}
|
|
9493
9685
|
function positiveInt(value, fallback) {
|
|
@@ -9598,9 +9790,9 @@ function createCommandRunner(binary) {
|
|
|
9598
9790
|
const stderrChunks = [];
|
|
9599
9791
|
child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
9600
9792
|
child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
9601
|
-
return await new Promise((
|
|
9602
|
-
child.once("error", (error) =>
|
|
9603
|
-
child.once("close", (code) =>
|
|
9793
|
+
return await new Promise((resolve24) => {
|
|
9794
|
+
child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
|
|
9795
|
+
child.once("close", (code) => resolve24({
|
|
9604
9796
|
exitCode: code ?? 1,
|
|
9605
9797
|
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
9606
9798
|
stderr: Buffer.concat(stderrChunks).toString("utf8")
|
|
@@ -9674,7 +9866,7 @@ async function runTaskRunPostValidationLifecycle(input) {
|
|
|
9674
9866
|
config,
|
|
9675
9867
|
sourceTask: input.sourceTask,
|
|
9676
9868
|
uploadedSnapshot: input.uploadedSnapshot,
|
|
9677
|
-
artifactRoot:
|
|
9869
|
+
artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
|
|
9678
9870
|
command: ghCommand,
|
|
9679
9871
|
gitCommand,
|
|
9680
9872
|
steerPi,
|
|
@@ -9804,7 +9996,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
|
|
|
9804
9996
|
return null;
|
|
9805
9997
|
}
|
|
9806
9998
|
for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
|
|
9807
|
-
const summary = readJsonFile3(
|
|
9999
|
+
const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
|
|
9808
10000
|
if (!summary || summary.status !== "fail") {
|
|
9809
10001
|
continue;
|
|
9810
10002
|
}
|
|
@@ -9885,9 +10077,9 @@ function readTaskRunAcceptedArtifactState(input) {
|
|
|
9885
10077
|
if (!input.taskId || !input.workspaceDir) {
|
|
9886
10078
|
return { accepted: false, reason: null };
|
|
9887
10079
|
}
|
|
9888
|
-
const artifactDir =
|
|
9889
|
-
const reviewStatusPath =
|
|
9890
|
-
const taskResultPath =
|
|
10080
|
+
const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
|
|
10081
|
+
const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
|
|
10082
|
+
const taskResultPath = resolve23(artifactDir, "task-result.json");
|
|
9891
10083
|
const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
|
|
9892
10084
|
if (reviewStatus !== "APPROVED") {
|
|
9893
10085
|
return { accepted: false, reason: null };
|
|
@@ -9924,12 +10116,12 @@ function resolveTaskRunRetryContext(input) {
|
|
|
9924
10116
|
if (!input.taskId || !input.workspaceDir) {
|
|
9925
10117
|
return { shouldRetry: false, failureDetail: null, nextPrompt: null };
|
|
9926
10118
|
}
|
|
9927
|
-
const artifactDir =
|
|
9928
|
-
const reviewStatePath =
|
|
9929
|
-
const reviewFeedbackPath =
|
|
9930
|
-
const reviewStatusPath =
|
|
9931
|
-
const failedApproachesPath =
|
|
9932
|
-
const validationSummaryPath =
|
|
10119
|
+
const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
|
|
10120
|
+
const reviewStatePath = resolve23(artifactDir, "review-state.json");
|
|
10121
|
+
const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
|
|
10122
|
+
const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
|
|
10123
|
+
const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
|
|
10124
|
+
const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
|
|
9933
10125
|
const reviewState = readJsonFile3(reviewStatePath, null);
|
|
9934
10126
|
const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
|
|
9935
10127
|
const reviewRejected = isTaskRunReviewRejected(reviewState);
|
|
@@ -10115,11 +10307,11 @@ function appendToolTimelineFromLog(input) {
|
|
|
10115
10307
|
});
|
|
10116
10308
|
}
|
|
10117
10309
|
function readTaskRunReviewStatus(reviewStatusPath) {
|
|
10118
|
-
if (!
|
|
10310
|
+
if (!existsSync14(reviewStatusPath)) {
|
|
10119
10311
|
return null;
|
|
10120
10312
|
}
|
|
10121
10313
|
try {
|
|
10122
|
-
const status =
|
|
10314
|
+
const status = readFileSync11(reviewStatusPath, "utf8").trim().toUpperCase();
|
|
10123
10315
|
return status === "APPROVED" || status === "REJECTED" ? status : null;
|
|
10124
10316
|
} catch {
|
|
10125
10317
|
return null;
|
|
@@ -10333,15 +10525,15 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
10333
10525
|
const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
|
|
10334
10526
|
const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
|
|
10335
10527
|
const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
|
|
10336
|
-
const planningArtifactPath =
|
|
10528
|
+
const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
|
|
10337
10529
|
const persistedPlanning = {
|
|
10338
10530
|
...planningClassification,
|
|
10339
10531
|
classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
|
|
10340
10532
|
artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
|
|
10341
10533
|
classifiedAt: new Date().toISOString()
|
|
10342
10534
|
};
|
|
10343
|
-
|
|
10344
|
-
|
|
10535
|
+
mkdirSync9(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
|
|
10536
|
+
writeFileSync7(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
|
|
10345
10537
|
`, "utf8");
|
|
10346
10538
|
patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
|
|
10347
10539
|
prompt = `${prompt}
|
|
@@ -10391,7 +10583,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
10391
10583
|
let verificationStarted = false;
|
|
10392
10584
|
let reviewStarted = false;
|
|
10393
10585
|
let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
|
|
10394
|
-
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ?
|
|
10586
|
+
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
|
|
10395
10587
|
let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
|
|
10396
10588
|
let latestProviderCommand = null;
|
|
10397
10589
|
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
@@ -10477,10 +10669,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
10477
10669
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
10478
10670
|
status: "running",
|
|
10479
10671
|
worktreePath: latestRuntimeWorkspace,
|
|
10480
|
-
artifactRoot: latestRuntimeWorkspace && input.taskId ?
|
|
10672
|
+
artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
|
|
10481
10673
|
logRoot: latestLogsDir,
|
|
10482
|
-
sessionPath: latestSessionDir ?
|
|
10483
|
-
sessionLogPath: latestLogsDir ?
|
|
10674
|
+
sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
|
|
10675
|
+
sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
|
|
10484
10676
|
branch: runtimeId
|
|
10485
10677
|
});
|
|
10486
10678
|
if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
|
|
@@ -10488,8 +10680,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
10488
10680
|
const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
|
|
10489
10681
|
const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
|
|
10490
10682
|
if (readyFile) {
|
|
10491
|
-
|
|
10492
|
-
|
|
10683
|
+
mkdirSync9(resolve23(readyFile, ".."), { recursive: true });
|
|
10684
|
+
writeFileSync7(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
|
|
10493
10685
|
`, "utf8");
|
|
10494
10686
|
}
|
|
10495
10687
|
appendRunLog(context.projectRoot, input.runId, {
|
|
@@ -10873,7 +11065,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
10873
11065
|
let acceptedArtifactObservedAt = null;
|
|
10874
11066
|
let acceptedArtifactPollTimer = null;
|
|
10875
11067
|
let acceptedArtifactKillTimer = null;
|
|
10876
|
-
const attemptExit = await new Promise((
|
|
11068
|
+
const attemptExit = await new Promise((resolve24) => {
|
|
10877
11069
|
let settled = false;
|
|
10878
11070
|
const settle = (result) => {
|
|
10879
11071
|
if (settled)
|
|
@@ -10881,7 +11073,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
10881
11073
|
settled = true;
|
|
10882
11074
|
if (acceptedArtifactPollTimer)
|
|
10883
11075
|
clearInterval(acceptedArtifactPollTimer);
|
|
10884
|
-
|
|
11076
|
+
resolve24(result);
|
|
10885
11077
|
};
|
|
10886
11078
|
const pollAcceptedArtifacts = () => {
|
|
10887
11079
|
const artifactState = readTaskRunAcceptedArtifactState({
|
|
@@ -11083,8 +11275,8 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
11083
11275
|
}
|
|
11084
11276
|
if (planningClassification.planningRequired) {
|
|
11085
11277
|
const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
|
|
11086
|
-
const expectedPlanPath =
|
|
11087
|
-
if (!
|
|
11278
|
+
const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
|
|
11279
|
+
if (!existsSync14(expectedPlanPath)) {
|
|
11088
11280
|
const failedAt = new Date().toISOString();
|
|
11089
11281
|
const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
|
|
11090
11282
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
@@ -11254,9 +11446,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
11254
11446
|
});
|
|
11255
11447
|
emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
|
|
11256
11448
|
});
|
|
11257
|
-
const exitCode = await new Promise((
|
|
11258
|
-
child.once("error", () =>
|
|
11259
|
-
child.once("close", (code) =>
|
|
11449
|
+
const exitCode = await new Promise((resolve24) => {
|
|
11450
|
+
child.once("error", () => resolve24(1));
|
|
11451
|
+
child.once("close", (code) => resolve24(code ?? 1));
|
|
11260
11452
|
});
|
|
11261
11453
|
for (const pendingLog of flushPendingClaudeToolUseLogs({
|
|
11262
11454
|
runId: input.runId,
|
|
@@ -11398,8 +11590,8 @@ async function executeTest(context, args) {
|
|
|
11398
11590
|
|
|
11399
11591
|
// packages/cli/src/commands/setup.ts
|
|
11400
11592
|
init_runner();
|
|
11401
|
-
import { existsSync as
|
|
11402
|
-
import { resolve as
|
|
11593
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync8 } from "fs";
|
|
11594
|
+
import { resolve as resolve24 } from "path";
|
|
11403
11595
|
import { createPluginHost } from "@rig/core";
|
|
11404
11596
|
import {
|
|
11405
11597
|
isSupportedBunVersion as isSupportedBunVersion2,
|
|
@@ -11454,12 +11646,12 @@ function runSetupInit(projectRoot) {
|
|
|
11454
11646
|
const stateDir = resolveControlPlaneHostStateDir(projectRoot);
|
|
11455
11647
|
const logsDir = resolveControlPlaneHostLogsDir(projectRoot);
|
|
11456
11648
|
const artifactsDir = resolveControlPlaneArtifactsDir(projectRoot);
|
|
11457
|
-
|
|
11458
|
-
|
|
11459
|
-
|
|
11460
|
-
const failuresPath =
|
|
11461
|
-
if (!
|
|
11462
|
-
|
|
11649
|
+
mkdirSync10(stateDir, { recursive: true });
|
|
11650
|
+
mkdirSync10(logsDir, { recursive: true });
|
|
11651
|
+
mkdirSync10(artifactsDir, { recursive: true });
|
|
11652
|
+
const failuresPath = resolve24(stateDir, "failed_approaches.md");
|
|
11653
|
+
if (!existsSync15(failuresPath)) {
|
|
11654
|
+
writeFileSync8(failuresPath, `# Failed Approaches
|
|
11463
11655
|
|
|
11464
11656
|
`, "utf-8");
|
|
11465
11657
|
}
|
|
@@ -11476,18 +11668,18 @@ async function runSetupCheck(projectRoot) {
|
|
|
11476
11668
|
}
|
|
11477
11669
|
async function runSetupPreflight(projectRoot) {
|
|
11478
11670
|
await runSetupCheck(projectRoot);
|
|
11479
|
-
const validationRoot =
|
|
11480
|
-
if (
|
|
11671
|
+
const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
|
|
11672
|
+
if (existsSync15(validationRoot)) {
|
|
11481
11673
|
const validators = readdirSync2(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
|
|
11482
11674
|
for (const validator of validators) {
|
|
11483
|
-
const script =
|
|
11484
|
-
if (
|
|
11675
|
+
const script = resolve24(validationRoot, validator.name, "validate.sh");
|
|
11676
|
+
if (existsSync15(script)) {
|
|
11485
11677
|
console.log(`OK: validator script ${script}`);
|
|
11486
11678
|
}
|
|
11487
11679
|
}
|
|
11488
11680
|
}
|
|
11489
|
-
const hooksRoot =
|
|
11490
|
-
if (
|
|
11681
|
+
const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
|
|
11682
|
+
if (existsSync15(hooksRoot)) {
|
|
11491
11683
|
const hooks = readdirSync2(hooksRoot).filter((name) => name.endsWith(".sh"));
|
|
11492
11684
|
for (const hook of hooks) {
|
|
11493
11685
|
console.log(`OK: hook ${hook}`);
|
|
@@ -11632,7 +11824,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
|
|
|
11632
11824
|
]);
|
|
11633
11825
|
var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
|
|
11634
11826
|
function hasInitializedRigProject(projectRoot) {
|
|
11635
|
-
return RIG_CONFIG_FILENAMES.some((name) =>
|
|
11827
|
+
return RIG_CONFIG_FILENAMES.some((name) => existsSync16(resolve25(projectRoot, name))) || existsSync16(resolve25(projectRoot, ".rig"));
|
|
11636
11828
|
}
|
|
11637
11829
|
function requireInitializedRigProject(context, group) {
|
|
11638
11830
|
if (hasInitializedRigProject(context.projectRoot)) {
|
|
@@ -11658,6 +11850,7 @@ var GROUPS = new Set([
|
|
|
11658
11850
|
"review",
|
|
11659
11851
|
"git",
|
|
11660
11852
|
"harness",
|
|
11853
|
+
"pi",
|
|
11661
11854
|
"plugin",
|
|
11662
11855
|
"queue",
|
|
11663
11856
|
"agent",
|
|
@@ -11803,6 +11996,8 @@ async function executeGroup(context, group, args) {
|
|
|
11803
11996
|
return executeGit(context, args);
|
|
11804
11997
|
case "harness":
|
|
11805
11998
|
return executeHarness(context, args);
|
|
11999
|
+
case "pi":
|
|
12000
|
+
return executePi(context, args);
|
|
11806
12001
|
case "plugin":
|
|
11807
12002
|
return executePlugin(context, args);
|
|
11808
12003
|
case "queue":
|
|
@@ -11832,8 +12027,8 @@ async function executeGroup(context, group, args) {
|
|
|
11832
12027
|
}
|
|
11833
12028
|
}
|
|
11834
12029
|
// packages/cli/src/launcher.ts
|
|
11835
|
-
import { existsSync as
|
|
11836
|
-
import { basename as basename2, resolve as
|
|
12030
|
+
import { existsSync as existsSync17 } from "fs";
|
|
12031
|
+
import { basename as basename2, resolve as resolve26 } from "path";
|
|
11837
12032
|
import { loadDotEnvSecrets } from "@rig/runtime/baked-secrets";
|
|
11838
12033
|
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, resolveNearestRigProjectRoot } from "@rig/runtime/layout";
|
|
11839
12034
|
function parsePolicyMode(value) {
|
|
@@ -11846,7 +12041,7 @@ function parsePolicyMode(value) {
|
|
|
11846
12041
|
throw new Error(`Invalid --policy-mode value: ${value}. Use off|observe|enforce.`);
|
|
11847
12042
|
}
|
|
11848
12043
|
function hasRigProjectMarker(candidate) {
|
|
11849
|
-
return
|
|
12044
|
+
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
12045
|
}
|
|
11851
12046
|
function resolveProjectRoot({
|
|
11852
12047
|
envProjectRoot,
|
|
@@ -11855,19 +12050,19 @@ function resolveProjectRoot({
|
|
|
11855
12050
|
cwd = process.cwd()
|
|
11856
12051
|
}) {
|
|
11857
12052
|
if (envProjectRoot) {
|
|
11858
|
-
return
|
|
12053
|
+
return resolve26(cwd, envProjectRoot);
|
|
11859
12054
|
}
|
|
11860
12055
|
const fallbackImportDir = importDir ?? cwd;
|
|
11861
12056
|
const execName = basename2(execPath).toLowerCase();
|
|
11862
|
-
const execCandidates = execName === "rig" || execName === "rig.exe" ? [
|
|
11863
|
-
const candidates = [cwd, ...execCandidates,
|
|
12057
|
+
const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve26(execPath, "..", "..")] : [];
|
|
12058
|
+
const candidates = [cwd, ...execCandidates, resolve26(fallbackImportDir, "..")];
|
|
11864
12059
|
for (const candidate of candidates) {
|
|
11865
12060
|
const nearest = resolveNearestRigProjectRoot(candidate);
|
|
11866
12061
|
if (hasRigProjectMarker(nearest)) {
|
|
11867
12062
|
return nearest;
|
|
11868
12063
|
}
|
|
11869
12064
|
}
|
|
11870
|
-
return
|
|
12065
|
+
return resolve26(cwd);
|
|
11871
12066
|
}
|
|
11872
12067
|
function normalizeCliErrorCode(message2, isCliError) {
|
|
11873
12068
|
if (message2.startsWith("Invalid --policy-mode value:")) {
|
|
@@ -11934,7 +12129,7 @@ async function runRigCli(module, options = {}) {
|
|
|
11934
12129
|
runId: context.runId,
|
|
11935
12130
|
outcome,
|
|
11936
12131
|
eventsFile: context.eventBus.getEventsFile(),
|
|
11937
|
-
policyFile:
|
|
12132
|
+
policyFile: resolve26(projectRoot, "rig", "policy", "policy.json"),
|
|
11938
12133
|
policyMode: context.policyMode ?? policyMode ?? module.loadPolicy(projectRoot).mode
|
|
11939
12134
|
}, null, 2));
|
|
11940
12135
|
}
|