@h-rig/runtime 0.0.6-alpha.27 → 0.0.6-alpha.29
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 +552 -483
- package/dist/bin/rig-agent.js +418 -364
- package/dist/src/control-plane/agent-wrapper.js +557 -488
- package/dist/src/control-plane/harness-main.js +559 -1418
- package/dist/src/control-plane/hooks/completion-verification.js +451 -808
- package/dist/src/control-plane/hooks/inject-context.js +191 -137
- package/dist/src/control-plane/hooks/submodule-branch.js +596 -542
- package/dist/src/control-plane/hooks/task-runtime-start.js +596 -542
- package/dist/src/control-plane/materialize-task-config.js +64 -8
- package/dist/src/control-plane/native/git-ops.js +3 -0
- package/dist/src/control-plane/native/harness-cli.js +544 -496
- package/dist/src/control-plane/native/repo-ops.js +3 -0
- package/dist/src/control-plane/native/run-ops.js +3 -0
- package/dist/src/control-plane/native/task-ops.js +418 -370
- package/dist/src/control-plane/native/validator.js +161 -107
- package/dist/src/control-plane/native/verifier.js +217 -169
- package/dist/src/control-plane/pi-sessiond/launcher.js +12 -2
- 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 +487 -718
- package/dist/src/control-plane/runtime/isolation/index.js +511 -457
- package/dist/src/control-plane/runtime/isolation.js +511 -457
- package/dist/src/control-plane/runtime/plugin-mode.js +3 -27
- package/dist/src/control-plane/runtime/queue.js +428 -381
- 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-lifecycle.js +84 -30
- package/dist/src/index.js +0 -278
- 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/package.json +8 -7
- package/dist/src/control-plane/runtime/plugins.js +0 -1131
- package/dist/src/plugins.js +0 -329
|
@@ -150,32 +150,32 @@ var RIG_DEFINITION_DIRNAME = "rig", RIG_ARTIFACTS_DIRNAME = "artifacts";
|
|
|
150
150
|
var init_layout = () => {};
|
|
151
151
|
|
|
152
152
|
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
153
|
-
import { existsSync as
|
|
154
|
-
import { resolve as
|
|
153
|
+
import { existsSync as existsSync20, readdirSync as readdirSync4, realpathSync } from "fs";
|
|
154
|
+
import { resolve as resolve20 } from "path";
|
|
155
155
|
function toRealPath(path) {
|
|
156
|
-
if (!
|
|
157
|
-
return
|
|
156
|
+
if (!existsSync20(path)) {
|
|
157
|
+
return resolve20(path);
|
|
158
158
|
}
|
|
159
159
|
try {
|
|
160
160
|
return realpathSync.native(path);
|
|
161
161
|
} catch {
|
|
162
|
-
return
|
|
162
|
+
return resolve20(path);
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
166
166
|
const candidates = new Set;
|
|
167
167
|
const addPath = (candidate) => {
|
|
168
|
-
if (
|
|
168
|
+
if (existsSync20(candidate)) {
|
|
169
169
|
candidates.add(toRealPath(candidate));
|
|
170
170
|
}
|
|
171
171
|
};
|
|
172
|
-
addPath(
|
|
173
|
-
addPath(
|
|
172
|
+
addPath(resolve20(projectRoot, ".git"));
|
|
173
|
+
addPath(resolve20(workspaceDir, "..", "..", ".git"));
|
|
174
174
|
for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
|
|
175
|
-
addPath(
|
|
175
|
+
addPath(resolve20(repoRoot, ".git"));
|
|
176
176
|
}
|
|
177
|
-
const workspaceGit =
|
|
178
|
-
if (
|
|
177
|
+
const workspaceGit = resolve20(workspaceDir, ".git");
|
|
178
|
+
if (existsSync20(workspaceGit)) {
|
|
179
179
|
addPath(workspaceGit);
|
|
180
180
|
}
|
|
181
181
|
return [...candidates];
|
|
@@ -183,7 +183,7 @@ function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
|
183
183
|
function resolveHostRepoRootPaths(projectRoot) {
|
|
184
184
|
const candidates = new Set;
|
|
185
185
|
const addPath = (candidate) => {
|
|
186
|
-
if (
|
|
186
|
+
if (existsSync20(candidate)) {
|
|
187
187
|
candidates.add(toRealPath(candidate));
|
|
188
188
|
}
|
|
189
189
|
};
|
|
@@ -193,11 +193,11 @@ function resolveHostRepoRootPaths(projectRoot) {
|
|
|
193
193
|
addPath(monorepoRoot);
|
|
194
194
|
}
|
|
195
195
|
} catch {}
|
|
196
|
-
const reposDir =
|
|
197
|
-
if (
|
|
198
|
-
for (const entry of
|
|
196
|
+
const reposDir = resolve20(projectRoot, "repos");
|
|
197
|
+
if (existsSync20(reposDir)) {
|
|
198
|
+
for (const entry of readdirSync4(reposDir, { withFileTypes: true })) {
|
|
199
199
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
200
|
-
addPath(
|
|
200
|
+
addPath(resolve20(reposDir, entry.name));
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
}
|
|
@@ -241,8 +241,8 @@ var exports_backend_seatbelt = {};
|
|
|
241
241
|
__export(exports_backend_seatbelt, {
|
|
242
242
|
SeatbeltBackend: () => SeatbeltBackend
|
|
243
243
|
});
|
|
244
|
-
import { mkdirSync as
|
|
245
|
-
import { resolve as
|
|
244
|
+
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync12 } from "fs";
|
|
245
|
+
import { resolve as resolve32 } from "path";
|
|
246
246
|
|
|
247
247
|
class SeatbeltBackend {
|
|
248
248
|
kind = "macos-seatbelt";
|
|
@@ -266,11 +266,11 @@ class SeatbeltBackend {
|
|
|
266
266
|
};
|
|
267
267
|
}
|
|
268
268
|
writeSeatbeltProfile(options) {
|
|
269
|
-
const sandboxDir =
|
|
270
|
-
|
|
271
|
-
const profilePath =
|
|
269
|
+
const sandboxDir = resolve32(options.runtime.rootDir, "sandbox");
|
|
270
|
+
mkdirSync17(sandboxDir, { recursive: true });
|
|
271
|
+
const profilePath = resolve32(sandboxDir, "seatbelt.sb");
|
|
272
272
|
const profile = this.renderProfile(options);
|
|
273
|
-
|
|
273
|
+
writeFileSync12(profilePath, `${profile}
|
|
274
274
|
`, "utf-8");
|
|
275
275
|
return profilePath;
|
|
276
276
|
}
|
|
@@ -355,7 +355,7 @@ class SeatbeltBackend {
|
|
|
355
355
|
const realHome = process.env.HOME?.trim();
|
|
356
356
|
if (realHome) {
|
|
357
357
|
for (const binSubdir of [".local/bin", ".cargo/bin"]) {
|
|
358
|
-
const binPath =
|
|
358
|
+
const binPath = resolve32(realHome, binSubdir);
|
|
359
359
|
if (ctx.pathExists(binPath)) {
|
|
360
360
|
lines.push(`(allow file-read* (subpath ${seatbeltString(ctx.realPath(binPath))}))`);
|
|
361
361
|
}
|
|
@@ -384,8 +384,8 @@ var exports_backend_bwrap = {};
|
|
|
384
384
|
__export(exports_backend_bwrap, {
|
|
385
385
|
BwrapBackend: () => BwrapBackend
|
|
386
386
|
});
|
|
387
|
-
import { mkdirSync as
|
|
388
|
-
import { resolve as
|
|
387
|
+
import { mkdirSync as mkdirSync18 } from "fs";
|
|
388
|
+
import { resolve as resolve33 } from "path";
|
|
389
389
|
|
|
390
390
|
class BwrapBackend {
|
|
391
391
|
kind = "linux-bwrap";
|
|
@@ -514,18 +514,18 @@ class BwrapBackend {
|
|
|
514
514
|
const realHome = process.env.HOME?.trim();
|
|
515
515
|
if (realHome) {
|
|
516
516
|
for (const binSubdir of [".local/bin", ".local/lib", ".cargo/bin"]) {
|
|
517
|
-
const binPath = ctx.realPath(
|
|
517
|
+
const binPath = ctx.realPath(resolve33(realHome, binSubdir));
|
|
518
518
|
if (ctx.pathExists(binPath)) {
|
|
519
519
|
args.push("--ro-bind", binPath, binPath);
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
|
-
const agentSshDir =
|
|
522
|
+
const agentSshDir = resolve33(homeReal, ".ssh");
|
|
523
523
|
if (ctx.pathExists(agentSshDir)) {
|
|
524
524
|
args.push("--ro-bind", agentSshDir, agentSshDir);
|
|
525
525
|
} else {
|
|
526
|
-
const hostSshDir =
|
|
526
|
+
const hostSshDir = resolve33(realHome, ".ssh");
|
|
527
527
|
if (ctx.pathExists(hostSshDir)) {
|
|
528
|
-
|
|
528
|
+
mkdirSync18(agentSshDir, { recursive: true });
|
|
529
529
|
args.push("--ro-bind", hostSshDir, agentSshDir);
|
|
530
530
|
args.push("--ro-bind", hostSshDir, hostSshDir);
|
|
531
531
|
}
|
|
@@ -568,8 +568,8 @@ var init_backend_bwrap = __esm(() => {
|
|
|
568
568
|
|
|
569
569
|
// packages/runtime/src/control-plane/agent-wrapper.ts
|
|
570
570
|
import { createRequire } from "module";
|
|
571
|
-
import { resolve as
|
|
572
|
-
import { existsSync as
|
|
571
|
+
import { resolve as resolve37 } from "path";
|
|
572
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync21, writeFileSync as writeFileSync14 } from "fs";
|
|
573
573
|
|
|
574
574
|
// packages/runtime/src/control-plane/runtime/context.ts
|
|
575
575
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -777,9 +777,9 @@ function isAgentRuntimeContextPath(path) {
|
|
|
777
777
|
}
|
|
778
778
|
|
|
779
779
|
// packages/runtime/src/control-plane/runtime/isolation/index.ts
|
|
780
|
-
import { existsSync as
|
|
780
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync19, readFileSync as readFileSync16, rmSync as rmSync13 } from "fs";
|
|
781
781
|
import { copyFile, mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
|
|
782
|
-
import { resolve as
|
|
782
|
+
import { resolve as resolve35 } from "path";
|
|
783
783
|
|
|
784
784
|
// packages/runtime/src/control-plane/native/git-native.ts
|
|
785
785
|
import { chmodSync, copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -1854,8 +1854,8 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
|
|
|
1854
1854
|
var DEFAULT_RESULT_LIMIT = DEFAULT_RUNTIME_MEMORY_RETRIEVAL.topK;
|
|
1855
1855
|
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
1856
1856
|
// packages/runtime/src/control-plane/native/task-ops.ts
|
|
1857
|
-
import { appendFileSync, existsSync as
|
|
1858
|
-
import { resolve as
|
|
1857
|
+
import { appendFileSync, existsSync as existsSync23, mkdirSync as mkdirSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
|
|
1858
|
+
import { resolve as resolve24 } from "path";
|
|
1859
1859
|
|
|
1860
1860
|
// packages/runtime/src/build-time-config.ts
|
|
1861
1861
|
function normalizeBuildConfig(value) {
|
|
@@ -2706,6 +2706,49 @@ function safeReadJson(path) {
|
|
|
2706
2706
|
}
|
|
2707
2707
|
}
|
|
2708
2708
|
|
|
2709
|
+
// packages/runtime/src/control-plane/skill-materializer.ts
|
|
2710
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync5, readdirSync, rmSync as rmSync7, writeFileSync as writeFileSync5 } from "fs";
|
|
2711
|
+
import { resolve as resolve12 } from "path";
|
|
2712
|
+
import { loadSkill } from "@rig/skill-loader";
|
|
2713
|
+
var MARKER_FILENAME = ".rig-plugin";
|
|
2714
|
+
function skillDirName(id) {
|
|
2715
|
+
return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
2716
|
+
}
|
|
2717
|
+
async function materializeSkills(projectRoot, entries) {
|
|
2718
|
+
const skillsRoot = resolve12(projectRoot, ".pi", "skills");
|
|
2719
|
+
if (existsSync12(skillsRoot)) {
|
|
2720
|
+
for (const name of readdirSync(skillsRoot)) {
|
|
2721
|
+
const dir = resolve12(skillsRoot, name);
|
|
2722
|
+
if (existsSync12(resolve12(dir, MARKER_FILENAME))) {
|
|
2723
|
+
rmSync7(dir, { recursive: true, force: true });
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
const written = [];
|
|
2728
|
+
for (const { pluginName, skill } of entries) {
|
|
2729
|
+
const sourcePath = resolve12(projectRoot, skill.path);
|
|
2730
|
+
if (!existsSync12(sourcePath)) {
|
|
2731
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
|
|
2732
|
+
continue;
|
|
2733
|
+
}
|
|
2734
|
+
let body;
|
|
2735
|
+
try {
|
|
2736
|
+
await loadSkill(sourcePath);
|
|
2737
|
+
body = readFileSync5(sourcePath, "utf-8");
|
|
2738
|
+
} catch (err) {
|
|
2739
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
|
|
2740
|
+
continue;
|
|
2741
|
+
}
|
|
2742
|
+
const dir = resolve12(skillsRoot, skillDirName(skill.id));
|
|
2743
|
+
mkdirSync8(dir, { recursive: true });
|
|
2744
|
+
writeFileSync5(resolve12(dir, "SKILL.md"), body, "utf-8");
|
|
2745
|
+
writeFileSync5(resolve12(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
|
|
2746
|
+
`, "utf-8");
|
|
2747
|
+
written.push({ id: skill.id, pluginName, directory: dir });
|
|
2748
|
+
}
|
|
2749
|
+
return written;
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2709
2752
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
2710
2753
|
async function buildPluginHostContext(projectRoot) {
|
|
2711
2754
|
let config;
|
|
@@ -2742,6 +2785,17 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2742
2785
|
} catch (err) {
|
|
2743
2786
|
console.warn(`[plugin-host] hook materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2744
2787
|
}
|
|
2788
|
+
try {
|
|
2789
|
+
const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
|
|
2790
|
+
pluginName: plugin.name,
|
|
2791
|
+
skill
|
|
2792
|
+
})));
|
|
2793
|
+
if (skillEntries.length > 0) {
|
|
2794
|
+
await materializeSkills(projectRoot, skillEntries);
|
|
2795
|
+
}
|
|
2796
|
+
} catch (err) {
|
|
2797
|
+
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2798
|
+
}
|
|
2745
2799
|
return {
|
|
2746
2800
|
config,
|
|
2747
2801
|
pluginHost,
|
|
@@ -2755,12 +2809,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2755
2809
|
|
|
2756
2810
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
2757
2811
|
import { spawnSync } from "child_process";
|
|
2758
|
-
import { existsSync as
|
|
2759
|
-
import { basename as basename4, join as join3, resolve as
|
|
2812
|
+
import { existsSync as existsSync14, readFileSync as readFileSync7, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
2813
|
+
import { basename as basename4, join as join3, resolve as resolve14 } from "path";
|
|
2760
2814
|
|
|
2761
2815
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
2762
|
-
import { existsSync as
|
|
2763
|
-
import { resolve as
|
|
2816
|
+
import { existsSync as existsSync13, readFileSync as readFileSync6 } from "fs";
|
|
2817
|
+
import { resolve as resolve13 } from "path";
|
|
2764
2818
|
|
|
2765
2819
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
2766
2820
|
async function findTaskById(reader, id) {
|
|
@@ -2783,7 +2837,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
2783
2837
|
}
|
|
2784
2838
|
}
|
|
2785
2839
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2786
|
-
const configPath = options.configPath ??
|
|
2840
|
+
const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
|
|
2787
2841
|
const reader = {
|
|
2788
2842
|
async listTasks() {
|
|
2789
2843
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -2794,8 +2848,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
2794
2848
|
};
|
|
2795
2849
|
return reader;
|
|
2796
2850
|
}
|
|
2797
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
2798
|
-
if (!
|
|
2851
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve13(projectRoot, ".rig", "task-config.json")) {
|
|
2852
|
+
if (!existsSync13(configPath)) {
|
|
2799
2853
|
return [];
|
|
2800
2854
|
}
|
|
2801
2855
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -2803,7 +2857,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve12(projectRoot,
|
|
|
2803
2857
|
}
|
|
2804
2858
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
2805
2859
|
try {
|
|
2806
|
-
const parsed = JSON.parse(
|
|
2860
|
+
const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
|
|
2807
2861
|
if (isPlainRecord(parsed)) {
|
|
2808
2862
|
return parsed;
|
|
2809
2863
|
}
|
|
@@ -2887,7 +2941,7 @@ function isPlainRecord(candidate) {
|
|
|
2887
2941
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
2888
2942
|
var FILE_TASK_PATTERN = /\.(task\.)?json$/;
|
|
2889
2943
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2890
|
-
const configPath = options.configPath ??
|
|
2944
|
+
const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
|
|
2891
2945
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
2892
2946
|
const spawnFn = options.spawn ?? spawnSync;
|
|
2893
2947
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -2978,10 +3032,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
2978
3032
|
return metadata;
|
|
2979
3033
|
}
|
|
2980
3034
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
2981
|
-
const jsonPath =
|
|
2982
|
-
if (
|
|
3035
|
+
const jsonPath = resolve14(projectRoot, "rig.config.json");
|
|
3036
|
+
if (existsSync14(jsonPath)) {
|
|
2983
3037
|
try {
|
|
2984
|
-
const parsed = JSON.parse(
|
|
3038
|
+
const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
|
|
2985
3039
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
2986
3040
|
const source = parsed.taskSource;
|
|
2987
3041
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -2990,12 +3044,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
2990
3044
|
return null;
|
|
2991
3045
|
}
|
|
2992
3046
|
}
|
|
2993
|
-
const tsPath =
|
|
2994
|
-
if (!
|
|
3047
|
+
const tsPath = resolve14(projectRoot, "rig.config.ts");
|
|
3048
|
+
if (!existsSync14(tsPath)) {
|
|
2995
3049
|
return null;
|
|
2996
3050
|
}
|
|
2997
3051
|
try {
|
|
2998
|
-
const source =
|
|
3052
|
+
const source = readFileSync7(tsPath, "utf8");
|
|
2999
3053
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3000
3054
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3001
3055
|
if (kind !== "files") {
|
|
@@ -3015,10 +3069,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
3015
3069
|
return isPlainRecord2(entry) ? entry : null;
|
|
3016
3070
|
}
|
|
3017
3071
|
function readRawTaskConfig(configPath) {
|
|
3018
|
-
if (!
|
|
3072
|
+
if (!existsSync14(configPath)) {
|
|
3019
3073
|
return null;
|
|
3020
3074
|
}
|
|
3021
|
-
const parsed = JSON.parse(
|
|
3075
|
+
const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
|
|
3022
3076
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
3023
3077
|
}
|
|
3024
3078
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -3026,12 +3080,12 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
3026
3080
|
return tasks;
|
|
3027
3081
|
}
|
|
3028
3082
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
3029
|
-
const directory =
|
|
3030
|
-
if (!
|
|
3083
|
+
const directory = resolve14(projectRoot, sourcePath);
|
|
3084
|
+
if (!existsSync14(directory)) {
|
|
3031
3085
|
return [];
|
|
3032
3086
|
}
|
|
3033
3087
|
const tasks = [];
|
|
3034
|
-
for (const name of
|
|
3088
|
+
for (const name of readdirSync2(directory)) {
|
|
3035
3089
|
if (!FILE_TASK_PATTERN.test(name))
|
|
3036
3090
|
continue;
|
|
3037
3091
|
const inferredId = basename4(name).replace(FILE_TASK_PATTERN, "");
|
|
@@ -3042,11 +3096,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
3042
3096
|
return tasks;
|
|
3043
3097
|
}
|
|
3044
3098
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
3045
|
-
const file = findFileBackedTaskFile(
|
|
3099
|
+
const file = findFileBackedTaskFile(resolve14(projectRoot, sourcePath), taskId);
|
|
3046
3100
|
if (!file) {
|
|
3047
3101
|
return null;
|
|
3048
3102
|
}
|
|
3049
|
-
const raw = JSON.parse(
|
|
3103
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
3050
3104
|
if (!isPlainRecord2(raw)) {
|
|
3051
3105
|
return null;
|
|
3052
3106
|
}
|
|
@@ -3059,17 +3113,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
3059
3113
|
};
|
|
3060
3114
|
}
|
|
3061
3115
|
function findFileBackedTaskFile(directory, taskId) {
|
|
3062
|
-
if (!
|
|
3116
|
+
if (!existsSync14(directory)) {
|
|
3063
3117
|
return null;
|
|
3064
3118
|
}
|
|
3065
|
-
for (const name of
|
|
3119
|
+
for (const name of readdirSync2(directory)) {
|
|
3066
3120
|
if (!FILE_TASK_PATTERN.test(name))
|
|
3067
3121
|
continue;
|
|
3068
3122
|
const file = join3(directory, name);
|
|
3069
3123
|
try {
|
|
3070
3124
|
if (!statSync3(file).isFile())
|
|
3071
3125
|
continue;
|
|
3072
|
-
const raw = JSON.parse(
|
|
3126
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
3073
3127
|
const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
|
|
3074
3128
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
3075
3129
|
if (id === taskId) {
|
|
@@ -3229,8 +3283,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
|
|
|
3229
3283
|
}
|
|
3230
3284
|
|
|
3231
3285
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
3232
|
-
import { existsSync as
|
|
3233
|
-
import { basename as basename6, resolve as
|
|
3286
|
+
import { existsSync as existsSync18, readFileSync as readFileSync9, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
3287
|
+
import { basename as basename6, resolve as resolve18 } from "path";
|
|
3234
3288
|
|
|
3235
3289
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
3236
3290
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -3338,39 +3392,39 @@ function readTaskStateMetadataEnvelope(raw) {
|
|
|
3338
3392
|
};
|
|
3339
3393
|
}
|
|
3340
3394
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
3341
|
-
import { existsSync as
|
|
3342
|
-
import { resolve as
|
|
3395
|
+
import { existsSync as existsSync17, readFileSync as readFileSync8 } from "fs";
|
|
3396
|
+
import { resolve as resolve17 } from "path";
|
|
3343
3397
|
|
|
3344
3398
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
3345
|
-
import { existsSync as
|
|
3346
|
-
import { resolve as
|
|
3399
|
+
import { existsSync as existsSync16 } from "fs";
|
|
3400
|
+
import { resolve as resolve16 } from "path";
|
|
3347
3401
|
|
|
3348
3402
|
// packages/runtime/src/control-plane/repos/layout.ts
|
|
3349
3403
|
init_layout();
|
|
3350
|
-
import { existsSync as
|
|
3351
|
-
import { basename as basename5, dirname as dirname9, join as join4, resolve as
|
|
3404
|
+
import { existsSync as existsSync15 } from "fs";
|
|
3405
|
+
import { basename as basename5, dirname as dirname9, join as join4, resolve as resolve15 } from "path";
|
|
3352
3406
|
function resolveRepoStateDir(projectRoot) {
|
|
3353
|
-
const normalizedProjectRoot =
|
|
3407
|
+
const normalizedProjectRoot = resolve15(projectRoot);
|
|
3354
3408
|
const projectParent = dirname9(normalizedProjectRoot);
|
|
3355
3409
|
if (basename5(projectParent) === ".worktrees") {
|
|
3356
3410
|
const ownerRoot = dirname9(projectParent);
|
|
3357
|
-
const ownerHasRepoMarkers =
|
|
3411
|
+
const ownerHasRepoMarkers = existsSync15(resolve15(ownerRoot, ".git")) || existsSync15(resolve15(ownerRoot, ".rig", "state"));
|
|
3358
3412
|
if (ownerHasRepoMarkers) {
|
|
3359
|
-
return
|
|
3413
|
+
return resolve15(ownerRoot, ".rig", "state");
|
|
3360
3414
|
}
|
|
3361
3415
|
}
|
|
3362
|
-
return
|
|
3416
|
+
return resolve15(projectRoot, ".rig", "state");
|
|
3363
3417
|
}
|
|
3364
3418
|
function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
3365
|
-
const normalizedProjectRoot =
|
|
3419
|
+
const normalizedProjectRoot = resolve15(projectRoot);
|
|
3366
3420
|
const entry = getManagedRepoEntry(repoId);
|
|
3367
3421
|
const stateDir = resolveRepoStateDir(normalizedProjectRoot);
|
|
3368
3422
|
const metadataRelativePath = join4("repos", entry.id);
|
|
3369
|
-
const metadataRoot =
|
|
3423
|
+
const metadataRoot = resolve15(stateDir, metadataRelativePath);
|
|
3370
3424
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3371
|
-
const runsInsideTaskWorktree = runtimeWorkspace &&
|
|
3425
|
+
const runsInsideTaskWorktree = runtimeWorkspace && resolve15(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
|
|
3372
3426
|
const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
|
|
3373
|
-
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ?
|
|
3427
|
+
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve15(process.env[entry.checkoutEnvVar].trim()) : resolve15(normalizedProjectRoot, entry.alias);
|
|
3374
3428
|
return {
|
|
3375
3429
|
projectRoot: normalizedProjectRoot,
|
|
3376
3430
|
repoId: entry.id,
|
|
@@ -3378,12 +3432,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
|
3378
3432
|
defaultBranch: entry.defaultBranch,
|
|
3379
3433
|
remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
|
|
3380
3434
|
checkoutRoot,
|
|
3381
|
-
worktreesRoot:
|
|
3435
|
+
worktreesRoot: resolve15(checkoutRoot, ".worktrees"),
|
|
3382
3436
|
stateDir,
|
|
3383
3437
|
metadataRoot,
|
|
3384
3438
|
metadataRelativePath,
|
|
3385
|
-
mirrorRoot:
|
|
3386
|
-
mirrorStatePath:
|
|
3439
|
+
mirrorRoot: resolve15(metadataRoot, "mirror.git"),
|
|
3440
|
+
mirrorStatePath: resolve15(metadataRoot, "mirror-state.json"),
|
|
3387
3441
|
mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
|
|
3388
3442
|
};
|
|
3389
3443
|
}
|
|
@@ -3401,7 +3455,7 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3401
3455
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3402
3456
|
try {
|
|
3403
3457
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
3404
|
-
if (
|
|
3458
|
+
if (existsSync16(resolve16(layout.mirrorRoot, "HEAD"))) {
|
|
3405
3459
|
return layout.mirrorRoot;
|
|
3406
3460
|
}
|
|
3407
3461
|
} catch {}
|
|
@@ -3412,8 +3466,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3412
3466
|
var DEFAULT_READ_DEPS2 = {
|
|
3413
3467
|
fetchRef: nativeFetchRef,
|
|
3414
3468
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
3415
|
-
exists:
|
|
3416
|
-
readFile: (path) =>
|
|
3469
|
+
exists: existsSync17,
|
|
3470
|
+
readFile: (path) => readFileSync8(path, "utf8")
|
|
3417
3471
|
};
|
|
3418
3472
|
function parseIssueStatus(rawStatus) {
|
|
3419
3473
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -3494,12 +3548,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
3494
3548
|
if (runtimeContextPath) {
|
|
3495
3549
|
return true;
|
|
3496
3550
|
}
|
|
3497
|
-
return
|
|
3551
|
+
return existsSync17(resolve17(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
3498
3552
|
}
|
|
3499
3553
|
function readLocalTrackerState(projectRoot, deps) {
|
|
3500
3554
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3501
|
-
const issuesPath =
|
|
3502
|
-
const taskStatePath =
|
|
3555
|
+
const issuesPath = resolve17(monorepoRoot, ".beads", "issues.jsonl");
|
|
3556
|
+
const taskStatePath = resolve17(monorepoRoot, ".beads", "task-state.json");
|
|
3503
3557
|
return projectSyncedTrackerSnapshot({
|
|
3504
3558
|
source: "local",
|
|
3505
3559
|
issuesBaseOid: null,
|
|
@@ -3561,7 +3615,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
3561
3615
|
return readValidationDescriptionMap(raw);
|
|
3562
3616
|
}
|
|
3563
3617
|
function readSourceValidationDescriptions(projectRoot) {
|
|
3564
|
-
const rootRaw = readJsonFile(
|
|
3618
|
+
const rootRaw = readJsonFile(resolve18(projectRoot, "rig", "task-config.json"), {});
|
|
3565
3619
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
3566
3620
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
3567
3621
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -3637,15 +3691,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
3637
3691
|
return meta.validation_descriptions;
|
|
3638
3692
|
}
|
|
3639
3693
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
3640
|
-
const taskStatePath =
|
|
3694
|
+
const taskStatePath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
3641
3695
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
3642
3696
|
}
|
|
3643
3697
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
3644
|
-
const issuesPath =
|
|
3645
|
-
if (!
|
|
3698
|
+
const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3699
|
+
if (!existsSync18(issuesPath)) {
|
|
3646
3700
|
return null;
|
|
3647
3701
|
}
|
|
3648
|
-
for (const line of
|
|
3702
|
+
for (const line of readFileSync9(issuesPath, "utf8").split(/\r?\n/)) {
|
|
3649
3703
|
const trimmed = line.trim();
|
|
3650
3704
|
if (!trimmed) {
|
|
3651
3705
|
continue;
|
|
@@ -3670,25 +3724,25 @@ function inferTaskIdFromRuntimePath(path) {
|
|
|
3670
3724
|
function artifactDirForId(projectRoot, id) {
|
|
3671
3725
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3672
3726
|
if (workspaceDir) {
|
|
3673
|
-
const worktreeArtifacts =
|
|
3674
|
-
if (
|
|
3727
|
+
const worktreeArtifacts = resolve18(workspaceDir, "artifacts", id);
|
|
3728
|
+
if (existsSync18(worktreeArtifacts) || existsSync18(resolve18(workspaceDir, "artifacts"))) {
|
|
3675
3729
|
return worktreeArtifacts;
|
|
3676
3730
|
}
|
|
3677
3731
|
}
|
|
3678
3732
|
try {
|
|
3679
3733
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3680
|
-
return
|
|
3734
|
+
return resolve18(paths.artifactsDir, id);
|
|
3681
3735
|
} catch {
|
|
3682
|
-
return
|
|
3736
|
+
return resolve18(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
3683
3737
|
}
|
|
3684
3738
|
}
|
|
3685
3739
|
function resolveTaskConfigPath(projectRoot) {
|
|
3686
3740
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3687
|
-
if (
|
|
3741
|
+
if (existsSync18(paths.taskConfigPath)) {
|
|
3688
3742
|
return paths.taskConfigPath;
|
|
3689
3743
|
}
|
|
3690
3744
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3691
|
-
if (
|
|
3745
|
+
if (existsSync18(candidate)) {
|
|
3692
3746
|
return candidate;
|
|
3693
3747
|
}
|
|
3694
3748
|
}
|
|
@@ -3696,7 +3750,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
3696
3750
|
}
|
|
3697
3751
|
function findSourceTaskConfigPath(projectRoot) {
|
|
3698
3752
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3699
|
-
if (
|
|
3753
|
+
if (existsSync18(candidate)) {
|
|
3700
3754
|
return candidate;
|
|
3701
3755
|
}
|
|
3702
3756
|
}
|
|
@@ -3709,7 +3763,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
3709
3763
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
3710
3764
|
if (sourcePath && synced.updated) {
|
|
3711
3765
|
try {
|
|
3712
|
-
|
|
3766
|
+
writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
3713
3767
|
`, "utf-8");
|
|
3714
3768
|
} catch {}
|
|
3715
3769
|
}
|
|
@@ -3761,12 +3815,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
3761
3815
|
return !candidate.role;
|
|
3762
3816
|
}
|
|
3763
3817
|
function readSourceIssueRecords(projectRoot) {
|
|
3764
|
-
const issuesPath =
|
|
3765
|
-
if (!
|
|
3818
|
+
const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3819
|
+
if (!existsSync18(issuesPath)) {
|
|
3766
3820
|
return [];
|
|
3767
3821
|
}
|
|
3768
3822
|
const records = [];
|
|
3769
|
-
for (const line of
|
|
3823
|
+
for (const line of readFileSync9(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
3770
3824
|
const trimmed = line.trim();
|
|
3771
3825
|
if (!trimmed) {
|
|
3772
3826
|
continue;
|
|
@@ -3822,19 +3876,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
3822
3876
|
if (!sourcePath) {
|
|
3823
3877
|
return {};
|
|
3824
3878
|
}
|
|
3825
|
-
const directory =
|
|
3826
|
-
if (!
|
|
3879
|
+
const directory = resolve18(projectRoot, sourcePath);
|
|
3880
|
+
if (!existsSync18(directory)) {
|
|
3827
3881
|
return {};
|
|
3828
3882
|
}
|
|
3829
3883
|
const config = {};
|
|
3830
|
-
for (const name of
|
|
3884
|
+
for (const name of readdirSync3(directory)) {
|
|
3831
3885
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
3832
3886
|
continue;
|
|
3833
|
-
const file =
|
|
3887
|
+
const file = resolve18(directory, name);
|
|
3834
3888
|
try {
|
|
3835
3889
|
if (!statSync4(file).isFile())
|
|
3836
3890
|
continue;
|
|
3837
|
-
const raw = JSON.parse(
|
|
3891
|
+
const raw = JSON.parse(readFileSync9(file, "utf8"));
|
|
3838
3892
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
3839
3893
|
continue;
|
|
3840
3894
|
const record = raw;
|
|
@@ -3876,10 +3930,10 @@ function firstStringList2(...candidates) {
|
|
|
3876
3930
|
return [];
|
|
3877
3931
|
}
|
|
3878
3932
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
3879
|
-
const jsonPath =
|
|
3880
|
-
if (
|
|
3933
|
+
const jsonPath = resolve18(projectRoot, "rig.config.json");
|
|
3934
|
+
if (existsSync18(jsonPath)) {
|
|
3881
3935
|
try {
|
|
3882
|
-
const parsed = JSON.parse(
|
|
3936
|
+
const parsed = JSON.parse(readFileSync9(jsonPath, "utf8"));
|
|
3883
3937
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3884
3938
|
const taskSource = parsed.taskSource;
|
|
3885
3939
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -3891,12 +3945,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3891
3945
|
return null;
|
|
3892
3946
|
}
|
|
3893
3947
|
}
|
|
3894
|
-
const tsPath =
|
|
3895
|
-
if (!
|
|
3948
|
+
const tsPath = resolve18(projectRoot, "rig.config.ts");
|
|
3949
|
+
if (!existsSync18(tsPath)) {
|
|
3896
3950
|
return null;
|
|
3897
3951
|
}
|
|
3898
3952
|
try {
|
|
3899
|
-
const source =
|
|
3953
|
+
const source = readFileSync9(tsPath, "utf8");
|
|
3900
3954
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3901
3955
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3902
3956
|
if (kind !== "files") {
|
|
@@ -3910,9 +3964,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3910
3964
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
3911
3965
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
3912
3966
|
return [
|
|
3913
|
-
runtimeContext?.monorepoMainRoot ?
|
|
3914
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
3915
|
-
|
|
3967
|
+
runtimeContext?.monorepoMainRoot ? resolve18(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
3968
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve18(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
3969
|
+
resolve18(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
3916
3970
|
].filter(Boolean);
|
|
3917
3971
|
}
|
|
3918
3972
|
|
|
@@ -3921,8 +3975,8 @@ init_layout();
|
|
|
3921
3975
|
|
|
3922
3976
|
// packages/runtime/src/binary-run.ts
|
|
3923
3977
|
init_layout();
|
|
3924
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
3925
|
-
import { basename as basename7, dirname as dirname10, resolve as
|
|
3978
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync19, mkdirSync as mkdirSync9, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
3979
|
+
import { basename as basename7, dirname as dirname10, resolve as resolve19 } from "path";
|
|
3926
3980
|
import { fileURLToPath } from "url";
|
|
3927
3981
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
3928
3982
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -3948,9 +4002,9 @@ async function buildRuntimeBinary(options) {
|
|
|
3948
4002
|
});
|
|
3949
4003
|
}
|
|
3950
4004
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
3951
|
-
const tempBuildDir =
|
|
3952
|
-
const tempOutputPath =
|
|
3953
|
-
|
|
4005
|
+
const tempBuildDir = resolve19(dirname10(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4006
|
+
const tempOutputPath = resolve19(tempBuildDir, basename7(options.outputPath));
|
|
4007
|
+
mkdirSync9(tempBuildDir, { recursive: true });
|
|
3954
4008
|
await withTemporaryEnv({
|
|
3955
4009
|
...options.env,
|
|
3956
4010
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -3975,7 +4029,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
3975
4029
|
`);
|
|
3976
4030
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
3977
4031
|
}
|
|
3978
|
-
if (!
|
|
4032
|
+
if (!existsSync19(tempOutputPath)) {
|
|
3979
4033
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
3980
4034
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
3981
4035
|
}
|
|
@@ -3990,7 +4044,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
3990
4044
|
});
|
|
3991
4045
|
}
|
|
3992
4046
|
})).finally(() => {
|
|
3993
|
-
|
|
4047
|
+
rmSync8(tempBuildDir, { recursive: true, force: true });
|
|
3994
4048
|
});
|
|
3995
4049
|
}
|
|
3996
4050
|
function runBestEffortBuildGc() {
|
|
@@ -4007,8 +4061,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4007
4061
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4008
4062
|
return {
|
|
4009
4063
|
...options,
|
|
4010
|
-
entrypoint:
|
|
4011
|
-
outputPath:
|
|
4064
|
+
entrypoint: resolve19(options.cwd, options.sourcePath),
|
|
4065
|
+
outputPath: resolve19(options.outputPath)
|
|
4012
4066
|
};
|
|
4013
4067
|
}
|
|
4014
4068
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4022,7 +4076,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4022
4076
|
}
|
|
4023
4077
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4024
4078
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4025
|
-
if (!workerSourcePath || !
|
|
4079
|
+
if (!workerSourcePath || !existsSync19(workerSourcePath)) {
|
|
4026
4080
|
await buildRuntimeBinaryInProcess(options, {
|
|
4027
4081
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4028
4082
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4053,13 +4107,13 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4053
4107
|
new Response(build.stdout).text(),
|
|
4054
4108
|
new Response(build.stderr).text()
|
|
4055
4109
|
]);
|
|
4056
|
-
|
|
4110
|
+
rmSync8(payloadPath, { force: true });
|
|
4057
4111
|
if (exitCode !== 0) {
|
|
4058
4112
|
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
4059
4113
|
}
|
|
4060
4114
|
}
|
|
4061
4115
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4062
|
-
return
|
|
4116
|
+
return resolve19(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4063
4117
|
}
|
|
4064
4118
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4065
4119
|
const envRoots = [
|
|
@@ -4068,13 +4122,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4068
4122
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4069
4123
|
].filter(Boolean);
|
|
4070
4124
|
for (const root of envRoots) {
|
|
4071
|
-
const candidate =
|
|
4072
|
-
if (
|
|
4125
|
+
const candidate = resolve19(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4126
|
+
if (existsSync19(candidate)) {
|
|
4073
4127
|
return candidate;
|
|
4074
4128
|
}
|
|
4075
4129
|
}
|
|
4076
|
-
const localCandidate =
|
|
4077
|
-
return
|
|
4130
|
+
const localCandidate = resolve19(import.meta.dir, "binary-build-worker.ts");
|
|
4131
|
+
return existsSync19(localCandidate) ? localCandidate : null;
|
|
4078
4132
|
}
|
|
4079
4133
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4080
4134
|
const bunPath = Bun.which("bun");
|
|
@@ -4110,7 +4164,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4110
4164
|
});
|
|
4111
4165
|
}
|
|
4112
4166
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4113
|
-
if (!
|
|
4167
|
+
if (!existsSync19(input.outputPath) || !existsSync19(input.manifestPath)) {
|
|
4114
4168
|
return false;
|
|
4115
4169
|
}
|
|
4116
4170
|
let manifest = null;
|
|
@@ -4123,7 +4177,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4123
4177
|
return false;
|
|
4124
4178
|
}
|
|
4125
4179
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4126
|
-
if (!
|
|
4180
|
+
if (!existsSync19(filePath)) {
|
|
4127
4181
|
return false;
|
|
4128
4182
|
}
|
|
4129
4183
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4136,7 +4190,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4136
4190
|
const inputs = {};
|
|
4137
4191
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4138
4192
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4139
|
-
if (!normalized || !
|
|
4193
|
+
if (!normalized || !existsSync19(normalized)) {
|
|
4140
4194
|
continue;
|
|
4141
4195
|
}
|
|
4142
4196
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4159,7 +4213,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4159
4213
|
if (inputPath.startsWith("<")) {
|
|
4160
4214
|
return null;
|
|
4161
4215
|
}
|
|
4162
|
-
return
|
|
4216
|
+
return resolve19(cwd, inputPath);
|
|
4163
4217
|
}
|
|
4164
4218
|
async function sha256File4(path) {
|
|
4165
4219
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4175,8 +4229,8 @@ function sortRecord(value) {
|
|
|
4175
4229
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4176
4230
|
const previous = runtimeBinaryBuildQueue;
|
|
4177
4231
|
let release;
|
|
4178
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4179
|
-
release =
|
|
4232
|
+
runtimeBinaryBuildQueue = new Promise((resolve20) => {
|
|
4233
|
+
release = resolve20;
|
|
4180
4234
|
});
|
|
4181
4235
|
await previous;
|
|
4182
4236
|
try {
|
|
@@ -4221,11 +4275,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4221
4275
|
}
|
|
4222
4276
|
|
|
4223
4277
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4224
|
-
import { delimiter, resolve as
|
|
4278
|
+
import { delimiter, resolve as resolve22 } from "path";
|
|
4225
4279
|
|
|
4226
4280
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
4227
|
-
import { existsSync as
|
|
4228
|
-
import { resolve as
|
|
4281
|
+
import { existsSync as existsSync21, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
4282
|
+
import { resolve as resolve21 } from "path";
|
|
4229
4283
|
|
|
4230
4284
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
4231
4285
|
init_utils();
|
|
@@ -4242,7 +4296,7 @@ function resolveBunBinaryPath() {
|
|
|
4242
4296
|
}
|
|
4243
4297
|
const home = process.env.HOME?.trim();
|
|
4244
4298
|
const fallbackCandidates = [
|
|
4245
|
-
home ?
|
|
4299
|
+
home ? resolve21(home, ".bun/bin/bun") : "",
|
|
4246
4300
|
"/opt/homebrew/bin/bun",
|
|
4247
4301
|
"/usr/local/bin/bun",
|
|
4248
4302
|
"/usr/bin/bun"
|
|
@@ -4270,8 +4324,8 @@ function resolveClaudeBinaryPath() {
|
|
|
4270
4324
|
}
|
|
4271
4325
|
const home = process.env.HOME?.trim();
|
|
4272
4326
|
const fallbackCandidates = [
|
|
4273
|
-
home ?
|
|
4274
|
-
home ?
|
|
4327
|
+
home ? resolve21(home, ".local/bin/claude") : "",
|
|
4328
|
+
home ? resolve21(home, ".local/share/claude/local/claude") : "",
|
|
4275
4329
|
"/opt/homebrew/bin/claude",
|
|
4276
4330
|
"/usr/local/bin/claude",
|
|
4277
4331
|
"/usr/bin/claude"
|
|
@@ -4285,35 +4339,35 @@ function resolveClaudeBinaryPath() {
|
|
|
4285
4339
|
throw new Error("claude not found in PATH");
|
|
4286
4340
|
}
|
|
4287
4341
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
4288
|
-
return
|
|
4342
|
+
return resolve21(bunBinaryPath, "../..");
|
|
4289
4343
|
}
|
|
4290
4344
|
function resolveClaudeInstallDir() {
|
|
4291
4345
|
const realPath = resolveClaudeBinaryPath();
|
|
4292
|
-
return
|
|
4346
|
+
return resolve21(realPath, "..");
|
|
4293
4347
|
}
|
|
4294
4348
|
function resolveNodeInstallDir() {
|
|
4295
4349
|
const preferredNode = resolvePreferredNodeBinary();
|
|
4296
4350
|
if (!preferredNode)
|
|
4297
4351
|
return null;
|
|
4298
4352
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
4299
|
-
if (explicitNode &&
|
|
4300
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
4353
|
+
if (explicitNode && resolve21(explicitNode) === resolve21(preferredNode)) {
|
|
4354
|
+
return preferredNode.endsWith("/bin/node") ? resolve21(preferredNode, "../..") : resolve21(preferredNode, "..");
|
|
4301
4355
|
}
|
|
4302
4356
|
try {
|
|
4303
4357
|
const realPath = realpathSync2(preferredNode);
|
|
4304
4358
|
if (realPath.endsWith("/bin/node")) {
|
|
4305
|
-
return
|
|
4359
|
+
return resolve21(realPath, "../..");
|
|
4306
4360
|
}
|
|
4307
|
-
return
|
|
4361
|
+
return resolve21(realPath, "..");
|
|
4308
4362
|
} catch {
|
|
4309
|
-
return
|
|
4363
|
+
return resolve21(preferredNode, "..");
|
|
4310
4364
|
}
|
|
4311
4365
|
}
|
|
4312
4366
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
4313
4367
|
const roots = [];
|
|
4314
4368
|
if (process.platform === "darwin") {
|
|
4315
4369
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
4316
|
-
if (
|
|
4370
|
+
if (existsSync21(macPath)) {
|
|
4317
4371
|
roots.push(macPath);
|
|
4318
4372
|
}
|
|
4319
4373
|
}
|
|
@@ -4331,23 +4385,23 @@ function resolvePreferredNodeBinary() {
|
|
|
4331
4385
|
const candidates = [];
|
|
4332
4386
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
4333
4387
|
if (envNode) {
|
|
4334
|
-
const explicit =
|
|
4335
|
-
if (
|
|
4388
|
+
const explicit = resolve21(envNode);
|
|
4389
|
+
if (existsSync21(explicit)) {
|
|
4336
4390
|
return explicit;
|
|
4337
4391
|
}
|
|
4338
4392
|
}
|
|
4339
4393
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
4340
4394
|
if (nvmBin) {
|
|
4341
|
-
candidates.push(
|
|
4395
|
+
candidates.push(resolve21(nvmBin, "node"));
|
|
4342
4396
|
}
|
|
4343
4397
|
const home = process.env.HOME?.trim();
|
|
4344
4398
|
if (home) {
|
|
4345
|
-
const nvmVersionsDir =
|
|
4346
|
-
if (
|
|
4399
|
+
const nvmVersionsDir = resolve21(home, ".nvm/versions/node");
|
|
4400
|
+
if (existsSync21(nvmVersionsDir)) {
|
|
4347
4401
|
try {
|
|
4348
|
-
const versionDirs =
|
|
4402
|
+
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/, "")));
|
|
4349
4403
|
for (const versionDir of versionDirs) {
|
|
4350
|
-
candidates.push(
|
|
4404
|
+
candidates.push(resolve21(nvmVersionsDir, versionDir, "bin/node"));
|
|
4351
4405
|
}
|
|
4352
4406
|
} catch {}
|
|
4353
4407
|
}
|
|
@@ -4356,8 +4410,8 @@ function resolvePreferredNodeBinary() {
|
|
|
4356
4410
|
if (whichNode) {
|
|
4357
4411
|
candidates.push(whichNode);
|
|
4358
4412
|
}
|
|
4359
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
4360
|
-
const existing = deduped.filter((candidate) =>
|
|
4413
|
+
const deduped = uniq(candidates.map((candidate) => resolve21(candidate)));
|
|
4414
|
+
const existing = deduped.filter((candidate) => existsSync21(candidate));
|
|
4361
4415
|
if (existing.length === 0) {
|
|
4362
4416
|
return null;
|
|
4363
4417
|
}
|
|
@@ -4371,7 +4425,7 @@ function resolvePreferredNodeBinary() {
|
|
|
4371
4425
|
return existing[0] ?? null;
|
|
4372
4426
|
}
|
|
4373
4427
|
function inferNodeMajor(nodeBinaryPath) {
|
|
4374
|
-
const normalized =
|
|
4428
|
+
const normalized = resolve21(nodeBinaryPath).replace(/\\/g, "/");
|
|
4375
4429
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
4376
4430
|
if (!match) {
|
|
4377
4431
|
return null;
|
|
@@ -4383,8 +4437,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
4383
4437
|
if (!candidate) {
|
|
4384
4438
|
return "";
|
|
4385
4439
|
}
|
|
4386
|
-
const normalized =
|
|
4387
|
-
if (!
|
|
4440
|
+
const normalized = resolve21(candidate);
|
|
4441
|
+
if (!existsSync21(normalized)) {
|
|
4388
4442
|
return "";
|
|
4389
4443
|
}
|
|
4390
4444
|
try {
|
|
@@ -4394,7 +4448,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
4394
4448
|
}
|
|
4395
4449
|
}
|
|
4396
4450
|
function looksLikeRuntimeGateway(candidate) {
|
|
4397
|
-
const normalized =
|
|
4451
|
+
const normalized = resolve21(candidate).replace(/\\/g, "/");
|
|
4398
4452
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
4399
4453
|
}
|
|
4400
4454
|
|
|
@@ -4415,7 +4469,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4415
4469
|
try {
|
|
4416
4470
|
return resolveClaudeInstallDir();
|
|
4417
4471
|
} catch {
|
|
4418
|
-
return
|
|
4472
|
+
return resolve22(claudeBinary, "..");
|
|
4419
4473
|
}
|
|
4420
4474
|
})() : "";
|
|
4421
4475
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -4425,8 +4479,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4425
4479
|
`${bunDir}/bin`,
|
|
4426
4480
|
claudeDir,
|
|
4427
4481
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
4428
|
-
realHome ?
|
|
4429
|
-
realHome ?
|
|
4482
|
+
realHome ? resolve22(realHome, ".local/bin") : "",
|
|
4483
|
+
realHome ? resolve22(realHome, ".cargo/bin") : "",
|
|
4430
4484
|
...inheritedPath,
|
|
4431
4485
|
"/usr/local/bin",
|
|
4432
4486
|
"/usr/local/sbin",
|
|
@@ -4455,8 +4509,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4455
4509
|
}
|
|
4456
4510
|
|
|
4457
4511
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
4458
|
-
import { existsSync as
|
|
4459
|
-
import { resolve as
|
|
4512
|
+
import { existsSync as existsSync22, readFileSync as readFileSync10 } from "fs";
|
|
4513
|
+
import { resolve as resolve23 } from "path";
|
|
4460
4514
|
var BAKED_RUNTIME_SECRETS = {
|
|
4461
4515
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
4462
4516
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -4499,12 +4553,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
4499
4553
|
return resolved;
|
|
4500
4554
|
}
|
|
4501
4555
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
4502
|
-
const dotenvPath =
|
|
4503
|
-
if (!
|
|
4556
|
+
const dotenvPath = resolve23(projectRoot, ".env");
|
|
4557
|
+
if (!existsSync22(dotenvPath)) {
|
|
4504
4558
|
return {};
|
|
4505
4559
|
}
|
|
4506
4560
|
const parsed = {};
|
|
4507
|
-
const lines =
|
|
4561
|
+
const lines = readFileSync10(dotenvPath, "utf-8").split(/\r?\n/);
|
|
4508
4562
|
for (const rawLine of lines) {
|
|
4509
4563
|
const line = rawLine.trim();
|
|
4510
4564
|
if (!line || line.startsWith("#")) {
|
|
@@ -4861,16 +4915,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
4861
4915
|
for (const dep of deps) {
|
|
4862
4916
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
4863
4917
|
console.log(`=== ${dep} ===`);
|
|
4864
|
-
if (!
|
|
4918
|
+
if (!existsSync23(artifactDir)) {
|
|
4865
4919
|
console.log(` (no artifacts yet)
|
|
4866
4920
|
`);
|
|
4867
4921
|
continue;
|
|
4868
4922
|
}
|
|
4869
|
-
printArtifactSection(
|
|
4870
|
-
printArtifactSection(
|
|
4871
|
-
const changedFiles =
|
|
4872
|
-
if (
|
|
4873
|
-
const lines =
|
|
4923
|
+
printArtifactSection(resolve24(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
4924
|
+
printArtifactSection(resolve24(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
4925
|
+
const changedFiles = resolve24(artifactDir, "changed-files.txt");
|
|
4926
|
+
if (existsSync23(changedFiles)) {
|
|
4927
|
+
const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
4874
4928
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
4875
4929
|
for (const line of lines) {
|
|
4876
4930
|
console.log(line);
|
|
@@ -4994,12 +5048,12 @@ function printIndented(text) {
|
|
|
4994
5048
|
}
|
|
4995
5049
|
}
|
|
4996
5050
|
function readLocalBeadsTasks(projectRoot) {
|
|
4997
|
-
const issuesPath =
|
|
4998
|
-
if (!
|
|
5051
|
+
const issuesPath = resolve24(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5052
|
+
if (!existsSync23(issuesPath)) {
|
|
4999
5053
|
return [];
|
|
5000
5054
|
}
|
|
5001
5055
|
const tasks = [];
|
|
5002
|
-
for (const line of
|
|
5056
|
+
for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
5003
5057
|
const trimmed = line.trim();
|
|
5004
5058
|
if (!trimmed) {
|
|
5005
5059
|
continue;
|
|
@@ -5112,11 +5166,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5112
5166
|
return [...ids].sort();
|
|
5113
5167
|
}
|
|
5114
5168
|
function printArtifactSection(path, header) {
|
|
5115
|
-
if (!
|
|
5169
|
+
if (!existsSync23(path)) {
|
|
5116
5170
|
return;
|
|
5117
5171
|
}
|
|
5118
5172
|
console.log(header);
|
|
5119
|
-
process.stdout.write(
|
|
5173
|
+
process.stdout.write(readFileSync11(path, "utf-8"));
|
|
5120
5174
|
console.log("");
|
|
5121
5175
|
}
|
|
5122
5176
|
|
|
@@ -5218,7 +5272,7 @@ init_layout();
|
|
|
5218
5272
|
|
|
5219
5273
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5220
5274
|
init_layout();
|
|
5221
|
-
import { mkdirSync as
|
|
5275
|
+
import { mkdirSync as mkdirSync11 } from "fs";
|
|
5222
5276
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5223
5277
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5224
5278
|
const rootDir = layout.rigRoot;
|
|
@@ -5230,14 +5284,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5230
5284
|
const sessionDir = layout.sessionDir;
|
|
5231
5285
|
const runtimeDir = layout.runtimeDir;
|
|
5232
5286
|
const contextPath = layout.contextPath;
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5287
|
+
mkdirSync11(rootDir, { recursive: true });
|
|
5288
|
+
mkdirSync11(homeDir, { recursive: true });
|
|
5289
|
+
mkdirSync11(tmpDir, { recursive: true });
|
|
5290
|
+
mkdirSync11(cacheDir, { recursive: true });
|
|
5291
|
+
mkdirSync11(logsDir, { recursive: true });
|
|
5292
|
+
mkdirSync11(stateDir, { recursive: true });
|
|
5293
|
+
mkdirSync11(sessionDir, { recursive: true });
|
|
5294
|
+
mkdirSync11(runtimeDir, { recursive: true });
|
|
5241
5295
|
return {
|
|
5242
5296
|
rootDir,
|
|
5243
5297
|
homeDir,
|
|
@@ -5255,17 +5309,17 @@ import {
|
|
|
5255
5309
|
chmodSync as chmodSync5,
|
|
5256
5310
|
copyFileSync as copyFileSync5,
|
|
5257
5311
|
cpSync as cpSync2,
|
|
5258
|
-
existsSync as
|
|
5259
|
-
mkdirSync as
|
|
5312
|
+
existsSync as existsSync25,
|
|
5313
|
+
mkdirSync as mkdirSync12,
|
|
5260
5314
|
statSync as statSync5,
|
|
5261
|
-
writeFileSync as
|
|
5315
|
+
writeFileSync as writeFileSync10
|
|
5262
5316
|
} from "fs";
|
|
5263
5317
|
import { mkdir } from "fs/promises";
|
|
5264
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
5318
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve26 } from "path";
|
|
5265
5319
|
|
|
5266
5320
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
5267
|
-
import { existsSync as
|
|
5268
|
-
import { resolve as
|
|
5321
|
+
import { existsSync as existsSync24, readFileSync as readFileSync12, rmSync as rmSync9 } from "fs";
|
|
5322
|
+
import { resolve as resolve25 } from "path";
|
|
5269
5323
|
var generatedCredentialFiles = new Set;
|
|
5270
5324
|
var credentialCleanupRegistered = false;
|
|
5271
5325
|
function resolveMonorepoRoot3(projectRoot) {
|
|
@@ -5289,7 +5343,7 @@ function resolveHostGitBinary() {
|
|
|
5289
5343
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
5290
5344
|
continue;
|
|
5291
5345
|
}
|
|
5292
|
-
if (
|
|
5346
|
+
if (existsSync24(candidate)) {
|
|
5293
5347
|
return candidate;
|
|
5294
5348
|
}
|
|
5295
5349
|
}
|
|
@@ -5355,7 +5409,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
5355
5409
|
}
|
|
5356
5410
|
}
|
|
5357
5411
|
async function tryReadGitHead(repoRoot) {
|
|
5358
|
-
if (!
|
|
5412
|
+
if (!existsSync24(resolve25(repoRoot, ".git"))) {
|
|
5359
5413
|
return;
|
|
5360
5414
|
}
|
|
5361
5415
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -5366,7 +5420,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
5366
5420
|
return value || undefined;
|
|
5367
5421
|
}
|
|
5368
5422
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
5369
|
-
if (!
|
|
5423
|
+
if (!existsSync24(resolve25(repoRoot, ".git"))) {
|
|
5370
5424
|
return [];
|
|
5371
5425
|
}
|
|
5372
5426
|
const files = new Set;
|
|
@@ -5402,7 +5456,7 @@ function registerCredentialCleanup(path) {
|
|
|
5402
5456
|
const cleanup = () => {
|
|
5403
5457
|
for (const filePath of generatedCredentialFiles) {
|
|
5404
5458
|
try {
|
|
5405
|
-
|
|
5459
|
+
rmSync9(filePath, { force: true });
|
|
5406
5460
|
} catch {}
|
|
5407
5461
|
}
|
|
5408
5462
|
generatedCredentialFiles.clear();
|
|
@@ -5454,16 +5508,16 @@ 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
5514
|
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
5461
|
-
if (
|
|
5515
|
+
if (existsSync24(candidate)) {
|
|
5462
5516
|
return candidate;
|
|
5463
5517
|
}
|
|
5464
5518
|
}
|
|
5465
5519
|
const bunResolved = Bun.which("gh");
|
|
5466
|
-
if (bunResolved &&
|
|
5520
|
+
if (bunResolved && existsSync24(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
5467
5521
|
return bunResolved;
|
|
5468
5522
|
}
|
|
5469
5523
|
return "";
|
|
@@ -5497,17 +5551,17 @@ function resolveSystemCertBundlePath() {
|
|
|
5497
5551
|
"/opt/homebrew/etc/openssl@3/cert.pem"
|
|
5498
5552
|
];
|
|
5499
5553
|
for (const candidate of candidates) {
|
|
5500
|
-
if (candidate &&
|
|
5501
|
-
return
|
|
5554
|
+
if (candidate && existsSync24(candidate)) {
|
|
5555
|
+
return resolve25(candidate);
|
|
5502
5556
|
}
|
|
5503
5557
|
}
|
|
5504
5558
|
return "";
|
|
5505
5559
|
}
|
|
5506
5560
|
function readKnownHosts(path) {
|
|
5507
|
-
if (!
|
|
5561
|
+
if (!existsSync24(path)) {
|
|
5508
5562
|
return new Set;
|
|
5509
5563
|
}
|
|
5510
|
-
return new Set(
|
|
5564
|
+
return new Set(readFileSync12(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
5511
5565
|
}
|
|
5512
5566
|
|
|
5513
5567
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -5522,12 +5576,12 @@ function resolveControlPlaneSourceRoot(projectRoot) {
|
|
|
5522
5576
|
const candidates = [
|
|
5523
5577
|
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
5524
5578
|
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
5525
|
-
|
|
5579
|
+
resolve26(import.meta.dir, "../../../../.."),
|
|
5526
5580
|
projectRoot
|
|
5527
5581
|
].filter((value) => Boolean(value));
|
|
5528
5582
|
for (const candidate of candidates) {
|
|
5529
|
-
const root =
|
|
5530
|
-
if (
|
|
5583
|
+
const root = resolve26(candidate);
|
|
5584
|
+
if (existsSync25(resolve26(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
5531
5585
|
return root;
|
|
5532
5586
|
}
|
|
5533
5587
|
}
|
|
@@ -5547,7 +5601,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5547
5601
|
try {
|
|
5548
5602
|
return resolveClaudeInstallDir();
|
|
5549
5603
|
} catch {
|
|
5550
|
-
return
|
|
5604
|
+
return resolve26(claudeBinaryPath, "..");
|
|
5551
5605
|
}
|
|
5552
5606
|
})() : "";
|
|
5553
5607
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -5562,8 +5616,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5562
5616
|
`${bunDir}/bin`,
|
|
5563
5617
|
claudeDir,
|
|
5564
5618
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
5565
|
-
realHome ?
|
|
5566
|
-
realHome ?
|
|
5619
|
+
realHome ? resolve26(realHome, ".local/bin") : "",
|
|
5620
|
+
realHome ? resolve26(realHome, ".cargo/bin") : "",
|
|
5567
5621
|
...inheritedPath,
|
|
5568
5622
|
"/usr/local/bin",
|
|
5569
5623
|
"/usr/local/sbin",
|
|
@@ -5574,9 +5628,9 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5574
5628
|
"/usr/sbin",
|
|
5575
5629
|
"/sbin"
|
|
5576
5630
|
].filter(Boolean);
|
|
5577
|
-
const runtimeBash =
|
|
5578
|
-
const runtimeRigGit =
|
|
5579
|
-
const preferredShell =
|
|
5631
|
+
const runtimeBash = resolve26(runtime.binDir, "bash");
|
|
5632
|
+
const runtimeRigGit = resolve26(runtime.binDir, runtimeRigGitFileName());
|
|
5633
|
+
const preferredShell = existsSync25(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
5580
5634
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
5581
5635
|
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
5582
5636
|
const env = {
|
|
@@ -5597,30 +5651,30 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5597
5651
|
RIG_RUNTIME_MODE: runtime.mode,
|
|
5598
5652
|
RIG_RUNTIME_HOME: runtime.rootDir,
|
|
5599
5653
|
RIG_RUNTIME_BIN_DIR: runtime.binDir,
|
|
5600
|
-
...
|
|
5654
|
+
...existsSync25(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
|
|
5601
5655
|
RIG_BUN_PATH: bunBinaryPath,
|
|
5602
5656
|
...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
|
|
5603
|
-
RIG_AGENT_BIN:
|
|
5657
|
+
RIG_AGENT_BIN: resolve26(runtime.binDir, "rig-agent"),
|
|
5604
5658
|
RIG_HOOKS_ACTIVE: "1",
|
|
5605
5659
|
RIG_AUTO_PR_ON_COMPLETE: "1",
|
|
5606
|
-
RIG_POLICY_FILE:
|
|
5660
|
+
RIG_POLICY_FILE: resolve26(projectRoot, "rig/policy/policy.json"),
|
|
5607
5661
|
RIG_STATE_DIR: runtime.stateDir,
|
|
5608
5662
|
RIG_LOGS_DIR: runtime.logsDir,
|
|
5609
|
-
RIG_SESSION_FILE:
|
|
5663
|
+
RIG_SESSION_FILE: resolve26(runtime.sessionDir, "session.json"),
|
|
5610
5664
|
MONOREPO_ROOT: runtime.workspaceDir,
|
|
5611
5665
|
MONOREPO_MAIN_ROOT: monorepoMainRoot,
|
|
5612
|
-
TS_API_TESTS_DIR:
|
|
5666
|
+
TS_API_TESTS_DIR: resolve26(runtime.workspaceDir, "TSAPITests"),
|
|
5613
5667
|
BASH: preferredShell,
|
|
5614
5668
|
SHELL: preferredShell,
|
|
5615
5669
|
PATH: [...new Set(pathEntries)].join(delimiter2),
|
|
5616
5670
|
LANG: process.env.LANG ?? "en_US.UTF-8",
|
|
5617
5671
|
TERM: process.env.TERM ?? "xterm-256color",
|
|
5618
5672
|
PYTHONDONTWRITEBYTECODE: "1",
|
|
5619
|
-
PYTHONPYCACHEPREFIX:
|
|
5673
|
+
PYTHONPYCACHEPREFIX: resolve26(runtime.cacheDir, "python"),
|
|
5620
5674
|
...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
|
|
5621
5675
|
...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
|
|
5622
5676
|
CLAUDE_HOME: runtime.claudeHomeDir,
|
|
5623
|
-
PI_CODING_AGENT_DIR:
|
|
5677
|
+
PI_CODING_AGENT_DIR: resolve26(runtime.homeDir, ".pi", "agent"),
|
|
5624
5678
|
[RUNTIME_CONTEXT_ENV]: runtime.contextFile,
|
|
5625
5679
|
...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
|
|
5626
5680
|
...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
|
|
@@ -5631,16 +5685,16 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5631
5685
|
NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
|
|
5632
5686
|
} : {}
|
|
5633
5687
|
};
|
|
5634
|
-
const knownHostsPath =
|
|
5635
|
-
if (
|
|
5636
|
-
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");
|
|
5637
5691
|
const sshParts = [
|
|
5638
5692
|
"ssh",
|
|
5639
5693
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
5640
5694
|
"-o StrictHostKeyChecking=yes",
|
|
5641
5695
|
"-F /dev/null"
|
|
5642
5696
|
];
|
|
5643
|
-
if (
|
|
5697
|
+
if (existsSync25(agentSshKey)) {
|
|
5644
5698
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
5645
5699
|
}
|
|
5646
5700
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -5677,7 +5731,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5677
5731
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
5678
5732
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
5679
5733
|
}
|
|
5680
|
-
if (
|
|
5734
|
+
if (existsSync25(runtime.contextFile)) {
|
|
5681
5735
|
const runtimeContext = loadRuntimeContext(runtime.contextFile);
|
|
5682
5736
|
Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
|
|
5683
5737
|
Object.assign(env, browserEnvFromContext(runtimeContext.browser));
|
|
@@ -5691,30 +5745,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
5691
5745
|
await mkdir(runtime.cacheDir, { recursive: true });
|
|
5692
5746
|
await provisionAgentSshKey(runtime.homeDir);
|
|
5693
5747
|
if (options.provider === "codex") {
|
|
5694
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
5748
|
+
const hasCodexAuth = await injectCodexAuth(resolve26(runtime.homeDir, ".codex"));
|
|
5695
5749
|
if (!hasCodexAuth) {
|
|
5696
5750
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
5697
5751
|
}
|
|
5698
5752
|
}
|
|
5699
5753
|
if (options.provider === "pi") {
|
|
5700
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
5754
|
+
const hasPiAuth = await injectPiAgentConfig(resolve26(runtime.homeDir, ".pi", "agent"));
|
|
5701
5755
|
if (!hasPiAuth) {
|
|
5702
5756
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
5703
5757
|
}
|
|
5704
5758
|
}
|
|
5705
5759
|
}
|
|
5706
5760
|
async function provisionClaudeHome(config) {
|
|
5707
|
-
|
|
5708
|
-
const workspaceSettings =
|
|
5709
|
-
const hostSettings =
|
|
5710
|
-
const projectSettings =
|
|
5761
|
+
mkdirSync12(config.claudeHomeDir, { recursive: true });
|
|
5762
|
+
const workspaceSettings = resolve26(config.workspaceDir, ".claude/settings.json");
|
|
5763
|
+
const hostSettings = resolve26(config.hostProjectRoot, ".claude/settings.json");
|
|
5764
|
+
const projectSettings = existsSync25(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
5711
5765
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
5712
|
-
if (
|
|
5713
|
-
|
|
5766
|
+
if (existsSync25(projectSettings)) {
|
|
5767
|
+
writeFileSync10(resolve26(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5714
5768
|
`, "utf-8");
|
|
5715
5769
|
}
|
|
5716
5770
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
5717
|
-
|
|
5771
|
+
writeFileSync10(resolve26(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
5718
5772
|
permissions: { defaultMode: "bypassPermissions" },
|
|
5719
5773
|
autoMemoryEnabled: false
|
|
5720
5774
|
}, null, 2));
|
|
@@ -5722,12 +5776,12 @@ async function provisionClaudeHome(config) {
|
|
|
5722
5776
|
if (!hasCredentials) {
|
|
5723
5777
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
5724
5778
|
}
|
|
5725
|
-
const realClaudeHome =
|
|
5726
|
-
if (process.env.HOME &&
|
|
5727
|
-
cpSync2(
|
|
5779
|
+
const realClaudeHome = resolve26(process.env.HOME ?? "", ".claude");
|
|
5780
|
+
if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "CLAUDE.md"))) {
|
|
5781
|
+
cpSync2(resolve26(realClaudeHome, "CLAUDE.md"), resolve26(config.claudeHomeDir, "CLAUDE.md"));
|
|
5728
5782
|
}
|
|
5729
|
-
if (process.env.HOME &&
|
|
5730
|
-
cpSync2(
|
|
5783
|
+
if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "agents"))) {
|
|
5784
|
+
cpSync2(resolve26(realClaudeHome, "agents"), resolve26(config.claudeHomeDir, "agents"), { recursive: true });
|
|
5731
5785
|
}
|
|
5732
5786
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
5733
5787
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -5738,10 +5792,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
5738
5792
|
if (!sourcePath) {
|
|
5739
5793
|
return "";
|
|
5740
5794
|
}
|
|
5741
|
-
const certsDir =
|
|
5742
|
-
const targetPath =
|
|
5795
|
+
const certsDir = resolve26(runtime.rootDir, "certs");
|
|
5796
|
+
const targetPath = resolve26(certsDir, "ca-certificates.pem");
|
|
5743
5797
|
await mkdir(certsDir, { recursive: true });
|
|
5744
|
-
let shouldCopy = !
|
|
5798
|
+
let shouldCopy = !existsSync25(targetPath);
|
|
5745
5799
|
if (!shouldCopy) {
|
|
5746
5800
|
try {
|
|
5747
5801
|
shouldCopy = statSync5(sourcePath).mtimeMs > statSync5(targetPath).mtimeMs;
|
|
@@ -5763,7 +5817,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
5763
5817
|
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';
|
|
5764
5818
|
}
|
|
5765
5819
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
5766
|
-
const secretsPath =
|
|
5820
|
+
const secretsPath = resolve26(runtimeRoot, "runtime-secrets.json");
|
|
5767
5821
|
const persisted = {};
|
|
5768
5822
|
for (const key of [
|
|
5769
5823
|
"GITHUB_TOKEN",
|
|
@@ -5782,12 +5836,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
5782
5836
|
if (Object.keys(persisted).length === 0) {
|
|
5783
5837
|
return;
|
|
5784
5838
|
}
|
|
5785
|
-
|
|
5839
|
+
writeFileSync10(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
5786
5840
|
`, "utf-8");
|
|
5787
5841
|
}
|
|
5788
5842
|
async function provisionAgentSshKey(homeDir) {
|
|
5789
|
-
const sshDir =
|
|
5790
|
-
if (!
|
|
5843
|
+
const sshDir = resolve26(homeDir, ".ssh");
|
|
5844
|
+
if (!existsSync25(sshDir)) {
|
|
5791
5845
|
await mkdir(sshDir, { recursive: true });
|
|
5792
5846
|
}
|
|
5793
5847
|
seedKnownHosts(sshDir);
|
|
@@ -5795,27 +5849,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
5795
5849
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
5796
5850
|
if (!privateKey) {
|
|
5797
5851
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
5798
|
-
if (!process.env.HOME || !
|
|
5852
|
+
if (!process.env.HOME || !existsSync25(hostKeyPath)) {
|
|
5799
5853
|
return;
|
|
5800
5854
|
}
|
|
5801
|
-
const agentKeyPath2 =
|
|
5802
|
-
if (!
|
|
5855
|
+
const agentKeyPath2 = resolve26(sshDir, "rig-agent-key");
|
|
5856
|
+
if (!existsSync25(agentKeyPath2)) {
|
|
5803
5857
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
5804
5858
|
chmodSync5(agentKeyPath2, 384);
|
|
5805
5859
|
}
|
|
5806
5860
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
5807
|
-
if (
|
|
5861
|
+
if (existsSync25(hostPubPath)) {
|
|
5808
5862
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
5809
|
-
if (!
|
|
5863
|
+
if (!existsSync25(agentPubPath)) {
|
|
5810
5864
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
5811
5865
|
}
|
|
5812
5866
|
}
|
|
5813
5867
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
5814
5868
|
return;
|
|
5815
5869
|
}
|
|
5816
|
-
const agentKeyPath =
|
|
5817
|
-
if (!
|
|
5818
|
-
|
|
5870
|
+
const agentKeyPath = resolve26(sshDir, "rig-agent-key");
|
|
5871
|
+
if (!existsSync25(agentKeyPath)) {
|
|
5872
|
+
writeFileSync10(agentKeyPath, privateKey, { mode: 384 });
|
|
5819
5873
|
}
|
|
5820
5874
|
writeSshConfig(sshDir, agentKeyPath);
|
|
5821
5875
|
}
|
|
@@ -5832,21 +5886,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
5832
5886
|
`;
|
|
5833
5887
|
}
|
|
5834
5888
|
function resolveHostSshKeyPath(homeDir) {
|
|
5835
|
-
const sshDir =
|
|
5889
|
+
const sshDir = resolve26(homeDir, ".ssh");
|
|
5836
5890
|
const candidates = [
|
|
5837
5891
|
"rig-agent-key",
|
|
5838
5892
|
"id_ed25519",
|
|
5839
5893
|
"id_ecdsa",
|
|
5840
5894
|
"id_rsa"
|
|
5841
|
-
].map((name) =>
|
|
5842
|
-
return candidates.find((candidate) =>
|
|
5895
|
+
].map((name) => resolve26(sshDir, name));
|
|
5896
|
+
return candidates.find((candidate) => existsSync25(candidate)) ?? resolve26(sshDir, "rig-agent-key");
|
|
5843
5897
|
}
|
|
5844
5898
|
function writeSshConfig(sshDir, keyPath) {
|
|
5845
|
-
const configPath =
|
|
5846
|
-
if (
|
|
5899
|
+
const configPath = resolve26(sshDir, "config");
|
|
5900
|
+
if (existsSync25(configPath)) {
|
|
5847
5901
|
return;
|
|
5848
5902
|
}
|
|
5849
|
-
const knownHostsPath =
|
|
5903
|
+
const knownHostsPath = resolve26(sshDir, "known_hosts");
|
|
5850
5904
|
const config = [
|
|
5851
5905
|
"Host github.com",
|
|
5852
5906
|
` IdentityFile ${keyPath}`,
|
|
@@ -5856,10 +5910,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
5856
5910
|
""
|
|
5857
5911
|
].join(`
|
|
5858
5912
|
`);
|
|
5859
|
-
|
|
5913
|
+
writeFileSync10(configPath, config, { mode: 420 });
|
|
5860
5914
|
}
|
|
5861
5915
|
function seedKnownHosts(sshDir) {
|
|
5862
|
-
const knownHostsPath =
|
|
5916
|
+
const knownHostsPath = resolve26(sshDir, "known_hosts");
|
|
5863
5917
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
5864
5918
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
5865
5919
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -5870,23 +5924,23 @@ function seedKnownHosts(sshDir) {
|
|
|
5870
5924
|
for (const line of missing) {
|
|
5871
5925
|
existingLines.add(line);
|
|
5872
5926
|
}
|
|
5873
|
-
|
|
5927
|
+
writeFileSync10(knownHostsPath, `${Array.from(existingLines).join(`
|
|
5874
5928
|
`)}
|
|
5875
5929
|
`, { mode: 420 });
|
|
5876
5930
|
} catch (err) {
|
|
5877
|
-
const hint =
|
|
5931
|
+
const hint = existsSync25(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
5878
5932
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
5879
5933
|
}
|
|
5880
5934
|
}
|
|
5881
5935
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
5882
5936
|
const projectHash = hashProjectPath(workspaceDir);
|
|
5883
|
-
const projectDir =
|
|
5884
|
-
|
|
5885
|
-
|
|
5937
|
+
const projectDir = resolve26(claudeHomeDir, "projects", projectHash);
|
|
5938
|
+
mkdirSync12(projectDir, { recursive: true });
|
|
5939
|
+
writeFileSync10(resolve26(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5886
5940
|
`, "utf-8");
|
|
5887
5941
|
}
|
|
5888
5942
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
5889
|
-
if (!
|
|
5943
|
+
if (!existsSync25(projectSettingsPath)) {
|
|
5890
5944
|
return {};
|
|
5891
5945
|
}
|
|
5892
5946
|
let parsed;
|
|
@@ -5932,7 +5986,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
5932
5986
|
return clone;
|
|
5933
5987
|
}
|
|
5934
5988
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
5935
|
-
const credentialsPath =
|
|
5989
|
+
const credentialsPath = resolve26(claudeHomeDir, ".credentials.json");
|
|
5936
5990
|
const platform = options.platform ?? process.platform;
|
|
5937
5991
|
if (platform === "darwin") {
|
|
5938
5992
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -5942,16 +5996,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
5942
5996
|
if (raw) {
|
|
5943
5997
|
try {
|
|
5944
5998
|
JSON.parse(raw);
|
|
5945
|
-
|
|
5999
|
+
writeFileSync10(credentialsPath, raw, { mode: 384 });
|
|
5946
6000
|
registerCredentialCleanup(credentialsPath);
|
|
5947
6001
|
return true;
|
|
5948
6002
|
} catch {}
|
|
5949
6003
|
}
|
|
5950
6004
|
}
|
|
5951
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6005
|
+
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") : "";
|
|
5952
6006
|
if (hostClaudeHome) {
|
|
5953
|
-
const realCredentials =
|
|
5954
|
-
if (
|
|
6007
|
+
const realCredentials = resolve26(hostClaudeHome, ".credentials.json");
|
|
6008
|
+
if (existsSync25(realCredentials)) {
|
|
5955
6009
|
cpSync2(realCredentials, credentialsPath);
|
|
5956
6010
|
return true;
|
|
5957
6011
|
}
|
|
@@ -5959,36 +6013,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
5959
6013
|
return false;
|
|
5960
6014
|
}
|
|
5961
6015
|
async function injectCodexAuth(codexHomeDir) {
|
|
5962
|
-
|
|
5963
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6016
|
+
mkdirSync12(codexHomeDir, { recursive: true });
|
|
6017
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve26(process.env.CODEX_HOME) : process.env.HOME ? resolve26(process.env.HOME, ".codex") : "";
|
|
5964
6018
|
if (!hostCodexHome) {
|
|
5965
6019
|
return false;
|
|
5966
6020
|
}
|
|
5967
|
-
const hostAuthPath =
|
|
5968
|
-
if (!
|
|
6021
|
+
const hostAuthPath = resolve26(hostCodexHome, "auth.json");
|
|
6022
|
+
if (!existsSync25(hostAuthPath)) {
|
|
5969
6023
|
return false;
|
|
5970
6024
|
}
|
|
5971
|
-
const runtimeAuthPath =
|
|
6025
|
+
const runtimeAuthPath = resolve26(codexHomeDir, "auth.json");
|
|
5972
6026
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
5973
6027
|
chmodSync5(runtimeAuthPath, 384);
|
|
5974
6028
|
return true;
|
|
5975
6029
|
}
|
|
5976
6030
|
async function injectPiAgentConfig(piAgentDir) {
|
|
5977
|
-
|
|
5978
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6031
|
+
mkdirSync12(piAgentDir, { recursive: true });
|
|
6032
|
+
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") : "";
|
|
5979
6033
|
if (!hostPiAgentDir) {
|
|
5980
6034
|
return false;
|
|
5981
6035
|
}
|
|
5982
|
-
const hostAuthPath =
|
|
5983
|
-
if (!
|
|
6036
|
+
const hostAuthPath = resolve26(hostPiAgentDir, "auth.json");
|
|
6037
|
+
if (!existsSync25(hostAuthPath)) {
|
|
5984
6038
|
return false;
|
|
5985
6039
|
}
|
|
5986
|
-
const runtimeAuthPath =
|
|
6040
|
+
const runtimeAuthPath = resolve26(piAgentDir, "auth.json");
|
|
5987
6041
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
5988
6042
|
chmodSync5(runtimeAuthPath, 384);
|
|
5989
|
-
const hostSettingsPath =
|
|
5990
|
-
if (
|
|
5991
|
-
const runtimeSettingsPath =
|
|
6043
|
+
const hostSettingsPath = resolve26(hostPiAgentDir, "settings.json");
|
|
6044
|
+
if (existsSync25(hostSettingsPath)) {
|
|
6045
|
+
const runtimeSettingsPath = resolve26(piAgentDir, "settings.json");
|
|
5992
6046
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
5993
6047
|
chmodSync5(runtimeSettingsPath, 384);
|
|
5994
6048
|
}
|
|
@@ -5996,8 +6050,8 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
5996
6050
|
}
|
|
5997
6051
|
|
|
5998
6052
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
5999
|
-
import { existsSync as
|
|
6000
|
-
import { resolve as
|
|
6053
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync13, statSync as statSync6, writeFileSync as writeFileSync11 } from "fs";
|
|
6054
|
+
import { resolve as resolve27 } from "path";
|
|
6001
6055
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6002
6056
|
var CLAUDE_DISABLED_FILE_TOOLS = [
|
|
6003
6057
|
"Read",
|
|
@@ -6095,7 +6149,7 @@ function claudeRuntimeToolCliArgs(configPath) {
|
|
|
6095
6149
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6096
6150
|
return {
|
|
6097
6151
|
type: "stdio",
|
|
6098
|
-
command:
|
|
6152
|
+
command: resolve27(options.binDir, "rig-tool-router"),
|
|
6099
6153
|
args: [],
|
|
6100
6154
|
env: {
|
|
6101
6155
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6129,14 +6183,14 @@ function codexRuntimeToolCliArgs(options) {
|
|
|
6129
6183
|
];
|
|
6130
6184
|
}
|
|
6131
6185
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6132
|
-
const configPath =
|
|
6133
|
-
|
|
6186
|
+
const configPath = resolve27(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6187
|
+
mkdirSync13(options.stateDir, { recursive: true });
|
|
6134
6188
|
const payload = {
|
|
6135
6189
|
mcpServers: {
|
|
6136
6190
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6137
6191
|
}
|
|
6138
6192
|
};
|
|
6139
|
-
|
|
6193
|
+
writeFileSync11(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6140
6194
|
`, "utf-8");
|
|
6141
6195
|
return configPath;
|
|
6142
6196
|
}
|
|
@@ -6223,7 +6277,7 @@ function resolveRuntimeToolBinary(toolName, env) {
|
|
|
6223
6277
|
grep: "rig-grep"
|
|
6224
6278
|
};
|
|
6225
6279
|
const executable = mapping[toolName];
|
|
6226
|
-
return executable ?
|
|
6280
|
+
return executable ? resolve27(binDir, executable) : "";
|
|
6227
6281
|
}
|
|
6228
6282
|
function renderToolText(toolName, payload) {
|
|
6229
6283
|
if (toolName === "shell") {
|
|
@@ -6288,10 +6342,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
|
|
|
6288
6342
|
isError: true
|
|
6289
6343
|
};
|
|
6290
6344
|
}
|
|
6291
|
-
const workspaceRoot =
|
|
6345
|
+
const workspaceRoot = resolve27(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
|
|
6292
6346
|
const requestedWorkdir = typeof args.workdir === "string" ? args.workdir.trim() : "";
|
|
6293
6347
|
const workdir = requestedWorkdir ? resolveWithinWorkspace(workspaceRoot, requestedWorkdir) : workspaceRoot;
|
|
6294
|
-
if (!
|
|
6348
|
+
if (!existsSync26(workdir)) {
|
|
6295
6349
|
return {
|
|
6296
6350
|
content: [{
|
|
6297
6351
|
type: "text",
|
|
@@ -6358,10 +6412,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
|
|
|
6358
6412
|
}
|
|
6359
6413
|
function resolveRuntimeShellBinary(shellName, env) {
|
|
6360
6414
|
const binDir = env.RIG_RUNTIME_BIN_DIR?.trim() || "";
|
|
6361
|
-
return binDir ?
|
|
6415
|
+
return binDir ? resolve27(binDir, shellName) : "";
|
|
6362
6416
|
}
|
|
6363
6417
|
function resolveWithinWorkspace(workspaceRoot, target) {
|
|
6364
|
-
const resolvedTarget =
|
|
6418
|
+
const resolvedTarget = resolve27(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
|
|
6365
6419
|
const normalizedWorkspace = workspaceRoot.endsWith("/") ? workspaceRoot : `${workspaceRoot}/`;
|
|
6366
6420
|
const normalizedTarget = resolvedTarget.endsWith("/") ? resolvedTarget : `${resolvedTarget}/`;
|
|
6367
6421
|
if (resolvedTarget === workspaceRoot || normalizedTarget.startsWith(normalizedWorkspace)) {
|
|
@@ -6399,8 +6453,8 @@ if (false) {}
|
|
|
6399
6453
|
init_layout();
|
|
6400
6454
|
|
|
6401
6455
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6402
|
-
import { existsSync as
|
|
6403
|
-
import { dirname as dirname11, resolve as
|
|
6456
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync14, rmSync as rmSync10 } from "fs";
|
|
6457
|
+
import { dirname as dirname11, resolve as resolve28 } from "path";
|
|
6404
6458
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6405
6459
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6406
6460
|
if (explicit) {
|
|
@@ -6436,12 +6490,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6436
6490
|
}
|
|
6437
6491
|
async function provisionRuntimeWorktree(config) {
|
|
6438
6492
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6439
|
-
let hasValidWorktree =
|
|
6440
|
-
if (
|
|
6441
|
-
|
|
6493
|
+
let hasValidWorktree = existsSync27(resolve28(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6494
|
+
if (existsSync27(config.workspaceDir) && !hasValidWorktree) {
|
|
6495
|
+
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6442
6496
|
}
|
|
6443
6497
|
if (!hasValidWorktree) {
|
|
6444
|
-
|
|
6498
|
+
mkdirSync14(dirname11(config.workspaceDir), { recursive: true });
|
|
6445
6499
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6446
6500
|
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]);
|
|
6447
6501
|
if (add.exitCode !== 0) {
|
|
@@ -6617,31 +6671,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
6617
6671
|
|
|
6618
6672
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
6619
6673
|
import {
|
|
6620
|
-
existsSync as
|
|
6674
|
+
existsSync as existsSync29,
|
|
6621
6675
|
lstatSync,
|
|
6622
|
-
mkdirSync as
|
|
6623
|
-
readdirSync as
|
|
6624
|
-
readFileSync as
|
|
6625
|
-
rmSync as
|
|
6676
|
+
mkdirSync as mkdirSync16,
|
|
6677
|
+
readdirSync as readdirSync6,
|
|
6678
|
+
readFileSync as readFileSync14,
|
|
6679
|
+
rmSync as rmSync11,
|
|
6626
6680
|
statSync as statSync8,
|
|
6627
6681
|
symlinkSync as symlinkSync4
|
|
6628
6682
|
} from "fs";
|
|
6629
6683
|
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
6630
|
-
import { dirname as dirname13, resolve as
|
|
6684
|
+
import { dirname as dirname13, resolve as resolve30 } from "path";
|
|
6631
6685
|
|
|
6632
6686
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
6633
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
6687
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync28, mkdirSync as mkdirSync15, statSync as statSync7 } from "fs";
|
|
6634
6688
|
import { tmpdir as tmpdir6 } from "os";
|
|
6635
|
-
import { dirname as dirname12, resolve as
|
|
6636
|
-
var sharedRouterOutputDir =
|
|
6637
|
-
var sharedRouterOutputPath =
|
|
6689
|
+
import { dirname as dirname12, resolve as resolve29 } from "path";
|
|
6690
|
+
var sharedRouterOutputDir = resolve29(tmpdir6(), "rig-native");
|
|
6691
|
+
var sharedRouterOutputPath = resolve29(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
6638
6692
|
function runtimeClaudeToolRouterFileName() {
|
|
6639
6693
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
6640
6694
|
}
|
|
6641
6695
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
6642
|
-
const sourcePath =
|
|
6643
|
-
|
|
6644
|
-
const needsBuild = !
|
|
6696
|
+
const sourcePath = resolve29(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
6697
|
+
mkdirSync15(dirname12(outputPath), { recursive: true });
|
|
6698
|
+
const needsBuild = !existsSync28(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
|
|
6645
6699
|
if (!needsBuild) {
|
|
6646
6700
|
return outputPath;
|
|
6647
6701
|
}
|
|
@@ -6655,9 +6709,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
6655
6709
|
}
|
|
6656
6710
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
6657
6711
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
6658
|
-
const targetPath =
|
|
6659
|
-
|
|
6660
|
-
const needsCopy = !
|
|
6712
|
+
const targetPath = resolve29(targetDir, runtimeClaudeToolRouterFileName());
|
|
6713
|
+
mkdirSync15(targetDir, { recursive: true });
|
|
6714
|
+
const needsCopy = !existsSync28(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
|
|
6661
6715
|
if (needsCopy) {
|
|
6662
6716
|
copyFileSync6(sourcePath, targetPath);
|
|
6663
6717
|
chmodSync6(targetPath, 493);
|
|
@@ -6670,48 +6724,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
6670
6724
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
6671
6725
|
function resolveRigSourceRoot(projectRoot) {
|
|
6672
6726
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6673
|
-
if (hostProjectRoot &&
|
|
6727
|
+
if (hostProjectRoot && existsSync29(resolve30(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6674
6728
|
return hostProjectRoot;
|
|
6675
6729
|
}
|
|
6676
|
-
const fromModule =
|
|
6677
|
-
if (
|
|
6730
|
+
const fromModule = resolve30(import.meta.dir, "../../../../../..");
|
|
6731
|
+
if (existsSync29(resolve30(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6678
6732
|
return fromModule;
|
|
6679
6733
|
}
|
|
6680
6734
|
return projectRoot;
|
|
6681
6735
|
}
|
|
6682
6736
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
6683
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
6737
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve30(sessionDir, "session.json")]) {
|
|
6684
6738
|
removeSymbolicLink(path);
|
|
6685
6739
|
}
|
|
6686
6740
|
runtimePrepareTrackedPathsNative({
|
|
6687
6741
|
logsDir,
|
|
6688
6742
|
stateDir,
|
|
6689
6743
|
sessionDir,
|
|
6690
|
-
controlledBashLogFile:
|
|
6691
|
-
eventsFile:
|
|
6744
|
+
controlledBashLogFile: resolve30(logsDir, "controlled-bash.jsonl"),
|
|
6745
|
+
eventsFile: resolve30(logsDir, "control-plane.events.jsonl")
|
|
6692
6746
|
});
|
|
6693
6747
|
}
|
|
6694
6748
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
6695
6749
|
await mkdir2(stateDir, { recursive: true });
|
|
6696
6750
|
await mkdir2(sessionDir, { recursive: true });
|
|
6697
|
-
const failedApproachesPath =
|
|
6698
|
-
if (!
|
|
6751
|
+
const failedApproachesPath = resolve30(stateDir, "failed_approaches.md");
|
|
6752
|
+
if (!existsSync29(failedApproachesPath)) {
|
|
6699
6753
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
6700
6754
|
|
|
6701
6755
|
`);
|
|
6702
6756
|
}
|
|
6703
|
-
const hookTripsPath =
|
|
6704
|
-
if (!
|
|
6757
|
+
const hookTripsPath = resolve30(stateDir, "hook_trips.log");
|
|
6758
|
+
if (!existsSync29(hookTripsPath)) {
|
|
6705
6759
|
await writeFile(hookTripsPath, "");
|
|
6706
6760
|
}
|
|
6707
|
-
const sessionFile =
|
|
6761
|
+
const sessionFile = resolve30(sessionDir, "session.json");
|
|
6708
6762
|
if (taskId) {
|
|
6709
6763
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
6710
6764
|
}
|
|
6711
6765
|
}
|
|
6712
6766
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
6713
|
-
const artifactDir =
|
|
6714
|
-
const runtimeSnapshotDir =
|
|
6767
|
+
const artifactDir = resolve30(workspaceDir, "artifacts", taskId);
|
|
6768
|
+
const runtimeSnapshotDir = resolve30(artifactDir, "runtime-snapshots");
|
|
6715
6769
|
let preservedTrackedFiles = false;
|
|
6716
6770
|
for (const file of [
|
|
6717
6771
|
"changed-files.txt",
|
|
@@ -6727,13 +6781,13 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
6727
6781
|
preservedTrackedFiles = true;
|
|
6728
6782
|
continue;
|
|
6729
6783
|
}
|
|
6730
|
-
|
|
6784
|
+
rmSync11(resolve30(artifactDir, file), { force: true });
|
|
6731
6785
|
}
|
|
6732
6786
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
6733
6787
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
6734
6788
|
preservedTrackedFiles = true;
|
|
6735
6789
|
} else {
|
|
6736
|
-
|
|
6790
|
+
rmSync11(runtimeSnapshotDir, { recursive: true, force: true });
|
|
6737
6791
|
}
|
|
6738
6792
|
if (preservedTrackedFiles) {
|
|
6739
6793
|
console.log(`[rig-agent] Preserved tracked runtime artifact files in ${taskId}; skipped ephemeral cleanup for committed paths.`);
|
|
@@ -6766,28 +6820,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
6766
6820
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
6767
6821
|
}
|
|
6768
6822
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
6769
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
6770
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
6823
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve30(options.binDir, "rig"), rigSourceRoot);
|
|
6824
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve30(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
6771
6825
|
...options.runtimeSecretDefines,
|
|
6772
6826
|
AGENT_TASK_ID: options.taskId,
|
|
6773
6827
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6774
6828
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
6775
6829
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
6776
6830
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
6777
|
-
AGENT_BINARY_PATH:
|
|
6831
|
+
AGENT_BINARY_PATH: resolve30(options.binDir, "rig-agent"),
|
|
6778
6832
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
6779
6833
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
6780
6834
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
6781
6835
|
});
|
|
6782
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
6836
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve30(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
6783
6837
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6784
6838
|
AGENT_LOGS_DIR: options.logsDir,
|
|
6785
6839
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
6786
|
-
AGENT_TS_API_TESTS_DIR:
|
|
6787
|
-
AGENT_RIG_AGENT_BIN:
|
|
6840
|
+
AGENT_TS_API_TESTS_DIR: resolve30(options.workspaceDir, "TSAPITests"),
|
|
6841
|
+
AGENT_RIG_AGENT_BIN: resolve30(options.binDir, "rig-agent")
|
|
6788
6842
|
});
|
|
6789
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
6790
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
6843
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve30(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
6844
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve30(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
6791
6845
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6792
6846
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6793
6847
|
});
|
|
@@ -6796,15 +6850,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
6796
6850
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6797
6851
|
};
|
|
6798
6852
|
for (const hookName of hookNames) {
|
|
6799
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
6853
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve30(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
6800
6854
|
}
|
|
6801
|
-
const pluginsDir =
|
|
6802
|
-
if (
|
|
6803
|
-
for (const entry of
|
|
6855
|
+
const pluginsDir = resolve30(options.projectRoot, "rig/plugins");
|
|
6856
|
+
if (existsSync29(pluginsDir)) {
|
|
6857
|
+
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
6804
6858
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
6805
6859
|
if (!match)
|
|
6806
6860
|
continue;
|
|
6807
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
6861
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve30(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
6808
6862
|
}
|
|
6809
6863
|
}
|
|
6810
6864
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -6814,8 +6868,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
6814
6868
|
}
|
|
6815
6869
|
async function writeRuntimeManifest(config) {
|
|
6816
6870
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
6817
|
-
const binarySha256 = sha256Hex(
|
|
6818
|
-
const manifestPath =
|
|
6871
|
+
const binarySha256 = sha256Hex(readFileSync14(config.binaryPath));
|
|
6872
|
+
const manifestPath = resolve30(config.runtimeRoot, "manifest.json");
|
|
6819
6873
|
const manifest = {
|
|
6820
6874
|
runtimeId: config.runtimeId,
|
|
6821
6875
|
taskId: config.taskId,
|
|
@@ -6849,7 +6903,7 @@ function removeSymbolicLink(path) {
|
|
|
6849
6903
|
} catch {
|
|
6850
6904
|
return;
|
|
6851
6905
|
}
|
|
6852
|
-
|
|
6906
|
+
rmSync11(path, { force: true, recursive: true });
|
|
6853
6907
|
}
|
|
6854
6908
|
async function resetTrackedArtifactPath(workspaceDir, relativePath) {
|
|
6855
6909
|
const tracked = await runGitLsFiles(workspaceDir, relativePath);
|
|
@@ -6875,7 +6929,7 @@ async function restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, r
|
|
|
6875
6929
|
const retryDelayMs = options.retryDelayMs ?? GIT_INDEX_LOCK_RETRY_DELAY_MS;
|
|
6876
6930
|
const now = options.now ?? Date.now;
|
|
6877
6931
|
const statMtimeMs = options.statMtimeMs ?? readFileMtimeMs;
|
|
6878
|
-
const removeFile = options.removeFile ?? ((path) =>
|
|
6932
|
+
const removeFile = options.removeFile ?? ((path) => rmSync11(path, { force: true }));
|
|
6879
6933
|
const log = options.log ?? console.warn;
|
|
6880
6934
|
let lastOutput = "";
|
|
6881
6935
|
for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
|
|
@@ -6935,31 +6989,31 @@ function readFileMtimeMs(path) {
|
|
|
6935
6989
|
}
|
|
6936
6990
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
6937
6991
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
6938
|
-
const sourceNodeModules =
|
|
6939
|
-
if (!
|
|
6940
|
-
const runtimeHumoongate =
|
|
6941
|
-
if (
|
|
6942
|
-
const targetNodeModules =
|
|
6992
|
+
const sourceNodeModules = resolve30(monorepoRoot, "humoongate", "node_modules");
|
|
6993
|
+
if (!existsSync29(sourceNodeModules)) {} else {
|
|
6994
|
+
const runtimeHumoongate = resolve30(workspaceDir, "humoongate");
|
|
6995
|
+
if (existsSync29(resolve30(runtimeHumoongate, "package.json"))) {
|
|
6996
|
+
const targetNodeModules = resolve30(runtimeHumoongate, "node_modules");
|
|
6943
6997
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
6944
6998
|
}
|
|
6945
6999
|
}
|
|
6946
|
-
const runtimeHpNext =
|
|
6947
|
-
if (!
|
|
7000
|
+
const runtimeHpNext = resolve30(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
7001
|
+
if (!existsSync29(resolve30(runtimeHpNext, "package.json"))) {
|
|
6948
7002
|
return;
|
|
6949
7003
|
}
|
|
6950
|
-
const sourceHpNextNodeModules =
|
|
6951
|
-
const sourceMonorepoNodeModules =
|
|
6952
|
-
const targetHpNextNodeModules =
|
|
6953
|
-
if (
|
|
7004
|
+
const sourceHpNextNodeModules = resolve30(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
7005
|
+
const sourceMonorepoNodeModules = resolve30(monorepoRoot, "node_modules");
|
|
7006
|
+
const targetHpNextNodeModules = resolve30(runtimeHpNext, "node_modules");
|
|
7007
|
+
if (existsSync29(sourceHpNextNodeModules)) {
|
|
6954
7008
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
6955
7009
|
return;
|
|
6956
7010
|
}
|
|
6957
|
-
if (
|
|
7011
|
+
if (existsSync29(sourceMonorepoNodeModules)) {
|
|
6958
7012
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
6959
7013
|
}
|
|
6960
7014
|
}
|
|
6961
7015
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
6962
|
-
linkNodeModulesLayer(
|
|
7016
|
+
linkNodeModulesLayer(resolve30(monorepoRoot, "node_modules"), resolve30(workspaceDir, "node_modules"));
|
|
6963
7017
|
for (const relativePackageDir of [
|
|
6964
7018
|
"apps/native-app/apps/marketing",
|
|
6965
7019
|
"apps/native-app/apps/web",
|
|
@@ -6981,15 +7035,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
6981
7035
|
"packages/standard-plugin",
|
|
6982
7036
|
"packages/validator-kit"
|
|
6983
7037
|
]) {
|
|
6984
|
-
const workspacePackageDir =
|
|
6985
|
-
if (!
|
|
7038
|
+
const workspacePackageDir = resolve30(workspaceDir, relativePackageDir);
|
|
7039
|
+
if (!existsSync29(resolve30(workspacePackageDir, "package.json"))) {
|
|
6986
7040
|
continue;
|
|
6987
7041
|
}
|
|
6988
|
-
linkNodeModulesLayer(
|
|
7042
|
+
linkNodeModulesLayer(resolve30(monorepoRoot, relativePackageDir, "node_modules"), resolve30(workspacePackageDir, "node_modules"));
|
|
6989
7043
|
}
|
|
6990
7044
|
}
|
|
6991
7045
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
6992
|
-
if (!
|
|
7046
|
+
if (!existsSync29(sourceDir) || existsSync29(targetDir)) {
|
|
6993
7047
|
return;
|
|
6994
7048
|
}
|
|
6995
7049
|
try {
|
|
@@ -6998,30 +7052,30 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
6998
7052
|
} catch (error) {
|
|
6999
7053
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
7000
7054
|
}
|
|
7001
|
-
|
|
7055
|
+
mkdirSync16(dirname13(targetDir), { recursive: true });
|
|
7002
7056
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
7003
7057
|
}
|
|
7004
7058
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
7005
|
-
const hooksDir =
|
|
7006
|
-
const pluginsDir =
|
|
7007
|
-
const validatorsDir =
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7059
|
+
const hooksDir = resolve30(runtimeBinDir, "hooks");
|
|
7060
|
+
const pluginsDir = resolve30(runtimeBinDir, "plugins");
|
|
7061
|
+
const validatorsDir = resolve30(runtimeBinDir, "validators");
|
|
7062
|
+
mkdirSync16(hooksDir, { recursive: true });
|
|
7063
|
+
mkdirSync16(pluginsDir, { recursive: true });
|
|
7064
|
+
mkdirSync16(validatorsDir, { recursive: true });
|
|
7011
7065
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
7012
7066
|
}
|
|
7013
7067
|
|
|
7014
7068
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
7015
|
-
import { existsSync as
|
|
7016
|
-
import { basename as basename9, resolve as
|
|
7069
|
+
import { existsSync as existsSync32, rmSync as rmSync12, writeFileSync as writeFileSync13 } from "fs";
|
|
7070
|
+
import { basename as basename9, resolve as resolve34 } from "path";
|
|
7017
7071
|
|
|
7018
7072
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
7019
|
-
import { existsSync as
|
|
7073
|
+
import { existsSync as existsSync31 } from "fs";
|
|
7020
7074
|
|
|
7021
7075
|
// packages/runtime/src/control-plane/runtime/guard.ts
|
|
7022
7076
|
import { optimizeNextInvocation } from "bun:jsc";
|
|
7023
|
-
import { existsSync as
|
|
7024
|
-
import { resolve as
|
|
7077
|
+
import { existsSync as existsSync30, readFileSync as readFileSync15, statSync as statSync9 } from "fs";
|
|
7078
|
+
import { resolve as resolve31 } from "path";
|
|
7025
7079
|
|
|
7026
7080
|
// packages/runtime/src/control-plane/runtime/guard-types.ts
|
|
7027
7081
|
var POLICY_VERSION = 1;
|
|
@@ -7084,8 +7138,8 @@ function loadPolicy(projectRoot) {
|
|
|
7084
7138
|
if (seededPolicyConfig) {
|
|
7085
7139
|
return seededPolicyConfig;
|
|
7086
7140
|
}
|
|
7087
|
-
const configPath =
|
|
7088
|
-
if (!
|
|
7141
|
+
const configPath = resolve31(projectRoot, "rig/policy/policy.json");
|
|
7142
|
+
if (!existsSync30(configPath)) {
|
|
7089
7143
|
return defaultPolicy();
|
|
7090
7144
|
}
|
|
7091
7145
|
let mtimeMs;
|
|
@@ -7099,7 +7153,7 @@ function loadPolicy(projectRoot) {
|
|
|
7099
7153
|
}
|
|
7100
7154
|
let parsed;
|
|
7101
7155
|
try {
|
|
7102
|
-
parsed = JSON.parse(
|
|
7156
|
+
parsed = JSON.parse(readFileSync15(configPath, "utf-8"));
|
|
7103
7157
|
} catch {
|
|
7104
7158
|
return defaultPolicy();
|
|
7105
7159
|
}
|
|
@@ -7315,28 +7369,28 @@ function resolveAction(mode, matched) {
|
|
|
7315
7369
|
}
|
|
7316
7370
|
function resolveAbsolutePath(projectRoot, rawPath) {
|
|
7317
7371
|
if (rawPath.startsWith("/"))
|
|
7318
|
-
return
|
|
7319
|
-
return
|
|
7372
|
+
return resolve31(rawPath);
|
|
7373
|
+
return resolve31(projectRoot, rawPath);
|
|
7320
7374
|
}
|
|
7321
7375
|
function isHarnessPath(projectRoot, rawPath) {
|
|
7322
7376
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7323
7377
|
const managedRoots = [
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7378
|
+
resolve31(projectRoot, "rig"),
|
|
7379
|
+
resolve31(projectRoot, ".rig"),
|
|
7380
|
+
resolve31(projectRoot, "artifacts")
|
|
7327
7381
|
];
|
|
7328
7382
|
return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
|
|
7329
7383
|
}
|
|
7330
7384
|
function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
|
|
7331
7385
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7332
7386
|
if (taskWorkspace) {
|
|
7333
|
-
const workspaceRigRoot =
|
|
7334
|
-
const workspaceArtifactsRoot =
|
|
7387
|
+
const workspaceRigRoot = resolve31(taskWorkspace, ".rig");
|
|
7388
|
+
const workspaceArtifactsRoot = resolve31(taskWorkspace, "artifacts");
|
|
7335
7389
|
if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
|
|
7336
7390
|
return true;
|
|
7337
7391
|
}
|
|
7338
7392
|
}
|
|
7339
|
-
const runtimeRoot =
|
|
7393
|
+
const runtimeRoot = resolve31(projectRoot, ".rig/runtime/agents");
|
|
7340
7394
|
return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
|
|
7341
7395
|
}
|
|
7342
7396
|
function isTestFile(path) {
|
|
@@ -7384,7 +7438,7 @@ function evaluateScope(policy, context, filePath, access) {
|
|
|
7384
7438
|
return allowed();
|
|
7385
7439
|
}
|
|
7386
7440
|
if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
|
|
7387
|
-
const absPath =
|
|
7441
|
+
const absPath = resolve31(filePath);
|
|
7388
7442
|
if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
|
|
7389
7443
|
const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
|
|
7390
7444
|
const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
|
|
@@ -7712,13 +7766,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
7712
7766
|
depRoots
|
|
7713
7767
|
};
|
|
7714
7768
|
const fsContext = {
|
|
7715
|
-
pathExists: (p) =>
|
|
7769
|
+
pathExists: (p) => existsSync31(p),
|
|
7716
7770
|
realPath: toRealPath
|
|
7717
7771
|
};
|
|
7718
7772
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
7719
7773
|
const seatbelt = Bun.which("sandbox-exec");
|
|
7720
7774
|
probed.push("sandbox-exec");
|
|
7721
|
-
if (seatbelt &&
|
|
7775
|
+
if (seatbelt && existsSync31(seatbelt)) {
|
|
7722
7776
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
7723
7777
|
if (SeatbeltBackendClass) {
|
|
7724
7778
|
return {
|
|
@@ -7839,10 +7893,10 @@ init_layout();
|
|
|
7839
7893
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
7840
7894
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
7841
7895
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
7842
|
-
const readyFile =
|
|
7843
|
-
const requestFile =
|
|
7844
|
-
|
|
7845
|
-
|
|
7896
|
+
const readyFile = resolve34(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
7897
|
+
const requestFile = resolve34(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
7898
|
+
rmSync12(readyFile, { force: true });
|
|
7899
|
+
rmSync12(requestFile, { force: true });
|
|
7846
7900
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
7847
7901
|
const useCompiledSidecar = shouldUseCompiledSnapshotSidecar(sidecarBinary);
|
|
7848
7902
|
const bunCli = useCompiledSidecar ? null : resolveBunCliInvocation();
|
|
@@ -7880,19 +7934,19 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
7880
7934
|
proc.kill("SIGTERM");
|
|
7881
7935
|
} catch {}
|
|
7882
7936
|
await proc.exited;
|
|
7883
|
-
|
|
7884
|
-
|
|
7937
|
+
rmSync12(readyFile, { force: true });
|
|
7938
|
+
rmSync12(requestFile, { force: true });
|
|
7885
7939
|
},
|
|
7886
7940
|
finalize: async (commandParts, exitCode) => {
|
|
7887
|
-
|
|
7941
|
+
writeFileSync13(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
7888
7942
|
`, "utf-8");
|
|
7889
7943
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
7890
7944
|
proc.exited,
|
|
7891
7945
|
stdoutTextPromise,
|
|
7892
7946
|
stderrTextPromise
|
|
7893
7947
|
]);
|
|
7894
|
-
|
|
7895
|
-
|
|
7948
|
+
rmSync12(readyFile, { force: true });
|
|
7949
|
+
rmSync12(requestFile, { force: true });
|
|
7896
7950
|
if (sidecarExitCode !== 0) {
|
|
7897
7951
|
throw new Error(`snapshot sidecar failed (${sidecarExitCode}): ${stderr || stdout}`);
|
|
7898
7952
|
}
|
|
@@ -7912,10 +7966,10 @@ function resolveSnapshotSidecarScriptPath() {
|
|
|
7912
7966
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
7913
7967
|
}
|
|
7914
7968
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
7915
|
-
return
|
|
7969
|
+
return resolve34(binDir, "snapshot-sidecar");
|
|
7916
7970
|
}
|
|
7917
7971
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
7918
|
-
if (!
|
|
7972
|
+
if (!existsSync32(binaryPath)) {
|
|
7919
7973
|
return false;
|
|
7920
7974
|
}
|
|
7921
7975
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -7930,12 +7984,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
7930
7984
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
7931
7985
|
].filter((value) => Boolean(value));
|
|
7932
7986
|
for (const root of hostRoots) {
|
|
7933
|
-
const candidate =
|
|
7934
|
-
if (
|
|
7987
|
+
const candidate = resolve34(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
7988
|
+
if (existsSync32(candidate)) {
|
|
7935
7989
|
return candidate;
|
|
7936
7990
|
}
|
|
7937
7991
|
}
|
|
7938
|
-
return
|
|
7992
|
+
return resolve34(import.meta.dir, "..", fileName);
|
|
7939
7993
|
}
|
|
7940
7994
|
function resolveBunCliInvocation() {
|
|
7941
7995
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -7962,7 +8016,7 @@ function resolveBunCliInvocation() {
|
|
|
7962
8016
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
7963
8017
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
7964
8018
|
while (Date.now() < deadline) {
|
|
7965
|
-
if (
|
|
8019
|
+
if (existsSync32(readyFile)) {
|
|
7966
8020
|
return;
|
|
7967
8021
|
}
|
|
7968
8022
|
const exitCode = proc.exitCode;
|
|
@@ -7980,9 +8034,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
7980
8034
|
async function hydrateRuntimeMemory(options) {
|
|
7981
8035
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
7982
8036
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
7983
|
-
const hydratedPath =
|
|
8037
|
+
const hydratedPath = resolve35(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
7984
8038
|
try {
|
|
7985
|
-
await mkdir3(
|
|
8039
|
+
await mkdir3(resolve35(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
7986
8040
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
7987
8041
|
return {
|
|
7988
8042
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -7997,12 +8051,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
7997
8051
|
}
|
|
7998
8052
|
}
|
|
7999
8053
|
async function createRuntimeTaskRecordReader(options) {
|
|
8000
|
-
const legacyConfigPath =
|
|
8054
|
+
const legacyConfigPath = resolve35(options.projectRoot, ".rig", "task-config.json");
|
|
8001
8055
|
let pluginHostContext = null;
|
|
8002
8056
|
try {
|
|
8003
8057
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
8004
8058
|
} catch (error) {
|
|
8005
|
-
if (!
|
|
8059
|
+
if (!existsSync33(legacyConfigPath)) {
|
|
8006
8060
|
throw error;
|
|
8007
8061
|
}
|
|
8008
8062
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -8022,7 +8076,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
8022
8076
|
source: "plugin"
|
|
8023
8077
|
};
|
|
8024
8078
|
}
|
|
8025
|
-
if (
|
|
8079
|
+
if (existsSync33(legacyConfigPath)) {
|
|
8026
8080
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
8027
8081
|
options.diagnostics?.(message);
|
|
8028
8082
|
console.warn(message);
|
|
@@ -8039,10 +8093,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
8039
8093
|
};
|
|
8040
8094
|
}
|
|
8041
8095
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
8042
|
-
const jsonPath =
|
|
8043
|
-
if (
|
|
8096
|
+
const jsonPath = resolve35(projectRoot, "rig.config.json");
|
|
8097
|
+
if (existsSync33(jsonPath)) {
|
|
8044
8098
|
try {
|
|
8045
|
-
const parsed = JSON.parse(
|
|
8099
|
+
const parsed = JSON.parse(readFileSync16(jsonPath, "utf8"));
|
|
8046
8100
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
8047
8101
|
const taskSource = parsed.taskSource;
|
|
8048
8102
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -8054,12 +8108,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
8054
8108
|
return null;
|
|
8055
8109
|
}
|
|
8056
8110
|
}
|
|
8057
|
-
const tsPath =
|
|
8058
|
-
if (!
|
|
8111
|
+
const tsPath = resolve35(projectRoot, "rig.config.ts");
|
|
8112
|
+
if (!existsSync33(tsPath)) {
|
|
8059
8113
|
return null;
|
|
8060
8114
|
}
|
|
8061
8115
|
try {
|
|
8062
|
-
const source =
|
|
8116
|
+
const source = readFileSync16(tsPath, "utf8");
|
|
8063
8117
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
8064
8118
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
8065
8119
|
return kind ?? null;
|
|
@@ -8129,8 +8183,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
8129
8183
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
8130
8184
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
8131
8185
|
};
|
|
8132
|
-
const configPath =
|
|
8133
|
-
await mkdir3(
|
|
8186
|
+
const configPath = resolve35(options.workspaceDir, ".rig", "task-config.json");
|
|
8187
|
+
await mkdir3(resolve35(options.workspaceDir, ".rig"), { recursive: true });
|
|
8134
8188
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
8135
8189
|
`, "utf-8");
|
|
8136
8190
|
}
|
|
@@ -8194,9 +8248,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8194
8248
|
}
|
|
8195
8249
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8196
8250
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8197
|
-
const workspaceDir =
|
|
8251
|
+
const workspaceDir = resolve35(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8198
8252
|
const createdAt = new Date().toISOString();
|
|
8199
|
-
if (!
|
|
8253
|
+
if (!existsSync33(resolve35(monorepoRoot, ".git"))) {
|
|
8200
8254
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8201
8255
|
}
|
|
8202
8256
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8231,7 +8285,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8231
8285
|
logsDir: overlay.logsDir,
|
|
8232
8286
|
stateDir: overlay.stateDir,
|
|
8233
8287
|
sessionDir: overlay.sessionDir,
|
|
8234
|
-
claudeHomeDir:
|
|
8288
|
+
claudeHomeDir: resolve35(workspaceLayout.homeDir, ".claude"),
|
|
8235
8289
|
contextFile: overlay.contextPath,
|
|
8236
8290
|
binDir: workspaceLayout.binDir,
|
|
8237
8291
|
createdAt
|
|
@@ -8244,8 +8298,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8244
8298
|
projectRoot: options.projectRoot,
|
|
8245
8299
|
workspaceDir
|
|
8246
8300
|
});
|
|
8247
|
-
|
|
8248
|
-
|
|
8301
|
+
mkdirSync19(runtime.binDir, { recursive: true });
|
|
8302
|
+
mkdirSync19(workspaceLayout.distDir, { recursive: true });
|
|
8249
8303
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8250
8304
|
if (options.preserveTaskArtifacts) {
|
|
8251
8305
|
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
@@ -8264,7 +8318,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8264
8318
|
runtimeId: options.id
|
|
8265
8319
|
}),
|
|
8266
8320
|
workspaceDir,
|
|
8267
|
-
artifactRoot:
|
|
8321
|
+
artifactRoot: resolve35(workspaceDir, "artifacts", options.taskId),
|
|
8268
8322
|
hostProjectRoot: options.projectRoot,
|
|
8269
8323
|
monorepoMainRoot: monorepoRoot,
|
|
8270
8324
|
monorepoBaseRef: baseRef,
|
|
@@ -8280,8 +8334,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8280
8334
|
stateDir: overlay.stateDir,
|
|
8281
8335
|
logsDir: overlay.logsDir,
|
|
8282
8336
|
sessionDir: overlay.sessionDir,
|
|
8283
|
-
sessionFile:
|
|
8284
|
-
policyFile:
|
|
8337
|
+
sessionFile: resolve35(overlay.sessionDir, "session.json"),
|
|
8338
|
+
policyFile: resolve35(options.projectRoot, "rig/policy/policy.json"),
|
|
8285
8339
|
binDir: runtime.binDir,
|
|
8286
8340
|
createdAt,
|
|
8287
8341
|
memory
|
|
@@ -8292,9 +8346,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8292
8346
|
task: taskResolution.task,
|
|
8293
8347
|
taskEntry
|
|
8294
8348
|
});
|
|
8295
|
-
const manifestPath =
|
|
8349
|
+
const manifestPath = resolve35(runtimeRoot, "manifest.json");
|
|
8296
8350
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8297
|
-
const runtimeAgentBinary =
|
|
8351
|
+
const runtimeAgentBinary = resolve35(runtime.binDir, "rig-agent");
|
|
8298
8352
|
await ensureRigGitBinaryPath();
|
|
8299
8353
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8300
8354
|
projectRoot: options.projectRoot,
|
|
@@ -8309,10 +8363,10 @@ async function ensureAgentRuntime(options) {
|
|
|
8309
8363
|
const bakedStatusOutput = await captureStdout(async () => {
|
|
8310
8364
|
taskStatus(options.projectRoot);
|
|
8311
8365
|
});
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8366
|
+
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8367
|
+
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8368
|
+
mkdirSync19(runtime.binDir, { recursive: true });
|
|
8369
|
+
mkdirSync19(workspaceLayout.distDir, { recursive: true });
|
|
8316
8370
|
await buildRuntimeToolchain({
|
|
8317
8371
|
projectRoot: options.projectRoot,
|
|
8318
8372
|
workspaceDir,
|
|
@@ -8349,9 +8403,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8349
8403
|
workspaceDir,
|
|
8350
8404
|
taskEntry
|
|
8351
8405
|
});
|
|
8352
|
-
const sandboxDir =
|
|
8406
|
+
const sandboxDir = resolve35(runtimeRoot, "sandbox");
|
|
8353
8407
|
await mkdir3(sandboxDir, { recursive: true });
|
|
8354
|
-
await writeFile2(
|
|
8408
|
+
await writeFile2(resolve35(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8355
8409
|
id: options.id,
|
|
8356
8410
|
taskId: options.taskId,
|
|
8357
8411
|
mode: "worktree",
|
|
@@ -8458,8 +8512,8 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8458
8512
|
const sendRequest = async (method, params) => {
|
|
8459
8513
|
const id = nextRequestId;
|
|
8460
8514
|
nextRequestId += 1;
|
|
8461
|
-
const resultPromise = new Promise((
|
|
8462
|
-
pendingResponses.set(id, { resolve:
|
|
8515
|
+
const resultPromise = new Promise((resolve36, reject) => {
|
|
8516
|
+
pendingResponses.set(id, { resolve: resolve36, reject });
|
|
8463
8517
|
});
|
|
8464
8518
|
await sendMessage({ id, method, params });
|
|
8465
8519
|
return resultPromise;
|
|
@@ -8658,8 +8712,8 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8658
8712
|
console.error(line);
|
|
8659
8713
|
}
|
|
8660
8714
|
});
|
|
8661
|
-
const exitPromise = new Promise((
|
|
8662
|
-
child.once("close", (code, signal) =>
|
|
8715
|
+
const exitPromise = new Promise((resolve36) => {
|
|
8716
|
+
child.once("close", (code, signal) => resolve36({ code, signal }));
|
|
8663
8717
|
});
|
|
8664
8718
|
await sendRequest("initialize", {
|
|
8665
8719
|
clientInfo: DEFAULT_CLIENT_INFO,
|
|
@@ -8700,7 +8754,7 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8700
8754
|
while (!completionState.current) {
|
|
8701
8755
|
exitResult = await Promise.race([
|
|
8702
8756
|
exitPromise,
|
|
8703
|
-
new Promise((
|
|
8757
|
+
new Promise((resolve36) => setTimeout(() => resolve36(null), 100))
|
|
8704
8758
|
]);
|
|
8705
8759
|
if (exitResult) {
|
|
8706
8760
|
break;
|
|
@@ -8849,13 +8903,13 @@ function sanitizeEnv(env) {
|
|
|
8849
8903
|
return next;
|
|
8850
8904
|
}
|
|
8851
8905
|
function writeChildLine(child, line) {
|
|
8852
|
-
return new Promise((
|
|
8906
|
+
return new Promise((resolve36, reject) => {
|
|
8853
8907
|
child.stdin.write(line, (error) => {
|
|
8854
8908
|
if (error) {
|
|
8855
8909
|
reject(error);
|
|
8856
8910
|
return;
|
|
8857
8911
|
}
|
|
8858
|
-
|
|
8912
|
+
resolve36();
|
|
8859
8913
|
});
|
|
8860
8914
|
});
|
|
8861
8915
|
}
|
|
@@ -8903,8 +8957,8 @@ function formatJsonRpcError(error) {
|
|
|
8903
8957
|
|
|
8904
8958
|
// packages/runtime/src/control-plane/pi-sessiond/launcher.ts
|
|
8905
8959
|
import { randomBytes } from "crypto";
|
|
8906
|
-
import { existsSync as
|
|
8907
|
-
import { dirname as dirname14, resolve as
|
|
8960
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync20, readFileSync as readFileSync17, rmSync as rmSync14 } from "fs";
|
|
8961
|
+
import { dirname as dirname14, resolve as resolve36 } from "path";
|
|
8908
8962
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8909
8963
|
|
|
8910
8964
|
// packages/runtime/src/control-plane/pi-sessiond/client.ts
|
|
@@ -8949,15 +9003,15 @@ class RigPiSessionDaemonClient {
|
|
|
8949
9003
|
var BUILD_CONFIG2 = {};
|
|
8950
9004
|
var BAKED_RIG_SOURCE_ROOT = BUILD_CONFIG2.RIG_SOURCE_ROOT ?? "";
|
|
8951
9005
|
async function ensureRigPiSessionDaemon(input) {
|
|
8952
|
-
const rootDir =
|
|
8953
|
-
|
|
8954
|
-
const readyFile =
|
|
9006
|
+
const rootDir = resolve36(input.rootDir);
|
|
9007
|
+
mkdirSync20(rootDir, { recursive: true });
|
|
9008
|
+
const readyFile = resolve36(rootDir, "ready.json");
|
|
8955
9009
|
const existing = readDaemonReadyFile(readyFile);
|
|
8956
9010
|
const existingHandle = existing ? await tryReady(existing) : null;
|
|
8957
9011
|
if (existingHandle)
|
|
8958
9012
|
return existingHandle;
|
|
8959
9013
|
try {
|
|
8960
|
-
|
|
9014
|
+
rmSync14(readyFile, { force: true });
|
|
8961
9015
|
} catch {}
|
|
8962
9016
|
const token = randomBytes(32).toString("hex");
|
|
8963
9017
|
const binPath = resolveRigPiSessionDaemonBinPath(input.env);
|
|
@@ -8987,7 +9041,12 @@ async function ensureRigPiSessionDaemon(input) {
|
|
|
8987
9041
|
return handle;
|
|
8988
9042
|
await sleep(100);
|
|
8989
9043
|
}
|
|
8990
|
-
throw new Error(
|
|
9044
|
+
throw new Error([
|
|
9045
|
+
`Rig Pi session daemon did not become ready at ${readyFile}.`,
|
|
9046
|
+
"Usual causes: the bundled Pi runtime is missing or broken. Run `rig doctor` to check Pi wiring,",
|
|
9047
|
+
"set RIG_PI_BINARY to a working Pi build, or run without Pi via RIG_RUNTIME_ADAPTER=claude-code."
|
|
9048
|
+
].join(`
|
|
9049
|
+
`));
|
|
8991
9050
|
}
|
|
8992
9051
|
function privateMetadataForDaemon(input) {
|
|
8993
9052
|
return { public: input.publicMetadata, daemonConnection: input.connection };
|
|
@@ -9028,20 +9087,25 @@ function resolveRigPiSessionDaemonBinPath(env) {
|
|
|
9028
9087
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
9029
9088
|
].filter((value) => Boolean(value));
|
|
9030
9089
|
for (const root of roots) {
|
|
9031
|
-
const candidate =
|
|
9032
|
-
if (
|
|
9090
|
+
const candidate = resolve36(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts");
|
|
9091
|
+
if (existsSync34(candidate))
|
|
9033
9092
|
return candidate;
|
|
9034
9093
|
}
|
|
9035
9094
|
const moduleCandidate = fileURLToPath2(new URL("./bin.ts", import.meta.url));
|
|
9036
|
-
if (
|
|
9095
|
+
if (existsSync34(moduleCandidate))
|
|
9037
9096
|
return moduleCandidate;
|
|
9038
|
-
throw new Error(
|
|
9097
|
+
throw new Error([
|
|
9098
|
+
"Unable to locate rig-pi-sessiond entrypoint.",
|
|
9099
|
+
"Set RIG_PI_SESSIOND_BIN or RIG_CONTROL_PLANE_SOURCE_ROOT to the Rig source checkout,",
|
|
9100
|
+
"or run without the Pi daemon via RIG_RUNTIME_ADAPTER=claude-code."
|
|
9101
|
+
].join(`
|
|
9102
|
+
`));
|
|
9039
9103
|
}
|
|
9040
9104
|
function readDaemonReadyFile(path) {
|
|
9041
|
-
if (!
|
|
9105
|
+
if (!existsSync34(path))
|
|
9042
9106
|
return null;
|
|
9043
9107
|
try {
|
|
9044
|
-
const parsed = JSON.parse(
|
|
9108
|
+
const parsed = JSON.parse(readFileSync17(path, "utf8"));
|
|
9045
9109
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
9046
9110
|
} catch {
|
|
9047
9111
|
return null;
|
|
@@ -9051,10 +9115,10 @@ function sleep(ms) {
|
|
|
9051
9115
|
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
9052
9116
|
}
|
|
9053
9117
|
function resolveRigPiSessionDaemonRoot(stateDir) {
|
|
9054
|
-
const root =
|
|
9055
|
-
|
|
9056
|
-
if (!
|
|
9057
|
-
|
|
9118
|
+
const root = resolve36(stateDir, "pi-sessiond");
|
|
9119
|
+
mkdirSync20(dirname14(root), { recursive: true });
|
|
9120
|
+
if (!existsSync34(root))
|
|
9121
|
+
mkdirSync20(root, { recursive: true });
|
|
9058
9122
|
return root;
|
|
9059
9123
|
}
|
|
9060
9124
|
|
|
@@ -9092,7 +9156,7 @@ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar = start
|
|
|
9092
9156
|
}
|
|
9093
9157
|
}
|
|
9094
9158
|
async function runAgentWrapper(options = {}) {
|
|
9095
|
-
const projectRoot =
|
|
9159
|
+
const projectRoot = resolve37(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
|
|
9096
9160
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
9097
9161
|
const argv = options.argv || process.argv.slice(2);
|
|
9098
9162
|
if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
|
|
@@ -9168,11 +9232,11 @@ async function runAgentWrapper(options = {}) {
|
|
|
9168
9232
|
const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
|
|
9169
9233
|
const runClaudeCompatUnsandboxed = provider === "claude-code" && bypassOuterRuntimeSandbox;
|
|
9170
9234
|
if (runClaudeCompatUnsandboxed && process.env.HOME?.trim()) {
|
|
9171
|
-
env.CLAUDE_HOME =
|
|
9235
|
+
env.CLAUDE_HOME = resolve37(process.env.HOME.trim(), ".claude");
|
|
9172
9236
|
env.RIG_CLAUDE_RUNTIME_HOME = runtime.claudeHomeDir;
|
|
9173
9237
|
}
|
|
9174
9238
|
if (provider === "pi") {
|
|
9175
|
-
env.PI_CODING_AGENT_DIR =
|
|
9239
|
+
env.PI_CODING_AGENT_DIR = resolve37(runtime.homeDir, ".pi", "agent");
|
|
9176
9240
|
env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
|
|
9177
9241
|
}
|
|
9178
9242
|
env.RIG_RUNTIME_SANDBOX = "enforce";
|
|
@@ -9373,7 +9437,7 @@ async function runPiSessionDaemonProvider(input) {
|
|
|
9373
9437
|
const start = await daemon.client.request("POST", "/sessions", {
|
|
9374
9438
|
runId,
|
|
9375
9439
|
cwd: input.runtime.workspaceDir,
|
|
9376
|
-
agentDir: input.env.PI_CODING_AGENT_DIR ||
|
|
9440
|
+
agentDir: input.env.PI_CODING_AGENT_DIR || resolve37(input.runtime.homeDir, ".pi", "agent"),
|
|
9377
9441
|
sessionDir: input.runtime.sessionDir,
|
|
9378
9442
|
sessionName: input.sessionName
|
|
9379
9443
|
});
|
|
@@ -9704,6 +9768,7 @@ async function runBeadsJson(projectRoot, args) {
|
|
|
9704
9768
|
return null;
|
|
9705
9769
|
}
|
|
9706
9770
|
}
|
|
9771
|
+
var warnedUnknownRuntimeAdapter = false;
|
|
9707
9772
|
function resolveProvider() {
|
|
9708
9773
|
const value = process.env.RIG_RUNTIME_ADAPTER?.trim().toLowerCase();
|
|
9709
9774
|
if (!value) {
|
|
@@ -9715,6 +9780,10 @@ function resolveProvider() {
|
|
|
9715
9780
|
if (value === "pi" || value === "rig-pi" || value === "@rig/pi") {
|
|
9716
9781
|
return "pi";
|
|
9717
9782
|
}
|
|
9783
|
+
if (value !== "claude-code" && value !== "claude" && !warnedUnknownRuntimeAdapter) {
|
|
9784
|
+
warnedUnknownRuntimeAdapter = true;
|
|
9785
|
+
console.warn(`[rig-agent] Unknown RIG_RUNTIME_ADAPTER value "${value}"; falling back to claude-code. Use pi|claude-code|codex.`);
|
|
9786
|
+
}
|
|
9718
9787
|
return "claude-code";
|
|
9719
9788
|
}
|
|
9720
9789
|
function hasCliOption(argv, option) {
|
|
@@ -9767,8 +9836,8 @@ function resolveFromShellPath(binary) {
|
|
|
9767
9836
|
function resolveBundledPiBinary() {
|
|
9768
9837
|
try {
|
|
9769
9838
|
const packageJson = requireFromRuntime.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
9770
|
-
const binaryPath =
|
|
9771
|
-
return
|
|
9839
|
+
const binaryPath = resolve37(packageJson, "..", "dist", "cli.js");
|
|
9840
|
+
return existsSync35(binaryPath) ? binaryPath : null;
|
|
9772
9841
|
} catch {
|
|
9773
9842
|
return null;
|
|
9774
9843
|
}
|
|
@@ -9804,7 +9873,7 @@ async function waitForDirtyBaselineReady(runtime, taskId) {
|
|
|
9804
9873
|
workspaceDir: runtime.workspaceDir,
|
|
9805
9874
|
readyFile
|
|
9806
9875
|
});
|
|
9807
|
-
while (!
|
|
9876
|
+
while (!existsSync35(readyFile)) {
|
|
9808
9877
|
if (Date.now() >= deadline) {
|
|
9809
9878
|
throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
|
|
9810
9879
|
}
|
|
@@ -9872,9 +9941,9 @@ async function readPluginTaskStatus(projectRoot, taskId) {
|
|
|
9872
9941
|
}
|
|
9873
9942
|
}
|
|
9874
9943
|
function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
9875
|
-
const handoffDir =
|
|
9876
|
-
|
|
9877
|
-
const handoffPath =
|
|
9944
|
+
const handoffDir = resolve37(hostProjectRoot, ".rig/runtime/handoffs");
|
|
9945
|
+
mkdirSync21(handoffDir, { recursive: true });
|
|
9946
|
+
const handoffPath = resolve37(handoffDir, `${taskId}-${Date.now()}.json`);
|
|
9878
9947
|
const handoff = {
|
|
9879
9948
|
taskId,
|
|
9880
9949
|
runtimeId: runtime.id,
|
|
@@ -9890,7 +9959,7 @@ function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
|
9890
9959
|
`rig git open-pr --task ${taskId}`
|
|
9891
9960
|
]
|
|
9892
9961
|
};
|
|
9893
|
-
|
|
9962
|
+
writeFileSync14(handoffPath, `${JSON.stringify(handoff, null, 2)}
|
|
9894
9963
|
`, "utf-8");
|
|
9895
9964
|
console.log(`[rig-agent] Completion verification paused for ${taskId}.`);
|
|
9896
9965
|
console.log(`[rig-agent] Runtime handoff saved: ${handoffPath}`);
|
|
@@ -9940,13 +10009,13 @@ async function readTaskMetadata2(taskRoot, taskId) {
|
|
|
9940
10009
|
async function readTaskConfigHints(taskRoot, taskId) {
|
|
9941
10010
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
9942
10011
|
const candidates = [
|
|
9943
|
-
runtimeContext?.monorepoMainRoot ?
|
|
9944
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
9945
|
-
|
|
9946
|
-
|
|
10012
|
+
runtimeContext?.monorepoMainRoot ? resolve37(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
10013
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve37(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
10014
|
+
resolve37(taskRoot, ".rig", "task-config.json"),
|
|
10015
|
+
resolve37(taskRoot, "rig", "task-config.json")
|
|
9947
10016
|
].filter(Boolean);
|
|
9948
10017
|
for (const configPath of candidates) {
|
|
9949
|
-
if (!
|
|
10018
|
+
if (!existsSync35(configPath)) {
|
|
9950
10019
|
continue;
|
|
9951
10020
|
}
|
|
9952
10021
|
try {
|