@h-rig/runtime 0.0.6-alpha.34 → 0.0.6-alpha.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/rig-agent-dispatch.js +518 -459
- package/dist/bin/rig-agent.js +430 -361
- package/dist/src/control-plane/agent-wrapper.js +523 -464
- package/dist/src/control-plane/harness-main.js +544 -463
- package/dist/src/control-plane/hooks/completion-verification.js +369 -288
- package/dist/src/control-plane/hooks/inject-context.js +158 -99
- package/dist/src/control-plane/hooks/submodule-branch.js +538 -479
- package/dist/src/control-plane/hooks/task-runtime-start.js +538 -479
- package/dist/src/control-plane/materialize-task-config.js +68 -8
- package/dist/src/control-plane/native/git-ops.js +10 -0
- package/dist/src/control-plane/native/harness-cli.js +529 -448
- package/dist/src/control-plane/native/task-ops.js +408 -327
- package/dist/src/control-plane/native/validator.js +159 -100
- package/dist/src/control-plane/native/verifier.js +243 -171
- package/dist/src/control-plane/pi-sessiond/bin.js +0 -7
- package/dist/src/control-plane/pi-sessiond/server.js +0 -7
- package/dist/src/control-plane/pi-sessiond/session-service.js +0 -3
- package/dist/src/control-plane/pi-settings-materializer.js +52 -0
- package/dist/src/control-plane/plugin-host-context.js +59 -0
- package/dist/src/control-plane/runtime/index.js +469 -410
- package/dist/src/control-plane/runtime/isolation/index.js +493 -434
- package/dist/src/control-plane/runtime/isolation.js +493 -434
- package/dist/src/control-plane/runtime/queue.js +411 -352
- package/dist/src/control-plane/tasks/source-lifecycle.js +87 -28
- package/dist/src/index.js +16 -8
- package/dist/src/local-server.js +17 -8
- package/package.json +8 -8
|
@@ -150,32 +150,32 @@ var RIG_DEFINITION_DIRNAME = "rig", RIG_ARTIFACTS_DIRNAME = "artifacts";
|
|
|
150
150
|
var init_layout = () => {};
|
|
151
151
|
|
|
152
152
|
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
153
|
-
import { existsSync as
|
|
154
|
-
import { resolve as
|
|
153
|
+
import { existsSync as existsSync22, readdirSync as readdirSync4, realpathSync } from "fs";
|
|
154
|
+
import { resolve as resolve21 } from "path";
|
|
155
155
|
function toRealPath(path) {
|
|
156
|
-
if (!
|
|
157
|
-
return
|
|
156
|
+
if (!existsSync22(path)) {
|
|
157
|
+
return resolve21(path);
|
|
158
158
|
}
|
|
159
159
|
try {
|
|
160
160
|
return realpathSync.native(path);
|
|
161
161
|
} catch {
|
|
162
|
-
return
|
|
162
|
+
return resolve21(path);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
166
166
|
const candidates = new Set;
|
|
167
167
|
const addPath = (candidate) => {
|
|
168
|
-
if (
|
|
168
|
+
if (existsSync22(candidate)) {
|
|
169
169
|
candidates.add(toRealPath(candidate));
|
|
170
170
|
}
|
|
171
171
|
};
|
|
172
|
-
addPath(
|
|
173
|
-
addPath(
|
|
172
|
+
addPath(resolve21(projectRoot, ".git"));
|
|
173
|
+
addPath(resolve21(workspaceDir, "..", "..", ".git"));
|
|
174
174
|
for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
|
|
175
|
-
addPath(
|
|
175
|
+
addPath(resolve21(repoRoot, ".git"));
|
|
176
176
|
}
|
|
177
|
-
const workspaceGit =
|
|
178
|
-
if (
|
|
177
|
+
const workspaceGit = resolve21(workspaceDir, ".git");
|
|
178
|
+
if (existsSync22(workspaceGit)) {
|
|
179
179
|
addPath(workspaceGit);
|
|
180
180
|
}
|
|
181
181
|
return [...candidates];
|
|
@@ -183,7 +183,7 @@ function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
|
183
183
|
function resolveHostRepoRootPaths(projectRoot) {
|
|
184
184
|
const candidates = new Set;
|
|
185
185
|
const addPath = (candidate) => {
|
|
186
|
-
if (
|
|
186
|
+
if (existsSync22(candidate)) {
|
|
187
187
|
candidates.add(toRealPath(candidate));
|
|
188
188
|
}
|
|
189
189
|
};
|
|
@@ -193,11 +193,11 @@ function resolveHostRepoRootPaths(projectRoot) {
|
|
|
193
193
|
addPath(monorepoRoot);
|
|
194
194
|
}
|
|
195
195
|
} catch {}
|
|
196
|
-
const reposDir =
|
|
197
|
-
if (
|
|
196
|
+
const reposDir = resolve21(projectRoot, "repos");
|
|
197
|
+
if (existsSync22(reposDir)) {
|
|
198
198
|
for (const entry of readdirSync4(reposDir, { withFileTypes: true })) {
|
|
199
199
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
200
|
-
addPath(
|
|
200
|
+
addPath(resolve21(reposDir, entry.name));
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
}
|
|
@@ -241,8 +241,8 @@ var exports_backend_seatbelt = {};
|
|
|
241
241
|
__export(exports_backend_seatbelt, {
|
|
242
242
|
SeatbeltBackend: () => SeatbeltBackend
|
|
243
243
|
});
|
|
244
|
-
import { mkdirSync as
|
|
245
|
-
import { resolve as
|
|
244
|
+
import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync13 } from "fs";
|
|
245
|
+
import { resolve as resolve33 } from "path";
|
|
246
246
|
|
|
247
247
|
class SeatbeltBackend {
|
|
248
248
|
kind = "macos-seatbelt";
|
|
@@ -266,11 +266,11 @@ class SeatbeltBackend {
|
|
|
266
266
|
};
|
|
267
267
|
}
|
|
268
268
|
writeSeatbeltProfile(options) {
|
|
269
|
-
const sandboxDir =
|
|
270
|
-
|
|
271
|
-
const profilePath =
|
|
269
|
+
const sandboxDir = resolve33(options.runtime.rootDir, "sandbox");
|
|
270
|
+
mkdirSync18(sandboxDir, { recursive: true });
|
|
271
|
+
const profilePath = resolve33(sandboxDir, "seatbelt.sb");
|
|
272
272
|
const profile = this.renderProfile(options);
|
|
273
|
-
|
|
273
|
+
writeFileSync13(profilePath, `${profile}
|
|
274
274
|
`, "utf-8");
|
|
275
275
|
return profilePath;
|
|
276
276
|
}
|
|
@@ -355,7 +355,7 @@ class SeatbeltBackend {
|
|
|
355
355
|
const realHome = process.env.HOME?.trim();
|
|
356
356
|
if (realHome) {
|
|
357
357
|
for (const binSubdir of [".local/bin", ".cargo/bin"]) {
|
|
358
|
-
const binPath =
|
|
358
|
+
const binPath = resolve33(realHome, binSubdir);
|
|
359
359
|
if (ctx.pathExists(binPath)) {
|
|
360
360
|
lines.push(`(allow file-read* (subpath ${seatbeltString(ctx.realPath(binPath))}))`);
|
|
361
361
|
}
|
|
@@ -384,8 +384,8 @@ var exports_backend_bwrap = {};
|
|
|
384
384
|
__export(exports_backend_bwrap, {
|
|
385
385
|
BwrapBackend: () => BwrapBackend
|
|
386
386
|
});
|
|
387
|
-
import { mkdirSync as
|
|
388
|
-
import { resolve as
|
|
387
|
+
import { mkdirSync as mkdirSync19 } from "fs";
|
|
388
|
+
import { resolve as resolve34 } from "path";
|
|
389
389
|
|
|
390
390
|
class BwrapBackend {
|
|
391
391
|
kind = "linux-bwrap";
|
|
@@ -514,18 +514,18 @@ class BwrapBackend {
|
|
|
514
514
|
const realHome = process.env.HOME?.trim();
|
|
515
515
|
if (realHome) {
|
|
516
516
|
for (const binSubdir of [".local/bin", ".local/lib", ".cargo/bin"]) {
|
|
517
|
-
const binPath = ctx.realPath(
|
|
517
|
+
const binPath = ctx.realPath(resolve34(realHome, binSubdir));
|
|
518
518
|
if (ctx.pathExists(binPath)) {
|
|
519
519
|
args.push("--ro-bind", binPath, binPath);
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
|
-
const agentSshDir =
|
|
522
|
+
const agentSshDir = resolve34(homeReal, ".ssh");
|
|
523
523
|
if (ctx.pathExists(agentSshDir)) {
|
|
524
524
|
args.push("--ro-bind", agentSshDir, agentSshDir);
|
|
525
525
|
} else {
|
|
526
|
-
const hostSshDir =
|
|
526
|
+
const hostSshDir = resolve34(realHome, ".ssh");
|
|
527
527
|
if (ctx.pathExists(hostSshDir)) {
|
|
528
|
-
|
|
528
|
+
mkdirSync19(agentSshDir, { recursive: true });
|
|
529
529
|
args.push("--ro-bind", hostSshDir, agentSshDir);
|
|
530
530
|
args.push("--ro-bind", hostSshDir, hostSshDir);
|
|
531
531
|
}
|
|
@@ -568,8 +568,8 @@ var init_backend_bwrap = __esm(() => {
|
|
|
568
568
|
|
|
569
569
|
// packages/runtime/src/control-plane/agent-wrapper.ts
|
|
570
570
|
import { createRequire } from "module";
|
|
571
|
-
import { resolve as
|
|
572
|
-
import { existsSync as
|
|
571
|
+
import { resolve as resolve38 } from "path";
|
|
572
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync22, writeFileSync as writeFileSync15 } from "fs";
|
|
573
573
|
|
|
574
574
|
// packages/runtime/src/control-plane/runtime/context.ts
|
|
575
575
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -777,9 +777,9 @@ function isAgentRuntimeContextPath(path) {
|
|
|
777
777
|
}
|
|
778
778
|
|
|
779
779
|
// packages/runtime/src/control-plane/runtime/isolation/index.ts
|
|
780
|
-
import { existsSync as
|
|
780
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync20, readFileSync as readFileSync17, rmSync as rmSync13 } from "fs";
|
|
781
781
|
import { copyFile, mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
|
|
782
|
-
import { resolve as
|
|
782
|
+
import { resolve as resolve36 } from "path";
|
|
783
783
|
|
|
784
784
|
// packages/runtime/src/control-plane/native/git-native.ts
|
|
785
785
|
import { chmodSync, copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -1854,8 +1854,8 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
|
|
|
1854
1854
|
var DEFAULT_RESULT_LIMIT = DEFAULT_RUNTIME_MEMORY_RETRIEVAL.topK;
|
|
1855
1855
|
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
1856
1856
|
// packages/runtime/src/control-plane/native/task-ops.ts
|
|
1857
|
-
import { appendFileSync, existsSync as
|
|
1858
|
-
import { resolve as
|
|
1857
|
+
import { appendFileSync, existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync12, writeFileSync as writeFileSync10 } from "fs";
|
|
1858
|
+
import { resolve as resolve25 } from "path";
|
|
1859
1859
|
|
|
1860
1860
|
// packages/runtime/src/build-time-config.ts
|
|
1861
1861
|
function normalizeBuildConfig(value) {
|
|
@@ -2419,6 +2419,8 @@ function buildBrowserGuidanceLines(browser) {
|
|
|
2419
2419
|
}
|
|
2420
2420
|
|
|
2421
2421
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
2422
|
+
import { existsSync as existsSync14 } from "fs";
|
|
2423
|
+
import { resolve as resolvePath } from "path";
|
|
2422
2424
|
import { createPluginHost } from "@rig/core";
|
|
2423
2425
|
import { loadConfig } from "@rig/core/load-config";
|
|
2424
2426
|
|
|
@@ -2749,6 +2751,55 @@ async function materializeSkills(projectRoot, entries) {
|
|
|
2749
2751
|
return written;
|
|
2750
2752
|
}
|
|
2751
2753
|
|
|
2754
|
+
// packages/runtime/src/control-plane/pi-settings-materializer.ts
|
|
2755
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
2756
|
+
import { dirname as dirname9, resolve as resolve13 } from "path";
|
|
2757
|
+
var SETTINGS_RELATIVE_PATH = ".pi/settings.json";
|
|
2758
|
+
var MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
|
|
2759
|
+
function readJson(path, fallback) {
|
|
2760
|
+
if (!existsSync13(path))
|
|
2761
|
+
return fallback;
|
|
2762
|
+
try {
|
|
2763
|
+
return JSON.parse(readFileSync6(path, "utf-8"));
|
|
2764
|
+
} catch {
|
|
2765
|
+
return fallback;
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
function packageKey(entry) {
|
|
2769
|
+
if (typeof entry === "string")
|
|
2770
|
+
return entry;
|
|
2771
|
+
if (entry && typeof entry === "object" && typeof entry.source === "string") {
|
|
2772
|
+
return entry.source;
|
|
2773
|
+
}
|
|
2774
|
+
return JSON.stringify(entry);
|
|
2775
|
+
}
|
|
2776
|
+
function materializePiPackages(projectRoot, declaredPackages) {
|
|
2777
|
+
const settingsPath = resolve13(projectRoot, SETTINGS_RELATIVE_PATH);
|
|
2778
|
+
const managedRecordPath = resolve13(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
|
|
2779
|
+
const settings = readJson(settingsPath, {});
|
|
2780
|
+
const previouslyManaged = new Set(readJson(managedRecordPath, []));
|
|
2781
|
+
const existing = Array.isArray(settings.packages) ? settings.packages : [];
|
|
2782
|
+
const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
|
|
2783
|
+
const operatorKeys = new Set(operatorEntries.map(packageKey));
|
|
2784
|
+
const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
|
|
2785
|
+
const nextPackages = [...operatorEntries, ...managedToAdd];
|
|
2786
|
+
if (nextPackages.length > 0 || existsSync13(settingsPath)) {
|
|
2787
|
+
const nextSettings = { ...settings };
|
|
2788
|
+
if (nextPackages.length > 0) {
|
|
2789
|
+
nextSettings.packages = nextPackages;
|
|
2790
|
+
} else {
|
|
2791
|
+
delete nextSettings.packages;
|
|
2792
|
+
}
|
|
2793
|
+
mkdirSync9(dirname9(settingsPath), { recursive: true });
|
|
2794
|
+
writeFileSync6(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
|
|
2795
|
+
`, "utf-8");
|
|
2796
|
+
}
|
|
2797
|
+
mkdirSync9(dirname9(managedRecordPath), { recursive: true });
|
|
2798
|
+
writeFileSync6(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
|
|
2799
|
+
`, "utf-8");
|
|
2800
|
+
return { settingsPath, packages: managedToAdd };
|
|
2801
|
+
}
|
|
2802
|
+
|
|
2752
2803
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
2753
2804
|
async function buildPluginHostContext(projectRoot) {
|
|
2754
2805
|
let config;
|
|
@@ -2796,6 +2847,14 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2796
2847
|
} catch (err) {
|
|
2797
2848
|
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2798
2849
|
}
|
|
2850
|
+
try {
|
|
2851
|
+
const piPackages = config.runtime?.pi?.packages ?? [];
|
|
2852
|
+
if (piPackages.length > 0 || existsSync14(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
|
|
2853
|
+
materializePiPackages(projectRoot, piPackages);
|
|
2854
|
+
}
|
|
2855
|
+
} catch (err) {
|
|
2856
|
+
console.warn(`[plugin-host] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2857
|
+
}
|
|
2799
2858
|
return {
|
|
2800
2859
|
config,
|
|
2801
2860
|
pluginHost,
|
|
@@ -2809,12 +2868,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2809
2868
|
|
|
2810
2869
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
2811
2870
|
import { spawnSync } from "child_process";
|
|
2812
|
-
import { existsSync as
|
|
2813
|
-
import { basename as basename4, join as join3, resolve as
|
|
2871
|
+
import { existsSync as existsSync16, readFileSync as readFileSync8, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync7 } from "fs";
|
|
2872
|
+
import { basename as basename4, join as join3, resolve as resolve15 } from "path";
|
|
2814
2873
|
|
|
2815
2874
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
2816
|
-
import { existsSync as
|
|
2817
|
-
import { resolve as
|
|
2875
|
+
import { existsSync as existsSync15, readFileSync as readFileSync7 } from "fs";
|
|
2876
|
+
import { resolve as resolve14 } from "path";
|
|
2818
2877
|
|
|
2819
2878
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
2820
2879
|
async function findTaskById(reader, id) {
|
|
@@ -2837,7 +2896,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
2837
2896
|
}
|
|
2838
2897
|
}
|
|
2839
2898
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2840
|
-
const configPath = options.configPath ??
|
|
2899
|
+
const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
|
|
2841
2900
|
const reader = {
|
|
2842
2901
|
async listTasks() {
|
|
2843
2902
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -2848,8 +2907,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
2848
2907
|
};
|
|
2849
2908
|
return reader;
|
|
2850
2909
|
}
|
|
2851
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
2852
|
-
if (!
|
|
2910
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve14(projectRoot, ".rig", "task-config.json")) {
|
|
2911
|
+
if (!existsSync15(configPath)) {
|
|
2853
2912
|
return [];
|
|
2854
2913
|
}
|
|
2855
2914
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -2857,7 +2916,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve13(projectRoot,
|
|
|
2857
2916
|
}
|
|
2858
2917
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
2859
2918
|
try {
|
|
2860
|
-
const parsed = JSON.parse(
|
|
2919
|
+
const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
|
|
2861
2920
|
if (isPlainRecord(parsed)) {
|
|
2862
2921
|
return parsed;
|
|
2863
2922
|
}
|
|
@@ -2941,7 +3000,7 @@ function isPlainRecord(candidate) {
|
|
|
2941
3000
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
2942
3001
|
var FILE_TASK_PATTERN = /\.(task\.)?json$/;
|
|
2943
3002
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2944
|
-
const configPath = options.configPath ??
|
|
3003
|
+
const configPath = options.configPath ?? resolve15(projectRoot, ".rig", "task-config.json");
|
|
2945
3004
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
2946
3005
|
const spawnFn = options.spawn ?? spawnSync;
|
|
2947
3006
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -3018,7 +3077,7 @@ function updateGithubIssueTaskBySourceIssueId(sourceIssueId, taskId, update, opt
|
|
|
3018
3077
|
return true;
|
|
3019
3078
|
}
|
|
3020
3079
|
function updateSourceAwareTaskConfigTask(projectRoot, taskId, update, options = {}) {
|
|
3021
|
-
const configPath = options.configPath ??
|
|
3080
|
+
const configPath = options.configPath ?? resolve15(projectRoot, ".rig", "task-config.json");
|
|
3022
3081
|
const rawEntry = readRawTaskEntry(configPath, taskId);
|
|
3023
3082
|
if (!rawEntry) {
|
|
3024
3083
|
const configuredFilesPath = readConfiguredFilesTaskSourcePath(projectRoot);
|
|
@@ -3071,10 +3130,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
3071
3130
|
return metadata;
|
|
3072
3131
|
}
|
|
3073
3132
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
3074
|
-
const jsonPath =
|
|
3075
|
-
if (
|
|
3133
|
+
const jsonPath = resolve15(projectRoot, "rig.config.json");
|
|
3134
|
+
if (existsSync16(jsonPath)) {
|
|
3076
3135
|
try {
|
|
3077
|
-
const parsed = JSON.parse(
|
|
3136
|
+
const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
|
|
3078
3137
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
3079
3138
|
const source = parsed.taskSource;
|
|
3080
3139
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -3083,12 +3142,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
3083
3142
|
return null;
|
|
3084
3143
|
}
|
|
3085
3144
|
}
|
|
3086
|
-
const tsPath =
|
|
3087
|
-
if (!
|
|
3145
|
+
const tsPath = resolve15(projectRoot, "rig.config.ts");
|
|
3146
|
+
if (!existsSync16(tsPath)) {
|
|
3088
3147
|
return null;
|
|
3089
3148
|
}
|
|
3090
3149
|
try {
|
|
3091
|
-
const source =
|
|
3150
|
+
const source = readFileSync8(tsPath, "utf8");
|
|
3092
3151
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3093
3152
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3094
3153
|
if (kind !== "files") {
|
|
@@ -3108,10 +3167,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
3108
3167
|
return isPlainRecord2(entry) ? entry : null;
|
|
3109
3168
|
}
|
|
3110
3169
|
function readRawTaskConfig(configPath) {
|
|
3111
|
-
if (!
|
|
3170
|
+
if (!existsSync16(configPath)) {
|
|
3112
3171
|
return null;
|
|
3113
3172
|
}
|
|
3114
|
-
const parsed = JSON.parse(
|
|
3173
|
+
const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
|
|
3115
3174
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
3116
3175
|
}
|
|
3117
3176
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -3128,16 +3187,16 @@ function writeLegacyTaskStatus(configPath, taskId, status) {
|
|
|
3128
3187
|
return;
|
|
3129
3188
|
}
|
|
3130
3189
|
entry.status = status;
|
|
3131
|
-
|
|
3190
|
+
writeFileSync7(configPath, `${JSON.stringify(rawConfig, null, 2)}
|
|
3132
3191
|
`, "utf8");
|
|
3133
3192
|
}
|
|
3134
3193
|
function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
|
|
3135
|
-
const directory =
|
|
3194
|
+
const directory = resolve15(projectRoot, sourcePath);
|
|
3136
3195
|
const file = findFileBackedTaskFile(directory, taskId);
|
|
3137
3196
|
if (!file) {
|
|
3138
3197
|
return false;
|
|
3139
3198
|
}
|
|
3140
|
-
const raw = JSON.parse(
|
|
3199
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
3141
3200
|
if (!isPlainRecord2(raw)) {
|
|
3142
3201
|
return false;
|
|
3143
3202
|
}
|
|
@@ -3154,13 +3213,13 @@ function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
|
|
|
3154
3213
|
{ body: update.comment, createdAt: new Date().toISOString(), source: "rig" }
|
|
3155
3214
|
];
|
|
3156
3215
|
}
|
|
3157
|
-
|
|
3216
|
+
writeFileSync7(file, `${JSON.stringify(raw, null, 2)}
|
|
3158
3217
|
`, "utf8");
|
|
3159
3218
|
return true;
|
|
3160
3219
|
}
|
|
3161
3220
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
3162
|
-
const directory =
|
|
3163
|
-
if (!
|
|
3221
|
+
const directory = resolve15(projectRoot, sourcePath);
|
|
3222
|
+
if (!existsSync16(directory)) {
|
|
3164
3223
|
return [];
|
|
3165
3224
|
}
|
|
3166
3225
|
const tasks = [];
|
|
@@ -3175,11 +3234,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
3175
3234
|
return tasks;
|
|
3176
3235
|
}
|
|
3177
3236
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
3178
|
-
const file = findFileBackedTaskFile(
|
|
3237
|
+
const file = findFileBackedTaskFile(resolve15(projectRoot, sourcePath), taskId);
|
|
3179
3238
|
if (!file) {
|
|
3180
3239
|
return null;
|
|
3181
3240
|
}
|
|
3182
|
-
const raw = JSON.parse(
|
|
3241
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
3183
3242
|
if (!isPlainRecord2(raw)) {
|
|
3184
3243
|
return null;
|
|
3185
3244
|
}
|
|
@@ -3192,7 +3251,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
3192
3251
|
};
|
|
3193
3252
|
}
|
|
3194
3253
|
function findFileBackedTaskFile(directory, taskId) {
|
|
3195
|
-
if (!
|
|
3254
|
+
if (!existsSync16(directory)) {
|
|
3196
3255
|
return null;
|
|
3197
3256
|
}
|
|
3198
3257
|
for (const name of readdirSync2(directory)) {
|
|
@@ -3202,7 +3261,7 @@ function findFileBackedTaskFile(directory, taskId) {
|
|
|
3202
3261
|
try {
|
|
3203
3262
|
if (!statSync3(file).isFile())
|
|
3204
3263
|
continue;
|
|
3205
|
-
const raw = JSON.parse(
|
|
3264
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
3206
3265
|
const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
|
|
3207
3266
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
3208
3267
|
if (id === taskId) {
|
|
@@ -3551,8 +3610,8 @@ function buildTaskRunLifecycleComment(input) {
|
|
|
3551
3610
|
}
|
|
3552
3611
|
|
|
3553
3612
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
3554
|
-
import { existsSync as
|
|
3555
|
-
import { basename as basename6, resolve as
|
|
3613
|
+
import { existsSync as existsSync20, readFileSync as readFileSync10, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
|
|
3614
|
+
import { basename as basename6, resolve as resolve19 } from "path";
|
|
3556
3615
|
|
|
3557
3616
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
3558
3617
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -3660,39 +3719,39 @@ function readTaskStateMetadataEnvelope(raw) {
|
|
|
3660
3719
|
};
|
|
3661
3720
|
}
|
|
3662
3721
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
3663
|
-
import { existsSync as
|
|
3664
|
-
import { resolve as
|
|
3722
|
+
import { existsSync as existsSync19, readFileSync as readFileSync9 } from "fs";
|
|
3723
|
+
import { resolve as resolve18 } from "path";
|
|
3665
3724
|
|
|
3666
3725
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
3667
|
-
import { existsSync as
|
|
3668
|
-
import { resolve as
|
|
3726
|
+
import { existsSync as existsSync18 } from "fs";
|
|
3727
|
+
import { resolve as resolve17 } from "path";
|
|
3669
3728
|
|
|
3670
3729
|
// packages/runtime/src/control-plane/repos/layout.ts
|
|
3671
3730
|
init_layout();
|
|
3672
|
-
import { existsSync as
|
|
3673
|
-
import { basename as basename5, dirname as
|
|
3731
|
+
import { existsSync as existsSync17 } from "fs";
|
|
3732
|
+
import { basename as basename5, dirname as dirname10, join as join4, resolve as resolve16 } from "path";
|
|
3674
3733
|
function resolveRepoStateDir(projectRoot) {
|
|
3675
|
-
const normalizedProjectRoot =
|
|
3676
|
-
const projectParent =
|
|
3734
|
+
const normalizedProjectRoot = resolve16(projectRoot);
|
|
3735
|
+
const projectParent = dirname10(normalizedProjectRoot);
|
|
3677
3736
|
if (basename5(projectParent) === ".worktrees") {
|
|
3678
|
-
const ownerRoot =
|
|
3679
|
-
const ownerHasRepoMarkers =
|
|
3737
|
+
const ownerRoot = dirname10(projectParent);
|
|
3738
|
+
const ownerHasRepoMarkers = existsSync17(resolve16(ownerRoot, ".git")) || existsSync17(resolve16(ownerRoot, ".rig", "state"));
|
|
3680
3739
|
if (ownerHasRepoMarkers) {
|
|
3681
|
-
return
|
|
3740
|
+
return resolve16(ownerRoot, ".rig", "state");
|
|
3682
3741
|
}
|
|
3683
3742
|
}
|
|
3684
|
-
return
|
|
3743
|
+
return resolve16(projectRoot, ".rig", "state");
|
|
3685
3744
|
}
|
|
3686
3745
|
function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
3687
|
-
const normalizedProjectRoot =
|
|
3746
|
+
const normalizedProjectRoot = resolve16(projectRoot);
|
|
3688
3747
|
const entry = getManagedRepoEntry(repoId);
|
|
3689
3748
|
const stateDir = resolveRepoStateDir(normalizedProjectRoot);
|
|
3690
3749
|
const metadataRelativePath = join4("repos", entry.id);
|
|
3691
|
-
const metadataRoot =
|
|
3750
|
+
const metadataRoot = resolve16(stateDir, metadataRelativePath);
|
|
3692
3751
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3693
|
-
const runsInsideTaskWorktree = runtimeWorkspace &&
|
|
3752
|
+
const runsInsideTaskWorktree = runtimeWorkspace && resolve16(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname10(normalizedProjectRoot)) === ".worktrees";
|
|
3694
3753
|
const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
|
|
3695
|
-
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ?
|
|
3754
|
+
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve16(process.env[entry.checkoutEnvVar].trim()) : resolve16(normalizedProjectRoot, entry.alias);
|
|
3696
3755
|
return {
|
|
3697
3756
|
projectRoot: normalizedProjectRoot,
|
|
3698
3757
|
repoId: entry.id,
|
|
@@ -3700,12 +3759,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
|
3700
3759
|
defaultBranch: entry.defaultBranch,
|
|
3701
3760
|
remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
|
|
3702
3761
|
checkoutRoot,
|
|
3703
|
-
worktreesRoot:
|
|
3762
|
+
worktreesRoot: resolve16(checkoutRoot, ".worktrees"),
|
|
3704
3763
|
stateDir,
|
|
3705
3764
|
metadataRoot,
|
|
3706
3765
|
metadataRelativePath,
|
|
3707
|
-
mirrorRoot:
|
|
3708
|
-
mirrorStatePath:
|
|
3766
|
+
mirrorRoot: resolve16(metadataRoot, "mirror.git"),
|
|
3767
|
+
mirrorStatePath: resolve16(metadataRoot, "mirror-state.json"),
|
|
3709
3768
|
mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
|
|
3710
3769
|
};
|
|
3711
3770
|
}
|
|
@@ -3723,7 +3782,7 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3723
3782
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3724
3783
|
try {
|
|
3725
3784
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
3726
|
-
if (
|
|
3785
|
+
if (existsSync18(resolve17(layout.mirrorRoot, "HEAD"))) {
|
|
3727
3786
|
return layout.mirrorRoot;
|
|
3728
3787
|
}
|
|
3729
3788
|
} catch {}
|
|
@@ -3734,8 +3793,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3734
3793
|
var DEFAULT_READ_DEPS2 = {
|
|
3735
3794
|
fetchRef: nativeFetchRef,
|
|
3736
3795
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
3737
|
-
exists:
|
|
3738
|
-
readFile: (path) =>
|
|
3796
|
+
exists: existsSync19,
|
|
3797
|
+
readFile: (path) => readFileSync9(path, "utf8")
|
|
3739
3798
|
};
|
|
3740
3799
|
function parseIssueStatus(rawStatus) {
|
|
3741
3800
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -3816,12 +3875,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
3816
3875
|
if (runtimeContextPath) {
|
|
3817
3876
|
return true;
|
|
3818
3877
|
}
|
|
3819
|
-
return
|
|
3878
|
+
return existsSync19(resolve18(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
3820
3879
|
}
|
|
3821
3880
|
function readLocalTrackerState(projectRoot, deps) {
|
|
3822
3881
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3823
|
-
const issuesPath =
|
|
3824
|
-
const taskStatePath =
|
|
3882
|
+
const issuesPath = resolve18(monorepoRoot, ".beads", "issues.jsonl");
|
|
3883
|
+
const taskStatePath = resolve18(monorepoRoot, ".beads", "task-state.json");
|
|
3825
3884
|
return projectSyncedTrackerSnapshot({
|
|
3826
3885
|
source: "local",
|
|
3827
3886
|
issuesBaseOid: null,
|
|
@@ -3883,7 +3942,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
3883
3942
|
return readValidationDescriptionMap(raw);
|
|
3884
3943
|
}
|
|
3885
3944
|
function readSourceValidationDescriptions(projectRoot) {
|
|
3886
|
-
const rootRaw = readJsonFile(
|
|
3945
|
+
const rootRaw = readJsonFile(resolve19(projectRoot, "rig", "task-config.json"), {});
|
|
3887
3946
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
3888
3947
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
3889
3948
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -3959,15 +4018,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
3959
4018
|
return meta.validation_descriptions;
|
|
3960
4019
|
}
|
|
3961
4020
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
3962
|
-
const taskStatePath =
|
|
4021
|
+
const taskStatePath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
3963
4022
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
3964
4023
|
}
|
|
3965
4024
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
3966
|
-
const issuesPath =
|
|
3967
|
-
if (!
|
|
4025
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
4026
|
+
if (!existsSync20(issuesPath)) {
|
|
3968
4027
|
return null;
|
|
3969
4028
|
}
|
|
3970
|
-
for (const line of
|
|
4029
|
+
for (const line of readFileSync10(issuesPath, "utf8").split(/\r?\n/)) {
|
|
3971
4030
|
const trimmed = line.trim();
|
|
3972
4031
|
if (!trimmed) {
|
|
3973
4032
|
continue;
|
|
@@ -3992,25 +4051,25 @@ function inferTaskIdFromRuntimePath(path) {
|
|
|
3992
4051
|
function artifactDirForId(projectRoot, id) {
|
|
3993
4052
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3994
4053
|
if (workspaceDir) {
|
|
3995
|
-
const worktreeArtifacts =
|
|
3996
|
-
if (
|
|
4054
|
+
const worktreeArtifacts = resolve19(workspaceDir, "artifacts", id);
|
|
4055
|
+
if (existsSync20(worktreeArtifacts) || existsSync20(resolve19(workspaceDir, "artifacts"))) {
|
|
3997
4056
|
return worktreeArtifacts;
|
|
3998
4057
|
}
|
|
3999
4058
|
}
|
|
4000
4059
|
try {
|
|
4001
4060
|
const paths = resolveHarnessPaths(projectRoot);
|
|
4002
|
-
return
|
|
4061
|
+
return resolve19(paths.artifactsDir, id);
|
|
4003
4062
|
} catch {
|
|
4004
|
-
return
|
|
4063
|
+
return resolve19(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
4005
4064
|
}
|
|
4006
4065
|
}
|
|
4007
4066
|
function resolveTaskConfigPath(projectRoot) {
|
|
4008
4067
|
const paths = resolveHarnessPaths(projectRoot);
|
|
4009
|
-
if (
|
|
4068
|
+
if (existsSync20(paths.taskConfigPath)) {
|
|
4010
4069
|
return paths.taskConfigPath;
|
|
4011
4070
|
}
|
|
4012
4071
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
4013
|
-
if (
|
|
4072
|
+
if (existsSync20(candidate)) {
|
|
4014
4073
|
return candidate;
|
|
4015
4074
|
}
|
|
4016
4075
|
}
|
|
@@ -4018,7 +4077,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
4018
4077
|
}
|
|
4019
4078
|
function findSourceTaskConfigPath(projectRoot) {
|
|
4020
4079
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
4021
|
-
if (
|
|
4080
|
+
if (existsSync20(candidate)) {
|
|
4022
4081
|
return candidate;
|
|
4023
4082
|
}
|
|
4024
4083
|
}
|
|
@@ -4031,7 +4090,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
4031
4090
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
4032
4091
|
if (sourcePath && synced.updated) {
|
|
4033
4092
|
try {
|
|
4034
|
-
|
|
4093
|
+
writeFileSync8(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
4035
4094
|
`, "utf-8");
|
|
4036
4095
|
} catch {}
|
|
4037
4096
|
}
|
|
@@ -4083,12 +4142,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
4083
4142
|
return !candidate.role;
|
|
4084
4143
|
}
|
|
4085
4144
|
function readSourceIssueRecords(projectRoot) {
|
|
4086
|
-
const issuesPath =
|
|
4087
|
-
if (!
|
|
4145
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
4146
|
+
if (!existsSync20(issuesPath)) {
|
|
4088
4147
|
return [];
|
|
4089
4148
|
}
|
|
4090
4149
|
const records = [];
|
|
4091
|
-
for (const line of
|
|
4150
|
+
for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
4092
4151
|
const trimmed = line.trim();
|
|
4093
4152
|
if (!trimmed) {
|
|
4094
4153
|
continue;
|
|
@@ -4144,19 +4203,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
4144
4203
|
if (!sourcePath) {
|
|
4145
4204
|
return {};
|
|
4146
4205
|
}
|
|
4147
|
-
const directory =
|
|
4148
|
-
if (!
|
|
4206
|
+
const directory = resolve19(projectRoot, sourcePath);
|
|
4207
|
+
if (!existsSync20(directory)) {
|
|
4149
4208
|
return {};
|
|
4150
4209
|
}
|
|
4151
4210
|
const config = {};
|
|
4152
4211
|
for (const name of readdirSync3(directory)) {
|
|
4153
4212
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
4154
4213
|
continue;
|
|
4155
|
-
const file =
|
|
4214
|
+
const file = resolve19(directory, name);
|
|
4156
4215
|
try {
|
|
4157
4216
|
if (!statSync4(file).isFile())
|
|
4158
4217
|
continue;
|
|
4159
|
-
const raw = JSON.parse(
|
|
4218
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
4160
4219
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
4161
4220
|
continue;
|
|
4162
4221
|
const record = raw;
|
|
@@ -4198,10 +4257,10 @@ function firstStringList2(...candidates) {
|
|
|
4198
4257
|
return [];
|
|
4199
4258
|
}
|
|
4200
4259
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
4201
|
-
const jsonPath =
|
|
4202
|
-
if (
|
|
4260
|
+
const jsonPath = resolve19(projectRoot, "rig.config.json");
|
|
4261
|
+
if (existsSync20(jsonPath)) {
|
|
4203
4262
|
try {
|
|
4204
|
-
const parsed = JSON.parse(
|
|
4263
|
+
const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
|
|
4205
4264
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4206
4265
|
const taskSource = parsed.taskSource;
|
|
4207
4266
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -4213,12 +4272,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
4213
4272
|
return null;
|
|
4214
4273
|
}
|
|
4215
4274
|
}
|
|
4216
|
-
const tsPath =
|
|
4217
|
-
if (!
|
|
4275
|
+
const tsPath = resolve19(projectRoot, "rig.config.ts");
|
|
4276
|
+
if (!existsSync20(tsPath)) {
|
|
4218
4277
|
return null;
|
|
4219
4278
|
}
|
|
4220
4279
|
try {
|
|
4221
|
-
const source =
|
|
4280
|
+
const source = readFileSync10(tsPath, "utf8");
|
|
4222
4281
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
4223
4282
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
4224
4283
|
if (kind !== "files") {
|
|
@@ -4232,9 +4291,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
4232
4291
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
4233
4292
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
4234
4293
|
return [
|
|
4235
|
-
runtimeContext?.monorepoMainRoot ?
|
|
4236
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
4237
|
-
|
|
4294
|
+
runtimeContext?.monorepoMainRoot ? resolve19(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
4295
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve19(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
4296
|
+
resolve19(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
4238
4297
|
].filter(Boolean);
|
|
4239
4298
|
}
|
|
4240
4299
|
|
|
@@ -4243,8 +4302,8 @@ init_layout();
|
|
|
4243
4302
|
|
|
4244
4303
|
// packages/runtime/src/binary-run.ts
|
|
4245
4304
|
init_layout();
|
|
4246
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
4247
|
-
import { basename as basename7, dirname as
|
|
4305
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync21, mkdirSync as mkdirSync10, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
4306
|
+
import { basename as basename7, dirname as dirname11, resolve as resolve20 } from "path";
|
|
4248
4307
|
import { fileURLToPath } from "url";
|
|
4249
4308
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
4250
4309
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -4270,9 +4329,9 @@ async function buildRuntimeBinary(options) {
|
|
|
4270
4329
|
});
|
|
4271
4330
|
}
|
|
4272
4331
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
4273
|
-
const tempBuildDir =
|
|
4274
|
-
const tempOutputPath =
|
|
4275
|
-
|
|
4332
|
+
const tempBuildDir = resolve20(dirname11(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4333
|
+
const tempOutputPath = resolve20(tempBuildDir, basename7(options.outputPath));
|
|
4334
|
+
mkdirSync10(tempBuildDir, { recursive: true });
|
|
4276
4335
|
await withTemporaryEnv({
|
|
4277
4336
|
...options.env,
|
|
4278
4337
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -4297,7 +4356,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4297
4356
|
`);
|
|
4298
4357
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
4299
4358
|
}
|
|
4300
|
-
if (!
|
|
4359
|
+
if (!existsSync21(tempOutputPath)) {
|
|
4301
4360
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
4302
4361
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
4303
4362
|
}
|
|
@@ -4329,8 +4388,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4329
4388
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4330
4389
|
return {
|
|
4331
4390
|
...options,
|
|
4332
|
-
entrypoint:
|
|
4333
|
-
outputPath:
|
|
4391
|
+
entrypoint: resolve20(options.cwd, options.sourcePath),
|
|
4392
|
+
outputPath: resolve20(options.outputPath)
|
|
4334
4393
|
};
|
|
4335
4394
|
}
|
|
4336
4395
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4344,7 +4403,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4344
4403
|
}
|
|
4345
4404
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4346
4405
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4347
|
-
if (!workerSourcePath || !
|
|
4406
|
+
if (!workerSourcePath || !existsSync21(workerSourcePath)) {
|
|
4348
4407
|
await buildRuntimeBinaryInProcess(options, {
|
|
4349
4408
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4350
4409
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4381,7 +4440,7 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4381
4440
|
}
|
|
4382
4441
|
}
|
|
4383
4442
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4384
|
-
return
|
|
4443
|
+
return resolve20(dirname11(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4385
4444
|
}
|
|
4386
4445
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4387
4446
|
const envRoots = [
|
|
@@ -4390,13 +4449,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4390
4449
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4391
4450
|
].filter(Boolean);
|
|
4392
4451
|
for (const root of envRoots) {
|
|
4393
|
-
const candidate =
|
|
4394
|
-
if (
|
|
4452
|
+
const candidate = resolve20(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4453
|
+
if (existsSync21(candidate)) {
|
|
4395
4454
|
return candidate;
|
|
4396
4455
|
}
|
|
4397
4456
|
}
|
|
4398
|
-
const localCandidate =
|
|
4399
|
-
return
|
|
4457
|
+
const localCandidate = resolve20(import.meta.dir, "binary-build-worker.ts");
|
|
4458
|
+
return existsSync21(localCandidate) ? localCandidate : null;
|
|
4400
4459
|
}
|
|
4401
4460
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4402
4461
|
const bunPath = Bun.which("bun");
|
|
@@ -4432,7 +4491,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4432
4491
|
});
|
|
4433
4492
|
}
|
|
4434
4493
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4435
|
-
if (!
|
|
4494
|
+
if (!existsSync21(input.outputPath) || !existsSync21(input.manifestPath)) {
|
|
4436
4495
|
return false;
|
|
4437
4496
|
}
|
|
4438
4497
|
let manifest = null;
|
|
@@ -4445,7 +4504,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4445
4504
|
return false;
|
|
4446
4505
|
}
|
|
4447
4506
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4448
|
-
if (!
|
|
4507
|
+
if (!existsSync21(filePath)) {
|
|
4449
4508
|
return false;
|
|
4450
4509
|
}
|
|
4451
4510
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4458,7 +4517,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4458
4517
|
const inputs = {};
|
|
4459
4518
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4460
4519
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4461
|
-
if (!normalized || !
|
|
4520
|
+
if (!normalized || !existsSync21(normalized)) {
|
|
4462
4521
|
continue;
|
|
4463
4522
|
}
|
|
4464
4523
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4481,7 +4540,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4481
4540
|
if (inputPath.startsWith("<")) {
|
|
4482
4541
|
return null;
|
|
4483
4542
|
}
|
|
4484
|
-
return
|
|
4543
|
+
return resolve20(cwd, inputPath);
|
|
4485
4544
|
}
|
|
4486
4545
|
async function sha256File4(path) {
|
|
4487
4546
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4497,8 +4556,8 @@ function sortRecord(value) {
|
|
|
4497
4556
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4498
4557
|
const previous = runtimeBinaryBuildQueue;
|
|
4499
4558
|
let release;
|
|
4500
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4501
|
-
release =
|
|
4559
|
+
runtimeBinaryBuildQueue = new Promise((resolve21) => {
|
|
4560
|
+
release = resolve21;
|
|
4502
4561
|
});
|
|
4503
4562
|
await previous;
|
|
4504
4563
|
try {
|
|
@@ -4543,11 +4602,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4543
4602
|
}
|
|
4544
4603
|
|
|
4545
4604
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4546
|
-
import { delimiter, resolve as
|
|
4605
|
+
import { delimiter, resolve as resolve23 } from "path";
|
|
4547
4606
|
|
|
4548
4607
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
4549
|
-
import { existsSync as
|
|
4550
|
-
import { resolve as
|
|
4608
|
+
import { existsSync as existsSync23, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
4609
|
+
import { resolve as resolve22 } from "path";
|
|
4551
4610
|
|
|
4552
4611
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
4553
4612
|
init_utils();
|
|
@@ -4564,7 +4623,7 @@ function resolveBunBinaryPath() {
|
|
|
4564
4623
|
}
|
|
4565
4624
|
const home = process.env.HOME?.trim();
|
|
4566
4625
|
const fallbackCandidates = [
|
|
4567
|
-
home ?
|
|
4626
|
+
home ? resolve22(home, ".bun/bin/bun") : "",
|
|
4568
4627
|
"/opt/homebrew/bin/bun",
|
|
4569
4628
|
"/usr/local/bin/bun",
|
|
4570
4629
|
"/usr/bin/bun"
|
|
@@ -4592,8 +4651,8 @@ function resolveClaudeBinaryPath() {
|
|
|
4592
4651
|
}
|
|
4593
4652
|
const home = process.env.HOME?.trim();
|
|
4594
4653
|
const fallbackCandidates = [
|
|
4595
|
-
home ?
|
|
4596
|
-
home ?
|
|
4654
|
+
home ? resolve22(home, ".local/bin/claude") : "",
|
|
4655
|
+
home ? resolve22(home, ".local/share/claude/local/claude") : "",
|
|
4597
4656
|
"/opt/homebrew/bin/claude",
|
|
4598
4657
|
"/usr/local/bin/claude",
|
|
4599
4658
|
"/usr/bin/claude"
|
|
@@ -4607,35 +4666,35 @@ function resolveClaudeBinaryPath() {
|
|
|
4607
4666
|
throw new Error("claude not found in PATH");
|
|
4608
4667
|
}
|
|
4609
4668
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
4610
|
-
return
|
|
4669
|
+
return resolve22(bunBinaryPath, "../..");
|
|
4611
4670
|
}
|
|
4612
4671
|
function resolveClaudeInstallDir() {
|
|
4613
4672
|
const realPath = resolveClaudeBinaryPath();
|
|
4614
|
-
return
|
|
4673
|
+
return resolve22(realPath, "..");
|
|
4615
4674
|
}
|
|
4616
4675
|
function resolveNodeInstallDir() {
|
|
4617
4676
|
const preferredNode = resolvePreferredNodeBinary();
|
|
4618
4677
|
if (!preferredNode)
|
|
4619
4678
|
return null;
|
|
4620
4679
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
4621
|
-
if (explicitNode &&
|
|
4622
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
4680
|
+
if (explicitNode && resolve22(explicitNode) === resolve22(preferredNode)) {
|
|
4681
|
+
return preferredNode.endsWith("/bin/node") ? resolve22(preferredNode, "../..") : resolve22(preferredNode, "..");
|
|
4623
4682
|
}
|
|
4624
4683
|
try {
|
|
4625
4684
|
const realPath = realpathSync2(preferredNode);
|
|
4626
4685
|
if (realPath.endsWith("/bin/node")) {
|
|
4627
|
-
return
|
|
4686
|
+
return resolve22(realPath, "../..");
|
|
4628
4687
|
}
|
|
4629
|
-
return
|
|
4688
|
+
return resolve22(realPath, "..");
|
|
4630
4689
|
} catch {
|
|
4631
|
-
return
|
|
4690
|
+
return resolve22(preferredNode, "..");
|
|
4632
4691
|
}
|
|
4633
4692
|
}
|
|
4634
4693
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
4635
4694
|
const roots = [];
|
|
4636
4695
|
if (process.platform === "darwin") {
|
|
4637
4696
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
4638
|
-
if (
|
|
4697
|
+
if (existsSync23(macPath)) {
|
|
4639
4698
|
roots.push(macPath);
|
|
4640
4699
|
}
|
|
4641
4700
|
}
|
|
@@ -4653,23 +4712,23 @@ function resolvePreferredNodeBinary() {
|
|
|
4653
4712
|
const candidates = [];
|
|
4654
4713
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
4655
4714
|
if (envNode) {
|
|
4656
|
-
const explicit =
|
|
4657
|
-
if (
|
|
4715
|
+
const explicit = resolve22(envNode);
|
|
4716
|
+
if (existsSync23(explicit)) {
|
|
4658
4717
|
return explicit;
|
|
4659
4718
|
}
|
|
4660
4719
|
}
|
|
4661
4720
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
4662
4721
|
if (nvmBin) {
|
|
4663
|
-
candidates.push(
|
|
4722
|
+
candidates.push(resolve22(nvmBin, "node"));
|
|
4664
4723
|
}
|
|
4665
4724
|
const home = process.env.HOME?.trim();
|
|
4666
4725
|
if (home) {
|
|
4667
|
-
const nvmVersionsDir =
|
|
4668
|
-
if (
|
|
4726
|
+
const nvmVersionsDir = resolve22(home, ".nvm/versions/node");
|
|
4727
|
+
if (existsSync23(nvmVersionsDir)) {
|
|
4669
4728
|
try {
|
|
4670
4729
|
const versionDirs = readdirSync5(nvmVersionsDir).map((entry) => entry.trim()).filter((entry) => /^v\d+\.\d+\.\d+$/.test(entry)).sort((a, b) => Bun.semver.order(b.replace(/^v/, ""), a.replace(/^v/, "")));
|
|
4671
4730
|
for (const versionDir of versionDirs) {
|
|
4672
|
-
candidates.push(
|
|
4731
|
+
candidates.push(resolve22(nvmVersionsDir, versionDir, "bin/node"));
|
|
4673
4732
|
}
|
|
4674
4733
|
} catch {}
|
|
4675
4734
|
}
|
|
@@ -4678,8 +4737,8 @@ function resolvePreferredNodeBinary() {
|
|
|
4678
4737
|
if (whichNode) {
|
|
4679
4738
|
candidates.push(whichNode);
|
|
4680
4739
|
}
|
|
4681
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
4682
|
-
const existing = deduped.filter((candidate) =>
|
|
4740
|
+
const deduped = uniq(candidates.map((candidate) => resolve22(candidate)));
|
|
4741
|
+
const existing = deduped.filter((candidate) => existsSync23(candidate));
|
|
4683
4742
|
if (existing.length === 0) {
|
|
4684
4743
|
return null;
|
|
4685
4744
|
}
|
|
@@ -4693,7 +4752,7 @@ function resolvePreferredNodeBinary() {
|
|
|
4693
4752
|
return existing[0] ?? null;
|
|
4694
4753
|
}
|
|
4695
4754
|
function inferNodeMajor(nodeBinaryPath) {
|
|
4696
|
-
const normalized =
|
|
4755
|
+
const normalized = resolve22(nodeBinaryPath).replace(/\\/g, "/");
|
|
4697
4756
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
4698
4757
|
if (!match) {
|
|
4699
4758
|
return null;
|
|
@@ -4705,8 +4764,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
4705
4764
|
if (!candidate) {
|
|
4706
4765
|
return "";
|
|
4707
4766
|
}
|
|
4708
|
-
const normalized =
|
|
4709
|
-
if (!
|
|
4767
|
+
const normalized = resolve22(candidate);
|
|
4768
|
+
if (!existsSync23(normalized)) {
|
|
4710
4769
|
return "";
|
|
4711
4770
|
}
|
|
4712
4771
|
try {
|
|
@@ -4716,7 +4775,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
4716
4775
|
}
|
|
4717
4776
|
}
|
|
4718
4777
|
function looksLikeRuntimeGateway(candidate) {
|
|
4719
|
-
const normalized =
|
|
4778
|
+
const normalized = resolve22(candidate).replace(/\\/g, "/");
|
|
4720
4779
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
4721
4780
|
}
|
|
4722
4781
|
|
|
@@ -4737,7 +4796,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4737
4796
|
try {
|
|
4738
4797
|
return resolveClaudeInstallDir();
|
|
4739
4798
|
} catch {
|
|
4740
|
-
return
|
|
4799
|
+
return resolve23(claudeBinary, "..");
|
|
4741
4800
|
}
|
|
4742
4801
|
})() : "";
|
|
4743
4802
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -4747,8 +4806,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4747
4806
|
`${bunDir}/bin`,
|
|
4748
4807
|
claudeDir,
|
|
4749
4808
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
4750
|
-
realHome ?
|
|
4751
|
-
realHome ?
|
|
4809
|
+
realHome ? resolve23(realHome, ".local/bin") : "",
|
|
4810
|
+
realHome ? resolve23(realHome, ".cargo/bin") : "",
|
|
4752
4811
|
...inheritedPath,
|
|
4753
4812
|
"/usr/local/bin",
|
|
4754
4813
|
"/usr/local/sbin",
|
|
@@ -4777,8 +4836,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4777
4836
|
}
|
|
4778
4837
|
|
|
4779
4838
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
4780
|
-
import { existsSync as
|
|
4781
|
-
import { resolve as
|
|
4839
|
+
import { existsSync as existsSync24, readFileSync as readFileSync11 } from "fs";
|
|
4840
|
+
import { resolve as resolve24 } from "path";
|
|
4782
4841
|
var BAKED_RUNTIME_SECRETS = {
|
|
4783
4842
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
4784
4843
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -4821,12 +4880,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
4821
4880
|
return resolved;
|
|
4822
4881
|
}
|
|
4823
4882
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
4824
|
-
const dotenvPath =
|
|
4825
|
-
if (!
|
|
4883
|
+
const dotenvPath = resolve24(projectRoot, ".env");
|
|
4884
|
+
if (!existsSync24(dotenvPath)) {
|
|
4826
4885
|
return {};
|
|
4827
4886
|
}
|
|
4828
4887
|
const parsed = {};
|
|
4829
|
-
const lines =
|
|
4888
|
+
const lines = readFileSync11(dotenvPath, "utf-8").split(/\r?\n/);
|
|
4830
4889
|
for (const rawLine of lines) {
|
|
4831
4890
|
const line = rawLine.trim();
|
|
4832
4891
|
if (!line || line.startsWith("#")) {
|
|
@@ -5183,16 +5242,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
5183
5242
|
for (const dep of deps) {
|
|
5184
5243
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
5185
5244
|
console.log(`=== ${dep} ===`);
|
|
5186
|
-
if (!
|
|
5245
|
+
if (!existsSync25(artifactDir)) {
|
|
5187
5246
|
console.log(` (no artifacts yet)
|
|
5188
5247
|
`);
|
|
5189
5248
|
continue;
|
|
5190
5249
|
}
|
|
5191
|
-
printArtifactSection(
|
|
5192
|
-
printArtifactSection(
|
|
5193
|
-
const changedFiles =
|
|
5194
|
-
if (
|
|
5195
|
-
const lines =
|
|
5250
|
+
printArtifactSection(resolve25(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
5251
|
+
printArtifactSection(resolve25(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
5252
|
+
const changedFiles = resolve25(artifactDir, "changed-files.txt");
|
|
5253
|
+
if (existsSync25(changedFiles)) {
|
|
5254
|
+
const lines = readFileSync12(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
5196
5255
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
5197
5256
|
for (const line of lines) {
|
|
5198
5257
|
console.log(line);
|
|
@@ -5316,12 +5375,12 @@ function printIndented(text) {
|
|
|
5316
5375
|
}
|
|
5317
5376
|
}
|
|
5318
5377
|
function readLocalBeadsTasks(projectRoot) {
|
|
5319
|
-
const issuesPath =
|
|
5320
|
-
if (!
|
|
5378
|
+
const issuesPath = resolve25(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5379
|
+
if (!existsSync25(issuesPath)) {
|
|
5321
5380
|
return [];
|
|
5322
5381
|
}
|
|
5323
5382
|
const tasks = [];
|
|
5324
|
-
for (const line of
|
|
5383
|
+
for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
5325
5384
|
const trimmed = line.trim();
|
|
5326
5385
|
if (!trimmed) {
|
|
5327
5386
|
continue;
|
|
@@ -5434,11 +5493,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5434
5493
|
return [...ids].sort();
|
|
5435
5494
|
}
|
|
5436
5495
|
function printArtifactSection(path, header) {
|
|
5437
|
-
if (!
|
|
5496
|
+
if (!existsSync25(path)) {
|
|
5438
5497
|
return;
|
|
5439
5498
|
}
|
|
5440
5499
|
console.log(header);
|
|
5441
|
-
process.stdout.write(
|
|
5500
|
+
process.stdout.write(readFileSync12(path, "utf-8"));
|
|
5442
5501
|
console.log("");
|
|
5443
5502
|
}
|
|
5444
5503
|
|
|
@@ -5540,7 +5599,7 @@ init_layout();
|
|
|
5540
5599
|
|
|
5541
5600
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5542
5601
|
init_layout();
|
|
5543
|
-
import { mkdirSync as
|
|
5602
|
+
import { mkdirSync as mkdirSync12 } from "fs";
|
|
5544
5603
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5545
5604
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5546
5605
|
const rootDir = layout.rigRoot;
|
|
@@ -5552,14 +5611,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5552
5611
|
const sessionDir = layout.sessionDir;
|
|
5553
5612
|
const runtimeDir = layout.runtimeDir;
|
|
5554
5613
|
const contextPath = layout.contextPath;
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5614
|
+
mkdirSync12(rootDir, { recursive: true });
|
|
5615
|
+
mkdirSync12(homeDir, { recursive: true });
|
|
5616
|
+
mkdirSync12(tmpDir, { recursive: true });
|
|
5617
|
+
mkdirSync12(cacheDir, { recursive: true });
|
|
5618
|
+
mkdirSync12(logsDir, { recursive: true });
|
|
5619
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
5620
|
+
mkdirSync12(sessionDir, { recursive: true });
|
|
5621
|
+
mkdirSync12(runtimeDir, { recursive: true });
|
|
5563
5622
|
return {
|
|
5564
5623
|
rootDir,
|
|
5565
5624
|
homeDir,
|
|
@@ -5577,17 +5636,17 @@ import {
|
|
|
5577
5636
|
chmodSync as chmodSync5,
|
|
5578
5637
|
copyFileSync as copyFileSync5,
|
|
5579
5638
|
cpSync as cpSync2,
|
|
5580
|
-
existsSync as
|
|
5581
|
-
mkdirSync as
|
|
5639
|
+
existsSync as existsSync27,
|
|
5640
|
+
mkdirSync as mkdirSync13,
|
|
5582
5641
|
statSync as statSync5,
|
|
5583
|
-
writeFileSync as
|
|
5642
|
+
writeFileSync as writeFileSync11
|
|
5584
5643
|
} from "fs";
|
|
5585
5644
|
import { mkdir } from "fs/promises";
|
|
5586
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
5645
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve27 } from "path";
|
|
5587
5646
|
|
|
5588
5647
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
5589
|
-
import { existsSync as
|
|
5590
|
-
import { resolve as
|
|
5648
|
+
import { existsSync as existsSync26, readFileSync as readFileSync13, rmSync as rmSync9 } from "fs";
|
|
5649
|
+
import { resolve as resolve26 } from "path";
|
|
5591
5650
|
var generatedCredentialFiles = new Set;
|
|
5592
5651
|
var credentialCleanupRegistered = false;
|
|
5593
5652
|
function resolveMonorepoRoot3(projectRoot) {
|
|
@@ -5611,7 +5670,7 @@ function resolveHostGitBinary() {
|
|
|
5611
5670
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
5612
5671
|
continue;
|
|
5613
5672
|
}
|
|
5614
|
-
if (
|
|
5673
|
+
if (existsSync26(candidate)) {
|
|
5615
5674
|
return candidate;
|
|
5616
5675
|
}
|
|
5617
5676
|
}
|
|
@@ -5677,7 +5736,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
5677
5736
|
}
|
|
5678
5737
|
}
|
|
5679
5738
|
async function tryReadGitHead(repoRoot) {
|
|
5680
|
-
if (!
|
|
5739
|
+
if (!existsSync26(resolve26(repoRoot, ".git"))) {
|
|
5681
5740
|
return;
|
|
5682
5741
|
}
|
|
5683
5742
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -5688,7 +5747,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
5688
5747
|
return value || undefined;
|
|
5689
5748
|
}
|
|
5690
5749
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
5691
|
-
if (!
|
|
5750
|
+
if (!existsSync26(resolve26(repoRoot, ".git"))) {
|
|
5692
5751
|
return [];
|
|
5693
5752
|
}
|
|
5694
5753
|
const files = new Set;
|
|
@@ -5776,16 +5835,16 @@ function hashProjectPath(workspaceDir) {
|
|
|
5776
5835
|
}
|
|
5777
5836
|
function resolveGithubCliBinaryPath() {
|
|
5778
5837
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
5779
|
-
if (explicit &&
|
|
5838
|
+
if (explicit && existsSync26(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
5780
5839
|
return explicit;
|
|
5781
5840
|
}
|
|
5782
5841
|
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
5783
|
-
if (
|
|
5842
|
+
if (existsSync26(candidate)) {
|
|
5784
5843
|
return candidate;
|
|
5785
5844
|
}
|
|
5786
5845
|
}
|
|
5787
5846
|
const bunResolved = Bun.which("gh");
|
|
5788
|
-
if (bunResolved &&
|
|
5847
|
+
if (bunResolved && existsSync26(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
5789
5848
|
return bunResolved;
|
|
5790
5849
|
}
|
|
5791
5850
|
return "";
|
|
@@ -5819,17 +5878,17 @@ function resolveSystemCertBundlePath() {
|
|
|
5819
5878
|
"/opt/homebrew/etc/openssl@3/cert.pem"
|
|
5820
5879
|
];
|
|
5821
5880
|
for (const candidate of candidates) {
|
|
5822
|
-
if (candidate &&
|
|
5823
|
-
return
|
|
5881
|
+
if (candidate && existsSync26(candidate)) {
|
|
5882
|
+
return resolve26(candidate);
|
|
5824
5883
|
}
|
|
5825
5884
|
}
|
|
5826
5885
|
return "";
|
|
5827
5886
|
}
|
|
5828
5887
|
function readKnownHosts(path) {
|
|
5829
|
-
if (!
|
|
5888
|
+
if (!existsSync26(path)) {
|
|
5830
5889
|
return new Set;
|
|
5831
5890
|
}
|
|
5832
|
-
return new Set(
|
|
5891
|
+
return new Set(readFileSync13(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
5833
5892
|
}
|
|
5834
5893
|
|
|
5835
5894
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -5844,12 +5903,12 @@ function resolveControlPlaneSourceRoot(projectRoot) {
|
|
|
5844
5903
|
const candidates = [
|
|
5845
5904
|
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
5846
5905
|
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
5847
|
-
|
|
5906
|
+
resolve27(import.meta.dir, "../../../../.."),
|
|
5848
5907
|
projectRoot
|
|
5849
5908
|
].filter((value) => Boolean(value));
|
|
5850
5909
|
for (const candidate of candidates) {
|
|
5851
|
-
const root =
|
|
5852
|
-
if (
|
|
5910
|
+
const root = resolve27(candidate);
|
|
5911
|
+
if (existsSync27(resolve27(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
5853
5912
|
return root;
|
|
5854
5913
|
}
|
|
5855
5914
|
}
|
|
@@ -5869,7 +5928,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5869
5928
|
try {
|
|
5870
5929
|
return resolveClaudeInstallDir();
|
|
5871
5930
|
} catch {
|
|
5872
|
-
return
|
|
5931
|
+
return resolve27(claudeBinaryPath, "..");
|
|
5873
5932
|
}
|
|
5874
5933
|
})() : "";
|
|
5875
5934
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -5884,8 +5943,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5884
5943
|
`${bunDir}/bin`,
|
|
5885
5944
|
claudeDir,
|
|
5886
5945
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
5887
|
-
realHome ?
|
|
5888
|
-
realHome ?
|
|
5946
|
+
realHome ? resolve27(realHome, ".local/bin") : "",
|
|
5947
|
+
realHome ? resolve27(realHome, ".cargo/bin") : "",
|
|
5889
5948
|
...inheritedPath,
|
|
5890
5949
|
"/usr/local/bin",
|
|
5891
5950
|
"/usr/local/sbin",
|
|
@@ -5896,9 +5955,9 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5896
5955
|
"/usr/sbin",
|
|
5897
5956
|
"/sbin"
|
|
5898
5957
|
].filter(Boolean);
|
|
5899
|
-
const runtimeBash =
|
|
5900
|
-
const runtimeRigGit =
|
|
5901
|
-
const preferredShell =
|
|
5958
|
+
const runtimeBash = resolve27(runtime.binDir, "bash");
|
|
5959
|
+
const runtimeRigGit = resolve27(runtime.binDir, runtimeRigGitFileName());
|
|
5960
|
+
const preferredShell = existsSync27(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
5902
5961
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
5903
5962
|
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
5904
5963
|
const env = {
|
|
@@ -5919,30 +5978,30 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5919
5978
|
RIG_RUNTIME_MODE: runtime.mode,
|
|
5920
5979
|
RIG_RUNTIME_HOME: runtime.rootDir,
|
|
5921
5980
|
RIG_RUNTIME_BIN_DIR: runtime.binDir,
|
|
5922
|
-
...
|
|
5981
|
+
...existsSync27(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
|
|
5923
5982
|
RIG_BUN_PATH: bunBinaryPath,
|
|
5924
5983
|
...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
|
|
5925
|
-
RIG_AGENT_BIN:
|
|
5984
|
+
RIG_AGENT_BIN: resolve27(runtime.binDir, "rig-agent"),
|
|
5926
5985
|
RIG_HOOKS_ACTIVE: "1",
|
|
5927
5986
|
RIG_AUTO_PR_ON_COMPLETE: "1",
|
|
5928
|
-
RIG_POLICY_FILE:
|
|
5987
|
+
RIG_POLICY_FILE: resolve27(projectRoot, "rig/policy/policy.json"),
|
|
5929
5988
|
RIG_STATE_DIR: runtime.stateDir,
|
|
5930
5989
|
RIG_LOGS_DIR: runtime.logsDir,
|
|
5931
|
-
RIG_SESSION_FILE:
|
|
5990
|
+
RIG_SESSION_FILE: resolve27(runtime.sessionDir, "session.json"),
|
|
5932
5991
|
MONOREPO_ROOT: runtime.workspaceDir,
|
|
5933
5992
|
MONOREPO_MAIN_ROOT: monorepoMainRoot,
|
|
5934
|
-
TS_API_TESTS_DIR:
|
|
5993
|
+
TS_API_TESTS_DIR: resolve27(runtime.workspaceDir, "TSAPITests"),
|
|
5935
5994
|
BASH: preferredShell,
|
|
5936
5995
|
SHELL: preferredShell,
|
|
5937
5996
|
PATH: [...new Set(pathEntries)].join(delimiter2),
|
|
5938
5997
|
LANG: process.env.LANG ?? "en_US.UTF-8",
|
|
5939
5998
|
TERM: process.env.TERM ?? "xterm-256color",
|
|
5940
5999
|
PYTHONDONTWRITEBYTECODE: "1",
|
|
5941
|
-
PYTHONPYCACHEPREFIX:
|
|
6000
|
+
PYTHONPYCACHEPREFIX: resolve27(runtime.cacheDir, "python"),
|
|
5942
6001
|
...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
|
|
5943
6002
|
...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
|
|
5944
6003
|
CLAUDE_HOME: runtime.claudeHomeDir,
|
|
5945
|
-
PI_CODING_AGENT_DIR:
|
|
6004
|
+
PI_CODING_AGENT_DIR: resolve27(runtime.homeDir, ".pi", "agent"),
|
|
5946
6005
|
[RUNTIME_CONTEXT_ENV]: runtime.contextFile,
|
|
5947
6006
|
...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
|
|
5948
6007
|
...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
|
|
@@ -5953,16 +6012,16 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5953
6012
|
NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
|
|
5954
6013
|
} : {}
|
|
5955
6014
|
};
|
|
5956
|
-
const knownHostsPath =
|
|
5957
|
-
if (
|
|
5958
|
-
const agentSshKey =
|
|
6015
|
+
const knownHostsPath = resolve27(runtime.homeDir, ".ssh", "known_hosts");
|
|
6016
|
+
if (existsSync27(knownHostsPath)) {
|
|
6017
|
+
const agentSshKey = resolve27(runtime.homeDir, ".ssh", "rig-agent-key");
|
|
5959
6018
|
const sshParts = [
|
|
5960
6019
|
"ssh",
|
|
5961
6020
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
5962
6021
|
"-o StrictHostKeyChecking=yes",
|
|
5963
6022
|
"-F /dev/null"
|
|
5964
6023
|
];
|
|
5965
|
-
if (
|
|
6024
|
+
if (existsSync27(agentSshKey)) {
|
|
5966
6025
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
5967
6026
|
}
|
|
5968
6027
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -5999,7 +6058,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5999
6058
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
6000
6059
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
6001
6060
|
}
|
|
6002
|
-
if (
|
|
6061
|
+
if (existsSync27(runtime.contextFile)) {
|
|
6003
6062
|
const runtimeContext = loadRuntimeContext(runtime.contextFile);
|
|
6004
6063
|
Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
|
|
6005
6064
|
Object.assign(env, browserEnvFromContext(runtimeContext.browser));
|
|
@@ -6013,30 +6072,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
6013
6072
|
await mkdir(runtime.cacheDir, { recursive: true });
|
|
6014
6073
|
await provisionAgentSshKey(runtime.homeDir);
|
|
6015
6074
|
if (options.provider === "codex") {
|
|
6016
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
6075
|
+
const hasCodexAuth = await injectCodexAuth(resolve27(runtime.homeDir, ".codex"));
|
|
6017
6076
|
if (!hasCodexAuth) {
|
|
6018
6077
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
6019
6078
|
}
|
|
6020
6079
|
}
|
|
6021
6080
|
if (options.provider === "pi") {
|
|
6022
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
6081
|
+
const hasPiAuth = await injectPiAgentConfig(resolve27(runtime.homeDir, ".pi", "agent"));
|
|
6023
6082
|
if (!hasPiAuth) {
|
|
6024
6083
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
6025
6084
|
}
|
|
6026
6085
|
}
|
|
6027
6086
|
}
|
|
6028
6087
|
async function provisionClaudeHome(config) {
|
|
6029
|
-
|
|
6030
|
-
const workspaceSettings =
|
|
6031
|
-
const hostSettings =
|
|
6032
|
-
const projectSettings =
|
|
6088
|
+
mkdirSync13(config.claudeHomeDir, { recursive: true });
|
|
6089
|
+
const workspaceSettings = resolve27(config.workspaceDir, ".claude/settings.json");
|
|
6090
|
+
const hostSettings = resolve27(config.hostProjectRoot, ".claude/settings.json");
|
|
6091
|
+
const projectSettings = existsSync27(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
6033
6092
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
6034
|
-
if (
|
|
6035
|
-
|
|
6093
|
+
if (existsSync27(projectSettings)) {
|
|
6094
|
+
writeFileSync11(resolve27(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6036
6095
|
`, "utf-8");
|
|
6037
6096
|
}
|
|
6038
6097
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
6039
|
-
|
|
6098
|
+
writeFileSync11(resolve27(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
6040
6099
|
permissions: { defaultMode: "bypassPermissions" },
|
|
6041
6100
|
autoMemoryEnabled: false
|
|
6042
6101
|
}, null, 2));
|
|
@@ -6044,12 +6103,12 @@ async function provisionClaudeHome(config) {
|
|
|
6044
6103
|
if (!hasCredentials) {
|
|
6045
6104
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
6046
6105
|
}
|
|
6047
|
-
const realClaudeHome =
|
|
6048
|
-
if (process.env.HOME &&
|
|
6049
|
-
cpSync2(
|
|
6106
|
+
const realClaudeHome = resolve27(process.env.HOME ?? "", ".claude");
|
|
6107
|
+
if (process.env.HOME && existsSync27(resolve27(realClaudeHome, "CLAUDE.md"))) {
|
|
6108
|
+
cpSync2(resolve27(realClaudeHome, "CLAUDE.md"), resolve27(config.claudeHomeDir, "CLAUDE.md"));
|
|
6050
6109
|
}
|
|
6051
|
-
if (process.env.HOME &&
|
|
6052
|
-
cpSync2(
|
|
6110
|
+
if (process.env.HOME && existsSync27(resolve27(realClaudeHome, "agents"))) {
|
|
6111
|
+
cpSync2(resolve27(realClaudeHome, "agents"), resolve27(config.claudeHomeDir, "agents"), { recursive: true });
|
|
6053
6112
|
}
|
|
6054
6113
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
6055
6114
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -6060,10 +6119,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
6060
6119
|
if (!sourcePath) {
|
|
6061
6120
|
return "";
|
|
6062
6121
|
}
|
|
6063
|
-
const certsDir =
|
|
6064
|
-
const targetPath =
|
|
6122
|
+
const certsDir = resolve27(runtime.rootDir, "certs");
|
|
6123
|
+
const targetPath = resolve27(certsDir, "ca-certificates.pem");
|
|
6065
6124
|
await mkdir(certsDir, { recursive: true });
|
|
6066
|
-
let shouldCopy = !
|
|
6125
|
+
let shouldCopy = !existsSync27(targetPath);
|
|
6067
6126
|
if (!shouldCopy) {
|
|
6068
6127
|
try {
|
|
6069
6128
|
shouldCopy = statSync5(sourcePath).mtimeMs > statSync5(targetPath).mtimeMs;
|
|
@@ -6085,7 +6144,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
6085
6144
|
env.GIT_CONFIG_VALUE_1 = '!f() { test "$1" = get || exit 0; token="${GITHUB_TOKEN:-${GH_TOKEN:-${RIG_GITHUB_TOKEN:-}}}"; test -n "$token" || exit 0; echo username=x-access-token; echo password="$token"; }; f';
|
|
6086
6145
|
}
|
|
6087
6146
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
6088
|
-
const secretsPath =
|
|
6147
|
+
const secretsPath = resolve27(runtimeRoot, "runtime-secrets.json");
|
|
6089
6148
|
const persisted = {};
|
|
6090
6149
|
for (const key of [
|
|
6091
6150
|
"GITHUB_TOKEN",
|
|
@@ -6104,12 +6163,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
6104
6163
|
if (Object.keys(persisted).length === 0) {
|
|
6105
6164
|
return;
|
|
6106
6165
|
}
|
|
6107
|
-
|
|
6166
|
+
writeFileSync11(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
6108
6167
|
`, "utf-8");
|
|
6109
6168
|
}
|
|
6110
6169
|
async function provisionAgentSshKey(homeDir) {
|
|
6111
|
-
const sshDir =
|
|
6112
|
-
if (!
|
|
6170
|
+
const sshDir = resolve27(homeDir, ".ssh");
|
|
6171
|
+
if (!existsSync27(sshDir)) {
|
|
6113
6172
|
await mkdir(sshDir, { recursive: true });
|
|
6114
6173
|
}
|
|
6115
6174
|
seedKnownHosts(sshDir);
|
|
@@ -6117,27 +6176,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
6117
6176
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
6118
6177
|
if (!privateKey) {
|
|
6119
6178
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
6120
|
-
if (!process.env.HOME || !
|
|
6179
|
+
if (!process.env.HOME || !existsSync27(hostKeyPath)) {
|
|
6121
6180
|
return;
|
|
6122
6181
|
}
|
|
6123
|
-
const agentKeyPath2 =
|
|
6124
|
-
if (!
|
|
6182
|
+
const agentKeyPath2 = resolve27(sshDir, "rig-agent-key");
|
|
6183
|
+
if (!existsSync27(agentKeyPath2)) {
|
|
6125
6184
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
6126
6185
|
chmodSync5(agentKeyPath2, 384);
|
|
6127
6186
|
}
|
|
6128
6187
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
6129
|
-
if (
|
|
6188
|
+
if (existsSync27(hostPubPath)) {
|
|
6130
6189
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
6131
|
-
if (!
|
|
6190
|
+
if (!existsSync27(agentPubPath)) {
|
|
6132
6191
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
6133
6192
|
}
|
|
6134
6193
|
}
|
|
6135
6194
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
6136
6195
|
return;
|
|
6137
6196
|
}
|
|
6138
|
-
const agentKeyPath =
|
|
6139
|
-
if (!
|
|
6140
|
-
|
|
6197
|
+
const agentKeyPath = resolve27(sshDir, "rig-agent-key");
|
|
6198
|
+
if (!existsSync27(agentKeyPath)) {
|
|
6199
|
+
writeFileSync11(agentKeyPath, privateKey, { mode: 384 });
|
|
6141
6200
|
}
|
|
6142
6201
|
writeSshConfig(sshDir, agentKeyPath);
|
|
6143
6202
|
}
|
|
@@ -6154,21 +6213,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
6154
6213
|
`;
|
|
6155
6214
|
}
|
|
6156
6215
|
function resolveHostSshKeyPath(homeDir) {
|
|
6157
|
-
const sshDir =
|
|
6216
|
+
const sshDir = resolve27(homeDir, ".ssh");
|
|
6158
6217
|
const candidates = [
|
|
6159
6218
|
"rig-agent-key",
|
|
6160
6219
|
"id_ed25519",
|
|
6161
6220
|
"id_ecdsa",
|
|
6162
6221
|
"id_rsa"
|
|
6163
|
-
].map((name) =>
|
|
6164
|
-
return candidates.find((candidate) =>
|
|
6222
|
+
].map((name) => resolve27(sshDir, name));
|
|
6223
|
+
return candidates.find((candidate) => existsSync27(candidate)) ?? resolve27(sshDir, "rig-agent-key");
|
|
6165
6224
|
}
|
|
6166
6225
|
function writeSshConfig(sshDir, keyPath) {
|
|
6167
|
-
const configPath =
|
|
6168
|
-
if (
|
|
6226
|
+
const configPath = resolve27(sshDir, "config");
|
|
6227
|
+
if (existsSync27(configPath)) {
|
|
6169
6228
|
return;
|
|
6170
6229
|
}
|
|
6171
|
-
const knownHostsPath =
|
|
6230
|
+
const knownHostsPath = resolve27(sshDir, "known_hosts");
|
|
6172
6231
|
const config = [
|
|
6173
6232
|
"Host github.com",
|
|
6174
6233
|
` IdentityFile ${keyPath}`,
|
|
@@ -6178,10 +6237,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
6178
6237
|
""
|
|
6179
6238
|
].join(`
|
|
6180
6239
|
`);
|
|
6181
|
-
|
|
6240
|
+
writeFileSync11(configPath, config, { mode: 420 });
|
|
6182
6241
|
}
|
|
6183
6242
|
function seedKnownHosts(sshDir) {
|
|
6184
|
-
const knownHostsPath =
|
|
6243
|
+
const knownHostsPath = resolve27(sshDir, "known_hosts");
|
|
6185
6244
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
6186
6245
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
6187
6246
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -6192,23 +6251,23 @@ function seedKnownHosts(sshDir) {
|
|
|
6192
6251
|
for (const line of missing) {
|
|
6193
6252
|
existingLines.add(line);
|
|
6194
6253
|
}
|
|
6195
|
-
|
|
6254
|
+
writeFileSync11(knownHostsPath, `${Array.from(existingLines).join(`
|
|
6196
6255
|
`)}
|
|
6197
6256
|
`, { mode: 420 });
|
|
6198
6257
|
} catch (err) {
|
|
6199
|
-
const hint =
|
|
6258
|
+
const hint = existsSync27(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
6200
6259
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
6201
6260
|
}
|
|
6202
6261
|
}
|
|
6203
6262
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
6204
6263
|
const projectHash = hashProjectPath(workspaceDir);
|
|
6205
|
-
const projectDir =
|
|
6206
|
-
|
|
6207
|
-
|
|
6264
|
+
const projectDir = resolve27(claudeHomeDir, "projects", projectHash);
|
|
6265
|
+
mkdirSync13(projectDir, { recursive: true });
|
|
6266
|
+
writeFileSync11(resolve27(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6208
6267
|
`, "utf-8");
|
|
6209
6268
|
}
|
|
6210
6269
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
6211
|
-
if (!
|
|
6270
|
+
if (!existsSync27(projectSettingsPath)) {
|
|
6212
6271
|
return {};
|
|
6213
6272
|
}
|
|
6214
6273
|
let parsed;
|
|
@@ -6254,7 +6313,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
6254
6313
|
return clone;
|
|
6255
6314
|
}
|
|
6256
6315
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
6257
|
-
const credentialsPath =
|
|
6316
|
+
const credentialsPath = resolve27(claudeHomeDir, ".credentials.json");
|
|
6258
6317
|
const platform = options.platform ?? process.platform;
|
|
6259
6318
|
if (platform === "darwin") {
|
|
6260
6319
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -6264,16 +6323,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6264
6323
|
if (raw) {
|
|
6265
6324
|
try {
|
|
6266
6325
|
JSON.parse(raw);
|
|
6267
|
-
|
|
6326
|
+
writeFileSync11(credentialsPath, raw, { mode: 384 });
|
|
6268
6327
|
registerCredentialCleanup(credentialsPath);
|
|
6269
6328
|
return true;
|
|
6270
6329
|
} catch {}
|
|
6271
6330
|
}
|
|
6272
6331
|
}
|
|
6273
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6332
|
+
const hostClaudeHome = options.hostClaudeHome ? resolve27(options.hostClaudeHome) : process.env.CLAUDE_HOME?.trim() ? resolve27(process.env.CLAUDE_HOME) : process.env.HOME ? resolve27(process.env.HOME, ".claude") : "";
|
|
6274
6333
|
if (hostClaudeHome) {
|
|
6275
|
-
const realCredentials =
|
|
6276
|
-
if (
|
|
6334
|
+
const realCredentials = resolve27(hostClaudeHome, ".credentials.json");
|
|
6335
|
+
if (existsSync27(realCredentials)) {
|
|
6277
6336
|
cpSync2(realCredentials, credentialsPath);
|
|
6278
6337
|
return true;
|
|
6279
6338
|
}
|
|
@@ -6281,36 +6340,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6281
6340
|
return false;
|
|
6282
6341
|
}
|
|
6283
6342
|
async function injectCodexAuth(codexHomeDir) {
|
|
6284
|
-
|
|
6285
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6343
|
+
mkdirSync13(codexHomeDir, { recursive: true });
|
|
6344
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve27(process.env.CODEX_HOME) : process.env.HOME ? resolve27(process.env.HOME, ".codex") : "";
|
|
6286
6345
|
if (!hostCodexHome) {
|
|
6287
6346
|
return false;
|
|
6288
6347
|
}
|
|
6289
|
-
const hostAuthPath =
|
|
6290
|
-
if (!
|
|
6348
|
+
const hostAuthPath = resolve27(hostCodexHome, "auth.json");
|
|
6349
|
+
if (!existsSync27(hostAuthPath)) {
|
|
6291
6350
|
return false;
|
|
6292
6351
|
}
|
|
6293
|
-
const runtimeAuthPath =
|
|
6352
|
+
const runtimeAuthPath = resolve27(codexHomeDir, "auth.json");
|
|
6294
6353
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6295
6354
|
chmodSync5(runtimeAuthPath, 384);
|
|
6296
6355
|
return true;
|
|
6297
6356
|
}
|
|
6298
6357
|
async function injectPiAgentConfig(piAgentDir) {
|
|
6299
|
-
|
|
6300
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6358
|
+
mkdirSync13(piAgentDir, { recursive: true });
|
|
6359
|
+
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ? resolve27(process.env.PI_CODING_AGENT_DIR) : process.env.HOME ? resolve27(process.env.HOME, ".pi", "agent") : "";
|
|
6301
6360
|
if (!hostPiAgentDir) {
|
|
6302
6361
|
return false;
|
|
6303
6362
|
}
|
|
6304
|
-
const hostAuthPath =
|
|
6305
|
-
if (!
|
|
6363
|
+
const hostAuthPath = resolve27(hostPiAgentDir, "auth.json");
|
|
6364
|
+
if (!existsSync27(hostAuthPath)) {
|
|
6306
6365
|
return false;
|
|
6307
6366
|
}
|
|
6308
|
-
const runtimeAuthPath =
|
|
6367
|
+
const runtimeAuthPath = resolve27(piAgentDir, "auth.json");
|
|
6309
6368
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6310
6369
|
chmodSync5(runtimeAuthPath, 384);
|
|
6311
|
-
const hostSettingsPath =
|
|
6312
|
-
if (
|
|
6313
|
-
const runtimeSettingsPath =
|
|
6370
|
+
const hostSettingsPath = resolve27(hostPiAgentDir, "settings.json");
|
|
6371
|
+
if (existsSync27(hostSettingsPath)) {
|
|
6372
|
+
const runtimeSettingsPath = resolve27(piAgentDir, "settings.json");
|
|
6314
6373
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
6315
6374
|
chmodSync5(runtimeSettingsPath, 384);
|
|
6316
6375
|
}
|
|
@@ -6318,8 +6377,8 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
6318
6377
|
}
|
|
6319
6378
|
|
|
6320
6379
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
6321
|
-
import { existsSync as
|
|
6322
|
-
import { resolve as
|
|
6380
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync14, statSync as statSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
6381
|
+
import { resolve as resolve28 } from "path";
|
|
6323
6382
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6324
6383
|
var CLAUDE_DISABLED_FILE_TOOLS = [
|
|
6325
6384
|
"Read",
|
|
@@ -6417,7 +6476,7 @@ function claudeRuntimeToolCliArgs(configPath) {
|
|
|
6417
6476
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6418
6477
|
return {
|
|
6419
6478
|
type: "stdio",
|
|
6420
|
-
command:
|
|
6479
|
+
command: resolve28(options.binDir, "rig-tool-router"),
|
|
6421
6480
|
args: [],
|
|
6422
6481
|
env: {
|
|
6423
6482
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6451,14 +6510,14 @@ function codexRuntimeToolCliArgs(options) {
|
|
|
6451
6510
|
];
|
|
6452
6511
|
}
|
|
6453
6512
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6454
|
-
const configPath =
|
|
6455
|
-
|
|
6513
|
+
const configPath = resolve28(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6514
|
+
mkdirSync14(options.stateDir, { recursive: true });
|
|
6456
6515
|
const payload = {
|
|
6457
6516
|
mcpServers: {
|
|
6458
6517
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6459
6518
|
}
|
|
6460
6519
|
};
|
|
6461
|
-
|
|
6520
|
+
writeFileSync12(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6462
6521
|
`, "utf-8");
|
|
6463
6522
|
return configPath;
|
|
6464
6523
|
}
|
|
@@ -6545,7 +6604,7 @@ function resolveRuntimeToolBinary(toolName, env) {
|
|
|
6545
6604
|
grep: "rig-grep"
|
|
6546
6605
|
};
|
|
6547
6606
|
const executable = mapping[toolName];
|
|
6548
|
-
return executable ?
|
|
6607
|
+
return executable ? resolve28(binDir, executable) : "";
|
|
6549
6608
|
}
|
|
6550
6609
|
function renderToolText(toolName, payload) {
|
|
6551
6610
|
if (toolName === "shell") {
|
|
@@ -6610,10 +6669,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
|
|
|
6610
6669
|
isError: true
|
|
6611
6670
|
};
|
|
6612
6671
|
}
|
|
6613
|
-
const workspaceRoot =
|
|
6672
|
+
const workspaceRoot = resolve28(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
|
|
6614
6673
|
const requestedWorkdir = typeof args.workdir === "string" ? args.workdir.trim() : "";
|
|
6615
6674
|
const workdir = requestedWorkdir ? resolveWithinWorkspace(workspaceRoot, requestedWorkdir) : workspaceRoot;
|
|
6616
|
-
if (!
|
|
6675
|
+
if (!existsSync28(workdir)) {
|
|
6617
6676
|
return {
|
|
6618
6677
|
content: [{
|
|
6619
6678
|
type: "text",
|
|
@@ -6680,10 +6739,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
|
|
|
6680
6739
|
}
|
|
6681
6740
|
function resolveRuntimeShellBinary(shellName, env) {
|
|
6682
6741
|
const binDir = env.RIG_RUNTIME_BIN_DIR?.trim() || "";
|
|
6683
|
-
return binDir ?
|
|
6742
|
+
return binDir ? resolve28(binDir, shellName) : "";
|
|
6684
6743
|
}
|
|
6685
6744
|
function resolveWithinWorkspace(workspaceRoot, target) {
|
|
6686
|
-
const resolvedTarget =
|
|
6745
|
+
const resolvedTarget = resolve28(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
|
|
6687
6746
|
const normalizedWorkspace = workspaceRoot.endsWith("/") ? workspaceRoot : `${workspaceRoot}/`;
|
|
6688
6747
|
const normalizedTarget = resolvedTarget.endsWith("/") ? resolvedTarget : `${resolvedTarget}/`;
|
|
6689
6748
|
if (resolvedTarget === workspaceRoot || normalizedTarget.startsWith(normalizedWorkspace)) {
|
|
@@ -6721,8 +6780,8 @@ if (false) {}
|
|
|
6721
6780
|
init_layout();
|
|
6722
6781
|
|
|
6723
6782
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6724
|
-
import { existsSync as
|
|
6725
|
-
import { dirname as
|
|
6783
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync15, rmSync as rmSync10 } from "fs";
|
|
6784
|
+
import { dirname as dirname12, resolve as resolve29 } from "path";
|
|
6726
6785
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6727
6786
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6728
6787
|
if (explicit) {
|
|
@@ -6758,12 +6817,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6758
6817
|
}
|
|
6759
6818
|
async function provisionRuntimeWorktree(config) {
|
|
6760
6819
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6761
|
-
let hasValidWorktree =
|
|
6762
|
-
if (
|
|
6820
|
+
let hasValidWorktree = existsSync29(resolve29(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6821
|
+
if (existsSync29(config.workspaceDir) && !hasValidWorktree) {
|
|
6763
6822
|
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6764
6823
|
}
|
|
6765
6824
|
if (!hasValidWorktree) {
|
|
6766
|
-
|
|
6825
|
+
mkdirSync15(dirname12(config.workspaceDir), { recursive: true });
|
|
6767
6826
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6768
6827
|
const add = branchExists.exitCode === 0 ? await runGitCommand(config.monorepoRoot, ["worktree", "add", "--force", config.workspaceDir, branch]) : await runGitCommand(config.monorepoRoot, ["worktree", "add", "--force", "-b", branch, config.workspaceDir, config.baseRef]);
|
|
6769
6828
|
if (add.exitCode !== 0) {
|
|
@@ -6939,31 +6998,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
6939
6998
|
|
|
6940
6999
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
6941
7000
|
import {
|
|
6942
|
-
existsSync as
|
|
7001
|
+
existsSync as existsSync31,
|
|
6943
7002
|
lstatSync,
|
|
6944
|
-
mkdirSync as
|
|
7003
|
+
mkdirSync as mkdirSync17,
|
|
6945
7004
|
readdirSync as readdirSync6,
|
|
6946
|
-
readFileSync as
|
|
7005
|
+
readFileSync as readFileSync15,
|
|
6947
7006
|
rmSync as rmSync11,
|
|
6948
7007
|
statSync as statSync8,
|
|
6949
7008
|
symlinkSync as symlinkSync4
|
|
6950
7009
|
} from "fs";
|
|
6951
7010
|
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
6952
|
-
import { dirname as
|
|
7011
|
+
import { dirname as dirname14, resolve as resolve31 } from "path";
|
|
6953
7012
|
|
|
6954
7013
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
6955
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
7014
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync30, mkdirSync as mkdirSync16, statSync as statSync7 } from "fs";
|
|
6956
7015
|
import { tmpdir as tmpdir6 } from "os";
|
|
6957
|
-
import { dirname as
|
|
6958
|
-
var sharedRouterOutputDir =
|
|
6959
|
-
var sharedRouterOutputPath =
|
|
7016
|
+
import { dirname as dirname13, resolve as resolve30 } from "path";
|
|
7017
|
+
var sharedRouterOutputDir = resolve30(tmpdir6(), "rig-native");
|
|
7018
|
+
var sharedRouterOutputPath = resolve30(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
6960
7019
|
function runtimeClaudeToolRouterFileName() {
|
|
6961
7020
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
6962
7021
|
}
|
|
6963
7022
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
6964
|
-
const sourcePath =
|
|
6965
|
-
|
|
6966
|
-
const needsBuild = !
|
|
7023
|
+
const sourcePath = resolve30(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
7024
|
+
mkdirSync16(dirname13(outputPath), { recursive: true });
|
|
7025
|
+
const needsBuild = !existsSync30(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
|
|
6967
7026
|
if (!needsBuild) {
|
|
6968
7027
|
return outputPath;
|
|
6969
7028
|
}
|
|
@@ -6977,9 +7036,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
6977
7036
|
}
|
|
6978
7037
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
6979
7038
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
6980
|
-
const targetPath =
|
|
6981
|
-
|
|
6982
|
-
const needsCopy = !
|
|
7039
|
+
const targetPath = resolve30(targetDir, runtimeClaudeToolRouterFileName());
|
|
7040
|
+
mkdirSync16(targetDir, { recursive: true });
|
|
7041
|
+
const needsCopy = !existsSync30(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
|
|
6983
7042
|
if (needsCopy) {
|
|
6984
7043
|
copyFileSync6(sourcePath, targetPath);
|
|
6985
7044
|
chmodSync6(targetPath, 493);
|
|
@@ -6992,48 +7051,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
6992
7051
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
6993
7052
|
function resolveRigSourceRoot(projectRoot) {
|
|
6994
7053
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6995
|
-
if (hostProjectRoot &&
|
|
7054
|
+
if (hostProjectRoot && existsSync31(resolve31(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6996
7055
|
return hostProjectRoot;
|
|
6997
7056
|
}
|
|
6998
|
-
const fromModule =
|
|
6999
|
-
if (
|
|
7057
|
+
const fromModule = resolve31(import.meta.dir, "../../../../../..");
|
|
7058
|
+
if (existsSync31(resolve31(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
7000
7059
|
return fromModule;
|
|
7001
7060
|
}
|
|
7002
7061
|
return projectRoot;
|
|
7003
7062
|
}
|
|
7004
7063
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
7005
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
7064
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve31(sessionDir, "session.json")]) {
|
|
7006
7065
|
removeSymbolicLink(path);
|
|
7007
7066
|
}
|
|
7008
7067
|
runtimePrepareTrackedPathsNative({
|
|
7009
7068
|
logsDir,
|
|
7010
7069
|
stateDir,
|
|
7011
7070
|
sessionDir,
|
|
7012
|
-
controlledBashLogFile:
|
|
7013
|
-
eventsFile:
|
|
7071
|
+
controlledBashLogFile: resolve31(logsDir, "controlled-bash.jsonl"),
|
|
7072
|
+
eventsFile: resolve31(logsDir, "control-plane.events.jsonl")
|
|
7014
7073
|
});
|
|
7015
7074
|
}
|
|
7016
7075
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
7017
7076
|
await mkdir2(stateDir, { recursive: true });
|
|
7018
7077
|
await mkdir2(sessionDir, { recursive: true });
|
|
7019
|
-
const failedApproachesPath =
|
|
7020
|
-
if (!
|
|
7078
|
+
const failedApproachesPath = resolve31(stateDir, "failed_approaches.md");
|
|
7079
|
+
if (!existsSync31(failedApproachesPath)) {
|
|
7021
7080
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
7022
7081
|
|
|
7023
7082
|
`);
|
|
7024
7083
|
}
|
|
7025
|
-
const hookTripsPath =
|
|
7026
|
-
if (!
|
|
7084
|
+
const hookTripsPath = resolve31(stateDir, "hook_trips.log");
|
|
7085
|
+
if (!existsSync31(hookTripsPath)) {
|
|
7027
7086
|
await writeFile(hookTripsPath, "");
|
|
7028
7087
|
}
|
|
7029
|
-
const sessionFile =
|
|
7088
|
+
const sessionFile = resolve31(sessionDir, "session.json");
|
|
7030
7089
|
if (taskId) {
|
|
7031
7090
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
7032
7091
|
}
|
|
7033
7092
|
}
|
|
7034
7093
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
7035
|
-
const artifactDir =
|
|
7036
|
-
const runtimeSnapshotDir =
|
|
7094
|
+
const artifactDir = resolve31(workspaceDir, "artifacts", taskId);
|
|
7095
|
+
const runtimeSnapshotDir = resolve31(artifactDir, "runtime-snapshots");
|
|
7037
7096
|
let preservedTrackedFiles = false;
|
|
7038
7097
|
for (const file of [
|
|
7039
7098
|
"changed-files.txt",
|
|
@@ -7049,7 +7108,7 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
7049
7108
|
preservedTrackedFiles = true;
|
|
7050
7109
|
continue;
|
|
7051
7110
|
}
|
|
7052
|
-
rmSync11(
|
|
7111
|
+
rmSync11(resolve31(artifactDir, file), { force: true });
|
|
7053
7112
|
}
|
|
7054
7113
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
7055
7114
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
@@ -7088,28 +7147,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
7088
7147
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
7089
7148
|
}
|
|
7090
7149
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
7091
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
7092
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
7150
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve31(options.binDir, "rig"), rigSourceRoot);
|
|
7151
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve31(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
7093
7152
|
...options.runtimeSecretDefines,
|
|
7094
7153
|
AGENT_TASK_ID: options.taskId,
|
|
7095
7154
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7096
7155
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
7097
7156
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
7098
7157
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
7099
|
-
AGENT_BINARY_PATH:
|
|
7158
|
+
AGENT_BINARY_PATH: resolve31(options.binDir, "rig-agent"),
|
|
7100
7159
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
7101
7160
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
7102
7161
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
7103
7162
|
});
|
|
7104
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
7163
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve31(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
7105
7164
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7106
7165
|
AGENT_LOGS_DIR: options.logsDir,
|
|
7107
7166
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
7108
|
-
AGENT_TS_API_TESTS_DIR:
|
|
7109
|
-
AGENT_RIG_AGENT_BIN:
|
|
7167
|
+
AGENT_TS_API_TESTS_DIR: resolve31(options.workspaceDir, "TSAPITests"),
|
|
7168
|
+
AGENT_RIG_AGENT_BIN: resolve31(options.binDir, "rig-agent")
|
|
7110
7169
|
});
|
|
7111
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
7112
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
7170
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve31(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
7171
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve31(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
7113
7172
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7114
7173
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7115
7174
|
});
|
|
@@ -7118,15 +7177,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
7118
7177
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7119
7178
|
};
|
|
7120
7179
|
for (const hookName of hookNames) {
|
|
7121
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
7180
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve31(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
7122
7181
|
}
|
|
7123
|
-
const pluginsDir =
|
|
7124
|
-
if (
|
|
7182
|
+
const pluginsDir = resolve31(options.projectRoot, "rig/plugins");
|
|
7183
|
+
if (existsSync31(pluginsDir)) {
|
|
7125
7184
|
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
7126
7185
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
7127
7186
|
if (!match)
|
|
7128
7187
|
continue;
|
|
7129
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
7188
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve31(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
7130
7189
|
}
|
|
7131
7190
|
}
|
|
7132
7191
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -7136,8 +7195,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
7136
7195
|
}
|
|
7137
7196
|
async function writeRuntimeManifest(config) {
|
|
7138
7197
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
7139
|
-
const binarySha256 = sha256Hex(
|
|
7140
|
-
const manifestPath =
|
|
7198
|
+
const binarySha256 = sha256Hex(readFileSync15(config.binaryPath));
|
|
7199
|
+
const manifestPath = resolve31(config.runtimeRoot, "manifest.json");
|
|
7141
7200
|
const manifest = {
|
|
7142
7201
|
runtimeId: config.runtimeId,
|
|
7143
7202
|
taskId: config.taskId,
|
|
@@ -7257,31 +7316,31 @@ function readFileMtimeMs(path) {
|
|
|
7257
7316
|
}
|
|
7258
7317
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
7259
7318
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
7260
|
-
const sourceNodeModules =
|
|
7261
|
-
if (!
|
|
7262
|
-
const runtimeHumoongate =
|
|
7263
|
-
if (
|
|
7264
|
-
const targetNodeModules =
|
|
7319
|
+
const sourceNodeModules = resolve31(monorepoRoot, "humoongate", "node_modules");
|
|
7320
|
+
if (!existsSync31(sourceNodeModules)) {} else {
|
|
7321
|
+
const runtimeHumoongate = resolve31(workspaceDir, "humoongate");
|
|
7322
|
+
if (existsSync31(resolve31(runtimeHumoongate, "package.json"))) {
|
|
7323
|
+
const targetNodeModules = resolve31(runtimeHumoongate, "node_modules");
|
|
7265
7324
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
7266
7325
|
}
|
|
7267
7326
|
}
|
|
7268
|
-
const runtimeHpNext =
|
|
7269
|
-
if (!
|
|
7327
|
+
const runtimeHpNext = resolve31(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
7328
|
+
if (!existsSync31(resolve31(runtimeHpNext, "package.json"))) {
|
|
7270
7329
|
return;
|
|
7271
7330
|
}
|
|
7272
|
-
const sourceHpNextNodeModules =
|
|
7273
|
-
const sourceMonorepoNodeModules =
|
|
7274
|
-
const targetHpNextNodeModules =
|
|
7275
|
-
if (
|
|
7331
|
+
const sourceHpNextNodeModules = resolve31(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
7332
|
+
const sourceMonorepoNodeModules = resolve31(monorepoRoot, "node_modules");
|
|
7333
|
+
const targetHpNextNodeModules = resolve31(runtimeHpNext, "node_modules");
|
|
7334
|
+
if (existsSync31(sourceHpNextNodeModules)) {
|
|
7276
7335
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
7277
7336
|
return;
|
|
7278
7337
|
}
|
|
7279
|
-
if (
|
|
7338
|
+
if (existsSync31(sourceMonorepoNodeModules)) {
|
|
7280
7339
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
7281
7340
|
}
|
|
7282
7341
|
}
|
|
7283
7342
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
7284
|
-
linkNodeModulesLayer(
|
|
7343
|
+
linkNodeModulesLayer(resolve31(monorepoRoot, "node_modules"), resolve31(workspaceDir, "node_modules"));
|
|
7285
7344
|
for (const relativePackageDir of [
|
|
7286
7345
|
"apps/native-app/apps/marketing",
|
|
7287
7346
|
"apps/native-app/apps/web",
|
|
@@ -7303,15 +7362,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
7303
7362
|
"packages/standard-plugin",
|
|
7304
7363
|
"packages/validator-kit"
|
|
7305
7364
|
]) {
|
|
7306
|
-
const workspacePackageDir =
|
|
7307
|
-
if (!
|
|
7365
|
+
const workspacePackageDir = resolve31(workspaceDir, relativePackageDir);
|
|
7366
|
+
if (!existsSync31(resolve31(workspacePackageDir, "package.json"))) {
|
|
7308
7367
|
continue;
|
|
7309
7368
|
}
|
|
7310
|
-
linkNodeModulesLayer(
|
|
7369
|
+
linkNodeModulesLayer(resolve31(monorepoRoot, relativePackageDir, "node_modules"), resolve31(workspacePackageDir, "node_modules"));
|
|
7311
7370
|
}
|
|
7312
7371
|
}
|
|
7313
7372
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
7314
|
-
if (!
|
|
7373
|
+
if (!existsSync31(sourceDir) || existsSync31(targetDir)) {
|
|
7315
7374
|
return;
|
|
7316
7375
|
}
|
|
7317
7376
|
try {
|
|
@@ -7320,30 +7379,30 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
7320
7379
|
} catch (error) {
|
|
7321
7380
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
7322
7381
|
}
|
|
7323
|
-
|
|
7382
|
+
mkdirSync17(dirname14(targetDir), { recursive: true });
|
|
7324
7383
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
7325
7384
|
}
|
|
7326
7385
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
7327
|
-
const hooksDir =
|
|
7328
|
-
const pluginsDir =
|
|
7329
|
-
const validatorsDir =
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7386
|
+
const hooksDir = resolve31(runtimeBinDir, "hooks");
|
|
7387
|
+
const pluginsDir = resolve31(runtimeBinDir, "plugins");
|
|
7388
|
+
const validatorsDir = resolve31(runtimeBinDir, "validators");
|
|
7389
|
+
mkdirSync17(hooksDir, { recursive: true });
|
|
7390
|
+
mkdirSync17(pluginsDir, { recursive: true });
|
|
7391
|
+
mkdirSync17(validatorsDir, { recursive: true });
|
|
7333
7392
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
7334
7393
|
}
|
|
7335
7394
|
|
|
7336
7395
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
7337
|
-
import { existsSync as
|
|
7338
|
-
import { basename as basename9, resolve as
|
|
7396
|
+
import { existsSync as existsSync34, rmSync as rmSync12, writeFileSync as writeFileSync14 } from "fs";
|
|
7397
|
+
import { basename as basename9, resolve as resolve35 } from "path";
|
|
7339
7398
|
|
|
7340
7399
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
7341
|
-
import { existsSync as
|
|
7400
|
+
import { existsSync as existsSync33 } from "fs";
|
|
7342
7401
|
|
|
7343
7402
|
// packages/runtime/src/control-plane/runtime/guard.ts
|
|
7344
7403
|
import { optimizeNextInvocation } from "bun:jsc";
|
|
7345
|
-
import { existsSync as
|
|
7346
|
-
import { resolve as
|
|
7404
|
+
import { existsSync as existsSync32, readFileSync as readFileSync16, statSync as statSync9 } from "fs";
|
|
7405
|
+
import { resolve as resolve32 } from "path";
|
|
7347
7406
|
|
|
7348
7407
|
// packages/runtime/src/control-plane/runtime/guard-types.ts
|
|
7349
7408
|
var POLICY_VERSION = 1;
|
|
@@ -7406,8 +7465,8 @@ function loadPolicy(projectRoot) {
|
|
|
7406
7465
|
if (seededPolicyConfig) {
|
|
7407
7466
|
return seededPolicyConfig;
|
|
7408
7467
|
}
|
|
7409
|
-
const configPath =
|
|
7410
|
-
if (!
|
|
7468
|
+
const configPath = resolve32(projectRoot, "rig/policy/policy.json");
|
|
7469
|
+
if (!existsSync32(configPath)) {
|
|
7411
7470
|
return defaultPolicy();
|
|
7412
7471
|
}
|
|
7413
7472
|
let mtimeMs;
|
|
@@ -7421,7 +7480,7 @@ function loadPolicy(projectRoot) {
|
|
|
7421
7480
|
}
|
|
7422
7481
|
let parsed;
|
|
7423
7482
|
try {
|
|
7424
|
-
parsed = JSON.parse(
|
|
7483
|
+
parsed = JSON.parse(readFileSync16(configPath, "utf-8"));
|
|
7425
7484
|
} catch {
|
|
7426
7485
|
return defaultPolicy();
|
|
7427
7486
|
}
|
|
@@ -7637,28 +7696,28 @@ function resolveAction(mode, matched) {
|
|
|
7637
7696
|
}
|
|
7638
7697
|
function resolveAbsolutePath(projectRoot, rawPath) {
|
|
7639
7698
|
if (rawPath.startsWith("/"))
|
|
7640
|
-
return
|
|
7641
|
-
return
|
|
7699
|
+
return resolve32(rawPath);
|
|
7700
|
+
return resolve32(projectRoot, rawPath);
|
|
7642
7701
|
}
|
|
7643
7702
|
function isHarnessPath(projectRoot, rawPath) {
|
|
7644
7703
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7645
7704
|
const managedRoots = [
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7705
|
+
resolve32(projectRoot, "rig"),
|
|
7706
|
+
resolve32(projectRoot, ".rig"),
|
|
7707
|
+
resolve32(projectRoot, "artifacts")
|
|
7649
7708
|
];
|
|
7650
7709
|
return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
|
|
7651
7710
|
}
|
|
7652
7711
|
function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
|
|
7653
7712
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7654
7713
|
if (taskWorkspace) {
|
|
7655
|
-
const workspaceRigRoot =
|
|
7656
|
-
const workspaceArtifactsRoot =
|
|
7714
|
+
const workspaceRigRoot = resolve32(taskWorkspace, ".rig");
|
|
7715
|
+
const workspaceArtifactsRoot = resolve32(taskWorkspace, "artifacts");
|
|
7657
7716
|
if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
|
|
7658
7717
|
return true;
|
|
7659
7718
|
}
|
|
7660
7719
|
}
|
|
7661
|
-
const runtimeRoot =
|
|
7720
|
+
const runtimeRoot = resolve32(projectRoot, ".rig/runtime/agents");
|
|
7662
7721
|
return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
|
|
7663
7722
|
}
|
|
7664
7723
|
function isTestFile(path) {
|
|
@@ -7706,7 +7765,7 @@ function evaluateScope(policy, context, filePath, access) {
|
|
|
7706
7765
|
return allowed();
|
|
7707
7766
|
}
|
|
7708
7767
|
if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
|
|
7709
|
-
const absPath =
|
|
7768
|
+
const absPath = resolve32(filePath);
|
|
7710
7769
|
if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
|
|
7711
7770
|
const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
|
|
7712
7771
|
const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
|
|
@@ -8034,13 +8093,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
8034
8093
|
depRoots
|
|
8035
8094
|
};
|
|
8036
8095
|
const fsContext = {
|
|
8037
|
-
pathExists: (p) =>
|
|
8096
|
+
pathExists: (p) => existsSync33(p),
|
|
8038
8097
|
realPath: toRealPath
|
|
8039
8098
|
};
|
|
8040
8099
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
8041
8100
|
const seatbelt = Bun.which("sandbox-exec");
|
|
8042
8101
|
probed.push("sandbox-exec");
|
|
8043
|
-
if (seatbelt &&
|
|
8102
|
+
if (seatbelt && existsSync33(seatbelt)) {
|
|
8044
8103
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
8045
8104
|
if (SeatbeltBackendClass) {
|
|
8046
8105
|
return {
|
|
@@ -8161,8 +8220,8 @@ init_layout();
|
|
|
8161
8220
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
8162
8221
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
8163
8222
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
8164
|
-
const readyFile =
|
|
8165
|
-
const requestFile =
|
|
8223
|
+
const readyFile = resolve35(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
8224
|
+
const requestFile = resolve35(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
8166
8225
|
rmSync12(readyFile, { force: true });
|
|
8167
8226
|
rmSync12(requestFile, { force: true });
|
|
8168
8227
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
@@ -8206,7 +8265,7 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
8206
8265
|
rmSync12(requestFile, { force: true });
|
|
8207
8266
|
},
|
|
8208
8267
|
finalize: async (commandParts, exitCode) => {
|
|
8209
|
-
|
|
8268
|
+
writeFileSync14(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
8210
8269
|
`, "utf-8");
|
|
8211
8270
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
8212
8271
|
proc.exited,
|
|
@@ -8234,10 +8293,10 @@ function resolveSnapshotSidecarScriptPath() {
|
|
|
8234
8293
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
8235
8294
|
}
|
|
8236
8295
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
8237
|
-
return
|
|
8296
|
+
return resolve35(binDir, "snapshot-sidecar");
|
|
8238
8297
|
}
|
|
8239
8298
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
8240
|
-
if (!
|
|
8299
|
+
if (!existsSync34(binaryPath)) {
|
|
8241
8300
|
return false;
|
|
8242
8301
|
}
|
|
8243
8302
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -8252,12 +8311,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
8252
8311
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
8253
8312
|
].filter((value) => Boolean(value));
|
|
8254
8313
|
for (const root of hostRoots) {
|
|
8255
|
-
const candidate =
|
|
8256
|
-
if (
|
|
8314
|
+
const candidate = resolve35(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
8315
|
+
if (existsSync34(candidate)) {
|
|
8257
8316
|
return candidate;
|
|
8258
8317
|
}
|
|
8259
8318
|
}
|
|
8260
|
-
return
|
|
8319
|
+
return resolve35(import.meta.dir, "..", fileName);
|
|
8261
8320
|
}
|
|
8262
8321
|
function resolveBunCliInvocation() {
|
|
8263
8322
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -8284,7 +8343,7 @@ function resolveBunCliInvocation() {
|
|
|
8284
8343
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
8285
8344
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
8286
8345
|
while (Date.now() < deadline) {
|
|
8287
|
-
if (
|
|
8346
|
+
if (existsSync34(readyFile)) {
|
|
8288
8347
|
return;
|
|
8289
8348
|
}
|
|
8290
8349
|
const exitCode = proc.exitCode;
|
|
@@ -8302,9 +8361,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
8302
8361
|
async function hydrateRuntimeMemory(options) {
|
|
8303
8362
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
8304
8363
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
8305
|
-
const hydratedPath =
|
|
8364
|
+
const hydratedPath = resolve36(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
8306
8365
|
try {
|
|
8307
|
-
await mkdir3(
|
|
8366
|
+
await mkdir3(resolve36(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
8308
8367
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
8309
8368
|
return {
|
|
8310
8369
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -8319,12 +8378,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
8319
8378
|
}
|
|
8320
8379
|
}
|
|
8321
8380
|
async function createRuntimeTaskRecordReader(options) {
|
|
8322
|
-
const legacyConfigPath =
|
|
8381
|
+
const legacyConfigPath = resolve36(options.projectRoot, ".rig", "task-config.json");
|
|
8323
8382
|
let pluginHostContext = null;
|
|
8324
8383
|
try {
|
|
8325
8384
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
8326
8385
|
} catch (error) {
|
|
8327
|
-
if (!
|
|
8386
|
+
if (!existsSync35(legacyConfigPath)) {
|
|
8328
8387
|
throw error;
|
|
8329
8388
|
}
|
|
8330
8389
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -8344,7 +8403,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
8344
8403
|
source: "plugin"
|
|
8345
8404
|
};
|
|
8346
8405
|
}
|
|
8347
|
-
if (
|
|
8406
|
+
if (existsSync35(legacyConfigPath)) {
|
|
8348
8407
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
8349
8408
|
options.diagnostics?.(message);
|
|
8350
8409
|
console.warn(message);
|
|
@@ -8361,10 +8420,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
8361
8420
|
};
|
|
8362
8421
|
}
|
|
8363
8422
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
8364
|
-
const jsonPath =
|
|
8365
|
-
if (
|
|
8423
|
+
const jsonPath = resolve36(projectRoot, "rig.config.json");
|
|
8424
|
+
if (existsSync35(jsonPath)) {
|
|
8366
8425
|
try {
|
|
8367
|
-
const parsed = JSON.parse(
|
|
8426
|
+
const parsed = JSON.parse(readFileSync17(jsonPath, "utf8"));
|
|
8368
8427
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
8369
8428
|
const taskSource = parsed.taskSource;
|
|
8370
8429
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -8376,12 +8435,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
8376
8435
|
return null;
|
|
8377
8436
|
}
|
|
8378
8437
|
}
|
|
8379
|
-
const tsPath =
|
|
8380
|
-
if (!
|
|
8438
|
+
const tsPath = resolve36(projectRoot, "rig.config.ts");
|
|
8439
|
+
if (!existsSync35(tsPath)) {
|
|
8381
8440
|
return null;
|
|
8382
8441
|
}
|
|
8383
8442
|
try {
|
|
8384
|
-
const source =
|
|
8443
|
+
const source = readFileSync17(tsPath, "utf8");
|
|
8385
8444
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
8386
8445
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
8387
8446
|
return kind ?? null;
|
|
@@ -8451,8 +8510,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
8451
8510
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
8452
8511
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
8453
8512
|
};
|
|
8454
|
-
const configPath =
|
|
8455
|
-
await mkdir3(
|
|
8513
|
+
const configPath = resolve36(options.workspaceDir, ".rig", "task-config.json");
|
|
8514
|
+
await mkdir3(resolve36(options.workspaceDir, ".rig"), { recursive: true });
|
|
8456
8515
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
8457
8516
|
`, "utf-8");
|
|
8458
8517
|
}
|
|
@@ -8516,9 +8575,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8516
8575
|
}
|
|
8517
8576
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8518
8577
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8519
|
-
const workspaceDir =
|
|
8578
|
+
const workspaceDir = resolve36(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8520
8579
|
const createdAt = new Date().toISOString();
|
|
8521
|
-
if (!
|
|
8580
|
+
if (!existsSync35(resolve36(monorepoRoot, ".git"))) {
|
|
8522
8581
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8523
8582
|
}
|
|
8524
8583
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8553,7 +8612,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8553
8612
|
logsDir: overlay.logsDir,
|
|
8554
8613
|
stateDir: overlay.stateDir,
|
|
8555
8614
|
sessionDir: overlay.sessionDir,
|
|
8556
|
-
claudeHomeDir:
|
|
8615
|
+
claudeHomeDir: resolve36(workspaceLayout.homeDir, ".claude"),
|
|
8557
8616
|
contextFile: overlay.contextPath,
|
|
8558
8617
|
binDir: workspaceLayout.binDir,
|
|
8559
8618
|
createdAt
|
|
@@ -8566,8 +8625,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8566
8625
|
projectRoot: options.projectRoot,
|
|
8567
8626
|
workspaceDir
|
|
8568
8627
|
});
|
|
8569
|
-
|
|
8570
|
-
|
|
8628
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8629
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8571
8630
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8572
8631
|
if (options.preserveTaskArtifacts) {
|
|
8573
8632
|
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
@@ -8586,7 +8645,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8586
8645
|
runtimeId: options.id
|
|
8587
8646
|
}),
|
|
8588
8647
|
workspaceDir,
|
|
8589
|
-
artifactRoot:
|
|
8648
|
+
artifactRoot: resolve36(workspaceDir, "artifacts", options.taskId),
|
|
8590
8649
|
hostProjectRoot: options.projectRoot,
|
|
8591
8650
|
monorepoMainRoot: monorepoRoot,
|
|
8592
8651
|
monorepoBaseRef: baseRef,
|
|
@@ -8602,8 +8661,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8602
8661
|
stateDir: overlay.stateDir,
|
|
8603
8662
|
logsDir: overlay.logsDir,
|
|
8604
8663
|
sessionDir: overlay.sessionDir,
|
|
8605
|
-
sessionFile:
|
|
8606
|
-
policyFile:
|
|
8664
|
+
sessionFile: resolve36(overlay.sessionDir, "session.json"),
|
|
8665
|
+
policyFile: resolve36(options.projectRoot, "rig/policy/policy.json"),
|
|
8607
8666
|
binDir: runtime.binDir,
|
|
8608
8667
|
createdAt,
|
|
8609
8668
|
memory
|
|
@@ -8614,9 +8673,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8614
8673
|
task: taskResolution.task,
|
|
8615
8674
|
taskEntry
|
|
8616
8675
|
});
|
|
8617
|
-
const manifestPath =
|
|
8676
|
+
const manifestPath = resolve36(runtimeRoot, "manifest.json");
|
|
8618
8677
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8619
|
-
const runtimeAgentBinary =
|
|
8678
|
+
const runtimeAgentBinary = resolve36(runtime.binDir, "rig-agent");
|
|
8620
8679
|
await ensureRigGitBinaryPath();
|
|
8621
8680
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8622
8681
|
projectRoot: options.projectRoot,
|
|
@@ -8633,8 +8692,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8633
8692
|
});
|
|
8634
8693
|
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8635
8694
|
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8636
|
-
|
|
8637
|
-
|
|
8695
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8696
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8638
8697
|
await buildRuntimeToolchain({
|
|
8639
8698
|
projectRoot: options.projectRoot,
|
|
8640
8699
|
workspaceDir,
|
|
@@ -8671,9 +8730,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8671
8730
|
workspaceDir,
|
|
8672
8731
|
taskEntry
|
|
8673
8732
|
});
|
|
8674
|
-
const sandboxDir =
|
|
8733
|
+
const sandboxDir = resolve36(runtimeRoot, "sandbox");
|
|
8675
8734
|
await mkdir3(sandboxDir, { recursive: true });
|
|
8676
|
-
await writeFile2(
|
|
8735
|
+
await writeFile2(resolve36(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8677
8736
|
id: options.id,
|
|
8678
8737
|
taskId: options.taskId,
|
|
8679
8738
|
mode: "worktree",
|
|
@@ -8780,8 +8839,8 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8780
8839
|
const sendRequest = async (method, params) => {
|
|
8781
8840
|
const id = nextRequestId;
|
|
8782
8841
|
nextRequestId += 1;
|
|
8783
|
-
const resultPromise = new Promise((
|
|
8784
|
-
pendingResponses.set(id, { resolve:
|
|
8842
|
+
const resultPromise = new Promise((resolve37, reject) => {
|
|
8843
|
+
pendingResponses.set(id, { resolve: resolve37, reject });
|
|
8785
8844
|
});
|
|
8786
8845
|
await sendMessage({ id, method, params });
|
|
8787
8846
|
return resultPromise;
|
|
@@ -8980,8 +9039,8 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8980
9039
|
console.error(line);
|
|
8981
9040
|
}
|
|
8982
9041
|
});
|
|
8983
|
-
const exitPromise = new Promise((
|
|
8984
|
-
child.once("close", (code, signal) =>
|
|
9042
|
+
const exitPromise = new Promise((resolve37) => {
|
|
9043
|
+
child.once("close", (code, signal) => resolve37({ code, signal }));
|
|
8985
9044
|
});
|
|
8986
9045
|
await sendRequest("initialize", {
|
|
8987
9046
|
clientInfo: DEFAULT_CLIENT_INFO,
|
|
@@ -9022,7 +9081,7 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
9022
9081
|
while (!completionState.current) {
|
|
9023
9082
|
exitResult = await Promise.race([
|
|
9024
9083
|
exitPromise,
|
|
9025
|
-
new Promise((
|
|
9084
|
+
new Promise((resolve37) => setTimeout(() => resolve37(null), 100))
|
|
9026
9085
|
]);
|
|
9027
9086
|
if (exitResult) {
|
|
9028
9087
|
break;
|
|
@@ -9171,13 +9230,13 @@ function sanitizeEnv(env) {
|
|
|
9171
9230
|
return next;
|
|
9172
9231
|
}
|
|
9173
9232
|
function writeChildLine(child, line) {
|
|
9174
|
-
return new Promise((
|
|
9233
|
+
return new Promise((resolve37, reject) => {
|
|
9175
9234
|
child.stdin.write(line, (error) => {
|
|
9176
9235
|
if (error) {
|
|
9177
9236
|
reject(error);
|
|
9178
9237
|
return;
|
|
9179
9238
|
}
|
|
9180
|
-
|
|
9239
|
+
resolve37();
|
|
9181
9240
|
});
|
|
9182
9241
|
});
|
|
9183
9242
|
}
|
|
@@ -9225,8 +9284,8 @@ function formatJsonRpcError(error) {
|
|
|
9225
9284
|
|
|
9226
9285
|
// packages/runtime/src/control-plane/pi-sessiond/launcher.ts
|
|
9227
9286
|
import { randomBytes } from "crypto";
|
|
9228
|
-
import { existsSync as
|
|
9229
|
-
import { dirname as
|
|
9287
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync21, readFileSync as readFileSync18, rmSync as rmSync14 } from "fs";
|
|
9288
|
+
import { dirname as dirname15, resolve as resolve37 } from "path";
|
|
9230
9289
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9231
9290
|
|
|
9232
9291
|
// packages/runtime/src/control-plane/pi-sessiond/client.ts
|
|
@@ -9271,9 +9330,9 @@ class RigPiSessionDaemonClient {
|
|
|
9271
9330
|
var BUILD_CONFIG2 = {};
|
|
9272
9331
|
var BAKED_RIG_SOURCE_ROOT = BUILD_CONFIG2.RIG_SOURCE_ROOT ?? "";
|
|
9273
9332
|
async function ensureRigPiSessionDaemon(input) {
|
|
9274
|
-
const rootDir =
|
|
9275
|
-
|
|
9276
|
-
const readyFile =
|
|
9333
|
+
const rootDir = resolve37(input.rootDir);
|
|
9334
|
+
mkdirSync21(rootDir, { recursive: true });
|
|
9335
|
+
const readyFile = resolve37(rootDir, "ready.json");
|
|
9277
9336
|
const existing = readDaemonReadyFile(readyFile);
|
|
9278
9337
|
const existingHandle = existing ? await tryReady(existing) : null;
|
|
9279
9338
|
if (existingHandle)
|
|
@@ -9367,12 +9426,12 @@ function resolveRigPiSessionDaemonBinPath(env) {
|
|
|
9367
9426
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
9368
9427
|
].filter((value) => Boolean(value));
|
|
9369
9428
|
for (const root of roots) {
|
|
9370
|
-
const candidate =
|
|
9371
|
-
if (
|
|
9429
|
+
const candidate = resolve37(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts");
|
|
9430
|
+
if (existsSync36(candidate))
|
|
9372
9431
|
return candidate;
|
|
9373
9432
|
}
|
|
9374
9433
|
const moduleCandidate = fileURLToPath2(new URL("./bin.ts", import.meta.url));
|
|
9375
|
-
if (
|
|
9434
|
+
if (existsSync36(moduleCandidate))
|
|
9376
9435
|
return moduleCandidate;
|
|
9377
9436
|
throw new Error([
|
|
9378
9437
|
"Unable to locate rig-pi-sessiond entrypoint.",
|
|
@@ -9382,10 +9441,10 @@ function resolveRigPiSessionDaemonBinPath(env) {
|
|
|
9382
9441
|
`));
|
|
9383
9442
|
}
|
|
9384
9443
|
function readDaemonReadyFile(path) {
|
|
9385
|
-
if (!
|
|
9444
|
+
if (!existsSync36(path))
|
|
9386
9445
|
return null;
|
|
9387
9446
|
try {
|
|
9388
|
-
const parsed = JSON.parse(
|
|
9447
|
+
const parsed = JSON.parse(readFileSync18(path, "utf8"));
|
|
9389
9448
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
9390
9449
|
} catch {
|
|
9391
9450
|
return null;
|
|
@@ -9395,10 +9454,10 @@ function sleep(ms) {
|
|
|
9395
9454
|
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
9396
9455
|
}
|
|
9397
9456
|
function resolveRigPiSessionDaemonRoot(stateDir) {
|
|
9398
|
-
const root =
|
|
9399
|
-
|
|
9400
|
-
if (!
|
|
9401
|
-
|
|
9457
|
+
const root = resolve37(stateDir, "pi-sessiond");
|
|
9458
|
+
mkdirSync21(dirname15(root), { recursive: true });
|
|
9459
|
+
if (!existsSync36(root))
|
|
9460
|
+
mkdirSync21(root, { recursive: true });
|
|
9402
9461
|
return root;
|
|
9403
9462
|
}
|
|
9404
9463
|
|
|
@@ -9436,7 +9495,7 @@ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar = start
|
|
|
9436
9495
|
}
|
|
9437
9496
|
}
|
|
9438
9497
|
async function runAgentWrapper(options = {}) {
|
|
9439
|
-
const projectRoot =
|
|
9498
|
+
const projectRoot = resolve38(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
|
|
9440
9499
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
9441
9500
|
const argv = options.argv || process.argv.slice(2);
|
|
9442
9501
|
if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
|
|
@@ -9512,11 +9571,11 @@ async function runAgentWrapper(options = {}) {
|
|
|
9512
9571
|
const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
|
|
9513
9572
|
const runClaudeCompatUnsandboxed = provider === "claude-code" && bypassOuterRuntimeSandbox;
|
|
9514
9573
|
if (runClaudeCompatUnsandboxed && process.env.HOME?.trim()) {
|
|
9515
|
-
env.CLAUDE_HOME =
|
|
9574
|
+
env.CLAUDE_HOME = resolve38(process.env.HOME.trim(), ".claude");
|
|
9516
9575
|
env.RIG_CLAUDE_RUNTIME_HOME = runtime.claudeHomeDir;
|
|
9517
9576
|
}
|
|
9518
9577
|
if (provider === "pi") {
|
|
9519
|
-
env.PI_CODING_AGENT_DIR =
|
|
9578
|
+
env.PI_CODING_AGENT_DIR = resolve38(runtime.homeDir, ".pi", "agent");
|
|
9520
9579
|
env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
|
|
9521
9580
|
}
|
|
9522
9581
|
env.RIG_RUNTIME_SANDBOX = "enforce";
|
|
@@ -9717,7 +9776,7 @@ async function runPiSessionDaemonProvider(input) {
|
|
|
9717
9776
|
const start = await daemon.client.request("POST", "/sessions", {
|
|
9718
9777
|
runId,
|
|
9719
9778
|
cwd: input.runtime.workspaceDir,
|
|
9720
|
-
agentDir: input.env.PI_CODING_AGENT_DIR ||
|
|
9779
|
+
agentDir: input.env.PI_CODING_AGENT_DIR || resolve38(input.runtime.homeDir, ".pi", "agent"),
|
|
9721
9780
|
sessionDir: input.runtime.sessionDir,
|
|
9722
9781
|
sessionName: input.sessionName
|
|
9723
9782
|
});
|
|
@@ -10117,8 +10176,8 @@ function resolveFromShellPath(binary) {
|
|
|
10117
10176
|
function resolveBundledPiBinary() {
|
|
10118
10177
|
try {
|
|
10119
10178
|
const packageJson = requireFromRuntime.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
10120
|
-
const binaryPath =
|
|
10121
|
-
return
|
|
10179
|
+
const binaryPath = resolve38(packageJson, "..", "dist", "cli.js");
|
|
10180
|
+
return existsSync37(binaryPath) ? binaryPath : null;
|
|
10122
10181
|
} catch {
|
|
10123
10182
|
return null;
|
|
10124
10183
|
}
|
|
@@ -10154,7 +10213,7 @@ async function waitForDirtyBaselineReady(runtime, taskId) {
|
|
|
10154
10213
|
workspaceDir: runtime.workspaceDir,
|
|
10155
10214
|
readyFile
|
|
10156
10215
|
});
|
|
10157
|
-
while (!
|
|
10216
|
+
while (!existsSync37(readyFile)) {
|
|
10158
10217
|
if (Date.now() >= deadline) {
|
|
10159
10218
|
throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
|
|
10160
10219
|
}
|
|
@@ -10257,9 +10316,9 @@ async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
|
|
|
10257
10316
|
}
|
|
10258
10317
|
}
|
|
10259
10318
|
function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
10260
|
-
const handoffDir =
|
|
10261
|
-
|
|
10262
|
-
const handoffPath =
|
|
10319
|
+
const handoffDir = resolve38(hostProjectRoot, ".rig/runtime/handoffs");
|
|
10320
|
+
mkdirSync22(handoffDir, { recursive: true });
|
|
10321
|
+
const handoffPath = resolve38(handoffDir, `${taskId}-${Date.now()}.json`);
|
|
10263
10322
|
const handoff = {
|
|
10264
10323
|
taskId,
|
|
10265
10324
|
runtimeId: runtime.id,
|
|
@@ -10275,7 +10334,7 @@ function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
|
10275
10334
|
`rig git open-pr --task ${taskId}`
|
|
10276
10335
|
]
|
|
10277
10336
|
};
|
|
10278
|
-
|
|
10337
|
+
writeFileSync15(handoffPath, `${JSON.stringify(handoff, null, 2)}
|
|
10279
10338
|
`, "utf-8");
|
|
10280
10339
|
console.log(`[rig-agent] Completion verification paused for ${taskId}.`);
|
|
10281
10340
|
console.log(`[rig-agent] Runtime handoff saved: ${handoffPath}`);
|
|
@@ -10325,13 +10384,13 @@ async function readTaskMetadata2(taskRoot, taskId) {
|
|
|
10325
10384
|
async function readTaskConfigHints(taskRoot, taskId) {
|
|
10326
10385
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
10327
10386
|
const candidates = [
|
|
10328
|
-
runtimeContext?.monorepoMainRoot ?
|
|
10329
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
10330
|
-
|
|
10331
|
-
|
|
10387
|
+
runtimeContext?.monorepoMainRoot ? resolve38(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
10388
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve38(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
10389
|
+
resolve38(taskRoot, ".rig", "task-config.json"),
|
|
10390
|
+
resolve38(taskRoot, "rig", "task-config.json")
|
|
10332
10391
|
].filter(Boolean);
|
|
10333
10392
|
for (const configPath of candidates) {
|
|
10334
|
-
if (!
|
|
10393
|
+
if (!existsSync37(configPath)) {
|
|
10335
10394
|
continue;
|
|
10336
10395
|
}
|
|
10337
10396
|
try {
|