@h-rig/runtime 0.0.6-alpha.33 → 0.0.6-alpha.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/rig-agent-dispatch.js +518 -459
- package/dist/bin/rig-agent.js +431 -362
- package/dist/src/control-plane/agent-wrapper.js +523 -464
- package/dist/src/control-plane/harness-main.js +529 -459
- package/dist/src/control-plane/hooks/completion-verification.js +353 -283
- package/dist/src/control-plane/hooks/inject-context.js +158 -99
- package/dist/src/control-plane/hooks/submodule-branch.js +538 -479
- package/dist/src/control-plane/hooks/task-runtime-start.js +538 -479
- package/dist/src/control-plane/materialize-task-config.js +68 -8
- package/dist/src/control-plane/native/git-ops.js +11 -1
- package/dist/src/control-plane/native/harness-cli.js +514 -444
- package/dist/src/control-plane/native/task-ops.js +392 -322
- package/dist/src/control-plane/native/validator.js +159 -100
- package/dist/src/control-plane/native/verifier.js +227 -166
- package/dist/src/control-plane/pi-sessiond/bin.js +62 -0
- package/dist/src/control-plane/pi-sessiond/server.js +62 -0
- package/dist/src/control-plane/pi-sessiond/session-service.js +62 -0
- package/dist/src/control-plane/pi-settings-materializer.js +52 -0
- package/dist/src/control-plane/plugin-host-context.js +59 -0
- package/dist/src/control-plane/runtime/index.js +469 -410
- package/dist/src/control-plane/runtime/isolation/index.js +493 -434
- package/dist/src/control-plane/runtime/isolation.js +493 -434
- package/dist/src/control-plane/runtime/queue.js +411 -352
- package/dist/src/control-plane/tasks/source-lifecycle.js +87 -28
- package/package.json +8 -8
|
@@ -149,32 +149,32 @@ var RIG_DEFINITION_DIRNAME = "rig", RIG_ARTIFACTS_DIRNAME = "artifacts";
|
|
|
149
149
|
var init_layout = () => {};
|
|
150
150
|
|
|
151
151
|
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
152
|
-
import { existsSync as
|
|
153
|
-
import { resolve as
|
|
152
|
+
import { existsSync as existsSync23, readdirSync as readdirSync4, realpathSync } from "fs";
|
|
153
|
+
import { resolve as resolve23 } from "path";
|
|
154
154
|
function toRealPath(path) {
|
|
155
|
-
if (!
|
|
156
|
-
return
|
|
155
|
+
if (!existsSync23(path)) {
|
|
156
|
+
return resolve23(path);
|
|
157
157
|
}
|
|
158
158
|
try {
|
|
159
159
|
return realpathSync.native(path);
|
|
160
160
|
} catch {
|
|
161
|
-
return
|
|
161
|
+
return resolve23(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 (existsSync23(candidate)) {
|
|
168
168
|
candidates.add(toRealPath(candidate));
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
|
-
addPath(
|
|
172
|
-
addPath(
|
|
171
|
+
addPath(resolve23(projectRoot, ".git"));
|
|
172
|
+
addPath(resolve23(workspaceDir, "..", "..", ".git"));
|
|
173
173
|
for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
|
|
174
|
-
addPath(
|
|
174
|
+
addPath(resolve23(repoRoot, ".git"));
|
|
175
175
|
}
|
|
176
|
-
const workspaceGit =
|
|
177
|
-
if (
|
|
176
|
+
const workspaceGit = resolve23(workspaceDir, ".git");
|
|
177
|
+
if (existsSync23(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 (existsSync23(candidate)) {
|
|
186
186
|
candidates.add(toRealPath(candidate));
|
|
187
187
|
}
|
|
188
188
|
};
|
|
@@ -192,11 +192,11 @@ function resolveHostRepoRootPaths(projectRoot) {
|
|
|
192
192
|
addPath(monorepoRoot);
|
|
193
193
|
}
|
|
194
194
|
} catch {}
|
|
195
|
-
const reposDir =
|
|
196
|
-
if (
|
|
195
|
+
const reposDir = resolve23(projectRoot, "repos");
|
|
196
|
+
if (existsSync23(reposDir)) {
|
|
197
197
|
for (const entry of readdirSync4(reposDir, { withFileTypes: true })) {
|
|
198
198
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
199
|
-
addPath(
|
|
199
|
+
addPath(resolve23(reposDir, entry.name));
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
}
|
|
@@ -240,8 +240,8 @@ var exports_backend_seatbelt = {};
|
|
|
240
240
|
__export(exports_backend_seatbelt, {
|
|
241
241
|
SeatbeltBackend: () => SeatbeltBackend
|
|
242
242
|
});
|
|
243
|
-
import { mkdirSync as
|
|
244
|
-
import { resolve as
|
|
243
|
+
import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync13 } from "fs";
|
|
244
|
+
import { resolve as resolve34 } from "path";
|
|
245
245
|
|
|
246
246
|
class SeatbeltBackend {
|
|
247
247
|
kind = "macos-seatbelt";
|
|
@@ -265,11 +265,11 @@ class SeatbeltBackend {
|
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
writeSeatbeltProfile(options) {
|
|
268
|
-
const sandboxDir =
|
|
269
|
-
|
|
270
|
-
const profilePath =
|
|
268
|
+
const sandboxDir = resolve34(options.runtime.rootDir, "sandbox");
|
|
269
|
+
mkdirSync18(sandboxDir, { recursive: true });
|
|
270
|
+
const profilePath = resolve34(sandboxDir, "seatbelt.sb");
|
|
271
271
|
const profile = this.renderProfile(options);
|
|
272
|
-
|
|
272
|
+
writeFileSync13(profilePath, `${profile}
|
|
273
273
|
`, "utf-8");
|
|
274
274
|
return profilePath;
|
|
275
275
|
}
|
|
@@ -354,7 +354,7 @@ class SeatbeltBackend {
|
|
|
354
354
|
const realHome = process.env.HOME?.trim();
|
|
355
355
|
if (realHome) {
|
|
356
356
|
for (const binSubdir of [".local/bin", ".cargo/bin"]) {
|
|
357
|
-
const binPath =
|
|
357
|
+
const binPath = resolve34(realHome, binSubdir);
|
|
358
358
|
if (ctx.pathExists(binPath)) {
|
|
359
359
|
lines.push(`(allow file-read* (subpath ${seatbeltString(ctx.realPath(binPath))}))`);
|
|
360
360
|
}
|
|
@@ -383,8 +383,8 @@ var exports_backend_bwrap = {};
|
|
|
383
383
|
__export(exports_backend_bwrap, {
|
|
384
384
|
BwrapBackend: () => BwrapBackend
|
|
385
385
|
});
|
|
386
|
-
import { mkdirSync as
|
|
387
|
-
import { resolve as
|
|
386
|
+
import { mkdirSync as mkdirSync19 } from "fs";
|
|
387
|
+
import { resolve as resolve35 } from "path";
|
|
388
388
|
|
|
389
389
|
class BwrapBackend {
|
|
390
390
|
kind = "linux-bwrap";
|
|
@@ -513,18 +513,18 @@ class BwrapBackend {
|
|
|
513
513
|
const realHome = process.env.HOME?.trim();
|
|
514
514
|
if (realHome) {
|
|
515
515
|
for (const binSubdir of [".local/bin", ".local/lib", ".cargo/bin"]) {
|
|
516
|
-
const binPath = ctx.realPath(
|
|
516
|
+
const binPath = ctx.realPath(resolve35(realHome, binSubdir));
|
|
517
517
|
if (ctx.pathExists(binPath)) {
|
|
518
518
|
args.push("--ro-bind", binPath, binPath);
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
|
-
const agentSshDir =
|
|
521
|
+
const agentSshDir = resolve35(homeReal, ".ssh");
|
|
522
522
|
if (ctx.pathExists(agentSshDir)) {
|
|
523
523
|
args.push("--ro-bind", agentSshDir, agentSshDir);
|
|
524
524
|
} else {
|
|
525
|
-
const hostSshDir =
|
|
525
|
+
const hostSshDir = resolve35(realHome, ".ssh");
|
|
526
526
|
if (ctx.pathExists(hostSshDir)) {
|
|
527
|
-
|
|
527
|
+
mkdirSync19(agentSshDir, { recursive: true });
|
|
528
528
|
args.push("--ro-bind", hostSshDir, agentSshDir);
|
|
529
529
|
args.push("--ro-bind", hostSshDir, hostSshDir);
|
|
530
530
|
}
|
|
@@ -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 existsSync36 } from "fs";
|
|
571
|
+
import { resolve as resolve38 } 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 existsSync35, mkdirSync as mkdirSync20, readFileSync as readFileSync17, 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 resolve37 } 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 existsSync26, mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "fs";
|
|
3323
|
+
import { resolve as resolve27 } from "path";
|
|
3324
3324
|
|
|
3325
3325
|
// packages/runtime/src/build-time-config.ts
|
|
3326
3326
|
function normalizeBuildConfig(value) {
|
|
@@ -3884,6 +3884,8 @@ function buildBrowserGuidanceLines(browser) {
|
|
|
3884
3884
|
}
|
|
3885
3885
|
|
|
3886
3886
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
3887
|
+
import { existsSync as existsSync19 } from "fs";
|
|
3888
|
+
import { resolve as resolvePath } from "path";
|
|
3887
3889
|
import { createPluginHost } from "@rig/core";
|
|
3888
3890
|
import { loadConfig } from "@rig/core/load-config";
|
|
3889
3891
|
|
|
@@ -4165,6 +4167,55 @@ async function materializeSkills(projectRoot, entries) {
|
|
|
4165
4167
|
return written;
|
|
4166
4168
|
}
|
|
4167
4169
|
|
|
4170
|
+
// packages/runtime/src/control-plane/pi-settings-materializer.ts
|
|
4171
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
4172
|
+
import { dirname as dirname11, resolve as resolve19 } from "path";
|
|
4173
|
+
var SETTINGS_RELATIVE_PATH = ".pi/settings.json";
|
|
4174
|
+
var MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
|
|
4175
|
+
function readJson(path, fallback) {
|
|
4176
|
+
if (!existsSync18(path))
|
|
4177
|
+
return fallback;
|
|
4178
|
+
try {
|
|
4179
|
+
return JSON.parse(readFileSync9(path, "utf-8"));
|
|
4180
|
+
} catch {
|
|
4181
|
+
return fallback;
|
|
4182
|
+
}
|
|
4183
|
+
}
|
|
4184
|
+
function packageKey(entry) {
|
|
4185
|
+
if (typeof entry === "string")
|
|
4186
|
+
return entry;
|
|
4187
|
+
if (entry && typeof entry === "object" && typeof entry.source === "string") {
|
|
4188
|
+
return entry.source;
|
|
4189
|
+
}
|
|
4190
|
+
return JSON.stringify(entry);
|
|
4191
|
+
}
|
|
4192
|
+
function materializePiPackages(projectRoot, declaredPackages) {
|
|
4193
|
+
const settingsPath = resolve19(projectRoot, SETTINGS_RELATIVE_PATH);
|
|
4194
|
+
const managedRecordPath = resolve19(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
|
|
4195
|
+
const settings = readJson(settingsPath, {});
|
|
4196
|
+
const previouslyManaged = new Set(readJson(managedRecordPath, []));
|
|
4197
|
+
const existing = Array.isArray(settings.packages) ? settings.packages : [];
|
|
4198
|
+
const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
|
|
4199
|
+
const operatorKeys = new Set(operatorEntries.map(packageKey));
|
|
4200
|
+
const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
|
|
4201
|
+
const nextPackages = [...operatorEntries, ...managedToAdd];
|
|
4202
|
+
if (nextPackages.length > 0 || existsSync18(settingsPath)) {
|
|
4203
|
+
const nextSettings = { ...settings };
|
|
4204
|
+
if (nextPackages.length > 0) {
|
|
4205
|
+
nextSettings.packages = nextPackages;
|
|
4206
|
+
} else {
|
|
4207
|
+
delete nextSettings.packages;
|
|
4208
|
+
}
|
|
4209
|
+
mkdirSync9(dirname11(settingsPath), { recursive: true });
|
|
4210
|
+
writeFileSync7(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
|
|
4211
|
+
`, "utf-8");
|
|
4212
|
+
}
|
|
4213
|
+
mkdirSync9(dirname11(managedRecordPath), { recursive: true });
|
|
4214
|
+
writeFileSync7(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
|
|
4215
|
+
`, "utf-8");
|
|
4216
|
+
return { settingsPath, packages: managedToAdd };
|
|
4217
|
+
}
|
|
4218
|
+
|
|
4168
4219
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
4169
4220
|
async function buildPluginHostContext(projectRoot) {
|
|
4170
4221
|
let config;
|
|
@@ -4212,6 +4263,14 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
4212
4263
|
} catch (err) {
|
|
4213
4264
|
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
4214
4265
|
}
|
|
4266
|
+
try {
|
|
4267
|
+
const piPackages = config.runtime?.pi?.packages ?? [];
|
|
4268
|
+
if (piPackages.length > 0 || existsSync19(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
|
|
4269
|
+
materializePiPackages(projectRoot, piPackages);
|
|
4270
|
+
}
|
|
4271
|
+
} catch (err) {
|
|
4272
|
+
console.warn(`[plugin-host] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
4273
|
+
}
|
|
4215
4274
|
return {
|
|
4216
4275
|
config,
|
|
4217
4276
|
pluginHost,
|
|
@@ -4225,12 +4284,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
4225
4284
|
|
|
4226
4285
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
4227
4286
|
import { spawnSync } from "child_process";
|
|
4228
|
-
import { existsSync as
|
|
4229
|
-
import { basename as basename6, join as join4, resolve as
|
|
4287
|
+
import { existsSync as existsSync21, readFileSync as readFileSync11, readdirSync as readdirSync3, statSync as statSync5, writeFileSync as writeFileSync8 } from "fs";
|
|
4288
|
+
import { basename as basename6, join as join4, resolve as resolve21 } from "path";
|
|
4230
4289
|
|
|
4231
4290
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
4232
|
-
import { existsSync as
|
|
4233
|
-
import { resolve as
|
|
4291
|
+
import { existsSync as existsSync20, readFileSync as readFileSync10 } from "fs";
|
|
4292
|
+
import { resolve as resolve20 } from "path";
|
|
4234
4293
|
|
|
4235
4294
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
4236
4295
|
async function findTaskById(reader, id) {
|
|
@@ -4253,7 +4312,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
4253
4312
|
}
|
|
4254
4313
|
}
|
|
4255
4314
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
4256
|
-
const configPath = options.configPath ??
|
|
4315
|
+
const configPath = options.configPath ?? resolve20(projectRoot, ".rig", "task-config.json");
|
|
4257
4316
|
const reader = {
|
|
4258
4317
|
async listTasks() {
|
|
4259
4318
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -4264,8 +4323,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
4264
4323
|
};
|
|
4265
4324
|
return reader;
|
|
4266
4325
|
}
|
|
4267
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
4268
|
-
if (!
|
|
4326
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve20(projectRoot, ".rig", "task-config.json")) {
|
|
4327
|
+
if (!existsSync20(configPath)) {
|
|
4269
4328
|
return [];
|
|
4270
4329
|
}
|
|
4271
4330
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -4273,7 +4332,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve19(projectRoot,
|
|
|
4273
4332
|
}
|
|
4274
4333
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
4275
4334
|
try {
|
|
4276
|
-
const parsed = JSON.parse(
|
|
4335
|
+
const parsed = JSON.parse(readFileSync10(configPath, "utf8"));
|
|
4277
4336
|
if (isPlainRecord(parsed)) {
|
|
4278
4337
|
return parsed;
|
|
4279
4338
|
}
|
|
@@ -4357,7 +4416,7 @@ function isPlainRecord(candidate) {
|
|
|
4357
4416
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
4358
4417
|
var FILE_TASK_PATTERN2 = /\.(task\.)?json$/;
|
|
4359
4418
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
4360
|
-
const configPath = options.configPath ??
|
|
4419
|
+
const configPath = options.configPath ?? resolve21(projectRoot, ".rig", "task-config.json");
|
|
4361
4420
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
4362
4421
|
const spawnFn = options.spawn ?? spawnSync;
|
|
4363
4422
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -4440,10 +4499,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
4440
4499
|
return metadata;
|
|
4441
4500
|
}
|
|
4442
4501
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
4443
|
-
const jsonPath =
|
|
4444
|
-
if (
|
|
4502
|
+
const jsonPath = resolve21(projectRoot, "rig.config.json");
|
|
4503
|
+
if (existsSync21(jsonPath)) {
|
|
4445
4504
|
try {
|
|
4446
|
-
const parsed = JSON.parse(
|
|
4505
|
+
const parsed = JSON.parse(readFileSync11(jsonPath, "utf8"));
|
|
4447
4506
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
4448
4507
|
const source = parsed.taskSource;
|
|
4449
4508
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -4452,12 +4511,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
4452
4511
|
return null;
|
|
4453
4512
|
}
|
|
4454
4513
|
}
|
|
4455
|
-
const tsPath =
|
|
4456
|
-
if (!
|
|
4514
|
+
const tsPath = resolve21(projectRoot, "rig.config.ts");
|
|
4515
|
+
if (!existsSync21(tsPath)) {
|
|
4457
4516
|
return null;
|
|
4458
4517
|
}
|
|
4459
4518
|
try {
|
|
4460
|
-
const source =
|
|
4519
|
+
const source = readFileSync11(tsPath, "utf8");
|
|
4461
4520
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
4462
4521
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
4463
4522
|
if (kind !== "files") {
|
|
@@ -4477,10 +4536,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
4477
4536
|
return isPlainRecord2(entry) ? entry : null;
|
|
4478
4537
|
}
|
|
4479
4538
|
function readRawTaskConfig(configPath) {
|
|
4480
|
-
if (!
|
|
4539
|
+
if (!existsSync21(configPath)) {
|
|
4481
4540
|
return null;
|
|
4482
4541
|
}
|
|
4483
|
-
const parsed = JSON.parse(
|
|
4542
|
+
const parsed = JSON.parse(readFileSync11(configPath, "utf8"));
|
|
4484
4543
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
4485
4544
|
}
|
|
4486
4545
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -4488,8 +4547,8 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
4488
4547
|
return tasks;
|
|
4489
4548
|
}
|
|
4490
4549
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
4491
|
-
const directory =
|
|
4492
|
-
if (!
|
|
4550
|
+
const directory = resolve21(projectRoot, sourcePath);
|
|
4551
|
+
if (!existsSync21(directory)) {
|
|
4493
4552
|
return [];
|
|
4494
4553
|
}
|
|
4495
4554
|
const tasks = [];
|
|
@@ -4504,11 +4563,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
4504
4563
|
return tasks;
|
|
4505
4564
|
}
|
|
4506
4565
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
4507
|
-
const file = findFileBackedTaskFile(
|
|
4566
|
+
const file = findFileBackedTaskFile(resolve21(projectRoot, sourcePath), taskId);
|
|
4508
4567
|
if (!file) {
|
|
4509
4568
|
return null;
|
|
4510
4569
|
}
|
|
4511
|
-
const raw = JSON.parse(
|
|
4570
|
+
const raw = JSON.parse(readFileSync11(file, "utf8"));
|
|
4512
4571
|
if (!isPlainRecord2(raw)) {
|
|
4513
4572
|
return null;
|
|
4514
4573
|
}
|
|
@@ -4521,7 +4580,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
4521
4580
|
};
|
|
4522
4581
|
}
|
|
4523
4582
|
function findFileBackedTaskFile(directory, taskId) {
|
|
4524
|
-
if (!
|
|
4583
|
+
if (!existsSync21(directory)) {
|
|
4525
4584
|
return null;
|
|
4526
4585
|
}
|
|
4527
4586
|
for (const name of readdirSync3(directory)) {
|
|
@@ -4531,7 +4590,7 @@ function findFileBackedTaskFile(directory, taskId) {
|
|
|
4531
4590
|
try {
|
|
4532
4591
|
if (!statSync5(file).isFile())
|
|
4533
4592
|
continue;
|
|
4534
|
-
const raw = JSON.parse(
|
|
4593
|
+
const raw = JSON.parse(readFileSync11(file, "utf8"));
|
|
4535
4594
|
const inferredId = basename6(file).replace(FILE_TASK_PATTERN2, "");
|
|
4536
4595
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
4537
4596
|
if (id === taskId) {
|
|
@@ -4695,8 +4754,8 @@ init_layout();
|
|
|
4695
4754
|
|
|
4696
4755
|
// packages/runtime/src/binary-run.ts
|
|
4697
4756
|
init_layout();
|
|
4698
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
4699
|
-
import { basename as basename7, dirname as
|
|
4757
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync22, mkdirSync as mkdirSync10, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
4758
|
+
import { basename as basename7, dirname as dirname12, resolve as resolve22 } from "path";
|
|
4700
4759
|
import { fileURLToPath } from "url";
|
|
4701
4760
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
4702
4761
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -4722,9 +4781,9 @@ async function buildRuntimeBinary(options) {
|
|
|
4722
4781
|
});
|
|
4723
4782
|
}
|
|
4724
4783
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
4725
|
-
const tempBuildDir =
|
|
4726
|
-
const tempOutputPath =
|
|
4727
|
-
|
|
4784
|
+
const tempBuildDir = resolve22(dirname12(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4785
|
+
const tempOutputPath = resolve22(tempBuildDir, basename7(options.outputPath));
|
|
4786
|
+
mkdirSync10(tempBuildDir, { recursive: true });
|
|
4728
4787
|
await withTemporaryEnv({
|
|
4729
4788
|
...options.env,
|
|
4730
4789
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -4749,7 +4808,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4749
4808
|
`);
|
|
4750
4809
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
4751
4810
|
}
|
|
4752
|
-
if (!
|
|
4811
|
+
if (!existsSync22(tempOutputPath)) {
|
|
4753
4812
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
4754
4813
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
4755
4814
|
}
|
|
@@ -4781,8 +4840,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4781
4840
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4782
4841
|
return {
|
|
4783
4842
|
...options,
|
|
4784
|
-
entrypoint:
|
|
4785
|
-
outputPath:
|
|
4843
|
+
entrypoint: resolve22(options.cwd, options.sourcePath),
|
|
4844
|
+
outputPath: resolve22(options.outputPath)
|
|
4786
4845
|
};
|
|
4787
4846
|
}
|
|
4788
4847
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4796,7 +4855,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4796
4855
|
}
|
|
4797
4856
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4798
4857
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4799
|
-
if (!workerSourcePath || !
|
|
4858
|
+
if (!workerSourcePath || !existsSync22(workerSourcePath)) {
|
|
4800
4859
|
await buildRuntimeBinaryInProcess(options, {
|
|
4801
4860
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4802
4861
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4833,7 +4892,7 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4833
4892
|
}
|
|
4834
4893
|
}
|
|
4835
4894
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4836
|
-
return
|
|
4895
|
+
return resolve22(dirname12(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4837
4896
|
}
|
|
4838
4897
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4839
4898
|
const envRoots = [
|
|
@@ -4842,13 +4901,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4842
4901
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4843
4902
|
].filter(Boolean);
|
|
4844
4903
|
for (const root of envRoots) {
|
|
4845
|
-
const candidate =
|
|
4846
|
-
if (
|
|
4904
|
+
const candidate = resolve22(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4905
|
+
if (existsSync22(candidate)) {
|
|
4847
4906
|
return candidate;
|
|
4848
4907
|
}
|
|
4849
4908
|
}
|
|
4850
|
-
const localCandidate =
|
|
4851
|
-
return
|
|
4909
|
+
const localCandidate = resolve22(import.meta.dir, "binary-build-worker.ts");
|
|
4910
|
+
return existsSync22(localCandidate) ? localCandidate : null;
|
|
4852
4911
|
}
|
|
4853
4912
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4854
4913
|
const bunPath = Bun.which("bun");
|
|
@@ -4884,7 +4943,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4884
4943
|
});
|
|
4885
4944
|
}
|
|
4886
4945
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4887
|
-
if (!
|
|
4946
|
+
if (!existsSync22(input.outputPath) || !existsSync22(input.manifestPath)) {
|
|
4888
4947
|
return false;
|
|
4889
4948
|
}
|
|
4890
4949
|
let manifest = null;
|
|
@@ -4897,7 +4956,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4897
4956
|
return false;
|
|
4898
4957
|
}
|
|
4899
4958
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4900
|
-
if (!
|
|
4959
|
+
if (!existsSync22(filePath)) {
|
|
4901
4960
|
return false;
|
|
4902
4961
|
}
|
|
4903
4962
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4910,7 +4969,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4910
4969
|
const inputs = {};
|
|
4911
4970
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4912
4971
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4913
|
-
if (!normalized || !
|
|
4972
|
+
if (!normalized || !existsSync22(normalized)) {
|
|
4914
4973
|
continue;
|
|
4915
4974
|
}
|
|
4916
4975
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4933,7 +4992,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4933
4992
|
if (inputPath.startsWith("<")) {
|
|
4934
4993
|
return null;
|
|
4935
4994
|
}
|
|
4936
|
-
return
|
|
4995
|
+
return resolve22(cwd, inputPath);
|
|
4937
4996
|
}
|
|
4938
4997
|
async function sha256File4(path) {
|
|
4939
4998
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4949,8 +5008,8 @@ function sortRecord(value) {
|
|
|
4949
5008
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4950
5009
|
const previous = runtimeBinaryBuildQueue;
|
|
4951
5010
|
let release;
|
|
4952
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4953
|
-
release =
|
|
5011
|
+
runtimeBinaryBuildQueue = new Promise((resolve23) => {
|
|
5012
|
+
release = resolve23;
|
|
4954
5013
|
});
|
|
4955
5014
|
await previous;
|
|
4956
5015
|
try {
|
|
@@ -4995,11 +5054,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4995
5054
|
}
|
|
4996
5055
|
|
|
4997
5056
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4998
|
-
import { delimiter, resolve as
|
|
5057
|
+
import { delimiter, resolve as resolve25 } from "path";
|
|
4999
5058
|
|
|
5000
5059
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
5001
|
-
import { existsSync as
|
|
5002
|
-
import { resolve as
|
|
5060
|
+
import { existsSync as existsSync24, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
5061
|
+
import { resolve as resolve24 } from "path";
|
|
5003
5062
|
|
|
5004
5063
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
5005
5064
|
init_utils();
|
|
@@ -5016,7 +5075,7 @@ function resolveBunBinaryPath() {
|
|
|
5016
5075
|
}
|
|
5017
5076
|
const home = process.env.HOME?.trim();
|
|
5018
5077
|
const fallbackCandidates = [
|
|
5019
|
-
home ?
|
|
5078
|
+
home ? resolve24(home, ".bun/bin/bun") : "",
|
|
5020
5079
|
"/opt/homebrew/bin/bun",
|
|
5021
5080
|
"/usr/local/bin/bun",
|
|
5022
5081
|
"/usr/bin/bun"
|
|
@@ -5044,8 +5103,8 @@ function resolveClaudeBinaryPath() {
|
|
|
5044
5103
|
}
|
|
5045
5104
|
const home = process.env.HOME?.trim();
|
|
5046
5105
|
const fallbackCandidates = [
|
|
5047
|
-
home ?
|
|
5048
|
-
home ?
|
|
5106
|
+
home ? resolve24(home, ".local/bin/claude") : "",
|
|
5107
|
+
home ? resolve24(home, ".local/share/claude/local/claude") : "",
|
|
5049
5108
|
"/opt/homebrew/bin/claude",
|
|
5050
5109
|
"/usr/local/bin/claude",
|
|
5051
5110
|
"/usr/bin/claude"
|
|
@@ -5059,35 +5118,35 @@ function resolveClaudeBinaryPath() {
|
|
|
5059
5118
|
throw new Error("claude not found in PATH");
|
|
5060
5119
|
}
|
|
5061
5120
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
5062
|
-
return
|
|
5121
|
+
return resolve24(bunBinaryPath, "../..");
|
|
5063
5122
|
}
|
|
5064
5123
|
function resolveClaudeInstallDir() {
|
|
5065
5124
|
const realPath = resolveClaudeBinaryPath();
|
|
5066
|
-
return
|
|
5125
|
+
return resolve24(realPath, "..");
|
|
5067
5126
|
}
|
|
5068
5127
|
function resolveNodeInstallDir() {
|
|
5069
5128
|
const preferredNode = resolvePreferredNodeBinary();
|
|
5070
5129
|
if (!preferredNode)
|
|
5071
5130
|
return null;
|
|
5072
5131
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
5073
|
-
if (explicitNode &&
|
|
5074
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
5132
|
+
if (explicitNode && resolve24(explicitNode) === resolve24(preferredNode)) {
|
|
5133
|
+
return preferredNode.endsWith("/bin/node") ? resolve24(preferredNode, "../..") : resolve24(preferredNode, "..");
|
|
5075
5134
|
}
|
|
5076
5135
|
try {
|
|
5077
5136
|
const realPath = realpathSync2(preferredNode);
|
|
5078
5137
|
if (realPath.endsWith("/bin/node")) {
|
|
5079
|
-
return
|
|
5138
|
+
return resolve24(realPath, "../..");
|
|
5080
5139
|
}
|
|
5081
|
-
return
|
|
5140
|
+
return resolve24(realPath, "..");
|
|
5082
5141
|
} catch {
|
|
5083
|
-
return
|
|
5142
|
+
return resolve24(preferredNode, "..");
|
|
5084
5143
|
}
|
|
5085
5144
|
}
|
|
5086
5145
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
5087
5146
|
const roots = [];
|
|
5088
5147
|
if (process.platform === "darwin") {
|
|
5089
5148
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
5090
|
-
if (
|
|
5149
|
+
if (existsSync24(macPath)) {
|
|
5091
5150
|
roots.push(macPath);
|
|
5092
5151
|
}
|
|
5093
5152
|
}
|
|
@@ -5105,23 +5164,23 @@ function resolvePreferredNodeBinary() {
|
|
|
5105
5164
|
const candidates = [];
|
|
5106
5165
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
5107
5166
|
if (envNode) {
|
|
5108
|
-
const explicit =
|
|
5109
|
-
if (
|
|
5167
|
+
const explicit = resolve24(envNode);
|
|
5168
|
+
if (existsSync24(explicit)) {
|
|
5110
5169
|
return explicit;
|
|
5111
5170
|
}
|
|
5112
5171
|
}
|
|
5113
5172
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
5114
5173
|
if (nvmBin) {
|
|
5115
|
-
candidates.push(
|
|
5174
|
+
candidates.push(resolve24(nvmBin, "node"));
|
|
5116
5175
|
}
|
|
5117
5176
|
const home = process.env.HOME?.trim();
|
|
5118
5177
|
if (home) {
|
|
5119
|
-
const nvmVersionsDir =
|
|
5120
|
-
if (
|
|
5178
|
+
const nvmVersionsDir = resolve24(home, ".nvm/versions/node");
|
|
5179
|
+
if (existsSync24(nvmVersionsDir)) {
|
|
5121
5180
|
try {
|
|
5122
5181
|
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/, "")));
|
|
5123
5182
|
for (const versionDir of versionDirs) {
|
|
5124
|
-
candidates.push(
|
|
5183
|
+
candidates.push(resolve24(nvmVersionsDir, versionDir, "bin/node"));
|
|
5125
5184
|
}
|
|
5126
5185
|
} catch {}
|
|
5127
5186
|
}
|
|
@@ -5130,8 +5189,8 @@ function resolvePreferredNodeBinary() {
|
|
|
5130
5189
|
if (whichNode) {
|
|
5131
5190
|
candidates.push(whichNode);
|
|
5132
5191
|
}
|
|
5133
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
5134
|
-
const existing = deduped.filter((candidate) =>
|
|
5192
|
+
const deduped = uniq(candidates.map((candidate) => resolve24(candidate)));
|
|
5193
|
+
const existing = deduped.filter((candidate) => existsSync24(candidate));
|
|
5135
5194
|
if (existing.length === 0) {
|
|
5136
5195
|
return null;
|
|
5137
5196
|
}
|
|
@@ -5145,7 +5204,7 @@ function resolvePreferredNodeBinary() {
|
|
|
5145
5204
|
return existing[0] ?? null;
|
|
5146
5205
|
}
|
|
5147
5206
|
function inferNodeMajor(nodeBinaryPath) {
|
|
5148
|
-
const normalized =
|
|
5207
|
+
const normalized = resolve24(nodeBinaryPath).replace(/\\/g, "/");
|
|
5149
5208
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
5150
5209
|
if (!match) {
|
|
5151
5210
|
return null;
|
|
@@ -5157,8 +5216,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
5157
5216
|
if (!candidate) {
|
|
5158
5217
|
return "";
|
|
5159
5218
|
}
|
|
5160
|
-
const normalized =
|
|
5161
|
-
if (!
|
|
5219
|
+
const normalized = resolve24(candidate);
|
|
5220
|
+
if (!existsSync24(normalized)) {
|
|
5162
5221
|
return "";
|
|
5163
5222
|
}
|
|
5164
5223
|
try {
|
|
@@ -5168,7 +5227,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
5168
5227
|
}
|
|
5169
5228
|
}
|
|
5170
5229
|
function looksLikeRuntimeGateway(candidate) {
|
|
5171
|
-
const normalized =
|
|
5230
|
+
const normalized = resolve24(candidate).replace(/\\/g, "/");
|
|
5172
5231
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
5173
5232
|
}
|
|
5174
5233
|
|
|
@@ -5189,7 +5248,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5189
5248
|
try {
|
|
5190
5249
|
return resolveClaudeInstallDir();
|
|
5191
5250
|
} catch {
|
|
5192
|
-
return
|
|
5251
|
+
return resolve25(claudeBinary, "..");
|
|
5193
5252
|
}
|
|
5194
5253
|
})() : "";
|
|
5195
5254
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -5199,8 +5258,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5199
5258
|
`${bunDir}/bin`,
|
|
5200
5259
|
claudeDir,
|
|
5201
5260
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
5202
|
-
realHome ?
|
|
5203
|
-
realHome ?
|
|
5261
|
+
realHome ? resolve25(realHome, ".local/bin") : "",
|
|
5262
|
+
realHome ? resolve25(realHome, ".cargo/bin") : "",
|
|
5204
5263
|
...inheritedPath,
|
|
5205
5264
|
"/usr/local/bin",
|
|
5206
5265
|
"/usr/local/sbin",
|
|
@@ -5229,8 +5288,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5229
5288
|
}
|
|
5230
5289
|
|
|
5231
5290
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
5232
|
-
import { existsSync as
|
|
5233
|
-
import { resolve as
|
|
5291
|
+
import { existsSync as existsSync25, readFileSync as readFileSync12 } from "fs";
|
|
5292
|
+
import { resolve as resolve26 } from "path";
|
|
5234
5293
|
var BAKED_RUNTIME_SECRETS = {
|
|
5235
5294
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
5236
5295
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -5273,12 +5332,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
5273
5332
|
return resolved;
|
|
5274
5333
|
}
|
|
5275
5334
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
5276
|
-
const dotenvPath =
|
|
5277
|
-
if (!
|
|
5335
|
+
const dotenvPath = resolve26(projectRoot, ".env");
|
|
5336
|
+
if (!existsSync25(dotenvPath)) {
|
|
5278
5337
|
return {};
|
|
5279
5338
|
}
|
|
5280
5339
|
const parsed = {};
|
|
5281
|
-
const lines =
|
|
5340
|
+
const lines = readFileSync12(dotenvPath, "utf-8").split(/\r?\n/);
|
|
5282
5341
|
for (const rawLine of lines) {
|
|
5283
5342
|
const line = rawLine.trim();
|
|
5284
5343
|
if (!line || line.startsWith("#")) {
|
|
@@ -5635,16 +5694,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
5635
5694
|
for (const dep of deps) {
|
|
5636
5695
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
5637
5696
|
console.log(`=== ${dep} ===`);
|
|
5638
|
-
if (!
|
|
5697
|
+
if (!existsSync26(artifactDir)) {
|
|
5639
5698
|
console.log(` (no artifacts yet)
|
|
5640
5699
|
`);
|
|
5641
5700
|
continue;
|
|
5642
5701
|
}
|
|
5643
|
-
printArtifactSection(
|
|
5644
|
-
printArtifactSection(
|
|
5645
|
-
const changedFiles =
|
|
5646
|
-
if (
|
|
5647
|
-
const lines =
|
|
5702
|
+
printArtifactSection(resolve27(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
5703
|
+
printArtifactSection(resolve27(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
5704
|
+
const changedFiles = resolve27(artifactDir, "changed-files.txt");
|
|
5705
|
+
if (existsSync26(changedFiles)) {
|
|
5706
|
+
const lines = readFileSync13(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
5648
5707
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
5649
5708
|
for (const line of lines) {
|
|
5650
5709
|
console.log(line);
|
|
@@ -5768,12 +5827,12 @@ function printIndented(text) {
|
|
|
5768
5827
|
}
|
|
5769
5828
|
}
|
|
5770
5829
|
function readLocalBeadsTasks(projectRoot) {
|
|
5771
|
-
const issuesPath =
|
|
5772
|
-
if (!
|
|
5830
|
+
const issuesPath = resolve27(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5831
|
+
if (!existsSync26(issuesPath)) {
|
|
5773
5832
|
return [];
|
|
5774
5833
|
}
|
|
5775
5834
|
const tasks = [];
|
|
5776
|
-
for (const line of
|
|
5835
|
+
for (const line of readFileSync13(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
5777
5836
|
const trimmed = line.trim();
|
|
5778
5837
|
if (!trimmed) {
|
|
5779
5838
|
continue;
|
|
@@ -5886,11 +5945,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5886
5945
|
return [...ids].sort();
|
|
5887
5946
|
}
|
|
5888
5947
|
function printArtifactSection(path, header) {
|
|
5889
|
-
if (!
|
|
5948
|
+
if (!existsSync26(path)) {
|
|
5890
5949
|
return;
|
|
5891
5950
|
}
|
|
5892
5951
|
console.log(header);
|
|
5893
|
-
process.stdout.write(
|
|
5952
|
+
process.stdout.write(readFileSync13(path, "utf-8"));
|
|
5894
5953
|
console.log("");
|
|
5895
5954
|
}
|
|
5896
5955
|
|
|
@@ -5992,7 +6051,7 @@ init_layout();
|
|
|
5992
6051
|
|
|
5993
6052
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5994
6053
|
init_layout();
|
|
5995
|
-
import { mkdirSync as
|
|
6054
|
+
import { mkdirSync as mkdirSync12 } from "fs";
|
|
5996
6055
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5997
6056
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5998
6057
|
const rootDir = layout.rigRoot;
|
|
@@ -6004,14 +6063,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
6004
6063
|
const sessionDir = layout.sessionDir;
|
|
6005
6064
|
const runtimeDir = layout.runtimeDir;
|
|
6006
6065
|
const contextPath = layout.contextPath;
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6066
|
+
mkdirSync12(rootDir, { recursive: true });
|
|
6067
|
+
mkdirSync12(homeDir, { recursive: true });
|
|
6068
|
+
mkdirSync12(tmpDir, { recursive: true });
|
|
6069
|
+
mkdirSync12(cacheDir, { recursive: true });
|
|
6070
|
+
mkdirSync12(logsDir, { recursive: true });
|
|
6071
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
6072
|
+
mkdirSync12(sessionDir, { recursive: true });
|
|
6073
|
+
mkdirSync12(runtimeDir, { recursive: true });
|
|
6015
6074
|
return {
|
|
6016
6075
|
rootDir,
|
|
6017
6076
|
homeDir,
|
|
@@ -6029,17 +6088,17 @@ import {
|
|
|
6029
6088
|
chmodSync as chmodSync5,
|
|
6030
6089
|
copyFileSync as copyFileSync5,
|
|
6031
6090
|
cpSync as cpSync2,
|
|
6032
|
-
existsSync as
|
|
6033
|
-
mkdirSync as
|
|
6091
|
+
existsSync as existsSync28,
|
|
6092
|
+
mkdirSync as mkdirSync13,
|
|
6034
6093
|
statSync as statSync6,
|
|
6035
|
-
writeFileSync as
|
|
6094
|
+
writeFileSync as writeFileSync11
|
|
6036
6095
|
} from "fs";
|
|
6037
6096
|
import { mkdir as mkdir2 } from "fs/promises";
|
|
6038
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
6097
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve29 } from "path";
|
|
6039
6098
|
|
|
6040
6099
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
6041
|
-
import { existsSync as
|
|
6042
|
-
import { resolve as
|
|
6100
|
+
import { existsSync as existsSync27, readFileSync as readFileSync14, rmSync as rmSync9 } from "fs";
|
|
6101
|
+
import { resolve as resolve28 } from "path";
|
|
6043
6102
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
6044
6103
|
var generatedCredentialFiles = new Set;
|
|
6045
6104
|
var credentialCleanupRegistered = false;
|
|
@@ -6064,7 +6123,7 @@ function resolveHostGitBinary() {
|
|
|
6064
6123
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
6065
6124
|
continue;
|
|
6066
6125
|
}
|
|
6067
|
-
if (
|
|
6126
|
+
if (existsSync27(candidate)) {
|
|
6068
6127
|
return candidate;
|
|
6069
6128
|
}
|
|
6070
6129
|
}
|
|
@@ -6130,7 +6189,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
6130
6189
|
}
|
|
6131
6190
|
}
|
|
6132
6191
|
async function tryReadGitHead(repoRoot) {
|
|
6133
|
-
if (!
|
|
6192
|
+
if (!existsSync27(resolve28(repoRoot, ".git"))) {
|
|
6134
6193
|
return;
|
|
6135
6194
|
}
|
|
6136
6195
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -6141,7 +6200,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
6141
6200
|
return value || undefined;
|
|
6142
6201
|
}
|
|
6143
6202
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
6144
|
-
if (!
|
|
6203
|
+
if (!existsSync27(resolve28(repoRoot, ".git"))) {
|
|
6145
6204
|
return [];
|
|
6146
6205
|
}
|
|
6147
6206
|
const files = new Set;
|
|
@@ -6232,16 +6291,16 @@ function hashProjectPath(workspaceDir) {
|
|
|
6232
6291
|
}
|
|
6233
6292
|
function resolveGithubCliBinaryPath() {
|
|
6234
6293
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
6235
|
-
if (explicit &&
|
|
6294
|
+
if (explicit && existsSync27(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
6236
6295
|
return explicit;
|
|
6237
6296
|
}
|
|
6238
6297
|
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
6239
|
-
if (
|
|
6298
|
+
if (existsSync27(candidate)) {
|
|
6240
6299
|
return candidate;
|
|
6241
6300
|
}
|
|
6242
6301
|
}
|
|
6243
6302
|
const bunResolved = Bun.which("gh");
|
|
6244
|
-
if (bunResolved &&
|
|
6303
|
+
if (bunResolved && existsSync27(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
6245
6304
|
return bunResolved;
|
|
6246
6305
|
}
|
|
6247
6306
|
return "";
|
|
@@ -6275,17 +6334,17 @@ function resolveSystemCertBundlePath() {
|
|
|
6275
6334
|
"/opt/homebrew/etc/openssl@3/cert.pem"
|
|
6276
6335
|
];
|
|
6277
6336
|
for (const candidate of candidates) {
|
|
6278
|
-
if (candidate &&
|
|
6279
|
-
return
|
|
6337
|
+
if (candidate && existsSync27(candidate)) {
|
|
6338
|
+
return resolve28(candidate);
|
|
6280
6339
|
}
|
|
6281
6340
|
}
|
|
6282
6341
|
return "";
|
|
6283
6342
|
}
|
|
6284
6343
|
function readKnownHosts(path) {
|
|
6285
|
-
if (!
|
|
6344
|
+
if (!existsSync27(path)) {
|
|
6286
6345
|
return new Set;
|
|
6287
6346
|
}
|
|
6288
|
-
return new Set(
|
|
6347
|
+
return new Set(readFileSync14(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
6289
6348
|
}
|
|
6290
6349
|
|
|
6291
6350
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -6300,12 +6359,12 @@ function resolveControlPlaneSourceRoot(projectRoot) {
|
|
|
6300
6359
|
const candidates = [
|
|
6301
6360
|
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
6302
6361
|
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
6303
|
-
|
|
6362
|
+
resolve29(import.meta.dir, "../../../../.."),
|
|
6304
6363
|
projectRoot
|
|
6305
6364
|
].filter((value) => Boolean(value));
|
|
6306
6365
|
for (const candidate of candidates) {
|
|
6307
|
-
const root =
|
|
6308
|
-
if (
|
|
6366
|
+
const root = resolve29(candidate);
|
|
6367
|
+
if (existsSync28(resolve29(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
6309
6368
|
return root;
|
|
6310
6369
|
}
|
|
6311
6370
|
}
|
|
@@ -6325,7 +6384,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6325
6384
|
try {
|
|
6326
6385
|
return resolveClaudeInstallDir();
|
|
6327
6386
|
} catch {
|
|
6328
|
-
return
|
|
6387
|
+
return resolve29(claudeBinaryPath, "..");
|
|
6329
6388
|
}
|
|
6330
6389
|
})() : "";
|
|
6331
6390
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -6340,8 +6399,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6340
6399
|
`${bunDir}/bin`,
|
|
6341
6400
|
claudeDir,
|
|
6342
6401
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
6343
|
-
realHome ?
|
|
6344
|
-
realHome ?
|
|
6402
|
+
realHome ? resolve29(realHome, ".local/bin") : "",
|
|
6403
|
+
realHome ? resolve29(realHome, ".cargo/bin") : "",
|
|
6345
6404
|
...inheritedPath,
|
|
6346
6405
|
"/usr/local/bin",
|
|
6347
6406
|
"/usr/local/sbin",
|
|
@@ -6352,9 +6411,9 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6352
6411
|
"/usr/sbin",
|
|
6353
6412
|
"/sbin"
|
|
6354
6413
|
].filter(Boolean);
|
|
6355
|
-
const runtimeBash =
|
|
6356
|
-
const runtimeRigGit =
|
|
6357
|
-
const preferredShell =
|
|
6414
|
+
const runtimeBash = resolve29(runtime.binDir, "bash");
|
|
6415
|
+
const runtimeRigGit = resolve29(runtime.binDir, runtimeRigGitFileName());
|
|
6416
|
+
const preferredShell = existsSync28(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
6358
6417
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
6359
6418
|
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
6360
6419
|
const env = {
|
|
@@ -6375,30 +6434,30 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6375
6434
|
RIG_RUNTIME_MODE: runtime.mode,
|
|
6376
6435
|
RIG_RUNTIME_HOME: runtime.rootDir,
|
|
6377
6436
|
RIG_RUNTIME_BIN_DIR: runtime.binDir,
|
|
6378
|
-
...
|
|
6437
|
+
...existsSync28(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
|
|
6379
6438
|
RIG_BUN_PATH: bunBinaryPath,
|
|
6380
6439
|
...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
|
|
6381
|
-
RIG_AGENT_BIN:
|
|
6440
|
+
RIG_AGENT_BIN: resolve29(runtime.binDir, "rig-agent"),
|
|
6382
6441
|
RIG_HOOKS_ACTIVE: "1",
|
|
6383
6442
|
RIG_AUTO_PR_ON_COMPLETE: "1",
|
|
6384
|
-
RIG_POLICY_FILE:
|
|
6443
|
+
RIG_POLICY_FILE: resolve29(projectRoot, "rig/policy/policy.json"),
|
|
6385
6444
|
RIG_STATE_DIR: runtime.stateDir,
|
|
6386
6445
|
RIG_LOGS_DIR: runtime.logsDir,
|
|
6387
|
-
RIG_SESSION_FILE:
|
|
6446
|
+
RIG_SESSION_FILE: resolve29(runtime.sessionDir, "session.json"),
|
|
6388
6447
|
MONOREPO_ROOT: runtime.workspaceDir,
|
|
6389
6448
|
MONOREPO_MAIN_ROOT: monorepoMainRoot,
|
|
6390
|
-
TS_API_TESTS_DIR:
|
|
6449
|
+
TS_API_TESTS_DIR: resolve29(runtime.workspaceDir, "TSAPITests"),
|
|
6391
6450
|
BASH: preferredShell,
|
|
6392
6451
|
SHELL: preferredShell,
|
|
6393
6452
|
PATH: [...new Set(pathEntries)].join(delimiter2),
|
|
6394
6453
|
LANG: process.env.LANG ?? "en_US.UTF-8",
|
|
6395
6454
|
TERM: process.env.TERM ?? "xterm-256color",
|
|
6396
6455
|
PYTHONDONTWRITEBYTECODE: "1",
|
|
6397
|
-
PYTHONPYCACHEPREFIX:
|
|
6456
|
+
PYTHONPYCACHEPREFIX: resolve29(runtime.cacheDir, "python"),
|
|
6398
6457
|
...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
|
|
6399
6458
|
...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
|
|
6400
6459
|
CLAUDE_HOME: runtime.claudeHomeDir,
|
|
6401
|
-
PI_CODING_AGENT_DIR:
|
|
6460
|
+
PI_CODING_AGENT_DIR: resolve29(runtime.homeDir, ".pi", "agent"),
|
|
6402
6461
|
[RUNTIME_CONTEXT_ENV]: runtime.contextFile,
|
|
6403
6462
|
...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
|
|
6404
6463
|
...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
|
|
@@ -6409,16 +6468,16 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6409
6468
|
NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
|
|
6410
6469
|
} : {}
|
|
6411
6470
|
};
|
|
6412
|
-
const knownHostsPath =
|
|
6413
|
-
if (
|
|
6414
|
-
const agentSshKey =
|
|
6471
|
+
const knownHostsPath = resolve29(runtime.homeDir, ".ssh", "known_hosts");
|
|
6472
|
+
if (existsSync28(knownHostsPath)) {
|
|
6473
|
+
const agentSshKey = resolve29(runtime.homeDir, ".ssh", "rig-agent-key");
|
|
6415
6474
|
const sshParts = [
|
|
6416
6475
|
"ssh",
|
|
6417
6476
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
6418
6477
|
"-o StrictHostKeyChecking=yes",
|
|
6419
6478
|
"-F /dev/null"
|
|
6420
6479
|
];
|
|
6421
|
-
if (
|
|
6480
|
+
if (existsSync28(agentSshKey)) {
|
|
6422
6481
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
6423
6482
|
}
|
|
6424
6483
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -6455,7 +6514,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6455
6514
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
6456
6515
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
6457
6516
|
}
|
|
6458
|
-
if (
|
|
6517
|
+
if (existsSync28(runtime.contextFile)) {
|
|
6459
6518
|
const runtimeContext = loadRuntimeContext(runtime.contextFile);
|
|
6460
6519
|
Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
|
|
6461
6520
|
Object.assign(env, browserEnvFromContext(runtimeContext.browser));
|
|
@@ -6484,30 +6543,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
6484
6543
|
await mkdir2(runtime.cacheDir, { recursive: true });
|
|
6485
6544
|
await provisionAgentSshKey(runtime.homeDir);
|
|
6486
6545
|
if (options.provider === "codex") {
|
|
6487
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
6546
|
+
const hasCodexAuth = await injectCodexAuth(resolve29(runtime.homeDir, ".codex"));
|
|
6488
6547
|
if (!hasCodexAuth) {
|
|
6489
6548
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
6490
6549
|
}
|
|
6491
6550
|
}
|
|
6492
6551
|
if (options.provider === "pi") {
|
|
6493
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
6552
|
+
const hasPiAuth = await injectPiAgentConfig(resolve29(runtime.homeDir, ".pi", "agent"));
|
|
6494
6553
|
if (!hasPiAuth) {
|
|
6495
6554
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
6496
6555
|
}
|
|
6497
6556
|
}
|
|
6498
6557
|
}
|
|
6499
6558
|
async function provisionClaudeHome(config) {
|
|
6500
|
-
|
|
6501
|
-
const workspaceSettings =
|
|
6502
|
-
const hostSettings =
|
|
6503
|
-
const projectSettings =
|
|
6559
|
+
mkdirSync13(config.claudeHomeDir, { recursive: true });
|
|
6560
|
+
const workspaceSettings = resolve29(config.workspaceDir, ".claude/settings.json");
|
|
6561
|
+
const hostSettings = resolve29(config.hostProjectRoot, ".claude/settings.json");
|
|
6562
|
+
const projectSettings = existsSync28(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
6504
6563
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
6505
|
-
if (
|
|
6506
|
-
|
|
6564
|
+
if (existsSync28(projectSettings)) {
|
|
6565
|
+
writeFileSync11(resolve29(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6507
6566
|
`, "utf-8");
|
|
6508
6567
|
}
|
|
6509
6568
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
6510
|
-
|
|
6569
|
+
writeFileSync11(resolve29(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
6511
6570
|
permissions: { defaultMode: "bypassPermissions" },
|
|
6512
6571
|
autoMemoryEnabled: false
|
|
6513
6572
|
}, null, 2));
|
|
@@ -6515,12 +6574,12 @@ async function provisionClaudeHome(config) {
|
|
|
6515
6574
|
if (!hasCredentials) {
|
|
6516
6575
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
6517
6576
|
}
|
|
6518
|
-
const realClaudeHome =
|
|
6519
|
-
if (process.env.HOME &&
|
|
6520
|
-
cpSync2(
|
|
6577
|
+
const realClaudeHome = resolve29(process.env.HOME ?? "", ".claude");
|
|
6578
|
+
if (process.env.HOME && existsSync28(resolve29(realClaudeHome, "CLAUDE.md"))) {
|
|
6579
|
+
cpSync2(resolve29(realClaudeHome, "CLAUDE.md"), resolve29(config.claudeHomeDir, "CLAUDE.md"));
|
|
6521
6580
|
}
|
|
6522
|
-
if (process.env.HOME &&
|
|
6523
|
-
cpSync2(
|
|
6581
|
+
if (process.env.HOME && existsSync28(resolve29(realClaudeHome, "agents"))) {
|
|
6582
|
+
cpSync2(resolve29(realClaudeHome, "agents"), resolve29(config.claudeHomeDir, "agents"), { recursive: true });
|
|
6524
6583
|
}
|
|
6525
6584
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
6526
6585
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -6531,10 +6590,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
6531
6590
|
if (!sourcePath) {
|
|
6532
6591
|
return "";
|
|
6533
6592
|
}
|
|
6534
|
-
const certsDir =
|
|
6535
|
-
const targetPath =
|
|
6593
|
+
const certsDir = resolve29(runtime.rootDir, "certs");
|
|
6594
|
+
const targetPath = resolve29(certsDir, "ca-certificates.pem");
|
|
6536
6595
|
await mkdir2(certsDir, { recursive: true });
|
|
6537
|
-
let shouldCopy = !
|
|
6596
|
+
let shouldCopy = !existsSync28(targetPath);
|
|
6538
6597
|
if (!shouldCopy) {
|
|
6539
6598
|
try {
|
|
6540
6599
|
shouldCopy = statSync6(sourcePath).mtimeMs > statSync6(targetPath).mtimeMs;
|
|
@@ -6556,7 +6615,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
6556
6615
|
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';
|
|
6557
6616
|
}
|
|
6558
6617
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
6559
|
-
const secretsPath =
|
|
6618
|
+
const secretsPath = resolve29(runtimeRoot, "runtime-secrets.json");
|
|
6560
6619
|
const persisted = {};
|
|
6561
6620
|
for (const key of [
|
|
6562
6621
|
"GITHUB_TOKEN",
|
|
@@ -6575,12 +6634,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
6575
6634
|
if (Object.keys(persisted).length === 0) {
|
|
6576
6635
|
return;
|
|
6577
6636
|
}
|
|
6578
|
-
|
|
6637
|
+
writeFileSync11(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
6579
6638
|
`, "utf-8");
|
|
6580
6639
|
}
|
|
6581
6640
|
async function provisionAgentSshKey(homeDir) {
|
|
6582
|
-
const sshDir =
|
|
6583
|
-
if (!
|
|
6641
|
+
const sshDir = resolve29(homeDir, ".ssh");
|
|
6642
|
+
if (!existsSync28(sshDir)) {
|
|
6584
6643
|
await mkdir2(sshDir, { recursive: true });
|
|
6585
6644
|
}
|
|
6586
6645
|
seedKnownHosts(sshDir);
|
|
@@ -6588,27 +6647,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
6588
6647
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
6589
6648
|
if (!privateKey) {
|
|
6590
6649
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
6591
|
-
if (!process.env.HOME || !
|
|
6650
|
+
if (!process.env.HOME || !existsSync28(hostKeyPath)) {
|
|
6592
6651
|
return;
|
|
6593
6652
|
}
|
|
6594
|
-
const agentKeyPath2 =
|
|
6595
|
-
if (!
|
|
6653
|
+
const agentKeyPath2 = resolve29(sshDir, "rig-agent-key");
|
|
6654
|
+
if (!existsSync28(agentKeyPath2)) {
|
|
6596
6655
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
6597
6656
|
chmodSync5(agentKeyPath2, 384);
|
|
6598
6657
|
}
|
|
6599
6658
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
6600
|
-
if (
|
|
6659
|
+
if (existsSync28(hostPubPath)) {
|
|
6601
6660
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
6602
|
-
if (!
|
|
6661
|
+
if (!existsSync28(agentPubPath)) {
|
|
6603
6662
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
6604
6663
|
}
|
|
6605
6664
|
}
|
|
6606
6665
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
6607
6666
|
return;
|
|
6608
6667
|
}
|
|
6609
|
-
const agentKeyPath =
|
|
6610
|
-
if (!
|
|
6611
|
-
|
|
6668
|
+
const agentKeyPath = resolve29(sshDir, "rig-agent-key");
|
|
6669
|
+
if (!existsSync28(agentKeyPath)) {
|
|
6670
|
+
writeFileSync11(agentKeyPath, privateKey, { mode: 384 });
|
|
6612
6671
|
}
|
|
6613
6672
|
writeSshConfig(sshDir, agentKeyPath);
|
|
6614
6673
|
}
|
|
@@ -6625,21 +6684,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
6625
6684
|
`;
|
|
6626
6685
|
}
|
|
6627
6686
|
function resolveHostSshKeyPath(homeDir) {
|
|
6628
|
-
const sshDir =
|
|
6687
|
+
const sshDir = resolve29(homeDir, ".ssh");
|
|
6629
6688
|
const candidates = [
|
|
6630
6689
|
"rig-agent-key",
|
|
6631
6690
|
"id_ed25519",
|
|
6632
6691
|
"id_ecdsa",
|
|
6633
6692
|
"id_rsa"
|
|
6634
|
-
].map((name) =>
|
|
6635
|
-
return candidates.find((candidate) =>
|
|
6693
|
+
].map((name) => resolve29(sshDir, name));
|
|
6694
|
+
return candidates.find((candidate) => existsSync28(candidate)) ?? resolve29(sshDir, "rig-agent-key");
|
|
6636
6695
|
}
|
|
6637
6696
|
function writeSshConfig(sshDir, keyPath) {
|
|
6638
|
-
const configPath =
|
|
6639
|
-
if (
|
|
6697
|
+
const configPath = resolve29(sshDir, "config");
|
|
6698
|
+
if (existsSync28(configPath)) {
|
|
6640
6699
|
return;
|
|
6641
6700
|
}
|
|
6642
|
-
const knownHostsPath =
|
|
6701
|
+
const knownHostsPath = resolve29(sshDir, "known_hosts");
|
|
6643
6702
|
const config = [
|
|
6644
6703
|
"Host github.com",
|
|
6645
6704
|
` IdentityFile ${keyPath}`,
|
|
@@ -6649,10 +6708,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
6649
6708
|
""
|
|
6650
6709
|
].join(`
|
|
6651
6710
|
`);
|
|
6652
|
-
|
|
6711
|
+
writeFileSync11(configPath, config, { mode: 420 });
|
|
6653
6712
|
}
|
|
6654
6713
|
function seedKnownHosts(sshDir) {
|
|
6655
|
-
const knownHostsPath =
|
|
6714
|
+
const knownHostsPath = resolve29(sshDir, "known_hosts");
|
|
6656
6715
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
6657
6716
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
6658
6717
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -6663,23 +6722,23 @@ function seedKnownHosts(sshDir) {
|
|
|
6663
6722
|
for (const line of missing) {
|
|
6664
6723
|
existingLines.add(line);
|
|
6665
6724
|
}
|
|
6666
|
-
|
|
6725
|
+
writeFileSync11(knownHostsPath, `${Array.from(existingLines).join(`
|
|
6667
6726
|
`)}
|
|
6668
6727
|
`, { mode: 420 });
|
|
6669
6728
|
} catch (err) {
|
|
6670
|
-
const hint =
|
|
6729
|
+
const hint = existsSync28(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
6671
6730
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
6672
6731
|
}
|
|
6673
6732
|
}
|
|
6674
6733
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
6675
6734
|
const projectHash = hashProjectPath(workspaceDir);
|
|
6676
|
-
const projectDir =
|
|
6677
|
-
|
|
6678
|
-
|
|
6735
|
+
const projectDir = resolve29(claudeHomeDir, "projects", projectHash);
|
|
6736
|
+
mkdirSync13(projectDir, { recursive: true });
|
|
6737
|
+
writeFileSync11(resolve29(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6679
6738
|
`, "utf-8");
|
|
6680
6739
|
}
|
|
6681
6740
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
6682
|
-
if (!
|
|
6741
|
+
if (!existsSync28(projectSettingsPath)) {
|
|
6683
6742
|
return {};
|
|
6684
6743
|
}
|
|
6685
6744
|
let parsed;
|
|
@@ -6725,7 +6784,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
6725
6784
|
return clone;
|
|
6726
6785
|
}
|
|
6727
6786
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
6728
|
-
const credentialsPath =
|
|
6787
|
+
const credentialsPath = resolve29(claudeHomeDir, ".credentials.json");
|
|
6729
6788
|
const platform = options.platform ?? process.platform;
|
|
6730
6789
|
if (platform === "darwin") {
|
|
6731
6790
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -6735,16 +6794,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6735
6794
|
if (raw) {
|
|
6736
6795
|
try {
|
|
6737
6796
|
JSON.parse(raw);
|
|
6738
|
-
|
|
6797
|
+
writeFileSync11(credentialsPath, raw, { mode: 384 });
|
|
6739
6798
|
registerCredentialCleanup(credentialsPath);
|
|
6740
6799
|
return true;
|
|
6741
6800
|
} catch {}
|
|
6742
6801
|
}
|
|
6743
6802
|
}
|
|
6744
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6803
|
+
const hostClaudeHome = options.hostClaudeHome ? resolve29(options.hostClaudeHome) : process.env.CLAUDE_HOME?.trim() ? resolve29(process.env.CLAUDE_HOME) : process.env.HOME ? resolve29(process.env.HOME, ".claude") : "";
|
|
6745
6804
|
if (hostClaudeHome) {
|
|
6746
|
-
const realCredentials =
|
|
6747
|
-
if (
|
|
6805
|
+
const realCredentials = resolve29(hostClaudeHome, ".credentials.json");
|
|
6806
|
+
if (existsSync28(realCredentials)) {
|
|
6748
6807
|
cpSync2(realCredentials, credentialsPath);
|
|
6749
6808
|
return true;
|
|
6750
6809
|
}
|
|
@@ -6752,36 +6811,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6752
6811
|
return false;
|
|
6753
6812
|
}
|
|
6754
6813
|
async function injectCodexAuth(codexHomeDir) {
|
|
6755
|
-
|
|
6756
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6814
|
+
mkdirSync13(codexHomeDir, { recursive: true });
|
|
6815
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve29(process.env.CODEX_HOME) : process.env.HOME ? resolve29(process.env.HOME, ".codex") : "";
|
|
6757
6816
|
if (!hostCodexHome) {
|
|
6758
6817
|
return false;
|
|
6759
6818
|
}
|
|
6760
|
-
const hostAuthPath =
|
|
6761
|
-
if (!
|
|
6819
|
+
const hostAuthPath = resolve29(hostCodexHome, "auth.json");
|
|
6820
|
+
if (!existsSync28(hostAuthPath)) {
|
|
6762
6821
|
return false;
|
|
6763
6822
|
}
|
|
6764
|
-
const runtimeAuthPath =
|
|
6823
|
+
const runtimeAuthPath = resolve29(codexHomeDir, "auth.json");
|
|
6765
6824
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6766
6825
|
chmodSync5(runtimeAuthPath, 384);
|
|
6767
6826
|
return true;
|
|
6768
6827
|
}
|
|
6769
6828
|
async function injectPiAgentConfig(piAgentDir) {
|
|
6770
|
-
|
|
6771
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6829
|
+
mkdirSync13(piAgentDir, { recursive: true });
|
|
6830
|
+
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ? resolve29(process.env.PI_CODING_AGENT_DIR) : process.env.HOME ? resolve29(process.env.HOME, ".pi", "agent") : "";
|
|
6772
6831
|
if (!hostPiAgentDir) {
|
|
6773
6832
|
return false;
|
|
6774
6833
|
}
|
|
6775
|
-
const hostAuthPath =
|
|
6776
|
-
if (!
|
|
6834
|
+
const hostAuthPath = resolve29(hostPiAgentDir, "auth.json");
|
|
6835
|
+
if (!existsSync28(hostAuthPath)) {
|
|
6777
6836
|
return false;
|
|
6778
6837
|
}
|
|
6779
|
-
const runtimeAuthPath =
|
|
6838
|
+
const runtimeAuthPath = resolve29(piAgentDir, "auth.json");
|
|
6780
6839
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6781
6840
|
chmodSync5(runtimeAuthPath, 384);
|
|
6782
|
-
const hostSettingsPath =
|
|
6783
|
-
if (
|
|
6784
|
-
const runtimeSettingsPath =
|
|
6841
|
+
const hostSettingsPath = resolve29(hostPiAgentDir, "settings.json");
|
|
6842
|
+
if (existsSync28(hostSettingsPath)) {
|
|
6843
|
+
const runtimeSettingsPath = resolve29(piAgentDir, "settings.json");
|
|
6785
6844
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
6786
6845
|
chmodSync5(runtimeSettingsPath, 384);
|
|
6787
6846
|
}
|
|
@@ -6789,13 +6848,13 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
6789
6848
|
}
|
|
6790
6849
|
|
|
6791
6850
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
6792
|
-
import { existsSync as
|
|
6793
|
-
import { resolve as
|
|
6851
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync14, statSync as statSync7, writeFileSync as writeFileSync12 } from "fs";
|
|
6852
|
+
import { resolve as resolve30 } from "path";
|
|
6794
6853
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6795
6854
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6796
6855
|
return {
|
|
6797
6856
|
type: "stdio",
|
|
6798
|
-
command:
|
|
6857
|
+
command: resolve30(options.binDir, "rig-tool-router"),
|
|
6799
6858
|
args: [],
|
|
6800
6859
|
env: {
|
|
6801
6860
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6804,14 +6863,14 @@ function buildRuntimeToolRouterServerConfig(options) {
|
|
|
6804
6863
|
};
|
|
6805
6864
|
}
|
|
6806
6865
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6807
|
-
const configPath =
|
|
6808
|
-
|
|
6866
|
+
const configPath = resolve30(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6867
|
+
mkdirSync14(options.stateDir, { recursive: true });
|
|
6809
6868
|
const payload = {
|
|
6810
6869
|
mcpServers: {
|
|
6811
6870
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6812
6871
|
}
|
|
6813
6872
|
};
|
|
6814
|
-
|
|
6873
|
+
writeFileSync12(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6815
6874
|
`, "utf-8");
|
|
6816
6875
|
return configPath;
|
|
6817
6876
|
}
|
|
@@ -6820,8 +6879,8 @@ if (false) {}
|
|
|
6820
6879
|
init_layout();
|
|
6821
6880
|
|
|
6822
6881
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6823
|
-
import { existsSync as
|
|
6824
|
-
import { dirname as
|
|
6882
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync15, rmSync as rmSync10 } from "fs";
|
|
6883
|
+
import { dirname as dirname13, resolve as resolve31 } from "path";
|
|
6825
6884
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6826
6885
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6827
6886
|
if (explicit) {
|
|
@@ -6857,12 +6916,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6857
6916
|
}
|
|
6858
6917
|
async function provisionRuntimeWorktree(config) {
|
|
6859
6918
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6860
|
-
let hasValidWorktree =
|
|
6861
|
-
if (
|
|
6919
|
+
let hasValidWorktree = existsSync30(resolve31(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6920
|
+
if (existsSync30(config.workspaceDir) && !hasValidWorktree) {
|
|
6862
6921
|
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6863
6922
|
}
|
|
6864
6923
|
if (!hasValidWorktree) {
|
|
6865
|
-
|
|
6924
|
+
mkdirSync15(dirname13(config.workspaceDir), { recursive: true });
|
|
6866
6925
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6867
6926
|
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]);
|
|
6868
6927
|
if (add.exitCode !== 0) {
|
|
@@ -7038,31 +7097,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
7038
7097
|
|
|
7039
7098
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
7040
7099
|
import {
|
|
7041
|
-
existsSync as
|
|
7100
|
+
existsSync as existsSync32,
|
|
7042
7101
|
lstatSync,
|
|
7043
|
-
mkdirSync as
|
|
7102
|
+
mkdirSync as mkdirSync17,
|
|
7044
7103
|
readdirSync as readdirSync6,
|
|
7045
|
-
readFileSync as
|
|
7104
|
+
readFileSync as readFileSync16,
|
|
7046
7105
|
rmSync as rmSync11,
|
|
7047
7106
|
statSync as statSync9,
|
|
7048
7107
|
symlinkSync as symlinkSync4
|
|
7049
7108
|
} from "fs";
|
|
7050
7109
|
import { mkdir as mkdir3, writeFile } from "fs/promises";
|
|
7051
|
-
import { dirname as
|
|
7110
|
+
import { dirname as dirname15, resolve as resolve33 } from "path";
|
|
7052
7111
|
|
|
7053
7112
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
7054
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
7113
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync31, mkdirSync as mkdirSync16, statSync as statSync8 } from "fs";
|
|
7055
7114
|
import { tmpdir as tmpdir6 } from "os";
|
|
7056
|
-
import { dirname as
|
|
7057
|
-
var sharedRouterOutputDir =
|
|
7058
|
-
var sharedRouterOutputPath =
|
|
7115
|
+
import { dirname as dirname14, resolve as resolve32 } from "path";
|
|
7116
|
+
var sharedRouterOutputDir = resolve32(tmpdir6(), "rig-native");
|
|
7117
|
+
var sharedRouterOutputPath = resolve32(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
7059
7118
|
function runtimeClaudeToolRouterFileName() {
|
|
7060
7119
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
7061
7120
|
}
|
|
7062
7121
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
7063
|
-
const sourcePath =
|
|
7064
|
-
|
|
7065
|
-
const needsBuild = !
|
|
7122
|
+
const sourcePath = resolve32(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
7123
|
+
mkdirSync16(dirname14(outputPath), { recursive: true });
|
|
7124
|
+
const needsBuild = !existsSync31(outputPath) || statSync8(sourcePath).mtimeMs > statSync8(outputPath).mtimeMs;
|
|
7066
7125
|
if (!needsBuild) {
|
|
7067
7126
|
return outputPath;
|
|
7068
7127
|
}
|
|
@@ -7076,9 +7135,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
7076
7135
|
}
|
|
7077
7136
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
7078
7137
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
7079
|
-
const targetPath =
|
|
7080
|
-
|
|
7081
|
-
const needsCopy = !
|
|
7138
|
+
const targetPath = resolve32(targetDir, runtimeClaudeToolRouterFileName());
|
|
7139
|
+
mkdirSync16(targetDir, { recursive: true });
|
|
7140
|
+
const needsCopy = !existsSync31(targetPath) || statSync8(sourcePath).mtimeMs > statSync8(targetPath).mtimeMs;
|
|
7082
7141
|
if (needsCopy) {
|
|
7083
7142
|
copyFileSync6(sourcePath, targetPath);
|
|
7084
7143
|
chmodSync6(targetPath, 493);
|
|
@@ -7091,48 +7150,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
7091
7150
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
7092
7151
|
function resolveRigSourceRoot(projectRoot) {
|
|
7093
7152
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
7094
|
-
if (hostProjectRoot &&
|
|
7153
|
+
if (hostProjectRoot && existsSync32(resolve33(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
7095
7154
|
return hostProjectRoot;
|
|
7096
7155
|
}
|
|
7097
|
-
const fromModule =
|
|
7098
|
-
if (
|
|
7156
|
+
const fromModule = resolve33(import.meta.dir, "../../../../../..");
|
|
7157
|
+
if (existsSync32(resolve33(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
7099
7158
|
return fromModule;
|
|
7100
7159
|
}
|
|
7101
7160
|
return projectRoot;
|
|
7102
7161
|
}
|
|
7103
7162
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
7104
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
7163
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve33(sessionDir, "session.json")]) {
|
|
7105
7164
|
removeSymbolicLink(path);
|
|
7106
7165
|
}
|
|
7107
7166
|
runtimePrepareTrackedPathsNative({
|
|
7108
7167
|
logsDir,
|
|
7109
7168
|
stateDir,
|
|
7110
7169
|
sessionDir,
|
|
7111
|
-
controlledBashLogFile:
|
|
7112
|
-
eventsFile:
|
|
7170
|
+
controlledBashLogFile: resolve33(logsDir, "controlled-bash.jsonl"),
|
|
7171
|
+
eventsFile: resolve33(logsDir, "control-plane.events.jsonl")
|
|
7113
7172
|
});
|
|
7114
7173
|
}
|
|
7115
7174
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
7116
7175
|
await mkdir3(stateDir, { recursive: true });
|
|
7117
7176
|
await mkdir3(sessionDir, { recursive: true });
|
|
7118
|
-
const failedApproachesPath =
|
|
7119
|
-
if (!
|
|
7177
|
+
const failedApproachesPath = resolve33(stateDir, "failed_approaches.md");
|
|
7178
|
+
if (!existsSync32(failedApproachesPath)) {
|
|
7120
7179
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
7121
7180
|
|
|
7122
7181
|
`);
|
|
7123
7182
|
}
|
|
7124
|
-
const hookTripsPath =
|
|
7125
|
-
if (!
|
|
7183
|
+
const hookTripsPath = resolve33(stateDir, "hook_trips.log");
|
|
7184
|
+
if (!existsSync32(hookTripsPath)) {
|
|
7126
7185
|
await writeFile(hookTripsPath, "");
|
|
7127
7186
|
}
|
|
7128
|
-
const sessionFile =
|
|
7187
|
+
const sessionFile = resolve33(sessionDir, "session.json");
|
|
7129
7188
|
if (taskId) {
|
|
7130
7189
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
7131
7190
|
}
|
|
7132
7191
|
}
|
|
7133
7192
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
7134
|
-
const artifactDir =
|
|
7135
|
-
const runtimeSnapshotDir =
|
|
7193
|
+
const artifactDir = resolve33(workspaceDir, "artifacts", taskId);
|
|
7194
|
+
const runtimeSnapshotDir = resolve33(artifactDir, "runtime-snapshots");
|
|
7136
7195
|
let preservedTrackedFiles = false;
|
|
7137
7196
|
for (const file of [
|
|
7138
7197
|
"changed-files.txt",
|
|
@@ -7148,7 +7207,7 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
7148
7207
|
preservedTrackedFiles = true;
|
|
7149
7208
|
continue;
|
|
7150
7209
|
}
|
|
7151
|
-
rmSync11(
|
|
7210
|
+
rmSync11(resolve33(artifactDir, file), { force: true });
|
|
7152
7211
|
}
|
|
7153
7212
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
7154
7213
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
@@ -7187,28 +7246,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
7187
7246
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
7188
7247
|
}
|
|
7189
7248
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
7190
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
7191
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
7249
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve33(options.binDir, "rig"), rigSourceRoot);
|
|
7250
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve33(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
7192
7251
|
...options.runtimeSecretDefines,
|
|
7193
7252
|
AGENT_TASK_ID: options.taskId,
|
|
7194
7253
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7195
7254
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
7196
7255
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
7197
7256
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
7198
|
-
AGENT_BINARY_PATH:
|
|
7257
|
+
AGENT_BINARY_PATH: resolve33(options.binDir, "rig-agent"),
|
|
7199
7258
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
7200
7259
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
7201
7260
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
7202
7261
|
});
|
|
7203
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
7262
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve33(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
7204
7263
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7205
7264
|
AGENT_LOGS_DIR: options.logsDir,
|
|
7206
7265
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
7207
|
-
AGENT_TS_API_TESTS_DIR:
|
|
7208
|
-
AGENT_RIG_AGENT_BIN:
|
|
7266
|
+
AGENT_TS_API_TESTS_DIR: resolve33(options.workspaceDir, "TSAPITests"),
|
|
7267
|
+
AGENT_RIG_AGENT_BIN: resolve33(options.binDir, "rig-agent")
|
|
7209
7268
|
});
|
|
7210
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
7211
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
7269
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve33(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
7270
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve33(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
7212
7271
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7213
7272
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7214
7273
|
});
|
|
@@ -7217,15 +7276,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
7217
7276
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7218
7277
|
};
|
|
7219
7278
|
for (const hookName of hookNames) {
|
|
7220
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
7279
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve33(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
7221
7280
|
}
|
|
7222
|
-
const pluginsDir =
|
|
7223
|
-
if (
|
|
7281
|
+
const pluginsDir = resolve33(options.projectRoot, "rig/plugins");
|
|
7282
|
+
if (existsSync32(pluginsDir)) {
|
|
7224
7283
|
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
7225
7284
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
7226
7285
|
if (!match)
|
|
7227
7286
|
continue;
|
|
7228
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
7287
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve33(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
7229
7288
|
}
|
|
7230
7289
|
}
|
|
7231
7290
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -7235,8 +7294,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
7235
7294
|
}
|
|
7236
7295
|
async function writeRuntimeManifest(config) {
|
|
7237
7296
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
7238
|
-
const binarySha256 = sha256Hex(
|
|
7239
|
-
const manifestPath =
|
|
7297
|
+
const binarySha256 = sha256Hex(readFileSync16(config.binaryPath));
|
|
7298
|
+
const manifestPath = resolve33(config.runtimeRoot, "manifest.json");
|
|
7240
7299
|
const manifest = {
|
|
7241
7300
|
runtimeId: config.runtimeId,
|
|
7242
7301
|
taskId: config.taskId,
|
|
@@ -7356,31 +7415,31 @@ function readFileMtimeMs(path) {
|
|
|
7356
7415
|
}
|
|
7357
7416
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
7358
7417
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
7359
|
-
const sourceNodeModules =
|
|
7360
|
-
if (!
|
|
7361
|
-
const runtimeHumoongate =
|
|
7362
|
-
if (
|
|
7363
|
-
const targetNodeModules =
|
|
7418
|
+
const sourceNodeModules = resolve33(monorepoRoot, "humoongate", "node_modules");
|
|
7419
|
+
if (!existsSync32(sourceNodeModules)) {} else {
|
|
7420
|
+
const runtimeHumoongate = resolve33(workspaceDir, "humoongate");
|
|
7421
|
+
if (existsSync32(resolve33(runtimeHumoongate, "package.json"))) {
|
|
7422
|
+
const targetNodeModules = resolve33(runtimeHumoongate, "node_modules");
|
|
7364
7423
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
7365
7424
|
}
|
|
7366
7425
|
}
|
|
7367
|
-
const runtimeHpNext =
|
|
7368
|
-
if (!
|
|
7426
|
+
const runtimeHpNext = resolve33(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
7427
|
+
if (!existsSync32(resolve33(runtimeHpNext, "package.json"))) {
|
|
7369
7428
|
return;
|
|
7370
7429
|
}
|
|
7371
|
-
const sourceHpNextNodeModules =
|
|
7372
|
-
const sourceMonorepoNodeModules =
|
|
7373
|
-
const targetHpNextNodeModules =
|
|
7374
|
-
if (
|
|
7430
|
+
const sourceHpNextNodeModules = resolve33(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
7431
|
+
const sourceMonorepoNodeModules = resolve33(monorepoRoot, "node_modules");
|
|
7432
|
+
const targetHpNextNodeModules = resolve33(runtimeHpNext, "node_modules");
|
|
7433
|
+
if (existsSync32(sourceHpNextNodeModules)) {
|
|
7375
7434
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
7376
7435
|
return;
|
|
7377
7436
|
}
|
|
7378
|
-
if (
|
|
7437
|
+
if (existsSync32(sourceMonorepoNodeModules)) {
|
|
7379
7438
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
7380
7439
|
}
|
|
7381
7440
|
}
|
|
7382
7441
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
7383
|
-
linkNodeModulesLayer(
|
|
7442
|
+
linkNodeModulesLayer(resolve33(monorepoRoot, "node_modules"), resolve33(workspaceDir, "node_modules"));
|
|
7384
7443
|
for (const relativePackageDir of [
|
|
7385
7444
|
"apps/native-app/apps/marketing",
|
|
7386
7445
|
"apps/native-app/apps/web",
|
|
@@ -7402,15 +7461,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
7402
7461
|
"packages/standard-plugin",
|
|
7403
7462
|
"packages/validator-kit"
|
|
7404
7463
|
]) {
|
|
7405
|
-
const workspacePackageDir =
|
|
7406
|
-
if (!
|
|
7464
|
+
const workspacePackageDir = resolve33(workspaceDir, relativePackageDir);
|
|
7465
|
+
if (!existsSync32(resolve33(workspacePackageDir, "package.json"))) {
|
|
7407
7466
|
continue;
|
|
7408
7467
|
}
|
|
7409
|
-
linkNodeModulesLayer(
|
|
7468
|
+
linkNodeModulesLayer(resolve33(monorepoRoot, relativePackageDir, "node_modules"), resolve33(workspacePackageDir, "node_modules"));
|
|
7410
7469
|
}
|
|
7411
7470
|
}
|
|
7412
7471
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
7413
|
-
if (!
|
|
7472
|
+
if (!existsSync32(sourceDir) || existsSync32(targetDir)) {
|
|
7414
7473
|
return;
|
|
7415
7474
|
}
|
|
7416
7475
|
try {
|
|
@@ -7419,25 +7478,25 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
7419
7478
|
} catch (error) {
|
|
7420
7479
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
7421
7480
|
}
|
|
7422
|
-
|
|
7481
|
+
mkdirSync17(dirname15(targetDir), { recursive: true });
|
|
7423
7482
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
7424
7483
|
}
|
|
7425
7484
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
7426
|
-
const hooksDir =
|
|
7427
|
-
const pluginsDir =
|
|
7428
|
-
const validatorsDir =
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7485
|
+
const hooksDir = resolve33(runtimeBinDir, "hooks");
|
|
7486
|
+
const pluginsDir = resolve33(runtimeBinDir, "plugins");
|
|
7487
|
+
const validatorsDir = resolve33(runtimeBinDir, "validators");
|
|
7488
|
+
mkdirSync17(hooksDir, { recursive: true });
|
|
7489
|
+
mkdirSync17(pluginsDir, { recursive: true });
|
|
7490
|
+
mkdirSync17(validatorsDir, { recursive: true });
|
|
7432
7491
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
7433
7492
|
}
|
|
7434
7493
|
|
|
7435
7494
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
7436
|
-
import { existsSync as
|
|
7437
|
-
import { basename as basename9, resolve as
|
|
7495
|
+
import { existsSync as existsSync34, rmSync as rmSync12, writeFileSync as writeFileSync14 } from "fs";
|
|
7496
|
+
import { basename as basename9, resolve as resolve36 } from "path";
|
|
7438
7497
|
|
|
7439
7498
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
7440
|
-
import { existsSync as
|
|
7499
|
+
import { existsSync as existsSync33 } from "fs";
|
|
7441
7500
|
init_utils();
|
|
7442
7501
|
|
|
7443
7502
|
// packages/runtime/src/control-plane/runtime/sandbox/backend-none.ts
|
|
@@ -7537,13 +7596,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
7537
7596
|
depRoots
|
|
7538
7597
|
};
|
|
7539
7598
|
const fsContext = {
|
|
7540
|
-
pathExists: (p) =>
|
|
7599
|
+
pathExists: (p) => existsSync33(p),
|
|
7541
7600
|
realPath: toRealPath
|
|
7542
7601
|
};
|
|
7543
7602
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
7544
7603
|
const seatbelt = Bun.which("sandbox-exec");
|
|
7545
7604
|
probed.push("sandbox-exec");
|
|
7546
|
-
if (seatbelt &&
|
|
7605
|
+
if (seatbelt && existsSync33(seatbelt)) {
|
|
7547
7606
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
7548
7607
|
if (SeatbeltBackendClass) {
|
|
7549
7608
|
return {
|
|
@@ -7664,8 +7723,8 @@ init_layout();
|
|
|
7664
7723
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
7665
7724
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
7666
7725
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
7667
|
-
const readyFile =
|
|
7668
|
-
const requestFile =
|
|
7726
|
+
const readyFile = resolve36(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
7727
|
+
const requestFile = resolve36(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
7669
7728
|
rmSync12(readyFile, { force: true });
|
|
7670
7729
|
rmSync12(requestFile, { force: true });
|
|
7671
7730
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
@@ -7709,7 +7768,7 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
7709
7768
|
rmSync12(requestFile, { force: true });
|
|
7710
7769
|
},
|
|
7711
7770
|
finalize: async (commandParts, exitCode) => {
|
|
7712
|
-
|
|
7771
|
+
writeFileSync14(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
7713
7772
|
`, "utf-8");
|
|
7714
7773
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
7715
7774
|
proc.exited,
|
|
@@ -7773,8 +7832,8 @@ async function runInAgentRuntime(options) {
|
|
|
7773
7832
|
const stdout = await new Response(proc.stdout).text();
|
|
7774
7833
|
const stderr = await new Response(proc.stderr).text();
|
|
7775
7834
|
try {
|
|
7776
|
-
await Bun.write(
|
|
7777
|
-
await Bun.write(
|
|
7835
|
+
await Bun.write(resolve36(options.runtime.logsDir, "agent-stdout.log"), stdout);
|
|
7836
|
+
await Bun.write(resolve36(options.runtime.logsDir, "agent-stderr.log"), stderr);
|
|
7778
7837
|
} catch {}
|
|
7779
7838
|
await snapshotSidecar.finalize(runtimeCommand, exitCode);
|
|
7780
7839
|
return {
|
|
@@ -7806,10 +7865,10 @@ function resolveSnapshotSidecarScriptPath() {
|
|
|
7806
7865
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
7807
7866
|
}
|
|
7808
7867
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
7809
|
-
return
|
|
7868
|
+
return resolve36(binDir, "snapshot-sidecar");
|
|
7810
7869
|
}
|
|
7811
7870
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
7812
|
-
if (!
|
|
7871
|
+
if (!existsSync34(binaryPath)) {
|
|
7813
7872
|
return false;
|
|
7814
7873
|
}
|
|
7815
7874
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -7824,12 +7883,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
7824
7883
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
7825
7884
|
].filter((value) => Boolean(value));
|
|
7826
7885
|
for (const root of hostRoots) {
|
|
7827
|
-
const candidate =
|
|
7828
|
-
if (
|
|
7886
|
+
const candidate = resolve36(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
7887
|
+
if (existsSync34(candidate)) {
|
|
7829
7888
|
return candidate;
|
|
7830
7889
|
}
|
|
7831
7890
|
}
|
|
7832
|
-
return
|
|
7891
|
+
return resolve36(import.meta.dir, "..", fileName);
|
|
7833
7892
|
}
|
|
7834
7893
|
function resolveBunCliInvocation() {
|
|
7835
7894
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -7856,7 +7915,7 @@ function resolveBunCliInvocation() {
|
|
|
7856
7915
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
7857
7916
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
7858
7917
|
while (Date.now() < deadline) {
|
|
7859
|
-
if (
|
|
7918
|
+
if (existsSync34(readyFile)) {
|
|
7860
7919
|
return;
|
|
7861
7920
|
}
|
|
7862
7921
|
const exitCode = proc.exitCode;
|
|
@@ -7874,9 +7933,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
7874
7933
|
async function hydrateRuntimeMemory(options) {
|
|
7875
7934
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
7876
7935
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
7877
|
-
const hydratedPath =
|
|
7936
|
+
const hydratedPath = resolve37(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
7878
7937
|
try {
|
|
7879
|
-
await mkdir4(
|
|
7938
|
+
await mkdir4(resolve37(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
7880
7939
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
7881
7940
|
return {
|
|
7882
7941
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -7891,12 +7950,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
7891
7950
|
}
|
|
7892
7951
|
}
|
|
7893
7952
|
async function createRuntimeTaskRecordReader(options) {
|
|
7894
|
-
const legacyConfigPath =
|
|
7953
|
+
const legacyConfigPath = resolve37(options.projectRoot, ".rig", "task-config.json");
|
|
7895
7954
|
let pluginHostContext = null;
|
|
7896
7955
|
try {
|
|
7897
7956
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
7898
7957
|
} catch (error) {
|
|
7899
|
-
if (!
|
|
7958
|
+
if (!existsSync35(legacyConfigPath)) {
|
|
7900
7959
|
throw error;
|
|
7901
7960
|
}
|
|
7902
7961
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -7916,7 +7975,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7916
7975
|
source: "plugin"
|
|
7917
7976
|
};
|
|
7918
7977
|
}
|
|
7919
|
-
if (
|
|
7978
|
+
if (existsSync35(legacyConfigPath)) {
|
|
7920
7979
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
7921
7980
|
options.diagnostics?.(message);
|
|
7922
7981
|
console.warn(message);
|
|
@@ -7933,10 +7992,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7933
7992
|
};
|
|
7934
7993
|
}
|
|
7935
7994
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
7936
|
-
const jsonPath =
|
|
7937
|
-
if (
|
|
7995
|
+
const jsonPath = resolve37(projectRoot, "rig.config.json");
|
|
7996
|
+
if (existsSync35(jsonPath)) {
|
|
7938
7997
|
try {
|
|
7939
|
-
const parsed = JSON.parse(
|
|
7998
|
+
const parsed = JSON.parse(readFileSync17(jsonPath, "utf8"));
|
|
7940
7999
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7941
8000
|
const taskSource = parsed.taskSource;
|
|
7942
8001
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -7948,12 +8007,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
7948
8007
|
return null;
|
|
7949
8008
|
}
|
|
7950
8009
|
}
|
|
7951
|
-
const tsPath =
|
|
7952
|
-
if (!
|
|
8010
|
+
const tsPath = resolve37(projectRoot, "rig.config.ts");
|
|
8011
|
+
if (!existsSync35(tsPath)) {
|
|
7953
8012
|
return null;
|
|
7954
8013
|
}
|
|
7955
8014
|
try {
|
|
7956
|
-
const source =
|
|
8015
|
+
const source = readFileSync17(tsPath, "utf8");
|
|
7957
8016
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
7958
8017
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
7959
8018
|
return kind ?? null;
|
|
@@ -8023,8 +8082,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
8023
8082
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
8024
8083
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
8025
8084
|
};
|
|
8026
|
-
const configPath =
|
|
8027
|
-
await mkdir4(
|
|
8085
|
+
const configPath = resolve37(options.workspaceDir, ".rig", "task-config.json");
|
|
8086
|
+
await mkdir4(resolve37(options.workspaceDir, ".rig"), { recursive: true });
|
|
8028
8087
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
8029
8088
|
`, "utf-8");
|
|
8030
8089
|
}
|
|
@@ -8088,9 +8147,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8088
8147
|
}
|
|
8089
8148
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8090
8149
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8091
|
-
const workspaceDir =
|
|
8150
|
+
const workspaceDir = resolve37(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8092
8151
|
const createdAt = new Date().toISOString();
|
|
8093
|
-
if (!
|
|
8152
|
+
if (!existsSync35(resolve37(monorepoRoot, ".git"))) {
|
|
8094
8153
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8095
8154
|
}
|
|
8096
8155
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8125,7 +8184,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8125
8184
|
logsDir: overlay.logsDir,
|
|
8126
8185
|
stateDir: overlay.stateDir,
|
|
8127
8186
|
sessionDir: overlay.sessionDir,
|
|
8128
|
-
claudeHomeDir:
|
|
8187
|
+
claudeHomeDir: resolve37(workspaceLayout.homeDir, ".claude"),
|
|
8129
8188
|
contextFile: overlay.contextPath,
|
|
8130
8189
|
binDir: workspaceLayout.binDir,
|
|
8131
8190
|
createdAt
|
|
@@ -8138,8 +8197,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8138
8197
|
projectRoot: options.projectRoot,
|
|
8139
8198
|
workspaceDir
|
|
8140
8199
|
});
|
|
8141
|
-
|
|
8142
|
-
|
|
8200
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8201
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8143
8202
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8144
8203
|
if (options.preserveTaskArtifacts) {
|
|
8145
8204
|
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
@@ -8158,7 +8217,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8158
8217
|
runtimeId: options.id
|
|
8159
8218
|
}),
|
|
8160
8219
|
workspaceDir,
|
|
8161
|
-
artifactRoot:
|
|
8220
|
+
artifactRoot: resolve37(workspaceDir, "artifacts", options.taskId),
|
|
8162
8221
|
hostProjectRoot: options.projectRoot,
|
|
8163
8222
|
monorepoMainRoot: monorepoRoot,
|
|
8164
8223
|
monorepoBaseRef: baseRef,
|
|
@@ -8174,8 +8233,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8174
8233
|
stateDir: overlay.stateDir,
|
|
8175
8234
|
logsDir: overlay.logsDir,
|
|
8176
8235
|
sessionDir: overlay.sessionDir,
|
|
8177
|
-
sessionFile:
|
|
8178
|
-
policyFile:
|
|
8236
|
+
sessionFile: resolve37(overlay.sessionDir, "session.json"),
|
|
8237
|
+
policyFile: resolve37(options.projectRoot, "rig/policy/policy.json"),
|
|
8179
8238
|
binDir: runtime.binDir,
|
|
8180
8239
|
createdAt,
|
|
8181
8240
|
memory
|
|
@@ -8186,9 +8245,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8186
8245
|
task: taskResolution.task,
|
|
8187
8246
|
taskEntry
|
|
8188
8247
|
});
|
|
8189
|
-
const manifestPath =
|
|
8248
|
+
const manifestPath = resolve37(runtimeRoot, "manifest.json");
|
|
8190
8249
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8191
|
-
const runtimeAgentBinary =
|
|
8250
|
+
const runtimeAgentBinary = resolve37(runtime.binDir, "rig-agent");
|
|
8192
8251
|
await ensureRigGitBinaryPath();
|
|
8193
8252
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8194
8253
|
projectRoot: options.projectRoot,
|
|
@@ -8205,8 +8264,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8205
8264
|
});
|
|
8206
8265
|
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8207
8266
|
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8208
|
-
|
|
8209
|
-
|
|
8267
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8268
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8210
8269
|
await buildRuntimeToolchain({
|
|
8211
8270
|
projectRoot: options.projectRoot,
|
|
8212
8271
|
workspaceDir,
|
|
@@ -8243,9 +8302,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8243
8302
|
workspaceDir,
|
|
8244
8303
|
taskEntry
|
|
8245
8304
|
});
|
|
8246
|
-
const sandboxDir =
|
|
8305
|
+
const sandboxDir = resolve37(runtimeRoot, "sandbox");
|
|
8247
8306
|
await mkdir4(sandboxDir, { recursive: true });
|
|
8248
|
-
await writeFile2(
|
|
8307
|
+
await writeFile2(resolve37(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8249
8308
|
id: options.id,
|
|
8250
8309
|
taskId: options.taskId,
|
|
8251
8310
|
mode: "worktree",
|
|
@@ -8399,12 +8458,12 @@ ${result.stderr.trim()}` : ""}`);
|
|
|
8399
8458
|
}
|
|
8400
8459
|
function resolveTaskCommand(projectRoot, action, taskId, hostProjectRoot = projectRoot) {
|
|
8401
8460
|
try {
|
|
8402
|
-
const compiledRig =
|
|
8403
|
-
if (
|
|
8461
|
+
const compiledRig = resolve38(resolveRigLayout(projectRoot).binDir, "rig");
|
|
8462
|
+
if (existsSync36(compiledRig)) {
|
|
8404
8463
|
return [compiledRig, "task", action, "--task", taskId];
|
|
8405
8464
|
}
|
|
8406
8465
|
} catch {}
|
|
8407
|
-
return ["bun", "run",
|
|
8466
|
+
return ["bun", "run", resolve38(hostProjectRoot, "packages/cli/bin/rig.ts"), "task", action, "--task", taskId];
|
|
8408
8467
|
}
|
|
8409
8468
|
function rankTasks(projectRoot, snapshot) {
|
|
8410
8469
|
const readyTaskIds = listReadyTaskIdsFromTracker(snapshot);
|