@h-rig/runtime 0.0.6-alpha.34 → 0.0.6-alpha.36
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 +430 -361
- package/dist/src/control-plane/agent-wrapper.js +523 -464
- package/dist/src/control-plane/harness-main.js +544 -463
- package/dist/src/control-plane/hooks/completion-verification.js +369 -288
- 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 +10 -0
- package/dist/src/control-plane/native/harness-cli.js +529 -448
- package/dist/src/control-plane/native/task-ops.js +408 -327
- package/dist/src/control-plane/native/validator.js +159 -100
- package/dist/src/control-plane/native/verifier.js +243 -171
- package/dist/src/control-plane/pi-sessiond/bin.js +0 -7
- package/dist/src/control-plane/pi-sessiond/server.js +0 -7
- package/dist/src/control-plane/pi-sessiond/session-service.js +0 -3
- 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/dist/src/index.js +16 -8
- package/dist/src/local-server.js +17 -8
- 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 resolve35 } 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 = resolve35(options.runtime.rootDir, "sandbox");
|
|
269
|
+
mkdirSync18(sandboxDir, { recursive: true });
|
|
270
|
+
const profilePath = resolve35(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 = resolve35(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 resolve36 } 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(resolve36(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 = resolve36(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 = resolve36(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
|
}
|
|
@@ -1671,9 +1671,9 @@ function primeGuardHotPaths() {
|
|
|
1671
1671
|
}
|
|
1672
1672
|
primeGuardHotPaths();
|
|
1673
1673
|
// packages/runtime/src/control-plane/runtime/isolation/index.ts
|
|
1674
|
-
import { existsSync as
|
|
1674
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync20, readFileSync as readFileSync17, rmSync as rmSync13 } from "fs";
|
|
1675
1675
|
import { copyFile, mkdir as mkdir4, writeFile as writeFile2 } from "fs/promises";
|
|
1676
|
-
import { resolve as
|
|
1676
|
+
import { resolve as resolve38 } from "path";
|
|
1677
1677
|
|
|
1678
1678
|
// packages/runtime/src/control-plane/native/git-native.ts
|
|
1679
1679
|
import { chmodSync, copyFileSync as copyFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync as renameSync2, rmSync as rmSync2, writeFileSync } from "fs";
|
|
@@ -2558,8 +2558,8 @@ function isAgentRuntimeContextPath(path) {
|
|
|
2558
2558
|
var DEFAULT_RESULT_LIMIT = DEFAULT_RUNTIME_MEMORY_RETRIEVAL.topK;
|
|
2559
2559
|
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
2560
2560
|
// packages/runtime/src/control-plane/native/task-ops.ts
|
|
2561
|
-
import { appendFileSync, existsSync as
|
|
2562
|
-
import { resolve as
|
|
2561
|
+
import { appendFileSync, existsSync as existsSync26, mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "fs";
|
|
2562
|
+
import { resolve as resolve27 } from "path";
|
|
2563
2563
|
|
|
2564
2564
|
// packages/runtime/src/build-time-config.ts
|
|
2565
2565
|
function normalizeBuildConfig(value) {
|
|
@@ -3123,6 +3123,8 @@ function buildBrowserGuidanceLines(browser) {
|
|
|
3123
3123
|
}
|
|
3124
3124
|
|
|
3125
3125
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
3126
|
+
import { existsSync as existsSync15 } from "fs";
|
|
3127
|
+
import { resolve as resolvePath } from "path";
|
|
3126
3128
|
import { createPluginHost } from "@rig/core";
|
|
3127
3129
|
import { loadConfig } from "@rig/core/load-config";
|
|
3128
3130
|
|
|
@@ -3453,6 +3455,55 @@ async function materializeSkills(projectRoot, entries) {
|
|
|
3453
3455
|
return written;
|
|
3454
3456
|
}
|
|
3455
3457
|
|
|
3458
|
+
// packages/runtime/src/control-plane/pi-settings-materializer.ts
|
|
3459
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
3460
|
+
import { dirname as dirname10, resolve as resolve15 } from "path";
|
|
3461
|
+
var SETTINGS_RELATIVE_PATH = ".pi/settings.json";
|
|
3462
|
+
var MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
|
|
3463
|
+
function readJson(path, fallback) {
|
|
3464
|
+
if (!existsSync14(path))
|
|
3465
|
+
return fallback;
|
|
3466
|
+
try {
|
|
3467
|
+
return JSON.parse(readFileSync7(path, "utf-8"));
|
|
3468
|
+
} catch {
|
|
3469
|
+
return fallback;
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
function packageKey(entry) {
|
|
3473
|
+
if (typeof entry === "string")
|
|
3474
|
+
return entry;
|
|
3475
|
+
if (entry && typeof entry === "object" && typeof entry.source === "string") {
|
|
3476
|
+
return entry.source;
|
|
3477
|
+
}
|
|
3478
|
+
return JSON.stringify(entry);
|
|
3479
|
+
}
|
|
3480
|
+
function materializePiPackages(projectRoot, declaredPackages) {
|
|
3481
|
+
const settingsPath = resolve15(projectRoot, SETTINGS_RELATIVE_PATH);
|
|
3482
|
+
const managedRecordPath = resolve15(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
|
|
3483
|
+
const settings = readJson(settingsPath, {});
|
|
3484
|
+
const previouslyManaged = new Set(readJson(managedRecordPath, []));
|
|
3485
|
+
const existing = Array.isArray(settings.packages) ? settings.packages : [];
|
|
3486
|
+
const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
|
|
3487
|
+
const operatorKeys = new Set(operatorEntries.map(packageKey));
|
|
3488
|
+
const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
|
|
3489
|
+
const nextPackages = [...operatorEntries, ...managedToAdd];
|
|
3490
|
+
if (nextPackages.length > 0 || existsSync14(settingsPath)) {
|
|
3491
|
+
const nextSettings = { ...settings };
|
|
3492
|
+
if (nextPackages.length > 0) {
|
|
3493
|
+
nextSettings.packages = nextPackages;
|
|
3494
|
+
} else {
|
|
3495
|
+
delete nextSettings.packages;
|
|
3496
|
+
}
|
|
3497
|
+
mkdirSync9(dirname10(settingsPath), { recursive: true });
|
|
3498
|
+
writeFileSync6(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
|
|
3499
|
+
`, "utf-8");
|
|
3500
|
+
}
|
|
3501
|
+
mkdirSync9(dirname10(managedRecordPath), { recursive: true });
|
|
3502
|
+
writeFileSync6(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
|
|
3503
|
+
`, "utf-8");
|
|
3504
|
+
return { settingsPath, packages: managedToAdd };
|
|
3505
|
+
}
|
|
3506
|
+
|
|
3456
3507
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
3457
3508
|
async function buildPluginHostContext(projectRoot) {
|
|
3458
3509
|
let config;
|
|
@@ -3500,6 +3551,14 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
3500
3551
|
} catch (err) {
|
|
3501
3552
|
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
3502
3553
|
}
|
|
3554
|
+
try {
|
|
3555
|
+
const piPackages = config.runtime?.pi?.packages ?? [];
|
|
3556
|
+
if (piPackages.length > 0 || existsSync15(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
|
|
3557
|
+
materializePiPackages(projectRoot, piPackages);
|
|
3558
|
+
}
|
|
3559
|
+
} catch (err) {
|
|
3560
|
+
console.warn(`[plugin-host] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
3561
|
+
}
|
|
3503
3562
|
return {
|
|
3504
3563
|
config,
|
|
3505
3564
|
pluginHost,
|
|
@@ -3513,12 +3572,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
3513
3572
|
|
|
3514
3573
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
3515
3574
|
import { spawnSync } from "child_process";
|
|
3516
|
-
import { existsSync as
|
|
3517
|
-
import { basename as basename4, join as join3, resolve as
|
|
3575
|
+
import { existsSync as existsSync17, readFileSync as readFileSync9, readdirSync as readdirSync2, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
3576
|
+
import { basename as basename4, join as join3, resolve as resolve17 } from "path";
|
|
3518
3577
|
|
|
3519
3578
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
3520
|
-
import { existsSync as
|
|
3521
|
-
import { resolve as
|
|
3579
|
+
import { existsSync as existsSync16, readFileSync as readFileSync8 } from "fs";
|
|
3580
|
+
import { resolve as resolve16 } from "path";
|
|
3522
3581
|
|
|
3523
3582
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
3524
3583
|
async function findTaskById(reader, id) {
|
|
@@ -3541,7 +3600,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
3541
3600
|
}
|
|
3542
3601
|
}
|
|
3543
3602
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
3544
|
-
const configPath = options.configPath ??
|
|
3603
|
+
const configPath = options.configPath ?? resolve16(projectRoot, ".rig", "task-config.json");
|
|
3545
3604
|
const reader = {
|
|
3546
3605
|
async listTasks() {
|
|
3547
3606
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -3552,8 +3611,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
3552
3611
|
};
|
|
3553
3612
|
return reader;
|
|
3554
3613
|
}
|
|
3555
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
3556
|
-
if (!
|
|
3614
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve16(projectRoot, ".rig", "task-config.json")) {
|
|
3615
|
+
if (!existsSync16(configPath)) {
|
|
3557
3616
|
return [];
|
|
3558
3617
|
}
|
|
3559
3618
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -3561,7 +3620,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve15(projectRoot,
|
|
|
3561
3620
|
}
|
|
3562
3621
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
3563
3622
|
try {
|
|
3564
|
-
const parsed = JSON.parse(
|
|
3623
|
+
const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
|
|
3565
3624
|
if (isPlainRecord(parsed)) {
|
|
3566
3625
|
return parsed;
|
|
3567
3626
|
}
|
|
@@ -3645,7 +3704,7 @@ function isPlainRecord(candidate) {
|
|
|
3645
3704
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
3646
3705
|
var FILE_TASK_PATTERN = /\.(task\.)?json$/;
|
|
3647
3706
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
3648
|
-
const configPath = options.configPath ??
|
|
3707
|
+
const configPath = options.configPath ?? resolve17(projectRoot, ".rig", "task-config.json");
|
|
3649
3708
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
3650
3709
|
const spawnFn = options.spawn ?? spawnSync;
|
|
3651
3710
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -3728,10 +3787,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
3728
3787
|
return metadata;
|
|
3729
3788
|
}
|
|
3730
3789
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
3731
|
-
const jsonPath =
|
|
3732
|
-
if (
|
|
3790
|
+
const jsonPath = resolve17(projectRoot, "rig.config.json");
|
|
3791
|
+
if (existsSync17(jsonPath)) {
|
|
3733
3792
|
try {
|
|
3734
|
-
const parsed = JSON.parse(
|
|
3793
|
+
const parsed = JSON.parse(readFileSync9(jsonPath, "utf8"));
|
|
3735
3794
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
3736
3795
|
const source = parsed.taskSource;
|
|
3737
3796
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -3740,12 +3799,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
3740
3799
|
return null;
|
|
3741
3800
|
}
|
|
3742
3801
|
}
|
|
3743
|
-
const tsPath =
|
|
3744
|
-
if (!
|
|
3802
|
+
const tsPath = resolve17(projectRoot, "rig.config.ts");
|
|
3803
|
+
if (!existsSync17(tsPath)) {
|
|
3745
3804
|
return null;
|
|
3746
3805
|
}
|
|
3747
3806
|
try {
|
|
3748
|
-
const source =
|
|
3807
|
+
const source = readFileSync9(tsPath, "utf8");
|
|
3749
3808
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3750
3809
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3751
3810
|
if (kind !== "files") {
|
|
@@ -3765,10 +3824,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
3765
3824
|
return isPlainRecord2(entry) ? entry : null;
|
|
3766
3825
|
}
|
|
3767
3826
|
function readRawTaskConfig(configPath) {
|
|
3768
|
-
if (!
|
|
3827
|
+
if (!existsSync17(configPath)) {
|
|
3769
3828
|
return null;
|
|
3770
3829
|
}
|
|
3771
|
-
const parsed = JSON.parse(
|
|
3830
|
+
const parsed = JSON.parse(readFileSync9(configPath, "utf8"));
|
|
3772
3831
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
3773
3832
|
}
|
|
3774
3833
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -3776,8 +3835,8 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
3776
3835
|
return tasks;
|
|
3777
3836
|
}
|
|
3778
3837
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
3779
|
-
const directory =
|
|
3780
|
-
if (!
|
|
3838
|
+
const directory = resolve17(projectRoot, sourcePath);
|
|
3839
|
+
if (!existsSync17(directory)) {
|
|
3781
3840
|
return [];
|
|
3782
3841
|
}
|
|
3783
3842
|
const tasks = [];
|
|
@@ -3792,11 +3851,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
3792
3851
|
return tasks;
|
|
3793
3852
|
}
|
|
3794
3853
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
3795
|
-
const file = findFileBackedTaskFile(
|
|
3854
|
+
const file = findFileBackedTaskFile(resolve17(projectRoot, sourcePath), taskId);
|
|
3796
3855
|
if (!file) {
|
|
3797
3856
|
return null;
|
|
3798
3857
|
}
|
|
3799
|
-
const raw = JSON.parse(
|
|
3858
|
+
const raw = JSON.parse(readFileSync9(file, "utf8"));
|
|
3800
3859
|
if (!isPlainRecord2(raw)) {
|
|
3801
3860
|
return null;
|
|
3802
3861
|
}
|
|
@@ -3809,7 +3868,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
3809
3868
|
};
|
|
3810
3869
|
}
|
|
3811
3870
|
function findFileBackedTaskFile(directory, taskId) {
|
|
3812
|
-
if (!
|
|
3871
|
+
if (!existsSync17(directory)) {
|
|
3813
3872
|
return null;
|
|
3814
3873
|
}
|
|
3815
3874
|
for (const name of readdirSync2(directory)) {
|
|
@@ -3819,7 +3878,7 @@ function findFileBackedTaskFile(directory, taskId) {
|
|
|
3819
3878
|
try {
|
|
3820
3879
|
if (!statSync4(file).isFile())
|
|
3821
3880
|
continue;
|
|
3822
|
-
const raw = JSON.parse(
|
|
3881
|
+
const raw = JSON.parse(readFileSync9(file, "utf8"));
|
|
3823
3882
|
const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
|
|
3824
3883
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
3825
3884
|
if (id === taskId) {
|
|
@@ -3979,8 +4038,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
|
|
|
3979
4038
|
}
|
|
3980
4039
|
|
|
3981
4040
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
3982
|
-
import { existsSync as
|
|
3983
|
-
import { basename as basename6, resolve as
|
|
4041
|
+
import { existsSync as existsSync21, readFileSync as readFileSync11, readdirSync as readdirSync3, statSync as statSync5, writeFileSync as writeFileSync8 } from "fs";
|
|
4042
|
+
import { basename as basename6, resolve as resolve21 } from "path";
|
|
3984
4043
|
|
|
3985
4044
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
3986
4045
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -4088,39 +4147,39 @@ function readTaskStateMetadataEnvelope(raw) {
|
|
|
4088
4147
|
};
|
|
4089
4148
|
}
|
|
4090
4149
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
4091
|
-
import { existsSync as
|
|
4092
|
-
import { resolve as
|
|
4150
|
+
import { existsSync as existsSync20, readFileSync as readFileSync10 } from "fs";
|
|
4151
|
+
import { resolve as resolve20 } from "path";
|
|
4093
4152
|
|
|
4094
4153
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
4095
|
-
import { existsSync as
|
|
4096
|
-
import { resolve as
|
|
4154
|
+
import { existsSync as existsSync19 } from "fs";
|
|
4155
|
+
import { resolve as resolve19 } from "path";
|
|
4097
4156
|
|
|
4098
4157
|
// packages/runtime/src/control-plane/repos/layout.ts
|
|
4099
4158
|
init_layout();
|
|
4100
|
-
import { existsSync as
|
|
4101
|
-
import { basename as basename5, dirname as
|
|
4159
|
+
import { existsSync as existsSync18 } from "fs";
|
|
4160
|
+
import { basename as basename5, dirname as dirname11, join as join4, resolve as resolve18 } from "path";
|
|
4102
4161
|
function resolveRepoStateDir(projectRoot) {
|
|
4103
|
-
const normalizedProjectRoot =
|
|
4104
|
-
const projectParent =
|
|
4162
|
+
const normalizedProjectRoot = resolve18(projectRoot);
|
|
4163
|
+
const projectParent = dirname11(normalizedProjectRoot);
|
|
4105
4164
|
if (basename5(projectParent) === ".worktrees") {
|
|
4106
|
-
const ownerRoot =
|
|
4107
|
-
const ownerHasRepoMarkers =
|
|
4165
|
+
const ownerRoot = dirname11(projectParent);
|
|
4166
|
+
const ownerHasRepoMarkers = existsSync18(resolve18(ownerRoot, ".git")) || existsSync18(resolve18(ownerRoot, ".rig", "state"));
|
|
4108
4167
|
if (ownerHasRepoMarkers) {
|
|
4109
|
-
return
|
|
4168
|
+
return resolve18(ownerRoot, ".rig", "state");
|
|
4110
4169
|
}
|
|
4111
4170
|
}
|
|
4112
|
-
return
|
|
4171
|
+
return resolve18(projectRoot, ".rig", "state");
|
|
4113
4172
|
}
|
|
4114
4173
|
function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
4115
|
-
const normalizedProjectRoot =
|
|
4174
|
+
const normalizedProjectRoot = resolve18(projectRoot);
|
|
4116
4175
|
const entry = getManagedRepoEntry(repoId);
|
|
4117
4176
|
const stateDir = resolveRepoStateDir(normalizedProjectRoot);
|
|
4118
4177
|
const metadataRelativePath = join4("repos", entry.id);
|
|
4119
|
-
const metadataRoot =
|
|
4178
|
+
const metadataRoot = resolve18(stateDir, metadataRelativePath);
|
|
4120
4179
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
4121
|
-
const runsInsideTaskWorktree = runtimeWorkspace &&
|
|
4180
|
+
const runsInsideTaskWorktree = runtimeWorkspace && resolve18(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname11(normalizedProjectRoot)) === ".worktrees";
|
|
4122
4181
|
const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
|
|
4123
|
-
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ?
|
|
4182
|
+
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve18(process.env[entry.checkoutEnvVar].trim()) : resolve18(normalizedProjectRoot, entry.alias);
|
|
4124
4183
|
return {
|
|
4125
4184
|
projectRoot: normalizedProjectRoot,
|
|
4126
4185
|
repoId: entry.id,
|
|
@@ -4128,12 +4187,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
|
4128
4187
|
defaultBranch: entry.defaultBranch,
|
|
4129
4188
|
remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
|
|
4130
4189
|
checkoutRoot,
|
|
4131
|
-
worktreesRoot:
|
|
4190
|
+
worktreesRoot: resolve18(checkoutRoot, ".worktrees"),
|
|
4132
4191
|
stateDir,
|
|
4133
4192
|
metadataRoot,
|
|
4134
4193
|
metadataRelativePath,
|
|
4135
|
-
mirrorRoot:
|
|
4136
|
-
mirrorStatePath:
|
|
4194
|
+
mirrorRoot: resolve18(metadataRoot, "mirror.git"),
|
|
4195
|
+
mirrorStatePath: resolve18(metadataRoot, "mirror-state.json"),
|
|
4137
4196
|
mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
|
|
4138
4197
|
};
|
|
4139
4198
|
}
|
|
@@ -4151,7 +4210,7 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
4151
4210
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
4152
4211
|
try {
|
|
4153
4212
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
4154
|
-
if (
|
|
4213
|
+
if (existsSync19(resolve19(layout.mirrorRoot, "HEAD"))) {
|
|
4155
4214
|
return layout.mirrorRoot;
|
|
4156
4215
|
}
|
|
4157
4216
|
} catch {}
|
|
@@ -4162,8 +4221,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
4162
4221
|
var DEFAULT_READ_DEPS2 = {
|
|
4163
4222
|
fetchRef: nativeFetchRef,
|
|
4164
4223
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
4165
|
-
exists:
|
|
4166
|
-
readFile: (path) =>
|
|
4224
|
+
exists: existsSync20,
|
|
4225
|
+
readFile: (path) => readFileSync10(path, "utf8")
|
|
4167
4226
|
};
|
|
4168
4227
|
function parseIssueStatus(rawStatus) {
|
|
4169
4228
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -4244,12 +4303,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
4244
4303
|
if (runtimeContextPath) {
|
|
4245
4304
|
return true;
|
|
4246
4305
|
}
|
|
4247
|
-
return
|
|
4306
|
+
return existsSync20(resolve20(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
4248
4307
|
}
|
|
4249
4308
|
function readLocalTrackerState(projectRoot, deps) {
|
|
4250
4309
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
4251
|
-
const issuesPath =
|
|
4252
|
-
const taskStatePath =
|
|
4310
|
+
const issuesPath = resolve20(monorepoRoot, ".beads", "issues.jsonl");
|
|
4311
|
+
const taskStatePath = resolve20(monorepoRoot, ".beads", "task-state.json");
|
|
4253
4312
|
return projectSyncedTrackerSnapshot({
|
|
4254
4313
|
source: "local",
|
|
4255
4314
|
issuesBaseOid: null,
|
|
@@ -4311,7 +4370,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
4311
4370
|
return readValidationDescriptionMap(raw);
|
|
4312
4371
|
}
|
|
4313
4372
|
function readSourceValidationDescriptions(projectRoot) {
|
|
4314
|
-
const rootRaw = readJsonFile(
|
|
4373
|
+
const rootRaw = readJsonFile(resolve21(projectRoot, "rig", "task-config.json"), {});
|
|
4315
4374
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
4316
4375
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
4317
4376
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -4387,15 +4446,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
4387
4446
|
return meta.validation_descriptions;
|
|
4388
4447
|
}
|
|
4389
4448
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
4390
|
-
const taskStatePath =
|
|
4449
|
+
const taskStatePath = resolve21(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
4391
4450
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
4392
4451
|
}
|
|
4393
4452
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
4394
|
-
const issuesPath =
|
|
4395
|
-
if (!
|
|
4453
|
+
const issuesPath = resolve21(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
4454
|
+
if (!existsSync21(issuesPath)) {
|
|
4396
4455
|
return null;
|
|
4397
4456
|
}
|
|
4398
|
-
for (const line of
|
|
4457
|
+
for (const line of readFileSync11(issuesPath, "utf8").split(/\r?\n/)) {
|
|
4399
4458
|
const trimmed = line.trim();
|
|
4400
4459
|
if (!trimmed) {
|
|
4401
4460
|
continue;
|
|
@@ -4420,25 +4479,25 @@ function inferTaskIdFromRuntimePath(path) {
|
|
|
4420
4479
|
function artifactDirForId(projectRoot, id) {
|
|
4421
4480
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
4422
4481
|
if (workspaceDir) {
|
|
4423
|
-
const worktreeArtifacts =
|
|
4424
|
-
if (
|
|
4482
|
+
const worktreeArtifacts = resolve21(workspaceDir, "artifacts", id);
|
|
4483
|
+
if (existsSync21(worktreeArtifacts) || existsSync21(resolve21(workspaceDir, "artifacts"))) {
|
|
4425
4484
|
return worktreeArtifacts;
|
|
4426
4485
|
}
|
|
4427
4486
|
}
|
|
4428
4487
|
try {
|
|
4429
4488
|
const paths = resolveHarnessPaths(projectRoot);
|
|
4430
|
-
return
|
|
4489
|
+
return resolve21(paths.artifactsDir, id);
|
|
4431
4490
|
} catch {
|
|
4432
|
-
return
|
|
4491
|
+
return resolve21(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
4433
4492
|
}
|
|
4434
4493
|
}
|
|
4435
4494
|
function resolveTaskConfigPath(projectRoot) {
|
|
4436
4495
|
const paths = resolveHarnessPaths(projectRoot);
|
|
4437
|
-
if (
|
|
4496
|
+
if (existsSync21(paths.taskConfigPath)) {
|
|
4438
4497
|
return paths.taskConfigPath;
|
|
4439
4498
|
}
|
|
4440
4499
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
4441
|
-
if (
|
|
4500
|
+
if (existsSync21(candidate)) {
|
|
4442
4501
|
return candidate;
|
|
4443
4502
|
}
|
|
4444
4503
|
}
|
|
@@ -4446,7 +4505,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
4446
4505
|
}
|
|
4447
4506
|
function findSourceTaskConfigPath(projectRoot) {
|
|
4448
4507
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
4449
|
-
if (
|
|
4508
|
+
if (existsSync21(candidate)) {
|
|
4450
4509
|
return candidate;
|
|
4451
4510
|
}
|
|
4452
4511
|
}
|
|
@@ -4459,7 +4518,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
4459
4518
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
4460
4519
|
if (sourcePath && synced.updated) {
|
|
4461
4520
|
try {
|
|
4462
|
-
|
|
4521
|
+
writeFileSync8(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
4463
4522
|
`, "utf-8");
|
|
4464
4523
|
} catch {}
|
|
4465
4524
|
}
|
|
@@ -4511,12 +4570,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
4511
4570
|
return !candidate.role;
|
|
4512
4571
|
}
|
|
4513
4572
|
function readSourceIssueRecords(projectRoot) {
|
|
4514
|
-
const issuesPath =
|
|
4515
|
-
if (!
|
|
4573
|
+
const issuesPath = resolve21(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
4574
|
+
if (!existsSync21(issuesPath)) {
|
|
4516
4575
|
return [];
|
|
4517
4576
|
}
|
|
4518
4577
|
const records = [];
|
|
4519
|
-
for (const line of
|
|
4578
|
+
for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
4520
4579
|
const trimmed = line.trim();
|
|
4521
4580
|
if (!trimmed) {
|
|
4522
4581
|
continue;
|
|
@@ -4572,19 +4631,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
4572
4631
|
if (!sourcePath) {
|
|
4573
4632
|
return {};
|
|
4574
4633
|
}
|
|
4575
|
-
const directory =
|
|
4576
|
-
if (!
|
|
4634
|
+
const directory = resolve21(projectRoot, sourcePath);
|
|
4635
|
+
if (!existsSync21(directory)) {
|
|
4577
4636
|
return {};
|
|
4578
4637
|
}
|
|
4579
4638
|
const config = {};
|
|
4580
4639
|
for (const name of readdirSync3(directory)) {
|
|
4581
4640
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
4582
4641
|
continue;
|
|
4583
|
-
const file =
|
|
4642
|
+
const file = resolve21(directory, name);
|
|
4584
4643
|
try {
|
|
4585
4644
|
if (!statSync5(file).isFile())
|
|
4586
4645
|
continue;
|
|
4587
|
-
const raw = JSON.parse(
|
|
4646
|
+
const raw = JSON.parse(readFileSync11(file, "utf8"));
|
|
4588
4647
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
4589
4648
|
continue;
|
|
4590
4649
|
const record = raw;
|
|
@@ -4626,10 +4685,10 @@ function firstStringList2(...candidates) {
|
|
|
4626
4685
|
return [];
|
|
4627
4686
|
}
|
|
4628
4687
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
4629
|
-
const jsonPath =
|
|
4630
|
-
if (
|
|
4688
|
+
const jsonPath = resolve21(projectRoot, "rig.config.json");
|
|
4689
|
+
if (existsSync21(jsonPath)) {
|
|
4631
4690
|
try {
|
|
4632
|
-
const parsed = JSON.parse(
|
|
4691
|
+
const parsed = JSON.parse(readFileSync11(jsonPath, "utf8"));
|
|
4633
4692
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4634
4693
|
const taskSource = parsed.taskSource;
|
|
4635
4694
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -4641,12 +4700,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
4641
4700
|
return null;
|
|
4642
4701
|
}
|
|
4643
4702
|
}
|
|
4644
|
-
const tsPath =
|
|
4645
|
-
if (!
|
|
4703
|
+
const tsPath = resolve21(projectRoot, "rig.config.ts");
|
|
4704
|
+
if (!existsSync21(tsPath)) {
|
|
4646
4705
|
return null;
|
|
4647
4706
|
}
|
|
4648
4707
|
try {
|
|
4649
|
-
const source =
|
|
4708
|
+
const source = readFileSync11(tsPath, "utf8");
|
|
4650
4709
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
4651
4710
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
4652
4711
|
if (kind !== "files") {
|
|
@@ -4660,9 +4719,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
4660
4719
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
4661
4720
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
4662
4721
|
return [
|
|
4663
|
-
runtimeContext?.monorepoMainRoot ?
|
|
4664
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
4665
|
-
|
|
4722
|
+
runtimeContext?.monorepoMainRoot ? resolve21(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
4723
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve21(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
4724
|
+
resolve21(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
4666
4725
|
].filter(Boolean);
|
|
4667
4726
|
}
|
|
4668
4727
|
|
|
@@ -4671,8 +4730,8 @@ init_layout();
|
|
|
4671
4730
|
|
|
4672
4731
|
// packages/runtime/src/binary-run.ts
|
|
4673
4732
|
init_layout();
|
|
4674
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
4675
|
-
import { basename as basename7, dirname as
|
|
4733
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync22, mkdirSync as mkdirSync10, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
4734
|
+
import { basename as basename7, dirname as dirname12, resolve as resolve22 } from "path";
|
|
4676
4735
|
import { fileURLToPath } from "url";
|
|
4677
4736
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
4678
4737
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -4698,9 +4757,9 @@ async function buildRuntimeBinary(options) {
|
|
|
4698
4757
|
});
|
|
4699
4758
|
}
|
|
4700
4759
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
4701
|
-
const tempBuildDir =
|
|
4702
|
-
const tempOutputPath =
|
|
4703
|
-
|
|
4760
|
+
const tempBuildDir = resolve22(dirname12(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
4761
|
+
const tempOutputPath = resolve22(tempBuildDir, basename7(options.outputPath));
|
|
4762
|
+
mkdirSync10(tempBuildDir, { recursive: true });
|
|
4704
4763
|
await withTemporaryEnv({
|
|
4705
4764
|
...options.env,
|
|
4706
4765
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -4725,7 +4784,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
4725
4784
|
`);
|
|
4726
4785
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
4727
4786
|
}
|
|
4728
|
-
if (!
|
|
4787
|
+
if (!existsSync22(tempOutputPath)) {
|
|
4729
4788
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
4730
4789
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
4731
4790
|
}
|
|
@@ -4757,8 +4816,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
4757
4816
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
4758
4817
|
return {
|
|
4759
4818
|
...options,
|
|
4760
|
-
entrypoint:
|
|
4761
|
-
outputPath:
|
|
4819
|
+
entrypoint: resolve22(options.cwd, options.sourcePath),
|
|
4820
|
+
outputPath: resolve22(options.outputPath)
|
|
4762
4821
|
};
|
|
4763
4822
|
}
|
|
4764
4823
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -4772,7 +4831,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
4772
4831
|
}
|
|
4773
4832
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
4774
4833
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
4775
|
-
if (!workerSourcePath || !
|
|
4834
|
+
if (!workerSourcePath || !existsSync22(workerSourcePath)) {
|
|
4776
4835
|
await buildRuntimeBinaryInProcess(options, {
|
|
4777
4836
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
4778
4837
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -4809,7 +4868,7 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
4809
4868
|
}
|
|
4810
4869
|
}
|
|
4811
4870
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
4812
|
-
return
|
|
4871
|
+
return resolve22(dirname12(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
4813
4872
|
}
|
|
4814
4873
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
4815
4874
|
const envRoots = [
|
|
@@ -4818,13 +4877,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
4818
4877
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4819
4878
|
].filter(Boolean);
|
|
4820
4879
|
for (const root of envRoots) {
|
|
4821
|
-
const candidate =
|
|
4822
|
-
if (
|
|
4880
|
+
const candidate = resolve22(root, "packages/runtime/src/binary-build-worker.ts");
|
|
4881
|
+
if (existsSync22(candidate)) {
|
|
4823
4882
|
return candidate;
|
|
4824
4883
|
}
|
|
4825
4884
|
}
|
|
4826
|
-
const localCandidate =
|
|
4827
|
-
return
|
|
4885
|
+
const localCandidate = resolve22(import.meta.dir, "binary-build-worker.ts");
|
|
4886
|
+
return existsSync22(localCandidate) ? localCandidate : null;
|
|
4828
4887
|
}
|
|
4829
4888
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
4830
4889
|
const bunPath = Bun.which("bun");
|
|
@@ -4860,7 +4919,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
4860
4919
|
});
|
|
4861
4920
|
}
|
|
4862
4921
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
4863
|
-
if (!
|
|
4922
|
+
if (!existsSync22(input.outputPath) || !existsSync22(input.manifestPath)) {
|
|
4864
4923
|
return false;
|
|
4865
4924
|
}
|
|
4866
4925
|
let manifest = null;
|
|
@@ -4873,7 +4932,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
4873
4932
|
return false;
|
|
4874
4933
|
}
|
|
4875
4934
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
4876
|
-
if (!
|
|
4935
|
+
if (!existsSync22(filePath)) {
|
|
4877
4936
|
return false;
|
|
4878
4937
|
}
|
|
4879
4938
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -4886,7 +4945,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
4886
4945
|
const inputs = {};
|
|
4887
4946
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
4888
4947
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
4889
|
-
if (!normalized || !
|
|
4948
|
+
if (!normalized || !existsSync22(normalized)) {
|
|
4890
4949
|
continue;
|
|
4891
4950
|
}
|
|
4892
4951
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -4909,7 +4968,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
4909
4968
|
if (inputPath.startsWith("<")) {
|
|
4910
4969
|
return null;
|
|
4911
4970
|
}
|
|
4912
|
-
return
|
|
4971
|
+
return resolve22(cwd, inputPath);
|
|
4913
4972
|
}
|
|
4914
4973
|
async function sha256File4(path) {
|
|
4915
4974
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -4925,8 +4984,8 @@ function sortRecord(value) {
|
|
|
4925
4984
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
4926
4985
|
const previous = runtimeBinaryBuildQueue;
|
|
4927
4986
|
let release;
|
|
4928
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
4929
|
-
release =
|
|
4987
|
+
runtimeBinaryBuildQueue = new Promise((resolve23) => {
|
|
4988
|
+
release = resolve23;
|
|
4930
4989
|
});
|
|
4931
4990
|
await previous;
|
|
4932
4991
|
try {
|
|
@@ -4971,11 +5030,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
4971
5030
|
}
|
|
4972
5031
|
|
|
4973
5032
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
4974
|
-
import { delimiter, resolve as
|
|
5033
|
+
import { delimiter, resolve as resolve25 } from "path";
|
|
4975
5034
|
|
|
4976
5035
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
4977
|
-
import { existsSync as
|
|
4978
|
-
import { resolve as
|
|
5036
|
+
import { existsSync as existsSync24, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
|
|
5037
|
+
import { resolve as resolve24 } from "path";
|
|
4979
5038
|
|
|
4980
5039
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
4981
5040
|
init_utils();
|
|
@@ -4992,7 +5051,7 @@ function resolveBunBinaryPath() {
|
|
|
4992
5051
|
}
|
|
4993
5052
|
const home = process.env.HOME?.trim();
|
|
4994
5053
|
const fallbackCandidates = [
|
|
4995
|
-
home ?
|
|
5054
|
+
home ? resolve24(home, ".bun/bin/bun") : "",
|
|
4996
5055
|
"/opt/homebrew/bin/bun",
|
|
4997
5056
|
"/usr/local/bin/bun",
|
|
4998
5057
|
"/usr/bin/bun"
|
|
@@ -5020,8 +5079,8 @@ function resolveClaudeBinaryPath() {
|
|
|
5020
5079
|
}
|
|
5021
5080
|
const home = process.env.HOME?.trim();
|
|
5022
5081
|
const fallbackCandidates = [
|
|
5023
|
-
home ?
|
|
5024
|
-
home ?
|
|
5082
|
+
home ? resolve24(home, ".local/bin/claude") : "",
|
|
5083
|
+
home ? resolve24(home, ".local/share/claude/local/claude") : "",
|
|
5025
5084
|
"/opt/homebrew/bin/claude",
|
|
5026
5085
|
"/usr/local/bin/claude",
|
|
5027
5086
|
"/usr/bin/claude"
|
|
@@ -5035,35 +5094,35 @@ function resolveClaudeBinaryPath() {
|
|
|
5035
5094
|
throw new Error("claude not found in PATH");
|
|
5036
5095
|
}
|
|
5037
5096
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
5038
|
-
return
|
|
5097
|
+
return resolve24(bunBinaryPath, "../..");
|
|
5039
5098
|
}
|
|
5040
5099
|
function resolveClaudeInstallDir() {
|
|
5041
5100
|
const realPath = resolveClaudeBinaryPath();
|
|
5042
|
-
return
|
|
5101
|
+
return resolve24(realPath, "..");
|
|
5043
5102
|
}
|
|
5044
5103
|
function resolveNodeInstallDir() {
|
|
5045
5104
|
const preferredNode = resolvePreferredNodeBinary();
|
|
5046
5105
|
if (!preferredNode)
|
|
5047
5106
|
return null;
|
|
5048
5107
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
5049
|
-
if (explicitNode &&
|
|
5050
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
5108
|
+
if (explicitNode && resolve24(explicitNode) === resolve24(preferredNode)) {
|
|
5109
|
+
return preferredNode.endsWith("/bin/node") ? resolve24(preferredNode, "../..") : resolve24(preferredNode, "..");
|
|
5051
5110
|
}
|
|
5052
5111
|
try {
|
|
5053
5112
|
const realPath = realpathSync2(preferredNode);
|
|
5054
5113
|
if (realPath.endsWith("/bin/node")) {
|
|
5055
|
-
return
|
|
5114
|
+
return resolve24(realPath, "../..");
|
|
5056
5115
|
}
|
|
5057
|
-
return
|
|
5116
|
+
return resolve24(realPath, "..");
|
|
5058
5117
|
} catch {
|
|
5059
|
-
return
|
|
5118
|
+
return resolve24(preferredNode, "..");
|
|
5060
5119
|
}
|
|
5061
5120
|
}
|
|
5062
5121
|
function resolveRuntimeDependencyRoots(runtimeDirs) {
|
|
5063
5122
|
const roots = [];
|
|
5064
5123
|
if (process.platform === "darwin") {
|
|
5065
5124
|
for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
|
|
5066
|
-
if (
|
|
5125
|
+
if (existsSync24(macPath)) {
|
|
5067
5126
|
roots.push(macPath);
|
|
5068
5127
|
}
|
|
5069
5128
|
}
|
|
@@ -5081,23 +5140,23 @@ function resolvePreferredNodeBinary() {
|
|
|
5081
5140
|
const candidates = [];
|
|
5082
5141
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
5083
5142
|
if (envNode) {
|
|
5084
|
-
const explicit =
|
|
5085
|
-
if (
|
|
5143
|
+
const explicit = resolve24(envNode);
|
|
5144
|
+
if (existsSync24(explicit)) {
|
|
5086
5145
|
return explicit;
|
|
5087
5146
|
}
|
|
5088
5147
|
}
|
|
5089
5148
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
5090
5149
|
if (nvmBin) {
|
|
5091
|
-
candidates.push(
|
|
5150
|
+
candidates.push(resolve24(nvmBin, "node"));
|
|
5092
5151
|
}
|
|
5093
5152
|
const home = process.env.HOME?.trim();
|
|
5094
5153
|
if (home) {
|
|
5095
|
-
const nvmVersionsDir =
|
|
5096
|
-
if (
|
|
5154
|
+
const nvmVersionsDir = resolve24(home, ".nvm/versions/node");
|
|
5155
|
+
if (existsSync24(nvmVersionsDir)) {
|
|
5097
5156
|
try {
|
|
5098
5157
|
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/, "")));
|
|
5099
5158
|
for (const versionDir of versionDirs) {
|
|
5100
|
-
candidates.push(
|
|
5159
|
+
candidates.push(resolve24(nvmVersionsDir, versionDir, "bin/node"));
|
|
5101
5160
|
}
|
|
5102
5161
|
} catch {}
|
|
5103
5162
|
}
|
|
@@ -5106,8 +5165,8 @@ function resolvePreferredNodeBinary() {
|
|
|
5106
5165
|
if (whichNode) {
|
|
5107
5166
|
candidates.push(whichNode);
|
|
5108
5167
|
}
|
|
5109
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
5110
|
-
const existing = deduped.filter((candidate) =>
|
|
5168
|
+
const deduped = uniq(candidates.map((candidate) => resolve24(candidate)));
|
|
5169
|
+
const existing = deduped.filter((candidate) => existsSync24(candidate));
|
|
5111
5170
|
if (existing.length === 0) {
|
|
5112
5171
|
return null;
|
|
5113
5172
|
}
|
|
@@ -5121,7 +5180,7 @@ function resolvePreferredNodeBinary() {
|
|
|
5121
5180
|
return existing[0] ?? null;
|
|
5122
5181
|
}
|
|
5123
5182
|
function inferNodeMajor(nodeBinaryPath) {
|
|
5124
|
-
const normalized =
|
|
5183
|
+
const normalized = resolve24(nodeBinaryPath).replace(/\\/g, "/");
|
|
5125
5184
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
5126
5185
|
if (!match) {
|
|
5127
5186
|
return null;
|
|
@@ -5133,8 +5192,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
5133
5192
|
if (!candidate) {
|
|
5134
5193
|
return "";
|
|
5135
5194
|
}
|
|
5136
|
-
const normalized =
|
|
5137
|
-
if (!
|
|
5195
|
+
const normalized = resolve24(candidate);
|
|
5196
|
+
if (!existsSync24(normalized)) {
|
|
5138
5197
|
return "";
|
|
5139
5198
|
}
|
|
5140
5199
|
try {
|
|
@@ -5144,7 +5203,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
5144
5203
|
}
|
|
5145
5204
|
}
|
|
5146
5205
|
function looksLikeRuntimeGateway(candidate) {
|
|
5147
|
-
const normalized =
|
|
5206
|
+
const normalized = resolve24(candidate).replace(/\\/g, "/");
|
|
5148
5207
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
5149
5208
|
}
|
|
5150
5209
|
|
|
@@ -5165,7 +5224,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5165
5224
|
try {
|
|
5166
5225
|
return resolveClaudeInstallDir();
|
|
5167
5226
|
} catch {
|
|
5168
|
-
return
|
|
5227
|
+
return resolve25(claudeBinary, "..");
|
|
5169
5228
|
}
|
|
5170
5229
|
})() : "";
|
|
5171
5230
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -5175,8 +5234,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5175
5234
|
`${bunDir}/bin`,
|
|
5176
5235
|
claudeDir,
|
|
5177
5236
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
5178
|
-
realHome ?
|
|
5179
|
-
realHome ?
|
|
5237
|
+
realHome ? resolve25(realHome, ".local/bin") : "",
|
|
5238
|
+
realHome ? resolve25(realHome, ".cargo/bin") : "",
|
|
5180
5239
|
...inheritedPath,
|
|
5181
5240
|
"/usr/local/bin",
|
|
5182
5241
|
"/usr/local/sbin",
|
|
@@ -5205,8 +5264,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
5205
5264
|
}
|
|
5206
5265
|
|
|
5207
5266
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
5208
|
-
import { existsSync as
|
|
5209
|
-
import { resolve as
|
|
5267
|
+
import { existsSync as existsSync25, readFileSync as readFileSync12 } from "fs";
|
|
5268
|
+
import { resolve as resolve26 } from "path";
|
|
5210
5269
|
var BAKED_RUNTIME_SECRETS = {
|
|
5211
5270
|
ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
|
|
5212
5271
|
OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
|
|
@@ -5249,12 +5308,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
|
|
|
5249
5308
|
return resolved;
|
|
5250
5309
|
}
|
|
5251
5310
|
function loadDotEnvSecrets(projectRoot, env = process.env) {
|
|
5252
|
-
const dotenvPath =
|
|
5253
|
-
if (!
|
|
5311
|
+
const dotenvPath = resolve26(projectRoot, ".env");
|
|
5312
|
+
if (!existsSync25(dotenvPath)) {
|
|
5254
5313
|
return {};
|
|
5255
5314
|
}
|
|
5256
5315
|
const parsed = {};
|
|
5257
|
-
const lines =
|
|
5316
|
+
const lines = readFileSync12(dotenvPath, "utf-8").split(/\r?\n/);
|
|
5258
5317
|
for (const rawLine of lines) {
|
|
5259
5318
|
const line = rawLine.trim();
|
|
5260
5319
|
if (!line || line.startsWith("#")) {
|
|
@@ -5611,16 +5670,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
5611
5670
|
for (const dep of deps) {
|
|
5612
5671
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
5613
5672
|
console.log(`=== ${dep} ===`);
|
|
5614
|
-
if (!
|
|
5673
|
+
if (!existsSync26(artifactDir)) {
|
|
5615
5674
|
console.log(` (no artifacts yet)
|
|
5616
5675
|
`);
|
|
5617
5676
|
continue;
|
|
5618
5677
|
}
|
|
5619
|
-
printArtifactSection(
|
|
5620
|
-
printArtifactSection(
|
|
5621
|
-
const changedFiles =
|
|
5622
|
-
if (
|
|
5623
|
-
const lines =
|
|
5678
|
+
printArtifactSection(resolve27(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
5679
|
+
printArtifactSection(resolve27(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
5680
|
+
const changedFiles = resolve27(artifactDir, "changed-files.txt");
|
|
5681
|
+
if (existsSync26(changedFiles)) {
|
|
5682
|
+
const lines = readFileSync13(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
5624
5683
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
5625
5684
|
for (const line of lines) {
|
|
5626
5685
|
console.log(line);
|
|
@@ -5744,12 +5803,12 @@ function printIndented(text) {
|
|
|
5744
5803
|
}
|
|
5745
5804
|
}
|
|
5746
5805
|
function readLocalBeadsTasks(projectRoot) {
|
|
5747
|
-
const issuesPath =
|
|
5748
|
-
if (!
|
|
5806
|
+
const issuesPath = resolve27(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
5807
|
+
if (!existsSync26(issuesPath)) {
|
|
5749
5808
|
return [];
|
|
5750
5809
|
}
|
|
5751
5810
|
const tasks = [];
|
|
5752
|
-
for (const line of
|
|
5811
|
+
for (const line of readFileSync13(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
5753
5812
|
const trimmed = line.trim();
|
|
5754
5813
|
if (!trimmed) {
|
|
5755
5814
|
continue;
|
|
@@ -5862,11 +5921,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
5862
5921
|
return [...ids].sort();
|
|
5863
5922
|
}
|
|
5864
5923
|
function printArtifactSection(path, header) {
|
|
5865
|
-
if (!
|
|
5924
|
+
if (!existsSync26(path)) {
|
|
5866
5925
|
return;
|
|
5867
5926
|
}
|
|
5868
5927
|
console.log(header);
|
|
5869
|
-
process.stdout.write(
|
|
5928
|
+
process.stdout.write(readFileSync13(path, "utf-8"));
|
|
5870
5929
|
console.log("");
|
|
5871
5930
|
}
|
|
5872
5931
|
|
|
@@ -5968,7 +6027,7 @@ init_layout();
|
|
|
5968
6027
|
|
|
5969
6028
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5970
6029
|
init_layout();
|
|
5971
|
-
import { mkdirSync as
|
|
6030
|
+
import { mkdirSync as mkdirSync12 } from "fs";
|
|
5972
6031
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5973
6032
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5974
6033
|
const rootDir = layout.rigRoot;
|
|
@@ -5980,14 +6039,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5980
6039
|
const sessionDir = layout.sessionDir;
|
|
5981
6040
|
const runtimeDir = layout.runtimeDir;
|
|
5982
6041
|
const contextPath = layout.contextPath;
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
6042
|
+
mkdirSync12(rootDir, { recursive: true });
|
|
6043
|
+
mkdirSync12(homeDir, { recursive: true });
|
|
6044
|
+
mkdirSync12(tmpDir, { recursive: true });
|
|
6045
|
+
mkdirSync12(cacheDir, { recursive: true });
|
|
6046
|
+
mkdirSync12(logsDir, { recursive: true });
|
|
6047
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
6048
|
+
mkdirSync12(sessionDir, { recursive: true });
|
|
6049
|
+
mkdirSync12(runtimeDir, { recursive: true });
|
|
5991
6050
|
return {
|
|
5992
6051
|
rootDir,
|
|
5993
6052
|
homeDir,
|
|
@@ -6005,17 +6064,17 @@ import {
|
|
|
6005
6064
|
chmodSync as chmodSync5,
|
|
6006
6065
|
copyFileSync as copyFileSync5,
|
|
6007
6066
|
cpSync as cpSync2,
|
|
6008
|
-
existsSync as
|
|
6009
|
-
mkdirSync as
|
|
6067
|
+
existsSync as existsSync28,
|
|
6068
|
+
mkdirSync as mkdirSync13,
|
|
6010
6069
|
statSync as statSync6,
|
|
6011
|
-
writeFileSync as
|
|
6070
|
+
writeFileSync as writeFileSync11
|
|
6012
6071
|
} from "fs";
|
|
6013
6072
|
import { mkdir as mkdir2 } from "fs/promises";
|
|
6014
|
-
import { basename as basename8, delimiter as delimiter2, resolve as
|
|
6073
|
+
import { basename as basename8, delimiter as delimiter2, resolve as resolve29 } from "path";
|
|
6015
6074
|
|
|
6016
6075
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
6017
|
-
import { existsSync as
|
|
6018
|
-
import { resolve as
|
|
6076
|
+
import { existsSync as existsSync27, readFileSync as readFileSync14, rmSync as rmSync9 } from "fs";
|
|
6077
|
+
import { resolve as resolve28 } from "path";
|
|
6019
6078
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
6020
6079
|
var generatedCredentialFiles = new Set;
|
|
6021
6080
|
var credentialCleanupRegistered = false;
|
|
@@ -6040,7 +6099,7 @@ function resolveHostGitBinary() {
|
|
|
6040
6099
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
6041
6100
|
continue;
|
|
6042
6101
|
}
|
|
6043
|
-
if (
|
|
6102
|
+
if (existsSync27(candidate)) {
|
|
6044
6103
|
return candidate;
|
|
6045
6104
|
}
|
|
6046
6105
|
}
|
|
@@ -6106,7 +6165,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
6106
6165
|
}
|
|
6107
6166
|
}
|
|
6108
6167
|
async function tryReadGitHead(repoRoot) {
|
|
6109
|
-
if (!
|
|
6168
|
+
if (!existsSync27(resolve28(repoRoot, ".git"))) {
|
|
6110
6169
|
return;
|
|
6111
6170
|
}
|
|
6112
6171
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -6117,7 +6176,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
6117
6176
|
return value || undefined;
|
|
6118
6177
|
}
|
|
6119
6178
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
6120
|
-
if (!
|
|
6179
|
+
if (!existsSync27(resolve28(repoRoot, ".git"))) {
|
|
6121
6180
|
return [];
|
|
6122
6181
|
}
|
|
6123
6182
|
const files = new Set;
|
|
@@ -6208,16 +6267,16 @@ function hashProjectPath(workspaceDir) {
|
|
|
6208
6267
|
}
|
|
6209
6268
|
function resolveGithubCliBinaryPath() {
|
|
6210
6269
|
const explicit = process.env.RIG_GH_BIN?.trim();
|
|
6211
|
-
if (explicit &&
|
|
6270
|
+
if (explicit && existsSync27(explicit) && !isRuntimeGatewayGhPath(explicit)) {
|
|
6212
6271
|
return explicit;
|
|
6213
6272
|
}
|
|
6214
6273
|
for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
|
|
6215
|
-
if (
|
|
6274
|
+
if (existsSync27(candidate)) {
|
|
6216
6275
|
return candidate;
|
|
6217
6276
|
}
|
|
6218
6277
|
}
|
|
6219
6278
|
const bunResolved = Bun.which("gh");
|
|
6220
|
-
if (bunResolved &&
|
|
6279
|
+
if (bunResolved && existsSync27(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
|
|
6221
6280
|
return bunResolved;
|
|
6222
6281
|
}
|
|
6223
6282
|
return "";
|
|
@@ -6251,17 +6310,17 @@ function resolveSystemCertBundlePath() {
|
|
|
6251
6310
|
"/opt/homebrew/etc/openssl@3/cert.pem"
|
|
6252
6311
|
];
|
|
6253
6312
|
for (const candidate of candidates) {
|
|
6254
|
-
if (candidate &&
|
|
6255
|
-
return
|
|
6313
|
+
if (candidate && existsSync27(candidate)) {
|
|
6314
|
+
return resolve28(candidate);
|
|
6256
6315
|
}
|
|
6257
6316
|
}
|
|
6258
6317
|
return "";
|
|
6259
6318
|
}
|
|
6260
6319
|
function readKnownHosts(path) {
|
|
6261
|
-
if (!
|
|
6320
|
+
if (!existsSync27(path)) {
|
|
6262
6321
|
return new Set;
|
|
6263
6322
|
}
|
|
6264
|
-
return new Set(
|
|
6323
|
+
return new Set(readFileSync14(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
6265
6324
|
}
|
|
6266
6325
|
|
|
6267
6326
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -6276,12 +6335,12 @@ function resolveControlPlaneSourceRoot(projectRoot) {
|
|
|
6276
6335
|
const candidates = [
|
|
6277
6336
|
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
6278
6337
|
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
6279
|
-
|
|
6338
|
+
resolve29(import.meta.dir, "../../../../.."),
|
|
6280
6339
|
projectRoot
|
|
6281
6340
|
].filter((value) => Boolean(value));
|
|
6282
6341
|
for (const candidate of candidates) {
|
|
6283
|
-
const root =
|
|
6284
|
-
if (
|
|
6342
|
+
const root = resolve29(candidate);
|
|
6343
|
+
if (existsSync28(resolve29(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
6285
6344
|
return root;
|
|
6286
6345
|
}
|
|
6287
6346
|
}
|
|
@@ -6301,7 +6360,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6301
6360
|
try {
|
|
6302
6361
|
return resolveClaudeInstallDir();
|
|
6303
6362
|
} catch {
|
|
6304
|
-
return
|
|
6363
|
+
return resolve29(claudeBinaryPath, "..");
|
|
6305
6364
|
}
|
|
6306
6365
|
})() : "";
|
|
6307
6366
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -6316,8 +6375,8 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6316
6375
|
`${bunDir}/bin`,
|
|
6317
6376
|
claudeDir,
|
|
6318
6377
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
6319
|
-
realHome ?
|
|
6320
|
-
realHome ?
|
|
6378
|
+
realHome ? resolve29(realHome, ".local/bin") : "",
|
|
6379
|
+
realHome ? resolve29(realHome, ".cargo/bin") : "",
|
|
6321
6380
|
...inheritedPath,
|
|
6322
6381
|
"/usr/local/bin",
|
|
6323
6382
|
"/usr/local/sbin",
|
|
@@ -6328,9 +6387,9 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6328
6387
|
"/usr/sbin",
|
|
6329
6388
|
"/sbin"
|
|
6330
6389
|
].filter(Boolean);
|
|
6331
|
-
const runtimeBash =
|
|
6332
|
-
const runtimeRigGit =
|
|
6333
|
-
const preferredShell =
|
|
6390
|
+
const runtimeBash = resolve29(runtime.binDir, "bash");
|
|
6391
|
+
const runtimeRigGit = resolve29(runtime.binDir, runtimeRigGitFileName());
|
|
6392
|
+
const preferredShell = existsSync28(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
6334
6393
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
6335
6394
|
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
6336
6395
|
const env = {
|
|
@@ -6351,30 +6410,30 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6351
6410
|
RIG_RUNTIME_MODE: runtime.mode,
|
|
6352
6411
|
RIG_RUNTIME_HOME: runtime.rootDir,
|
|
6353
6412
|
RIG_RUNTIME_BIN_DIR: runtime.binDir,
|
|
6354
|
-
...
|
|
6413
|
+
...existsSync28(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
|
|
6355
6414
|
RIG_BUN_PATH: bunBinaryPath,
|
|
6356
6415
|
...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
|
|
6357
|
-
RIG_AGENT_BIN:
|
|
6416
|
+
RIG_AGENT_BIN: resolve29(runtime.binDir, "rig-agent"),
|
|
6358
6417
|
RIG_HOOKS_ACTIVE: "1",
|
|
6359
6418
|
RIG_AUTO_PR_ON_COMPLETE: "1",
|
|
6360
|
-
RIG_POLICY_FILE:
|
|
6419
|
+
RIG_POLICY_FILE: resolve29(projectRoot, "rig/policy/policy.json"),
|
|
6361
6420
|
RIG_STATE_DIR: runtime.stateDir,
|
|
6362
6421
|
RIG_LOGS_DIR: runtime.logsDir,
|
|
6363
|
-
RIG_SESSION_FILE:
|
|
6422
|
+
RIG_SESSION_FILE: resolve29(runtime.sessionDir, "session.json"),
|
|
6364
6423
|
MONOREPO_ROOT: runtime.workspaceDir,
|
|
6365
6424
|
MONOREPO_MAIN_ROOT: monorepoMainRoot,
|
|
6366
|
-
TS_API_TESTS_DIR:
|
|
6425
|
+
TS_API_TESTS_DIR: resolve29(runtime.workspaceDir, "TSAPITests"),
|
|
6367
6426
|
BASH: preferredShell,
|
|
6368
6427
|
SHELL: preferredShell,
|
|
6369
6428
|
PATH: [...new Set(pathEntries)].join(delimiter2),
|
|
6370
6429
|
LANG: process.env.LANG ?? "en_US.UTF-8",
|
|
6371
6430
|
TERM: process.env.TERM ?? "xterm-256color",
|
|
6372
6431
|
PYTHONDONTWRITEBYTECODE: "1",
|
|
6373
|
-
PYTHONPYCACHEPREFIX:
|
|
6432
|
+
PYTHONPYCACHEPREFIX: resolve29(runtime.cacheDir, "python"),
|
|
6374
6433
|
...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
|
|
6375
6434
|
...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
|
|
6376
6435
|
CLAUDE_HOME: runtime.claudeHomeDir,
|
|
6377
|
-
PI_CODING_AGENT_DIR:
|
|
6436
|
+
PI_CODING_AGENT_DIR: resolve29(runtime.homeDir, ".pi", "agent"),
|
|
6378
6437
|
[RUNTIME_CONTEXT_ENV]: runtime.contextFile,
|
|
6379
6438
|
...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
|
|
6380
6439
|
...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
|
|
@@ -6385,16 +6444,16 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6385
6444
|
NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
|
|
6386
6445
|
} : {}
|
|
6387
6446
|
};
|
|
6388
|
-
const knownHostsPath =
|
|
6389
|
-
if (
|
|
6390
|
-
const agentSshKey =
|
|
6447
|
+
const knownHostsPath = resolve29(runtime.homeDir, ".ssh", "known_hosts");
|
|
6448
|
+
if (existsSync28(knownHostsPath)) {
|
|
6449
|
+
const agentSshKey = resolve29(runtime.homeDir, ".ssh", "rig-agent-key");
|
|
6391
6450
|
const sshParts = [
|
|
6392
6451
|
"ssh",
|
|
6393
6452
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
6394
6453
|
"-o StrictHostKeyChecking=yes",
|
|
6395
6454
|
"-F /dev/null"
|
|
6396
6455
|
];
|
|
6397
|
-
if (
|
|
6456
|
+
if (existsSync28(agentSshKey)) {
|
|
6398
6457
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
6399
6458
|
}
|
|
6400
6459
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -6431,7 +6490,7 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
6431
6490
|
if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
|
|
6432
6491
|
env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
|
|
6433
6492
|
}
|
|
6434
|
-
if (
|
|
6493
|
+
if (existsSync28(runtime.contextFile)) {
|
|
6435
6494
|
const runtimeContext = loadRuntimeContext(runtime.contextFile);
|
|
6436
6495
|
Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
|
|
6437
6496
|
Object.assign(env, browserEnvFromContext(runtimeContext.browser));
|
|
@@ -6460,30 +6519,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
6460
6519
|
await mkdir2(runtime.cacheDir, { recursive: true });
|
|
6461
6520
|
await provisionAgentSshKey(runtime.homeDir);
|
|
6462
6521
|
if (options.provider === "codex") {
|
|
6463
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
6522
|
+
const hasCodexAuth = await injectCodexAuth(resolve29(runtime.homeDir, ".codex"));
|
|
6464
6523
|
if (!hasCodexAuth) {
|
|
6465
6524
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
6466
6525
|
}
|
|
6467
6526
|
}
|
|
6468
6527
|
if (options.provider === "pi") {
|
|
6469
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
6528
|
+
const hasPiAuth = await injectPiAgentConfig(resolve29(runtime.homeDir, ".pi", "agent"));
|
|
6470
6529
|
if (!hasPiAuth) {
|
|
6471
6530
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
6472
6531
|
}
|
|
6473
6532
|
}
|
|
6474
6533
|
}
|
|
6475
6534
|
async function provisionClaudeHome(config) {
|
|
6476
|
-
|
|
6477
|
-
const workspaceSettings =
|
|
6478
|
-
const hostSettings =
|
|
6479
|
-
const projectSettings =
|
|
6535
|
+
mkdirSync13(config.claudeHomeDir, { recursive: true });
|
|
6536
|
+
const workspaceSettings = resolve29(config.workspaceDir, ".claude/settings.json");
|
|
6537
|
+
const hostSettings = resolve29(config.hostProjectRoot, ".claude/settings.json");
|
|
6538
|
+
const projectSettings = existsSync28(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
6480
6539
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
6481
|
-
if (
|
|
6482
|
-
|
|
6540
|
+
if (existsSync28(projectSettings)) {
|
|
6541
|
+
writeFileSync11(resolve29(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6483
6542
|
`, "utf-8");
|
|
6484
6543
|
}
|
|
6485
6544
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
6486
|
-
|
|
6545
|
+
writeFileSync11(resolve29(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
6487
6546
|
permissions: { defaultMode: "bypassPermissions" },
|
|
6488
6547
|
autoMemoryEnabled: false
|
|
6489
6548
|
}, null, 2));
|
|
@@ -6491,12 +6550,12 @@ async function provisionClaudeHome(config) {
|
|
|
6491
6550
|
if (!hasCredentials) {
|
|
6492
6551
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
6493
6552
|
}
|
|
6494
|
-
const realClaudeHome =
|
|
6495
|
-
if (process.env.HOME &&
|
|
6496
|
-
cpSync2(
|
|
6553
|
+
const realClaudeHome = resolve29(process.env.HOME ?? "", ".claude");
|
|
6554
|
+
if (process.env.HOME && existsSync28(resolve29(realClaudeHome, "CLAUDE.md"))) {
|
|
6555
|
+
cpSync2(resolve29(realClaudeHome, "CLAUDE.md"), resolve29(config.claudeHomeDir, "CLAUDE.md"));
|
|
6497
6556
|
}
|
|
6498
|
-
if (process.env.HOME &&
|
|
6499
|
-
cpSync2(
|
|
6557
|
+
if (process.env.HOME && existsSync28(resolve29(realClaudeHome, "agents"))) {
|
|
6558
|
+
cpSync2(resolve29(realClaudeHome, "agents"), resolve29(config.claudeHomeDir, "agents"), { recursive: true });
|
|
6500
6559
|
}
|
|
6501
6560
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
6502
6561
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
@@ -6507,10 +6566,10 @@ async function materializeRuntimeCertBundle(runtime) {
|
|
|
6507
6566
|
if (!sourcePath) {
|
|
6508
6567
|
return "";
|
|
6509
6568
|
}
|
|
6510
|
-
const certsDir =
|
|
6511
|
-
const targetPath =
|
|
6569
|
+
const certsDir = resolve29(runtime.rootDir, "certs");
|
|
6570
|
+
const targetPath = resolve29(certsDir, "ca-certificates.pem");
|
|
6512
6571
|
await mkdir2(certsDir, { recursive: true });
|
|
6513
|
-
let shouldCopy = !
|
|
6572
|
+
let shouldCopy = !existsSync28(targetPath);
|
|
6514
6573
|
if (!shouldCopy) {
|
|
6515
6574
|
try {
|
|
6516
6575
|
shouldCopy = statSync6(sourcePath).mtimeMs > statSync6(targetPath).mtimeMs;
|
|
@@ -6532,7 +6591,7 @@ function applyGitHubCredentialHelperEnv(env) {
|
|
|
6532
6591
|
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';
|
|
6533
6592
|
}
|
|
6534
6593
|
function persistRuntimeSecrets(runtimeRoot, env) {
|
|
6535
|
-
const secretsPath =
|
|
6594
|
+
const secretsPath = resolve29(runtimeRoot, "runtime-secrets.json");
|
|
6536
6595
|
const persisted = {};
|
|
6537
6596
|
for (const key of [
|
|
6538
6597
|
"GITHUB_TOKEN",
|
|
@@ -6551,12 +6610,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
|
|
|
6551
6610
|
if (Object.keys(persisted).length === 0) {
|
|
6552
6611
|
return;
|
|
6553
6612
|
}
|
|
6554
|
-
|
|
6613
|
+
writeFileSync11(secretsPath, `${JSON.stringify(persisted, null, 2)}
|
|
6555
6614
|
`, "utf-8");
|
|
6556
6615
|
}
|
|
6557
6616
|
async function provisionAgentSshKey(homeDir) {
|
|
6558
|
-
const sshDir =
|
|
6559
|
-
if (!
|
|
6617
|
+
const sshDir = resolve29(homeDir, ".ssh");
|
|
6618
|
+
if (!existsSync28(sshDir)) {
|
|
6560
6619
|
await mkdir2(sshDir, { recursive: true });
|
|
6561
6620
|
}
|
|
6562
6621
|
seedKnownHosts(sshDir);
|
|
@@ -6564,27 +6623,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
6564
6623
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
6565
6624
|
if (!privateKey) {
|
|
6566
6625
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
6567
|
-
if (!process.env.HOME || !
|
|
6626
|
+
if (!process.env.HOME || !existsSync28(hostKeyPath)) {
|
|
6568
6627
|
return;
|
|
6569
6628
|
}
|
|
6570
|
-
const agentKeyPath2 =
|
|
6571
|
-
if (!
|
|
6629
|
+
const agentKeyPath2 = resolve29(sshDir, "rig-agent-key");
|
|
6630
|
+
if (!existsSync28(agentKeyPath2)) {
|
|
6572
6631
|
copyFileSync5(hostKeyPath, agentKeyPath2);
|
|
6573
6632
|
chmodSync5(agentKeyPath2, 384);
|
|
6574
6633
|
}
|
|
6575
6634
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
6576
|
-
if (
|
|
6635
|
+
if (existsSync28(hostPubPath)) {
|
|
6577
6636
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
6578
|
-
if (!
|
|
6637
|
+
if (!existsSync28(agentPubPath)) {
|
|
6579
6638
|
copyFileSync5(hostPubPath, agentPubPath);
|
|
6580
6639
|
}
|
|
6581
6640
|
}
|
|
6582
6641
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
6583
6642
|
return;
|
|
6584
6643
|
}
|
|
6585
|
-
const agentKeyPath =
|
|
6586
|
-
if (!
|
|
6587
|
-
|
|
6644
|
+
const agentKeyPath = resolve29(sshDir, "rig-agent-key");
|
|
6645
|
+
if (!existsSync28(agentKeyPath)) {
|
|
6646
|
+
writeFileSync11(agentKeyPath, privateKey, { mode: 384 });
|
|
6588
6647
|
}
|
|
6589
6648
|
writeSshConfig(sshDir, agentKeyPath);
|
|
6590
6649
|
}
|
|
@@ -6601,21 +6660,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
6601
6660
|
`;
|
|
6602
6661
|
}
|
|
6603
6662
|
function resolveHostSshKeyPath(homeDir) {
|
|
6604
|
-
const sshDir =
|
|
6663
|
+
const sshDir = resolve29(homeDir, ".ssh");
|
|
6605
6664
|
const candidates = [
|
|
6606
6665
|
"rig-agent-key",
|
|
6607
6666
|
"id_ed25519",
|
|
6608
6667
|
"id_ecdsa",
|
|
6609
6668
|
"id_rsa"
|
|
6610
|
-
].map((name) =>
|
|
6611
|
-
return candidates.find((candidate) =>
|
|
6669
|
+
].map((name) => resolve29(sshDir, name));
|
|
6670
|
+
return candidates.find((candidate) => existsSync28(candidate)) ?? resolve29(sshDir, "rig-agent-key");
|
|
6612
6671
|
}
|
|
6613
6672
|
function writeSshConfig(sshDir, keyPath) {
|
|
6614
|
-
const configPath =
|
|
6615
|
-
if (
|
|
6673
|
+
const configPath = resolve29(sshDir, "config");
|
|
6674
|
+
if (existsSync28(configPath)) {
|
|
6616
6675
|
return;
|
|
6617
6676
|
}
|
|
6618
|
-
const knownHostsPath =
|
|
6677
|
+
const knownHostsPath = resolve29(sshDir, "known_hosts");
|
|
6619
6678
|
const config = [
|
|
6620
6679
|
"Host github.com",
|
|
6621
6680
|
` IdentityFile ${keyPath}`,
|
|
@@ -6625,10 +6684,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
6625
6684
|
""
|
|
6626
6685
|
].join(`
|
|
6627
6686
|
`);
|
|
6628
|
-
|
|
6687
|
+
writeFileSync11(configPath, config, { mode: 420 });
|
|
6629
6688
|
}
|
|
6630
6689
|
function seedKnownHosts(sshDir) {
|
|
6631
|
-
const knownHostsPath =
|
|
6690
|
+
const knownHostsPath = resolve29(sshDir, "known_hosts");
|
|
6632
6691
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
6633
6692
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
6634
6693
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -6639,23 +6698,23 @@ function seedKnownHosts(sshDir) {
|
|
|
6639
6698
|
for (const line of missing) {
|
|
6640
6699
|
existingLines.add(line);
|
|
6641
6700
|
}
|
|
6642
|
-
|
|
6701
|
+
writeFileSync11(knownHostsPath, `${Array.from(existingLines).join(`
|
|
6643
6702
|
`)}
|
|
6644
6703
|
`, { mode: 420 });
|
|
6645
6704
|
} catch (err) {
|
|
6646
|
-
const hint =
|
|
6705
|
+
const hint = existsSync28(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
6647
6706
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
6648
6707
|
}
|
|
6649
6708
|
}
|
|
6650
6709
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
6651
6710
|
const projectHash = hashProjectPath(workspaceDir);
|
|
6652
|
-
const projectDir =
|
|
6653
|
-
|
|
6654
|
-
|
|
6711
|
+
const projectDir = resolve29(claudeHomeDir, "projects", projectHash);
|
|
6712
|
+
mkdirSync13(projectDir, { recursive: true });
|
|
6713
|
+
writeFileSync11(resolve29(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6655
6714
|
`, "utf-8");
|
|
6656
6715
|
}
|
|
6657
6716
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
6658
|
-
if (!
|
|
6717
|
+
if (!existsSync28(projectSettingsPath)) {
|
|
6659
6718
|
return {};
|
|
6660
6719
|
}
|
|
6661
6720
|
let parsed;
|
|
@@ -6701,7 +6760,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
6701
6760
|
return clone;
|
|
6702
6761
|
}
|
|
6703
6762
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
6704
|
-
const credentialsPath =
|
|
6763
|
+
const credentialsPath = resolve29(claudeHomeDir, ".credentials.json");
|
|
6705
6764
|
const platform = options.platform ?? process.platform;
|
|
6706
6765
|
if (platform === "darwin") {
|
|
6707
6766
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -6711,16 +6770,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6711
6770
|
if (raw) {
|
|
6712
6771
|
try {
|
|
6713
6772
|
JSON.parse(raw);
|
|
6714
|
-
|
|
6773
|
+
writeFileSync11(credentialsPath, raw, { mode: 384 });
|
|
6715
6774
|
registerCredentialCleanup(credentialsPath);
|
|
6716
6775
|
return true;
|
|
6717
6776
|
} catch {}
|
|
6718
6777
|
}
|
|
6719
6778
|
}
|
|
6720
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6779
|
+
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") : "";
|
|
6721
6780
|
if (hostClaudeHome) {
|
|
6722
|
-
const realCredentials =
|
|
6723
|
-
if (
|
|
6781
|
+
const realCredentials = resolve29(hostClaudeHome, ".credentials.json");
|
|
6782
|
+
if (existsSync28(realCredentials)) {
|
|
6724
6783
|
cpSync2(realCredentials, credentialsPath);
|
|
6725
6784
|
return true;
|
|
6726
6785
|
}
|
|
@@ -6728,36 +6787,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6728
6787
|
return false;
|
|
6729
6788
|
}
|
|
6730
6789
|
async function injectCodexAuth(codexHomeDir) {
|
|
6731
|
-
|
|
6732
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6790
|
+
mkdirSync13(codexHomeDir, { recursive: true });
|
|
6791
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve29(process.env.CODEX_HOME) : process.env.HOME ? resolve29(process.env.HOME, ".codex") : "";
|
|
6733
6792
|
if (!hostCodexHome) {
|
|
6734
6793
|
return false;
|
|
6735
6794
|
}
|
|
6736
|
-
const hostAuthPath =
|
|
6737
|
-
if (!
|
|
6795
|
+
const hostAuthPath = resolve29(hostCodexHome, "auth.json");
|
|
6796
|
+
if (!existsSync28(hostAuthPath)) {
|
|
6738
6797
|
return false;
|
|
6739
6798
|
}
|
|
6740
|
-
const runtimeAuthPath =
|
|
6799
|
+
const runtimeAuthPath = resolve29(codexHomeDir, "auth.json");
|
|
6741
6800
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6742
6801
|
chmodSync5(runtimeAuthPath, 384);
|
|
6743
6802
|
return true;
|
|
6744
6803
|
}
|
|
6745
6804
|
async function injectPiAgentConfig(piAgentDir) {
|
|
6746
|
-
|
|
6747
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6805
|
+
mkdirSync13(piAgentDir, { recursive: true });
|
|
6806
|
+
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") : "";
|
|
6748
6807
|
if (!hostPiAgentDir) {
|
|
6749
6808
|
return false;
|
|
6750
6809
|
}
|
|
6751
|
-
const hostAuthPath =
|
|
6752
|
-
if (!
|
|
6810
|
+
const hostAuthPath = resolve29(hostPiAgentDir, "auth.json");
|
|
6811
|
+
if (!existsSync28(hostAuthPath)) {
|
|
6753
6812
|
return false;
|
|
6754
6813
|
}
|
|
6755
|
-
const runtimeAuthPath =
|
|
6814
|
+
const runtimeAuthPath = resolve29(piAgentDir, "auth.json");
|
|
6756
6815
|
copyFileSync5(hostAuthPath, runtimeAuthPath);
|
|
6757
6816
|
chmodSync5(runtimeAuthPath, 384);
|
|
6758
|
-
const hostSettingsPath =
|
|
6759
|
-
if (
|
|
6760
|
-
const runtimeSettingsPath =
|
|
6817
|
+
const hostSettingsPath = resolve29(hostPiAgentDir, "settings.json");
|
|
6818
|
+
if (existsSync28(hostSettingsPath)) {
|
|
6819
|
+
const runtimeSettingsPath = resolve29(piAgentDir, "settings.json");
|
|
6761
6820
|
copyFileSync5(hostSettingsPath, runtimeSettingsPath);
|
|
6762
6821
|
chmodSync5(runtimeSettingsPath, 384);
|
|
6763
6822
|
}
|
|
@@ -6765,13 +6824,13 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
6765
6824
|
}
|
|
6766
6825
|
|
|
6767
6826
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
6768
|
-
import { existsSync as
|
|
6769
|
-
import { resolve as
|
|
6827
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync14, statSync as statSync7, writeFileSync as writeFileSync12 } from "fs";
|
|
6828
|
+
import { resolve as resolve30 } from "path";
|
|
6770
6829
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6771
6830
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6772
6831
|
return {
|
|
6773
6832
|
type: "stdio",
|
|
6774
|
-
command:
|
|
6833
|
+
command: resolve30(options.binDir, "rig-tool-router"),
|
|
6775
6834
|
args: [],
|
|
6776
6835
|
env: {
|
|
6777
6836
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6780,25 +6839,25 @@ function buildRuntimeToolRouterServerConfig(options) {
|
|
|
6780
6839
|
};
|
|
6781
6840
|
}
|
|
6782
6841
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6783
|
-
const configPath =
|
|
6784
|
-
|
|
6842
|
+
const configPath = resolve30(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6843
|
+
mkdirSync14(options.stateDir, { recursive: true });
|
|
6785
6844
|
const payload = {
|
|
6786
6845
|
mcpServers: {
|
|
6787
6846
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6788
6847
|
}
|
|
6789
6848
|
};
|
|
6790
|
-
|
|
6849
|
+
writeFileSync12(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6791
6850
|
`, "utf-8");
|
|
6792
6851
|
return configPath;
|
|
6793
6852
|
}
|
|
6794
6853
|
if (false) {}
|
|
6795
6854
|
// packages/runtime/src/control-plane/runtime/isolation/discovery.ts
|
|
6796
6855
|
init_layout();
|
|
6797
|
-
import { resolve as
|
|
6856
|
+
import { resolve as resolve34 } from "path";
|
|
6798
6857
|
|
|
6799
6858
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6800
|
-
import { existsSync as
|
|
6801
|
-
import { dirname as
|
|
6859
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync15, rmSync as rmSync10 } from "fs";
|
|
6860
|
+
import { dirname as dirname13, resolve as resolve31 } from "path";
|
|
6802
6861
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6803
6862
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6804
6863
|
if (explicit) {
|
|
@@ -6834,12 +6893,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6834
6893
|
}
|
|
6835
6894
|
async function provisionRuntimeWorktree(config) {
|
|
6836
6895
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6837
|
-
let hasValidWorktree =
|
|
6838
|
-
if (
|
|
6896
|
+
let hasValidWorktree = existsSync30(resolve31(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6897
|
+
if (existsSync30(config.workspaceDir) && !hasValidWorktree) {
|
|
6839
6898
|
rmSync10(config.workspaceDir, { recursive: true, force: true });
|
|
6840
6899
|
}
|
|
6841
6900
|
if (!hasValidWorktree) {
|
|
6842
|
-
|
|
6901
|
+
mkdirSync15(dirname13(config.workspaceDir), { recursive: true });
|
|
6843
6902
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6844
6903
|
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]);
|
|
6845
6904
|
if (add.exitCode !== 0) {
|
|
@@ -7021,31 +7080,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
7021
7080
|
|
|
7022
7081
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
7023
7082
|
import {
|
|
7024
|
-
existsSync as
|
|
7083
|
+
existsSync as existsSync32,
|
|
7025
7084
|
lstatSync,
|
|
7026
|
-
mkdirSync as
|
|
7085
|
+
mkdirSync as mkdirSync17,
|
|
7027
7086
|
readdirSync as readdirSync6,
|
|
7028
|
-
readFileSync as
|
|
7087
|
+
readFileSync as readFileSync16,
|
|
7029
7088
|
rmSync as rmSync11,
|
|
7030
7089
|
statSync as statSync9,
|
|
7031
7090
|
symlinkSync as symlinkSync4
|
|
7032
7091
|
} from "fs";
|
|
7033
7092
|
import { mkdir as mkdir3, writeFile } from "fs/promises";
|
|
7034
|
-
import { dirname as
|
|
7093
|
+
import { dirname as dirname15, resolve as resolve33 } from "path";
|
|
7035
7094
|
|
|
7036
7095
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
7037
|
-
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as
|
|
7096
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync31, mkdirSync as mkdirSync16, statSync as statSync8 } from "fs";
|
|
7038
7097
|
import { tmpdir as tmpdir6 } from "os";
|
|
7039
|
-
import { dirname as
|
|
7040
|
-
var sharedRouterOutputDir =
|
|
7041
|
-
var sharedRouterOutputPath =
|
|
7098
|
+
import { dirname as dirname14, resolve as resolve32 } from "path";
|
|
7099
|
+
var sharedRouterOutputDir = resolve32(tmpdir6(), "rig-native");
|
|
7100
|
+
var sharedRouterOutputPath = resolve32(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
7042
7101
|
function runtimeClaudeToolRouterFileName() {
|
|
7043
7102
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
7044
7103
|
}
|
|
7045
7104
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
7046
|
-
const sourcePath =
|
|
7047
|
-
|
|
7048
|
-
const needsBuild = !
|
|
7105
|
+
const sourcePath = resolve32(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
7106
|
+
mkdirSync16(dirname14(outputPath), { recursive: true });
|
|
7107
|
+
const needsBuild = !existsSync31(outputPath) || statSync8(sourcePath).mtimeMs > statSync8(outputPath).mtimeMs;
|
|
7049
7108
|
if (!needsBuild) {
|
|
7050
7109
|
return outputPath;
|
|
7051
7110
|
}
|
|
@@ -7059,9 +7118,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
7059
7118
|
}
|
|
7060
7119
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
7061
7120
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
7062
|
-
const targetPath =
|
|
7063
|
-
|
|
7064
|
-
const needsCopy = !
|
|
7121
|
+
const targetPath = resolve32(targetDir, runtimeClaudeToolRouterFileName());
|
|
7122
|
+
mkdirSync16(targetDir, { recursive: true });
|
|
7123
|
+
const needsCopy = !existsSync31(targetPath) || statSync8(sourcePath).mtimeMs > statSync8(targetPath).mtimeMs;
|
|
7065
7124
|
if (needsCopy) {
|
|
7066
7125
|
copyFileSync6(sourcePath, targetPath);
|
|
7067
7126
|
chmodSync6(targetPath, 493);
|
|
@@ -7074,48 +7133,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
7074
7133
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
7075
7134
|
function resolveRigSourceRoot(projectRoot) {
|
|
7076
7135
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
7077
|
-
if (hostProjectRoot &&
|
|
7136
|
+
if (hostProjectRoot && existsSync32(resolve33(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
7078
7137
|
return hostProjectRoot;
|
|
7079
7138
|
}
|
|
7080
|
-
const fromModule =
|
|
7081
|
-
if (
|
|
7139
|
+
const fromModule = resolve33(import.meta.dir, "../../../../../..");
|
|
7140
|
+
if (existsSync32(resolve33(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
7082
7141
|
return fromModule;
|
|
7083
7142
|
}
|
|
7084
7143
|
return projectRoot;
|
|
7085
7144
|
}
|
|
7086
7145
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
7087
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
7146
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve33(sessionDir, "session.json")]) {
|
|
7088
7147
|
removeSymbolicLink(path);
|
|
7089
7148
|
}
|
|
7090
7149
|
runtimePrepareTrackedPathsNative({
|
|
7091
7150
|
logsDir,
|
|
7092
7151
|
stateDir,
|
|
7093
7152
|
sessionDir,
|
|
7094
|
-
controlledBashLogFile:
|
|
7095
|
-
eventsFile:
|
|
7153
|
+
controlledBashLogFile: resolve33(logsDir, "controlled-bash.jsonl"),
|
|
7154
|
+
eventsFile: resolve33(logsDir, "control-plane.events.jsonl")
|
|
7096
7155
|
});
|
|
7097
7156
|
}
|
|
7098
7157
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
7099
7158
|
await mkdir3(stateDir, { recursive: true });
|
|
7100
7159
|
await mkdir3(sessionDir, { recursive: true });
|
|
7101
|
-
const failedApproachesPath =
|
|
7102
|
-
if (!
|
|
7160
|
+
const failedApproachesPath = resolve33(stateDir, "failed_approaches.md");
|
|
7161
|
+
if (!existsSync32(failedApproachesPath)) {
|
|
7103
7162
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
7104
7163
|
|
|
7105
7164
|
`);
|
|
7106
7165
|
}
|
|
7107
|
-
const hookTripsPath =
|
|
7108
|
-
if (!
|
|
7166
|
+
const hookTripsPath = resolve33(stateDir, "hook_trips.log");
|
|
7167
|
+
if (!existsSync32(hookTripsPath)) {
|
|
7109
7168
|
await writeFile(hookTripsPath, "");
|
|
7110
7169
|
}
|
|
7111
|
-
const sessionFile =
|
|
7170
|
+
const sessionFile = resolve33(sessionDir, "session.json");
|
|
7112
7171
|
if (taskId) {
|
|
7113
7172
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
7114
7173
|
}
|
|
7115
7174
|
}
|
|
7116
7175
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
7117
|
-
const artifactDir =
|
|
7118
|
-
const runtimeSnapshotDir =
|
|
7176
|
+
const artifactDir = resolve33(workspaceDir, "artifacts", taskId);
|
|
7177
|
+
const runtimeSnapshotDir = resolve33(artifactDir, "runtime-snapshots");
|
|
7119
7178
|
let preservedTrackedFiles = false;
|
|
7120
7179
|
for (const file of [
|
|
7121
7180
|
"changed-files.txt",
|
|
@@ -7131,7 +7190,7 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
7131
7190
|
preservedTrackedFiles = true;
|
|
7132
7191
|
continue;
|
|
7133
7192
|
}
|
|
7134
|
-
rmSync11(
|
|
7193
|
+
rmSync11(resolve33(artifactDir, file), { force: true });
|
|
7135
7194
|
}
|
|
7136
7195
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
7137
7196
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
@@ -7170,28 +7229,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
7170
7229
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
7171
7230
|
}
|
|
7172
7231
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
7173
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
7174
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
7232
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve33(options.binDir, "rig"), rigSourceRoot);
|
|
7233
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve33(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
7175
7234
|
...options.runtimeSecretDefines,
|
|
7176
7235
|
AGENT_TASK_ID: options.taskId,
|
|
7177
7236
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7178
7237
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
7179
7238
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
7180
7239
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
7181
|
-
AGENT_BINARY_PATH:
|
|
7240
|
+
AGENT_BINARY_PATH: resolve33(options.binDir, "rig-agent"),
|
|
7182
7241
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
7183
7242
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
7184
7243
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
7185
7244
|
});
|
|
7186
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
7245
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve33(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
7187
7246
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7188
7247
|
AGENT_LOGS_DIR: options.logsDir,
|
|
7189
7248
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
7190
|
-
AGENT_TS_API_TESTS_DIR:
|
|
7191
|
-
AGENT_RIG_AGENT_BIN:
|
|
7249
|
+
AGENT_TS_API_TESTS_DIR: resolve33(options.workspaceDir, "TSAPITests"),
|
|
7250
|
+
AGENT_RIG_AGENT_BIN: resolve33(options.binDir, "rig-agent")
|
|
7192
7251
|
});
|
|
7193
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
7194
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
7252
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve33(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
7253
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve33(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
7195
7254
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
7196
7255
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7197
7256
|
});
|
|
@@ -7200,15 +7259,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
7200
7259
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
7201
7260
|
};
|
|
7202
7261
|
for (const hookName of hookNames) {
|
|
7203
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
7262
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve33(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
7204
7263
|
}
|
|
7205
|
-
const pluginsDir =
|
|
7206
|
-
if (
|
|
7264
|
+
const pluginsDir = resolve33(options.projectRoot, "rig/plugins");
|
|
7265
|
+
if (existsSync32(pluginsDir)) {
|
|
7207
7266
|
for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
|
|
7208
7267
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
7209
7268
|
if (!match)
|
|
7210
7269
|
continue;
|
|
7211
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
7270
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve33(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
7212
7271
|
}
|
|
7213
7272
|
}
|
|
7214
7273
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -7218,8 +7277,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
7218
7277
|
}
|
|
7219
7278
|
async function writeRuntimeManifest(config) {
|
|
7220
7279
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
7221
|
-
const binarySha256 = sha256Hex(
|
|
7222
|
-
const manifestPath =
|
|
7280
|
+
const binarySha256 = sha256Hex(readFileSync16(config.binaryPath));
|
|
7281
|
+
const manifestPath = resolve33(config.runtimeRoot, "manifest.json");
|
|
7223
7282
|
const manifest = {
|
|
7224
7283
|
runtimeId: config.runtimeId,
|
|
7225
7284
|
taskId: config.taskId,
|
|
@@ -7339,31 +7398,31 @@ function readFileMtimeMs(path) {
|
|
|
7339
7398
|
}
|
|
7340
7399
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
7341
7400
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
7342
|
-
const sourceNodeModules =
|
|
7343
|
-
if (!
|
|
7344
|
-
const runtimeHumoongate =
|
|
7345
|
-
if (
|
|
7346
|
-
const targetNodeModules =
|
|
7401
|
+
const sourceNodeModules = resolve33(monorepoRoot, "humoongate", "node_modules");
|
|
7402
|
+
if (!existsSync32(sourceNodeModules)) {} else {
|
|
7403
|
+
const runtimeHumoongate = resolve33(workspaceDir, "humoongate");
|
|
7404
|
+
if (existsSync32(resolve33(runtimeHumoongate, "package.json"))) {
|
|
7405
|
+
const targetNodeModules = resolve33(runtimeHumoongate, "node_modules");
|
|
7347
7406
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
7348
7407
|
}
|
|
7349
7408
|
}
|
|
7350
|
-
const runtimeHpNext =
|
|
7351
|
-
if (!
|
|
7409
|
+
const runtimeHpNext = resolve33(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
7410
|
+
if (!existsSync32(resolve33(runtimeHpNext, "package.json"))) {
|
|
7352
7411
|
return;
|
|
7353
7412
|
}
|
|
7354
|
-
const sourceHpNextNodeModules =
|
|
7355
|
-
const sourceMonorepoNodeModules =
|
|
7356
|
-
const targetHpNextNodeModules =
|
|
7357
|
-
if (
|
|
7413
|
+
const sourceHpNextNodeModules = resolve33(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
7414
|
+
const sourceMonorepoNodeModules = resolve33(monorepoRoot, "node_modules");
|
|
7415
|
+
const targetHpNextNodeModules = resolve33(runtimeHpNext, "node_modules");
|
|
7416
|
+
if (existsSync32(sourceHpNextNodeModules)) {
|
|
7358
7417
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
7359
7418
|
return;
|
|
7360
7419
|
}
|
|
7361
|
-
if (
|
|
7420
|
+
if (existsSync32(sourceMonorepoNodeModules)) {
|
|
7362
7421
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
7363
7422
|
}
|
|
7364
7423
|
}
|
|
7365
7424
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
7366
|
-
linkNodeModulesLayer(
|
|
7425
|
+
linkNodeModulesLayer(resolve33(monorepoRoot, "node_modules"), resolve33(workspaceDir, "node_modules"));
|
|
7367
7426
|
for (const relativePackageDir of [
|
|
7368
7427
|
"apps/native-app/apps/marketing",
|
|
7369
7428
|
"apps/native-app/apps/web",
|
|
@@ -7385,15 +7444,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
7385
7444
|
"packages/standard-plugin",
|
|
7386
7445
|
"packages/validator-kit"
|
|
7387
7446
|
]) {
|
|
7388
|
-
const workspacePackageDir =
|
|
7389
|
-
if (!
|
|
7447
|
+
const workspacePackageDir = resolve33(workspaceDir, relativePackageDir);
|
|
7448
|
+
if (!existsSync32(resolve33(workspacePackageDir, "package.json"))) {
|
|
7390
7449
|
continue;
|
|
7391
7450
|
}
|
|
7392
|
-
linkNodeModulesLayer(
|
|
7451
|
+
linkNodeModulesLayer(resolve33(monorepoRoot, relativePackageDir, "node_modules"), resolve33(workspacePackageDir, "node_modules"));
|
|
7393
7452
|
}
|
|
7394
7453
|
}
|
|
7395
7454
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
7396
|
-
if (!
|
|
7455
|
+
if (!existsSync32(sourceDir) || existsSync32(targetDir)) {
|
|
7397
7456
|
return;
|
|
7398
7457
|
}
|
|
7399
7458
|
try {
|
|
@@ -7402,16 +7461,16 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
7402
7461
|
} catch (error) {
|
|
7403
7462
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
7404
7463
|
}
|
|
7405
|
-
|
|
7464
|
+
mkdirSync17(dirname15(targetDir), { recursive: true });
|
|
7406
7465
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
7407
7466
|
}
|
|
7408
7467
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
7409
|
-
const hooksDir =
|
|
7410
|
-
const pluginsDir =
|
|
7411
|
-
const validatorsDir =
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7468
|
+
const hooksDir = resolve33(runtimeBinDir, "hooks");
|
|
7469
|
+
const pluginsDir = resolve33(runtimeBinDir, "plugins");
|
|
7470
|
+
const validatorsDir = resolve33(runtimeBinDir, "validators");
|
|
7471
|
+
mkdirSync17(hooksDir, { recursive: true });
|
|
7472
|
+
mkdirSync17(pluginsDir, { recursive: true });
|
|
7473
|
+
mkdirSync17(validatorsDir, { recursive: true });
|
|
7415
7474
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
7416
7475
|
}
|
|
7417
7476
|
|
|
@@ -7422,17 +7481,17 @@ function runtimeRootForCleanup(projectRoot, runtimeId) {
|
|
|
7422
7481
|
monorepoRoot = resolveMonorepoRoot3(projectRoot);
|
|
7423
7482
|
} catch {}
|
|
7424
7483
|
const workspaceRootCandidate = monorepoRoot ?? projectRoot;
|
|
7425
|
-
const initialWorkspaceDir =
|
|
7484
|
+
const initialWorkspaceDir = resolve34(workspaceRootCandidate, ".worktrees", runtimeWorktreeNameFromRuntimeId(runtimeId));
|
|
7426
7485
|
const runtimeRoot = resolveRuntimeWorkspaceLayout(initialWorkspaceDir).runtimeDir;
|
|
7427
7486
|
return { monorepoRoot, initialWorkspaceDir, runtimeRoot };
|
|
7428
7487
|
}
|
|
7429
7488
|
|
|
7430
7489
|
// packages/runtime/src/control-plane/runtime/isolation/runner.ts
|
|
7431
|
-
import { existsSync as
|
|
7432
|
-
import { basename as basename9, resolve as
|
|
7490
|
+
import { existsSync as existsSync34, rmSync as rmSync12, writeFileSync as writeFileSync14 } from "fs";
|
|
7491
|
+
import { basename as basename9, resolve as resolve37 } from "path";
|
|
7433
7492
|
|
|
7434
7493
|
// packages/runtime/src/control-plane/runtime/sandbox/backend.ts
|
|
7435
|
-
import { existsSync as
|
|
7494
|
+
import { existsSync as existsSync33 } from "fs";
|
|
7436
7495
|
init_utils();
|
|
7437
7496
|
|
|
7438
7497
|
// packages/runtime/src/control-plane/runtime/sandbox/backend-none.ts
|
|
@@ -7532,13 +7591,13 @@ async function resolveBackend(projectRoot, options) {
|
|
|
7532
7591
|
depRoots
|
|
7533
7592
|
};
|
|
7534
7593
|
const fsContext = {
|
|
7535
|
-
pathExists: (p) =>
|
|
7594
|
+
pathExists: (p) => existsSync33(p),
|
|
7536
7595
|
realPath: toRealPath
|
|
7537
7596
|
};
|
|
7538
7597
|
if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
|
|
7539
7598
|
const seatbelt = Bun.which("sandbox-exec");
|
|
7540
7599
|
probed.push("sandbox-exec");
|
|
7541
|
-
if (seatbelt &&
|
|
7600
|
+
if (seatbelt && existsSync33(seatbelt)) {
|
|
7542
7601
|
const SeatbeltBackendClass = loadSeatbeltBackend();
|
|
7543
7602
|
if (SeatbeltBackendClass) {
|
|
7544
7603
|
return {
|
|
@@ -7659,8 +7718,8 @@ init_layout();
|
|
|
7659
7718
|
var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
|
|
7660
7719
|
async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
7661
7720
|
const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
|
|
7662
|
-
const readyFile =
|
|
7663
|
-
const requestFile =
|
|
7721
|
+
const readyFile = resolve37(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
|
|
7722
|
+
const requestFile = resolve37(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
|
|
7664
7723
|
rmSync12(readyFile, { force: true });
|
|
7665
7724
|
rmSync12(requestFile, { force: true });
|
|
7666
7725
|
const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
|
|
@@ -7704,7 +7763,7 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
|
|
|
7704
7763
|
rmSync12(requestFile, { force: true });
|
|
7705
7764
|
},
|
|
7706
7765
|
finalize: async (commandParts, exitCode) => {
|
|
7707
|
-
|
|
7766
|
+
writeFileSync14(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
|
|
7708
7767
|
`, "utf-8");
|
|
7709
7768
|
const [sidecarExitCode, stdout, stderr] = await Promise.all([
|
|
7710
7769
|
proc.exited,
|
|
@@ -7768,8 +7827,8 @@ async function runInAgentRuntime(options) {
|
|
|
7768
7827
|
const stdout = await new Response(proc.stdout).text();
|
|
7769
7828
|
const stderr = await new Response(proc.stderr).text();
|
|
7770
7829
|
try {
|
|
7771
|
-
await Bun.write(
|
|
7772
|
-
await Bun.write(
|
|
7830
|
+
await Bun.write(resolve37(options.runtime.logsDir, "agent-stdout.log"), stdout);
|
|
7831
|
+
await Bun.write(resolve37(options.runtime.logsDir, "agent-stderr.log"), stderr);
|
|
7773
7832
|
} catch {}
|
|
7774
7833
|
await snapshotSidecar.finalize(runtimeCommand, exitCode);
|
|
7775
7834
|
return {
|
|
@@ -7799,18 +7858,18 @@ function resolveInternalRuntimeCommand(command) {
|
|
|
7799
7858
|
}
|
|
7800
7859
|
async function cleanupAgentRuntime(options) {
|
|
7801
7860
|
const { monorepoRoot, initialWorkspaceDir, runtimeRoot } = runtimeRootForCleanup(options.projectRoot, options.id);
|
|
7802
|
-
const metadataPath =
|
|
7803
|
-
if (!
|
|
7861
|
+
const metadataPath = resolve37(runtimeRoot, "runtime.json");
|
|
7862
|
+
if (!existsSync34(runtimeRoot)) {
|
|
7804
7863
|
return;
|
|
7805
7864
|
}
|
|
7806
7865
|
let mode = "worktree";
|
|
7807
7866
|
let workspaceDir = "";
|
|
7808
7867
|
const metadata = await readRuntimeMetadata(metadataPath);
|
|
7809
|
-
const metadataMatchesRequestedRuntime = metadata !== null && metadata.id === options.id &&
|
|
7868
|
+
const metadataMatchesRequestedRuntime = metadata !== null && metadata.id === options.id && resolve37(metadata.workspaceDir) === resolve37(initialWorkspaceDir);
|
|
7810
7869
|
if (metadata && metadataMatchesRequestedRuntime) {
|
|
7811
7870
|
mode = metadata.mode;
|
|
7812
7871
|
workspaceDir = metadata.workspaceDir;
|
|
7813
|
-
} else if (
|
|
7872
|
+
} else if (existsSync34(initialWorkspaceDir)) {
|
|
7814
7873
|
workspaceDir = initialWorkspaceDir;
|
|
7815
7874
|
}
|
|
7816
7875
|
const preservesTaskWorktree = metadataMatchesRequestedRuntime && metadata ? options.id === taskRuntimeId(metadata.taskId) : false;
|
|
@@ -7842,10 +7901,10 @@ function resolveSnapshotSidecarScriptPath() {
|
|
|
7842
7901
|
return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
|
|
7843
7902
|
}
|
|
7844
7903
|
function resolveSnapshotSidecarBinaryPath(binDir) {
|
|
7845
|
-
return
|
|
7904
|
+
return resolve37(binDir, "snapshot-sidecar");
|
|
7846
7905
|
}
|
|
7847
7906
|
function shouldUseCompiledSnapshotSidecar(binaryPath) {
|
|
7848
|
-
if (!
|
|
7907
|
+
if (!existsSync34(binaryPath)) {
|
|
7849
7908
|
return false;
|
|
7850
7909
|
}
|
|
7851
7910
|
const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
|
|
@@ -7860,12 +7919,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
|
|
|
7860
7919
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
7861
7920
|
].filter((value) => Boolean(value));
|
|
7862
7921
|
for (const root of hostRoots) {
|
|
7863
|
-
const candidate =
|
|
7864
|
-
if (
|
|
7922
|
+
const candidate = resolve37(root, "packages/runtime/src/control-plane/runtime", fileName);
|
|
7923
|
+
if (existsSync34(candidate)) {
|
|
7865
7924
|
return candidate;
|
|
7866
7925
|
}
|
|
7867
7926
|
}
|
|
7868
|
-
return
|
|
7927
|
+
return resolve37(import.meta.dir, "..", fileName);
|
|
7869
7928
|
}
|
|
7870
7929
|
function resolveBunCliInvocation() {
|
|
7871
7930
|
if (process.env.RIG_BUN_PATH?.trim()) {
|
|
@@ -7892,7 +7951,7 @@ function resolveBunCliInvocation() {
|
|
|
7892
7951
|
async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
|
|
7893
7952
|
const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
|
|
7894
7953
|
while (Date.now() < deadline) {
|
|
7895
|
-
if (
|
|
7954
|
+
if (existsSync34(readyFile)) {
|
|
7896
7955
|
return;
|
|
7897
7956
|
}
|
|
7898
7957
|
const exitCode = proc.exitCode;
|
|
@@ -7905,7 +7964,7 @@ async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, s
|
|
|
7905
7964
|
throw new Error(`snapshot sidecar did not become ready within ${SNAPSHOT_SIDECAR_READY_TIMEOUT_MS}ms`);
|
|
7906
7965
|
}
|
|
7907
7966
|
async function readRuntimeMetadata(metadataPath) {
|
|
7908
|
-
if (!
|
|
7967
|
+
if (!existsSync34(metadataPath)) {
|
|
7909
7968
|
return null;
|
|
7910
7969
|
}
|
|
7911
7970
|
try {
|
|
@@ -7920,9 +7979,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
7920
7979
|
async function hydrateRuntimeMemory(options) {
|
|
7921
7980
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
7922
7981
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
7923
|
-
const hydratedPath =
|
|
7982
|
+
const hydratedPath = resolve38(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
7924
7983
|
try {
|
|
7925
|
-
await mkdir4(
|
|
7984
|
+
await mkdir4(resolve38(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
7926
7985
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
7927
7986
|
return {
|
|
7928
7987
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -7937,12 +7996,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
7937
7996
|
}
|
|
7938
7997
|
}
|
|
7939
7998
|
async function createRuntimeTaskRecordReader(options) {
|
|
7940
|
-
const legacyConfigPath =
|
|
7999
|
+
const legacyConfigPath = resolve38(options.projectRoot, ".rig", "task-config.json");
|
|
7941
8000
|
let pluginHostContext = null;
|
|
7942
8001
|
try {
|
|
7943
8002
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
7944
8003
|
} catch (error) {
|
|
7945
|
-
if (!
|
|
8004
|
+
if (!existsSync35(legacyConfigPath)) {
|
|
7946
8005
|
throw error;
|
|
7947
8006
|
}
|
|
7948
8007
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -7962,7 +8021,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7962
8021
|
source: "plugin"
|
|
7963
8022
|
};
|
|
7964
8023
|
}
|
|
7965
|
-
if (
|
|
8024
|
+
if (existsSync35(legacyConfigPath)) {
|
|
7966
8025
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
7967
8026
|
options.diagnostics?.(message);
|
|
7968
8027
|
console.warn(message);
|
|
@@ -7979,10 +8038,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7979
8038
|
};
|
|
7980
8039
|
}
|
|
7981
8040
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
7982
|
-
const jsonPath =
|
|
7983
|
-
if (
|
|
8041
|
+
const jsonPath = resolve38(projectRoot, "rig.config.json");
|
|
8042
|
+
if (existsSync35(jsonPath)) {
|
|
7984
8043
|
try {
|
|
7985
|
-
const parsed = JSON.parse(
|
|
8044
|
+
const parsed = JSON.parse(readFileSync17(jsonPath, "utf8"));
|
|
7986
8045
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7987
8046
|
const taskSource = parsed.taskSource;
|
|
7988
8047
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -7994,12 +8053,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
7994
8053
|
return null;
|
|
7995
8054
|
}
|
|
7996
8055
|
}
|
|
7997
|
-
const tsPath =
|
|
7998
|
-
if (!
|
|
8056
|
+
const tsPath = resolve38(projectRoot, "rig.config.ts");
|
|
8057
|
+
if (!existsSync35(tsPath)) {
|
|
7999
8058
|
return null;
|
|
8000
8059
|
}
|
|
8001
8060
|
try {
|
|
8002
|
-
const source =
|
|
8061
|
+
const source = readFileSync17(tsPath, "utf8");
|
|
8003
8062
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
8004
8063
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
8005
8064
|
return kind ?? null;
|
|
@@ -8069,8 +8128,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
8069
8128
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
8070
8129
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
8071
8130
|
};
|
|
8072
|
-
const configPath =
|
|
8073
|
-
await mkdir4(
|
|
8131
|
+
const configPath = resolve38(options.workspaceDir, ".rig", "task-config.json");
|
|
8132
|
+
await mkdir4(resolve38(options.workspaceDir, ".rig"), { recursive: true });
|
|
8074
8133
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
8075
8134
|
`, "utf-8");
|
|
8076
8135
|
}
|
|
@@ -8134,9 +8193,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8134
8193
|
}
|
|
8135
8194
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
8136
8195
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
8137
|
-
const workspaceDir =
|
|
8196
|
+
const workspaceDir = resolve38(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
8138
8197
|
const createdAt = new Date().toISOString();
|
|
8139
|
-
if (!
|
|
8198
|
+
if (!existsSync35(resolve38(monorepoRoot, ".git"))) {
|
|
8140
8199
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
8141
8200
|
}
|
|
8142
8201
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -8171,7 +8230,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8171
8230
|
logsDir: overlay.logsDir,
|
|
8172
8231
|
stateDir: overlay.stateDir,
|
|
8173
8232
|
sessionDir: overlay.sessionDir,
|
|
8174
|
-
claudeHomeDir:
|
|
8233
|
+
claudeHomeDir: resolve38(workspaceLayout.homeDir, ".claude"),
|
|
8175
8234
|
contextFile: overlay.contextPath,
|
|
8176
8235
|
binDir: workspaceLayout.binDir,
|
|
8177
8236
|
createdAt
|
|
@@ -8184,8 +8243,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8184
8243
|
projectRoot: options.projectRoot,
|
|
8185
8244
|
workspaceDir
|
|
8186
8245
|
});
|
|
8187
|
-
|
|
8188
|
-
|
|
8246
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8247
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8189
8248
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
8190
8249
|
if (options.preserveTaskArtifacts) {
|
|
8191
8250
|
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
@@ -8204,7 +8263,7 @@ async function ensureAgentRuntime(options) {
|
|
|
8204
8263
|
runtimeId: options.id
|
|
8205
8264
|
}),
|
|
8206
8265
|
workspaceDir,
|
|
8207
|
-
artifactRoot:
|
|
8266
|
+
artifactRoot: resolve38(workspaceDir, "artifacts", options.taskId),
|
|
8208
8267
|
hostProjectRoot: options.projectRoot,
|
|
8209
8268
|
monorepoMainRoot: monorepoRoot,
|
|
8210
8269
|
monorepoBaseRef: baseRef,
|
|
@@ -8220,8 +8279,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8220
8279
|
stateDir: overlay.stateDir,
|
|
8221
8280
|
logsDir: overlay.logsDir,
|
|
8222
8281
|
sessionDir: overlay.sessionDir,
|
|
8223
|
-
sessionFile:
|
|
8224
|
-
policyFile:
|
|
8282
|
+
sessionFile: resolve38(overlay.sessionDir, "session.json"),
|
|
8283
|
+
policyFile: resolve38(options.projectRoot, "rig/policy/policy.json"),
|
|
8225
8284
|
binDir: runtime.binDir,
|
|
8226
8285
|
createdAt,
|
|
8227
8286
|
memory
|
|
@@ -8232,9 +8291,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8232
8291
|
task: taskResolution.task,
|
|
8233
8292
|
taskEntry
|
|
8234
8293
|
});
|
|
8235
|
-
const manifestPath =
|
|
8294
|
+
const manifestPath = resolve38(runtimeRoot, "manifest.json");
|
|
8236
8295
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
8237
|
-
const runtimeAgentBinary =
|
|
8296
|
+
const runtimeAgentBinary = resolve38(runtime.binDir, "rig-agent");
|
|
8238
8297
|
await ensureRigGitBinaryPath();
|
|
8239
8298
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
8240
8299
|
projectRoot: options.projectRoot,
|
|
@@ -8251,8 +8310,8 @@ async function ensureAgentRuntime(options) {
|
|
|
8251
8310
|
});
|
|
8252
8311
|
rmSync13(runtime.binDir, { recursive: true, force: true });
|
|
8253
8312
|
rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
|
|
8254
|
-
|
|
8255
|
-
|
|
8313
|
+
mkdirSync20(runtime.binDir, { recursive: true });
|
|
8314
|
+
mkdirSync20(workspaceLayout.distDir, { recursive: true });
|
|
8256
8315
|
await buildRuntimeToolchain({
|
|
8257
8316
|
projectRoot: options.projectRoot,
|
|
8258
8317
|
workspaceDir,
|
|
@@ -8289,9 +8348,9 @@ async function ensureAgentRuntime(options) {
|
|
|
8289
8348
|
workspaceDir,
|
|
8290
8349
|
taskEntry
|
|
8291
8350
|
});
|
|
8292
|
-
const sandboxDir =
|
|
8351
|
+
const sandboxDir = resolve38(runtimeRoot, "sandbox");
|
|
8293
8352
|
await mkdir4(sandboxDir, { recursive: true });
|
|
8294
|
-
await writeFile2(
|
|
8353
|
+
await writeFile2(resolve38(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
8295
8354
|
id: options.id,
|
|
8296
8355
|
taskId: options.taskId,
|
|
8297
8356
|
mode: "worktree",
|