@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
|
@@ -149,32 +149,32 @@ var RIG_DEFINITION_DIRNAME = "rig", RIG_ARTIFACTS_DIRNAME = "artifacts";
|
|
|
149
149
|
var init_layout = () => {};
|
|
150
150
|
|
|
151
151
|
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
152
|
-
import { existsSync as
|
|
153
|
-
import { resolve as
|
|
152
|
+
import { existsSync as existsSync21, readdirSync as readdirSync4, realpathSync } from "fs";
|
|
153
|
+
import { resolve as resolve22 } from "path";
|
|
154
154
|
function toRealPath(path) {
|
|
155
|
-
if (!
|
|
156
|
-
return
|
|
155
|
+
if (!existsSync21(path)) {
|
|
156
|
+
return resolve22(path);
|
|
157
157
|
}
|
|
158
158
|
try {
|
|
159
159
|
return realpathSync.native(path);
|
|
160
160
|
} catch {
|
|
161
|
-
return
|
|
161
|
+
return resolve22(path);
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
165
165
|
const candidates = new Set;
|
|
166
166
|
const addPath = (candidate) => {
|
|
167
|
-
if (
|
|
167
|
+
if (existsSync21(candidate)) {
|
|
168
168
|
candidates.add(toRealPath(candidate));
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
|
-
addPath(
|
|
172
|
-
addPath(
|
|
171
|
+
addPath(resolve22(projectRoot, ".git"));
|
|
172
|
+
addPath(resolve22(workspaceDir, "..", "..", ".git"));
|
|
173
173
|
for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
|
|
174
|
-
addPath(
|
|
174
|
+
addPath(resolve22(repoRoot, ".git"));
|
|
175
175
|
}
|
|
176
|
-
const workspaceGit =
|
|
177
|
-
if (
|
|
176
|
+
const workspaceGit = resolve22(workspaceDir, ".git");
|
|
177
|
+
if (existsSync21(workspaceGit)) {
|
|
178
178
|
addPath(workspaceGit);
|
|
179
179
|
}
|
|
180
180
|
return [...candidates];
|
|
@@ -182,7 +182,7 @@ function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
|
182
182
|
function resolveHostRepoRootPaths(projectRoot) {
|
|
183
183
|
const candidates = new Set;
|
|
184
184
|
const addPath = (candidate) => {
|
|
185
|
-
if (
|
|
185
|
+
if (existsSync21(candidate)) {
|
|
186
186
|
candidates.add(toRealPath(candidate));
|
|
187
187
|
}
|
|
188
188
|
};
|
|
@@ -192,11 +192,11 @@ function resolveHostRepoRootPaths(projectRoot) {
|
|
|
192
192
|
addPath(monorepoRoot);
|
|
193
193
|
}
|
|
194
194
|
} catch {}
|
|
195
|
-
const reposDir =
|
|
196
|
-
if (
|
|
197
|
-
for (const entry of
|
|
195
|
+
const reposDir = resolve22(projectRoot, "repos");
|
|
196
|
+
if (existsSync21(reposDir)) {
|
|
197
|
+
for (const entry of readdirSync4(reposDir, { withFileTypes: true })) {
|
|
198
198
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
199
|
-
addPath(
|
|
199
|
+
addPath(resolve22(reposDir, entry.name));
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
}
|
|
@@ -240,8 +240,8 @@ var exports_backend_seatbelt = {};
|
|
|
240
240
|
__export(exports_backend_seatbelt, {
|
|
241
241
|
SeatbeltBackend: () => SeatbeltBackend
|
|
242
242
|
});
|
|
243
|
-
import { mkdirSync as
|
|
244
|
-
import { resolve as
|
|
243
|
+
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync12 } from "fs";
|
|
244
|
+
import { resolve as resolve33 } from "path";
|
|
245
245
|
|
|
246
246
|
class SeatbeltBackend {
|
|
247
247
|
kind = "macos-seatbelt";
|
|
@@ -265,11 +265,11 @@ class SeatbeltBackend {
|
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
writeSeatbeltProfile(options) {
|
|
268
|
-
const sandboxDir =
|
|
269
|
-
|
|
270
|
-
const profilePath =
|
|
268
|
+
const sandboxDir = resolve33(options.runtime.rootDir, "sandbox");
|
|
269
|
+
mkdirSync17(sandboxDir, { recursive: true });
|
|
270
|
+
const profilePath = resolve33(sandboxDir, "seatbelt.sb");
|
|
271
271
|
const profile = this.renderProfile(options);
|
|
272
|
-
|
|
272
|
+
writeFileSync12(profilePath, `${profile}
|
|
273
273
|
`, "utf-8");
|
|
274
274
|
return profilePath;
|
|
275
275
|
}
|
|
@@ -354,7 +354,7 @@ class SeatbeltBackend {
|
|
|
354
354
|
const realHome = process.env.HOME?.trim();
|
|
355
355
|
if (realHome) {
|
|
356
356
|
for (const binSubdir of [".local/bin", ".cargo/bin"]) {
|
|
357
|
-
const binPath =
|
|
357
|
+
const binPath = resolve33(realHome, binSubdir);
|
|
358
358
|
if (ctx.pathExists(binPath)) {
|
|
359
359
|
lines.push(`(allow file-read* (subpath ${seatbeltString(ctx.realPath(binPath))}))`);
|
|
360
360
|
}
|
|
@@ -383,8 +383,8 @@ var exports_backend_bwrap = {};
|
|
|
383
383
|
__export(exports_backend_bwrap, {
|
|
384
384
|
BwrapBackend: () => BwrapBackend
|
|
385
385
|
});
|
|
386
|
-
import { mkdirSync as
|
|
387
|
-
import { resolve as
|
|
386
|
+
import { mkdirSync as mkdirSync18 } from "fs";
|
|
387
|
+
import { resolve as resolve34 } from "path";
|
|
388
388
|
|
|
389
389
|
class BwrapBackend {
|
|
390
390
|
kind = "linux-bwrap";
|
|
@@ -513,18 +513,18 @@ class BwrapBackend {
|
|
|
513
513
|
const realHome = process.env.HOME?.trim();
|
|
514
514
|
if (realHome) {
|
|
515
515
|
for (const binSubdir of [".local/bin", ".local/lib", ".cargo/bin"]) {
|
|
516
|
-
const binPath = ctx.realPath(
|
|
516
|
+
const binPath = ctx.realPath(resolve34(realHome, binSubdir));
|
|
517
517
|
if (ctx.pathExists(binPath)) {
|
|
518
518
|
args.push("--ro-bind", binPath, binPath);
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
|
-
const agentSshDir =
|
|
521
|
+
const agentSshDir = resolve34(homeReal, ".ssh");
|
|
522
522
|
if (ctx.pathExists(agentSshDir)) {
|
|
523
523
|
args.push("--ro-bind", agentSshDir, agentSshDir);
|
|
524
524
|
} else {
|
|
525
|
-
const hostSshDir =
|
|
525
|
+
const hostSshDir = resolve34(realHome, ".ssh");
|
|
526
526
|
if (ctx.pathExists(hostSshDir)) {
|
|
527
|
-
|
|
527
|
+
mkdirSync18(agentSshDir, { recursive: true });
|
|
528
528
|
args.push("--ro-bind", hostSshDir, agentSshDir);
|
|
529
529
|
args.push("--ro-bind", hostSshDir, hostSshDir);
|
|
530
530
|
}
|
|
@@ -567,8 +567,8 @@ var init_backend_bwrap = __esm(() => {
|
|
|
567
567
|
|
|
568
568
|
// packages/runtime/src/control-plane/runtime/queue.ts
|
|
569
569
|
init_layout();
|
|
570
|
-
import { existsSync as
|
|
571
|
-
import { resolve as
|
|
570
|
+
import { existsSync as existsSync34 } from "fs";
|
|
571
|
+
import { resolve as resolve37 } from "path";
|
|
572
572
|
|
|
573
573
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
574
574
|
import { existsSync as existsSync9, readFileSync as readFileSync5, readdirSync, statSync as statSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -3029,9 +3029,9 @@ function primeGuardHotPaths() {
|
|
|
3029
3029
|
}
|
|
3030
3030
|
primeGuardHotPaths();
|
|
3031
3031
|
// packages/runtime/src/control-plane/runtime/isolation/index.ts
|
|
3032
|
-
import { existsSync as
|
|
3032
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync19, readFileSync as readFileSync16, rmSync as rmSync13 } from "fs";
|
|
3033
3033
|
import { copyFile, mkdir as mkdir4, writeFile as writeFile2 } from "fs/promises";
|
|
3034
|
-
import { resolve as
|
|
3034
|
+
import { resolve as resolve36 } from "path";
|
|
3035
3035
|
// packages/runtime/src/control-plane/memory-sync/db.ts
|
|
3036
3036
|
import { Database } from "bun:sqlite";
|
|
3037
3037
|
import { mkdirSync as mkdirSync4 } from "fs";
|
|
@@ -3319,8 +3319,8 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
|
|
|
3319
3319
|
var DEFAULT_RESULT_LIMIT = DEFAULT_RUNTIME_MEMORY_RETRIEVAL.topK;
|
|
3320
3320
|
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
3321
3321
|
// packages/runtime/src/control-plane/native/task-ops.ts
|
|
3322
|
-
import { appendFileSync, existsSync as
|
|
3323
|
-
import { resolve as
|
|
3322
|
+
import { appendFileSync, existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
|
|
3323
|
+
import { resolve as resolve26 } from "path";
|
|
3324
3324
|
|
|
3325
3325
|
// packages/runtime/src/build-time-config.ts
|
|
3326
3326
|
function normalizeBuildConfig(value) {
|
|
@@ -4122,6 +4122,49 @@ function safeReadJson(path) {
|
|
|
4122
4122
|
}
|
|
4123
4123
|
}
|
|
4124
4124
|
|
|
4125
|
+
// packages/runtime/src/control-plane/skill-materializer.ts
|
|
4126
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync8, readFileSync as readFileSync8, readdirSync as readdirSync2, rmSync as rmSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
4127
|
+
import { resolve as resolve18 } from "path";
|
|
4128
|
+
import { loadSkill } from "@rig/skill-loader";
|
|
4129
|
+
var MARKER_FILENAME = ".rig-plugin";
|
|
4130
|
+
function skillDirName(id) {
|
|
4131
|
+
return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
4132
|
+
}
|
|
4133
|
+
async function materializeSkills(projectRoot, entries) {
|
|
4134
|
+
const skillsRoot = resolve18(projectRoot, ".pi", "skills");
|
|
4135
|
+
if (existsSync17(skillsRoot)) {
|
|
4136
|
+
for (const name of readdirSync2(skillsRoot)) {
|
|
4137
|
+
const dir = resolve18(skillsRoot, name);
|
|
4138
|
+
if (existsSync17(resolve18(dir, MARKER_FILENAME))) {
|
|
4139
|
+
rmSync7(dir, { recursive: true, force: true });
|
|
4140
|
+
}
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
const written = [];
|
|
4144
|
+
for (const { pluginName, skill } of entries) {
|
|
4145
|
+
const sourcePath = resolve18(projectRoot, skill.path);
|
|
4146
|
+
if (!existsSync17(sourcePath)) {
|
|
4147
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
|
|
4148
|
+
continue;
|
|
4149
|
+
}
|
|
4150
|
+
let body;
|
|
4151
|
+
try {
|
|
4152
|
+
await loadSkill(sourcePath);
|
|
4153
|
+
body = readFileSync8(sourcePath, "utf-8");
|
|
4154
|
+
} catch (err) {
|
|
4155
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
|
|
4156
|
+
continue;
|
|
4157
|
+
}
|
|
4158
|
+
const dir = resolve18(skillsRoot, skillDirName(skill.id));
|
|
4159
|
+
mkdirSync8(dir, { recursive: true });
|
|
4160
|
+
writeFileSync6(resolve18(dir, "SKILL.md"), body, "utf-8");
|
|
4161
|
+
writeFileSync6(resolve18(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
|
|
4162
|
+
`, "utf-8");
|
|
4163
|
+
written.push({ id: skill.id, pluginName, directory: dir });
|
|
4164
|
+
}
|
|
4165
|
+
return written;
|
|
4166
|
+
}
|
|
4167
|
+
|
|
4125
4168
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
4126
4169
|
async function buildPluginHostContext(projectRoot) {
|
|
4127
4170
|
let config;
|
|
@@ -4158,6 +4201,17 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
4158
4201
|
} catch (err) {
|
|
4159
4202
|
console.warn(`[plugin-host] hook materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
4160
4203
|
}
|
|
4204
|
+
try {
|
|
4205
|
+
const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
|
|
4206
|
+
pluginName: plugin.name,
|
|
4207
|
+
skill
|
|
4208
|
+
})));
|
|
4209
|
+
if (skillEntries.length > 0) {
|
|
4210
|
+
await materializeSkills(projectRoot, skillEntries);
|
|
4211
|
+
}
|
|
4212
|
+
} catch (err) {
|
|
4213
|
+
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
4214
|
+
}
|
|
4161
4215
|
return {
|
|
4162
4216
|
config,
|
|
4163
4217
|
pluginHost,
|
|
@@ -4171,12 +4225,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
4171
4225
|
|
|
4172
4226
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
4173
4227
|
import { spawnSync } from "child_process";
|
|
4174
|
-
import { existsSync as
|
|
4175
|
-
import { basename as basename6, join as join4, resolve as
|
|
4228
|
+
import { existsSync as existsSync19, readFileSync as readFileSync10, readdirSync as readdirSync3, statSync as statSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
4229
|
+
import { basename as basename6, join as join4, resolve as resolve20 } from "path";
|
|
4176
4230
|
|
|
4177
4231
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
4178
|
-
import { existsSync as
|
|
4179
|
-
import { resolve as
|
|
4232
|
+
import { existsSync as existsSync18, readFileSync as readFileSync9 } from "fs";
|
|
4233
|
+
import { resolve as resolve19 } from "path";
|
|
4180
4234
|
|
|
4181
4235
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
4182
4236
|
async function findTaskById(reader, id) {
|
|
@@ -4199,7 +4253,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
4199
4253
|
}
|
|
4200
4254
|
}
|
|
4201
4255
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
4202
|
-
const configPath = options.configPath ??
|
|
4256
|
+
const configPath = options.configPath ?? resolve19(projectRoot, ".rig", "task-config.json");
|
|
4203
4257
|
const reader = {
|
|
4204
4258
|
async listTasks() {
|
|
4205
4259
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -4210,8 +4264,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
4210
4264
|
};
|
|
4211
4265
|
return reader;
|
|
4212
4266
|
}
|
|
4213
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
4214
|
-
if (!
|
|
4267
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve19(projectRoot, ".rig", "task-config.json")) {
|
|
4268
|
+
if (!existsSync18(configPath)) {
|
|
4215
4269
|
return [];
|
|
4216
4270
|
}
|
|
4217
4271
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -4219,7 +4273,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve18(projectRoot,
|
|
|
4219
4273
|
}
|
|
4220
4274
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
4221
4275
|
try {
|
|
4222
|
-
const parsed = JSON.parse(
|
|
4276
|
+
const parsed = JSON.parse(readFileSync9(configPath, "utf8"));
|
|
4223
4277
|
if (isPlainRecord(parsed)) {
|
|
4224
4278
|
return parsed;
|
|
4225
4279
|
}
|
|
@@ -4303,7 +4357,7 @@ function isPlainRecord(candidate) {
|
|
|
4303
4357
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
4304
4358
|
var FILE_TASK_PATTERN2 = /\.(task\.)?json$/;
|
|
4305
4359
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
4306
|
-
const configPath = options.configPath ??
|
|
4360
|
+
const configPath = options.configPath ?? resolve20(projectRoot, ".rig", "task-config.json");
|
|
4307
4361
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
4308
4362
|
const spawnFn = options.spawn ?? spawnSync;
|
|
4309
4363
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -4386,10 +4440,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
4386
4440
|
return metadata;
|
|
4387
4441
|
}
|
|
4388
4442
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
4389
|
-
const jsonPath =
|
|
4390
|
-
if (
|
|
4443
|
+
const jsonPath = resolve20(projectRoot, "rig.config.json");
|
|
4444
|
+
if (existsSync19(jsonPath)) {
|
|
4391
4445
|
try {
|
|
4392
|
-
const parsed = JSON.parse(
|
|
4446
|
+
const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
|
|
4393
4447
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
4394
4448
|
const source = parsed.taskSource;
|
|
4395
4449
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -4398,12 +4452,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
4398
4452
|
return null;
|
|
4399
4453
|
}
|
|
4400
4454
|
}
|
|
4401
|
-
const tsPath =
|
|
4402
|
-
if (!
|
|
4455
|
+
const tsPath = resolve20(projectRoot, "rig.config.ts");
|
|
4456
|
+
if (!existsSync19(tsPath)) {
|
|
4403
4457
|
return null;
|
|
4404
4458
|
}
|
|
4405
4459
|
try {
|
|
4406
|
-
const source =
|
|
4460
|
+
const source = readFileSync10(tsPath, "utf8");
|
|
4407
4461
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
4408
4462
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
4409
4463
|
if (kind !== "files") {
|
|
@@ -4423,10 +4477,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
4423
4477
|
return isPlainRecord2(entry) ? entry : null;
|
|
4424
4478
|
}
|
|
4425
4479
|
function readRawTaskConfig(configPath) {
|
|
4426
|
-
if (!
|
|
4480
|
+
if (!existsSync19(configPath)) {
|
|
4427
4481
|
return null;
|
|
4428
4482
|
}
|
|
4429
|
-
const parsed = JSON.parse(
|
|
4483
|
+
const parsed = JSON.parse(readFileSync10(configPath, "utf8"));
|
|
4430
4484
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
4431
4485
|
}
|
|
4432
4486
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -4434,12 +4488,12 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
4434
4488
|
return tasks;
|
|
4435
4489
|
}
|
|
4436
4490
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
4437
|
-
const directory =
|
|
4438
|
-
if (!
|
|
4491
|
+
const directory = resolve20(projectRoot, sourcePath);
|
|
4492
|
+
if (!existsSync19(directory)) {
|
|
4439
4493
|
return [];
|
|
4440
4494
|
}
|
|
4441
4495
|
const tasks = [];
|
|
4442
|
-
for (const name of
|
|
4496
|
+
for (const name of readdirSync3(directory)) {
|
|
4443
4497
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
4444
4498
|
continue;
|
|
4445
4499
|
const inferredId = basename6(name).replace(FILE_TASK_PATTERN2, "");
|
|
@@ -4450,11 +4504,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
4450
4504
|
return tasks;
|
|
4451
4505
|
}
|
|
4452
4506
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
4453
|
-
const file = findFileBackedTaskFile(
|
|
4507
|
+
const file = findFileBackedTaskFile(resolve20(projectRoot, sourcePath), taskId);
|
|
4454
4508
|
if (!file) {
|
|
4455
4509
|
return null;
|
|
4456
4510
|
}
|
|
4457
|
-
const raw = JSON.parse(
|
|
4511
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
4458
4512
|
if (!isPlainRecord2(raw)) {
|
|
4459
4513
|
return null;
|
|
4460
4514
|
}
|
|
@@ -4467,17 +4521,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
4467
4521
|
};
|
|
4468
4522
|
}
|
|
4469
4523
|
function findFileBackedTaskFile(directory, taskId) {
|
|
4470
|
-
if (!
|
|
4524
|
+
if (!existsSync19(directory)) {
|
|
4471
4525
|
return null;
|
|
4472
4526
|
}
|
|
4473
|
-
for (const name of
|
|
4527
|
+
for (const name of readdirSync3(directory)) {
|
|
4474
4528
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
4475
4529
|
continue;
|
|
4476
4530
|
const file = join4(directory, name);
|
|
4477
4531
|
try {
|
|
4478
4532
|
if (!statSync5(file).isFile())
|
|
4479
4533
|
continue;
|
|
4480
|
-
const raw = JSON.parse(
|
|
4534
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
4481
4535
|
const inferredId = basename6(file).replace(FILE_TASK_PATTERN2, "");
|
|
4482
4536
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
4483
4537
|
if (id === taskId) {
|
|
@@ -4641,8 +4695,8 @@ init_layout();
|
|
|
4641
4695
|
|
|
4642
4696
|
// packages/runtime/src/binary-run.ts
|
|
4643
4697
|
init_layout();
|
|
4644
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
4645
|
-
import { basename as basename7, dirname as dirname11, resolve as
|
|
4698
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync20, mkdirSync as mkdirSync9, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
4699
|
+
import { basename as basename7, dirname as dirname11, resolve as resolve21 } from "path";
|
|
4646
4700
|
import { fileURLToPath } from "url";
|
|
4647
4701
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
4648
4702
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -4668,9 +4722,9 @@ async function buildRuntimeBinary(options) {
|
|
|
4668
4722
|
});
|
|
4669
4723
|
}
|
|
4670
4724
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
4671
|
-
const tempBuildDir =
|
|
4672
|
-
const tempOutputPath =
|
|
4673
|
-
|
|
4725
|
+
const tempBuildDir = resolve21(dirname11(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4726
|
+
const tempOutputPath = resolve21(tempBuildDir, basename7(options.outputPath));
|
|
4727
|
+
mkdirSync9(tempBuildDir, { recursive: true });
|
|
4674
4728
|
await withTemporaryEnv({
|
|
4675
4729
|
...options.env,
|
|
4676
4730
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -4695,7 +4749,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4695
4749
|
`);
|
|
4696
4750
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
4697
4751
|
}
|
|
4698
|
-
if (!
|
|
4752
|
+
if (!existsSync20(tempOutputPath)) {
|
|
4699
4753
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
4700
4754
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
4701
4755
|
}
|
|
@@ -4710,7 +4764,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4710
4764
|
});
|
|
4711
4765
|
}
|
|
4712
4766
|
})).finally(() => {
|
|
4713
|
-
|
|
4767
|
+
rmSync8(tempBuildDir, { recursive: true, force: true });
|
|
4714
4768
|
});
|
|
4715
4769
|
}
|
|
4716
4770
|
function runBestEffortBuildGc() {
|
|
@@ -4727,8 +4781,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4727
4781
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4728
4782
|
return {
|
|
4729
4783
|
...options,
|
|
4730
|
-
entrypoint:
|
|
4731
|
-
outputPath:
|
|
4784
|
+
entrypoint: resolve21(options.cwd, options.sourcePath),
|
|
4785
|
+
outputPath: resolve21(options.outputPath)
|
|
4732
4786
|
};
|
|
4733
4787
|
}
|
|
4734
4788
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4742,7 +4796,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4742
4796
|
}
|
|
4743
4797
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4744
4798
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4745
|
-
if (!workerSourcePath || !
|
|
4799
|
+
if (!workerSourcePath || !existsSync20(workerSourcePath)) {
|
|
4746
4800
|
await buildRuntimeBinaryInProcess(options, {
|
|
4747
4801
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4748
4802
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4773,13 +4827,13 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4773
4827
|
new Response(build.stdout).text(),
|
|
4774
4828
|
new Response(build.stderr).text()
|
|
4775
4829
|
]);
|
|
4776
|
-
|
|
4830
|
+
rmSync8(payloadPath, { force: true });
|
|
4777
4831
|
if (exitCode !== 0) {
|
|
4778
4832
|
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
4779
4833
|
}
|
|
4780
4834
|
}
|
|
4781
4835
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4782
|
-
return
|
|
4836
|
+
return resolve21(dirname11(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4783
4837
|
}
|
|
4784
4838
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4785
4839
|
const envRoots = [
|
|
@@ -4788,13 +4842,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4788
4842
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4789
4843
|
].filter(Boolean);
|
|
4790
4844
|
for (const root of envRoots) {
|
|
4791
|
-
const candidate =
|
|
4792
|
-
if (
|
|
4845
|
+
const candidate = resolve21(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4846
|
+
if (existsSync20(candidate)) {
|
|
4793
4847
|
return candidate;
|
|
4794
4848
|
}
|
|
4795
4849
|
}
|
|
4796
|
-
const localCandidate =
|
|
4797
|
-
return
|
|
4850
|
+
const localCandidate = resolve21(import.meta.dir, "binary-build-worker.ts");
|
|
4851
|
+
return existsSync20(localCandidate) ? localCandidate : null;
|
|
4798
4852
|
}
|
|
4799
4853
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4800
4854
|
const bunPath = Bun.which("bun");
|
|
@@ -4830,7 +4884,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4830
4884
|
});
|
|
4831
4885
|
}
|
|
4832
4886
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4833
|
-
if (!
|
|
4887
|
+
if (!existsSync20(input.outputPath) || !existsSync20(input.manifestPath)) {
|
|
4834
4888
|
return false;
|
|
4835
4889
|
}
|
|
4836
4890
|
let manifest = null;
|
|
@@ -4843,7 +4897,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4843
4897
|
return false;
|
|
4844
4898
|
}
|
|
4845
4899
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4846
|
-
if (!
|
|
4900
|
+
if (!existsSync20(filePath)) {
|
|
4847
4901
|
return false;
|
|
4848
4902
|
}
|
|
4849
4903
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4856,7 +4910,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4856
4910
|
const inputs = {};
|
|
4857
4911
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4858
4912
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4859
|
-
if (!normalized || !
|
|
4913
|
+
if (!normalized || !existsSync20(normalized)) {
|
|
4860
4914
|
continue;
|
|
4861
4915
|
}
|
|
4862
4916
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4879,7 +4933,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4879
4933
|
if (inputPath.startsWith("<")) {
|
|
4880
4934
|
return null;
|
|
4881
4935
|
}
|
|
4882
|
-
return
|
|
4936
|
+
return resolve21(cwd, inputPath);
|
|
4883
4937
|
}
|
|
4884
4938
|
async function sha256File4(path) {
|
|
4885
4939
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4895,8 +4949,8 @@ function sortRecord(value) {
|
|
|
4895
4949
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4896
4950
|
const previous = runtimeBinaryBuildQueue;
|
|
4897
4951
|
let release;
|
|
4898
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4899
|
-
release =
|
|
4952
|
+
runtimeBinaryBuildQueue = new Promise((resolve22) => {
|
|
4953
|
+
release = resolve22;
|
|
4900
4954
|
});
|
|
4901
4955
|
await previous;
|
|
4902
4956
|
try {
|
|
@@ -4941,11 +4995,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4941
4995
|
}
|
|
4942
4996
|
|
|
4943
4997
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4944
|
-
import { delimiter, resolve as
|
|
4998
|
+
import { delimiter, resolve as resolve24 } from "path";
|
|
4945
4999
|
|
|
4946
5000
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
4947
|
-
import { existsSync as
|
|
4948
|
-
import { resolve as
|
|
5001
|
+
import { existsSync as existsSync22, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
5002
|
+
import { resolve as resolve23 } from "path";
|
|
4949
5003
|
|
|
4950
5004
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
4951
5005
|
init_utils();
|
|
@@ -4962,7 +5016,7 @@ function resolveBunBinaryPath() {
|
|
|
4962
5016
|
}
|
|
4963
5017
|
const home = process.env.HOME?.trim();
|
|
4964
5018
|
const fallbackCandidates = [
|
|
4965
|
-
home ?
|
|
5019
|
+
home ? resolve23(home, ".bun/bin/bun") : "",
|
|
4966
5020
|
"/opt/homebrew/bin/bun",
|
|
4967
5021
|
"/usr/local/bin/bun",
|
|
4968
5022
|
"/usr/bin/bun"
|
|
@@ -4990,8 +5044,8 @@ function resolveClaudeBinaryPath() {
|
|
|
4990
5044
|
}
|
|
4991
5045
|
const home = process.env.HOME?.trim();
|
|
4992
5046
|
const fallbackCandidates = [
|
|
4993
|
-
home ?
|
|
4994
|
-
home ?
|
|
5047
|
+
home ? resolve23(home, ".local/bin/claude") : "",
|
|
5048
|
+
home ? resolve23(home, ".local/share/claude/local/claude") : "",
|
|
4995
5049
|
"/opt/homebrew/bin/claude",
|
|
4996
5050
|
"/usr/local/bin/claude",
|
|
4997
5051
|
"/usr/bin/claude"
|
|
@@ -5005,35 +5059,35 @@ function resolveClaudeBinaryPath() {
|
|
|
5005
5059
|
throw new Error("claude not found in PATH");
|
|
5006
5060
|
}
|
|
5007
5061
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
5008
|
-
return
|
|
5062
|
+
return resolve23(bunBinaryPath, "../..");
|
|
5009
5063
|
}
|
|
5010
5064
|
function resolveClaudeInstallDir() {
|
|
5011
5065
|
const realPath = resolveClaudeBinaryPath();
|
|
5012
|
-
return
|
|
5066
|
+
return resolve23(realPath, "..");
|
|
5013
5067
|
}
|
|
5014
5068
|
function resolveNodeInstallDir() {
|
|
5015
5069
|
const preferredNode = resolvePreferredNodeBinary();
|
|
5016
5070
|
if (!preferredNode)
|
|
5017
5071
|
return null;
|
|
5018
5072
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
5019
|
-
if (explicitNode &&
|
|
5020
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
5073
|
+
if (explicitNode && resolve23(explicitNode) === resolve23(preferredNode)) {
|
|
5074
|
+
return preferredNode.endsWith("/bin/node") ? resolve23(preferredNode, "../..") : resolve23(preferredNode, "..");
|
|
5021
5075
|
}
|
|
5022
5076
|
try {
|
|
5023
5077
|
const realPath = realpathSync2(preferredNode);
|
|
5024
5078
|
if (realPath.endsWith("/bin/node")) {
|
|
5025
|
-
return
|
|
5079
|
+
return resolve23(realPath, "../..");
|
|
5026
5080
|
}
|
|
5027
|
-
return
|
|
5081
|
+
return resolve23(realPath, "..");
|
|
5028
5082
|
} catch {
|
|
5029
|
-
return
|
|
5083
|
+
return resolve23(preferredNode, "..");
|
|
5030
5084
|
}
|
|
5031
5085
|
}
|
|
5032
5086
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
5033
5087
|
const roots = [];
|
|
5034
5088
|
if (process.platform === "darwin") {
|
|
5035
5089
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
5036
|
-
if (
|
|
5090
|
+
if (existsSync22(macPath)) {
|
|
5037
5091
|
roots.push(macPath);
|
|
5038
5092
|
}
|
|
5039
5093
|
}
|
|
@@ -5051,23 +5105,23 @@ function resolvePreferredNodeBinary() {
|
|
|
5051
5105
|
const candidates = [];
|
|
5052
5106
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
5053
5107
|
if (envNode) {
|
|
5054
|
-
const explicit =
|
|
5055
|
-
if (
|
|
5108
|
+
const explicit = resolve23(envNode);
|
|
5109
|
+
if (existsSync22(explicit)) {
|
|
5056
5110
|
return explicit;
|
|
5057
5111
|
}
|
|
5058
5112
|
}
|
|
5059
5113
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
5060
5114
|
if (nvmBin) {
|
|
5061
|
-
candidates.push(
|
|
5115
|
+
candidates.push(resolve23(nvmBin, "node"));
|
|
5062
5116
|
}
|
|
5063
5117
|
const home = process.env.HOME?.trim();
|
|
5064
5118
|
if (home) {
|
|
5065
|
-
const nvmVersionsDir =
|
|
5066
|
-
if (
|
|
5119
|
+
const nvmVersionsDir = resolve23(home, ".nvm/versions/node");
|
|
5120
|
+
if (existsSync22(nvmVersionsDir)) {
|
|
5067
5121
|
try {
|
|
5068
|
-
const versionDirs =
|
|
5122
|
+
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/, "")));
|
|
5069
5123
|
for (const versionDir of versionDirs) {
|
|
5070
|
-
candidates.push(
|
|
5124
|
+
candidates.push(resolve23(nvmVersionsDir, versionDir, "bin/node"));
|
|
5071
5125
|
}
|
|
5072
5126
|
} catch {}
|
|
5073
5127
|
}
|
|
@@ -5076,8 +5130,8 @@ function resolvePreferredNodeBinary() {
|
|
|
5076
5130
|
if (whichNode) {
|
|
5077
5131
|
candidates.push(whichNode);
|
|
5078
5132
|
}
|
|
5079
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
5080
|
-
const existing = deduped.filter((candidate) =>
|
|
5133
|
+
const deduped = uniq(candidates.map((candidate) => resolve23(candidate)));
|
|
5134
|
+
const existing = deduped.filter((candidate) => existsSync22(candidate));
|
|
5081
5135
|
if (existing.length === 0) {
|
|
5082
5136
|
return null;
|
|
5083
5137
|
}
|
|
@@ -5091,7 +5145,7 @@ function resolvePreferredNodeBinary() {
|
|
|
5091
5145
|
return existing[0] ?? null;
|
|
5092
5146
|
}
|
|
5093
5147
|
function inferNodeMajor(nodeBinaryPath) {
|
|
5094
|
-
const normalized =
|
|
5148
|
+
const normalized = resolve23(nodeBinaryPath).replace(/\\/g, "/");
|
|
5095
5149
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
5096
5150
|
if (!match) {
|
|
5097
5151
|
return null;
|
|
@@ -5103,8 +5157,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
5103
5157
|
if (!candidate) {
|
|
5104
5158
|
return "";
|
|
5105
5159
|
}
|
|
5106
|
-
const normalized =
|
|
5107
|
-
if (!
|
|
5160
|
+
const normalized = resolve23(candidate);
|
|
5161
|
+
if (!existsSync22(normalized)) {
|
|
5108
5162
|
return "";
|
|
5109
5163
|
}
|
|
5110
5164
|
try {
|
|
@@ -5114,7 +5168,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
5114
5168
|
}
|
|
5115
5169
|
}
|
|
5116
5170
|
function looksLikeRuntimeGateway(candidate) {
|
|
5117
|
-
const normalized =
|
|
5171
|
+
const normalized = resolve23(candidate).replace(/\\/g, "/");
|
|
5118
5172
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
5119
5173
|
}
|
|
5120
5174
|
|
|
@@ -5135,7 +5189,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5135
5189
|
try {
|
|
5136
5190
|
return resolveClaudeInstallDir();
|
|
5137
5191
|
} catch {
|
|
5138
|
-
return
|
|
5192
|
+
return resolve24(claudeBinary, "..");
|
|
5139
5193
|
}
|
|
5140
5194
|
})() : "";
|
|
5141
5195
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -5145,8 +5199,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5145
5199
|
`${bunDir}/bin`,
|
|
5146
5200
|
claudeDir,
|
|
5147
5201
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
5148
|
-
realHome ?
|
|
5149
|
-
realHome ?
|
|
5202
|
+
realHome ? resolve24(realHome, ".local/bin") : "",
|
|
5203
|
+
realHome ? resolve24(realHome, ".cargo/bin") : "",
|
|
5150
5204
|
...inheritedPath,
|
|
5151
5205
|
"/usr/local/bin",
|
|
5152
5206
|
"/usr/local/sbin",
|
|
@@ -5175,8 +5229,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5175
5229
|
}
|
|
5176
5230
|
|
|
5177
5231
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
5178
|
-
import { existsSync as
|
|
5179
|
-
import { resolve as
|
|
5232
|
+
import { existsSync as existsSync23, readFileSync as readFileSync11 } from "fs";
|
|
5233
|
+
import { resolve as resolve25 } from "path";
|
|
5180
5234
|
var BAKED_RUNTIME_SECRETS = {
|
|
5181
5235
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
5182
5236
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -5219,12 +5273,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
5219
5273
|
return resolved;
|
|
5220
5274
|
}
|
|
5221
5275
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
5222
|
-
const dotenvPath =
|
|
5223
|
-
if (!
|
|
5276
|
+
const dotenvPath = resolve25(projectRoot, ".env");
|
|
5277
|
+
if (!existsSync23(dotenvPath)) {
|
|
5224
5278
|
return {};
|
|
5225
5279
|
}
|
|
5226
5280
|
const parsed = {};
|
|
5227
|
-
const lines =
|
|
5281
|
+
const lines = readFileSync11(dotenvPath, "utf-8").split(/\r?\n/);
|
|
5228
5282
|
for (const rawLine of lines) {
|
|
5229
5283
|
const line = rawLine.trim();
|
|
5230
5284
|
if (!line || line.startsWith("#")) {
|
|
@@ -5581,16 +5635,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
5581
5635
|
for (const dep of deps) {
|
|
5582
5636
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
5583
5637
|
console.log(`=== ${dep} ===`);
|
|
5584
|
-
if (!
|
|
5638
|
+
if (!existsSync24(artifactDir)) {
|
|
5585
5639
|
console.log(` (no artifacts yet)
|
|
5586
5640
|
`);
|
|
5587
5641
|
continue;
|
|
5588
5642
|
}
|
|
5589
|
-
printArtifactSection(
|
|
5590
|
-
printArtifactSection(
|
|
5591
|
-
const changedFiles =
|
|
5592
|
-
if (
|
|
5593
|
-
const lines =
|
|
5643
|
+
printArtifactSection(resolve26(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
5644
|
+
printArtifactSection(resolve26(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
5645
|
+
const changedFiles = resolve26(artifactDir, "changed-files.txt");
|
|
5646
|
+
if (existsSync24(changedFiles)) {
|
|
5647
|
+
const lines = readFileSync12(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
5594
5648
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
5595
5649
|
for (const line of lines) {
|
|
5596
5650
|
console.log(line);
|
|
@@ -5714,12 +5768,12 @@ function printIndented(text) {
|
|
|
5714
5768
|
}
|
|
5715
5769
|
}
|
|
5716
5770
|
function readLocalBeadsTasks(projectRoot) {
|
|
5717
|
-
const issuesPath =
|
|
5718
|
-
if (!
|
|
5771
|
+
const issuesPath = resolve26(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5772
|
+
if (!existsSync24(issuesPath)) {
|
|
5719
5773
|
return [];
|
|
5720
5774
|
}
|
|
5721
5775
|
const tasks = [];
|
|
5722
|
-
for (const line of
|
|
5776
|
+
for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
5723
5777
|
const trimmed = line.trim();
|
|
5724
5778
|
if (!trimmed) {
|
|
5725
5779
|
continue;
|
|
@@ -5832,11 +5886,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5832
5886
|
return [...ids].sort();
|
|
5833
5887
|
}
|
|
5834
5888
|
function printArtifactSection(path, header) {
|
|
5835
|
-
if (!
|
|
5889
|
+
if (!existsSync24(path)) {
|
|
5836
5890
|
return;
|
|
5837
5891
|
}
|
|
5838
5892
|
console.log(header);
|
|
5839
|
-
process.stdout.write(
|
|
5893
|
+
process.stdout.write(readFileSync12(path, "utf-8"));
|
|
5840
5894
|
console.log("");
|
|
5841
5895
|
}
|
|
5842
5896
|
|
|
@@ -5938,7 +5992,7 @@ init_layout();
|
|
|
5938
5992
|
|
|
5939
5993
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5940
5994
|
init_layout();
|
|
5941
|
-
import { mkdirSync as
|
|
5995
|
+
import { mkdirSync as mkdirSync11 } from "fs";
|
|
5942
5996
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5943
5997
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5944
5998
|
const rootDir = layout.rigRoot;
|
|
@@ -5950,14 +6004,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5950
6004
|
const sessionDir = layout.sessionDir;
|
|
5951
6005
|
const runtimeDir = layout.runtimeDir;
|
|
5952
6006
|
const contextPath = layout.contextPath;
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
6007
|
+
mkdirSync11(rootDir, { recursive: true });
|
|
6008
|
+
mkdirSync11(homeDir, { recursive: true });
|
|
6009
|
+
mkdirSync11(tmpDir, { recursive: true });
|
|
6010
|
+
mkdirSync11(cacheDir, { recursive: true });
|
|
6011
|
+
mkdirSync11(logsDir, { recursive: true });
|
|
6012
|
+
mkdirSync11(stateDir, { recursive: true });
|
|
6013
|
+
mkdirSync11(sessionDir, { recursive: true });
|
|
6014
|
+
mkdirSync11(runtimeDir, { recursive: true });
|
|
5961
6015
|
return {
|
|
5962
6016
|
rootDir,
|
|
5963
6017
|
homeDir,
|
|
@@ -5975,17 +6029,17 @@ import {
|
|
|
5975
6029
|
chmodSync as chmodSync5,
|
|
5976
6030
|
copyFileSync as copyFileSync5,
|
|
5977
6031
|
cpSync as cpSync2,
|
|
5978
|
-
existsSync as
|
|
5979
|
-
mkdirSync as
|
|
6032
|
+
existsSync as existsSync26,
|
|
6033
|
+
mkdirSync as mkdirSync12,
|
|
5980
6034
|
statSync as statSync6,
|
|
5981
|
-
writeFileSync as
|
|
6035
|
+
writeFileSync as writeFileSync10
|
|
5982
6036
|
} from "fs";
|
|
5983
6037
|
import { mkdir as mkdir2 } from "fs/promises";
|
|
5984
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
6038
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve28 } from "path";
|
|
5985
6039
|
|
|
5986
6040
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
5987
|
-
import { existsSync as
|
|
5988
|
-
import { resolve as
|
|
6041
|
+
import { existsSync as existsSync25, readFileSync as readFileSync13, rmSync as rmSync9 } from "fs";
|
|
6042
|
+
import { resolve as resolve27 } from "path";
|
|
5989
6043
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5990
6044
|
var generatedCredentialFiles = new Set;
|
|
5991
6045
|
var credentialCleanupRegistered = false;
|
|
@@ -6010,7 +6064,7 @@ function resolveHostGitBinary() {
|
|
|
6010
6064
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
6011
6065
|
continue;
|
|
6012
6066
|
}
|
|
6013
|
-
if (
|
|
6067
|
+
if (existsSync25(candidate)) {
|
|
6014
6068
|
return candidate;
|
|
6015
6069
|
}
|
|
6016
6070
|
}
|
|
@@ -6076,7 +6130,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
6076
6130
|
}
|
|
6077
6131
|
}
|
|
6078
6132
|
async function tryReadGitHead(repoRoot) {
|
|
6079
|
-
if (!
|
|
6133
|
+
if (!existsSync25(resolve27(repoRoot, ".git"))) {
|
|
6080
6134
|
return;
|
|
6081
6135
|
}
|
|
6082
6136
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -6087,7 +6141,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
6087
6141
|
return value || undefined;
|
|
6088
6142
|
}
|
|
6089
6143
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
6090
|
-
if (!
|
|
6144
|
+
if (!existsSync25(resolve27(repoRoot, ".git"))) {
|
|
6091
6145
|
return [];
|
|
6092
6146
|
}
|
|
6093
6147
|
const files = new Set;
|
|
@@ -6123,7 +6177,7 @@ function registerCredentialCleanup(path) {
|
|
|
6123
6177
|
const cleanup = () => {
|
|
6124
6178
|
for (const filePath of generatedCredentialFiles) {
|
|
6125
6179
|
try {
|
|
6126
|
-
|
|
6180
|
+
rmSync9(filePath, { force: true });
|
|
6127
6181
|
} catch {}
|
|
6128
6182
|
}
|
|
6129
6183
|
generatedCredentialFiles.clear();
|
|
@@ -6178,16 +6232,16 @@ function hashProjectPath(workspaceDir) {
|
|
|
6178
6232
|
}
|
|
6179
6233
|
function resolveGithubCliBinaryPath() {
|
|
6180
6234
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
6181
|
-
if (explicit &&
|
|
6235
|
+
if (explicit && existsSync25(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
6182
6236
|
return explicit;
|
|
6183
6237
|
}
|
|
6184
6238
|
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
6185
|
-
if (
|
|
6239
|
+
if (existsSync25(candidate)) {
|
|
6186
6240
|
return candidate;
|
|
6187
6241
|
}
|
|
6188
6242
|
}
|
|
6189
6243
|
const bunResolved = Bun.which("gh");
|
|
6190
|
-
if (bunResolved &&
|
|
6244
|
+
if (bunResolved && existsSync25(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
6191
6245
|
return bunResolved;
|
|
6192
6246
|
}
|
|
6193
6247
|
return "";
|
|
@@ -6221,17 +6275,17 @@ function resolveSystemCertBundlePath() {
|
|
|
6221
6275
|
"/opt/homebrew/etc/openssl@3/cert.pem"
|
|
6222
6276
|
];
|
|
6223
6277
|
for (const candidate of candidates) {
|
|
6224
|
-
if (candidate &&
|
|
6225
|
-
return
|
|
6278
|
+
if (candidate && existsSync25(candidate)) {
|
|
6279
|
+
return resolve27(candidate);
|
|
6226
6280
|
}
|
|
6227
6281
|
}
|
|
6228
6282
|
return "";
|
|
6229
6283
|
}
|
|
6230
6284
|
function readKnownHosts(path) {
|
|
6231
|
-
if (!
|
|
6285
|
+
if (!existsSync25(path)) {
|
|
6232
6286
|
return new Set;
|
|
6233
6287
|
}
|
|
6234
|
-
return new Set(
|
|
6288
|
+
return new Set(readFileSync13(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
6235
6289
|
}
|
|
6236
6290
|
|
|
6237
6291
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -6246,12 +6300,12 @@ function resolveControlPlaneSourceRoot(projectRoot) {
|
|
|
6246
6300
|
const candidates = [
|
|
6247
6301
|
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
6248
6302
|
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
6249
|
-
|
|
6303
|
+
resolve28(import.meta.dir, "../../../../.."),
|
|
6250
6304
|
projectRoot
|
|
6251
6305
|
].filter((value) => Boolean(value));
|
|
6252
6306
|
for (const candidate of candidates) {
|
|
6253
|
-
const root =
|
|
6254
|
-
if (
|
|
6307
|
+
const root = resolve28(candidate);
|
|
6308
|
+
if (existsSync26(resolve28(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
6255
6309
|
return root;
|
|
6256
6310
|
}
|
|
6257
6311
|
}
|
|
@@ -6271,7 +6325,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6271
6325
|
try {
|
|
6272
6326
|
return resolveClaudeInstallDir();
|
|
6273
6327
|
} catch {
|
|
6274
|
-
return
|
|
6328
|
+
return resolve28(claudeBinaryPath, "..");
|
|
6275
6329
|
}
|
|
6276
6330
|
})() : "";
|
|
6277
6331
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -6286,8 +6340,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6286
6340
|
`${bunDir}/bin`,
|
|
6287
6341
|
claudeDir,
|
|
6288
6342
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
6289
|
-
realHome ?
|
|
6290
|
-
realHome ?
|
|
6343
|
+
realHome ? resolve28(realHome, ".local/bin") : "",
|
|
6344
|
+
realHome ? resolve28(realHome, ".cargo/bin") : "",
|
|
6291
6345
|
...inheritedPath,
|
|
6292
6346
|
"/usr/local/bin",
|
|
6293
6347
|
"/usr/local/sbin",
|
|
@@ -6298,9 +6352,9 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6298
6352
|
"/usr/sbin",
|
|
6299
6353
|
"/sbin"
|
|
6300
6354
|
].filter(Boolean);
|
|
6301
|
-
const runtimeBash =
|
|
6302
|
-
const runtimeRigGit =
|
|
6303
|
-
const preferredShell =
|
|
6355
|
+
const runtimeBash = resolve28(runtime.binDir, "bash");
|
|
6356
|
+
const runtimeRigGit = resolve28(runtime.binDir, runtimeRigGitFileName());
|
|
6357
|
+
const preferredShell = existsSync26(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
6304
6358
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
6305
6359
|
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
6306
6360
|
const env = {
|
|
@@ -6321,30 +6375,30 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6321
6375
|
RIG_RUNTIME_MODE: runtime.mode,
|
|
6322
6376
|
RIG_RUNTIME_HOME: runtime.rootDir,
|
|
6323
6377
|
RIG_RUNTIME_BIN_DIR: runtime.binDir,
|
|
6324
|
-
...
|
|
6378
|
+
...existsSync26(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
|
|
6325
6379
|
RIG_BUN_PATH: bunBinaryPath,
|
|
6326
6380
|
...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
|
|
6327
|
-
RIG_AGENT_BIN:
|
|
6381
|
+
RIG_AGENT_BIN: resolve28(runtime.binDir, "rig-agent"),
|
|
6328
6382
|
RIG_HOOKS_ACTIVE: "1",
|
|
6329
6383
|
RIG_AUTO_PR_ON_COMPLETE: "1",
|
|
6330
|
-
RIG_POLICY_FILE:
|
|
6384
|
+
RIG_POLICY_FILE: resolve28(projectRoot, "rig/policy/policy.json"),
|
|
6331
6385
|
RIG_STATE_DIR: runtime.stateDir,
|
|
6332
6386
|
RIG_LOGS_DIR: runtime.logsDir,
|
|
6333
|
-
RIG_SESSION_FILE:
|
|
6387
|
+
RIG_SESSION_FILE: resolve28(runtime.sessionDir, "session.json"),
|
|
6334
6388
|
MONOREPO_ROOT: runtime.workspaceDir,
|
|
6335
6389
|
MONOREPO_MAIN_ROOT: monorepoMainRoot,
|
|
6336
|
-
TS_API_TESTS_DIR:
|
|
6390
|
+
TS_API_TESTS_DIR: resolve28(runtime.workspaceDir, "TSAPITests"),
|
|
6337
6391
|
BASH: preferredShell,
|
|
6338
6392
|
SHELL: preferredShell,
|
|
6339
6393
|
PATH: [...new Set(pathEntries)].join(delimiter2),
|
|
6340
6394
|
LANG: process.env.LANG ?? "en_US.UTF-8",
|
|
6341
6395
|
TERM: process.env.TERM ?? "xterm-256color",
|
|
6342
6396
|
PYTHONDONTWRITEBYTECODE: "1",
|
|
6343
|
-
PYTHONPYCACHEPREFIX:
|
|
6397
|
+
PYTHONPYCACHEPREFIX: resolve28(runtime.cacheDir, "python"),
|
|
6344
6398
|
...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
|
|
6345
6399
|
...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
|
|
6346
6400
|
CLAUDE_HOME: runtime.claudeHomeDir,
|
|
6347
|
-
PI_CODING_AGENT_DIR:
|
|
6401
|
+
PI_CODING_AGENT_DIR: resolve28(runtime.homeDir, ".pi", "agent"),
|
|
6348
6402
|
[RUNTIME_CONTEXT_ENV]: runtime.contextFile,
|
|
6349
6403
|
...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
|
|
6350
6404
|
...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
|
|
@@ -6355,16 +6409,16 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6355
6409
|
NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
|
|
6356
6410
|
} : {}
|
|
6357
6411
|
};
|
|
6358
|
-
const knownHostsPath =
|
|
6359
|
-
if (
|
|
6360
|
-
const agentSshKey =
|
|
6412
|
+
const knownHostsPath = resolve28(runtime.homeDir, ".ssh", "known_hosts");
|
|
6413
|
+
if (existsSync26(knownHostsPath)) {
|
|
6414
|
+
const agentSshKey = resolve28(runtime.homeDir, ".ssh", "rig-agent-key");
|
|
6361
6415
|
const sshParts = [
|
|
6362
6416
|
"ssh",
|
|
6363
6417
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
6364
6418
|
"-o StrictHostKeyChecking=yes",
|
|
6365
6419
|
"-F /dev/null"
|
|
6366
6420
|
];
|
|
6367
|
-
if (
|
|
6421
|
+
if (existsSync26(agentSshKey)) {
|
|
6368
6422
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
6369
6423
|
}
|
|
6370
6424
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -6401,7 +6455,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6401
6455
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
6402
6456
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
6403
6457
|
}
|
|
6404
|
-
if (
|
|
6458
|
+
if (existsSync26(runtime.contextFile)) {
|
|
6405
6459
|
const runtimeContext = loadRuntimeContext(runtime.contextFile);
|
|
6406
6460
|
Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
|
|
6407
6461
|
Object.assign(env, browserEnvFromContext(runtimeContext.browser));
|
|
@@ -6430,30 +6484,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
6430
6484
|
await mkdir2(runtime.cacheDir, { recursive: true });
|
|
6431
6485
|
await provisionAgentSshKey(runtime.homeDir);
|
|
6432
6486
|
if (options.provider === "codex") {
|
|
6433
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
6487
|
+
const hasCodexAuth = await injectCodexAuth(resolve28(runtime.homeDir, ".codex"));
|
|
6434
6488
|
if (!hasCodexAuth) {
|
|
6435
6489
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
6436
6490
|
}
|
|
6437
6491
|
}
|
|
6438
6492
|
if (options.provider === "pi") {
|
|
6439
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
6493
|
+
const hasPiAuth = await injectPiAgentConfig(resolve28(runtime.homeDir, ".pi", "agent"));
|
|
6440
6494
|
if (!hasPiAuth) {
|
|
6441
6495
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
6442
6496
|
}
|
|
6443
6497
|
}
|
|
6444
6498
|
}
|
|
6445
6499
|
async function provisionClaudeHome(config) {
|
|
6446
|
-
|
|
6447
|
-
const workspaceSettings =
|
|
6448
|
-
const hostSettings =
|
|
6449
|
-
const projectSettings =
|
|
6500
|
+
mkdirSync12(config.claudeHomeDir, { recursive: true });
|
|
6501
|
+
const workspaceSettings = resolve28(config.workspaceDir, ".claude/settings.json");
|
|
6502
|
+
const hostSettings = resolve28(config.hostProjectRoot, ".claude/settings.json");
|
|
6503
|
+
const projectSettings = existsSync26(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
6450
6504
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
6451
|
-
if (
|
|
6452
|
-
|
|
6505
|
+
if (existsSync26(projectSettings)) {
|
|
6506
|
+
writeFileSync10(resolve28(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6453
6507
|
`, "utf-8");
|
|
6454
6508
|
}
|
|
6455
6509
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
6456
|
-
|
|
6510
|
+
writeFileSync10(resolve28(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
6457
6511
|
permissions: { defaultMode: "bypassPermissions" },
|
|
6458
6512
|
autoMemoryEnabled: false
|
|
6459
6513
|
}, null, 2));
|
|
@@ -6461,12 +6515,12 @@ async function provisionClaudeHome(config) {
|
|
|
6461
6515
|
if (!hasCredentials) {
|
|
6462
6516
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
6463
6517
|
}
|
|
6464
|
-
const realClaudeHome =
|
|
6465
|
-
if (process.env.HOME &&
|
|
6466
|
-
cpSync2(
|
|
6518
|
+
const realClaudeHome = resolve28(process.env.HOME ?? "", ".claude");
|
|
6519
|
+
if (process.env.HOME && existsSync26(resolve28(realClaudeHome, "CLAUDE.md"))) {
|
|
6520
|
+
cpSync2(resolve28(realClaudeHome, "CLAUDE.md"), resolve28(config.claudeHomeDir, "CLAUDE.md"));
|
|
6467
6521
|
}
|
|
6468
|
-
if (process.env.HOME &&
|
|
6469
|
-
cpSync2(
|
|
6522
|
+
if (process.env.HOME && existsSync26(resolve28(realClaudeHome, "agents"))) {
|
|
6523
|
+
cpSync2(resolve28(realClaudeHome, "agents"), resolve28(config.claudeHomeDir, "agents"), { recursive: true });
|
|
6470
6524
|
}
|
|
6471
6525
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
6472
6526
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -6477,10 +6531,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
6477
6531
|
if (!sourcePath) {
|
|
6478
6532
|
return "";
|
|
6479
6533
|
}
|
|
6480
|
-
const certsDir =
|
|
6481
|
-
const targetPath =
|
|
6534
|
+
const certsDir = resolve28(runtime.rootDir, "certs");
|
|
6535
|
+
const targetPath = resolve28(certsDir, "ca-certificates.pem");
|
|
6482
6536
|
await mkdir2(certsDir, { recursive: true });
|
|
6483
|
-
let shouldCopy = !
|
|
6537
|
+
let shouldCopy = !existsSync26(targetPath);
|
|
6484
6538
|
if (!shouldCopy) {
|
|
6485
6539
|
try {
|
|
6486
6540
|
shouldCopy = statSync6(sourcePath).mtimeMs > statSync6(targetPath).mtimeMs;
|
|
@@ -6502,7 +6556,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
6502
6556
|
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';
|
|
6503
6557
|
}
|
|
6504
6558
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
6505
|
-
const secretsPath =
|
|
6559
|
+
const secretsPath = resolve28(runtimeRoot, "runtime-secrets.json");
|
|
6506
6560
|
const persisted = {};
|
|
6507
6561
|
for (const key of [
|
|
6508
6562
|
"GITHUB_TOKEN",
|
|
@@ -6521,12 +6575,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
6521
6575
|
if (Object.keys(persisted).length === 0) {
|
|
6522
6576
|
return;
|
|
6523
6577
|
}
|
|
6524
|
-
|
|
6578
|
+
writeFileSync10(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
6525
6579
|
`, "utf-8");
|
|
6526
6580
|
}
|
|
6527
6581
|
async function provisionAgentSshKey(homeDir) {
|
|
6528
|
-
const sshDir =
|
|
6529
|
-
if (!
|
|
6582
|
+
const sshDir = resolve28(homeDir, ".ssh");
|
|
6583
|
+
if (!existsSync26(sshDir)) {
|
|
6530
6584
|
await mkdir2(sshDir, { recursive: true });
|
|
6531
6585
|
}
|
|
6532
6586
|
seedKnownHosts(sshDir);
|
|
@@ -6534,27 +6588,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
6534
6588
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
6535
6589
|
if (!privateKey) {
|
|
6536
6590
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
6537
|
-
if (!process.env.HOME || !
|
|
6591
|
+
if (!process.env.HOME || !existsSync26(hostKeyPath)) {
|
|
6538
6592
|
return;
|
|
6539
6593
|
}
|
|
6540
|
-
const agentKeyPath2 =
|
|
6541
|
-
if (!
|
|
6594
|
+
const agentKeyPath2 = resolve28(sshDir, "rig-agent-key");
|
|
6595
|
+
if (!existsSync26(agentKeyPath2)) {
|
|
6542
6596
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
6543
6597
|
chmodSync5(agentKeyPath2, 384);
|
|
6544
6598
|
}
|
|
6545
6599
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
6546
|
-
if (
|
|
6600
|
+
if (existsSync26(hostPubPath)) {
|
|
6547
6601
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
6548
|
-
if (!
|
|
6602
|
+
if (!existsSync26(agentPubPath)) {
|
|
6549
6603
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
6550
6604
|
}
|
|
6551
6605
|
}
|
|
6552
6606
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
6553
6607
|
return;
|
|
6554
6608
|
}
|
|
6555
|
-
const agentKeyPath =
|
|
6556
|
-
if (!
|
|
6557
|
-
|
|
6609
|
+
const agentKeyPath = resolve28(sshDir, "rig-agent-key");
|
|
6610
|
+
if (!existsSync26(agentKeyPath)) {
|
|
6611
|
+
writeFileSync10(agentKeyPath, privateKey, { mode: 384 });
|
|
6558
6612
|
}
|
|
6559
6613
|
writeSshConfig(sshDir, agentKeyPath);
|
|
6560
6614
|
}
|
|
@@ -6571,21 +6625,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
6571
6625
|
`;
|
|
6572
6626
|
}
|
|
6573
6627
|
function resolveHostSshKeyPath(homeDir) {
|
|
6574
|
-
const sshDir =
|
|
6628
|
+
const sshDir = resolve28(homeDir, ".ssh");
|
|
6575
6629
|
const candidates = [
|
|
6576
6630
|
"rig-agent-key",
|
|
6577
6631
|
"id_ed25519",
|
|
6578
6632
|
"id_ecdsa",
|
|
6579
6633
|
"id_rsa"
|
|
6580
|
-
].map((name) =>
|
|
6581
|
-
return candidates.find((candidate) =>
|
|
6634
|
+
].map((name) => resolve28(sshDir, name));
|
|
6635
|
+
return candidates.find((candidate) => existsSync26(candidate)) ?? resolve28(sshDir, "rig-agent-key");
|
|
6582
6636
|
}
|
|
6583
6637
|
function writeSshConfig(sshDir, keyPath) {
|
|
6584
|
-
const configPath =
|
|
6585
|
-
if (
|
|
6638
|
+
const configPath = resolve28(sshDir, "config");
|
|
6639
|
+
if (existsSync26(configPath)) {
|
|
6586
6640
|
return;
|
|
6587
6641
|
}
|
|
6588
|
-
const knownHostsPath =
|
|
6642
|
+
const knownHostsPath = resolve28(sshDir, "known_hosts");
|
|
6589
6643
|
const config = [
|
|
6590
6644
|
"Host github.com",
|
|
6591
6645
|
` IdentityFile ${keyPath}`,
|
|
@@ -6595,10 +6649,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
6595
6649
|
""
|
|
6596
6650
|
].join(`
|
|
6597
6651
|
`);
|
|
6598
|
-
|
|
6652
|
+
writeFileSync10(configPath, config, { mode: 420 });
|
|
6599
6653
|
}
|
|
6600
6654
|
function seedKnownHosts(sshDir) {
|
|
6601
|
-
const knownHostsPath =
|
|
6655
|
+
const knownHostsPath = resolve28(sshDir, "known_hosts");
|
|
6602
6656
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
6603
6657
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
6604
6658
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -6609,23 +6663,23 @@ function seedKnownHosts(sshDir) {
|
|
|
6609
6663
|
for (const line of missing) {
|
|
6610
6664
|
existingLines.add(line);
|
|
6611
6665
|
}
|
|
6612
|
-
|
|
6666
|
+
writeFileSync10(knownHostsPath, `${Array.from(existingLines).join(`
|
|
6613
6667
|
`)}
|
|
6614
6668
|
`, { mode: 420 });
|
|
6615
6669
|
} catch (err) {
|
|
6616
|
-
const hint =
|
|
6670
|
+
const hint = existsSync26(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
6617
6671
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
6618
6672
|
}
|
|
6619
6673
|
}
|
|
6620
6674
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
6621
6675
|
const projectHash = hashProjectPath(workspaceDir);
|
|
6622
|
-
const projectDir =
|
|
6623
|
-
|
|
6624
|
-
|
|
6676
|
+
const projectDir = resolve28(claudeHomeDir, "projects", projectHash);
|
|
6677
|
+
mkdirSync12(projectDir, { recursive: true });
|
|
6678
|
+
writeFileSync10(resolve28(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6625
6679
|
`, "utf-8");
|
|
6626
6680
|
}
|
|
6627
6681
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
6628
|
-
if (!
|
|
6682
|
+
if (!existsSync26(projectSettingsPath)) {
|
|
6629
6683
|
return {};
|
|
6630
6684
|
}
|
|
6631
6685
|
let parsed;
|
|
@@ -6671,7 +6725,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
6671
6725
|
return clone;
|
|
6672
6726
|
}
|
|
6673
6727
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
6674
|
-
const credentialsPath =
|
|
6728
|
+
const credentialsPath = resolve28(claudeHomeDir, ".credentials.json");
|
|
6675
6729
|
const platform = options.platform ?? process.platform;
|
|
6676
6730
|
if (platform === "darwin") {
|
|
6677
6731
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -6681,16 +6735,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6681
6735
|
if (raw) {
|
|
6682
6736
|
try {
|
|
6683
6737
|
JSON.parse(raw);
|
|
6684
|
-
|
|
6738
|
+
writeFileSync10(credentialsPath, raw, { mode: 384 });
|
|
6685
6739
|
registerCredentialCleanup(credentialsPath);
|
|
6686
6740
|
return true;
|
|
6687
6741
|
} catch {}
|
|
6688
6742
|
}
|
|
6689
6743
|
}
|
|
6690
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6744
|
+
const hostClaudeHome = options.hostClaudeHome ? resolve28(options.hostClaudeHome) : process.env.CLAUDE_HOME?.trim() ? resolve28(process.env.CLAUDE_HOME) : process.env.HOME ? resolve28(process.env.HOME, ".claude") : "";
|
|
6691
6745
|
if (hostClaudeHome) {
|
|
6692
|
-
const realCredentials =
|
|
6693
|
-
if (
|
|
6746
|
+
const realCredentials = resolve28(hostClaudeHome, ".credentials.json");
|
|
6747
|
+
if (existsSync26(realCredentials)) {
|
|
6694
6748
|
cpSync2(realCredentials, credentialsPath);
|
|
6695
6749
|
return true;
|
|
6696
6750
|
}
|
|
@@ -6698,36 +6752,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6698
6752
|
return false;
|
|
6699
6753
|
}
|
|
6700
6754
|
async function injectCodexAuth(codexHomeDir) {
|
|
6701
|
-
|
|
6702
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6755
|
+
mkdirSync12(codexHomeDir, { recursive: true });
|
|
6756
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve28(process.env.CODEX_HOME) : process.env.HOME ? resolve28(process.env.HOME, ".codex") : "";
|
|
6703
6757
|
if (!hostCodexHome) {
|
|
6704
6758
|
return false;
|
|
6705
6759
|
}
|
|
6706
|
-
const hostAuthPath =
|
|
6707
|
-
if (!
|
|
6760
|
+
const hostAuthPath = resolve28(hostCodexHome, "auth.json");
|
|
6761
|
+
if (!existsSync26(hostAuthPath)) {
|
|
6708
6762
|
return false;
|
|
6709
6763
|
}
|
|
6710
|
-
const runtimeAuthPath =
|
|
6764
|
+
const runtimeAuthPath = resolve28(codexHomeDir, "auth.json");
|
|
6711
6765
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6712
6766
|
chmodSync5(runtimeAuthPath, 384);
|
|
6713
6767
|
return true;
|
|
6714
6768
|
}
|
|
6715
6769
|
async function injectPiAgentConfig(piAgentDir) {
|
|
6716
|
-
|
|
6717
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6770
|
+
mkdirSync12(piAgentDir, { recursive: true });
|
|
6771
|
+
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ? resolve28(process.env.PI_CODING_AGENT_DIR) : process.env.HOME ? resolve28(process.env.HOME, ".pi", "agent") : "";
|
|
6718
6772
|
if (!hostPiAgentDir) {
|
|
6719
6773
|
return false;
|
|
6720
6774
|
}
|
|
6721
|
-
const hostAuthPath =
|
|
6722
|
-
if (!
|
|
6775
|
+
const hostAuthPath = resolve28(hostPiAgentDir, "auth.json");
|
|
6776
|
+
if (!existsSync26(hostAuthPath)) {
|
|
6723
6777
|
return false;
|
|
6724
6778
|
}
|
|
6725
|
-
const runtimeAuthPath =
|
|
6779
|
+
const runtimeAuthPath = resolve28(piAgentDir, "auth.json");
|
|
6726
6780
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6727
6781
|
chmodSync5(runtimeAuthPath, 384);
|
|
6728
|
-
const hostSettingsPath =
|
|
6729
|
-
if (
|
|
6730
|
-
const runtimeSettingsPath =
|
|
6782
|
+
const hostSettingsPath = resolve28(hostPiAgentDir, "settings.json");
|
|
6783
|
+
if (existsSync26(hostSettingsPath)) {
|
|
6784
|
+
const runtimeSettingsPath = resolve28(piAgentDir, "settings.json");
|
|
6731
6785
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
6732
6786
|
chmodSync5(runtimeSettingsPath, 384);
|
|
6733
6787
|
}
|
|
@@ -6735,13 +6789,13 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
6735
6789
|
}
|
|
6736
6790
|
|
|
6737
6791
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
6738
|
-
import { existsSync as
|
|
6739
|
-
import { resolve as
|
|
6792
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync13, statSync as statSync7, writeFileSync as writeFileSync11 } from "fs";
|
|
6793
|
+
import { resolve as resolve29 } from "path";
|
|
6740
6794
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6741
6795
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6742
6796
|
return {
|
|
6743
6797
|
type: "stdio",
|
|
6744
|
-
command:
|
|
6798
|
+
command: resolve29(options.binDir, "rig-tool-router"),
|
|
6745
6799
|
args: [],
|
|
6746
6800
|
env: {
|
|
6747
6801
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6750,14 +6804,14 @@ function buildRuntimeToolRouterServerConfig(options) {
|
|
|
6750
6804
|
};
|
|
6751
6805
|
}
|
|
6752
6806
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6753
|
-
const configPath =
|
|
6754
|
-
|
|
6807
|
+
const configPath = resolve29(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6808
|
+
mkdirSync13(options.stateDir, { recursive: true });
|
|
6755
6809
|
const payload = {
|
|
6756
6810
|
mcpServers: {
|
|
6757
6811
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6758
6812
|
}
|
|
6759
6813
|
};
|
|
6760
|
-
|
|
6814
|
+
writeFileSync11(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6761
6815
|
`, "utf-8");
|
|
6762
6816
|
return configPath;
|
|
6763
6817
|
}
|
|
@@ -6766,8 +6820,8 @@ if (false) {}
|
|
|
6766
6820
|
init_layout();
|
|
6767
6821
|
|
|
6768
6822
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6769
|
-
import { existsSync as
|
|
6770
|
-
import { dirname as dirname12, resolve as
|
|
6823
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync14, rmSync as rmSync10 } from "fs";
|
|
6824
|
+
import { dirname as dirname12, resolve as resolve30 } from "path";
|
|
6771
6825
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6772
6826
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6773
6827
|
if (explicit) {
|
|
@@ -6803,12 +6857,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6803
6857
|
}
|
|
6804
6858
|
async function provisionRuntimeWorktree(config) {
|
|
6805
6859
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6806
|
-
let hasValidWorktree =
|
|
6807
|
-
if (
|
|
6808
|
-
|
|
6860
|
+
let hasValidWorktree = existsSync28(resolve30(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6861
|
+
if (existsSync28(config.workspaceDir) && !hasValidWorktree) {
|
|
6862
|
+
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6809
6863
|
}
|
|
6810
6864
|
if (!hasValidWorktree) {
|
|
6811
|
-
|
|
6865
|
+
mkdirSync14(dirname12(config.workspaceDir), { recursive: true });
|
|
6812
6866
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6813
6867
|
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]);
|
|
6814
6868
|
if (add.exitCode !== 0) {
|
|
@@ -6984,31 +7038,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
6984
7038
|
|
|
6985
7039
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
6986
7040
|
import {
|
|
6987
|
-
existsSync as
|
|
7041
|
+
existsSync as existsSync30,
|
|
6988
7042
|
lstatSync,
|
|
6989
|
-
mkdirSync as
|
|
6990
|
-
readdirSync as
|
|
6991
|
-
readFileSync as
|
|
6992
|
-
rmSync as
|
|
7043
|
+
mkdirSync as mkdirSync16,
|
|
7044
|
+
readdirSync as readdirSync6,
|
|
7045
|
+
readFileSync as readFileSync15,
|
|
7046
|
+
rmSync as rmSync11,
|
|
6993
7047
|
statSync as statSync9,
|
|
6994
7048
|
symlinkSync as symlinkSync4
|
|
6995
7049
|
} from "fs";
|
|
6996
7050
|
import { mkdir as mkdir3, writeFile } from "fs/promises";
|
|
6997
|
-
import { dirname as dirname14, resolve as
|
|
7051
|
+
import { dirname as dirname14, resolve as resolve32 } from "path";
|
|
6998
7052
|
|
|
6999
7053
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
7000
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
7054
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync29, mkdirSync as mkdirSync15, statSync as statSync8 } from "fs";
|
|
7001
7055
|
import { tmpdir as tmpdir6 } from "os";
|
|
7002
|
-
import { dirname as dirname13, resolve as
|
|
7003
|
-
var sharedRouterOutputDir =
|
|
7004
|
-
var sharedRouterOutputPath =
|
|
7056
|
+
import { dirname as dirname13, resolve as resolve31 } from "path";
|
|
7057
|
+
var sharedRouterOutputDir = resolve31(tmpdir6(), "rig-native");
|
|
7058
|
+
var sharedRouterOutputPath = resolve31(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
7005
7059
|
function runtimeClaudeToolRouterFileName() {
|
|
7006
7060
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
7007
7061
|
}
|
|
7008
7062
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
7009
|
-
const sourcePath =
|
|
7010
|
-
|
|
7011
|
-
const needsBuild = !
|
|
7063
|
+
const sourcePath = resolve31(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
7064
|
+
mkdirSync15(dirname13(outputPath), { recursive: true });
|
|
7065
|
+
const needsBuild = !existsSync29(outputPath) || statSync8(sourcePath).mtimeMs > statSync8(outputPath).mtimeMs;
|
|
7012
7066
|
if (!needsBuild) {
|
|
7013
7067
|
return outputPath;
|
|
7014
7068
|
}
|
|
@@ -7022,9 +7076,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
7022
7076
|
}
|
|
7023
7077
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
7024
7078
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
7025
|
-
const targetPath =
|
|
7026
|
-
|
|
7027
|
-
const needsCopy = !
|
|
7079
|
+
const targetPath = resolve31(targetDir, runtimeClaudeToolRouterFileName());
|
|
7080
|
+
mkdirSync15(targetDir, { recursive: true });
|
|
7081
|
+
const needsCopy = !existsSync29(targetPath) || statSync8(sourcePath).mtimeMs > statSync8(targetPath).mtimeMs;
|
|
7028
7082
|
if (needsCopy) {
|
|
7029
7083
|
copyFileSync6(sourcePath, targetPath);
|
|
7030
7084
|
chmodSync6(targetPath, 493);
|
|
@@ -7037,48 +7091,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
7037
7091
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
7038
7092
|
function resolveRigSourceRoot(projectRoot) {
|
|
7039
7093
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
7040
|
-
if (hostProjectRoot &&
|
|
7094
|
+
if (hostProjectRoot && existsSync30(resolve32(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
7041
7095
|
return hostProjectRoot;
|
|
7042
7096
|
}
|
|
7043
|
-
const fromModule =
|
|
7044
|
-
if (
|
|
7097
|
+
const fromModule = resolve32(import.meta.dir, "../../../../../..");
|
|
7098
|
+
if (existsSync30(resolve32(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
7045
7099
|
return fromModule;
|
|
7046
7100
|
}
|
|
7047
7101
|
return projectRoot;
|
|
7048
7102
|
}
|
|
7049
7103
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
7050
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
7104
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve32(sessionDir, "session.json")]) {
|
|
7051
7105
|
removeSymbolicLink(path);
|
|
7052
7106
|
}
|
|
7053
7107
|
runtimePrepareTrackedPathsNative({
|
|
7054
7108
|
logsDir,
|
|
7055
7109
|
stateDir,
|
|
7056
7110
|
sessionDir,
|
|
7057
|
-
controlledBashLogFile:
|
|
7058
|
-
eventsFile:
|
|
7111
|
+
controlledBashLogFile: resolve32(logsDir, "controlled-bash.jsonl"),
|
|
7112
|
+
eventsFile: resolve32(logsDir, "control-plane.events.jsonl")
|
|
7059
7113
|
});
|
|
7060
7114
|
}
|
|
7061
7115
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
7062
7116
|
await mkdir3(stateDir, { recursive: true });
|
|
7063
7117
|
await mkdir3(sessionDir, { recursive: true });
|
|
7064
|
-
const failedApproachesPath =
|
|
7065
|
-
if (!
|
|
7118
|
+
const failedApproachesPath = resolve32(stateDir, "failed_approaches.md");
|
|
7119
|
+
if (!existsSync30(failedApproachesPath)) {
|
|
7066
7120
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
7067
7121
|
|
|
7068
7122
|
`);
|
|
7069
7123
|
}
|
|
7070
|
-
const hookTripsPath =
|
|
7071
|
-
if (!
|
|
7124
|
+
const hookTripsPath = resolve32(stateDir, "hook_trips.log");
|
|
7125
|
+
if (!existsSync30(hookTripsPath)) {
|
|
7072
7126
|
await writeFile(hookTripsPath, "");
|
|
7073
7127
|
}
|
|
7074
|
-
const sessionFile =
|
|
7128
|
+
const sessionFile = resolve32(sessionDir, "session.json");
|
|
7075
7129
|
if (taskId) {
|
|
7076
7130
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
7077
7131
|
}
|
|
7078
7132
|
}
|
|
7079
7133
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
7080
|
-
const artifactDir =
|
|
7081
|
-
const runtimeSnapshotDir =
|
|
7134
|
+
const artifactDir = resolve32(workspaceDir, "artifacts", taskId);
|
|
7135
|
+
const runtimeSnapshotDir = resolve32(artifactDir, "runtime-snapshots");
|
|
7082
7136
|
let preservedTrackedFiles = false;
|
|
7083
7137
|
for (const file of [
|
|
7084
7138
|
"changed-files.txt",
|
|
@@ -7094,13 +7148,13 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
7094
7148
|
preservedTrackedFiles = true;
|
|
7095
7149
|
continue;
|
|
7096
7150
|
}
|
|
7097
|
-
|
|
7151
|
+
rmSync11(resolve32(artifactDir, file), { force: true });
|
|
7098
7152
|
}
|
|
7099
7153
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
7100
7154
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
7101
7155
|
preservedTrackedFiles = true;
|
|
7102
7156
|
} else {
|
|
7103
|
-
|
|
7157
|
+
rmSync11(runtimeSnapshotDir, { recursive: true, force: true });
|
|
7104
7158
|
}
|
|
7105
7159
|
if (preservedTrackedFiles) {
|
|
7106
7160
|
console.log(`[rig-agent] Preserved tracked runtime artifact files in ${taskId}; skipped ephemeral cleanup for committed paths.`);
|
|
@@ -7133,28 +7187,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
7133
7187
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
7134
7188
|
}
|
|
7135
7189
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
7136
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
7137
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
7190
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve32(options.binDir, "rig"), rigSourceRoot);
|
|
7191
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve32(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
7138
7192
|
...options.runtimeSecretDefines,
|
|
7139
7193
|
AGENT_TASK_ID: options.taskId,
|
|
7140
7194
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7141
7195
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
7142
7196
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
7143
7197
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
7144
|
-
AGENT_BINARY_PATH:
|
|
7198
|
+
AGENT_BINARY_PATH: resolve32(options.binDir, "rig-agent"),
|
|
7145
7199
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
7146
7200
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
7147
7201
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
7148
7202
|
});
|
|
7149
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
7203
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve32(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
7150
7204
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7151
7205
|
AGENT_LOGS_DIR: options.logsDir,
|
|
7152
7206
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
7153
|
-
AGENT_TS_API_TESTS_DIR:
|
|
7154
|
-
AGENT_RIG_AGENT_BIN:
|
|
7207
|
+
AGENT_TS_API_TESTS_DIR: resolve32(options.workspaceDir, "TSAPITests"),
|
|
7208
|
+
AGENT_RIG_AGENT_BIN: resolve32(options.binDir, "rig-agent")
|
|
7155
7209
|
});
|
|
7156
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
7157
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
7210
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve32(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
7211
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve32(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
7158
7212
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7159
7213
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7160
7214
|
});
|
|
@@ -7163,15 +7217,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
7163
7217
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7164
7218
|
};
|
|
7165
7219
|
for (const hookName of hookNames) {
|
|
7166
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
7220
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve32(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
7167
7221
|
}
|
|
7168
|
-
const pluginsDir =
|
|
7169
|
-
if (
|
|
7170
|
-
for (const entry of
|
|
7222
|
+
const pluginsDir = resolve32(options.projectRoot, "rig/plugins");
|
|
7223
|
+
if (existsSync30(pluginsDir)) {
|
|
7224
|
+
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
7171
7225
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
7172
7226
|
if (!match)
|
|
7173
7227
|
continue;
|
|
7174
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
7228
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve32(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
7175
7229
|
}
|
|
7176
7230
|
}
|
|
7177
7231
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -7181,8 +7235,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
7181
7235
|
}
|
|
7182
7236
|
async function writeRuntimeManifest(config) {
|
|
7183
7237
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
7184
|
-
const binarySha256 = sha256Hex(
|
|
7185
|
-
const manifestPath =
|
|
7238
|
+
const binarySha256 = sha256Hex(readFileSync15(config.binaryPath));
|
|
7239
|
+
const manifestPath = resolve32(config.runtimeRoot, "manifest.json");
|
|
7186
7240
|
const manifest = {
|
|
7187
7241
|
runtimeId: config.runtimeId,
|
|
7188
7242
|
taskId: config.taskId,
|
|
@@ -7216,7 +7270,7 @@ function removeSymbolicLink(path) {
|
|
|
7216
7270
|
} catch {
|
|
7217
7271
|
return;
|
|
7218
7272
|
}
|
|
7219
|
-
|
|
7273
|
+
rmSync11(path, { force: true, recursive: true });
|
|
7220
7274
|
}
|
|
7221
7275
|
async function resetTrackedArtifactPath(workspaceDir, relativePath) {
|
|
7222
7276
|
const tracked = await runGitLsFiles(workspaceDir, relativePath);
|
|
@@ -7242,7 +7296,7 @@ async function restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, r
|
|
|
7242
7296
|
const retryDelayMs = options.retryDelayMs ?? GIT_INDEX_LOCK_RETRY_DELAY_MS;
|
|
7243
7297
|
const now = options.now ?? Date.now;
|
|
7244
7298
|
const statMtimeMs = options.statMtimeMs ?? readFileMtimeMs;
|
|
7245
|
-
const removeFile = options.removeFile ?? ((path) =>
|
|
7299
|
+
const removeFile = options.removeFile ?? ((path) => rmSync11(path, { force: true }));
|
|
7246
7300
|
const log = options.log ?? console.warn;
|
|
7247
7301
|
let lastOutput = "";
|
|
7248
7302
|
for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
|
|
@@ -7302,31 +7356,31 @@ function readFileMtimeMs(path) {
|
|
|
7302
7356
|
}
|
|
7303
7357
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
7304
7358
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
7305
|
-
const sourceNodeModules =
|
|
7306
|
-
if (!
|
|
7307
|
-
const runtimeHumoongate =
|
|
7308
|
-
if (
|
|
7309
|
-
const targetNodeModules =
|
|
7359
|
+
const sourceNodeModules = resolve32(monorepoRoot, "humoongate", "node_modules");
|
|
7360
|
+
if (!existsSync30(sourceNodeModules)) {} else {
|
|
7361
|
+
const runtimeHumoongate = resolve32(workspaceDir, "humoongate");
|
|
7362
|
+
if (existsSync30(resolve32(runtimeHumoongate, "package.json"))) {
|
|
7363
|
+
const targetNodeModules = resolve32(runtimeHumoongate, "node_modules");
|
|
7310
7364
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
7311
7365
|
}
|
|
7312
7366
|
}
|
|
7313
|
-
const runtimeHpNext =
|
|
7314
|
-
if (!
|
|
7367
|
+
const runtimeHpNext = resolve32(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
7368
|
+
if (!existsSync30(resolve32(runtimeHpNext, "package.json"))) {
|
|
7315
7369
|
return;
|
|
7316
7370
|
}
|
|
7317
|
-
const sourceHpNextNodeModules =
|
|
7318
|
-
const sourceMonorepoNodeModules =
|
|
7319
|
-
const targetHpNextNodeModules =
|
|
7320
|
-
if (
|
|
7371
|
+
const sourceHpNextNodeModules = resolve32(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
7372
|
+
const sourceMonorepoNodeModules = resolve32(monorepoRoot, "node_modules");
|
|
7373
|
+
const targetHpNextNodeModules = resolve32(runtimeHpNext, "node_modules");
|
|
7374
|
+
if (existsSync30(sourceHpNextNodeModules)) {
|
|
7321
7375
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
7322
7376
|
return;
|
|
7323
7377
|
}
|
|
7324
|
-
if (
|
|
7378
|
+
if (existsSync30(sourceMonorepoNodeModules)) {
|
|
7325
7379
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
7326
7380
|
}
|
|
7327
7381
|
}
|
|
7328
7382
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
7329
|
-
linkNodeModulesLayer(
|
|
7383
|
+
linkNodeModulesLayer(resolve32(monorepoRoot, "node_modules"), resolve32(workspaceDir, "node_modules"));
|
|
7330
7384
|
for (const relativePackageDir of [
|
|
7331
7385
|
"apps/native-app/apps/marketing",
|
|
7332
7386
|
"apps/native-app/apps/web",
|
|
@@ -7348,15 +7402,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
7348
7402
|
"packages/standard-plugin",
|
|
7349
7403
|
"packages/validator-kit"
|
|
7350
7404
|
]) {
|
|
7351
|
-
const workspacePackageDir =
|
|
7352
|
-
if (!
|
|
7405
|
+
const workspacePackageDir = resolve32(workspaceDir, relativePackageDir);
|
|
7406
|
+
if (!existsSync30(resolve32(workspacePackageDir, "package.json"))) {
|
|
7353
7407
|
continue;
|
|
7354
7408
|
}
|
|
7355
|
-
linkNodeModulesLayer(
|
|
7409
|
+
linkNodeModulesLayer(resolve32(monorepoRoot, relativePackageDir, "node_modules"), resolve32(workspacePackageDir, "node_modules"));
|
|
7356
7410
|
}
|
|
7357
7411
|
}
|
|
7358
7412
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
7359
|
-
if (!
|
|
7413
|
+
if (!existsSync30(sourceDir) || existsSync30(targetDir)) {
|
|
7360
7414
|
return;
|
|
7361
7415
|
}
|
|
7362
7416
|
try {
|
|
@@ -7365,25 +7419,25 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
7365
7419
|
} catch (error) {
|
|
7366
7420
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
7367
7421
|
}
|
|
7368
|
-
|
|
7422
|
+
mkdirSync16(dirname14(targetDir), { recursive: true });
|
|
7369
7423
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
7370
7424
|
}
|
|
7371
7425
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
7372
|
-
const hooksDir =
|
|
7373
|
-
const pluginsDir =
|
|
7374
|
-
const validatorsDir =
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7426
|
+
const hooksDir = resolve32(runtimeBinDir, "hooks");
|
|
7427
|
+
const pluginsDir = resolve32(runtimeBinDir, "plugins");
|
|
7428
|
+
const validatorsDir = resolve32(runtimeBinDir, "validators");
|
|
7429
|
+
mkdirSync16(hooksDir, { recursive: true });
|
|
7430
|
+
mkdirSync16(pluginsDir, { recursive: true });
|
|
7431
|
+
mkdirSync16(validatorsDir, { recursive: true });
|
|
7378
7432
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
7379
7433
|
}
|
|
7380
7434
|
|
|
7381
7435
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
7382
|
-
import { existsSync as
|
|
7383
|
-
import { basename as basename9, resolve as
|
|
7436
|
+
import { existsSync as existsSync32, rmSync as rmSync12, writeFileSync as writeFileSync13 } from "fs";
|
|
7437
|
+
import { basename as basename9, resolve as resolve35 } from "path";
|
|
7384
7438
|
|
|
7385
7439
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
7386
|
-
import { existsSync as
|
|
7440
|
+
import { existsSync as existsSync31 } from "fs";
|
|
7387
7441
|
init_utils();
|
|
7388
7442
|
|
|
7389
7443
|
// packages/runtime/src/control-plane/runtime/sandbox/backend-none.ts
|
|
@@ -7483,13 +7537,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
7483
7537
|
depRoots
|
|
7484
7538
|
};
|
|
7485
7539
|
const fsContext = {
|
|
7486
|
-
pathExists: (p) =>
|
|
7540
|
+
pathExists: (p) => existsSync31(p),
|
|
7487
7541
|
realPath: toRealPath
|
|
7488
7542
|
};
|
|
7489
7543
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
7490
7544
|
const seatbelt = Bun.which("sandbox-exec");
|
|
7491
7545
|
probed.push("sandbox-exec");
|
|
7492
|
-
if (seatbelt &&
|
|
7546
|
+
if (seatbelt && existsSync31(seatbelt)) {
|
|
7493
7547
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
7494
7548
|
if (SeatbeltBackendClass) {
|
|
7495
7549
|
return {
|
|
@@ -7610,10 +7664,10 @@ init_layout();
|
|
|
7610
7664
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
7611
7665
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
7612
7666
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
7613
|
-
const readyFile =
|
|
7614
|
-
const requestFile =
|
|
7615
|
-
|
|
7616
|
-
|
|
7667
|
+
const readyFile = resolve35(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
7668
|
+
const requestFile = resolve35(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
7669
|
+
rmSync12(readyFile, { force: true });
|
|
7670
|
+
rmSync12(requestFile, { force: true });
|
|
7617
7671
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
7618
7672
|
const useCompiledSidecar = shouldUseCompiledSnapshotSidecar(sidecarBinary);
|
|
7619
7673
|
const bunCli = useCompiledSidecar ? null : resolveBunCliInvocation();
|
|
@@ -7651,19 +7705,19 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
7651
7705
|
proc.kill("SIGTERM");
|
|
7652
7706
|
} catch {}
|
|
7653
7707
|
await proc.exited;
|
|
7654
|
-
|
|
7655
|
-
|
|
7708
|
+
rmSync12(readyFile, { force: true });
|
|
7709
|
+
rmSync12(requestFile, { force: true });
|
|
7656
7710
|
},
|
|
7657
7711
|
finalize: async (commandParts, exitCode) => {
|
|
7658
|
-
|
|
7712
|
+
writeFileSync13(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
7659
7713
|
`, "utf-8");
|
|
7660
7714
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
7661
7715
|
proc.exited,
|
|
7662
7716
|
stdoutTextPromise,
|
|
7663
7717
|
stderrTextPromise
|
|
7664
7718
|
]);
|
|
7665
|
-
|
|
7666
|
-
|
|
7719
|
+
rmSync12(readyFile, { force: true });
|
|
7720
|
+
rmSync12(requestFile, { force: true });
|
|
7667
7721
|
if (sidecarExitCode !== 0) {
|
|
7668
7722
|
throw new Error(`snapshot sidecar failed (${sidecarExitCode}): ${stderr || stdout}`);
|
|
7669
7723
|
}
|
|
@@ -7719,8 +7773,8 @@ async function runInAgentRuntime(options) {
|
|
|
7719
7773
|
const stdout = await new Response(proc.stdout).text();
|
|
7720
7774
|
const stderr = await new Response(proc.stderr).text();
|
|
7721
7775
|
try {
|
|
7722
|
-
await Bun.write(
|
|
7723
|
-
await Bun.write(
|
|
7776
|
+
await Bun.write(resolve35(options.runtime.logsDir, "agent-stdout.log"), stdout);
|
|
7777
|
+
await Bun.write(resolve35(options.runtime.logsDir, "agent-stderr.log"), stderr);
|
|
7724
7778
|
} catch {}
|
|
7725
7779
|
await snapshotSidecar.finalize(runtimeCommand, exitCode);
|
|
7726
7780
|
return {
|
|
@@ -7752,10 +7806,10 @@ function resolveSnapshotSidecarScriptPath() {
|
|
|
7752
7806
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
7753
7807
|
}
|
|
7754
7808
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
7755
|
-
return
|
|
7809
|
+
return resolve35(binDir, "snapshot-sidecar");
|
|
7756
7810
|
}
|
|
7757
7811
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
7758
|
-
if (!
|
|
7812
|
+
if (!existsSync32(binaryPath)) {
|
|
7759
7813
|
return false;
|
|
7760
7814
|
}
|
|
7761
7815
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -7770,12 +7824,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
7770
7824
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
7771
7825
|
].filter((value) => Boolean(value));
|
|
7772
7826
|
for (const root of hostRoots) {
|
|
7773
|
-
const candidate =
|
|
7774
|
-
if (
|
|
7827
|
+
const candidate = resolve35(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
7828
|
+
if (existsSync32(candidate)) {
|
|
7775
7829
|
return candidate;
|
|
7776
7830
|
}
|
|
7777
7831
|
}
|
|
7778
|
-
return
|
|
7832
|
+
return resolve35(import.meta.dir, "..", fileName);
|
|
7779
7833
|
}
|
|
7780
7834
|
function resolveBunCliInvocation() {
|
|
7781
7835
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -7802,7 +7856,7 @@ function resolveBunCliInvocation() {
|
|
|
7802
7856
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
7803
7857
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
7804
7858
|
while (Date.now() < deadline) {
|
|
7805
|
-
if (
|
|
7859
|
+
if (existsSync32(readyFile)) {
|
|
7806
7860
|
return;
|
|
7807
7861
|
}
|
|
7808
7862
|
const exitCode = proc.exitCode;
|
|
@@ -7820,9 +7874,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
7820
7874
|
async function hydrateRuntimeMemory(options) {
|
|
7821
7875
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
7822
7876
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
7823
|
-
const hydratedPath =
|
|
7877
|
+
const hydratedPath = resolve36(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
7824
7878
|
try {
|
|
7825
|
-
await mkdir4(
|
|
7879
|
+
await mkdir4(resolve36(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
7826
7880
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
7827
7881
|
return {
|
|
7828
7882
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -7837,12 +7891,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
7837
7891
|
}
|
|
7838
7892
|
}
|
|
7839
7893
|
async function createRuntimeTaskRecordReader(options) {
|
|
7840
|
-
const legacyConfigPath =
|
|
7894
|
+
const legacyConfigPath = resolve36(options.projectRoot, ".rig", "task-config.json");
|
|
7841
7895
|
let pluginHostContext = null;
|
|
7842
7896
|
try {
|
|
7843
7897
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
7844
7898
|
} catch (error) {
|
|
7845
|
-
if (!
|
|
7899
|
+
if (!existsSync33(legacyConfigPath)) {
|
|
7846
7900
|
throw error;
|
|
7847
7901
|
}
|
|
7848
7902
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -7862,7 +7916,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7862
7916
|
source: "plugin"
|
|
7863
7917
|
};
|
|
7864
7918
|
}
|
|
7865
|
-
if (
|
|
7919
|
+
if (existsSync33(legacyConfigPath)) {
|
|
7866
7920
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
7867
7921
|
options.diagnostics?.(message);
|
|
7868
7922
|
console.warn(message);
|
|
@@ -7879,10 +7933,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7879
7933
|
};
|
|
7880
7934
|
}
|
|
7881
7935
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
7882
|
-
const jsonPath =
|
|
7883
|
-
if (
|
|
7936
|
+
const jsonPath = resolve36(projectRoot, "rig.config.json");
|
|
7937
|
+
if (existsSync33(jsonPath)) {
|
|
7884
7938
|
try {
|
|
7885
|
-
const parsed = JSON.parse(
|
|
7939
|
+
const parsed = JSON.parse(readFileSync16(jsonPath, "utf8"));
|
|
7886
7940
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7887
7941
|
const taskSource = parsed.taskSource;
|
|
7888
7942
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -7894,12 +7948,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
7894
7948
|
return null;
|
|
7895
7949
|
}
|
|
7896
7950
|
}
|
|
7897
|
-
const tsPath =
|
|
7898
|
-
if (!
|
|
7951
|
+
const tsPath = resolve36(projectRoot, "rig.config.ts");
|
|
7952
|
+
if (!existsSync33(tsPath)) {
|
|
7899
7953
|
return null;
|
|
7900
7954
|
}
|
|
7901
7955
|
try {
|
|
7902
|
-
const source =
|
|
7956
|
+
const source = readFileSync16(tsPath, "utf8");
|
|
7903
7957
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
7904
7958
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
7905
7959
|
return kind ?? null;
|
|
@@ -7969,8 +8023,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
7969
8023
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
7970
8024
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
7971
8025
|
};
|
|
7972
|
-
const configPath =
|
|
7973
|
-
await mkdir4(
|
|
8026
|
+
const configPath = resolve36(options.workspaceDir, ".rig", "task-config.json");
|
|
8027
|
+
await mkdir4(resolve36(options.workspaceDir, ".rig"), { recursive: true });
|
|
7974
8028
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
7975
8029
|
`, "utf-8");
|
|
7976
8030
|
}
|
|
@@ -8034,9 +8088,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8034
8088
|
}
|
|
8035
8089
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8036
8090
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8037
|
-
const workspaceDir =
|
|
8091
|
+
const workspaceDir = resolve36(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8038
8092
|
const createdAt = new Date().toISOString();
|
|
8039
|
-
if (!
|
|
8093
|
+
if (!existsSync33(resolve36(monorepoRoot, ".git"))) {
|
|
8040
8094
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8041
8095
|
}
|
|
8042
8096
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8071,7 +8125,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8071
8125
|
logsDir: overlay.logsDir,
|
|
8072
8126
|
stateDir: overlay.stateDir,
|
|
8073
8127
|
sessionDir: overlay.sessionDir,
|
|
8074
|
-
claudeHomeDir:
|
|
8128
|
+
claudeHomeDir: resolve36(workspaceLayout.homeDir, ".claude"),
|
|
8075
8129
|
contextFile: overlay.contextPath,
|
|
8076
8130
|
binDir: workspaceLayout.binDir,
|
|
8077
8131
|
createdAt
|
|
@@ -8084,8 +8138,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8084
8138
|
projectRoot: options.projectRoot,
|
|
8085
8139
|
workspaceDir
|
|
8086
8140
|
});
|
|
8087
|
-
|
|
8088
|
-
|
|
8141
|
+
mkdirSync19(runtime.binDir, { recursive: true });
|
|
8142
|
+
mkdirSync19(workspaceLayout.distDir, { recursive: true });
|
|
8089
8143
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8090
8144
|
if (options.preserveTaskArtifacts) {
|
|
8091
8145
|
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
@@ -8104,7 +8158,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8104
8158
|
runtimeId: options.id
|
|
8105
8159
|
}),
|
|
8106
8160
|
workspaceDir,
|
|
8107
|
-
artifactRoot:
|
|
8161
|
+
artifactRoot: resolve36(workspaceDir, "artifacts", options.taskId),
|
|
8108
8162
|
hostProjectRoot: options.projectRoot,
|
|
8109
8163
|
monorepoMainRoot: monorepoRoot,
|
|
8110
8164
|
monorepoBaseRef: baseRef,
|
|
@@ -8120,8 +8174,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8120
8174
|
stateDir: overlay.stateDir,
|
|
8121
8175
|
logsDir: overlay.logsDir,
|
|
8122
8176
|
sessionDir: overlay.sessionDir,
|
|
8123
|
-
sessionFile:
|
|
8124
|
-
policyFile:
|
|
8177
|
+
sessionFile: resolve36(overlay.sessionDir, "session.json"),
|
|
8178
|
+
policyFile: resolve36(options.projectRoot, "rig/policy/policy.json"),
|
|
8125
8179
|
binDir: runtime.binDir,
|
|
8126
8180
|
createdAt,
|
|
8127
8181
|
memory
|
|
@@ -8132,9 +8186,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8132
8186
|
task: taskResolution.task,
|
|
8133
8187
|
taskEntry
|
|
8134
8188
|
});
|
|
8135
|
-
const manifestPath =
|
|
8189
|
+
const manifestPath = resolve36(runtimeRoot, "manifest.json");
|
|
8136
8190
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8137
|
-
const runtimeAgentBinary =
|
|
8191
|
+
const runtimeAgentBinary = resolve36(runtime.binDir, "rig-agent");
|
|
8138
8192
|
await ensureRigGitBinaryPath();
|
|
8139
8193
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8140
8194
|
projectRoot: options.projectRoot,
|
|
@@ -8149,10 +8203,10 @@ async function ensureAgentRuntime(options) {
|
|
|
8149
8203
|
const bakedStatusOutput = await captureStdout(async () => {
|
|
8150
8204
|
taskStatus(options.projectRoot);
|
|
8151
8205
|
});
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8206
|
+
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8207
|
+
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8208
|
+
mkdirSync19(runtime.binDir, { recursive: true });
|
|
8209
|
+
mkdirSync19(workspaceLayout.distDir, { recursive: true });
|
|
8156
8210
|
await buildRuntimeToolchain({
|
|
8157
8211
|
projectRoot: options.projectRoot,
|
|
8158
8212
|
workspaceDir,
|
|
@@ -8189,9 +8243,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8189
8243
|
workspaceDir,
|
|
8190
8244
|
taskEntry
|
|
8191
8245
|
});
|
|
8192
|
-
const sandboxDir =
|
|
8246
|
+
const sandboxDir = resolve36(runtimeRoot, "sandbox");
|
|
8193
8247
|
await mkdir4(sandboxDir, { recursive: true });
|
|
8194
|
-
await writeFile2(
|
|
8248
|
+
await writeFile2(resolve36(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8195
8249
|
id: options.id,
|
|
8196
8250
|
taskId: options.taskId,
|
|
8197
8251
|
mode: "worktree",
|
|
@@ -8247,13 +8301,6 @@ async function runPriorityQueue(context, options) {
|
|
|
8247
8301
|
let result;
|
|
8248
8302
|
if (options.action === "pipeline") {
|
|
8249
8303
|
result = await runTaskStep(context, task.id, "validate", effectiveIsolation, workerRuntime);
|
|
8250
|
-
if (!context.dryRun) {
|
|
8251
|
-
const validatorResults = await context.plugins.runValidators(task.id);
|
|
8252
|
-
const failedValidators = validatorResults.filter((item) => !item.passed);
|
|
8253
|
-
if (failedValidators.length > 0) {
|
|
8254
|
-
throw new Error(`Plugin validators failed for ${task.id}: ${failedValidators.map((item) => item.id).join(", ")}`);
|
|
8255
|
-
}
|
|
8256
|
-
}
|
|
8257
8304
|
result = await runTaskStep(context, task.id, "verify", effectiveIsolation, workerRuntime);
|
|
8258
8305
|
} else {
|
|
8259
8306
|
result = await runTaskStep(context, task.id, options.action, effectiveIsolation, workerRuntime);
|
|
@@ -8352,12 +8399,12 @@ ${result.stderr.trim()}` : ""}`);
|
|
|
8352
8399
|
}
|
|
8353
8400
|
function resolveTaskCommand(projectRoot, action, taskId, hostProjectRoot = projectRoot) {
|
|
8354
8401
|
try {
|
|
8355
|
-
const compiledRig =
|
|
8356
|
-
if (
|
|
8402
|
+
const compiledRig = resolve37(resolveRigLayout(projectRoot).binDir, "rig");
|
|
8403
|
+
if (existsSync34(compiledRig)) {
|
|
8357
8404
|
return [compiledRig, "task", action, "--task", taskId];
|
|
8358
8405
|
}
|
|
8359
8406
|
} catch {}
|
|
8360
|
-
return ["bun", "run",
|
|
8407
|
+
return ["bun", "run", resolve37(hostProjectRoot, "packages/cli/bin/rig.ts"), "task", action, "--task", taskId];
|
|
8361
8408
|
}
|
|
8362
8409
|
function rankTasks(projectRoot, snapshot) {
|
|
8363
8410
|
const readyTaskIds = listReadyTaskIdsFromTracker(snapshot);
|