@h-rig/runtime 0.0.6-alpha.3 → 0.0.6-alpha.30
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 +1165 -785
- package/dist/bin/rig-agent.js +458 -389
- package/dist/src/control-plane/agent-wrapper.js +1191 -504
- package/dist/src/control-plane/authority-files.js +12 -6
- package/dist/src/control-plane/harness-main.js +2186 -1786
- package/dist/src/control-plane/hooks/completion-verification.js +2084 -1019
- package/dist/src/control-plane/hooks/inject-context.js +193 -139
- package/dist/src/control-plane/hooks/submodule-branch.js +603 -545
- package/dist/src/control-plane/hooks/task-runtime-start.js +603 -545
- package/dist/src/control-plane/materialize-task-config.js +64 -8
- package/dist/src/control-plane/native/git-ops.js +90 -64
- package/dist/src/control-plane/native/harness-cli.js +1989 -682
- package/dist/src/control-plane/native/pr-automation.js +1657 -54
- package/dist/src/control-plane/native/pr-review-gate.js +1455 -0
- package/dist/src/control-plane/native/repo-ops.js +3 -0
- package/dist/src/control-plane/native/run-ops.js +39 -13
- package/dist/src/control-plane/native/task-ops.js +1819 -527
- package/dist/src/control-plane/native/validator.js +163 -109
- package/dist/src/control-plane/native/verifier.js +1616 -323
- package/dist/src/control-plane/native/workspace-ops.js +12 -6
- package/dist/src/control-plane/pi-sessiond/bin.js +793 -0
- package/dist/src/control-plane/pi-sessiond/client.js +41 -0
- package/dist/src/control-plane/pi-sessiond/event-hub.js +59 -0
- package/dist/src/control-plane/pi-sessiond/extension-ui-context.js +198 -0
- package/dist/src/control-plane/pi-sessiond/launcher.js +173 -0
- package/dist/src/control-plane/pi-sessiond/server.js +802 -0
- package/dist/src/control-plane/pi-sessiond/session-service.js +540 -0
- package/dist/src/control-plane/pi-sessiond/types.js +1 -0
- package/dist/src/control-plane/plugin-host-context.js +54 -0
- package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +3 -0
- package/dist/src/control-plane/runtime/image/index.js +3 -0
- package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +3 -0
- package/dist/src/control-plane/runtime/image.js +3 -0
- package/dist/src/control-plane/runtime/index.js +517 -722
- package/dist/src/control-plane/runtime/isolation/home.js +28 -6
- package/dist/src/control-plane/runtime/isolation/index.js +541 -461
- package/dist/src/control-plane/runtime/isolation/runner.js +28 -6
- package/dist/src/control-plane/runtime/isolation/shared.js +9 -6
- package/dist/src/control-plane/runtime/isolation.js +541 -461
- package/dist/src/control-plane/runtime/plugin-mode.js +3 -27
- package/dist/src/control-plane/runtime/queue.js +458 -385
- package/dist/src/control-plane/runtime/snapshot/task-run.js +3 -0
- package/dist/src/control-plane/runtime/task-run-snapshot.js +3 -0
- package/dist/src/control-plane/skill-materializer.js +46 -0
- package/dist/src/control-plane/tasks/source-aware-task-config-source.js +14 -2
- package/dist/src/control-plane/tasks/source-lifecycle.js +86 -32
- package/dist/src/index.js +27 -298
- package/dist/src/layout.js +12 -7
- package/dist/src/local-server.js +20 -14
- package/native/darwin-arm64/rig-git +0 -0
- package/native/darwin-arm64/rig-git.build-manifest.json +1 -1
- package/native/darwin-arm64/rig-shell +0 -0
- package/native/darwin-arm64/rig-shell.build-manifest.json +1 -1
- package/native/darwin-arm64/rig-tools +0 -0
- package/native/darwin-arm64/rig-tools.build-manifest.json +1 -1
- package/native/darwin-arm64/runtime-native.dylib +0 -0
- package/package.json +8 -6
- package/dist/src/control-plane/runtime/plugins.js +0 -1131
- package/dist/src/plugins.js +0 -329
|
@@ -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 existsSync20, readdirSync as readdirSync4, realpathSync } from "fs";
|
|
153
|
+
import { resolve as resolve20 } from "path";
|
|
154
154
|
function toRealPath(path) {
|
|
155
|
-
if (!
|
|
156
|
-
return
|
|
155
|
+
if (!existsSync20(path)) {
|
|
156
|
+
return resolve20(path);
|
|
157
157
|
}
|
|
158
158
|
try {
|
|
159
159
|
return realpathSync.native(path);
|
|
160
160
|
} catch {
|
|
161
|
-
return
|
|
161
|
+
return resolve20(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 (existsSync20(candidate)) {
|
|
168
168
|
candidates.add(toRealPath(candidate));
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
|
-
addPath(
|
|
172
|
-
addPath(
|
|
171
|
+
addPath(resolve20(projectRoot, ".git"));
|
|
172
|
+
addPath(resolve20(workspaceDir, "..", "..", ".git"));
|
|
173
173
|
for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
|
|
174
|
-
addPath(
|
|
174
|
+
addPath(resolve20(repoRoot, ".git"));
|
|
175
175
|
}
|
|
176
|
-
const workspaceGit =
|
|
177
|
-
if (
|
|
176
|
+
const workspaceGit = resolve20(workspaceDir, ".git");
|
|
177
|
+
if (existsSync20(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 (existsSync20(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 (
|
|
197
|
-
for (const entry of
|
|
195
|
+
const reposDir = resolve20(projectRoot, "repos");
|
|
196
|
+
if (existsSync20(reposDir)) {
|
|
197
|
+
for (const entry of readdirSync4(reposDir, { withFileTypes: true })) {
|
|
198
198
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
199
|
-
addPath(
|
|
199
|
+
addPath(resolve20(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 mkdirSync17, writeFileSync as writeFileSync12 } from "fs";
|
|
244
|
+
import { resolve as resolve33 } 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 = resolve33(options.runtime.rootDir, "sandbox");
|
|
269
|
+
mkdirSync17(sandboxDir, { recursive: true });
|
|
270
|
+
const profilePath = resolve33(sandboxDir, "seatbelt.sb");
|
|
271
271
|
const profile = this.renderProfile(options);
|
|
272
|
-
|
|
272
|
+
writeFileSync12(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 = resolve33(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 mkdirSync18 } from "fs";
|
|
387
|
+
import { resolve as resolve34 } 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(resolve34(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 = resolve34(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 = resolve34(realHome, ".ssh");
|
|
526
526
|
if (ctx.pathExists(hostSshDir)) {
|
|
527
|
-
|
|
527
|
+
mkdirSync18(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 existsSync34, mkdirSync as mkdirSync19, readFileSync as readFileSync16, 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 resolve36 } 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 existsSync23, mkdirSync as mkdirSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
|
|
1862
|
+
import { resolve as resolve24 } from "path";
|
|
1863
1863
|
|
|
1864
1864
|
// packages/runtime/src/build-time-config.ts
|
|
1865
1865
|
function normalizeBuildConfig(value) {
|
|
@@ -2710,6 +2710,49 @@ function safeReadJson(path) {
|
|
|
2710
2710
|
}
|
|
2711
2711
|
}
|
|
2712
2712
|
|
|
2713
|
+
// packages/runtime/src/control-plane/skill-materializer.ts
|
|
2714
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync5, readdirSync, rmSync as rmSync7, writeFileSync as writeFileSync5 } from "fs";
|
|
2715
|
+
import { resolve as resolve12 } from "path";
|
|
2716
|
+
import { loadSkill } from "@rig/skill-loader";
|
|
2717
|
+
var MARKER_FILENAME = ".rig-plugin";
|
|
2718
|
+
function skillDirName(id) {
|
|
2719
|
+
return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
2720
|
+
}
|
|
2721
|
+
async function materializeSkills(projectRoot, entries) {
|
|
2722
|
+
const skillsRoot = resolve12(projectRoot, ".pi", "skills");
|
|
2723
|
+
if (existsSync12(skillsRoot)) {
|
|
2724
|
+
for (const name of readdirSync(skillsRoot)) {
|
|
2725
|
+
const dir = resolve12(skillsRoot, name);
|
|
2726
|
+
if (existsSync12(resolve12(dir, MARKER_FILENAME))) {
|
|
2727
|
+
rmSync7(dir, { recursive: true, force: true });
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
const written = [];
|
|
2732
|
+
for (const { pluginName, skill } of entries) {
|
|
2733
|
+
const sourcePath = resolve12(projectRoot, skill.path);
|
|
2734
|
+
if (!existsSync12(sourcePath)) {
|
|
2735
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
|
|
2736
|
+
continue;
|
|
2737
|
+
}
|
|
2738
|
+
let body;
|
|
2739
|
+
try {
|
|
2740
|
+
await loadSkill(sourcePath);
|
|
2741
|
+
body = readFileSync5(sourcePath, "utf-8");
|
|
2742
|
+
} catch (err) {
|
|
2743
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
|
|
2744
|
+
continue;
|
|
2745
|
+
}
|
|
2746
|
+
const dir = resolve12(skillsRoot, skillDirName(skill.id));
|
|
2747
|
+
mkdirSync8(dir, { recursive: true });
|
|
2748
|
+
writeFileSync5(resolve12(dir, "SKILL.md"), body, "utf-8");
|
|
2749
|
+
writeFileSync5(resolve12(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
|
|
2750
|
+
`, "utf-8");
|
|
2751
|
+
written.push({ id: skill.id, pluginName, directory: dir });
|
|
2752
|
+
}
|
|
2753
|
+
return written;
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2713
2756
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
2714
2757
|
async function buildPluginHostContext(projectRoot) {
|
|
2715
2758
|
let config;
|
|
@@ -2746,6 +2789,17 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2746
2789
|
} catch (err) {
|
|
2747
2790
|
console.warn(`[plugin-host] hook materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2748
2791
|
}
|
|
2792
|
+
try {
|
|
2793
|
+
const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
|
|
2794
|
+
pluginName: plugin.name,
|
|
2795
|
+
skill
|
|
2796
|
+
})));
|
|
2797
|
+
if (skillEntries.length > 0) {
|
|
2798
|
+
await materializeSkills(projectRoot, skillEntries);
|
|
2799
|
+
}
|
|
2800
|
+
} catch (err) {
|
|
2801
|
+
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2802
|
+
}
|
|
2749
2803
|
return {
|
|
2750
2804
|
config,
|
|
2751
2805
|
pluginHost,
|
|
@@ -2759,12 +2813,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2759
2813
|
|
|
2760
2814
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
2761
2815
|
import { spawnSync } from "child_process";
|
|
2762
|
-
import { existsSync as
|
|
2763
|
-
import { basename as basename4, join as join3, resolve as
|
|
2816
|
+
import { existsSync as existsSync14, readFileSync as readFileSync7, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
2817
|
+
import { basename as basename4, join as join3, resolve as resolve14 } from "path";
|
|
2764
2818
|
|
|
2765
2819
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
2766
|
-
import { existsSync as
|
|
2767
|
-
import { resolve as
|
|
2820
|
+
import { existsSync as existsSync13, readFileSync as readFileSync6 } from "fs";
|
|
2821
|
+
import { resolve as resolve13 } from "path";
|
|
2768
2822
|
|
|
2769
2823
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
2770
2824
|
async function findTaskById(reader, id) {
|
|
@@ -2787,7 +2841,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
2787
2841
|
}
|
|
2788
2842
|
}
|
|
2789
2843
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2790
|
-
const configPath = options.configPath ??
|
|
2844
|
+
const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
|
|
2791
2845
|
const reader = {
|
|
2792
2846
|
async listTasks() {
|
|
2793
2847
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -2798,8 +2852,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
2798
2852
|
};
|
|
2799
2853
|
return reader;
|
|
2800
2854
|
}
|
|
2801
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
2802
|
-
if (!
|
|
2855
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve13(projectRoot, ".rig", "task-config.json")) {
|
|
2856
|
+
if (!existsSync13(configPath)) {
|
|
2803
2857
|
return [];
|
|
2804
2858
|
}
|
|
2805
2859
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -2807,7 +2861,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve12(projectRoot,
|
|
|
2807
2861
|
}
|
|
2808
2862
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
2809
2863
|
try {
|
|
2810
|
-
const parsed = JSON.parse(
|
|
2864
|
+
const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
|
|
2811
2865
|
if (isPlainRecord(parsed)) {
|
|
2812
2866
|
return parsed;
|
|
2813
2867
|
}
|
|
@@ -2891,7 +2945,7 @@ function isPlainRecord(candidate) {
|
|
|
2891
2945
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
2892
2946
|
var FILE_TASK_PATTERN = /\.(task\.)?json$/;
|
|
2893
2947
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2894
|
-
const configPath = options.configPath ??
|
|
2948
|
+
const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
|
|
2895
2949
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
2896
2950
|
const spawnFn = options.spawn ?? spawnSync;
|
|
2897
2951
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -2974,10 +3028,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
2974
3028
|
return metadata;
|
|
2975
3029
|
}
|
|
2976
3030
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
2977
|
-
const jsonPath =
|
|
2978
|
-
if (
|
|
3031
|
+
const jsonPath = resolve14(projectRoot, "rig.config.json");
|
|
3032
|
+
if (existsSync14(jsonPath)) {
|
|
2979
3033
|
try {
|
|
2980
|
-
const parsed = JSON.parse(
|
|
3034
|
+
const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
|
|
2981
3035
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
2982
3036
|
const source = parsed.taskSource;
|
|
2983
3037
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -2986,12 +3040,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
2986
3040
|
return null;
|
|
2987
3041
|
}
|
|
2988
3042
|
}
|
|
2989
|
-
const tsPath =
|
|
2990
|
-
if (!
|
|
3043
|
+
const tsPath = resolve14(projectRoot, "rig.config.ts");
|
|
3044
|
+
if (!existsSync14(tsPath)) {
|
|
2991
3045
|
return null;
|
|
2992
3046
|
}
|
|
2993
3047
|
try {
|
|
2994
|
-
const source =
|
|
3048
|
+
const source = readFileSync7(tsPath, "utf8");
|
|
2995
3049
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
2996
3050
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
2997
3051
|
if (kind !== "files") {
|
|
@@ -3011,10 +3065,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
3011
3065
|
return isPlainRecord2(entry) ? entry : null;
|
|
3012
3066
|
}
|
|
3013
3067
|
function readRawTaskConfig(configPath) {
|
|
3014
|
-
if (!
|
|
3068
|
+
if (!existsSync14(configPath)) {
|
|
3015
3069
|
return null;
|
|
3016
3070
|
}
|
|
3017
|
-
const parsed = JSON.parse(
|
|
3071
|
+
const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
|
|
3018
3072
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
3019
3073
|
}
|
|
3020
3074
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -3022,12 +3076,12 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
3022
3076
|
return tasks;
|
|
3023
3077
|
}
|
|
3024
3078
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
3025
|
-
const directory =
|
|
3026
|
-
if (!
|
|
3079
|
+
const directory = resolve14(projectRoot, sourcePath);
|
|
3080
|
+
if (!existsSync14(directory)) {
|
|
3027
3081
|
return [];
|
|
3028
3082
|
}
|
|
3029
3083
|
const tasks = [];
|
|
3030
|
-
for (const name of
|
|
3084
|
+
for (const name of readdirSync2(directory)) {
|
|
3031
3085
|
if (!FILE_TASK_PATTERN.test(name))
|
|
3032
3086
|
continue;
|
|
3033
3087
|
const inferredId = basename4(name).replace(FILE_TASK_PATTERN, "");
|
|
@@ -3038,11 +3092,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
3038
3092
|
return tasks;
|
|
3039
3093
|
}
|
|
3040
3094
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
3041
|
-
const file = findFileBackedTaskFile(
|
|
3095
|
+
const file = findFileBackedTaskFile(resolve14(projectRoot, sourcePath), taskId);
|
|
3042
3096
|
if (!file) {
|
|
3043
3097
|
return null;
|
|
3044
3098
|
}
|
|
3045
|
-
const raw = JSON.parse(
|
|
3099
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
3046
3100
|
if (!isPlainRecord2(raw)) {
|
|
3047
3101
|
return null;
|
|
3048
3102
|
}
|
|
@@ -3055,17 +3109,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
3055
3109
|
};
|
|
3056
3110
|
}
|
|
3057
3111
|
function findFileBackedTaskFile(directory, taskId) {
|
|
3058
|
-
if (!
|
|
3112
|
+
if (!existsSync14(directory)) {
|
|
3059
3113
|
return null;
|
|
3060
3114
|
}
|
|
3061
|
-
for (const name of
|
|
3115
|
+
for (const name of readdirSync2(directory)) {
|
|
3062
3116
|
if (!FILE_TASK_PATTERN.test(name))
|
|
3063
3117
|
continue;
|
|
3064
3118
|
const file = join3(directory, name);
|
|
3065
3119
|
try {
|
|
3066
3120
|
if (!statSync3(file).isFile())
|
|
3067
3121
|
continue;
|
|
3068
|
-
const raw = JSON.parse(
|
|
3122
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
3069
3123
|
const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
|
|
3070
3124
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
3071
3125
|
if (id === taskId) {
|
|
@@ -3148,8 +3202,8 @@ function githubStatusFor(issue) {
|
|
|
3148
3202
|
return "open";
|
|
3149
3203
|
}
|
|
3150
3204
|
function selectedGitHubEnv() {
|
|
3151
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
3152
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
3205
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
3206
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
3153
3207
|
}
|
|
3154
3208
|
function ghSpawnOptions() {
|
|
3155
3209
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -3225,8 +3279,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
|
|
|
3225
3279
|
}
|
|
3226
3280
|
|
|
3227
3281
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
3228
|
-
import { existsSync as
|
|
3229
|
-
import { basename as basename6, resolve as
|
|
3282
|
+
import { existsSync as existsSync18, readFileSync as readFileSync9, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
3283
|
+
import { basename as basename6, resolve as resolve18 } from "path";
|
|
3230
3284
|
|
|
3231
3285
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
3232
3286
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -3334,39 +3388,39 @@ function readTaskStateMetadataEnvelope(raw) {
|
|
|
3334
3388
|
};
|
|
3335
3389
|
}
|
|
3336
3390
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
3337
|
-
import { existsSync as
|
|
3338
|
-
import { resolve as
|
|
3391
|
+
import { existsSync as existsSync17, readFileSync as readFileSync8 } from "fs";
|
|
3392
|
+
import { resolve as resolve17 } from "path";
|
|
3339
3393
|
|
|
3340
3394
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
3341
|
-
import { existsSync as
|
|
3342
|
-
import { resolve as
|
|
3395
|
+
import { existsSync as existsSync16 } from "fs";
|
|
3396
|
+
import { resolve as resolve16 } from "path";
|
|
3343
3397
|
|
|
3344
3398
|
// packages/runtime/src/control-plane/repos/layout.ts
|
|
3345
3399
|
init_layout();
|
|
3346
|
-
import { existsSync as
|
|
3347
|
-
import { basename as basename5, dirname as dirname9, join as join4, resolve as
|
|
3400
|
+
import { existsSync as existsSync15 } from "fs";
|
|
3401
|
+
import { basename as basename5, dirname as dirname9, join as join4, resolve as resolve15 } from "path";
|
|
3348
3402
|
function resolveRepoStateDir(projectRoot) {
|
|
3349
|
-
const normalizedProjectRoot =
|
|
3403
|
+
const normalizedProjectRoot = resolve15(projectRoot);
|
|
3350
3404
|
const projectParent = dirname9(normalizedProjectRoot);
|
|
3351
3405
|
if (basename5(projectParent) === ".worktrees") {
|
|
3352
3406
|
const ownerRoot = dirname9(projectParent);
|
|
3353
|
-
const ownerHasRepoMarkers =
|
|
3407
|
+
const ownerHasRepoMarkers = existsSync15(resolve15(ownerRoot, ".git")) || existsSync15(resolve15(ownerRoot, ".rig", "state"));
|
|
3354
3408
|
if (ownerHasRepoMarkers) {
|
|
3355
|
-
return
|
|
3409
|
+
return resolve15(ownerRoot, ".rig", "state");
|
|
3356
3410
|
}
|
|
3357
3411
|
}
|
|
3358
|
-
return
|
|
3412
|
+
return resolve15(projectRoot, ".rig", "state");
|
|
3359
3413
|
}
|
|
3360
3414
|
function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
3361
|
-
const normalizedProjectRoot =
|
|
3415
|
+
const normalizedProjectRoot = resolve15(projectRoot);
|
|
3362
3416
|
const entry = getManagedRepoEntry(repoId);
|
|
3363
3417
|
const stateDir = resolveRepoStateDir(normalizedProjectRoot);
|
|
3364
3418
|
const metadataRelativePath = join4("repos", entry.id);
|
|
3365
|
-
const metadataRoot =
|
|
3419
|
+
const metadataRoot = resolve15(stateDir, metadataRelativePath);
|
|
3366
3420
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3367
|
-
const runsInsideTaskWorktree = runtimeWorkspace &&
|
|
3421
|
+
const runsInsideTaskWorktree = runtimeWorkspace && resolve15(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
|
|
3368
3422
|
const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
|
|
3369
|
-
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ?
|
|
3423
|
+
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve15(process.env[entry.checkoutEnvVar].trim()) : resolve15(normalizedProjectRoot, entry.alias);
|
|
3370
3424
|
return {
|
|
3371
3425
|
projectRoot: normalizedProjectRoot,
|
|
3372
3426
|
repoId: entry.id,
|
|
@@ -3374,12 +3428,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
|
3374
3428
|
defaultBranch: entry.defaultBranch,
|
|
3375
3429
|
remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
|
|
3376
3430
|
checkoutRoot,
|
|
3377
|
-
worktreesRoot:
|
|
3431
|
+
worktreesRoot: resolve15(checkoutRoot, ".worktrees"),
|
|
3378
3432
|
stateDir,
|
|
3379
3433
|
metadataRoot,
|
|
3380
3434
|
metadataRelativePath,
|
|
3381
|
-
mirrorRoot:
|
|
3382
|
-
mirrorStatePath:
|
|
3435
|
+
mirrorRoot: resolve15(metadataRoot, "mirror.git"),
|
|
3436
|
+
mirrorStatePath: resolve15(metadataRoot, "mirror-state.json"),
|
|
3383
3437
|
mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
|
|
3384
3438
|
};
|
|
3385
3439
|
}
|
|
@@ -3397,7 +3451,7 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3397
3451
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3398
3452
|
try {
|
|
3399
3453
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
3400
|
-
if (
|
|
3454
|
+
if (existsSync16(resolve16(layout.mirrorRoot, "HEAD"))) {
|
|
3401
3455
|
return layout.mirrorRoot;
|
|
3402
3456
|
}
|
|
3403
3457
|
} catch {}
|
|
@@ -3408,8 +3462,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3408
3462
|
var DEFAULT_READ_DEPS2 = {
|
|
3409
3463
|
fetchRef: nativeFetchRef,
|
|
3410
3464
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
3411
|
-
exists:
|
|
3412
|
-
readFile: (path) =>
|
|
3465
|
+
exists: existsSync17,
|
|
3466
|
+
readFile: (path) => readFileSync8(path, "utf8")
|
|
3413
3467
|
};
|
|
3414
3468
|
function parseIssueStatus(rawStatus) {
|
|
3415
3469
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -3490,12 +3544,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
3490
3544
|
if (runtimeContextPath) {
|
|
3491
3545
|
return true;
|
|
3492
3546
|
}
|
|
3493
|
-
return
|
|
3547
|
+
return existsSync17(resolve17(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
3494
3548
|
}
|
|
3495
3549
|
function readLocalTrackerState(projectRoot, deps) {
|
|
3496
3550
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3497
|
-
const issuesPath =
|
|
3498
|
-
const taskStatePath =
|
|
3551
|
+
const issuesPath = resolve17(monorepoRoot, ".beads", "issues.jsonl");
|
|
3552
|
+
const taskStatePath = resolve17(monorepoRoot, ".beads", "task-state.json");
|
|
3499
3553
|
return projectSyncedTrackerSnapshot({
|
|
3500
3554
|
source: "local",
|
|
3501
3555
|
issuesBaseOid: null,
|
|
@@ -3557,7 +3611,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
3557
3611
|
return readValidationDescriptionMap(raw);
|
|
3558
3612
|
}
|
|
3559
3613
|
function readSourceValidationDescriptions(projectRoot) {
|
|
3560
|
-
const rootRaw = readJsonFile(
|
|
3614
|
+
const rootRaw = readJsonFile(resolve18(projectRoot, "rig", "task-config.json"), {});
|
|
3561
3615
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
3562
3616
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
3563
3617
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -3633,15 +3687,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
3633
3687
|
return meta.validation_descriptions;
|
|
3634
3688
|
}
|
|
3635
3689
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
3636
|
-
const taskStatePath =
|
|
3690
|
+
const taskStatePath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
3637
3691
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
3638
3692
|
}
|
|
3639
3693
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
3640
|
-
const issuesPath =
|
|
3641
|
-
if (!
|
|
3694
|
+
const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3695
|
+
if (!existsSync18(issuesPath)) {
|
|
3642
3696
|
return null;
|
|
3643
3697
|
}
|
|
3644
|
-
for (const line of
|
|
3698
|
+
for (const line of readFileSync9(issuesPath, "utf8").split(/\r?\n/)) {
|
|
3645
3699
|
const trimmed = line.trim();
|
|
3646
3700
|
if (!trimmed) {
|
|
3647
3701
|
continue;
|
|
@@ -3666,25 +3720,25 @@ function inferTaskIdFromRuntimePath(path) {
|
|
|
3666
3720
|
function artifactDirForId(projectRoot, id) {
|
|
3667
3721
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3668
3722
|
if (workspaceDir) {
|
|
3669
|
-
const worktreeArtifacts =
|
|
3670
|
-
if (
|
|
3723
|
+
const worktreeArtifacts = resolve18(workspaceDir, "artifacts", id);
|
|
3724
|
+
if (existsSync18(worktreeArtifacts) || existsSync18(resolve18(workspaceDir, "artifacts"))) {
|
|
3671
3725
|
return worktreeArtifacts;
|
|
3672
3726
|
}
|
|
3673
3727
|
}
|
|
3674
3728
|
try {
|
|
3675
3729
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3676
|
-
return
|
|
3730
|
+
return resolve18(paths.artifactsDir, id);
|
|
3677
3731
|
} catch {
|
|
3678
|
-
return
|
|
3732
|
+
return resolve18(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
3679
3733
|
}
|
|
3680
3734
|
}
|
|
3681
3735
|
function resolveTaskConfigPath(projectRoot) {
|
|
3682
3736
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3683
|
-
if (
|
|
3737
|
+
if (existsSync18(paths.taskConfigPath)) {
|
|
3684
3738
|
return paths.taskConfigPath;
|
|
3685
3739
|
}
|
|
3686
3740
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3687
|
-
if (
|
|
3741
|
+
if (existsSync18(candidate)) {
|
|
3688
3742
|
return candidate;
|
|
3689
3743
|
}
|
|
3690
3744
|
}
|
|
@@ -3692,7 +3746,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
3692
3746
|
}
|
|
3693
3747
|
function findSourceTaskConfigPath(projectRoot) {
|
|
3694
3748
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3695
|
-
if (
|
|
3749
|
+
if (existsSync18(candidate)) {
|
|
3696
3750
|
return candidate;
|
|
3697
3751
|
}
|
|
3698
3752
|
}
|
|
@@ -3705,7 +3759,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
3705
3759
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
3706
3760
|
if (sourcePath && synced.updated) {
|
|
3707
3761
|
try {
|
|
3708
|
-
|
|
3762
|
+
writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
3709
3763
|
`, "utf-8");
|
|
3710
3764
|
} catch {}
|
|
3711
3765
|
}
|
|
@@ -3757,12 +3811,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
3757
3811
|
return !candidate.role;
|
|
3758
3812
|
}
|
|
3759
3813
|
function readSourceIssueRecords(projectRoot) {
|
|
3760
|
-
const issuesPath =
|
|
3761
|
-
if (!
|
|
3814
|
+
const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3815
|
+
if (!existsSync18(issuesPath)) {
|
|
3762
3816
|
return [];
|
|
3763
3817
|
}
|
|
3764
3818
|
const records = [];
|
|
3765
|
-
for (const line of
|
|
3819
|
+
for (const line of readFileSync9(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
3766
3820
|
const trimmed = line.trim();
|
|
3767
3821
|
if (!trimmed) {
|
|
3768
3822
|
continue;
|
|
@@ -3818,19 +3872,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
3818
3872
|
if (!sourcePath) {
|
|
3819
3873
|
return {};
|
|
3820
3874
|
}
|
|
3821
|
-
const directory =
|
|
3822
|
-
if (!
|
|
3875
|
+
const directory = resolve18(projectRoot, sourcePath);
|
|
3876
|
+
if (!existsSync18(directory)) {
|
|
3823
3877
|
return {};
|
|
3824
3878
|
}
|
|
3825
3879
|
const config = {};
|
|
3826
|
-
for (const name of
|
|
3880
|
+
for (const name of readdirSync3(directory)) {
|
|
3827
3881
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
3828
3882
|
continue;
|
|
3829
|
-
const file =
|
|
3883
|
+
const file = resolve18(directory, name);
|
|
3830
3884
|
try {
|
|
3831
3885
|
if (!statSync4(file).isFile())
|
|
3832
3886
|
continue;
|
|
3833
|
-
const raw = JSON.parse(
|
|
3887
|
+
const raw = JSON.parse(readFileSync9(file, "utf8"));
|
|
3834
3888
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
3835
3889
|
continue;
|
|
3836
3890
|
const record = raw;
|
|
@@ -3872,10 +3926,10 @@ function firstStringList2(...candidates) {
|
|
|
3872
3926
|
return [];
|
|
3873
3927
|
}
|
|
3874
3928
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
3875
|
-
const jsonPath =
|
|
3876
|
-
if (
|
|
3929
|
+
const jsonPath = resolve18(projectRoot, "rig.config.json");
|
|
3930
|
+
if (existsSync18(jsonPath)) {
|
|
3877
3931
|
try {
|
|
3878
|
-
const parsed = JSON.parse(
|
|
3932
|
+
const parsed = JSON.parse(readFileSync9(jsonPath, "utf8"));
|
|
3879
3933
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3880
3934
|
const taskSource = parsed.taskSource;
|
|
3881
3935
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -3887,12 +3941,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3887
3941
|
return null;
|
|
3888
3942
|
}
|
|
3889
3943
|
}
|
|
3890
|
-
const tsPath =
|
|
3891
|
-
if (!
|
|
3944
|
+
const tsPath = resolve18(projectRoot, "rig.config.ts");
|
|
3945
|
+
if (!existsSync18(tsPath)) {
|
|
3892
3946
|
return null;
|
|
3893
3947
|
}
|
|
3894
3948
|
try {
|
|
3895
|
-
const source =
|
|
3949
|
+
const source = readFileSync9(tsPath, "utf8");
|
|
3896
3950
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3897
3951
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3898
3952
|
if (kind !== "files") {
|
|
@@ -3906,9 +3960,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3906
3960
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
3907
3961
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
3908
3962
|
return [
|
|
3909
|
-
runtimeContext?.monorepoMainRoot ?
|
|
3910
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
3911
|
-
|
|
3963
|
+
runtimeContext?.monorepoMainRoot ? resolve18(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
3964
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve18(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
3965
|
+
resolve18(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
3912
3966
|
].filter(Boolean);
|
|
3913
3967
|
}
|
|
3914
3968
|
|
|
@@ -3917,8 +3971,8 @@ init_layout();
|
|
|
3917
3971
|
|
|
3918
3972
|
// packages/runtime/src/binary-run.ts
|
|
3919
3973
|
init_layout();
|
|
3920
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
3921
|
-
import { basename as basename7, dirname as dirname10, resolve as
|
|
3974
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync19, mkdirSync as mkdirSync9, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
3975
|
+
import { basename as basename7, dirname as dirname10, resolve as resolve19 } from "path";
|
|
3922
3976
|
import { fileURLToPath } from "url";
|
|
3923
3977
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
3924
3978
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -3944,9 +3998,9 @@ async function buildRuntimeBinary(options) {
|
|
|
3944
3998
|
});
|
|
3945
3999
|
}
|
|
3946
4000
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
3947
|
-
const tempBuildDir =
|
|
3948
|
-
const tempOutputPath =
|
|
3949
|
-
|
|
4001
|
+
const tempBuildDir = resolve19(dirname10(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4002
|
+
const tempOutputPath = resolve19(tempBuildDir, basename7(options.outputPath));
|
|
4003
|
+
mkdirSync9(tempBuildDir, { recursive: true });
|
|
3950
4004
|
await withTemporaryEnv({
|
|
3951
4005
|
...options.env,
|
|
3952
4006
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -3971,7 +4025,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
3971
4025
|
`);
|
|
3972
4026
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
3973
4027
|
}
|
|
3974
|
-
if (!
|
|
4028
|
+
if (!existsSync19(tempOutputPath)) {
|
|
3975
4029
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
3976
4030
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
3977
4031
|
}
|
|
@@ -3986,7 +4040,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
3986
4040
|
});
|
|
3987
4041
|
}
|
|
3988
4042
|
})).finally(() => {
|
|
3989
|
-
|
|
4043
|
+
rmSync8(tempBuildDir, { recursive: true, force: true });
|
|
3990
4044
|
});
|
|
3991
4045
|
}
|
|
3992
4046
|
function runBestEffortBuildGc() {
|
|
@@ -4003,8 +4057,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4003
4057
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4004
4058
|
return {
|
|
4005
4059
|
...options,
|
|
4006
|
-
entrypoint:
|
|
4007
|
-
outputPath:
|
|
4060
|
+
entrypoint: resolve19(options.cwd, options.sourcePath),
|
|
4061
|
+
outputPath: resolve19(options.outputPath)
|
|
4008
4062
|
};
|
|
4009
4063
|
}
|
|
4010
4064
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4018,7 +4072,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4018
4072
|
}
|
|
4019
4073
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4020
4074
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4021
|
-
if (!workerSourcePath || !
|
|
4075
|
+
if (!workerSourcePath || !existsSync19(workerSourcePath)) {
|
|
4022
4076
|
await buildRuntimeBinaryInProcess(options, {
|
|
4023
4077
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4024
4078
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4049,13 +4103,13 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4049
4103
|
new Response(build.stdout).text(),
|
|
4050
4104
|
new Response(build.stderr).text()
|
|
4051
4105
|
]);
|
|
4052
|
-
|
|
4106
|
+
rmSync8(payloadPath, { force: true });
|
|
4053
4107
|
if (exitCode !== 0) {
|
|
4054
4108
|
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
4055
4109
|
}
|
|
4056
4110
|
}
|
|
4057
4111
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4058
|
-
return
|
|
4112
|
+
return resolve19(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4059
4113
|
}
|
|
4060
4114
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4061
4115
|
const envRoots = [
|
|
@@ -4064,13 +4118,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4064
4118
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4065
4119
|
].filter(Boolean);
|
|
4066
4120
|
for (const root of envRoots) {
|
|
4067
|
-
const candidate =
|
|
4068
|
-
if (
|
|
4121
|
+
const candidate = resolve19(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4122
|
+
if (existsSync19(candidate)) {
|
|
4069
4123
|
return candidate;
|
|
4070
4124
|
}
|
|
4071
4125
|
}
|
|
4072
|
-
const localCandidate =
|
|
4073
|
-
return
|
|
4126
|
+
const localCandidate = resolve19(import.meta.dir, "binary-build-worker.ts");
|
|
4127
|
+
return existsSync19(localCandidate) ? localCandidate : null;
|
|
4074
4128
|
}
|
|
4075
4129
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4076
4130
|
const bunPath = Bun.which("bun");
|
|
@@ -4106,7 +4160,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4106
4160
|
});
|
|
4107
4161
|
}
|
|
4108
4162
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4109
|
-
if (!
|
|
4163
|
+
if (!existsSync19(input.outputPath) || !existsSync19(input.manifestPath)) {
|
|
4110
4164
|
return false;
|
|
4111
4165
|
}
|
|
4112
4166
|
let manifest = null;
|
|
@@ -4119,7 +4173,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4119
4173
|
return false;
|
|
4120
4174
|
}
|
|
4121
4175
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4122
|
-
if (!
|
|
4176
|
+
if (!existsSync19(filePath)) {
|
|
4123
4177
|
return false;
|
|
4124
4178
|
}
|
|
4125
4179
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4132,7 +4186,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4132
4186
|
const inputs = {};
|
|
4133
4187
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4134
4188
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4135
|
-
if (!normalized || !
|
|
4189
|
+
if (!normalized || !existsSync19(normalized)) {
|
|
4136
4190
|
continue;
|
|
4137
4191
|
}
|
|
4138
4192
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4155,7 +4209,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4155
4209
|
if (inputPath.startsWith("<")) {
|
|
4156
4210
|
return null;
|
|
4157
4211
|
}
|
|
4158
|
-
return
|
|
4212
|
+
return resolve19(cwd, inputPath);
|
|
4159
4213
|
}
|
|
4160
4214
|
async function sha256File4(path) {
|
|
4161
4215
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4171,8 +4225,8 @@ function sortRecord(value) {
|
|
|
4171
4225
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4172
4226
|
const previous = runtimeBinaryBuildQueue;
|
|
4173
4227
|
let release;
|
|
4174
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4175
|
-
release =
|
|
4228
|
+
runtimeBinaryBuildQueue = new Promise((resolve20) => {
|
|
4229
|
+
release = resolve20;
|
|
4176
4230
|
});
|
|
4177
4231
|
await previous;
|
|
4178
4232
|
try {
|
|
@@ -4217,11 +4271,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4217
4271
|
}
|
|
4218
4272
|
|
|
4219
4273
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4220
|
-
import { delimiter, resolve as
|
|
4274
|
+
import { delimiter, resolve as resolve22 } from "path";
|
|
4221
4275
|
|
|
4222
4276
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
4223
|
-
import { existsSync as
|
|
4224
|
-
import { resolve as
|
|
4277
|
+
import { existsSync as existsSync21, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
4278
|
+
import { resolve as resolve21 } from "path";
|
|
4225
4279
|
|
|
4226
4280
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
4227
4281
|
init_utils();
|
|
@@ -4238,7 +4292,7 @@ function resolveBunBinaryPath() {
|
|
|
4238
4292
|
}
|
|
4239
4293
|
const home = process.env.HOME?.trim();
|
|
4240
4294
|
const fallbackCandidates = [
|
|
4241
|
-
home ?
|
|
4295
|
+
home ? resolve21(home, ".bun/bin/bun") : "",
|
|
4242
4296
|
"/opt/homebrew/bin/bun",
|
|
4243
4297
|
"/usr/local/bin/bun",
|
|
4244
4298
|
"/usr/bin/bun"
|
|
@@ -4266,8 +4320,8 @@ function resolveClaudeBinaryPath() {
|
|
|
4266
4320
|
}
|
|
4267
4321
|
const home = process.env.HOME?.trim();
|
|
4268
4322
|
const fallbackCandidates = [
|
|
4269
|
-
home ?
|
|
4270
|
-
home ?
|
|
4323
|
+
home ? resolve21(home, ".local/bin/claude") : "",
|
|
4324
|
+
home ? resolve21(home, ".local/share/claude/local/claude") : "",
|
|
4271
4325
|
"/opt/homebrew/bin/claude",
|
|
4272
4326
|
"/usr/local/bin/claude",
|
|
4273
4327
|
"/usr/bin/claude"
|
|
@@ -4281,35 +4335,35 @@ function resolveClaudeBinaryPath() {
|
|
|
4281
4335
|
throw new Error("claude not found in PATH");
|
|
4282
4336
|
}
|
|
4283
4337
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
4284
|
-
return
|
|
4338
|
+
return resolve21(bunBinaryPath, "../..");
|
|
4285
4339
|
}
|
|
4286
4340
|
function resolveClaudeInstallDir() {
|
|
4287
4341
|
const realPath = resolveClaudeBinaryPath();
|
|
4288
|
-
return
|
|
4342
|
+
return resolve21(realPath, "..");
|
|
4289
4343
|
}
|
|
4290
4344
|
function resolveNodeInstallDir() {
|
|
4291
4345
|
const preferredNode = resolvePreferredNodeBinary();
|
|
4292
4346
|
if (!preferredNode)
|
|
4293
4347
|
return null;
|
|
4294
4348
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
4295
|
-
if (explicitNode &&
|
|
4296
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
4349
|
+
if (explicitNode && resolve21(explicitNode) === resolve21(preferredNode)) {
|
|
4350
|
+
return preferredNode.endsWith("/bin/node") ? resolve21(preferredNode, "../..") : resolve21(preferredNode, "..");
|
|
4297
4351
|
}
|
|
4298
4352
|
try {
|
|
4299
4353
|
const realPath = realpathSync2(preferredNode);
|
|
4300
4354
|
if (realPath.endsWith("/bin/node")) {
|
|
4301
|
-
return
|
|
4355
|
+
return resolve21(realPath, "../..");
|
|
4302
4356
|
}
|
|
4303
|
-
return
|
|
4357
|
+
return resolve21(realPath, "..");
|
|
4304
4358
|
} catch {
|
|
4305
|
-
return
|
|
4359
|
+
return resolve21(preferredNode, "..");
|
|
4306
4360
|
}
|
|
4307
4361
|
}
|
|
4308
4362
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
4309
4363
|
const roots = [];
|
|
4310
4364
|
if (process.platform === "darwin") {
|
|
4311
4365
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
4312
|
-
if (
|
|
4366
|
+
if (existsSync21(macPath)) {
|
|
4313
4367
|
roots.push(macPath);
|
|
4314
4368
|
}
|
|
4315
4369
|
}
|
|
@@ -4327,23 +4381,23 @@ function resolvePreferredNodeBinary() {
|
|
|
4327
4381
|
const candidates = [];
|
|
4328
4382
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
4329
4383
|
if (envNode) {
|
|
4330
|
-
const explicit =
|
|
4331
|
-
if (
|
|
4384
|
+
const explicit = resolve21(envNode);
|
|
4385
|
+
if (existsSync21(explicit)) {
|
|
4332
4386
|
return explicit;
|
|
4333
4387
|
}
|
|
4334
4388
|
}
|
|
4335
4389
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
4336
4390
|
if (nvmBin) {
|
|
4337
|
-
candidates.push(
|
|
4391
|
+
candidates.push(resolve21(nvmBin, "node"));
|
|
4338
4392
|
}
|
|
4339
4393
|
const home = process.env.HOME?.trim();
|
|
4340
4394
|
if (home) {
|
|
4341
|
-
const nvmVersionsDir =
|
|
4342
|
-
if (
|
|
4395
|
+
const nvmVersionsDir = resolve21(home, ".nvm/versions/node");
|
|
4396
|
+
if (existsSync21(nvmVersionsDir)) {
|
|
4343
4397
|
try {
|
|
4344
|
-
const versionDirs =
|
|
4398
|
+
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/, "")));
|
|
4345
4399
|
for (const versionDir of versionDirs) {
|
|
4346
|
-
candidates.push(
|
|
4400
|
+
candidates.push(resolve21(nvmVersionsDir, versionDir, "bin/node"));
|
|
4347
4401
|
}
|
|
4348
4402
|
} catch {}
|
|
4349
4403
|
}
|
|
@@ -4352,8 +4406,8 @@ function resolvePreferredNodeBinary() {
|
|
|
4352
4406
|
if (whichNode) {
|
|
4353
4407
|
candidates.push(whichNode);
|
|
4354
4408
|
}
|
|
4355
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
4356
|
-
const existing = deduped.filter((candidate) =>
|
|
4409
|
+
const deduped = uniq(candidates.map((candidate) => resolve21(candidate)));
|
|
4410
|
+
const existing = deduped.filter((candidate) => existsSync21(candidate));
|
|
4357
4411
|
if (existing.length === 0) {
|
|
4358
4412
|
return null;
|
|
4359
4413
|
}
|
|
@@ -4367,7 +4421,7 @@ function resolvePreferredNodeBinary() {
|
|
|
4367
4421
|
return existing[0] ?? null;
|
|
4368
4422
|
}
|
|
4369
4423
|
function inferNodeMajor(nodeBinaryPath) {
|
|
4370
|
-
const normalized =
|
|
4424
|
+
const normalized = resolve21(nodeBinaryPath).replace(/\\/g, "/");
|
|
4371
4425
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
4372
4426
|
if (!match) {
|
|
4373
4427
|
return null;
|
|
@@ -4379,8 +4433,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
4379
4433
|
if (!candidate) {
|
|
4380
4434
|
return "";
|
|
4381
4435
|
}
|
|
4382
|
-
const normalized =
|
|
4383
|
-
if (!
|
|
4436
|
+
const normalized = resolve21(candidate);
|
|
4437
|
+
if (!existsSync21(normalized)) {
|
|
4384
4438
|
return "";
|
|
4385
4439
|
}
|
|
4386
4440
|
try {
|
|
@@ -4390,7 +4444,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
4390
4444
|
}
|
|
4391
4445
|
}
|
|
4392
4446
|
function looksLikeRuntimeGateway(candidate) {
|
|
4393
|
-
const normalized =
|
|
4447
|
+
const normalized = resolve21(candidate).replace(/\\/g, "/");
|
|
4394
4448
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
4395
4449
|
}
|
|
4396
4450
|
|
|
@@ -4411,7 +4465,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4411
4465
|
try {
|
|
4412
4466
|
return resolveClaudeInstallDir();
|
|
4413
4467
|
} catch {
|
|
4414
|
-
return
|
|
4468
|
+
return resolve22(claudeBinary, "..");
|
|
4415
4469
|
}
|
|
4416
4470
|
})() : "";
|
|
4417
4471
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -4421,8 +4475,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4421
4475
|
`${bunDir}/bin`,
|
|
4422
4476
|
claudeDir,
|
|
4423
4477
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
4424
|
-
realHome ?
|
|
4425
|
-
realHome ?
|
|
4478
|
+
realHome ? resolve22(realHome, ".local/bin") : "",
|
|
4479
|
+
realHome ? resolve22(realHome, ".cargo/bin") : "",
|
|
4426
4480
|
...inheritedPath,
|
|
4427
4481
|
"/usr/local/bin",
|
|
4428
4482
|
"/usr/local/sbin",
|
|
@@ -4451,8 +4505,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4451
4505
|
}
|
|
4452
4506
|
|
|
4453
4507
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
4454
|
-
import { existsSync as
|
|
4455
|
-
import { resolve as
|
|
4508
|
+
import { existsSync as existsSync22, readFileSync as readFileSync10 } from "fs";
|
|
4509
|
+
import { resolve as resolve23 } from "path";
|
|
4456
4510
|
var BAKED_RUNTIME_SECRETS = {
|
|
4457
4511
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
4458
4512
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -4495,12 +4549,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
4495
4549
|
return resolved;
|
|
4496
4550
|
}
|
|
4497
4551
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
4498
|
-
const dotenvPath =
|
|
4499
|
-
if (!
|
|
4552
|
+
const dotenvPath = resolve23(projectRoot, ".env");
|
|
4553
|
+
if (!existsSync22(dotenvPath)) {
|
|
4500
4554
|
return {};
|
|
4501
4555
|
}
|
|
4502
4556
|
const parsed = {};
|
|
4503
|
-
const lines =
|
|
4557
|
+
const lines = readFileSync10(dotenvPath, "utf-8").split(/\r?\n/);
|
|
4504
4558
|
for (const rawLine of lines) {
|
|
4505
4559
|
const line = rawLine.trim();
|
|
4506
4560
|
if (!line || line.startsWith("#")) {
|
|
@@ -4857,16 +4911,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
4857
4911
|
for (const dep of deps) {
|
|
4858
4912
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
4859
4913
|
console.log(`=== ${dep} ===`);
|
|
4860
|
-
if (!
|
|
4914
|
+
if (!existsSync23(artifactDir)) {
|
|
4861
4915
|
console.log(` (no artifacts yet)
|
|
4862
4916
|
`);
|
|
4863
4917
|
continue;
|
|
4864
4918
|
}
|
|
4865
|
-
printArtifactSection(
|
|
4866
|
-
printArtifactSection(
|
|
4867
|
-
const changedFiles =
|
|
4868
|
-
if (
|
|
4869
|
-
const lines =
|
|
4919
|
+
printArtifactSection(resolve24(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
4920
|
+
printArtifactSection(resolve24(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
4921
|
+
const changedFiles = resolve24(artifactDir, "changed-files.txt");
|
|
4922
|
+
if (existsSync23(changedFiles)) {
|
|
4923
|
+
const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
4870
4924
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
4871
4925
|
for (const line of lines) {
|
|
4872
4926
|
console.log(line);
|
|
@@ -4990,12 +5044,12 @@ function printIndented(text) {
|
|
|
4990
5044
|
}
|
|
4991
5045
|
}
|
|
4992
5046
|
function readLocalBeadsTasks(projectRoot) {
|
|
4993
|
-
const issuesPath =
|
|
4994
|
-
if (!
|
|
5047
|
+
const issuesPath = resolve24(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5048
|
+
if (!existsSync23(issuesPath)) {
|
|
4995
5049
|
return [];
|
|
4996
5050
|
}
|
|
4997
5051
|
const tasks = [];
|
|
4998
|
-
for (const line of
|
|
5052
|
+
for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
4999
5053
|
const trimmed = line.trim();
|
|
5000
5054
|
if (!trimmed) {
|
|
5001
5055
|
continue;
|
|
@@ -5108,11 +5162,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5108
5162
|
return [...ids].sort();
|
|
5109
5163
|
}
|
|
5110
5164
|
function printArtifactSection(path, header) {
|
|
5111
|
-
if (!
|
|
5165
|
+
if (!existsSync23(path)) {
|
|
5112
5166
|
return;
|
|
5113
5167
|
}
|
|
5114
5168
|
console.log(header);
|
|
5115
|
-
process.stdout.write(
|
|
5169
|
+
process.stdout.write(readFileSync11(path, "utf-8"));
|
|
5116
5170
|
console.log("");
|
|
5117
5171
|
}
|
|
5118
5172
|
|
|
@@ -5214,7 +5268,7 @@ init_layout();
|
|
|
5214
5268
|
|
|
5215
5269
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5216
5270
|
init_layout();
|
|
5217
|
-
import { mkdirSync as
|
|
5271
|
+
import { mkdirSync as mkdirSync11 } from "fs";
|
|
5218
5272
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5219
5273
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5220
5274
|
const rootDir = layout.rigRoot;
|
|
@@ -5226,14 +5280,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5226
5280
|
const sessionDir = layout.sessionDir;
|
|
5227
5281
|
const runtimeDir = layout.runtimeDir;
|
|
5228
5282
|
const contextPath = layout.contextPath;
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5283
|
+
mkdirSync11(rootDir, { recursive: true });
|
|
5284
|
+
mkdirSync11(homeDir, { recursive: true });
|
|
5285
|
+
mkdirSync11(tmpDir, { recursive: true });
|
|
5286
|
+
mkdirSync11(cacheDir, { recursive: true });
|
|
5287
|
+
mkdirSync11(logsDir, { recursive: true });
|
|
5288
|
+
mkdirSync11(stateDir, { recursive: true });
|
|
5289
|
+
mkdirSync11(sessionDir, { recursive: true });
|
|
5290
|
+
mkdirSync11(runtimeDir, { recursive: true });
|
|
5237
5291
|
return {
|
|
5238
5292
|
rootDir,
|
|
5239
5293
|
homeDir,
|
|
@@ -5251,17 +5305,17 @@ import {
|
|
|
5251
5305
|
chmodSync as chmodSync5,
|
|
5252
5306
|
copyFileSync as copyFileSync5,
|
|
5253
5307
|
cpSync as cpSync2,
|
|
5254
|
-
existsSync as
|
|
5255
|
-
mkdirSync as
|
|
5308
|
+
existsSync as existsSync25,
|
|
5309
|
+
mkdirSync as mkdirSync12,
|
|
5256
5310
|
statSync as statSync5,
|
|
5257
|
-
writeFileSync as
|
|
5311
|
+
writeFileSync as writeFileSync10
|
|
5258
5312
|
} from "fs";
|
|
5259
5313
|
import { mkdir } from "fs/promises";
|
|
5260
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
5314
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve26 } from "path";
|
|
5261
5315
|
|
|
5262
5316
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
5263
|
-
import { existsSync as
|
|
5264
|
-
import { resolve as
|
|
5317
|
+
import { existsSync as existsSync24, readFileSync as readFileSync12, rmSync as rmSync9 } from "fs";
|
|
5318
|
+
import { resolve as resolve25 } from "path";
|
|
5265
5319
|
import { randomUUID } from "crypto";
|
|
5266
5320
|
var generatedCredentialFiles = new Set;
|
|
5267
5321
|
var credentialCleanupRegistered = false;
|
|
@@ -5286,7 +5340,7 @@ function resolveHostGitBinary() {
|
|
|
5286
5340
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
5287
5341
|
continue;
|
|
5288
5342
|
}
|
|
5289
|
-
if (
|
|
5343
|
+
if (existsSync24(candidate)) {
|
|
5290
5344
|
return candidate;
|
|
5291
5345
|
}
|
|
5292
5346
|
}
|
|
@@ -5352,7 +5406,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
5352
5406
|
}
|
|
5353
5407
|
}
|
|
5354
5408
|
async function tryReadGitHead(repoRoot) {
|
|
5355
|
-
if (!
|
|
5409
|
+
if (!existsSync24(resolve25(repoRoot, ".git"))) {
|
|
5356
5410
|
return;
|
|
5357
5411
|
}
|
|
5358
5412
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -5363,7 +5417,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
5363
5417
|
return value || undefined;
|
|
5364
5418
|
}
|
|
5365
5419
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
5366
|
-
if (!
|
|
5420
|
+
if (!existsSync24(resolve25(repoRoot, ".git"))) {
|
|
5367
5421
|
return [];
|
|
5368
5422
|
}
|
|
5369
5423
|
const files = new Set;
|
|
@@ -5399,7 +5453,7 @@ function registerCredentialCleanup(path) {
|
|
|
5399
5453
|
const cleanup = () => {
|
|
5400
5454
|
for (const filePath of generatedCredentialFiles) {
|
|
5401
5455
|
try {
|
|
5402
|
-
|
|
5456
|
+
rmSync9(filePath, { force: true });
|
|
5403
5457
|
} catch {}
|
|
5404
5458
|
}
|
|
5405
5459
|
generatedCredentialFiles.clear();
|
|
@@ -5454,20 +5508,23 @@ function hashProjectPath(workspaceDir) {
|
|
|
5454
5508
|
}
|
|
5455
5509
|
function resolveGithubCliBinaryPath() {
|
|
5456
5510
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
5457
|
-
if (explicit &&
|
|
5511
|
+
if (explicit && existsSync24(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
5458
5512
|
return explicit;
|
|
5459
5513
|
}
|
|
5460
|
-
const
|
|
5461
|
-
|
|
5462
|
-
return bunResolved;
|
|
5463
|
-
}
|
|
5464
|
-
for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
|
|
5465
|
-
if (existsSync23(candidate)) {
|
|
5514
|
+
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
5515
|
+
if (existsSync24(candidate)) {
|
|
5466
5516
|
return candidate;
|
|
5467
5517
|
}
|
|
5468
5518
|
}
|
|
5519
|
+
const bunResolved = Bun.which("gh");
|
|
5520
|
+
if (bunResolved && existsSync24(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
5521
|
+
return bunResolved;
|
|
5522
|
+
}
|
|
5469
5523
|
return "";
|
|
5470
5524
|
}
|
|
5525
|
+
function isRuntimeGatewayGhPath(candidate) {
|
|
5526
|
+
return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
|
|
5527
|
+
}
|
|
5471
5528
|
async function resolveGithubCliAuthToken(ghBinary = "") {
|
|
5472
5529
|
const gh = ghBinary || resolveGithubCliBinaryPath();
|
|
5473
5530
|
if (!gh) {
|
|
@@ -5494,17 +5551,17 @@ function resolveSystemCertBundlePath() {
|
|
|
5494
5551
|
"/opt/homebrew/etc/openssl@3/cert.pem"
|
|
5495
5552
|
];
|
|
5496
5553
|
for (const candidate of candidates) {
|
|
5497
|
-
if (candidate &&
|
|
5498
|
-
return
|
|
5554
|
+
if (candidate && existsSync24(candidate)) {
|
|
5555
|
+
return resolve25(candidate);
|
|
5499
5556
|
}
|
|
5500
5557
|
}
|
|
5501
5558
|
return "";
|
|
5502
5559
|
}
|
|
5503
5560
|
function readKnownHosts(path) {
|
|
5504
|
-
if (!
|
|
5561
|
+
if (!existsSync24(path)) {
|
|
5505
5562
|
return new Set;
|
|
5506
5563
|
}
|
|
5507
|
-
return new Set(
|
|
5564
|
+
return new Set(readFileSync12(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
5508
5565
|
}
|
|
5509
5566
|
|
|
5510
5567
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -5515,6 +5572,21 @@ var GITHUB_KNOWN_HOSTS = [
|
|
|
5515
5572
|
"github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
|
|
5516
5573
|
].join(`
|
|
5517
5574
|
`);
|
|
5575
|
+
function resolveControlPlaneSourceRoot(projectRoot) {
|
|
5576
|
+
const candidates = [
|
|
5577
|
+
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
5578
|
+
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
5579
|
+
resolve26(import.meta.dir, "../../../../.."),
|
|
5580
|
+
projectRoot
|
|
5581
|
+
].filter((value) => Boolean(value));
|
|
5582
|
+
for (const candidate of candidates) {
|
|
5583
|
+
const root = resolve26(candidate);
|
|
5584
|
+
if (existsSync25(resolve26(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
5585
|
+
return root;
|
|
5586
|
+
}
|
|
5587
|
+
}
|
|
5588
|
+
return "";
|
|
5589
|
+
}
|
|
5518
5590
|
async function runtimeEnv(projectRoot, runtime) {
|
|
5519
5591
|
const bunBinaryPath = resolveBunBinaryPath();
|
|
5520
5592
|
const bunDir = resolveBunInstallDir(bunBinaryPath);
|
|
@@ -5529,7 +5601,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5529
5601
|
try {
|
|
5530
5602
|
return resolveClaudeInstallDir();
|
|
5531
5603
|
} catch {
|
|
5532
|
-
return
|
|
5604
|
+
return resolve26(claudeBinaryPath, "..");
|
|
5533
5605
|
}
|
|
5534
5606
|
})() : "";
|
|
5535
5607
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -5544,8 +5616,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5544
5616
|
`${bunDir}/bin`,
|
|
5545
5617
|
claudeDir,
|
|
5546
5618
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
5547
|
-
realHome ?
|
|
5548
|
-
realHome ?
|
|
5619
|
+
realHome ? resolve26(realHome, ".local/bin") : "",
|
|
5620
|
+
realHome ? resolve26(realHome, ".cargo/bin") : "",
|
|
5549
5621
|
...inheritedPath,
|
|
5550
5622
|
"/usr/local/bin",
|
|
5551
5623
|
"/usr/local/sbin",
|
|
@@ -5556,18 +5628,22 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5556
5628
|
"/usr/sbin",
|
|
5557
5629
|
"/sbin"
|
|
5558
5630
|
].filter(Boolean);
|
|
5559
|
-
const runtimeBash =
|
|
5560
|
-
const runtimeRigGit =
|
|
5561
|
-
const preferredShell =
|
|
5631
|
+
const runtimeBash = resolve26(runtime.binDir, "bash");
|
|
5632
|
+
const runtimeRigGit = resolve26(runtime.binDir, runtimeRigGitFileName());
|
|
5633
|
+
const preferredShell = existsSync25(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
5562
5634
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
5635
|
+
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
5563
5636
|
const env = {
|
|
5564
5637
|
PROJECT_RIG_ROOT: projectRoot,
|
|
5565
5638
|
RIG_HOST_PROJECT_ROOT: projectRoot,
|
|
5639
|
+
...controlPlaneSourceRoot ? { RIG_CONTROL_PLANE_SOURCE_ROOT: controlPlaneSourceRoot } : {},
|
|
5566
5640
|
HOME: runtime.homeDir,
|
|
5567
5641
|
TMPDIR: runtime.tmpDir,
|
|
5568
5642
|
XDG_CACHE_HOME: runtime.cacheDir,
|
|
5569
5643
|
XDG_STATE_HOME: runtime.stateDir,
|
|
5570
5644
|
RIG_AGENT_ID: runtime.id,
|
|
5645
|
+
...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
|
|
5646
|
+
...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
|
|
5571
5647
|
RIG_TASK_ID: runtime.taskId,
|
|
5572
5648
|
RIG_TASK_RUNTIME_ID: runtime.id,
|
|
5573
5649
|
RIG_TASK_WORKSPACE: runtime.workspaceDir,
|
|
@@ -5575,30 +5651,30 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5575
5651
|
RIG_RUNTIME_MODE: runtime.mode,
|
|
5576
5652
|
RIG_RUNTIME_HOME: runtime.rootDir,
|
|
5577
5653
|
RIG_RUNTIME_BIN_DIR: runtime.binDir,
|
|
5578
|
-
...
|
|
5654
|
+
...existsSync25(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
|
|
5579
5655
|
RIG_BUN_PATH: bunBinaryPath,
|
|
5580
5656
|
...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
|
|
5581
|
-
RIG_AGENT_BIN:
|
|
5657
|
+
RIG_AGENT_BIN: resolve26(runtime.binDir, "rig-agent"),
|
|
5582
5658
|
RIG_HOOKS_ACTIVE: "1",
|
|
5583
5659
|
RIG_AUTO_PR_ON_COMPLETE: "1",
|
|
5584
|
-
RIG_POLICY_FILE:
|
|
5660
|
+
RIG_POLICY_FILE: resolve26(projectRoot, "rig/policy/policy.json"),
|
|
5585
5661
|
RIG_STATE_DIR: runtime.stateDir,
|
|
5586
5662
|
RIG_LOGS_DIR: runtime.logsDir,
|
|
5587
|
-
RIG_SESSION_FILE:
|
|
5663
|
+
RIG_SESSION_FILE: resolve26(runtime.sessionDir, "session.json"),
|
|
5588
5664
|
MONOREPO_ROOT: runtime.workspaceDir,
|
|
5589
5665
|
MONOREPO_MAIN_ROOT: monorepoMainRoot,
|
|
5590
|
-
TS_API_TESTS_DIR:
|
|
5666
|
+
TS_API_TESTS_DIR: resolve26(runtime.workspaceDir, "TSAPITests"),
|
|
5591
5667
|
BASH: preferredShell,
|
|
5592
5668
|
SHELL: preferredShell,
|
|
5593
5669
|
PATH: [...new Set(pathEntries)].join(delimiter2),
|
|
5594
5670
|
LANG: process.env.LANG ?? "en_US.UTF-8",
|
|
5595
5671
|
TERM: process.env.TERM ?? "xterm-256color",
|
|
5596
5672
|
PYTHONDONTWRITEBYTECODE: "1",
|
|
5597
|
-
PYTHONPYCACHEPREFIX:
|
|
5673
|
+
PYTHONPYCACHEPREFIX: resolve26(runtime.cacheDir, "python"),
|
|
5598
5674
|
...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
|
|
5599
5675
|
...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
|
|
5600
5676
|
CLAUDE_HOME: runtime.claudeHomeDir,
|
|
5601
|
-
PI_CODING_AGENT_DIR:
|
|
5677
|
+
PI_CODING_AGENT_DIR: resolve26(runtime.homeDir, ".pi", "agent"),
|
|
5602
5678
|
[RUNTIME_CONTEXT_ENV]: runtime.contextFile,
|
|
5603
5679
|
...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
|
|
5604
5680
|
...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
|
|
@@ -5609,16 +5685,16 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5609
5685
|
NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
|
|
5610
5686
|
} : {}
|
|
5611
5687
|
};
|
|
5612
|
-
const knownHostsPath =
|
|
5613
|
-
if (
|
|
5614
|
-
const agentSshKey =
|
|
5688
|
+
const knownHostsPath = resolve26(runtime.homeDir, ".ssh", "known_hosts");
|
|
5689
|
+
if (existsSync25(knownHostsPath)) {
|
|
5690
|
+
const agentSshKey = resolve26(runtime.homeDir, ".ssh", "rig-agent-key");
|
|
5615
5691
|
const sshParts = [
|
|
5616
5692
|
"ssh",
|
|
5617
5693
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
5618
5694
|
"-o StrictHostKeyChecking=yes",
|
|
5619
5695
|
"-F /dev/null"
|
|
5620
5696
|
];
|
|
5621
|
-
if (
|
|
5697
|
+
if (existsSync25(agentSshKey)) {
|
|
5622
5698
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
5623
5699
|
}
|
|
5624
5700
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -5655,7 +5731,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5655
5731
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
5656
5732
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
5657
5733
|
}
|
|
5658
|
-
if (
|
|
5734
|
+
if (existsSync25(runtime.contextFile)) {
|
|
5659
5735
|
const runtimeContext = loadRuntimeContext(runtime.contextFile);
|
|
5660
5736
|
Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
|
|
5661
5737
|
Object.assign(env, browserEnvFromContext(runtimeContext.browser));
|
|
@@ -5684,30 +5760,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
5684
5760
|
await mkdir(runtime.cacheDir, { recursive: true });
|
|
5685
5761
|
await provisionAgentSshKey(runtime.homeDir);
|
|
5686
5762
|
if (options.provider === "codex") {
|
|
5687
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
5763
|
+
const hasCodexAuth = await injectCodexAuth(resolve26(runtime.homeDir, ".codex"));
|
|
5688
5764
|
if (!hasCodexAuth) {
|
|
5689
5765
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
5690
5766
|
}
|
|
5691
5767
|
}
|
|
5692
5768
|
if (options.provider === "pi") {
|
|
5693
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
5769
|
+
const hasPiAuth = await injectPiAgentConfig(resolve26(runtime.homeDir, ".pi", "agent"));
|
|
5694
5770
|
if (!hasPiAuth) {
|
|
5695
5771
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
5696
5772
|
}
|
|
5697
5773
|
}
|
|
5698
5774
|
}
|
|
5699
5775
|
async function provisionClaudeHome(config) {
|
|
5700
|
-
|
|
5701
|
-
const workspaceSettings =
|
|
5702
|
-
const hostSettings =
|
|
5703
|
-
const projectSettings =
|
|
5776
|
+
mkdirSync12(config.claudeHomeDir, { recursive: true });
|
|
5777
|
+
const workspaceSettings = resolve26(config.workspaceDir, ".claude/settings.json");
|
|
5778
|
+
const hostSettings = resolve26(config.hostProjectRoot, ".claude/settings.json");
|
|
5779
|
+
const projectSettings = existsSync25(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
5704
5780
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
5705
|
-
if (
|
|
5706
|
-
|
|
5781
|
+
if (existsSync25(projectSettings)) {
|
|
5782
|
+
writeFileSync10(resolve26(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5707
5783
|
`, "utf-8");
|
|
5708
5784
|
}
|
|
5709
5785
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
5710
|
-
|
|
5786
|
+
writeFileSync10(resolve26(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
5711
5787
|
permissions: { defaultMode: "bypassPermissions" },
|
|
5712
5788
|
autoMemoryEnabled: false
|
|
5713
5789
|
}, null, 2));
|
|
@@ -5715,12 +5791,12 @@ async function provisionClaudeHome(config) {
|
|
|
5715
5791
|
if (!hasCredentials) {
|
|
5716
5792
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
5717
5793
|
}
|
|
5718
|
-
const realClaudeHome =
|
|
5719
|
-
if (process.env.HOME &&
|
|
5720
|
-
cpSync2(
|
|
5794
|
+
const realClaudeHome = resolve26(process.env.HOME ?? "", ".claude");
|
|
5795
|
+
if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "CLAUDE.md"))) {
|
|
5796
|
+
cpSync2(resolve26(realClaudeHome, "CLAUDE.md"), resolve26(config.claudeHomeDir, "CLAUDE.md"));
|
|
5721
5797
|
}
|
|
5722
|
-
if (process.env.HOME &&
|
|
5723
|
-
cpSync2(
|
|
5798
|
+
if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "agents"))) {
|
|
5799
|
+
cpSync2(resolve26(realClaudeHome, "agents"), resolve26(config.claudeHomeDir, "agents"), { recursive: true });
|
|
5724
5800
|
}
|
|
5725
5801
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
5726
5802
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -5731,10 +5807,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
5731
5807
|
if (!sourcePath) {
|
|
5732
5808
|
return "";
|
|
5733
5809
|
}
|
|
5734
|
-
const certsDir =
|
|
5735
|
-
const targetPath =
|
|
5810
|
+
const certsDir = resolve26(runtime.rootDir, "certs");
|
|
5811
|
+
const targetPath = resolve26(certsDir, "ca-certificates.pem");
|
|
5736
5812
|
await mkdir(certsDir, { recursive: true });
|
|
5737
|
-
let shouldCopy = !
|
|
5813
|
+
let shouldCopy = !existsSync25(targetPath);
|
|
5738
5814
|
if (!shouldCopy) {
|
|
5739
5815
|
try {
|
|
5740
5816
|
shouldCopy = statSync5(sourcePath).mtimeMs > statSync5(targetPath).mtimeMs;
|
|
@@ -5756,7 +5832,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
5756
5832
|
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';
|
|
5757
5833
|
}
|
|
5758
5834
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
5759
|
-
const secretsPath =
|
|
5835
|
+
const secretsPath = resolve26(runtimeRoot, "runtime-secrets.json");
|
|
5760
5836
|
const persisted = {};
|
|
5761
5837
|
for (const key of [
|
|
5762
5838
|
"GITHUB_TOKEN",
|
|
@@ -5775,12 +5851,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
5775
5851
|
if (Object.keys(persisted).length === 0) {
|
|
5776
5852
|
return;
|
|
5777
5853
|
}
|
|
5778
|
-
|
|
5854
|
+
writeFileSync10(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
5779
5855
|
`, "utf-8");
|
|
5780
5856
|
}
|
|
5781
5857
|
async function provisionAgentSshKey(homeDir) {
|
|
5782
|
-
const sshDir =
|
|
5783
|
-
if (!
|
|
5858
|
+
const sshDir = resolve26(homeDir, ".ssh");
|
|
5859
|
+
if (!existsSync25(sshDir)) {
|
|
5784
5860
|
await mkdir(sshDir, { recursive: true });
|
|
5785
5861
|
}
|
|
5786
5862
|
seedKnownHosts(sshDir);
|
|
@@ -5788,27 +5864,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
5788
5864
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
5789
5865
|
if (!privateKey) {
|
|
5790
5866
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
5791
|
-
if (!process.env.HOME || !
|
|
5867
|
+
if (!process.env.HOME || !existsSync25(hostKeyPath)) {
|
|
5792
5868
|
return;
|
|
5793
5869
|
}
|
|
5794
|
-
const agentKeyPath2 =
|
|
5795
|
-
if (!
|
|
5870
|
+
const agentKeyPath2 = resolve26(sshDir, "rig-agent-key");
|
|
5871
|
+
if (!existsSync25(agentKeyPath2)) {
|
|
5796
5872
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
5797
5873
|
chmodSync5(agentKeyPath2, 384);
|
|
5798
5874
|
}
|
|
5799
5875
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
5800
|
-
if (
|
|
5876
|
+
if (existsSync25(hostPubPath)) {
|
|
5801
5877
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
5802
|
-
if (!
|
|
5878
|
+
if (!existsSync25(agentPubPath)) {
|
|
5803
5879
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
5804
5880
|
}
|
|
5805
5881
|
}
|
|
5806
5882
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
5807
5883
|
return;
|
|
5808
5884
|
}
|
|
5809
|
-
const agentKeyPath =
|
|
5810
|
-
if (!
|
|
5811
|
-
|
|
5885
|
+
const agentKeyPath = resolve26(sshDir, "rig-agent-key");
|
|
5886
|
+
if (!existsSync25(agentKeyPath)) {
|
|
5887
|
+
writeFileSync10(agentKeyPath, privateKey, { mode: 384 });
|
|
5812
5888
|
}
|
|
5813
5889
|
writeSshConfig(sshDir, agentKeyPath);
|
|
5814
5890
|
}
|
|
@@ -5825,21 +5901,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
5825
5901
|
`;
|
|
5826
5902
|
}
|
|
5827
5903
|
function resolveHostSshKeyPath(homeDir) {
|
|
5828
|
-
const sshDir =
|
|
5904
|
+
const sshDir = resolve26(homeDir, ".ssh");
|
|
5829
5905
|
const candidates = [
|
|
5830
5906
|
"rig-agent-key",
|
|
5831
5907
|
"id_ed25519",
|
|
5832
5908
|
"id_ecdsa",
|
|
5833
5909
|
"id_rsa"
|
|
5834
|
-
].map((name) =>
|
|
5835
|
-
return candidates.find((candidate) =>
|
|
5910
|
+
].map((name) => resolve26(sshDir, name));
|
|
5911
|
+
return candidates.find((candidate) => existsSync25(candidate)) ?? resolve26(sshDir, "rig-agent-key");
|
|
5836
5912
|
}
|
|
5837
5913
|
function writeSshConfig(sshDir, keyPath) {
|
|
5838
|
-
const configPath =
|
|
5839
|
-
if (
|
|
5914
|
+
const configPath = resolve26(sshDir, "config");
|
|
5915
|
+
if (existsSync25(configPath)) {
|
|
5840
5916
|
return;
|
|
5841
5917
|
}
|
|
5842
|
-
const knownHostsPath =
|
|
5918
|
+
const knownHostsPath = resolve26(sshDir, "known_hosts");
|
|
5843
5919
|
const config = [
|
|
5844
5920
|
"Host github.com",
|
|
5845
5921
|
` IdentityFile ${keyPath}`,
|
|
@@ -5849,10 +5925,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
5849
5925
|
""
|
|
5850
5926
|
].join(`
|
|
5851
5927
|
`);
|
|
5852
|
-
|
|
5928
|
+
writeFileSync10(configPath, config, { mode: 420 });
|
|
5853
5929
|
}
|
|
5854
5930
|
function seedKnownHosts(sshDir) {
|
|
5855
|
-
const knownHostsPath =
|
|
5931
|
+
const knownHostsPath = resolve26(sshDir, "known_hosts");
|
|
5856
5932
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
5857
5933
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
5858
5934
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -5863,23 +5939,23 @@ function seedKnownHosts(sshDir) {
|
|
|
5863
5939
|
for (const line of missing) {
|
|
5864
5940
|
existingLines.add(line);
|
|
5865
5941
|
}
|
|
5866
|
-
|
|
5942
|
+
writeFileSync10(knownHostsPath, `${Array.from(existingLines).join(`
|
|
5867
5943
|
`)}
|
|
5868
5944
|
`, { mode: 420 });
|
|
5869
5945
|
} catch (err) {
|
|
5870
|
-
const hint =
|
|
5946
|
+
const hint = existsSync25(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
5871
5947
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
5872
5948
|
}
|
|
5873
5949
|
}
|
|
5874
5950
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
5875
5951
|
const projectHash = hashProjectPath(workspaceDir);
|
|
5876
|
-
const projectDir =
|
|
5877
|
-
|
|
5878
|
-
|
|
5952
|
+
const projectDir = resolve26(claudeHomeDir, "projects", projectHash);
|
|
5953
|
+
mkdirSync12(projectDir, { recursive: true });
|
|
5954
|
+
writeFileSync10(resolve26(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5879
5955
|
`, "utf-8");
|
|
5880
5956
|
}
|
|
5881
5957
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
5882
|
-
if (!
|
|
5958
|
+
if (!existsSync25(projectSettingsPath)) {
|
|
5883
5959
|
return {};
|
|
5884
5960
|
}
|
|
5885
5961
|
let parsed;
|
|
@@ -5925,7 +6001,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
5925
6001
|
return clone;
|
|
5926
6002
|
}
|
|
5927
6003
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
5928
|
-
const credentialsPath =
|
|
6004
|
+
const credentialsPath = resolve26(claudeHomeDir, ".credentials.json");
|
|
5929
6005
|
const platform = options.platform ?? process.platform;
|
|
5930
6006
|
if (platform === "darwin") {
|
|
5931
6007
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -5935,16 +6011,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
5935
6011
|
if (raw) {
|
|
5936
6012
|
try {
|
|
5937
6013
|
JSON.parse(raw);
|
|
5938
|
-
|
|
6014
|
+
writeFileSync10(credentialsPath, raw, { mode: 384 });
|
|
5939
6015
|
registerCredentialCleanup(credentialsPath);
|
|
5940
6016
|
return true;
|
|
5941
6017
|
} catch {}
|
|
5942
6018
|
}
|
|
5943
6019
|
}
|
|
5944
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6020
|
+
const hostClaudeHome = options.hostClaudeHome ? resolve26(options.hostClaudeHome) : process.env.CLAUDE_HOME?.trim() ? resolve26(process.env.CLAUDE_HOME) : process.env.HOME ? resolve26(process.env.HOME, ".claude") : "";
|
|
5945
6021
|
if (hostClaudeHome) {
|
|
5946
|
-
const realCredentials =
|
|
5947
|
-
if (
|
|
6022
|
+
const realCredentials = resolve26(hostClaudeHome, ".credentials.json");
|
|
6023
|
+
if (existsSync25(realCredentials)) {
|
|
5948
6024
|
cpSync2(realCredentials, credentialsPath);
|
|
5949
6025
|
return true;
|
|
5950
6026
|
}
|
|
@@ -5952,36 +6028,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
5952
6028
|
return false;
|
|
5953
6029
|
}
|
|
5954
6030
|
async function injectCodexAuth(codexHomeDir) {
|
|
5955
|
-
|
|
5956
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6031
|
+
mkdirSync12(codexHomeDir, { recursive: true });
|
|
6032
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve26(process.env.CODEX_HOME) : process.env.HOME ? resolve26(process.env.HOME, ".codex") : "";
|
|
5957
6033
|
if (!hostCodexHome) {
|
|
5958
6034
|
return false;
|
|
5959
6035
|
}
|
|
5960
|
-
const hostAuthPath =
|
|
5961
|
-
if (!
|
|
6036
|
+
const hostAuthPath = resolve26(hostCodexHome, "auth.json");
|
|
6037
|
+
if (!existsSync25(hostAuthPath)) {
|
|
5962
6038
|
return false;
|
|
5963
6039
|
}
|
|
5964
|
-
const runtimeAuthPath =
|
|
6040
|
+
const runtimeAuthPath = resolve26(codexHomeDir, "auth.json");
|
|
5965
6041
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
5966
6042
|
chmodSync5(runtimeAuthPath, 384);
|
|
5967
6043
|
return true;
|
|
5968
6044
|
}
|
|
5969
6045
|
async function injectPiAgentConfig(piAgentDir) {
|
|
5970
|
-
|
|
5971
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6046
|
+
mkdirSync12(piAgentDir, { recursive: true });
|
|
6047
|
+
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ? resolve26(process.env.PI_CODING_AGENT_DIR) : process.env.HOME ? resolve26(process.env.HOME, ".pi", "agent") : "";
|
|
5972
6048
|
if (!hostPiAgentDir) {
|
|
5973
6049
|
return false;
|
|
5974
6050
|
}
|
|
5975
|
-
const hostAuthPath =
|
|
5976
|
-
if (!
|
|
6051
|
+
const hostAuthPath = resolve26(hostPiAgentDir, "auth.json");
|
|
6052
|
+
if (!existsSync25(hostAuthPath)) {
|
|
5977
6053
|
return false;
|
|
5978
6054
|
}
|
|
5979
|
-
const runtimeAuthPath =
|
|
6055
|
+
const runtimeAuthPath = resolve26(piAgentDir, "auth.json");
|
|
5980
6056
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
5981
6057
|
chmodSync5(runtimeAuthPath, 384);
|
|
5982
|
-
const hostSettingsPath =
|
|
5983
|
-
if (
|
|
5984
|
-
const runtimeSettingsPath =
|
|
6058
|
+
const hostSettingsPath = resolve26(hostPiAgentDir, "settings.json");
|
|
6059
|
+
if (existsSync25(hostSettingsPath)) {
|
|
6060
|
+
const runtimeSettingsPath = resolve26(piAgentDir, "settings.json");
|
|
5985
6061
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
5986
6062
|
chmodSync5(runtimeSettingsPath, 384);
|
|
5987
6063
|
}
|
|
@@ -5989,13 +6065,13 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
5989
6065
|
}
|
|
5990
6066
|
|
|
5991
6067
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
5992
|
-
import { existsSync as
|
|
5993
|
-
import { resolve as
|
|
6068
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync13, statSync as statSync6, writeFileSync as writeFileSync11 } from "fs";
|
|
6069
|
+
import { resolve as resolve27 } from "path";
|
|
5994
6070
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
5995
6071
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
5996
6072
|
return {
|
|
5997
6073
|
type: "stdio",
|
|
5998
|
-
command:
|
|
6074
|
+
command: resolve27(options.binDir, "rig-tool-router"),
|
|
5999
6075
|
args: [],
|
|
6000
6076
|
env: {
|
|
6001
6077
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6004,26 +6080,26 @@ function buildRuntimeToolRouterServerConfig(options) {
|
|
|
6004
6080
|
};
|
|
6005
6081
|
}
|
|
6006
6082
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6007
|
-
const configPath =
|
|
6008
|
-
|
|
6083
|
+
const configPath = resolve27(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6084
|
+
mkdirSync13(options.stateDir, { recursive: true });
|
|
6009
6085
|
const payload = {
|
|
6010
6086
|
mcpServers: {
|
|
6011
6087
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6012
6088
|
}
|
|
6013
6089
|
};
|
|
6014
|
-
|
|
6090
|
+
writeFileSync11(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6015
6091
|
`, "utf-8");
|
|
6016
6092
|
return configPath;
|
|
6017
6093
|
}
|
|
6018
6094
|
if (false) {}
|
|
6019
6095
|
// packages/runtime/src/control-plane/runtime/isolation/discovery.ts
|
|
6020
6096
|
init_layout();
|
|
6021
|
-
import { existsSync as
|
|
6022
|
-
import { resolve as
|
|
6097
|
+
import { existsSync as existsSync30 } from "fs";
|
|
6098
|
+
import { resolve as resolve31 } from "path";
|
|
6023
6099
|
|
|
6024
6100
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6025
|
-
import { existsSync as
|
|
6026
|
-
import { dirname as dirname11, resolve as
|
|
6101
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync14, rmSync as rmSync10 } from "fs";
|
|
6102
|
+
import { dirname as dirname11, resolve as resolve28 } from "path";
|
|
6027
6103
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6028
6104
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6029
6105
|
if (explicit) {
|
|
@@ -6059,12 +6135,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6059
6135
|
}
|
|
6060
6136
|
async function provisionRuntimeWorktree(config) {
|
|
6061
6137
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6062
|
-
let hasValidWorktree =
|
|
6063
|
-
if (
|
|
6064
|
-
|
|
6138
|
+
let hasValidWorktree = existsSync27(resolve28(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6139
|
+
if (existsSync27(config.workspaceDir) && !hasValidWorktree) {
|
|
6140
|
+
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6065
6141
|
}
|
|
6066
6142
|
if (!hasValidWorktree) {
|
|
6067
|
-
|
|
6143
|
+
mkdirSync14(dirname11(config.workspaceDir), { recursive: true });
|
|
6068
6144
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6069
6145
|
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]);
|
|
6070
6146
|
if (add.exitCode !== 0) {
|
|
@@ -6246,31 +6322,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
6246
6322
|
|
|
6247
6323
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
6248
6324
|
import {
|
|
6249
|
-
existsSync as
|
|
6325
|
+
existsSync as existsSync29,
|
|
6250
6326
|
lstatSync,
|
|
6251
|
-
mkdirSync as
|
|
6252
|
-
readdirSync as
|
|
6253
|
-
readFileSync as
|
|
6254
|
-
rmSync as
|
|
6327
|
+
mkdirSync as mkdirSync16,
|
|
6328
|
+
readdirSync as readdirSync6,
|
|
6329
|
+
readFileSync as readFileSync14,
|
|
6330
|
+
rmSync as rmSync11,
|
|
6255
6331
|
statSync as statSync8,
|
|
6256
6332
|
symlinkSync as symlinkSync4
|
|
6257
6333
|
} from "fs";
|
|
6258
6334
|
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
6259
|
-
import { dirname as dirname13, resolve as
|
|
6335
|
+
import { dirname as dirname13, resolve as resolve30 } from "path";
|
|
6260
6336
|
|
|
6261
6337
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
6262
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
6338
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync28, mkdirSync as mkdirSync15, statSync as statSync7 } from "fs";
|
|
6263
6339
|
import { tmpdir as tmpdir6 } from "os";
|
|
6264
|
-
import { dirname as dirname12, resolve as
|
|
6265
|
-
var sharedRouterOutputDir =
|
|
6266
|
-
var sharedRouterOutputPath =
|
|
6340
|
+
import { dirname as dirname12, resolve as resolve29 } from "path";
|
|
6341
|
+
var sharedRouterOutputDir = resolve29(tmpdir6(), "rig-native");
|
|
6342
|
+
var sharedRouterOutputPath = resolve29(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
6267
6343
|
function runtimeClaudeToolRouterFileName() {
|
|
6268
6344
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
6269
6345
|
}
|
|
6270
6346
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
6271
|
-
const sourcePath =
|
|
6272
|
-
|
|
6273
|
-
const needsBuild = !
|
|
6347
|
+
const sourcePath = resolve29(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
6348
|
+
mkdirSync15(dirname12(outputPath), { recursive: true });
|
|
6349
|
+
const needsBuild = !existsSync28(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
|
|
6274
6350
|
if (!needsBuild) {
|
|
6275
6351
|
return outputPath;
|
|
6276
6352
|
}
|
|
@@ -6284,9 +6360,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
6284
6360
|
}
|
|
6285
6361
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
6286
6362
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
6287
|
-
const targetPath =
|
|
6288
|
-
|
|
6289
|
-
const needsCopy = !
|
|
6363
|
+
const targetPath = resolve29(targetDir, runtimeClaudeToolRouterFileName());
|
|
6364
|
+
mkdirSync15(targetDir, { recursive: true });
|
|
6365
|
+
const needsCopy = !existsSync28(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
|
|
6290
6366
|
if (needsCopy) {
|
|
6291
6367
|
copyFileSync6(sourcePath, targetPath);
|
|
6292
6368
|
chmodSync6(targetPath, 493);
|
|
@@ -6299,48 +6375,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
6299
6375
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
6300
6376
|
function resolveRigSourceRoot(projectRoot) {
|
|
6301
6377
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6302
|
-
if (hostProjectRoot &&
|
|
6378
|
+
if (hostProjectRoot && existsSync29(resolve30(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6303
6379
|
return hostProjectRoot;
|
|
6304
6380
|
}
|
|
6305
|
-
const fromModule =
|
|
6306
|
-
if (
|
|
6381
|
+
const fromModule = resolve30(import.meta.dir, "../../../../../..");
|
|
6382
|
+
if (existsSync29(resolve30(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6307
6383
|
return fromModule;
|
|
6308
6384
|
}
|
|
6309
6385
|
return projectRoot;
|
|
6310
6386
|
}
|
|
6311
6387
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
6312
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
6388
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve30(sessionDir, "session.json")]) {
|
|
6313
6389
|
removeSymbolicLink(path);
|
|
6314
6390
|
}
|
|
6315
6391
|
runtimePrepareTrackedPathsNative({
|
|
6316
6392
|
logsDir,
|
|
6317
6393
|
stateDir,
|
|
6318
6394
|
sessionDir,
|
|
6319
|
-
controlledBashLogFile:
|
|
6320
|
-
eventsFile:
|
|
6395
|
+
controlledBashLogFile: resolve30(logsDir, "controlled-bash.jsonl"),
|
|
6396
|
+
eventsFile: resolve30(logsDir, "control-plane.events.jsonl")
|
|
6321
6397
|
});
|
|
6322
6398
|
}
|
|
6323
6399
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
6324
6400
|
await mkdir2(stateDir, { recursive: true });
|
|
6325
6401
|
await mkdir2(sessionDir, { recursive: true });
|
|
6326
|
-
const failedApproachesPath =
|
|
6327
|
-
if (!
|
|
6402
|
+
const failedApproachesPath = resolve30(stateDir, "failed_approaches.md");
|
|
6403
|
+
if (!existsSync29(failedApproachesPath)) {
|
|
6328
6404
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
6329
6405
|
|
|
6330
6406
|
`);
|
|
6331
6407
|
}
|
|
6332
|
-
const hookTripsPath =
|
|
6333
|
-
if (!
|
|
6408
|
+
const hookTripsPath = resolve30(stateDir, "hook_trips.log");
|
|
6409
|
+
if (!existsSync29(hookTripsPath)) {
|
|
6334
6410
|
await writeFile(hookTripsPath, "");
|
|
6335
6411
|
}
|
|
6336
|
-
const sessionFile =
|
|
6412
|
+
const sessionFile = resolve30(sessionDir, "session.json");
|
|
6337
6413
|
if (taskId) {
|
|
6338
6414
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
6339
6415
|
}
|
|
6340
6416
|
}
|
|
6341
6417
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
6342
|
-
const artifactDir =
|
|
6343
|
-
const runtimeSnapshotDir =
|
|
6418
|
+
const artifactDir = resolve30(workspaceDir, "artifacts", taskId);
|
|
6419
|
+
const runtimeSnapshotDir = resolve30(artifactDir, "runtime-snapshots");
|
|
6344
6420
|
let preservedTrackedFiles = false;
|
|
6345
6421
|
for (const file of [
|
|
6346
6422
|
"changed-files.txt",
|
|
@@ -6356,13 +6432,13 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
6356
6432
|
preservedTrackedFiles = true;
|
|
6357
6433
|
continue;
|
|
6358
6434
|
}
|
|
6359
|
-
|
|
6435
|
+
rmSync11(resolve30(artifactDir, file), { force: true });
|
|
6360
6436
|
}
|
|
6361
6437
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
6362
6438
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
6363
6439
|
preservedTrackedFiles = true;
|
|
6364
6440
|
} else {
|
|
6365
|
-
|
|
6441
|
+
rmSync11(runtimeSnapshotDir, { recursive: true, force: true });
|
|
6366
6442
|
}
|
|
6367
6443
|
if (preservedTrackedFiles) {
|
|
6368
6444
|
console.log(`[rig-agent] Preserved tracked runtime artifact files in ${taskId}; skipped ephemeral cleanup for committed paths.`);
|
|
@@ -6395,28 +6471,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
6395
6471
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
6396
6472
|
}
|
|
6397
6473
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
6398
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
6399
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
6474
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve30(options.binDir, "rig"), rigSourceRoot);
|
|
6475
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve30(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
6400
6476
|
...options.runtimeSecretDefines,
|
|
6401
6477
|
AGENT_TASK_ID: options.taskId,
|
|
6402
6478
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6403
6479
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
6404
6480
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
6405
6481
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
6406
|
-
AGENT_BINARY_PATH:
|
|
6482
|
+
AGENT_BINARY_PATH: resolve30(options.binDir, "rig-agent"),
|
|
6407
6483
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
6408
6484
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
6409
6485
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
6410
6486
|
});
|
|
6411
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
6487
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve30(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
6412
6488
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6413
6489
|
AGENT_LOGS_DIR: options.logsDir,
|
|
6414
6490
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
6415
|
-
AGENT_TS_API_TESTS_DIR:
|
|
6416
|
-
AGENT_RIG_AGENT_BIN:
|
|
6491
|
+
AGENT_TS_API_TESTS_DIR: resolve30(options.workspaceDir, "TSAPITests"),
|
|
6492
|
+
AGENT_RIG_AGENT_BIN: resolve30(options.binDir, "rig-agent")
|
|
6417
6493
|
});
|
|
6418
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
6419
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
6494
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve30(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
6495
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve30(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
6420
6496
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6421
6497
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6422
6498
|
});
|
|
@@ -6425,15 +6501,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
6425
6501
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6426
6502
|
};
|
|
6427
6503
|
for (const hookName of hookNames) {
|
|
6428
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
6504
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve30(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
6429
6505
|
}
|
|
6430
|
-
const pluginsDir =
|
|
6431
|
-
if (
|
|
6432
|
-
for (const entry of
|
|
6506
|
+
const pluginsDir = resolve30(options.projectRoot, "rig/plugins");
|
|
6507
|
+
if (existsSync29(pluginsDir)) {
|
|
6508
|
+
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
6433
6509
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
6434
6510
|
if (!match)
|
|
6435
6511
|
continue;
|
|
6436
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
6512
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve30(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
6437
6513
|
}
|
|
6438
6514
|
}
|
|
6439
6515
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -6443,8 +6519,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
6443
6519
|
}
|
|
6444
6520
|
async function writeRuntimeManifest(config) {
|
|
6445
6521
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
6446
|
-
const binarySha256 = sha256Hex(
|
|
6447
|
-
const manifestPath =
|
|
6522
|
+
const binarySha256 = sha256Hex(readFileSync14(config.binaryPath));
|
|
6523
|
+
const manifestPath = resolve30(config.runtimeRoot, "manifest.json");
|
|
6448
6524
|
const manifest = {
|
|
6449
6525
|
runtimeId: config.runtimeId,
|
|
6450
6526
|
taskId: config.taskId,
|
|
@@ -6478,7 +6554,7 @@ function removeSymbolicLink(path) {
|
|
|
6478
6554
|
} catch {
|
|
6479
6555
|
return;
|
|
6480
6556
|
}
|
|
6481
|
-
|
|
6557
|
+
rmSync11(path, { force: true, recursive: true });
|
|
6482
6558
|
}
|
|
6483
6559
|
async function resetTrackedArtifactPath(workspaceDir, relativePath) {
|
|
6484
6560
|
const tracked = await runGitLsFiles(workspaceDir, relativePath);
|
|
@@ -6504,7 +6580,7 @@ async function restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, r
|
|
|
6504
6580
|
const retryDelayMs = options.retryDelayMs ?? GIT_INDEX_LOCK_RETRY_DELAY_MS;
|
|
6505
6581
|
const now = options.now ?? Date.now;
|
|
6506
6582
|
const statMtimeMs = options.statMtimeMs ?? readFileMtimeMs;
|
|
6507
|
-
const removeFile = options.removeFile ?? ((path) =>
|
|
6583
|
+
const removeFile = options.removeFile ?? ((path) => rmSync11(path, { force: true }));
|
|
6508
6584
|
const log = options.log ?? console.warn;
|
|
6509
6585
|
let lastOutput = "";
|
|
6510
6586
|
for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
|
|
@@ -6564,31 +6640,31 @@ function readFileMtimeMs(path) {
|
|
|
6564
6640
|
}
|
|
6565
6641
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
6566
6642
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
6567
|
-
const sourceNodeModules =
|
|
6568
|
-
if (!
|
|
6569
|
-
const runtimeHumoongate =
|
|
6570
|
-
if (
|
|
6571
|
-
const targetNodeModules =
|
|
6643
|
+
const sourceNodeModules = resolve30(monorepoRoot, "humoongate", "node_modules");
|
|
6644
|
+
if (!existsSync29(sourceNodeModules)) {} else {
|
|
6645
|
+
const runtimeHumoongate = resolve30(workspaceDir, "humoongate");
|
|
6646
|
+
if (existsSync29(resolve30(runtimeHumoongate, "package.json"))) {
|
|
6647
|
+
const targetNodeModules = resolve30(runtimeHumoongate, "node_modules");
|
|
6572
6648
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
6573
6649
|
}
|
|
6574
6650
|
}
|
|
6575
|
-
const runtimeHpNext =
|
|
6576
|
-
if (!
|
|
6651
|
+
const runtimeHpNext = resolve30(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
6652
|
+
if (!existsSync29(resolve30(runtimeHpNext, "package.json"))) {
|
|
6577
6653
|
return;
|
|
6578
6654
|
}
|
|
6579
|
-
const sourceHpNextNodeModules =
|
|
6580
|
-
const sourceMonorepoNodeModules =
|
|
6581
|
-
const targetHpNextNodeModules =
|
|
6582
|
-
if (
|
|
6655
|
+
const sourceHpNextNodeModules = resolve30(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
6656
|
+
const sourceMonorepoNodeModules = resolve30(monorepoRoot, "node_modules");
|
|
6657
|
+
const targetHpNextNodeModules = resolve30(runtimeHpNext, "node_modules");
|
|
6658
|
+
if (existsSync29(sourceHpNextNodeModules)) {
|
|
6583
6659
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
6584
6660
|
return;
|
|
6585
6661
|
}
|
|
6586
|
-
if (
|
|
6662
|
+
if (existsSync29(sourceMonorepoNodeModules)) {
|
|
6587
6663
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
6588
6664
|
}
|
|
6589
6665
|
}
|
|
6590
6666
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
6591
|
-
linkNodeModulesLayer(
|
|
6667
|
+
linkNodeModulesLayer(resolve30(monorepoRoot, "node_modules"), resolve30(workspaceDir, "node_modules"));
|
|
6592
6668
|
for (const relativePackageDir of [
|
|
6593
6669
|
"apps/native-app/apps/marketing",
|
|
6594
6670
|
"apps/native-app/apps/web",
|
|
@@ -6610,15 +6686,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
6610
6686
|
"packages/standard-plugin",
|
|
6611
6687
|
"packages/validator-kit"
|
|
6612
6688
|
]) {
|
|
6613
|
-
const workspacePackageDir =
|
|
6614
|
-
if (!
|
|
6689
|
+
const workspacePackageDir = resolve30(workspaceDir, relativePackageDir);
|
|
6690
|
+
if (!existsSync29(resolve30(workspacePackageDir, "package.json"))) {
|
|
6615
6691
|
continue;
|
|
6616
6692
|
}
|
|
6617
|
-
linkNodeModulesLayer(
|
|
6693
|
+
linkNodeModulesLayer(resolve30(monorepoRoot, relativePackageDir, "node_modules"), resolve30(workspacePackageDir, "node_modules"));
|
|
6618
6694
|
}
|
|
6619
6695
|
}
|
|
6620
6696
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
6621
|
-
if (!
|
|
6697
|
+
if (!existsSync29(sourceDir) || existsSync29(targetDir)) {
|
|
6622
6698
|
return;
|
|
6623
6699
|
}
|
|
6624
6700
|
try {
|
|
@@ -6627,16 +6703,16 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
6627
6703
|
} catch (error) {
|
|
6628
6704
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
6629
6705
|
}
|
|
6630
|
-
|
|
6706
|
+
mkdirSync16(dirname13(targetDir), { recursive: true });
|
|
6631
6707
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
6632
6708
|
}
|
|
6633
6709
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
6634
|
-
const hooksDir =
|
|
6635
|
-
const pluginsDir =
|
|
6636
|
-
const validatorsDir =
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6710
|
+
const hooksDir = resolve30(runtimeBinDir, "hooks");
|
|
6711
|
+
const pluginsDir = resolve30(runtimeBinDir, "plugins");
|
|
6712
|
+
const validatorsDir = resolve30(runtimeBinDir, "validators");
|
|
6713
|
+
mkdirSync16(hooksDir, { recursive: true });
|
|
6714
|
+
mkdirSync16(pluginsDir, { recursive: true });
|
|
6715
|
+
mkdirSync16(validatorsDir, { recursive: true });
|
|
6640
6716
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
6641
6717
|
}
|
|
6642
6718
|
function runtimeWorktreeId(workspaceDir) {
|
|
@@ -6645,7 +6721,7 @@ function runtimeWorktreeId(workspaceDir) {
|
|
|
6645
6721
|
|
|
6646
6722
|
// packages/runtime/src/control-plane/runtime/isolation/discovery.ts
|
|
6647
6723
|
async function readRuntimeMetadata(metadataPath) {
|
|
6648
|
-
if (!
|
|
6724
|
+
if (!existsSync30(metadataPath)) {
|
|
6649
6725
|
return null;
|
|
6650
6726
|
}
|
|
6651
6727
|
try {
|
|
@@ -6657,8 +6733,8 @@ async function readRuntimeMetadata(metadataPath) {
|
|
|
6657
6733
|
async function listAgentRuntimes(projectRoot) {
|
|
6658
6734
|
const runtimes = [];
|
|
6659
6735
|
const monorepoRoot = resolveMonorepoRoot3(projectRoot);
|
|
6660
|
-
const worktreesRoot =
|
|
6661
|
-
if (!
|
|
6736
|
+
const worktreesRoot = resolve31(monorepoRoot, ".worktrees");
|
|
6737
|
+
if (!existsSync30(worktreesRoot)) {
|
|
6662
6738
|
return [];
|
|
6663
6739
|
}
|
|
6664
6740
|
const workspaces = runtimeScanWorktreesNative(worktreesRoot);
|
|
@@ -6666,7 +6742,7 @@ async function listAgentRuntimes(projectRoot) {
|
|
|
6666
6742
|
let workspacePath = scan.workspaceDir;
|
|
6667
6743
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(workspacePath);
|
|
6668
6744
|
const rootDir = scan.runtimeDir || workspaceLayout.runtimeDir;
|
|
6669
|
-
const metadataPath = scan.metadataPath ||
|
|
6745
|
+
const metadataPath = scan.metadataPath || resolve31(rootDir, "runtime.json");
|
|
6670
6746
|
const contextFile = scan.contextPath || workspaceLayout.contextPath;
|
|
6671
6747
|
let mode = "worktree";
|
|
6672
6748
|
let createdAt = new Date().toISOString();
|
|
@@ -6682,7 +6758,7 @@ async function listAgentRuntimes(projectRoot) {
|
|
|
6682
6758
|
mode = metadata.mode;
|
|
6683
6759
|
createdAt = metadata.createdAt;
|
|
6684
6760
|
}
|
|
6685
|
-
if (
|
|
6761
|
+
if (existsSync30(contextFile)) {
|
|
6686
6762
|
try {
|
|
6687
6763
|
const ctx = loadRuntimeContext(contextFile);
|
|
6688
6764
|
taskId = ctx.taskId;
|
|
@@ -6702,13 +6778,13 @@ async function listAgentRuntimes(projectRoot) {
|
|
|
6702
6778
|
mode,
|
|
6703
6779
|
rootDir,
|
|
6704
6780
|
workspaceDir: workspacePath,
|
|
6705
|
-
homeDir:
|
|
6706
|
-
tmpDir:
|
|
6707
|
-
cacheDir:
|
|
6781
|
+
homeDir: resolve31(rootDir, "home"),
|
|
6782
|
+
tmpDir: resolve31(rootDir, "tmp"),
|
|
6783
|
+
cacheDir: resolve31(rootDir, "cache"),
|
|
6708
6784
|
logsDir,
|
|
6709
6785
|
stateDir,
|
|
6710
6786
|
sessionDir,
|
|
6711
|
-
claudeHomeDir:
|
|
6787
|
+
claudeHomeDir: resolve31(rootDir, "home", ".claude"),
|
|
6712
6788
|
contextFile,
|
|
6713
6789
|
binDir,
|
|
6714
6790
|
createdAt
|
|
@@ -6722,22 +6798,22 @@ function runtimeRootForCleanup(projectRoot, runtimeId) {
|
|
|
6722
6798
|
monorepoRoot = resolveMonorepoRoot3(projectRoot);
|
|
6723
6799
|
} catch {}
|
|
6724
6800
|
const workspaceRootCandidate = monorepoRoot ?? projectRoot;
|
|
6725
|
-
const initialWorkspaceDir =
|
|
6801
|
+
const initialWorkspaceDir = resolve31(workspaceRootCandidate, ".worktrees", runtimeWorktreeNameFromRuntimeId(runtimeId));
|
|
6726
6802
|
const runtimeRoot = resolveRuntimeWorkspaceLayout(initialWorkspaceDir).runtimeDir;
|
|
6727
6803
|
return { monorepoRoot, initialWorkspaceDir, runtimeRoot };
|
|
6728
6804
|
}
|
|
6729
6805
|
|
|
6730
6806
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
6731
|
-
import { existsSync as
|
|
6732
|
-
import { basename as basename9, resolve as
|
|
6807
|
+
import { existsSync as existsSync33, rmSync as rmSync12, writeFileSync as writeFileSync13 } from "fs";
|
|
6808
|
+
import { basename as basename9, resolve as resolve35 } from "path";
|
|
6733
6809
|
|
|
6734
6810
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
6735
|
-
import { existsSync as
|
|
6811
|
+
import { existsSync as existsSync32 } from "fs";
|
|
6736
6812
|
|
|
6737
6813
|
// packages/runtime/src/control-plane/runtime/guard.ts
|
|
6738
6814
|
import { optimizeNextInvocation } from "bun:jsc";
|
|
6739
|
-
import { existsSync as
|
|
6740
|
-
import { resolve as
|
|
6815
|
+
import { existsSync as existsSync31, readFileSync as readFileSync15, statSync as statSync9 } from "fs";
|
|
6816
|
+
import { resolve as resolve32 } from "path";
|
|
6741
6817
|
|
|
6742
6818
|
// packages/runtime/src/control-plane/runtime/guard-types.ts
|
|
6743
6819
|
var POLICY_VERSION = 1;
|
|
@@ -6800,8 +6876,8 @@ function loadPolicy(projectRoot) {
|
|
|
6800
6876
|
if (seededPolicyConfig) {
|
|
6801
6877
|
return seededPolicyConfig;
|
|
6802
6878
|
}
|
|
6803
|
-
const configPath =
|
|
6804
|
-
if (!
|
|
6879
|
+
const configPath = resolve32(projectRoot, "rig/policy/policy.json");
|
|
6880
|
+
if (!existsSync31(configPath)) {
|
|
6805
6881
|
return defaultPolicy();
|
|
6806
6882
|
}
|
|
6807
6883
|
let mtimeMs;
|
|
@@ -6815,7 +6891,7 @@ function loadPolicy(projectRoot) {
|
|
|
6815
6891
|
}
|
|
6816
6892
|
let parsed;
|
|
6817
6893
|
try {
|
|
6818
|
-
parsed = JSON.parse(
|
|
6894
|
+
parsed = JSON.parse(readFileSync15(configPath, "utf-8"));
|
|
6819
6895
|
} catch {
|
|
6820
6896
|
return defaultPolicy();
|
|
6821
6897
|
}
|
|
@@ -7031,28 +7107,28 @@ function resolveAction(mode, matched) {
|
|
|
7031
7107
|
}
|
|
7032
7108
|
function resolveAbsolutePath(projectRoot, rawPath) {
|
|
7033
7109
|
if (rawPath.startsWith("/"))
|
|
7034
|
-
return
|
|
7035
|
-
return
|
|
7110
|
+
return resolve32(rawPath);
|
|
7111
|
+
return resolve32(projectRoot, rawPath);
|
|
7036
7112
|
}
|
|
7037
7113
|
function isHarnessPath(projectRoot, rawPath) {
|
|
7038
7114
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7039
7115
|
const managedRoots = [
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7116
|
+
resolve32(projectRoot, "rig"),
|
|
7117
|
+
resolve32(projectRoot, ".rig"),
|
|
7118
|
+
resolve32(projectRoot, "artifacts")
|
|
7043
7119
|
];
|
|
7044
7120
|
return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
|
|
7045
7121
|
}
|
|
7046
7122
|
function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
|
|
7047
7123
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7048
7124
|
if (taskWorkspace) {
|
|
7049
|
-
const workspaceRigRoot =
|
|
7050
|
-
const workspaceArtifactsRoot =
|
|
7125
|
+
const workspaceRigRoot = resolve32(taskWorkspace, ".rig");
|
|
7126
|
+
const workspaceArtifactsRoot = resolve32(taskWorkspace, "artifacts");
|
|
7051
7127
|
if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
|
|
7052
7128
|
return true;
|
|
7053
7129
|
}
|
|
7054
7130
|
}
|
|
7055
|
-
const runtimeRoot =
|
|
7131
|
+
const runtimeRoot = resolve32(projectRoot, ".rig/runtime/agents");
|
|
7056
7132
|
return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
|
|
7057
7133
|
}
|
|
7058
7134
|
function isTestFile(path) {
|
|
@@ -7100,7 +7176,7 @@ function evaluateScope(policy, context, filePath, access) {
|
|
|
7100
7176
|
return allowed();
|
|
7101
7177
|
}
|
|
7102
7178
|
if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
|
|
7103
|
-
const absPath =
|
|
7179
|
+
const absPath = resolve32(filePath);
|
|
7104
7180
|
if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
|
|
7105
7181
|
const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
|
|
7106
7182
|
const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
|
|
@@ -7425,13 +7501,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
7425
7501
|
depRoots
|
|
7426
7502
|
};
|
|
7427
7503
|
const fsContext = {
|
|
7428
|
-
pathExists: (p) =>
|
|
7504
|
+
pathExists: (p) => existsSync32(p),
|
|
7429
7505
|
realPath: toRealPath
|
|
7430
7506
|
};
|
|
7431
7507
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
7432
7508
|
const seatbelt = Bun.which("sandbox-exec");
|
|
7433
7509
|
probed.push("sandbox-exec");
|
|
7434
|
-
if (seatbelt &&
|
|
7510
|
+
if (seatbelt && existsSync32(seatbelt)) {
|
|
7435
7511
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
7436
7512
|
if (SeatbeltBackendClass) {
|
|
7437
7513
|
return {
|
|
@@ -7552,10 +7628,10 @@ init_layout();
|
|
|
7552
7628
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
7553
7629
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
7554
7630
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
7555
|
-
const readyFile =
|
|
7556
|
-
const requestFile =
|
|
7557
|
-
|
|
7558
|
-
|
|
7631
|
+
const readyFile = resolve35(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
7632
|
+
const requestFile = resolve35(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
7633
|
+
rmSync12(readyFile, { force: true });
|
|
7634
|
+
rmSync12(requestFile, { force: true });
|
|
7559
7635
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
7560
7636
|
const useCompiledSidecar = shouldUseCompiledSnapshotSidecar(sidecarBinary);
|
|
7561
7637
|
const bunCli = useCompiledSidecar ? null : resolveBunCliInvocation();
|
|
@@ -7593,19 +7669,19 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
7593
7669
|
proc.kill("SIGTERM");
|
|
7594
7670
|
} catch {}
|
|
7595
7671
|
await proc.exited;
|
|
7596
|
-
|
|
7597
|
-
|
|
7672
|
+
rmSync12(readyFile, { force: true });
|
|
7673
|
+
rmSync12(requestFile, { force: true });
|
|
7598
7674
|
},
|
|
7599
7675
|
finalize: async (commandParts, exitCode) => {
|
|
7600
|
-
|
|
7676
|
+
writeFileSync13(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
7601
7677
|
`, "utf-8");
|
|
7602
7678
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
7603
7679
|
proc.exited,
|
|
7604
7680
|
stdoutTextPromise,
|
|
7605
7681
|
stderrTextPromise
|
|
7606
7682
|
]);
|
|
7607
|
-
|
|
7608
|
-
|
|
7683
|
+
rmSync12(readyFile, { force: true });
|
|
7684
|
+
rmSync12(requestFile, { force: true });
|
|
7609
7685
|
if (sidecarExitCode !== 0) {
|
|
7610
7686
|
throw new Error(`snapshot sidecar failed (${sidecarExitCode}): ${stderr || stdout}`);
|
|
7611
7687
|
}
|
|
@@ -7661,8 +7737,8 @@ async function runInAgentRuntime(options) {
|
|
|
7661
7737
|
const stdout = await new Response(proc.stdout).text();
|
|
7662
7738
|
const stderr = await new Response(proc.stderr).text();
|
|
7663
7739
|
try {
|
|
7664
|
-
await Bun.write(
|
|
7665
|
-
await Bun.write(
|
|
7740
|
+
await Bun.write(resolve35(options.runtime.logsDir, "agent-stdout.log"), stdout);
|
|
7741
|
+
await Bun.write(resolve35(options.runtime.logsDir, "agent-stderr.log"), stderr);
|
|
7666
7742
|
} catch {}
|
|
7667
7743
|
await snapshotSidecar.finalize(runtimeCommand, exitCode);
|
|
7668
7744
|
return {
|
|
@@ -7692,18 +7768,18 @@ function resolveInternalRuntimeCommand(command) {
|
|
|
7692
7768
|
}
|
|
7693
7769
|
async function cleanupAgentRuntime(options) {
|
|
7694
7770
|
const { monorepoRoot, initialWorkspaceDir, runtimeRoot } = runtimeRootForCleanup(options.projectRoot, options.id);
|
|
7695
|
-
const metadataPath =
|
|
7696
|
-
if (!
|
|
7771
|
+
const metadataPath = resolve35(runtimeRoot, "runtime.json");
|
|
7772
|
+
if (!existsSync33(runtimeRoot)) {
|
|
7697
7773
|
return;
|
|
7698
7774
|
}
|
|
7699
7775
|
let mode = "worktree";
|
|
7700
7776
|
let workspaceDir = "";
|
|
7701
7777
|
const metadata = await readRuntimeMetadata2(metadataPath);
|
|
7702
|
-
const metadataMatchesRequestedRuntime = metadata !== null && metadata.id === options.id &&
|
|
7778
|
+
const metadataMatchesRequestedRuntime = metadata !== null && metadata.id === options.id && resolve35(metadata.workspaceDir) === resolve35(initialWorkspaceDir);
|
|
7703
7779
|
if (metadata && metadataMatchesRequestedRuntime) {
|
|
7704
7780
|
mode = metadata.mode;
|
|
7705
7781
|
workspaceDir = metadata.workspaceDir;
|
|
7706
|
-
} else if (
|
|
7782
|
+
} else if (existsSync33(initialWorkspaceDir)) {
|
|
7707
7783
|
workspaceDir = initialWorkspaceDir;
|
|
7708
7784
|
}
|
|
7709
7785
|
const preservesTaskWorktree = metadataMatchesRequestedRuntime && metadata ? options.id === taskRuntimeId(metadata.taskId) : false;
|
|
@@ -7712,7 +7788,7 @@ async function cleanupAgentRuntime(options) {
|
|
|
7712
7788
|
} else if (mode === "worktree" && workspaceDir && preservesTaskWorktree) {
|
|
7713
7789
|
cleanupTaskRuntimeOverlay(workspaceDir);
|
|
7714
7790
|
}
|
|
7715
|
-
|
|
7791
|
+
rmSync12(runtimeRoot, { recursive: true, force: true });
|
|
7716
7792
|
}
|
|
7717
7793
|
function cleanupTaskRuntimeOverlay(workspaceDir) {
|
|
7718
7794
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir);
|
|
@@ -7728,17 +7804,17 @@ function cleanupTaskRuntimeOverlay(workspaceDir) {
|
|
|
7728
7804
|
layout.runtimeDir,
|
|
7729
7805
|
layout.contextPath
|
|
7730
7806
|
]) {
|
|
7731
|
-
|
|
7807
|
+
rmSync12(path, { recursive: true, force: true });
|
|
7732
7808
|
}
|
|
7733
7809
|
}
|
|
7734
7810
|
function resolveSnapshotSidecarScriptPath() {
|
|
7735
7811
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
7736
7812
|
}
|
|
7737
7813
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
7738
|
-
return
|
|
7814
|
+
return resolve35(binDir, "snapshot-sidecar");
|
|
7739
7815
|
}
|
|
7740
7816
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
7741
|
-
if (!
|
|
7817
|
+
if (!existsSync33(binaryPath)) {
|
|
7742
7818
|
return false;
|
|
7743
7819
|
}
|
|
7744
7820
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -7753,12 +7829,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
7753
7829
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
7754
7830
|
].filter((value) => Boolean(value));
|
|
7755
7831
|
for (const root of hostRoots) {
|
|
7756
|
-
const candidate =
|
|
7757
|
-
if (
|
|
7832
|
+
const candidate = resolve35(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
7833
|
+
if (existsSync33(candidate)) {
|
|
7758
7834
|
return candidate;
|
|
7759
7835
|
}
|
|
7760
7836
|
}
|
|
7761
|
-
return
|
|
7837
|
+
return resolve35(import.meta.dir, "..", fileName);
|
|
7762
7838
|
}
|
|
7763
7839
|
function resolveBunCliInvocation() {
|
|
7764
7840
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -7785,7 +7861,7 @@ function resolveBunCliInvocation() {
|
|
|
7785
7861
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
7786
7862
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
7787
7863
|
while (Date.now() < deadline) {
|
|
7788
|
-
if (
|
|
7864
|
+
if (existsSync33(readyFile)) {
|
|
7789
7865
|
return;
|
|
7790
7866
|
}
|
|
7791
7867
|
const exitCode = proc.exitCode;
|
|
@@ -7798,7 +7874,7 @@ async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, s
|
|
|
7798
7874
|
throw new Error(`snapshot sidecar did not become ready within ${SNAPSHOT_SIDECAR_READY_TIMEOUT_MS}ms`);
|
|
7799
7875
|
}
|
|
7800
7876
|
async function readRuntimeMetadata2(metadataPath) {
|
|
7801
|
-
if (!
|
|
7877
|
+
if (!existsSync33(metadataPath)) {
|
|
7802
7878
|
return null;
|
|
7803
7879
|
}
|
|
7804
7880
|
try {
|
|
@@ -7813,9 +7889,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
7813
7889
|
async function hydrateRuntimeMemory(options) {
|
|
7814
7890
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
7815
7891
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
7816
|
-
const hydratedPath =
|
|
7892
|
+
const hydratedPath = resolve36(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
7817
7893
|
try {
|
|
7818
|
-
await mkdir3(
|
|
7894
|
+
await mkdir3(resolve36(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
7819
7895
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
7820
7896
|
return {
|
|
7821
7897
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -7830,12 +7906,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
7830
7906
|
}
|
|
7831
7907
|
}
|
|
7832
7908
|
async function createRuntimeTaskRecordReader(options) {
|
|
7833
|
-
const legacyConfigPath =
|
|
7909
|
+
const legacyConfigPath = resolve36(options.projectRoot, ".rig", "task-config.json");
|
|
7834
7910
|
let pluginHostContext = null;
|
|
7835
7911
|
try {
|
|
7836
7912
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
7837
7913
|
} catch (error) {
|
|
7838
|
-
if (!
|
|
7914
|
+
if (!existsSync34(legacyConfigPath)) {
|
|
7839
7915
|
throw error;
|
|
7840
7916
|
}
|
|
7841
7917
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -7855,7 +7931,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7855
7931
|
source: "plugin"
|
|
7856
7932
|
};
|
|
7857
7933
|
}
|
|
7858
|
-
if (
|
|
7934
|
+
if (existsSync34(legacyConfigPath)) {
|
|
7859
7935
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
7860
7936
|
options.diagnostics?.(message);
|
|
7861
7937
|
console.warn(message);
|
|
@@ -7872,10 +7948,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7872
7948
|
};
|
|
7873
7949
|
}
|
|
7874
7950
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
7875
|
-
const jsonPath =
|
|
7876
|
-
if (
|
|
7951
|
+
const jsonPath = resolve36(projectRoot, "rig.config.json");
|
|
7952
|
+
if (existsSync34(jsonPath)) {
|
|
7877
7953
|
try {
|
|
7878
|
-
const parsed = JSON.parse(
|
|
7954
|
+
const parsed = JSON.parse(readFileSync16(jsonPath, "utf8"));
|
|
7879
7955
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7880
7956
|
const taskSource = parsed.taskSource;
|
|
7881
7957
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -7887,12 +7963,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
7887
7963
|
return null;
|
|
7888
7964
|
}
|
|
7889
7965
|
}
|
|
7890
|
-
const tsPath =
|
|
7891
|
-
if (!
|
|
7966
|
+
const tsPath = resolve36(projectRoot, "rig.config.ts");
|
|
7967
|
+
if (!existsSync34(tsPath)) {
|
|
7892
7968
|
return null;
|
|
7893
7969
|
}
|
|
7894
7970
|
try {
|
|
7895
|
-
const source =
|
|
7971
|
+
const source = readFileSync16(tsPath, "utf8");
|
|
7896
7972
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
7897
7973
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
7898
7974
|
return kind ?? null;
|
|
@@ -7962,8 +8038,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
7962
8038
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
7963
8039
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
7964
8040
|
};
|
|
7965
|
-
const configPath =
|
|
7966
|
-
await mkdir3(
|
|
8041
|
+
const configPath = resolve36(options.workspaceDir, ".rig", "task-config.json");
|
|
8042
|
+
await mkdir3(resolve36(options.workspaceDir, ".rig"), { recursive: true });
|
|
7967
8043
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
7968
8044
|
`, "utf-8");
|
|
7969
8045
|
}
|
|
@@ -8027,9 +8103,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8027
8103
|
}
|
|
8028
8104
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8029
8105
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8030
|
-
const workspaceDir =
|
|
8106
|
+
const workspaceDir = resolve36(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8031
8107
|
const createdAt = new Date().toISOString();
|
|
8032
|
-
if (!
|
|
8108
|
+
if (!existsSync34(resolve36(monorepoRoot, ".git"))) {
|
|
8033
8109
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8034
8110
|
}
|
|
8035
8111
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8064,7 +8140,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8064
8140
|
logsDir: overlay.logsDir,
|
|
8065
8141
|
stateDir: overlay.stateDir,
|
|
8066
8142
|
sessionDir: overlay.sessionDir,
|
|
8067
|
-
claudeHomeDir:
|
|
8143
|
+
claudeHomeDir: resolve36(workspaceLayout.homeDir, ".claude"),
|
|
8068
8144
|
contextFile: overlay.contextPath,
|
|
8069
8145
|
binDir: workspaceLayout.binDir,
|
|
8070
8146
|
createdAt
|
|
@@ -8077,10 +8153,14 @@ async function ensureAgentRuntime(options) {
|
|
|
8077
8153
|
projectRoot: options.projectRoot,
|
|
8078
8154
|
workspaceDir
|
|
8079
8155
|
});
|
|
8080
|
-
|
|
8081
|
-
|
|
8156
|
+
mkdirSync19(runtime.binDir, { recursive: true });
|
|
8157
|
+
mkdirSync19(workspaceLayout.distDir, { recursive: true });
|
|
8082
8158
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8083
|
-
|
|
8159
|
+
if (options.preserveTaskArtifacts) {
|
|
8160
|
+
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
8161
|
+
} else {
|
|
8162
|
+
await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
|
|
8163
|
+
}
|
|
8084
8164
|
const ctx = {
|
|
8085
8165
|
runtimeId: options.id,
|
|
8086
8166
|
taskId: options.taskId,
|
|
@@ -8093,7 +8173,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8093
8173
|
runtimeId: options.id
|
|
8094
8174
|
}),
|
|
8095
8175
|
workspaceDir,
|
|
8096
|
-
artifactRoot:
|
|
8176
|
+
artifactRoot: resolve36(workspaceDir, "artifacts", options.taskId),
|
|
8097
8177
|
hostProjectRoot: options.projectRoot,
|
|
8098
8178
|
monorepoMainRoot: monorepoRoot,
|
|
8099
8179
|
monorepoBaseRef: baseRef,
|
|
@@ -8109,8 +8189,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8109
8189
|
stateDir: overlay.stateDir,
|
|
8110
8190
|
logsDir: overlay.logsDir,
|
|
8111
8191
|
sessionDir: overlay.sessionDir,
|
|
8112
|
-
sessionFile:
|
|
8113
|
-
policyFile:
|
|
8192
|
+
sessionFile: resolve36(overlay.sessionDir, "session.json"),
|
|
8193
|
+
policyFile: resolve36(options.projectRoot, "rig/policy/policy.json"),
|
|
8114
8194
|
binDir: runtime.binDir,
|
|
8115
8195
|
createdAt,
|
|
8116
8196
|
memory
|
|
@@ -8121,9 +8201,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8121
8201
|
task: taskResolution.task,
|
|
8122
8202
|
taskEntry
|
|
8123
8203
|
});
|
|
8124
|
-
const manifestPath =
|
|
8204
|
+
const manifestPath = resolve36(runtimeRoot, "manifest.json");
|
|
8125
8205
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8126
|
-
const runtimeAgentBinary =
|
|
8206
|
+
const runtimeAgentBinary = resolve36(runtime.binDir, "rig-agent");
|
|
8127
8207
|
await ensureRigGitBinaryPath();
|
|
8128
8208
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8129
8209
|
projectRoot: options.projectRoot,
|
|
@@ -8138,10 +8218,10 @@ async function ensureAgentRuntime(options) {
|
|
|
8138
8218
|
const bakedStatusOutput = await captureStdout(async () => {
|
|
8139
8219
|
taskStatus(options.projectRoot);
|
|
8140
8220
|
});
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8221
|
+
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8222
|
+
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8223
|
+
mkdirSync19(runtime.binDir, { recursive: true });
|
|
8224
|
+
mkdirSync19(workspaceLayout.distDir, { recursive: true });
|
|
8145
8225
|
await buildRuntimeToolchain({
|
|
8146
8226
|
projectRoot: options.projectRoot,
|
|
8147
8227
|
workspaceDir,
|
|
@@ -8178,9 +8258,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8178
8258
|
workspaceDir,
|
|
8179
8259
|
taskEntry
|
|
8180
8260
|
});
|
|
8181
|
-
const sandboxDir =
|
|
8261
|
+
const sandboxDir = resolve36(runtimeRoot, "sandbox");
|
|
8182
8262
|
await mkdir3(sandboxDir, { recursive: true });
|
|
8183
|
-
await writeFile2(
|
|
8263
|
+
await writeFile2(resolve36(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8184
8264
|
id: options.id,
|
|
8185
8265
|
taskId: options.taskId,
|
|
8186
8266
|
mode: "worktree",
|