@h-rig/server 0.0.6-alpha.35 → 0.0.6-alpha.37
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/src/index.js +121 -95
- package/dist/src/scheduler.js +1 -1
- package/dist/src/server-helpers/http-router.js +1 -3
- package/dist/src/server-helpers/run-mutations.js +20 -2
- package/dist/src/server-helpers/snapshot-orchestrator.js +24 -0
- package/dist/src/server-helpers/snapshot-service.js +26 -2
- package/dist/src/server-helpers/ws-router.js +1 -1
- package/dist/src/server.js +121 -95
- package/package.json +4 -4
package/dist/src/server.js
CHANGED
|
@@ -4,7 +4,7 @@ var __require = import.meta.require;
|
|
|
4
4
|
|
|
5
5
|
// packages/server/src/server.ts
|
|
6
6
|
import { spawn as spawn5 } from "child_process";
|
|
7
|
-
import { existsSync as
|
|
7
|
+
import { existsSync as existsSync20, readdirSync as readdirSync5, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
|
|
8
8
|
import { open } from "fs/promises";
|
|
9
9
|
import { dirname as dirname20, resolve as resolve24 } from "path";
|
|
10
10
|
import {
|
|
@@ -1206,6 +1206,7 @@ function resolveServerAuthorityPaths(projectRoot) {
|
|
|
1206
1206
|
import { listAgentRuntimes } from "@rig/runtime/control-plane/runtime/isolation";
|
|
1207
1207
|
|
|
1208
1208
|
// packages/server/src/server-helpers/snapshot-orchestrator.ts
|
|
1209
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
1209
1210
|
import { dirname as dirname7, resolve as resolve8 } from "path";
|
|
1210
1211
|
import {
|
|
1211
1212
|
listAuthorityRuns as listAuthorityRuns3,
|
|
@@ -1783,6 +1784,28 @@ function buildConversationSnapshot(projectRoot, options = {}) {
|
|
|
1783
1784
|
}
|
|
1784
1785
|
|
|
1785
1786
|
// packages/server/src/server-helpers/snapshot-orchestrator.ts
|
|
1787
|
+
function readPriorPrProgress(projectRoot, taskId) {
|
|
1788
|
+
for (const candidate of [
|
|
1789
|
+
resolve8(projectRoot, ".worktrees", taskId, "artifacts", taskId, "pr-state.json"),
|
|
1790
|
+
resolve8(projectRoot, "artifacts", taskId, "pr-state.json")
|
|
1791
|
+
]) {
|
|
1792
|
+
if (!existsSync4(candidate))
|
|
1793
|
+
continue;
|
|
1794
|
+
try {
|
|
1795
|
+
const raw = JSON.parse(readFileSync2(candidate, "utf-8"));
|
|
1796
|
+
const entries = Array.isArray(raw) ? raw : [raw];
|
|
1797
|
+
const first = entries.find((entry) => entry && typeof entry === "object" && typeof entry.url === "string");
|
|
1798
|
+
if (!first)
|
|
1799
|
+
continue;
|
|
1800
|
+
return [
|
|
1801
|
+
`Prior progress exists for this task: PR ${first.url}${first.branch ? ` (branch ${first.branch})` : ""} was opened by an earlier run.`,
|
|
1802
|
+
"Check its current state first (diff, checks, review). If the work is already complete and checks are green,",
|
|
1803
|
+
"run `rig-agent completion-verification` to merge and close instead of re-implementing anything."
|
|
1804
|
+
].join(" ");
|
|
1805
|
+
} catch {}
|
|
1806
|
+
}
|
|
1807
|
+
return null;
|
|
1808
|
+
}
|
|
1786
1809
|
async function buildTaskPrompt(projectRoot, taskId, readers) {
|
|
1787
1810
|
const task = (await readers.readWorkspaceTasks(projectRoot)).find((entry) => entry.id === taskId);
|
|
1788
1811
|
if (!task) {
|
|
@@ -1800,6 +1823,7 @@ ${task.acceptanceCriteria}` : null,
|
|
|
1800
1823
|
task.validation.length > 0 ? `Validation:
|
|
1801
1824
|
- ${task.validation.join(`
|
|
1802
1825
|
- `)}` : null,
|
|
1826
|
+
readPriorPrProgress(projectRoot, String(task.id)),
|
|
1803
1827
|
"Work directly in the assigned runtime workspace and leave the result in a reviewable state."
|
|
1804
1828
|
];
|
|
1805
1829
|
return sections.filter((value) => Boolean(value)).join(`
|
|
@@ -1941,7 +1965,7 @@ async function buildEngineSnapshotPayload(inputs) {
|
|
|
1941
1965
|
}
|
|
1942
1966
|
|
|
1943
1967
|
// packages/server/src/server-helpers/plugin-host-cache.ts
|
|
1944
|
-
import { existsSync as
|
|
1968
|
+
import { existsSync as existsSync5, statSync as statSync4 } from "fs";
|
|
1945
1969
|
import { resolve as resolve9 } from "path";
|
|
1946
1970
|
var contextCache = new Map;
|
|
1947
1971
|
var taskListCache = new Map;
|
|
@@ -1949,7 +1973,7 @@ var DEFAULT_TASK_LIST_TTL_MS = 2000;
|
|
|
1949
1973
|
function getPluginHostConfigMtime(projectRoot) {
|
|
1950
1974
|
for (const name of ["rig.config.ts", "rig.config.json"]) {
|
|
1951
1975
|
const path = resolve9(projectRoot, name);
|
|
1952
|
-
if (
|
|
1976
|
+
if (existsSync5(path)) {
|
|
1953
1977
|
try {
|
|
1954
1978
|
return statSync4(path).mtimeMs;
|
|
1955
1979
|
} catch {
|
|
@@ -2243,7 +2267,7 @@ function createSnapshotService(options) {
|
|
|
2243
2267
|
}
|
|
2244
2268
|
|
|
2245
2269
|
// packages/server/src/server-helpers/task-projection.ts
|
|
2246
|
-
import { existsSync as
|
|
2270
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
2247
2271
|
import { resolve as resolve10 } from "path";
|
|
2248
2272
|
function projectionPath(projectRoot) {
|
|
2249
2273
|
return resolve10(projectRoot, ".rig", "state", "task-projection.json");
|
|
@@ -2282,10 +2306,10 @@ function writeTaskProjection(projectRoot, input) {
|
|
|
2282
2306
|
}
|
|
2283
2307
|
function readTaskProjection(projectRoot) {
|
|
2284
2308
|
const file = projectionPath(projectRoot);
|
|
2285
|
-
if (!
|
|
2309
|
+
if (!existsSync6(file))
|
|
2286
2310
|
return null;
|
|
2287
2311
|
try {
|
|
2288
|
-
const parsed = JSON.parse(
|
|
2312
|
+
const parsed = JSON.parse(readFileSync3(file, "utf8"));
|
|
2289
2313
|
return parsed && parsed.version === 1 && Array.isArray(parsed.tasks) ? parsed : null;
|
|
2290
2314
|
} catch {
|
|
2291
2315
|
return null;
|
|
@@ -3232,7 +3256,7 @@ function applyOrchestrationCommand(state, command) {
|
|
|
3232
3256
|
// packages/server/src/server-helpers/run-mutations.ts
|
|
3233
3257
|
import { spawn as spawn3 } from "child_process";
|
|
3234
3258
|
import { loadConfig } from "@rig/core/load-config";
|
|
3235
|
-
import { existsSync as
|
|
3259
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync5, statSync as statSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
3236
3260
|
import { dirname as dirname9, relative as relative2, resolve as resolve14 } from "path";
|
|
3237
3261
|
import {
|
|
3238
3262
|
listAuthorityRuns as listAuthorityRuns4,
|
|
@@ -3255,7 +3279,7 @@ import {
|
|
|
3255
3279
|
// packages/server/src/scheduler.ts
|
|
3256
3280
|
import { normalizeTaskLifecycleStatus } from "@rig/runtime/control-plane/state-sync/types";
|
|
3257
3281
|
var TERMINAL_RUN_STATUSES = new Set(["done", "completed", "error", "failed", "stopped", "cancelled"]);
|
|
3258
|
-
var RUNNABLE_TASK_STATUSES = new Set(["draft", "open", "ready", "queued"]);
|
|
3282
|
+
var RUNNABLE_TASK_STATUSES = new Set(["draft", "open", "ready", "queued", "in_progress"]);
|
|
3259
3283
|
var REMOTE_READY_STATUSES = new Set(["ready", "idle", "connected"]);
|
|
3260
3284
|
function resolveLocalSchedulerWorkerCount(env = process.env) {
|
|
3261
3285
|
const raw = env.RIG_SCHEDULER_LOCAL_WORKERS?.trim();
|
|
@@ -3362,7 +3386,7 @@ function summarizeRunValidationFailure(projectRoot, run) {
|
|
|
3362
3386
|
|
|
3363
3387
|
// packages/server/src/server-helpers/github-auth-store.ts
|
|
3364
3388
|
import { randomBytes } from "crypto";
|
|
3365
|
-
import { chmodSync, copyFileSync, existsSync as
|
|
3389
|
+
import { chmodSync, copyFileSync, existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
3366
3390
|
import { dirname as dirname8, resolve as resolve13 } from "path";
|
|
3367
3391
|
function cleanString(value) {
|
|
3368
3392
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
@@ -3414,10 +3438,10 @@ function parsePendingDevices(value) {
|
|
|
3414
3438
|
});
|
|
3415
3439
|
}
|
|
3416
3440
|
function readStoredAuth(stateFile) {
|
|
3417
|
-
if (!
|
|
3441
|
+
if (!existsSync7(stateFile))
|
|
3418
3442
|
return {};
|
|
3419
3443
|
try {
|
|
3420
|
-
const parsed = JSON.parse(
|
|
3444
|
+
const parsed = JSON.parse(readFileSync4(stateFile, "utf8"));
|
|
3421
3445
|
return {
|
|
3422
3446
|
...cleanString(parsed.token) ? { token: cleanString(parsed.token) } : {},
|
|
3423
3447
|
login: cleanString(parsed.login),
|
|
@@ -3454,7 +3478,7 @@ function resolveGitHubAuthStateFile(projectRoot) {
|
|
|
3454
3478
|
function copyGitHubAuthStateToLocalProjectRoot(stateFile, projectRoot) {
|
|
3455
3479
|
const targetFile = localProjectAuthStateFile(projectRoot);
|
|
3456
3480
|
mkdirSync6(dirname8(targetFile), { recursive: true });
|
|
3457
|
-
if (
|
|
3481
|
+
if (existsSync7(stateFile)) {
|
|
3458
3482
|
copyFileSync(stateFile, targetFile);
|
|
3459
3483
|
try {
|
|
3460
3484
|
chmodSync(targetFile, 384);
|
|
@@ -4483,7 +4507,7 @@ async function startLocalRun(state, runId, options) {
|
|
|
4483
4507
|
broadcastSnapshotInvalidation(state);
|
|
4484
4508
|
const cliProjectRoot = resolveLocalRunCliProjectRoot(state.projectRoot);
|
|
4485
4509
|
const cliEntryPoint = resolve14(cliProjectRoot, "packages/cli/bin/rig.ts");
|
|
4486
|
-
if (!
|
|
4510
|
+
if (!existsSync8(cliEntryPoint)) {
|
|
4487
4511
|
const completedAt = new Date().toISOString();
|
|
4488
4512
|
const failureSummary = `Rig task-run entrypoint missing at ${relative2(state.projectRoot, cliEntryPoint)}`;
|
|
4489
4513
|
patchRunRecord(state.projectRoot, runId, {
|
|
@@ -4728,17 +4752,17 @@ function resolveLocalRunCliProjectRoot(projectRoot) {
|
|
|
4728
4752
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
4729
4753
|
].filter((value) => !!value);
|
|
4730
4754
|
for (const candidate of envCandidates) {
|
|
4731
|
-
if (
|
|
4755
|
+
if (existsSync8(resolve14(candidate, "packages/cli/bin/rig.ts"))) {
|
|
4732
4756
|
return resolve14(candidate);
|
|
4733
4757
|
}
|
|
4734
4758
|
}
|
|
4735
|
-
if (
|
|
4759
|
+
if (existsSync8(resolve14(projectRoot, "packages/cli/bin/rig.ts"))) {
|
|
4736
4760
|
return projectRoot;
|
|
4737
4761
|
}
|
|
4738
4762
|
try {
|
|
4739
4763
|
const monorepoRoot = resolveMonorepoRoot3(projectRoot);
|
|
4740
4764
|
const outerProjectRoot = dirname9(dirname9(monorepoRoot));
|
|
4741
|
-
if (
|
|
4765
|
+
if (existsSync8(resolve14(outerProjectRoot, "packages/cli/bin/rig.ts"))) {
|
|
4742
4766
|
return outerProjectRoot;
|
|
4743
4767
|
}
|
|
4744
4768
|
} catch {}
|
|
@@ -4778,7 +4802,7 @@ function appendRunMessage(projectRoot, input) {
|
|
|
4778
4802
|
throw new Error(`Run not found: ${input.runId}`);
|
|
4779
4803
|
}
|
|
4780
4804
|
const timelinePath = resolve14(resolveAuthorityRunDir3(projectRoot, input.runId), "timeline.jsonl");
|
|
4781
|
-
const existingLines = fileExists(timelinePath) ?
|
|
4805
|
+
const existingLines = fileExists(timelinePath) ? readFileSync5(timelinePath, "utf8").trim() : "";
|
|
4782
4806
|
const nextLine = JSON.stringify({
|
|
4783
4807
|
id: input.messageId,
|
|
4784
4808
|
type: "user_message",
|
|
@@ -4898,10 +4922,14 @@ function recoverStaleLocalRun(projectRoot, run) {
|
|
|
4898
4922
|
if (hasLiveRecordedProcess && serverPid === process.pid)
|
|
4899
4923
|
return false;
|
|
4900
4924
|
const completedAt = new Date().toISOString();
|
|
4925
|
+
const taskId = normalizeString(record.taskId);
|
|
4926
|
+
if (taskId) {
|
|
4927
|
+
enqueueTaskState(projectRoot, taskId, 0);
|
|
4928
|
+
}
|
|
4901
4929
|
patchRunRecord(projectRoot, run.runId, {
|
|
4902
4930
|
status: "failed",
|
|
4903
4931
|
completedAt,
|
|
4904
|
-
errorText: `Recovered stale local run ${run.runId} after server startup; no active server-owned process was tracking it.`
|
|
4932
|
+
errorText: taskId ? `Recovered stale local run ${run.runId} after server startup; no active server-owned process was tracking it. Task ${taskId} was re-queued for automatic restart.` : `Recovered stale local run ${run.runId} after server startup; no active server-owned process was tracking it.`
|
|
4905
4933
|
});
|
|
4906
4934
|
return true;
|
|
4907
4935
|
}
|
|
@@ -5023,7 +5051,7 @@ async function reconcileScheduler(state, reason) {
|
|
|
5023
5051
|
import { randomUUID } from "crypto";
|
|
5024
5052
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
5025
5053
|
import { basename, dirname as dirname15, isAbsolute as isAbsolute4, resolve as resolve20 } from "path";
|
|
5026
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
5054
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync14, mkdirSync as mkdirSync13, readFileSync as readFileSync10, writeFileSync as writeFileSync12 } from "fs";
|
|
5027
5055
|
import {
|
|
5028
5056
|
listAuthorityRuns as listAuthorityRuns5,
|
|
5029
5057
|
readAuthorityRun as readAuthorityRun7,
|
|
@@ -5102,16 +5130,16 @@ function tokenFromRef(ref) {
|
|
|
5102
5130
|
|
|
5103
5131
|
// packages/server/src/server-helpers/run-steering.ts
|
|
5104
5132
|
import { dirname as dirname10, resolve as resolve15 } from "path";
|
|
5105
|
-
import { existsSync as
|
|
5133
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync6 } from "fs";
|
|
5106
5134
|
import { appendJsonlRecord as appendJsonlRecord2, readAuthorityRun as readAuthorityRun6, resolveAuthorityRunDir as resolveAuthorityRunDir4 } from "@rig/runtime/control-plane/authority-files";
|
|
5107
5135
|
var steeringSequence = 0;
|
|
5108
5136
|
function runSteeringPath(projectRoot, runId) {
|
|
5109
5137
|
return resolve15(resolveAuthorityRunDir4(projectRoot, runId), "steering.jsonl");
|
|
5110
5138
|
}
|
|
5111
5139
|
function readJsonl(path) {
|
|
5112
|
-
if (!
|
|
5140
|
+
if (!existsSync9(path))
|
|
5113
5141
|
return [];
|
|
5114
|
-
return
|
|
5142
|
+
return readFileSync6(path, "utf8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).flatMap((line) => {
|
|
5115
5143
|
try {
|
|
5116
5144
|
const value = JSON.parse(line);
|
|
5117
5145
|
return value && typeof value === "object" && !Array.isArray(value) ? [value] : [];
|
|
@@ -5226,11 +5254,11 @@ import {
|
|
|
5226
5254
|
} from "@rig/runtime/control-plane/tasks/source-lifecycle";
|
|
5227
5255
|
|
|
5228
5256
|
// packages/server/src/server-helpers/github-api-session-index.ts
|
|
5229
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
5257
|
+
import { chmodSync as chmodSync3, existsSync as existsSync11, mkdirSync as mkdirSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
5230
5258
|
import { dirname as dirname12, resolve as resolve17 } from "path";
|
|
5231
5259
|
|
|
5232
5260
|
// packages/server/src/server-helpers/github-user-namespace.ts
|
|
5233
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
5261
|
+
import { chmodSync as chmodSync2, existsSync as existsSync10, mkdirSync as mkdirSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync8 } from "fs";
|
|
5234
5262
|
import { dirname as dirname11, isAbsolute as isAbsolute2, relative as relative3, resolve as resolve16 } from "path";
|
|
5235
5263
|
function cleanString3(value) {
|
|
5236
5264
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
@@ -5297,10 +5325,10 @@ function isPathInsideNamespace(namespaceRoot, candidatePath) {
|
|
|
5297
5325
|
function writeRemoteUserNamespaceMetadata(namespace) {
|
|
5298
5326
|
mkdirSync9(namespace.stateDir, { recursive: true });
|
|
5299
5327
|
const previous = (() => {
|
|
5300
|
-
if (!
|
|
5328
|
+
if (!existsSync10(namespace.metadataFile))
|
|
5301
5329
|
return null;
|
|
5302
5330
|
try {
|
|
5303
|
-
const parsed = JSON.parse(
|
|
5331
|
+
const parsed = JSON.parse(readFileSync7(namespace.metadataFile, "utf8"));
|
|
5304
5332
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
5305
5333
|
} catch {
|
|
5306
5334
|
return null;
|
|
@@ -5357,10 +5385,10 @@ function parseEntry(value) {
|
|
|
5357
5385
|
};
|
|
5358
5386
|
}
|
|
5359
5387
|
function readIndex(indexFile) {
|
|
5360
|
-
if (!
|
|
5388
|
+
if (!existsSync11(indexFile))
|
|
5361
5389
|
return [];
|
|
5362
5390
|
try {
|
|
5363
|
-
const parsed = JSON.parse(
|
|
5391
|
+
const parsed = JSON.parse(readFileSync8(indexFile, "utf8"));
|
|
5364
5392
|
return Array.isArray(parsed.sessions) ? parsed.sessions.flatMap((entry) => {
|
|
5365
5393
|
const parsedEntry = parseEntry(entry);
|
|
5366
5394
|
return parsedEntry ? [parsedEntry] : [];
|
|
@@ -5509,7 +5537,7 @@ function inspectorAgentLifecycleSnapshot(input) {
|
|
|
5509
5537
|
// packages/server/src/server-helpers/project-registry.ts
|
|
5510
5538
|
import { createHash as createHash2 } from "crypto";
|
|
5511
5539
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
5512
|
-
import { existsSync as
|
|
5540
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync11, readFileSync as readFileSync9, readdirSync as readdirSync3, writeFileSync as writeFileSync10 } from "fs";
|
|
5513
5541
|
import { dirname as dirname13, resolve as resolve18 } from "path";
|
|
5514
5542
|
function normalizeRepoSlug(value) {
|
|
5515
5543
|
const trimmed = value.trim();
|
|
@@ -5520,10 +5548,10 @@ function registryPath(projectRoot) {
|
|
|
5520
5548
|
}
|
|
5521
5549
|
function readRegistry(projectRoot) {
|
|
5522
5550
|
const path = registryPath(projectRoot);
|
|
5523
|
-
if (!
|
|
5551
|
+
if (!existsSync12(path))
|
|
5524
5552
|
return {};
|
|
5525
5553
|
try {
|
|
5526
|
-
const payload = JSON.parse(
|
|
5554
|
+
const payload = JSON.parse(readFileSync9(path, "utf8"));
|
|
5527
5555
|
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
5528
5556
|
return {};
|
|
5529
5557
|
const projects = payload.projects;
|
|
@@ -5541,7 +5569,7 @@ function writeRegistry(projectRoot, projects) {
|
|
|
5541
5569
|
function resolveConfigPath(projectRoot) {
|
|
5542
5570
|
for (const name of ["rig.config.ts", "rig.config.mts", "rig.config.json"]) {
|
|
5543
5571
|
const path = resolve18(projectRoot, name);
|
|
5544
|
-
if (
|
|
5572
|
+
if (existsSync12(path))
|
|
5545
5573
|
return path;
|
|
5546
5574
|
}
|
|
5547
5575
|
return null;
|
|
@@ -5550,7 +5578,7 @@ function hashFile(path) {
|
|
|
5550
5578
|
if (!path)
|
|
5551
5579
|
return null;
|
|
5552
5580
|
try {
|
|
5553
|
-
return createHash2("sha256").update(
|
|
5581
|
+
return createHash2("sha256").update(readFileSync9(path)).digest("hex");
|
|
5554
5582
|
} catch {
|
|
5555
5583
|
return null;
|
|
5556
5584
|
}
|
|
@@ -5570,7 +5598,7 @@ function buildRunSummary(projectRoot) {
|
|
|
5570
5598
|
try {
|
|
5571
5599
|
const runs = readdirSync3(runsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).flatMap((entry) => {
|
|
5572
5600
|
try {
|
|
5573
|
-
const run = JSON.parse(
|
|
5601
|
+
const run = JSON.parse(readFileSync9(resolve18(runsDir, entry.name, "run.json"), "utf8"));
|
|
5574
5602
|
return [{ runId: typeof run.runId === "string" ? run.runId : entry.name, status: typeof run.status === "string" ? run.status : "unknown", updatedAt: typeof run.updatedAt === "string" ? run.updatedAt : "" }];
|
|
5575
5603
|
} catch {
|
|
5576
5604
|
return [];
|
|
@@ -5628,7 +5656,7 @@ function projectRegistryContainsCheckout(projectRoot, checkoutPath) {
|
|
|
5628
5656
|
}
|
|
5629
5657
|
|
|
5630
5658
|
// packages/server/src/server-helpers/remote-checkout.ts
|
|
5631
|
-
import { existsSync as
|
|
5659
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync12, writeFileSync as writeFileSync11 } from "fs";
|
|
5632
5660
|
import { dirname as dirname14, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve19 } from "path";
|
|
5633
5661
|
function safeSlugSegments(repoSlug) {
|
|
5634
5662
|
const segments = repoSlug.split("/").map((part) => part.trim()).filter(Boolean);
|
|
@@ -5727,7 +5755,7 @@ function gitCredentialConfig(token) {
|
|
|
5727
5755
|
};
|
|
5728
5756
|
}
|
|
5729
5757
|
async function prepareRemoteCheckout(input) {
|
|
5730
|
-
const exists = input.exists ??
|
|
5758
|
+
const exists = input.exists ?? existsSync13;
|
|
5731
5759
|
const strategy = input.strategy;
|
|
5732
5760
|
if (strategy.kind === "uploaded-snapshot") {
|
|
5733
5761
|
return extractUploadedSnapshotArchive({
|
|
@@ -5775,9 +5803,9 @@ function buildServerControlStatus() {
|
|
|
5775
5803
|
};
|
|
5776
5804
|
}
|
|
5777
5805
|
function buildProjectConfigStatus(root) {
|
|
5778
|
-
const hasConfigTs =
|
|
5779
|
-
const hasConfigJson =
|
|
5780
|
-
const hasLegacyTaskConfig =
|
|
5806
|
+
const hasConfigTs = existsSync14(resolve20(root, "rig.config.ts"));
|
|
5807
|
+
const hasConfigJson = existsSync14(resolve20(root, "rig.config.json"));
|
|
5808
|
+
const hasLegacyTaskConfig = existsSync14(resolve20(root, ".rig", "task-config.json"));
|
|
5781
5809
|
let kind = "missing";
|
|
5782
5810
|
if (hasConfigTs)
|
|
5783
5811
|
kind = "rig-config-ts";
|
|
@@ -5895,11 +5923,11 @@ function backupCheckoutFile(checkoutPath, relativePath) {
|
|
|
5895
5923
|
}
|
|
5896
5924
|
function parsePackageJsonLosslessly(checkoutPath) {
|
|
5897
5925
|
const packagePath = resolve20(checkoutPath, "package.json");
|
|
5898
|
-
if (!
|
|
5926
|
+
if (!existsSync14(packagePath)) {
|
|
5899
5927
|
return { existed: false, packageJson: { name: basename(checkoutPath) || "rig-project", private: true } };
|
|
5900
5928
|
}
|
|
5901
5929
|
try {
|
|
5902
|
-
const parsed = JSON.parse(
|
|
5930
|
+
const parsed = JSON.parse(readFileSync10(packagePath, "utf8"));
|
|
5903
5931
|
return {
|
|
5904
5932
|
existed: true,
|
|
5905
5933
|
packageJson: parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : { name: basename(checkoutPath) || "rig-project", private: true }
|
|
@@ -5913,9 +5941,9 @@ function parsePackageJsonLosslessly(checkoutPath) {
|
|
|
5913
5941
|
}
|
|
5914
5942
|
}
|
|
5915
5943
|
function ensureRemoteCheckoutRigPackageDeps(checkoutPath) {
|
|
5916
|
-
const hasConfig = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) =>
|
|
5944
|
+
const hasConfig = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) => existsSync14(resolve20(checkoutPath, name)));
|
|
5917
5945
|
const packagePath = resolve20(checkoutPath, "package.json");
|
|
5918
|
-
if (!hasConfig && !
|
|
5946
|
+
if (!hasConfig && !existsSync14(packagePath)) {
|
|
5919
5947
|
return { skipped: true, reason: "package.json and rig.config missing" };
|
|
5920
5948
|
}
|
|
5921
5949
|
const parsed = parsePackageJsonLosslessly(checkoutPath);
|
|
@@ -5961,10 +5989,10 @@ function configLooksStructurallyUsable(source) {
|
|
|
5961
5989
|
}
|
|
5962
5990
|
function ensureRemoteCheckoutRigConfig(checkoutPath, repoSlug, reason = "missing or incomplete rig config") {
|
|
5963
5991
|
const configPath = resolve20(checkoutPath, "rig.config.ts");
|
|
5964
|
-
const existingConfigName = ["rig.config.ts", "rig.config.mts", "rig.config.json"].find((name) =>
|
|
5992
|
+
const existingConfigName = ["rig.config.ts", "rig.config.mts", "rig.config.json"].find((name) => existsSync14(resolve20(checkoutPath, name)));
|
|
5965
5993
|
if (existingConfigName) {
|
|
5966
5994
|
const existingPath = resolve20(checkoutPath, existingConfigName);
|
|
5967
|
-
const source =
|
|
5995
|
+
const source = readFileSync10(existingPath, "utf8");
|
|
5968
5996
|
if (existingConfigName !== "rig.config.json" && configLooksStructurallyUsable(source)) {
|
|
5969
5997
|
return { path: existingPath, changed: false, reason: "config structurally complete" };
|
|
5970
5998
|
}
|
|
@@ -5987,7 +6015,7 @@ function ensureRemoteCheckoutRigConfig(checkoutPath, repoSlug, reason = "missing
|
|
|
5987
6015
|
};
|
|
5988
6016
|
}
|
|
5989
6017
|
function validateRemoteCheckoutRigConfig(checkoutPath) {
|
|
5990
|
-
const configFile = ["rig.config.ts", "rig.config.mts", "rig.config.json"].find((name) =>
|
|
6018
|
+
const configFile = ["rig.config.ts", "rig.config.mts", "rig.config.json"].find((name) => existsSync14(resolve20(checkoutPath, name)));
|
|
5991
6019
|
if (!configFile)
|
|
5992
6020
|
return { ok: false, error: "missing rig config" };
|
|
5993
6021
|
if (process.env.RIG_TEST_SKIP_REMOTE_CHECKOUT_INSTALL === "1") {
|
|
@@ -6009,7 +6037,7 @@ function validateRemoteCheckoutRigConfig(checkoutPath) {
|
|
|
6009
6037
|
return { ok: true, configFile };
|
|
6010
6038
|
}
|
|
6011
6039
|
function installRemoteCheckoutPackages(checkoutPath) {
|
|
6012
|
-
if (!
|
|
6040
|
+
if (!existsSync14(resolve20(checkoutPath, "package.json"))) {
|
|
6013
6041
|
return { skipped: true, reason: "package.json missing" };
|
|
6014
6042
|
}
|
|
6015
6043
|
if (process.env.RIG_TEST_SKIP_REMOTE_CHECKOUT_INSTALL === "1") {
|
|
@@ -6022,8 +6050,8 @@ function installRemoteCheckoutPackages(checkoutPath) {
|
|
|
6022
6050
|
return { ok: true, command: "bun install", stdout: result.stdout?.trim() || undefined };
|
|
6023
6051
|
}
|
|
6024
6052
|
function repairRemoteCheckoutForRig(checkoutPath, repoSlug) {
|
|
6025
|
-
const hasConfig = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) =>
|
|
6026
|
-
const hasPackage =
|
|
6053
|
+
const hasConfig = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) => existsSync14(resolve20(checkoutPath, name)));
|
|
6054
|
+
const hasPackage = existsSync14(resolve20(checkoutPath, "package.json"));
|
|
6027
6055
|
if (!hasConfig && !hasPackage) {
|
|
6028
6056
|
return {
|
|
6029
6057
|
packageJson: { skipped: true, reason: "package.json and rig.config missing" },
|
|
@@ -6123,24 +6151,24 @@ function readGitHeadCommit(projectRoot) {
|
|
|
6123
6151
|
try {
|
|
6124
6152
|
let gitDir = resolve20(projectRoot, ".git");
|
|
6125
6153
|
try {
|
|
6126
|
-
const dotGit =
|
|
6154
|
+
const dotGit = readFileSync10(gitDir, "utf8").trim();
|
|
6127
6155
|
const gitDirPrefix = "gitdir:";
|
|
6128
6156
|
if (dotGit.startsWith(gitDirPrefix)) {
|
|
6129
6157
|
gitDir = resolve20(projectRoot, dotGit.slice(gitDirPrefix.length).trim());
|
|
6130
6158
|
}
|
|
6131
6159
|
} catch {}
|
|
6132
|
-
const head =
|
|
6160
|
+
const head = readFileSync10(resolve20(gitDir, "HEAD"), "utf8").trim();
|
|
6133
6161
|
const refPrefix = "ref:";
|
|
6134
6162
|
if (!head.startsWith(refPrefix)) {
|
|
6135
6163
|
return normalizeCommit(head);
|
|
6136
6164
|
}
|
|
6137
6165
|
const ref = head.slice(refPrefix.length).trim();
|
|
6138
6166
|
const refPath = resolve20(gitDir, ref);
|
|
6139
|
-
if (
|
|
6140
|
-
return normalizeCommit(
|
|
6167
|
+
if (existsSync14(refPath)) {
|
|
6168
|
+
return normalizeCommit(readFileSync10(refPath, "utf8").trim());
|
|
6141
6169
|
}
|
|
6142
|
-
const commonDir = normalizeString(
|
|
6143
|
-
return commonDir ? normalizeCommit(
|
|
6170
|
+
const commonDir = normalizeString(readFileSync10(resolve20(gitDir, "commondir"), "utf8"));
|
|
6171
|
+
return commonDir ? normalizeCommit(readFileSync10(resolve20(gitDir, commonDir, ref), "utf8").trim()) : null;
|
|
6144
6172
|
} catch {
|
|
6145
6173
|
return null;
|
|
6146
6174
|
}
|
|
@@ -6437,7 +6465,7 @@ function saveGitHubTokenForRemoteUser(input) {
|
|
|
6437
6465
|
const apiSession = store.createApiSession();
|
|
6438
6466
|
registerGitHubApiSession({ projectRoot: input.projectRoot, token: apiSession.token, namespace, selectedRepo: input.selectedRepo });
|
|
6439
6467
|
const requestedRoot = normalizeString(input.requestedProjectRoot);
|
|
6440
|
-
if (requestedRoot && isAbsolute4(requestedRoot) &&
|
|
6468
|
+
if (requestedRoot && isAbsolute4(requestedRoot) && existsSync14(resolve20(requestedRoot))) {
|
|
6441
6469
|
copyGitHubAuthStateToLocalProjectRoot(namespace.authStateFile, resolve20(requestedRoot));
|
|
6442
6470
|
}
|
|
6443
6471
|
if (shouldWriteRootAuthCompat(input.projectRoot)) {
|
|
@@ -6475,7 +6503,7 @@ function resolveRequestedProjectRoot(currentRoot, rawRoot) {
|
|
|
6475
6503
|
throw new Error("projectRoot must be an absolute path on the Rig server host");
|
|
6476
6504
|
}
|
|
6477
6505
|
const normalizedRoot = resolve20(requestedRoot);
|
|
6478
|
-
if (!
|
|
6506
|
+
if (!existsSync14(normalizedRoot)) {
|
|
6479
6507
|
throw new Error("projectRoot does not exist on the Rig server host");
|
|
6480
6508
|
}
|
|
6481
6509
|
return normalizedRoot;
|
|
@@ -7367,7 +7395,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
7367
7395
|
return deps.badRequest("projectRoot must be an absolute path on the Rig server host");
|
|
7368
7396
|
}
|
|
7369
7397
|
const normalizedRoot = resolve20(requestedRoot);
|
|
7370
|
-
const exists =
|
|
7398
|
+
const exists = existsSync14(normalizedRoot);
|
|
7371
7399
|
if (exists && requestAuth.userNamespace) {
|
|
7372
7400
|
const allowedByNamespace = isPathInsideNamespace(requestAuth.userNamespace.root, normalizedRoot);
|
|
7373
7401
|
const allowedByRegistry = projectRegistryContainsCheckout(requestAuth.userNamespace.root, normalizedRoot);
|
|
@@ -7397,7 +7425,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
7397
7425
|
message: "Requested project root does not exist on the Rig server host."
|
|
7398
7426
|
}, 404);
|
|
7399
7427
|
}
|
|
7400
|
-
if (!
|
|
7428
|
+
if (!existsSync14(resolve20(normalizedRoot, "rig.config.ts")) && !existsSync14(resolve20(normalizedRoot, "rig.config.json"))) {
|
|
7401
7429
|
return deps.jsonResponse({
|
|
7402
7430
|
ok: false,
|
|
7403
7431
|
projectRoot: state.projectRoot,
|
|
@@ -7615,8 +7643,8 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
7615
7643
|
ok: true,
|
|
7616
7644
|
projectRoot: targetRoot,
|
|
7617
7645
|
configPath,
|
|
7618
|
-
exists:
|
|
7619
|
-
requiresOverwrite:
|
|
7646
|
+
exists: existsSync14(configPath),
|
|
7647
|
+
requiresOverwrite: existsSync14(configPath),
|
|
7620
7648
|
source,
|
|
7621
7649
|
owner,
|
|
7622
7650
|
repo,
|
|
@@ -7653,7 +7681,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
7653
7681
|
githubUserId: authStatus.userId ?? authStatus.login
|
|
7654
7682
|
});
|
|
7655
7683
|
const configPath = resolve20(targetRoot, "rig.config.ts");
|
|
7656
|
-
if (
|
|
7684
|
+
if (existsSync14(configPath) && !overwrite) {
|
|
7657
7685
|
return deps.jsonResponse({
|
|
7658
7686
|
ok: false,
|
|
7659
7687
|
error: "rig.config.ts already exists. Confirm overwrite to replace it; Rig will create a backup first.",
|
|
@@ -7669,7 +7697,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
7669
7697
|
return deps.jsonResponse({ ok: false, error: repoProbe.message, repoProbe }, 400);
|
|
7670
7698
|
}
|
|
7671
7699
|
let backupPath = null;
|
|
7672
|
-
if (
|
|
7700
|
+
if (existsSync14(configPath)) {
|
|
7673
7701
|
backupPath = backupConfigPath(configPath);
|
|
7674
7702
|
copyFileSync2(configPath, backupPath);
|
|
7675
7703
|
}
|
|
@@ -7959,7 +7987,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
7959
7987
|
}
|
|
7960
7988
|
if (url.pathname === "/api/pi-rig/install" && req.method === "POST") {
|
|
7961
7989
|
const configuredPackageSource = normalizeString(process.env.RIG_PI_RIG_PACKAGE_SOURCE);
|
|
7962
|
-
const packageSource = configuredPackageSource ?? [process.env.RIG_HOST_PROJECT_ROOT, process.cwd(), state.projectRoot].map((root) => normalizeString(root)).filter((root) => Boolean(root)).map((root) => resolve20(root, "packages", "pi-rig")).find((candidate) =>
|
|
7990
|
+
const packageSource = configuredPackageSource ?? [process.env.RIG_HOST_PROJECT_ROOT, process.cwd(), state.projectRoot].map((root) => normalizeString(root)).filter((root) => Boolean(root)).map((root) => resolve20(root, "packages", "pi-rig")).find((candidate) => existsSync14(resolve20(candidate, "package.json"))) ?? "npm:@h-rig/pi-rig";
|
|
7963
7991
|
if (process.env.RIG_TEST_FAKE_PI_INSTALL === "1") {
|
|
7964
7992
|
return deps.jsonResponse({ ok: true, installed: true, piOk: true, piRigOk: true, extensionPath: "remote:~/.pi/agent/extensions/pi-rig", packageSource });
|
|
7965
7993
|
}
|
|
@@ -8506,7 +8534,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
8506
8534
|
} catch {
|
|
8507
8535
|
return deps.badRequest("Invalid artifact path");
|
|
8508
8536
|
}
|
|
8509
|
-
if (!
|
|
8537
|
+
if (!existsSync14(artifactPath)) {
|
|
8510
8538
|
return deps.notFound();
|
|
8511
8539
|
}
|
|
8512
8540
|
return new Response(Bun.file(artifactPath));
|
|
@@ -8576,8 +8604,6 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
8576
8604
|
return `${sessionPath}/shell`;
|
|
8577
8605
|
if (action === "commands/run" && req.method === "POST")
|
|
8578
8606
|
return `${sessionPath}/commands/run`;
|
|
8579
|
-
if (action === "commands/respond" && req.method === "POST")
|
|
8580
|
-
return `${sessionPath}/commands/respond`;
|
|
8581
8607
|
if (action === "extension-ui/respond" && req.method === "POST")
|
|
8582
8608
|
return `${sessionPath}/extension-ui/respond`;
|
|
8583
8609
|
if (action === "abort" && req.method === "POST")
|
|
@@ -9450,7 +9476,7 @@ async function routeWebSocketRequest(state, deps, request) {
|
|
|
9450
9476
|
}
|
|
9451
9477
|
|
|
9452
9478
|
// packages/server/src/server-helpers/inspector-jobs.ts
|
|
9453
|
-
import { existsSync as
|
|
9479
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync15 } from "fs";
|
|
9454
9480
|
import { dirname as dirname18, resolve as resolve23 } from "path";
|
|
9455
9481
|
import { readJsonFile as readJsonFile3 } from "@rig/runtime/control-plane/authority-files";
|
|
9456
9482
|
import { resolveMonorepoRoot as resolveMonorepoRoot5 } from "@rig/runtime/control-plane/native/utils";
|
|
@@ -9559,7 +9585,7 @@ import { randomUUID as randomUUID3 } from "crypto";
|
|
|
9559
9585
|
|
|
9560
9586
|
// packages/server/src/inspector/mission.ts
|
|
9561
9587
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
9562
|
-
import { appendFileSync, existsSync as
|
|
9588
|
+
import { appendFileSync, existsSync as existsSync15, mkdirSync as mkdirSync14, readFileSync as readFileSync11, readdirSync as readdirSync4, renameSync, writeFileSync as writeFileSync13 } from "fs";
|
|
9563
9589
|
import { dirname as dirname16, join, resolve as resolve21 } from "path";
|
|
9564
9590
|
function isJsonValue(value) {
|
|
9565
9591
|
if (value === null)
|
|
@@ -9600,7 +9626,7 @@ function isRecord2(value) {
|
|
|
9600
9626
|
}
|
|
9601
9627
|
function readJsonRecord(path) {
|
|
9602
9628
|
try {
|
|
9603
|
-
const parsed = JSON.parse(
|
|
9629
|
+
const parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
9604
9630
|
if (!isRecord2(parsed)) {
|
|
9605
9631
|
return { ok: false, error: `Mission file ${path} does not contain an object` };
|
|
9606
9632
|
}
|
|
@@ -9713,9 +9739,9 @@ function createInspectorMissionController(options) {
|
|
|
9713
9739
|
}
|
|
9714
9740
|
function listMissionJournal(missionId) {
|
|
9715
9741
|
const path = journalPath(missionId);
|
|
9716
|
-
if (!
|
|
9742
|
+
if (!existsSync15(path))
|
|
9717
9743
|
return [];
|
|
9718
|
-
return
|
|
9744
|
+
return readFileSync11(path, "utf8").split(`
|
|
9719
9745
|
`).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line)).filter(isRecord2).map((entry) => ({
|
|
9720
9746
|
id: typeof entry.id === "string" ? entry.id : `journal:${randomUUID2()}`,
|
|
9721
9747
|
missionId,
|
|
@@ -9731,7 +9757,7 @@ function createInspectorMissionController(options) {
|
|
|
9731
9757
|
}
|
|
9732
9758
|
function readMissionOnly(missionId) {
|
|
9733
9759
|
const path = missionPath(missionId);
|
|
9734
|
-
if (!
|
|
9760
|
+
if (!existsSync15(path)) {
|
|
9735
9761
|
return { ok: false, error: `Mission ${missionId} was not found` };
|
|
9736
9762
|
}
|
|
9737
9763
|
const read = readJsonRecord(path);
|
|
@@ -9782,7 +9808,7 @@ function createInspectorMissionController(options) {
|
|
|
9782
9808
|
const source = cloneJsonRecord(input.sourceTask);
|
|
9783
9809
|
const missionId = nextId();
|
|
9784
9810
|
const path = missionPath(missionId);
|
|
9785
|
-
if (
|
|
9811
|
+
if (existsSync15(path)) {
|
|
9786
9812
|
const existing = readMissionOnly(missionId);
|
|
9787
9813
|
if (!existing.ok)
|
|
9788
9814
|
return existing;
|
|
@@ -12289,7 +12315,7 @@ function createGlobalInspectorService(options) {
|
|
|
12289
12315
|
|
|
12290
12316
|
// packages/server/src/inspector/upstream-sync.ts
|
|
12291
12317
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
12292
|
-
import { existsSync as
|
|
12318
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync14 } from "fs";
|
|
12293
12319
|
import { dirname as dirname17, resolve as resolve22 } from "path";
|
|
12294
12320
|
import { resolveMonorepoRoot as resolveMonorepoRoot4 } from "@rig/runtime/control-plane/native/utils";
|
|
12295
12321
|
var UPSTREAM_VALIDATION_DESCRIPTIONS = {
|
|
@@ -12434,11 +12460,11 @@ function upstreamStatePath(projectRoot, override) {
|
|
|
12434
12460
|
}
|
|
12435
12461
|
function readUpstreamState(projectRoot, statePath) {
|
|
12436
12462
|
const path = upstreamStatePath(projectRoot, statePath);
|
|
12437
|
-
if (!
|
|
12463
|
+
if (!existsSync16(path)) {
|
|
12438
12464
|
return null;
|
|
12439
12465
|
}
|
|
12440
12466
|
try {
|
|
12441
|
-
return JSON.parse(
|
|
12467
|
+
return JSON.parse(readFileSync12(path, "utf-8"));
|
|
12442
12468
|
} catch {
|
|
12443
12469
|
return null;
|
|
12444
12470
|
}
|
|
@@ -12452,10 +12478,10 @@ function writeUpstreamState(projectRoot, state, statePath) {
|
|
|
12452
12478
|
function readImportedRevision(projectRoot, upstreamsDocPath) {
|
|
12453
12479
|
const monorepoRoot = resolveMonorepoRoot4(projectRoot);
|
|
12454
12480
|
const docPath = upstreamsDocPath ? resolve22(upstreamsDocPath) : resolve22(monorepoRoot, "docs", "UPSTREAMS.md");
|
|
12455
|
-
if (!
|
|
12481
|
+
if (!existsSync16(docPath)) {
|
|
12456
12482
|
throw new Error(`UPSTREAMS.md not found at ${docPath}`);
|
|
12457
12483
|
}
|
|
12458
|
-
const docContent =
|
|
12484
|
+
const docContent = readFileSync12(docPath, "utf-8");
|
|
12459
12485
|
const revision = parseImportedUpstreamRevision(docContent, "upstream") ?? parseImportedUpstreamRevision(docContent, "humoongate");
|
|
12460
12486
|
if (!revision) {
|
|
12461
12487
|
throw new Error(`Failed to parse upstream imported revision from ${docPath}`);
|
|
@@ -12477,7 +12503,7 @@ function resolveRemoteBranch(repoRoot, remote, gitRunner) {
|
|
|
12477
12503
|
return null;
|
|
12478
12504
|
}
|
|
12479
12505
|
function isGitCheckout(path, gitRunner) {
|
|
12480
|
-
if (!
|
|
12506
|
+
if (!existsSync16(resolve22(path, ".git"))) {
|
|
12481
12507
|
return false;
|
|
12482
12508
|
}
|
|
12483
12509
|
const result = gitRunner(path, ["rev-parse", "--is-inside-work-tree"]);
|
|
@@ -12727,10 +12753,10 @@ async function runUpstreamSyncScan(options) {
|
|
|
12727
12753
|
}
|
|
12728
12754
|
|
|
12729
12755
|
// packages/server/src/server-helpers/task-config.ts
|
|
12730
|
-
import { existsSync as
|
|
12756
|
+
import { existsSync as existsSync17 } from "fs";
|
|
12731
12757
|
async function readTaskConfig(projectRoot) {
|
|
12732
12758
|
const taskConfigPath = resolveRigServerPaths(projectRoot).taskConfigPath;
|
|
12733
|
-
if (!
|
|
12759
|
+
if (!existsSync17(taskConfigPath)) {
|
|
12734
12760
|
return {};
|
|
12735
12761
|
}
|
|
12736
12762
|
try {
|
|
@@ -12789,7 +12815,7 @@ async function createInspectorFollowupTask(projectRoot, input) {
|
|
|
12789
12815
|
const sourceKey = normalizeString(input.sourceKey) ?? normalizeString(input.details?.sourceKey);
|
|
12790
12816
|
const createdAt = normalizeString(input.createdAt) ?? new Date().toISOString();
|
|
12791
12817
|
const status = normalizeTaskLifecycleStatus2(normalizeString(input.status) ?? "open") ?? "open";
|
|
12792
|
-
const existingIssueLines =
|
|
12818
|
+
const existingIssueLines = existsSync18(issuesPath) ? readFileSync13(issuesPath, "utf8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean) : [];
|
|
12793
12819
|
const existingIssues = existingIssueLines.map((line) => {
|
|
12794
12820
|
try {
|
|
12795
12821
|
return JSON.parse(line);
|
|
@@ -12798,7 +12824,7 @@ async function createInspectorFollowupTask(projectRoot, input) {
|
|
|
12798
12824
|
}
|
|
12799
12825
|
}).filter((value) => value !== null);
|
|
12800
12826
|
const existingIds = new Set(existingIssues.map((issue) => typeof issue.id === "string" ? issue.id : null).filter((value) => value !== null));
|
|
12801
|
-
const rawTaskState =
|
|
12827
|
+
const rawTaskState = existsSync18(taskStatePath) ? readJsonFile3(taskStatePath, {}) : {};
|
|
12802
12828
|
const tasks = rawTaskState.tasks && typeof rawTaskState.tasks === "object" && !Array.isArray(rawTaskState.tasks) ? rawTaskState.tasks : {};
|
|
12803
12829
|
const existingTaskIdFromSourceKey = sourceKey == null ? null : Object.entries(tasks).find(([, metadata]) => {
|
|
12804
12830
|
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
@@ -13169,10 +13195,10 @@ function isAuthorizedLinearWebhookRequest(req) {
|
|
|
13169
13195
|
}
|
|
13170
13196
|
|
|
13171
13197
|
// packages/server/src/server-helpers/notifications.ts
|
|
13172
|
-
import { existsSync as
|
|
13198
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync17, readFileSync as readFileSync14 } from "fs";
|
|
13173
13199
|
import { dirname as dirname19 } from "path";
|
|
13174
13200
|
async function loadNotificationConfig(path) {
|
|
13175
|
-
if (!
|
|
13201
|
+
if (!existsSync19(path)) {
|
|
13176
13202
|
const defaultConfig = { targets: [] };
|
|
13177
13203
|
mkdirSync17(dirname19(path), { recursive: true });
|
|
13178
13204
|
await Bun.write(path, `${JSON.stringify(defaultConfig, null, 2)}
|
|
@@ -13189,10 +13215,10 @@ async function loadNotificationConfig(path) {
|
|
|
13189
13215
|
}
|
|
13190
13216
|
}
|
|
13191
13217
|
function readRecentEvents(file, limit) {
|
|
13192
|
-
if (!
|
|
13218
|
+
if (!existsSync19(file)) {
|
|
13193
13219
|
return [];
|
|
13194
13220
|
}
|
|
13195
|
-
const lines =
|
|
13221
|
+
const lines = readFileSync14(file, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).slice(-limit);
|
|
13196
13222
|
const events = [];
|
|
13197
13223
|
for (const line of lines) {
|
|
13198
13224
|
try {
|
|
@@ -13288,10 +13314,10 @@ function extractObjectLiteralBlock(source, property) {
|
|
|
13288
13314
|
function readFallbackIssueAnalysisConfig(projectRoot) {
|
|
13289
13315
|
for (const fileName of ["rig.config.ts", "rig.config.json"]) {
|
|
13290
13316
|
const path = resolve24(projectRoot, fileName);
|
|
13291
|
-
if (!
|
|
13317
|
+
if (!existsSync20(path))
|
|
13292
13318
|
continue;
|
|
13293
13319
|
try {
|
|
13294
|
-
const source =
|
|
13320
|
+
const source = readFileSync15(path, "utf8");
|
|
13295
13321
|
if (fileName.endsWith(".json"))
|
|
13296
13322
|
return JSON.parse(source);
|
|
13297
13323
|
const issueBlock = extractObjectLiteralBlock(source, "issueAnalysis");
|
|
@@ -13463,7 +13489,7 @@ async function withServerAuthorityEnvIfNeeded(projectRoot, fn) {
|
|
|
13463
13489
|
async function readWorkspaceTasks(projectRoot) {
|
|
13464
13490
|
const issuesPath = resolve24(resolveMonorepoRoot6(projectRoot), ".beads", "issues.jsonl");
|
|
13465
13491
|
const taskConfig = await readTaskConfig(projectRoot);
|
|
13466
|
-
if (!
|
|
13492
|
+
if (!existsSync20(issuesPath)) {
|
|
13467
13493
|
return [];
|
|
13468
13494
|
}
|
|
13469
13495
|
const latestById = new Map;
|
|
@@ -13555,7 +13581,7 @@ async function listArtifactSummaries(projectRoot, taskId, knownTaskIds, knownRun
|
|
|
13555
13581
|
}
|
|
13556
13582
|
}
|
|
13557
13583
|
return taskIds.flatMap((currentTaskId) => {
|
|
13558
|
-
const currentRoot = resolveTaskArtifactDirsFromRuns(projectRoot, currentTaskId, runs).find((path) =>
|
|
13584
|
+
const currentRoot = resolveTaskArtifactDirsFromRuns(projectRoot, currentTaskId, runs).find((path) => existsSync20(path));
|
|
13559
13585
|
if (!currentRoot) {
|
|
13560
13586
|
return [];
|
|
13561
13587
|
}
|
|
@@ -13610,7 +13636,7 @@ function buildInspectorStreamPayload(state, sequence) {
|
|
|
13610
13636
|
}
|
|
13611
13637
|
function listRemoteRunArtifacts(projectRoot, runId) {
|
|
13612
13638
|
const root = remoteArtifactsRoot(projectRoot, runId);
|
|
13613
|
-
if (!
|
|
13639
|
+
if (!existsSync20(root)) {
|
|
13614
13640
|
return [];
|
|
13615
13641
|
}
|
|
13616
13642
|
return readdirSync5(root, { withFileTypes: true }).filter((entry) => entry.isFile()).filter((entry) => !entry.name.endsWith(".json")).map((entry) => {
|
|
@@ -13908,10 +13934,10 @@ function startRunFileWatcher(state, pollMs) {
|
|
|
13908
13934
|
}, Math.max(250, Math.min(pollMs, 1000)));
|
|
13909
13935
|
}
|
|
13910
13936
|
function startPoller(state, pollMs) {
|
|
13911
|
-
let offset =
|
|
13937
|
+
let offset = existsSync20(state.eventsFile) ? statSync6(state.eventsFile).size : 0;
|
|
13912
13938
|
return setInterval(async () => {
|
|
13913
13939
|
try {
|
|
13914
|
-
if (!
|
|
13940
|
+
if (!existsSync20(state.eventsFile)) {
|
|
13915
13941
|
return;
|
|
13916
13942
|
}
|
|
13917
13943
|
const file = await open(state.eventsFile, "r");
|