@h-rig/runtime 0.0.6-alpha.28 → 0.0.6-alpha.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/rig-agent-dispatch.js +552 -483
- package/dist/bin/rig-agent.js +418 -364
- package/dist/src/control-plane/agent-wrapper.js +557 -488
- package/dist/src/control-plane/harness-main.js +559 -1418
- package/dist/src/control-plane/hooks/completion-verification.js +451 -808
- package/dist/src/control-plane/hooks/inject-context.js +191 -137
- package/dist/src/control-plane/hooks/submodule-branch.js +596 -542
- package/dist/src/control-plane/hooks/task-runtime-start.js +596 -542
- package/dist/src/control-plane/materialize-task-config.js +64 -8
- package/dist/src/control-plane/native/git-ops.js +3 -0
- package/dist/src/control-plane/native/harness-cli.js +544 -496
- package/dist/src/control-plane/native/repo-ops.js +3 -0
- package/dist/src/control-plane/native/run-ops.js +3 -0
- package/dist/src/control-plane/native/task-ops.js +418 -370
- package/dist/src/control-plane/native/validator.js +161 -107
- package/dist/src/control-plane/native/verifier.js +217 -169
- package/dist/src/control-plane/pi-sessiond/launcher.js +12 -2
- package/dist/src/control-plane/plugin-host-context.js +54 -0
- package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +3 -0
- package/dist/src/control-plane/runtime/image/index.js +3 -0
- package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +3 -0
- package/dist/src/control-plane/runtime/image.js +3 -0
- package/dist/src/control-plane/runtime/index.js +487 -718
- package/dist/src/control-plane/runtime/isolation/index.js +511 -457
- package/dist/src/control-plane/runtime/isolation.js +511 -457
- package/dist/src/control-plane/runtime/plugin-mode.js +3 -27
- package/dist/src/control-plane/runtime/queue.js +428 -381
- package/dist/src/control-plane/runtime/snapshot/task-run.js +3 -0
- package/dist/src/control-plane/runtime/task-run-snapshot.js +3 -0
- package/dist/src/control-plane/skill-materializer.js +46 -0
- package/dist/src/control-plane/tasks/source-lifecycle.js +84 -30
- package/dist/src/index.js +0 -278
- package/native/darwin-arm64/rig-shell +0 -0
- package/native/darwin-arm64/rig-shell.build-manifest.json +1 -1
- package/native/darwin-arm64/rig-tools +0 -0
- package/native/darwin-arm64/rig-tools.build-manifest.json +1 -1
- package/package.json +8 -7
- package/dist/src/control-plane/runtime/plugins.js +0 -1131
- package/dist/src/plugins.js +0 -329
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
4
|
// packages/runtime/src/control-plane/hooks/inject-context.ts
|
|
5
|
-
import { existsSync as
|
|
6
|
-
import { resolve as
|
|
5
|
+
import { existsSync as existsSync21, readFileSync as readFileSync13 } from "fs";
|
|
6
|
+
import { resolve as resolve22 } from "path";
|
|
7
7
|
import { resolveProjectRoot } from "@rig/hook-kit";
|
|
8
8
|
|
|
9
9
|
// packages/runtime/src/control-plane/memory-sync/db.ts
|
|
@@ -1128,8 +1128,8 @@ async function loadReviewProfile(path) {
|
|
|
1128
1128
|
}
|
|
1129
1129
|
|
|
1130
1130
|
// packages/runtime/src/control-plane/native/repo-ops.ts
|
|
1131
|
-
import { existsSync as
|
|
1132
|
-
import { basename as basename7, dirname as dirname11, resolve as
|
|
1131
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync12, readFileSync as readFileSync12, readdirSync as readdirSync5, rmSync as rmSync5, writeFileSync as writeFileSync10 } from "fs";
|
|
1132
|
+
import { basename as basename7, dirname as dirname11, resolve as resolve21 } from "path";
|
|
1133
1133
|
|
|
1134
1134
|
// packages/runtime/src/control-plane/state-sync/types.ts
|
|
1135
1135
|
var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
|
|
@@ -1626,8 +1626,8 @@ function syncManagedRepo(projectRoot, repoId) {
|
|
|
1626
1626
|
return { layout, headCommit };
|
|
1627
1627
|
}
|
|
1628
1628
|
// packages/runtime/src/control-plane/native/task-ops.ts
|
|
1629
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
1630
|
-
import { resolve as
|
|
1629
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
|
|
1630
|
+
import { resolve as resolve20 } from "path";
|
|
1631
1631
|
|
|
1632
1632
|
// packages/runtime/src/build-time-config.ts
|
|
1633
1633
|
function normalizeBuildConfig(value) {
|
|
@@ -2046,6 +2046,49 @@ function safeReadJson(path) {
|
|
|
2046
2046
|
}
|
|
2047
2047
|
}
|
|
2048
2048
|
|
|
2049
|
+
// packages/runtime/src/control-plane/skill-materializer.ts
|
|
2050
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync5, readdirSync as readdirSync2, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
2051
|
+
import { resolve as resolve13 } from "path";
|
|
2052
|
+
import { loadSkill } from "@rig/skill-loader";
|
|
2053
|
+
var MARKER_FILENAME = ".rig-plugin";
|
|
2054
|
+
function skillDirName(id) {
|
|
2055
|
+
return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
2056
|
+
}
|
|
2057
|
+
async function materializeSkills(projectRoot, entries) {
|
|
2058
|
+
const skillsRoot = resolve13(projectRoot, ".pi", "skills");
|
|
2059
|
+
if (existsSync12(skillsRoot)) {
|
|
2060
|
+
for (const name of readdirSync2(skillsRoot)) {
|
|
2061
|
+
const dir = resolve13(skillsRoot, name);
|
|
2062
|
+
if (existsSync12(resolve13(dir, MARKER_FILENAME))) {
|
|
2063
|
+
rmSync3(dir, { recursive: true, force: true });
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
const written = [];
|
|
2068
|
+
for (const { pluginName, skill } of entries) {
|
|
2069
|
+
const sourcePath = resolve13(projectRoot, skill.path);
|
|
2070
|
+
if (!existsSync12(sourcePath)) {
|
|
2071
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
|
|
2072
|
+
continue;
|
|
2073
|
+
}
|
|
2074
|
+
let body;
|
|
2075
|
+
try {
|
|
2076
|
+
await loadSkill(sourcePath);
|
|
2077
|
+
body = readFileSync5(sourcePath, "utf-8");
|
|
2078
|
+
} catch (err) {
|
|
2079
|
+
console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
|
|
2080
|
+
continue;
|
|
2081
|
+
}
|
|
2082
|
+
const dir = resolve13(skillsRoot, skillDirName(skill.id));
|
|
2083
|
+
mkdirSync9(dir, { recursive: true });
|
|
2084
|
+
writeFileSync5(resolve13(dir, "SKILL.md"), body, "utf-8");
|
|
2085
|
+
writeFileSync5(resolve13(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
|
|
2086
|
+
`, "utf-8");
|
|
2087
|
+
written.push({ id: skill.id, pluginName, directory: dir });
|
|
2088
|
+
}
|
|
2089
|
+
return written;
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2049
2092
|
// packages/runtime/src/control-plane/plugin-host-context.ts
|
|
2050
2093
|
async function buildPluginHostContext(projectRoot) {
|
|
2051
2094
|
let config;
|
|
@@ -2082,6 +2125,17 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2082
2125
|
} catch (err) {
|
|
2083
2126
|
console.warn(`[plugin-host] hook materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2084
2127
|
}
|
|
2128
|
+
try {
|
|
2129
|
+
const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
|
|
2130
|
+
pluginName: plugin.name,
|
|
2131
|
+
skill
|
|
2132
|
+
})));
|
|
2133
|
+
if (skillEntries.length > 0) {
|
|
2134
|
+
await materializeSkills(projectRoot, skillEntries);
|
|
2135
|
+
}
|
|
2136
|
+
} catch (err) {
|
|
2137
|
+
console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
|
|
2138
|
+
}
|
|
2085
2139
|
return {
|
|
2086
2140
|
config,
|
|
2087
2141
|
pluginHost,
|
|
@@ -2095,12 +2149,12 @@ async function buildPluginHostContext(projectRoot) {
|
|
|
2095
2149
|
|
|
2096
2150
|
// packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
|
|
2097
2151
|
import { spawnSync } from "child_process";
|
|
2098
|
-
import { existsSync as
|
|
2099
|
-
import { basename as basename5, join as join4, resolve as
|
|
2152
|
+
import { existsSync as existsSync14, readFileSync as readFileSync7, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
2153
|
+
import { basename as basename5, join as join4, resolve as resolve15 } from "path";
|
|
2100
2154
|
|
|
2101
2155
|
// packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
|
|
2102
|
-
import { existsSync as
|
|
2103
|
-
import { resolve as
|
|
2156
|
+
import { existsSync as existsSync13, readFileSync as readFileSync6 } from "fs";
|
|
2157
|
+
import { resolve as resolve14 } from "path";
|
|
2104
2158
|
|
|
2105
2159
|
// packages/runtime/src/control-plane/tasks/task-record-reader.ts
|
|
2106
2160
|
async function findTaskById(reader, id) {
|
|
@@ -2123,7 +2177,7 @@ class LegacyTaskConfigReadError extends Error {
|
|
|
2123
2177
|
}
|
|
2124
2178
|
}
|
|
2125
2179
|
function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2126
|
-
const configPath = options.configPath ??
|
|
2180
|
+
const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
|
|
2127
2181
|
const reader = {
|
|
2128
2182
|
async listTasks() {
|
|
2129
2183
|
return readLegacyTaskRecords(projectRoot, configPath);
|
|
@@ -2134,8 +2188,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
|
|
|
2134
2188
|
};
|
|
2135
2189
|
return reader;
|
|
2136
2190
|
}
|
|
2137
|
-
function readLegacyTaskRecords(projectRoot, configPath =
|
|
2138
|
-
if (!
|
|
2191
|
+
function readLegacyTaskRecords(projectRoot, configPath = resolve14(projectRoot, ".rig", "task-config.json")) {
|
|
2192
|
+
if (!existsSync13(configPath)) {
|
|
2139
2193
|
return [];
|
|
2140
2194
|
}
|
|
2141
2195
|
const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
|
|
@@ -2143,7 +2197,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve13(projectRoot,
|
|
|
2143
2197
|
}
|
|
2144
2198
|
function readLegacyTaskConfigJson(projectRoot, configPath) {
|
|
2145
2199
|
try {
|
|
2146
|
-
const parsed = JSON.parse(
|
|
2200
|
+
const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
|
|
2147
2201
|
if (isPlainRecord(parsed)) {
|
|
2148
2202
|
return parsed;
|
|
2149
2203
|
}
|
|
@@ -2227,7 +2281,7 @@ function isPlainRecord(candidate) {
|
|
|
2227
2281
|
var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
|
|
2228
2282
|
var FILE_TASK_PATTERN = /\.(task\.)?json$/;
|
|
2229
2283
|
function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
|
|
2230
|
-
const configPath = options.configPath ??
|
|
2284
|
+
const configPath = options.configPath ?? resolve15(projectRoot, ".rig", "task-config.json");
|
|
2231
2285
|
const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
|
|
2232
2286
|
const spawnFn = options.spawn ?? spawnSync;
|
|
2233
2287
|
const ghBinary = options.ghBinary ?? "gh";
|
|
@@ -2310,10 +2364,10 @@ function readMaterializedTaskMetadata(entry) {
|
|
|
2310
2364
|
return metadata;
|
|
2311
2365
|
}
|
|
2312
2366
|
function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
2313
|
-
const jsonPath =
|
|
2314
|
-
if (
|
|
2367
|
+
const jsonPath = resolve15(projectRoot, "rig.config.json");
|
|
2368
|
+
if (existsSync14(jsonPath)) {
|
|
2315
2369
|
try {
|
|
2316
|
-
const parsed = JSON.parse(
|
|
2370
|
+
const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
|
|
2317
2371
|
if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
|
|
2318
2372
|
const source = parsed.taskSource;
|
|
2319
2373
|
return source.kind === "files" && typeof source.path === "string" ? source.path : null;
|
|
@@ -2322,12 +2376,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
|
|
|
2322
2376
|
return null;
|
|
2323
2377
|
}
|
|
2324
2378
|
}
|
|
2325
|
-
const tsPath =
|
|
2326
|
-
if (!
|
|
2379
|
+
const tsPath = resolve15(projectRoot, "rig.config.ts");
|
|
2380
|
+
if (!existsSync14(tsPath)) {
|
|
2327
2381
|
return null;
|
|
2328
2382
|
}
|
|
2329
2383
|
try {
|
|
2330
|
-
const source =
|
|
2384
|
+
const source = readFileSync7(tsPath, "utf8");
|
|
2331
2385
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
2332
2386
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
2333
2387
|
if (kind !== "files") {
|
|
@@ -2347,10 +2401,10 @@ function readRawTaskEntry(configPath, taskId) {
|
|
|
2347
2401
|
return isPlainRecord2(entry) ? entry : null;
|
|
2348
2402
|
}
|
|
2349
2403
|
function readRawTaskConfig(configPath) {
|
|
2350
|
-
if (!
|
|
2404
|
+
if (!existsSync14(configPath)) {
|
|
2351
2405
|
return null;
|
|
2352
2406
|
}
|
|
2353
|
-
const parsed = JSON.parse(
|
|
2407
|
+
const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
|
|
2354
2408
|
return isPlainRecord2(parsed) ? parsed : null;
|
|
2355
2409
|
}
|
|
2356
2410
|
function stripLegacyTaskConfigMetadata2(raw) {
|
|
@@ -2358,12 +2412,12 @@ function stripLegacyTaskConfigMetadata2(raw) {
|
|
|
2358
2412
|
return tasks;
|
|
2359
2413
|
}
|
|
2360
2414
|
function listFileBackedTasks(projectRoot, sourcePath) {
|
|
2361
|
-
const directory =
|
|
2362
|
-
if (!
|
|
2415
|
+
const directory = resolve15(projectRoot, sourcePath);
|
|
2416
|
+
if (!existsSync14(directory)) {
|
|
2363
2417
|
return [];
|
|
2364
2418
|
}
|
|
2365
2419
|
const tasks = [];
|
|
2366
|
-
for (const name of
|
|
2420
|
+
for (const name of readdirSync3(directory)) {
|
|
2367
2421
|
if (!FILE_TASK_PATTERN.test(name))
|
|
2368
2422
|
continue;
|
|
2369
2423
|
const inferredId = basename5(name).replace(FILE_TASK_PATTERN, "");
|
|
@@ -2374,11 +2428,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
|
|
|
2374
2428
|
return tasks;
|
|
2375
2429
|
}
|
|
2376
2430
|
function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
2377
|
-
const file = findFileBackedTaskFile(
|
|
2431
|
+
const file = findFileBackedTaskFile(resolve15(projectRoot, sourcePath), taskId);
|
|
2378
2432
|
if (!file) {
|
|
2379
2433
|
return null;
|
|
2380
2434
|
}
|
|
2381
|
-
const raw = JSON.parse(
|
|
2435
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
2382
2436
|
if (!isPlainRecord2(raw)) {
|
|
2383
2437
|
return null;
|
|
2384
2438
|
}
|
|
@@ -2391,17 +2445,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
|
|
|
2391
2445
|
};
|
|
2392
2446
|
}
|
|
2393
2447
|
function findFileBackedTaskFile(directory, taskId) {
|
|
2394
|
-
if (!
|
|
2448
|
+
if (!existsSync14(directory)) {
|
|
2395
2449
|
return null;
|
|
2396
2450
|
}
|
|
2397
|
-
for (const name of
|
|
2451
|
+
for (const name of readdirSync3(directory)) {
|
|
2398
2452
|
if (!FILE_TASK_PATTERN.test(name))
|
|
2399
2453
|
continue;
|
|
2400
2454
|
const file = join4(directory, name);
|
|
2401
2455
|
try {
|
|
2402
2456
|
if (!statSync3(file).isFile())
|
|
2403
2457
|
continue;
|
|
2404
|
-
const raw = JSON.parse(
|
|
2458
|
+
const raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
2405
2459
|
const inferredId = basename5(file).replace(FILE_TASK_PATTERN, "");
|
|
2406
2460
|
const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
|
|
2407
2461
|
if (id === taskId) {
|
|
@@ -2561,30 +2615,30 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
|
|
|
2561
2615
|
}
|
|
2562
2616
|
|
|
2563
2617
|
// packages/runtime/src/control-plane/native/task-state.ts
|
|
2564
|
-
import { existsSync as
|
|
2565
|
-
import { basename as basename6, resolve as
|
|
2618
|
+
import { existsSync as existsSync18, readFileSync as readFileSync10, readdirSync as readdirSync4, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
|
|
2619
|
+
import { basename as basename6, resolve as resolve19 } from "path";
|
|
2566
2620
|
// packages/runtime/src/control-plane/state-sync/read.ts
|
|
2567
|
-
import { existsSync as
|
|
2568
|
-
import { resolve as
|
|
2621
|
+
import { existsSync as existsSync17, readFileSync as readFileSync9 } from "fs";
|
|
2622
|
+
import { resolve as resolve18 } from "path";
|
|
2569
2623
|
|
|
2570
2624
|
// packages/runtime/src/control-plane/native/git-native.ts
|
|
2571
|
-
import { chmodSync as chmodSync2, copyFileSync as copyFileSync3, existsSync as
|
|
2625
|
+
import { chmodSync as chmodSync2, copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync8, renameSync as renameSync2, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
2572
2626
|
import { tmpdir as tmpdir4 } from "os";
|
|
2573
|
-
import { dirname as dirname10, isAbsolute, resolve as
|
|
2627
|
+
import { dirname as dirname10, isAbsolute, resolve as resolve16 } from "path";
|
|
2574
2628
|
import { createHash as createHash2 } from "crypto";
|
|
2575
|
-
var sharedGitNativeOutputDir =
|
|
2576
|
-
var sharedGitNativeOutputPath =
|
|
2629
|
+
var sharedGitNativeOutputDir = resolve16(tmpdir4(), "rig-native");
|
|
2630
|
+
var sharedGitNativeOutputPath = resolve16(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
2577
2631
|
var trackerCommandUsageProbe = "usage: rig-git fetch-ref <repo-path> <remote> <branch>";
|
|
2578
2632
|
function temporaryGitBinaryOutputPath(outputPath) {
|
|
2579
2633
|
const suffix2 = process.platform === "win32" ? ".exe" : "";
|
|
2580
|
-
return
|
|
2634
|
+
return resolve16(dirname10(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix2}`);
|
|
2581
2635
|
}
|
|
2582
2636
|
function publishGitBinary(tempOutputPath, outputPath) {
|
|
2583
2637
|
try {
|
|
2584
2638
|
renameSync2(tempOutputPath, outputPath);
|
|
2585
2639
|
} catch (error) {
|
|
2586
|
-
if (process.platform === "win32" &&
|
|
2587
|
-
|
|
2640
|
+
if (process.platform === "win32" && existsSync15(outputPath)) {
|
|
2641
|
+
rmSync4(outputPath, { force: true });
|
|
2588
2642
|
renameSync2(tempOutputPath, outputPath);
|
|
2589
2643
|
return;
|
|
2590
2644
|
}
|
|
@@ -2599,22 +2653,22 @@ function rigGitSourceCandidates() {
|
|
|
2599
2653
|
const cwd = process.cwd()?.trim() || "";
|
|
2600
2654
|
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
2601
2655
|
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
2602
|
-
const moduleRelativeSource =
|
|
2656
|
+
const moduleRelativeSource = resolve16(import.meta.dir, "../../../native/rig-git.zig");
|
|
2603
2657
|
return [...new Set([
|
|
2604
2658
|
process.env.RIG_NATIVE_GIT_SOURCE?.trim() || "",
|
|
2605
2659
|
moduleRelativeSource,
|
|
2606
|
-
projectRoot ?
|
|
2607
|
-
hostProjectRoot ?
|
|
2608
|
-
cwd ?
|
|
2609
|
-
execDir ?
|
|
2610
|
-
execDir ?
|
|
2660
|
+
projectRoot ? resolve16(projectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
2661
|
+
hostProjectRoot ? resolve16(hostProjectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
2662
|
+
cwd ? resolve16(cwd, "packages/runtime/native/rig-git.zig") : "",
|
|
2663
|
+
execDir ? resolve16(execDir, "..", "..", "packages/runtime/native/rig-git.zig") : "",
|
|
2664
|
+
execDir ? resolve16(execDir, "..", "native", "rig-git.zig") : ""
|
|
2611
2665
|
].filter(Boolean))];
|
|
2612
2666
|
}
|
|
2613
2667
|
function nativePackageBinaryCandidates(fromDir, fileName) {
|
|
2614
2668
|
const candidates = [];
|
|
2615
|
-
let cursor =
|
|
2669
|
+
let cursor = resolve16(fromDir);
|
|
2616
2670
|
for (let index = 0;index < 8; index += 1) {
|
|
2617
|
-
candidates.push(
|
|
2671
|
+
candidates.push(resolve16(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve16(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve16(cursor, "native", fileName), resolve16(cursor, "native", "bin", fileName));
|
|
2618
2672
|
const parent = dirname10(cursor);
|
|
2619
2673
|
if (parent === cursor)
|
|
2620
2674
|
break;
|
|
@@ -2629,15 +2683,15 @@ function rigGitBinaryCandidates() {
|
|
|
2629
2683
|
return [...new Set([
|
|
2630
2684
|
explicit,
|
|
2631
2685
|
...nativePackageBinaryCandidates(import.meta.dir, fileName),
|
|
2632
|
-
execDir ?
|
|
2633
|
-
execDir ?
|
|
2634
|
-
execDir ?
|
|
2686
|
+
execDir ? resolve16(execDir, fileName) : "",
|
|
2687
|
+
execDir ? resolve16(execDir, "..", fileName) : "",
|
|
2688
|
+
execDir ? resolve16(execDir, "..", "bin", fileName) : "",
|
|
2635
2689
|
sharedGitNativeOutputPath
|
|
2636
2690
|
].filter(Boolean))];
|
|
2637
2691
|
}
|
|
2638
2692
|
function resolveGitSourcePath() {
|
|
2639
2693
|
for (const candidate of rigGitSourceCandidates()) {
|
|
2640
|
-
if (candidate &&
|
|
2694
|
+
if (candidate && existsSync15(candidate)) {
|
|
2641
2695
|
return candidate;
|
|
2642
2696
|
}
|
|
2643
2697
|
}
|
|
@@ -2648,7 +2702,7 @@ function resolveGitBinaryPath() {
|
|
|
2648
2702
|
return null;
|
|
2649
2703
|
}
|
|
2650
2704
|
for (const candidate of rigGitBinaryCandidates()) {
|
|
2651
|
-
if (candidate &&
|
|
2705
|
+
if (candidate && existsSync15(candidate)) {
|
|
2652
2706
|
return candidate;
|
|
2653
2707
|
}
|
|
2654
2708
|
}
|
|
@@ -2678,18 +2732,18 @@ function nativeBuildManifestPath(outputPath) {
|
|
|
2678
2732
|
return `${outputPath}.build-manifest.json`;
|
|
2679
2733
|
}
|
|
2680
2734
|
function hasMatchingNativeBuildManifestSync(manifestPath, buildKey) {
|
|
2681
|
-
if (!
|
|
2735
|
+
if (!existsSync15(manifestPath)) {
|
|
2682
2736
|
return false;
|
|
2683
2737
|
}
|
|
2684
2738
|
try {
|
|
2685
|
-
const manifest = JSON.parse(
|
|
2739
|
+
const manifest = JSON.parse(readFileSync8(manifestPath, "utf8"));
|
|
2686
2740
|
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
2687
2741
|
} catch {
|
|
2688
2742
|
return false;
|
|
2689
2743
|
}
|
|
2690
2744
|
}
|
|
2691
2745
|
function sha256FileSync(path) {
|
|
2692
|
-
return createHash2("sha256").update(
|
|
2746
|
+
return createHash2("sha256").update(readFileSync8(path)).digest("hex");
|
|
2693
2747
|
}
|
|
2694
2748
|
function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath()) {
|
|
2695
2749
|
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
@@ -2707,7 +2761,7 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
|
|
|
2707
2761
|
if (!zigBinary) {
|
|
2708
2762
|
throw new Error("zig is required to build native Rig git tools.");
|
|
2709
2763
|
}
|
|
2710
|
-
|
|
2764
|
+
mkdirSync10(dirname10(outputPath), { recursive: true });
|
|
2711
2765
|
const sourceDigest = sha256FileSync(sourcePath);
|
|
2712
2766
|
const buildKey = JSON.stringify({
|
|
2713
2767
|
version: 1,
|
|
@@ -2718,7 +2772,7 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
|
|
|
2718
2772
|
sourceDigest
|
|
2719
2773
|
});
|
|
2720
2774
|
const manifestPath = nativeBuildManifestPath(outputPath);
|
|
2721
|
-
const needsBuild = !
|
|
2775
|
+
const needsBuild = !existsSync15(outputPath) || !hasMatchingNativeBuildManifestSync(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
2722
2776
|
if (!needsBuild) {
|
|
2723
2777
|
chmodSync2(outputPath, 493);
|
|
2724
2778
|
return outputPath;
|
|
@@ -2736,7 +2790,7 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
|
|
|
2736
2790
|
stdout: "pipe",
|
|
2737
2791
|
stderr: "pipe"
|
|
2738
2792
|
});
|
|
2739
|
-
if (build.exitCode !== 0 || !
|
|
2793
|
+
if (build.exitCode !== 0 || !existsSync15(tempOutputPath)) {
|
|
2740
2794
|
const stderr = build.stderr.toString().trim();
|
|
2741
2795
|
const stdout = build.stdout.toString().trim();
|
|
2742
2796
|
const details = [stderr, stdout].filter(Boolean).join(`
|
|
@@ -2744,17 +2798,17 @@ function ensureRigGitBinaryPathSync(outputPath = preferredGitBinaryOutputPath())
|
|
|
2744
2798
|
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${build.exitCode}`}`);
|
|
2745
2799
|
}
|
|
2746
2800
|
chmodSync2(tempOutputPath, 493);
|
|
2747
|
-
if (
|
|
2748
|
-
|
|
2801
|
+
if (existsSync15(outputPath) && hasMatchingNativeBuildManifestSync(manifestPath, buildKey)) {
|
|
2802
|
+
rmSync4(tempOutputPath, { force: true });
|
|
2749
2803
|
chmodSync2(outputPath, 493);
|
|
2750
2804
|
return outputPath;
|
|
2751
2805
|
}
|
|
2752
2806
|
publishGitBinary(tempOutputPath, outputPath);
|
|
2753
2807
|
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
2754
|
-
|
|
2808
|
+
rmSync4(outputPath, { force: true });
|
|
2755
2809
|
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
2756
2810
|
}
|
|
2757
|
-
|
|
2811
|
+
writeFileSync7(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
2758
2812
|
`, "utf8");
|
|
2759
2813
|
return outputPath;
|
|
2760
2814
|
}
|
|
@@ -2776,7 +2830,7 @@ function runGitNative(command, args) {
|
|
|
2776
2830
|
}
|
|
2777
2831
|
} else {
|
|
2778
2832
|
const explicitBinaryPath = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
2779
|
-
binaryPath = explicitBinaryPath &&
|
|
2833
|
+
binaryPath = explicitBinaryPath && existsSync15(explicitBinaryPath) ? explicitBinaryPath : !explicitBinaryPath ? resolveGitBinaryPath() : null;
|
|
2780
2834
|
if (!binaryPath) {
|
|
2781
2835
|
try {
|
|
2782
2836
|
binaryPath = ensureRigGitBinaryPathSync(preferredGitBinaryOutputPath());
|
|
@@ -2832,25 +2886,25 @@ function nativeFetchRef(repoPath, remote, branch) {
|
|
|
2832
2886
|
return requireGitNativeString("fetch-ref", [repoPath, remote, branch]);
|
|
2833
2887
|
}
|
|
2834
2888
|
function nativeReadBlobAtRef(repoPath, ref, path) {
|
|
2835
|
-
const requestDir =
|
|
2836
|
-
|
|
2837
|
-
const outputPath =
|
|
2889
|
+
const requestDir = resolve16(sharedGitNativeOutputDir, "reads", `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
|
|
2890
|
+
mkdirSync10(requestDir, { recursive: true });
|
|
2891
|
+
const outputPath = resolve16(requestDir, "blob.txt");
|
|
2838
2892
|
try {
|
|
2839
2893
|
requireGitNative("read-blob-at-ref", [repoPath, ref, path, outputPath]);
|
|
2840
|
-
return
|
|
2894
|
+
return readFileSync8(outputPath, "utf8");
|
|
2841
2895
|
} finally {
|
|
2842
|
-
|
|
2896
|
+
rmSync4(requestDir, { recursive: true, force: true });
|
|
2843
2897
|
}
|
|
2844
2898
|
}
|
|
2845
2899
|
|
|
2846
2900
|
// packages/runtime/src/control-plane/state-sync/repo.ts
|
|
2847
|
-
import { existsSync as
|
|
2848
|
-
import { resolve as
|
|
2901
|
+
import { existsSync as existsSync16 } from "fs";
|
|
2902
|
+
import { resolve as resolve17 } from "path";
|
|
2849
2903
|
function resolveTrackerRepoPath(projectRoot) {
|
|
2850
2904
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
2851
2905
|
try {
|
|
2852
2906
|
const layout = resolveMonorepoRepoLayout(projectRoot);
|
|
2853
|
-
if (
|
|
2907
|
+
if (existsSync16(resolve17(layout.mirrorRoot, "HEAD"))) {
|
|
2854
2908
|
return layout.mirrorRoot;
|
|
2855
2909
|
}
|
|
2856
2910
|
} catch {}
|
|
@@ -2861,8 +2915,8 @@ function resolveTrackerRepoPath(projectRoot) {
|
|
|
2861
2915
|
var DEFAULT_READ_DEPS = {
|
|
2862
2916
|
fetchRef: nativeFetchRef,
|
|
2863
2917
|
readBlobAtRef: nativeReadBlobAtRef,
|
|
2864
|
-
exists:
|
|
2865
|
-
readFile: (path) =>
|
|
2918
|
+
exists: existsSync17,
|
|
2919
|
+
readFile: (path) => readFileSync9(path, "utf8")
|
|
2866
2920
|
};
|
|
2867
2921
|
function parseIssueStatus(rawStatus) {
|
|
2868
2922
|
const normalized = normalizeTaskLifecycleStatus(rawStatus);
|
|
@@ -2943,12 +2997,12 @@ function shouldPreferLocalTrackerState(options) {
|
|
|
2943
2997
|
if (runtimeContextPath) {
|
|
2944
2998
|
return true;
|
|
2945
2999
|
}
|
|
2946
|
-
return
|
|
3000
|
+
return existsSync17(resolve18(runtimeWorkspace, ".rig", "runtime-context.json"));
|
|
2947
3001
|
}
|
|
2948
3002
|
function readLocalTrackerState(projectRoot, deps) {
|
|
2949
3003
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
2950
|
-
const issuesPath =
|
|
2951
|
-
const taskStatePath =
|
|
3004
|
+
const issuesPath = resolve18(monorepoRoot, ".beads", "issues.jsonl");
|
|
3005
|
+
const taskStatePath = resolve18(monorepoRoot, ".beads", "task-state.json");
|
|
2952
3006
|
return projectSyncedTrackerSnapshot({
|
|
2953
3007
|
source: "local",
|
|
2954
3008
|
issuesBaseOid: null,
|
|
@@ -3010,7 +3064,7 @@ function readValidationDescriptions(projectRoot) {
|
|
|
3010
3064
|
return readValidationDescriptionMap(raw);
|
|
3011
3065
|
}
|
|
3012
3066
|
function readSourceValidationDescriptions(projectRoot) {
|
|
3013
|
-
const rootRaw = readJsonFile(
|
|
3067
|
+
const rootRaw = readJsonFile(resolve19(projectRoot, "rig", "task-config.json"), {});
|
|
3014
3068
|
const sourcePath = findSourceTaskConfigPath(projectRoot);
|
|
3015
3069
|
const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
|
|
3016
3070
|
const rootDescriptions = readValidationDescriptionMap(rootRaw);
|
|
@@ -3086,15 +3140,15 @@ function readValidationDescriptionsFromMeta(meta) {
|
|
|
3086
3140
|
return meta.validation_descriptions;
|
|
3087
3141
|
}
|
|
3088
3142
|
function readLocalSourceTaskStateEnvelope(projectRoot) {
|
|
3089
|
-
const taskStatePath =
|
|
3143
|
+
const taskStatePath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
|
|
3090
3144
|
return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
|
|
3091
3145
|
}
|
|
3092
3146
|
function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
|
|
3093
|
-
const issuesPath =
|
|
3094
|
-
if (!
|
|
3147
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3148
|
+
if (!existsSync18(issuesPath)) {
|
|
3095
3149
|
return null;
|
|
3096
3150
|
}
|
|
3097
|
-
for (const line of
|
|
3151
|
+
for (const line of readFileSync10(issuesPath, "utf8").split(/\r?\n/)) {
|
|
3098
3152
|
const trimmed = line.trim();
|
|
3099
3153
|
if (!trimmed) {
|
|
3100
3154
|
continue;
|
|
@@ -3119,25 +3173,25 @@ function inferTaskIdFromRuntimePath(path) {
|
|
|
3119
3173
|
function artifactDirForId(projectRoot, id) {
|
|
3120
3174
|
const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
3121
3175
|
if (workspaceDir) {
|
|
3122
|
-
const worktreeArtifacts =
|
|
3123
|
-
if (
|
|
3176
|
+
const worktreeArtifacts = resolve19(workspaceDir, "artifacts", id);
|
|
3177
|
+
if (existsSync18(worktreeArtifacts) || existsSync18(resolve19(workspaceDir, "artifacts"))) {
|
|
3124
3178
|
return worktreeArtifacts;
|
|
3125
3179
|
}
|
|
3126
3180
|
}
|
|
3127
3181
|
try {
|
|
3128
3182
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3129
|
-
return
|
|
3183
|
+
return resolve19(paths.artifactsDir, id);
|
|
3130
3184
|
} catch {
|
|
3131
|
-
return
|
|
3185
|
+
return resolve19(resolveMonorepoRoot2(projectRoot), "artifacts", id);
|
|
3132
3186
|
}
|
|
3133
3187
|
}
|
|
3134
3188
|
function resolveTaskConfigPath(projectRoot) {
|
|
3135
3189
|
const paths = resolveHarnessPaths(projectRoot);
|
|
3136
|
-
if (
|
|
3190
|
+
if (existsSync18(paths.taskConfigPath)) {
|
|
3137
3191
|
return paths.taskConfigPath;
|
|
3138
3192
|
}
|
|
3139
3193
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3140
|
-
if (
|
|
3194
|
+
if (existsSync18(candidate)) {
|
|
3141
3195
|
return candidate;
|
|
3142
3196
|
}
|
|
3143
3197
|
}
|
|
@@ -3145,7 +3199,7 @@ function resolveTaskConfigPath(projectRoot) {
|
|
|
3145
3199
|
}
|
|
3146
3200
|
function findSourceTaskConfigPath(projectRoot) {
|
|
3147
3201
|
for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
|
|
3148
|
-
if (
|
|
3202
|
+
if (existsSync18(candidate)) {
|
|
3149
3203
|
return candidate;
|
|
3150
3204
|
}
|
|
3151
3205
|
}
|
|
@@ -3158,7 +3212,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
|
|
|
3158
3212
|
const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
|
|
3159
3213
|
if (sourcePath && synced.updated) {
|
|
3160
3214
|
try {
|
|
3161
|
-
|
|
3215
|
+
writeFileSync8(sourcePath, `${JSON.stringify(synced.config, null, 2)}
|
|
3162
3216
|
`, "utf-8");
|
|
3163
3217
|
} catch {}
|
|
3164
3218
|
}
|
|
@@ -3210,12 +3264,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
|
|
|
3210
3264
|
return !candidate.role;
|
|
3211
3265
|
}
|
|
3212
3266
|
function readSourceIssueRecords(projectRoot) {
|
|
3213
|
-
const issuesPath =
|
|
3214
|
-
if (!
|
|
3267
|
+
const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
|
|
3268
|
+
if (!existsSync18(issuesPath)) {
|
|
3215
3269
|
return [];
|
|
3216
3270
|
}
|
|
3217
3271
|
const records = [];
|
|
3218
|
-
for (const line of
|
|
3272
|
+
for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
3219
3273
|
const trimmed = line.trim();
|
|
3220
3274
|
if (!trimmed) {
|
|
3221
3275
|
continue;
|
|
@@ -3271,19 +3325,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
|
|
|
3271
3325
|
if (!sourcePath) {
|
|
3272
3326
|
return {};
|
|
3273
3327
|
}
|
|
3274
|
-
const directory =
|
|
3275
|
-
if (!
|
|
3328
|
+
const directory = resolve19(projectRoot, sourcePath);
|
|
3329
|
+
if (!existsSync18(directory)) {
|
|
3276
3330
|
return {};
|
|
3277
3331
|
}
|
|
3278
3332
|
const config = {};
|
|
3279
|
-
for (const name of
|
|
3333
|
+
for (const name of readdirSync4(directory)) {
|
|
3280
3334
|
if (!FILE_TASK_PATTERN2.test(name))
|
|
3281
3335
|
continue;
|
|
3282
|
-
const file =
|
|
3336
|
+
const file = resolve19(directory, name);
|
|
3283
3337
|
try {
|
|
3284
3338
|
if (!statSync4(file).isFile())
|
|
3285
3339
|
continue;
|
|
3286
|
-
const raw = JSON.parse(
|
|
3340
|
+
const raw = JSON.parse(readFileSync10(file, "utf8"));
|
|
3287
3341
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
3288
3342
|
continue;
|
|
3289
3343
|
const record = raw;
|
|
@@ -3325,10 +3379,10 @@ function firstStringList2(...candidates) {
|
|
|
3325
3379
|
return [];
|
|
3326
3380
|
}
|
|
3327
3381
|
function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
3328
|
-
const jsonPath =
|
|
3329
|
-
if (
|
|
3382
|
+
const jsonPath = resolve19(projectRoot, "rig.config.json");
|
|
3383
|
+
if (existsSync18(jsonPath)) {
|
|
3330
3384
|
try {
|
|
3331
|
-
const parsed = JSON.parse(
|
|
3385
|
+
const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
|
|
3332
3386
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3333
3387
|
const taskSource = parsed.taskSource;
|
|
3334
3388
|
if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
|
|
@@ -3340,12 +3394,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3340
3394
|
return null;
|
|
3341
3395
|
}
|
|
3342
3396
|
}
|
|
3343
|
-
const tsPath =
|
|
3344
|
-
if (!
|
|
3397
|
+
const tsPath = resolve19(projectRoot, "rig.config.ts");
|
|
3398
|
+
if (!existsSync18(tsPath)) {
|
|
3345
3399
|
return null;
|
|
3346
3400
|
}
|
|
3347
3401
|
try {
|
|
3348
|
-
const source =
|
|
3402
|
+
const source = readFileSync10(tsPath, "utf8");
|
|
3349
3403
|
const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
|
|
3350
3404
|
const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
|
|
3351
3405
|
if (kind !== "files") {
|
|
@@ -3359,9 +3413,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
|
|
|
3359
3413
|
function sourceTaskConfigCandidates(projectRoot) {
|
|
3360
3414
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
3361
3415
|
return [
|
|
3362
|
-
runtimeContext?.monorepoMainRoot ?
|
|
3363
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
3364
|
-
|
|
3416
|
+
runtimeContext?.monorepoMainRoot ? resolve19(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
3417
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve19(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
3418
|
+
resolve19(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
|
|
3365
3419
|
].filter(Boolean);
|
|
3366
3420
|
}
|
|
3367
3421
|
|
|
@@ -3660,16 +3714,16 @@ async function taskDeps(projectRoot, taskId) {
|
|
|
3660
3714
|
for (const dep of deps) {
|
|
3661
3715
|
const artifactDir = artifactDirForId(projectRoot, dep);
|
|
3662
3716
|
console.log(`=== ${dep} ===`);
|
|
3663
|
-
if (!
|
|
3717
|
+
if (!existsSync19(artifactDir)) {
|
|
3664
3718
|
console.log(` (no artifacts yet)
|
|
3665
3719
|
`);
|
|
3666
3720
|
continue;
|
|
3667
3721
|
}
|
|
3668
|
-
printArtifactSection(
|
|
3669
|
-
printArtifactSection(
|
|
3670
|
-
const changedFiles =
|
|
3671
|
-
if (
|
|
3672
|
-
const lines =
|
|
3722
|
+
printArtifactSection(resolve20(artifactDir, "decision-log.md"), "--- Decisions ---");
|
|
3723
|
+
printArtifactSection(resolve20(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
|
|
3724
|
+
const changedFiles = resolve20(artifactDir, "changed-files.txt");
|
|
3725
|
+
if (existsSync19(changedFiles)) {
|
|
3726
|
+
const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
|
|
3673
3727
|
console.log(`--- Changed Files (${lines.length}) ---`);
|
|
3674
3728
|
for (const line of lines) {
|
|
3675
3729
|
console.log(line);
|
|
@@ -3770,12 +3824,12 @@ function printIndented(text) {
|
|
|
3770
3824
|
}
|
|
3771
3825
|
}
|
|
3772
3826
|
function readLocalBeadsTasks(projectRoot) {
|
|
3773
|
-
const issuesPath =
|
|
3774
|
-
if (!
|
|
3827
|
+
const issuesPath = resolve20(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
|
|
3828
|
+
if (!existsSync19(issuesPath)) {
|
|
3775
3829
|
return [];
|
|
3776
3830
|
}
|
|
3777
3831
|
const tasks = [];
|
|
3778
|
-
for (const line of
|
|
3832
|
+
for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
|
|
3779
3833
|
const trimmed = line.trim();
|
|
3780
3834
|
if (!trimmed) {
|
|
3781
3835
|
continue;
|
|
@@ -3888,11 +3942,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
|
|
|
3888
3942
|
return [...ids].sort();
|
|
3889
3943
|
}
|
|
3890
3944
|
function printArtifactSection(path, header) {
|
|
3891
|
-
if (!
|
|
3945
|
+
if (!existsSync19(path)) {
|
|
3892
3946
|
return;
|
|
3893
3947
|
}
|
|
3894
3948
|
console.log(header);
|
|
3895
|
-
process.stdout.write(
|
|
3949
|
+
process.stdout.write(readFileSync11(path, "utf-8"));
|
|
3896
3950
|
console.log("");
|
|
3897
3951
|
}
|
|
3898
3952
|
|
|
@@ -3918,7 +3972,7 @@ function repoDiscover(projectRoot, taskId) {
|
|
|
3918
3972
|
}
|
|
3919
3973
|
function repoBaseline(projectRoot, refresh = false) {
|
|
3920
3974
|
const paths = resolveRepoDiscoveryPaths(projectRoot);
|
|
3921
|
-
if (!refresh &&
|
|
3975
|
+
if (!refresh && existsSync20(paths.baseRepoPinsPath)) {
|
|
3922
3976
|
const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
|
|
3923
3977
|
return baseline.repos || {};
|
|
3924
3978
|
}
|
|
@@ -3932,8 +3986,8 @@ function repoBaseline(projectRoot, refresh = false) {
|
|
|
3932
3986
|
}
|
|
3933
3987
|
function persistBaselinePins(projectRoot, repos) {
|
|
3934
3988
|
const paths = resolveRepoDiscoveryPaths(projectRoot);
|
|
3935
|
-
|
|
3936
|
-
|
|
3989
|
+
mkdirSync12(resolve21(paths.baseRepoPinsPath, ".."), { recursive: true });
|
|
3990
|
+
writeFileSync10(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
|
|
3937
3991
|
`, "utf-8");
|
|
3938
3992
|
return repos;
|
|
3939
3993
|
}
|
|
@@ -4005,28 +4059,28 @@ function readRepoDiscoveryTaskConfig(projectRoot) {
|
|
|
4005
4059
|
function resolveRepoDiscoveryPaths(projectRoot) {
|
|
4006
4060
|
const monorepoRoot = resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
|
|
4007
4061
|
const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
|
|
4008
|
-
const normalizedProjectRoot =
|
|
4062
|
+
const normalizedProjectRoot = resolve21(projectRoot);
|
|
4009
4063
|
const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
|
|
4010
|
-
const stateDir =
|
|
4064
|
+
const stateDir = resolve21(hostProjectRoot, ".rig", "state");
|
|
4011
4065
|
return {
|
|
4012
4066
|
monorepoRoot,
|
|
4013
|
-
taskRepoCommitsPath:
|
|
4014
|
-
baseRepoPinsPath:
|
|
4067
|
+
taskRepoCommitsPath: resolve21(stateDir, "task-repo-commits.json"),
|
|
4068
|
+
baseRepoPinsPath: resolve21(stateDir, "base-repo-pins.json")
|
|
4015
4069
|
};
|
|
4016
4070
|
}
|
|
4017
4071
|
function shouldUseHostProjectStateRoot(projectRoot) {
|
|
4018
4072
|
const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
4019
|
-
if (runtimeWorkspace &&
|
|
4073
|
+
if (runtimeWorkspace && resolve21(runtimeWorkspace) === projectRoot) {
|
|
4020
4074
|
return true;
|
|
4021
4075
|
}
|
|
4022
4076
|
return basename7(dirname11(projectRoot)) === ".worktrees";
|
|
4023
4077
|
}
|
|
4024
4078
|
function readPinFromArtifact(projectRoot, depTask, repoKey) {
|
|
4025
|
-
const snapshot =
|
|
4026
|
-
if (!
|
|
4079
|
+
const snapshot = resolve21(artifactDirForId(projectRoot, depTask), "git-state.txt");
|
|
4080
|
+
if (!existsSync20(snapshot)) {
|
|
4027
4081
|
return "";
|
|
4028
4082
|
}
|
|
4029
|
-
const content =
|
|
4083
|
+
const content = readFileSync12(snapshot, "utf-8");
|
|
4030
4084
|
const chunk = content.split(/\r?\n/);
|
|
4031
4085
|
let inSection = false;
|
|
4032
4086
|
for (const line of chunk) {
|
|
@@ -4055,7 +4109,7 @@ function defaultMemoryQuery(taskId, runtimeContext) {
|
|
|
4055
4109
|
async function printSharedMemorySection(taskId) {
|
|
4056
4110
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
4057
4111
|
const memory = runtimeContext?.memory;
|
|
4058
|
-
if (!memory?.hydratedPath || !
|
|
4112
|
+
if (!memory?.hydratedPath || !existsSync21(memory.hydratedPath)) {
|
|
4059
4113
|
return;
|
|
4060
4114
|
}
|
|
4061
4115
|
const db = await openMemoryDb(memory.hydratedPath);
|
|
@@ -4102,17 +4156,17 @@ async function main() {
|
|
|
4102
4156
|
console.log("(no explicit/discovered task pins)");
|
|
4103
4157
|
} else {
|
|
4104
4158
|
for (const [key, expected] of Object.entries(pins)) {
|
|
4105
|
-
const repoPath = key.startsWith("/") ? key :
|
|
4159
|
+
const repoPath = key.startsWith("/") ? key : resolve22(projectRoot, key);
|
|
4106
4160
|
let current = "missing";
|
|
4107
|
-
if (
|
|
4161
|
+
if (existsSync21(resolve22(repoPath, ".git"))) {
|
|
4108
4162
|
current = runCapture(["git", "-C", repoPath, "rev-parse", "HEAD"], projectRoot).stdout.trim() || "unknown";
|
|
4109
4163
|
}
|
|
4110
4164
|
console.log(`${current === expected ? "OK " : "WARN"} ${key} expected ${expected} got ${current}`);
|
|
4111
4165
|
}
|
|
4112
4166
|
}
|
|
4113
|
-
const failedPath =
|
|
4114
|
-
if (
|
|
4115
|
-
const lines =
|
|
4167
|
+
const failedPath = resolve22(resolveHarnessPaths(projectRoot).stateDir, "failed_approaches.md");
|
|
4168
|
+
if (existsSync21(failedPath)) {
|
|
4169
|
+
const lines = readFileSync13(failedPath, "utf-8").split(/\r?\n/);
|
|
4116
4170
|
let printing = false;
|
|
4117
4171
|
const failureLines = [];
|
|
4118
4172
|
for (const line of lines) {
|