@h-rig/runtime 0.0.6-alpha.33 → 0.0.6-alpha.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/rig-agent-dispatch.js +518 -459
- package/dist/bin/rig-agent.js +431 -362
- package/dist/src/control-plane/agent-wrapper.js +523 -464
- package/dist/src/control-plane/harness-main.js +529 -459
- package/dist/src/control-plane/hooks/completion-verification.js +353 -283
- 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 +11 -1
- package/dist/src/control-plane/native/harness-cli.js +514 -444
- package/dist/src/control-plane/native/task-ops.js +392 -322
- package/dist/src/control-plane/native/validator.js +159 -100
- package/dist/src/control-plane/native/verifier.js +227 -166
- package/dist/src/control-plane/pi-sessiond/bin.js +62 -0
- package/dist/src/control-plane/pi-sessiond/server.js +62 -0
- package/dist/src/control-plane/pi-sessiond/session-service.js +62 -0
- 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/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";
|
|
@@ -3032,10 +3091,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
3032
3091
|
return metadata;
|
|
3033
3092
|
}
|
|
3034
3093
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
3035
|
-
const jsonPath =
|
|
3036
|
-
if (
|
|
3094
|
+
const jsonPath = resolve15(projectRoot, "rig.config.json");
|
|
3095
|
+
if (existsSync16(jsonPath)) {
|
|
3037
3096
|
try {
|
|
3038
|
-
const parsed = JSON.parse(
|
|
3097
|
+
const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
|
|
3039
3098
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
3040
3099
|
const source = parsed.taskSource;
|
|
3041
3100
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -3044,12 +3103,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
3044
3103
|
return null;
|
|
3045
3104
|
}
|
|
3046
3105
|
}
|
|
3047
|
-
const tsPath =
|
|
3048
|
-
if (!
|
|
3106
|
+
const tsPath = resolve15(projectRoot, "rig.config.ts");
|
|
3107
|
+
if (!existsSync16(tsPath)) {
|
|
3049
3108
|
return null;
|
|
3050
3109
|
}
|
|
3051
3110
|
try {
|
|
3052
|
-
const source =
|
|
3111
|
+
const source = readFileSync8(tsPath, "utf8");
|
|
3053
3112
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3054
3113
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3055
3114
|
if (kind !== "files") {
|
|
@@ -3069,10 +3128,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
3069
3128
|
return isPlainRecord2(entry) ? entry : null;
|
|
3070
3129
|
}
|
|
3071
3130
|
function readRawTaskConfig(configPath) {
|
|
3072
|
-
if (!
|
|
3131
|
+
if (!existsSync16(configPath)) {
|
|
3073
3132
|
return null;
|
|
3074
3133
|
}
|
|
3075
|
-
const parsed = JSON.parse(
|
|
3134
|
+
const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
|
|
3076
3135
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
3077
3136
|
}
|
|
3078
3137
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -3080,8 +3139,8 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
3080
3139
|
return tasks;
|
|
3081
3140
|
}
|
|
3082
3141
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
3083
|
-
const directory =
|
|
3084
|
-
if (!
|
|
3142
|
+
const directory = resolve15(projectRoot, sourcePath);
|
|
3143
|
+
if (!existsSync16(directory)) {
|
|
3085
3144
|
return [];
|
|
3086
3145
|
}
|
|
3087
3146
|
const tasks = [];
|
|
@@ -3096,11 +3155,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
3096
3155
|
return tasks;
|
|
3097
3156
|
}
|
|
3098
3157
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
3099
|
-
const file = findFileBackedTaskFile(
|
|
3158
|
+
const file = findFileBackedTaskFile(resolve15(projectRoot, sourcePath), taskId);
|
|
3100
3159
|
if (!file) {
|
|
3101
3160
|
return null;
|
|
3102
3161
|
}
|
|
3103
|
-
const raw = JSON.parse(
|
|
3162
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
3104
3163
|
if (!isPlainRecord2(raw)) {
|
|
3105
3164
|
return null;
|
|
3106
3165
|
}
|
|
@@ -3113,7 +3172,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
3113
3172
|
};
|
|
3114
3173
|
}
|
|
3115
3174
|
function findFileBackedTaskFile(directory, taskId) {
|
|
3116
|
-
if (!
|
|
3175
|
+
if (!existsSync16(directory)) {
|
|
3117
3176
|
return null;
|
|
3118
3177
|
}
|
|
3119
3178
|
for (const name of readdirSync2(directory)) {
|
|
@@ -3123,7 +3182,7 @@ function findFileBackedTaskFile(directory, taskId) {
|
|
|
3123
3182
|
try {
|
|
3124
3183
|
if (!statSync3(file).isFile())
|
|
3125
3184
|
continue;
|
|
3126
|
-
const raw = JSON.parse(
|
|
3185
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
3127
3186
|
const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
|
|
3128
3187
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
3129
3188
|
if (id === taskId) {
|
|
@@ -3283,8 +3342,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
|
|
|
3283
3342
|
}
|
|
3284
3343
|
|
|
3285
3344
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
3286
|
-
import { existsSync as
|
|
3287
|
-
import { basename as basename6, resolve as
|
|
3345
|
+
import { existsSync as existsSync20, readFileSync as readFileSync10, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
|
|
3346
|
+
import { basename as basename6, resolve as resolve19 } from "path";
|
|
3288
3347
|
|
|
3289
3348
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
3290
3349
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -3392,39 +3451,39 @@ function readTaskStateMetadataEnvelope(raw) {
|
|
|
3392
3451
|
};
|
|
3393
3452
|
}
|
|
3394
3453
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
3395
|
-
import { existsSync as
|
|
3396
|
-
import { resolve as
|
|
3454
|
+
import { existsSync as existsSync19, readFileSync as readFileSync9 } from "fs";
|
|
3455
|
+
import { resolve as resolve18 } from "path";
|
|
3397
3456
|
|
|
3398
3457
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
3399
|
-
import { existsSync as
|
|
3400
|
-
import { resolve as
|
|
3458
|
+
import { existsSync as existsSync18 } from "fs";
|
|
3459
|
+
import { resolve as resolve17 } from "path";
|
|
3401
3460
|
|
|
3402
3461
|
// packages/runtime/src/control-plane/repos/layout.ts
|
|
3403
3462
|
init_layout();
|
|
3404
|
-
import { existsSync as
|
|
3405
|
-
import { basename as basename5, dirname as
|
|
3463
|
+
import { existsSync as existsSync17 } from "fs";
|
|
3464
|
+
import { basename as basename5, dirname as dirname10, join as join4, resolve as resolve16 } from "path";
|
|
3406
3465
|
function resolveRepoStateDir(projectRoot) {
|
|
3407
|
-
const normalizedProjectRoot =
|
|
3408
|
-
const projectParent =
|
|
3466
|
+
const normalizedProjectRoot = resolve16(projectRoot);
|
|
3467
|
+
const projectParent = dirname10(normalizedProjectRoot);
|
|
3409
3468
|
if (basename5(projectParent) === ".worktrees") {
|
|
3410
|
-
const ownerRoot =
|
|
3411
|
-
const ownerHasRepoMarkers =
|
|
3469
|
+
const ownerRoot = dirname10(projectParent);
|
|
3470
|
+
const ownerHasRepoMarkers = existsSync17(resolve16(ownerRoot, ".git")) || existsSync17(resolve16(ownerRoot, ".rig", "state"));
|
|
3412
3471
|
if (ownerHasRepoMarkers) {
|
|
3413
|
-
return
|
|
3472
|
+
return resolve16(ownerRoot, ".rig", "state");
|
|
3414
3473
|
}
|
|
3415
3474
|
}
|
|
3416
|
-
return
|
|
3475
|
+
return resolve16(projectRoot, ".rig", "state");
|
|
3417
3476
|
}
|
|
3418
3477
|
function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
3419
|
-
const normalizedProjectRoot =
|
|
3478
|
+
const normalizedProjectRoot = resolve16(projectRoot);
|
|
3420
3479
|
const entry = getManagedRepoEntry(repoId);
|
|
3421
3480
|
const stateDir = resolveRepoStateDir(normalizedProjectRoot);
|
|
3422
3481
|
const metadataRelativePath = join4("repos", entry.id);
|
|
3423
|
-
const metadataRoot =
|
|
3482
|
+
const metadataRoot = resolve16(stateDir, metadataRelativePath);
|
|
3424
3483
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3425
|
-
const runsInsideTaskWorktree = runtimeWorkspace &&
|
|
3484
|
+
const runsInsideTaskWorktree = runtimeWorkspace && resolve16(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname10(normalizedProjectRoot)) === ".worktrees";
|
|
3426
3485
|
const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
|
|
3427
|
-
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ?
|
|
3486
|
+
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve16(process.env[entry.checkoutEnvVar].trim()) : resolve16(normalizedProjectRoot, entry.alias);
|
|
3428
3487
|
return {
|
|
3429
3488
|
projectRoot: normalizedProjectRoot,
|
|
3430
3489
|
repoId: entry.id,
|
|
@@ -3432,12 +3491,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
|
3432
3491
|
defaultBranch: entry.defaultBranch,
|
|
3433
3492
|
remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
|
|
3434
3493
|
checkoutRoot,
|
|
3435
|
-
worktreesRoot:
|
|
3494
|
+
worktreesRoot: resolve16(checkoutRoot, ".worktrees"),
|
|
3436
3495
|
stateDir,
|
|
3437
3496
|
metadataRoot,
|
|
3438
3497
|
metadataRelativePath,
|
|
3439
|
-
mirrorRoot:
|
|
3440
|
-
mirrorStatePath:
|
|
3498
|
+
mirrorRoot: resolve16(metadataRoot, "mirror.git"),
|
|
3499
|
+
mirrorStatePath: resolve16(metadataRoot, "mirror-state.json"),
|
|
3441
3500
|
mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
|
|
3442
3501
|
};
|
|
3443
3502
|
}
|
|
@@ -3455,7 +3514,7 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3455
3514
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3456
3515
|
try {
|
|
3457
3516
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
3458
|
-
if (
|
|
3517
|
+
if (existsSync18(resolve17(layout.mirrorRoot, "HEAD"))) {
|
|
3459
3518
|
return layout.mirrorRoot;
|
|
3460
3519
|
}
|
|
3461
3520
|
} catch {}
|
|
@@ -3466,8 +3525,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3466
3525
|
var DEFAULT_READ_DEPS2 = {
|
|
3467
3526
|
fetchRef: nativeFetchRef,
|
|
3468
3527
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
3469
|
-
exists:
|
|
3470
|
-
readFile: (path) =>
|
|
3528
|
+
exists: existsSync19,
|
|
3529
|
+
readFile: (path) => readFileSync9(path, "utf8")
|
|
3471
3530
|
};
|
|
3472
3531
|
function parseIssueStatus(rawStatus) {
|
|
3473
3532
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -3548,12 +3607,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
3548
3607
|
if (runtimeContextPath) {
|
|
3549
3608
|
return true;
|
|
3550
3609
|
}
|
|
3551
|
-
return
|
|
3610
|
+
return existsSync19(resolve18(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
3552
3611
|
}
|
|
3553
3612
|
function readLocalTrackerState(projectRoot, deps) {
|
|
3554
3613
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3555
|
-
const issuesPath =
|
|
3556
|
-
const taskStatePath =
|
|
3614
|
+
const issuesPath = resolve18(monorepoRoot, ".beads", "issues.jsonl");
|
|
3615
|
+
const taskStatePath = resolve18(monorepoRoot, ".beads", "task-state.json");
|
|
3557
3616
|
return projectSyncedTrackerSnapshot({
|
|
3558
3617
|
source: "local",
|
|
3559
3618
|
issuesBaseOid: null,
|
|
@@ -3615,7 +3674,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
3615
3674
|
return readValidationDescriptionMap(raw);
|
|
3616
3675
|
}
|
|
3617
3676
|
function readSourceValidationDescriptions(projectRoot) {
|
|
3618
|
-
const rootRaw = readJsonFile(
|
|
3677
|
+
const rootRaw = readJsonFile(resolve19(projectRoot, "rig", "task-config.json"), {});
|
|
3619
3678
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
3620
3679
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
3621
3680
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -3691,15 +3750,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
3691
3750
|
return meta.validation_descriptions;
|
|
3692
3751
|
}
|
|
3693
3752
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
3694
|
-
const taskStatePath =
|
|
3753
|
+
const taskStatePath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
3695
3754
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
3696
3755
|
}
|
|
3697
3756
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
3698
|
-
const issuesPath =
|
|
3699
|
-
if (!
|
|
3757
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3758
|
+
if (!existsSync20(issuesPath)) {
|
|
3700
3759
|
return null;
|
|
3701
3760
|
}
|
|
3702
|
-
for (const line of
|
|
3761
|
+
for (const line of readFileSync10(issuesPath, "utf8").split(/\r?\n/)) {
|
|
3703
3762
|
const trimmed = line.trim();
|
|
3704
3763
|
if (!trimmed) {
|
|
3705
3764
|
continue;
|
|
@@ -3724,25 +3783,25 @@ function inferTaskIdFromRuntimePath(path) {
|
|
|
3724
3783
|
function artifactDirForId(projectRoot, id) {
|
|
3725
3784
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3726
3785
|
if (workspaceDir) {
|
|
3727
|
-
const worktreeArtifacts =
|
|
3728
|
-
if (
|
|
3786
|
+
const worktreeArtifacts = resolve19(workspaceDir, "artifacts", id);
|
|
3787
|
+
if (existsSync20(worktreeArtifacts) || existsSync20(resolve19(workspaceDir, "artifacts"))) {
|
|
3729
3788
|
return worktreeArtifacts;
|
|
3730
3789
|
}
|
|
3731
3790
|
}
|
|
3732
3791
|
try {
|
|
3733
3792
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3734
|
-
return
|
|
3793
|
+
return resolve19(paths.artifactsDir, id);
|
|
3735
3794
|
} catch {
|
|
3736
|
-
return
|
|
3795
|
+
return resolve19(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
3737
3796
|
}
|
|
3738
3797
|
}
|
|
3739
3798
|
function resolveTaskConfigPath(projectRoot) {
|
|
3740
3799
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3741
|
-
if (
|
|
3800
|
+
if (existsSync20(paths.taskConfigPath)) {
|
|
3742
3801
|
return paths.taskConfigPath;
|
|
3743
3802
|
}
|
|
3744
3803
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3745
|
-
if (
|
|
3804
|
+
if (existsSync20(candidate)) {
|
|
3746
3805
|
return candidate;
|
|
3747
3806
|
}
|
|
3748
3807
|
}
|
|
@@ -3750,7 +3809,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
3750
3809
|
}
|
|
3751
3810
|
function findSourceTaskConfigPath(projectRoot) {
|
|
3752
3811
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3753
|
-
if (
|
|
3812
|
+
if (existsSync20(candidate)) {
|
|
3754
3813
|
return candidate;
|
|
3755
3814
|
}
|
|
3756
3815
|
}
|
|
@@ -3763,7 +3822,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
3763
3822
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
3764
3823
|
if (sourcePath && synced.updated) {
|
|
3765
3824
|
try {
|
|
3766
|
-
|
|
3825
|
+
writeFileSync8(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
3767
3826
|
`, "utf-8");
|
|
3768
3827
|
} catch {}
|
|
3769
3828
|
}
|
|
@@ -3815,12 +3874,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
3815
3874
|
return !candidate.role;
|
|
3816
3875
|
}
|
|
3817
3876
|
function readSourceIssueRecords(projectRoot) {
|
|
3818
|
-
const issuesPath =
|
|
3819
|
-
if (!
|
|
3877
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3878
|
+
if (!existsSync20(issuesPath)) {
|
|
3820
3879
|
return [];
|
|
3821
3880
|
}
|
|
3822
3881
|
const records = [];
|
|
3823
|
-
for (const line of
|
|
3882
|
+
for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
3824
3883
|
const trimmed = line.trim();
|
|
3825
3884
|
if (!trimmed) {
|
|
3826
3885
|
continue;
|
|
@@ -3876,19 +3935,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
3876
3935
|
if (!sourcePath) {
|
|
3877
3936
|
return {};
|
|
3878
3937
|
}
|
|
3879
|
-
const directory =
|
|
3880
|
-
if (!
|
|
3938
|
+
const directory = resolve19(projectRoot, sourcePath);
|
|
3939
|
+
if (!existsSync20(directory)) {
|
|
3881
3940
|
return {};
|
|
3882
3941
|
}
|
|
3883
3942
|
const config = {};
|
|
3884
3943
|
for (const name of readdirSync3(directory)) {
|
|
3885
3944
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
3886
3945
|
continue;
|
|
3887
|
-
const file =
|
|
3946
|
+
const file = resolve19(directory, name);
|
|
3888
3947
|
try {
|
|
3889
3948
|
if (!statSync4(file).isFile())
|
|
3890
3949
|
continue;
|
|
3891
|
-
const raw = JSON.parse(
|
|
3950
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
3892
3951
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
3893
3952
|
continue;
|
|
3894
3953
|
const record = raw;
|
|
@@ -3930,10 +3989,10 @@ function firstStringList2(...candidates) {
|
|
|
3930
3989
|
return [];
|
|
3931
3990
|
}
|
|
3932
3991
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
3933
|
-
const jsonPath =
|
|
3934
|
-
if (
|
|
3992
|
+
const jsonPath = resolve19(projectRoot, "rig.config.json");
|
|
3993
|
+
if (existsSync20(jsonPath)) {
|
|
3935
3994
|
try {
|
|
3936
|
-
const parsed = JSON.parse(
|
|
3995
|
+
const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
|
|
3937
3996
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3938
3997
|
const taskSource = parsed.taskSource;
|
|
3939
3998
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -3945,12 +4004,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3945
4004
|
return null;
|
|
3946
4005
|
}
|
|
3947
4006
|
}
|
|
3948
|
-
const tsPath =
|
|
3949
|
-
if (!
|
|
4007
|
+
const tsPath = resolve19(projectRoot, "rig.config.ts");
|
|
4008
|
+
if (!existsSync20(tsPath)) {
|
|
3950
4009
|
return null;
|
|
3951
4010
|
}
|
|
3952
4011
|
try {
|
|
3953
|
-
const source =
|
|
4012
|
+
const source = readFileSync10(tsPath, "utf8");
|
|
3954
4013
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3955
4014
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3956
4015
|
if (kind !== "files") {
|
|
@@ -3964,9 +4023,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3964
4023
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
3965
4024
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
3966
4025
|
return [
|
|
3967
|
-
runtimeContext?.monorepoMainRoot ?
|
|
3968
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
3969
|
-
|
|
4026
|
+
runtimeContext?.monorepoMainRoot ? resolve19(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
4027
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve19(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
4028
|
+
resolve19(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
3970
4029
|
].filter(Boolean);
|
|
3971
4030
|
}
|
|
3972
4031
|
|
|
@@ -3975,8 +4034,8 @@ init_layout();
|
|
|
3975
4034
|
|
|
3976
4035
|
// packages/runtime/src/binary-run.ts
|
|
3977
4036
|
init_layout();
|
|
3978
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
3979
|
-
import { basename as basename7, dirname as
|
|
4037
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync21, mkdirSync as mkdirSync10, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
4038
|
+
import { basename as basename7, dirname as dirname11, resolve as resolve20 } from "path";
|
|
3980
4039
|
import { fileURLToPath } from "url";
|
|
3981
4040
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
3982
4041
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -4002,9 +4061,9 @@ async function buildRuntimeBinary(options) {
|
|
|
4002
4061
|
});
|
|
4003
4062
|
}
|
|
4004
4063
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
4005
|
-
const tempBuildDir =
|
|
4006
|
-
const tempOutputPath =
|
|
4007
|
-
|
|
4064
|
+
const tempBuildDir = resolve20(dirname11(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4065
|
+
const tempOutputPath = resolve20(tempBuildDir, basename7(options.outputPath));
|
|
4066
|
+
mkdirSync10(tempBuildDir, { recursive: true });
|
|
4008
4067
|
await withTemporaryEnv({
|
|
4009
4068
|
...options.env,
|
|
4010
4069
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -4029,7 +4088,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4029
4088
|
`);
|
|
4030
4089
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
4031
4090
|
}
|
|
4032
|
-
if (!
|
|
4091
|
+
if (!existsSync21(tempOutputPath)) {
|
|
4033
4092
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
4034
4093
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
4035
4094
|
}
|
|
@@ -4061,8 +4120,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4061
4120
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4062
4121
|
return {
|
|
4063
4122
|
...options,
|
|
4064
|
-
entrypoint:
|
|
4065
|
-
outputPath:
|
|
4123
|
+
entrypoint: resolve20(options.cwd, options.sourcePath),
|
|
4124
|
+
outputPath: resolve20(options.outputPath)
|
|
4066
4125
|
};
|
|
4067
4126
|
}
|
|
4068
4127
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4076,7 +4135,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4076
4135
|
}
|
|
4077
4136
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4078
4137
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4079
|
-
if (!workerSourcePath || !
|
|
4138
|
+
if (!workerSourcePath || !existsSync21(workerSourcePath)) {
|
|
4080
4139
|
await buildRuntimeBinaryInProcess(options, {
|
|
4081
4140
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4082
4141
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4113,7 +4172,7 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4113
4172
|
}
|
|
4114
4173
|
}
|
|
4115
4174
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4116
|
-
return
|
|
4175
|
+
return resolve20(dirname11(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4117
4176
|
}
|
|
4118
4177
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4119
4178
|
const envRoots = [
|
|
@@ -4122,13 +4181,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4122
4181
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4123
4182
|
].filter(Boolean);
|
|
4124
4183
|
for (const root of envRoots) {
|
|
4125
|
-
const candidate =
|
|
4126
|
-
if (
|
|
4184
|
+
const candidate = resolve20(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4185
|
+
if (existsSync21(candidate)) {
|
|
4127
4186
|
return candidate;
|
|
4128
4187
|
}
|
|
4129
4188
|
}
|
|
4130
|
-
const localCandidate =
|
|
4131
|
-
return
|
|
4189
|
+
const localCandidate = resolve20(import.meta.dir, "binary-build-worker.ts");
|
|
4190
|
+
return existsSync21(localCandidate) ? localCandidate : null;
|
|
4132
4191
|
}
|
|
4133
4192
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4134
4193
|
const bunPath = Bun.which("bun");
|
|
@@ -4164,7 +4223,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4164
4223
|
});
|
|
4165
4224
|
}
|
|
4166
4225
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4167
|
-
if (!
|
|
4226
|
+
if (!existsSync21(input.outputPath) || !existsSync21(input.manifestPath)) {
|
|
4168
4227
|
return false;
|
|
4169
4228
|
}
|
|
4170
4229
|
let manifest = null;
|
|
@@ -4177,7 +4236,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4177
4236
|
return false;
|
|
4178
4237
|
}
|
|
4179
4238
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4180
|
-
if (!
|
|
4239
|
+
if (!existsSync21(filePath)) {
|
|
4181
4240
|
return false;
|
|
4182
4241
|
}
|
|
4183
4242
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4190,7 +4249,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4190
4249
|
const inputs = {};
|
|
4191
4250
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4192
4251
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4193
|
-
if (!normalized || !
|
|
4252
|
+
if (!normalized || !existsSync21(normalized)) {
|
|
4194
4253
|
continue;
|
|
4195
4254
|
}
|
|
4196
4255
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4213,7 +4272,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4213
4272
|
if (inputPath.startsWith("<")) {
|
|
4214
4273
|
return null;
|
|
4215
4274
|
}
|
|
4216
|
-
return
|
|
4275
|
+
return resolve20(cwd, inputPath);
|
|
4217
4276
|
}
|
|
4218
4277
|
async function sha256File4(path) {
|
|
4219
4278
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4229,8 +4288,8 @@ function sortRecord(value) {
|
|
|
4229
4288
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4230
4289
|
const previous = runtimeBinaryBuildQueue;
|
|
4231
4290
|
let release;
|
|
4232
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4233
|
-
release =
|
|
4291
|
+
runtimeBinaryBuildQueue = new Promise((resolve21) => {
|
|
4292
|
+
release = resolve21;
|
|
4234
4293
|
});
|
|
4235
4294
|
await previous;
|
|
4236
4295
|
try {
|
|
@@ -4275,11 +4334,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4275
4334
|
}
|
|
4276
4335
|
|
|
4277
4336
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4278
|
-
import { delimiter, resolve as
|
|
4337
|
+
import { delimiter, resolve as resolve23 } from "path";
|
|
4279
4338
|
|
|
4280
4339
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
4281
|
-
import { existsSync as
|
|
4282
|
-
import { resolve as
|
|
4340
|
+
import { existsSync as existsSync23, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
4341
|
+
import { resolve as resolve22 } from "path";
|
|
4283
4342
|
|
|
4284
4343
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
4285
4344
|
init_utils();
|
|
@@ -4296,7 +4355,7 @@ function resolveBunBinaryPath() {
|
|
|
4296
4355
|
}
|
|
4297
4356
|
const home = process.env.HOME?.trim();
|
|
4298
4357
|
const fallbackCandidates = [
|
|
4299
|
-
home ?
|
|
4358
|
+
home ? resolve22(home, ".bun/bin/bun") : "",
|
|
4300
4359
|
"/opt/homebrew/bin/bun",
|
|
4301
4360
|
"/usr/local/bin/bun",
|
|
4302
4361
|
"/usr/bin/bun"
|
|
@@ -4324,8 +4383,8 @@ function resolveClaudeBinaryPath() {
|
|
|
4324
4383
|
}
|
|
4325
4384
|
const home = process.env.HOME?.trim();
|
|
4326
4385
|
const fallbackCandidates = [
|
|
4327
|
-
home ?
|
|
4328
|
-
home ?
|
|
4386
|
+
home ? resolve22(home, ".local/bin/claude") : "",
|
|
4387
|
+
home ? resolve22(home, ".local/share/claude/local/claude") : "",
|
|
4329
4388
|
"/opt/homebrew/bin/claude",
|
|
4330
4389
|
"/usr/local/bin/claude",
|
|
4331
4390
|
"/usr/bin/claude"
|
|
@@ -4339,35 +4398,35 @@ function resolveClaudeBinaryPath() {
|
|
|
4339
4398
|
throw new Error("claude not found in PATH");
|
|
4340
4399
|
}
|
|
4341
4400
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
4342
|
-
return
|
|
4401
|
+
return resolve22(bunBinaryPath, "../..");
|
|
4343
4402
|
}
|
|
4344
4403
|
function resolveClaudeInstallDir() {
|
|
4345
4404
|
const realPath = resolveClaudeBinaryPath();
|
|
4346
|
-
return
|
|
4405
|
+
return resolve22(realPath, "..");
|
|
4347
4406
|
}
|
|
4348
4407
|
function resolveNodeInstallDir() {
|
|
4349
4408
|
const preferredNode = resolvePreferredNodeBinary();
|
|
4350
4409
|
if (!preferredNode)
|
|
4351
4410
|
return null;
|
|
4352
4411
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
4353
|
-
if (explicitNode &&
|
|
4354
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
4412
|
+
if (explicitNode && resolve22(explicitNode) === resolve22(preferredNode)) {
|
|
4413
|
+
return preferredNode.endsWith("/bin/node") ? resolve22(preferredNode, "../..") : resolve22(preferredNode, "..");
|
|
4355
4414
|
}
|
|
4356
4415
|
try {
|
|
4357
4416
|
const realPath = realpathSync2(preferredNode);
|
|
4358
4417
|
if (realPath.endsWith("/bin/node")) {
|
|
4359
|
-
return
|
|
4418
|
+
return resolve22(realPath, "../..");
|
|
4360
4419
|
}
|
|
4361
|
-
return
|
|
4420
|
+
return resolve22(realPath, "..");
|
|
4362
4421
|
} catch {
|
|
4363
|
-
return
|
|
4422
|
+
return resolve22(preferredNode, "..");
|
|
4364
4423
|
}
|
|
4365
4424
|
}
|
|
4366
4425
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
4367
4426
|
const roots = [];
|
|
4368
4427
|
if (process.platform === "darwin") {
|
|
4369
4428
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
4370
|
-
if (
|
|
4429
|
+
if (existsSync23(macPath)) {
|
|
4371
4430
|
roots.push(macPath);
|
|
4372
4431
|
}
|
|
4373
4432
|
}
|
|
@@ -4385,23 +4444,23 @@ function resolvePreferredNodeBinary() {
|
|
|
4385
4444
|
const candidates = [];
|
|
4386
4445
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
4387
4446
|
if (envNode) {
|
|
4388
|
-
const explicit =
|
|
4389
|
-
if (
|
|
4447
|
+
const explicit = resolve22(envNode);
|
|
4448
|
+
if (existsSync23(explicit)) {
|
|
4390
4449
|
return explicit;
|
|
4391
4450
|
}
|
|
4392
4451
|
}
|
|
4393
4452
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
4394
4453
|
if (nvmBin) {
|
|
4395
|
-
candidates.push(
|
|
4454
|
+
candidates.push(resolve22(nvmBin, "node"));
|
|
4396
4455
|
}
|
|
4397
4456
|
const home = process.env.HOME?.trim();
|
|
4398
4457
|
if (home) {
|
|
4399
|
-
const nvmVersionsDir =
|
|
4400
|
-
if (
|
|
4458
|
+
const nvmVersionsDir = resolve22(home, ".nvm/versions/node");
|
|
4459
|
+
if (existsSync23(nvmVersionsDir)) {
|
|
4401
4460
|
try {
|
|
4402
4461
|
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/, "")));
|
|
4403
4462
|
for (const versionDir of versionDirs) {
|
|
4404
|
-
candidates.push(
|
|
4463
|
+
candidates.push(resolve22(nvmVersionsDir, versionDir, "bin/node"));
|
|
4405
4464
|
}
|
|
4406
4465
|
} catch {}
|
|
4407
4466
|
}
|
|
@@ -4410,8 +4469,8 @@ function resolvePreferredNodeBinary() {
|
|
|
4410
4469
|
if (whichNode) {
|
|
4411
4470
|
candidates.push(whichNode);
|
|
4412
4471
|
}
|
|
4413
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
4414
|
-
const existing = deduped.filter((candidate) =>
|
|
4472
|
+
const deduped = uniq(candidates.map((candidate) => resolve22(candidate)));
|
|
4473
|
+
const existing = deduped.filter((candidate) => existsSync23(candidate));
|
|
4415
4474
|
if (existing.length === 0) {
|
|
4416
4475
|
return null;
|
|
4417
4476
|
}
|
|
@@ -4425,7 +4484,7 @@ function resolvePreferredNodeBinary() {
|
|
|
4425
4484
|
return existing[0] ?? null;
|
|
4426
4485
|
}
|
|
4427
4486
|
function inferNodeMajor(nodeBinaryPath) {
|
|
4428
|
-
const normalized =
|
|
4487
|
+
const normalized = resolve22(nodeBinaryPath).replace(/\\/g, "/");
|
|
4429
4488
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
4430
4489
|
if (!match) {
|
|
4431
4490
|
return null;
|
|
@@ -4437,8 +4496,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
4437
4496
|
if (!candidate) {
|
|
4438
4497
|
return "";
|
|
4439
4498
|
}
|
|
4440
|
-
const normalized =
|
|
4441
|
-
if (!
|
|
4499
|
+
const normalized = resolve22(candidate);
|
|
4500
|
+
if (!existsSync23(normalized)) {
|
|
4442
4501
|
return "";
|
|
4443
4502
|
}
|
|
4444
4503
|
try {
|
|
@@ -4448,7 +4507,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
4448
4507
|
}
|
|
4449
4508
|
}
|
|
4450
4509
|
function looksLikeRuntimeGateway(candidate) {
|
|
4451
|
-
const normalized =
|
|
4510
|
+
const normalized = resolve22(candidate).replace(/\\/g, "/");
|
|
4452
4511
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
4453
4512
|
}
|
|
4454
4513
|
|
|
@@ -4469,7 +4528,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4469
4528
|
try {
|
|
4470
4529
|
return resolveClaudeInstallDir();
|
|
4471
4530
|
} catch {
|
|
4472
|
-
return
|
|
4531
|
+
return resolve23(claudeBinary, "..");
|
|
4473
4532
|
}
|
|
4474
4533
|
})() : "";
|
|
4475
4534
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -4479,8 +4538,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4479
4538
|
`${bunDir}/bin`,
|
|
4480
4539
|
claudeDir,
|
|
4481
4540
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
4482
|
-
realHome ?
|
|
4483
|
-
realHome ?
|
|
4541
|
+
realHome ? resolve23(realHome, ".local/bin") : "",
|
|
4542
|
+
realHome ? resolve23(realHome, ".cargo/bin") : "",
|
|
4484
4543
|
...inheritedPath,
|
|
4485
4544
|
"/usr/local/bin",
|
|
4486
4545
|
"/usr/local/sbin",
|
|
@@ -4509,8 +4568,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4509
4568
|
}
|
|
4510
4569
|
|
|
4511
4570
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
4512
|
-
import { existsSync as
|
|
4513
|
-
import { resolve as
|
|
4571
|
+
import { existsSync as existsSync24, readFileSync as readFileSync11 } from "fs";
|
|
4572
|
+
import { resolve as resolve24 } from "path";
|
|
4514
4573
|
var BAKED_RUNTIME_SECRETS = {
|
|
4515
4574
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
4516
4575
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -4553,12 +4612,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
4553
4612
|
return resolved;
|
|
4554
4613
|
}
|
|
4555
4614
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
4556
|
-
const dotenvPath =
|
|
4557
|
-
if (!
|
|
4615
|
+
const dotenvPath = resolve24(projectRoot, ".env");
|
|
4616
|
+
if (!existsSync24(dotenvPath)) {
|
|
4558
4617
|
return {};
|
|
4559
4618
|
}
|
|
4560
4619
|
const parsed = {};
|
|
4561
|
-
const lines =
|
|
4620
|
+
const lines = readFileSync11(dotenvPath, "utf-8").split(/\r?\n/);
|
|
4562
4621
|
for (const rawLine of lines) {
|
|
4563
4622
|
const line = rawLine.trim();
|
|
4564
4623
|
if (!line || line.startsWith("#")) {
|
|
@@ -4915,16 +4974,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
4915
4974
|
for (const dep of deps) {
|
|
4916
4975
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
4917
4976
|
console.log(`=== ${dep} ===`);
|
|
4918
|
-
if (!
|
|
4977
|
+
if (!existsSync25(artifactDir)) {
|
|
4919
4978
|
console.log(` (no artifacts yet)
|
|
4920
4979
|
`);
|
|
4921
4980
|
continue;
|
|
4922
4981
|
}
|
|
4923
|
-
printArtifactSection(
|
|
4924
|
-
printArtifactSection(
|
|
4925
|
-
const changedFiles =
|
|
4926
|
-
if (
|
|
4927
|
-
const lines =
|
|
4982
|
+
printArtifactSection(resolve25(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
4983
|
+
printArtifactSection(resolve25(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
4984
|
+
const changedFiles = resolve25(artifactDir, "changed-files.txt");
|
|
4985
|
+
if (existsSync25(changedFiles)) {
|
|
4986
|
+
const lines = readFileSync12(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
4928
4987
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
4929
4988
|
for (const line of lines) {
|
|
4930
4989
|
console.log(line);
|
|
@@ -5048,12 +5107,12 @@ function printIndented(text) {
|
|
|
5048
5107
|
}
|
|
5049
5108
|
}
|
|
5050
5109
|
function readLocalBeadsTasks(projectRoot) {
|
|
5051
|
-
const issuesPath =
|
|
5052
|
-
if (!
|
|
5110
|
+
const issuesPath = resolve25(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5111
|
+
if (!existsSync25(issuesPath)) {
|
|
5053
5112
|
return [];
|
|
5054
5113
|
}
|
|
5055
5114
|
const tasks = [];
|
|
5056
|
-
for (const line of
|
|
5115
|
+
for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
5057
5116
|
const trimmed = line.trim();
|
|
5058
5117
|
if (!trimmed) {
|
|
5059
5118
|
continue;
|
|
@@ -5166,11 +5225,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5166
5225
|
return [...ids].sort();
|
|
5167
5226
|
}
|
|
5168
5227
|
function printArtifactSection(path, header) {
|
|
5169
|
-
if (!
|
|
5228
|
+
if (!existsSync25(path)) {
|
|
5170
5229
|
return;
|
|
5171
5230
|
}
|
|
5172
5231
|
console.log(header);
|
|
5173
|
-
process.stdout.write(
|
|
5232
|
+
process.stdout.write(readFileSync12(path, "utf-8"));
|
|
5174
5233
|
console.log("");
|
|
5175
5234
|
}
|
|
5176
5235
|
|
|
@@ -5272,7 +5331,7 @@ init_layout();
|
|
|
5272
5331
|
|
|
5273
5332
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5274
5333
|
init_layout();
|
|
5275
|
-
import { mkdirSync as
|
|
5334
|
+
import { mkdirSync as mkdirSync12 } from "fs";
|
|
5276
5335
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5277
5336
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5278
5337
|
const rootDir = layout.rigRoot;
|
|
@@ -5284,14 +5343,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5284
5343
|
const sessionDir = layout.sessionDir;
|
|
5285
5344
|
const runtimeDir = layout.runtimeDir;
|
|
5286
5345
|
const contextPath = layout.contextPath;
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5346
|
+
mkdirSync12(rootDir, { recursive: true });
|
|
5347
|
+
mkdirSync12(homeDir, { recursive: true });
|
|
5348
|
+
mkdirSync12(tmpDir, { recursive: true });
|
|
5349
|
+
mkdirSync12(cacheDir, { recursive: true });
|
|
5350
|
+
mkdirSync12(logsDir, { recursive: true });
|
|
5351
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
5352
|
+
mkdirSync12(sessionDir, { recursive: true });
|
|
5353
|
+
mkdirSync12(runtimeDir, { recursive: true });
|
|
5295
5354
|
return {
|
|
5296
5355
|
rootDir,
|
|
5297
5356
|
homeDir,
|
|
@@ -5309,17 +5368,17 @@ import {
|
|
|
5309
5368
|
chmodSync as chmodSync5,
|
|
5310
5369
|
copyFileSync as copyFileSync5,
|
|
5311
5370
|
cpSync as cpSync2,
|
|
5312
|
-
existsSync as
|
|
5313
|
-
mkdirSync as
|
|
5371
|
+
existsSync as existsSync27,
|
|
5372
|
+
mkdirSync as mkdirSync13,
|
|
5314
5373
|
statSync as statSync5,
|
|
5315
|
-
writeFileSync as
|
|
5374
|
+
writeFileSync as writeFileSync11
|
|
5316
5375
|
} from "fs";
|
|
5317
5376
|
import { mkdir } from "fs/promises";
|
|
5318
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
5377
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve27 } from "path";
|
|
5319
5378
|
|
|
5320
5379
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
5321
|
-
import { existsSync as
|
|
5322
|
-
import { resolve as
|
|
5380
|
+
import { existsSync as existsSync26, readFileSync as readFileSync13, rmSync as rmSync9 } from "fs";
|
|
5381
|
+
import { resolve as resolve26 } from "path";
|
|
5323
5382
|
var generatedCredentialFiles = new Set;
|
|
5324
5383
|
var credentialCleanupRegistered = false;
|
|
5325
5384
|
function resolveMonorepoRoot3(projectRoot) {
|
|
@@ -5343,7 +5402,7 @@ function resolveHostGitBinary() {
|
|
|
5343
5402
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
5344
5403
|
continue;
|
|
5345
5404
|
}
|
|
5346
|
-
if (
|
|
5405
|
+
if (existsSync26(candidate)) {
|
|
5347
5406
|
return candidate;
|
|
5348
5407
|
}
|
|
5349
5408
|
}
|
|
@@ -5409,7 +5468,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
5409
5468
|
}
|
|
5410
5469
|
}
|
|
5411
5470
|
async function tryReadGitHead(repoRoot) {
|
|
5412
|
-
if (!
|
|
5471
|
+
if (!existsSync26(resolve26(repoRoot, ".git"))) {
|
|
5413
5472
|
return;
|
|
5414
5473
|
}
|
|
5415
5474
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -5420,7 +5479,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
5420
5479
|
return value || undefined;
|
|
5421
5480
|
}
|
|
5422
5481
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
5423
|
-
if (!
|
|
5482
|
+
if (!existsSync26(resolve26(repoRoot, ".git"))) {
|
|
5424
5483
|
return [];
|
|
5425
5484
|
}
|
|
5426
5485
|
const files = new Set;
|
|
@@ -5508,16 +5567,16 @@ function hashProjectPath(workspaceDir) {
|
|
|
5508
5567
|
}
|
|
5509
5568
|
function resolveGithubCliBinaryPath() {
|
|
5510
5569
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
5511
|
-
if (explicit &&
|
|
5570
|
+
if (explicit && existsSync26(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
5512
5571
|
return explicit;
|
|
5513
5572
|
}
|
|
5514
5573
|
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
5515
|
-
if (
|
|
5574
|
+
if (existsSync26(candidate)) {
|
|
5516
5575
|
return candidate;
|
|
5517
5576
|
}
|
|
5518
5577
|
}
|
|
5519
5578
|
const bunResolved = Bun.which("gh");
|
|
5520
|
-
if (bunResolved &&
|
|
5579
|
+
if (bunResolved && existsSync26(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
5521
5580
|
return bunResolved;
|
|
5522
5581
|
}
|
|
5523
5582
|
return "";
|
|
@@ -5551,17 +5610,17 @@ function resolveSystemCertBundlePath() {
|
|
|
5551
5610
|
"/opt/homebrew/etc/openssl@3/cert.pem"
|
|
5552
5611
|
];
|
|
5553
5612
|
for (const candidate of candidates) {
|
|
5554
|
-
if (candidate &&
|
|
5555
|
-
return
|
|
5613
|
+
if (candidate && existsSync26(candidate)) {
|
|
5614
|
+
return resolve26(candidate);
|
|
5556
5615
|
}
|
|
5557
5616
|
}
|
|
5558
5617
|
return "";
|
|
5559
5618
|
}
|
|
5560
5619
|
function readKnownHosts(path) {
|
|
5561
|
-
if (!
|
|
5620
|
+
if (!existsSync26(path)) {
|
|
5562
5621
|
return new Set;
|
|
5563
5622
|
}
|
|
5564
|
-
return new Set(
|
|
5623
|
+
return new Set(readFileSync13(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
5565
5624
|
}
|
|
5566
5625
|
|
|
5567
5626
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -5576,12 +5635,12 @@ function resolveControlPlaneSourceRoot(projectRoot) {
|
|
|
5576
5635
|
const candidates = [
|
|
5577
5636
|
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
5578
5637
|
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
5579
|
-
|
|
5638
|
+
resolve27(import.meta.dir, "../../../../.."),
|
|
5580
5639
|
projectRoot
|
|
5581
5640
|
].filter((value) => Boolean(value));
|
|
5582
5641
|
for (const candidate of candidates) {
|
|
5583
|
-
const root =
|
|
5584
|
-
if (
|
|
5642
|
+
const root = resolve27(candidate);
|
|
5643
|
+
if (existsSync27(resolve27(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
5585
5644
|
return root;
|
|
5586
5645
|
}
|
|
5587
5646
|
}
|
|
@@ -5601,7 +5660,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5601
5660
|
try {
|
|
5602
5661
|
return resolveClaudeInstallDir();
|
|
5603
5662
|
} catch {
|
|
5604
|
-
return
|
|
5663
|
+
return resolve27(claudeBinaryPath, "..");
|
|
5605
5664
|
}
|
|
5606
5665
|
})() : "";
|
|
5607
5666
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -5616,8 +5675,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5616
5675
|
`${bunDir}/bin`,
|
|
5617
5676
|
claudeDir,
|
|
5618
5677
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
5619
|
-
realHome ?
|
|
5620
|
-
realHome ?
|
|
5678
|
+
realHome ? resolve27(realHome, ".local/bin") : "",
|
|
5679
|
+
realHome ? resolve27(realHome, ".cargo/bin") : "",
|
|
5621
5680
|
...inheritedPath,
|
|
5622
5681
|
"/usr/local/bin",
|
|
5623
5682
|
"/usr/local/sbin",
|
|
@@ -5628,9 +5687,9 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5628
5687
|
"/usr/sbin",
|
|
5629
5688
|
"/sbin"
|
|
5630
5689
|
].filter(Boolean);
|
|
5631
|
-
const runtimeBash =
|
|
5632
|
-
const runtimeRigGit =
|
|
5633
|
-
const preferredShell =
|
|
5690
|
+
const runtimeBash = resolve27(runtime.binDir, "bash");
|
|
5691
|
+
const runtimeRigGit = resolve27(runtime.binDir, runtimeRigGitFileName());
|
|
5692
|
+
const preferredShell = existsSync27(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
5634
5693
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
5635
5694
|
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
5636
5695
|
const env = {
|
|
@@ -5651,30 +5710,30 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5651
5710
|
RIG_RUNTIME_MODE: runtime.mode,
|
|
5652
5711
|
RIG_RUNTIME_HOME: runtime.rootDir,
|
|
5653
5712
|
RIG_RUNTIME_BIN_DIR: runtime.binDir,
|
|
5654
|
-
...
|
|
5713
|
+
...existsSync27(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
|
|
5655
5714
|
RIG_BUN_PATH: bunBinaryPath,
|
|
5656
5715
|
...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
|
|
5657
|
-
RIG_AGENT_BIN:
|
|
5716
|
+
RIG_AGENT_BIN: resolve27(runtime.binDir, "rig-agent"),
|
|
5658
5717
|
RIG_HOOKS_ACTIVE: "1",
|
|
5659
5718
|
RIG_AUTO_PR_ON_COMPLETE: "1",
|
|
5660
|
-
RIG_POLICY_FILE:
|
|
5719
|
+
RIG_POLICY_FILE: resolve27(projectRoot, "rig/policy/policy.json"),
|
|
5661
5720
|
RIG_STATE_DIR: runtime.stateDir,
|
|
5662
5721
|
RIG_LOGS_DIR: runtime.logsDir,
|
|
5663
|
-
RIG_SESSION_FILE:
|
|
5722
|
+
RIG_SESSION_FILE: resolve27(runtime.sessionDir, "session.json"),
|
|
5664
5723
|
MONOREPO_ROOT: runtime.workspaceDir,
|
|
5665
5724
|
MONOREPO_MAIN_ROOT: monorepoMainRoot,
|
|
5666
|
-
TS_API_TESTS_DIR:
|
|
5725
|
+
TS_API_TESTS_DIR: resolve27(runtime.workspaceDir, "TSAPITests"),
|
|
5667
5726
|
BASH: preferredShell,
|
|
5668
5727
|
SHELL: preferredShell,
|
|
5669
5728
|
PATH: [...new Set(pathEntries)].join(delimiter2),
|
|
5670
5729
|
LANG: process.env.LANG ?? "en_US.UTF-8",
|
|
5671
5730
|
TERM: process.env.TERM ?? "xterm-256color",
|
|
5672
5731
|
PYTHONDONTWRITEBYTECODE: "1",
|
|
5673
|
-
PYTHONPYCACHEPREFIX:
|
|
5732
|
+
PYTHONPYCACHEPREFIX: resolve27(runtime.cacheDir, "python"),
|
|
5674
5733
|
...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
|
|
5675
5734
|
...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
|
|
5676
5735
|
CLAUDE_HOME: runtime.claudeHomeDir,
|
|
5677
|
-
PI_CODING_AGENT_DIR:
|
|
5736
|
+
PI_CODING_AGENT_DIR: resolve27(runtime.homeDir, ".pi", "agent"),
|
|
5678
5737
|
[RUNTIME_CONTEXT_ENV]: runtime.contextFile,
|
|
5679
5738
|
...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
|
|
5680
5739
|
...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
|
|
@@ -5685,16 +5744,16 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5685
5744
|
NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
|
|
5686
5745
|
} : {}
|
|
5687
5746
|
};
|
|
5688
|
-
const knownHostsPath =
|
|
5689
|
-
if (
|
|
5690
|
-
const agentSshKey =
|
|
5747
|
+
const knownHostsPath = resolve27(runtime.homeDir, ".ssh", "known_hosts");
|
|
5748
|
+
if (existsSync27(knownHostsPath)) {
|
|
5749
|
+
const agentSshKey = resolve27(runtime.homeDir, ".ssh", "rig-agent-key");
|
|
5691
5750
|
const sshParts = [
|
|
5692
5751
|
"ssh",
|
|
5693
5752
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
5694
5753
|
"-o StrictHostKeyChecking=yes",
|
|
5695
5754
|
"-F /dev/null"
|
|
5696
5755
|
];
|
|
5697
|
-
if (
|
|
5756
|
+
if (existsSync27(agentSshKey)) {
|
|
5698
5757
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
5699
5758
|
}
|
|
5700
5759
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -5731,7 +5790,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5731
5790
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
5732
5791
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
5733
5792
|
}
|
|
5734
|
-
if (
|
|
5793
|
+
if (existsSync27(runtime.contextFile)) {
|
|
5735
5794
|
const runtimeContext = loadRuntimeContext(runtime.contextFile);
|
|
5736
5795
|
Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
|
|
5737
5796
|
Object.assign(env, browserEnvFromContext(runtimeContext.browser));
|
|
@@ -5745,30 +5804,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
5745
5804
|
await mkdir(runtime.cacheDir, { recursive: true });
|
|
5746
5805
|
await provisionAgentSshKey(runtime.homeDir);
|
|
5747
5806
|
if (options.provider === "codex") {
|
|
5748
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
5807
|
+
const hasCodexAuth = await injectCodexAuth(resolve27(runtime.homeDir, ".codex"));
|
|
5749
5808
|
if (!hasCodexAuth) {
|
|
5750
5809
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
5751
5810
|
}
|
|
5752
5811
|
}
|
|
5753
5812
|
if (options.provider === "pi") {
|
|
5754
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
5813
|
+
const hasPiAuth = await injectPiAgentConfig(resolve27(runtime.homeDir, ".pi", "agent"));
|
|
5755
5814
|
if (!hasPiAuth) {
|
|
5756
5815
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
5757
5816
|
}
|
|
5758
5817
|
}
|
|
5759
5818
|
}
|
|
5760
5819
|
async function provisionClaudeHome(config) {
|
|
5761
|
-
|
|
5762
|
-
const workspaceSettings =
|
|
5763
|
-
const hostSettings =
|
|
5764
|
-
const projectSettings =
|
|
5820
|
+
mkdirSync13(config.claudeHomeDir, { recursive: true });
|
|
5821
|
+
const workspaceSettings = resolve27(config.workspaceDir, ".claude/settings.json");
|
|
5822
|
+
const hostSettings = resolve27(config.hostProjectRoot, ".claude/settings.json");
|
|
5823
|
+
const projectSettings = existsSync27(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
5765
5824
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
5766
|
-
if (
|
|
5767
|
-
|
|
5825
|
+
if (existsSync27(projectSettings)) {
|
|
5826
|
+
writeFileSync11(resolve27(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5768
5827
|
`, "utf-8");
|
|
5769
5828
|
}
|
|
5770
5829
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
5771
|
-
|
|
5830
|
+
writeFileSync11(resolve27(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
5772
5831
|
permissions: { defaultMode: "bypassPermissions" },
|
|
5773
5832
|
autoMemoryEnabled: false
|
|
5774
5833
|
}, null, 2));
|
|
@@ -5776,12 +5835,12 @@ async function provisionClaudeHome(config) {
|
|
|
5776
5835
|
if (!hasCredentials) {
|
|
5777
5836
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
5778
5837
|
}
|
|
5779
|
-
const realClaudeHome =
|
|
5780
|
-
if (process.env.HOME &&
|
|
5781
|
-
cpSync2(
|
|
5838
|
+
const realClaudeHome = resolve27(process.env.HOME ?? "", ".claude");
|
|
5839
|
+
if (process.env.HOME && existsSync27(resolve27(realClaudeHome, "CLAUDE.md"))) {
|
|
5840
|
+
cpSync2(resolve27(realClaudeHome, "CLAUDE.md"), resolve27(config.claudeHomeDir, "CLAUDE.md"));
|
|
5782
5841
|
}
|
|
5783
|
-
if (process.env.HOME &&
|
|
5784
|
-
cpSync2(
|
|
5842
|
+
if (process.env.HOME && existsSync27(resolve27(realClaudeHome, "agents"))) {
|
|
5843
|
+
cpSync2(resolve27(realClaudeHome, "agents"), resolve27(config.claudeHomeDir, "agents"), { recursive: true });
|
|
5785
5844
|
}
|
|
5786
5845
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
5787
5846
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -5792,10 +5851,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
5792
5851
|
if (!sourcePath) {
|
|
5793
5852
|
return "";
|
|
5794
5853
|
}
|
|
5795
|
-
const certsDir =
|
|
5796
|
-
const targetPath =
|
|
5854
|
+
const certsDir = resolve27(runtime.rootDir, "certs");
|
|
5855
|
+
const targetPath = resolve27(certsDir, "ca-certificates.pem");
|
|
5797
5856
|
await mkdir(certsDir, { recursive: true });
|
|
5798
|
-
let shouldCopy = !
|
|
5857
|
+
let shouldCopy = !existsSync27(targetPath);
|
|
5799
5858
|
if (!shouldCopy) {
|
|
5800
5859
|
try {
|
|
5801
5860
|
shouldCopy = statSync5(sourcePath).mtimeMs > statSync5(targetPath).mtimeMs;
|
|
@@ -5817,7 +5876,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
5817
5876
|
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';
|
|
5818
5877
|
}
|
|
5819
5878
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
5820
|
-
const secretsPath =
|
|
5879
|
+
const secretsPath = resolve27(runtimeRoot, "runtime-secrets.json");
|
|
5821
5880
|
const persisted = {};
|
|
5822
5881
|
for (const key of [
|
|
5823
5882
|
"GITHUB_TOKEN",
|
|
@@ -5836,12 +5895,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
5836
5895
|
if (Object.keys(persisted).length === 0) {
|
|
5837
5896
|
return;
|
|
5838
5897
|
}
|
|
5839
|
-
|
|
5898
|
+
writeFileSync11(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
5840
5899
|
`, "utf-8");
|
|
5841
5900
|
}
|
|
5842
5901
|
async function provisionAgentSshKey(homeDir) {
|
|
5843
|
-
const sshDir =
|
|
5844
|
-
if (!
|
|
5902
|
+
const sshDir = resolve27(homeDir, ".ssh");
|
|
5903
|
+
if (!existsSync27(sshDir)) {
|
|
5845
5904
|
await mkdir(sshDir, { recursive: true });
|
|
5846
5905
|
}
|
|
5847
5906
|
seedKnownHosts(sshDir);
|
|
@@ -5849,27 +5908,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
5849
5908
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
5850
5909
|
if (!privateKey) {
|
|
5851
5910
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
5852
|
-
if (!process.env.HOME || !
|
|
5911
|
+
if (!process.env.HOME || !existsSync27(hostKeyPath)) {
|
|
5853
5912
|
return;
|
|
5854
5913
|
}
|
|
5855
|
-
const agentKeyPath2 =
|
|
5856
|
-
if (!
|
|
5914
|
+
const agentKeyPath2 = resolve27(sshDir, "rig-agent-key");
|
|
5915
|
+
if (!existsSync27(agentKeyPath2)) {
|
|
5857
5916
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
5858
5917
|
chmodSync5(agentKeyPath2, 384);
|
|
5859
5918
|
}
|
|
5860
5919
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
5861
|
-
if (
|
|
5920
|
+
if (existsSync27(hostPubPath)) {
|
|
5862
5921
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
5863
|
-
if (!
|
|
5922
|
+
if (!existsSync27(agentPubPath)) {
|
|
5864
5923
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
5865
5924
|
}
|
|
5866
5925
|
}
|
|
5867
5926
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
5868
5927
|
return;
|
|
5869
5928
|
}
|
|
5870
|
-
const agentKeyPath =
|
|
5871
|
-
if (!
|
|
5872
|
-
|
|
5929
|
+
const agentKeyPath = resolve27(sshDir, "rig-agent-key");
|
|
5930
|
+
if (!existsSync27(agentKeyPath)) {
|
|
5931
|
+
writeFileSync11(agentKeyPath, privateKey, { mode: 384 });
|
|
5873
5932
|
}
|
|
5874
5933
|
writeSshConfig(sshDir, agentKeyPath);
|
|
5875
5934
|
}
|
|
@@ -5886,21 +5945,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
5886
5945
|
`;
|
|
5887
5946
|
}
|
|
5888
5947
|
function resolveHostSshKeyPath(homeDir) {
|
|
5889
|
-
const sshDir =
|
|
5948
|
+
const sshDir = resolve27(homeDir, ".ssh");
|
|
5890
5949
|
const candidates = [
|
|
5891
5950
|
"rig-agent-key",
|
|
5892
5951
|
"id_ed25519",
|
|
5893
5952
|
"id_ecdsa",
|
|
5894
5953
|
"id_rsa"
|
|
5895
|
-
].map((name) =>
|
|
5896
|
-
return candidates.find((candidate) =>
|
|
5954
|
+
].map((name) => resolve27(sshDir, name));
|
|
5955
|
+
return candidates.find((candidate) => existsSync27(candidate)) ?? resolve27(sshDir, "rig-agent-key");
|
|
5897
5956
|
}
|
|
5898
5957
|
function writeSshConfig(sshDir, keyPath) {
|
|
5899
|
-
const configPath =
|
|
5900
|
-
if (
|
|
5958
|
+
const configPath = resolve27(sshDir, "config");
|
|
5959
|
+
if (existsSync27(configPath)) {
|
|
5901
5960
|
return;
|
|
5902
5961
|
}
|
|
5903
|
-
const knownHostsPath =
|
|
5962
|
+
const knownHostsPath = resolve27(sshDir, "known_hosts");
|
|
5904
5963
|
const config = [
|
|
5905
5964
|
"Host github.com",
|
|
5906
5965
|
` IdentityFile ${keyPath}`,
|
|
@@ -5910,10 +5969,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
5910
5969
|
""
|
|
5911
5970
|
].join(`
|
|
5912
5971
|
`);
|
|
5913
|
-
|
|
5972
|
+
writeFileSync11(configPath, config, { mode: 420 });
|
|
5914
5973
|
}
|
|
5915
5974
|
function seedKnownHosts(sshDir) {
|
|
5916
|
-
const knownHostsPath =
|
|
5975
|
+
const knownHostsPath = resolve27(sshDir, "known_hosts");
|
|
5917
5976
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
5918
5977
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
5919
5978
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -5924,23 +5983,23 @@ function seedKnownHosts(sshDir) {
|
|
|
5924
5983
|
for (const line of missing) {
|
|
5925
5984
|
existingLines.add(line);
|
|
5926
5985
|
}
|
|
5927
|
-
|
|
5986
|
+
writeFileSync11(knownHostsPath, `${Array.from(existingLines).join(`
|
|
5928
5987
|
`)}
|
|
5929
5988
|
`, { mode: 420 });
|
|
5930
5989
|
} catch (err) {
|
|
5931
|
-
const hint =
|
|
5990
|
+
const hint = existsSync27(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
5932
5991
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
5933
5992
|
}
|
|
5934
5993
|
}
|
|
5935
5994
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
5936
5995
|
const projectHash = hashProjectPath(workspaceDir);
|
|
5937
|
-
const projectDir =
|
|
5938
|
-
|
|
5939
|
-
|
|
5996
|
+
const projectDir = resolve27(claudeHomeDir, "projects", projectHash);
|
|
5997
|
+
mkdirSync13(projectDir, { recursive: true });
|
|
5998
|
+
writeFileSync11(resolve27(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5940
5999
|
`, "utf-8");
|
|
5941
6000
|
}
|
|
5942
6001
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
5943
|
-
if (!
|
|
6002
|
+
if (!existsSync27(projectSettingsPath)) {
|
|
5944
6003
|
return {};
|
|
5945
6004
|
}
|
|
5946
6005
|
let parsed;
|
|
@@ -5986,7 +6045,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
5986
6045
|
return clone;
|
|
5987
6046
|
}
|
|
5988
6047
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
5989
|
-
const credentialsPath =
|
|
6048
|
+
const credentialsPath = resolve27(claudeHomeDir, ".credentials.json");
|
|
5990
6049
|
const platform = options.platform ?? process.platform;
|
|
5991
6050
|
if (platform === "darwin") {
|
|
5992
6051
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -5996,16 +6055,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
5996
6055
|
if (raw) {
|
|
5997
6056
|
try {
|
|
5998
6057
|
JSON.parse(raw);
|
|
5999
|
-
|
|
6058
|
+
writeFileSync11(credentialsPath, raw, { mode: 384 });
|
|
6000
6059
|
registerCredentialCleanup(credentialsPath);
|
|
6001
6060
|
return true;
|
|
6002
6061
|
} catch {}
|
|
6003
6062
|
}
|
|
6004
6063
|
}
|
|
6005
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6064
|
+
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") : "";
|
|
6006
6065
|
if (hostClaudeHome) {
|
|
6007
|
-
const realCredentials =
|
|
6008
|
-
if (
|
|
6066
|
+
const realCredentials = resolve27(hostClaudeHome, ".credentials.json");
|
|
6067
|
+
if (existsSync27(realCredentials)) {
|
|
6009
6068
|
cpSync2(realCredentials, credentialsPath);
|
|
6010
6069
|
return true;
|
|
6011
6070
|
}
|
|
@@ -6013,36 +6072,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6013
6072
|
return false;
|
|
6014
6073
|
}
|
|
6015
6074
|
async function injectCodexAuth(codexHomeDir) {
|
|
6016
|
-
|
|
6017
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6075
|
+
mkdirSync13(codexHomeDir, { recursive: true });
|
|
6076
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve27(process.env.CODEX_HOME) : process.env.HOME ? resolve27(process.env.HOME, ".codex") : "";
|
|
6018
6077
|
if (!hostCodexHome) {
|
|
6019
6078
|
return false;
|
|
6020
6079
|
}
|
|
6021
|
-
const hostAuthPath =
|
|
6022
|
-
if (!
|
|
6080
|
+
const hostAuthPath = resolve27(hostCodexHome, "auth.json");
|
|
6081
|
+
if (!existsSync27(hostAuthPath)) {
|
|
6023
6082
|
return false;
|
|
6024
6083
|
}
|
|
6025
|
-
const runtimeAuthPath =
|
|
6084
|
+
const runtimeAuthPath = resolve27(codexHomeDir, "auth.json");
|
|
6026
6085
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6027
6086
|
chmodSync5(runtimeAuthPath, 384);
|
|
6028
6087
|
return true;
|
|
6029
6088
|
}
|
|
6030
6089
|
async function injectPiAgentConfig(piAgentDir) {
|
|
6031
|
-
|
|
6032
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6090
|
+
mkdirSync13(piAgentDir, { recursive: true });
|
|
6091
|
+
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") : "";
|
|
6033
6092
|
if (!hostPiAgentDir) {
|
|
6034
6093
|
return false;
|
|
6035
6094
|
}
|
|
6036
|
-
const hostAuthPath =
|
|
6037
|
-
if (!
|
|
6095
|
+
const hostAuthPath = resolve27(hostPiAgentDir, "auth.json");
|
|
6096
|
+
if (!existsSync27(hostAuthPath)) {
|
|
6038
6097
|
return false;
|
|
6039
6098
|
}
|
|
6040
|
-
const runtimeAuthPath =
|
|
6099
|
+
const runtimeAuthPath = resolve27(piAgentDir, "auth.json");
|
|
6041
6100
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6042
6101
|
chmodSync5(runtimeAuthPath, 384);
|
|
6043
|
-
const hostSettingsPath =
|
|
6044
|
-
if (
|
|
6045
|
-
const runtimeSettingsPath =
|
|
6102
|
+
const hostSettingsPath = resolve27(hostPiAgentDir, "settings.json");
|
|
6103
|
+
if (existsSync27(hostSettingsPath)) {
|
|
6104
|
+
const runtimeSettingsPath = resolve27(piAgentDir, "settings.json");
|
|
6046
6105
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
6047
6106
|
chmodSync5(runtimeSettingsPath, 384);
|
|
6048
6107
|
}
|
|
@@ -6050,8 +6109,8 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
6050
6109
|
}
|
|
6051
6110
|
|
|
6052
6111
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
6053
|
-
import { existsSync as
|
|
6054
|
-
import { resolve as
|
|
6112
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync14, statSync as statSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
6113
|
+
import { resolve as resolve28 } from "path";
|
|
6055
6114
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6056
6115
|
var CLAUDE_DISABLED_FILE_TOOLS = [
|
|
6057
6116
|
"Read",
|
|
@@ -6149,7 +6208,7 @@ function claudeRuntimeToolCliArgs(configPath) {
|
|
|
6149
6208
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6150
6209
|
return {
|
|
6151
6210
|
type: "stdio",
|
|
6152
|
-
command:
|
|
6211
|
+
command: resolve28(options.binDir, "rig-tool-router"),
|
|
6153
6212
|
args: [],
|
|
6154
6213
|
env: {
|
|
6155
6214
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6183,14 +6242,14 @@ function codexRuntimeToolCliArgs(options) {
|
|
|
6183
6242
|
];
|
|
6184
6243
|
}
|
|
6185
6244
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6186
|
-
const configPath =
|
|
6187
|
-
|
|
6245
|
+
const configPath = resolve28(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6246
|
+
mkdirSync14(options.stateDir, { recursive: true });
|
|
6188
6247
|
const payload = {
|
|
6189
6248
|
mcpServers: {
|
|
6190
6249
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6191
6250
|
}
|
|
6192
6251
|
};
|
|
6193
|
-
|
|
6252
|
+
writeFileSync12(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6194
6253
|
`, "utf-8");
|
|
6195
6254
|
return configPath;
|
|
6196
6255
|
}
|
|
@@ -6277,7 +6336,7 @@ function resolveRuntimeToolBinary(toolName, env) {
|
|
|
6277
6336
|
grep: "rig-grep"
|
|
6278
6337
|
};
|
|
6279
6338
|
const executable = mapping[toolName];
|
|
6280
|
-
return executable ?
|
|
6339
|
+
return executable ? resolve28(binDir, executable) : "";
|
|
6281
6340
|
}
|
|
6282
6341
|
function renderToolText(toolName, payload) {
|
|
6283
6342
|
if (toolName === "shell") {
|
|
@@ -6342,10 +6401,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
|
|
|
6342
6401
|
isError: true
|
|
6343
6402
|
};
|
|
6344
6403
|
}
|
|
6345
|
-
const workspaceRoot =
|
|
6404
|
+
const workspaceRoot = resolve28(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
|
|
6346
6405
|
const requestedWorkdir = typeof args.workdir === "string" ? args.workdir.trim() : "";
|
|
6347
6406
|
const workdir = requestedWorkdir ? resolveWithinWorkspace(workspaceRoot, requestedWorkdir) : workspaceRoot;
|
|
6348
|
-
if (!
|
|
6407
|
+
if (!existsSync28(workdir)) {
|
|
6349
6408
|
return {
|
|
6350
6409
|
content: [{
|
|
6351
6410
|
type: "text",
|
|
@@ -6412,10 +6471,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
|
|
|
6412
6471
|
}
|
|
6413
6472
|
function resolveRuntimeShellBinary(shellName, env) {
|
|
6414
6473
|
const binDir = env.RIG_RUNTIME_BIN_DIR?.trim() || "";
|
|
6415
|
-
return binDir ?
|
|
6474
|
+
return binDir ? resolve28(binDir, shellName) : "";
|
|
6416
6475
|
}
|
|
6417
6476
|
function resolveWithinWorkspace(workspaceRoot, target) {
|
|
6418
|
-
const resolvedTarget =
|
|
6477
|
+
const resolvedTarget = resolve28(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
|
|
6419
6478
|
const normalizedWorkspace = workspaceRoot.endsWith("/") ? workspaceRoot : `${workspaceRoot}/`;
|
|
6420
6479
|
const normalizedTarget = resolvedTarget.endsWith("/") ? resolvedTarget : `${resolvedTarget}/`;
|
|
6421
6480
|
if (resolvedTarget === workspaceRoot || normalizedTarget.startsWith(normalizedWorkspace)) {
|
|
@@ -6453,8 +6512,8 @@ if (false) {}
|
|
|
6453
6512
|
init_layout();
|
|
6454
6513
|
|
|
6455
6514
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6456
|
-
import { existsSync as
|
|
6457
|
-
import { dirname as
|
|
6515
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync15, rmSync as rmSync10 } from "fs";
|
|
6516
|
+
import { dirname as dirname12, resolve as resolve29 } from "path";
|
|
6458
6517
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6459
6518
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6460
6519
|
if (explicit) {
|
|
@@ -6490,12 +6549,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6490
6549
|
}
|
|
6491
6550
|
async function provisionRuntimeWorktree(config) {
|
|
6492
6551
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6493
|
-
let hasValidWorktree =
|
|
6494
|
-
if (
|
|
6552
|
+
let hasValidWorktree = existsSync29(resolve29(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6553
|
+
if (existsSync29(config.workspaceDir) && !hasValidWorktree) {
|
|
6495
6554
|
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6496
6555
|
}
|
|
6497
6556
|
if (!hasValidWorktree) {
|
|
6498
|
-
|
|
6557
|
+
mkdirSync15(dirname12(config.workspaceDir), { recursive: true });
|
|
6499
6558
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6500
6559
|
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]);
|
|
6501
6560
|
if (add.exitCode !== 0) {
|
|
@@ -6671,31 +6730,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
6671
6730
|
|
|
6672
6731
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
6673
6732
|
import {
|
|
6674
|
-
existsSync as
|
|
6733
|
+
existsSync as existsSync31,
|
|
6675
6734
|
lstatSync,
|
|
6676
|
-
mkdirSync as
|
|
6735
|
+
mkdirSync as mkdirSync17,
|
|
6677
6736
|
readdirSync as readdirSync6,
|
|
6678
|
-
readFileSync as
|
|
6737
|
+
readFileSync as readFileSync15,
|
|
6679
6738
|
rmSync as rmSync11,
|
|
6680
6739
|
statSync as statSync8,
|
|
6681
6740
|
symlinkSync as symlinkSync4
|
|
6682
6741
|
} from "fs";
|
|
6683
6742
|
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
6684
|
-
import { dirname as
|
|
6743
|
+
import { dirname as dirname14, resolve as resolve31 } from "path";
|
|
6685
6744
|
|
|
6686
6745
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
6687
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
6746
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync30, mkdirSync as mkdirSync16, statSync as statSync7 } from "fs";
|
|
6688
6747
|
import { tmpdir as tmpdir6 } from "os";
|
|
6689
|
-
import { dirname as
|
|
6690
|
-
var sharedRouterOutputDir =
|
|
6691
|
-
var sharedRouterOutputPath =
|
|
6748
|
+
import { dirname as dirname13, resolve as resolve30 } from "path";
|
|
6749
|
+
var sharedRouterOutputDir = resolve30(tmpdir6(), "rig-native");
|
|
6750
|
+
var sharedRouterOutputPath = resolve30(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
6692
6751
|
function runtimeClaudeToolRouterFileName() {
|
|
6693
6752
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
6694
6753
|
}
|
|
6695
6754
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
6696
|
-
const sourcePath =
|
|
6697
|
-
|
|
6698
|
-
const needsBuild = !
|
|
6755
|
+
const sourcePath = resolve30(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
6756
|
+
mkdirSync16(dirname13(outputPath), { recursive: true });
|
|
6757
|
+
const needsBuild = !existsSync30(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
|
|
6699
6758
|
if (!needsBuild) {
|
|
6700
6759
|
return outputPath;
|
|
6701
6760
|
}
|
|
@@ -6709,9 +6768,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
6709
6768
|
}
|
|
6710
6769
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
6711
6770
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
6712
|
-
const targetPath =
|
|
6713
|
-
|
|
6714
|
-
const needsCopy = !
|
|
6771
|
+
const targetPath = resolve30(targetDir, runtimeClaudeToolRouterFileName());
|
|
6772
|
+
mkdirSync16(targetDir, { recursive: true });
|
|
6773
|
+
const needsCopy = !existsSync30(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
|
|
6715
6774
|
if (needsCopy) {
|
|
6716
6775
|
copyFileSync6(sourcePath, targetPath);
|
|
6717
6776
|
chmodSync6(targetPath, 493);
|
|
@@ -6724,48 +6783,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
6724
6783
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
6725
6784
|
function resolveRigSourceRoot(projectRoot) {
|
|
6726
6785
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6727
|
-
if (hostProjectRoot &&
|
|
6786
|
+
if (hostProjectRoot && existsSync31(resolve31(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6728
6787
|
return hostProjectRoot;
|
|
6729
6788
|
}
|
|
6730
|
-
const fromModule =
|
|
6731
|
-
if (
|
|
6789
|
+
const fromModule = resolve31(import.meta.dir, "../../../../../..");
|
|
6790
|
+
if (existsSync31(resolve31(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6732
6791
|
return fromModule;
|
|
6733
6792
|
}
|
|
6734
6793
|
return projectRoot;
|
|
6735
6794
|
}
|
|
6736
6795
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
6737
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
6796
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve31(sessionDir, "session.json")]) {
|
|
6738
6797
|
removeSymbolicLink(path);
|
|
6739
6798
|
}
|
|
6740
6799
|
runtimePrepareTrackedPathsNative({
|
|
6741
6800
|
logsDir,
|
|
6742
6801
|
stateDir,
|
|
6743
6802
|
sessionDir,
|
|
6744
|
-
controlledBashLogFile:
|
|
6745
|
-
eventsFile:
|
|
6803
|
+
controlledBashLogFile: resolve31(logsDir, "controlled-bash.jsonl"),
|
|
6804
|
+
eventsFile: resolve31(logsDir, "control-plane.events.jsonl")
|
|
6746
6805
|
});
|
|
6747
6806
|
}
|
|
6748
6807
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
6749
6808
|
await mkdir2(stateDir, { recursive: true });
|
|
6750
6809
|
await mkdir2(sessionDir, { recursive: true });
|
|
6751
|
-
const failedApproachesPath =
|
|
6752
|
-
if (!
|
|
6810
|
+
const failedApproachesPath = resolve31(stateDir, "failed_approaches.md");
|
|
6811
|
+
if (!existsSync31(failedApproachesPath)) {
|
|
6753
6812
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
6754
6813
|
|
|
6755
6814
|
`);
|
|
6756
6815
|
}
|
|
6757
|
-
const hookTripsPath =
|
|
6758
|
-
if (!
|
|
6816
|
+
const hookTripsPath = resolve31(stateDir, "hook_trips.log");
|
|
6817
|
+
if (!existsSync31(hookTripsPath)) {
|
|
6759
6818
|
await writeFile(hookTripsPath, "");
|
|
6760
6819
|
}
|
|
6761
|
-
const sessionFile =
|
|
6820
|
+
const sessionFile = resolve31(sessionDir, "session.json");
|
|
6762
6821
|
if (taskId) {
|
|
6763
6822
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
6764
6823
|
}
|
|
6765
6824
|
}
|
|
6766
6825
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
6767
|
-
const artifactDir =
|
|
6768
|
-
const runtimeSnapshotDir =
|
|
6826
|
+
const artifactDir = resolve31(workspaceDir, "artifacts", taskId);
|
|
6827
|
+
const runtimeSnapshotDir = resolve31(artifactDir, "runtime-snapshots");
|
|
6769
6828
|
let preservedTrackedFiles = false;
|
|
6770
6829
|
for (const file of [
|
|
6771
6830
|
"changed-files.txt",
|
|
@@ -6781,7 +6840,7 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
6781
6840
|
preservedTrackedFiles = true;
|
|
6782
6841
|
continue;
|
|
6783
6842
|
}
|
|
6784
|
-
rmSync11(
|
|
6843
|
+
rmSync11(resolve31(artifactDir, file), { force: true });
|
|
6785
6844
|
}
|
|
6786
6845
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
6787
6846
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
@@ -6820,28 +6879,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
6820
6879
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
6821
6880
|
}
|
|
6822
6881
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
6823
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
6824
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
6882
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve31(options.binDir, "rig"), rigSourceRoot);
|
|
6883
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve31(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
6825
6884
|
...options.runtimeSecretDefines,
|
|
6826
6885
|
AGENT_TASK_ID: options.taskId,
|
|
6827
6886
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6828
6887
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
6829
6888
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
6830
6889
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
6831
|
-
AGENT_BINARY_PATH:
|
|
6890
|
+
AGENT_BINARY_PATH: resolve31(options.binDir, "rig-agent"),
|
|
6832
6891
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
6833
6892
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
6834
6893
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
6835
6894
|
});
|
|
6836
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
6895
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve31(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
6837
6896
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6838
6897
|
AGENT_LOGS_DIR: options.logsDir,
|
|
6839
6898
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
6840
|
-
AGENT_TS_API_TESTS_DIR:
|
|
6841
|
-
AGENT_RIG_AGENT_BIN:
|
|
6899
|
+
AGENT_TS_API_TESTS_DIR: resolve31(options.workspaceDir, "TSAPITests"),
|
|
6900
|
+
AGENT_RIG_AGENT_BIN: resolve31(options.binDir, "rig-agent")
|
|
6842
6901
|
});
|
|
6843
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
6844
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
6902
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve31(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
6903
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve31(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
6845
6904
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6846
6905
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6847
6906
|
});
|
|
@@ -6850,15 +6909,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
6850
6909
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6851
6910
|
};
|
|
6852
6911
|
for (const hookName of hookNames) {
|
|
6853
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
6912
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve31(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
6854
6913
|
}
|
|
6855
|
-
const pluginsDir =
|
|
6856
|
-
if (
|
|
6914
|
+
const pluginsDir = resolve31(options.projectRoot, "rig/plugins");
|
|
6915
|
+
if (existsSync31(pluginsDir)) {
|
|
6857
6916
|
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
6858
6917
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
6859
6918
|
if (!match)
|
|
6860
6919
|
continue;
|
|
6861
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
6920
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve31(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
6862
6921
|
}
|
|
6863
6922
|
}
|
|
6864
6923
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -6868,8 +6927,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
6868
6927
|
}
|
|
6869
6928
|
async function writeRuntimeManifest(config) {
|
|
6870
6929
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
6871
|
-
const binarySha256 = sha256Hex(
|
|
6872
|
-
const manifestPath =
|
|
6930
|
+
const binarySha256 = sha256Hex(readFileSync15(config.binaryPath));
|
|
6931
|
+
const manifestPath = resolve31(config.runtimeRoot, "manifest.json");
|
|
6873
6932
|
const manifest = {
|
|
6874
6933
|
runtimeId: config.runtimeId,
|
|
6875
6934
|
taskId: config.taskId,
|
|
@@ -6989,31 +7048,31 @@ function readFileMtimeMs(path) {
|
|
|
6989
7048
|
}
|
|
6990
7049
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
6991
7050
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
6992
|
-
const sourceNodeModules =
|
|
6993
|
-
if (!
|
|
6994
|
-
const runtimeHumoongate =
|
|
6995
|
-
if (
|
|
6996
|
-
const targetNodeModules =
|
|
7051
|
+
const sourceNodeModules = resolve31(monorepoRoot, "humoongate", "node_modules");
|
|
7052
|
+
if (!existsSync31(sourceNodeModules)) {} else {
|
|
7053
|
+
const runtimeHumoongate = resolve31(workspaceDir, "humoongate");
|
|
7054
|
+
if (existsSync31(resolve31(runtimeHumoongate, "package.json"))) {
|
|
7055
|
+
const targetNodeModules = resolve31(runtimeHumoongate, "node_modules");
|
|
6997
7056
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
6998
7057
|
}
|
|
6999
7058
|
}
|
|
7000
|
-
const runtimeHpNext =
|
|
7001
|
-
if (!
|
|
7059
|
+
const runtimeHpNext = resolve31(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
7060
|
+
if (!existsSync31(resolve31(runtimeHpNext, "package.json"))) {
|
|
7002
7061
|
return;
|
|
7003
7062
|
}
|
|
7004
|
-
const sourceHpNextNodeModules =
|
|
7005
|
-
const sourceMonorepoNodeModules =
|
|
7006
|
-
const targetHpNextNodeModules =
|
|
7007
|
-
if (
|
|
7063
|
+
const sourceHpNextNodeModules = resolve31(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
7064
|
+
const sourceMonorepoNodeModules = resolve31(monorepoRoot, "node_modules");
|
|
7065
|
+
const targetHpNextNodeModules = resolve31(runtimeHpNext, "node_modules");
|
|
7066
|
+
if (existsSync31(sourceHpNextNodeModules)) {
|
|
7008
7067
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
7009
7068
|
return;
|
|
7010
7069
|
}
|
|
7011
|
-
if (
|
|
7070
|
+
if (existsSync31(sourceMonorepoNodeModules)) {
|
|
7012
7071
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
7013
7072
|
}
|
|
7014
7073
|
}
|
|
7015
7074
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
7016
|
-
linkNodeModulesLayer(
|
|
7075
|
+
linkNodeModulesLayer(resolve31(monorepoRoot, "node_modules"), resolve31(workspaceDir, "node_modules"));
|
|
7017
7076
|
for (const relativePackageDir of [
|
|
7018
7077
|
"apps/native-app/apps/marketing",
|
|
7019
7078
|
"apps/native-app/apps/web",
|
|
@@ -7035,15 +7094,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
7035
7094
|
"packages/standard-plugin",
|
|
7036
7095
|
"packages/validator-kit"
|
|
7037
7096
|
]) {
|
|
7038
|
-
const workspacePackageDir =
|
|
7039
|
-
if (!
|
|
7097
|
+
const workspacePackageDir = resolve31(workspaceDir, relativePackageDir);
|
|
7098
|
+
if (!existsSync31(resolve31(workspacePackageDir, "package.json"))) {
|
|
7040
7099
|
continue;
|
|
7041
7100
|
}
|
|
7042
|
-
linkNodeModulesLayer(
|
|
7101
|
+
linkNodeModulesLayer(resolve31(monorepoRoot, relativePackageDir, "node_modules"), resolve31(workspacePackageDir, "node_modules"));
|
|
7043
7102
|
}
|
|
7044
7103
|
}
|
|
7045
7104
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
7046
|
-
if (!
|
|
7105
|
+
if (!existsSync31(sourceDir) || existsSync31(targetDir)) {
|
|
7047
7106
|
return;
|
|
7048
7107
|
}
|
|
7049
7108
|
try {
|
|
@@ -7052,30 +7111,30 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
7052
7111
|
} catch (error) {
|
|
7053
7112
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
7054
7113
|
}
|
|
7055
|
-
|
|
7114
|
+
mkdirSync17(dirname14(targetDir), { recursive: true });
|
|
7056
7115
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
7057
7116
|
}
|
|
7058
7117
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
7059
|
-
const hooksDir =
|
|
7060
|
-
const pluginsDir =
|
|
7061
|
-
const validatorsDir =
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7118
|
+
const hooksDir = resolve31(runtimeBinDir, "hooks");
|
|
7119
|
+
const pluginsDir = resolve31(runtimeBinDir, "plugins");
|
|
7120
|
+
const validatorsDir = resolve31(runtimeBinDir, "validators");
|
|
7121
|
+
mkdirSync17(hooksDir, { recursive: true });
|
|
7122
|
+
mkdirSync17(pluginsDir, { recursive: true });
|
|
7123
|
+
mkdirSync17(validatorsDir, { recursive: true });
|
|
7065
7124
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
7066
7125
|
}
|
|
7067
7126
|
|
|
7068
7127
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
7069
|
-
import { existsSync as
|
|
7070
|
-
import { basename as basename9, resolve as
|
|
7128
|
+
import { existsSync as existsSync34, rmSync as rmSync12, writeFileSync as writeFileSync14 } from "fs";
|
|
7129
|
+
import { basename as basename9, resolve as resolve35 } from "path";
|
|
7071
7130
|
|
|
7072
7131
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
7073
|
-
import { existsSync as
|
|
7132
|
+
import { existsSync as existsSync33 } from "fs";
|
|
7074
7133
|
|
|
7075
7134
|
// packages/runtime/src/control-plane/runtime/guard.ts
|
|
7076
7135
|
import { optimizeNextInvocation } from "bun:jsc";
|
|
7077
|
-
import { existsSync as
|
|
7078
|
-
import { resolve as
|
|
7136
|
+
import { existsSync as existsSync32, readFileSync as readFileSync16, statSync as statSync9 } from "fs";
|
|
7137
|
+
import { resolve as resolve32 } from "path";
|
|
7079
7138
|
|
|
7080
7139
|
// packages/runtime/src/control-plane/runtime/guard-types.ts
|
|
7081
7140
|
var POLICY_VERSION = 1;
|
|
@@ -7138,8 +7197,8 @@ function loadPolicy(projectRoot) {
|
|
|
7138
7197
|
if (seededPolicyConfig) {
|
|
7139
7198
|
return seededPolicyConfig;
|
|
7140
7199
|
}
|
|
7141
|
-
const configPath =
|
|
7142
|
-
if (!
|
|
7200
|
+
const configPath = resolve32(projectRoot, "rig/policy/policy.json");
|
|
7201
|
+
if (!existsSync32(configPath)) {
|
|
7143
7202
|
return defaultPolicy();
|
|
7144
7203
|
}
|
|
7145
7204
|
let mtimeMs;
|
|
@@ -7153,7 +7212,7 @@ function loadPolicy(projectRoot) {
|
|
|
7153
7212
|
}
|
|
7154
7213
|
let parsed;
|
|
7155
7214
|
try {
|
|
7156
|
-
parsed = JSON.parse(
|
|
7215
|
+
parsed = JSON.parse(readFileSync16(configPath, "utf-8"));
|
|
7157
7216
|
} catch {
|
|
7158
7217
|
return defaultPolicy();
|
|
7159
7218
|
}
|
|
@@ -7369,28 +7428,28 @@ function resolveAction(mode, matched) {
|
|
|
7369
7428
|
}
|
|
7370
7429
|
function resolveAbsolutePath(projectRoot, rawPath) {
|
|
7371
7430
|
if (rawPath.startsWith("/"))
|
|
7372
|
-
return
|
|
7373
|
-
return
|
|
7431
|
+
return resolve32(rawPath);
|
|
7432
|
+
return resolve32(projectRoot, rawPath);
|
|
7374
7433
|
}
|
|
7375
7434
|
function isHarnessPath(projectRoot, rawPath) {
|
|
7376
7435
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7377
7436
|
const managedRoots = [
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7437
|
+
resolve32(projectRoot, "rig"),
|
|
7438
|
+
resolve32(projectRoot, ".rig"),
|
|
7439
|
+
resolve32(projectRoot, "artifacts")
|
|
7381
7440
|
];
|
|
7382
7441
|
return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
|
|
7383
7442
|
}
|
|
7384
7443
|
function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
|
|
7385
7444
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7386
7445
|
if (taskWorkspace) {
|
|
7387
|
-
const workspaceRigRoot =
|
|
7388
|
-
const workspaceArtifactsRoot =
|
|
7446
|
+
const workspaceRigRoot = resolve32(taskWorkspace, ".rig");
|
|
7447
|
+
const workspaceArtifactsRoot = resolve32(taskWorkspace, "artifacts");
|
|
7389
7448
|
if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
|
|
7390
7449
|
return true;
|
|
7391
7450
|
}
|
|
7392
7451
|
}
|
|
7393
|
-
const runtimeRoot =
|
|
7452
|
+
const runtimeRoot = resolve32(projectRoot, ".rig/runtime/agents");
|
|
7394
7453
|
return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
|
|
7395
7454
|
}
|
|
7396
7455
|
function isTestFile(path) {
|
|
@@ -7438,7 +7497,7 @@ function evaluateScope(policy, context, filePath, access) {
|
|
|
7438
7497
|
return allowed();
|
|
7439
7498
|
}
|
|
7440
7499
|
if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
|
|
7441
|
-
const absPath =
|
|
7500
|
+
const absPath = resolve32(filePath);
|
|
7442
7501
|
if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
|
|
7443
7502
|
const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
|
|
7444
7503
|
const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
|
|
@@ -7766,13 +7825,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
7766
7825
|
depRoots
|
|
7767
7826
|
};
|
|
7768
7827
|
const fsContext = {
|
|
7769
|
-
pathExists: (p) =>
|
|
7828
|
+
pathExists: (p) => existsSync33(p),
|
|
7770
7829
|
realPath: toRealPath
|
|
7771
7830
|
};
|
|
7772
7831
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
7773
7832
|
const seatbelt = Bun.which("sandbox-exec");
|
|
7774
7833
|
probed.push("sandbox-exec");
|
|
7775
|
-
if (seatbelt &&
|
|
7834
|
+
if (seatbelt && existsSync33(seatbelt)) {
|
|
7776
7835
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
7777
7836
|
if (SeatbeltBackendClass) {
|
|
7778
7837
|
return {
|
|
@@ -7893,8 +7952,8 @@ init_layout();
|
|
|
7893
7952
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
7894
7953
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
7895
7954
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
7896
|
-
const readyFile =
|
|
7897
|
-
const requestFile =
|
|
7955
|
+
const readyFile = resolve35(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
7956
|
+
const requestFile = resolve35(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
7898
7957
|
rmSync12(readyFile, { force: true });
|
|
7899
7958
|
rmSync12(requestFile, { force: true });
|
|
7900
7959
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
@@ -7938,7 +7997,7 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
7938
7997
|
rmSync12(requestFile, { force: true });
|
|
7939
7998
|
},
|
|
7940
7999
|
finalize: async (commandParts, exitCode) => {
|
|
7941
|
-
|
|
8000
|
+
writeFileSync14(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
7942
8001
|
`, "utf-8");
|
|
7943
8002
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
7944
8003
|
proc.exited,
|
|
@@ -7966,10 +8025,10 @@ function resolveSnapshotSidecarScriptPath() {
|
|
|
7966
8025
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
7967
8026
|
}
|
|
7968
8027
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
7969
|
-
return
|
|
8028
|
+
return resolve35(binDir, "snapshot-sidecar");
|
|
7970
8029
|
}
|
|
7971
8030
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
7972
|
-
if (!
|
|
8031
|
+
if (!existsSync34(binaryPath)) {
|
|
7973
8032
|
return false;
|
|
7974
8033
|
}
|
|
7975
8034
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -7984,12 +8043,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
7984
8043
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
7985
8044
|
].filter((value) => Boolean(value));
|
|
7986
8045
|
for (const root of hostRoots) {
|
|
7987
|
-
const candidate =
|
|
7988
|
-
if (
|
|
8046
|
+
const candidate = resolve35(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
8047
|
+
if (existsSync34(candidate)) {
|
|
7989
8048
|
return candidate;
|
|
7990
8049
|
}
|
|
7991
8050
|
}
|
|
7992
|
-
return
|
|
8051
|
+
return resolve35(import.meta.dir, "..", fileName);
|
|
7993
8052
|
}
|
|
7994
8053
|
function resolveBunCliInvocation() {
|
|
7995
8054
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -8016,7 +8075,7 @@ function resolveBunCliInvocation() {
|
|
|
8016
8075
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
8017
8076
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
8018
8077
|
while (Date.now() < deadline) {
|
|
8019
|
-
if (
|
|
8078
|
+
if (existsSync34(readyFile)) {
|
|
8020
8079
|
return;
|
|
8021
8080
|
}
|
|
8022
8081
|
const exitCode = proc.exitCode;
|
|
@@ -8034,9 +8093,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
8034
8093
|
async function hydrateRuntimeMemory(options) {
|
|
8035
8094
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
8036
8095
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
8037
|
-
const hydratedPath =
|
|
8096
|
+
const hydratedPath = resolve36(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
8038
8097
|
try {
|
|
8039
|
-
await mkdir3(
|
|
8098
|
+
await mkdir3(resolve36(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
8040
8099
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
8041
8100
|
return {
|
|
8042
8101
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -8051,12 +8110,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
8051
8110
|
}
|
|
8052
8111
|
}
|
|
8053
8112
|
async function createRuntimeTaskRecordReader(options) {
|
|
8054
|
-
const legacyConfigPath =
|
|
8113
|
+
const legacyConfigPath = resolve36(options.projectRoot, ".rig", "task-config.json");
|
|
8055
8114
|
let pluginHostContext = null;
|
|
8056
8115
|
try {
|
|
8057
8116
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
8058
8117
|
} catch (error) {
|
|
8059
|
-
if (!
|
|
8118
|
+
if (!existsSync35(legacyConfigPath)) {
|
|
8060
8119
|
throw error;
|
|
8061
8120
|
}
|
|
8062
8121
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -8076,7 +8135,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
8076
8135
|
source: "plugin"
|
|
8077
8136
|
};
|
|
8078
8137
|
}
|
|
8079
|
-
if (
|
|
8138
|
+
if (existsSync35(legacyConfigPath)) {
|
|
8080
8139
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
8081
8140
|
options.diagnostics?.(message);
|
|
8082
8141
|
console.warn(message);
|
|
@@ -8093,10 +8152,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
8093
8152
|
};
|
|
8094
8153
|
}
|
|
8095
8154
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
8096
|
-
const jsonPath =
|
|
8097
|
-
if (
|
|
8155
|
+
const jsonPath = resolve36(projectRoot, "rig.config.json");
|
|
8156
|
+
if (existsSync35(jsonPath)) {
|
|
8098
8157
|
try {
|
|
8099
|
-
const parsed = JSON.parse(
|
|
8158
|
+
const parsed = JSON.parse(readFileSync17(jsonPath, "utf8"));
|
|
8100
8159
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
8101
8160
|
const taskSource = parsed.taskSource;
|
|
8102
8161
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -8108,12 +8167,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
8108
8167
|
return null;
|
|
8109
8168
|
}
|
|
8110
8169
|
}
|
|
8111
|
-
const tsPath =
|
|
8112
|
-
if (!
|
|
8170
|
+
const tsPath = resolve36(projectRoot, "rig.config.ts");
|
|
8171
|
+
if (!existsSync35(tsPath)) {
|
|
8113
8172
|
return null;
|
|
8114
8173
|
}
|
|
8115
8174
|
try {
|
|
8116
|
-
const source =
|
|
8175
|
+
const source = readFileSync17(tsPath, "utf8");
|
|
8117
8176
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
8118
8177
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
8119
8178
|
return kind ?? null;
|
|
@@ -8183,8 +8242,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
8183
8242
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
8184
8243
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
8185
8244
|
};
|
|
8186
|
-
const configPath =
|
|
8187
|
-
await mkdir3(
|
|
8245
|
+
const configPath = resolve36(options.workspaceDir, ".rig", "task-config.json");
|
|
8246
|
+
await mkdir3(resolve36(options.workspaceDir, ".rig"), { recursive: true });
|
|
8188
8247
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
8189
8248
|
`, "utf-8");
|
|
8190
8249
|
}
|
|
@@ -8248,9 +8307,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8248
8307
|
}
|
|
8249
8308
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8250
8309
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8251
|
-
const workspaceDir =
|
|
8310
|
+
const workspaceDir = resolve36(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8252
8311
|
const createdAt = new Date().toISOString();
|
|
8253
|
-
if (!
|
|
8312
|
+
if (!existsSync35(resolve36(monorepoRoot, ".git"))) {
|
|
8254
8313
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8255
8314
|
}
|
|
8256
8315
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8285,7 +8344,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8285
8344
|
logsDir: overlay.logsDir,
|
|
8286
8345
|
stateDir: overlay.stateDir,
|
|
8287
8346
|
sessionDir: overlay.sessionDir,
|
|
8288
|
-
claudeHomeDir:
|
|
8347
|
+
claudeHomeDir: resolve36(workspaceLayout.homeDir, ".claude"),
|
|
8289
8348
|
contextFile: overlay.contextPath,
|
|
8290
8349
|
binDir: workspaceLayout.binDir,
|
|
8291
8350
|
createdAt
|
|
@@ -8298,8 +8357,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8298
8357
|
projectRoot: options.projectRoot,
|
|
8299
8358
|
workspaceDir
|
|
8300
8359
|
});
|
|
8301
|
-
|
|
8302
|
-
|
|
8360
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8361
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8303
8362
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8304
8363
|
if (options.preserveTaskArtifacts) {
|
|
8305
8364
|
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
@@ -8318,7 +8377,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8318
8377
|
runtimeId: options.id
|
|
8319
8378
|
}),
|
|
8320
8379
|
workspaceDir,
|
|
8321
|
-
artifactRoot:
|
|
8380
|
+
artifactRoot: resolve36(workspaceDir, "artifacts", options.taskId),
|
|
8322
8381
|
hostProjectRoot: options.projectRoot,
|
|
8323
8382
|
monorepoMainRoot: monorepoRoot,
|
|
8324
8383
|
monorepoBaseRef: baseRef,
|
|
@@ -8334,8 +8393,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8334
8393
|
stateDir: overlay.stateDir,
|
|
8335
8394
|
logsDir: overlay.logsDir,
|
|
8336
8395
|
sessionDir: overlay.sessionDir,
|
|
8337
|
-
sessionFile:
|
|
8338
|
-
policyFile:
|
|
8396
|
+
sessionFile: resolve36(overlay.sessionDir, "session.json"),
|
|
8397
|
+
policyFile: resolve36(options.projectRoot, "rig/policy/policy.json"),
|
|
8339
8398
|
binDir: runtime.binDir,
|
|
8340
8399
|
createdAt,
|
|
8341
8400
|
memory
|
|
@@ -8346,9 +8405,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8346
8405
|
task: taskResolution.task,
|
|
8347
8406
|
taskEntry
|
|
8348
8407
|
});
|
|
8349
|
-
const manifestPath =
|
|
8408
|
+
const manifestPath = resolve36(runtimeRoot, "manifest.json");
|
|
8350
8409
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8351
|
-
const runtimeAgentBinary =
|
|
8410
|
+
const runtimeAgentBinary = resolve36(runtime.binDir, "rig-agent");
|
|
8352
8411
|
await ensureRigGitBinaryPath();
|
|
8353
8412
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8354
8413
|
projectRoot: options.projectRoot,
|
|
@@ -8365,8 +8424,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8365
8424
|
});
|
|
8366
8425
|
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8367
8426
|
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8368
|
-
|
|
8369
|
-
|
|
8427
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8428
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8370
8429
|
await buildRuntimeToolchain({
|
|
8371
8430
|
projectRoot: options.projectRoot,
|
|
8372
8431
|
workspaceDir,
|
|
@@ -8403,9 +8462,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8403
8462
|
workspaceDir,
|
|
8404
8463
|
taskEntry
|
|
8405
8464
|
});
|
|
8406
|
-
const sandboxDir =
|
|
8465
|
+
const sandboxDir = resolve36(runtimeRoot, "sandbox");
|
|
8407
8466
|
await mkdir3(sandboxDir, { recursive: true });
|
|
8408
|
-
await writeFile2(
|
|
8467
|
+
await writeFile2(resolve36(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8409
8468
|
id: options.id,
|
|
8410
8469
|
taskId: options.taskId,
|
|
8411
8470
|
mode: "worktree",
|
|
@@ -8512,8 +8571,8 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8512
8571
|
const sendRequest = async (method, params) => {
|
|
8513
8572
|
const id = nextRequestId;
|
|
8514
8573
|
nextRequestId += 1;
|
|
8515
|
-
const resultPromise = new Promise((
|
|
8516
|
-
pendingResponses.set(id, { resolve:
|
|
8574
|
+
const resultPromise = new Promise((resolve37, reject) => {
|
|
8575
|
+
pendingResponses.set(id, { resolve: resolve37, reject });
|
|
8517
8576
|
});
|
|
8518
8577
|
await sendMessage({ id, method, params });
|
|
8519
8578
|
return resultPromise;
|
|
@@ -8712,8 +8771,8 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8712
8771
|
console.error(line);
|
|
8713
8772
|
}
|
|
8714
8773
|
});
|
|
8715
|
-
const exitPromise = new Promise((
|
|
8716
|
-
child.once("close", (code, signal) =>
|
|
8774
|
+
const exitPromise = new Promise((resolve37) => {
|
|
8775
|
+
child.once("close", (code, signal) => resolve37({ code, signal }));
|
|
8717
8776
|
});
|
|
8718
8777
|
await sendRequest("initialize", {
|
|
8719
8778
|
clientInfo: DEFAULT_CLIENT_INFO,
|
|
@@ -8754,7 +8813,7 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8754
8813
|
while (!completionState.current) {
|
|
8755
8814
|
exitResult = await Promise.race([
|
|
8756
8815
|
exitPromise,
|
|
8757
|
-
new Promise((
|
|
8816
|
+
new Promise((resolve37) => setTimeout(() => resolve37(null), 100))
|
|
8758
8817
|
]);
|
|
8759
8818
|
if (exitResult) {
|
|
8760
8819
|
break;
|
|
@@ -8903,13 +8962,13 @@ function sanitizeEnv(env) {
|
|
|
8903
8962
|
return next;
|
|
8904
8963
|
}
|
|
8905
8964
|
function writeChildLine(child, line) {
|
|
8906
|
-
return new Promise((
|
|
8965
|
+
return new Promise((resolve37, reject) => {
|
|
8907
8966
|
child.stdin.write(line, (error) => {
|
|
8908
8967
|
if (error) {
|
|
8909
8968
|
reject(error);
|
|
8910
8969
|
return;
|
|
8911
8970
|
}
|
|
8912
|
-
|
|
8971
|
+
resolve37();
|
|
8913
8972
|
});
|
|
8914
8973
|
});
|
|
8915
8974
|
}
|
|
@@ -8957,8 +9016,8 @@ function formatJsonRpcError(error) {
|
|
|
8957
9016
|
|
|
8958
9017
|
// packages/runtime/src/control-plane/pi-sessiond/launcher.ts
|
|
8959
9018
|
import { randomBytes } from "crypto";
|
|
8960
|
-
import { existsSync as
|
|
8961
|
-
import { dirname as
|
|
9019
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync21, readFileSync as readFileSync18, rmSync as rmSync14 } from "fs";
|
|
9020
|
+
import { dirname as dirname15, resolve as resolve37 } from "path";
|
|
8962
9021
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8963
9022
|
|
|
8964
9023
|
// packages/runtime/src/control-plane/pi-sessiond/client.ts
|
|
@@ -9003,9 +9062,9 @@ class RigPiSessionDaemonClient {
|
|
|
9003
9062
|
var BUILD_CONFIG2 = {};
|
|
9004
9063
|
var BAKED_RIG_SOURCE_ROOT = BUILD_CONFIG2.RIG_SOURCE_ROOT ?? "";
|
|
9005
9064
|
async function ensureRigPiSessionDaemon(input) {
|
|
9006
|
-
const rootDir =
|
|
9007
|
-
|
|
9008
|
-
const readyFile =
|
|
9065
|
+
const rootDir = resolve37(input.rootDir);
|
|
9066
|
+
mkdirSync21(rootDir, { recursive: true });
|
|
9067
|
+
const readyFile = resolve37(rootDir, "ready.json");
|
|
9009
9068
|
const existing = readDaemonReadyFile(readyFile);
|
|
9010
9069
|
const existingHandle = existing ? await tryReady(existing) : null;
|
|
9011
9070
|
if (existingHandle)
|
|
@@ -9099,12 +9158,12 @@ function resolveRigPiSessionDaemonBinPath(env) {
|
|
|
9099
9158
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
9100
9159
|
].filter((value) => Boolean(value));
|
|
9101
9160
|
for (const root of roots) {
|
|
9102
|
-
const candidate =
|
|
9103
|
-
if (
|
|
9161
|
+
const candidate = resolve37(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts");
|
|
9162
|
+
if (existsSync36(candidate))
|
|
9104
9163
|
return candidate;
|
|
9105
9164
|
}
|
|
9106
9165
|
const moduleCandidate = fileURLToPath2(new URL("./bin.ts", import.meta.url));
|
|
9107
|
-
if (
|
|
9166
|
+
if (existsSync36(moduleCandidate))
|
|
9108
9167
|
return moduleCandidate;
|
|
9109
9168
|
throw new Error([
|
|
9110
9169
|
"Unable to locate rig-pi-sessiond entrypoint.",
|
|
@@ -9114,10 +9173,10 @@ function resolveRigPiSessionDaemonBinPath(env) {
|
|
|
9114
9173
|
`));
|
|
9115
9174
|
}
|
|
9116
9175
|
function readDaemonReadyFile(path) {
|
|
9117
|
-
if (!
|
|
9176
|
+
if (!existsSync36(path))
|
|
9118
9177
|
return null;
|
|
9119
9178
|
try {
|
|
9120
|
-
const parsed = JSON.parse(
|
|
9179
|
+
const parsed = JSON.parse(readFileSync18(path, "utf8"));
|
|
9121
9180
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
9122
9181
|
} catch {
|
|
9123
9182
|
return null;
|
|
@@ -9127,10 +9186,10 @@ function sleep(ms) {
|
|
|
9127
9186
|
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
9128
9187
|
}
|
|
9129
9188
|
function resolveRigPiSessionDaemonRoot(stateDir) {
|
|
9130
|
-
const root =
|
|
9131
|
-
|
|
9132
|
-
if (!
|
|
9133
|
-
|
|
9189
|
+
const root = resolve37(stateDir, "pi-sessiond");
|
|
9190
|
+
mkdirSync21(dirname15(root), { recursive: true });
|
|
9191
|
+
if (!existsSync36(root))
|
|
9192
|
+
mkdirSync21(root, { recursive: true });
|
|
9134
9193
|
return root;
|
|
9135
9194
|
}
|
|
9136
9195
|
|
|
@@ -9168,7 +9227,7 @@ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar = start
|
|
|
9168
9227
|
}
|
|
9169
9228
|
}
|
|
9170
9229
|
async function runAgentWrapper(options = {}) {
|
|
9171
|
-
const projectRoot =
|
|
9230
|
+
const projectRoot = resolve38(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
|
|
9172
9231
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
9173
9232
|
const argv = options.argv || process.argv.slice(2);
|
|
9174
9233
|
if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
|
|
@@ -9244,11 +9303,11 @@ async function runAgentWrapper(options = {}) {
|
|
|
9244
9303
|
const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
|
|
9245
9304
|
const runClaudeCompatUnsandboxed = provider === "claude-code" && bypassOuterRuntimeSandbox;
|
|
9246
9305
|
if (runClaudeCompatUnsandboxed && process.env.HOME?.trim()) {
|
|
9247
|
-
env.CLAUDE_HOME =
|
|
9306
|
+
env.CLAUDE_HOME = resolve38(process.env.HOME.trim(), ".claude");
|
|
9248
9307
|
env.RIG_CLAUDE_RUNTIME_HOME = runtime.claudeHomeDir;
|
|
9249
9308
|
}
|
|
9250
9309
|
if (provider === "pi") {
|
|
9251
|
-
env.PI_CODING_AGENT_DIR =
|
|
9310
|
+
env.PI_CODING_AGENT_DIR = resolve38(runtime.homeDir, ".pi", "agent");
|
|
9252
9311
|
env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
|
|
9253
9312
|
}
|
|
9254
9313
|
env.RIG_RUNTIME_SANDBOX = "enforce";
|
|
@@ -9449,7 +9508,7 @@ async function runPiSessionDaemonProvider(input) {
|
|
|
9449
9508
|
const start = await daemon.client.request("POST", "/sessions", {
|
|
9450
9509
|
runId,
|
|
9451
9510
|
cwd: input.runtime.workspaceDir,
|
|
9452
|
-
agentDir: input.env.PI_CODING_AGENT_DIR ||
|
|
9511
|
+
agentDir: input.env.PI_CODING_AGENT_DIR || resolve38(input.runtime.homeDir, ".pi", "agent"),
|
|
9453
9512
|
sessionDir: input.runtime.sessionDir,
|
|
9454
9513
|
sessionName: input.sessionName
|
|
9455
9514
|
});
|
|
@@ -9848,8 +9907,8 @@ function resolveFromShellPath(binary) {
|
|
|
9848
9907
|
function resolveBundledPiBinary() {
|
|
9849
9908
|
try {
|
|
9850
9909
|
const packageJson = requireFromRuntime.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
9851
|
-
const binaryPath =
|
|
9852
|
-
return
|
|
9910
|
+
const binaryPath = resolve38(packageJson, "..", "dist", "cli.js");
|
|
9911
|
+
return existsSync37(binaryPath) ? binaryPath : null;
|
|
9853
9912
|
} catch {
|
|
9854
9913
|
return null;
|
|
9855
9914
|
}
|
|
@@ -9885,7 +9944,7 @@ async function waitForDirtyBaselineReady(runtime, taskId) {
|
|
|
9885
9944
|
workspaceDir: runtime.workspaceDir,
|
|
9886
9945
|
readyFile
|
|
9887
9946
|
});
|
|
9888
|
-
while (!
|
|
9947
|
+
while (!existsSync37(readyFile)) {
|
|
9889
9948
|
if (Date.now() >= deadline) {
|
|
9890
9949
|
throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
|
|
9891
9950
|
}
|
|
@@ -9953,9 +10012,9 @@ async function readPluginTaskStatus(projectRoot, taskId) {
|
|
|
9953
10012
|
}
|
|
9954
10013
|
}
|
|
9955
10014
|
function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
9956
|
-
const handoffDir =
|
|
9957
|
-
|
|
9958
|
-
const handoffPath =
|
|
10015
|
+
const handoffDir = resolve38(hostProjectRoot, ".rig/runtime/handoffs");
|
|
10016
|
+
mkdirSync22(handoffDir, { recursive: true });
|
|
10017
|
+
const handoffPath = resolve38(handoffDir, `${taskId}-${Date.now()}.json`);
|
|
9959
10018
|
const handoff = {
|
|
9960
10019
|
taskId,
|
|
9961
10020
|
runtimeId: runtime.id,
|
|
@@ -9971,7 +10030,7 @@ function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
|
9971
10030
|
`rig git open-pr --task ${taskId}`
|
|
9972
10031
|
]
|
|
9973
10032
|
};
|
|
9974
|
-
|
|
10033
|
+
writeFileSync15(handoffPath, `${JSON.stringify(handoff, null, 2)}
|
|
9975
10034
|
`, "utf-8");
|
|
9976
10035
|
console.log(`[rig-agent] Completion verification paused for ${taskId}.`);
|
|
9977
10036
|
console.log(`[rig-agent] Runtime handoff saved: ${handoffPath}`);
|
|
@@ -10021,13 +10080,13 @@ async function readTaskMetadata2(taskRoot, taskId) {
|
|
|
10021
10080
|
async function readTaskConfigHints(taskRoot, taskId) {
|
|
10022
10081
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
10023
10082
|
const candidates = [
|
|
10024
|
-
runtimeContext?.monorepoMainRoot ?
|
|
10025
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
10026
|
-
|
|
10027
|
-
|
|
10083
|
+
runtimeContext?.monorepoMainRoot ? resolve38(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
10084
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve38(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
10085
|
+
resolve38(taskRoot, ".rig", "task-config.json"),
|
|
10086
|
+
resolve38(taskRoot, "rig", "task-config.json")
|
|
10028
10087
|
].filter(Boolean);
|
|
10029
10088
|
for (const configPath of candidates) {
|
|
10030
|
-
if (!
|
|
10089
|
+
if (!existsSync37(configPath)) {
|
|
10031
10090
|
continue;
|
|
10032
10091
|
}
|
|
10033
10092
|
try {
|