@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";
|
|
@@ -2964,7 +3018,7 @@ function updateGithubIssueTaskBySourceIssueId(sourceIssueId, taskId, update, opt
|
|
|
2964
3018
|
return true;
|
|
2965
3019
|
}
|
|
2966
3020
|
function updateSourceAwareTaskConfigTask(projectRoot, taskId, update, options = {}) {
|
|
2967
|
-
const configPath = options.configPath ??
|
|
3021
|
+
const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
|
|
2968
3022
|
const rawEntry = readRawTaskEntry(configPath, taskId);
|
|
2969
3023
|
if (!rawEntry) {
|
|
2970
3024
|
const configuredFilesPath = readConfiguredFilesTaskSourcePath(projectRoot);
|
|
@@ -3017,10 +3071,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
3017
3071
|
return metadata;
|
|
3018
3072
|
}
|
|
3019
3073
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
3020
|
-
const jsonPath =
|
|
3021
|
-
if (
|
|
3074
|
+
const jsonPath = resolve14(projectRoot, "rig.config.json");
|
|
3075
|
+
if (existsSync14(jsonPath)) {
|
|
3022
3076
|
try {
|
|
3023
|
-
const parsed = JSON.parse(
|
|
3077
|
+
const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
|
|
3024
3078
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
3025
3079
|
const source = parsed.taskSource;
|
|
3026
3080
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -3029,12 +3083,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
3029
3083
|
return null;
|
|
3030
3084
|
}
|
|
3031
3085
|
}
|
|
3032
|
-
const tsPath =
|
|
3033
|
-
if (!
|
|
3086
|
+
const tsPath = resolve14(projectRoot, "rig.config.ts");
|
|
3087
|
+
if (!existsSync14(tsPath)) {
|
|
3034
3088
|
return null;
|
|
3035
3089
|
}
|
|
3036
3090
|
try {
|
|
3037
|
-
const source =
|
|
3091
|
+
const source = readFileSync7(tsPath, "utf8");
|
|
3038
3092
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3039
3093
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3040
3094
|
if (kind !== "files") {
|
|
@@ -3054,10 +3108,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
3054
3108
|
return isPlainRecord2(entry) ? entry : null;
|
|
3055
3109
|
}
|
|
3056
3110
|
function readRawTaskConfig(configPath) {
|
|
3057
|
-
if (!
|
|
3111
|
+
if (!existsSync14(configPath)) {
|
|
3058
3112
|
return null;
|
|
3059
3113
|
}
|
|
3060
|
-
const parsed = JSON.parse(
|
|
3114
|
+
const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
|
|
3061
3115
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
3062
3116
|
}
|
|
3063
3117
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -3074,16 +3128,16 @@ function writeLegacyTaskStatus(configPath, taskId, status) {
|
|
|
3074
3128
|
return;
|
|
3075
3129
|
}
|
|
3076
3130
|
entry.status = status;
|
|
3077
|
-
|
|
3131
|
+
writeFileSync6(configPath, `${JSON.stringify(rawConfig, null, 2)}
|
|
3078
3132
|
`, "utf8");
|
|
3079
3133
|
}
|
|
3080
3134
|
function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
|
|
3081
|
-
const directory =
|
|
3135
|
+
const directory = resolve14(projectRoot, sourcePath);
|
|
3082
3136
|
const file = findFileBackedTaskFile(directory, taskId);
|
|
3083
3137
|
if (!file) {
|
|
3084
3138
|
return false;
|
|
3085
3139
|
}
|
|
3086
|
-
const raw = JSON.parse(
|
|
3140
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
3087
3141
|
if (!isPlainRecord2(raw)) {
|
|
3088
3142
|
return false;
|
|
3089
3143
|
}
|
|
@@ -3100,17 +3154,17 @@ function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
|
|
|
3100
3154
|
{ body: update.comment, createdAt: new Date().toISOString(), source: "rig" }
|
|
3101
3155
|
];
|
|
3102
3156
|
}
|
|
3103
|
-
|
|
3157
|
+
writeFileSync6(file, `${JSON.stringify(raw, null, 2)}
|
|
3104
3158
|
`, "utf8");
|
|
3105
3159
|
return true;
|
|
3106
3160
|
}
|
|
3107
3161
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
3108
|
-
const directory =
|
|
3109
|
-
if (!
|
|
3162
|
+
const directory = resolve14(projectRoot, sourcePath);
|
|
3163
|
+
if (!existsSync14(directory)) {
|
|
3110
3164
|
return [];
|
|
3111
3165
|
}
|
|
3112
3166
|
const tasks = [];
|
|
3113
|
-
for (const name of
|
|
3167
|
+
for (const name of readdirSync2(directory)) {
|
|
3114
3168
|
if (!FILE_TASK_PATTERN.test(name))
|
|
3115
3169
|
continue;
|
|
3116
3170
|
const inferredId = basename4(name).replace(FILE_TASK_PATTERN, "");
|
|
@@ -3121,11 +3175,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
3121
3175
|
return tasks;
|
|
3122
3176
|
}
|
|
3123
3177
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
3124
|
-
const file = findFileBackedTaskFile(
|
|
3178
|
+
const file = findFileBackedTaskFile(resolve14(projectRoot, sourcePath), taskId);
|
|
3125
3179
|
if (!file) {
|
|
3126
3180
|
return null;
|
|
3127
3181
|
}
|
|
3128
|
-
const raw = JSON.parse(
|
|
3182
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
3129
3183
|
if (!isPlainRecord2(raw)) {
|
|
3130
3184
|
return null;
|
|
3131
3185
|
}
|
|
@@ -3138,17 +3192,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
3138
3192
|
};
|
|
3139
3193
|
}
|
|
3140
3194
|
function findFileBackedTaskFile(directory, taskId) {
|
|
3141
|
-
if (!
|
|
3195
|
+
if (!existsSync14(directory)) {
|
|
3142
3196
|
return null;
|
|
3143
3197
|
}
|
|
3144
|
-
for (const name of
|
|
3198
|
+
for (const name of readdirSync2(directory)) {
|
|
3145
3199
|
if (!FILE_TASK_PATTERN.test(name))
|
|
3146
3200
|
continue;
|
|
3147
3201
|
const file = join3(directory, name);
|
|
3148
3202
|
try {
|
|
3149
3203
|
if (!statSync3(file).isFile())
|
|
3150
3204
|
continue;
|
|
3151
|
-
const raw = JSON.parse(
|
|
3205
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
3152
3206
|
const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
|
|
3153
3207
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
3154
3208
|
if (id === taskId) {
|
|
@@ -3497,8 +3551,8 @@ function buildTaskRunLifecycleComment(input) {
|
|
|
3497
3551
|
}
|
|
3498
3552
|
|
|
3499
3553
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
3500
|
-
import { existsSync as
|
|
3501
|
-
import { basename as basename6, resolve as
|
|
3554
|
+
import { existsSync as existsSync18, readFileSync as readFileSync9, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
3555
|
+
import { basename as basename6, resolve as resolve18 } from "path";
|
|
3502
3556
|
|
|
3503
3557
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
3504
3558
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -3606,39 +3660,39 @@ function readTaskStateMetadataEnvelope(raw) {
|
|
|
3606
3660
|
};
|
|
3607
3661
|
}
|
|
3608
3662
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
3609
|
-
import { existsSync as
|
|
3610
|
-
import { resolve as
|
|
3663
|
+
import { existsSync as existsSync17, readFileSync as readFileSync8 } from "fs";
|
|
3664
|
+
import { resolve as resolve17 } from "path";
|
|
3611
3665
|
|
|
3612
3666
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
3613
|
-
import { existsSync as
|
|
3614
|
-
import { resolve as
|
|
3667
|
+
import { existsSync as existsSync16 } from "fs";
|
|
3668
|
+
import { resolve as resolve16 } from "path";
|
|
3615
3669
|
|
|
3616
3670
|
// packages/runtime/src/control-plane/repos/layout.ts
|
|
3617
3671
|
init_layout();
|
|
3618
|
-
import { existsSync as
|
|
3619
|
-
import { basename as basename5, dirname as dirname9, join as join4, resolve as
|
|
3672
|
+
import { existsSync as existsSync15 } from "fs";
|
|
3673
|
+
import { basename as basename5, dirname as dirname9, join as join4, resolve as resolve15 } from "path";
|
|
3620
3674
|
function resolveRepoStateDir(projectRoot) {
|
|
3621
|
-
const normalizedProjectRoot =
|
|
3675
|
+
const normalizedProjectRoot = resolve15(projectRoot);
|
|
3622
3676
|
const projectParent = dirname9(normalizedProjectRoot);
|
|
3623
3677
|
if (basename5(projectParent) === ".worktrees") {
|
|
3624
3678
|
const ownerRoot = dirname9(projectParent);
|
|
3625
|
-
const ownerHasRepoMarkers =
|
|
3679
|
+
const ownerHasRepoMarkers = existsSync15(resolve15(ownerRoot, ".git")) || existsSync15(resolve15(ownerRoot, ".rig", "state"));
|
|
3626
3680
|
if (ownerHasRepoMarkers) {
|
|
3627
|
-
return
|
|
3681
|
+
return resolve15(ownerRoot, ".rig", "state");
|
|
3628
3682
|
}
|
|
3629
3683
|
}
|
|
3630
|
-
return
|
|
3684
|
+
return resolve15(projectRoot, ".rig", "state");
|
|
3631
3685
|
}
|
|
3632
3686
|
function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
3633
|
-
const normalizedProjectRoot =
|
|
3687
|
+
const normalizedProjectRoot = resolve15(projectRoot);
|
|
3634
3688
|
const entry = getManagedRepoEntry(repoId);
|
|
3635
3689
|
const stateDir = resolveRepoStateDir(normalizedProjectRoot);
|
|
3636
3690
|
const metadataRelativePath = join4("repos", entry.id);
|
|
3637
|
-
const metadataRoot =
|
|
3691
|
+
const metadataRoot = resolve15(stateDir, metadataRelativePath);
|
|
3638
3692
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3639
|
-
const runsInsideTaskWorktree = runtimeWorkspace &&
|
|
3693
|
+
const runsInsideTaskWorktree = runtimeWorkspace && resolve15(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
|
|
3640
3694
|
const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
|
|
3641
|
-
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ?
|
|
3695
|
+
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve15(process.env[entry.checkoutEnvVar].trim()) : resolve15(normalizedProjectRoot, entry.alias);
|
|
3642
3696
|
return {
|
|
3643
3697
|
projectRoot: normalizedProjectRoot,
|
|
3644
3698
|
repoId: entry.id,
|
|
@@ -3646,12 +3700,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
|
3646
3700
|
defaultBranch: entry.defaultBranch,
|
|
3647
3701
|
remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
|
|
3648
3702
|
checkoutRoot,
|
|
3649
|
-
worktreesRoot:
|
|
3703
|
+
worktreesRoot: resolve15(checkoutRoot, ".worktrees"),
|
|
3650
3704
|
stateDir,
|
|
3651
3705
|
metadataRoot,
|
|
3652
3706
|
metadataRelativePath,
|
|
3653
|
-
mirrorRoot:
|
|
3654
|
-
mirrorStatePath:
|
|
3707
|
+
mirrorRoot: resolve15(metadataRoot, "mirror.git"),
|
|
3708
|
+
mirrorStatePath: resolve15(metadataRoot, "mirror-state.json"),
|
|
3655
3709
|
mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
|
|
3656
3710
|
};
|
|
3657
3711
|
}
|
|
@@ -3669,7 +3723,7 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3669
3723
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3670
3724
|
try {
|
|
3671
3725
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
3672
|
-
if (
|
|
3726
|
+
if (existsSync16(resolve16(layout.mirrorRoot, "HEAD"))) {
|
|
3673
3727
|
return layout.mirrorRoot;
|
|
3674
3728
|
}
|
|
3675
3729
|
} catch {}
|
|
@@ -3680,8 +3734,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
3680
3734
|
var DEFAULT_READ_DEPS2 = {
|
|
3681
3735
|
fetchRef: nativeFetchRef,
|
|
3682
3736
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
3683
|
-
exists:
|
|
3684
|
-
readFile: (path) =>
|
|
3737
|
+
exists: existsSync17,
|
|
3738
|
+
readFile: (path) => readFileSync8(path, "utf8")
|
|
3685
3739
|
};
|
|
3686
3740
|
function parseIssueStatus(rawStatus) {
|
|
3687
3741
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -3762,12 +3816,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
3762
3816
|
if (runtimeContextPath) {
|
|
3763
3817
|
return true;
|
|
3764
3818
|
}
|
|
3765
|
-
return
|
|
3819
|
+
return existsSync17(resolve17(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
3766
3820
|
}
|
|
3767
3821
|
function readLocalTrackerState(projectRoot, deps) {
|
|
3768
3822
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
3769
|
-
const issuesPath =
|
|
3770
|
-
const taskStatePath =
|
|
3823
|
+
const issuesPath = resolve17(monorepoRoot, ".beads", "issues.jsonl");
|
|
3824
|
+
const taskStatePath = resolve17(monorepoRoot, ".beads", "task-state.json");
|
|
3771
3825
|
return projectSyncedTrackerSnapshot({
|
|
3772
3826
|
source: "local",
|
|
3773
3827
|
issuesBaseOid: null,
|
|
@@ -3829,7 +3883,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
3829
3883
|
return readValidationDescriptionMap(raw);
|
|
3830
3884
|
}
|
|
3831
3885
|
function readSourceValidationDescriptions(projectRoot) {
|
|
3832
|
-
const rootRaw = readJsonFile(
|
|
3886
|
+
const rootRaw = readJsonFile(resolve18(projectRoot, "rig", "task-config.json"), {});
|
|
3833
3887
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
3834
3888
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
3835
3889
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -3905,15 +3959,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
3905
3959
|
return meta.validation_descriptions;
|
|
3906
3960
|
}
|
|
3907
3961
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
3908
|
-
const taskStatePath =
|
|
3962
|
+
const taskStatePath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
3909
3963
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
3910
3964
|
}
|
|
3911
3965
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
3912
|
-
const issuesPath =
|
|
3913
|
-
if (!
|
|
3966
|
+
const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3967
|
+
if (!existsSync18(issuesPath)) {
|
|
3914
3968
|
return null;
|
|
3915
3969
|
}
|
|
3916
|
-
for (const line of
|
|
3970
|
+
for (const line of readFileSync9(issuesPath, "utf8").split(/\r?\n/)) {
|
|
3917
3971
|
const trimmed = line.trim();
|
|
3918
3972
|
if (!trimmed) {
|
|
3919
3973
|
continue;
|
|
@@ -3938,25 +3992,25 @@ function inferTaskIdFromRuntimePath(path) {
|
|
|
3938
3992
|
function artifactDirForId(projectRoot, id) {
|
|
3939
3993
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3940
3994
|
if (workspaceDir) {
|
|
3941
|
-
const worktreeArtifacts =
|
|
3942
|
-
if (
|
|
3995
|
+
const worktreeArtifacts = resolve18(workspaceDir, "artifacts", id);
|
|
3996
|
+
if (existsSync18(worktreeArtifacts) || existsSync18(resolve18(workspaceDir, "artifacts"))) {
|
|
3943
3997
|
return worktreeArtifacts;
|
|
3944
3998
|
}
|
|
3945
3999
|
}
|
|
3946
4000
|
try {
|
|
3947
4001
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3948
|
-
return
|
|
4002
|
+
return resolve18(paths.artifactsDir, id);
|
|
3949
4003
|
} catch {
|
|
3950
|
-
return
|
|
4004
|
+
return resolve18(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
3951
4005
|
}
|
|
3952
4006
|
}
|
|
3953
4007
|
function resolveTaskConfigPath(projectRoot) {
|
|
3954
4008
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3955
|
-
if (
|
|
4009
|
+
if (existsSync18(paths.taskConfigPath)) {
|
|
3956
4010
|
return paths.taskConfigPath;
|
|
3957
4011
|
}
|
|
3958
4012
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3959
|
-
if (
|
|
4013
|
+
if (existsSync18(candidate)) {
|
|
3960
4014
|
return candidate;
|
|
3961
4015
|
}
|
|
3962
4016
|
}
|
|
@@ -3964,7 +4018,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
3964
4018
|
}
|
|
3965
4019
|
function findSourceTaskConfigPath(projectRoot) {
|
|
3966
4020
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3967
|
-
if (
|
|
4021
|
+
if (existsSync18(candidate)) {
|
|
3968
4022
|
return candidate;
|
|
3969
4023
|
}
|
|
3970
4024
|
}
|
|
@@ -3977,7 +4031,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
3977
4031
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
3978
4032
|
if (sourcePath && synced.updated) {
|
|
3979
4033
|
try {
|
|
3980
|
-
|
|
4034
|
+
writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
3981
4035
|
`, "utf-8");
|
|
3982
4036
|
} catch {}
|
|
3983
4037
|
}
|
|
@@ -4029,12 +4083,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
4029
4083
|
return !candidate.role;
|
|
4030
4084
|
}
|
|
4031
4085
|
function readSourceIssueRecords(projectRoot) {
|
|
4032
|
-
const issuesPath =
|
|
4033
|
-
if (!
|
|
4086
|
+
const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
4087
|
+
if (!existsSync18(issuesPath)) {
|
|
4034
4088
|
return [];
|
|
4035
4089
|
}
|
|
4036
4090
|
const records = [];
|
|
4037
|
-
for (const line of
|
|
4091
|
+
for (const line of readFileSync9(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
4038
4092
|
const trimmed = line.trim();
|
|
4039
4093
|
if (!trimmed) {
|
|
4040
4094
|
continue;
|
|
@@ -4090,19 +4144,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
4090
4144
|
if (!sourcePath) {
|
|
4091
4145
|
return {};
|
|
4092
4146
|
}
|
|
4093
|
-
const directory =
|
|
4094
|
-
if (!
|
|
4147
|
+
const directory = resolve18(projectRoot, sourcePath);
|
|
4148
|
+
if (!existsSync18(directory)) {
|
|
4095
4149
|
return {};
|
|
4096
4150
|
}
|
|
4097
4151
|
const config = {};
|
|
4098
|
-
for (const name of
|
|
4152
|
+
for (const name of readdirSync3(directory)) {
|
|
4099
4153
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
4100
4154
|
continue;
|
|
4101
|
-
const file =
|
|
4155
|
+
const file = resolve18(directory, name);
|
|
4102
4156
|
try {
|
|
4103
4157
|
if (!statSync4(file).isFile())
|
|
4104
4158
|
continue;
|
|
4105
|
-
const raw = JSON.parse(
|
|
4159
|
+
const raw = JSON.parse(readFileSync9(file, "utf8"));
|
|
4106
4160
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
4107
4161
|
continue;
|
|
4108
4162
|
const record = raw;
|
|
@@ -4144,10 +4198,10 @@ function firstStringList2(...candidates) {
|
|
|
4144
4198
|
return [];
|
|
4145
4199
|
}
|
|
4146
4200
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
4147
|
-
const jsonPath =
|
|
4148
|
-
if (
|
|
4201
|
+
const jsonPath = resolve18(projectRoot, "rig.config.json");
|
|
4202
|
+
if (existsSync18(jsonPath)) {
|
|
4149
4203
|
try {
|
|
4150
|
-
const parsed = JSON.parse(
|
|
4204
|
+
const parsed = JSON.parse(readFileSync9(jsonPath, "utf8"));
|
|
4151
4205
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4152
4206
|
const taskSource = parsed.taskSource;
|
|
4153
4207
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -4159,12 +4213,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
4159
4213
|
return null;
|
|
4160
4214
|
}
|
|
4161
4215
|
}
|
|
4162
|
-
const tsPath =
|
|
4163
|
-
if (!
|
|
4216
|
+
const tsPath = resolve18(projectRoot, "rig.config.ts");
|
|
4217
|
+
if (!existsSync18(tsPath)) {
|
|
4164
4218
|
return null;
|
|
4165
4219
|
}
|
|
4166
4220
|
try {
|
|
4167
|
-
const source =
|
|
4221
|
+
const source = readFileSync9(tsPath, "utf8");
|
|
4168
4222
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
4169
4223
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
4170
4224
|
if (kind !== "files") {
|
|
@@ -4178,9 +4232,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
4178
4232
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
4179
4233
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
4180
4234
|
return [
|
|
4181
|
-
runtimeContext?.monorepoMainRoot ?
|
|
4182
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
4183
|
-
|
|
4235
|
+
runtimeContext?.monorepoMainRoot ? resolve18(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
4236
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve18(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
4237
|
+
resolve18(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
4184
4238
|
].filter(Boolean);
|
|
4185
4239
|
}
|
|
4186
4240
|
|
|
@@ -4189,8 +4243,8 @@ init_layout();
|
|
|
4189
4243
|
|
|
4190
4244
|
// packages/runtime/src/binary-run.ts
|
|
4191
4245
|
init_layout();
|
|
4192
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
4193
|
-
import { basename as basename7, dirname as dirname10, resolve as
|
|
4246
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync19, mkdirSync as mkdirSync9, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
4247
|
+
import { basename as basename7, dirname as dirname10, resolve as resolve19 } from "path";
|
|
4194
4248
|
import { fileURLToPath } from "url";
|
|
4195
4249
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
4196
4250
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -4216,9 +4270,9 @@ async function buildRuntimeBinary(options) {
|
|
|
4216
4270
|
});
|
|
4217
4271
|
}
|
|
4218
4272
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
4219
|
-
const tempBuildDir =
|
|
4220
|
-
const tempOutputPath =
|
|
4221
|
-
|
|
4273
|
+
const tempBuildDir = resolve19(dirname10(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4274
|
+
const tempOutputPath = resolve19(tempBuildDir, basename7(options.outputPath));
|
|
4275
|
+
mkdirSync9(tempBuildDir, { recursive: true });
|
|
4222
4276
|
await withTemporaryEnv({
|
|
4223
4277
|
...options.env,
|
|
4224
4278
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -4243,7 +4297,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4243
4297
|
`);
|
|
4244
4298
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
4245
4299
|
}
|
|
4246
|
-
if (!
|
|
4300
|
+
if (!existsSync19(tempOutputPath)) {
|
|
4247
4301
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
4248
4302
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
4249
4303
|
}
|
|
@@ -4258,7 +4312,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4258
4312
|
});
|
|
4259
4313
|
}
|
|
4260
4314
|
})).finally(() => {
|
|
4261
|
-
|
|
4315
|
+
rmSync8(tempBuildDir, { recursive: true, force: true });
|
|
4262
4316
|
});
|
|
4263
4317
|
}
|
|
4264
4318
|
function runBestEffortBuildGc() {
|
|
@@ -4275,8 +4329,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4275
4329
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4276
4330
|
return {
|
|
4277
4331
|
...options,
|
|
4278
|
-
entrypoint:
|
|
4279
|
-
outputPath:
|
|
4332
|
+
entrypoint: resolve19(options.cwd, options.sourcePath),
|
|
4333
|
+
outputPath: resolve19(options.outputPath)
|
|
4280
4334
|
};
|
|
4281
4335
|
}
|
|
4282
4336
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4290,7 +4344,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4290
4344
|
}
|
|
4291
4345
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4292
4346
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4293
|
-
if (!workerSourcePath || !
|
|
4347
|
+
if (!workerSourcePath || !existsSync19(workerSourcePath)) {
|
|
4294
4348
|
await buildRuntimeBinaryInProcess(options, {
|
|
4295
4349
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4296
4350
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4321,13 +4375,13 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4321
4375
|
new Response(build.stdout).text(),
|
|
4322
4376
|
new Response(build.stderr).text()
|
|
4323
4377
|
]);
|
|
4324
|
-
|
|
4378
|
+
rmSync8(payloadPath, { force: true });
|
|
4325
4379
|
if (exitCode !== 0) {
|
|
4326
4380
|
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
4327
4381
|
}
|
|
4328
4382
|
}
|
|
4329
4383
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4330
|
-
return
|
|
4384
|
+
return resolve19(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4331
4385
|
}
|
|
4332
4386
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4333
4387
|
const envRoots = [
|
|
@@ -4336,13 +4390,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4336
4390
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4337
4391
|
].filter(Boolean);
|
|
4338
4392
|
for (const root of envRoots) {
|
|
4339
|
-
const candidate =
|
|
4340
|
-
if (
|
|
4393
|
+
const candidate = resolve19(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4394
|
+
if (existsSync19(candidate)) {
|
|
4341
4395
|
return candidate;
|
|
4342
4396
|
}
|
|
4343
4397
|
}
|
|
4344
|
-
const localCandidate =
|
|
4345
|
-
return
|
|
4398
|
+
const localCandidate = resolve19(import.meta.dir, "binary-build-worker.ts");
|
|
4399
|
+
return existsSync19(localCandidate) ? localCandidate : null;
|
|
4346
4400
|
}
|
|
4347
4401
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4348
4402
|
const bunPath = Bun.which("bun");
|
|
@@ -4378,7 +4432,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4378
4432
|
});
|
|
4379
4433
|
}
|
|
4380
4434
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4381
|
-
if (!
|
|
4435
|
+
if (!existsSync19(input.outputPath) || !existsSync19(input.manifestPath)) {
|
|
4382
4436
|
return false;
|
|
4383
4437
|
}
|
|
4384
4438
|
let manifest = null;
|
|
@@ -4391,7 +4445,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4391
4445
|
return false;
|
|
4392
4446
|
}
|
|
4393
4447
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4394
|
-
if (!
|
|
4448
|
+
if (!existsSync19(filePath)) {
|
|
4395
4449
|
return false;
|
|
4396
4450
|
}
|
|
4397
4451
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4404,7 +4458,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4404
4458
|
const inputs = {};
|
|
4405
4459
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4406
4460
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4407
|
-
if (!normalized || !
|
|
4461
|
+
if (!normalized || !existsSync19(normalized)) {
|
|
4408
4462
|
continue;
|
|
4409
4463
|
}
|
|
4410
4464
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4427,7 +4481,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4427
4481
|
if (inputPath.startsWith("<")) {
|
|
4428
4482
|
return null;
|
|
4429
4483
|
}
|
|
4430
|
-
return
|
|
4484
|
+
return resolve19(cwd, inputPath);
|
|
4431
4485
|
}
|
|
4432
4486
|
async function sha256File4(path) {
|
|
4433
4487
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4443,8 +4497,8 @@ function sortRecord(value) {
|
|
|
4443
4497
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4444
4498
|
const previous = runtimeBinaryBuildQueue;
|
|
4445
4499
|
let release;
|
|
4446
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4447
|
-
release =
|
|
4500
|
+
runtimeBinaryBuildQueue = new Promise((resolve20) => {
|
|
4501
|
+
release = resolve20;
|
|
4448
4502
|
});
|
|
4449
4503
|
await previous;
|
|
4450
4504
|
try {
|
|
@@ -4489,11 +4543,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4489
4543
|
}
|
|
4490
4544
|
|
|
4491
4545
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4492
|
-
import { delimiter, resolve as
|
|
4546
|
+
import { delimiter, resolve as resolve22 } from "path";
|
|
4493
4547
|
|
|
4494
4548
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
4495
|
-
import { existsSync as
|
|
4496
|
-
import { resolve as
|
|
4549
|
+
import { existsSync as existsSync21, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
4550
|
+
import { resolve as resolve21 } from "path";
|
|
4497
4551
|
|
|
4498
4552
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
4499
4553
|
init_utils();
|
|
@@ -4510,7 +4564,7 @@ function resolveBunBinaryPath() {
|
|
|
4510
4564
|
}
|
|
4511
4565
|
const home = process.env.HOME?.trim();
|
|
4512
4566
|
const fallbackCandidates = [
|
|
4513
|
-
home ?
|
|
4567
|
+
home ? resolve21(home, ".bun/bin/bun") : "",
|
|
4514
4568
|
"/opt/homebrew/bin/bun",
|
|
4515
4569
|
"/usr/local/bin/bun",
|
|
4516
4570
|
"/usr/bin/bun"
|
|
@@ -4538,8 +4592,8 @@ function resolveClaudeBinaryPath() {
|
|
|
4538
4592
|
}
|
|
4539
4593
|
const home = process.env.HOME?.trim();
|
|
4540
4594
|
const fallbackCandidates = [
|
|
4541
|
-
home ?
|
|
4542
|
-
home ?
|
|
4595
|
+
home ? resolve21(home, ".local/bin/claude") : "",
|
|
4596
|
+
home ? resolve21(home, ".local/share/claude/local/claude") : "",
|
|
4543
4597
|
"/opt/homebrew/bin/claude",
|
|
4544
4598
|
"/usr/local/bin/claude",
|
|
4545
4599
|
"/usr/bin/claude"
|
|
@@ -4553,35 +4607,35 @@ function resolveClaudeBinaryPath() {
|
|
|
4553
4607
|
throw new Error("claude not found in PATH");
|
|
4554
4608
|
}
|
|
4555
4609
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
4556
|
-
return
|
|
4610
|
+
return resolve21(bunBinaryPath, "../..");
|
|
4557
4611
|
}
|
|
4558
4612
|
function resolveClaudeInstallDir() {
|
|
4559
4613
|
const realPath = resolveClaudeBinaryPath();
|
|
4560
|
-
return
|
|
4614
|
+
return resolve21(realPath, "..");
|
|
4561
4615
|
}
|
|
4562
4616
|
function resolveNodeInstallDir() {
|
|
4563
4617
|
const preferredNode = resolvePreferredNodeBinary();
|
|
4564
4618
|
if (!preferredNode)
|
|
4565
4619
|
return null;
|
|
4566
4620
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
4567
|
-
if (explicitNode &&
|
|
4568
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
4621
|
+
if (explicitNode && resolve21(explicitNode) === resolve21(preferredNode)) {
|
|
4622
|
+
return preferredNode.endsWith("/bin/node") ? resolve21(preferredNode, "../..") : resolve21(preferredNode, "..");
|
|
4569
4623
|
}
|
|
4570
4624
|
try {
|
|
4571
4625
|
const realPath = realpathSync2(preferredNode);
|
|
4572
4626
|
if (realPath.endsWith("/bin/node")) {
|
|
4573
|
-
return
|
|
4627
|
+
return resolve21(realPath, "../..");
|
|
4574
4628
|
}
|
|
4575
|
-
return
|
|
4629
|
+
return resolve21(realPath, "..");
|
|
4576
4630
|
} catch {
|
|
4577
|
-
return
|
|
4631
|
+
return resolve21(preferredNode, "..");
|
|
4578
4632
|
}
|
|
4579
4633
|
}
|
|
4580
4634
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
4581
4635
|
const roots = [];
|
|
4582
4636
|
if (process.platform === "darwin") {
|
|
4583
4637
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
4584
|
-
if (
|
|
4638
|
+
if (existsSync21(macPath)) {
|
|
4585
4639
|
roots.push(macPath);
|
|
4586
4640
|
}
|
|
4587
4641
|
}
|
|
@@ -4599,23 +4653,23 @@ function resolvePreferredNodeBinary() {
|
|
|
4599
4653
|
const candidates = [];
|
|
4600
4654
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
4601
4655
|
if (envNode) {
|
|
4602
|
-
const explicit =
|
|
4603
|
-
if (
|
|
4656
|
+
const explicit = resolve21(envNode);
|
|
4657
|
+
if (existsSync21(explicit)) {
|
|
4604
4658
|
return explicit;
|
|
4605
4659
|
}
|
|
4606
4660
|
}
|
|
4607
4661
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
4608
4662
|
if (nvmBin) {
|
|
4609
|
-
candidates.push(
|
|
4663
|
+
candidates.push(resolve21(nvmBin, "node"));
|
|
4610
4664
|
}
|
|
4611
4665
|
const home = process.env.HOME?.trim();
|
|
4612
4666
|
if (home) {
|
|
4613
|
-
const nvmVersionsDir =
|
|
4614
|
-
if (
|
|
4667
|
+
const nvmVersionsDir = resolve21(home, ".nvm/versions/node");
|
|
4668
|
+
if (existsSync21(nvmVersionsDir)) {
|
|
4615
4669
|
try {
|
|
4616
|
-
const versionDirs =
|
|
4670
|
+
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/, "")));
|
|
4617
4671
|
for (const versionDir of versionDirs) {
|
|
4618
|
-
candidates.push(
|
|
4672
|
+
candidates.push(resolve21(nvmVersionsDir, versionDir, "bin/node"));
|
|
4619
4673
|
}
|
|
4620
4674
|
} catch {}
|
|
4621
4675
|
}
|
|
@@ -4624,8 +4678,8 @@ function resolvePreferredNodeBinary() {
|
|
|
4624
4678
|
if (whichNode) {
|
|
4625
4679
|
candidates.push(whichNode);
|
|
4626
4680
|
}
|
|
4627
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
4628
|
-
const existing = deduped.filter((candidate) =>
|
|
4681
|
+
const deduped = uniq(candidates.map((candidate) => resolve21(candidate)));
|
|
4682
|
+
const existing = deduped.filter((candidate) => existsSync21(candidate));
|
|
4629
4683
|
if (existing.length === 0) {
|
|
4630
4684
|
return null;
|
|
4631
4685
|
}
|
|
@@ -4639,7 +4693,7 @@ function resolvePreferredNodeBinary() {
|
|
|
4639
4693
|
return existing[0] ?? null;
|
|
4640
4694
|
}
|
|
4641
4695
|
function inferNodeMajor(nodeBinaryPath) {
|
|
4642
|
-
const normalized =
|
|
4696
|
+
const normalized = resolve21(nodeBinaryPath).replace(/\\/g, "/");
|
|
4643
4697
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
4644
4698
|
if (!match) {
|
|
4645
4699
|
return null;
|
|
@@ -4651,8 +4705,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
4651
4705
|
if (!candidate) {
|
|
4652
4706
|
return "";
|
|
4653
4707
|
}
|
|
4654
|
-
const normalized =
|
|
4655
|
-
if (!
|
|
4708
|
+
const normalized = resolve21(candidate);
|
|
4709
|
+
if (!existsSync21(normalized)) {
|
|
4656
4710
|
return "";
|
|
4657
4711
|
}
|
|
4658
4712
|
try {
|
|
@@ -4662,7 +4716,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
4662
4716
|
}
|
|
4663
4717
|
}
|
|
4664
4718
|
function looksLikeRuntimeGateway(candidate) {
|
|
4665
|
-
const normalized =
|
|
4719
|
+
const normalized = resolve21(candidate).replace(/\\/g, "/");
|
|
4666
4720
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
4667
4721
|
}
|
|
4668
4722
|
|
|
@@ -4683,7 +4737,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4683
4737
|
try {
|
|
4684
4738
|
return resolveClaudeInstallDir();
|
|
4685
4739
|
} catch {
|
|
4686
|
-
return
|
|
4740
|
+
return resolve22(claudeBinary, "..");
|
|
4687
4741
|
}
|
|
4688
4742
|
})() : "";
|
|
4689
4743
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -4693,8 +4747,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4693
4747
|
`${bunDir}/bin`,
|
|
4694
4748
|
claudeDir,
|
|
4695
4749
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
4696
|
-
realHome ?
|
|
4697
|
-
realHome ?
|
|
4750
|
+
realHome ? resolve22(realHome, ".local/bin") : "",
|
|
4751
|
+
realHome ? resolve22(realHome, ".cargo/bin") : "",
|
|
4698
4752
|
...inheritedPath,
|
|
4699
4753
|
"/usr/local/bin",
|
|
4700
4754
|
"/usr/local/sbin",
|
|
@@ -4723,8 +4777,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
4723
4777
|
}
|
|
4724
4778
|
|
|
4725
4779
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
4726
|
-
import { existsSync as
|
|
4727
|
-
import { resolve as
|
|
4780
|
+
import { existsSync as existsSync22, readFileSync as readFileSync10 } from "fs";
|
|
4781
|
+
import { resolve as resolve23 } from "path";
|
|
4728
4782
|
var BAKED_RUNTIME_SECRETS = {
|
|
4729
4783
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
4730
4784
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -4767,12 +4821,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
4767
4821
|
return resolved;
|
|
4768
4822
|
}
|
|
4769
4823
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
4770
|
-
const dotenvPath =
|
|
4771
|
-
if (!
|
|
4824
|
+
const dotenvPath = resolve23(projectRoot, ".env");
|
|
4825
|
+
if (!existsSync22(dotenvPath)) {
|
|
4772
4826
|
return {};
|
|
4773
4827
|
}
|
|
4774
4828
|
const parsed = {};
|
|
4775
|
-
const lines =
|
|
4829
|
+
const lines = readFileSync10(dotenvPath, "utf-8").split(/\r?\n/);
|
|
4776
4830
|
for (const rawLine of lines) {
|
|
4777
4831
|
const line = rawLine.trim();
|
|
4778
4832
|
if (!line || line.startsWith("#")) {
|
|
@@ -5129,16 +5183,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
5129
5183
|
for (const dep of deps) {
|
|
5130
5184
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
5131
5185
|
console.log(`=== ${dep} ===`);
|
|
5132
|
-
if (!
|
|
5186
|
+
if (!existsSync23(artifactDir)) {
|
|
5133
5187
|
console.log(` (no artifacts yet)
|
|
5134
5188
|
`);
|
|
5135
5189
|
continue;
|
|
5136
5190
|
}
|
|
5137
|
-
printArtifactSection(
|
|
5138
|
-
printArtifactSection(
|
|
5139
|
-
const changedFiles =
|
|
5140
|
-
if (
|
|
5141
|
-
const lines =
|
|
5191
|
+
printArtifactSection(resolve24(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
5192
|
+
printArtifactSection(resolve24(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
5193
|
+
const changedFiles = resolve24(artifactDir, "changed-files.txt");
|
|
5194
|
+
if (existsSync23(changedFiles)) {
|
|
5195
|
+
const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
5142
5196
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
5143
5197
|
for (const line of lines) {
|
|
5144
5198
|
console.log(line);
|
|
@@ -5262,12 +5316,12 @@ function printIndented(text) {
|
|
|
5262
5316
|
}
|
|
5263
5317
|
}
|
|
5264
5318
|
function readLocalBeadsTasks(projectRoot) {
|
|
5265
|
-
const issuesPath =
|
|
5266
|
-
if (!
|
|
5319
|
+
const issuesPath = resolve24(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5320
|
+
if (!existsSync23(issuesPath)) {
|
|
5267
5321
|
return [];
|
|
5268
5322
|
}
|
|
5269
5323
|
const tasks = [];
|
|
5270
|
-
for (const line of
|
|
5324
|
+
for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
5271
5325
|
const trimmed = line.trim();
|
|
5272
5326
|
if (!trimmed) {
|
|
5273
5327
|
continue;
|
|
@@ -5380,11 +5434,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5380
5434
|
return [...ids].sort();
|
|
5381
5435
|
}
|
|
5382
5436
|
function printArtifactSection(path, header) {
|
|
5383
|
-
if (!
|
|
5437
|
+
if (!existsSync23(path)) {
|
|
5384
5438
|
return;
|
|
5385
5439
|
}
|
|
5386
5440
|
console.log(header);
|
|
5387
|
-
process.stdout.write(
|
|
5441
|
+
process.stdout.write(readFileSync11(path, "utf-8"));
|
|
5388
5442
|
console.log("");
|
|
5389
5443
|
}
|
|
5390
5444
|
|
|
@@ -5486,7 +5540,7 @@ init_layout();
|
|
|
5486
5540
|
|
|
5487
5541
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5488
5542
|
init_layout();
|
|
5489
|
-
import { mkdirSync as
|
|
5543
|
+
import { mkdirSync as mkdirSync11 } from "fs";
|
|
5490
5544
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5491
5545
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5492
5546
|
const rootDir = layout.rigRoot;
|
|
@@ -5498,14 +5552,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5498
5552
|
const sessionDir = layout.sessionDir;
|
|
5499
5553
|
const runtimeDir = layout.runtimeDir;
|
|
5500
5554
|
const contextPath = layout.contextPath;
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5555
|
+
mkdirSync11(rootDir, { recursive: true });
|
|
5556
|
+
mkdirSync11(homeDir, { recursive: true });
|
|
5557
|
+
mkdirSync11(tmpDir, { recursive: true });
|
|
5558
|
+
mkdirSync11(cacheDir, { recursive: true });
|
|
5559
|
+
mkdirSync11(logsDir, { recursive: true });
|
|
5560
|
+
mkdirSync11(stateDir, { recursive: true });
|
|
5561
|
+
mkdirSync11(sessionDir, { recursive: true });
|
|
5562
|
+
mkdirSync11(runtimeDir, { recursive: true });
|
|
5509
5563
|
return {
|
|
5510
5564
|
rootDir,
|
|
5511
5565
|
homeDir,
|
|
@@ -5523,17 +5577,17 @@ import {
|
|
|
5523
5577
|
chmodSync as chmodSync5,
|
|
5524
5578
|
copyFileSync as copyFileSync5,
|
|
5525
5579
|
cpSync as cpSync2,
|
|
5526
|
-
existsSync as
|
|
5527
|
-
mkdirSync as
|
|
5580
|
+
existsSync as existsSync25,
|
|
5581
|
+
mkdirSync as mkdirSync12,
|
|
5528
5582
|
statSync as statSync5,
|
|
5529
|
-
writeFileSync as
|
|
5583
|
+
writeFileSync as writeFileSync10
|
|
5530
5584
|
} from "fs";
|
|
5531
5585
|
import { mkdir } from "fs/promises";
|
|
5532
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
5586
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve26 } from "path";
|
|
5533
5587
|
|
|
5534
5588
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
5535
|
-
import { existsSync as
|
|
5536
|
-
import { resolve as
|
|
5589
|
+
import { existsSync as existsSync24, readFileSync as readFileSync12, rmSync as rmSync9 } from "fs";
|
|
5590
|
+
import { resolve as resolve25 } from "path";
|
|
5537
5591
|
var generatedCredentialFiles = new Set;
|
|
5538
5592
|
var credentialCleanupRegistered = false;
|
|
5539
5593
|
function resolveMonorepoRoot3(projectRoot) {
|
|
@@ -5557,7 +5611,7 @@ function resolveHostGitBinary() {
|
|
|
5557
5611
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
5558
5612
|
continue;
|
|
5559
5613
|
}
|
|
5560
|
-
if (
|
|
5614
|
+
if (existsSync24(candidate)) {
|
|
5561
5615
|
return candidate;
|
|
5562
5616
|
}
|
|
5563
5617
|
}
|
|
@@ -5623,7 +5677,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
5623
5677
|
}
|
|
5624
5678
|
}
|
|
5625
5679
|
async function tryReadGitHead(repoRoot) {
|
|
5626
|
-
if (!
|
|
5680
|
+
if (!existsSync24(resolve25(repoRoot, ".git"))) {
|
|
5627
5681
|
return;
|
|
5628
5682
|
}
|
|
5629
5683
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -5634,7 +5688,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
5634
5688
|
return value || undefined;
|
|
5635
5689
|
}
|
|
5636
5690
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
5637
|
-
if (!
|
|
5691
|
+
if (!existsSync24(resolve25(repoRoot, ".git"))) {
|
|
5638
5692
|
return [];
|
|
5639
5693
|
}
|
|
5640
5694
|
const files = new Set;
|
|
@@ -5670,7 +5724,7 @@ function registerCredentialCleanup(path) {
|
|
|
5670
5724
|
const cleanup = () => {
|
|
5671
5725
|
for (const filePath of generatedCredentialFiles) {
|
|
5672
5726
|
try {
|
|
5673
|
-
|
|
5727
|
+
rmSync9(filePath, { force: true });
|
|
5674
5728
|
} catch {}
|
|
5675
5729
|
}
|
|
5676
5730
|
generatedCredentialFiles.clear();
|
|
@@ -5722,16 +5776,16 @@ function hashProjectPath(workspaceDir) {
|
|
|
5722
5776
|
}
|
|
5723
5777
|
function resolveGithubCliBinaryPath() {
|
|
5724
5778
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
5725
|
-
if (explicit &&
|
|
5779
|
+
if (explicit && existsSync24(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
5726
5780
|
return explicit;
|
|
5727
5781
|
}
|
|
5728
5782
|
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
5729
|
-
if (
|
|
5783
|
+
if (existsSync24(candidate)) {
|
|
5730
5784
|
return candidate;
|
|
5731
5785
|
}
|
|
5732
5786
|
}
|
|
5733
5787
|
const bunResolved = Bun.which("gh");
|
|
5734
|
-
if (bunResolved &&
|
|
5788
|
+
if (bunResolved && existsSync24(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
5735
5789
|
return bunResolved;
|
|
5736
5790
|
}
|
|
5737
5791
|
return "";
|
|
@@ -5765,17 +5819,17 @@ function resolveSystemCertBundlePath() {
|
|
|
5765
5819
|
"/opt/homebrew/etc/openssl@3/cert.pem"
|
|
5766
5820
|
];
|
|
5767
5821
|
for (const candidate of candidates) {
|
|
5768
|
-
if (candidate &&
|
|
5769
|
-
return
|
|
5822
|
+
if (candidate && existsSync24(candidate)) {
|
|
5823
|
+
return resolve25(candidate);
|
|
5770
5824
|
}
|
|
5771
5825
|
}
|
|
5772
5826
|
return "";
|
|
5773
5827
|
}
|
|
5774
5828
|
function readKnownHosts(path) {
|
|
5775
|
-
if (!
|
|
5829
|
+
if (!existsSync24(path)) {
|
|
5776
5830
|
return new Set;
|
|
5777
5831
|
}
|
|
5778
|
-
return new Set(
|
|
5832
|
+
return new Set(readFileSync12(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
5779
5833
|
}
|
|
5780
5834
|
|
|
5781
5835
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -5790,12 +5844,12 @@ function resolveControlPlaneSourceRoot(projectRoot) {
|
|
|
5790
5844
|
const candidates = [
|
|
5791
5845
|
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
5792
5846
|
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
5793
|
-
|
|
5847
|
+
resolve26(import.meta.dir, "../../../../.."),
|
|
5794
5848
|
projectRoot
|
|
5795
5849
|
].filter((value) => Boolean(value));
|
|
5796
5850
|
for (const candidate of candidates) {
|
|
5797
|
-
const root =
|
|
5798
|
-
if (
|
|
5851
|
+
const root = resolve26(candidate);
|
|
5852
|
+
if (existsSync25(resolve26(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
5799
5853
|
return root;
|
|
5800
5854
|
}
|
|
5801
5855
|
}
|
|
@@ -5815,7 +5869,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5815
5869
|
try {
|
|
5816
5870
|
return resolveClaudeInstallDir();
|
|
5817
5871
|
} catch {
|
|
5818
|
-
return
|
|
5872
|
+
return resolve26(claudeBinaryPath, "..");
|
|
5819
5873
|
}
|
|
5820
5874
|
})() : "";
|
|
5821
5875
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -5830,8 +5884,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5830
5884
|
`${bunDir}/bin`,
|
|
5831
5885
|
claudeDir,
|
|
5832
5886
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
5833
|
-
realHome ?
|
|
5834
|
-
realHome ?
|
|
5887
|
+
realHome ? resolve26(realHome, ".local/bin") : "",
|
|
5888
|
+
realHome ? resolve26(realHome, ".cargo/bin") : "",
|
|
5835
5889
|
...inheritedPath,
|
|
5836
5890
|
"/usr/local/bin",
|
|
5837
5891
|
"/usr/local/sbin",
|
|
@@ -5842,9 +5896,9 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5842
5896
|
"/usr/sbin",
|
|
5843
5897
|
"/sbin"
|
|
5844
5898
|
].filter(Boolean);
|
|
5845
|
-
const runtimeBash =
|
|
5846
|
-
const runtimeRigGit =
|
|
5847
|
-
const preferredShell =
|
|
5899
|
+
const runtimeBash = resolve26(runtime.binDir, "bash");
|
|
5900
|
+
const runtimeRigGit = resolve26(runtime.binDir, runtimeRigGitFileName());
|
|
5901
|
+
const preferredShell = existsSync25(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
5848
5902
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
5849
5903
|
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
5850
5904
|
const env = {
|
|
@@ -5865,30 +5919,30 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5865
5919
|
RIG_RUNTIME_MODE: runtime.mode,
|
|
5866
5920
|
RIG_RUNTIME_HOME: runtime.rootDir,
|
|
5867
5921
|
RIG_RUNTIME_BIN_DIR: runtime.binDir,
|
|
5868
|
-
...
|
|
5922
|
+
...existsSync25(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
|
|
5869
5923
|
RIG_BUN_PATH: bunBinaryPath,
|
|
5870
5924
|
...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
|
|
5871
|
-
RIG_AGENT_BIN:
|
|
5925
|
+
RIG_AGENT_BIN: resolve26(runtime.binDir, "rig-agent"),
|
|
5872
5926
|
RIG_HOOKS_ACTIVE: "1",
|
|
5873
5927
|
RIG_AUTO_PR_ON_COMPLETE: "1",
|
|
5874
|
-
RIG_POLICY_FILE:
|
|
5928
|
+
RIG_POLICY_FILE: resolve26(projectRoot, "rig/policy/policy.json"),
|
|
5875
5929
|
RIG_STATE_DIR: runtime.stateDir,
|
|
5876
5930
|
RIG_LOGS_DIR: runtime.logsDir,
|
|
5877
|
-
RIG_SESSION_FILE:
|
|
5931
|
+
RIG_SESSION_FILE: resolve26(runtime.sessionDir, "session.json"),
|
|
5878
5932
|
MONOREPO_ROOT: runtime.workspaceDir,
|
|
5879
5933
|
MONOREPO_MAIN_ROOT: monorepoMainRoot,
|
|
5880
|
-
TS_API_TESTS_DIR:
|
|
5934
|
+
TS_API_TESTS_DIR: resolve26(runtime.workspaceDir, "TSAPITests"),
|
|
5881
5935
|
BASH: preferredShell,
|
|
5882
5936
|
SHELL: preferredShell,
|
|
5883
5937
|
PATH: [...new Set(pathEntries)].join(delimiter2),
|
|
5884
5938
|
LANG: process.env.LANG ?? "en_US.UTF-8",
|
|
5885
5939
|
TERM: process.env.TERM ?? "xterm-256color",
|
|
5886
5940
|
PYTHONDONTWRITEBYTECODE: "1",
|
|
5887
|
-
PYTHONPYCACHEPREFIX:
|
|
5941
|
+
PYTHONPYCACHEPREFIX: resolve26(runtime.cacheDir, "python"),
|
|
5888
5942
|
...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
|
|
5889
5943
|
...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
|
|
5890
5944
|
CLAUDE_HOME: runtime.claudeHomeDir,
|
|
5891
|
-
PI_CODING_AGENT_DIR:
|
|
5945
|
+
PI_CODING_AGENT_DIR: resolve26(runtime.homeDir, ".pi", "agent"),
|
|
5892
5946
|
[RUNTIME_CONTEXT_ENV]: runtime.contextFile,
|
|
5893
5947
|
...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
|
|
5894
5948
|
...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
|
|
@@ -5899,16 +5953,16 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5899
5953
|
NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
|
|
5900
5954
|
} : {}
|
|
5901
5955
|
};
|
|
5902
|
-
const knownHostsPath =
|
|
5903
|
-
if (
|
|
5904
|
-
const agentSshKey =
|
|
5956
|
+
const knownHostsPath = resolve26(runtime.homeDir, ".ssh", "known_hosts");
|
|
5957
|
+
if (existsSync25(knownHostsPath)) {
|
|
5958
|
+
const agentSshKey = resolve26(runtime.homeDir, ".ssh", "rig-agent-key");
|
|
5905
5959
|
const sshParts = [
|
|
5906
5960
|
"ssh",
|
|
5907
5961
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
5908
5962
|
"-o StrictHostKeyChecking=yes",
|
|
5909
5963
|
"-F /dev/null"
|
|
5910
5964
|
];
|
|
5911
|
-
if (
|
|
5965
|
+
if (existsSync25(agentSshKey)) {
|
|
5912
5966
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
5913
5967
|
}
|
|
5914
5968
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -5945,7 +5999,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5945
5999
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
5946
6000
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
5947
6001
|
}
|
|
5948
|
-
if (
|
|
6002
|
+
if (existsSync25(runtime.contextFile)) {
|
|
5949
6003
|
const runtimeContext = loadRuntimeContext(runtime.contextFile);
|
|
5950
6004
|
Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
|
|
5951
6005
|
Object.assign(env, browserEnvFromContext(runtimeContext.browser));
|
|
@@ -5959,30 +6013,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
5959
6013
|
await mkdir(runtime.cacheDir, { recursive: true });
|
|
5960
6014
|
await provisionAgentSshKey(runtime.homeDir);
|
|
5961
6015
|
if (options.provider === "codex") {
|
|
5962
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
6016
|
+
const hasCodexAuth = await injectCodexAuth(resolve26(runtime.homeDir, ".codex"));
|
|
5963
6017
|
if (!hasCodexAuth) {
|
|
5964
6018
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
5965
6019
|
}
|
|
5966
6020
|
}
|
|
5967
6021
|
if (options.provider === "pi") {
|
|
5968
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
6022
|
+
const hasPiAuth = await injectPiAgentConfig(resolve26(runtime.homeDir, ".pi", "agent"));
|
|
5969
6023
|
if (!hasPiAuth) {
|
|
5970
6024
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
5971
6025
|
}
|
|
5972
6026
|
}
|
|
5973
6027
|
}
|
|
5974
6028
|
async function provisionClaudeHome(config) {
|
|
5975
|
-
|
|
5976
|
-
const workspaceSettings =
|
|
5977
|
-
const hostSettings =
|
|
5978
|
-
const projectSettings =
|
|
6029
|
+
mkdirSync12(config.claudeHomeDir, { recursive: true });
|
|
6030
|
+
const workspaceSettings = resolve26(config.workspaceDir, ".claude/settings.json");
|
|
6031
|
+
const hostSettings = resolve26(config.hostProjectRoot, ".claude/settings.json");
|
|
6032
|
+
const projectSettings = existsSync25(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
5979
6033
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
5980
|
-
if (
|
|
5981
|
-
|
|
6034
|
+
if (existsSync25(projectSettings)) {
|
|
6035
|
+
writeFileSync10(resolve26(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5982
6036
|
`, "utf-8");
|
|
5983
6037
|
}
|
|
5984
6038
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
5985
|
-
|
|
6039
|
+
writeFileSync10(resolve26(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
5986
6040
|
permissions: { defaultMode: "bypassPermissions" },
|
|
5987
6041
|
autoMemoryEnabled: false
|
|
5988
6042
|
}, null, 2));
|
|
@@ -5990,12 +6044,12 @@ async function provisionClaudeHome(config) {
|
|
|
5990
6044
|
if (!hasCredentials) {
|
|
5991
6045
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
5992
6046
|
}
|
|
5993
|
-
const realClaudeHome =
|
|
5994
|
-
if (process.env.HOME &&
|
|
5995
|
-
cpSync2(
|
|
6047
|
+
const realClaudeHome = resolve26(process.env.HOME ?? "", ".claude");
|
|
6048
|
+
if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "CLAUDE.md"))) {
|
|
6049
|
+
cpSync2(resolve26(realClaudeHome, "CLAUDE.md"), resolve26(config.claudeHomeDir, "CLAUDE.md"));
|
|
5996
6050
|
}
|
|
5997
|
-
if (process.env.HOME &&
|
|
5998
|
-
cpSync2(
|
|
6051
|
+
if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "agents"))) {
|
|
6052
|
+
cpSync2(resolve26(realClaudeHome, "agents"), resolve26(config.claudeHomeDir, "agents"), { recursive: true });
|
|
5999
6053
|
}
|
|
6000
6054
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
6001
6055
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -6006,10 +6060,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
6006
6060
|
if (!sourcePath) {
|
|
6007
6061
|
return "";
|
|
6008
6062
|
}
|
|
6009
|
-
const certsDir =
|
|
6010
|
-
const targetPath =
|
|
6063
|
+
const certsDir = resolve26(runtime.rootDir, "certs");
|
|
6064
|
+
const targetPath = resolve26(certsDir, "ca-certificates.pem");
|
|
6011
6065
|
await mkdir(certsDir, { recursive: true });
|
|
6012
|
-
let shouldCopy = !
|
|
6066
|
+
let shouldCopy = !existsSync25(targetPath);
|
|
6013
6067
|
if (!shouldCopy) {
|
|
6014
6068
|
try {
|
|
6015
6069
|
shouldCopy = statSync5(sourcePath).mtimeMs > statSync5(targetPath).mtimeMs;
|
|
@@ -6031,7 +6085,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
6031
6085
|
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';
|
|
6032
6086
|
}
|
|
6033
6087
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
6034
|
-
const secretsPath =
|
|
6088
|
+
const secretsPath = resolve26(runtimeRoot, "runtime-secrets.json");
|
|
6035
6089
|
const persisted = {};
|
|
6036
6090
|
for (const key of [
|
|
6037
6091
|
"GITHUB_TOKEN",
|
|
@@ -6050,12 +6104,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
6050
6104
|
if (Object.keys(persisted).length === 0) {
|
|
6051
6105
|
return;
|
|
6052
6106
|
}
|
|
6053
|
-
|
|
6107
|
+
writeFileSync10(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
6054
6108
|
`, "utf-8");
|
|
6055
6109
|
}
|
|
6056
6110
|
async function provisionAgentSshKey(homeDir) {
|
|
6057
|
-
const sshDir =
|
|
6058
|
-
if (!
|
|
6111
|
+
const sshDir = resolve26(homeDir, ".ssh");
|
|
6112
|
+
if (!existsSync25(sshDir)) {
|
|
6059
6113
|
await mkdir(sshDir, { recursive: true });
|
|
6060
6114
|
}
|
|
6061
6115
|
seedKnownHosts(sshDir);
|
|
@@ -6063,27 +6117,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
6063
6117
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
6064
6118
|
if (!privateKey) {
|
|
6065
6119
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
6066
|
-
if (!process.env.HOME || !
|
|
6120
|
+
if (!process.env.HOME || !existsSync25(hostKeyPath)) {
|
|
6067
6121
|
return;
|
|
6068
6122
|
}
|
|
6069
|
-
const agentKeyPath2 =
|
|
6070
|
-
if (!
|
|
6123
|
+
const agentKeyPath2 = resolve26(sshDir, "rig-agent-key");
|
|
6124
|
+
if (!existsSync25(agentKeyPath2)) {
|
|
6071
6125
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
6072
6126
|
chmodSync5(agentKeyPath2, 384);
|
|
6073
6127
|
}
|
|
6074
6128
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
6075
|
-
if (
|
|
6129
|
+
if (existsSync25(hostPubPath)) {
|
|
6076
6130
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
6077
|
-
if (!
|
|
6131
|
+
if (!existsSync25(agentPubPath)) {
|
|
6078
6132
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
6079
6133
|
}
|
|
6080
6134
|
}
|
|
6081
6135
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
6082
6136
|
return;
|
|
6083
6137
|
}
|
|
6084
|
-
const agentKeyPath =
|
|
6085
|
-
if (!
|
|
6086
|
-
|
|
6138
|
+
const agentKeyPath = resolve26(sshDir, "rig-agent-key");
|
|
6139
|
+
if (!existsSync25(agentKeyPath)) {
|
|
6140
|
+
writeFileSync10(agentKeyPath, privateKey, { mode: 384 });
|
|
6087
6141
|
}
|
|
6088
6142
|
writeSshConfig(sshDir, agentKeyPath);
|
|
6089
6143
|
}
|
|
@@ -6100,21 +6154,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
6100
6154
|
`;
|
|
6101
6155
|
}
|
|
6102
6156
|
function resolveHostSshKeyPath(homeDir) {
|
|
6103
|
-
const sshDir =
|
|
6157
|
+
const sshDir = resolve26(homeDir, ".ssh");
|
|
6104
6158
|
const candidates = [
|
|
6105
6159
|
"rig-agent-key",
|
|
6106
6160
|
"id_ed25519",
|
|
6107
6161
|
"id_ecdsa",
|
|
6108
6162
|
"id_rsa"
|
|
6109
|
-
].map((name) =>
|
|
6110
|
-
return candidates.find((candidate) =>
|
|
6163
|
+
].map((name) => resolve26(sshDir, name));
|
|
6164
|
+
return candidates.find((candidate) => existsSync25(candidate)) ?? resolve26(sshDir, "rig-agent-key");
|
|
6111
6165
|
}
|
|
6112
6166
|
function writeSshConfig(sshDir, keyPath) {
|
|
6113
|
-
const configPath =
|
|
6114
|
-
if (
|
|
6167
|
+
const configPath = resolve26(sshDir, "config");
|
|
6168
|
+
if (existsSync25(configPath)) {
|
|
6115
6169
|
return;
|
|
6116
6170
|
}
|
|
6117
|
-
const knownHostsPath =
|
|
6171
|
+
const knownHostsPath = resolve26(sshDir, "known_hosts");
|
|
6118
6172
|
const config = [
|
|
6119
6173
|
"Host github.com",
|
|
6120
6174
|
` IdentityFile ${keyPath}`,
|
|
@@ -6124,10 +6178,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
6124
6178
|
""
|
|
6125
6179
|
].join(`
|
|
6126
6180
|
`);
|
|
6127
|
-
|
|
6181
|
+
writeFileSync10(configPath, config, { mode: 420 });
|
|
6128
6182
|
}
|
|
6129
6183
|
function seedKnownHosts(sshDir) {
|
|
6130
|
-
const knownHostsPath =
|
|
6184
|
+
const knownHostsPath = resolve26(sshDir, "known_hosts");
|
|
6131
6185
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
6132
6186
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
6133
6187
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -6138,23 +6192,23 @@ function seedKnownHosts(sshDir) {
|
|
|
6138
6192
|
for (const line of missing) {
|
|
6139
6193
|
existingLines.add(line);
|
|
6140
6194
|
}
|
|
6141
|
-
|
|
6195
|
+
writeFileSync10(knownHostsPath, `${Array.from(existingLines).join(`
|
|
6142
6196
|
`)}
|
|
6143
6197
|
`, { mode: 420 });
|
|
6144
6198
|
} catch (err) {
|
|
6145
|
-
const hint =
|
|
6199
|
+
const hint = existsSync25(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
6146
6200
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
6147
6201
|
}
|
|
6148
6202
|
}
|
|
6149
6203
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
6150
6204
|
const projectHash = hashProjectPath(workspaceDir);
|
|
6151
|
-
const projectDir =
|
|
6152
|
-
|
|
6153
|
-
|
|
6205
|
+
const projectDir = resolve26(claudeHomeDir, "projects", projectHash);
|
|
6206
|
+
mkdirSync12(projectDir, { recursive: true });
|
|
6207
|
+
writeFileSync10(resolve26(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6154
6208
|
`, "utf-8");
|
|
6155
6209
|
}
|
|
6156
6210
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
6157
|
-
if (!
|
|
6211
|
+
if (!existsSync25(projectSettingsPath)) {
|
|
6158
6212
|
return {};
|
|
6159
6213
|
}
|
|
6160
6214
|
let parsed;
|
|
@@ -6200,7 +6254,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
6200
6254
|
return clone;
|
|
6201
6255
|
}
|
|
6202
6256
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
6203
|
-
const credentialsPath =
|
|
6257
|
+
const credentialsPath = resolve26(claudeHomeDir, ".credentials.json");
|
|
6204
6258
|
const platform = options.platform ?? process.platform;
|
|
6205
6259
|
if (platform === "darwin") {
|
|
6206
6260
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -6210,16 +6264,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6210
6264
|
if (raw) {
|
|
6211
6265
|
try {
|
|
6212
6266
|
JSON.parse(raw);
|
|
6213
|
-
|
|
6267
|
+
writeFileSync10(credentialsPath, raw, { mode: 384 });
|
|
6214
6268
|
registerCredentialCleanup(credentialsPath);
|
|
6215
6269
|
return true;
|
|
6216
6270
|
} catch {}
|
|
6217
6271
|
}
|
|
6218
6272
|
}
|
|
6219
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6273
|
+
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") : "";
|
|
6220
6274
|
if (hostClaudeHome) {
|
|
6221
|
-
const realCredentials =
|
|
6222
|
-
if (
|
|
6275
|
+
const realCredentials = resolve26(hostClaudeHome, ".credentials.json");
|
|
6276
|
+
if (existsSync25(realCredentials)) {
|
|
6223
6277
|
cpSync2(realCredentials, credentialsPath);
|
|
6224
6278
|
return true;
|
|
6225
6279
|
}
|
|
@@ -6227,36 +6281,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6227
6281
|
return false;
|
|
6228
6282
|
}
|
|
6229
6283
|
async function injectCodexAuth(codexHomeDir) {
|
|
6230
|
-
|
|
6231
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6284
|
+
mkdirSync12(codexHomeDir, { recursive: true });
|
|
6285
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve26(process.env.CODEX_HOME) : process.env.HOME ? resolve26(process.env.HOME, ".codex") : "";
|
|
6232
6286
|
if (!hostCodexHome) {
|
|
6233
6287
|
return false;
|
|
6234
6288
|
}
|
|
6235
|
-
const hostAuthPath =
|
|
6236
|
-
if (!
|
|
6289
|
+
const hostAuthPath = resolve26(hostCodexHome, "auth.json");
|
|
6290
|
+
if (!existsSync25(hostAuthPath)) {
|
|
6237
6291
|
return false;
|
|
6238
6292
|
}
|
|
6239
|
-
const runtimeAuthPath =
|
|
6293
|
+
const runtimeAuthPath = resolve26(codexHomeDir, "auth.json");
|
|
6240
6294
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6241
6295
|
chmodSync5(runtimeAuthPath, 384);
|
|
6242
6296
|
return true;
|
|
6243
6297
|
}
|
|
6244
6298
|
async function injectPiAgentConfig(piAgentDir) {
|
|
6245
|
-
|
|
6246
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6299
|
+
mkdirSync12(piAgentDir, { recursive: true });
|
|
6300
|
+
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") : "";
|
|
6247
6301
|
if (!hostPiAgentDir) {
|
|
6248
6302
|
return false;
|
|
6249
6303
|
}
|
|
6250
|
-
const hostAuthPath =
|
|
6251
|
-
if (!
|
|
6304
|
+
const hostAuthPath = resolve26(hostPiAgentDir, "auth.json");
|
|
6305
|
+
if (!existsSync25(hostAuthPath)) {
|
|
6252
6306
|
return false;
|
|
6253
6307
|
}
|
|
6254
|
-
const runtimeAuthPath =
|
|
6308
|
+
const runtimeAuthPath = resolve26(piAgentDir, "auth.json");
|
|
6255
6309
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6256
6310
|
chmodSync5(runtimeAuthPath, 384);
|
|
6257
|
-
const hostSettingsPath =
|
|
6258
|
-
if (
|
|
6259
|
-
const runtimeSettingsPath =
|
|
6311
|
+
const hostSettingsPath = resolve26(hostPiAgentDir, "settings.json");
|
|
6312
|
+
if (existsSync25(hostSettingsPath)) {
|
|
6313
|
+
const runtimeSettingsPath = resolve26(piAgentDir, "settings.json");
|
|
6260
6314
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
6261
6315
|
chmodSync5(runtimeSettingsPath, 384);
|
|
6262
6316
|
}
|
|
@@ -6264,8 +6318,8 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
6264
6318
|
}
|
|
6265
6319
|
|
|
6266
6320
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
6267
|
-
import { existsSync as
|
|
6268
|
-
import { resolve as
|
|
6321
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync13, statSync as statSync6, writeFileSync as writeFileSync11 } from "fs";
|
|
6322
|
+
import { resolve as resolve27 } from "path";
|
|
6269
6323
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6270
6324
|
var CLAUDE_DISABLED_FILE_TOOLS = [
|
|
6271
6325
|
"Read",
|
|
@@ -6363,7 +6417,7 @@ function claudeRuntimeToolCliArgs(configPath) {
|
|
|
6363
6417
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6364
6418
|
return {
|
|
6365
6419
|
type: "stdio",
|
|
6366
|
-
command:
|
|
6420
|
+
command: resolve27(options.binDir, "rig-tool-router"),
|
|
6367
6421
|
args: [],
|
|
6368
6422
|
env: {
|
|
6369
6423
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6397,14 +6451,14 @@ function codexRuntimeToolCliArgs(options) {
|
|
|
6397
6451
|
];
|
|
6398
6452
|
}
|
|
6399
6453
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6400
|
-
const configPath =
|
|
6401
|
-
|
|
6454
|
+
const configPath = resolve27(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6455
|
+
mkdirSync13(options.stateDir, { recursive: true });
|
|
6402
6456
|
const payload = {
|
|
6403
6457
|
mcpServers: {
|
|
6404
6458
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6405
6459
|
}
|
|
6406
6460
|
};
|
|
6407
|
-
|
|
6461
|
+
writeFileSync11(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6408
6462
|
`, "utf-8");
|
|
6409
6463
|
return configPath;
|
|
6410
6464
|
}
|
|
@@ -6491,7 +6545,7 @@ function resolveRuntimeToolBinary(toolName, env) {
|
|
|
6491
6545
|
grep: "rig-grep"
|
|
6492
6546
|
};
|
|
6493
6547
|
const executable = mapping[toolName];
|
|
6494
|
-
return executable ?
|
|
6548
|
+
return executable ? resolve27(binDir, executable) : "";
|
|
6495
6549
|
}
|
|
6496
6550
|
function renderToolText(toolName, payload) {
|
|
6497
6551
|
if (toolName === "shell") {
|
|
@@ -6556,10 +6610,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
|
|
|
6556
6610
|
isError: true
|
|
6557
6611
|
};
|
|
6558
6612
|
}
|
|
6559
|
-
const workspaceRoot =
|
|
6613
|
+
const workspaceRoot = resolve27(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
|
|
6560
6614
|
const requestedWorkdir = typeof args.workdir === "string" ? args.workdir.trim() : "";
|
|
6561
6615
|
const workdir = requestedWorkdir ? resolveWithinWorkspace(workspaceRoot, requestedWorkdir) : workspaceRoot;
|
|
6562
|
-
if (!
|
|
6616
|
+
if (!existsSync26(workdir)) {
|
|
6563
6617
|
return {
|
|
6564
6618
|
content: [{
|
|
6565
6619
|
type: "text",
|
|
@@ -6626,10 +6680,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
|
|
|
6626
6680
|
}
|
|
6627
6681
|
function resolveRuntimeShellBinary(shellName, env) {
|
|
6628
6682
|
const binDir = env.RIG_RUNTIME_BIN_DIR?.trim() || "";
|
|
6629
|
-
return binDir ?
|
|
6683
|
+
return binDir ? resolve27(binDir, shellName) : "";
|
|
6630
6684
|
}
|
|
6631
6685
|
function resolveWithinWorkspace(workspaceRoot, target) {
|
|
6632
|
-
const resolvedTarget =
|
|
6686
|
+
const resolvedTarget = resolve27(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
|
|
6633
6687
|
const normalizedWorkspace = workspaceRoot.endsWith("/") ? workspaceRoot : `${workspaceRoot}/`;
|
|
6634
6688
|
const normalizedTarget = resolvedTarget.endsWith("/") ? resolvedTarget : `${resolvedTarget}/`;
|
|
6635
6689
|
if (resolvedTarget === workspaceRoot || normalizedTarget.startsWith(normalizedWorkspace)) {
|
|
@@ -6667,8 +6721,8 @@ if (false) {}
|
|
|
6667
6721
|
init_layout();
|
|
6668
6722
|
|
|
6669
6723
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6670
|
-
import { existsSync as
|
|
6671
|
-
import { dirname as dirname11, resolve as
|
|
6724
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync14, rmSync as rmSync10 } from "fs";
|
|
6725
|
+
import { dirname as dirname11, resolve as resolve28 } from "path";
|
|
6672
6726
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6673
6727
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6674
6728
|
if (explicit) {
|
|
@@ -6704,12 +6758,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6704
6758
|
}
|
|
6705
6759
|
async function provisionRuntimeWorktree(config) {
|
|
6706
6760
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6707
|
-
let hasValidWorktree =
|
|
6708
|
-
if (
|
|
6709
|
-
|
|
6761
|
+
let hasValidWorktree = existsSync27(resolve28(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6762
|
+
if (existsSync27(config.workspaceDir) && !hasValidWorktree) {
|
|
6763
|
+
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6710
6764
|
}
|
|
6711
6765
|
if (!hasValidWorktree) {
|
|
6712
|
-
|
|
6766
|
+
mkdirSync14(dirname11(config.workspaceDir), { recursive: true });
|
|
6713
6767
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6714
6768
|
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]);
|
|
6715
6769
|
if (add.exitCode !== 0) {
|
|
@@ -6885,31 +6939,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
6885
6939
|
|
|
6886
6940
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
6887
6941
|
import {
|
|
6888
|
-
existsSync as
|
|
6942
|
+
existsSync as existsSync29,
|
|
6889
6943
|
lstatSync,
|
|
6890
|
-
mkdirSync as
|
|
6891
|
-
readdirSync as
|
|
6892
|
-
readFileSync as
|
|
6893
|
-
rmSync as
|
|
6944
|
+
mkdirSync as mkdirSync16,
|
|
6945
|
+
readdirSync as readdirSync6,
|
|
6946
|
+
readFileSync as readFileSync14,
|
|
6947
|
+
rmSync as rmSync11,
|
|
6894
6948
|
statSync as statSync8,
|
|
6895
6949
|
symlinkSync as symlinkSync4
|
|
6896
6950
|
} from "fs";
|
|
6897
6951
|
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
6898
|
-
import { dirname as dirname13, resolve as
|
|
6952
|
+
import { dirname as dirname13, resolve as resolve30 } from "path";
|
|
6899
6953
|
|
|
6900
6954
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
6901
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
6955
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync28, mkdirSync as mkdirSync15, statSync as statSync7 } from "fs";
|
|
6902
6956
|
import { tmpdir as tmpdir6 } from "os";
|
|
6903
|
-
import { dirname as dirname12, resolve as
|
|
6904
|
-
var sharedRouterOutputDir =
|
|
6905
|
-
var sharedRouterOutputPath =
|
|
6957
|
+
import { dirname as dirname12, resolve as resolve29 } from "path";
|
|
6958
|
+
var sharedRouterOutputDir = resolve29(tmpdir6(), "rig-native");
|
|
6959
|
+
var sharedRouterOutputPath = resolve29(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
6906
6960
|
function runtimeClaudeToolRouterFileName() {
|
|
6907
6961
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
6908
6962
|
}
|
|
6909
6963
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
6910
|
-
const sourcePath =
|
|
6911
|
-
|
|
6912
|
-
const needsBuild = !
|
|
6964
|
+
const sourcePath = resolve29(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
6965
|
+
mkdirSync15(dirname12(outputPath), { recursive: true });
|
|
6966
|
+
const needsBuild = !existsSync28(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
|
|
6913
6967
|
if (!needsBuild) {
|
|
6914
6968
|
return outputPath;
|
|
6915
6969
|
}
|
|
@@ -6923,9 +6977,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
6923
6977
|
}
|
|
6924
6978
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
6925
6979
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
6926
|
-
const targetPath =
|
|
6927
|
-
|
|
6928
|
-
const needsCopy = !
|
|
6980
|
+
const targetPath = resolve29(targetDir, runtimeClaudeToolRouterFileName());
|
|
6981
|
+
mkdirSync15(targetDir, { recursive: true });
|
|
6982
|
+
const needsCopy = !existsSync28(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
|
|
6929
6983
|
if (needsCopy) {
|
|
6930
6984
|
copyFileSync6(sourcePath, targetPath);
|
|
6931
6985
|
chmodSync6(targetPath, 493);
|
|
@@ -6938,48 +6992,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
6938
6992
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
6939
6993
|
function resolveRigSourceRoot(projectRoot) {
|
|
6940
6994
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6941
|
-
if (hostProjectRoot &&
|
|
6995
|
+
if (hostProjectRoot && existsSync29(resolve30(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6942
6996
|
return hostProjectRoot;
|
|
6943
6997
|
}
|
|
6944
|
-
const fromModule =
|
|
6945
|
-
if (
|
|
6998
|
+
const fromModule = resolve30(import.meta.dir, "../../../../../..");
|
|
6999
|
+
if (existsSync29(resolve30(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6946
7000
|
return fromModule;
|
|
6947
7001
|
}
|
|
6948
7002
|
return projectRoot;
|
|
6949
7003
|
}
|
|
6950
7004
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
6951
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
7005
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve30(sessionDir, "session.json")]) {
|
|
6952
7006
|
removeSymbolicLink(path);
|
|
6953
7007
|
}
|
|
6954
7008
|
runtimePrepareTrackedPathsNative({
|
|
6955
7009
|
logsDir,
|
|
6956
7010
|
stateDir,
|
|
6957
7011
|
sessionDir,
|
|
6958
|
-
controlledBashLogFile:
|
|
6959
|
-
eventsFile:
|
|
7012
|
+
controlledBashLogFile: resolve30(logsDir, "controlled-bash.jsonl"),
|
|
7013
|
+
eventsFile: resolve30(logsDir, "control-plane.events.jsonl")
|
|
6960
7014
|
});
|
|
6961
7015
|
}
|
|
6962
7016
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
6963
7017
|
await mkdir2(stateDir, { recursive: true });
|
|
6964
7018
|
await mkdir2(sessionDir, { recursive: true });
|
|
6965
|
-
const failedApproachesPath =
|
|
6966
|
-
if (!
|
|
7019
|
+
const failedApproachesPath = resolve30(stateDir, "failed_approaches.md");
|
|
7020
|
+
if (!existsSync29(failedApproachesPath)) {
|
|
6967
7021
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
6968
7022
|
|
|
6969
7023
|
`);
|
|
6970
7024
|
}
|
|
6971
|
-
const hookTripsPath =
|
|
6972
|
-
if (!
|
|
7025
|
+
const hookTripsPath = resolve30(stateDir, "hook_trips.log");
|
|
7026
|
+
if (!existsSync29(hookTripsPath)) {
|
|
6973
7027
|
await writeFile(hookTripsPath, "");
|
|
6974
7028
|
}
|
|
6975
|
-
const sessionFile =
|
|
7029
|
+
const sessionFile = resolve30(sessionDir, "session.json");
|
|
6976
7030
|
if (taskId) {
|
|
6977
7031
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
6978
7032
|
}
|
|
6979
7033
|
}
|
|
6980
7034
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
6981
|
-
const artifactDir =
|
|
6982
|
-
const runtimeSnapshotDir =
|
|
7035
|
+
const artifactDir = resolve30(workspaceDir, "artifacts", taskId);
|
|
7036
|
+
const runtimeSnapshotDir = resolve30(artifactDir, "runtime-snapshots");
|
|
6983
7037
|
let preservedTrackedFiles = false;
|
|
6984
7038
|
for (const file of [
|
|
6985
7039
|
"changed-files.txt",
|
|
@@ -6995,13 +7049,13 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
6995
7049
|
preservedTrackedFiles = true;
|
|
6996
7050
|
continue;
|
|
6997
7051
|
}
|
|
6998
|
-
|
|
7052
|
+
rmSync11(resolve30(artifactDir, file), { force: true });
|
|
6999
7053
|
}
|
|
7000
7054
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
7001
7055
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
7002
7056
|
preservedTrackedFiles = true;
|
|
7003
7057
|
} else {
|
|
7004
|
-
|
|
7058
|
+
rmSync11(runtimeSnapshotDir, { recursive: true, force: true });
|
|
7005
7059
|
}
|
|
7006
7060
|
if (preservedTrackedFiles) {
|
|
7007
7061
|
console.log(`[rig-agent] Preserved tracked runtime artifact files in ${taskId}; skipped ephemeral cleanup for committed paths.`);
|
|
@@ -7034,28 +7088,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
7034
7088
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
7035
7089
|
}
|
|
7036
7090
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
7037
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
7038
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
7091
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve30(options.binDir, "rig"), rigSourceRoot);
|
|
7092
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve30(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
7039
7093
|
...options.runtimeSecretDefines,
|
|
7040
7094
|
AGENT_TASK_ID: options.taskId,
|
|
7041
7095
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7042
7096
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
7043
7097
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
7044
7098
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
7045
|
-
AGENT_BINARY_PATH:
|
|
7099
|
+
AGENT_BINARY_PATH: resolve30(options.binDir, "rig-agent"),
|
|
7046
7100
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
7047
7101
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
7048
7102
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
7049
7103
|
});
|
|
7050
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
7104
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve30(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
7051
7105
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7052
7106
|
AGENT_LOGS_DIR: options.logsDir,
|
|
7053
7107
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
7054
|
-
AGENT_TS_API_TESTS_DIR:
|
|
7055
|
-
AGENT_RIG_AGENT_BIN:
|
|
7108
|
+
AGENT_TS_API_TESTS_DIR: resolve30(options.workspaceDir, "TSAPITests"),
|
|
7109
|
+
AGENT_RIG_AGENT_BIN: resolve30(options.binDir, "rig-agent")
|
|
7056
7110
|
});
|
|
7057
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
7058
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
7111
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve30(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
7112
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve30(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
7059
7113
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7060
7114
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7061
7115
|
});
|
|
@@ -7064,15 +7118,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
7064
7118
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7065
7119
|
};
|
|
7066
7120
|
for (const hookName of hookNames) {
|
|
7067
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
7121
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve30(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
7068
7122
|
}
|
|
7069
|
-
const pluginsDir =
|
|
7070
|
-
if (
|
|
7071
|
-
for (const entry of
|
|
7123
|
+
const pluginsDir = resolve30(options.projectRoot, "rig/plugins");
|
|
7124
|
+
if (existsSync29(pluginsDir)) {
|
|
7125
|
+
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
7072
7126
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
7073
7127
|
if (!match)
|
|
7074
7128
|
continue;
|
|
7075
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
7129
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve30(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
7076
7130
|
}
|
|
7077
7131
|
}
|
|
7078
7132
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -7082,8 +7136,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
7082
7136
|
}
|
|
7083
7137
|
async function writeRuntimeManifest(config) {
|
|
7084
7138
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
7085
|
-
const binarySha256 = sha256Hex(
|
|
7086
|
-
const manifestPath =
|
|
7139
|
+
const binarySha256 = sha256Hex(readFileSync14(config.binaryPath));
|
|
7140
|
+
const manifestPath = resolve30(config.runtimeRoot, "manifest.json");
|
|
7087
7141
|
const manifest = {
|
|
7088
7142
|
runtimeId: config.runtimeId,
|
|
7089
7143
|
taskId: config.taskId,
|
|
@@ -7117,7 +7171,7 @@ function removeSymbolicLink(path) {
|
|
|
7117
7171
|
} catch {
|
|
7118
7172
|
return;
|
|
7119
7173
|
}
|
|
7120
|
-
|
|
7174
|
+
rmSync11(path, { force: true, recursive: true });
|
|
7121
7175
|
}
|
|
7122
7176
|
async function resetTrackedArtifactPath(workspaceDir, relativePath) {
|
|
7123
7177
|
const tracked = await runGitLsFiles(workspaceDir, relativePath);
|
|
@@ -7143,7 +7197,7 @@ async function restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, r
|
|
|
7143
7197
|
const retryDelayMs = options.retryDelayMs ?? GIT_INDEX_LOCK_RETRY_DELAY_MS;
|
|
7144
7198
|
const now = options.now ?? Date.now;
|
|
7145
7199
|
const statMtimeMs = options.statMtimeMs ?? readFileMtimeMs;
|
|
7146
|
-
const removeFile = options.removeFile ?? ((path) =>
|
|
7200
|
+
const removeFile = options.removeFile ?? ((path) => rmSync11(path, { force: true }));
|
|
7147
7201
|
const log = options.log ?? console.warn;
|
|
7148
7202
|
let lastOutput = "";
|
|
7149
7203
|
for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
|
|
@@ -7203,31 +7257,31 @@ function readFileMtimeMs(path) {
|
|
|
7203
7257
|
}
|
|
7204
7258
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
7205
7259
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
7206
|
-
const sourceNodeModules =
|
|
7207
|
-
if (!
|
|
7208
|
-
const runtimeHumoongate =
|
|
7209
|
-
if (
|
|
7210
|
-
const targetNodeModules =
|
|
7260
|
+
const sourceNodeModules = resolve30(monorepoRoot, "humoongate", "node_modules");
|
|
7261
|
+
if (!existsSync29(sourceNodeModules)) {} else {
|
|
7262
|
+
const runtimeHumoongate = resolve30(workspaceDir, "humoongate");
|
|
7263
|
+
if (existsSync29(resolve30(runtimeHumoongate, "package.json"))) {
|
|
7264
|
+
const targetNodeModules = resolve30(runtimeHumoongate, "node_modules");
|
|
7211
7265
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
7212
7266
|
}
|
|
7213
7267
|
}
|
|
7214
|
-
const runtimeHpNext =
|
|
7215
|
-
if (!
|
|
7268
|
+
const runtimeHpNext = resolve30(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
7269
|
+
if (!existsSync29(resolve30(runtimeHpNext, "package.json"))) {
|
|
7216
7270
|
return;
|
|
7217
7271
|
}
|
|
7218
|
-
const sourceHpNextNodeModules =
|
|
7219
|
-
const sourceMonorepoNodeModules =
|
|
7220
|
-
const targetHpNextNodeModules =
|
|
7221
|
-
if (
|
|
7272
|
+
const sourceHpNextNodeModules = resolve30(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
7273
|
+
const sourceMonorepoNodeModules = resolve30(monorepoRoot, "node_modules");
|
|
7274
|
+
const targetHpNextNodeModules = resolve30(runtimeHpNext, "node_modules");
|
|
7275
|
+
if (existsSync29(sourceHpNextNodeModules)) {
|
|
7222
7276
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
7223
7277
|
return;
|
|
7224
7278
|
}
|
|
7225
|
-
if (
|
|
7279
|
+
if (existsSync29(sourceMonorepoNodeModules)) {
|
|
7226
7280
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
7227
7281
|
}
|
|
7228
7282
|
}
|
|
7229
7283
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
7230
|
-
linkNodeModulesLayer(
|
|
7284
|
+
linkNodeModulesLayer(resolve30(monorepoRoot, "node_modules"), resolve30(workspaceDir, "node_modules"));
|
|
7231
7285
|
for (const relativePackageDir of [
|
|
7232
7286
|
"apps/native-app/apps/marketing",
|
|
7233
7287
|
"apps/native-app/apps/web",
|
|
@@ -7249,15 +7303,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
7249
7303
|
"packages/standard-plugin",
|
|
7250
7304
|
"packages/validator-kit"
|
|
7251
7305
|
]) {
|
|
7252
|
-
const workspacePackageDir =
|
|
7253
|
-
if (!
|
|
7306
|
+
const workspacePackageDir = resolve30(workspaceDir, relativePackageDir);
|
|
7307
|
+
if (!existsSync29(resolve30(workspacePackageDir, "package.json"))) {
|
|
7254
7308
|
continue;
|
|
7255
7309
|
}
|
|
7256
|
-
linkNodeModulesLayer(
|
|
7310
|
+
linkNodeModulesLayer(resolve30(monorepoRoot, relativePackageDir, "node_modules"), resolve30(workspacePackageDir, "node_modules"));
|
|
7257
7311
|
}
|
|
7258
7312
|
}
|
|
7259
7313
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
7260
|
-
if (!
|
|
7314
|
+
if (!existsSync29(sourceDir) || existsSync29(targetDir)) {
|
|
7261
7315
|
return;
|
|
7262
7316
|
}
|
|
7263
7317
|
try {
|
|
@@ -7266,30 +7320,30 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
7266
7320
|
} catch (error) {
|
|
7267
7321
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
7268
7322
|
}
|
|
7269
|
-
|
|
7323
|
+
mkdirSync16(dirname13(targetDir), { recursive: true });
|
|
7270
7324
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
7271
7325
|
}
|
|
7272
7326
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
7273
|
-
const hooksDir =
|
|
7274
|
-
const pluginsDir =
|
|
7275
|
-
const validatorsDir =
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7327
|
+
const hooksDir = resolve30(runtimeBinDir, "hooks");
|
|
7328
|
+
const pluginsDir = resolve30(runtimeBinDir, "plugins");
|
|
7329
|
+
const validatorsDir = resolve30(runtimeBinDir, "validators");
|
|
7330
|
+
mkdirSync16(hooksDir, { recursive: true });
|
|
7331
|
+
mkdirSync16(pluginsDir, { recursive: true });
|
|
7332
|
+
mkdirSync16(validatorsDir, { recursive: true });
|
|
7279
7333
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
7280
7334
|
}
|
|
7281
7335
|
|
|
7282
7336
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
7283
|
-
import { existsSync as
|
|
7284
|
-
import { basename as basename9, resolve as
|
|
7337
|
+
import { existsSync as existsSync32, rmSync as rmSync12, writeFileSync as writeFileSync13 } from "fs";
|
|
7338
|
+
import { basename as basename9, resolve as resolve34 } from "path";
|
|
7285
7339
|
|
|
7286
7340
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
7287
|
-
import { existsSync as
|
|
7341
|
+
import { existsSync as existsSync31 } from "fs";
|
|
7288
7342
|
|
|
7289
7343
|
// packages/runtime/src/control-plane/runtime/guard.ts
|
|
7290
7344
|
import { optimizeNextInvocation } from "bun:jsc";
|
|
7291
|
-
import { existsSync as
|
|
7292
|
-
import { resolve as
|
|
7345
|
+
import { existsSync as existsSync30, readFileSync as readFileSync15, statSync as statSync9 } from "fs";
|
|
7346
|
+
import { resolve as resolve31 } from "path";
|
|
7293
7347
|
|
|
7294
7348
|
// packages/runtime/src/control-plane/runtime/guard-types.ts
|
|
7295
7349
|
var POLICY_VERSION = 1;
|
|
@@ -7352,8 +7406,8 @@ function loadPolicy(projectRoot) {
|
|
|
7352
7406
|
if (seededPolicyConfig) {
|
|
7353
7407
|
return seededPolicyConfig;
|
|
7354
7408
|
}
|
|
7355
|
-
const configPath =
|
|
7356
|
-
if (!
|
|
7409
|
+
const configPath = resolve31(projectRoot, "rig/policy/policy.json");
|
|
7410
|
+
if (!existsSync30(configPath)) {
|
|
7357
7411
|
return defaultPolicy();
|
|
7358
7412
|
}
|
|
7359
7413
|
let mtimeMs;
|
|
@@ -7367,7 +7421,7 @@ function loadPolicy(projectRoot) {
|
|
|
7367
7421
|
}
|
|
7368
7422
|
let parsed;
|
|
7369
7423
|
try {
|
|
7370
|
-
parsed = JSON.parse(
|
|
7424
|
+
parsed = JSON.parse(readFileSync15(configPath, "utf-8"));
|
|
7371
7425
|
} catch {
|
|
7372
7426
|
return defaultPolicy();
|
|
7373
7427
|
}
|
|
@@ -7583,28 +7637,28 @@ function resolveAction(mode, matched) {
|
|
|
7583
7637
|
}
|
|
7584
7638
|
function resolveAbsolutePath(projectRoot, rawPath) {
|
|
7585
7639
|
if (rawPath.startsWith("/"))
|
|
7586
|
-
return
|
|
7587
|
-
return
|
|
7640
|
+
return resolve31(rawPath);
|
|
7641
|
+
return resolve31(projectRoot, rawPath);
|
|
7588
7642
|
}
|
|
7589
7643
|
function isHarnessPath(projectRoot, rawPath) {
|
|
7590
7644
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7591
7645
|
const managedRoots = [
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7646
|
+
resolve31(projectRoot, "rig"),
|
|
7647
|
+
resolve31(projectRoot, ".rig"),
|
|
7648
|
+
resolve31(projectRoot, "artifacts")
|
|
7595
7649
|
];
|
|
7596
7650
|
return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
|
|
7597
7651
|
}
|
|
7598
7652
|
function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
|
|
7599
7653
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7600
7654
|
if (taskWorkspace) {
|
|
7601
|
-
const workspaceRigRoot =
|
|
7602
|
-
const workspaceArtifactsRoot =
|
|
7655
|
+
const workspaceRigRoot = resolve31(taskWorkspace, ".rig");
|
|
7656
|
+
const workspaceArtifactsRoot = resolve31(taskWorkspace, "artifacts");
|
|
7603
7657
|
if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
|
|
7604
7658
|
return true;
|
|
7605
7659
|
}
|
|
7606
7660
|
}
|
|
7607
|
-
const runtimeRoot =
|
|
7661
|
+
const runtimeRoot = resolve31(projectRoot, ".rig/runtime/agents");
|
|
7608
7662
|
return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
|
|
7609
7663
|
}
|
|
7610
7664
|
function isTestFile(path) {
|
|
@@ -7652,7 +7706,7 @@ function evaluateScope(policy, context, filePath, access) {
|
|
|
7652
7706
|
return allowed();
|
|
7653
7707
|
}
|
|
7654
7708
|
if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
|
|
7655
|
-
const absPath =
|
|
7709
|
+
const absPath = resolve31(filePath);
|
|
7656
7710
|
if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
|
|
7657
7711
|
const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
|
|
7658
7712
|
const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
|
|
@@ -7980,13 +8034,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
7980
8034
|
depRoots
|
|
7981
8035
|
};
|
|
7982
8036
|
const fsContext = {
|
|
7983
|
-
pathExists: (p) =>
|
|
8037
|
+
pathExists: (p) => existsSync31(p),
|
|
7984
8038
|
realPath: toRealPath
|
|
7985
8039
|
};
|
|
7986
8040
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
7987
8041
|
const seatbelt = Bun.which("sandbox-exec");
|
|
7988
8042
|
probed.push("sandbox-exec");
|
|
7989
|
-
if (seatbelt &&
|
|
8043
|
+
if (seatbelt && existsSync31(seatbelt)) {
|
|
7990
8044
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
7991
8045
|
if (SeatbeltBackendClass) {
|
|
7992
8046
|
return {
|
|
@@ -8107,10 +8161,10 @@ init_layout();
|
|
|
8107
8161
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
8108
8162
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
8109
8163
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
8110
|
-
const readyFile =
|
|
8111
|
-
const requestFile =
|
|
8112
|
-
|
|
8113
|
-
|
|
8164
|
+
const readyFile = resolve34(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
8165
|
+
const requestFile = resolve34(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
8166
|
+
rmSync12(readyFile, { force: true });
|
|
8167
|
+
rmSync12(requestFile, { force: true });
|
|
8114
8168
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
8115
8169
|
const useCompiledSidecar = shouldUseCompiledSnapshotSidecar(sidecarBinary);
|
|
8116
8170
|
const bunCli = useCompiledSidecar ? null : resolveBunCliInvocation();
|
|
@@ -8148,19 +8202,19 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
8148
8202
|
proc.kill("SIGTERM");
|
|
8149
8203
|
} catch {}
|
|
8150
8204
|
await proc.exited;
|
|
8151
|
-
|
|
8152
|
-
|
|
8205
|
+
rmSync12(readyFile, { force: true });
|
|
8206
|
+
rmSync12(requestFile, { force: true });
|
|
8153
8207
|
},
|
|
8154
8208
|
finalize: async (commandParts, exitCode) => {
|
|
8155
|
-
|
|
8209
|
+
writeFileSync13(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
8156
8210
|
`, "utf-8");
|
|
8157
8211
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
8158
8212
|
proc.exited,
|
|
8159
8213
|
stdoutTextPromise,
|
|
8160
8214
|
stderrTextPromise
|
|
8161
8215
|
]);
|
|
8162
|
-
|
|
8163
|
-
|
|
8216
|
+
rmSync12(readyFile, { force: true });
|
|
8217
|
+
rmSync12(requestFile, { force: true });
|
|
8164
8218
|
if (sidecarExitCode !== 0) {
|
|
8165
8219
|
throw new Error(`snapshot sidecar failed (${sidecarExitCode}): ${stderr || stdout}`);
|
|
8166
8220
|
}
|
|
@@ -8180,10 +8234,10 @@ function resolveSnapshotSidecarScriptPath() {
|
|
|
8180
8234
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
8181
8235
|
}
|
|
8182
8236
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
8183
|
-
return
|
|
8237
|
+
return resolve34(binDir, "snapshot-sidecar");
|
|
8184
8238
|
}
|
|
8185
8239
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
8186
|
-
if (!
|
|
8240
|
+
if (!existsSync32(binaryPath)) {
|
|
8187
8241
|
return false;
|
|
8188
8242
|
}
|
|
8189
8243
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -8198,12 +8252,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
8198
8252
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
8199
8253
|
].filter((value) => Boolean(value));
|
|
8200
8254
|
for (const root of hostRoots) {
|
|
8201
|
-
const candidate =
|
|
8202
|
-
if (
|
|
8255
|
+
const candidate = resolve34(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
8256
|
+
if (existsSync32(candidate)) {
|
|
8203
8257
|
return candidate;
|
|
8204
8258
|
}
|
|
8205
8259
|
}
|
|
8206
|
-
return
|
|
8260
|
+
return resolve34(import.meta.dir, "..", fileName);
|
|
8207
8261
|
}
|
|
8208
8262
|
function resolveBunCliInvocation() {
|
|
8209
8263
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -8230,7 +8284,7 @@ function resolveBunCliInvocation() {
|
|
|
8230
8284
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
8231
8285
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
8232
8286
|
while (Date.now() < deadline) {
|
|
8233
|
-
if (
|
|
8287
|
+
if (existsSync32(readyFile)) {
|
|
8234
8288
|
return;
|
|
8235
8289
|
}
|
|
8236
8290
|
const exitCode = proc.exitCode;
|
|
@@ -8248,9 +8302,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
8248
8302
|
async function hydrateRuntimeMemory(options) {
|
|
8249
8303
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
8250
8304
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
8251
|
-
const hydratedPath =
|
|
8305
|
+
const hydratedPath = resolve35(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
8252
8306
|
try {
|
|
8253
|
-
await mkdir3(
|
|
8307
|
+
await mkdir3(resolve35(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
8254
8308
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
8255
8309
|
return {
|
|
8256
8310
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -8265,12 +8319,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
8265
8319
|
}
|
|
8266
8320
|
}
|
|
8267
8321
|
async function createRuntimeTaskRecordReader(options) {
|
|
8268
|
-
const legacyConfigPath =
|
|
8322
|
+
const legacyConfigPath = resolve35(options.projectRoot, ".rig", "task-config.json");
|
|
8269
8323
|
let pluginHostContext = null;
|
|
8270
8324
|
try {
|
|
8271
8325
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
8272
8326
|
} catch (error) {
|
|
8273
|
-
if (!
|
|
8327
|
+
if (!existsSync33(legacyConfigPath)) {
|
|
8274
8328
|
throw error;
|
|
8275
8329
|
}
|
|
8276
8330
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -8290,7 +8344,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
8290
8344
|
source: "plugin"
|
|
8291
8345
|
};
|
|
8292
8346
|
}
|
|
8293
|
-
if (
|
|
8347
|
+
if (existsSync33(legacyConfigPath)) {
|
|
8294
8348
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
8295
8349
|
options.diagnostics?.(message);
|
|
8296
8350
|
console.warn(message);
|
|
@@ -8307,10 +8361,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
8307
8361
|
};
|
|
8308
8362
|
}
|
|
8309
8363
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
8310
|
-
const jsonPath =
|
|
8311
|
-
if (
|
|
8364
|
+
const jsonPath = resolve35(projectRoot, "rig.config.json");
|
|
8365
|
+
if (existsSync33(jsonPath)) {
|
|
8312
8366
|
try {
|
|
8313
|
-
const parsed = JSON.parse(
|
|
8367
|
+
const parsed = JSON.parse(readFileSync16(jsonPath, "utf8"));
|
|
8314
8368
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
8315
8369
|
const taskSource = parsed.taskSource;
|
|
8316
8370
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -8322,12 +8376,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
8322
8376
|
return null;
|
|
8323
8377
|
}
|
|
8324
8378
|
}
|
|
8325
|
-
const tsPath =
|
|
8326
|
-
if (!
|
|
8379
|
+
const tsPath = resolve35(projectRoot, "rig.config.ts");
|
|
8380
|
+
if (!existsSync33(tsPath)) {
|
|
8327
8381
|
return null;
|
|
8328
8382
|
}
|
|
8329
8383
|
try {
|
|
8330
|
-
const source =
|
|
8384
|
+
const source = readFileSync16(tsPath, "utf8");
|
|
8331
8385
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
8332
8386
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
8333
8387
|
return kind ?? null;
|
|
@@ -8397,8 +8451,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
8397
8451
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
8398
8452
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
8399
8453
|
};
|
|
8400
|
-
const configPath =
|
|
8401
|
-
await mkdir3(
|
|
8454
|
+
const configPath = resolve35(options.workspaceDir, ".rig", "task-config.json");
|
|
8455
|
+
await mkdir3(resolve35(options.workspaceDir, ".rig"), { recursive: true });
|
|
8402
8456
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
8403
8457
|
`, "utf-8");
|
|
8404
8458
|
}
|
|
@@ -8462,9 +8516,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8462
8516
|
}
|
|
8463
8517
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8464
8518
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8465
|
-
const workspaceDir =
|
|
8519
|
+
const workspaceDir = resolve35(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8466
8520
|
const createdAt = new Date().toISOString();
|
|
8467
|
-
if (!
|
|
8521
|
+
if (!existsSync33(resolve35(monorepoRoot, ".git"))) {
|
|
8468
8522
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8469
8523
|
}
|
|
8470
8524
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8499,7 +8553,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8499
8553
|
logsDir: overlay.logsDir,
|
|
8500
8554
|
stateDir: overlay.stateDir,
|
|
8501
8555
|
sessionDir: overlay.sessionDir,
|
|
8502
|
-
claudeHomeDir:
|
|
8556
|
+
claudeHomeDir: resolve35(workspaceLayout.homeDir, ".claude"),
|
|
8503
8557
|
contextFile: overlay.contextPath,
|
|
8504
8558
|
binDir: workspaceLayout.binDir,
|
|
8505
8559
|
createdAt
|
|
@@ -8512,8 +8566,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8512
8566
|
projectRoot: options.projectRoot,
|
|
8513
8567
|
workspaceDir
|
|
8514
8568
|
});
|
|
8515
|
-
|
|
8516
|
-
|
|
8569
|
+
mkdirSync19(runtime.binDir, { recursive: true });
|
|
8570
|
+
mkdirSync19(workspaceLayout.distDir, { recursive: true });
|
|
8517
8571
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8518
8572
|
if (options.preserveTaskArtifacts) {
|
|
8519
8573
|
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
@@ -8532,7 +8586,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8532
8586
|
runtimeId: options.id
|
|
8533
8587
|
}),
|
|
8534
8588
|
workspaceDir,
|
|
8535
|
-
artifactRoot:
|
|
8589
|
+
artifactRoot: resolve35(workspaceDir, "artifacts", options.taskId),
|
|
8536
8590
|
hostProjectRoot: options.projectRoot,
|
|
8537
8591
|
monorepoMainRoot: monorepoRoot,
|
|
8538
8592
|
monorepoBaseRef: baseRef,
|
|
@@ -8548,8 +8602,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8548
8602
|
stateDir: overlay.stateDir,
|
|
8549
8603
|
logsDir: overlay.logsDir,
|
|
8550
8604
|
sessionDir: overlay.sessionDir,
|
|
8551
|
-
sessionFile:
|
|
8552
|
-
policyFile:
|
|
8605
|
+
sessionFile: resolve35(overlay.sessionDir, "session.json"),
|
|
8606
|
+
policyFile: resolve35(options.projectRoot, "rig/policy/policy.json"),
|
|
8553
8607
|
binDir: runtime.binDir,
|
|
8554
8608
|
createdAt,
|
|
8555
8609
|
memory
|
|
@@ -8560,9 +8614,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8560
8614
|
task: taskResolution.task,
|
|
8561
8615
|
taskEntry
|
|
8562
8616
|
});
|
|
8563
|
-
const manifestPath =
|
|
8617
|
+
const manifestPath = resolve35(runtimeRoot, "manifest.json");
|
|
8564
8618
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8565
|
-
const runtimeAgentBinary =
|
|
8619
|
+
const runtimeAgentBinary = resolve35(runtime.binDir, "rig-agent");
|
|
8566
8620
|
await ensureRigGitBinaryPath();
|
|
8567
8621
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8568
8622
|
projectRoot: options.projectRoot,
|
|
@@ -8577,10 +8631,10 @@ async function ensureAgentRuntime(options) {
|
|
|
8577
8631
|
const bakedStatusOutput = await captureStdout(async () => {
|
|
8578
8632
|
taskStatus(options.projectRoot);
|
|
8579
8633
|
});
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8634
|
+
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8635
|
+
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8636
|
+
mkdirSync19(runtime.binDir, { recursive: true });
|
|
8637
|
+
mkdirSync19(workspaceLayout.distDir, { recursive: true });
|
|
8584
8638
|
await buildRuntimeToolchain({
|
|
8585
8639
|
projectRoot: options.projectRoot,
|
|
8586
8640
|
workspaceDir,
|
|
@@ -8617,9 +8671,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8617
8671
|
workspaceDir,
|
|
8618
8672
|
taskEntry
|
|
8619
8673
|
});
|
|
8620
|
-
const sandboxDir =
|
|
8674
|
+
const sandboxDir = resolve35(runtimeRoot, "sandbox");
|
|
8621
8675
|
await mkdir3(sandboxDir, { recursive: true });
|
|
8622
|
-
await writeFile2(
|
|
8676
|
+
await writeFile2(resolve35(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8623
8677
|
id: options.id,
|
|
8624
8678
|
taskId: options.taskId,
|
|
8625
8679
|
mode: "worktree",
|
|
@@ -8726,8 +8780,8 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8726
8780
|
const sendRequest = async (method, params) => {
|
|
8727
8781
|
const id = nextRequestId;
|
|
8728
8782
|
nextRequestId += 1;
|
|
8729
|
-
const resultPromise = new Promise((
|
|
8730
|
-
pendingResponses.set(id, { resolve:
|
|
8783
|
+
const resultPromise = new Promise((resolve36, reject) => {
|
|
8784
|
+
pendingResponses.set(id, { resolve: resolve36, reject });
|
|
8731
8785
|
});
|
|
8732
8786
|
await sendMessage({ id, method, params });
|
|
8733
8787
|
return resultPromise;
|
|
@@ -8926,8 +8980,8 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8926
8980
|
console.error(line);
|
|
8927
8981
|
}
|
|
8928
8982
|
});
|
|
8929
|
-
const exitPromise = new Promise((
|
|
8930
|
-
child.once("close", (code, signal) =>
|
|
8983
|
+
const exitPromise = new Promise((resolve36) => {
|
|
8984
|
+
child.once("close", (code, signal) => resolve36({ code, signal }));
|
|
8931
8985
|
});
|
|
8932
8986
|
await sendRequest("initialize", {
|
|
8933
8987
|
clientInfo: DEFAULT_CLIENT_INFO,
|
|
@@ -8968,7 +9022,7 @@ async function runCodexAppServerTaskRun(options) {
|
|
|
8968
9022
|
while (!completionState.current) {
|
|
8969
9023
|
exitResult = await Promise.race([
|
|
8970
9024
|
exitPromise,
|
|
8971
|
-
new Promise((
|
|
9025
|
+
new Promise((resolve36) => setTimeout(() => resolve36(null), 100))
|
|
8972
9026
|
]);
|
|
8973
9027
|
if (exitResult) {
|
|
8974
9028
|
break;
|
|
@@ -9117,13 +9171,13 @@ function sanitizeEnv(env) {
|
|
|
9117
9171
|
return next;
|
|
9118
9172
|
}
|
|
9119
9173
|
function writeChildLine(child, line) {
|
|
9120
|
-
return new Promise((
|
|
9174
|
+
return new Promise((resolve36, reject) => {
|
|
9121
9175
|
child.stdin.write(line, (error) => {
|
|
9122
9176
|
if (error) {
|
|
9123
9177
|
reject(error);
|
|
9124
9178
|
return;
|
|
9125
9179
|
}
|
|
9126
|
-
|
|
9180
|
+
resolve36();
|
|
9127
9181
|
});
|
|
9128
9182
|
});
|
|
9129
9183
|
}
|
|
@@ -9171,8 +9225,8 @@ function formatJsonRpcError(error) {
|
|
|
9171
9225
|
|
|
9172
9226
|
// packages/runtime/src/control-plane/pi-sessiond/launcher.ts
|
|
9173
9227
|
import { randomBytes } from "crypto";
|
|
9174
|
-
import { existsSync as
|
|
9175
|
-
import { dirname as dirname14, resolve as
|
|
9228
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync20, readFileSync as readFileSync17, rmSync as rmSync14 } from "fs";
|
|
9229
|
+
import { dirname as dirname14, resolve as resolve36 } from "path";
|
|
9176
9230
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9177
9231
|
|
|
9178
9232
|
// packages/runtime/src/control-plane/pi-sessiond/client.ts
|
|
@@ -9217,15 +9271,15 @@ class RigPiSessionDaemonClient {
|
|
|
9217
9271
|
var BUILD_CONFIG2 = {};
|
|
9218
9272
|
var BAKED_RIG_SOURCE_ROOT = BUILD_CONFIG2.RIG_SOURCE_ROOT ?? "";
|
|
9219
9273
|
async function ensureRigPiSessionDaemon(input) {
|
|
9220
|
-
const rootDir =
|
|
9221
|
-
|
|
9222
|
-
const readyFile =
|
|
9274
|
+
const rootDir = resolve36(input.rootDir);
|
|
9275
|
+
mkdirSync20(rootDir, { recursive: true });
|
|
9276
|
+
const readyFile = resolve36(rootDir, "ready.json");
|
|
9223
9277
|
const existing = readDaemonReadyFile(readyFile);
|
|
9224
9278
|
const existingHandle = existing ? await tryReady(existing) : null;
|
|
9225
9279
|
if (existingHandle)
|
|
9226
9280
|
return existingHandle;
|
|
9227
9281
|
try {
|
|
9228
|
-
|
|
9282
|
+
rmSync14(readyFile, { force: true });
|
|
9229
9283
|
} catch {}
|
|
9230
9284
|
const token = randomBytes(32).toString("hex");
|
|
9231
9285
|
const binPath = resolveRigPiSessionDaemonBinPath(input.env);
|
|
@@ -9255,7 +9309,12 @@ async function ensureRigPiSessionDaemon(input) {
|
|
|
9255
9309
|
return handle;
|
|
9256
9310
|
await sleep(100);
|
|
9257
9311
|
}
|
|
9258
|
-
throw new Error(
|
|
9312
|
+
throw new Error([
|
|
9313
|
+
`Rig Pi session daemon did not become ready at ${readyFile}.`,
|
|
9314
|
+
"Usual causes: the bundled Pi runtime is missing or broken. Run `rig doctor` to check Pi wiring,",
|
|
9315
|
+
"set RIG_PI_BINARY to a working Pi build, or run without Pi via RIG_RUNTIME_ADAPTER=claude-code."
|
|
9316
|
+
].join(`
|
|
9317
|
+
`));
|
|
9259
9318
|
}
|
|
9260
9319
|
function privateMetadataForDaemon(input) {
|
|
9261
9320
|
return { public: input.publicMetadata, daemonConnection: input.connection };
|
|
@@ -9296,20 +9355,25 @@ function resolveRigPiSessionDaemonBinPath(env) {
|
|
|
9296
9355
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
9297
9356
|
].filter((value) => Boolean(value));
|
|
9298
9357
|
for (const root of roots) {
|
|
9299
|
-
const candidate =
|
|
9300
|
-
if (
|
|
9358
|
+
const candidate = resolve36(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts");
|
|
9359
|
+
if (existsSync34(candidate))
|
|
9301
9360
|
return candidate;
|
|
9302
9361
|
}
|
|
9303
9362
|
const moduleCandidate = fileURLToPath2(new URL("./bin.ts", import.meta.url));
|
|
9304
|
-
if (
|
|
9363
|
+
if (existsSync34(moduleCandidate))
|
|
9305
9364
|
return moduleCandidate;
|
|
9306
|
-
throw new Error(
|
|
9365
|
+
throw new Error([
|
|
9366
|
+
"Unable to locate rig-pi-sessiond entrypoint.",
|
|
9367
|
+
"Set RIG_PI_SESSIOND_BIN or RIG_CONTROL_PLANE_SOURCE_ROOT to the Rig source checkout,",
|
|
9368
|
+
"or run without the Pi daemon via RIG_RUNTIME_ADAPTER=claude-code."
|
|
9369
|
+
].join(`
|
|
9370
|
+
`));
|
|
9307
9371
|
}
|
|
9308
9372
|
function readDaemonReadyFile(path) {
|
|
9309
|
-
if (!
|
|
9373
|
+
if (!existsSync34(path))
|
|
9310
9374
|
return null;
|
|
9311
9375
|
try {
|
|
9312
|
-
const parsed = JSON.parse(
|
|
9376
|
+
const parsed = JSON.parse(readFileSync17(path, "utf8"));
|
|
9313
9377
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
9314
9378
|
} catch {
|
|
9315
9379
|
return null;
|
|
@@ -9319,10 +9383,10 @@ function sleep(ms) {
|
|
|
9319
9383
|
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
9320
9384
|
}
|
|
9321
9385
|
function resolveRigPiSessionDaemonRoot(stateDir) {
|
|
9322
|
-
const root =
|
|
9323
|
-
|
|
9324
|
-
if (!
|
|
9325
|
-
|
|
9386
|
+
const root = resolve36(stateDir, "pi-sessiond");
|
|
9387
|
+
mkdirSync20(dirname14(root), { recursive: true });
|
|
9388
|
+
if (!existsSync34(root))
|
|
9389
|
+
mkdirSync20(root, { recursive: true });
|
|
9326
9390
|
return root;
|
|
9327
9391
|
}
|
|
9328
9392
|
|
|
@@ -9360,7 +9424,7 @@ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar = start
|
|
|
9360
9424
|
}
|
|
9361
9425
|
}
|
|
9362
9426
|
async function runAgentWrapper(options = {}) {
|
|
9363
|
-
const projectRoot =
|
|
9427
|
+
const projectRoot = resolve37(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
|
|
9364
9428
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
9365
9429
|
const argv = options.argv || process.argv.slice(2);
|
|
9366
9430
|
if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
|
|
@@ -9436,11 +9500,11 @@ async function runAgentWrapper(options = {}) {
|
|
|
9436
9500
|
const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
|
|
9437
9501
|
const runClaudeCompatUnsandboxed = provider === "claude-code" && bypassOuterRuntimeSandbox;
|
|
9438
9502
|
if (runClaudeCompatUnsandboxed && process.env.HOME?.trim()) {
|
|
9439
|
-
env.CLAUDE_HOME =
|
|
9503
|
+
env.CLAUDE_HOME = resolve37(process.env.HOME.trim(), ".claude");
|
|
9440
9504
|
env.RIG_CLAUDE_RUNTIME_HOME = runtime.claudeHomeDir;
|
|
9441
9505
|
}
|
|
9442
9506
|
if (provider === "pi") {
|
|
9443
|
-
env.PI_CODING_AGENT_DIR =
|
|
9507
|
+
env.PI_CODING_AGENT_DIR = resolve37(runtime.homeDir, ".pi", "agent");
|
|
9444
9508
|
env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
|
|
9445
9509
|
}
|
|
9446
9510
|
env.RIG_RUNTIME_SANDBOX = "enforce";
|
|
@@ -9641,7 +9705,7 @@ async function runPiSessionDaemonProvider(input) {
|
|
|
9641
9705
|
const start = await daemon.client.request("POST", "/sessions", {
|
|
9642
9706
|
runId,
|
|
9643
9707
|
cwd: input.runtime.workspaceDir,
|
|
9644
|
-
agentDir: input.env.PI_CODING_AGENT_DIR ||
|
|
9708
|
+
agentDir: input.env.PI_CODING_AGENT_DIR || resolve37(input.runtime.homeDir, ".pi", "agent"),
|
|
9645
9709
|
sessionDir: input.runtime.sessionDir,
|
|
9646
9710
|
sessionName: input.sessionName
|
|
9647
9711
|
});
|
|
@@ -9973,6 +10037,7 @@ async function runBeadsJson(projectRoot, args) {
|
|
|
9973
10037
|
return null;
|
|
9974
10038
|
}
|
|
9975
10039
|
}
|
|
10040
|
+
var warnedUnknownRuntimeAdapter = false;
|
|
9976
10041
|
function resolveProvider() {
|
|
9977
10042
|
const value = process.env.RIG_RUNTIME_ADAPTER?.trim().toLowerCase();
|
|
9978
10043
|
if (!value) {
|
|
@@ -9984,6 +10049,10 @@ function resolveProvider() {
|
|
|
9984
10049
|
if (value === "pi" || value === "rig-pi" || value === "@rig/pi") {
|
|
9985
10050
|
return "pi";
|
|
9986
10051
|
}
|
|
10052
|
+
if (value !== "claude-code" && value !== "claude" && !warnedUnknownRuntimeAdapter) {
|
|
10053
|
+
warnedUnknownRuntimeAdapter = true;
|
|
10054
|
+
console.warn(`[rig-agent] Unknown RIG_RUNTIME_ADAPTER value "${value}"; falling back to claude-code. Use pi|claude-code|codex.`);
|
|
10055
|
+
}
|
|
9987
10056
|
return "claude-code";
|
|
9988
10057
|
}
|
|
9989
10058
|
function hasCliOption(argv, option) {
|
|
@@ -10036,8 +10105,8 @@ function resolveFromShellPath(binary) {
|
|
|
10036
10105
|
function resolveBundledPiBinary() {
|
|
10037
10106
|
try {
|
|
10038
10107
|
const packageJson = requireFromRuntime.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
10039
|
-
const binaryPath =
|
|
10040
|
-
return
|
|
10108
|
+
const binaryPath = resolve37(packageJson, "..", "dist", "cli.js");
|
|
10109
|
+
return existsSync35(binaryPath) ? binaryPath : null;
|
|
10041
10110
|
} catch {
|
|
10042
10111
|
return null;
|
|
10043
10112
|
}
|
|
@@ -10073,7 +10142,7 @@ async function waitForDirtyBaselineReady(runtime, taskId) {
|
|
|
10073
10142
|
workspaceDir: runtime.workspaceDir,
|
|
10074
10143
|
readyFile
|
|
10075
10144
|
});
|
|
10076
|
-
while (!
|
|
10145
|
+
while (!existsSync35(readyFile)) {
|
|
10077
10146
|
if (Date.now() >= deadline) {
|
|
10078
10147
|
throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
|
|
10079
10148
|
}
|
|
@@ -10176,9 +10245,9 @@ async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
|
|
|
10176
10245
|
}
|
|
10177
10246
|
}
|
|
10178
10247
|
function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
10179
|
-
const handoffDir =
|
|
10180
|
-
|
|
10181
|
-
const handoffPath =
|
|
10248
|
+
const handoffDir = resolve37(hostProjectRoot, ".rig/runtime/handoffs");
|
|
10249
|
+
mkdirSync21(handoffDir, { recursive: true });
|
|
10250
|
+
const handoffPath = resolve37(handoffDir, `${taskId}-${Date.now()}.json`);
|
|
10182
10251
|
const handoff = {
|
|
10183
10252
|
taskId,
|
|
10184
10253
|
runtimeId: runtime.id,
|
|
@@ -10194,7 +10263,7 @@ function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
|
10194
10263
|
`rig git open-pr --task ${taskId}`
|
|
10195
10264
|
]
|
|
10196
10265
|
};
|
|
10197
|
-
|
|
10266
|
+
writeFileSync14(handoffPath, `${JSON.stringify(handoff, null, 2)}
|
|
10198
10267
|
`, "utf-8");
|
|
10199
10268
|
console.log(`[rig-agent] Completion verification paused for ${taskId}.`);
|
|
10200
10269
|
console.log(`[rig-agent] Runtime handoff saved: ${handoffPath}`);
|
|
@@ -10244,13 +10313,13 @@ async function readTaskMetadata2(taskRoot, taskId) {
|
|
|
10244
10313
|
async function readTaskConfigHints(taskRoot, taskId) {
|
|
10245
10314
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
10246
10315
|
const candidates = [
|
|
10247
|
-
runtimeContext?.monorepoMainRoot ?
|
|
10248
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
10249
|
-
|
|
10250
|
-
|
|
10316
|
+
runtimeContext?.monorepoMainRoot ? resolve37(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
10317
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve37(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
10318
|
+
resolve37(taskRoot, ".rig", "task-config.json"),
|
|
10319
|
+
resolve37(taskRoot, "rig", "task-config.json")
|
|
10251
10320
|
].filter(Boolean);
|
|
10252
10321
|
for (const configPath of candidates) {
|
|
10253
|
-
if (!
|
|
10322
|
+
if (!existsSync35(configPath)) {
|
|
10254
10323
|
continue;
|
|
10255
10324
|
}
|
|
10256
10325
|
try {
|