@h-rig/runtime 0.0.6-alpha.3 → 0.0.6-alpha.31
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 +1165 -785
- package/dist/bin/rig-agent.js +458 -389
- package/dist/src/control-plane/agent-wrapper.js +1191 -504
- package/dist/src/control-plane/authority-files.js +12 -6
- package/dist/src/control-plane/harness-main.js +2186 -1786
- package/dist/src/control-plane/hooks/completion-verification.js +2084 -1019
- package/dist/src/control-plane/hooks/inject-context.js +193 -139
- package/dist/src/control-plane/hooks/submodule-branch.js +603 -545
- package/dist/src/control-plane/hooks/task-runtime-start.js +603 -545
- package/dist/src/control-plane/materialize-task-config.js +64 -8
- package/dist/src/control-plane/native/git-ops.js +90 -64
- package/dist/src/control-plane/native/harness-cli.js +1989 -682
- package/dist/src/control-plane/native/pr-automation.js +1657 -54
- package/dist/src/control-plane/native/pr-review-gate.js +1455 -0
- package/dist/src/control-plane/native/repo-ops.js +3 -0
- package/dist/src/control-plane/native/run-ops.js +39 -13
- package/dist/src/control-plane/native/task-ops.js +1819 -527
- package/dist/src/control-plane/native/validator.js +163 -109
- package/dist/src/control-plane/native/verifier.js +1616 -323
- package/dist/src/control-plane/native/workspace-ops.js +12 -6
- package/dist/src/control-plane/pi-sessiond/bin.js +793 -0
- package/dist/src/control-plane/pi-sessiond/client.js +41 -0
- package/dist/src/control-plane/pi-sessiond/event-hub.js +59 -0
- package/dist/src/control-plane/pi-sessiond/extension-ui-context.js +198 -0
- package/dist/src/control-plane/pi-sessiond/launcher.js +173 -0
- package/dist/src/control-plane/pi-sessiond/server.js +802 -0
- package/dist/src/control-plane/pi-sessiond/session-service.js +540 -0
- package/dist/src/control-plane/pi-sessiond/types.js +1 -0
- package/dist/src/control-plane/plugin-host-context.js +54 -0
- package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +3 -0
- package/dist/src/control-plane/runtime/image/index.js +3 -0
- package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +3 -0
- package/dist/src/control-plane/runtime/image.js +3 -0
- package/dist/src/control-plane/runtime/index.js +517 -722
- package/dist/src/control-plane/runtime/isolation/home.js +28 -6
- package/dist/src/control-plane/runtime/isolation/index.js +541 -461
- package/dist/src/control-plane/runtime/isolation/runner.js +28 -6
- package/dist/src/control-plane/runtime/isolation/shared.js +9 -6
- package/dist/src/control-plane/runtime/isolation.js +541 -461
- package/dist/src/control-plane/runtime/plugin-mode.js +3 -27
- package/dist/src/control-plane/runtime/queue.js +458 -385
- package/dist/src/control-plane/runtime/snapshot/task-run.js +3 -0
- package/dist/src/control-plane/runtime/task-run-snapshot.js +3 -0
- package/dist/src/control-plane/skill-materializer.js +46 -0
- package/dist/src/control-plane/tasks/source-aware-task-config-source.js +14 -2
- package/dist/src/control-plane/tasks/source-lifecycle.js +86 -32
- package/dist/src/index.js +27 -298
- package/dist/src/layout.js +12 -7
- package/dist/src/local-server.js +20 -14
- package/native/darwin-arm64/rig-git +0 -0
- package/native/darwin-arm64/rig-git.build-manifest.json +1 -1
- package/native/darwin-arm64/rig-shell +0 -0
- package/native/darwin-arm64/rig-shell.build-manifest.json +1 -1
- package/native/darwin-arm64/rig-tools +0 -0
- package/native/darwin-arm64/rig-tools.build-manifest.json +1 -1
- package/native/darwin-arm64/runtime-native.dylib +0 -0
- package/package.json +8 -6
- package/dist/src/control-plane/runtime/plugins.js +0 -1131
- package/dist/src/plugins.js +0 -329
|
@@ -121,13 +121,13 @@ var init_utils = __esm(() => {
|
|
|
121
121
|
|
|
122
122
|
// packages/runtime/src/control-plane/hooks/task-runtime-start.ts
|
|
123
123
|
init_layout();
|
|
124
|
-
import { existsSync as
|
|
125
|
-
import { resolve as
|
|
124
|
+
import { existsSync as existsSync36 } from "fs";
|
|
125
|
+
import { resolve as resolve37 } from "path";
|
|
126
126
|
import { resolveProjectRoot } from "@rig/hook-kit";
|
|
127
127
|
|
|
128
128
|
// packages/runtime/src/control-plane/native/git-ops.ts
|
|
129
|
-
import { existsSync as
|
|
130
|
-
import { dirname as dirname10, isAbsolute as isAbsolute2, resolve as
|
|
129
|
+
import { existsSync as existsSync23, lstatSync, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
|
|
130
|
+
import { dirname as dirname10, isAbsolute as isAbsolute2, resolve as resolve24 } from "path";
|
|
131
131
|
|
|
132
132
|
// packages/runtime/src/control-plane/runtime/baked-secrets.ts
|
|
133
133
|
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
@@ -432,8 +432,8 @@ function isAgentRuntimeContextPath(path) {
|
|
|
432
432
|
}
|
|
433
433
|
|
|
434
434
|
// packages/runtime/src/control-plane/native/task-ops.ts
|
|
435
|
-
import { appendFileSync, existsSync as
|
|
436
|
-
import { resolve as
|
|
435
|
+
import { appendFileSync, existsSync as existsSync22, mkdirSync as mkdirSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
436
|
+
import { resolve as resolve23 } from "path";
|
|
437
437
|
|
|
438
438
|
// packages/runtime/src/build-time-config.ts
|
|
439
439
|
function normalizeBuildConfig(value) {
|
|
@@ -1268,6 +1268,49 @@ function safeReadJson(path) {
|
|
|
1268
1268
|
}
|
|
1269
1269
|
}
|
|
1270
1270
|
|
|
1271
|
+
// packages/runtime/src/control-plane/skill-materializer.ts
|
|
1272
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync5, readFileSync as readFileSync4, readdirSync, rmSync as rmSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
1273
|
+
import { resolve as resolve10 } from "path";
|
|
1274
|
+
import { loadSkill } from "@rig/skill-loader";
|
|
1275
|
+
var MARKER_FILENAME = ".rig-plugin";
|
|
1276
|
+
function skillDirName(id) {
|
|
1277
|
+
return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
1278
|
+
}
|
|
1279
|
+
async function materializeSkills(projectRoot, entries) {
|
|
1280
|
+
const skillsRoot = resolve10(projectRoot, ".pi", "skills");
|
|
1281
|
+
if (existsSync10(skillsRoot)) {
|
|
1282
|
+
for (const name of readdirSync(skillsRoot)) {
|
|
1283
|
+
const dir = resolve10(skillsRoot, name);
|
|
1284
|
+
if (existsSync10(resolve10(dir, MARKER_FILENAME))) {
|
|
1285
|
+
rmSync4(dir, { recursive: true, force: true });
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
const written = [];
|
|
1290
|
+
for (const { pluginName, skill } of entries) {
|
|
1291
|
+
const sourcePath = resolve10(projectRoot, skill.path);
|
|
1292
|
+
if (!existsSync10(sourcePath)) {
|
|
1293
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
let body;
|
|
1297
|
+
try {
|
|
1298
|
+
await loadSkill(sourcePath);
|
|
1299
|
+
body = readFileSync4(sourcePath, "utf-8");
|
|
1300
|
+
} catch (err) {
|
|
1301
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
|
|
1302
|
+
continue;
|
|
1303
|
+
}
|
|
1304
|
+
const dir = resolve10(skillsRoot, skillDirName(skill.id));
|
|
1305
|
+
mkdirSync5(dir, { recursive: true });
|
|
1306
|
+
writeFileSync3(resolve10(dir, "SKILL.md"), body, "utf-8");
|
|
1307
|
+
writeFileSync3(resolve10(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
|
|
1308
|
+
`, "utf-8");
|
|
1309
|
+
written.push({ id: skill.id, pluginName, directory: dir });
|
|
1310
|
+
}
|
|
1311
|
+
return written;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1271
1314
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
1272
1315
|
async function buildPluginHostContext(projectRoot) {
|
|
1273
1316
|
let config;
|
|
@@ -1304,6 +1347,17 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
1304
1347
|
} catch (err) {
|
|
1305
1348
|
console.warn(`[plugin-host] hook materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
1306
1349
|
}
|
|
1350
|
+
try {
|
|
1351
|
+
const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
|
|
1352
|
+
pluginName: plugin.name,
|
|
1353
|
+
skill
|
|
1354
|
+
})));
|
|
1355
|
+
if (skillEntries.length > 0) {
|
|
1356
|
+
await materializeSkills(projectRoot, skillEntries);
|
|
1357
|
+
}
|
|
1358
|
+
} catch (err) {
|
|
1359
|
+
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
1360
|
+
}
|
|
1307
1361
|
return {
|
|
1308
1362
|
config,
|
|
1309
1363
|
pluginHost,
|
|
@@ -1317,12 +1371,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
1317
1371
|
|
|
1318
1372
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
1319
1373
|
import { spawnSync } from "child_process";
|
|
1320
|
-
import { existsSync as
|
|
1321
|
-
import { basename as basename4, join as join2, resolve as
|
|
1374
|
+
import { existsSync as existsSync12, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
1375
|
+
import { basename as basename4, join as join2, resolve as resolve12 } from "path";
|
|
1322
1376
|
|
|
1323
1377
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
1324
|
-
import { existsSync as
|
|
1325
|
-
import { resolve as
|
|
1378
|
+
import { existsSync as existsSync11, readFileSync as readFileSync5 } from "fs";
|
|
1379
|
+
import { resolve as resolve11 } from "path";
|
|
1326
1380
|
|
|
1327
1381
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
1328
1382
|
async function findTaskById(reader, id) {
|
|
@@ -1345,7 +1399,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
1345
1399
|
}
|
|
1346
1400
|
}
|
|
1347
1401
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
1348
|
-
const configPath = options.configPath ??
|
|
1402
|
+
const configPath = options.configPath ?? resolve11(projectRoot, ".rig", "task-config.json");
|
|
1349
1403
|
const reader = {
|
|
1350
1404
|
async listTasks() {
|
|
1351
1405
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -1356,8 +1410,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
1356
1410
|
};
|
|
1357
1411
|
return reader;
|
|
1358
1412
|
}
|
|
1359
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
1360
|
-
if (!
|
|
1413
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve11(projectRoot, ".rig", "task-config.json")) {
|
|
1414
|
+
if (!existsSync11(configPath)) {
|
|
1361
1415
|
return [];
|
|
1362
1416
|
}
|
|
1363
1417
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -1365,7 +1419,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve10(projectRoot,
|
|
|
1365
1419
|
}
|
|
1366
1420
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
1367
1421
|
try {
|
|
1368
|
-
const parsed = JSON.parse(
|
|
1422
|
+
const parsed = JSON.parse(readFileSync5(configPath, "utf8"));
|
|
1369
1423
|
if (isPlainRecord(parsed)) {
|
|
1370
1424
|
return parsed;
|
|
1371
1425
|
}
|
|
@@ -1449,7 +1503,7 @@ function isPlainRecord(candidate) {
|
|
|
1449
1503
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
1450
1504
|
var FILE_TASK_PATTERN = /\.(task\.)?json$/;
|
|
1451
1505
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
1452
|
-
const configPath = options.configPath ??
|
|
1506
|
+
const configPath = options.configPath ?? resolve12(projectRoot, ".rig", "task-config.json");
|
|
1453
1507
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
1454
1508
|
const spawnFn = options.spawn ?? spawnSync;
|
|
1455
1509
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -1532,10 +1586,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
1532
1586
|
return metadata;
|
|
1533
1587
|
}
|
|
1534
1588
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
1535
|
-
const jsonPath =
|
|
1536
|
-
if (
|
|
1589
|
+
const jsonPath = resolve12(projectRoot, "rig.config.json");
|
|
1590
|
+
if (existsSync12(jsonPath)) {
|
|
1537
1591
|
try {
|
|
1538
|
-
const parsed = JSON.parse(
|
|
1592
|
+
const parsed = JSON.parse(readFileSync6(jsonPath, "utf8"));
|
|
1539
1593
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
1540
1594
|
const source = parsed.taskSource;
|
|
1541
1595
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -1544,12 +1598,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
1544
1598
|
return null;
|
|
1545
1599
|
}
|
|
1546
1600
|
}
|
|
1547
|
-
const tsPath =
|
|
1548
|
-
if (!
|
|
1601
|
+
const tsPath = resolve12(projectRoot, "rig.config.ts");
|
|
1602
|
+
if (!existsSync12(tsPath)) {
|
|
1549
1603
|
return null;
|
|
1550
1604
|
}
|
|
1551
1605
|
try {
|
|
1552
|
-
const source =
|
|
1606
|
+
const source = readFileSync6(tsPath, "utf8");
|
|
1553
1607
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
1554
1608
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
1555
1609
|
if (kind !== "files") {
|
|
@@ -1569,10 +1623,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
1569
1623
|
return isPlainRecord2(entry) ? entry : null;
|
|
1570
1624
|
}
|
|
1571
1625
|
function readRawTaskConfig(configPath) {
|
|
1572
|
-
if (!
|
|
1626
|
+
if (!existsSync12(configPath)) {
|
|
1573
1627
|
return null;
|
|
1574
1628
|
}
|
|
1575
|
-
const parsed = JSON.parse(
|
|
1629
|
+
const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
|
|
1576
1630
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
1577
1631
|
}
|
|
1578
1632
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -1580,12 +1634,12 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
1580
1634
|
return tasks;
|
|
1581
1635
|
}
|
|
1582
1636
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
1583
|
-
const directory =
|
|
1584
|
-
if (!
|
|
1637
|
+
const directory = resolve12(projectRoot, sourcePath);
|
|
1638
|
+
if (!existsSync12(directory)) {
|
|
1585
1639
|
return [];
|
|
1586
1640
|
}
|
|
1587
1641
|
const tasks = [];
|
|
1588
|
-
for (const name of
|
|
1642
|
+
for (const name of readdirSync2(directory)) {
|
|
1589
1643
|
if (!FILE_TASK_PATTERN.test(name))
|
|
1590
1644
|
continue;
|
|
1591
1645
|
const inferredId = basename4(name).replace(FILE_TASK_PATTERN, "");
|
|
@@ -1596,11 +1650,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
1596
1650
|
return tasks;
|
|
1597
1651
|
}
|
|
1598
1652
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
1599
|
-
const file = findFileBackedTaskFile(
|
|
1653
|
+
const file = findFileBackedTaskFile(resolve12(projectRoot, sourcePath), taskId);
|
|
1600
1654
|
if (!file) {
|
|
1601
1655
|
return null;
|
|
1602
1656
|
}
|
|
1603
|
-
const raw = JSON.parse(
|
|
1657
|
+
const raw = JSON.parse(readFileSync6(file, "utf8"));
|
|
1604
1658
|
if (!isPlainRecord2(raw)) {
|
|
1605
1659
|
return null;
|
|
1606
1660
|
}
|
|
@@ -1613,17 +1667,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
1613
1667
|
};
|
|
1614
1668
|
}
|
|
1615
1669
|
function findFileBackedTaskFile(directory, taskId) {
|
|
1616
|
-
if (!
|
|
1670
|
+
if (!existsSync12(directory)) {
|
|
1617
1671
|
return null;
|
|
1618
1672
|
}
|
|
1619
|
-
for (const name of
|
|
1673
|
+
for (const name of readdirSync2(directory)) {
|
|
1620
1674
|
if (!FILE_TASK_PATTERN.test(name))
|
|
1621
1675
|
continue;
|
|
1622
1676
|
const file = join2(directory, name);
|
|
1623
1677
|
try {
|
|
1624
1678
|
if (!statSync2(file).isFile())
|
|
1625
1679
|
continue;
|
|
1626
|
-
const raw = JSON.parse(
|
|
1680
|
+
const raw = JSON.parse(readFileSync6(file, "utf8"));
|
|
1627
1681
|
const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
|
|
1628
1682
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
1629
1683
|
if (id === taskId) {
|
|
@@ -1706,8 +1760,8 @@ function githubStatusFor(issue) {
|
|
|
1706
1760
|
return "open";
|
|
1707
1761
|
}
|
|
1708
1762
|
function selectedGitHubEnv() {
|
|
1709
|
-
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim()
|
|
1710
|
-
return { GH_TOKEN: token, GITHUB_TOKEN: token };
|
|
1763
|
+
const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
|
|
1764
|
+
return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
|
|
1711
1765
|
}
|
|
1712
1766
|
function ghSpawnOptions() {
|
|
1713
1767
|
return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
|
|
@@ -1783,8 +1837,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
|
|
|
1783
1837
|
}
|
|
1784
1838
|
|
|
1785
1839
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
1786
|
-
import { existsSync as
|
|
1787
|
-
import { basename as basename6, resolve as
|
|
1840
|
+
import { existsSync as existsSync19, readFileSync as readFileSync10, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
1841
|
+
import { basename as basename6, resolve as resolve19 } from "path";
|
|
1788
1842
|
|
|
1789
1843
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
1790
1844
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -1892,27 +1946,27 @@ function readTaskStateMetadataEnvelope(raw) {
|
|
|
1892
1946
|
};
|
|
1893
1947
|
}
|
|
1894
1948
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
1895
|
-
import { existsSync as
|
|
1896
|
-
import { resolve as
|
|
1949
|
+
import { existsSync as existsSync18, readFileSync as readFileSync9 } from "fs";
|
|
1950
|
+
import { resolve as resolve18 } from "path";
|
|
1897
1951
|
|
|
1898
1952
|
// packages/runtime/src/control-plane/native/git-native.ts
|
|
1899
|
-
import { chmodSync as chmodSync3, copyFileSync as copyFileSync3, existsSync as
|
|
1953
|
+
import { chmodSync as chmodSync3, copyFileSync as copyFileSync3, existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
1900
1954
|
import { tmpdir as tmpdir3 } from "os";
|
|
1901
|
-
import { dirname as dirname6, isAbsolute, resolve as
|
|
1955
|
+
import { dirname as dirname6, isAbsolute, resolve as resolve13 } from "path";
|
|
1902
1956
|
import { createHash } from "crypto";
|
|
1903
|
-
var sharedGitNativeOutputDir =
|
|
1904
|
-
var sharedGitNativeOutputPath =
|
|
1957
|
+
var sharedGitNativeOutputDir = resolve13(tmpdir3(), "rig-native");
|
|
1958
|
+
var sharedGitNativeOutputPath = resolve13(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
1905
1959
|
var trackerCommandUsageProbe = "usage: rig-git fetch-ref <repo-path> <remote> <branch>";
|
|
1906
1960
|
function temporaryGitBinaryOutputPath(outputPath) {
|
|
1907
1961
|
const suffix = process.platform === "win32" ? ".exe" : "";
|
|
1908
|
-
return
|
|
1962
|
+
return resolve13(dirname6(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix}`);
|
|
1909
1963
|
}
|
|
1910
1964
|
function publishGitBinary(tempOutputPath, outputPath) {
|
|
1911
1965
|
try {
|
|
1912
1966
|
renameSync(tempOutputPath, outputPath);
|
|
1913
1967
|
} catch (error) {
|
|
1914
|
-
if (process.platform === "win32" &&
|
|
1915
|
-
|
|
1968
|
+
if (process.platform === "win32" && existsSync13(outputPath)) {
|
|
1969
|
+
rmSync5(outputPath, { force: true });
|
|
1916
1970
|
renameSync(tempOutputPath, outputPath);
|
|
1917
1971
|
return;
|
|
1918
1972
|
}
|
|
@@ -1927,22 +1981,22 @@ function rigGitSourceCandidates() {
|
|
|
1927
1981
|
const cwd = process.cwd()?.trim() || "";
|
|
1928
1982
|
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
1929
1983
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
1930
|
-
const moduleRelativeSource =
|
|
1984
|
+
const moduleRelativeSource = resolve13(import.meta.dir, "../../../native/rig-git.zig");
|
|
1931
1985
|
return [...new Set([
|
|
1932
1986
|
process.env.RIG_NATIVE_GIT_SOURCE?.trim() || "",
|
|
1933
1987
|
moduleRelativeSource,
|
|
1934
|
-
projectRoot ?
|
|
1935
|
-
hostProjectRoot ?
|
|
1936
|
-
cwd ?
|
|
1937
|
-
execDir ?
|
|
1938
|
-
execDir ?
|
|
1988
|
+
projectRoot ? resolve13(projectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
1989
|
+
hostProjectRoot ? resolve13(hostProjectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
1990
|
+
cwd ? resolve13(cwd, "packages/runtime/native/rig-git.zig") : "",
|
|
1991
|
+
execDir ? resolve13(execDir, "..", "..", "packages/runtime/native/rig-git.zig") : "",
|
|
1992
|
+
execDir ? resolve13(execDir, "..", "native", "rig-git.zig") : ""
|
|
1939
1993
|
].filter(Boolean))];
|
|
1940
1994
|
}
|
|
1941
1995
|
function nativePackageBinaryCandidates3(fromDir, fileName) {
|
|
1942
1996
|
const candidates = [];
|
|
1943
|
-
let cursor =
|
|
1997
|
+
let cursor = resolve13(fromDir);
|
|
1944
1998
|
for (let index = 0;index < 8; index += 1) {
|
|
1945
|
-
candidates.push(
|
|
1999
|
+
candidates.push(resolve13(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve13(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve13(cursor, "native", fileName), resolve13(cursor, "native", "bin", fileName));
|
|
1946
2000
|
const parent = dirname6(cursor);
|
|
1947
2001
|
if (parent === cursor)
|
|
1948
2002
|
break;
|
|
@@ -1957,15 +2011,15 @@ function rigGitBinaryCandidates() {
|
|
|
1957
2011
|
return [...new Set([
|
|
1958
2012
|
explicit,
|
|
1959
2013
|
...nativePackageBinaryCandidates3(import.meta.dir, fileName),
|
|
1960
|
-
execDir ?
|
|
1961
|
-
execDir ?
|
|
1962
|
-
execDir ?
|
|
2014
|
+
execDir ? resolve13(execDir, fileName) : "",
|
|
2015
|
+
execDir ? resolve13(execDir, "..", fileName) : "",
|
|
2016
|
+
execDir ? resolve13(execDir, "..", "bin", fileName) : "",
|
|
1963
2017
|
sharedGitNativeOutputPath
|
|
1964
2018
|
].filter(Boolean))];
|
|
1965
2019
|
}
|
|
1966
2020
|
function resolveGitSourcePath() {
|
|
1967
2021
|
for (const candidate of rigGitSourceCandidates()) {
|
|
1968
|
-
if (candidate &&
|
|
2022
|
+
if (candidate && existsSync13(candidate)) {
|
|
1969
2023
|
return candidate;
|
|
1970
2024
|
}
|
|
1971
2025
|
}
|
|
@@ -1976,7 +2030,7 @@ function resolveGitBinaryPath() {
|
|
|
1976
2030
|
return null;
|
|
1977
2031
|
}
|
|
1978
2032
|
for (const candidate of rigGitBinaryCandidates()) {
|
|
1979
|
-
if (candidate &&
|
|
2033
|
+
if (candidate && existsSync13(candidate)) {
|
|
1980
2034
|
return candidate;
|
|
1981
2035
|
}
|
|
1982
2036
|
}
|
|
@@ -2006,7 +2060,7 @@ function nativeBuildManifestPath3(outputPath) {
|
|
|
2006
2060
|
return `${outputPath}.build-manifest.json`;
|
|
2007
2061
|
}
|
|
2008
2062
|
async function hasMatchingNativeBuildManifest3(manifestPath, buildKey) {
|
|
2009
|
-
if (!
|
|
2063
|
+
if (!existsSync13(manifestPath)) {
|
|
2010
2064
|
return false;
|
|
2011
2065
|
}
|
|
2012
2066
|
try {
|
|
@@ -2017,11 +2071,11 @@ async function hasMatchingNativeBuildManifest3(manifestPath, buildKey) {
|
|
|
2017
2071
|
}
|
|
2018
2072
|
}
|
|
2019
2073
|
function hasMatchingNativeBuildManifestSync(manifestPath, buildKey) {
|
|
2020
|
-
if (!
|
|
2074
|
+
if (!existsSync13(manifestPath)) {
|
|
2021
2075
|
return false;
|
|
2022
2076
|
}
|
|
2023
2077
|
try {
|
|
2024
|
-
const manifest = JSON.parse(
|
|
2078
|
+
const manifest = JSON.parse(readFileSync7(manifestPath, "utf8"));
|
|
2025
2079
|
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
2026
2080
|
} catch {
|
|
2027
2081
|
return false;
|
|
@@ -2033,7 +2087,7 @@ async function sha256File3(path) {
|
|
|
2033
2087
|
return hasher.digest("hex");
|
|
2034
2088
|
}
|
|
2035
2089
|
function sha256FileSync(path) {
|
|
2036
|
-
return createHash("sha256").update(
|
|
2090
|
+
return createHash("sha256").update(readFileSync7(path)).digest("hex");
|
|
2037
2091
|
}
|
|
2038
2092
|
async function ensureRigGitBinaryPath(outputPath = sharedGitNativeOutputPath) {
|
|
2039
2093
|
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
@@ -2051,7 +2105,7 @@ async function ensureRigGitBinaryPath(outputPath = sharedGitNativeOutputPath) {
|
|
|
2051
2105
|
if (!zigBinary) {
|
|
2052
2106
|
throw new Error("zig is required to build native Rig git tools.");
|
|
2053
2107
|
}
|
|
2054
|
-
|
|
2108
|
+
mkdirSync6(dirname6(outputPath), { recursive: true });
|
|
2055
2109
|
const sourceDigest = await sha256File3(sourcePath);
|
|
2056
2110
|
const buildKey = JSON.stringify({
|
|
2057
2111
|
version: 1,
|
|
@@ -2062,7 +2116,7 @@ async function ensureRigGitBinaryPath(outputPath = sharedGitNativeOutputPath) {
|
|
|
2062
2116
|
sourceDigest
|
|
2063
2117
|
});
|
|
2064
2118
|
const manifestPath = nativeBuildManifestPath3(outputPath);
|
|
2065
|
-
const needsBuild = !
|
|
2119
|
+
const needsBuild = !existsSync13(outputPath) || !await hasMatchingNativeBuildManifest3(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
2066
2120
|
if (!needsBuild) {
|
|
2067
2121
|
chmodSync3(outputPath, 493);
|
|
2068
2122
|
return outputPath;
|
|
@@ -2085,20 +2139,20 @@ async function ensureRigGitBinaryPath(outputPath = sharedGitNativeOutputPath) {
|
|
|
2085
2139
|
new Response(build.stdout).text(),
|
|
2086
2140
|
new Response(build.stderr).text()
|
|
2087
2141
|
]);
|
|
2088
|
-
if (exitCode !== 0 || !
|
|
2142
|
+
if (exitCode !== 0 || !existsSync13(tempOutputPath)) {
|
|
2089
2143
|
const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
|
|
2090
2144
|
`);
|
|
2091
2145
|
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${exitCode}`}`);
|
|
2092
2146
|
}
|
|
2093
2147
|
chmodSync3(tempOutputPath, 493);
|
|
2094
|
-
if (
|
|
2095
|
-
|
|
2148
|
+
if (existsSync13(outputPath) && await hasMatchingNativeBuildManifest3(manifestPath, buildKey)) {
|
|
2149
|
+
rmSync5(tempOutputPath, { force: true });
|
|
2096
2150
|
chmodSync3(outputPath, 493);
|
|
2097
2151
|
return outputPath;
|
|
2098
2152
|
}
|
|
2099
2153
|
publishGitBinary(tempOutputPath, outputPath);
|
|
2100
2154
|
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
2101
|
-
|
|
2155
|
+
rmSync5(outputPath, { force: true });
|
|
2102
2156
|
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
2103
2157
|
}
|
|
2104
2158
|
await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
@@ -2121,7 +2175,7 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
|
|
|
2121
2175
|
if (!zigBinary) {
|
|
2122
2176
|
throw new Error("zig is required to build native Rig git tools.");
|
|
2123
2177
|
}
|
|
2124
|
-
|
|
2178
|
+
mkdirSync6(dirname6(outputPath), { recursive: true });
|
|
2125
2179
|
const sourceDigest = sha256FileSync(sourcePath);
|
|
2126
2180
|
const buildKey = JSON.stringify({
|
|
2127
2181
|
version: 1,
|
|
@@ -2132,7 +2186,7 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
|
|
|
2132
2186
|
sourceDigest
|
|
2133
2187
|
});
|
|
2134
2188
|
const manifestPath = nativeBuildManifestPath3(outputPath);
|
|
2135
|
-
const needsBuild = !
|
|
2189
|
+
const needsBuild = !existsSync13(outputPath) || !hasMatchingNativeBuildManifestSync(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
2136
2190
|
if (!needsBuild) {
|
|
2137
2191
|
chmodSync3(outputPath, 493);
|
|
2138
2192
|
return outputPath;
|
|
@@ -2150,7 +2204,7 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
|
|
|
2150
2204
|
stdout: "pipe",
|
|
2151
2205
|
stderr: "pipe"
|
|
2152
2206
|
});
|
|
2153
|
-
if (build.exitCode !== 0 || !
|
|
2207
|
+
if (build.exitCode !== 0 || !existsSync13(tempOutputPath)) {
|
|
2154
2208
|
const stderr = build.stderr.toString().trim();
|
|
2155
2209
|
const stdout = build.stdout.toString().trim();
|
|
2156
2210
|
const details = [stderr, stdout].filter(Boolean).join(`
|
|
@@ -2158,31 +2212,31 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
|
|
|
2158
2212
|
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${build.exitCode}`}`);
|
|
2159
2213
|
}
|
|
2160
2214
|
chmodSync3(tempOutputPath, 493);
|
|
2161
|
-
if (
|
|
2162
|
-
|
|
2215
|
+
if (existsSync13(outputPath) && hasMatchingNativeBuildManifestSync(manifestPath, buildKey)) {
|
|
2216
|
+
rmSync5(tempOutputPath, { force: true });
|
|
2163
2217
|
chmodSync3(outputPath, 493);
|
|
2164
2218
|
return outputPath;
|
|
2165
2219
|
}
|
|
2166
2220
|
publishGitBinary(tempOutputPath, outputPath);
|
|
2167
2221
|
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
2168
|
-
|
|
2222
|
+
rmSync5(outputPath, { force: true });
|
|
2169
2223
|
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
2170
2224
|
}
|
|
2171
|
-
|
|
2225
|
+
writeFileSync5(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
2172
2226
|
`, "utf8");
|
|
2173
2227
|
return outputPath;
|
|
2174
2228
|
}
|
|
2175
2229
|
async function materializeRigGitBinary(targetDir) {
|
|
2176
2230
|
const sourcePath = await ensureRigGitBinaryPath();
|
|
2177
|
-
const targetPath =
|
|
2178
|
-
|
|
2231
|
+
const targetPath = resolve13(targetDir, runtimeRigGitFileName());
|
|
2232
|
+
mkdirSync6(targetDir, { recursive: true });
|
|
2179
2233
|
const sourceDigest = await sha256File3(sourcePath);
|
|
2180
2234
|
const buildKey = JSON.stringify({
|
|
2181
2235
|
version: 1,
|
|
2182
2236
|
sourcePath,
|
|
2183
2237
|
sourceDigest
|
|
2184
2238
|
});
|
|
2185
|
-
const needsCopy = !
|
|
2239
|
+
const needsCopy = !existsSync13(targetPath) || !await hasMatchingNativeBuildManifest3(nativeBuildManifestPath3(targetPath), buildKey);
|
|
2186
2240
|
if (needsCopy) {
|
|
2187
2241
|
copyFileSync3(sourcePath, targetPath);
|
|
2188
2242
|
chmodSync3(targetPath, 493);
|
|
@@ -2209,7 +2263,7 @@ function runGitNative(command, args) {
|
|
|
2209
2263
|
}
|
|
2210
2264
|
} else {
|
|
2211
2265
|
const explicitBinaryPath = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
2212
|
-
binaryPath = explicitBinaryPath &&
|
|
2266
|
+
binaryPath = explicitBinaryPath && existsSync13(explicitBinaryPath) ? explicitBinaryPath : !explicitBinaryPath ? resolveGitBinaryPath() : null;
|
|
2213
2267
|
if (!binaryPath) {
|
|
2214
2268
|
try {
|
|
2215
2269
|
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
@@ -2273,41 +2327,41 @@ function nativeFetchRef(repoPath, remote, branch) {
|
|
|
2273
2327
|
return requireGitNativeString("fetch-ref", [repoPath, remote, branch]);
|
|
2274
2328
|
}
|
|
2275
2329
|
function nativeReadBlobAtRef(repoPath, ref, path) {
|
|
2276
|
-
const requestDir =
|
|
2277
|
-
|
|
2278
|
-
const outputPath =
|
|
2330
|
+
const requestDir = resolve13(sharedGitNativeOutputDir, "reads", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
2331
|
+
mkdirSync6(requestDir, { recursive: true });
|
|
2332
|
+
const outputPath = resolve13(requestDir, "blob.txt");
|
|
2279
2333
|
try {
|
|
2280
2334
|
requireGitNative("read-blob-at-ref", [repoPath, ref, path, outputPath]);
|
|
2281
|
-
return
|
|
2335
|
+
return readFileSync7(outputPath, "utf8");
|
|
2282
2336
|
} finally {
|
|
2283
|
-
|
|
2337
|
+
rmSync5(requestDir, { recursive: true, force: true });
|
|
2284
2338
|
}
|
|
2285
2339
|
}
|
|
2286
2340
|
function nativeReadBlobBytesAtRef(repoPath, ref, path) {
|
|
2287
|
-
const requestDir =
|
|
2288
|
-
|
|
2289
|
-
const outputPath =
|
|
2341
|
+
const requestDir = resolve13(sharedGitNativeOutputDir, "reads", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
2342
|
+
mkdirSync6(requestDir, { recursive: true });
|
|
2343
|
+
const outputPath = resolve13(requestDir, "blob.bin");
|
|
2290
2344
|
try {
|
|
2291
2345
|
requireGitNative("read-blob-at-ref", [repoPath, ref, path, outputPath]);
|
|
2292
|
-
return
|
|
2346
|
+
return readFileSync7(outputPath);
|
|
2293
2347
|
} finally {
|
|
2294
|
-
|
|
2348
|
+
rmSync5(requestDir, { recursive: true, force: true });
|
|
2295
2349
|
}
|
|
2296
2350
|
}
|
|
2297
2351
|
|
|
2298
2352
|
// packages/runtime/src/control-plane/native/utils.ts
|
|
2299
2353
|
init_layout();
|
|
2300
2354
|
import { ptr as ptr2 } from "bun:ffi";
|
|
2301
|
-
import { existsSync as
|
|
2302
|
-
import { resolve as
|
|
2355
|
+
import { existsSync as existsSync15, readFileSync as readFileSync8 } from "fs";
|
|
2356
|
+
import { resolve as resolve15 } from "path";
|
|
2303
2357
|
|
|
2304
2358
|
// packages/runtime/src/control-plane/native/runtime-native.ts
|
|
2305
2359
|
import { dlopen, ptr, suffix, toBuffer } from "bun:ffi";
|
|
2306
|
-
import { copyFileSync as copyFileSync4, existsSync as
|
|
2360
|
+
import { copyFileSync as copyFileSync4, existsSync as existsSync14, mkdirSync as mkdirSync7, renameSync as renameSync2, rmSync as rmSync6, statSync as statSync3 } from "fs";
|
|
2307
2361
|
import { tmpdir as tmpdir4 } from "os";
|
|
2308
|
-
import { dirname as dirname7, resolve as
|
|
2309
|
-
var sharedNativeRuntimeOutputDir =
|
|
2310
|
-
var sharedNativeRuntimeOutputPath =
|
|
2362
|
+
import { dirname as dirname7, resolve as resolve14 } from "path";
|
|
2363
|
+
var sharedNativeRuntimeOutputDir = resolve14(tmpdir4(), "rig-native");
|
|
2364
|
+
var sharedNativeRuntimeOutputPath = resolve14(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
|
|
2311
2365
|
var colocatedNativeRuntimeFileName = `runtime-native.${suffix}`;
|
|
2312
2366
|
var nativeRuntimeLibrary = await loadNativeRuntimeLibrary();
|
|
2313
2367
|
function requireNativeRuntimeLibrary(feature) {
|
|
@@ -2338,16 +2392,16 @@ async function ensureNativeRuntimeLibraryPath(outputPath = sharedNativeRuntimeOu
|
|
|
2338
2392
|
if (await buildNativeRuntimeLibrary(outputPath, options)) {
|
|
2339
2393
|
return outputPath;
|
|
2340
2394
|
}
|
|
2341
|
-
return !options.force &&
|
|
2395
|
+
return !options.force && existsSync14(outputPath) ? outputPath : null;
|
|
2342
2396
|
}
|
|
2343
2397
|
async function materializeNativeRuntimeLibrary(targetDir) {
|
|
2344
2398
|
const sourcePath = await ensureNativeRuntimeLibraryPath();
|
|
2345
2399
|
if (!sourcePath) {
|
|
2346
2400
|
return null;
|
|
2347
2401
|
}
|
|
2348
|
-
const targetPath =
|
|
2349
|
-
|
|
2350
|
-
const needsCopy = !
|
|
2402
|
+
const targetPath = resolve14(targetDir, colocatedNativeRuntimeFileName);
|
|
2403
|
+
mkdirSync7(targetDir, { recursive: true });
|
|
2404
|
+
const needsCopy = !existsSync14(targetPath) || statSync3(sourcePath).mtimeMs > statSync3(targetPath).mtimeMs;
|
|
2351
2405
|
if (needsCopy) {
|
|
2352
2406
|
copyFileSync4(sourcePath, targetPath);
|
|
2353
2407
|
}
|
|
@@ -2358,7 +2412,7 @@ async function loadNativeRuntimeLibrary() {
|
|
|
2358
2412
|
return null;
|
|
2359
2413
|
}
|
|
2360
2414
|
for (const candidate of nativeRuntimeLibraryCandidates()) {
|
|
2361
|
-
if (!candidate || !
|
|
2415
|
+
if (!candidate || !existsSync14(candidate)) {
|
|
2362
2416
|
continue;
|
|
2363
2417
|
}
|
|
2364
2418
|
const loaded = tryDlopenNativeRuntimeLibrary(candidate);
|
|
@@ -2374,10 +2428,10 @@ async function loadNativeRuntimeLibrary() {
|
|
|
2374
2428
|
}
|
|
2375
2429
|
function nativePackageLibraryCandidates(fromDir, names) {
|
|
2376
2430
|
const candidates = [];
|
|
2377
|
-
let cursor =
|
|
2431
|
+
let cursor = resolve14(fromDir);
|
|
2378
2432
|
for (let index = 0;index < 8; index += 1) {
|
|
2379
2433
|
for (const name of names) {
|
|
2380
|
-
candidates.push(
|
|
2434
|
+
candidates.push(resolve14(cursor, "native", `${process.platform}-${process.arch}`, name), resolve14(cursor, "native", `${process.platform}-${process.arch}`, "lib", name), resolve14(cursor, "native", name), resolve14(cursor, "native", "lib", name));
|
|
2381
2435
|
}
|
|
2382
2436
|
const parent = dirname7(cursor);
|
|
2383
2437
|
if (parent === cursor)
|
|
@@ -2393,22 +2447,22 @@ function nativeRuntimeLibraryCandidates() {
|
|
|
2393
2447
|
return [...new Set([
|
|
2394
2448
|
explicit,
|
|
2395
2449
|
...nativePackageLibraryCandidates(import.meta.dir, [colocatedNativeRuntimeFileName, platformSpecific]),
|
|
2396
|
-
execDir ?
|
|
2397
|
-
execDir ?
|
|
2398
|
-
execDir ?
|
|
2399
|
-
execDir ?
|
|
2400
|
-
execDir ?
|
|
2401
|
-
execDir ?
|
|
2450
|
+
execDir ? resolve14(execDir, colocatedNativeRuntimeFileName) : "",
|
|
2451
|
+
execDir ? resolve14(execDir, platformSpecific) : "",
|
|
2452
|
+
execDir ? resolve14(execDir, "..", colocatedNativeRuntimeFileName) : "",
|
|
2453
|
+
execDir ? resolve14(execDir, "..", platformSpecific) : "",
|
|
2454
|
+
execDir ? resolve14(execDir, "lib", colocatedNativeRuntimeFileName) : "",
|
|
2455
|
+
execDir ? resolve14(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
|
|
2402
2456
|
sharedNativeRuntimeOutputPath
|
|
2403
2457
|
].filter(Boolean))];
|
|
2404
2458
|
}
|
|
2405
2459
|
function resolveNativeRuntimeSourcePath() {
|
|
2406
2460
|
const explicit = process.env.RIG_NATIVE_RUNTIME_SOURCE?.trim();
|
|
2407
|
-
if (explicit &&
|
|
2461
|
+
if (explicit && existsSync14(explicit)) {
|
|
2408
2462
|
return explicit;
|
|
2409
2463
|
}
|
|
2410
|
-
const bundled =
|
|
2411
|
-
return
|
|
2464
|
+
const bundled = resolve14(import.meta.dir, "../../../native/snapshot.zig");
|
|
2465
|
+
return existsSync14(bundled) ? bundled : null;
|
|
2412
2466
|
}
|
|
2413
2467
|
function resolveNativeRuntimeSidecarSourcePath() {
|
|
2414
2468
|
const envRoots = [
|
|
@@ -2421,17 +2475,17 @@ function resolveNativeRuntimeSidecarSourcePath() {
|
|
|
2421
2475
|
"packages/runtime/src/control-plane/native/runtime-native-sidecar.ts",
|
|
2422
2476
|
"packages/runtime/dist/src/control-plane/native/runtime-native-sidecar.js"
|
|
2423
2477
|
]) {
|
|
2424
|
-
const candidate =
|
|
2425
|
-
if (
|
|
2478
|
+
const candidate = resolve14(root, relative);
|
|
2479
|
+
if (existsSync14(candidate)) {
|
|
2426
2480
|
return candidate;
|
|
2427
2481
|
}
|
|
2428
2482
|
}
|
|
2429
2483
|
}
|
|
2430
2484
|
for (const localCandidate of [
|
|
2431
|
-
|
|
2432
|
-
|
|
2485
|
+
resolve14(import.meta.dir, "runtime-native-sidecar.js"),
|
|
2486
|
+
resolve14(import.meta.dir, "runtime-native-sidecar.ts")
|
|
2433
2487
|
]) {
|
|
2434
|
-
if (
|
|
2488
|
+
if (existsSync14(localCandidate))
|
|
2435
2489
|
return localCandidate;
|
|
2436
2490
|
}
|
|
2437
2491
|
return null;
|
|
@@ -2447,8 +2501,8 @@ async function buildNativeRuntimeLibrary(outputPath, options = {}) {
|
|
|
2447
2501
|
}
|
|
2448
2502
|
const tempOutputPath = `${outputPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
2449
2503
|
try {
|
|
2450
|
-
|
|
2451
|
-
const needsBuild = options.force === true || !
|
|
2504
|
+
mkdirSync7(dirname7(outputPath), { recursive: true });
|
|
2505
|
+
const needsBuild = options.force === true || !existsSync14(outputPath) || statSync3(sourcePath).mtimeMs > statSync3(outputPath).mtimeMs;
|
|
2452
2506
|
if (!needsBuild) {
|
|
2453
2507
|
return true;
|
|
2454
2508
|
}
|
|
@@ -2466,14 +2520,14 @@ async function buildNativeRuntimeLibrary(outputPath, options = {}) {
|
|
|
2466
2520
|
stderr: "pipe"
|
|
2467
2521
|
});
|
|
2468
2522
|
const exitCode = await build.exited;
|
|
2469
|
-
if (exitCode !== 0 || !
|
|
2470
|
-
|
|
2523
|
+
if (exitCode !== 0 || !existsSync14(tempOutputPath)) {
|
|
2524
|
+
rmSync6(tempOutputPath, { force: true });
|
|
2471
2525
|
return false;
|
|
2472
2526
|
}
|
|
2473
2527
|
renameSync2(tempOutputPath, outputPath);
|
|
2474
2528
|
return true;
|
|
2475
2529
|
} catch {
|
|
2476
|
-
|
|
2530
|
+
rmSync6(tempOutputPath, { force: true });
|
|
2477
2531
|
return false;
|
|
2478
2532
|
}
|
|
2479
2533
|
}
|
|
@@ -2592,11 +2646,11 @@ function runCapture(command, cwd, env) {
|
|
|
2592
2646
|
};
|
|
2593
2647
|
}
|
|
2594
2648
|
function readJsonFile(path, fallback) {
|
|
2595
|
-
if (!
|
|
2649
|
+
if (!existsSync15(path)) {
|
|
2596
2650
|
return fallback;
|
|
2597
2651
|
}
|
|
2598
2652
|
try {
|
|
2599
|
-
return JSON.parse(
|
|
2653
|
+
return JSON.parse(readFileSync8(path, "utf-8"));
|
|
2600
2654
|
} catch {
|
|
2601
2655
|
return fallback;
|
|
2602
2656
|
}
|
|
@@ -2610,31 +2664,31 @@ function unique(values) {
|
|
|
2610
2664
|
function resolveHarnessPaths(projectRoot) {
|
|
2611
2665
|
const hasRuntimeWorkspace = Boolean(process.env.RIG_TASK_WORKSPACE?.trim());
|
|
2612
2666
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
2613
|
-
const harnessRoot =
|
|
2614
|
-
const stateRoot =
|
|
2667
|
+
const harnessRoot = resolve15(projectRoot, "rig");
|
|
2668
|
+
const stateRoot = resolve15(projectRoot, ".rig");
|
|
2615
2669
|
const layout = hasRuntimeWorkspace ? resolveRigLayout(projectRoot) : null;
|
|
2616
|
-
const stateDir = layout?.stateDir ??
|
|
2617
|
-
const logsDir = layout?.logsDir ??
|
|
2618
|
-
const artifactsDir = layout?.artifactsRoot ??
|
|
2619
|
-
const taskConfigPath = layout?.taskConfigPath ??
|
|
2620
|
-
const binDir = layout?.binDir ??
|
|
2670
|
+
const stateDir = layout?.stateDir ?? resolve15(stateRoot, "state");
|
|
2671
|
+
const logsDir = layout?.logsDir ?? resolve15(stateRoot, "logs");
|
|
2672
|
+
const artifactsDir = layout?.artifactsRoot ?? resolve15(monorepoRoot, "artifacts");
|
|
2673
|
+
const taskConfigPath = layout?.taskConfigPath ?? resolve15(monorepoRoot, ".rig", "task-config.json");
|
|
2674
|
+
const binDir = layout?.binDir ?? resolve15(stateRoot, "bin");
|
|
2621
2675
|
return {
|
|
2622
2676
|
harnessRoot,
|
|
2623
2677
|
stateDir: process.env.RIG_STATE_DIR || stateDir,
|
|
2624
2678
|
artifactsDir,
|
|
2625
2679
|
logsDir: process.env.RIG_LOGS_DIR || logsDir,
|
|
2626
2680
|
binDir,
|
|
2627
|
-
hooksDir:
|
|
2628
|
-
validationDir:
|
|
2681
|
+
hooksDir: resolve15(harnessRoot, "hooks"),
|
|
2682
|
+
validationDir: resolve15(harnessRoot, "validation"),
|
|
2629
2683
|
taskConfigPath,
|
|
2630
|
-
sessionPath: process.env.RIG_SESSION_FILE ||
|
|
2684
|
+
sessionPath: process.env.RIG_SESSION_FILE || resolve15(stateRoot, "session", "session.json"),
|
|
2631
2685
|
monorepoRoot,
|
|
2632
|
-
tsApiTestsDir: process.env.TS_API_TESTS_DIR ||
|
|
2633
|
-
taskRepoCommitsPath:
|
|
2634
|
-
baseRepoPinsPath:
|
|
2635
|
-
failedApproachesPath:
|
|
2636
|
-
agentProfilePath:
|
|
2637
|
-
reviewProfilePath:
|
|
2686
|
+
tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve15(monorepoRoot, "TSAPITests"),
|
|
2687
|
+
taskRepoCommitsPath: resolve15(stateDir, "task-repo-commits.json"),
|
|
2688
|
+
baseRepoPinsPath: resolve15(stateDir, "base-repo-pins.json"),
|
|
2689
|
+
failedApproachesPath: resolve15(stateDir, "failed_approaches.md"),
|
|
2690
|
+
agentProfilePath: resolve15(stateDir, "agent-profile.json"),
|
|
2691
|
+
reviewProfilePath: resolve15(stateDir, "review-profile.json")
|
|
2638
2692
|
};
|
|
2639
2693
|
}
|
|
2640
2694
|
function normalizeRelativeScopePath(inputPath) {
|
|
@@ -2696,35 +2750,35 @@ function createNativeScopeMatcher() {
|
|
|
2696
2750
|
}
|
|
2697
2751
|
|
|
2698
2752
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
2699
|
-
import { existsSync as
|
|
2700
|
-
import { resolve as
|
|
2753
|
+
import { existsSync as existsSync17 } from "fs";
|
|
2754
|
+
import { resolve as resolve17 } from "path";
|
|
2701
2755
|
|
|
2702
2756
|
// packages/runtime/src/control-plane/repos/layout.ts
|
|
2703
2757
|
init_layout();
|
|
2704
|
-
import { existsSync as
|
|
2705
|
-
import { basename as basename5, dirname as dirname8, join as join3, resolve as
|
|
2758
|
+
import { existsSync as existsSync16 } from "fs";
|
|
2759
|
+
import { basename as basename5, dirname as dirname8, join as join3, resolve as resolve16 } from "path";
|
|
2706
2760
|
function resolveRepoStateDir(projectRoot) {
|
|
2707
|
-
const normalizedProjectRoot =
|
|
2761
|
+
const normalizedProjectRoot = resolve16(projectRoot);
|
|
2708
2762
|
const projectParent = dirname8(normalizedProjectRoot);
|
|
2709
2763
|
if (basename5(projectParent) === ".worktrees") {
|
|
2710
2764
|
const ownerRoot = dirname8(projectParent);
|
|
2711
|
-
const ownerHasRepoMarkers =
|
|
2765
|
+
const ownerHasRepoMarkers = existsSync16(resolve16(ownerRoot, ".git")) || existsSync16(resolve16(ownerRoot, ".rig", "state"));
|
|
2712
2766
|
if (ownerHasRepoMarkers) {
|
|
2713
|
-
return
|
|
2767
|
+
return resolve16(ownerRoot, ".rig", "state");
|
|
2714
2768
|
}
|
|
2715
2769
|
}
|
|
2716
|
-
return
|
|
2770
|
+
return resolve16(projectRoot, ".rig", "state");
|
|
2717
2771
|
}
|
|
2718
2772
|
function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
2719
|
-
const normalizedProjectRoot =
|
|
2773
|
+
const normalizedProjectRoot = resolve16(projectRoot);
|
|
2720
2774
|
const entry = getManagedRepoEntry(repoId);
|
|
2721
2775
|
const stateDir = resolveRepoStateDir(normalizedProjectRoot);
|
|
2722
2776
|
const metadataRelativePath = join3("repos", entry.id);
|
|
2723
|
-
const metadataRoot =
|
|
2777
|
+
const metadataRoot = resolve16(stateDir, metadataRelativePath);
|
|
2724
2778
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
2725
|
-
const runsInsideTaskWorktree = runtimeWorkspace &&
|
|
2779
|
+
const runsInsideTaskWorktree = runtimeWorkspace && resolve16(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname8(normalizedProjectRoot)) === ".worktrees";
|
|
2726
2780
|
const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
|
|
2727
|
-
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ?
|
|
2781
|
+
const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve16(process.env[entry.checkoutEnvVar].trim()) : resolve16(normalizedProjectRoot, entry.alias);
|
|
2728
2782
|
return {
|
|
2729
2783
|
projectRoot: normalizedProjectRoot,
|
|
2730
2784
|
repoId: entry.id,
|
|
@@ -2732,12 +2786,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
|
|
|
2732
2786
|
defaultBranch: entry.defaultBranch,
|
|
2733
2787
|
remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
|
|
2734
2788
|
checkoutRoot,
|
|
2735
|
-
worktreesRoot:
|
|
2789
|
+
worktreesRoot: resolve16(checkoutRoot, ".worktrees"),
|
|
2736
2790
|
stateDir,
|
|
2737
2791
|
metadataRoot,
|
|
2738
2792
|
metadataRelativePath,
|
|
2739
|
-
mirrorRoot:
|
|
2740
|
-
mirrorStatePath:
|
|
2793
|
+
mirrorRoot: resolve16(metadataRoot, "mirror.git"),
|
|
2794
|
+
mirrorStatePath: resolve16(metadataRoot, "mirror-state.json"),
|
|
2741
2795
|
mirrorStateRelativePath: join3(metadataRelativePath, "mirror-state.json")
|
|
2742
2796
|
};
|
|
2743
2797
|
}
|
|
@@ -2759,7 +2813,7 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
2759
2813
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
2760
2814
|
try {
|
|
2761
2815
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
2762
|
-
if (
|
|
2816
|
+
if (existsSync17(resolve17(layout.mirrorRoot, "HEAD"))) {
|
|
2763
2817
|
return layout.mirrorRoot;
|
|
2764
2818
|
}
|
|
2765
2819
|
} catch {}
|
|
@@ -2770,8 +2824,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
2770
2824
|
var DEFAULT_READ_DEPS = {
|
|
2771
2825
|
fetchRef: nativeFetchRef,
|
|
2772
2826
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
2773
|
-
exists:
|
|
2774
|
-
readFile: (path) =>
|
|
2827
|
+
exists: existsSync18,
|
|
2828
|
+
readFile: (path) => readFileSync9(path, "utf8")
|
|
2775
2829
|
};
|
|
2776
2830
|
function parseIssueStatus(rawStatus) {
|
|
2777
2831
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -2852,12 +2906,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
2852
2906
|
if (runtimeContextPath) {
|
|
2853
2907
|
return true;
|
|
2854
2908
|
}
|
|
2855
|
-
return
|
|
2909
|
+
return existsSync18(resolve18(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
2856
2910
|
}
|
|
2857
2911
|
function readLocalTrackerState(projectRoot, deps) {
|
|
2858
2912
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
2859
|
-
const issuesPath =
|
|
2860
|
-
const taskStatePath =
|
|
2913
|
+
const issuesPath = resolve18(monorepoRoot, ".beads", "issues.jsonl");
|
|
2914
|
+
const taskStatePath = resolve18(monorepoRoot, ".beads", "task-state.json");
|
|
2861
2915
|
return projectSyncedTrackerSnapshot({
|
|
2862
2916
|
source: "local",
|
|
2863
2917
|
issuesBaseOid: null,
|
|
@@ -2919,7 +2973,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
2919
2973
|
return readValidationDescriptionMap(raw);
|
|
2920
2974
|
}
|
|
2921
2975
|
function readSourceValidationDescriptions(projectRoot) {
|
|
2922
|
-
const rootRaw = readJsonFile(
|
|
2976
|
+
const rootRaw = readJsonFile(resolve19(projectRoot, "rig", "task-config.json"), {});
|
|
2923
2977
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
2924
2978
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
2925
2979
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -2995,15 +3049,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
2995
3049
|
return meta.validation_descriptions;
|
|
2996
3050
|
}
|
|
2997
3051
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
2998
|
-
const taskStatePath =
|
|
3052
|
+
const taskStatePath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
2999
3053
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
3000
3054
|
}
|
|
3001
3055
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
3002
|
-
const issuesPath =
|
|
3003
|
-
if (!
|
|
3056
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3057
|
+
if (!existsSync19(issuesPath)) {
|
|
3004
3058
|
return null;
|
|
3005
3059
|
}
|
|
3006
|
-
for (const line of
|
|
3060
|
+
for (const line of readFileSync10(issuesPath, "utf8").split(/\r?\n/)) {
|
|
3007
3061
|
const trimmed = line.trim();
|
|
3008
3062
|
if (!trimmed) {
|
|
3009
3063
|
continue;
|
|
@@ -3044,25 +3098,25 @@ function lookupTask(projectRoot, input) {
|
|
|
3044
3098
|
function artifactDirForId(projectRoot, id) {
|
|
3045
3099
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3046
3100
|
if (workspaceDir) {
|
|
3047
|
-
const worktreeArtifacts =
|
|
3048
|
-
if (
|
|
3101
|
+
const worktreeArtifacts = resolve19(workspaceDir, "artifacts", id);
|
|
3102
|
+
if (existsSync19(worktreeArtifacts) || existsSync19(resolve19(workspaceDir, "artifacts"))) {
|
|
3049
3103
|
return worktreeArtifacts;
|
|
3050
3104
|
}
|
|
3051
3105
|
}
|
|
3052
3106
|
try {
|
|
3053
3107
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3054
|
-
return
|
|
3108
|
+
return resolve19(paths.artifactsDir, id);
|
|
3055
3109
|
} catch {
|
|
3056
|
-
return
|
|
3110
|
+
return resolve19(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
3057
3111
|
}
|
|
3058
3112
|
}
|
|
3059
3113
|
function resolveTaskConfigPath(projectRoot) {
|
|
3060
3114
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3061
|
-
if (
|
|
3115
|
+
if (existsSync19(paths.taskConfigPath)) {
|
|
3062
3116
|
return paths.taskConfigPath;
|
|
3063
3117
|
}
|
|
3064
3118
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3065
|
-
if (
|
|
3119
|
+
if (existsSync19(candidate)) {
|
|
3066
3120
|
return candidate;
|
|
3067
3121
|
}
|
|
3068
3122
|
}
|
|
@@ -3070,7 +3124,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
3070
3124
|
}
|
|
3071
3125
|
function findSourceTaskConfigPath(projectRoot) {
|
|
3072
3126
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3073
|
-
if (
|
|
3127
|
+
if (existsSync19(candidate)) {
|
|
3074
3128
|
return candidate;
|
|
3075
3129
|
}
|
|
3076
3130
|
}
|
|
@@ -3083,7 +3137,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
3083
3137
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
3084
3138
|
if (sourcePath && synced.updated) {
|
|
3085
3139
|
try {
|
|
3086
|
-
|
|
3140
|
+
writeFileSync6(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
3087
3141
|
`, "utf-8");
|
|
3088
3142
|
} catch {}
|
|
3089
3143
|
}
|
|
@@ -3135,12 +3189,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
3135
3189
|
return !candidate.role;
|
|
3136
3190
|
}
|
|
3137
3191
|
function readSourceIssueRecords(projectRoot) {
|
|
3138
|
-
const issuesPath =
|
|
3139
|
-
if (!
|
|
3192
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3193
|
+
if (!existsSync19(issuesPath)) {
|
|
3140
3194
|
return [];
|
|
3141
3195
|
}
|
|
3142
3196
|
const records = [];
|
|
3143
|
-
for (const line of
|
|
3197
|
+
for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
3144
3198
|
const trimmed = line.trim();
|
|
3145
3199
|
if (!trimmed) {
|
|
3146
3200
|
continue;
|
|
@@ -3196,19 +3250,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
3196
3250
|
if (!sourcePath) {
|
|
3197
3251
|
return {};
|
|
3198
3252
|
}
|
|
3199
|
-
const directory =
|
|
3200
|
-
if (!
|
|
3253
|
+
const directory = resolve19(projectRoot, sourcePath);
|
|
3254
|
+
if (!existsSync19(directory)) {
|
|
3201
3255
|
return {};
|
|
3202
3256
|
}
|
|
3203
3257
|
const config = {};
|
|
3204
|
-
for (const name of
|
|
3258
|
+
for (const name of readdirSync3(directory)) {
|
|
3205
3259
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
3206
3260
|
continue;
|
|
3207
|
-
const file =
|
|
3261
|
+
const file = resolve19(directory, name);
|
|
3208
3262
|
try {
|
|
3209
3263
|
if (!statSync4(file).isFile())
|
|
3210
3264
|
continue;
|
|
3211
|
-
const raw = JSON.parse(
|
|
3265
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
3212
3266
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
3213
3267
|
continue;
|
|
3214
3268
|
const record = raw;
|
|
@@ -3250,10 +3304,10 @@ function firstStringList2(...candidates) {
|
|
|
3250
3304
|
return [];
|
|
3251
3305
|
}
|
|
3252
3306
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
3253
|
-
const jsonPath =
|
|
3254
|
-
if (
|
|
3307
|
+
const jsonPath = resolve19(projectRoot, "rig.config.json");
|
|
3308
|
+
if (existsSync19(jsonPath)) {
|
|
3255
3309
|
try {
|
|
3256
|
-
const parsed = JSON.parse(
|
|
3310
|
+
const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
|
|
3257
3311
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3258
3312
|
const taskSource = parsed.taskSource;
|
|
3259
3313
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -3265,12 +3319,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3265
3319
|
return null;
|
|
3266
3320
|
}
|
|
3267
3321
|
}
|
|
3268
|
-
const tsPath =
|
|
3269
|
-
if (!
|
|
3322
|
+
const tsPath = resolve19(projectRoot, "rig.config.ts");
|
|
3323
|
+
if (!existsSync19(tsPath)) {
|
|
3270
3324
|
return null;
|
|
3271
3325
|
}
|
|
3272
3326
|
try {
|
|
3273
|
-
const source =
|
|
3327
|
+
const source = readFileSync10(tsPath, "utf8");
|
|
3274
3328
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3275
3329
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3276
3330
|
if (kind !== "files") {
|
|
@@ -3284,9 +3338,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3284
3338
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
3285
3339
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
3286
3340
|
return [
|
|
3287
|
-
runtimeContext?.monorepoMainRoot ?
|
|
3288
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
3289
|
-
|
|
3341
|
+
runtimeContext?.monorepoMainRoot ? resolve19(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
3342
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve19(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
3343
|
+
resolve19(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
3290
3344
|
].filter(Boolean);
|
|
3291
3345
|
}
|
|
3292
3346
|
|
|
@@ -3295,8 +3349,8 @@ init_layout();
|
|
|
3295
3349
|
|
|
3296
3350
|
// packages/runtime/src/binary-run.ts
|
|
3297
3351
|
init_layout();
|
|
3298
|
-
import { chmodSync as chmodSync4, cpSync, existsSync as
|
|
3299
|
-
import { basename as basename7, dirname as dirname9, resolve as
|
|
3352
|
+
import { chmodSync as chmodSync4, cpSync, existsSync as existsSync20, mkdirSync as mkdirSync8, renameSync as renameSync3, rmSync as rmSync7, writeFileSync as writeFileSync7 } from "fs";
|
|
3353
|
+
import { basename as basename7, dirname as dirname9, resolve as resolve20 } from "path";
|
|
3300
3354
|
import { fileURLToPath } from "url";
|
|
3301
3355
|
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
3302
3356
|
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
@@ -3322,9 +3376,9 @@ async function buildRuntimeBinary(options) {
|
|
|
3322
3376
|
});
|
|
3323
3377
|
}
|
|
3324
3378
|
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
3325
|
-
const tempBuildDir =
|
|
3326
|
-
const tempOutputPath =
|
|
3327
|
-
|
|
3379
|
+
const tempBuildDir = resolve20(dirname9(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
3380
|
+
const tempOutputPath = resolve20(tempBuildDir, basename7(options.outputPath));
|
|
3381
|
+
mkdirSync8(tempBuildDir, { recursive: true });
|
|
3328
3382
|
await withTemporaryEnv({
|
|
3329
3383
|
...options.env,
|
|
3330
3384
|
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
@@ -3349,7 +3403,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
3349
3403
|
`);
|
|
3350
3404
|
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
3351
3405
|
}
|
|
3352
|
-
if (!
|
|
3406
|
+
if (!existsSync20(tempOutputPath)) {
|
|
3353
3407
|
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
3354
3408
|
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
3355
3409
|
}
|
|
@@ -3364,7 +3418,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
|
3364
3418
|
});
|
|
3365
3419
|
}
|
|
3366
3420
|
})).finally(() => {
|
|
3367
|
-
|
|
3421
|
+
rmSync7(tempBuildDir, { recursive: true, force: true });
|
|
3368
3422
|
});
|
|
3369
3423
|
}
|
|
3370
3424
|
function runBestEffortBuildGc() {
|
|
@@ -3381,8 +3435,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
|
|
|
3381
3435
|
function resolveRuntimeBinaryBuildOptions(options) {
|
|
3382
3436
|
return {
|
|
3383
3437
|
...options,
|
|
3384
|
-
entrypoint:
|
|
3385
|
-
outputPath:
|
|
3438
|
+
entrypoint: resolve20(options.cwd, options.sourcePath),
|
|
3439
|
+
outputPath: resolve20(options.outputPath)
|
|
3386
3440
|
};
|
|
3387
3441
|
}
|
|
3388
3442
|
function shouldUseRuntimeBinaryBuildWorker() {
|
|
@@ -3396,7 +3450,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
|
|
|
3396
3450
|
}
|
|
3397
3451
|
async function buildRuntimeBinaryViaWorker(options) {
|
|
3398
3452
|
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
3399
|
-
if (!workerSourcePath || !
|
|
3453
|
+
if (!workerSourcePath || !existsSync20(workerSourcePath)) {
|
|
3400
3454
|
await buildRuntimeBinaryInProcess(options, {
|
|
3401
3455
|
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
3402
3456
|
buildKey: createRuntimeBinaryBuildKey({
|
|
@@ -3427,13 +3481,13 @@ async function buildRuntimeBinaryViaWorker(options) {
|
|
|
3427
3481
|
new Response(build.stdout).text(),
|
|
3428
3482
|
new Response(build.stderr).text()
|
|
3429
3483
|
]);
|
|
3430
|
-
|
|
3484
|
+
rmSync7(payloadPath, { force: true });
|
|
3431
3485
|
if (exitCode !== 0) {
|
|
3432
3486
|
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
3433
3487
|
}
|
|
3434
3488
|
}
|
|
3435
3489
|
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
3436
|
-
return
|
|
3490
|
+
return resolve20(dirname9(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
3437
3491
|
}
|
|
3438
3492
|
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
3439
3493
|
const envRoots = [
|
|
@@ -3442,13 +3496,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
|
3442
3496
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
3443
3497
|
].filter(Boolean);
|
|
3444
3498
|
for (const root of envRoots) {
|
|
3445
|
-
const candidate =
|
|
3446
|
-
if (
|
|
3499
|
+
const candidate = resolve20(root, "packages/runtime/src/binary-build-worker.ts");
|
|
3500
|
+
if (existsSync20(candidate)) {
|
|
3447
3501
|
return candidate;
|
|
3448
3502
|
}
|
|
3449
3503
|
}
|
|
3450
|
-
const localCandidate =
|
|
3451
|
-
return
|
|
3504
|
+
const localCandidate = resolve20(import.meta.dir, "binary-build-worker.ts");
|
|
3505
|
+
return existsSync20(localCandidate) ? localCandidate : null;
|
|
3452
3506
|
}
|
|
3453
3507
|
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
3454
3508
|
const bunPath = Bun.which("bun");
|
|
@@ -3484,7 +3538,7 @@ function createRuntimeBinaryBuildKey(input) {
|
|
|
3484
3538
|
});
|
|
3485
3539
|
}
|
|
3486
3540
|
async function isRuntimeBinaryBuildFresh(input) {
|
|
3487
|
-
if (!
|
|
3541
|
+
if (!existsSync20(input.outputPath) || !existsSync20(input.manifestPath)) {
|
|
3488
3542
|
return false;
|
|
3489
3543
|
}
|
|
3490
3544
|
let manifest = null;
|
|
@@ -3497,7 +3551,7 @@ async function isRuntimeBinaryBuildFresh(input) {
|
|
|
3497
3551
|
return false;
|
|
3498
3552
|
}
|
|
3499
3553
|
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
3500
|
-
if (!
|
|
3554
|
+
if (!existsSync20(filePath)) {
|
|
3501
3555
|
return false;
|
|
3502
3556
|
}
|
|
3503
3557
|
if (await sha256File4(filePath) !== expectedDigest) {
|
|
@@ -3510,7 +3564,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
|
|
|
3510
3564
|
const inputs = {};
|
|
3511
3565
|
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
3512
3566
|
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
3513
|
-
if (!normalized || !
|
|
3567
|
+
if (!normalized || !existsSync20(normalized)) {
|
|
3514
3568
|
continue;
|
|
3515
3569
|
}
|
|
3516
3570
|
inputs[normalized] = await sha256File4(normalized);
|
|
@@ -3533,7 +3587,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
|
|
|
3533
3587
|
if (inputPath.startsWith("<")) {
|
|
3534
3588
|
return null;
|
|
3535
3589
|
}
|
|
3536
|
-
return
|
|
3590
|
+
return resolve20(cwd, inputPath);
|
|
3537
3591
|
}
|
|
3538
3592
|
async function sha256File4(path) {
|
|
3539
3593
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
@@ -3549,8 +3603,8 @@ function sortRecord(value) {
|
|
|
3549
3603
|
async function runSerializedRuntimeBinaryBuild(action) {
|
|
3550
3604
|
const previous = runtimeBinaryBuildQueue;
|
|
3551
3605
|
let release;
|
|
3552
|
-
runtimeBinaryBuildQueue = new Promise((
|
|
3553
|
-
release =
|
|
3606
|
+
runtimeBinaryBuildQueue = new Promise((resolve21) => {
|
|
3607
|
+
release = resolve21;
|
|
3554
3608
|
});
|
|
3555
3609
|
await previous;
|
|
3556
3610
|
try {
|
|
@@ -3595,11 +3649,11 @@ async function withTemporaryCwd(cwd, action) {
|
|
|
3595
3649
|
}
|
|
3596
3650
|
|
|
3597
3651
|
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
3598
|
-
import { delimiter, resolve as
|
|
3652
|
+
import { delimiter, resolve as resolve22 } from "path";
|
|
3599
3653
|
|
|
3600
3654
|
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
3601
|
-
import { existsSync as
|
|
3602
|
-
import { resolve as
|
|
3655
|
+
import { existsSync as existsSync21, readdirSync as readdirSync4, realpathSync } from "fs";
|
|
3656
|
+
import { resolve as resolve21 } from "path";
|
|
3603
3657
|
|
|
3604
3658
|
// packages/runtime/src/control-plane/runtime/sandbox-utils.ts
|
|
3605
3659
|
init_utils();
|
|
@@ -3616,7 +3670,7 @@ function resolveBunBinaryPath() {
|
|
|
3616
3670
|
}
|
|
3617
3671
|
const home = process.env.HOME?.trim();
|
|
3618
3672
|
const fallbackCandidates = [
|
|
3619
|
-
home ?
|
|
3673
|
+
home ? resolve21(home, ".bun/bin/bun") : "",
|
|
3620
3674
|
"/opt/homebrew/bin/bun",
|
|
3621
3675
|
"/usr/local/bin/bun",
|
|
3622
3676
|
"/usr/bin/bun"
|
|
@@ -3644,8 +3698,8 @@ function resolveClaudeBinaryPath() {
|
|
|
3644
3698
|
}
|
|
3645
3699
|
const home = process.env.HOME?.trim();
|
|
3646
3700
|
const fallbackCandidates = [
|
|
3647
|
-
home ?
|
|
3648
|
-
home ?
|
|
3701
|
+
home ? resolve21(home, ".local/bin/claude") : "",
|
|
3702
|
+
home ? resolve21(home, ".local/share/claude/local/claude") : "",
|
|
3649
3703
|
"/opt/homebrew/bin/claude",
|
|
3650
3704
|
"/usr/local/bin/claude",
|
|
3651
3705
|
"/usr/bin/claude"
|
|
@@ -3659,51 +3713,51 @@ function resolveClaudeBinaryPath() {
|
|
|
3659
3713
|
throw new Error("claude not found in PATH");
|
|
3660
3714
|
}
|
|
3661
3715
|
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
3662
|
-
return
|
|
3716
|
+
return resolve21(bunBinaryPath, "../..");
|
|
3663
3717
|
}
|
|
3664
3718
|
function resolveClaudeInstallDir() {
|
|
3665
3719
|
const realPath = resolveClaudeBinaryPath();
|
|
3666
|
-
return
|
|
3720
|
+
return resolve21(realPath, "..");
|
|
3667
3721
|
}
|
|
3668
3722
|
function resolveNodeInstallDir() {
|
|
3669
3723
|
const preferredNode = resolvePreferredNodeBinary();
|
|
3670
3724
|
if (!preferredNode)
|
|
3671
3725
|
return null;
|
|
3672
3726
|
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
3673
|
-
if (explicitNode &&
|
|
3674
|
-
return preferredNode.endsWith("/bin/node") ?
|
|
3727
|
+
if (explicitNode && resolve21(explicitNode) === resolve21(preferredNode)) {
|
|
3728
|
+
return preferredNode.endsWith("/bin/node") ? resolve21(preferredNode, "../..") : resolve21(preferredNode, "..");
|
|
3675
3729
|
}
|
|
3676
3730
|
try {
|
|
3677
3731
|
const realPath = realpathSync(preferredNode);
|
|
3678
3732
|
if (realPath.endsWith("/bin/node")) {
|
|
3679
|
-
return
|
|
3733
|
+
return resolve21(realPath, "../..");
|
|
3680
3734
|
}
|
|
3681
|
-
return
|
|
3735
|
+
return resolve21(realPath, "..");
|
|
3682
3736
|
} catch {
|
|
3683
|
-
return
|
|
3737
|
+
return resolve21(preferredNode, "..");
|
|
3684
3738
|
}
|
|
3685
3739
|
}
|
|
3686
3740
|
function resolvePreferredNodeBinary() {
|
|
3687
3741
|
const candidates = [];
|
|
3688
3742
|
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
3689
3743
|
if (envNode) {
|
|
3690
|
-
const explicit =
|
|
3691
|
-
if (
|
|
3744
|
+
const explicit = resolve21(envNode);
|
|
3745
|
+
if (existsSync21(explicit)) {
|
|
3692
3746
|
return explicit;
|
|
3693
3747
|
}
|
|
3694
3748
|
}
|
|
3695
3749
|
const nvmBin = process.env.NVM_BIN?.trim();
|
|
3696
3750
|
if (nvmBin) {
|
|
3697
|
-
candidates.push(
|
|
3751
|
+
candidates.push(resolve21(nvmBin, "node"));
|
|
3698
3752
|
}
|
|
3699
3753
|
const home = process.env.HOME?.trim();
|
|
3700
3754
|
if (home) {
|
|
3701
|
-
const nvmVersionsDir =
|
|
3702
|
-
if (
|
|
3755
|
+
const nvmVersionsDir = resolve21(home, ".nvm/versions/node");
|
|
3756
|
+
if (existsSync21(nvmVersionsDir)) {
|
|
3703
3757
|
try {
|
|
3704
|
-
const versionDirs =
|
|
3758
|
+
const versionDirs = readdirSync4(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/, "")));
|
|
3705
3759
|
for (const versionDir of versionDirs) {
|
|
3706
|
-
candidates.push(
|
|
3760
|
+
candidates.push(resolve21(nvmVersionsDir, versionDir, "bin/node"));
|
|
3707
3761
|
}
|
|
3708
3762
|
} catch {}
|
|
3709
3763
|
}
|
|
@@ -3712,8 +3766,8 @@ function resolvePreferredNodeBinary() {
|
|
|
3712
3766
|
if (whichNode) {
|
|
3713
3767
|
candidates.push(whichNode);
|
|
3714
3768
|
}
|
|
3715
|
-
const deduped = uniq(candidates.map((candidate) =>
|
|
3716
|
-
const existing = deduped.filter((candidate) =>
|
|
3769
|
+
const deduped = uniq(candidates.map((candidate) => resolve21(candidate)));
|
|
3770
|
+
const existing = deduped.filter((candidate) => existsSync21(candidate));
|
|
3717
3771
|
if (existing.length === 0) {
|
|
3718
3772
|
return null;
|
|
3719
3773
|
}
|
|
@@ -3727,7 +3781,7 @@ function resolvePreferredNodeBinary() {
|
|
|
3727
3781
|
return existing[0] ?? null;
|
|
3728
3782
|
}
|
|
3729
3783
|
function inferNodeMajor(nodeBinaryPath) {
|
|
3730
|
-
const normalized =
|
|
3784
|
+
const normalized = resolve21(nodeBinaryPath).replace(/\\/g, "/");
|
|
3731
3785
|
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
3732
3786
|
if (!match) {
|
|
3733
3787
|
return null;
|
|
@@ -3739,8 +3793,8 @@ function normalizeExecutablePath(candidate) {
|
|
|
3739
3793
|
if (!candidate) {
|
|
3740
3794
|
return "";
|
|
3741
3795
|
}
|
|
3742
|
-
const normalized =
|
|
3743
|
-
if (!
|
|
3796
|
+
const normalized = resolve21(candidate);
|
|
3797
|
+
if (!existsSync21(normalized)) {
|
|
3744
3798
|
return "";
|
|
3745
3799
|
}
|
|
3746
3800
|
try {
|
|
@@ -3750,7 +3804,7 @@ function normalizeExecutablePath(candidate) {
|
|
|
3750
3804
|
}
|
|
3751
3805
|
}
|
|
3752
3806
|
function looksLikeRuntimeGateway(candidate) {
|
|
3753
|
-
const normalized =
|
|
3807
|
+
const normalized = resolve21(candidate).replace(/\\/g, "/");
|
|
3754
3808
|
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
3755
3809
|
}
|
|
3756
3810
|
|
|
@@ -3771,7 +3825,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
3771
3825
|
try {
|
|
3772
3826
|
return resolveClaudeInstallDir();
|
|
3773
3827
|
} catch {
|
|
3774
|
-
return
|
|
3828
|
+
return resolve22(claudeBinary, "..");
|
|
3775
3829
|
}
|
|
3776
3830
|
})() : "";
|
|
3777
3831
|
const nodeDir = resolveNodeInstallDir();
|
|
@@ -3781,8 +3835,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
|
3781
3835
|
`${bunDir}/bin`,
|
|
3782
3836
|
claudeDir,
|
|
3783
3837
|
nodeDir ? `${nodeDir}/bin` : "",
|
|
3784
|
-
realHome ?
|
|
3785
|
-
realHome ?
|
|
3838
|
+
realHome ? resolve22(realHome, ".local/bin") : "",
|
|
3839
|
+
realHome ? resolve22(realHome, ".cargo/bin") : "",
|
|
3786
3840
|
...inheritedPath,
|
|
3787
3841
|
"/usr/local/bin",
|
|
3788
3842
|
"/usr/local/sbin",
|
|
@@ -4091,16 +4145,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
4091
4145
|
for (const dep of deps) {
|
|
4092
4146
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
4093
4147
|
console.log(`=== ${dep} ===`);
|
|
4094
|
-
if (!
|
|
4148
|
+
if (!existsSync22(artifactDir)) {
|
|
4095
4149
|
console.log(` (no artifacts yet)
|
|
4096
4150
|
`);
|
|
4097
4151
|
continue;
|
|
4098
4152
|
}
|
|
4099
|
-
printArtifactSection(
|
|
4100
|
-
printArtifactSection(
|
|
4101
|
-
const changedFiles =
|
|
4102
|
-
if (
|
|
4103
|
-
const lines =
|
|
4153
|
+
printArtifactSection(resolve23(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
4154
|
+
printArtifactSection(resolve23(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
4155
|
+
const changedFiles = resolve23(artifactDir, "changed-files.txt");
|
|
4156
|
+
if (existsSync22(changedFiles)) {
|
|
4157
|
+
const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
4104
4158
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
4105
4159
|
for (const line of lines) {
|
|
4106
4160
|
console.log(line);
|
|
@@ -4224,12 +4278,12 @@ function printIndented(text) {
|
|
|
4224
4278
|
}
|
|
4225
4279
|
}
|
|
4226
4280
|
function readLocalBeadsTasks(projectRoot) {
|
|
4227
|
-
const issuesPath =
|
|
4228
|
-
if (!
|
|
4281
|
+
const issuesPath = resolve23(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
4282
|
+
if (!existsSync22(issuesPath)) {
|
|
4229
4283
|
return [];
|
|
4230
4284
|
}
|
|
4231
4285
|
const tasks = [];
|
|
4232
|
-
for (const line of
|
|
4286
|
+
for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
4233
4287
|
const trimmed = line.trim();
|
|
4234
4288
|
if (!trimmed) {
|
|
4235
4289
|
continue;
|
|
@@ -4342,11 +4396,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
4342
4396
|
return [...ids].sort();
|
|
4343
4397
|
}
|
|
4344
4398
|
function printArtifactSection(path, header) {
|
|
4345
|
-
if (!
|
|
4399
|
+
if (!existsSync22(path)) {
|
|
4346
4400
|
return;
|
|
4347
4401
|
}
|
|
4348
4402
|
console.log(header);
|
|
4349
|
-
process.stdout.write(
|
|
4403
|
+
process.stdout.write(readFileSync11(path, "utf-8"));
|
|
4350
4404
|
console.log("");
|
|
4351
4405
|
}
|
|
4352
4406
|
|
|
@@ -4366,8 +4420,8 @@ function isRuntimeGatewayGitPath(candidate) {
|
|
|
4366
4420
|
}
|
|
4367
4421
|
function resolveOptionalMonorepoRoot(projectRoot) {
|
|
4368
4422
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
4369
|
-
if (runtimeWorkspace &&
|
|
4370
|
-
return
|
|
4423
|
+
if (runtimeWorkspace && existsSync23(resolve24(runtimeWorkspace, ".git"))) {
|
|
4424
|
+
return resolve24(runtimeWorkspace);
|
|
4371
4425
|
}
|
|
4372
4426
|
try {
|
|
4373
4427
|
return resolveMonorepoRoot2(projectRoot);
|
|
@@ -4392,7 +4446,7 @@ function resolveGitBinary(projectRoot) {
|
|
|
4392
4446
|
if (!candidate || isRuntimeGatewayGitPath(candidate)) {
|
|
4393
4447
|
continue;
|
|
4394
4448
|
}
|
|
4395
|
-
if (
|
|
4449
|
+
if (existsSync23(candidate)) {
|
|
4396
4450
|
return candidate;
|
|
4397
4451
|
}
|
|
4398
4452
|
}
|
|
@@ -4416,7 +4470,7 @@ function gitSyncBranch(projectRoot, taskId, targetRepo = "monorepo") {
|
|
|
4416
4470
|
}
|
|
4417
4471
|
const repoRoot = targetRepo === "monorepo" ? resolveOptionalMonorepoRoot(projectRoot) || resolveMonorepoRoot2(projectRoot) : projectRoot;
|
|
4418
4472
|
const repoLabel = targetRepo === "monorepo" ? "Monorepo" : "Project";
|
|
4419
|
-
if (!
|
|
4473
|
+
if (!existsSync23(resolve24(repoRoot, ".git"))) {
|
|
4420
4474
|
throw new Error(`${repoLabel} repo not found at ${repoRoot}`);
|
|
4421
4475
|
}
|
|
4422
4476
|
const branchId = resolveTaskBranchId(projectRoot, resolvedTask);
|
|
@@ -4458,7 +4512,7 @@ function resolveTaskBranchId(projectRoot, taskId) {
|
|
|
4458
4512
|
}
|
|
4459
4513
|
} catch {}
|
|
4460
4514
|
const artifactDir = artifactDirForId(projectRoot, taskId);
|
|
4461
|
-
if (
|
|
4515
|
+
if (existsSync23(artifactDir)) {
|
|
4462
4516
|
return taskId;
|
|
4463
4517
|
}
|
|
4464
4518
|
throw new Error(`Unknown task id: ${taskId}`);
|
|
@@ -4475,11 +4529,11 @@ function runCapture2(command, cwd, projectRoot = cwd) {
|
|
|
4475
4529
|
}
|
|
4476
4530
|
function runtimeGitEnv(projectRoot) {
|
|
4477
4531
|
const { ctx, runtimeRoot } = resolveRuntimeMetadata(projectRoot);
|
|
4478
|
-
const runtimeHome = runtimeRoot ?
|
|
4479
|
-
const runtimeTmp = runtimeRoot ?
|
|
4480
|
-
const runtimeCache = runtimeRoot ?
|
|
4481
|
-
const runtimeKnownHosts = runtimeHome ?
|
|
4482
|
-
const runtimeKey = runtimeHome ?
|
|
4532
|
+
const runtimeHome = runtimeRoot ? resolve24(runtimeRoot, "home") : "";
|
|
4533
|
+
const runtimeTmp = runtimeRoot ? resolve24(runtimeRoot, "tmp") : "";
|
|
4534
|
+
const runtimeCache = runtimeRoot ? resolve24(runtimeRoot, "cache") : "";
|
|
4535
|
+
const runtimeKnownHosts = runtimeHome ? resolve24(runtimeHome, ".ssh", "known_hosts") : "";
|
|
4536
|
+
const runtimeKey = runtimeHome ? resolve24(runtimeHome, ".ssh", "rig-agent-key") : "";
|
|
4483
4537
|
const env = {};
|
|
4484
4538
|
if (ctx?.workspaceDir) {
|
|
4485
4539
|
env.PROJECT_RIG_ROOT = projectRoot;
|
|
@@ -4492,14 +4546,14 @@ function runtimeGitEnv(projectRoot) {
|
|
|
4492
4546
|
if (runtimeRoot) {
|
|
4493
4547
|
env.RIG_RUNTIME_HOME = runtimeRoot;
|
|
4494
4548
|
}
|
|
4495
|
-
if (runtimeHome &&
|
|
4549
|
+
if (runtimeHome && existsSync23(runtimeHome)) {
|
|
4496
4550
|
env.HOME = runtimeHome;
|
|
4497
4551
|
env.OPENSSL_CONF = ensureRuntimeOpenSslConfig(runtimeHome);
|
|
4498
4552
|
}
|
|
4499
|
-
if (runtimeTmp &&
|
|
4553
|
+
if (runtimeTmp && existsSync23(runtimeTmp)) {
|
|
4500
4554
|
env.TMPDIR = runtimeTmp;
|
|
4501
4555
|
}
|
|
4502
|
-
if (runtimeCache &&
|
|
4556
|
+
if (runtimeCache && existsSync23(runtimeCache)) {
|
|
4503
4557
|
env.XDG_CACHE_HOME = runtimeCache;
|
|
4504
4558
|
}
|
|
4505
4559
|
const workspaceSecrets = loadDotEnvSecrets(ctx?.workspaceDir || projectRoot, process.env);
|
|
@@ -4543,14 +4597,14 @@ function runtimeGitEnv(projectRoot) {
|
|
|
4543
4597
|
env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
|
|
4544
4598
|
applyGitHubCredentialHelperEnv(env);
|
|
4545
4599
|
}
|
|
4546
|
-
if (runtimeKnownHosts &&
|
|
4600
|
+
if (runtimeKnownHosts && existsSync23(runtimeKnownHosts)) {
|
|
4547
4601
|
const sshParts = [
|
|
4548
4602
|
"ssh",
|
|
4549
4603
|
`-o UserKnownHostsFile="${runtimeKnownHosts}"`,
|
|
4550
4604
|
"-o StrictHostKeyChecking=yes",
|
|
4551
4605
|
"-F /dev/null"
|
|
4552
4606
|
];
|
|
4553
|
-
if (runtimeKey &&
|
|
4607
|
+
if (runtimeKey && existsSync23(runtimeKey)) {
|
|
4554
4608
|
sshParts.splice(1, 0, `-i "${runtimeKey}"`, "-o IdentitiesOnly=yes");
|
|
4555
4609
|
}
|
|
4556
4610
|
env.GIT_SSH_COMMAND = sshParts.join(" ");
|
|
@@ -4571,12 +4625,12 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
|
|
|
4571
4625
|
if (!runtimeRoot) {
|
|
4572
4626
|
return {};
|
|
4573
4627
|
}
|
|
4574
|
-
const path =
|
|
4575
|
-
if (!
|
|
4628
|
+
const path = resolve24(runtimeRoot, "runtime-secrets.json");
|
|
4629
|
+
if (!existsSync23(path)) {
|
|
4576
4630
|
return {};
|
|
4577
4631
|
}
|
|
4578
4632
|
try {
|
|
4579
|
-
const parsed = JSON.parse(
|
|
4633
|
+
const parsed = JSON.parse(readFileSync12(path, "utf-8"));
|
|
4580
4634
|
const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string");
|
|
4581
4635
|
return Object.fromEntries(entries);
|
|
4582
4636
|
} catch {
|
|
@@ -4584,13 +4638,13 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
|
|
|
4584
4638
|
}
|
|
4585
4639
|
}
|
|
4586
4640
|
function ensureRuntimeOpenSslConfig(runtimeHome) {
|
|
4587
|
-
const sslDir =
|
|
4588
|
-
const sslConfig =
|
|
4589
|
-
if (!
|
|
4590
|
-
|
|
4641
|
+
const sslDir = resolve24(runtimeHome, ".ssl");
|
|
4642
|
+
const sslConfig = resolve24(sslDir, "openssl.cnf");
|
|
4643
|
+
if (!existsSync23(sslDir)) {
|
|
4644
|
+
mkdirSync10(sslDir, { recursive: true });
|
|
4591
4645
|
}
|
|
4592
|
-
if (!
|
|
4593
|
-
|
|
4646
|
+
if (!existsSync23(sslConfig)) {
|
|
4647
|
+
writeFileSync9(sslConfig, `# Rig runtime OpenSSL config placeholder
|
|
4594
4648
|
`);
|
|
4595
4649
|
}
|
|
4596
4650
|
return sslConfig;
|
|
@@ -4608,11 +4662,11 @@ function resolveRuntimeMetadata(projectRoot) {
|
|
|
4608
4662
|
if (contextFile) {
|
|
4609
4663
|
return {
|
|
4610
4664
|
ctx,
|
|
4611
|
-
runtimeRoot: dirname10(
|
|
4665
|
+
runtimeRoot: dirname10(resolve24(contextFile))
|
|
4612
4666
|
};
|
|
4613
4667
|
}
|
|
4614
4668
|
const inferredContextFile = findRuntimeContextFile2(projectRoot);
|
|
4615
|
-
if (
|
|
4669
|
+
if (existsSync23(inferredContextFile)) {
|
|
4616
4670
|
try {
|
|
4617
4671
|
ctx = loadRuntimeContext(inferredContextFile);
|
|
4618
4672
|
} catch {}
|
|
@@ -4624,10 +4678,10 @@ function resolveRuntimeMetadata(projectRoot) {
|
|
|
4624
4678
|
return { ctx, runtimeRoot: "" };
|
|
4625
4679
|
}
|
|
4626
4680
|
function findRuntimeContextFile2(startPath) {
|
|
4627
|
-
let current =
|
|
4681
|
+
let current = resolve24(startPath);
|
|
4628
4682
|
while (true) {
|
|
4629
|
-
const candidate =
|
|
4630
|
-
if (
|
|
4683
|
+
const candidate = resolve24(current, "runtime-context.json");
|
|
4684
|
+
if (existsSync23(candidate)) {
|
|
4631
4685
|
return candidate;
|
|
4632
4686
|
}
|
|
4633
4687
|
const parent = dirname10(current);
|
|
@@ -4639,45 +4693,45 @@ function findRuntimeContextFile2(startPath) {
|
|
|
4639
4693
|
}
|
|
4640
4694
|
|
|
4641
4695
|
// packages/runtime/src/control-plane/native/repo-ops.ts
|
|
4642
|
-
import { existsSync as
|
|
4643
|
-
import { basename as basename8, dirname as dirname12, resolve as
|
|
4696
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync14, readFileSync as readFileSync14, readdirSync as readdirSync6, rmSync as rmSync9, writeFileSync as writeFileSync11 } from "fs";
|
|
4697
|
+
import { basename as basename8, dirname as dirname12, resolve as resolve28 } from "path";
|
|
4644
4698
|
// packages/runtime/src/control-plane/repos/mirror/bootstrap.ts
|
|
4645
|
-
import { existsSync as
|
|
4646
|
-
import { resolve as
|
|
4699
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync12, realpathSync as realpathSync2 } from "fs";
|
|
4700
|
+
import { resolve as resolve26 } from "path";
|
|
4647
4701
|
|
|
4648
4702
|
// packages/runtime/src/control-plane/authority-files.ts
|
|
4649
|
-
import { existsSync as
|
|
4650
|
-
import { dirname as dirname11, join as join4, relative, resolve as
|
|
4703
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync10, appendFileSync as appendFileSync2, copyFileSync as copyFileSync5, statSync as statSync5, readdirSync as readdirSync5, chmodSync as chmodSync5 } from "fs";
|
|
4704
|
+
import { dirname as dirname11, join as join4, relative, resolve as resolve25 } from "path";
|
|
4651
4705
|
init_layout();
|
|
4652
4706
|
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
|
4653
4707
|
function resolveAuthorityProjectStateDir(projectRoot) {
|
|
4654
4708
|
const explicit = process.env.RIG_STATE_DIR?.trim();
|
|
4655
4709
|
if (explicit) {
|
|
4656
|
-
return
|
|
4710
|
+
return resolve25(explicit);
|
|
4657
4711
|
}
|
|
4658
|
-
return
|
|
4712
|
+
return resolve25(resolve25(projectRoot), ".rig", "state");
|
|
4659
4713
|
}
|
|
4660
4714
|
function readJsonAtPath(path, fallback) {
|
|
4661
|
-
if (!
|
|
4715
|
+
if (!existsSync24(path)) {
|
|
4662
4716
|
return fallback;
|
|
4663
4717
|
}
|
|
4664
4718
|
try {
|
|
4665
|
-
return JSON.parse(
|
|
4719
|
+
return JSON.parse(readFileSync13(path, "utf-8"));
|
|
4666
4720
|
} catch {
|
|
4667
4721
|
return fallback;
|
|
4668
4722
|
}
|
|
4669
4723
|
}
|
|
4670
4724
|
function writeJsonAtPath(path, value) {
|
|
4671
|
-
|
|
4672
|
-
|
|
4725
|
+
mkdirSync11(dirname11(path), { recursive: true });
|
|
4726
|
+
writeFileSync10(path, `${JSON.stringify(value, null, 2)}
|
|
4673
4727
|
`, "utf8");
|
|
4674
4728
|
return path;
|
|
4675
4729
|
}
|
|
4676
4730
|
function readAuthorityProjectStateJson(projectRoot, relativePath, fallback) {
|
|
4677
|
-
return readJsonAtPath(
|
|
4731
|
+
return readJsonAtPath(resolve25(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
|
|
4678
4732
|
}
|
|
4679
4733
|
function writeAuthorityProjectStateJson(projectRoot, relativePath, value) {
|
|
4680
|
-
return writeJsonAtPath(
|
|
4734
|
+
return writeJsonAtPath(resolve25(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
|
|
4681
4735
|
}
|
|
4682
4736
|
|
|
4683
4737
|
// packages/runtime/src/control-plane/repos/mirror/state.ts
|
|
@@ -4737,7 +4791,7 @@ function sameExistingPath(left, right) {
|
|
|
4737
4791
|
try {
|
|
4738
4792
|
return realpathSync2(left) === realpathSync2(right);
|
|
4739
4793
|
} catch {
|
|
4740
|
-
return
|
|
4794
|
+
return resolve26(left) === resolve26(right);
|
|
4741
4795
|
}
|
|
4742
4796
|
}
|
|
4743
4797
|
function repoLooksUsable(repoRoot, projectRoot) {
|
|
@@ -4773,7 +4827,7 @@ function resolveMirrorRemoteUrl(layout) {
|
|
|
4773
4827
|
}
|
|
4774
4828
|
}
|
|
4775
4829
|
}
|
|
4776
|
-
if (
|
|
4830
|
+
if (existsSync25(resolve26(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
|
|
4777
4831
|
const checkoutOrigin = runGit(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
|
|
4778
4832
|
if (checkoutOrigin.exitCode === 0) {
|
|
4779
4833
|
const currentOrigin = checkoutOrigin.stdout.trim();
|
|
@@ -4786,9 +4840,9 @@ function resolveMirrorRemoteUrl(layout) {
|
|
|
4786
4840
|
}
|
|
4787
4841
|
function ensureManagedRepoMirror(projectRoot, repoId) {
|
|
4788
4842
|
const layout = resolveManagedRepoLayout(projectRoot, repoId);
|
|
4789
|
-
|
|
4843
|
+
mkdirSync12(layout.metadataRoot, { recursive: true });
|
|
4790
4844
|
const remoteUrl = resolveMirrorRemoteUrl(layout);
|
|
4791
|
-
if (!
|
|
4845
|
+
if (!existsSync25(resolve26(layout.mirrorRoot, "HEAD"))) {
|
|
4792
4846
|
ensureGitSuccess(runGit(["git", "init", "--bare", layout.mirrorRoot], layout.projectRoot), ["git", "init", "--bare", layout.mirrorRoot]);
|
|
4793
4847
|
}
|
|
4794
4848
|
const getOrigin = runGit(["git", "--git-dir", layout.mirrorRoot, "remote", "get-url", "origin"], layout.projectRoot);
|
|
@@ -4808,8 +4862,8 @@ function ensureManagedRepoMirror(projectRoot, repoId) {
|
|
|
4808
4862
|
return layout;
|
|
4809
4863
|
}
|
|
4810
4864
|
// packages/runtime/src/control-plane/repos/mirror/refresh.ts
|
|
4811
|
-
import { existsSync as
|
|
4812
|
-
import { resolve as
|
|
4865
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync13, realpathSync as realpathSync3, rmSync as rmSync8 } from "fs";
|
|
4866
|
+
import { resolve as resolve27 } from "path";
|
|
4813
4867
|
function nowIso3() {
|
|
4814
4868
|
return new Date().toISOString();
|
|
4815
4869
|
}
|
|
@@ -4836,7 +4890,7 @@ function sameExistingPath2(left, right) {
|
|
|
4836
4890
|
try {
|
|
4837
4891
|
return realpathSync3(left) === realpathSync3(right);
|
|
4838
4892
|
} catch {
|
|
4839
|
-
return
|
|
4893
|
+
return resolve27(left) === resolve27(right);
|
|
4840
4894
|
}
|
|
4841
4895
|
}
|
|
4842
4896
|
function ensureMirrorHead(layout) {
|
|
@@ -4882,12 +4936,12 @@ function checkoutLooksUsable2(layout) {
|
|
|
4882
4936
|
return probe.exitCode === 0 && sameExistingPath2(probe.stdout.trim(), layout.checkoutRoot);
|
|
4883
4937
|
}
|
|
4884
4938
|
function ensureCheckoutFromMirror(layout) {
|
|
4885
|
-
|
|
4886
|
-
const gitPath =
|
|
4887
|
-
if (
|
|
4888
|
-
|
|
4939
|
+
mkdirSync13(resolve27(layout.checkoutRoot, ".."), { recursive: true });
|
|
4940
|
+
const gitPath = resolve27(layout.checkoutRoot, ".git");
|
|
4941
|
+
if (existsSync26(layout.checkoutRoot) && (!existsSync26(gitPath) || !checkoutLooksUsable2(layout))) {
|
|
4942
|
+
rmSync8(layout.checkoutRoot, { recursive: true, force: true });
|
|
4889
4943
|
}
|
|
4890
|
-
if (!
|
|
4944
|
+
if (!existsSync26(gitPath)) {
|
|
4891
4945
|
ensureGitSuccess2(runGit2(["git", "clone", layout.mirrorRoot, layout.checkoutRoot], layout.projectRoot), ["git", "clone", layout.mirrorRoot, layout.checkoutRoot]);
|
|
4892
4946
|
}
|
|
4893
4947
|
const getOrigin = runGit2(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
|
|
@@ -4961,7 +5015,7 @@ function repoEnsure(projectRoot, taskId) {
|
|
|
4961
5015
|
}
|
|
4962
5016
|
function repoBaseline(projectRoot, refresh = false) {
|
|
4963
5017
|
const paths = resolveRepoDiscoveryPaths(projectRoot);
|
|
4964
|
-
if (!refresh &&
|
|
5018
|
+
if (!refresh && existsSync27(paths.baseRepoPinsPath)) {
|
|
4965
5019
|
const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
|
|
4966
5020
|
return baseline.repos || {};
|
|
4967
5021
|
}
|
|
@@ -4985,8 +5039,8 @@ function ensureMonorepoReady(projectRoot) {
|
|
|
4985
5039
|
}
|
|
4986
5040
|
function persistBaselinePins(projectRoot, repos) {
|
|
4987
5041
|
const paths = resolveRepoDiscoveryPaths(projectRoot);
|
|
4988
|
-
|
|
4989
|
-
|
|
5042
|
+
mkdirSync14(resolve28(paths.baseRepoPinsPath, ".."), { recursive: true });
|
|
5043
|
+
writeFileSync11(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
|
|
4990
5044
|
`, "utf-8");
|
|
4991
5045
|
return repos;
|
|
4992
5046
|
}
|
|
@@ -5065,28 +5119,28 @@ function readRepoDiscoveryTaskConfig(projectRoot) {
|
|
|
5065
5119
|
function resolveRepoDiscoveryPaths(projectRoot) {
|
|
5066
5120
|
const monorepoRoot = resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
|
|
5067
5121
|
const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
|
|
5068
|
-
const normalizedProjectRoot =
|
|
5122
|
+
const normalizedProjectRoot = resolve28(projectRoot);
|
|
5069
5123
|
const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
|
|
5070
|
-
const stateDir =
|
|
5124
|
+
const stateDir = resolve28(hostProjectRoot, ".rig", "state");
|
|
5071
5125
|
return {
|
|
5072
5126
|
monorepoRoot,
|
|
5073
|
-
taskRepoCommitsPath:
|
|
5074
|
-
baseRepoPinsPath:
|
|
5127
|
+
taskRepoCommitsPath: resolve28(stateDir, "task-repo-commits.json"),
|
|
5128
|
+
baseRepoPinsPath: resolve28(stateDir, "base-repo-pins.json")
|
|
5075
5129
|
};
|
|
5076
5130
|
}
|
|
5077
5131
|
function shouldUseHostProjectStateRoot(projectRoot) {
|
|
5078
5132
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
5079
|
-
if (runtimeWorkspace &&
|
|
5133
|
+
if (runtimeWorkspace && resolve28(runtimeWorkspace) === projectRoot) {
|
|
5080
5134
|
return true;
|
|
5081
5135
|
}
|
|
5082
5136
|
return basename8(dirname12(projectRoot)) === ".worktrees";
|
|
5083
5137
|
}
|
|
5084
5138
|
function readPinFromArtifact(projectRoot, depTask, repoKey) {
|
|
5085
|
-
const snapshot =
|
|
5086
|
-
if (!
|
|
5139
|
+
const snapshot = resolve28(artifactDirForId(projectRoot, depTask), "git-state.txt");
|
|
5140
|
+
if (!existsSync27(snapshot)) {
|
|
5087
5141
|
return "";
|
|
5088
5142
|
}
|
|
5089
|
-
const content =
|
|
5143
|
+
const content = readFileSync14(snapshot, "utf-8");
|
|
5090
5144
|
const chunk = content.split(/\r?\n/);
|
|
5091
5145
|
let inSection = false;
|
|
5092
5146
|
for (const line of chunk) {
|
|
@@ -5108,12 +5162,12 @@ function repoPath(projectRoot, key) {
|
|
|
5108
5162
|
if (managed) {
|
|
5109
5163
|
return managed.checkoutRoot;
|
|
5110
5164
|
}
|
|
5111
|
-
return key.startsWith("/") ? key :
|
|
5165
|
+
return key.startsWith("/") ? key : resolve28(projectRoot, key);
|
|
5112
5166
|
}
|
|
5113
5167
|
function applyPins(projectRoot, pins) {
|
|
5114
5168
|
for (const [key, commit] of Object.entries(pins)) {
|
|
5115
5169
|
const path = repoPath(projectRoot, key);
|
|
5116
|
-
if (!
|
|
5170
|
+
if (!existsSync27(resolve28(path, ".git"))) {
|
|
5117
5171
|
throw new Error(`Repo for pin not available: ${key} (${path})`);
|
|
5118
5172
|
}
|
|
5119
5173
|
let hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
|
|
@@ -5142,7 +5196,7 @@ function verifyPins(projectRoot, pins) {
|
|
|
5142
5196
|
let ok = true;
|
|
5143
5197
|
for (const [key, expected] of Object.entries(pins)) {
|
|
5144
5198
|
const path = repoPath(projectRoot, key);
|
|
5145
|
-
if (!
|
|
5199
|
+
if (!existsSync27(resolve28(path, ".git"))) {
|
|
5146
5200
|
console.error(`ERROR: repo missing during pin verification: ${key}`);
|
|
5147
5201
|
ok = false;
|
|
5148
5202
|
continue;
|
|
@@ -5167,23 +5221,23 @@ function resolveRuntimeGitEnv() {
|
|
|
5167
5221
|
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND
|
|
5168
5222
|
};
|
|
5169
5223
|
}
|
|
5170
|
-
const runtimeRoot = process.env.RIG_RUNTIME_HOME?.trim() || (process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() ?
|
|
5171
|
-
const runtimeHome = runtimeRoot ?
|
|
5224
|
+
const runtimeRoot = process.env.RIG_RUNTIME_HOME?.trim() || (process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() ? resolve28(process.env.RIG_RUNTIME_CONTEXT_FILE, "..") : inferRuntimeRootFromWorkspace(process.cwd()));
|
|
5225
|
+
const runtimeHome = runtimeRoot ? resolve28(runtimeRoot, "home") : process.env.HOME?.trim() || "";
|
|
5172
5226
|
if (!runtimeHome) {
|
|
5173
5227
|
return;
|
|
5174
5228
|
}
|
|
5175
|
-
const knownHostsPath =
|
|
5176
|
-
if (!
|
|
5229
|
+
const knownHostsPath = resolve28(runtimeHome, ".ssh", "known_hosts");
|
|
5230
|
+
if (!existsSync27(knownHostsPath)) {
|
|
5177
5231
|
return { HOME: runtimeHome };
|
|
5178
5232
|
}
|
|
5179
|
-
const agentSshKey =
|
|
5233
|
+
const agentSshKey = resolve28(runtimeHome, ".ssh", "rig-agent-key");
|
|
5180
5234
|
const sshParts = [
|
|
5181
5235
|
"ssh",
|
|
5182
5236
|
`-o UserKnownHostsFile="${knownHostsPath}"`,
|
|
5183
5237
|
"-o StrictHostKeyChecking=yes",
|
|
5184
5238
|
"-F /dev/null"
|
|
5185
5239
|
];
|
|
5186
|
-
if (
|
|
5240
|
+
if (existsSync27(agentSshKey)) {
|
|
5187
5241
|
sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
|
|
5188
5242
|
}
|
|
5189
5243
|
return {
|
|
@@ -5193,24 +5247,24 @@ function resolveRuntimeGitEnv() {
|
|
|
5193
5247
|
}
|
|
5194
5248
|
function inferRuntimeRootFromWorkspace(cwd) {
|
|
5195
5249
|
const contextPath = findRuntimeContextFile3(cwd);
|
|
5196
|
-
if (!contextPath || !
|
|
5250
|
+
if (!contextPath || !existsSync27(contextPath)) {
|
|
5197
5251
|
return "";
|
|
5198
5252
|
}
|
|
5199
5253
|
try {
|
|
5200
5254
|
loadRuntimeContext(contextPath);
|
|
5201
|
-
return
|
|
5255
|
+
return resolve28(contextPath, "..");
|
|
5202
5256
|
} catch {
|
|
5203
5257
|
return "";
|
|
5204
5258
|
}
|
|
5205
5259
|
}
|
|
5206
5260
|
function findRuntimeContextFile3(startPath) {
|
|
5207
|
-
let current =
|
|
5261
|
+
let current = resolve28(startPath);
|
|
5208
5262
|
while (true) {
|
|
5209
|
-
const candidate =
|
|
5210
|
-
if (
|
|
5263
|
+
const candidate = resolve28(current, "runtime-context.json");
|
|
5264
|
+
if (existsSync27(candidate)) {
|
|
5211
5265
|
return candidate;
|
|
5212
5266
|
}
|
|
5213
|
-
const parent =
|
|
5267
|
+
const parent = resolve28(current, "..");
|
|
5214
5268
|
if (parent === current) {
|
|
5215
5269
|
return "";
|
|
5216
5270
|
}
|
|
@@ -5219,12 +5273,12 @@ function findRuntimeContextFile3(startPath) {
|
|
|
5219
5273
|
}
|
|
5220
5274
|
|
|
5221
5275
|
// packages/runtime/src/control-plane/runtime/isolation/index.ts
|
|
5222
|
-
import { existsSync as
|
|
5276
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync22, readFileSync as readFileSync19, rmSync as rmSync14 } from "fs";
|
|
5223
5277
|
import { copyFile, mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
|
|
5224
|
-
import { resolve as
|
|
5278
|
+
import { resolve as resolve36 } from "path";
|
|
5225
5279
|
// packages/runtime/src/control-plane/memory-sync/db.ts
|
|
5226
5280
|
import { Database } from "bun:sqlite";
|
|
5227
|
-
import { mkdirSync as
|
|
5281
|
+
import { mkdirSync as mkdirSync15 } from "fs";
|
|
5228
5282
|
import { dirname as dirname13 } from "path";
|
|
5229
5283
|
var SCHEMA_STATEMENTS = [
|
|
5230
5284
|
`CREATE TABLE IF NOT EXISTS memory_events (
|
|
@@ -5438,7 +5492,7 @@ async function ensureSchema(db) {
|
|
|
5438
5492
|
await ensureColumns(db.client, "memory_items", MEMORY_ITEM_COLUMNS);
|
|
5439
5493
|
}
|
|
5440
5494
|
async function openMemoryDb(dbPath) {
|
|
5441
|
-
|
|
5495
|
+
mkdirSync15(dirname13(dbPath), { recursive: true });
|
|
5442
5496
|
const sqlite = new Database(dbPath, { create: true, strict: true });
|
|
5443
5497
|
const client = createMemoryDbClient(sqlite);
|
|
5444
5498
|
const db = {
|
|
@@ -5452,7 +5506,7 @@ async function openMemoryDb(dbPath) {
|
|
|
5452
5506
|
return db;
|
|
5453
5507
|
}
|
|
5454
5508
|
// packages/runtime/src/control-plane/memory-sync/read.ts
|
|
5455
|
-
import { mkdtempSync, rmSync as
|
|
5509
|
+
import { mkdtempSync, rmSync as rmSync10, writeFileSync as writeFileSync12 } from "fs";
|
|
5456
5510
|
import { tmpdir as tmpdir5 } from "os";
|
|
5457
5511
|
import { join as join5 } from "path";
|
|
5458
5512
|
var CANONICAL_MEMORY_DB_PATH = "rig/memory/project-memory.db";
|
|
@@ -5461,7 +5515,7 @@ var DEFAULT_READ_DEPS2 = {
|
|
|
5461
5515
|
readBlobBytesAtRef: nativeReadBlobBytesAtRef,
|
|
5462
5516
|
openMemoryDb,
|
|
5463
5517
|
makeTempDir: () => mkdtempSync(join5(tmpdir5(), "memory-sync-read-")),
|
|
5464
|
-
removeDir: (path) =>
|
|
5518
|
+
removeDir: (path) => rmSync10(path, { recursive: true, force: true })
|
|
5465
5519
|
};
|
|
5466
5520
|
function isMissingCanonicalMemoryBlobError(error) {
|
|
5467
5521
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -5481,7 +5535,7 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
|
|
|
5481
5535
|
try {
|
|
5482
5536
|
try {
|
|
5483
5537
|
const bytes = readDeps.readBlobBytesAtRef(repoPath2, baseOid, CANONICAL_MEMORY_DB_PATH);
|
|
5484
|
-
|
|
5538
|
+
writeFileSync12(dbPath, bytes);
|
|
5485
5539
|
} catch (error) {
|
|
5486
5540
|
if (!isMissingCanonicalMemoryBlobError(error)) {
|
|
5487
5541
|
throw error;
|
|
@@ -5606,7 +5660,7 @@ init_layout();
|
|
|
5606
5660
|
|
|
5607
5661
|
// packages/runtime/src/control-plane/runtime/overlay.ts
|
|
5608
5662
|
init_layout();
|
|
5609
|
-
import { mkdirSync as
|
|
5663
|
+
import { mkdirSync as mkdirSync16 } from "fs";
|
|
5610
5664
|
function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
5611
5665
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
|
|
5612
5666
|
const rootDir = layout.rigRoot;
|
|
@@ -5618,14 +5672,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
|
|
|
5618
5672
|
const sessionDir = layout.sessionDir;
|
|
5619
5673
|
const runtimeDir = layout.runtimeDir;
|
|
5620
5674
|
const contextPath = layout.contextPath;
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5675
|
+
mkdirSync16(rootDir, { recursive: true });
|
|
5676
|
+
mkdirSync16(homeDir, { recursive: true });
|
|
5677
|
+
mkdirSync16(tmpDir, { recursive: true });
|
|
5678
|
+
mkdirSync16(cacheDir, { recursive: true });
|
|
5679
|
+
mkdirSync16(logsDir, { recursive: true });
|
|
5680
|
+
mkdirSync16(stateDir, { recursive: true });
|
|
5681
|
+
mkdirSync16(sessionDir, { recursive: true });
|
|
5682
|
+
mkdirSync16(runtimeDir, { recursive: true });
|
|
5629
5683
|
return {
|
|
5630
5684
|
rootDir,
|
|
5631
5685
|
homeDir,
|
|
@@ -5643,17 +5697,17 @@ import {
|
|
|
5643
5697
|
chmodSync as chmodSync6,
|
|
5644
5698
|
copyFileSync as copyFileSync6,
|
|
5645
5699
|
cpSync as cpSync2,
|
|
5646
|
-
existsSync as
|
|
5647
|
-
mkdirSync as
|
|
5700
|
+
existsSync as existsSync29,
|
|
5701
|
+
mkdirSync as mkdirSync17,
|
|
5648
5702
|
statSync as statSync6,
|
|
5649
|
-
writeFileSync as
|
|
5703
|
+
writeFileSync as writeFileSync13
|
|
5650
5704
|
} from "fs";
|
|
5651
5705
|
import { mkdir } from "fs/promises";
|
|
5652
|
-
import { basename as basename9, delimiter as delimiter2, resolve as
|
|
5706
|
+
import { basename as basename9, delimiter as delimiter2, resolve as resolve30 } from "path";
|
|
5653
5707
|
|
|
5654
5708
|
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
5655
|
-
import { existsSync as
|
|
5656
|
-
import { resolve as
|
|
5709
|
+
import { existsSync as existsSync28, readFileSync as readFileSync15, rmSync as rmSync11 } from "fs";
|
|
5710
|
+
import { resolve as resolve29 } from "path";
|
|
5657
5711
|
var generatedCredentialFiles = new Set;
|
|
5658
5712
|
var credentialCleanupRegistered = false;
|
|
5659
5713
|
function resolveMonorepoRoot3(projectRoot) {
|
|
@@ -5677,7 +5731,7 @@ function resolveHostGitBinary() {
|
|
|
5677
5731
|
if (!candidate || isRuntimeGatewayGitPath2(candidate)) {
|
|
5678
5732
|
continue;
|
|
5679
5733
|
}
|
|
5680
|
-
if (
|
|
5734
|
+
if (existsSync28(candidate)) {
|
|
5681
5735
|
return candidate;
|
|
5682
5736
|
}
|
|
5683
5737
|
}
|
|
@@ -5743,7 +5797,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
|
|
|
5743
5797
|
}
|
|
5744
5798
|
}
|
|
5745
5799
|
async function tryReadGitHead(repoRoot) {
|
|
5746
|
-
if (!
|
|
5800
|
+
if (!existsSync28(resolve29(repoRoot, ".git"))) {
|
|
5747
5801
|
return;
|
|
5748
5802
|
}
|
|
5749
5803
|
const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
|
|
@@ -5754,7 +5808,7 @@ async function tryReadGitHead(repoRoot) {
|
|
|
5754
5808
|
return value || undefined;
|
|
5755
5809
|
}
|
|
5756
5810
|
async function captureRepoDirtyFiles(repoRoot) {
|
|
5757
|
-
if (!
|
|
5811
|
+
if (!existsSync28(resolve29(repoRoot, ".git"))) {
|
|
5758
5812
|
return [];
|
|
5759
5813
|
}
|
|
5760
5814
|
const files = new Set;
|
|
@@ -5790,7 +5844,7 @@ function registerCredentialCleanup(path) {
|
|
|
5790
5844
|
const cleanup = () => {
|
|
5791
5845
|
for (const filePath of generatedCredentialFiles) {
|
|
5792
5846
|
try {
|
|
5793
|
-
|
|
5847
|
+
rmSync11(filePath, { force: true });
|
|
5794
5848
|
} catch {}
|
|
5795
5849
|
}
|
|
5796
5850
|
generatedCredentialFiles.clear();
|
|
@@ -5841,10 +5895,10 @@ function hashProjectPath(workspaceDir) {
|
|
|
5841
5895
|
return sha256Hex(workspaceDir).slice(0, 16);
|
|
5842
5896
|
}
|
|
5843
5897
|
function readKnownHosts(path) {
|
|
5844
|
-
if (!
|
|
5898
|
+
if (!existsSync28(path)) {
|
|
5845
5899
|
return new Set;
|
|
5846
5900
|
}
|
|
5847
|
-
return new Set(
|
|
5901
|
+
return new Set(readFileSync15(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
5848
5902
|
}
|
|
5849
5903
|
|
|
5850
5904
|
// packages/runtime/src/control-plane/runtime/isolation/home.ts
|
|
@@ -5861,30 +5915,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
|
|
|
5861
5915
|
await mkdir(runtime.cacheDir, { recursive: true });
|
|
5862
5916
|
await provisionAgentSshKey(runtime.homeDir);
|
|
5863
5917
|
if (options.provider === "codex") {
|
|
5864
|
-
const hasCodexAuth = await injectCodexAuth(
|
|
5918
|
+
const hasCodexAuth = await injectCodexAuth(resolve30(runtime.homeDir, ".codex"));
|
|
5865
5919
|
if (!hasCodexAuth) {
|
|
5866
5920
|
console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
|
|
5867
5921
|
}
|
|
5868
5922
|
}
|
|
5869
5923
|
if (options.provider === "pi") {
|
|
5870
|
-
const hasPiAuth = await injectPiAgentConfig(
|
|
5924
|
+
const hasPiAuth = await injectPiAgentConfig(resolve30(runtime.homeDir, ".pi", "agent"));
|
|
5871
5925
|
if (!hasPiAuth) {
|
|
5872
5926
|
console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
|
|
5873
5927
|
}
|
|
5874
5928
|
}
|
|
5875
5929
|
}
|
|
5876
5930
|
async function provisionClaudeHome(config) {
|
|
5877
|
-
|
|
5878
|
-
const workspaceSettings =
|
|
5879
|
-
const hostSettings =
|
|
5880
|
-
const projectSettings =
|
|
5931
|
+
mkdirSync17(config.claudeHomeDir, { recursive: true });
|
|
5932
|
+
const workspaceSettings = resolve30(config.workspaceDir, ".claude/settings.json");
|
|
5933
|
+
const hostSettings = resolve30(config.hostProjectRoot, ".claude/settings.json");
|
|
5934
|
+
const projectSettings = existsSync29(workspaceSettings) ? workspaceSettings : hostSettings;
|
|
5881
5935
|
const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
|
|
5882
|
-
if (
|
|
5883
|
-
|
|
5936
|
+
if (existsSync29(projectSettings)) {
|
|
5937
|
+
writeFileSync13(resolve30(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
5884
5938
|
`, "utf-8");
|
|
5885
5939
|
}
|
|
5886
5940
|
writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
|
|
5887
|
-
|
|
5941
|
+
writeFileSync13(resolve30(config.claudeHomeDir, "settings.json"), JSON.stringify({
|
|
5888
5942
|
permissions: { defaultMode: "bypassPermissions" },
|
|
5889
5943
|
autoMemoryEnabled: false
|
|
5890
5944
|
}, null, 2));
|
|
@@ -5892,20 +5946,20 @@ async function provisionClaudeHome(config) {
|
|
|
5892
5946
|
if (!hasCredentials) {
|
|
5893
5947
|
console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
|
|
5894
5948
|
}
|
|
5895
|
-
const realClaudeHome =
|
|
5896
|
-
if (process.env.HOME &&
|
|
5897
|
-
cpSync2(
|
|
5949
|
+
const realClaudeHome = resolve30(process.env.HOME ?? "", ".claude");
|
|
5950
|
+
if (process.env.HOME && existsSync29(resolve30(realClaudeHome, "CLAUDE.md"))) {
|
|
5951
|
+
cpSync2(resolve30(realClaudeHome, "CLAUDE.md"), resolve30(config.claudeHomeDir, "CLAUDE.md"));
|
|
5898
5952
|
}
|
|
5899
|
-
if (process.env.HOME &&
|
|
5900
|
-
cpSync2(
|
|
5953
|
+
if (process.env.HOME && existsSync29(resolve30(realClaudeHome, "agents"))) {
|
|
5954
|
+
cpSync2(resolve30(realClaudeHome, "agents"), resolve30(config.claudeHomeDir, "agents"), { recursive: true });
|
|
5901
5955
|
}
|
|
5902
5956
|
if (process.platform === "darwin" && process.env.HOME) {
|
|
5903
5957
|
writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
|
|
5904
5958
|
}
|
|
5905
5959
|
}
|
|
5906
5960
|
async function provisionAgentSshKey(homeDir) {
|
|
5907
|
-
const sshDir =
|
|
5908
|
-
if (!
|
|
5961
|
+
const sshDir = resolve30(homeDir, ".ssh");
|
|
5962
|
+
if (!existsSync29(sshDir)) {
|
|
5909
5963
|
await mkdir(sshDir, { recursive: true });
|
|
5910
5964
|
}
|
|
5911
5965
|
seedKnownHosts(sshDir);
|
|
@@ -5913,27 +5967,27 @@ async function provisionAgentSshKey(homeDir) {
|
|
|
5913
5967
|
const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
|
|
5914
5968
|
if (!privateKey) {
|
|
5915
5969
|
const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
|
|
5916
|
-
if (!process.env.HOME || !
|
|
5970
|
+
if (!process.env.HOME || !existsSync29(hostKeyPath)) {
|
|
5917
5971
|
return;
|
|
5918
5972
|
}
|
|
5919
|
-
const agentKeyPath2 =
|
|
5920
|
-
if (!
|
|
5973
|
+
const agentKeyPath2 = resolve30(sshDir, "rig-agent-key");
|
|
5974
|
+
if (!existsSync29(agentKeyPath2)) {
|
|
5921
5975
|
copyFileSync6(hostKeyPath, agentKeyPath2);
|
|
5922
5976
|
chmodSync6(agentKeyPath2, 384);
|
|
5923
5977
|
}
|
|
5924
5978
|
const hostPubPath = `${hostKeyPath}.pub`;
|
|
5925
|
-
if (
|
|
5979
|
+
if (existsSync29(hostPubPath)) {
|
|
5926
5980
|
const agentPubPath = `${agentKeyPath2}.pub`;
|
|
5927
|
-
if (!
|
|
5981
|
+
if (!existsSync29(agentPubPath)) {
|
|
5928
5982
|
copyFileSync6(hostPubPath, agentPubPath);
|
|
5929
5983
|
}
|
|
5930
5984
|
}
|
|
5931
5985
|
writeSshConfig(sshDir, agentKeyPath2);
|
|
5932
5986
|
return;
|
|
5933
5987
|
}
|
|
5934
|
-
const agentKeyPath =
|
|
5935
|
-
if (!
|
|
5936
|
-
|
|
5988
|
+
const agentKeyPath = resolve30(sshDir, "rig-agent-key");
|
|
5989
|
+
if (!existsSync29(agentKeyPath)) {
|
|
5990
|
+
writeFileSync13(agentKeyPath, privateKey, { mode: 384 });
|
|
5937
5991
|
}
|
|
5938
5992
|
writeSshConfig(sshDir, agentKeyPath);
|
|
5939
5993
|
}
|
|
@@ -5950,21 +6004,21 @@ function decodeProvisionedSshKey(encodedKey) {
|
|
|
5950
6004
|
`;
|
|
5951
6005
|
}
|
|
5952
6006
|
function resolveHostSshKeyPath(homeDir) {
|
|
5953
|
-
const sshDir =
|
|
6007
|
+
const sshDir = resolve30(homeDir, ".ssh");
|
|
5954
6008
|
const candidates = [
|
|
5955
6009
|
"rig-agent-key",
|
|
5956
6010
|
"id_ed25519",
|
|
5957
6011
|
"id_ecdsa",
|
|
5958
6012
|
"id_rsa"
|
|
5959
|
-
].map((name) =>
|
|
5960
|
-
return candidates.find((candidate) =>
|
|
6013
|
+
].map((name) => resolve30(sshDir, name));
|
|
6014
|
+
return candidates.find((candidate) => existsSync29(candidate)) ?? resolve30(sshDir, "rig-agent-key");
|
|
5961
6015
|
}
|
|
5962
6016
|
function writeSshConfig(sshDir, keyPath) {
|
|
5963
|
-
const configPath =
|
|
5964
|
-
if (
|
|
6017
|
+
const configPath = resolve30(sshDir, "config");
|
|
6018
|
+
if (existsSync29(configPath)) {
|
|
5965
6019
|
return;
|
|
5966
6020
|
}
|
|
5967
|
-
const knownHostsPath =
|
|
6021
|
+
const knownHostsPath = resolve30(sshDir, "known_hosts");
|
|
5968
6022
|
const config = [
|
|
5969
6023
|
"Host github.com",
|
|
5970
6024
|
` IdentityFile ${keyPath}`,
|
|
@@ -5974,10 +6028,10 @@ function writeSshConfig(sshDir, keyPath) {
|
|
|
5974
6028
|
""
|
|
5975
6029
|
].join(`
|
|
5976
6030
|
`);
|
|
5977
|
-
|
|
6031
|
+
writeFileSync13(configPath, config, { mode: 420 });
|
|
5978
6032
|
}
|
|
5979
6033
|
function seedKnownHosts(sshDir) {
|
|
5980
|
-
const knownHostsPath =
|
|
6034
|
+
const knownHostsPath = resolve30(sshDir, "known_hosts");
|
|
5981
6035
|
const existingLines = readKnownHosts(knownHostsPath);
|
|
5982
6036
|
const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
5983
6037
|
const missing = requiredLines.filter((line) => !existingLines.has(line));
|
|
@@ -5988,23 +6042,23 @@ function seedKnownHosts(sshDir) {
|
|
|
5988
6042
|
for (const line of missing) {
|
|
5989
6043
|
existingLines.add(line);
|
|
5990
6044
|
}
|
|
5991
|
-
|
|
6045
|
+
writeFileSync13(knownHostsPath, `${Array.from(existingLines).join(`
|
|
5992
6046
|
`)}
|
|
5993
6047
|
`, { mode: 420 });
|
|
5994
6048
|
} catch (err) {
|
|
5995
|
-
const hint =
|
|
6049
|
+
const hint = existsSync29(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
|
|
5996
6050
|
console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
|
|
5997
6051
|
}
|
|
5998
6052
|
}
|
|
5999
6053
|
function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
|
|
6000
6054
|
const projectHash = hashProjectPath(workspaceDir);
|
|
6001
|
-
const projectDir =
|
|
6002
|
-
|
|
6003
|
-
|
|
6055
|
+
const projectDir = resolve30(claudeHomeDir, "projects", projectHash);
|
|
6056
|
+
mkdirSync17(projectDir, { recursive: true });
|
|
6057
|
+
writeFileSync13(resolve30(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
|
|
6004
6058
|
`, "utf-8");
|
|
6005
6059
|
}
|
|
6006
6060
|
async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
6007
|
-
if (!
|
|
6061
|
+
if (!existsSync29(projectSettingsPath)) {
|
|
6008
6062
|
return {};
|
|
6009
6063
|
}
|
|
6010
6064
|
let parsed;
|
|
@@ -6050,7 +6104,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
|
|
|
6050
6104
|
return clone;
|
|
6051
6105
|
}
|
|
6052
6106
|
async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
6053
|
-
const credentialsPath =
|
|
6107
|
+
const credentialsPath = resolve30(claudeHomeDir, ".credentials.json");
|
|
6054
6108
|
const platform = options.platform ?? process.platform;
|
|
6055
6109
|
if (platform === "darwin") {
|
|
6056
6110
|
const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
|
|
@@ -6060,16 +6114,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6060
6114
|
if (raw) {
|
|
6061
6115
|
try {
|
|
6062
6116
|
JSON.parse(raw);
|
|
6063
|
-
|
|
6117
|
+
writeFileSync13(credentialsPath, raw, { mode: 384 });
|
|
6064
6118
|
registerCredentialCleanup(credentialsPath);
|
|
6065
6119
|
return true;
|
|
6066
6120
|
} catch {}
|
|
6067
6121
|
}
|
|
6068
6122
|
}
|
|
6069
|
-
const hostClaudeHome = options.hostClaudeHome ?
|
|
6123
|
+
const hostClaudeHome = options.hostClaudeHome ? resolve30(options.hostClaudeHome) : process.env.CLAUDE_HOME?.trim() ? resolve30(process.env.CLAUDE_HOME) : process.env.HOME ? resolve30(process.env.HOME, ".claude") : "";
|
|
6070
6124
|
if (hostClaudeHome) {
|
|
6071
|
-
const realCredentials =
|
|
6072
|
-
if (
|
|
6125
|
+
const realCredentials = resolve30(hostClaudeHome, ".credentials.json");
|
|
6126
|
+
if (existsSync29(realCredentials)) {
|
|
6073
6127
|
cpSync2(realCredentials, credentialsPath);
|
|
6074
6128
|
return true;
|
|
6075
6129
|
}
|
|
@@ -6077,36 +6131,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
|
|
|
6077
6131
|
return false;
|
|
6078
6132
|
}
|
|
6079
6133
|
async function injectCodexAuth(codexHomeDir) {
|
|
6080
|
-
|
|
6081
|
-
const hostCodexHome = process.env.CODEX_HOME?.trim() ?
|
|
6134
|
+
mkdirSync17(codexHomeDir, { recursive: true });
|
|
6135
|
+
const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve30(process.env.CODEX_HOME) : process.env.HOME ? resolve30(process.env.HOME, ".codex") : "";
|
|
6082
6136
|
if (!hostCodexHome) {
|
|
6083
6137
|
return false;
|
|
6084
6138
|
}
|
|
6085
|
-
const hostAuthPath =
|
|
6086
|
-
if (!
|
|
6139
|
+
const hostAuthPath = resolve30(hostCodexHome, "auth.json");
|
|
6140
|
+
if (!existsSync29(hostAuthPath)) {
|
|
6087
6141
|
return false;
|
|
6088
6142
|
}
|
|
6089
|
-
const runtimeAuthPath =
|
|
6143
|
+
const runtimeAuthPath = resolve30(codexHomeDir, "auth.json");
|
|
6090
6144
|
copyFileSync6(hostAuthPath, runtimeAuthPath);
|
|
6091
6145
|
chmodSync6(runtimeAuthPath, 384);
|
|
6092
6146
|
return true;
|
|
6093
6147
|
}
|
|
6094
6148
|
async function injectPiAgentConfig(piAgentDir) {
|
|
6095
|
-
|
|
6096
|
-
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ?
|
|
6149
|
+
mkdirSync17(piAgentDir, { recursive: true });
|
|
6150
|
+
const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ? resolve30(process.env.PI_CODING_AGENT_DIR) : process.env.HOME ? resolve30(process.env.HOME, ".pi", "agent") : "";
|
|
6097
6151
|
if (!hostPiAgentDir) {
|
|
6098
6152
|
return false;
|
|
6099
6153
|
}
|
|
6100
|
-
const hostAuthPath =
|
|
6101
|
-
if (!
|
|
6154
|
+
const hostAuthPath = resolve30(hostPiAgentDir, "auth.json");
|
|
6155
|
+
if (!existsSync29(hostAuthPath)) {
|
|
6102
6156
|
return false;
|
|
6103
6157
|
}
|
|
6104
|
-
const runtimeAuthPath =
|
|
6158
|
+
const runtimeAuthPath = resolve30(piAgentDir, "auth.json");
|
|
6105
6159
|
copyFileSync6(hostAuthPath, runtimeAuthPath);
|
|
6106
6160
|
chmodSync6(runtimeAuthPath, 384);
|
|
6107
|
-
const hostSettingsPath =
|
|
6108
|
-
if (
|
|
6109
|
-
const runtimeSettingsPath =
|
|
6161
|
+
const hostSettingsPath = resolve30(hostPiAgentDir, "settings.json");
|
|
6162
|
+
if (existsSync29(hostSettingsPath)) {
|
|
6163
|
+
const runtimeSettingsPath = resolve30(piAgentDir, "settings.json");
|
|
6110
6164
|
copyFileSync6(hostSettingsPath, runtimeSettingsPath);
|
|
6111
6165
|
chmodSync6(runtimeSettingsPath, 384);
|
|
6112
6166
|
}
|
|
@@ -6114,13 +6168,13 @@ async function injectPiAgentConfig(piAgentDir) {
|
|
|
6114
6168
|
}
|
|
6115
6169
|
|
|
6116
6170
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
6117
|
-
import { existsSync as
|
|
6118
|
-
import { resolve as
|
|
6171
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync18, statSync as statSync7, writeFileSync as writeFileSync14 } from "fs";
|
|
6172
|
+
import { resolve as resolve31 } from "path";
|
|
6119
6173
|
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
6120
6174
|
function buildRuntimeToolRouterServerConfig(options) {
|
|
6121
6175
|
return {
|
|
6122
6176
|
type: "stdio",
|
|
6123
|
-
command:
|
|
6177
|
+
command: resolve31(options.binDir, "rig-tool-router"),
|
|
6124
6178
|
args: [],
|
|
6125
6179
|
env: {
|
|
6126
6180
|
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
@@ -6129,14 +6183,14 @@ function buildRuntimeToolRouterServerConfig(options) {
|
|
|
6129
6183
|
};
|
|
6130
6184
|
}
|
|
6131
6185
|
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
6132
|
-
const configPath =
|
|
6133
|
-
|
|
6186
|
+
const configPath = resolve31(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
6187
|
+
mkdirSync18(options.stateDir, { recursive: true });
|
|
6134
6188
|
const payload = {
|
|
6135
6189
|
mcpServers: {
|
|
6136
6190
|
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
6137
6191
|
}
|
|
6138
6192
|
};
|
|
6139
|
-
|
|
6193
|
+
writeFileSync14(configPath, `${JSON.stringify(payload, null, 2)}
|
|
6140
6194
|
`, "utf-8");
|
|
6141
6195
|
return configPath;
|
|
6142
6196
|
}
|
|
@@ -6145,8 +6199,8 @@ if (false) {}
|
|
|
6145
6199
|
init_layout();
|
|
6146
6200
|
|
|
6147
6201
|
// packages/runtime/src/control-plane/runtime/isolation/worktree.ts
|
|
6148
|
-
import { existsSync as
|
|
6149
|
-
import { dirname as dirname14, resolve as
|
|
6202
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync19, rmSync as rmSync12 } from "fs";
|
|
6203
|
+
import { dirname as dirname14, resolve as resolve32 } from "path";
|
|
6150
6204
|
async function resolveMonorepoBaseRef(monorepoRoot) {
|
|
6151
6205
|
const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
|
|
6152
6206
|
if (explicit) {
|
|
@@ -6182,12 +6236,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
|
|
|
6182
6236
|
}
|
|
6183
6237
|
async function provisionRuntimeWorktree(config) {
|
|
6184
6238
|
const branch = runtimeBranchName(config.taskId, config.runtimeId);
|
|
6185
|
-
let hasValidWorktree =
|
|
6186
|
-
if (
|
|
6187
|
-
|
|
6239
|
+
let hasValidWorktree = existsSync31(resolve32(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
|
|
6240
|
+
if (existsSync31(config.workspaceDir) && !hasValidWorktree) {
|
|
6241
|
+
rmSync12(config.workspaceDir, { recursive: true, force: true });
|
|
6188
6242
|
}
|
|
6189
6243
|
if (!hasValidWorktree) {
|
|
6190
|
-
|
|
6244
|
+
mkdirSync19(dirname14(config.workspaceDir), { recursive: true });
|
|
6191
6245
|
const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
6192
6246
|
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]);
|
|
6193
6247
|
if (add.exitCode !== 0) {
|
|
@@ -6363,31 +6417,31 @@ async function preferredBaseRemotes(repoRoot) {
|
|
|
6363
6417
|
|
|
6364
6418
|
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
6365
6419
|
import {
|
|
6366
|
-
existsSync as
|
|
6420
|
+
existsSync as existsSync33,
|
|
6367
6421
|
lstatSync as lstatSync2,
|
|
6368
|
-
mkdirSync as
|
|
6369
|
-
readdirSync as
|
|
6370
|
-
readFileSync as
|
|
6371
|
-
rmSync as
|
|
6422
|
+
mkdirSync as mkdirSync21,
|
|
6423
|
+
readdirSync as readdirSync7,
|
|
6424
|
+
readFileSync as readFileSync17,
|
|
6425
|
+
rmSync as rmSync13,
|
|
6372
6426
|
statSync as statSync9,
|
|
6373
6427
|
symlinkSync as symlinkSync4
|
|
6374
6428
|
} from "fs";
|
|
6375
6429
|
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
6376
|
-
import { dirname as dirname16, resolve as
|
|
6430
|
+
import { dirname as dirname16, resolve as resolve34 } from "path";
|
|
6377
6431
|
|
|
6378
6432
|
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
6379
|
-
import { chmodSync as chmodSync7, copyFileSync as copyFileSync7, existsSync as
|
|
6433
|
+
import { chmodSync as chmodSync7, copyFileSync as copyFileSync7, existsSync as existsSync32, mkdirSync as mkdirSync20, statSync as statSync8 } from "fs";
|
|
6380
6434
|
import { tmpdir as tmpdir6 } from "os";
|
|
6381
|
-
import { dirname as dirname15, resolve as
|
|
6382
|
-
var sharedRouterOutputDir =
|
|
6383
|
-
var sharedRouterOutputPath =
|
|
6435
|
+
import { dirname as dirname15, resolve as resolve33 } from "path";
|
|
6436
|
+
var sharedRouterOutputDir = resolve33(tmpdir6(), "rig-native");
|
|
6437
|
+
var sharedRouterOutputPath = resolve33(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
6384
6438
|
function runtimeClaudeToolRouterFileName() {
|
|
6385
6439
|
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
6386
6440
|
}
|
|
6387
6441
|
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
6388
|
-
const sourcePath =
|
|
6389
|
-
|
|
6390
|
-
const needsBuild = !
|
|
6442
|
+
const sourcePath = resolve33(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
6443
|
+
mkdirSync20(dirname15(outputPath), { recursive: true });
|
|
6444
|
+
const needsBuild = !existsSync32(outputPath) || statSync8(sourcePath).mtimeMs > statSync8(outputPath).mtimeMs;
|
|
6391
6445
|
if (!needsBuild) {
|
|
6392
6446
|
return outputPath;
|
|
6393
6447
|
}
|
|
@@ -6401,9 +6455,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
|
|
|
6401
6455
|
}
|
|
6402
6456
|
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
6403
6457
|
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
6404
|
-
const targetPath =
|
|
6405
|
-
|
|
6406
|
-
const needsCopy = !
|
|
6458
|
+
const targetPath = resolve33(targetDir, runtimeClaudeToolRouterFileName());
|
|
6459
|
+
mkdirSync20(targetDir, { recursive: true });
|
|
6460
|
+
const needsCopy = !existsSync32(targetPath) || statSync8(sourcePath).mtimeMs > statSync8(targetPath).mtimeMs;
|
|
6407
6461
|
if (needsCopy) {
|
|
6408
6462
|
copyFileSync7(sourcePath, targetPath);
|
|
6409
6463
|
chmodSync7(targetPath, 493);
|
|
@@ -6416,48 +6470,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
|
6416
6470
|
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
6417
6471
|
function resolveRigSourceRoot(projectRoot) {
|
|
6418
6472
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
6419
|
-
if (hostProjectRoot &&
|
|
6473
|
+
if (hostProjectRoot && existsSync33(resolve34(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6420
6474
|
return hostProjectRoot;
|
|
6421
6475
|
}
|
|
6422
|
-
const fromModule =
|
|
6423
|
-
if (
|
|
6476
|
+
const fromModule = resolve34(import.meta.dir, "../../../../../..");
|
|
6477
|
+
if (existsSync33(resolve34(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
6424
6478
|
return fromModule;
|
|
6425
6479
|
}
|
|
6426
6480
|
return projectRoot;
|
|
6427
6481
|
}
|
|
6428
6482
|
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
6429
|
-
for (const path of [logsDir, stateDir, sessionDir,
|
|
6483
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve34(sessionDir, "session.json")]) {
|
|
6430
6484
|
removeSymbolicLink(path);
|
|
6431
6485
|
}
|
|
6432
6486
|
runtimePrepareTrackedPathsNative({
|
|
6433
6487
|
logsDir,
|
|
6434
6488
|
stateDir,
|
|
6435
6489
|
sessionDir,
|
|
6436
|
-
controlledBashLogFile:
|
|
6437
|
-
eventsFile:
|
|
6490
|
+
controlledBashLogFile: resolve34(logsDir, "controlled-bash.jsonl"),
|
|
6491
|
+
eventsFile: resolve34(logsDir, "control-plane.events.jsonl")
|
|
6438
6492
|
});
|
|
6439
6493
|
}
|
|
6440
6494
|
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
6441
6495
|
await mkdir2(stateDir, { recursive: true });
|
|
6442
6496
|
await mkdir2(sessionDir, { recursive: true });
|
|
6443
|
-
const failedApproachesPath =
|
|
6444
|
-
if (!
|
|
6497
|
+
const failedApproachesPath = resolve34(stateDir, "failed_approaches.md");
|
|
6498
|
+
if (!existsSync33(failedApproachesPath)) {
|
|
6445
6499
|
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
6446
6500
|
|
|
6447
6501
|
`);
|
|
6448
6502
|
}
|
|
6449
|
-
const hookTripsPath =
|
|
6450
|
-
if (!
|
|
6503
|
+
const hookTripsPath = resolve34(stateDir, "hook_trips.log");
|
|
6504
|
+
if (!existsSync33(hookTripsPath)) {
|
|
6451
6505
|
await writeFile(hookTripsPath, "");
|
|
6452
6506
|
}
|
|
6453
|
-
const sessionFile =
|
|
6507
|
+
const sessionFile = resolve34(sessionDir, "session.json");
|
|
6454
6508
|
if (taskId) {
|
|
6455
6509
|
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
6456
6510
|
}
|
|
6457
6511
|
}
|
|
6458
6512
|
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
6459
|
-
const artifactDir =
|
|
6460
|
-
const runtimeSnapshotDir =
|
|
6513
|
+
const artifactDir = resolve34(workspaceDir, "artifacts", taskId);
|
|
6514
|
+
const runtimeSnapshotDir = resolve34(artifactDir, "runtime-snapshots");
|
|
6461
6515
|
let preservedTrackedFiles = false;
|
|
6462
6516
|
for (const file of [
|
|
6463
6517
|
"changed-files.txt",
|
|
@@ -6473,13 +6527,13 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
|
6473
6527
|
preservedTrackedFiles = true;
|
|
6474
6528
|
continue;
|
|
6475
6529
|
}
|
|
6476
|
-
|
|
6530
|
+
rmSync13(resolve34(artifactDir, file), { force: true });
|
|
6477
6531
|
}
|
|
6478
6532
|
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
6479
6533
|
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
6480
6534
|
preservedTrackedFiles = true;
|
|
6481
6535
|
} else {
|
|
6482
|
-
|
|
6536
|
+
rmSync13(runtimeSnapshotDir, { recursive: true, force: true });
|
|
6483
6537
|
}
|
|
6484
6538
|
if (preservedTrackedFiles) {
|
|
6485
6539
|
console.log(`[rig-agent] Preserved tracked runtime artifact files in ${taskId}; skipped ephemeral cleanup for committed paths.`);
|
|
@@ -6512,28 +6566,28 @@ async function buildRuntimeToolchain(options) {
|
|
|
6512
6566
|
throw new Error("Failed to provision the native Zig runtime library.");
|
|
6513
6567
|
}
|
|
6514
6568
|
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
6515
|
-
await buildBinary("packages/cli/bin/rig.ts",
|
|
6516
|
-
await buildBinary("packages/runtime/bin/rig-agent.ts",
|
|
6569
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve34(options.binDir, "rig"), rigSourceRoot);
|
|
6570
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve34(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
6517
6571
|
...options.runtimeSecretDefines,
|
|
6518
6572
|
AGENT_TASK_ID: options.taskId,
|
|
6519
6573
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6520
6574
|
AGENT_RUNTIME_ID: options.runtimeId,
|
|
6521
6575
|
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
6522
6576
|
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
6523
|
-
AGENT_BINARY_PATH:
|
|
6577
|
+
AGENT_BINARY_PATH: resolve34(options.binDir, "rig-agent"),
|
|
6524
6578
|
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
6525
6579
|
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
6526
6580
|
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
6527
6581
|
});
|
|
6528
|
-
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts",
|
|
6582
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve34(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
6529
6583
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6530
6584
|
AGENT_LOGS_DIR: options.logsDir,
|
|
6531
6585
|
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
6532
|
-
AGENT_TS_API_TESTS_DIR:
|
|
6533
|
-
AGENT_RIG_AGENT_BIN:
|
|
6586
|
+
AGENT_TS_API_TESTS_DIR: resolve34(options.workspaceDir, "TSAPITests"),
|
|
6587
|
+
AGENT_RIG_AGENT_BIN: resolve34(options.binDir, "rig-agent")
|
|
6534
6588
|
});
|
|
6535
|
-
await buildBinary("packages/runtime/bin/rig-browser-tool.ts",
|
|
6536
|
-
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts",
|
|
6589
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve34(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
6590
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve34(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
6537
6591
|
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
6538
6592
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6539
6593
|
});
|
|
@@ -6542,15 +6596,15 @@ async function buildRuntimeToolchain(options) {
|
|
|
6542
6596
|
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
6543
6597
|
};
|
|
6544
6598
|
for (const hookName of hookNames) {
|
|
6545
|
-
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`,
|
|
6599
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve34(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
6546
6600
|
}
|
|
6547
|
-
const pluginsDir =
|
|
6548
|
-
if (
|
|
6549
|
-
for (const entry of
|
|
6601
|
+
const pluginsDir = resolve34(options.projectRoot, "rig/plugins");
|
|
6602
|
+
if (existsSync33(pluginsDir)) {
|
|
6603
|
+
for (const entry of readdirSync7(pluginsDir, { withFileTypes: true })) {
|
|
6550
6604
|
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
6551
6605
|
if (!match)
|
|
6552
6606
|
continue;
|
|
6553
|
-
await buildBinary(`rig/plugins/${entry.name}`,
|
|
6607
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve34(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
6554
6608
|
}
|
|
6555
6609
|
}
|
|
6556
6610
|
await materializeRigGitBinary(options.binDir);
|
|
@@ -6560,8 +6614,8 @@ async function buildRuntimeToolchain(options) {
|
|
|
6560
6614
|
}
|
|
6561
6615
|
async function writeRuntimeManifest(config) {
|
|
6562
6616
|
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
6563
|
-
const binarySha256 = sha256Hex(
|
|
6564
|
-
const manifestPath =
|
|
6617
|
+
const binarySha256 = sha256Hex(readFileSync17(config.binaryPath));
|
|
6618
|
+
const manifestPath = resolve34(config.runtimeRoot, "manifest.json");
|
|
6565
6619
|
const manifest = {
|
|
6566
6620
|
runtimeId: config.runtimeId,
|
|
6567
6621
|
taskId: config.taskId,
|
|
@@ -6595,7 +6649,7 @@ function removeSymbolicLink(path) {
|
|
|
6595
6649
|
} catch {
|
|
6596
6650
|
return;
|
|
6597
6651
|
}
|
|
6598
|
-
|
|
6652
|
+
rmSync13(path, { force: true, recursive: true });
|
|
6599
6653
|
}
|
|
6600
6654
|
async function resetTrackedArtifactPath(workspaceDir, relativePath) {
|
|
6601
6655
|
const tracked = await runGitLsFiles(workspaceDir, relativePath);
|
|
@@ -6621,7 +6675,7 @@ async function restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, r
|
|
|
6621
6675
|
const retryDelayMs = options.retryDelayMs ?? GIT_INDEX_LOCK_RETRY_DELAY_MS;
|
|
6622
6676
|
const now = options.now ?? Date.now;
|
|
6623
6677
|
const statMtimeMs = options.statMtimeMs ?? readFileMtimeMs;
|
|
6624
|
-
const removeFile = options.removeFile ?? ((path) =>
|
|
6678
|
+
const removeFile = options.removeFile ?? ((path) => rmSync13(path, { force: true }));
|
|
6625
6679
|
const log = options.log ?? console.warn;
|
|
6626
6680
|
let lastOutput = "";
|
|
6627
6681
|
for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
|
|
@@ -6681,31 +6735,31 @@ function readFileMtimeMs(path) {
|
|
|
6681
6735
|
}
|
|
6682
6736
|
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
6683
6737
|
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
6684
|
-
const sourceNodeModules =
|
|
6685
|
-
if (!
|
|
6686
|
-
const runtimeHumoongate =
|
|
6687
|
-
if (
|
|
6688
|
-
const targetNodeModules =
|
|
6738
|
+
const sourceNodeModules = resolve34(monorepoRoot, "humoongate", "node_modules");
|
|
6739
|
+
if (!existsSync33(sourceNodeModules)) {} else {
|
|
6740
|
+
const runtimeHumoongate = resolve34(workspaceDir, "humoongate");
|
|
6741
|
+
if (existsSync33(resolve34(runtimeHumoongate, "package.json"))) {
|
|
6742
|
+
const targetNodeModules = resolve34(runtimeHumoongate, "node_modules");
|
|
6689
6743
|
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
6690
6744
|
}
|
|
6691
6745
|
}
|
|
6692
|
-
const runtimeHpNext =
|
|
6693
|
-
if (!
|
|
6746
|
+
const runtimeHpNext = resolve34(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
6747
|
+
if (!existsSync33(resolve34(runtimeHpNext, "package.json"))) {
|
|
6694
6748
|
return;
|
|
6695
6749
|
}
|
|
6696
|
-
const sourceHpNextNodeModules =
|
|
6697
|
-
const sourceMonorepoNodeModules =
|
|
6698
|
-
const targetHpNextNodeModules =
|
|
6699
|
-
if (
|
|
6750
|
+
const sourceHpNextNodeModules = resolve34(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
6751
|
+
const sourceMonorepoNodeModules = resolve34(monorepoRoot, "node_modules");
|
|
6752
|
+
const targetHpNextNodeModules = resolve34(runtimeHpNext, "node_modules");
|
|
6753
|
+
if (existsSync33(sourceHpNextNodeModules)) {
|
|
6700
6754
|
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
6701
6755
|
return;
|
|
6702
6756
|
}
|
|
6703
|
-
if (
|
|
6757
|
+
if (existsSync33(sourceMonorepoNodeModules)) {
|
|
6704
6758
|
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
6705
6759
|
}
|
|
6706
6760
|
}
|
|
6707
6761
|
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
6708
|
-
linkNodeModulesLayer(
|
|
6762
|
+
linkNodeModulesLayer(resolve34(monorepoRoot, "node_modules"), resolve34(workspaceDir, "node_modules"));
|
|
6709
6763
|
for (const relativePackageDir of [
|
|
6710
6764
|
"apps/native-app/apps/marketing",
|
|
6711
6765
|
"apps/native-app/apps/web",
|
|
@@ -6727,15 +6781,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
|
6727
6781
|
"packages/standard-plugin",
|
|
6728
6782
|
"packages/validator-kit"
|
|
6729
6783
|
]) {
|
|
6730
|
-
const workspacePackageDir =
|
|
6731
|
-
if (!
|
|
6784
|
+
const workspacePackageDir = resolve34(workspaceDir, relativePackageDir);
|
|
6785
|
+
if (!existsSync33(resolve34(workspacePackageDir, "package.json"))) {
|
|
6732
6786
|
continue;
|
|
6733
6787
|
}
|
|
6734
|
-
linkNodeModulesLayer(
|
|
6788
|
+
linkNodeModulesLayer(resolve34(monorepoRoot, relativePackageDir, "node_modules"), resolve34(workspacePackageDir, "node_modules"));
|
|
6735
6789
|
}
|
|
6736
6790
|
}
|
|
6737
6791
|
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
6738
|
-
if (!
|
|
6792
|
+
if (!existsSync33(sourceDir) || existsSync33(targetDir)) {
|
|
6739
6793
|
return;
|
|
6740
6794
|
}
|
|
6741
6795
|
try {
|
|
@@ -6744,23 +6798,23 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
|
6744
6798
|
} catch (error) {
|
|
6745
6799
|
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
6746
6800
|
}
|
|
6747
|
-
|
|
6801
|
+
mkdirSync21(dirname16(targetDir), { recursive: true });
|
|
6748
6802
|
symlinkSync4(sourceDir, targetDir, "dir");
|
|
6749
6803
|
}
|
|
6750
6804
|
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
6751
|
-
const hooksDir =
|
|
6752
|
-
const pluginsDir =
|
|
6753
|
-
const validatorsDir =
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6805
|
+
const hooksDir = resolve34(runtimeBinDir, "hooks");
|
|
6806
|
+
const pluginsDir = resolve34(runtimeBinDir, "plugins");
|
|
6807
|
+
const validatorsDir = resolve34(runtimeBinDir, "validators");
|
|
6808
|
+
mkdirSync21(hooksDir, { recursive: true });
|
|
6809
|
+
mkdirSync21(pluginsDir, { recursive: true });
|
|
6810
|
+
mkdirSync21(validatorsDir, { recursive: true });
|
|
6757
6811
|
return { hooksDir, pluginsDir, validatorsDir };
|
|
6758
6812
|
}
|
|
6759
6813
|
|
|
6760
6814
|
// packages/runtime/src/control-plane/runtime/guard.ts
|
|
6761
6815
|
import { optimizeNextInvocation } from "bun:jsc";
|
|
6762
|
-
import { existsSync as
|
|
6763
|
-
import { resolve as
|
|
6816
|
+
import { existsSync as existsSync34, readFileSync as readFileSync18, statSync as statSync10 } from "fs";
|
|
6817
|
+
import { resolve as resolve35 } from "path";
|
|
6764
6818
|
|
|
6765
6819
|
// packages/runtime/src/control-plane/runtime/guard-types.ts
|
|
6766
6820
|
var POLICY_VERSION = 1;
|
|
@@ -6823,8 +6877,8 @@ function loadPolicy(projectRoot) {
|
|
|
6823
6877
|
if (seededPolicyConfig) {
|
|
6824
6878
|
return seededPolicyConfig;
|
|
6825
6879
|
}
|
|
6826
|
-
const configPath =
|
|
6827
|
-
if (!
|
|
6880
|
+
const configPath = resolve35(projectRoot, "rig/policy/policy.json");
|
|
6881
|
+
if (!existsSync34(configPath)) {
|
|
6828
6882
|
return defaultPolicy();
|
|
6829
6883
|
}
|
|
6830
6884
|
let mtimeMs;
|
|
@@ -6838,7 +6892,7 @@ function loadPolicy(projectRoot) {
|
|
|
6838
6892
|
}
|
|
6839
6893
|
let parsed;
|
|
6840
6894
|
try {
|
|
6841
|
-
parsed = JSON.parse(
|
|
6895
|
+
parsed = JSON.parse(readFileSync18(configPath, "utf-8"));
|
|
6842
6896
|
} catch {
|
|
6843
6897
|
return defaultPolicy();
|
|
6844
6898
|
}
|
|
@@ -7054,28 +7108,28 @@ function resolveAction(mode, matched) {
|
|
|
7054
7108
|
}
|
|
7055
7109
|
function resolveAbsolutePath(projectRoot, rawPath) {
|
|
7056
7110
|
if (rawPath.startsWith("/"))
|
|
7057
|
-
return
|
|
7058
|
-
return
|
|
7111
|
+
return resolve35(rawPath);
|
|
7112
|
+
return resolve35(projectRoot, rawPath);
|
|
7059
7113
|
}
|
|
7060
7114
|
function isHarnessPath(projectRoot, rawPath) {
|
|
7061
7115
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7062
7116
|
const managedRoots = [
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7117
|
+
resolve35(projectRoot, "rig"),
|
|
7118
|
+
resolve35(projectRoot, ".rig"),
|
|
7119
|
+
resolve35(projectRoot, "artifacts")
|
|
7066
7120
|
];
|
|
7067
7121
|
return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
|
|
7068
7122
|
}
|
|
7069
7123
|
function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
|
|
7070
7124
|
const absPath = resolveAbsolutePath(projectRoot, rawPath);
|
|
7071
7125
|
if (taskWorkspace) {
|
|
7072
|
-
const workspaceRigRoot =
|
|
7073
|
-
const workspaceArtifactsRoot =
|
|
7126
|
+
const workspaceRigRoot = resolve35(taskWorkspace, ".rig");
|
|
7127
|
+
const workspaceArtifactsRoot = resolve35(taskWorkspace, "artifacts");
|
|
7074
7128
|
if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
|
|
7075
7129
|
return true;
|
|
7076
7130
|
}
|
|
7077
7131
|
}
|
|
7078
|
-
const runtimeRoot =
|
|
7132
|
+
const runtimeRoot = resolve35(projectRoot, ".rig/runtime/agents");
|
|
7079
7133
|
return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
|
|
7080
7134
|
}
|
|
7081
7135
|
function isTestFile(path) {
|
|
@@ -7123,7 +7177,7 @@ function evaluateScope(policy, context, filePath, access) {
|
|
|
7123
7177
|
return allowed();
|
|
7124
7178
|
}
|
|
7125
7179
|
if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
|
|
7126
|
-
const absPath =
|
|
7180
|
+
const absPath = resolve35(filePath);
|
|
7127
7181
|
if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
|
|
7128
7182
|
const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
|
|
7129
7183
|
const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
|
|
@@ -7355,9 +7409,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
|
|
|
7355
7409
|
async function hydrateRuntimeMemory(options) {
|
|
7356
7410
|
const snapshot = await readCanonicalMemoryDb(options.projectRoot);
|
|
7357
7411
|
const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
|
|
7358
|
-
const hydratedPath =
|
|
7412
|
+
const hydratedPath = resolve36(workspaceLayout.stateDir, "memory", "project-memory.db");
|
|
7359
7413
|
try {
|
|
7360
|
-
await mkdir3(
|
|
7414
|
+
await mkdir3(resolve36(workspaceLayout.stateDir, "memory"), { recursive: true });
|
|
7361
7415
|
await copyFile(snapshot.dbPath, hydratedPath);
|
|
7362
7416
|
return {
|
|
7363
7417
|
canonicalPath: CANONICAL_MEMORY_DB_PATH2,
|
|
@@ -7372,12 +7426,12 @@ async function hydrateRuntimeMemory(options) {
|
|
|
7372
7426
|
}
|
|
7373
7427
|
}
|
|
7374
7428
|
async function createRuntimeTaskRecordReader(options) {
|
|
7375
|
-
const legacyConfigPath =
|
|
7429
|
+
const legacyConfigPath = resolve36(options.projectRoot, ".rig", "task-config.json");
|
|
7376
7430
|
let pluginHostContext = null;
|
|
7377
7431
|
try {
|
|
7378
7432
|
pluginHostContext = await buildPluginHostContext(options.projectRoot);
|
|
7379
7433
|
} catch (error) {
|
|
7380
|
-
if (!
|
|
7434
|
+
if (!existsSync35(legacyConfigPath)) {
|
|
7381
7435
|
throw error;
|
|
7382
7436
|
}
|
|
7383
7437
|
const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -7397,7 +7451,7 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7397
7451
|
source: "plugin"
|
|
7398
7452
|
};
|
|
7399
7453
|
}
|
|
7400
|
-
if (
|
|
7454
|
+
if (existsSync35(legacyConfigPath)) {
|
|
7401
7455
|
const message = "Using source-aware .rig/task-config.json task source compatibility path";
|
|
7402
7456
|
options.diagnostics?.(message);
|
|
7403
7457
|
console.warn(message);
|
|
@@ -7414,10 +7468,10 @@ async function createRuntimeTaskRecordReader(options) {
|
|
|
7414
7468
|
};
|
|
7415
7469
|
}
|
|
7416
7470
|
function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
7417
|
-
const jsonPath =
|
|
7418
|
-
if (
|
|
7471
|
+
const jsonPath = resolve36(projectRoot, "rig.config.json");
|
|
7472
|
+
if (existsSync35(jsonPath)) {
|
|
7419
7473
|
try {
|
|
7420
|
-
const parsed = JSON.parse(
|
|
7474
|
+
const parsed = JSON.parse(readFileSync19(jsonPath, "utf8"));
|
|
7421
7475
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7422
7476
|
const taskSource = parsed.taskSource;
|
|
7423
7477
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -7429,12 +7483,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
|
|
|
7429
7483
|
return null;
|
|
7430
7484
|
}
|
|
7431
7485
|
}
|
|
7432
|
-
const tsPath =
|
|
7433
|
-
if (!
|
|
7486
|
+
const tsPath = resolve36(projectRoot, "rig.config.ts");
|
|
7487
|
+
if (!existsSync35(tsPath)) {
|
|
7434
7488
|
return null;
|
|
7435
7489
|
}
|
|
7436
7490
|
try {
|
|
7437
|
-
const source =
|
|
7491
|
+
const source = readFileSync19(tsPath, "utf8");
|
|
7438
7492
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
7439
7493
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
7440
7494
|
return kind ?? null;
|
|
@@ -7504,8 +7558,8 @@ async function writeRuntimeTaskConfigProjection(options) {
|
|
|
7504
7558
|
...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
|
|
7505
7559
|
...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
|
|
7506
7560
|
};
|
|
7507
|
-
const configPath =
|
|
7508
|
-
await mkdir3(
|
|
7561
|
+
const configPath = resolve36(options.workspaceDir, ".rig", "task-config.json");
|
|
7562
|
+
await mkdir3(resolve36(options.workspaceDir, ".rig"), { recursive: true });
|
|
7509
7563
|
await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
|
|
7510
7564
|
`, "utf-8");
|
|
7511
7565
|
}
|
|
@@ -7569,9 +7623,9 @@ async function ensureAgentRuntime(options) {
|
|
|
7569
7623
|
}
|
|
7570
7624
|
ensureProvisioningHostProjectRootEnv(options.projectRoot);
|
|
7571
7625
|
const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
|
|
7572
|
-
const workspaceDir =
|
|
7626
|
+
const workspaceDir = resolve36(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
|
|
7573
7627
|
const createdAt = new Date().toISOString();
|
|
7574
|
-
if (!
|
|
7628
|
+
if (!existsSync35(resolve36(monorepoRoot, ".git"))) {
|
|
7575
7629
|
throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
|
|
7576
7630
|
}
|
|
7577
7631
|
const taskResolution = await resolveRuntimeTaskRecord({
|
|
@@ -7606,7 +7660,7 @@ async function ensureAgentRuntime(options) {
|
|
|
7606
7660
|
logsDir: overlay.logsDir,
|
|
7607
7661
|
stateDir: overlay.stateDir,
|
|
7608
7662
|
sessionDir: overlay.sessionDir,
|
|
7609
|
-
claudeHomeDir:
|
|
7663
|
+
claudeHomeDir: resolve36(workspaceLayout.homeDir, ".claude"),
|
|
7610
7664
|
contextFile: overlay.contextPath,
|
|
7611
7665
|
binDir: workspaceLayout.binDir,
|
|
7612
7666
|
createdAt
|
|
@@ -7619,10 +7673,14 @@ async function ensureAgentRuntime(options) {
|
|
|
7619
7673
|
projectRoot: options.projectRoot,
|
|
7620
7674
|
workspaceDir
|
|
7621
7675
|
});
|
|
7622
|
-
|
|
7623
|
-
|
|
7676
|
+
mkdirSync22(runtime.binDir, { recursive: true });
|
|
7677
|
+
mkdirSync22(workspaceLayout.distDir, { recursive: true });
|
|
7624
7678
|
prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
|
|
7625
|
-
|
|
7679
|
+
if (options.preserveTaskArtifacts) {
|
|
7680
|
+
console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
|
|
7681
|
+
} else {
|
|
7682
|
+
await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
|
|
7683
|
+
}
|
|
7626
7684
|
const ctx = {
|
|
7627
7685
|
runtimeId: options.id,
|
|
7628
7686
|
taskId: options.taskId,
|
|
@@ -7635,7 +7693,7 @@ async function ensureAgentRuntime(options) {
|
|
|
7635
7693
|
runtimeId: options.id
|
|
7636
7694
|
}),
|
|
7637
7695
|
workspaceDir,
|
|
7638
|
-
artifactRoot:
|
|
7696
|
+
artifactRoot: resolve36(workspaceDir, "artifacts", options.taskId),
|
|
7639
7697
|
hostProjectRoot: options.projectRoot,
|
|
7640
7698
|
monorepoMainRoot: monorepoRoot,
|
|
7641
7699
|
monorepoBaseRef: baseRef,
|
|
@@ -7651,8 +7709,8 @@ async function ensureAgentRuntime(options) {
|
|
|
7651
7709
|
stateDir: overlay.stateDir,
|
|
7652
7710
|
logsDir: overlay.logsDir,
|
|
7653
7711
|
sessionDir: overlay.sessionDir,
|
|
7654
|
-
sessionFile:
|
|
7655
|
-
policyFile:
|
|
7712
|
+
sessionFile: resolve36(overlay.sessionDir, "session.json"),
|
|
7713
|
+
policyFile: resolve36(options.projectRoot, "rig/policy/policy.json"),
|
|
7656
7714
|
binDir: runtime.binDir,
|
|
7657
7715
|
createdAt,
|
|
7658
7716
|
memory
|
|
@@ -7663,9 +7721,9 @@ async function ensureAgentRuntime(options) {
|
|
|
7663
7721
|
task: taskResolution.task,
|
|
7664
7722
|
taskEntry
|
|
7665
7723
|
});
|
|
7666
|
-
const manifestPath =
|
|
7724
|
+
const manifestPath = resolve36(runtimeRoot, "manifest.json");
|
|
7667
7725
|
const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
|
|
7668
|
-
const runtimeAgentBinary =
|
|
7726
|
+
const runtimeAgentBinary = resolve36(runtime.binDir, "rig-agent");
|
|
7669
7727
|
await ensureRigGitBinaryPath();
|
|
7670
7728
|
const bakedInfoOutput = await captureTaskInfoOutput({
|
|
7671
7729
|
projectRoot: options.projectRoot,
|
|
@@ -7680,10 +7738,10 @@ async function ensureAgentRuntime(options) {
|
|
|
7680
7738
|
const bakedStatusOutput = await captureStdout(async () => {
|
|
7681
7739
|
taskStatus(options.projectRoot);
|
|
7682
7740
|
});
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7741
|
+
rmSync14(runtime.binDir, { recursive: true, force: true });
|
|
7742
|
+
rmSync14(workspaceLayout.distDir, { recursive: true, force: true });
|
|
7743
|
+
mkdirSync22(runtime.binDir, { recursive: true });
|
|
7744
|
+
mkdirSync22(workspaceLayout.distDir, { recursive: true });
|
|
7687
7745
|
await buildRuntimeToolchain({
|
|
7688
7746
|
projectRoot: options.projectRoot,
|
|
7689
7747
|
workspaceDir,
|
|
@@ -7720,9 +7778,9 @@ async function ensureAgentRuntime(options) {
|
|
|
7720
7778
|
workspaceDir,
|
|
7721
7779
|
taskEntry
|
|
7722
7780
|
});
|
|
7723
|
-
const sandboxDir =
|
|
7781
|
+
const sandboxDir = resolve36(runtimeRoot, "sandbox");
|
|
7724
7782
|
await mkdir3(sandboxDir, { recursive: true });
|
|
7725
|
-
await writeFile2(
|
|
7783
|
+
await writeFile2(resolve36(runtimeRoot, "runtime.json"), JSON.stringify({
|
|
7726
7784
|
id: options.id,
|
|
7727
7785
|
taskId: options.taskId,
|
|
7728
7786
|
mode: "worktree",
|
|
@@ -7769,7 +7827,7 @@ function isProvisionedRuntimeWorkspace(workspaceDir) {
|
|
|
7769
7827
|
return false;
|
|
7770
7828
|
}
|
|
7771
7829
|
const layout = resolveRuntimeWorkspaceLayout(workspaceDir);
|
|
7772
|
-
return
|
|
7830
|
+
return existsSync36(resolve37(workspaceDir, ".git")) && existsSync36(resolve37(layout.binDir, "rig-agent")) && existsSync36(resolve37(layout.binDir, "hooks", "scope-guard")) && existsSync36(resolve37(layout.sessionDir, "session.json"));
|
|
7773
7831
|
}
|
|
7774
7832
|
async function main() {
|
|
7775
7833
|
const projectRoot = resolveProjectRoot();
|