@h-rig/server 0.0.6-alpha.34 → 0.0.6-alpha.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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/index.js
CHANGED
|
@@ -663,7 +663,7 @@ function createRemoteOrchestrationSummary(input) {
|
|
|
663
663
|
}
|
|
664
664
|
// packages/server/src/server.ts
|
|
665
665
|
import { spawn as spawn5 } from "child_process";
|
|
666
|
-
import { existsSync as
|
|
666
|
+
import { existsSync as existsSync20, readdirSync as readdirSync5, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
|
|
667
667
|
import { open } from "fs/promises";
|
|
668
668
|
import { dirname as dirname20, resolve as resolve24 } from "path";
|
|
669
669
|
import {
|
|
@@ -1712,6 +1712,7 @@ function resolveServerAuthorityPaths(projectRoot) {
|
|
|
1712
1712
|
import { listAgentRuntimes } from "@rig/runtime/control-plane/runtime/isolation";
|
|
1713
1713
|
|
|
1714
1714
|
// packages/server/src/server-helpers/snapshot-orchestrator.ts
|
|
1715
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
1715
1716
|
import { dirname as dirname7, resolve as resolve8 } from "path";
|
|
1716
1717
|
import {
|
|
1717
1718
|
listAuthorityRuns as listAuthorityRuns3,
|
|
@@ -2289,6 +2290,28 @@ function buildConversationSnapshot(projectRoot, options = {}) {
|
|
|
2289
2290
|
}
|
|
2290
2291
|
|
|
2291
2292
|
// packages/server/src/server-helpers/snapshot-orchestrator.ts
|
|
2293
|
+
function readPriorPrProgress(projectRoot, taskId) {
|
|
2294
|
+
for (const candidate of [
|
|
2295
|
+
resolve8(projectRoot, ".worktrees", taskId, "artifacts", taskId, "pr-state.json"),
|
|
2296
|
+
resolve8(projectRoot, "artifacts", taskId, "pr-state.json")
|
|
2297
|
+
]) {
|
|
2298
|
+
if (!existsSync4(candidate))
|
|
2299
|
+
continue;
|
|
2300
|
+
try {
|
|
2301
|
+
const raw = JSON.parse(readFileSync2(candidate, "utf-8"));
|
|
2302
|
+
const entries = Array.isArray(raw) ? raw : [raw];
|
|
2303
|
+
const first = entries.find((entry) => entry && typeof entry === "object" && typeof entry.url === "string");
|
|
2304
|
+
if (!first)
|
|
2305
|
+
continue;
|
|
2306
|
+
return [
|
|
2307
|
+
`Prior progress exists for this task: PR ${first.url}${first.branch ? ` (branch ${first.branch})` : ""} was opened by an earlier run.`,
|
|
2308
|
+
"Check its current state first (diff, checks, review). If the work is already complete and checks are green,",
|
|
2309
|
+
"run `rig-agent completion-verification` to merge and close instead of re-implementing anything."
|
|
2310
|
+
].join(" ");
|
|
2311
|
+
} catch {}
|
|
2312
|
+
}
|
|
2313
|
+
return null;
|
|
2314
|
+
}
|
|
2292
2315
|
async function buildTaskPrompt(projectRoot, taskId, readers) {
|
|
2293
2316
|
const task = (await readers.readWorkspaceTasks(projectRoot)).find((entry) => entry.id === taskId);
|
|
2294
2317
|
if (!task) {
|
|
@@ -2306,6 +2329,7 @@ ${task.acceptanceCriteria}` : null,
|
|
|
2306
2329
|
task.validation.length > 0 ? `Validation:
|
|
2307
2330
|
- ${task.validation.join(`
|
|
2308
2331
|
- `)}` : null,
|
|
2332
|
+
readPriorPrProgress(projectRoot, String(task.id)),
|
|
2309
2333
|
"Work directly in the assigned runtime workspace and leave the result in a reviewable state."
|
|
2310
2334
|
];
|
|
2311
2335
|
return sections.filter((value) => Boolean(value)).join(`
|
|
@@ -2447,7 +2471,7 @@ async function buildEngineSnapshotPayload(inputs) {
|
|
|
2447
2471
|
}
|
|
2448
2472
|
|
|
2449
2473
|
// packages/server/src/server-helpers/plugin-host-cache.ts
|
|
2450
|
-
import { existsSync as
|
|
2474
|
+
import { existsSync as existsSync5, statSync as statSync4 } from "fs";
|
|
2451
2475
|
import { resolve as resolve9 } from "path";
|
|
2452
2476
|
var contextCache = new Map;
|
|
2453
2477
|
var taskListCache = new Map;
|
|
@@ -2455,7 +2479,7 @@ var DEFAULT_TASK_LIST_TTL_MS = 2000;
|
|
|
2455
2479
|
function getPluginHostConfigMtime(projectRoot) {
|
|
2456
2480
|
for (const name of ["rig.config.ts", "rig.config.json"]) {
|
|
2457
2481
|
const path = resolve9(projectRoot, name);
|
|
2458
|
-
if (
|
|
2482
|
+
if (existsSync5(path)) {
|
|
2459
2483
|
try {
|
|
2460
2484
|
return statSync4(path).mtimeMs;
|
|
2461
2485
|
} catch {
|
|
@@ -2749,7 +2773,7 @@ function createSnapshotService(options) {
|
|
|
2749
2773
|
}
|
|
2750
2774
|
|
|
2751
2775
|
// packages/server/src/server-helpers/task-projection.ts
|
|
2752
|
-
import { existsSync as
|
|
2776
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
2753
2777
|
import { resolve as resolve10 } from "path";
|
|
2754
2778
|
function projectionPath(projectRoot) {
|
|
2755
2779
|
return resolve10(projectRoot, ".rig", "state", "task-projection.json");
|
|
@@ -2788,10 +2812,10 @@ function writeTaskProjection(projectRoot, input) {
|
|
|
2788
2812
|
}
|
|
2789
2813
|
function readTaskProjection(projectRoot) {
|
|
2790
2814
|
const file = projectionPath(projectRoot);
|
|
2791
|
-
if (!
|
|
2815
|
+
if (!existsSync6(file))
|
|
2792
2816
|
return null;
|
|
2793
2817
|
try {
|
|
2794
|
-
const parsed = JSON.parse(
|
|
2818
|
+
const parsed = JSON.parse(readFileSync3(file, "utf8"));
|
|
2795
2819
|
return parsed && parsed.version === 1 && Array.isArray(parsed.tasks) ? parsed : null;
|
|
2796
2820
|
} catch {
|
|
2797
2821
|
return null;
|
|
@@ -3738,7 +3762,7 @@ function applyOrchestrationCommand2(state, command) {
|
|
|
3738
3762
|
// packages/server/src/server-helpers/run-mutations.ts
|
|
3739
3763
|
import { spawn as spawn3 } from "child_process";
|
|
3740
3764
|
import { loadConfig } from "@rig/core/load-config";
|
|
3741
|
-
import { existsSync as
|
|
3765
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync5, statSync as statSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
3742
3766
|
import { dirname as dirname9, relative as relative2, resolve as resolve14 } from "path";
|
|
3743
3767
|
import {
|
|
3744
3768
|
listAuthorityRuns as listAuthorityRuns4,
|
|
@@ -3761,7 +3785,7 @@ import {
|
|
|
3761
3785
|
// packages/server/src/scheduler.ts
|
|
3762
3786
|
import { normalizeTaskLifecycleStatus } from "@rig/runtime/control-plane/state-sync/types";
|
|
3763
3787
|
var TERMINAL_RUN_STATUSES = new Set(["done", "completed", "error", "failed", "stopped", "cancelled"]);
|
|
3764
|
-
var RUNNABLE_TASK_STATUSES = new Set(["draft", "open", "ready", "queued"]);
|
|
3788
|
+
var RUNNABLE_TASK_STATUSES = new Set(["draft", "open", "ready", "queued", "in_progress"]);
|
|
3765
3789
|
var REMOTE_READY_STATUSES = new Set(["ready", "idle", "connected"]);
|
|
3766
3790
|
function resolveLocalSchedulerWorkerCount(env = process.env) {
|
|
3767
3791
|
const raw = env.RIG_SCHEDULER_LOCAL_WORKERS?.trim();
|
|
@@ -3868,7 +3892,7 @@ function summarizeRunValidationFailure(projectRoot, run) {
|
|
|
3868
3892
|
|
|
3869
3893
|
// packages/server/src/server-helpers/github-auth-store.ts
|
|
3870
3894
|
import { randomBytes } from "crypto";
|
|
3871
|
-
import { chmodSync, copyFileSync, existsSync as
|
|
3895
|
+
import { chmodSync, copyFileSync, existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
3872
3896
|
import { dirname as dirname8, resolve as resolve13 } from "path";
|
|
3873
3897
|
function cleanString(value) {
|
|
3874
3898
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
@@ -3920,10 +3944,10 @@ function parsePendingDevices(value) {
|
|
|
3920
3944
|
});
|
|
3921
3945
|
}
|
|
3922
3946
|
function readStoredAuth(stateFile) {
|
|
3923
|
-
if (!
|
|
3947
|
+
if (!existsSync7(stateFile))
|
|
3924
3948
|
return {};
|
|
3925
3949
|
try {
|
|
3926
|
-
const parsed = JSON.parse(
|
|
3950
|
+
const parsed = JSON.parse(readFileSync4(stateFile, "utf8"));
|
|
3927
3951
|
return {
|
|
3928
3952
|
...cleanString(parsed.token) ? { token: cleanString(parsed.token) } : {},
|
|
3929
3953
|
login: cleanString(parsed.login),
|
|
@@ -3960,7 +3984,7 @@ function resolveGitHubAuthStateFile(projectRoot) {
|
|
|
3960
3984
|
function copyGitHubAuthStateToLocalProjectRoot(stateFile, projectRoot) {
|
|
3961
3985
|
const targetFile = localProjectAuthStateFile(projectRoot);
|
|
3962
3986
|
mkdirSync6(dirname8(targetFile), { recursive: true });
|
|
3963
|
-
if (
|
|
3987
|
+
if (existsSync7(stateFile)) {
|
|
3964
3988
|
copyFileSync(stateFile, targetFile);
|
|
3965
3989
|
try {
|
|
3966
3990
|
chmodSync(targetFile, 384);
|
|
@@ -4989,7 +5013,7 @@ async function startLocalRun(state, runId, options) {
|
|
|
4989
5013
|
broadcastSnapshotInvalidation(state);
|
|
4990
5014
|
const cliProjectRoot = resolveLocalRunCliProjectRoot(state.projectRoot);
|
|
4991
5015
|
const cliEntryPoint = resolve14(cliProjectRoot, "packages/cli/bin/rig.ts");
|
|
4992
|
-
if (!
|
|
5016
|
+
if (!existsSync8(cliEntryPoint)) {
|
|
4993
5017
|
const completedAt = new Date().toISOString();
|
|
4994
5018
|
const failureSummary = `Rig task-run entrypoint missing at ${relative2(state.projectRoot, cliEntryPoint)}`;
|
|
4995
5019
|
patchRunRecord(state.projectRoot, runId, {
|
|
@@ -5234,17 +5258,17 @@ function resolveLocalRunCliProjectRoot(projectRoot) {
|
|
|
5234
5258
|
process.env.PROJECT_RIG_ROOT?.trim()
|
|
5235
5259
|
].filter((value) => !!value);
|
|
5236
5260
|
for (const candidate of envCandidates) {
|
|
5237
|
-
if (
|
|
5261
|
+
if (existsSync8(resolve14(candidate, "packages/cli/bin/rig.ts"))) {
|
|
5238
5262
|
return resolve14(candidate);
|
|
5239
5263
|
}
|
|
5240
5264
|
}
|
|
5241
|
-
if (
|
|
5265
|
+
if (existsSync8(resolve14(projectRoot, "packages/cli/bin/rig.ts"))) {
|
|
5242
5266
|
return projectRoot;
|
|
5243
5267
|
}
|
|
5244
5268
|
try {
|
|
5245
5269
|
const monorepoRoot = resolveMonorepoRoot3(projectRoot);
|
|
5246
5270
|
const outerProjectRoot = dirname9(dirname9(monorepoRoot));
|
|
5247
|
-
if (
|
|
5271
|
+
if (existsSync8(resolve14(outerProjectRoot, "packages/cli/bin/rig.ts"))) {
|
|
5248
5272
|
return outerProjectRoot;
|
|
5249
5273
|
}
|
|
5250
5274
|
} catch {}
|
|
@@ -5284,7 +5308,7 @@ function appendRunMessage(projectRoot, input) {
|
|
|
5284
5308
|
throw new Error(`Run not found: ${input.runId}`);
|
|
5285
5309
|
}
|
|
5286
5310
|
const timelinePath = resolve14(resolveAuthorityRunDir3(projectRoot, input.runId), "timeline.jsonl");
|
|
5287
|
-
const existingLines = fileExists(timelinePath) ?
|
|
5311
|
+
const existingLines = fileExists(timelinePath) ? readFileSync5(timelinePath, "utf8").trim() : "";
|
|
5288
5312
|
const nextLine = JSON.stringify({
|
|
5289
5313
|
id: input.messageId,
|
|
5290
5314
|
type: "user_message",
|
|
@@ -5404,10 +5428,14 @@ function recoverStaleLocalRun(projectRoot, run) {
|
|
|
5404
5428
|
if (hasLiveRecordedProcess && serverPid === process.pid)
|
|
5405
5429
|
return false;
|
|
5406
5430
|
const completedAt = new Date().toISOString();
|
|
5431
|
+
const taskId = normalizeString(record.taskId);
|
|
5432
|
+
if (taskId) {
|
|
5433
|
+
enqueueTaskState(projectRoot, taskId, 0);
|
|
5434
|
+
}
|
|
5407
5435
|
patchRunRecord(projectRoot, run.runId, {
|
|
5408
5436
|
status: "failed",
|
|
5409
5437
|
completedAt,
|
|
5410
|
-
errorText: `Recovered stale local run ${run.runId} after server startup; no active server-owned process was tracking it.`
|
|
5438
|
+
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.`
|
|
5411
5439
|
});
|
|
5412
5440
|
return true;
|
|
5413
5441
|
}
|
|
@@ -5529,7 +5557,7 @@ async function reconcileScheduler(state, reason) {
|
|
|
5529
5557
|
import { randomUUID } from "crypto";
|
|
5530
5558
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
5531
5559
|
import { basename, dirname as dirname15, isAbsolute as isAbsolute4, resolve as resolve20 } from "path";
|
|
5532
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
5560
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync14, mkdirSync as mkdirSync13, readFileSync as readFileSync10, writeFileSync as writeFileSync12 } from "fs";
|
|
5533
5561
|
import {
|
|
5534
5562
|
listAuthorityRuns as listAuthorityRuns5,
|
|
5535
5563
|
readAuthorityRun as readAuthorityRun7,
|
|
@@ -5608,16 +5636,16 @@ function tokenFromRef(ref) {
|
|
|
5608
5636
|
|
|
5609
5637
|
// packages/server/src/server-helpers/run-steering.ts
|
|
5610
5638
|
import { dirname as dirname10, resolve as resolve15 } from "path";
|
|
5611
|
-
import { existsSync as
|
|
5639
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync6 } from "fs";
|
|
5612
5640
|
import { appendJsonlRecord as appendJsonlRecord2, readAuthorityRun as readAuthorityRun6, resolveAuthorityRunDir as resolveAuthorityRunDir4 } from "@rig/runtime/control-plane/authority-files";
|
|
5613
5641
|
var steeringSequence = 0;
|
|
5614
5642
|
function runSteeringPath(projectRoot, runId) {
|
|
5615
5643
|
return resolve15(resolveAuthorityRunDir4(projectRoot, runId), "steering.jsonl");
|
|
5616
5644
|
}
|
|
5617
5645
|
function readJsonl(path) {
|
|
5618
|
-
if (!
|
|
5646
|
+
if (!existsSync9(path))
|
|
5619
5647
|
return [];
|
|
5620
|
-
return
|
|
5648
|
+
return readFileSync6(path, "utf8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).flatMap((line) => {
|
|
5621
5649
|
try {
|
|
5622
5650
|
const value = JSON.parse(line);
|
|
5623
5651
|
return value && typeof value === "object" && !Array.isArray(value) ? [value] : [];
|
|
@@ -5732,11 +5760,11 @@ import {
|
|
|
5732
5760
|
} from "@rig/runtime/control-plane/tasks/source-lifecycle";
|
|
5733
5761
|
|
|
5734
5762
|
// packages/server/src/server-helpers/github-api-session-index.ts
|
|
5735
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
5763
|
+
import { chmodSync as chmodSync3, existsSync as existsSync11, mkdirSync as mkdirSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
5736
5764
|
import { dirname as dirname12, resolve as resolve17 } from "path";
|
|
5737
5765
|
|
|
5738
5766
|
// packages/server/src/server-helpers/github-user-namespace.ts
|
|
5739
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
5767
|
+
import { chmodSync as chmodSync2, existsSync as existsSync10, mkdirSync as mkdirSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync8 } from "fs";
|
|
5740
5768
|
import { dirname as dirname11, isAbsolute as isAbsolute2, relative as relative3, resolve as resolve16 } from "path";
|
|
5741
5769
|
function cleanString3(value) {
|
|
5742
5770
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
@@ -5803,10 +5831,10 @@ function isPathInsideNamespace(namespaceRoot, candidatePath) {
|
|
|
5803
5831
|
function writeRemoteUserNamespaceMetadata(namespace) {
|
|
5804
5832
|
mkdirSync9(namespace.stateDir, { recursive: true });
|
|
5805
5833
|
const previous = (() => {
|
|
5806
|
-
if (!
|
|
5834
|
+
if (!existsSync10(namespace.metadataFile))
|
|
5807
5835
|
return null;
|
|
5808
5836
|
try {
|
|
5809
|
-
const parsed = JSON.parse(
|
|
5837
|
+
const parsed = JSON.parse(readFileSync7(namespace.metadataFile, "utf8"));
|
|
5810
5838
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
5811
5839
|
} catch {
|
|
5812
5840
|
return null;
|
|
@@ -5863,10 +5891,10 @@ function parseEntry(value) {
|
|
|
5863
5891
|
};
|
|
5864
5892
|
}
|
|
5865
5893
|
function readIndex(indexFile) {
|
|
5866
|
-
if (!
|
|
5894
|
+
if (!existsSync11(indexFile))
|
|
5867
5895
|
return [];
|
|
5868
5896
|
try {
|
|
5869
|
-
const parsed = JSON.parse(
|
|
5897
|
+
const parsed = JSON.parse(readFileSync8(indexFile, "utf8"));
|
|
5870
5898
|
return Array.isArray(parsed.sessions) ? parsed.sessions.flatMap((entry) => {
|
|
5871
5899
|
const parsedEntry = parseEntry(entry);
|
|
5872
5900
|
return parsedEntry ? [parsedEntry] : [];
|
|
@@ -6015,7 +6043,7 @@ function inspectorAgentLifecycleSnapshot(input) {
|
|
|
6015
6043
|
// packages/server/src/server-helpers/project-registry.ts
|
|
6016
6044
|
import { createHash as createHash2 } from "crypto";
|
|
6017
6045
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
6018
|
-
import { existsSync as
|
|
6046
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync11, readFileSync as readFileSync9, readdirSync as readdirSync3, writeFileSync as writeFileSync10 } from "fs";
|
|
6019
6047
|
import { dirname as dirname13, resolve as resolve18 } from "path";
|
|
6020
6048
|
function normalizeRepoSlug(value) {
|
|
6021
6049
|
const trimmed = value.trim();
|
|
@@ -6026,10 +6054,10 @@ function registryPath(projectRoot) {
|
|
|
6026
6054
|
}
|
|
6027
6055
|
function readRegistry(projectRoot) {
|
|
6028
6056
|
const path = registryPath(projectRoot);
|
|
6029
|
-
if (!
|
|
6057
|
+
if (!existsSync12(path))
|
|
6030
6058
|
return {};
|
|
6031
6059
|
try {
|
|
6032
|
-
const payload = JSON.parse(
|
|
6060
|
+
const payload = JSON.parse(readFileSync9(path, "utf8"));
|
|
6033
6061
|
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
6034
6062
|
return {};
|
|
6035
6063
|
const projects = payload.projects;
|
|
@@ -6047,7 +6075,7 @@ function writeRegistry(projectRoot, projects) {
|
|
|
6047
6075
|
function resolveConfigPath(projectRoot) {
|
|
6048
6076
|
for (const name of ["rig.config.ts", "rig.config.mts", "rig.config.json"]) {
|
|
6049
6077
|
const path = resolve18(projectRoot, name);
|
|
6050
|
-
if (
|
|
6078
|
+
if (existsSync12(path))
|
|
6051
6079
|
return path;
|
|
6052
6080
|
}
|
|
6053
6081
|
return null;
|
|
@@ -6056,7 +6084,7 @@ function hashFile(path) {
|
|
|
6056
6084
|
if (!path)
|
|
6057
6085
|
return null;
|
|
6058
6086
|
try {
|
|
6059
|
-
return createHash2("sha256").update(
|
|
6087
|
+
return createHash2("sha256").update(readFileSync9(path)).digest("hex");
|
|
6060
6088
|
} catch {
|
|
6061
6089
|
return null;
|
|
6062
6090
|
}
|
|
@@ -6076,7 +6104,7 @@ function buildRunSummary(projectRoot) {
|
|
|
6076
6104
|
try {
|
|
6077
6105
|
const runs = readdirSync3(runsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).flatMap((entry) => {
|
|
6078
6106
|
try {
|
|
6079
|
-
const run = JSON.parse(
|
|
6107
|
+
const run = JSON.parse(readFileSync9(resolve18(runsDir, entry.name, "run.json"), "utf8"));
|
|
6080
6108
|
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 : "" }];
|
|
6081
6109
|
} catch {
|
|
6082
6110
|
return [];
|
|
@@ -6134,7 +6162,7 @@ function projectRegistryContainsCheckout(projectRoot, checkoutPath) {
|
|
|
6134
6162
|
}
|
|
6135
6163
|
|
|
6136
6164
|
// packages/server/src/server-helpers/remote-checkout.ts
|
|
6137
|
-
import { existsSync as
|
|
6165
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync12, writeFileSync as writeFileSync11 } from "fs";
|
|
6138
6166
|
import { dirname as dirname14, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve19 } from "path";
|
|
6139
6167
|
function safeSlugSegments(repoSlug) {
|
|
6140
6168
|
const segments = repoSlug.split("/").map((part) => part.trim()).filter(Boolean);
|
|
@@ -6233,7 +6261,7 @@ function gitCredentialConfig(token) {
|
|
|
6233
6261
|
};
|
|
6234
6262
|
}
|
|
6235
6263
|
async function prepareRemoteCheckout(input) {
|
|
6236
|
-
const exists = input.exists ??
|
|
6264
|
+
const exists = input.exists ?? existsSync13;
|
|
6237
6265
|
const strategy = input.strategy;
|
|
6238
6266
|
if (strategy.kind === "uploaded-snapshot") {
|
|
6239
6267
|
return extractUploadedSnapshotArchive({
|
|
@@ -6281,9 +6309,9 @@ function buildServerControlStatus() {
|
|
|
6281
6309
|
};
|
|
6282
6310
|
}
|
|
6283
6311
|
function buildProjectConfigStatus(root) {
|
|
6284
|
-
const hasConfigTs =
|
|
6285
|
-
const hasConfigJson =
|
|
6286
|
-
const hasLegacyTaskConfig =
|
|
6312
|
+
const hasConfigTs = existsSync14(resolve20(root, "rig.config.ts"));
|
|
6313
|
+
const hasConfigJson = existsSync14(resolve20(root, "rig.config.json"));
|
|
6314
|
+
const hasLegacyTaskConfig = existsSync14(resolve20(root, ".rig", "task-config.json"));
|
|
6287
6315
|
let kind = "missing";
|
|
6288
6316
|
if (hasConfigTs)
|
|
6289
6317
|
kind = "rig-config-ts";
|
|
@@ -6401,11 +6429,11 @@ function backupCheckoutFile(checkoutPath, relativePath) {
|
|
|
6401
6429
|
}
|
|
6402
6430
|
function parsePackageJsonLosslessly(checkoutPath) {
|
|
6403
6431
|
const packagePath = resolve20(checkoutPath, "package.json");
|
|
6404
|
-
if (!
|
|
6432
|
+
if (!existsSync14(packagePath)) {
|
|
6405
6433
|
return { existed: false, packageJson: { name: basename(checkoutPath) || "rig-project", private: true } };
|
|
6406
6434
|
}
|
|
6407
6435
|
try {
|
|
6408
|
-
const parsed = JSON.parse(
|
|
6436
|
+
const parsed = JSON.parse(readFileSync10(packagePath, "utf8"));
|
|
6409
6437
|
return {
|
|
6410
6438
|
existed: true,
|
|
6411
6439
|
packageJson: parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : { name: basename(checkoutPath) || "rig-project", private: true }
|
|
@@ -6419,9 +6447,9 @@ function parsePackageJsonLosslessly(checkoutPath) {
|
|
|
6419
6447
|
}
|
|
6420
6448
|
}
|
|
6421
6449
|
function ensureRemoteCheckoutRigPackageDeps(checkoutPath) {
|
|
6422
|
-
const hasConfig = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) =>
|
|
6450
|
+
const hasConfig = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) => existsSync14(resolve20(checkoutPath, name)));
|
|
6423
6451
|
const packagePath = resolve20(checkoutPath, "package.json");
|
|
6424
|
-
if (!hasConfig && !
|
|
6452
|
+
if (!hasConfig && !existsSync14(packagePath)) {
|
|
6425
6453
|
return { skipped: true, reason: "package.json and rig.config missing" };
|
|
6426
6454
|
}
|
|
6427
6455
|
const parsed = parsePackageJsonLosslessly(checkoutPath);
|
|
@@ -6467,10 +6495,10 @@ function configLooksStructurallyUsable(source) {
|
|
|
6467
6495
|
}
|
|
6468
6496
|
function ensureRemoteCheckoutRigConfig(checkoutPath, repoSlug, reason = "missing or incomplete rig config") {
|
|
6469
6497
|
const configPath = resolve20(checkoutPath, "rig.config.ts");
|
|
6470
|
-
const existingConfigName = ["rig.config.ts", "rig.config.mts", "rig.config.json"].find((name) =>
|
|
6498
|
+
const existingConfigName = ["rig.config.ts", "rig.config.mts", "rig.config.json"].find((name) => existsSync14(resolve20(checkoutPath, name)));
|
|
6471
6499
|
if (existingConfigName) {
|
|
6472
6500
|
const existingPath = resolve20(checkoutPath, existingConfigName);
|
|
6473
|
-
const source =
|
|
6501
|
+
const source = readFileSync10(existingPath, "utf8");
|
|
6474
6502
|
if (existingConfigName !== "rig.config.json" && configLooksStructurallyUsable(source)) {
|
|
6475
6503
|
return { path: existingPath, changed: false, reason: "config structurally complete" };
|
|
6476
6504
|
}
|
|
@@ -6493,7 +6521,7 @@ function ensureRemoteCheckoutRigConfig(checkoutPath, repoSlug, reason = "missing
|
|
|
6493
6521
|
};
|
|
6494
6522
|
}
|
|
6495
6523
|
function validateRemoteCheckoutRigConfig(checkoutPath) {
|
|
6496
|
-
const configFile = ["rig.config.ts", "rig.config.mts", "rig.config.json"].find((name) =>
|
|
6524
|
+
const configFile = ["rig.config.ts", "rig.config.mts", "rig.config.json"].find((name) => existsSync14(resolve20(checkoutPath, name)));
|
|
6497
6525
|
if (!configFile)
|
|
6498
6526
|
return { ok: false, error: "missing rig config" };
|
|
6499
6527
|
if (process.env.RIG_TEST_SKIP_REMOTE_CHECKOUT_INSTALL === "1") {
|
|
@@ -6515,7 +6543,7 @@ function validateRemoteCheckoutRigConfig(checkoutPath) {
|
|
|
6515
6543
|
return { ok: true, configFile };
|
|
6516
6544
|
}
|
|
6517
6545
|
function installRemoteCheckoutPackages(checkoutPath) {
|
|
6518
|
-
if (!
|
|
6546
|
+
if (!existsSync14(resolve20(checkoutPath, "package.json"))) {
|
|
6519
6547
|
return { skipped: true, reason: "package.json missing" };
|
|
6520
6548
|
}
|
|
6521
6549
|
if (process.env.RIG_TEST_SKIP_REMOTE_CHECKOUT_INSTALL === "1") {
|
|
@@ -6528,8 +6556,8 @@ function installRemoteCheckoutPackages(checkoutPath) {
|
|
|
6528
6556
|
return { ok: true, command: "bun install", stdout: result.stdout?.trim() || undefined };
|
|
6529
6557
|
}
|
|
6530
6558
|
function repairRemoteCheckoutForRig(checkoutPath, repoSlug) {
|
|
6531
|
-
const hasConfig = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) =>
|
|
6532
|
-
const hasPackage =
|
|
6559
|
+
const hasConfig = ["rig.config.ts", "rig.config.mts", "rig.config.json"].some((name) => existsSync14(resolve20(checkoutPath, name)));
|
|
6560
|
+
const hasPackage = existsSync14(resolve20(checkoutPath, "package.json"));
|
|
6533
6561
|
if (!hasConfig && !hasPackage) {
|
|
6534
6562
|
return {
|
|
6535
6563
|
packageJson: { skipped: true, reason: "package.json and rig.config missing" },
|
|
@@ -6629,24 +6657,24 @@ function readGitHeadCommit(projectRoot) {
|
|
|
6629
6657
|
try {
|
|
6630
6658
|
let gitDir = resolve20(projectRoot, ".git");
|
|
6631
6659
|
try {
|
|
6632
|
-
const dotGit =
|
|
6660
|
+
const dotGit = readFileSync10(gitDir, "utf8").trim();
|
|
6633
6661
|
const gitDirPrefix = "gitdir:";
|
|
6634
6662
|
if (dotGit.startsWith(gitDirPrefix)) {
|
|
6635
6663
|
gitDir = resolve20(projectRoot, dotGit.slice(gitDirPrefix.length).trim());
|
|
6636
6664
|
}
|
|
6637
6665
|
} catch {}
|
|
6638
|
-
const head =
|
|
6666
|
+
const head = readFileSync10(resolve20(gitDir, "HEAD"), "utf8").trim();
|
|
6639
6667
|
const refPrefix = "ref:";
|
|
6640
6668
|
if (!head.startsWith(refPrefix)) {
|
|
6641
6669
|
return normalizeCommit(head);
|
|
6642
6670
|
}
|
|
6643
6671
|
const ref = head.slice(refPrefix.length).trim();
|
|
6644
6672
|
const refPath = resolve20(gitDir, ref);
|
|
6645
|
-
if (
|
|
6646
|
-
return normalizeCommit(
|
|
6673
|
+
if (existsSync14(refPath)) {
|
|
6674
|
+
return normalizeCommit(readFileSync10(refPath, "utf8").trim());
|
|
6647
6675
|
}
|
|
6648
|
-
const commonDir = normalizeString(
|
|
6649
|
-
return commonDir ? normalizeCommit(
|
|
6676
|
+
const commonDir = normalizeString(readFileSync10(resolve20(gitDir, "commondir"), "utf8"));
|
|
6677
|
+
return commonDir ? normalizeCommit(readFileSync10(resolve20(gitDir, commonDir, ref), "utf8").trim()) : null;
|
|
6650
6678
|
} catch {
|
|
6651
6679
|
return null;
|
|
6652
6680
|
}
|
|
@@ -6943,7 +6971,7 @@ function saveGitHubTokenForRemoteUser(input) {
|
|
|
6943
6971
|
const apiSession = store.createApiSession();
|
|
6944
6972
|
registerGitHubApiSession({ projectRoot: input.projectRoot, token: apiSession.token, namespace, selectedRepo: input.selectedRepo });
|
|
6945
6973
|
const requestedRoot = normalizeString(input.requestedProjectRoot);
|
|
6946
|
-
if (requestedRoot && isAbsolute4(requestedRoot) &&
|
|
6974
|
+
if (requestedRoot && isAbsolute4(requestedRoot) && existsSync14(resolve20(requestedRoot))) {
|
|
6947
6975
|
copyGitHubAuthStateToLocalProjectRoot(namespace.authStateFile, resolve20(requestedRoot));
|
|
6948
6976
|
}
|
|
6949
6977
|
if (shouldWriteRootAuthCompat(input.projectRoot)) {
|
|
@@ -6981,7 +7009,7 @@ function resolveRequestedProjectRoot(currentRoot, rawRoot) {
|
|
|
6981
7009
|
throw new Error("projectRoot must be an absolute path on the Rig server host");
|
|
6982
7010
|
}
|
|
6983
7011
|
const normalizedRoot = resolve20(requestedRoot);
|
|
6984
|
-
if (!
|
|
7012
|
+
if (!existsSync14(normalizedRoot)) {
|
|
6985
7013
|
throw new Error("projectRoot does not exist on the Rig server host");
|
|
6986
7014
|
}
|
|
6987
7015
|
return normalizedRoot;
|
|
@@ -7873,7 +7901,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
7873
7901
|
return deps.badRequest("projectRoot must be an absolute path on the Rig server host");
|
|
7874
7902
|
}
|
|
7875
7903
|
const normalizedRoot = resolve20(requestedRoot);
|
|
7876
|
-
const exists =
|
|
7904
|
+
const exists = existsSync14(normalizedRoot);
|
|
7877
7905
|
if (exists && requestAuth.userNamespace) {
|
|
7878
7906
|
const allowedByNamespace = isPathInsideNamespace(requestAuth.userNamespace.root, normalizedRoot);
|
|
7879
7907
|
const allowedByRegistry = projectRegistryContainsCheckout(requestAuth.userNamespace.root, normalizedRoot);
|
|
@@ -7903,7 +7931,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
7903
7931
|
message: "Requested project root does not exist on the Rig server host."
|
|
7904
7932
|
}, 404);
|
|
7905
7933
|
}
|
|
7906
|
-
if (!
|
|
7934
|
+
if (!existsSync14(resolve20(normalizedRoot, "rig.config.ts")) && !existsSync14(resolve20(normalizedRoot, "rig.config.json"))) {
|
|
7907
7935
|
return deps.jsonResponse({
|
|
7908
7936
|
ok: false,
|
|
7909
7937
|
projectRoot: state.projectRoot,
|
|
@@ -8121,8 +8149,8 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
8121
8149
|
ok: true,
|
|
8122
8150
|
projectRoot: targetRoot,
|
|
8123
8151
|
configPath,
|
|
8124
|
-
exists:
|
|
8125
|
-
requiresOverwrite:
|
|
8152
|
+
exists: existsSync14(configPath),
|
|
8153
|
+
requiresOverwrite: existsSync14(configPath),
|
|
8126
8154
|
source,
|
|
8127
8155
|
owner,
|
|
8128
8156
|
repo,
|
|
@@ -8159,7 +8187,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
8159
8187
|
githubUserId: authStatus.userId ?? authStatus.login
|
|
8160
8188
|
});
|
|
8161
8189
|
const configPath = resolve20(targetRoot, "rig.config.ts");
|
|
8162
|
-
if (
|
|
8190
|
+
if (existsSync14(configPath) && !overwrite) {
|
|
8163
8191
|
return deps.jsonResponse({
|
|
8164
8192
|
ok: false,
|
|
8165
8193
|
error: "rig.config.ts already exists. Confirm overwrite to replace it; Rig will create a backup first.",
|
|
@@ -8175,7 +8203,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
8175
8203
|
return deps.jsonResponse({ ok: false, error: repoProbe.message, repoProbe }, 400);
|
|
8176
8204
|
}
|
|
8177
8205
|
let backupPath = null;
|
|
8178
|
-
if (
|
|
8206
|
+
if (existsSync14(configPath)) {
|
|
8179
8207
|
backupPath = backupConfigPath(configPath);
|
|
8180
8208
|
copyFileSync2(configPath, backupPath);
|
|
8181
8209
|
}
|
|
@@ -8465,7 +8493,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
8465
8493
|
}
|
|
8466
8494
|
if (url.pathname === "/api/pi-rig/install" && req.method === "POST") {
|
|
8467
8495
|
const configuredPackageSource = normalizeString(process.env.RIG_PI_RIG_PACKAGE_SOURCE);
|
|
8468
|
-
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) =>
|
|
8496
|
+
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";
|
|
8469
8497
|
if (process.env.RIG_TEST_FAKE_PI_INSTALL === "1") {
|
|
8470
8498
|
return deps.jsonResponse({ ok: true, installed: true, piOk: true, piRigOk: true, extensionPath: "remote:~/.pi/agent/extensions/pi-rig", packageSource });
|
|
8471
8499
|
}
|
|
@@ -9012,7 +9040,7 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
9012
9040
|
} catch {
|
|
9013
9041
|
return deps.badRequest("Invalid artifact path");
|
|
9014
9042
|
}
|
|
9015
|
-
if (!
|
|
9043
|
+
if (!existsSync14(artifactPath)) {
|
|
9016
9044
|
return deps.notFound();
|
|
9017
9045
|
}
|
|
9018
9046
|
return new Response(Bun.file(artifactPath));
|
|
@@ -9082,8 +9110,6 @@ data: ${JSON.stringify({ connectedAt: new Date().toISOString() })}
|
|
|
9082
9110
|
return `${sessionPath}/shell`;
|
|
9083
9111
|
if (action === "commands/run" && req.method === "POST")
|
|
9084
9112
|
return `${sessionPath}/commands/run`;
|
|
9085
|
-
if (action === "commands/respond" && req.method === "POST")
|
|
9086
|
-
return `${sessionPath}/commands/respond`;
|
|
9087
9113
|
if (action === "extension-ui/respond" && req.method === "POST")
|
|
9088
9114
|
return `${sessionPath}/extension-ui/respond`;
|
|
9089
9115
|
if (action === "abort" && req.method === "POST")
|
|
@@ -9956,7 +9982,7 @@ async function routeWebSocketRequest(state, deps, request) {
|
|
|
9956
9982
|
}
|
|
9957
9983
|
|
|
9958
9984
|
// packages/server/src/server-helpers/inspector-jobs.ts
|
|
9959
|
-
import { existsSync as
|
|
9985
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync15 } from "fs";
|
|
9960
9986
|
import { dirname as dirname18, resolve as resolve23 } from "path";
|
|
9961
9987
|
import { readJsonFile as readJsonFile3 } from "@rig/runtime/control-plane/authority-files";
|
|
9962
9988
|
import { resolveMonorepoRoot as resolveMonorepoRoot5 } from "@rig/runtime/control-plane/native/utils";
|
|
@@ -10065,7 +10091,7 @@ import { randomUUID as randomUUID3 } from "crypto";
|
|
|
10065
10091
|
|
|
10066
10092
|
// packages/server/src/inspector/mission.ts
|
|
10067
10093
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
10068
|
-
import { appendFileSync, existsSync as
|
|
10094
|
+
import { appendFileSync, existsSync as existsSync15, mkdirSync as mkdirSync14, readFileSync as readFileSync11, readdirSync as readdirSync4, renameSync, writeFileSync as writeFileSync13 } from "fs";
|
|
10069
10095
|
import { dirname as dirname16, join, resolve as resolve21 } from "path";
|
|
10070
10096
|
function isJsonValue(value) {
|
|
10071
10097
|
if (value === null)
|
|
@@ -10106,7 +10132,7 @@ function isRecord2(value) {
|
|
|
10106
10132
|
}
|
|
10107
10133
|
function readJsonRecord(path) {
|
|
10108
10134
|
try {
|
|
10109
|
-
const parsed = JSON.parse(
|
|
10135
|
+
const parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
10110
10136
|
if (!isRecord2(parsed)) {
|
|
10111
10137
|
return { ok: false, error: `Mission file ${path} does not contain an object` };
|
|
10112
10138
|
}
|
|
@@ -10219,9 +10245,9 @@ function createInspectorMissionController(options) {
|
|
|
10219
10245
|
}
|
|
10220
10246
|
function listMissionJournal(missionId) {
|
|
10221
10247
|
const path = journalPath(missionId);
|
|
10222
|
-
if (!
|
|
10248
|
+
if (!existsSync15(path))
|
|
10223
10249
|
return [];
|
|
10224
|
-
return
|
|
10250
|
+
return readFileSync11(path, "utf8").split(`
|
|
10225
10251
|
`).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line)).filter(isRecord2).map((entry) => ({
|
|
10226
10252
|
id: typeof entry.id === "string" ? entry.id : `journal:${randomUUID2()}`,
|
|
10227
10253
|
missionId,
|
|
@@ -10237,7 +10263,7 @@ function createInspectorMissionController(options) {
|
|
|
10237
10263
|
}
|
|
10238
10264
|
function readMissionOnly(missionId) {
|
|
10239
10265
|
const path = missionPath(missionId);
|
|
10240
|
-
if (!
|
|
10266
|
+
if (!existsSync15(path)) {
|
|
10241
10267
|
return { ok: false, error: `Mission ${missionId} was not found` };
|
|
10242
10268
|
}
|
|
10243
10269
|
const read = readJsonRecord(path);
|
|
@@ -10288,7 +10314,7 @@ function createInspectorMissionController(options) {
|
|
|
10288
10314
|
const source = cloneJsonRecord(input.sourceTask);
|
|
10289
10315
|
const missionId = nextId();
|
|
10290
10316
|
const path = missionPath(missionId);
|
|
10291
|
-
if (
|
|
10317
|
+
if (existsSync15(path)) {
|
|
10292
10318
|
const existing = readMissionOnly(missionId);
|
|
10293
10319
|
if (!existing.ok)
|
|
10294
10320
|
return existing;
|
|
@@ -12795,7 +12821,7 @@ function createGlobalInspectorService(options) {
|
|
|
12795
12821
|
|
|
12796
12822
|
// packages/server/src/inspector/upstream-sync.ts
|
|
12797
12823
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
12798
|
-
import { existsSync as
|
|
12824
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync14 } from "fs";
|
|
12799
12825
|
import { dirname as dirname17, resolve as resolve22 } from "path";
|
|
12800
12826
|
import { resolveMonorepoRoot as resolveMonorepoRoot4 } from "@rig/runtime/control-plane/native/utils";
|
|
12801
12827
|
var UPSTREAM_VALIDATION_DESCRIPTIONS = {
|
|
@@ -12940,11 +12966,11 @@ function upstreamStatePath(projectRoot, override) {
|
|
|
12940
12966
|
}
|
|
12941
12967
|
function readUpstreamState(projectRoot, statePath) {
|
|
12942
12968
|
const path = upstreamStatePath(projectRoot, statePath);
|
|
12943
|
-
if (!
|
|
12969
|
+
if (!existsSync16(path)) {
|
|
12944
12970
|
return null;
|
|
12945
12971
|
}
|
|
12946
12972
|
try {
|
|
12947
|
-
return JSON.parse(
|
|
12973
|
+
return JSON.parse(readFileSync12(path, "utf-8"));
|
|
12948
12974
|
} catch {
|
|
12949
12975
|
return null;
|
|
12950
12976
|
}
|
|
@@ -12958,10 +12984,10 @@ function writeUpstreamState(projectRoot, state, statePath) {
|
|
|
12958
12984
|
function readImportedRevision(projectRoot, upstreamsDocPath) {
|
|
12959
12985
|
const monorepoRoot = resolveMonorepoRoot4(projectRoot);
|
|
12960
12986
|
const docPath = upstreamsDocPath ? resolve22(upstreamsDocPath) : resolve22(monorepoRoot, "docs", "UPSTREAMS.md");
|
|
12961
|
-
if (!
|
|
12987
|
+
if (!existsSync16(docPath)) {
|
|
12962
12988
|
throw new Error(`UPSTREAMS.md not found at ${docPath}`);
|
|
12963
12989
|
}
|
|
12964
|
-
const docContent =
|
|
12990
|
+
const docContent = readFileSync12(docPath, "utf-8");
|
|
12965
12991
|
const revision = parseImportedUpstreamRevision(docContent, "upstream") ?? parseImportedUpstreamRevision(docContent, "humoongate");
|
|
12966
12992
|
if (!revision) {
|
|
12967
12993
|
throw new Error(`Failed to parse upstream imported revision from ${docPath}`);
|
|
@@ -12983,7 +13009,7 @@ function resolveRemoteBranch(repoRoot, remote, gitRunner) {
|
|
|
12983
13009
|
return null;
|
|
12984
13010
|
}
|
|
12985
13011
|
function isGitCheckout(path, gitRunner) {
|
|
12986
|
-
if (!
|
|
13012
|
+
if (!existsSync16(resolve22(path, ".git"))) {
|
|
12987
13013
|
return false;
|
|
12988
13014
|
}
|
|
12989
13015
|
const result = gitRunner(path, ["rev-parse", "--is-inside-work-tree"]);
|
|
@@ -13233,10 +13259,10 @@ async function runUpstreamSyncScan(options) {
|
|
|
13233
13259
|
}
|
|
13234
13260
|
|
|
13235
13261
|
// packages/server/src/server-helpers/task-config.ts
|
|
13236
|
-
import { existsSync as
|
|
13262
|
+
import { existsSync as existsSync17 } from "fs";
|
|
13237
13263
|
async function readTaskConfig(projectRoot) {
|
|
13238
13264
|
const taskConfigPath = resolveRigServerPaths(projectRoot).taskConfigPath;
|
|
13239
|
-
if (!
|
|
13265
|
+
if (!existsSync17(taskConfigPath)) {
|
|
13240
13266
|
return {};
|
|
13241
13267
|
}
|
|
13242
13268
|
try {
|
|
@@ -13295,7 +13321,7 @@ async function createInspectorFollowupTask(projectRoot, input) {
|
|
|
13295
13321
|
const sourceKey = normalizeString(input.sourceKey) ?? normalizeString(input.details?.sourceKey);
|
|
13296
13322
|
const createdAt = normalizeString(input.createdAt) ?? new Date().toISOString();
|
|
13297
13323
|
const status = normalizeTaskLifecycleStatus2(normalizeString(input.status) ?? "open") ?? "open";
|
|
13298
|
-
const existingIssueLines =
|
|
13324
|
+
const existingIssueLines = existsSync18(issuesPath) ? readFileSync13(issuesPath, "utf8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean) : [];
|
|
13299
13325
|
const existingIssues = existingIssueLines.map((line) => {
|
|
13300
13326
|
try {
|
|
13301
13327
|
return JSON.parse(line);
|
|
@@ -13304,7 +13330,7 @@ async function createInspectorFollowupTask(projectRoot, input) {
|
|
|
13304
13330
|
}
|
|
13305
13331
|
}).filter((value) => value !== null);
|
|
13306
13332
|
const existingIds = new Set(existingIssues.map((issue) => typeof issue.id === "string" ? issue.id : null).filter((value) => value !== null));
|
|
13307
|
-
const rawTaskState =
|
|
13333
|
+
const rawTaskState = existsSync18(taskStatePath) ? readJsonFile3(taskStatePath, {}) : {};
|
|
13308
13334
|
const tasks = rawTaskState.tasks && typeof rawTaskState.tasks === "object" && !Array.isArray(rawTaskState.tasks) ? rawTaskState.tasks : {};
|
|
13309
13335
|
const existingTaskIdFromSourceKey = sourceKey == null ? null : Object.entries(tasks).find(([, metadata]) => {
|
|
13310
13336
|
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
@@ -13675,10 +13701,10 @@ function isAuthorizedLinearWebhookRequest(req) {
|
|
|
13675
13701
|
}
|
|
13676
13702
|
|
|
13677
13703
|
// packages/server/src/server-helpers/notifications.ts
|
|
13678
|
-
import { existsSync as
|
|
13704
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync17, readFileSync as readFileSync14 } from "fs";
|
|
13679
13705
|
import { dirname as dirname19 } from "path";
|
|
13680
13706
|
async function loadNotificationConfig(path) {
|
|
13681
|
-
if (!
|
|
13707
|
+
if (!existsSync19(path)) {
|
|
13682
13708
|
const defaultConfig = { targets: [] };
|
|
13683
13709
|
mkdirSync17(dirname19(path), { recursive: true });
|
|
13684
13710
|
await Bun.write(path, `${JSON.stringify(defaultConfig, null, 2)}
|
|
@@ -13695,10 +13721,10 @@ async function loadNotificationConfig(path) {
|
|
|
13695
13721
|
}
|
|
13696
13722
|
}
|
|
13697
13723
|
function readRecentEvents(file, limit) {
|
|
13698
|
-
if (!
|
|
13724
|
+
if (!existsSync19(file)) {
|
|
13699
13725
|
return [];
|
|
13700
13726
|
}
|
|
13701
|
-
const lines =
|
|
13727
|
+
const lines = readFileSync14(file, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).slice(-limit);
|
|
13702
13728
|
const events = [];
|
|
13703
13729
|
for (const line of lines) {
|
|
13704
13730
|
try {
|
|
@@ -13794,10 +13820,10 @@ function extractObjectLiteralBlock(source, property) {
|
|
|
13794
13820
|
function readFallbackIssueAnalysisConfig(projectRoot) {
|
|
13795
13821
|
for (const fileName of ["rig.config.ts", "rig.config.json"]) {
|
|
13796
13822
|
const path = resolve24(projectRoot, fileName);
|
|
13797
|
-
if (!
|
|
13823
|
+
if (!existsSync20(path))
|
|
13798
13824
|
continue;
|
|
13799
13825
|
try {
|
|
13800
|
-
const source =
|
|
13826
|
+
const source = readFileSync15(path, "utf8");
|
|
13801
13827
|
if (fileName.endsWith(".json"))
|
|
13802
13828
|
return JSON.parse(source);
|
|
13803
13829
|
const issueBlock = extractObjectLiteralBlock(source, "issueAnalysis");
|
|
@@ -13969,7 +13995,7 @@ async function withServerAuthorityEnvIfNeeded(projectRoot, fn) {
|
|
|
13969
13995
|
async function readWorkspaceTasks(projectRoot) {
|
|
13970
13996
|
const issuesPath = resolve24(resolveMonorepoRoot6(projectRoot), ".beads", "issues.jsonl");
|
|
13971
13997
|
const taskConfig = await readTaskConfig(projectRoot);
|
|
13972
|
-
if (!
|
|
13998
|
+
if (!existsSync20(issuesPath)) {
|
|
13973
13999
|
return [];
|
|
13974
14000
|
}
|
|
13975
14001
|
const latestById = new Map;
|
|
@@ -14061,7 +14087,7 @@ async function listArtifactSummaries(projectRoot, taskId, knownTaskIds, knownRun
|
|
|
14061
14087
|
}
|
|
14062
14088
|
}
|
|
14063
14089
|
return taskIds.flatMap((currentTaskId) => {
|
|
14064
|
-
const currentRoot = resolveTaskArtifactDirsFromRuns(projectRoot, currentTaskId, runs).find((path) =>
|
|
14090
|
+
const currentRoot = resolveTaskArtifactDirsFromRuns(projectRoot, currentTaskId, runs).find((path) => existsSync20(path));
|
|
14065
14091
|
if (!currentRoot) {
|
|
14066
14092
|
return [];
|
|
14067
14093
|
}
|
|
@@ -14116,7 +14142,7 @@ function buildInspectorStreamPayload(state, sequence) {
|
|
|
14116
14142
|
}
|
|
14117
14143
|
function listRemoteRunArtifacts(projectRoot, runId) {
|
|
14118
14144
|
const root = remoteArtifactsRoot(projectRoot, runId);
|
|
14119
|
-
if (!
|
|
14145
|
+
if (!existsSync20(root)) {
|
|
14120
14146
|
return [];
|
|
14121
14147
|
}
|
|
14122
14148
|
return readdirSync5(root, { withFileTypes: true }).filter((entry) => entry.isFile()).filter((entry) => !entry.name.endsWith(".json")).map((entry) => {
|
|
@@ -14414,10 +14440,10 @@ function startRunFileWatcher(state, pollMs) {
|
|
|
14414
14440
|
}, Math.max(250, Math.min(pollMs, 1000)));
|
|
14415
14441
|
}
|
|
14416
14442
|
function startPoller(state, pollMs) {
|
|
14417
|
-
let offset =
|
|
14443
|
+
let offset = existsSync20(state.eventsFile) ? statSync6(state.eventsFile).size : 0;
|
|
14418
14444
|
return setInterval(async () => {
|
|
14419
14445
|
try {
|
|
14420
|
-
if (!
|
|
14446
|
+
if (!existsSync20(state.eventsFile)) {
|
|
14421
14447
|
return;
|
|
14422
14448
|
}
|
|
14423
14449
|
const file = await open(state.eventsFile, "r");
|