@h-rig/runtime 0.0.6-alpha.34 → 0.0.6-alpha.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/rig-agent-dispatch.js +518 -459
- package/dist/bin/rig-agent.js +430 -361
- package/dist/src/control-plane/agent-wrapper.js +523 -464
- package/dist/src/control-plane/harness-main.js +528 -458
- 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 +10 -0
- package/dist/src/control-plane/native/harness-cli.js +513 -443
- 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-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
|
@@ -149,32 +149,32 @@ var RIG_DEFINITION_DIRNAME = "rig", RIG_ARTIFACTS_DIRNAME = "artifacts";
|
|
|
149
149
|
var init_layout = () => {};
|
|
150
150
|
|
|
151
151
|
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
152
|
-
import { existsSync as
|
|
153
|
-
import { resolve as
|
|
152
|
+
import { existsSync as existsSync22, readdirSync as readdirSync4, realpathSync } from "fs";
|
|
153
|
+
import { resolve as resolve21 } from "path";
|
|
154
154
|
function toRealPath(path) {
|
|
155
|
-
if (!
|
|
156
|
-
return
|
|
155
|
+
if (!existsSync22(path)) {
|
|
156
|
+
return resolve21(path);
|
|
157
157
|
}
|
|
158
158
|
try {
|
|
159
159
|
return realpathSync.native(path);
|
|
160
160
|
} catch {
|
|
161
|
-
return
|
|
161
|
+
return resolve21(path);
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
165
165
|
const candidates = new Set;
|
|
166
166
|
const addPath = (candidate) => {
|
|
167
|
-
if (
|
|
167
|
+
if (existsSync22(candidate)) {
|
|
168
168
|
candidates.add(toRealPath(candidate));
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
|
-
addPath(
|
|
172
|
-
addPath(
|
|
171
|
+
addPath(resolve21(projectRoot, ".git"));
|
|
172
|
+
addPath(resolve21(workspaceDir, "..", "..", ".git"));
|
|
173
173
|
for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
|
|
174
|
-
addPath(
|
|
174
|
+
addPath(resolve21(repoRoot, ".git"));
|
|
175
175
|
}
|
|
176
|
-
const workspaceGit =
|
|
177
|
-
if (
|
|
176
|
+
const workspaceGit = resolve21(workspaceDir, ".git");
|
|
177
|
+
if (existsSync22(workspaceGit)) {
|
|
178
178
|
addPath(workspaceGit);
|
|
179
179
|
}
|
|
180
180
|
return [...candidates];
|
|
@@ -182,7 +182,7 @@ function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
|
182
182
|
function resolveHostRepoRootPaths(projectRoot) {
|
|
183
183
|
const candidates = new Set;
|
|
184
184
|
const addPath = (candidate) => {
|
|
185
|
-
if (
|
|
185
|
+
if (existsSync22(candidate)) {
|
|
186
186
|
candidates.add(toRealPath(candidate));
|
|
187
187
|
}
|
|
188
188
|
};
|
|
@@ -192,11 +192,11 @@ function resolveHostRepoRootPaths(projectRoot) {
|
|
|
192
192
|
addPath(monorepoRoot);
|
|
193
193
|
}
|
|
194
194
|
} catch {}
|
|
195
|
-
const reposDir =
|
|
196
|
-
if (
|
|
195
|
+
const reposDir = resolve21(projectRoot, "repos");
|
|
196
|
+
if (existsSync22(reposDir)) {
|
|
197
197
|
for (const entry of readdirSync4(reposDir, { withFileTypes: true })) {
|
|
198
198
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
199
|
-
addPath(
|
|
199
|
+
addPath(resolve21(reposDir, entry.name));
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
}
|
|
@@ -240,8 +240,8 @@ var exports_backend_seatbelt = {};
|
|
|
240
240
|
__export(exports_backend_seatbelt, {
|
|
241
241
|
SeatbeltBackend: () => SeatbeltBackend
|
|
242
242
|
});
|
|
243
|
-
import { mkdirSync as
|
|
244
|
-
import { resolve as
|
|
243
|
+
import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync13 } from "fs";
|
|
244
|
+
import { resolve as resolve34 } from "path";
|
|
245
245
|
|
|
246
246
|
class SeatbeltBackend {
|
|
247
247
|
kind = "macos-seatbelt";
|
|
@@ -265,11 +265,11 @@ class SeatbeltBackend {
|
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
writeSeatbeltProfile(options) {
|
|
268
|
-
const sandboxDir =
|
|
269
|
-
|
|
270
|
-
const profilePath =
|
|
268
|
+
const sandboxDir = resolve34(options.runtime.rootDir, "sandbox");
|
|
269
|
+
mkdirSync18(sandboxDir, { recursive: true });
|
|
270
|
+
const profilePath = resolve34(sandboxDir, "seatbelt.sb");
|
|
271
271
|
const profile = this.renderProfile(options);
|
|
272
|
-
|
|
272
|
+
writeFileSync13(profilePath, `${profile}
|
|
273
273
|
`, "utf-8");
|
|
274
274
|
return profilePath;
|
|
275
275
|
}
|
|
@@ -354,7 +354,7 @@ class SeatbeltBackend {
|
|
|
354
354
|
const realHome = process.env.HOME?.trim();
|
|
355
355
|
if (realHome) {
|
|
356
356
|
for (const binSubdir of [".local/bin", ".cargo/bin"]) {
|
|
357
|
-
const binPath =
|
|
357
|
+
const binPath = resolve34(realHome, binSubdir);
|
|
358
358
|
if (ctx.pathExists(binPath)) {
|
|
359
359
|
lines.push(`(allow file-read* (subpath ${seatbeltString(ctx.realPath(binPath))}))`);
|
|
360
360
|
}
|
|
@@ -383,8 +383,8 @@ var exports_backend_bwrap = {};
|
|
|
383
383
|
__export(exports_backend_bwrap, {
|
|
384
384
|
BwrapBackend: () => BwrapBackend
|
|
385
385
|
});
|
|
386
|
-
import { mkdirSync as
|
|
387
|
-
import { resolve as
|
|
386
|
+
import { mkdirSync as mkdirSync19 } from "fs";
|
|
387
|
+
import { resolve as resolve35 } from "path";
|
|
388
388
|
|
|
389
389
|
class BwrapBackend {
|
|
390
390
|
kind = "linux-bwrap";
|
|
@@ -513,18 +513,18 @@ class BwrapBackend {
|
|
|
513
513
|
const realHome = process.env.HOME?.trim();
|
|
514
514
|
if (realHome) {
|
|
515
515
|
for (const binSubdir of [".local/bin", ".local/lib", ".cargo/bin"]) {
|
|
516
|
-
const binPath = ctx.realPath(
|
|
516
|
+
const binPath = ctx.realPath(resolve35(realHome, binSubdir));
|
|
517
517
|
if (ctx.pathExists(binPath)) {
|
|
518
518
|
args.push("--ro-bind", binPath, binPath);
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
|
-
const agentSshDir =
|
|
521
|
+
const agentSshDir = resolve35(homeReal, ".ssh");
|
|
522
522
|
if (ctx.pathExists(agentSshDir)) {
|
|
523
523
|
args.push("--ro-bind", agentSshDir, agentSshDir);
|
|
524
524
|
} else {
|
|
525
|
-
const hostSshDir =
|
|
525
|
+
const hostSshDir = resolve35(realHome, ".ssh");
|
|
526
526
|
if (ctx.pathExists(hostSshDir)) {
|
|
527
|
-
|
|
527
|
+
mkdirSync19(agentSshDir, { recursive: true });
|
|
528
528
|
args.push("--ro-bind", hostSshDir, agentSshDir);
|
|
529
529
|
args.push("--ro-bind", hostSshDir, hostSshDir);
|
|
530
530
|
}
|
|
@@ -566,9 +566,9 @@ var init_backend_bwrap = __esm(() => {
|
|
|
566
566
|
});
|
|
567
567
|
|
|
568
568
|
// packages/runtime/src/control-plane/runtime/isolation/index.ts
|
|
569
|
-
import { existsSync as
|
|
569
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync20, readFileSync as readFileSync17, rmSync as rmSync13 } from "fs";
|
|
570
570
|
import { copyFile, mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
|
|
571
|
-
import { resolve as
|
|
571
|
+
import { resolve as resolve37 } from "path";
|
|
572
572
|
|
|
573
573
|
// packages/runtime/src/control-plane/native/git-native.ts
|
|
574
574
|
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
@@ -1858,8 +1858,8 @@ function isAgentRuntimeContextPath(path) {
|
|
|
1858
1858
|
var DEFAULT_RESULT_LIMIT = DEFAULT_RUNTIME_MEMORY_RETRIEVAL.topK;
|
|
1859
1859
|
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
1860
1860
|
// packages/runtime/src/control-plane/native/task-ops.ts
|
|
1861
|
-
import { appendFileSync, existsSync as
|
|
1862
|
-
import { resolve as
|
|
1861
|
+
import { appendFileSync, existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync12, writeFileSync as writeFileSync10 } from "fs";
|
|
1862
|
+
import { resolve as resolve25 } from "path";
|
|
1863
1863
|
|
|
1864
1864
|
// packages/runtime/src/build-time-config.ts
|
|
1865
1865
|
function normalizeBuildConfig(value) {
|
|
@@ -2423,6 +2423,8 @@ function buildBrowserGuidanceLines(browser) {
|
|
|
2423
2423
|
}
|
|
2424
2424
|
|
|
2425
2425
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
2426
|
+
import { existsSync as existsSync14 } from "fs";
|
|
2427
|
+
import { resolve as resolvePath } from "path";
|
|
2426
2428
|
import { createPluginHost } from "@rig/core";
|
|
2427
2429
|
import { loadConfig } from "@rig/core/load-config";
|
|
2428
2430
|
|
|
@@ -2753,6 +2755,55 @@ async function materializeSkills(projectRoot, entries) {
|
|
|
2753
2755
|
return written;
|
|
2754
2756
|
}
|
|
2755
2757
|
|
|
2758
|
+
// packages/runtime/src/control-plane/pi-settings-materializer.ts
|
|
2759
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
2760
|
+
import { dirname as dirname9, resolve as resolve13 } from "path";
|
|
2761
|
+
var SETTINGS_RELATIVE_PATH = ".pi/settings.json";
|
|
2762
|
+
var MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
|
|
2763
|
+
function readJson(path, fallback) {
|
|
2764
|
+
if (!existsSync13(path))
|
|
2765
|
+
return fallback;
|
|
2766
|
+
try {
|
|
2767
|
+
return JSON.parse(readFileSync6(path, "utf-8"));
|
|
2768
|
+
} catch {
|
|
2769
|
+
return fallback;
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
function packageKey(entry) {
|
|
2773
|
+
if (typeof entry === "string")
|
|
2774
|
+
return entry;
|
|
2775
|
+
if (entry && typeof entry === "object" && typeof entry.source === "string") {
|
|
2776
|
+
return entry.source;
|
|
2777
|
+
}
|
|
2778
|
+
return JSON.stringify(entry);
|
|
2779
|
+
}
|
|
2780
|
+
function materializePiPackages(projectRoot, declaredPackages) {
|
|
2781
|
+
const settingsPath = resolve13(projectRoot, SETTINGS_RELATIVE_PATH);
|
|
2782
|
+
const managedRecordPath = resolve13(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
|
|
2783
|
+
const settings = readJson(settingsPath, {});
|
|
2784
|
+
const previouslyManaged = new Set(readJson(managedRecordPath, []));
|
|
2785
|
+
const existing = Array.isArray(settings.packages) ? settings.packages : [];
|
|
2786
|
+
const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
|
|
2787
|
+
const operatorKeys = new Set(operatorEntries.map(packageKey));
|
|
2788
|
+
const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
|
|
2789
|
+
const nextPackages = [...operatorEntries, ...managedToAdd];
|
|
2790
|
+
if (nextPackages.length > 0 || existsSync13(settingsPath)) {
|
|
2791
|
+
const nextSettings = { ...settings };
|
|
2792
|
+
if (nextPackages.length > 0) {
|
|
2793
|
+
nextSettings.packages = nextPackages;
|
|
2794
|
+
} else {
|
|
2795
|
+
delete nextSettings.packages;
|
|
2796
|
+
}
|
|
2797
|
+
mkdirSync9(dirname9(settingsPath), { recursive: true });
|
|
2798
|
+
writeFileSync6(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
|
|
2799
|
+
`, "utf-8");
|
|
2800
|
+
}
|
|
2801
|
+
mkdirSync9(dirname9(managedRecordPath), { recursive: true });
|
|
2802
|
+
writeFileSync6(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
|
|
2803
|
+
`, "utf-8");
|
|
2804
|
+
return { settingsPath, packages: managedToAdd };
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2756
2807
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
2757
2808
|
async function buildPluginHostContext(projectRoot) {
|
|
2758
2809
|
let config;
|
|
@@ -2800,6 +2851,14 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2800
2851
|
} catch (err) {
|
|
2801
2852
|
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2802
2853
|
}
|
|
2854
|
+
try {
|
|
2855
|
+
const piPackages = config.runtime?.pi?.packages ?? [];
|
|
2856
|
+
if (piPackages.length > 0 || existsSync14(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
|
|
2857
|
+
materializePiPackages(projectRoot, piPackages);
|
|
2858
|
+
}
|
|
2859
|
+
} catch (err) {
|
|
2860
|
+
console.warn(`[plugin-host] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2861
|
+
}
|
|
2803
2862
|
return {
|
|
2804
2863
|
config,
|
|
2805
2864
|
pluginHost,
|
|
@@ -2813,12 +2872,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2813
2872
|
|
|
2814
2873
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
2815
2874
|
import { spawnSync } from "child_process";
|
|
2816
|
-
import { existsSync as
|
|
2817
|
-
import { basename as basename4, join as join3, resolve as
|
|
2875
|
+
import { existsSync as existsSync16, readFileSync as readFileSync8, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync7 } from "fs";
|
|
2876
|
+
import { basename as basename4, join as join3, resolve as resolve15 } from "path";
|
|
2818
2877
|
|
|
2819
2878
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
2820
|
-
import { existsSync as
|
|
2821
|
-
import { resolve as
|
|
2879
|
+
import { existsSync as existsSync15, readFileSync as readFileSync7 } from "fs";
|
|
2880
|
+
import { resolve as resolve14 } from "path";
|
|
2822
2881
|
|
|
2823
2882
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
2824
2883
|
async function findTaskById(reader, id) {
|
|
@@ -2841,7 +2900,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
2841
2900
|
}
|
|
2842
2901
|
}
|
|
2843
2902
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2844
|
-
const configPath = options.configPath ??
|
|
2903
|
+
const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
|
|
2845
2904
|
const reader = {
|
|
2846
2905
|
async listTasks() {
|
|
2847
2906
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -2852,8 +2911,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
2852
2911
|
};
|
|
2853
2912
|
return reader;
|
|
2854
2913
|
}
|
|
2855
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
2856
|
-
if (!
|
|
2914
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve14(projectRoot, ".rig", "task-config.json")) {
|
|
2915
|
+
if (!existsSync15(configPath)) {
|
|
2857
2916
|
return [];
|
|
2858
2917
|
}
|
|
2859
2918
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -2861,7 +2920,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve13(projectRoot,
|
|
|
2861
2920
|
}
|
|
2862
2921
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
2863
2922
|
try {
|
|
2864
|
-
const parsed = JSON.parse(
|
|
2923
|
+
const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
|
|
2865
2924
|
if (isPlainRecord(parsed)) {
|
|
2866
2925
|
return parsed;
|
|
2867
2926
|
}
|
|
@@ -2945,7 +3004,7 @@ function isPlainRecord(candidate) {
|
|
|
2945
3004
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
2946
3005
|
var FILE_TASK_PATTERN = /\.(task\.)?json$/;
|
|
2947
3006
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2948
|
-
const configPath = options.configPath ??
|
|
3007
|
+
const configPath = options.configPath ?? resolve15(projectRoot, ".rig", "task-config.json");
|
|
2949
3008
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
2950
3009
|
const spawnFn = options.spawn ?? spawnSync;
|
|
2951
3010
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -3028,10 +3087,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
3028
3087
|
return metadata;
|
|
3029
3088
|
}
|
|
3030
3089
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
3031
|
-
const jsonPath =
|
|
3032
|
-
if (
|
|
3090
|
+
const jsonPath = resolve15(projectRoot, "rig.config.json");
|
|
3091
|
+
if (existsSync16(jsonPath)) {
|
|
3033
3092
|
try {
|
|
3034
|
-
const parsed = JSON.parse(
|
|
3093
|
+
const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
|
|
3035
3094
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
3036
3095
|
const source = parsed.taskSource;
|
|
3037
3096
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -3040,12 +3099,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
3040
3099
|
return null;
|
|
3041
3100
|
}
|
|
3042
3101
|
}
|
|
3043
|
-
const tsPath =
|
|
3044
|
-
if (!
|
|
3102
|
+
const tsPath = resolve15(projectRoot, "rig.config.ts");
|
|
3103
|
+
if (!existsSync16(tsPath)) {
|
|
3045
3104
|
return null;
|
|
3046
3105
|
}
|
|
3047
3106
|
try {
|
|
3048
|
-
const source =
|
|
3107
|
+
const source = readFileSync8(tsPath, "utf8");
|
|
3049
3108
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3050
3109
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3051
3110
|
if (kind !== "files") {
|
|
@@ -3065,10 +3124,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
3065
3124
|
return isPlainRecord2(entry) ? entry : null;
|
|
3066
3125
|
}
|
|
3067
3126
|
function readRawTaskConfig(configPath) {
|
|
3068
|
-
if (!
|
|
3127
|
+
if (!existsSync16(configPath)) {
|
|
3069
3128
|
return null;
|
|
3070
3129
|
}
|
|
3071
|
-
const parsed = JSON.parse(
|
|
3130
|
+
const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
|
|
3072
3131
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
3073
3132
|
}
|
|
3074
3133
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -3076,8 +3135,8 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
3076
3135
|
return tasks;
|
|
3077
3136
|
}
|
|
3078
3137
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
3079
|
-
const directory =
|
|
3080
|
-
if (!
|
|
3138
|
+
const directory = resolve15(projectRoot, sourcePath);
|
|
3139
|
+
if (!existsSync16(directory)) {
|
|
3081
3140
|
return [];
|
|
3082
3141
|
}
|
|
3083
3142
|
const tasks = [];
|
|
@@ -3092,11 +3151,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
3092
3151
|
return tasks;
|
|
3093
3152
|
}
|
|
3094
3153
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
3095
|
-
const file = findFileBackedTaskFile(
|
|
3154
|
+
const file = findFileBackedTaskFile(resolve15(projectRoot, sourcePath), taskId);
|
|
3096
3155
|
if (!file) {
|
|
3097
3156
|
return null;
|
|
3098
3157
|
}
|
|
3099
|
-
const raw = JSON.parse(
|
|
3158
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
3100
3159
|
if (!isPlainRecord2(raw)) {
|
|
3101
3160
|
return null;
|
|
3102
3161
|
}
|
|
@@ -3109,7 +3168,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
3109
3168
|
};
|
|
3110
3169
|
}
|
|
3111
3170
|
function findFileBackedTaskFile(directory, taskId) {
|
|
3112
|
-
if (!
|
|
3171
|
+
if (!existsSync16(directory)) {
|
|
3113
3172
|
return null;
|
|
3114
3173
|
}
|
|
3115
3174
|
for (const name of readdirSync2(directory)) {
|
|
@@ -3119,7 +3178,7 @@ function findFileBackedTaskFile(directory, taskId) {
|
|
|
3119
3178
|
try {
|
|
3120
3179
|
if (!statSync3(file).isFile())
|
|
3121
3180
|
continue;
|
|
3122
|
-
const raw = JSON.parse(
|
|
3181
|
+
const raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
3123
3182
|
const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
|
|
3124
3183
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
3125
3184
|
if (id === taskId) {
|
|
@@ -3279,8 +3338,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
|
|
|
3279
3338
|
}
|
|
3280
3339
|
|
|
3281
3340
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
3282
|
-
import { existsSync as
|
|
3283
|
-
import { basename as basename6, resolve as
|
|
3341
|
+
import { existsSync as existsSync20, readFileSync as readFileSync10, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
|
|
3342
|
+
import { basename as basename6, resolve as resolve19 } from "path";
|
|
3284
3343
|
|
|
3285
3344
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
3286
3345
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -3388,39 +3447,39 @@ function readTaskStateMetadataEnvelope(raw) {
|
|
|
3388
3447
|
};
|
|
3389
3448
|
}
|
|
3390
3449
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
3391
|
-
import { existsSync as
|
|
3392
|
-
import { resolve as
|
|
3450
|
+
import { existsSync as existsSync19, readFileSync as readFileSync9 } from "fs";
|
|
3451
|
+
import { resolve as resolve18 } from "path";
|
|
3393
3452
|
|
|
3394
3453
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
3395
|
-
import { existsSync as
|
|
3396
|
-
import { resolve as
|
|
3454
|
+
import { existsSync as existsSync18 } from "fs";
|
|
3455
|
+
import { resolve as resolve17 } from "path";
|
|
3397
3456
|
|
|
3398
3457
|
// packages/runtime/src/control-plane/repos/layout.ts
|
|
3399
3458
|
init_layout();
|
|
3400
|
-
import { existsSync as
|
|
3401
|
-
import { basename as basename5, dirname as
|
|
3459
|
+
import { existsSync as existsSync17 } from "fs";
|
|
3460
|
+
import { basename as basename5, dirname as dirname10, join as join4, resolve as resolve16 } from "path";
|
|
3402
3461
|
function resolveRepoStateDir(projectRoot) {
|
|
3403
|
-
const normalizedProjectRoot =
|
|
3404
|
-
const projectParent =
|
|
3462
|
+
const normalizedProjectRoot = resolve16(projectRoot);
|
|
3463
|
+
const projectParent = dirname10(normalizedProjectRoot);
|
|
3405
3464
|
if (basename5(projectParent) === ".worktrees") {
|
|
3406
|
-
const ownerRoot =
|
|
3407
|
-
const ownerHasRepoMarkers =
|
|
3465
|
+
const ownerRoot = dirname10(projectParent);
|
|
3466
|
+
const ownerHasRepoMarkers = existsSync17(resolve16(ownerRoot, ".git")) || existsSync17(resolve16(ownerRoot, ".rig", "state"));
|
|
3408
3467
|
if (ownerHasRepoMarkers) {
|
|
3409
|
-
return
|
|
3468
|
+
return resolve16(ownerRoot, ".rig", "state");
|
|
3410
3469
|
}
|
|
3411
3470
|
}
|
|
3412
|
-
return
|
|
3471
|
+
return resolve16(projectRoot, ".rig", "state");
|
|
3413
3472
|
}
|
|
3414
3473
|
function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
3415
|
-
const normalizedProjectRoot =
|
|
3474
|
+
const normalizedProjectRoot = resolve16(projectRoot);
|
|
3416
3475
|
const entry = getManagedRepoEntry(repoId);
|
|
3417
3476
|
const stateDir = resolveRepoStateDir(normalizedProjectRoot);
|
|
3418
3477
|
const metadataRelativePath = join4("repos", entry.id);
|
|
3419
|
-
const metadataRoot =
|
|
3478
|
+
const metadataRoot = resolve16(stateDir, metadataRelativePath);
|
|
3420
3479
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3421
|
-
const runsInsideTaskWorktree = runtimeWorkspace &&
|
|
3480
|
+
const runsInsideTaskWorktree = runtimeWorkspace && resolve16(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname10(normalizedProjectRoot)) === ".worktrees";
|
|
3422
3481
|
const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
|
|
3423
|
-
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ?
|
|
3482
|
+
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve16(process.env[entry.checkoutEnvVar].trim()) : resolve16(normalizedProjectRoot, entry.alias);
|
|
3424
3483
|
return {
|
|
3425
3484
|
projectRoot: normalizedProjectRoot,
|
|
3426
3485
|
repoId: entry.id,
|
|
@@ -3428,12 +3487,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
|
3428
3487
|
defaultBranch: entry.defaultBranch,
|
|
3429
3488
|
remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
|
|
3430
3489
|
checkoutRoot,
|
|
3431
|
-
worktreesRoot:
|
|
3490
|
+
worktreesRoot: resolve16(checkoutRoot, ".worktrees"),
|
|
3432
3491
|
stateDir,
|
|
3433
3492
|
metadataRoot,
|
|
3434
3493
|
metadataRelativePath,
|
|
3435
|
-
mirrorRoot:
|
|
3436
|
-
mirrorStatePath:
|
|
3494
|
+
mirrorRoot: resolve16(metadataRoot, "mirror.git"),
|
|
3495
|
+
mirrorStatePath: resolve16(metadataRoot, "mirror-state.json"),
|
|
3437
3496
|
mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
|
|
3438
3497
|
};
|
|
3439
3498
|
}
|
|
@@ -3451,7 +3510,7 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3451
3510
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3452
3511
|
try {
|
|
3453
3512
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
3454
|
-
if (
|
|
3513
|
+
if (existsSync18(resolve17(layout.mirrorRoot, "HEAD"))) {
|
|
3455
3514
|
return layout.mirrorRoot;
|
|
3456
3515
|
}
|
|
3457
3516
|
} catch {}
|
|
@@ -3462,8 +3521,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3462
3521
|
var DEFAULT_READ_DEPS2 = {
|
|
3463
3522
|
fetchRef: nativeFetchRef,
|
|
3464
3523
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
3465
|
-
exists:
|
|
3466
|
-
readFile: (path) =>
|
|
3524
|
+
exists: existsSync19,
|
|
3525
|
+
readFile: (path) => readFileSync9(path, "utf8")
|
|
3467
3526
|
};
|
|
3468
3527
|
function parseIssueStatus(rawStatus) {
|
|
3469
3528
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -3544,12 +3603,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
3544
3603
|
if (runtimeContextPath) {
|
|
3545
3604
|
return true;
|
|
3546
3605
|
}
|
|
3547
|
-
return
|
|
3606
|
+
return existsSync19(resolve18(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
3548
3607
|
}
|
|
3549
3608
|
function readLocalTrackerState(projectRoot, deps) {
|
|
3550
3609
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3551
|
-
const issuesPath =
|
|
3552
|
-
const taskStatePath =
|
|
3610
|
+
const issuesPath = resolve18(monorepoRoot, ".beads", "issues.jsonl");
|
|
3611
|
+
const taskStatePath = resolve18(monorepoRoot, ".beads", "task-state.json");
|
|
3553
3612
|
return projectSyncedTrackerSnapshot({
|
|
3554
3613
|
source: "local",
|
|
3555
3614
|
issuesBaseOid: null,
|
|
@@ -3611,7 +3670,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
3611
3670
|
return readValidationDescriptionMap(raw);
|
|
3612
3671
|
}
|
|
3613
3672
|
function readSourceValidationDescriptions(projectRoot) {
|
|
3614
|
-
const rootRaw = readJsonFile(
|
|
3673
|
+
const rootRaw = readJsonFile(resolve19(projectRoot, "rig", "task-config.json"), {});
|
|
3615
3674
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
3616
3675
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
3617
3676
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -3687,15 +3746,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
3687
3746
|
return meta.validation_descriptions;
|
|
3688
3747
|
}
|
|
3689
3748
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
3690
|
-
const taskStatePath =
|
|
3749
|
+
const taskStatePath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
3691
3750
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
3692
3751
|
}
|
|
3693
3752
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
3694
|
-
const issuesPath =
|
|
3695
|
-
if (!
|
|
3753
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3754
|
+
if (!existsSync20(issuesPath)) {
|
|
3696
3755
|
return null;
|
|
3697
3756
|
}
|
|
3698
|
-
for (const line of
|
|
3757
|
+
for (const line of readFileSync10(issuesPath, "utf8").split(/\r?\n/)) {
|
|
3699
3758
|
const trimmed = line.trim();
|
|
3700
3759
|
if (!trimmed) {
|
|
3701
3760
|
continue;
|
|
@@ -3720,25 +3779,25 @@ function inferTaskIdFromRuntimePath(path) {
|
|
|
3720
3779
|
function artifactDirForId(projectRoot, id) {
|
|
3721
3780
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3722
3781
|
if (workspaceDir) {
|
|
3723
|
-
const worktreeArtifacts =
|
|
3724
|
-
if (
|
|
3782
|
+
const worktreeArtifacts = resolve19(workspaceDir, "artifacts", id);
|
|
3783
|
+
if (existsSync20(worktreeArtifacts) || existsSync20(resolve19(workspaceDir, "artifacts"))) {
|
|
3725
3784
|
return worktreeArtifacts;
|
|
3726
3785
|
}
|
|
3727
3786
|
}
|
|
3728
3787
|
try {
|
|
3729
3788
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3730
|
-
return
|
|
3789
|
+
return resolve19(paths.artifactsDir, id);
|
|
3731
3790
|
} catch {
|
|
3732
|
-
return
|
|
3791
|
+
return resolve19(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
3733
3792
|
}
|
|
3734
3793
|
}
|
|
3735
3794
|
function resolveTaskConfigPath(projectRoot) {
|
|
3736
3795
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3737
|
-
if (
|
|
3796
|
+
if (existsSync20(paths.taskConfigPath)) {
|
|
3738
3797
|
return paths.taskConfigPath;
|
|
3739
3798
|
}
|
|
3740
3799
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3741
|
-
if (
|
|
3800
|
+
if (existsSync20(candidate)) {
|
|
3742
3801
|
return candidate;
|
|
3743
3802
|
}
|
|
3744
3803
|
}
|
|
@@ -3746,7 +3805,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
3746
3805
|
}
|
|
3747
3806
|
function findSourceTaskConfigPath(projectRoot) {
|
|
3748
3807
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3749
|
-
if (
|
|
3808
|
+
if (existsSync20(candidate)) {
|
|
3750
3809
|
return candidate;
|
|
3751
3810
|
}
|
|
3752
3811
|
}
|
|
@@ -3759,7 +3818,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
3759
3818
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
3760
3819
|
if (sourcePath && synced.updated) {
|
|
3761
3820
|
try {
|
|
3762
|
-
|
|
3821
|
+
writeFileSync8(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
3763
3822
|
`, "utf-8");
|
|
3764
3823
|
} catch {}
|
|
3765
3824
|
}
|
|
@@ -3811,12 +3870,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
3811
3870
|
return !candidate.role;
|
|
3812
3871
|
}
|
|
3813
3872
|
function readSourceIssueRecords(projectRoot) {
|
|
3814
|
-
const issuesPath =
|
|
3815
|
-
if (!
|
|
3873
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3874
|
+
if (!existsSync20(issuesPath)) {
|
|
3816
3875
|
return [];
|
|
3817
3876
|
}
|
|
3818
3877
|
const records = [];
|
|
3819
|
-
for (const line of
|
|
3878
|
+
for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
3820
3879
|
const trimmed = line.trim();
|
|
3821
3880
|
if (!trimmed) {
|
|
3822
3881
|
continue;
|
|
@@ -3872,19 +3931,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
3872
3931
|
if (!sourcePath) {
|
|
3873
3932
|
return {};
|
|
3874
3933
|
}
|
|
3875
|
-
const directory =
|
|
3876
|
-
if (!
|
|
3934
|
+
const directory = resolve19(projectRoot, sourcePath);
|
|
3935
|
+
if (!existsSync20(directory)) {
|
|
3877
3936
|
return {};
|
|
3878
3937
|
}
|
|
3879
3938
|
const config = {};
|
|
3880
3939
|
for (const name of readdirSync3(directory)) {
|
|
3881
3940
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
3882
3941
|
continue;
|
|
3883
|
-
const file =
|
|
3942
|
+
const file = resolve19(directory, name);
|
|
3884
3943
|
try {
|
|
3885
3944
|
if (!statSync4(file).isFile())
|
|
3886
3945
|
continue;
|
|
3887
|
-
const raw = JSON.parse(
|
|
3946
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
3888
3947
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
3889
3948
|
continue;
|
|
3890
3949
|
const record = raw;
|
|
@@ -3926,10 +3985,10 @@ function firstStringList2(...candidates) {
|
|
|
3926
3985
|
return [];
|
|
3927
3986
|
}
|
|
3928
3987
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
3929
|
-
const jsonPath =
|
|
3930
|
-
if (
|
|
3988
|
+
const jsonPath = resolve19(projectRoot, "rig.config.json");
|
|
3989
|
+
if (existsSync20(jsonPath)) {
|
|
3931
3990
|
try {
|
|
3932
|
-
const parsed = JSON.parse(
|
|
3991
|
+
const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
|
|
3933
3992
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3934
3993
|
const taskSource = parsed.taskSource;
|
|
3935
3994
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -3941,12 +4000,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3941
4000
|
return null;
|
|
3942
4001
|
}
|
|
3943
4002
|
}
|
|
3944
|
-
const tsPath =
|
|
3945
|
-
if (!
|
|
4003
|
+
const tsPath = resolve19(projectRoot, "rig.config.ts");
|
|
4004
|
+
if (!existsSync20(tsPath)) {
|
|
3946
4005
|
return null;
|
|
3947
4006
|
}
|
|
3948
4007
|
try {
|
|
3949
|
-
const source =
|
|
4008
|
+
const source = readFileSync10(tsPath, "utf8");
|
|
3950
4009
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3951
4010
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3952
4011
|
if (kind !== "files") {
|
|
@@ -3960,9 +4019,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3960
4019
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
3961
4020
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
3962
4021
|
return [
|
|
3963
|
-
runtimeContext?.monorepoMainRoot ?
|
|
3964
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
3965
|
-
|
|
4022
|
+
runtimeContext?.monorepoMainRoot ? resolve19(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
4023
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve19(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
4024
|
+
resolve19(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
3966
4025
|
].filter(Boolean);
|
|
3967
4026
|
}
|
|
3968
4027
|
|
|
@@ -3971,8 +4030,8 @@ init_layout();
|
|
|
3971
4030
|
|
|
3972
4031
|
// packages/runtime/src/binary-run.ts
|
|
3973
4032
|
init_layout();
|
|
3974
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
3975
|
-
import { basename as basename7, dirname as
|
|
4033
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync21, mkdirSync as mkdirSync10, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
4034
|
+
import { basename as basename7, dirname as dirname11, resolve as resolve20 } from "path";
|
|
3976
4035
|
import { fileURLToPath } from "url";
|
|
3977
4036
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
3978
4037
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -3998,9 +4057,9 @@ async function buildRuntimeBinary(options) {
|
|
|
3998
4057
|
});
|
|
3999
4058
|
}
|
|
4000
4059
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
4001
|
-
const tempBuildDir =
|
|
4002
|
-
const tempOutputPath =
|
|
4003
|
-
|
|
4060
|
+
const tempBuildDir = resolve20(dirname11(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4061
|
+
const tempOutputPath = resolve20(tempBuildDir, basename7(options.outputPath));
|
|
4062
|
+
mkdirSync10(tempBuildDir, { recursive: true });
|
|
4004
4063
|
await withTemporaryEnv({
|
|
4005
4064
|
...options.env,
|
|
4006
4065
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -4025,7 +4084,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4025
4084
|
`);
|
|
4026
4085
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
4027
4086
|
}
|
|
4028
|
-
if (!
|
|
4087
|
+
if (!existsSync21(tempOutputPath)) {
|
|
4029
4088
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
4030
4089
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
4031
4090
|
}
|
|
@@ -4057,8 +4116,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4057
4116
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4058
4117
|
return {
|
|
4059
4118
|
...options,
|
|
4060
|
-
entrypoint:
|
|
4061
|
-
outputPath:
|
|
4119
|
+
entrypoint: resolve20(options.cwd, options.sourcePath),
|
|
4120
|
+
outputPath: resolve20(options.outputPath)
|
|
4062
4121
|
};
|
|
4063
4122
|
}
|
|
4064
4123
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4072,7 +4131,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4072
4131
|
}
|
|
4073
4132
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4074
4133
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4075
|
-
if (!workerSourcePath || !
|
|
4134
|
+
if (!workerSourcePath || !existsSync21(workerSourcePath)) {
|
|
4076
4135
|
await buildRuntimeBinaryInProcess(options, {
|
|
4077
4136
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4078
4137
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4109,7 +4168,7 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4109
4168
|
}
|
|
4110
4169
|
}
|
|
4111
4170
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4112
|
-
return
|
|
4171
|
+
return resolve20(dirname11(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4113
4172
|
}
|
|
4114
4173
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4115
4174
|
const envRoots = [
|
|
@@ -4118,13 +4177,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4118
4177
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4119
4178
|
].filter(Boolean);
|
|
4120
4179
|
for (const root of envRoots) {
|
|
4121
|
-
const candidate =
|
|
4122
|
-
if (
|
|
4180
|
+
const candidate = resolve20(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4181
|
+
if (existsSync21(candidate)) {
|
|
4123
4182
|
return candidate;
|
|
4124
4183
|
}
|
|
4125
4184
|
}
|
|
4126
|
-
const localCandidate =
|
|
4127
|
-
return
|
|
4185
|
+
const localCandidate = resolve20(import.meta.dir, "binary-build-worker.ts");
|
|
4186
|
+
return existsSync21(localCandidate) ? localCandidate : null;
|
|
4128
4187
|
}
|
|
4129
4188
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4130
4189
|
const bunPath = Bun.which("bun");
|
|
@@ -4160,7 +4219,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4160
4219
|
});
|
|
4161
4220
|
}
|
|
4162
4221
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4163
|
-
if (!
|
|
4222
|
+
if (!existsSync21(input.outputPath) || !existsSync21(input.manifestPath)) {
|
|
4164
4223
|
return false;
|
|
4165
4224
|
}
|
|
4166
4225
|
let manifest = null;
|
|
@@ -4173,7 +4232,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4173
4232
|
return false;
|
|
4174
4233
|
}
|
|
4175
4234
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4176
|
-
if (!
|
|
4235
|
+
if (!existsSync21(filePath)) {
|
|
4177
4236
|
return false;
|
|
4178
4237
|
}
|
|
4179
4238
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4186,7 +4245,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4186
4245
|
const inputs = {};
|
|
4187
4246
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4188
4247
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4189
|
-
if (!normalized || !
|
|
4248
|
+
if (!normalized || !existsSync21(normalized)) {
|
|
4190
4249
|
continue;
|
|
4191
4250
|
}
|
|
4192
4251
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4209,7 +4268,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4209
4268
|
if (inputPath.startsWith("<")) {
|
|
4210
4269
|
return null;
|
|
4211
4270
|
}
|
|
4212
|
-
return
|
|
4271
|
+
return resolve20(cwd, inputPath);
|
|
4213
4272
|
}
|
|
4214
4273
|
async function sha256File4(path) {
|
|
4215
4274
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4225,8 +4284,8 @@ function sortRecord(value) {
|
|
|
4225
4284
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4226
4285
|
const previous = runtimeBinaryBuildQueue;
|
|
4227
4286
|
let release;
|
|
4228
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4229
|
-
release =
|
|
4287
|
+
runtimeBinaryBuildQueue = new Promise((resolve21) => {
|
|
4288
|
+
release = resolve21;
|
|
4230
4289
|
});
|
|
4231
4290
|
await previous;
|
|
4232
4291
|
try {
|
|
@@ -4271,11 +4330,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4271
4330
|
}
|
|
4272
4331
|
|
|
4273
4332
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4274
|
-
import { delimiter, resolve as
|
|
4333
|
+
import { delimiter, resolve as resolve23 } from "path";
|
|
4275
4334
|
|
|
4276
4335
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
4277
|
-
import { existsSync as
|
|
4278
|
-
import { resolve as
|
|
4336
|
+
import { existsSync as existsSync23, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
4337
|
+
import { resolve as resolve22 } from "path";
|
|
4279
4338
|
|
|
4280
4339
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
4281
4340
|
init_utils();
|
|
@@ -4292,7 +4351,7 @@ function resolveBunBinaryPath() {
|
|
|
4292
4351
|
}
|
|
4293
4352
|
const home = process.env.HOME?.trim();
|
|
4294
4353
|
const fallbackCandidates = [
|
|
4295
|
-
home ?
|
|
4354
|
+
home ? resolve22(home, ".bun/bin/bun") : "",
|
|
4296
4355
|
"/opt/homebrew/bin/bun",
|
|
4297
4356
|
"/usr/local/bin/bun",
|
|
4298
4357
|
"/usr/bin/bun"
|
|
@@ -4320,8 +4379,8 @@ function resolveClaudeBinaryPath() {
|
|
|
4320
4379
|
}
|
|
4321
4380
|
const home = process.env.HOME?.trim();
|
|
4322
4381
|
const fallbackCandidates = [
|
|
4323
|
-
home ?
|
|
4324
|
-
home ?
|
|
4382
|
+
home ? resolve22(home, ".local/bin/claude") : "",
|
|
4383
|
+
home ? resolve22(home, ".local/share/claude/local/claude") : "",
|
|
4325
4384
|
"/opt/homebrew/bin/claude",
|
|
4326
4385
|
"/usr/local/bin/claude",
|
|
4327
4386
|
"/usr/bin/claude"
|
|
@@ -4335,35 +4394,35 @@ function resolveClaudeBinaryPath() {
|
|
|
4335
4394
|
throw new Error("claude not found in PATH");
|
|
4336
4395
|
}
|
|
4337
4396
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
4338
|
-
return
|
|
4397
|
+
return resolve22(bunBinaryPath, "../..");
|
|
4339
4398
|
}
|
|
4340
4399
|
function resolveClaudeInstallDir() {
|
|
4341
4400
|
const realPath = resolveClaudeBinaryPath();
|
|
4342
|
-
return
|
|
4401
|
+
return resolve22(realPath, "..");
|
|
4343
4402
|
}
|
|
4344
4403
|
function resolveNodeInstallDir() {
|
|
4345
4404
|
const preferredNode = resolvePreferredNodeBinary();
|
|
4346
4405
|
if (!preferredNode)
|
|
4347
4406
|
return null;
|
|
4348
4407
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
4349
|
-
if (explicitNode &&
|
|
4350
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
4408
|
+
if (explicitNode && resolve22(explicitNode) === resolve22(preferredNode)) {
|
|
4409
|
+
return preferredNode.endsWith("/bin/node") ? resolve22(preferredNode, "../..") : resolve22(preferredNode, "..");
|
|
4351
4410
|
}
|
|
4352
4411
|
try {
|
|
4353
4412
|
const realPath = realpathSync2(preferredNode);
|
|
4354
4413
|
if (realPath.endsWith("/bin/node")) {
|
|
4355
|
-
return
|
|
4414
|
+
return resolve22(realPath, "../..");
|
|
4356
4415
|
}
|
|
4357
|
-
return
|
|
4416
|
+
return resolve22(realPath, "..");
|
|
4358
4417
|
} catch {
|
|
4359
|
-
return
|
|
4418
|
+
return resolve22(preferredNode, "..");
|
|
4360
4419
|
}
|
|
4361
4420
|
}
|
|
4362
4421
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
4363
4422
|
const roots = [];
|
|
4364
4423
|
if (process.platform === "darwin") {
|
|
4365
4424
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
4366
|
-
if (
|
|
4425
|
+
if (existsSync23(macPath)) {
|
|
4367
4426
|
roots.push(macPath);
|
|
4368
4427
|
}
|
|
4369
4428
|
}
|
|
@@ -4381,23 +4440,23 @@ function resolvePreferredNodeBinary() {
|
|
|
4381
4440
|
const candidates = [];
|
|
4382
4441
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
4383
4442
|
if (envNode) {
|
|
4384
|
-
const explicit =
|
|
4385
|
-
if (
|
|
4443
|
+
const explicit = resolve22(envNode);
|
|
4444
|
+
if (existsSync23(explicit)) {
|
|
4386
4445
|
return explicit;
|
|
4387
4446
|
}
|
|
4388
4447
|
}
|
|
4389
4448
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
4390
4449
|
if (nvmBin) {
|
|
4391
|
-
candidates.push(
|
|
4450
|
+
candidates.push(resolve22(nvmBin, "node"));
|
|
4392
4451
|
}
|
|
4393
4452
|
const home = process.env.HOME?.trim();
|
|
4394
4453
|
if (home) {
|
|
4395
|
-
const nvmVersionsDir =
|
|
4396
|
-
if (
|
|
4454
|
+
const nvmVersionsDir = resolve22(home, ".nvm/versions/node");
|
|
4455
|
+
if (existsSync23(nvmVersionsDir)) {
|
|
4397
4456
|
try {
|
|
4398
4457
|
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/, "")));
|
|
4399
4458
|
for (const versionDir of versionDirs) {
|
|
4400
|
-
candidates.push(
|
|
4459
|
+
candidates.push(resolve22(nvmVersionsDir, versionDir, "bin/node"));
|
|
4401
4460
|
}
|
|
4402
4461
|
} catch {}
|
|
4403
4462
|
}
|
|
@@ -4406,8 +4465,8 @@ function resolvePreferredNodeBinary() {
|
|
|
4406
4465
|
if (whichNode) {
|
|
4407
4466
|
candidates.push(whichNode);
|
|
4408
4467
|
}
|
|
4409
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
4410
|
-
const existing = deduped.filter((candidate) =>
|
|
4468
|
+
const deduped = uniq(candidates.map((candidate) => resolve22(candidate)));
|
|
4469
|
+
const existing = deduped.filter((candidate) => existsSync23(candidate));
|
|
4411
4470
|
if (existing.length === 0) {
|
|
4412
4471
|
return null;
|
|
4413
4472
|
}
|
|
@@ -4421,7 +4480,7 @@ function resolvePreferredNodeBinary() {
|
|
|
4421
4480
|
return existing[0] ?? null;
|
|
4422
4481
|
}
|
|
4423
4482
|
function inferNodeMajor(nodeBinaryPath) {
|
|
4424
|
-
const normalized =
|
|
4483
|
+
const normalized = resolve22(nodeBinaryPath).replace(/\\/g, "/");
|
|
4425
4484
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
4426
4485
|
if (!match) {
|
|
4427
4486
|
return null;
|
|
@@ -4433,8 +4492,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
4433
4492
|
if (!candidate) {
|
|
4434
4493
|
return "";
|
|
4435
4494
|
}
|
|
4436
|
-
const normalized =
|
|
4437
|
-
if (!
|
|
4495
|
+
const normalized = resolve22(candidate);
|
|
4496
|
+
if (!existsSync23(normalized)) {
|
|
4438
4497
|
return "";
|
|
4439
4498
|
}
|
|
4440
4499
|
try {
|
|
@@ -4444,7 +4503,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
4444
4503
|
}
|
|
4445
4504
|
}
|
|
4446
4505
|
function looksLikeRuntimeGateway(candidate) {
|
|
4447
|
-
const normalized =
|
|
4506
|
+
const normalized = resolve22(candidate).replace(/\\/g, "/");
|
|
4448
4507
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
4449
4508
|
}
|
|
4450
4509
|
|
|
@@ -4465,7 +4524,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4465
4524
|
try {
|
|
4466
4525
|
return resolveClaudeInstallDir();
|
|
4467
4526
|
} catch {
|
|
4468
|
-
return
|
|
4527
|
+
return resolve23(claudeBinary, "..");
|
|
4469
4528
|
}
|
|
4470
4529
|
})() : "";
|
|
4471
4530
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -4475,8 +4534,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4475
4534
|
`${bunDir}/bin`,
|
|
4476
4535
|
claudeDir,
|
|
4477
4536
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
4478
|
-
realHome ?
|
|
4479
|
-
realHome ?
|
|
4537
|
+
realHome ? resolve23(realHome, ".local/bin") : "",
|
|
4538
|
+
realHome ? resolve23(realHome, ".cargo/bin") : "",
|
|
4480
4539
|
...inheritedPath,
|
|
4481
4540
|
"/usr/local/bin",
|
|
4482
4541
|
"/usr/local/sbin",
|
|
@@ -4505,8 +4564,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4505
4564
|
}
|
|
4506
4565
|
|
|
4507
4566
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
4508
|
-
import { existsSync as
|
|
4509
|
-
import { resolve as
|
|
4567
|
+
import { existsSync as existsSync24, readFileSync as readFileSync11 } from "fs";
|
|
4568
|
+
import { resolve as resolve24 } from "path";
|
|
4510
4569
|
var BAKED_RUNTIME_SECRETS = {
|
|
4511
4570
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
4512
4571
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -4549,12 +4608,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
4549
4608
|
return resolved;
|
|
4550
4609
|
}
|
|
4551
4610
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
4552
|
-
const dotenvPath =
|
|
4553
|
-
if (!
|
|
4611
|
+
const dotenvPath = resolve24(projectRoot, ".env");
|
|
4612
|
+
if (!existsSync24(dotenvPath)) {
|
|
4554
4613
|
return {};
|
|
4555
4614
|
}
|
|
4556
4615
|
const parsed = {};
|
|
4557
|
-
const lines =
|
|
4616
|
+
const lines = readFileSync11(dotenvPath, "utf-8").split(/\r?\n/);
|
|
4558
4617
|
for (const rawLine of lines) {
|
|
4559
4618
|
const line = rawLine.trim();
|
|
4560
4619
|
if (!line || line.startsWith("#")) {
|
|
@@ -4911,16 +4970,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
4911
4970
|
for (const dep of deps) {
|
|
4912
4971
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
4913
4972
|
console.log(`=== ${dep} ===`);
|
|
4914
|
-
if (!
|
|
4973
|
+
if (!existsSync25(artifactDir)) {
|
|
4915
4974
|
console.log(` (no artifacts yet)
|
|
4916
4975
|
`);
|
|
4917
4976
|
continue;
|
|
4918
4977
|
}
|
|
4919
|
-
printArtifactSection(
|
|
4920
|
-
printArtifactSection(
|
|
4921
|
-
const changedFiles =
|
|
4922
|
-
if (
|
|
4923
|
-
const lines =
|
|
4978
|
+
printArtifactSection(resolve25(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
4979
|
+
printArtifactSection(resolve25(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
4980
|
+
const changedFiles = resolve25(artifactDir, "changed-files.txt");
|
|
4981
|
+
if (existsSync25(changedFiles)) {
|
|
4982
|
+
const lines = readFileSync12(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
4924
4983
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
4925
4984
|
for (const line of lines) {
|
|
4926
4985
|
console.log(line);
|
|
@@ -5044,12 +5103,12 @@ function printIndented(text) {
|
|
|
5044
5103
|
}
|
|
5045
5104
|
}
|
|
5046
5105
|
function readLocalBeadsTasks(projectRoot) {
|
|
5047
|
-
const issuesPath =
|
|
5048
|
-
if (!
|
|
5106
|
+
const issuesPath = resolve25(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5107
|
+
if (!existsSync25(issuesPath)) {
|
|
5049
5108
|
return [];
|
|
5050
5109
|
}
|
|
5051
5110
|
const tasks = [];
|
|
5052
|
-
for (const line of
|
|
5111
|
+
for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
5053
5112
|
const trimmed = line.trim();
|
|
5054
5113
|
if (!trimmed) {
|
|
5055
5114
|
continue;
|
|
@@ -5162,11 +5221,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5162
5221
|
return [...ids].sort();
|
|
5163
5222
|
}
|
|
5164
5223
|
function printArtifactSection(path, header) {
|
|
5165
|
-
if (!
|
|
5224
|
+
if (!existsSync25(path)) {
|
|
5166
5225
|
return;
|
|
5167
5226
|
}
|
|
5168
5227
|
console.log(header);
|
|
5169
|
-
process.stdout.write(
|
|
5228
|
+
process.stdout.write(readFileSync12(path, "utf-8"));
|
|
5170
5229
|
console.log("");
|
|
5171
5230
|
}
|
|
5172
5231
|
|
|
@@ -5268,7 +5327,7 @@ init_layout();
|
|
|
5268
5327
|
|
|
5269
5328
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5270
5329
|
init_layout();
|
|
5271
|
-
import { mkdirSync as
|
|
5330
|
+
import { mkdirSync as mkdirSync12 } from "fs";
|
|
5272
5331
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5273
5332
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5274
5333
|
const rootDir = layout.rigRoot;
|
|
@@ -5280,14 +5339,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5280
5339
|
const sessionDir = layout.sessionDir;
|
|
5281
5340
|
const runtimeDir = layout.runtimeDir;
|
|
5282
5341
|
const contextPath = layout.contextPath;
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5342
|
+
mkdirSync12(rootDir, { recursive: true });
|
|
5343
|
+
mkdirSync12(homeDir, { recursive: true });
|
|
5344
|
+
mkdirSync12(tmpDir, { recursive: true });
|
|
5345
|
+
mkdirSync12(cacheDir, { recursive: true });
|
|
5346
|
+
mkdirSync12(logsDir, { recursive: true });
|
|
5347
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
5348
|
+
mkdirSync12(sessionDir, { recursive: true });
|
|
5349
|
+
mkdirSync12(runtimeDir, { recursive: true });
|
|
5291
5350
|
return {
|
|
5292
5351
|
rootDir,
|
|
5293
5352
|
homeDir,
|
|
@@ -5305,17 +5364,17 @@ import {
|
|
|
5305
5364
|
chmodSync as chmodSync5,
|
|
5306
5365
|
copyFileSync as copyFileSync5,
|
|
5307
5366
|
cpSync as cpSync2,
|
|
5308
|
-
existsSync as
|
|
5309
|
-
mkdirSync as
|
|
5367
|
+
existsSync as existsSync27,
|
|
5368
|
+
mkdirSync as mkdirSync13,
|
|
5310
5369
|
statSync as statSync5,
|
|
5311
|
-
writeFileSync as
|
|
5370
|
+
writeFileSync as writeFileSync11
|
|
5312
5371
|
} from "fs";
|
|
5313
5372
|
import { mkdir } from "fs/promises";
|
|
5314
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
5373
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve27 } from "path";
|
|
5315
5374
|
|
|
5316
5375
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
5317
|
-
import { existsSync as
|
|
5318
|
-
import { resolve as
|
|
5376
|
+
import { existsSync as existsSync26, readFileSync as readFileSync13, rmSync as rmSync9 } from "fs";
|
|
5377
|
+
import { resolve as resolve26 } from "path";
|
|
5319
5378
|
import { randomUUID } from "crypto";
|
|
5320
5379
|
var generatedCredentialFiles = new Set;
|
|
5321
5380
|
var credentialCleanupRegistered = false;
|
|
@@ -5340,7 +5399,7 @@ function resolveHostGitBinary() {
|
|
|
5340
5399
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
5341
5400
|
continue;
|
|
5342
5401
|
}
|
|
5343
|
-
if (
|
|
5402
|
+
if (existsSync26(candidate)) {
|
|
5344
5403
|
return candidate;
|
|
5345
5404
|
}
|
|
5346
5405
|
}
|
|
@@ -5406,7 +5465,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
5406
5465
|
}
|
|
5407
5466
|
}
|
|
5408
5467
|
async function tryReadGitHead(repoRoot) {
|
|
5409
|
-
if (!
|
|
5468
|
+
if (!existsSync26(resolve26(repoRoot, ".git"))) {
|
|
5410
5469
|
return;
|
|
5411
5470
|
}
|
|
5412
5471
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -5417,7 +5476,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
5417
5476
|
return value || undefined;
|
|
5418
5477
|
}
|
|
5419
5478
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
5420
|
-
if (!
|
|
5479
|
+
if (!existsSync26(resolve26(repoRoot, ".git"))) {
|
|
5421
5480
|
return [];
|
|
5422
5481
|
}
|
|
5423
5482
|
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));
|
|
@@ -5760,30 +5819,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
5760
5819
|
await mkdir(runtime.cacheDir, { recursive: true });
|
|
5761
5820
|
await provisionAgentSshKey(runtime.homeDir);
|
|
5762
5821
|
if (options.provider === "codex") {
|
|
5763
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
5822
|
+
const hasCodexAuth = await injectCodexAuth(resolve27(runtime.homeDir, ".codex"));
|
|
5764
5823
|
if (!hasCodexAuth) {
|
|
5765
5824
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
5766
5825
|
}
|
|
5767
5826
|
}
|
|
5768
5827
|
if (options.provider === "pi") {
|
|
5769
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
5828
|
+
const hasPiAuth = await injectPiAgentConfig(resolve27(runtime.homeDir, ".pi", "agent"));
|
|
5770
5829
|
if (!hasPiAuth) {
|
|
5771
5830
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
5772
5831
|
}
|
|
5773
5832
|
}
|
|
5774
5833
|
}
|
|
5775
5834
|
async function provisionClaudeHome(config) {
|
|
5776
|
-
|
|
5777
|
-
const workspaceSettings =
|
|
5778
|
-
const hostSettings =
|
|
5779
|
-
const projectSettings =
|
|
5835
|
+
mkdirSync13(config.claudeHomeDir, { recursive: true });
|
|
5836
|
+
const workspaceSettings = resolve27(config.workspaceDir, ".claude/settings.json");
|
|
5837
|
+
const hostSettings = resolve27(config.hostProjectRoot, ".claude/settings.json");
|
|
5838
|
+
const projectSettings = existsSync27(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
5780
5839
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
5781
|
-
if (
|
|
5782
|
-
|
|
5840
|
+
if (existsSync27(projectSettings)) {
|
|
5841
|
+
writeFileSync11(resolve27(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5783
5842
|
`, "utf-8");
|
|
5784
5843
|
}
|
|
5785
5844
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
5786
|
-
|
|
5845
|
+
writeFileSync11(resolve27(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
5787
5846
|
permissions: { defaultMode: "bypassPermissions" },
|
|
5788
5847
|
autoMemoryEnabled: false
|
|
5789
5848
|
}, null, 2));
|
|
@@ -5791,12 +5850,12 @@ async function provisionClaudeHome(config) {
|
|
|
5791
5850
|
if (!hasCredentials) {
|
|
5792
5851
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
5793
5852
|
}
|
|
5794
|
-
const realClaudeHome =
|
|
5795
|
-
if (process.env.HOME &&
|
|
5796
|
-
cpSync2(
|
|
5853
|
+
const realClaudeHome = resolve27(process.env.HOME ?? "", ".claude");
|
|
5854
|
+
if (process.env.HOME && existsSync27(resolve27(realClaudeHome, "CLAUDE.md"))) {
|
|
5855
|
+
cpSync2(resolve27(realClaudeHome, "CLAUDE.md"), resolve27(config.claudeHomeDir, "CLAUDE.md"));
|
|
5797
5856
|
}
|
|
5798
|
-
if (process.env.HOME &&
|
|
5799
|
-
cpSync2(
|
|
5857
|
+
if (process.env.HOME && existsSync27(resolve27(realClaudeHome, "agents"))) {
|
|
5858
|
+
cpSync2(resolve27(realClaudeHome, "agents"), resolve27(config.claudeHomeDir, "agents"), { recursive: true });
|
|
5800
5859
|
}
|
|
5801
5860
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
5802
5861
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -5807,10 +5866,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
5807
5866
|
if (!sourcePath) {
|
|
5808
5867
|
return "";
|
|
5809
5868
|
}
|
|
5810
|
-
const certsDir =
|
|
5811
|
-
const targetPath =
|
|
5869
|
+
const certsDir = resolve27(runtime.rootDir, "certs");
|
|
5870
|
+
const targetPath = resolve27(certsDir, "ca-certificates.pem");
|
|
5812
5871
|
await mkdir(certsDir, { recursive: true });
|
|
5813
|
-
let shouldCopy = !
|
|
5872
|
+
let shouldCopy = !existsSync27(targetPath);
|
|
5814
5873
|
if (!shouldCopy) {
|
|
5815
5874
|
try {
|
|
5816
5875
|
shouldCopy = statSync5(sourcePath).mtimeMs > statSync5(targetPath).mtimeMs;
|
|
@@ -5832,7 +5891,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
5832
5891
|
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';
|
|
5833
5892
|
}
|
|
5834
5893
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
5835
|
-
const secretsPath =
|
|
5894
|
+
const secretsPath = resolve27(runtimeRoot, "runtime-secrets.json");
|
|
5836
5895
|
const persisted = {};
|
|
5837
5896
|
for (const key of [
|
|
5838
5897
|
"GITHUB_TOKEN",
|
|
@@ -5851,12 +5910,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
5851
5910
|
if (Object.keys(persisted).length === 0) {
|
|
5852
5911
|
return;
|
|
5853
5912
|
}
|
|
5854
|
-
|
|
5913
|
+
writeFileSync11(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
5855
5914
|
`, "utf-8");
|
|
5856
5915
|
}
|
|
5857
5916
|
async function provisionAgentSshKey(homeDir) {
|
|
5858
|
-
const sshDir =
|
|
5859
|
-
if (!
|
|
5917
|
+
const sshDir = resolve27(homeDir, ".ssh");
|
|
5918
|
+
if (!existsSync27(sshDir)) {
|
|
5860
5919
|
await mkdir(sshDir, { recursive: true });
|
|
5861
5920
|
}
|
|
5862
5921
|
seedKnownHosts(sshDir);
|
|
@@ -5864,27 +5923,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
5864
5923
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
5865
5924
|
if (!privateKey) {
|
|
5866
5925
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
5867
|
-
if (!process.env.HOME || !
|
|
5926
|
+
if (!process.env.HOME || !existsSync27(hostKeyPath)) {
|
|
5868
5927
|
return;
|
|
5869
5928
|
}
|
|
5870
|
-
const agentKeyPath2 =
|
|
5871
|
-
if (!
|
|
5929
|
+
const agentKeyPath2 = resolve27(sshDir, "rig-agent-key");
|
|
5930
|
+
if (!existsSync27(agentKeyPath2)) {
|
|
5872
5931
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
5873
5932
|
chmodSync5(agentKeyPath2, 384);
|
|
5874
5933
|
}
|
|
5875
5934
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
5876
|
-
if (
|
|
5935
|
+
if (existsSync27(hostPubPath)) {
|
|
5877
5936
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
5878
|
-
if (!
|
|
5937
|
+
if (!existsSync27(agentPubPath)) {
|
|
5879
5938
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
5880
5939
|
}
|
|
5881
5940
|
}
|
|
5882
5941
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
5883
5942
|
return;
|
|
5884
5943
|
}
|
|
5885
|
-
const agentKeyPath =
|
|
5886
|
-
if (!
|
|
5887
|
-
|
|
5944
|
+
const agentKeyPath = resolve27(sshDir, "rig-agent-key");
|
|
5945
|
+
if (!existsSync27(agentKeyPath)) {
|
|
5946
|
+
writeFileSync11(agentKeyPath, privateKey, { mode: 384 });
|
|
5888
5947
|
}
|
|
5889
5948
|
writeSshConfig(sshDir, agentKeyPath);
|
|
5890
5949
|
}
|
|
@@ -5901,21 +5960,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
5901
5960
|
`;
|
|
5902
5961
|
}
|
|
5903
5962
|
function resolveHostSshKeyPath(homeDir) {
|
|
5904
|
-
const sshDir =
|
|
5963
|
+
const sshDir = resolve27(homeDir, ".ssh");
|
|
5905
5964
|
const candidates = [
|
|
5906
5965
|
"rig-agent-key",
|
|
5907
5966
|
"id_ed25519",
|
|
5908
5967
|
"id_ecdsa",
|
|
5909
5968
|
"id_rsa"
|
|
5910
|
-
].map((name) =>
|
|
5911
|
-
return candidates.find((candidate) =>
|
|
5969
|
+
].map((name) => resolve27(sshDir, name));
|
|
5970
|
+
return candidates.find((candidate) => existsSync27(candidate)) ?? resolve27(sshDir, "rig-agent-key");
|
|
5912
5971
|
}
|
|
5913
5972
|
function writeSshConfig(sshDir, keyPath) {
|
|
5914
|
-
const configPath =
|
|
5915
|
-
if (
|
|
5973
|
+
const configPath = resolve27(sshDir, "config");
|
|
5974
|
+
if (existsSync27(configPath)) {
|
|
5916
5975
|
return;
|
|
5917
5976
|
}
|
|
5918
|
-
const knownHostsPath =
|
|
5977
|
+
const knownHostsPath = resolve27(sshDir, "known_hosts");
|
|
5919
5978
|
const config = [
|
|
5920
5979
|
"Host github.com",
|
|
5921
5980
|
` IdentityFile ${keyPath}`,
|
|
@@ -5925,10 +5984,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
5925
5984
|
""
|
|
5926
5985
|
].join(`
|
|
5927
5986
|
`);
|
|
5928
|
-
|
|
5987
|
+
writeFileSync11(configPath, config, { mode: 420 });
|
|
5929
5988
|
}
|
|
5930
5989
|
function seedKnownHosts(sshDir) {
|
|
5931
|
-
const knownHostsPath =
|
|
5990
|
+
const knownHostsPath = resolve27(sshDir, "known_hosts");
|
|
5932
5991
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
5933
5992
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
5934
5993
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -5939,23 +5998,23 @@ function seedKnownHosts(sshDir) {
|
|
|
5939
5998
|
for (const line of missing) {
|
|
5940
5999
|
existingLines.add(line);
|
|
5941
6000
|
}
|
|
5942
|
-
|
|
6001
|
+
writeFileSync11(knownHostsPath, `${Array.from(existingLines).join(`
|
|
5943
6002
|
`)}
|
|
5944
6003
|
`, { mode: 420 });
|
|
5945
6004
|
} catch (err) {
|
|
5946
|
-
const hint =
|
|
6005
|
+
const hint = existsSync27(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
5947
6006
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
5948
6007
|
}
|
|
5949
6008
|
}
|
|
5950
6009
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
5951
6010
|
const projectHash = hashProjectPath(workspaceDir);
|
|
5952
|
-
const projectDir =
|
|
5953
|
-
|
|
5954
|
-
|
|
6011
|
+
const projectDir = resolve27(claudeHomeDir, "projects", projectHash);
|
|
6012
|
+
mkdirSync13(projectDir, { recursive: true });
|
|
6013
|
+
writeFileSync11(resolve27(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5955
6014
|
`, "utf-8");
|
|
5956
6015
|
}
|
|
5957
6016
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
5958
|
-
if (!
|
|
6017
|
+
if (!existsSync27(projectSettingsPath)) {
|
|
5959
6018
|
return {};
|
|
5960
6019
|
}
|
|
5961
6020
|
let parsed;
|
|
@@ -6001,7 +6060,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
6001
6060
|
return clone;
|
|
6002
6061
|
}
|
|
6003
6062
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
6004
|
-
const credentialsPath =
|
|
6063
|
+
const credentialsPath = resolve27(claudeHomeDir, ".credentials.json");
|
|
6005
6064
|
const platform = options.platform ?? process.platform;
|
|
6006
6065
|
if (platform === "darwin") {
|
|
6007
6066
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -6011,16 +6070,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6011
6070
|
if (raw) {
|
|
6012
6071
|
try {
|
|
6013
6072
|
JSON.parse(raw);
|
|
6014
|
-
|
|
6073
|
+
writeFileSync11(credentialsPath, raw, { mode: 384 });
|
|
6015
6074
|
registerCredentialCleanup(credentialsPath);
|
|
6016
6075
|
return true;
|
|
6017
6076
|
} catch {}
|
|
6018
6077
|
}
|
|
6019
6078
|
}
|
|
6020
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6079
|
+
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") : "";
|
|
6021
6080
|
if (hostClaudeHome) {
|
|
6022
|
-
const realCredentials =
|
|
6023
|
-
if (
|
|
6081
|
+
const realCredentials = resolve27(hostClaudeHome, ".credentials.json");
|
|
6082
|
+
if (existsSync27(realCredentials)) {
|
|
6024
6083
|
cpSync2(realCredentials, credentialsPath);
|
|
6025
6084
|
return true;
|
|
6026
6085
|
}
|
|
@@ -6028,36 +6087,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6028
6087
|
return false;
|
|
6029
6088
|
}
|
|
6030
6089
|
async function injectCodexAuth(codexHomeDir) {
|
|
6031
|
-
|
|
6032
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6090
|
+
mkdirSync13(codexHomeDir, { recursive: true });
|
|
6091
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve27(process.env.CODEX_HOME) : process.env.HOME ? resolve27(process.env.HOME, ".codex") : "";
|
|
6033
6092
|
if (!hostCodexHome) {
|
|
6034
6093
|
return false;
|
|
6035
6094
|
}
|
|
6036
|
-
const hostAuthPath =
|
|
6037
|
-
if (!
|
|
6095
|
+
const hostAuthPath = resolve27(hostCodexHome, "auth.json");
|
|
6096
|
+
if (!existsSync27(hostAuthPath)) {
|
|
6038
6097
|
return false;
|
|
6039
6098
|
}
|
|
6040
|
-
const runtimeAuthPath =
|
|
6099
|
+
const runtimeAuthPath = resolve27(codexHomeDir, "auth.json");
|
|
6041
6100
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6042
6101
|
chmodSync5(runtimeAuthPath, 384);
|
|
6043
6102
|
return true;
|
|
6044
6103
|
}
|
|
6045
6104
|
async function injectPiAgentConfig(piAgentDir) {
|
|
6046
|
-
|
|
6047
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6105
|
+
mkdirSync13(piAgentDir, { recursive: true });
|
|
6106
|
+
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") : "";
|
|
6048
6107
|
if (!hostPiAgentDir) {
|
|
6049
6108
|
return false;
|
|
6050
6109
|
}
|
|
6051
|
-
const hostAuthPath =
|
|
6052
|
-
if (!
|
|
6110
|
+
const hostAuthPath = resolve27(hostPiAgentDir, "auth.json");
|
|
6111
|
+
if (!existsSync27(hostAuthPath)) {
|
|
6053
6112
|
return false;
|
|
6054
6113
|
}
|
|
6055
|
-
const runtimeAuthPath =
|
|
6114
|
+
const runtimeAuthPath = resolve27(piAgentDir, "auth.json");
|
|
6056
6115
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6057
6116
|
chmodSync5(runtimeAuthPath, 384);
|
|
6058
|
-
const hostSettingsPath =
|
|
6059
|
-
if (
|
|
6060
|
-
const runtimeSettingsPath =
|
|
6117
|
+
const hostSettingsPath = resolve27(hostPiAgentDir, "settings.json");
|
|
6118
|
+
if (existsSync27(hostSettingsPath)) {
|
|
6119
|
+
const runtimeSettingsPath = resolve27(piAgentDir, "settings.json");
|
|
6061
6120
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
6062
6121
|
chmodSync5(runtimeSettingsPath, 384);
|
|
6063
6122
|
}
|
|
@@ -6065,13 +6124,13 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
6065
6124
|
}
|
|
6066
6125
|
|
|
6067
6126
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
6068
|
-
import { existsSync as
|
|
6069
|
-
import { resolve as
|
|
6127
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync14, statSync as statSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
6128
|
+
import { resolve as resolve28 } from "path";
|
|
6070
6129
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6071
6130
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6072
6131
|
return {
|
|
6073
6132
|
type: "stdio",
|
|
6074
|
-
command:
|
|
6133
|
+
command: resolve28(options.binDir, "rig-tool-router"),
|
|
6075
6134
|
args: [],
|
|
6076
6135
|
env: {
|
|
6077
6136
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6080,26 +6139,26 @@ function buildRuntimeToolRouterServerConfig(options) {
|
|
|
6080
6139
|
};
|
|
6081
6140
|
}
|
|
6082
6141
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6083
|
-
const configPath =
|
|
6084
|
-
|
|
6142
|
+
const configPath = resolve28(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6143
|
+
mkdirSync14(options.stateDir, { recursive: true });
|
|
6085
6144
|
const payload = {
|
|
6086
6145
|
mcpServers: {
|
|
6087
6146
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6088
6147
|
}
|
|
6089
6148
|
};
|
|
6090
|
-
|
|
6149
|
+
writeFileSync12(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6091
6150
|
`, "utf-8");
|
|
6092
6151
|
return configPath;
|
|
6093
6152
|
}
|
|
6094
6153
|
if (false) {}
|
|
6095
6154
|
// packages/runtime/src/control-plane/runtime/isolation/discovery.ts
|
|
6096
6155
|
init_layout();
|
|
6097
|
-
import { existsSync as
|
|
6098
|
-
import { resolve as
|
|
6156
|
+
import { existsSync as existsSync32 } from "fs";
|
|
6157
|
+
import { resolve as resolve32 } from "path";
|
|
6099
6158
|
|
|
6100
6159
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6101
|
-
import { existsSync as
|
|
6102
|
-
import { dirname as
|
|
6160
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync15, rmSync as rmSync10 } from "fs";
|
|
6161
|
+
import { dirname as dirname12, resolve as resolve29 } from "path";
|
|
6103
6162
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6104
6163
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6105
6164
|
if (explicit) {
|
|
@@ -6135,12 +6194,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6135
6194
|
}
|
|
6136
6195
|
async function provisionRuntimeWorktree(config) {
|
|
6137
6196
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6138
|
-
let hasValidWorktree =
|
|
6139
|
-
if (
|
|
6197
|
+
let hasValidWorktree = existsSync29(resolve29(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6198
|
+
if (existsSync29(config.workspaceDir) && !hasValidWorktree) {
|
|
6140
6199
|
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6141
6200
|
}
|
|
6142
6201
|
if (!hasValidWorktree) {
|
|
6143
|
-
|
|
6202
|
+
mkdirSync15(dirname12(config.workspaceDir), { recursive: true });
|
|
6144
6203
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6145
6204
|
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]);
|
|
6146
6205
|
if (add.exitCode !== 0) {
|
|
@@ -6322,31 +6381,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
6322
6381
|
|
|
6323
6382
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
6324
6383
|
import {
|
|
6325
|
-
existsSync as
|
|
6384
|
+
existsSync as existsSync31,
|
|
6326
6385
|
lstatSync,
|
|
6327
|
-
mkdirSync as
|
|
6386
|
+
mkdirSync as mkdirSync17,
|
|
6328
6387
|
readdirSync as readdirSync6,
|
|
6329
|
-
readFileSync as
|
|
6388
|
+
readFileSync as readFileSync15,
|
|
6330
6389
|
rmSync as rmSync11,
|
|
6331
6390
|
statSync as statSync8,
|
|
6332
6391
|
symlinkSync as symlinkSync4
|
|
6333
6392
|
} from "fs";
|
|
6334
6393
|
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
6335
|
-
import { dirname as
|
|
6394
|
+
import { dirname as dirname14, resolve as resolve31 } from "path";
|
|
6336
6395
|
|
|
6337
6396
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
6338
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
6397
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync30, mkdirSync as mkdirSync16, statSync as statSync7 } from "fs";
|
|
6339
6398
|
import { tmpdir as tmpdir6 } from "os";
|
|
6340
|
-
import { dirname as
|
|
6341
|
-
var sharedRouterOutputDir =
|
|
6342
|
-
var sharedRouterOutputPath =
|
|
6399
|
+
import { dirname as dirname13, resolve as resolve30 } from "path";
|
|
6400
|
+
var sharedRouterOutputDir = resolve30(tmpdir6(), "rig-native");
|
|
6401
|
+
var sharedRouterOutputPath = resolve30(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
6343
6402
|
function runtimeClaudeToolRouterFileName() {
|
|
6344
6403
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
6345
6404
|
}
|
|
6346
6405
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
6347
|
-
const sourcePath =
|
|
6348
|
-
|
|
6349
|
-
const needsBuild = !
|
|
6406
|
+
const sourcePath = resolve30(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
6407
|
+
mkdirSync16(dirname13(outputPath), { recursive: true });
|
|
6408
|
+
const needsBuild = !existsSync30(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
|
|
6350
6409
|
if (!needsBuild) {
|
|
6351
6410
|
return outputPath;
|
|
6352
6411
|
}
|
|
@@ -6360,9 +6419,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
6360
6419
|
}
|
|
6361
6420
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
6362
6421
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
6363
|
-
const targetPath =
|
|
6364
|
-
|
|
6365
|
-
const needsCopy = !
|
|
6422
|
+
const targetPath = resolve30(targetDir, runtimeClaudeToolRouterFileName());
|
|
6423
|
+
mkdirSync16(targetDir, { recursive: true });
|
|
6424
|
+
const needsCopy = !existsSync30(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
|
|
6366
6425
|
if (needsCopy) {
|
|
6367
6426
|
copyFileSync6(sourcePath, targetPath);
|
|
6368
6427
|
chmodSync6(targetPath, 493);
|
|
@@ -6375,48 +6434,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
6375
6434
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
6376
6435
|
function resolveRigSourceRoot(projectRoot) {
|
|
6377
6436
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6378
|
-
if (hostProjectRoot &&
|
|
6437
|
+
if (hostProjectRoot && existsSync31(resolve31(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6379
6438
|
return hostProjectRoot;
|
|
6380
6439
|
}
|
|
6381
|
-
const fromModule =
|
|
6382
|
-
if (
|
|
6440
|
+
const fromModule = resolve31(import.meta.dir, "../../../../../..");
|
|
6441
|
+
if (existsSync31(resolve31(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6383
6442
|
return fromModule;
|
|
6384
6443
|
}
|
|
6385
6444
|
return projectRoot;
|
|
6386
6445
|
}
|
|
6387
6446
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
6388
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
6447
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve31(sessionDir, "session.json")]) {
|
|
6389
6448
|
removeSymbolicLink(path);
|
|
6390
6449
|
}
|
|
6391
6450
|
runtimePrepareTrackedPathsNative({
|
|
6392
6451
|
logsDir,
|
|
6393
6452
|
stateDir,
|
|
6394
6453
|
sessionDir,
|
|
6395
|
-
controlledBashLogFile:
|
|
6396
|
-
eventsFile:
|
|
6454
|
+
controlledBashLogFile: resolve31(logsDir, "controlled-bash.jsonl"),
|
|
6455
|
+
eventsFile: resolve31(logsDir, "control-plane.events.jsonl")
|
|
6397
6456
|
});
|
|
6398
6457
|
}
|
|
6399
6458
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
6400
6459
|
await mkdir2(stateDir, { recursive: true });
|
|
6401
6460
|
await mkdir2(sessionDir, { recursive: true });
|
|
6402
|
-
const failedApproachesPath =
|
|
6403
|
-
if (!
|
|
6461
|
+
const failedApproachesPath = resolve31(stateDir, "failed_approaches.md");
|
|
6462
|
+
if (!existsSync31(failedApproachesPath)) {
|
|
6404
6463
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
6405
6464
|
|
|
6406
6465
|
`);
|
|
6407
6466
|
}
|
|
6408
|
-
const hookTripsPath =
|
|
6409
|
-
if (!
|
|
6467
|
+
const hookTripsPath = resolve31(stateDir, "hook_trips.log");
|
|
6468
|
+
if (!existsSync31(hookTripsPath)) {
|
|
6410
6469
|
await writeFile(hookTripsPath, "");
|
|
6411
6470
|
}
|
|
6412
|
-
const sessionFile =
|
|
6471
|
+
const sessionFile = resolve31(sessionDir, "session.json");
|
|
6413
6472
|
if (taskId) {
|
|
6414
6473
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
6415
6474
|
}
|
|
6416
6475
|
}
|
|
6417
6476
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
6418
|
-
const artifactDir =
|
|
6419
|
-
const runtimeSnapshotDir =
|
|
6477
|
+
const artifactDir = resolve31(workspaceDir, "artifacts", taskId);
|
|
6478
|
+
const runtimeSnapshotDir = resolve31(artifactDir, "runtime-snapshots");
|
|
6420
6479
|
let preservedTrackedFiles = false;
|
|
6421
6480
|
for (const file of [
|
|
6422
6481
|
"changed-files.txt",
|
|
@@ -6432,7 +6491,7 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
6432
6491
|
preservedTrackedFiles = true;
|
|
6433
6492
|
continue;
|
|
6434
6493
|
}
|
|
6435
|
-
rmSync11(
|
|
6494
|
+
rmSync11(resolve31(artifactDir, file), { force: true });
|
|
6436
6495
|
}
|
|
6437
6496
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
6438
6497
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
@@ -6471,28 +6530,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
6471
6530
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
6472
6531
|
}
|
|
6473
6532
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
6474
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
6475
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
6533
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve31(options.binDir, "rig"), rigSourceRoot);
|
|
6534
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve31(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
6476
6535
|
...options.runtimeSecretDefines,
|
|
6477
6536
|
AGENT_TASK_ID: options.taskId,
|
|
6478
6537
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6479
6538
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
6480
6539
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
6481
6540
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
6482
|
-
AGENT_BINARY_PATH:
|
|
6541
|
+
AGENT_BINARY_PATH: resolve31(options.binDir, "rig-agent"),
|
|
6483
6542
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
6484
6543
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
6485
6544
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
6486
6545
|
});
|
|
6487
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
6546
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve31(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
6488
6547
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6489
6548
|
AGENT_LOGS_DIR: options.logsDir,
|
|
6490
6549
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
6491
|
-
AGENT_TS_API_TESTS_DIR:
|
|
6492
|
-
AGENT_RIG_AGENT_BIN:
|
|
6550
|
+
AGENT_TS_API_TESTS_DIR: resolve31(options.workspaceDir, "TSAPITests"),
|
|
6551
|
+
AGENT_RIG_AGENT_BIN: resolve31(options.binDir, "rig-agent")
|
|
6493
6552
|
});
|
|
6494
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
6495
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
6553
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve31(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
6554
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve31(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
6496
6555
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6497
6556
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6498
6557
|
});
|
|
@@ -6501,15 +6560,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
6501
6560
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6502
6561
|
};
|
|
6503
6562
|
for (const hookName of hookNames) {
|
|
6504
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
6563
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve31(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
6505
6564
|
}
|
|
6506
|
-
const pluginsDir =
|
|
6507
|
-
if (
|
|
6565
|
+
const pluginsDir = resolve31(options.projectRoot, "rig/plugins");
|
|
6566
|
+
if (existsSync31(pluginsDir)) {
|
|
6508
6567
|
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
6509
6568
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
6510
6569
|
if (!match)
|
|
6511
6570
|
continue;
|
|
6512
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
6571
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve31(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
6513
6572
|
}
|
|
6514
6573
|
}
|
|
6515
6574
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -6519,8 +6578,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
6519
6578
|
}
|
|
6520
6579
|
async function writeRuntimeManifest(config) {
|
|
6521
6580
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
6522
|
-
const binarySha256 = sha256Hex(
|
|
6523
|
-
const manifestPath =
|
|
6581
|
+
const binarySha256 = sha256Hex(readFileSync15(config.binaryPath));
|
|
6582
|
+
const manifestPath = resolve31(config.runtimeRoot, "manifest.json");
|
|
6524
6583
|
const manifest = {
|
|
6525
6584
|
runtimeId: config.runtimeId,
|
|
6526
6585
|
taskId: config.taskId,
|
|
@@ -6640,31 +6699,31 @@ function readFileMtimeMs(path) {
|
|
|
6640
6699
|
}
|
|
6641
6700
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
6642
6701
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
6643
|
-
const sourceNodeModules =
|
|
6644
|
-
if (!
|
|
6645
|
-
const runtimeHumoongate =
|
|
6646
|
-
if (
|
|
6647
|
-
const targetNodeModules =
|
|
6702
|
+
const sourceNodeModules = resolve31(monorepoRoot, "humoongate", "node_modules");
|
|
6703
|
+
if (!existsSync31(sourceNodeModules)) {} else {
|
|
6704
|
+
const runtimeHumoongate = resolve31(workspaceDir, "humoongate");
|
|
6705
|
+
if (existsSync31(resolve31(runtimeHumoongate, "package.json"))) {
|
|
6706
|
+
const targetNodeModules = resolve31(runtimeHumoongate, "node_modules");
|
|
6648
6707
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
6649
6708
|
}
|
|
6650
6709
|
}
|
|
6651
|
-
const runtimeHpNext =
|
|
6652
|
-
if (!
|
|
6710
|
+
const runtimeHpNext = resolve31(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
6711
|
+
if (!existsSync31(resolve31(runtimeHpNext, "package.json"))) {
|
|
6653
6712
|
return;
|
|
6654
6713
|
}
|
|
6655
|
-
const sourceHpNextNodeModules =
|
|
6656
|
-
const sourceMonorepoNodeModules =
|
|
6657
|
-
const targetHpNextNodeModules =
|
|
6658
|
-
if (
|
|
6714
|
+
const sourceHpNextNodeModules = resolve31(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
6715
|
+
const sourceMonorepoNodeModules = resolve31(monorepoRoot, "node_modules");
|
|
6716
|
+
const targetHpNextNodeModules = resolve31(runtimeHpNext, "node_modules");
|
|
6717
|
+
if (existsSync31(sourceHpNextNodeModules)) {
|
|
6659
6718
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
6660
6719
|
return;
|
|
6661
6720
|
}
|
|
6662
|
-
if (
|
|
6721
|
+
if (existsSync31(sourceMonorepoNodeModules)) {
|
|
6663
6722
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
6664
6723
|
}
|
|
6665
6724
|
}
|
|
6666
6725
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
6667
|
-
linkNodeModulesLayer(
|
|
6726
|
+
linkNodeModulesLayer(resolve31(monorepoRoot, "node_modules"), resolve31(workspaceDir, "node_modules"));
|
|
6668
6727
|
for (const relativePackageDir of [
|
|
6669
6728
|
"apps/native-app/apps/marketing",
|
|
6670
6729
|
"apps/native-app/apps/web",
|
|
@@ -6686,15 +6745,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
6686
6745
|
"packages/standard-plugin",
|
|
6687
6746
|
"packages/validator-kit"
|
|
6688
6747
|
]) {
|
|
6689
|
-
const workspacePackageDir =
|
|
6690
|
-
if (!
|
|
6748
|
+
const workspacePackageDir = resolve31(workspaceDir, relativePackageDir);
|
|
6749
|
+
if (!existsSync31(resolve31(workspacePackageDir, "package.json"))) {
|
|
6691
6750
|
continue;
|
|
6692
6751
|
}
|
|
6693
|
-
linkNodeModulesLayer(
|
|
6752
|
+
linkNodeModulesLayer(resolve31(monorepoRoot, relativePackageDir, "node_modules"), resolve31(workspacePackageDir, "node_modules"));
|
|
6694
6753
|
}
|
|
6695
6754
|
}
|
|
6696
6755
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
6697
|
-
if (!
|
|
6756
|
+
if (!existsSync31(sourceDir) || existsSync31(targetDir)) {
|
|
6698
6757
|
return;
|
|
6699
6758
|
}
|
|
6700
6759
|
try {
|
|
@@ -6703,16 +6762,16 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
6703
6762
|
} catch (error) {
|
|
6704
6763
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
6705
6764
|
}
|
|
6706
|
-
|
|
6765
|
+
mkdirSync17(dirname14(targetDir), { recursive: true });
|
|
6707
6766
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
6708
6767
|
}
|
|
6709
6768
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
6710
|
-
const hooksDir =
|
|
6711
|
-
const pluginsDir =
|
|
6712
|
-
const validatorsDir =
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6769
|
+
const hooksDir = resolve31(runtimeBinDir, "hooks");
|
|
6770
|
+
const pluginsDir = resolve31(runtimeBinDir, "plugins");
|
|
6771
|
+
const validatorsDir = resolve31(runtimeBinDir, "validators");
|
|
6772
|
+
mkdirSync17(hooksDir, { recursive: true });
|
|
6773
|
+
mkdirSync17(pluginsDir, { recursive: true });
|
|
6774
|
+
mkdirSync17(validatorsDir, { recursive: true });
|
|
6716
6775
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
6717
6776
|
}
|
|
6718
6777
|
function runtimeWorktreeId(workspaceDir) {
|
|
@@ -6721,7 +6780,7 @@ function runtimeWorktreeId(workspaceDir) {
|
|
|
6721
6780
|
|
|
6722
6781
|
// packages/runtime/src/control-plane/runtime/isolation/discovery.ts
|
|
6723
6782
|
async function readRuntimeMetadata(metadataPath) {
|
|
6724
|
-
if (!
|
|
6783
|
+
if (!existsSync32(metadataPath)) {
|
|
6725
6784
|
return null;
|
|
6726
6785
|
}
|
|
6727
6786
|
try {
|
|
@@ -6733,8 +6792,8 @@ async function readRuntimeMetadata(metadataPath) {
|
|
|
6733
6792
|
async function listAgentRuntimes(projectRoot) {
|
|
6734
6793
|
const runtimes = [];
|
|
6735
6794
|
const monorepoRoot = resolveMonorepoRoot3(projectRoot);
|
|
6736
|
-
const worktreesRoot =
|
|
6737
|
-
if (!
|
|
6795
|
+
const worktreesRoot = resolve32(monorepoRoot, ".worktrees");
|
|
6796
|
+
if (!existsSync32(worktreesRoot)) {
|
|
6738
6797
|
return [];
|
|
6739
6798
|
}
|
|
6740
6799
|
const workspaces = runtimeScanWorktreesNative(worktreesRoot);
|
|
@@ -6742,7 +6801,7 @@ async function listAgentRuntimes(projectRoot) {
|
|
|
6742
6801
|
let workspacePath = scan.workspaceDir;
|
|
6743
6802
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(workspacePath);
|
|
6744
6803
|
const rootDir = scan.runtimeDir || workspaceLayout.runtimeDir;
|
|
6745
|
-
const metadataPath = scan.metadataPath ||
|
|
6804
|
+
const metadataPath = scan.metadataPath || resolve32(rootDir, "runtime.json");
|
|
6746
6805
|
const contextFile = scan.contextPath || workspaceLayout.contextPath;
|
|
6747
6806
|
let mode = "worktree";
|
|
6748
6807
|
let createdAt = new Date().toISOString();
|
|
@@ -6758,7 +6817,7 @@ async function listAgentRuntimes(projectRoot) {
|
|
|
6758
6817
|
mode = metadata.mode;
|
|
6759
6818
|
createdAt = metadata.createdAt;
|
|
6760
6819
|
}
|
|
6761
|
-
if (
|
|
6820
|
+
if (existsSync32(contextFile)) {
|
|
6762
6821
|
try {
|
|
6763
6822
|
const ctx = loadRuntimeContext(contextFile);
|
|
6764
6823
|
taskId = ctx.taskId;
|
|
@@ -6778,13 +6837,13 @@ async function listAgentRuntimes(projectRoot) {
|
|
|
6778
6837
|
mode,
|
|
6779
6838
|
rootDir,
|
|
6780
6839
|
workspaceDir: workspacePath,
|
|
6781
|
-
homeDir:
|
|
6782
|
-
tmpDir:
|
|
6783
|
-
cacheDir:
|
|
6840
|
+
homeDir: resolve32(rootDir, "home"),
|
|
6841
|
+
tmpDir: resolve32(rootDir, "tmp"),
|
|
6842
|
+
cacheDir: resolve32(rootDir, "cache"),
|
|
6784
6843
|
logsDir,
|
|
6785
6844
|
stateDir,
|
|
6786
6845
|
sessionDir,
|
|
6787
|
-
claudeHomeDir:
|
|
6846
|
+
claudeHomeDir: resolve32(rootDir, "home", ".claude"),
|
|
6788
6847
|
contextFile,
|
|
6789
6848
|
binDir,
|
|
6790
6849
|
createdAt
|
|
@@ -6798,22 +6857,22 @@ function runtimeRootForCleanup(projectRoot, runtimeId) {
|
|
|
6798
6857
|
monorepoRoot = resolveMonorepoRoot3(projectRoot);
|
|
6799
6858
|
} catch {}
|
|
6800
6859
|
const workspaceRootCandidate = monorepoRoot ?? projectRoot;
|
|
6801
|
-
const initialWorkspaceDir =
|
|
6860
|
+
const initialWorkspaceDir = resolve32(workspaceRootCandidate, ".worktrees", runtimeWorktreeNameFromRuntimeId(runtimeId));
|
|
6802
6861
|
const runtimeRoot = resolveRuntimeWorkspaceLayout(initialWorkspaceDir).runtimeDir;
|
|
6803
6862
|
return { monorepoRoot, initialWorkspaceDir, runtimeRoot };
|
|
6804
6863
|
}
|
|
6805
6864
|
|
|
6806
6865
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
6807
|
-
import { existsSync as
|
|
6808
|
-
import { basename as basename9, resolve as
|
|
6866
|
+
import { existsSync as existsSync35, rmSync as rmSync12, writeFileSync as writeFileSync14 } from "fs";
|
|
6867
|
+
import { basename as basename9, resolve as resolve36 } from "path";
|
|
6809
6868
|
|
|
6810
6869
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
6811
|
-
import { existsSync as
|
|
6870
|
+
import { existsSync as existsSync34 } from "fs";
|
|
6812
6871
|
|
|
6813
6872
|
// packages/runtime/src/control-plane/runtime/guard.ts
|
|
6814
6873
|
import { optimizeNextInvocation } from "bun:jsc";
|
|
6815
|
-
import { existsSync as
|
|
6816
|
-
import { resolve as
|
|
6874
|
+
import { existsSync as existsSync33, readFileSync as readFileSync16, statSync as statSync9 } from "fs";
|
|
6875
|
+
import { resolve as resolve33 } from "path";
|
|
6817
6876
|
|
|
6818
6877
|
// packages/runtime/src/control-plane/runtime/guard-types.ts
|
|
6819
6878
|
var POLICY_VERSION = 1;
|
|
@@ -6876,8 +6935,8 @@ function loadPolicy(projectRoot) {
|
|
|
6876
6935
|
if (seededPolicyConfig) {
|
|
6877
6936
|
return seededPolicyConfig;
|
|
6878
6937
|
}
|
|
6879
|
-
const configPath =
|
|
6880
|
-
if (!
|
|
6938
|
+
const configPath = resolve33(projectRoot, "rig/policy/policy.json");
|
|
6939
|
+
if (!existsSync33(configPath)) {
|
|
6881
6940
|
return defaultPolicy();
|
|
6882
6941
|
}
|
|
6883
6942
|
let mtimeMs;
|
|
@@ -6891,7 +6950,7 @@ function loadPolicy(projectRoot) {
|
|
|
6891
6950
|
}
|
|
6892
6951
|
let parsed;
|
|
6893
6952
|
try {
|
|
6894
|
-
parsed = JSON.parse(
|
|
6953
|
+
parsed = JSON.parse(readFileSync16(configPath, "utf-8"));
|
|
6895
6954
|
} catch {
|
|
6896
6955
|
return defaultPolicy();
|
|
6897
6956
|
}
|
|
@@ -7107,28 +7166,28 @@ function resolveAction(mode, matched) {
|
|
|
7107
7166
|
}
|
|
7108
7167
|
function resolveAbsolutePath(projectRoot, rawPath) {
|
|
7109
7168
|
if (rawPath.startsWith("/"))
|
|
7110
|
-
return
|
|
7111
|
-
return
|
|
7169
|
+
return resolve33(rawPath);
|
|
7170
|
+
return resolve33(projectRoot, rawPath);
|
|
7112
7171
|
}
|
|
7113
7172
|
function isHarnessPath(projectRoot, rawPath) {
|
|
7114
7173
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7115
7174
|
const managedRoots = [
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7175
|
+
resolve33(projectRoot, "rig"),
|
|
7176
|
+
resolve33(projectRoot, ".rig"),
|
|
7177
|
+
resolve33(projectRoot, "artifacts")
|
|
7119
7178
|
];
|
|
7120
7179
|
return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
|
|
7121
7180
|
}
|
|
7122
7181
|
function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
|
|
7123
7182
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7124
7183
|
if (taskWorkspace) {
|
|
7125
|
-
const workspaceRigRoot =
|
|
7126
|
-
const workspaceArtifactsRoot =
|
|
7184
|
+
const workspaceRigRoot = resolve33(taskWorkspace, ".rig");
|
|
7185
|
+
const workspaceArtifactsRoot = resolve33(taskWorkspace, "artifacts");
|
|
7127
7186
|
if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
|
|
7128
7187
|
return true;
|
|
7129
7188
|
}
|
|
7130
7189
|
}
|
|
7131
|
-
const runtimeRoot =
|
|
7190
|
+
const runtimeRoot = resolve33(projectRoot, ".rig/runtime/agents");
|
|
7132
7191
|
return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
|
|
7133
7192
|
}
|
|
7134
7193
|
function isTestFile(path) {
|
|
@@ -7176,7 +7235,7 @@ function evaluateScope(policy, context, filePath, access) {
|
|
|
7176
7235
|
return allowed();
|
|
7177
7236
|
}
|
|
7178
7237
|
if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
|
|
7179
|
-
const absPath =
|
|
7238
|
+
const absPath = resolve33(filePath);
|
|
7180
7239
|
if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
|
|
7181
7240
|
const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
|
|
7182
7241
|
const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
|
|
@@ -7501,13 +7560,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
7501
7560
|
depRoots
|
|
7502
7561
|
};
|
|
7503
7562
|
const fsContext = {
|
|
7504
|
-
pathExists: (p) =>
|
|
7563
|
+
pathExists: (p) => existsSync34(p),
|
|
7505
7564
|
realPath: toRealPath
|
|
7506
7565
|
};
|
|
7507
7566
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
7508
7567
|
const seatbelt = Bun.which("sandbox-exec");
|
|
7509
7568
|
probed.push("sandbox-exec");
|
|
7510
|
-
if (seatbelt &&
|
|
7569
|
+
if (seatbelt && existsSync34(seatbelt)) {
|
|
7511
7570
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
7512
7571
|
if (SeatbeltBackendClass) {
|
|
7513
7572
|
return {
|
|
@@ -7628,8 +7687,8 @@ init_layout();
|
|
|
7628
7687
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
7629
7688
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
7630
7689
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
7631
|
-
const readyFile =
|
|
7632
|
-
const requestFile =
|
|
7690
|
+
const readyFile = resolve36(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
7691
|
+
const requestFile = resolve36(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
7633
7692
|
rmSync12(readyFile, { force: true });
|
|
7634
7693
|
rmSync12(requestFile, { force: true });
|
|
7635
7694
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
@@ -7673,7 +7732,7 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
7673
7732
|
rmSync12(requestFile, { force: true });
|
|
7674
7733
|
},
|
|
7675
7734
|
finalize: async (commandParts, exitCode) => {
|
|
7676
|
-
|
|
7735
|
+
writeFileSync14(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
7677
7736
|
`, "utf-8");
|
|
7678
7737
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
7679
7738
|
proc.exited,
|
|
@@ -7737,8 +7796,8 @@ async function runInAgentRuntime(options) {
|
|
|
7737
7796
|
const stdout = await new Response(proc.stdout).text();
|
|
7738
7797
|
const stderr = await new Response(proc.stderr).text();
|
|
7739
7798
|
try {
|
|
7740
|
-
await Bun.write(
|
|
7741
|
-
await Bun.write(
|
|
7799
|
+
await Bun.write(resolve36(options.runtime.logsDir, "agent-stdout.log"), stdout);
|
|
7800
|
+
await Bun.write(resolve36(options.runtime.logsDir, "agent-stderr.log"), stderr);
|
|
7742
7801
|
} catch {}
|
|
7743
7802
|
await snapshotSidecar.finalize(runtimeCommand, exitCode);
|
|
7744
7803
|
return {
|
|
@@ -7768,18 +7827,18 @@ function resolveInternalRuntimeCommand(command) {
|
|
|
7768
7827
|
}
|
|
7769
7828
|
async function cleanupAgentRuntime(options) {
|
|
7770
7829
|
const { monorepoRoot, initialWorkspaceDir, runtimeRoot } = runtimeRootForCleanup(options.projectRoot, options.id);
|
|
7771
|
-
const metadataPath =
|
|
7772
|
-
if (!
|
|
7830
|
+
const metadataPath = resolve36(runtimeRoot, "runtime.json");
|
|
7831
|
+
if (!existsSync35(runtimeRoot)) {
|
|
7773
7832
|
return;
|
|
7774
7833
|
}
|
|
7775
7834
|
let mode = "worktree";
|
|
7776
7835
|
let workspaceDir = "";
|
|
7777
7836
|
const metadata = await readRuntimeMetadata2(metadataPath);
|
|
7778
|
-
const metadataMatchesRequestedRuntime = metadata !== null && metadata.id === options.id &&
|
|
7837
|
+
const metadataMatchesRequestedRuntime = metadata !== null && metadata.id === options.id && resolve36(metadata.workspaceDir) === resolve36(initialWorkspaceDir);
|
|
7779
7838
|
if (metadata && metadataMatchesRequestedRuntime) {
|
|
7780
7839
|
mode = metadata.mode;
|
|
7781
7840
|
workspaceDir = metadata.workspaceDir;
|
|
7782
|
-
} else if (
|
|
7841
|
+
} else if (existsSync35(initialWorkspaceDir)) {
|
|
7783
7842
|
workspaceDir = initialWorkspaceDir;
|
|
7784
7843
|
}
|
|
7785
7844
|
const preservesTaskWorktree = metadataMatchesRequestedRuntime && metadata ? options.id === taskRuntimeId(metadata.taskId) : false;
|
|
@@ -7811,10 +7870,10 @@ function resolveSnapshotSidecarScriptPath() {
|
|
|
7811
7870
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
7812
7871
|
}
|
|
7813
7872
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
7814
|
-
return
|
|
7873
|
+
return resolve36(binDir, "snapshot-sidecar");
|
|
7815
7874
|
}
|
|
7816
7875
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
7817
|
-
if (!
|
|
7876
|
+
if (!existsSync35(binaryPath)) {
|
|
7818
7877
|
return false;
|
|
7819
7878
|
}
|
|
7820
7879
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -7829,12 +7888,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
7829
7888
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
7830
7889
|
].filter((value) => Boolean(value));
|
|
7831
7890
|
for (const root of hostRoots) {
|
|
7832
|
-
const candidate =
|
|
7833
|
-
if (
|
|
7891
|
+
const candidate = resolve36(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
7892
|
+
if (existsSync35(candidate)) {
|
|
7834
7893
|
return candidate;
|
|
7835
7894
|
}
|
|
7836
7895
|
}
|
|
7837
|
-
return
|
|
7896
|
+
return resolve36(import.meta.dir, "..", fileName);
|
|
7838
7897
|
}
|
|
7839
7898
|
function resolveBunCliInvocation() {
|
|
7840
7899
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -7861,7 +7920,7 @@ function resolveBunCliInvocation() {
|
|
|
7861
7920
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
7862
7921
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
7863
7922
|
while (Date.now() < deadline) {
|
|
7864
|
-
if (
|
|
7923
|
+
if (existsSync35(readyFile)) {
|
|
7865
7924
|
return;
|
|
7866
7925
|
}
|
|
7867
7926
|
const exitCode = proc.exitCode;
|
|
@@ -7874,7 +7933,7 @@ async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, s
|
|
|
7874
7933
|
throw new Error(`snapshot sidecar did not become ready within ${SNAPSHOT_SIDECAR_READY_TIMEOUT_MS}ms`);
|
|
7875
7934
|
}
|
|
7876
7935
|
async function readRuntimeMetadata2(metadataPath) {
|
|
7877
|
-
if (!
|
|
7936
|
+
if (!existsSync35(metadataPath)) {
|
|
7878
7937
|
return null;
|
|
7879
7938
|
}
|
|
7880
7939
|
try {
|
|
@@ -7889,9 +7948,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
7889
7948
|
async function hydrateRuntimeMemory(options) {
|
|
7890
7949
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
7891
7950
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
7892
|
-
const hydratedPath =
|
|
7951
|
+
const hydratedPath = resolve37(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
7893
7952
|
try {
|
|
7894
|
-
await mkdir3(
|
|
7953
|
+
await mkdir3(resolve37(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
7895
7954
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
7896
7955
|
return {
|
|
7897
7956
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -7906,12 +7965,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
7906
7965
|
}
|
|
7907
7966
|
}
|
|
7908
7967
|
async function createRuntimeTaskRecordReader(options) {
|
|
7909
|
-
const legacyConfigPath =
|
|
7968
|
+
const legacyConfigPath = resolve37(options.projectRoot, ".rig", "task-config.json");
|
|
7910
7969
|
let pluginHostContext = null;
|
|
7911
7970
|
try {
|
|
7912
7971
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
7913
7972
|
} catch (error) {
|
|
7914
|
-
if (!
|
|
7973
|
+
if (!existsSync36(legacyConfigPath)) {
|
|
7915
7974
|
throw error;
|
|
7916
7975
|
}
|
|
7917
7976
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -7931,7 +7990,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7931
7990
|
source: "plugin"
|
|
7932
7991
|
};
|
|
7933
7992
|
}
|
|
7934
|
-
if (
|
|
7993
|
+
if (existsSync36(legacyConfigPath)) {
|
|
7935
7994
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
7936
7995
|
options.diagnostics?.(message);
|
|
7937
7996
|
console.warn(message);
|
|
@@ -7948,10 +8007,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7948
8007
|
};
|
|
7949
8008
|
}
|
|
7950
8009
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
7951
|
-
const jsonPath =
|
|
7952
|
-
if (
|
|
8010
|
+
const jsonPath = resolve37(projectRoot, "rig.config.json");
|
|
8011
|
+
if (existsSync36(jsonPath)) {
|
|
7953
8012
|
try {
|
|
7954
|
-
const parsed = JSON.parse(
|
|
8013
|
+
const parsed = JSON.parse(readFileSync17(jsonPath, "utf8"));
|
|
7955
8014
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7956
8015
|
const taskSource = parsed.taskSource;
|
|
7957
8016
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -7963,12 +8022,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
7963
8022
|
return null;
|
|
7964
8023
|
}
|
|
7965
8024
|
}
|
|
7966
|
-
const tsPath =
|
|
7967
|
-
if (!
|
|
8025
|
+
const tsPath = resolve37(projectRoot, "rig.config.ts");
|
|
8026
|
+
if (!existsSync36(tsPath)) {
|
|
7968
8027
|
return null;
|
|
7969
8028
|
}
|
|
7970
8029
|
try {
|
|
7971
|
-
const source =
|
|
8030
|
+
const source = readFileSync17(tsPath, "utf8");
|
|
7972
8031
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
7973
8032
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
7974
8033
|
return kind ?? null;
|
|
@@ -8038,8 +8097,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
8038
8097
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
8039
8098
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
8040
8099
|
};
|
|
8041
|
-
const configPath =
|
|
8042
|
-
await mkdir3(
|
|
8100
|
+
const configPath = resolve37(options.workspaceDir, ".rig", "task-config.json");
|
|
8101
|
+
await mkdir3(resolve37(options.workspaceDir, ".rig"), { recursive: true });
|
|
8043
8102
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
8044
8103
|
`, "utf-8");
|
|
8045
8104
|
}
|
|
@@ -8103,9 +8162,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8103
8162
|
}
|
|
8104
8163
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8105
8164
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8106
|
-
const workspaceDir =
|
|
8165
|
+
const workspaceDir = resolve37(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8107
8166
|
const createdAt = new Date().toISOString();
|
|
8108
|
-
if (!
|
|
8167
|
+
if (!existsSync36(resolve37(monorepoRoot, ".git"))) {
|
|
8109
8168
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8110
8169
|
}
|
|
8111
8170
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8140,7 +8199,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8140
8199
|
logsDir: overlay.logsDir,
|
|
8141
8200
|
stateDir: overlay.stateDir,
|
|
8142
8201
|
sessionDir: overlay.sessionDir,
|
|
8143
|
-
claudeHomeDir:
|
|
8202
|
+
claudeHomeDir: resolve37(workspaceLayout.homeDir, ".claude"),
|
|
8144
8203
|
contextFile: overlay.contextPath,
|
|
8145
8204
|
binDir: workspaceLayout.binDir,
|
|
8146
8205
|
createdAt
|
|
@@ -8153,8 +8212,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8153
8212
|
projectRoot: options.projectRoot,
|
|
8154
8213
|
workspaceDir
|
|
8155
8214
|
});
|
|
8156
|
-
|
|
8157
|
-
|
|
8215
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8216
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8158
8217
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8159
8218
|
if (options.preserveTaskArtifacts) {
|
|
8160
8219
|
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
@@ -8173,7 +8232,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8173
8232
|
runtimeId: options.id
|
|
8174
8233
|
}),
|
|
8175
8234
|
workspaceDir,
|
|
8176
|
-
artifactRoot:
|
|
8235
|
+
artifactRoot: resolve37(workspaceDir, "artifacts", options.taskId),
|
|
8177
8236
|
hostProjectRoot: options.projectRoot,
|
|
8178
8237
|
monorepoMainRoot: monorepoRoot,
|
|
8179
8238
|
monorepoBaseRef: baseRef,
|
|
@@ -8189,8 +8248,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8189
8248
|
stateDir: overlay.stateDir,
|
|
8190
8249
|
logsDir: overlay.logsDir,
|
|
8191
8250
|
sessionDir: overlay.sessionDir,
|
|
8192
|
-
sessionFile:
|
|
8193
|
-
policyFile:
|
|
8251
|
+
sessionFile: resolve37(overlay.sessionDir, "session.json"),
|
|
8252
|
+
policyFile: resolve37(options.projectRoot, "rig/policy/policy.json"),
|
|
8194
8253
|
binDir: runtime.binDir,
|
|
8195
8254
|
createdAt,
|
|
8196
8255
|
memory
|
|
@@ -8201,9 +8260,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8201
8260
|
task: taskResolution.task,
|
|
8202
8261
|
taskEntry
|
|
8203
8262
|
});
|
|
8204
|
-
const manifestPath =
|
|
8263
|
+
const manifestPath = resolve37(runtimeRoot, "manifest.json");
|
|
8205
8264
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8206
|
-
const runtimeAgentBinary =
|
|
8265
|
+
const runtimeAgentBinary = resolve37(runtime.binDir, "rig-agent");
|
|
8207
8266
|
await ensureRigGitBinaryPath();
|
|
8208
8267
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8209
8268
|
projectRoot: options.projectRoot,
|
|
@@ -8220,8 +8279,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8220
8279
|
});
|
|
8221
8280
|
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8222
8281
|
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8223
|
-
|
|
8224
|
-
|
|
8282
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8283
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8225
8284
|
await buildRuntimeToolchain({
|
|
8226
8285
|
projectRoot: options.projectRoot,
|
|
8227
8286
|
workspaceDir,
|
|
@@ -8258,9 +8317,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8258
8317
|
workspaceDir,
|
|
8259
8318
|
taskEntry
|
|
8260
8319
|
});
|
|
8261
|
-
const sandboxDir =
|
|
8320
|
+
const sandboxDir = resolve37(runtimeRoot, "sandbox");
|
|
8262
8321
|
await mkdir3(sandboxDir, { recursive: true });
|
|
8263
|
-
await writeFile2(
|
|
8322
|
+
await writeFile2(resolve37(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8264
8323
|
id: options.id,
|
|
8265
8324
|
taskId: options.taskId,
|
|
8266
8325
|
mode: "worktree",
|