@gobing-ai/spur 0.4.12 → 0.4.13
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/.claude-plugin/marketplace.json +1 -1
- package/config/rules/boundary/config-loading-ownership.yaml +1 -1
- package/config/rules/strict/runtime-boundaries.yaml +2 -2
- package/config/rules/typescript/output-boundaries.yaml +4 -10
- package/config/workflows/task-pipeline.yaml +2 -2
- package/package.json +1 -1
- package/plugins/sp/commands/dev-run.md +1 -1
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +3 -3
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +4 -4
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +1 -1
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +1 -1
- package/spur.js +251 -246
- package/web/_astro/{BoardApp.BMprmPRc.js → BoardApp.Bjdp3XWV.js} +36 -36
- package/web/_astro/{BoardApp.B5rTVNd_.js → BoardApp.DCDZxLlQ.js} +1 -1
- package/web/_astro/{TaskDetail.Ddsur8qd.js → TaskDetail.B3vBxynO.js} +1 -1
- package/web/_astro/{arc.DLqVVBxP.js → arc.DcuHTB_T.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.C-Pk3uAi.js → architectureDiagram-3BPJPVTR.ClOFWBON.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.BRO1i_Nm.js → blockDiagram-GPEHLZMM.otYyr7Zb.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BU_cWu6e.js → c4Diagram-AAUBKEIU.BCjpc9LP.js} +1 -1
- package/web/_astro/channel.qgOLXjI_.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.D2VXiQ2t.js → chunk-2J33WTMH.D5Wpnpt_.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BcHT772J.js → chunk-4BX2VUAB.DkQGtWNz.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.DhDtICmo.js → chunk-55IACEB6.B7dqjAip.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.BoKHp7gV.js → chunk-727SXJPM.BDQvnKE2.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.Chu4JRpE.js → chunk-AQP2D5EJ.D92doBX5.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.wHdwKPlq.js → chunk-FMBD7UC4.C968oI5G.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.ffN-M1JB.js → chunk-ND2GUHAM.AkkYC1bY.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.FRubwg4S.js → chunk-QZHKN3VN.sCc-rKKo.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.c22tQsc_.js → classDiagram-4FO5ZUOK.pOQ9u0mY.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.c22tQsc_.js → classDiagram-v2-Q7XG4LA2.pOQ9u0mY.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.B9c6fiSj.js → cose-bilkent-S5V4N54A.CRaeD6FY.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.DrZsrUHl.js → cynefin-OW5HDTMX.BiCPBu54.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.DG1U4b3y.js → dagre-BM42HDAG.C1-q3vkT.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.CH15b-K3.js → diagram-2AECGRRQ.BSVOv30O.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.BH1j7twR.js → diagram-5GNKFQAL.CHMkjJ-V.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.q2zCkbAj.js → diagram-KO2AKTUF.CKY9M564.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.BLaaZnHV.js → diagram-LMA3HP47.B9yNJiTP.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.BcpRdQwI.js → diagram-OG6HWLK6.Dk8AUGsk.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.D7KBlqfM.js → erDiagram-TEJ5UH35.BQHR89TZ.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.D_gmuRqg.js → flowDiagram-I6XJVG4X.oNkWVgoK.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DzgWYniD.js → ganttDiagram-6RSMTGT7.Kz2U2nu9.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.576i3hm3.js → gitGraphDiagram-PVQCEYII.DHIZ_wPq.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.DMCclBiz.js → infoDiagram-5YYISTIA.D0NJLcv9.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.9Kyca4SH.js → ishikawaDiagram-YF4QCWOH.CFEfTWRG.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.chbdG-8q.js → journeyDiagram-JHISSGLW.Dc7IE7I4.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.Bds54-e0.js → kanban-definition-UN3LZRKU.D5v0xO9k.js} +1 -1
- package/web/_astro/{linear.D5ND9GN_.js → linear.wR5KzXnE.js} +1 -1
- package/web/_astro/{mermaid.core.D9N_PGbj.js → mermaid.core.BDQ2FoPd.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.t0xop5vp.js → mindmap-definition-RKZ34NQL.W6_INsia.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.DqgKh6hM.js → pieDiagram-4H26LBE5.61ihbgkK.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.DeuHVi2t.js → quadrantDiagram-W4KKPZXB.B5lEpFLo.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.BdYFSG4W.js → requirementDiagram-4Y6WPE33.CmhVBVX0.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.k1LPPETJ.js → sankeyDiagram-5OEKKPKP.D7Vvj9Wf.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.DdyfpzoG.js → sequenceDiagram-3UESZ5HK.B1vPLixM.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.DSEI8il0.js → stateDiagram-AJRCARHV.BnACmrGi.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CoMnQRKo.js → stateDiagram-v2-BHNVJYJU.CW4pnmc3.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.DM1AHNm-.js → timeline-definition-PNZ67QCA.CkzMCPnC.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.C-cJmVtl.js → vennDiagram-CIIHVFJN.CY4aNdAR.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.D0xMzKPb.js → wardleyDiagram-YWT4CUSO.BtoU9UFk.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.BH5xJcEq.js → xychartDiagram-2RQKCTM6._9ijUUAs.js} +1 -1
- package/web/index.html +1 -1
- package/web/_astro/channel.Bs3Illhy.js +0 -1
package/spur.js
CHANGED
|
@@ -85591,6 +85591,14 @@ async function findListeningPid(port, executor = new NodeProcessExecutor2, platf
|
|
|
85591
85591
|
} catch {}
|
|
85592
85592
|
return;
|
|
85593
85593
|
}
|
|
85594
|
+
function isPidAlive(pid) {
|
|
85595
|
+
try {
|
|
85596
|
+
process.kill(pid, 0);
|
|
85597
|
+
return true;
|
|
85598
|
+
} catch (error) {
|
|
85599
|
+
return error.code !== "ESRCH";
|
|
85600
|
+
}
|
|
85601
|
+
}
|
|
85594
85602
|
function sendSignalToPid(pid, signal) {
|
|
85595
85603
|
if (testProcessKiller) {
|
|
85596
85604
|
return testProcessKiller(pid, signal);
|
|
@@ -85814,7 +85822,17 @@ var init_project_stop = __esm(() => {
|
|
|
85814
85822
|
});
|
|
85815
85823
|
|
|
85816
85824
|
// ../../packages/app/src/services/project-registry.ts
|
|
85817
|
-
import {
|
|
85825
|
+
import {
|
|
85826
|
+
existsSync as existsSync8,
|
|
85827
|
+
mkdirSync as mkdirSync4,
|
|
85828
|
+
readdirSync as readdirSync4,
|
|
85829
|
+
readFileSync as readFileSync6,
|
|
85830
|
+
renameSync as renameSync4,
|
|
85831
|
+
rmdirSync,
|
|
85832
|
+
rmSync as rmSync3,
|
|
85833
|
+
unlinkSync as unlinkSync3,
|
|
85834
|
+
writeFileSync as writeFileSync4
|
|
85835
|
+
} from "fs";
|
|
85818
85836
|
import { dirname as dirname9, join as join18 } from "path";
|
|
85819
85837
|
|
|
85820
85838
|
class ProjectRegistry {
|
|
@@ -85853,6 +85871,8 @@ class ProjectRegistry {
|
|
|
85853
85871
|
if (code !== "EEXIST") {
|
|
85854
85872
|
throw err;
|
|
85855
85873
|
}
|
|
85874
|
+
if (this.reclaimDeadOwnerLock())
|
|
85875
|
+
continue;
|
|
85856
85876
|
await new Promise((r) => setTimeout(r, 50));
|
|
85857
85877
|
}
|
|
85858
85878
|
}
|
|
@@ -85882,6 +85902,24 @@ class ProjectRegistry {
|
|
|
85882
85902
|
}
|
|
85883
85903
|
}
|
|
85884
85904
|
}
|
|
85905
|
+
reclaimDeadOwnerLock() {
|
|
85906
|
+
let markers;
|
|
85907
|
+
try {
|
|
85908
|
+
markers = readdirSync4(this.lockDir);
|
|
85909
|
+
} catch {
|
|
85910
|
+
return false;
|
|
85911
|
+
}
|
|
85912
|
+
if (markers.length === 0 || markers.some((marker) => isPidAlive(Number.parseInt(marker, 10))))
|
|
85913
|
+
return false;
|
|
85914
|
+
const tombstone = `${this.lockDir}.stale-${crypto.randomUUID()}`;
|
|
85915
|
+
try {
|
|
85916
|
+
renameSync4(this.lockDir, tombstone);
|
|
85917
|
+
} catch {
|
|
85918
|
+
return false;
|
|
85919
|
+
}
|
|
85920
|
+
rmSync3(tombstone, { recursive: true, force: true });
|
|
85921
|
+
return true;
|
|
85922
|
+
}
|
|
85885
85923
|
readRaw() {
|
|
85886
85924
|
return this.readRawWithStatus().data;
|
|
85887
85925
|
}
|
|
@@ -87819,7 +87857,7 @@ import {
|
|
|
87819
87857
|
linkSync,
|
|
87820
87858
|
lstatSync,
|
|
87821
87859
|
mkdirSync as mkdirSync6,
|
|
87822
|
-
readdirSync as
|
|
87860
|
+
readdirSync as readdirSync5,
|
|
87823
87861
|
readFileSync as readFileSync9,
|
|
87824
87862
|
realpathSync as realpathSync4,
|
|
87825
87863
|
renameSync as renameSync5,
|
|
@@ -88076,7 +88114,7 @@ async function migrateRunStorage(input) {
|
|
|
88076
88114
|
let names;
|
|
88077
88115
|
try {
|
|
88078
88116
|
await resolveRunArtifactPath(fs, dirs.projectRoot, join26(dirs.scratchDir, "migration-probe"));
|
|
88079
|
-
const dirents =
|
|
88117
|
+
const dirents = readdirSync5(dirs.scratchDir, { withFileTypes: true });
|
|
88080
88118
|
names = dirents.filter((item) => item.isFile()).map((item) => item.name);
|
|
88081
88119
|
for (const item of dirents) {
|
|
88082
88120
|
if (!item.isDirectory())
|
|
@@ -88085,7 +88123,7 @@ async function migrateRunStorage(input) {
|
|
|
88085
88123
|
if (!existsSync11(join26(subtree, "agent-sessions")) && !existsSync11(join26(subtree, "artifacts")))
|
|
88086
88124
|
continue;
|
|
88087
88125
|
const walk = (dir) => {
|
|
88088
|
-
for (const entry of
|
|
88126
|
+
for (const entry of readdirSync5(dir, { withFileTypes: true })) {
|
|
88089
88127
|
if (entry.isDirectory())
|
|
88090
88128
|
walk(join26(dir, entry.name));
|
|
88091
88129
|
else if (entry.isFile())
|
|
@@ -92548,51 +92586,6 @@ var init_agent_doctor_report = __esm(() => {
|
|
|
92548
92586
|
USAGE_SNAPSHOT_STALE_MS = 6 * 60 * 60 * 1000;
|
|
92549
92587
|
});
|
|
92550
92588
|
|
|
92551
|
-
// ../../packages/app/src/services/inline-run-attribution.ts
|
|
92552
|
-
import { join as join31, resolve as resolve10 } from "path";
|
|
92553
|
-
async function openInlineRunProjectDb(workdir) {
|
|
92554
|
-
const { mkdirSync } = process.getBuiltinModule("node:fs");
|
|
92555
|
-
const url = join31(resolve10(workdir), ".spur", "spur.db");
|
|
92556
|
-
mkdirSync(join31(url, ".."), { recursive: true });
|
|
92557
|
-
const adapter = await createMigratedDb({ url });
|
|
92558
|
-
return { adapter, close: () => adapter.close() };
|
|
92559
|
-
}
|
|
92560
|
-
function countUnattributedInlineStages(projectRoot) {
|
|
92561
|
-
const scratchDir = runStoragePaths(projectRoot).scratchDir;
|
|
92562
|
-
let files;
|
|
92563
|
-
try {
|
|
92564
|
-
files = readdirSync5(scratchDir).filter((entry) => entry.endsWith("-attribution.jsonl"));
|
|
92565
|
-
} catch {
|
|
92566
|
-
return 0;
|
|
92567
|
-
}
|
|
92568
|
-
let count = 0;
|
|
92569
|
-
for (const file of files) {
|
|
92570
|
-
let text;
|
|
92571
|
-
try {
|
|
92572
|
-
text = readFileSync11(join31(scratchDir, file), "utf8");
|
|
92573
|
-
} catch {
|
|
92574
|
-
continue;
|
|
92575
|
-
}
|
|
92576
|
-
for (const line of text.split(`
|
|
92577
|
-
`)) {
|
|
92578
|
-
if (line.trim() === "")
|
|
92579
|
-
continue;
|
|
92580
|
-
try {
|
|
92581
|
-
const row = JSON.parse(line);
|
|
92582
|
-
if (row.executor === null)
|
|
92583
|
-
count += 1;
|
|
92584
|
-
} catch {}
|
|
92585
|
-
}
|
|
92586
|
-
}
|
|
92587
|
-
return count;
|
|
92588
|
-
}
|
|
92589
|
-
var readdirSync5, readFileSync11;
|
|
92590
|
-
var init_inline_run_attribution = __esm(() => {
|
|
92591
|
-
init_src2();
|
|
92592
|
-
init_run_storage();
|
|
92593
|
-
({ readdirSync: readdirSync5, readFileSync: readFileSync11 } = process.getBuiltinModule("node:fs"));
|
|
92594
|
-
});
|
|
92595
|
-
|
|
92596
92589
|
// ../../packages/app/src/services/agent-doctor-ops.ts
|
|
92597
92590
|
class AgentDoctorOps {
|
|
92598
92591
|
ctx;
|
|
@@ -92754,8 +92747,7 @@ class AgentDoctorOps {
|
|
|
92754
92747
|
cache: cacheField,
|
|
92755
92748
|
usage: usage ?? null,
|
|
92756
92749
|
inlineFailFast: {
|
|
92757
|
-
refreshJob: readObservationRefreshStatus(this.ctx.cwd)
|
|
92758
|
-
unattributedStages: countUnattributedInlineStages(this.ctx.cwd)
|
|
92750
|
+
refreshJob: readObservationRefreshStatus(this.ctx.cwd)
|
|
92759
92751
|
}
|
|
92760
92752
|
}, { enveloped }));
|
|
92761
92753
|
} else {
|
|
@@ -92775,12 +92767,11 @@ var init_agent_doctor_ops = __esm(() => {
|
|
|
92775
92767
|
init_agent_doctor_report();
|
|
92776
92768
|
init_agent_quota_refresh();
|
|
92777
92769
|
init_executor_tier();
|
|
92778
|
-
init_inline_run_attribution();
|
|
92779
92770
|
});
|
|
92780
92771
|
|
|
92781
92772
|
// ../../packages/app/src/observability/agent-run-log.ts
|
|
92782
92773
|
import { closeSync as closeSync4, mkdirSync as mkdirSync8, openSync as openSync4, writeSync as writeSync3 } from "fs";
|
|
92783
|
-
import { dirname as dirname17, join as
|
|
92774
|
+
import { dirname as dirname17, join as join31 } from "path";
|
|
92784
92775
|
|
|
92785
92776
|
class AgentRunLog {
|
|
92786
92777
|
filePath;
|
|
@@ -92792,7 +92783,7 @@ class AgentRunLog {
|
|
|
92792
92783
|
bytes = 0;
|
|
92793
92784
|
truncated = false;
|
|
92794
92785
|
constructor(options) {
|
|
92795
|
-
this.filePath =
|
|
92786
|
+
this.filePath = join31(options.dir, `${options.runId}.md`);
|
|
92796
92787
|
this.secrets = options.secrets ?? [];
|
|
92797
92788
|
this.maxBytes = options.maxBytes ?? DEFAULT_AGENT_RUN_LOG_MAX_BYTES;
|
|
92798
92789
|
}
|
|
@@ -93028,7 +93019,7 @@ var init_event_bridge = __esm(() => {
|
|
|
93028
93019
|
|
|
93029
93020
|
// ../../packages/app/src/services/run-session-observer.ts
|
|
93030
93021
|
import { homedir as homedir7 } from "os";
|
|
93031
|
-
import { basename as basename5, isAbsolute as isAbsolute6, relative as relative4, resolve as
|
|
93022
|
+
import { basename as basename5, isAbsolute as isAbsolute6, relative as relative4, resolve as resolve10, sep as sep5 } from "path";
|
|
93032
93023
|
function claudeProjectDir(cwd) {
|
|
93033
93024
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
93034
93025
|
}
|
|
@@ -93139,7 +93130,7 @@ class RunSessionObserver {
|
|
|
93139
93130
|
const candidates = [];
|
|
93140
93131
|
let newest = 0;
|
|
93141
93132
|
for (const rel of files) {
|
|
93142
|
-
const full =
|
|
93133
|
+
const full = resolve10(wm.root, rel);
|
|
93143
93134
|
if (wm.projectDirs !== undefined && !wm.projectDirs.has(relative4(wm.root, full).split(sep5, 1)[0] ?? "")) {
|
|
93144
93135
|
continue;
|
|
93145
93136
|
}
|
|
@@ -93230,10 +93221,10 @@ class RunSessionObserver {
|
|
|
93230
93221
|
}
|
|
93231
93222
|
resolveRoot(source, sessionDir) {
|
|
93232
93223
|
if (sessionDir !== undefined && sessionDir !== "") {
|
|
93233
|
-
return isAbsolute6(sessionDir) ? sessionDir :
|
|
93224
|
+
return isAbsolute6(sessionDir) ? sessionDir : resolve10(this.cwd, sessionDir);
|
|
93234
93225
|
}
|
|
93235
93226
|
const roots = SOURCE_DEFINITIONS[source].defaultRoots;
|
|
93236
|
-
return
|
|
93227
|
+
return resolve10(this.home, roots[0] ?? "");
|
|
93237
93228
|
}
|
|
93238
93229
|
}
|
|
93239
93230
|
function firstString2(...values) {
|
|
@@ -93266,7 +93257,7 @@ var init_run_session_observer = __esm(() => {
|
|
|
93266
93257
|
|
|
93267
93258
|
// ../../packages/app/src/services/agent-run-executor.ts
|
|
93268
93259
|
import { homedir as homedir8 } from "os";
|
|
93269
|
-
import { basename as basename6, join as
|
|
93260
|
+
import { basename as basename6, join as join32, relative as relative5 } from "path";
|
|
93270
93261
|
import { isatty as isatty2 } from "tty";
|
|
93271
93262
|
|
|
93272
93263
|
class AgentRunExecutor {
|
|
@@ -93377,7 +93368,7 @@ class AgentRunExecutor {
|
|
|
93377
93368
|
const envParentRunId = this.ctx.env.SPUR_RUN_ID ?? "";
|
|
93378
93369
|
const parentRunId = flagParentRunId !== "" ? flagParentRunId : envParentRunId !== "" && envParentRunId !== coordinationRunId ? envParentRunId : undefined;
|
|
93379
93370
|
const agentLog = new AgentRunLog({
|
|
93380
|
-
dir:
|
|
93371
|
+
dir: join32(this.ctx.cwd, ".spur", "memory", "runs"),
|
|
93381
93372
|
runId: coordinationRunId,
|
|
93382
93373
|
secrets: configuredSecretValues(this.ctx.env)
|
|
93383
93374
|
});
|
|
@@ -93688,9 +93679,9 @@ class AgentRunExecutor {
|
|
|
93688
93679
|
const relDir = relative5(this.ctx.cwd, runDir);
|
|
93689
93680
|
const record = readWorkflowRunRecord(runDir, runId);
|
|
93690
93681
|
if (record.kind === "pair" || record.kind === "incomplete") {
|
|
93691
|
-
refs.push({ kind: "log", path:
|
|
93682
|
+
refs.push({ kind: "log", path: join32(relDir, basename6(record.markdownPath)) });
|
|
93692
93683
|
} else if (record.kind === "legacy-log") {
|
|
93693
|
-
refs.push({ kind: "log", path:
|
|
93684
|
+
refs.push({ kind: "log", path: join32(relDir, basename6(record.logPath)) });
|
|
93694
93685
|
}
|
|
93695
93686
|
return refs;
|
|
93696
93687
|
}
|
|
@@ -93982,7 +93973,7 @@ var init_agent_service = __esm(() => {
|
|
|
93982
93973
|
});
|
|
93983
93974
|
|
|
93984
93975
|
// ../../packages/app/src/services/agent-trace-service.ts
|
|
93985
|
-
import { join as
|
|
93976
|
+
import { join as join33 } from "path";
|
|
93986
93977
|
|
|
93987
93978
|
class AgentTraceService {
|
|
93988
93979
|
deps;
|
|
@@ -93990,7 +93981,7 @@ class AgentTraceService {
|
|
|
93990
93981
|
this.deps = deps;
|
|
93991
93982
|
}
|
|
93992
93983
|
get logDir() {
|
|
93993
|
-
return this.deps.logDir ??
|
|
93984
|
+
return this.deps.logDir ?? join33(this.deps.projectPath, ".spur", "memory", "runs");
|
|
93994
93985
|
}
|
|
93995
93986
|
async trace(runId) {
|
|
93996
93987
|
const db = await this.deps.openDb(this.deps.projectPath);
|
|
@@ -94046,7 +94037,7 @@ class AgentTraceService {
|
|
|
94046
94037
|
return rows.map((row) => row.session_id).filter((id) => id !== null && id !== "");
|
|
94047
94038
|
}
|
|
94048
94039
|
async existingLog(runId) {
|
|
94049
|
-
const path =
|
|
94040
|
+
const path = join33(this.logDir, `${runId}.md`);
|
|
94050
94041
|
try {
|
|
94051
94042
|
return await createNodeFileSystem2(this.deps.projectPath).exists(path) ? path : null;
|
|
94052
94043
|
} catch {
|
|
@@ -94403,7 +94394,7 @@ var init_agent_usage_source = __esm(() => {
|
|
|
94403
94394
|
});
|
|
94404
94395
|
|
|
94405
94396
|
// ../../packages/app/src/services/anchor-qualifier.ts
|
|
94406
|
-
import { basename as basename7, join as
|
|
94397
|
+
import { basename as basename7, join as join34 } from "path";
|
|
94407
94398
|
function normalizeDoneReason(reason) {
|
|
94408
94399
|
const match = ABSOLUTE_DONE_REASON_RE.exec(reason);
|
|
94409
94400
|
if (match === null)
|
|
@@ -94555,7 +94546,7 @@ async function qualifyAnchors(fs, opts) {
|
|
|
94555
94546
|
const dryRun = opts.dryRun ?? false;
|
|
94556
94547
|
const projectRoot = await resolveRepoRoot(opts.projectRoot, taskDirs[0]);
|
|
94557
94548
|
const index = await buildTrackedBasenameIndex(projectRoot);
|
|
94558
|
-
const durableVerdictExists = opts.durableVerdictExists ?? ((wbs) => fs.exists(
|
|
94549
|
+
const durableVerdictExists = opts.durableVerdictExists ?? ((wbs) => fs.exists(join34(projectRoot, ".spur", "memory", "evidence", `${wbs}-verdict.json`)));
|
|
94559
94550
|
const fileReports = [];
|
|
94560
94551
|
const scopedFiles = opts.files === undefined ? null : [...opts.files].sort();
|
|
94561
94552
|
for (const dir of scopedFiles === null ? taskDirs : ["."]) {
|
|
@@ -94565,7 +94556,7 @@ async function qualifyAnchors(fs, opts) {
|
|
|
94565
94556
|
} catch {
|
|
94566
94557
|
continue;
|
|
94567
94558
|
}
|
|
94568
|
-
const mdFiles = scopedFiles ?? entries.filter((name) => name.endsWith(".md") && name !== "kanban.md").map((name) =>
|
|
94559
|
+
const mdFiles = scopedFiles ?? entries.filter((name) => name.endsWith(".md") && name !== "kanban.md").map((name) => join34(dir, name)).sort();
|
|
94569
94560
|
for (const filePath of mdFiles) {
|
|
94570
94561
|
let raw;
|
|
94571
94562
|
try {
|
|
@@ -94666,7 +94657,7 @@ var init_anchor_qualifier = __esm(() => {
|
|
|
94666
94657
|
});
|
|
94667
94658
|
|
|
94668
94659
|
// ../../packages/app/src/services/board-catalog-service.ts
|
|
94669
|
-
import { isAbsolute as isAbsolute7, relative as relative6, resolve as
|
|
94660
|
+
import { isAbsolute as isAbsolute7, relative as relative6, resolve as resolve11, sep as sep6 } from "path";
|
|
94670
94661
|
function declaredBoardModules(config) {
|
|
94671
94662
|
return config?.bootstrap?.modules ?? [];
|
|
94672
94663
|
}
|
|
@@ -94674,8 +94665,8 @@ function resolveContained(index, projectRoot, moduleDirectory, declaredPath, id)
|
|
|
94674
94665
|
if (isAbsolute7(declaredPath)) {
|
|
94675
94666
|
throw new BoardModuleConfigError(index, id, `"${declaredPath}" must be relative to the module directory`);
|
|
94676
94667
|
}
|
|
94677
|
-
const root =
|
|
94678
|
-
const target =
|
|
94668
|
+
const root = resolve11(projectRoot, moduleDirectory);
|
|
94669
|
+
const target = resolve11(root, declaredPath);
|
|
94679
94670
|
const rel = relative6(root, target);
|
|
94680
94671
|
if (rel === "" || rel.startsWith("..") || isAbsolute7(rel) || rel.split(sep6).includes("..")) {
|
|
94681
94672
|
throw new BoardModuleConfigError(index, id, `"${declaredPath}" escapes the module directory "${moduleDirectory}"`);
|
|
@@ -94725,7 +94716,7 @@ async function prepareBoardModules(input) {
|
|
|
94725
94716
|
descriptors.push({ ...descriptorBase(declaration), type: "iframe", route, url: declaration.url });
|
|
94726
94717
|
continue;
|
|
94727
94718
|
}
|
|
94728
|
-
const root =
|
|
94719
|
+
const root = resolve11(input.projectRoot, declaration.directory);
|
|
94729
94720
|
const entryPath = resolveContained(index, input.projectRoot, declaration.directory, declaration.entry, declaration.id);
|
|
94730
94721
|
const styles = declaration.styles.map((style) => ({
|
|
94731
94722
|
declared: style,
|
|
@@ -94857,7 +94848,7 @@ var init_bounded_child_run = __esm(() => {
|
|
|
94857
94848
|
});
|
|
94858
94849
|
|
|
94859
94850
|
// ../../packages/app/src/workflow/workflow-resolver.ts
|
|
94860
|
-
import { basename as basename8, isAbsolute as isAbsolute8, join as
|
|
94851
|
+
import { basename as basename8, isAbsolute as isAbsolute8, join as join35, resolve as resolve12 } from "path";
|
|
94861
94852
|
function registeredWorkflowPaths(config) {
|
|
94862
94853
|
const paths = config?.workflows?.paths ?? [".spur/workflows/"];
|
|
94863
94854
|
const bundledRoot = bundledConfigRoot();
|
|
@@ -94865,7 +94856,7 @@ function registeredWorkflowPaths(config) {
|
|
|
94865
94856
|
for (const path of paths) {
|
|
94866
94857
|
if (path.startsWith(BUNDLED_PATH_PREFIX)) {
|
|
94867
94858
|
if (bundledRoot !== null)
|
|
94868
|
-
expanded.push(
|
|
94859
|
+
expanded.push(join35(bundledRoot, path.slice(BUNDLED_PATH_PREFIX.length)));
|
|
94869
94860
|
} else {
|
|
94870
94861
|
expanded.push(path);
|
|
94871
94862
|
}
|
|
@@ -94873,11 +94864,11 @@ function registeredWorkflowPaths(config) {
|
|
|
94873
94864
|
return expanded;
|
|
94874
94865
|
}
|
|
94875
94866
|
function normalizeLayerPath(cwd, path) {
|
|
94876
|
-
return
|
|
94867
|
+
return resolve12(cwd, path);
|
|
94877
94868
|
}
|
|
94878
94869
|
function workflowLayers(opts) {
|
|
94879
94870
|
const sharedRoot = opts.sharedRoot !== undefined ? opts.sharedRoot : bundledConfigRoot();
|
|
94880
|
-
const sharedPath = sharedRoot !== null ? normalizeLayerPath(opts.cwd,
|
|
94871
|
+
const sharedPath = sharedRoot !== null ? normalizeLayerPath(opts.cwd, join35(sharedRoot, "workflows")) : null;
|
|
94881
94872
|
const layers = [];
|
|
94882
94873
|
const seen = new Set;
|
|
94883
94874
|
const add = (id, path) => {
|
|
@@ -94886,7 +94877,7 @@ function workflowLayers(opts) {
|
|
|
94886
94877
|
seen.add(path);
|
|
94887
94878
|
layers.push({ id, path });
|
|
94888
94879
|
};
|
|
94889
|
-
add("project", normalizeLayerPath(opts.cwd,
|
|
94880
|
+
add("project", normalizeLayerPath(opts.cwd, join35(opts.cwd, ".spur", "workflows")));
|
|
94890
94881
|
for (const entry of opts.registered) {
|
|
94891
94882
|
if (sharedPath !== null && normalizeLayerPath(opts.cwd, entry) === sharedPath)
|
|
94892
94883
|
continue;
|
|
@@ -94930,7 +94921,7 @@ async function scanWorkflowByName(cwd, name, registered) {
|
|
|
94930
94921
|
try {
|
|
94931
94922
|
const files = (await fs.readDir(layer.path)).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
94932
94923
|
for (const f of files) {
|
|
94933
|
-
const abs =
|
|
94924
|
+
const abs = join35(layer.path, f);
|
|
94934
94925
|
const wfName = await readWorkflowNameFast(fs, abs);
|
|
94935
94926
|
if (wfName === name) {
|
|
94936
94927
|
return { path: abs, source: layer.id };
|
|
@@ -94942,7 +94933,7 @@ async function scanWorkflowByName(cwd, name, registered) {
|
|
|
94942
94933
|
}
|
|
94943
94934
|
function resolveWorkflowFile(cwd, file) {
|
|
94944
94935
|
const fs = createNodeFileSystem2();
|
|
94945
|
-
const projectPath =
|
|
94936
|
+
const projectPath = resolve12(cwd, file);
|
|
94946
94937
|
if (fs.exists(projectPath)) {
|
|
94947
94938
|
return { path: projectPath, source: "project" };
|
|
94948
94939
|
}
|
|
@@ -94950,20 +94941,20 @@ function resolveWorkflowFile(cwd, file) {
|
|
|
94950
94941
|
const base = basename8(file);
|
|
94951
94942
|
if (!isAbsolute8(file)) {
|
|
94952
94943
|
const withYaml = isYaml ? file : `${file}.yaml`;
|
|
94953
|
-
const projectSpur =
|
|
94944
|
+
const projectSpur = resolve12(cwd, ".spur", "workflows", withYaml);
|
|
94954
94945
|
if (fs.exists(projectSpur)) {
|
|
94955
94946
|
return { path: projectSpur, source: "project" };
|
|
94956
94947
|
}
|
|
94957
94948
|
if (!isYaml) {
|
|
94958
|
-
const projectDirect =
|
|
94949
|
+
const projectDirect = resolve12(cwd, `${file}.yaml`);
|
|
94959
94950
|
if (fs.exists(projectDirect)) {
|
|
94960
94951
|
return { path: projectDirect, source: "project" };
|
|
94961
94952
|
}
|
|
94962
|
-
const projectSpurPipeline =
|
|
94953
|
+
const projectSpurPipeline = resolve12(cwd, ".spur", "workflows", `${file}-pipeline.yaml`);
|
|
94963
94954
|
if (fs.exists(projectSpurPipeline)) {
|
|
94964
94955
|
return { path: projectSpurPipeline, source: "project" };
|
|
94965
94956
|
}
|
|
94966
|
-
const projectDirectPipeline =
|
|
94957
|
+
const projectDirectPipeline = resolve12(cwd, `${file}-pipeline.yaml`);
|
|
94967
94958
|
if (fs.exists(projectDirectPipeline)) {
|
|
94968
94959
|
return { path: projectDirectPipeline, source: "project" };
|
|
94969
94960
|
}
|
|
@@ -94972,16 +94963,16 @@ function resolveWorkflowFile(cwd, file) {
|
|
|
94972
94963
|
const bundledRoot = bundledConfigRoot();
|
|
94973
94964
|
if (bundledRoot !== null) {
|
|
94974
94965
|
const sharedName = isYaml ? base : `${base}.yaml`;
|
|
94975
|
-
const sharedPath =
|
|
94966
|
+
const sharedPath = join35(bundledRoot, "workflows", sharedName);
|
|
94976
94967
|
if (fs.exists(sharedPath)) {
|
|
94977
94968
|
return { path: sharedPath, source: "shared" };
|
|
94978
94969
|
}
|
|
94979
94970
|
if (!isYaml) {
|
|
94980
|
-
const sharedPipeline =
|
|
94971
|
+
const sharedPipeline = join35(bundledRoot, "workflows", `${base}-pipeline.yaml`);
|
|
94981
94972
|
if (fs.exists(sharedPipeline)) {
|
|
94982
94973
|
return { path: sharedPipeline, source: "shared" };
|
|
94983
94974
|
}
|
|
94984
|
-
const sharedLiteral =
|
|
94975
|
+
const sharedLiteral = join35(bundledRoot, "workflows", base);
|
|
94985
94976
|
if (fs.exists(sharedLiteral)) {
|
|
94986
94977
|
return { path: sharedLiteral, source: "shared" };
|
|
94987
94978
|
}
|
|
@@ -94993,7 +94984,7 @@ function resolveWorkflowFile(cwd, file) {
|
|
|
94993
94984
|
async function resolveWorkflowDefinition(cwd, fileOrName, options = {}) {
|
|
94994
94985
|
const registered = options.registered ?? [];
|
|
94995
94986
|
const bareName = basename8(fileOrName) === fileOrName && !/\.ya?ml$/.test(fileOrName);
|
|
94996
|
-
const named = bareName && !createNodeFileSystem2().exists(
|
|
94987
|
+
const named = bareName && !createNodeFileSystem2().exists(resolve12(cwd, fileOrName)) ? await scanWorkflowByName(cwd, fileOrName, registered) : null;
|
|
94997
94988
|
let resolved = named ?? resolveWorkflowFile(cwd, fileOrName);
|
|
94998
94989
|
if (resolved.path === null) {
|
|
94999
94990
|
const scanned = await scanWorkflowByName(cwd, fileOrName, registered);
|
|
@@ -95030,7 +95021,7 @@ var init_workflow_resolver = __esm(() => {
|
|
|
95030
95021
|
});
|
|
95031
95022
|
|
|
95032
95023
|
// ../../packages/app/src/services/done-transition-guard.ts
|
|
95033
|
-
import { dirname as dirname19, join as
|
|
95024
|
+
import { dirname as dirname19, join as join36 } from "path";
|
|
95034
95025
|
async function readVerdictFrom(fs, path, wbs) {
|
|
95035
95026
|
let exists;
|
|
95036
95027
|
try {
|
|
@@ -95075,7 +95066,7 @@ async function readVerdictFrom(fs, path, wbs) {
|
|
|
95075
95066
|
return { artifact: parsed, path, missing: false };
|
|
95076
95067
|
}
|
|
95077
95068
|
async function readVerdictArtifact(fs, runDir, wbs) {
|
|
95078
|
-
const evidenceDir =
|
|
95069
|
+
const evidenceDir = join36(dirname19(runDir), "memory", "evidence");
|
|
95079
95070
|
const evidence = await readVerdictFrom(fs, `${evidenceDir}/${wbs}-verdict.json`, wbs);
|
|
95080
95071
|
if (!evidence.missing) {
|
|
95081
95072
|
const { missing: _missing, ...result } = evidence;
|
|
@@ -95103,7 +95094,7 @@ async function findUnresolvedTestEvidence(fs, projectRoot, artifact) {
|
|
|
95103
95094
|
if (String(row.status).toUpperCase() !== "MET" || typeof row.evidence !== "string")
|
|
95104
95095
|
continue;
|
|
95105
95096
|
for (const path of citedTestPaths(row.evidence)) {
|
|
95106
|
-
if (!await fs.exists(
|
|
95097
|
+
if (!await fs.exists(join36(projectRoot, path)))
|
|
95107
95098
|
unresolved.push(`${row.id ?? "?"}: ${path}`);
|
|
95108
95099
|
}
|
|
95109
95100
|
}
|
|
@@ -95823,7 +95814,7 @@ var init_planning_check_base = __esm(() => {
|
|
|
95823
95814
|
});
|
|
95824
95815
|
|
|
95825
95816
|
// ../../packages/app/src/services/task-record.ts
|
|
95826
|
-
import { join as
|
|
95817
|
+
import { join as join37 } from "path";
|
|
95827
95818
|
function escapeTablePipe(s) {
|
|
95828
95819
|
return s.replace(/\|/g, "\\|");
|
|
95829
95820
|
}
|
|
@@ -96237,7 +96228,7 @@ async function resolveDiffBase(options = {}) {
|
|
|
96237
96228
|
return explicit;
|
|
96238
96229
|
const wbs = options.wbs?.trim();
|
|
96239
96230
|
if (wbs !== undefined && wbs !== "") {
|
|
96240
|
-
const baseFile =
|
|
96231
|
+
const baseFile = join37(options.cwd ?? process.cwd(), ".spur", "run", `${wbs}-base.sha`);
|
|
96241
96232
|
try {
|
|
96242
96233
|
const sha = (await createNodeFileSystem2().readFile(baseFile)).trim();
|
|
96243
96234
|
if (DIFF_BASE_RE.test(sha))
|
|
@@ -96477,6 +96468,8 @@ function verifyConfidenceBasis(tables) {
|
|
|
96477
96468
|
if (weak.length > 0)
|
|
96478
96469
|
return `${weak.length} row(s) PARTIAL/UNMET`;
|
|
96479
96470
|
const nonExecutable = tables.acs.filter((row) => {
|
|
96471
|
+
if (row.status.trim().toUpperCase() !== "MET")
|
|
96472
|
+
return true;
|
|
96480
96473
|
const types = (row.evidenceType ?? "").split("+").map((t) => t.trim().toLowerCase());
|
|
96481
96474
|
return !types.some((t) => t === "test" || t === "command");
|
|
96482
96475
|
});
|
|
@@ -96761,7 +96754,7 @@ var init_verify_answer_lint = __esm(() => {
|
|
|
96761
96754
|
});
|
|
96762
96755
|
|
|
96763
96756
|
// ../../packages/app/src/services/feature-check.ts
|
|
96764
|
-
import { dirname as dirname20, join as
|
|
96757
|
+
import { dirname as dirname20, join as join38 } from "path";
|
|
96765
96758
|
function isGroupFeature(fm) {
|
|
96766
96759
|
const tags = fm.tags;
|
|
96767
96760
|
return Array.isArray(tags) && tags.includes("group") ? "group" : "standard";
|
|
@@ -96859,9 +96852,9 @@ function decodeVerdictRows(source, sectionName, required) {
|
|
|
96859
96852
|
function defaultVerdictRunDir(tasksDir) {
|
|
96860
96853
|
const norm = tasksDir.replace(/\\/g, "/");
|
|
96861
96854
|
if (/\/docs\/tasks\d*$/.test(norm) || /\/docs\/tasks$/.test(norm)) {
|
|
96862
|
-
return
|
|
96855
|
+
return join38(dirname20(dirname20(tasksDir)), ".spur", "run");
|
|
96863
96856
|
}
|
|
96864
|
-
return
|
|
96857
|
+
return join38(dirname20(tasksDir), ".spur", "run");
|
|
96865
96858
|
}
|
|
96866
96859
|
function scenarioKeys(scenarios) {
|
|
96867
96860
|
return scenarios.map((s, i) => ({
|
|
@@ -97220,7 +97213,7 @@ var init_feature_check = __esm(() => {
|
|
|
97220
97213
|
if (options?.asStatus === "done" && options?.runDir) {
|
|
97221
97214
|
await this.checkFeatureVerificationReceipt(featureId, raw, options.runDir, findings, options.receiptRunPort);
|
|
97222
97215
|
}
|
|
97223
|
-
const dogfoodDir = options?.dogfoodDir ?? (options?.featuresDir ?
|
|
97216
|
+
const dogfoodDir = options?.dogfoodDir ?? (options?.featuresDir ? join38(dirname20(options.featuresDir), "dogfood") : undefined);
|
|
97224
97217
|
const primaryTasksDir = options?.tasksDir ?? options?.tasksDirs?.[0];
|
|
97225
97218
|
const runDir = options?.runDir ?? (primaryTasksDir ? defaultVerdictRunDir(primaryTasksDir) : undefined);
|
|
97226
97219
|
const taskScanDirs = options?.tasksDirs && options.tasksDirs.length > 0 ? options.tasksDirs : options?.tasksDir ? [options.tasksDir] : [];
|
|
@@ -97348,7 +97341,7 @@ var init_feature_check = __esm(() => {
|
|
|
97348
97341
|
}
|
|
97349
97342
|
let learningsContent;
|
|
97350
97343
|
try {
|
|
97351
|
-
learningsContent = await this.fs.readFile(
|
|
97344
|
+
learningsContent = await this.fs.readFile(join38(this.projectRoot, ".spur", "context", "learnings.md"));
|
|
97352
97345
|
} catch {
|
|
97353
97346
|
learningsContent = undefined;
|
|
97354
97347
|
}
|
|
@@ -97834,7 +97827,7 @@ var init_task_size_precheck = __esm(() => {
|
|
|
97834
97827
|
});
|
|
97835
97828
|
|
|
97836
97829
|
// ../../packages/app/src/services/task-check.ts
|
|
97837
|
-
import { basename as basename9, dirname as dirname21, join as
|
|
97830
|
+
import { basename as basename9, dirname as dirname21, join as join39 } from "path";
|
|
97838
97831
|
function isPlaceholderBody(body) {
|
|
97839
97832
|
const stripped = body.replace(/<!--[\s\S]*?-->/g, "").replace(/^\s*>\s*TBD\s*$/gim, "").trim();
|
|
97840
97833
|
return stripped.length === 0;
|
|
@@ -98109,7 +98102,7 @@ var init_task_check = __esm(() => {
|
|
|
98109
98102
|
this.runL2(doc, entry, findings, raw);
|
|
98110
98103
|
this.runL3(doc, entry, effectiveStatus, findings, isTransitionTarget);
|
|
98111
98104
|
const tasksDir = dirname21(filePath);
|
|
98112
|
-
const featuresDir =
|
|
98105
|
+
const featuresDir = join39(dirname21(tasksDir), "features");
|
|
98113
98106
|
await this.runL4(doc, fm, effectiveStatus, findings, featuresDir, tasksDir, wbs, status);
|
|
98114
98107
|
await this.runL4Rollup(doc, wbs, effectiveStatus, findings, tasksDir);
|
|
98115
98108
|
if (effectiveStatus !== "done" && effectiveStatus !== "cancelled") {
|
|
@@ -98749,7 +98742,7 @@ var init_task_check = __esm(() => {
|
|
|
98749
98742
|
for (const cite of citations) {
|
|
98750
98743
|
if (reported >= 5)
|
|
98751
98744
|
break;
|
|
98752
|
-
const abs =
|
|
98745
|
+
const abs = join39(projectRoot, cite.path);
|
|
98753
98746
|
let exists = false;
|
|
98754
98747
|
try {
|
|
98755
98748
|
exists = await this.fs.exists(abs);
|
|
@@ -98835,7 +98828,7 @@ var init_task_check = __esm(() => {
|
|
|
98835
98828
|
continue;
|
|
98836
98829
|
}
|
|
98837
98830
|
try {
|
|
98838
|
-
const abs =
|
|
98831
|
+
const abs = join39(dir, name);
|
|
98839
98832
|
const stat = await this.fs.stat(abs);
|
|
98840
98833
|
if (stat !== null && stat !== undefined && stat.isDirectory?.())
|
|
98841
98834
|
stack.push(abs);
|
|
@@ -98930,7 +98923,7 @@ var init_task_check = __esm(() => {
|
|
|
98930
98923
|
}
|
|
98931
98924
|
async checkVerdictArtifact(wbs, tasksDir, findings) {
|
|
98932
98925
|
const projectRoot = resolveProjectRootFromTasksDir(tasksDir);
|
|
98933
|
-
const runDir =
|
|
98926
|
+
const runDir = join39(projectRoot, ".spur", "run");
|
|
98934
98927
|
const loaded = await readVerdictArtifact(this.fs, runDir, wbs);
|
|
98935
98928
|
const verdictPath = loaded.path;
|
|
98936
98929
|
if (loaded.readError) {
|
|
@@ -98988,13 +98981,13 @@ var init_task_check = __esm(() => {
|
|
|
98988
98981
|
});
|
|
98989
98982
|
|
|
98990
98983
|
// ../../packages/app/src/services/corpus-check.ts
|
|
98991
|
-
import { basename as basename10, dirname as dirname22, join as
|
|
98984
|
+
import { basename as basename10, dirname as dirname22, join as join40, relative as relative7, resolve as resolve13 } from "path";
|
|
98992
98985
|
async function loadTaskMatrix(projectRoot) {
|
|
98993
98986
|
const fs = createNodeFileSystem2(projectRoot);
|
|
98994
|
-
const candidates = [
|
|
98987
|
+
const candidates = [join40(projectRoot, ".spur", "tasks", "section-matrix.yaml")];
|
|
98995
98988
|
const bundledRoot = bundledConfigRoot();
|
|
98996
98989
|
if (bundledRoot !== null)
|
|
98997
|
-
candidates.push(
|
|
98990
|
+
candidates.push(join40(bundledRoot, "tasks", "section-matrix.yaml"));
|
|
98998
98991
|
let matrixPath;
|
|
98999
98992
|
for (const candidate of candidates) {
|
|
99000
98993
|
if (await fs.exists(candidate)) {
|
|
@@ -99037,7 +99030,7 @@ async function structuralSweep(projectRoot) {
|
|
|
99037
99030
|
const wbs = fileName.match(/^(\d{4})_.+\.md$/)?.[1];
|
|
99038
99031
|
if (wbs === undefined)
|
|
99039
99032
|
continue;
|
|
99040
|
-
const result = await taskService.check(
|
|
99033
|
+
const result = await taskService.check(join40(tasksDir, fileName), wbs);
|
|
99041
99034
|
for (const finding of result.findings) {
|
|
99042
99035
|
findings.push({
|
|
99043
99036
|
kind: "task",
|
|
@@ -99055,7 +99048,7 @@ async function structuralSweep(projectRoot) {
|
|
|
99055
99048
|
const id = fileName.match(/^([A-Z][0-9]*)_.+\.md$/)?.[1];
|
|
99056
99049
|
if (id === undefined)
|
|
99057
99050
|
continue;
|
|
99058
|
-
const result = await featureService.check(
|
|
99051
|
+
const result = await featureService.check(join40(featuresDir, fileName), id, {
|
|
99059
99052
|
featuresDir,
|
|
99060
99053
|
tasksDir: activeTasksDir,
|
|
99061
99054
|
tasksDirs: taskDirs,
|
|
@@ -99084,7 +99077,7 @@ async function duplicateIds(cwd, taskDirs, featuresDir) {
|
|
|
99084
99077
|
return [];
|
|
99085
99078
|
}
|
|
99086
99079
|
const pattern = kind === "task" ? /^(\d{4})_/ : /^([A-Z][0-9]*)_/;
|
|
99087
|
-
return names.map((n) => ({ m: n.match(pattern), n })).filter((x) => x.m !== null).map((x) => ({ id: x.m[1], file: relative7(cwd,
|
|
99080
|
+
return names.map((n) => ({ m: n.match(pattern), n })).filter((x) => x.m !== null).map((x) => ({ id: x.m[1], file: relative7(cwd, join40(dir, x.n)), kind }));
|
|
99088
99081
|
};
|
|
99089
99082
|
const all = [
|
|
99090
99083
|
...(await Promise.all(taskDirs.map((dir) => scan(dir, "task")))).flat(),
|
|
@@ -99136,14 +99129,14 @@ async function runCorpusCheck(cwd, since, report) {
|
|
|
99136
99129
|
}
|
|
99137
99130
|
function resolveProjectRoot(cwd) {
|
|
99138
99131
|
const fs = createNodeFileSystem2(cwd);
|
|
99139
|
-
let current =
|
|
99132
|
+
let current = resolve13(cwd);
|
|
99140
99133
|
while (true) {
|
|
99141
|
-
if (fs.exists(
|
|
99134
|
+
if (fs.exists(join40(current, ".spur", "config.yaml"))) {
|
|
99142
99135
|
return current;
|
|
99143
99136
|
}
|
|
99144
99137
|
const parent = dirname22(current);
|
|
99145
99138
|
if (parent === current)
|
|
99146
|
-
return
|
|
99139
|
+
return resolve13(cwd);
|
|
99147
99140
|
current = parent;
|
|
99148
99141
|
}
|
|
99149
99142
|
}
|
|
@@ -99160,14 +99153,14 @@ function diskReader(cwd) {
|
|
|
99160
99153
|
return {
|
|
99161
99154
|
list: async (dir) => {
|
|
99162
99155
|
try {
|
|
99163
|
-
return (await fs.readDir(
|
|
99156
|
+
return (await fs.readDir(join40(cwd, dir))).map((n) => `${dir}/${n}`);
|
|
99164
99157
|
} catch {
|
|
99165
99158
|
return [];
|
|
99166
99159
|
}
|
|
99167
99160
|
},
|
|
99168
99161
|
read: async (path) => {
|
|
99169
99162
|
try {
|
|
99170
|
-
return await fs.readFile(
|
|
99163
|
+
return await fs.readFile(join40(cwd, path));
|
|
99171
99164
|
} catch {
|
|
99172
99165
|
return null;
|
|
99173
99166
|
}
|
|
@@ -99327,7 +99320,7 @@ var init_corpus_check = __esm(() => {
|
|
|
99327
99320
|
});
|
|
99328
99321
|
|
|
99329
99322
|
// ../../packages/app/src/services/corpus-migrator.ts
|
|
99330
|
-
import { join as
|
|
99323
|
+
import { join as join41, relative as relative8 } from "path";
|
|
99331
99324
|
function applyM1(data, flags) {
|
|
99332
99325
|
const raw = data.status;
|
|
99333
99326
|
if (typeof raw !== "string")
|
|
@@ -99627,7 +99620,7 @@ class CorpusMigrator {
|
|
|
99627
99620
|
}
|
|
99628
99621
|
async discoverFiles() {
|
|
99629
99622
|
const entries = await this.fs.readDir(this.corpusDir);
|
|
99630
|
-
return entries.filter((name) => name.endsWith(".md")).filter((name) => name !== "kanban.md").map((name) =>
|
|
99623
|
+
return entries.filter((name) => name.endsWith(".md")).filter((name) => name !== "kanban.md").map((name) => join41(this.corpusDir, name)).sort();
|
|
99631
99624
|
}
|
|
99632
99625
|
async migrateFile(filePath, dryRun, gitDates = new Map) {
|
|
99633
99626
|
const flags = [];
|
|
@@ -99945,7 +99938,7 @@ var init_feature_receipt_run_port = __esm(() => {
|
|
|
99945
99938
|
|
|
99946
99939
|
// ../../packages/app/src/services/feature-sync-suppression.ts
|
|
99947
99940
|
import { createHash as createHash11 } from "crypto";
|
|
99948
|
-
import { dirname as dirname23, join as
|
|
99941
|
+
import { dirname as dirname23, join as join42 } from "path";
|
|
99949
99942
|
function computeSyncFingerprint(input) {
|
|
99950
99943
|
const material = [
|
|
99951
99944
|
input.featureContentHash,
|
|
@@ -99977,7 +99970,7 @@ async function readVerdictMtimeVector(fs, runDir) {
|
|
|
99977
99970
|
const dir = runDir.replace(/\/$/, "");
|
|
99978
99971
|
const vector = [];
|
|
99979
99972
|
const seen = new Set;
|
|
99980
|
-
for (const plane of [
|
|
99973
|
+
for (const plane of [join42(dirname23(dir), "memory", "evidence"), dir]) {
|
|
99981
99974
|
let entries;
|
|
99982
99975
|
try {
|
|
99983
99976
|
entries = await fs.readDir(plane);
|
|
@@ -99989,7 +99982,7 @@ async function readVerdictMtimeVector(fs, runDir) {
|
|
|
99989
99982
|
continue;
|
|
99990
99983
|
seen.add(entry);
|
|
99991
99984
|
try {
|
|
99992
|
-
const stat = await fs.stat(
|
|
99985
|
+
const stat = await fs.stat(join42(plane, entry));
|
|
99993
99986
|
if (stat)
|
|
99994
99987
|
vector.push(`${entry.replace("-verdict.json", "")}:${stat.mtimeMs}`);
|
|
99995
99988
|
} catch {}
|
|
@@ -100946,7 +100939,7 @@ class FleetDispatcher {
|
|
|
100946
100939
|
var RECEIPT_POLL_INTERVAL_MS = 250;
|
|
100947
100940
|
|
|
100948
100941
|
// ../../packages/app/src/services/fleet-guest-service.ts
|
|
100949
|
-
import { join as
|
|
100942
|
+
import { join as join43 } from "path";
|
|
100950
100943
|
|
|
100951
100944
|
class FleetGuestService {
|
|
100952
100945
|
ctx;
|
|
@@ -100972,7 +100965,7 @@ class FleetGuestService {
|
|
|
100972
100965
|
}
|
|
100973
100966
|
async read(id) {
|
|
100974
100967
|
try {
|
|
100975
|
-
const raw = await this.ctx.fs.readFile(
|
|
100968
|
+
const raw = await this.ctx.fs.readFile(join43(this.dir(), `${id}.json`));
|
|
100976
100969
|
const parsed = JSON.parse(raw);
|
|
100977
100970
|
if (typeof parsed.id !== "string" || typeof parsed.role !== "string")
|
|
100978
100971
|
return null;
|
|
@@ -101047,7 +101040,7 @@ class FleetGuestService {
|
|
|
101047
101040
|
joinedAt: new Date().toISOString()
|
|
101048
101041
|
};
|
|
101049
101042
|
await this.ctx.fs.ensureDir(this.dir());
|
|
101050
|
-
await this.ctx.fs.writeFile(
|
|
101043
|
+
await this.ctx.fs.writeFile(join43(this.dir(), `${id}.json`), `${JSON.stringify(record, null, 4)}
|
|
101051
101044
|
`);
|
|
101052
101045
|
return { ok: true, guest: record };
|
|
101053
101046
|
}
|
|
@@ -101097,7 +101090,7 @@ class FleetGuestService {
|
|
|
101097
101090
|
});
|
|
101098
101091
|
}
|
|
101099
101092
|
try {
|
|
101100
|
-
await this.ctx.fs.deleteFile(
|
|
101093
|
+
await this.ctx.fs.deleteFile(join43(this.dir(), `${record.id}.json`));
|
|
101101
101094
|
} catch {}
|
|
101102
101095
|
}
|
|
101103
101096
|
nextGuestId(role, declared, joined) {
|
|
@@ -101112,7 +101105,7 @@ class FleetGuestService {
|
|
|
101112
101105
|
return `${GUEST_CLAIM_PREFIX}${id}`;
|
|
101113
101106
|
}
|
|
101114
101107
|
dir() {
|
|
101115
|
-
return
|
|
101108
|
+
return join43(this.ctx.cwd, GUEST_RECORD_DIR);
|
|
101116
101109
|
}
|
|
101117
101110
|
}
|
|
101118
101111
|
var GUEST_LEASE_TTL_MS, GUEST_ROLES, GUEST_RECORD_DIR, GUEST_CLAIM_PREFIX = "guest:";
|
|
@@ -101120,7 +101113,7 @@ var init_fleet_guest_service = __esm(() => {
|
|
|
101120
101113
|
init_src2();
|
|
101121
101114
|
GUEST_LEASE_TTL_MS = CLAIM_TTL_MS;
|
|
101122
101115
|
GUEST_ROLES = ["scribe", "coder", "reviewer", "planner"];
|
|
101123
|
-
GUEST_RECORD_DIR =
|
|
101116
|
+
GUEST_RECORD_DIR = join43(".spur", "run", "guests");
|
|
101124
101117
|
});
|
|
101125
101118
|
|
|
101126
101119
|
// ../../packages/app/src/services/fleet-selector.ts
|
|
@@ -103263,16 +103256,16 @@ import {
|
|
|
103263
103256
|
existsSync as existsSync13,
|
|
103264
103257
|
mkdirSync as mkdirSync9,
|
|
103265
103258
|
readdirSync as readdirSync6,
|
|
103266
|
-
readFileSync as
|
|
103259
|
+
readFileSync as readFileSync11,
|
|
103267
103260
|
readlinkSync,
|
|
103268
103261
|
realpathSync as realpathSync5,
|
|
103269
|
-
rmSync as
|
|
103262
|
+
rmSync as rmSync4,
|
|
103270
103263
|
symlinkSync,
|
|
103271
103264
|
unlinkSync as unlinkSync5,
|
|
103272
103265
|
writeFileSync as writeFileSync7
|
|
103273
103266
|
} from "fs";
|
|
103274
103267
|
import { homedir as homedir9 } from "os";
|
|
103275
|
-
import { dirname as dirname24, isAbsolute as isAbsolute9, join as
|
|
103268
|
+
import { dirname as dirname24, isAbsolute as isAbsolute9, join as join44, resolve as resolve14, sep as sep7 } from "path";
|
|
103276
103269
|
function parseImporterVersion(version) {
|
|
103277
103270
|
if (version === undefined) {
|
|
103278
103271
|
return null;
|
|
@@ -103325,9 +103318,9 @@ async function buildRefreshCoverage(db, selector, fanOut) {
|
|
|
103325
103318
|
return { refreshed, skipped: [...DEFERRED_SOURCES], window: { since, until } };
|
|
103326
103319
|
}
|
|
103327
103320
|
async function runSessionAugmentedRoots(source, home, cwd, dao) {
|
|
103328
|
-
const roots = getSourceDefinition(source).defaultRoots.map((root) =>
|
|
103321
|
+
const roots = getSourceDefinition(source).defaultRoots.map((root) => resolve14(home, root));
|
|
103329
103322
|
const runRoots = [];
|
|
103330
|
-
const runBases = [runStoragePaths(cwd).recordsDir,
|
|
103323
|
+
const runBases = [runStoragePaths(cwd).recordsDir, join44(cwd, ".spur", "run")];
|
|
103331
103324
|
const seen = new Set;
|
|
103332
103325
|
const seenRunAgents = new Set;
|
|
103333
103326
|
const sourcesByRun = new Map;
|
|
@@ -103340,7 +103333,7 @@ async function runSessionAugmentedRoots(source, home, cwd, dao) {
|
|
|
103340
103333
|
if (!existsSync13(runBase))
|
|
103341
103334
|
continue;
|
|
103342
103335
|
for (const runId of readdirSync6(runBase)) {
|
|
103343
|
-
const sessionsRoot =
|
|
103336
|
+
const sessionsRoot = join44(runBase, runId, "agent-sessions");
|
|
103344
103337
|
if (!existsSync13(sessionsRoot))
|
|
103345
103338
|
continue;
|
|
103346
103339
|
const mappedSources = sourcesByRun.get(runId);
|
|
@@ -103352,7 +103345,7 @@ async function runSessionAugmentedRoots(source, home, cwd, dao) {
|
|
|
103352
103345
|
const identity = `${runId}\x00${agent}`;
|
|
103353
103346
|
if (seenRunAgents.has(identity))
|
|
103354
103347
|
continue;
|
|
103355
|
-
const root = realpathSync5(
|
|
103348
|
+
const root = realpathSync5(join44(sessionsRoot, agent));
|
|
103356
103349
|
if (seen.has(root))
|
|
103357
103350
|
continue;
|
|
103358
103351
|
seen.add(root);
|
|
@@ -103421,7 +103414,7 @@ class HistoryService {
|
|
|
103421
103414
|
const dao = new RunSessionDao(db);
|
|
103422
103415
|
const discovery = parsedSource !== "opencode" && opts.file === undefined && opts.root === undefined ? await runSessionAugmentedRoots(parsedSource, this.ctx.historyHome ?? homedir9(), this.ctx.cwd ?? process.cwd(), dao) : undefined;
|
|
103423
103416
|
const scope = await estimateImportScope(parsedSource === "opencode" && opts.file === undefined && opts.root === undefined ? {
|
|
103424
|
-
file: this.ctx.openCodeSourceDatabase ??
|
|
103417
|
+
file: this.ctx.openCodeSourceDatabase ?? join44(this.ctx.historyHome ?? homedir9(), ".local/share/opencode/opencode.db"),
|
|
103425
103418
|
roots: []
|
|
103426
103419
|
} : {
|
|
103427
103420
|
...opts.file !== undefined && opts.file.length > 0 ? { file: opts.file } : {},
|
|
@@ -103496,7 +103489,7 @@ class HistoryService {
|
|
|
103496
103489
|
}
|
|
103497
103490
|
async maintain(opts = {}) {
|
|
103498
103491
|
const db = await this.ctx.getDb();
|
|
103499
|
-
const dbPath = this.ctx.cwd ?
|
|
103492
|
+
const dbPath = this.ctx.cwd ? join44(this.ctx.cwd, ".spur", "spur.db") : undefined;
|
|
103500
103493
|
return maintainDatabase(db, {
|
|
103501
103494
|
...opts,
|
|
103502
103495
|
...dbPath && opts.dbPath === undefined ? { dbPath } : {}
|
|
@@ -104047,13 +104040,13 @@ function writeArtifact(artifact, opts) {
|
|
|
104047
104040
|
}
|
|
104048
104041
|
function resolveArtifactPaths(artifact, opts) {
|
|
104049
104042
|
if (opts.out !== undefined) {
|
|
104050
|
-
const out =
|
|
104043
|
+
const out = resolve14(opts.out);
|
|
104051
104044
|
return { artifactPath: out, sidecarPath: `${out.replace(/\.json$/, "")}.errors.jsonl` };
|
|
104052
104045
|
}
|
|
104053
|
-
const base =
|
|
104054
|
-
const dateDir =
|
|
104046
|
+
const base = resolve14(opts.cwd, ".spur", "reports", "history");
|
|
104047
|
+
const dateDir = join44(base, artifact.generatedAt.slice(0, 10));
|
|
104055
104048
|
const name = `analyze-${selectorDigest(artifact.selector)}`;
|
|
104056
|
-
return { artifactPath:
|
|
104049
|
+
return { artifactPath: join44(dateDir, `${name}.json`), sidecarPath: join44(dateDir, `${name}.errors.jsonl`) };
|
|
104057
104050
|
}
|
|
104058
104051
|
function boundCoverage(coverage) {
|
|
104059
104052
|
const overflow = [];
|
|
@@ -104075,8 +104068,8 @@ function boundCoverage(coverage) {
|
|
|
104075
104068
|
return { bounded, overflow };
|
|
104076
104069
|
}
|
|
104077
104070
|
function updateLatestPointer(opts, artifactPath) {
|
|
104078
|
-
const base =
|
|
104079
|
-
const latest =
|
|
104071
|
+
const base = resolve14(opts.cwd, ".spur", "reports", "history");
|
|
104072
|
+
const latest = join44(base, "latest.json");
|
|
104080
104073
|
mkdirSync9(base, { recursive: true });
|
|
104081
104074
|
if (existsSync13(latest))
|
|
104082
104075
|
unlinkSync5(latest);
|
|
@@ -104084,14 +104077,14 @@ function updateLatestPointer(opts, artifactPath) {
|
|
|
104084
104077
|
}
|
|
104085
104078
|
function resolveArtifactPath(explicitPath, cwd) {
|
|
104086
104079
|
if (explicitPath !== undefined && explicitPath.length > 0) {
|
|
104087
|
-
return { path:
|
|
104080
|
+
return { path: resolve14(explicitPath), resolution: "explicit" };
|
|
104088
104081
|
}
|
|
104089
|
-
const latest =
|
|
104082
|
+
const latest = resolve14(cwd, ".spur", "reports", "history", "latest.json");
|
|
104090
104083
|
if (!existsSync13(latest)) {
|
|
104091
104084
|
throw new Error(`No artifact path given and no latest pointer at ${latest}. ` + "Run `spur history analyze` first, or pass an explicit artifact path.");
|
|
104092
104085
|
}
|
|
104093
104086
|
const target = readlinkSync(latest);
|
|
104094
|
-
const resolved = isAbsolute9(target) ? target :
|
|
104087
|
+
const resolved = isAbsolute9(target) ? target : resolve14(dirname24(latest), target);
|
|
104095
104088
|
if (!existsSync13(resolved)) {
|
|
104096
104089
|
throw new Error(`Latest pointer ${latest} \u2192 ${resolved}, but the target does not exist.`);
|
|
104097
104090
|
}
|
|
@@ -104099,7 +104092,7 @@ function resolveArtifactPath(explicitPath, cwd) {
|
|
|
104099
104092
|
}
|
|
104100
104093
|
function runHistoryReport(opts) {
|
|
104101
104094
|
const { path: artifactPath, resolution } = resolveArtifactPath(opts.path, opts.cwd);
|
|
104102
|
-
const raw =
|
|
104095
|
+
const raw = readFileSync11(artifactPath, "utf8");
|
|
104103
104096
|
let parsed;
|
|
104104
104097
|
try {
|
|
104105
104098
|
parsed = JSON.parse(raw);
|
|
@@ -104142,7 +104135,7 @@ function formatIssue(issue) {
|
|
|
104142
104135
|
return `${issue.sourceFile}:${issue.sourceLine}: ${issue.reason}`;
|
|
104143
104136
|
}
|
|
104144
104137
|
function pruneReports(cwd, retentionDays = REPORT_RETENTION_DAYS, now = new Date) {
|
|
104145
|
-
const dir =
|
|
104138
|
+
const dir = join44(cwd, ".spur", "reports", "history");
|
|
104146
104139
|
let entries;
|
|
104147
104140
|
try {
|
|
104148
104141
|
entries = readdirSync6(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
@@ -104160,7 +104153,7 @@ function pruneReports(cwd, retentionDays = REPORT_RETENTION_DAYS, now = new Date
|
|
|
104160
104153
|
if (entryDate >= cutoff)
|
|
104161
104154
|
continue;
|
|
104162
104155
|
try {
|
|
104163
|
-
|
|
104156
|
+
rmSync4(join44(dir, name), { recursive: true, force: true });
|
|
104164
104157
|
pruned.push(name);
|
|
104165
104158
|
} catch {}
|
|
104166
104159
|
}
|
|
@@ -104205,6 +104198,19 @@ var init_history_service = __esm(() => {
|
|
|
104205
104198
|
HISTORY_BUSY_ERROR_PATTERN = /database is locked|SQLITE_BUSY/i;
|
|
104206
104199
|
});
|
|
104207
104200
|
|
|
104201
|
+
// ../../packages/app/src/services/inline-run-attribution.ts
|
|
104202
|
+
import { join as join45, resolve as resolve15 } from "path";
|
|
104203
|
+
async function openInlineRunProjectDb(workdir) {
|
|
104204
|
+
const { mkdirSync } = process.getBuiltinModule("node:fs");
|
|
104205
|
+
const url = join45(resolve15(workdir), ".spur", "spur.db");
|
|
104206
|
+
mkdirSync(join45(url, ".."), { recursive: true });
|
|
104207
|
+
const adapter = await createMigratedDb({ url });
|
|
104208
|
+
return { adapter, close: () => adapter.close() };
|
|
104209
|
+
}
|
|
104210
|
+
var init_inline_run_attribution = __esm(() => {
|
|
104211
|
+
init_src2();
|
|
104212
|
+
});
|
|
104213
|
+
|
|
104208
104214
|
// ../../packages/app/src/services/job-worker-service.ts
|
|
104209
104215
|
class JobHandlerRegistry {
|
|
104210
104216
|
handlers = new Map;
|
|
@@ -104993,7 +104999,7 @@ var HANDOFF_TIMEOUT_MS = 5000, HANDOFF_POLL_MS = 50;
|
|
|
104993
104999
|
var init_project_server_owner = () => {};
|
|
104994
105000
|
|
|
104995
105001
|
// ../../packages/app/src/services/project-start.ts
|
|
104996
|
-
import { existsSync as existsSync15, readdirSync as readdirSync8, readFileSync as
|
|
105002
|
+
import { existsSync as existsSync15, readdirSync as readdirSync8, readFileSync as readFileSync12, realpathSync as realpathSync7, statSync as statSync11 } from "fs";
|
|
104997
105003
|
import { basename as basename12, join as join47, resolve as resolve16 } from "path";
|
|
104998
105004
|
function shQuote(value) {
|
|
104999
105005
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
@@ -105056,14 +105062,6 @@ function resolveSpurServeCommand() {
|
|
|
105056
105062
|
}
|
|
105057
105063
|
throw new Error("Could not resolve the spur CLI to spawn `spur serve`. Ensure `spur` is on PATH (or invoke start via the monorepo CLI).");
|
|
105058
105064
|
}
|
|
105059
|
-
function isPidAlive(pid) {
|
|
105060
|
-
try {
|
|
105061
|
-
process.kill(pid, 0);
|
|
105062
|
-
return true;
|
|
105063
|
-
} catch (error) {
|
|
105064
|
-
return error.code !== "ESRCH";
|
|
105065
|
-
}
|
|
105066
|
-
}
|
|
105067
105065
|
function readOwnerClaimPid(projectRoot) {
|
|
105068
105066
|
try {
|
|
105069
105067
|
const directory = join47(realpathSync7(projectRoot), ".spur", "server-owner.lock");
|
|
@@ -105129,7 +105127,7 @@ function daemonLogSize(projectRoot) {
|
|
|
105129
105127
|
}
|
|
105130
105128
|
function daemonLogSuffix(projectRoot, offset) {
|
|
105131
105129
|
try {
|
|
105132
|
-
const content =
|
|
105130
|
+
const content = readFileSync12(join47(projectRoot, ".spur", "run", "serve-spawn.log"), "utf8");
|
|
105133
105131
|
const tail = content.slice(offset).trim().slice(-2000).replace(/\n+/g, " | ");
|
|
105134
105132
|
return tail === "" ? "" : ` Daemon log tail: ${tail}`;
|
|
105135
105133
|
} catch {
|
|
@@ -108340,7 +108338,7 @@ var init_section_matrix_loader = __esm(() => {
|
|
|
108340
108338
|
});
|
|
108341
108339
|
|
|
108342
108340
|
// ../../packages/app/src/services/slash-commands-service.ts
|
|
108343
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync11, readdirSync as readdirSync9, readFileSync as
|
|
108341
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync11, readdirSync as readdirSync9, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "fs";
|
|
108344
108342
|
import { homedir as homedir11 } from "os";
|
|
108345
108343
|
import { basename as basename13, dirname as dirname25, join as join50, resolve as resolve18 } from "path";
|
|
108346
108344
|
function getBuiltinClaudeCommands() {
|
|
@@ -108430,7 +108428,7 @@ function scanMarkdownCommands(dirPath, options = {}) {
|
|
|
108430
108428
|
}
|
|
108431
108429
|
const fullPath = join50(dirPath, entry.name);
|
|
108432
108430
|
const stem = basename13(entry.name, ".md");
|
|
108433
|
-
const fileContent =
|
|
108431
|
+
const fileContent = readFileSync13(fullPath, "utf-8");
|
|
108434
108432
|
const { frontmatter, body } = parseMarkdownFrontmatter(fileContent);
|
|
108435
108433
|
const cleanPrefix = prefix.endsWith(":") ? prefix : prefix.endsWith("/") ? prefix : `${prefix}:`;
|
|
108436
108434
|
const name = prefix === "/" ? `/${stem}` : `${cleanPrefix}${stem}`;
|
|
@@ -108522,13 +108520,13 @@ function discoverEnabledClaudePlugins(options = {}) {
|
|
|
108522
108520
|
let userSettings = {};
|
|
108523
108521
|
if (existsSync16(userSettingsPath)) {
|
|
108524
108522
|
try {
|
|
108525
|
-
userSettings = JSON.parse(
|
|
108523
|
+
userSettings = JSON.parse(readFileSync13(userSettingsPath, "utf-8"));
|
|
108526
108524
|
} catch {}
|
|
108527
108525
|
}
|
|
108528
108526
|
let projectSettings = {};
|
|
108529
108527
|
if (existsSync16(projectSettingsPath)) {
|
|
108530
108528
|
try {
|
|
108531
|
-
projectSettings = JSON.parse(
|
|
108529
|
+
projectSettings = JSON.parse(readFileSync13(projectSettingsPath, "utf-8"));
|
|
108532
108530
|
} catch {}
|
|
108533
108531
|
}
|
|
108534
108532
|
const enabledPlugins = {
|
|
@@ -108542,7 +108540,7 @@ function discoverEnabledClaudePlugins(options = {}) {
|
|
|
108542
108540
|
let installedManifest = { plugins: {} };
|
|
108543
108541
|
if (existsSync16(installedPath)) {
|
|
108544
108542
|
try {
|
|
108545
|
-
installedManifest = JSON.parse(
|
|
108543
|
+
installedManifest = JSON.parse(readFileSync13(installedPath, "utf-8"));
|
|
108546
108544
|
} catch {}
|
|
108547
108545
|
}
|
|
108548
108546
|
const installedPlugins = installedManifest.plugins ?? {};
|
|
@@ -108741,7 +108739,7 @@ function loadSlashCommands(filePath = getSlashCommandsFilePath(), autoGenerateIf
|
|
|
108741
108739
|
return getBuiltinClaudeCommands();
|
|
108742
108740
|
}
|
|
108743
108741
|
try {
|
|
108744
|
-
const content =
|
|
108742
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
108745
108743
|
const raw = JSON.parse(content);
|
|
108746
108744
|
const parsed = slashCommandsFileSchema.safeParse(raw);
|
|
108747
108745
|
if (parsed.success && parsed.data.commands.length > 0) {
|
|
@@ -119526,7 +119524,7 @@ async function runPersistOut(input) {
|
|
|
119526
119524
|
if (!wbs)
|
|
119527
119525
|
continue;
|
|
119528
119526
|
try {
|
|
119529
|
-
const raw =
|
|
119527
|
+
const raw = readFileSync14(resolve26(toWorkdir, taskFile), "utf8");
|
|
119530
119528
|
const status = MarkdownDocument.parse(raw, "task").frontmatterData?.status;
|
|
119531
119529
|
if (typeof status === "string" && (status === "done" || status === "cancelled")) {
|
|
119532
119530
|
await reconcileExistingLifecycleRow(async () => targetDb.adapter, TASK_LIFECYCLE_PROFILE, wbs, status);
|
|
@@ -119550,7 +119548,7 @@ async function runPersistOut(input) {
|
|
|
119550
119548
|
return { exitCode: 1, stdout: out, stderr: err };
|
|
119551
119549
|
}
|
|
119552
119550
|
}
|
|
119553
|
-
var existsSync20, mkdirSync13,
|
|
119551
|
+
var existsSync20, mkdirSync13, readFileSync14, writeFileSync10, lstat3, mkdir4, readdir4, readFile6, MAX_CITED_RUN_FILES = 64;
|
|
119554
119552
|
var init_worktree_persist = __esm(() => {
|
|
119555
119553
|
init_src2();
|
|
119556
119554
|
init_dist5();
|
|
@@ -119563,7 +119561,7 @@ var init_worktree_persist = __esm(() => {
|
|
|
119563
119561
|
init_inline_run_attribution();
|
|
119564
119562
|
init_run_storage();
|
|
119565
119563
|
init_verify_verdict();
|
|
119566
|
-
({ existsSync: existsSync20, mkdirSync: mkdirSync13, readFileSync:
|
|
119564
|
+
({ existsSync: existsSync20, mkdirSync: mkdirSync13, readFileSync: readFileSync14, writeFileSync: writeFileSync10 } = process.getBuiltinModule("node:fs"));
|
|
119567
119565
|
({ lstat: lstat3, mkdir: mkdir4, readdir: readdir4, readFile: readFile6 } = process.getBuiltinModule("node:fs/promises"));
|
|
119568
119566
|
});
|
|
119569
119567
|
|
|
@@ -125525,7 +125523,7 @@ function childEnv(env) {
|
|
|
125525
125523
|
|
|
125526
125524
|
// ../../packages/app/src/workflow/wrapup/drift-probe.ts
|
|
125527
125525
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
125528
|
-
import { mkdirSync as mkdirSync16, readFileSync as
|
|
125526
|
+
import { mkdirSync as mkdirSync16, readFileSync as readFileSync18, writeFileSync as writeFileSync11 } from "fs";
|
|
125529
125527
|
import { join as join74 } from "path";
|
|
125530
125528
|
function solutionSectionOf(content) {
|
|
125531
125529
|
const heading = /^#{2,4}\s+Solution\s*$/m.exec(content);
|
|
@@ -125601,7 +125599,7 @@ function runDriftProbe(env, options = {}, spur = defaultSpurRunner(env, options)
|
|
|
125601
125599
|
};
|
|
125602
125600
|
let tasks;
|
|
125603
125601
|
try {
|
|
125604
|
-
tasks = JSON.parse(
|
|
125602
|
+
tasks = JSON.parse(readFileSync18(abs(relTasksFile), "utf8"));
|
|
125605
125603
|
} catch {
|
|
125606
125604
|
tasks = undefined;
|
|
125607
125605
|
}
|
|
@@ -125682,7 +125680,7 @@ var init_drift_probe = __esm(() => {
|
|
|
125682
125680
|
|
|
125683
125681
|
// ../../packages/app/src/workflow/wrapup/steps.ts
|
|
125684
125682
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
125685
|
-
import { appendFileSync as appendFileSync6, existsSync as existsSync22, mkdirSync as mkdirSync17, readFileSync as
|
|
125683
|
+
import { appendFileSync as appendFileSync6, existsSync as existsSync22, mkdirSync as mkdirSync17, readFileSync as readFileSync19, writeFileSync as writeFileSync12 } from "fs";
|
|
125686
125684
|
import { join as join75 } from "path";
|
|
125687
125685
|
function jqPick(...values) {
|
|
125688
125686
|
for (const value of values) {
|
|
@@ -125856,13 +125854,13 @@ function writeRouteReason(env, options = {}) {
|
|
|
125856
125854
|
}
|
|
125857
125855
|
let taskCount = -1;
|
|
125858
125856
|
try {
|
|
125859
|
-
const parsed = JSON.parse(
|
|
125857
|
+
const parsed = JSON.parse(readFileSync19(abs(join75(".spur", "run", `${runId}-wrapup-tasks.json`)), "utf8"));
|
|
125860
125858
|
if (Array.isArray(parsed))
|
|
125861
125859
|
taskCount = parsed.length;
|
|
125862
125860
|
} catch {}
|
|
125863
125861
|
let probeClean = false;
|
|
125864
125862
|
try {
|
|
125865
|
-
const probe = JSON.parse(
|
|
125863
|
+
const probe = JSON.parse(readFileSync19(abs(join75(".spur", "run", `${runId}-drift-probe.json`)), "utf8"));
|
|
125866
125864
|
probeClean = probe?.clean === true;
|
|
125867
125865
|
} catch {}
|
|
125868
125866
|
const mode = env.mode ?? "";
|
|
@@ -125882,7 +125880,7 @@ function writeRouteReason(env, options = {}) {
|
|
|
125882
125880
|
}
|
|
125883
125881
|
function readFileSyncSafe(path) {
|
|
125884
125882
|
try {
|
|
125885
|
-
return
|
|
125883
|
+
return readFileSync19(path, "utf8");
|
|
125886
125884
|
} catch {
|
|
125887
125885
|
return null;
|
|
125888
125886
|
}
|
|
@@ -125905,7 +125903,7 @@ function verdictFromTestingSection(content) {
|
|
|
125905
125903
|
}
|
|
125906
125904
|
function verdictOfArtifact(verdictPath) {
|
|
125907
125905
|
try {
|
|
125908
|
-
const raw = jqPick(JSON.parse(
|
|
125906
|
+
const raw = jqPick(JSON.parse(readFileSync19(verdictPath, "utf8")).verdict, "");
|
|
125909
125907
|
const text = jqText(raw);
|
|
125910
125908
|
return text.length > 0 ? text : null;
|
|
125911
125909
|
} catch {
|
|
@@ -125928,7 +125926,7 @@ function runMetrics(env, options = {}) {
|
|
|
125928
125926
|
};
|
|
125929
125927
|
let captured;
|
|
125930
125928
|
try {
|
|
125931
|
-
captured = JSON.parse(
|
|
125929
|
+
captured = JSON.parse(readFileSync19(abs(relTasksFile), "utf8"));
|
|
125932
125930
|
} catch {
|
|
125933
125931
|
captured = undefined;
|
|
125934
125932
|
}
|
|
@@ -126267,7 +126265,7 @@ var init_pipeline_steps = __esm(() => {
|
|
|
126267
126265
|
});
|
|
126268
126266
|
|
|
126269
126267
|
// ../../packages/app/src/workflow/task-diffstat.ts
|
|
126270
|
-
import { fstatSync as fstatSync4, mkdirSync as mkdirSync18, readFileSync as
|
|
126268
|
+
import { fstatSync as fstatSync4, mkdirSync as mkdirSync18, readFileSync as readFileSync20, renameSync as renameSync7, statSync as statSync14, writeFileSync as writeFileSync13 } from "fs";
|
|
126271
126269
|
import { join as join76 } from "path";
|
|
126272
126270
|
function defaultGitRunner(cwd) {
|
|
126273
126271
|
return (args) => {
|
|
@@ -126283,7 +126281,7 @@ function defaultGitRunner(cwd) {
|
|
|
126283
126281
|
function countNewlines2(path, cwd) {
|
|
126284
126282
|
let content;
|
|
126285
126283
|
try {
|
|
126286
|
-
content =
|
|
126284
|
+
content = readFileSync20(cwd ? join76(cwd, path) : path, "utf8");
|
|
126287
126285
|
} catch {
|
|
126288
126286
|
return 0;
|
|
126289
126287
|
}
|
|
@@ -126328,7 +126326,7 @@ function runDiffstat(env, options = {}, git = defaultGitRunner(options.cwd)) {
|
|
|
126328
126326
|
} catch {}
|
|
126329
126327
|
let base = "";
|
|
126330
126328
|
try {
|
|
126331
|
-
base =
|
|
126329
|
+
base = readFileSync20(abs(join76(relRun, `${wbs}-base.sha`)), "utf8").trim();
|
|
126332
126330
|
} catch {}
|
|
126333
126331
|
if (!/^[0-9a-f]{7,40}$/i.test(base))
|
|
126334
126332
|
return failSafe("run base .spur/run/<wbs>-base.sha missing or malformed");
|
|
@@ -126484,9 +126482,9 @@ import {
|
|
|
126484
126482
|
mkdtempSync,
|
|
126485
126483
|
openSync as openSync8,
|
|
126486
126484
|
readdirSync as readdirSync11,
|
|
126487
|
-
readFileSync as
|
|
126485
|
+
readFileSync as readFileSync21,
|
|
126488
126486
|
rmdirSync as rmdirSync3,
|
|
126489
|
-
rmSync as
|
|
126487
|
+
rmSync as rmSync5,
|
|
126490
126488
|
statSync as statSync15,
|
|
126491
126489
|
unlinkSync as unlinkSync7,
|
|
126492
126490
|
writeFileSync as writeFileSync14
|
|
@@ -126564,7 +126562,7 @@ function buildReceipt(input) {
|
|
|
126564
126562
|
}
|
|
126565
126563
|
function readReceipt2(receiptPath) {
|
|
126566
126564
|
try {
|
|
126567
|
-
return JSON.parse(
|
|
126565
|
+
return JSON.parse(readFileSync21(receiptPath, "utf8"));
|
|
126568
126566
|
} catch {
|
|
126569
126567
|
return null;
|
|
126570
126568
|
}
|
|
@@ -126590,7 +126588,7 @@ function isTimeoutShapedLog(text) {
|
|
|
126590
126588
|
}
|
|
126591
126589
|
function readContendedRetryDigest(markerPath) {
|
|
126592
126590
|
try {
|
|
126593
|
-
return
|
|
126591
|
+
return readFileSync21(markerPath, "utf8").trim();
|
|
126594
126592
|
} catch {
|
|
126595
126593
|
return "";
|
|
126596
126594
|
}
|
|
@@ -126631,10 +126629,8 @@ function resolveReceiptReuse(receiptPath, wbs, capture) {
|
|
|
126631
126629
|
refusal: `receipt belongs to ${String(receipt.wbs)}, not ${wbs}`
|
|
126632
126630
|
};
|
|
126633
126631
|
}
|
|
126634
|
-
|
|
126635
|
-
|
|
126636
|
-
receiptStatus: readReceiptStatus(receiptPath, capture.tree, wbs)
|
|
126637
|
-
};
|
|
126632
|
+
const receiptStatus = readReceiptStatus(receiptPath, capture.tree, wbs);
|
|
126633
|
+
return { reuse: receiptStatus.reuse, receiptStatus };
|
|
126638
126634
|
}
|
|
126639
126635
|
function workspaceOf(file, exists) {
|
|
126640
126636
|
const segments = file.split("/");
|
|
@@ -126661,7 +126657,7 @@ function lightScope(changedFiles, exists = existsSync23) {
|
|
|
126661
126657
|
matched = true;
|
|
126662
126658
|
}
|
|
126663
126659
|
if (rest.startsWith("commands/")) {
|
|
126664
|
-
const flagTest = "
|
|
126660
|
+
const flagTest = "scripts/commands/flag-contract-parity.test.ts";
|
|
126665
126661
|
if (exists(flagTest)) {
|
|
126666
126662
|
tests.add(flagTest);
|
|
126667
126663
|
matched = true;
|
|
@@ -126699,7 +126695,7 @@ function lightScope(changedFiles, exists = existsSync23) {
|
|
|
126699
126695
|
}
|
|
126700
126696
|
function workspaceHasTypecheck(workspace) {
|
|
126701
126697
|
try {
|
|
126702
|
-
const pkg = JSON.parse(
|
|
126698
|
+
const pkg = JSON.parse(readFileSync21(join77(workspace, "package.json"), "utf8"));
|
|
126703
126699
|
return typeof pkg.scripts?.typecheck === "string";
|
|
126704
126700
|
} catch {
|
|
126705
126701
|
return false;
|
|
@@ -126727,7 +126723,8 @@ function planLightChecks(scope, hasTypecheck = workspaceHasTypecheck, builder) {
|
|
|
126727
126723
|
}
|
|
126728
126724
|
const testsByWorkspace = new Map;
|
|
126729
126725
|
for (const test of scope.tests) {
|
|
126730
|
-
const
|
|
126726
|
+
const cut = test.indexOf("/tests/");
|
|
126727
|
+
const workspace = test.slice(0, cut >= 0 ? cut : test.indexOf("/"));
|
|
126731
126728
|
const paths = testsByWorkspace.get(workspace) ?? [];
|
|
126732
126729
|
paths.push(test.slice(workspace.length + 1));
|
|
126733
126730
|
testsByWorkspace.set(workspace, paths);
|
|
@@ -126792,7 +126789,7 @@ function runLightGate(env, options = {}) {
|
|
|
126792
126789
|
let preserveFullReceipt = false;
|
|
126793
126790
|
if (digest.length > 0) {
|
|
126794
126791
|
try {
|
|
126795
|
-
const prior = JSON.parse(
|
|
126792
|
+
const prior = JSON.parse(readFileSync21(abs(receiptFile), "utf8"));
|
|
126796
126793
|
if (prior?.schemaVersion === RECEIPT_SCHEMA_VERSION && prior.inputDigest === digest) {
|
|
126797
126794
|
if (prior.tier === "full") {
|
|
126798
126795
|
preserveFullReceipt = true;
|
|
@@ -126883,10 +126880,10 @@ function runShellCommand(cmd, cwd, extraEnv) {
|
|
|
126883
126880
|
return { output: `sh -c failed: ${result.error.message}
|
|
126884
126881
|
`, code: 1 };
|
|
126885
126882
|
}
|
|
126886
|
-
return { output:
|
|
126883
|
+
return { output: readFileSync21(path, "utf8"), code: result.status ?? 1 };
|
|
126887
126884
|
} finally {
|
|
126888
126885
|
closeSync8(fd);
|
|
126889
|
-
|
|
126886
|
+
rmSync5(dir, { recursive: true, force: true });
|
|
126890
126887
|
}
|
|
126891
126888
|
}
|
|
126892
126889
|
function gateLockDir() {
|
|
@@ -126920,7 +126917,7 @@ function readGateLockClaim(dir) {
|
|
|
126920
126917
|
}
|
|
126921
126918
|
for (const marker of markers) {
|
|
126922
126919
|
try {
|
|
126923
|
-
const claim = JSON.parse(
|
|
126920
|
+
const claim = JSON.parse(readFileSync21(join77(dir, marker), "utf8"));
|
|
126924
126921
|
if (typeof claim.pid === "number")
|
|
126925
126922
|
return { claim, marker };
|
|
126926
126923
|
} catch {
|
|
@@ -127007,7 +127004,7 @@ function acquireGateLock(env, logLine = () => {}) {
|
|
|
127007
127004
|
return {
|
|
127008
127005
|
release() {
|
|
127009
127006
|
try {
|
|
127010
|
-
|
|
127007
|
+
rmSync5(join77(dir, marker), { force: true });
|
|
127011
127008
|
rmdirSync3(dir);
|
|
127012
127009
|
} catch {}
|
|
127013
127010
|
},
|
|
@@ -127096,7 +127093,7 @@ function runQualityGate(mode, env, options = {}) {
|
|
|
127096
127093
|
const statusFile = rel("-test-gate.status");
|
|
127097
127094
|
const attemptFile = rel("-test-fix-attempt");
|
|
127098
127095
|
const abs = (p) => cwd ? join77(cwd, p) : p;
|
|
127099
|
-
const priorLog = mode === "recheck" && existsSync23(abs(logFile)) ?
|
|
127096
|
+
const priorLog = mode === "recheck" && existsSync23(abs(logFile)) ? readFileSync21(abs(logFile), "utf8") : "";
|
|
127100
127097
|
writeFileSync14(abs(logFile), "");
|
|
127101
127098
|
if (mode === "run")
|
|
127102
127099
|
writeFileSync14(abs(attemptFile), `0
|
|
@@ -127127,7 +127124,7 @@ function runQualityGate(mode, env, options = {}) {
|
|
|
127127
127124
|
`;
|
|
127128
127125
|
process.stdout.write(line);
|
|
127129
127126
|
appendFileSync7(abs(logFile), line);
|
|
127130
|
-
writeFileSync14(abs(findingsFile), extractFindings(
|
|
127127
|
+
writeFileSync14(abs(findingsFile), extractFindings(readFileSync21(abs(logFile), "utf8")));
|
|
127131
127128
|
writeFileSync14(abs(statusFile), `PASS
|
|
127132
127129
|
`);
|
|
127133
127130
|
return { status: "PASS", attempts: 0, logFile, findingsFile, statusFile, attemptFile };
|
|
@@ -127155,7 +127152,7 @@ function runQualityGate(mode, env, options = {}) {
|
|
|
127155
127152
|
writeFileSync14(abs(`${logFile}.probe`), probe.output);
|
|
127156
127153
|
gateRc = probe.code;
|
|
127157
127154
|
appendFileSync7(abs(logFile), probe.output);
|
|
127158
|
-
|
|
127155
|
+
rmSync5(abs(`${logFile}.probe`), { force: true });
|
|
127159
127156
|
}
|
|
127160
127157
|
let gateRuntimeMs = 0;
|
|
127161
127158
|
let queueWaitMs = 0;
|
|
@@ -127177,7 +127174,7 @@ function runQualityGate(mode, env, options = {}) {
|
|
|
127177
127174
|
writeFileSync14(abs(attemptLogPath), attempt.output);
|
|
127178
127175
|
const locked = isTransientLock(attempt.output);
|
|
127179
127176
|
appendFileSync7(abs(logFile), attempt.output);
|
|
127180
|
-
|
|
127177
|
+
rmSync5(abs(attemptLogPath), { force: true });
|
|
127181
127178
|
gateRc = attempt.code;
|
|
127182
127179
|
if (gateRc === 0 || !locked || gateAttempt >= MAX_GATE_ATTEMPTS)
|
|
127183
127180
|
break;
|
|
@@ -127194,10 +127191,10 @@ function runQualityGate(mode, env, options = {}) {
|
|
|
127194
127191
|
`);
|
|
127195
127192
|
}
|
|
127196
127193
|
if (gateRc !== 0) {
|
|
127197
|
-
const gateLog = existsSync23(abs(logFile)) ?
|
|
127194
|
+
const gateLog = existsSync23(abs(logFile)) ? readFileSync21(abs(logFile), "utf8") : "";
|
|
127198
127195
|
if (/^\s*0 fail\b/m.test(gateLog) && !/^\s*[1-9]\d*\s+fail\b/m.test(gateLog)) {
|
|
127199
127196
|
const bunfigPath = cwd ? join77(cwd, "bunfig.toml") : "bunfig.toml";
|
|
127200
|
-
const threshold = existsSync23(bunfigPath) ? parseCoverageThreshold(
|
|
127197
|
+
const threshold = existsSync23(bunfigPath) ? parseCoverageThreshold(readFileSync21(bunfigPath, "utf8")) : null;
|
|
127201
127198
|
if (threshold) {
|
|
127202
127199
|
for (const shortfall of scanCoverageShortfalls(gateLog, threshold)) {
|
|
127203
127200
|
process.stdout.write(`${shortfall}
|
|
@@ -127216,9 +127213,9 @@ function runQualityGate(mode, env, options = {}) {
|
|
|
127216
127213
|
} else {
|
|
127217
127214
|
process.stdout.write(`quality gate FAIL \u2014 last 40 lines follow (full log: ${logFile})
|
|
127218
127215
|
`);
|
|
127219
|
-
process.stdout.write(tailLines(
|
|
127216
|
+
process.stdout.write(tailLines(readFileSync21(abs(logFile), "utf8"), 40));
|
|
127220
127217
|
}
|
|
127221
|
-
writeFileSync14(abs(findingsFile), extractFindings(
|
|
127218
|
+
writeFileSync14(abs(findingsFile), extractFindings(readFileSync21(abs(logFile), "utf8")));
|
|
127222
127219
|
const status = gateRc === 0 ? "PASS" : "FAIL";
|
|
127223
127220
|
writeFileSync14(abs(statusFile), `${status}
|
|
127224
127221
|
`);
|
|
@@ -127584,10 +127581,11 @@ function reviewConfidenceBasis(rows, verdict) {
|
|
|
127584
127581
|
return `${open.length} P1-P3 row(s) still open`;
|
|
127585
127582
|
const carried = rows.filter((row) => {
|
|
127586
127583
|
const disposition = row.disposition.trim().toUpperCase();
|
|
127587
|
-
|
|
127584
|
+
const openP4 = (disposition.length === 0 || disposition === "OPEN") && /^P4/.test(row.priority.trim().toUpperCase());
|
|
127585
|
+
return openP4 || disposition.startsWith("DEFER") || disposition === "ACCEPTED";
|
|
127588
127586
|
});
|
|
127589
127587
|
if (carried.length > 0)
|
|
127590
|
-
return `${carried.length} finding(s) carried as DEFER/ACCEPTED`;
|
|
127588
|
+
return `${carried.length} finding(s) carried as open P4/DEFER/ACCEPTED`;
|
|
127591
127589
|
return "every finding is closed";
|
|
127592
127590
|
}
|
|
127593
127591
|
function buildReviewGateArtifact(wbs, taskContent, deferrals) {
|
|
@@ -127992,9 +127990,9 @@ import {
|
|
|
127992
127990
|
fsyncSync as fsyncSync2,
|
|
127993
127991
|
openSync as openSync9,
|
|
127994
127992
|
readdirSync as readdirSync14,
|
|
127995
|
-
readFileSync as
|
|
127993
|
+
readFileSync as readFileSync25,
|
|
127996
127994
|
renameSync as renameSync9,
|
|
127997
|
-
rmSync as
|
|
127995
|
+
rmSync as rmSync7,
|
|
127998
127996
|
statSync as statSync17,
|
|
127999
127997
|
writeFileSync as writeFileSync17
|
|
128000
127998
|
} from "fs";
|
|
@@ -128243,10 +128241,10 @@ function logicDigest(path) {
|
|
|
128243
128241
|
const walk = (dir) => readdirSync14(dir, { withFileTypes: true }).flatMap((e) => e.isDirectory() ? walk(join85(dir, e.name)) : /\.(md|ya?ml)$/.test(e.name) ? [join85(dir, e.name)] : []).sort();
|
|
128244
128242
|
for (const f of walk(path)) {
|
|
128245
128243
|
h.update(f.slice(path.length));
|
|
128246
|
-
h.update(
|
|
128244
|
+
h.update(readFileSync25(f));
|
|
128247
128245
|
}
|
|
128248
128246
|
} else {
|
|
128249
|
-
h.update(
|
|
128247
|
+
h.update(readFileSync25(path));
|
|
128250
128248
|
}
|
|
128251
128249
|
return h.digest("hex");
|
|
128252
128250
|
} catch {
|
|
@@ -128402,7 +128400,7 @@ function validateSelector(opts) {
|
|
|
128402
128400
|
function buildProvenance(opts) {
|
|
128403
128401
|
let raw;
|
|
128404
128402
|
try {
|
|
128405
|
-
raw = JSON.parse(
|
|
128403
|
+
raw = JSON.parse(readFileSync25(opts.artifact, "utf8"));
|
|
128406
128404
|
} catch (err) {
|
|
128407
128405
|
throw new Error(`could not parse fresh analyze artifact at ${opts.artifact}: ${err.message}`);
|
|
128408
128406
|
}
|
|
@@ -128433,7 +128431,7 @@ function buildProvenance(opts) {
|
|
|
128433
128431
|
if (!(opts.baseline !== undefined && existsSync28(opts.baseline)))
|
|
128434
128432
|
return null;
|
|
128435
128433
|
try {
|
|
128436
|
-
return semanticArtifactDigest(JSON.parse(
|
|
128434
|
+
return semanticArtifactDigest(JSON.parse(readFileSync25(opts.baseline, "utf8")));
|
|
128437
128435
|
} catch (err) {
|
|
128438
128436
|
throw new Error(`could not parse baseline artifact at ${opts.baseline}: ${err.message}`);
|
|
128439
128437
|
}
|
|
@@ -128454,7 +128452,7 @@ function buildProvenance(opts) {
|
|
|
128454
128452
|
}
|
|
128455
128453
|
function probe(opts) {
|
|
128456
128454
|
const current = buildProvenance(opts);
|
|
128457
|
-
const cachedText = existsSync28(opts.target) ?
|
|
128455
|
+
const cachedText = existsSync28(opts.target) ? readFileSync25(opts.target, "utf8") : null;
|
|
128458
128456
|
const cached = cachedText === null ? null : parseProvenance(cachedText);
|
|
128459
128457
|
const decision = opts.mode === "ad-hoc" ? { disposition: "miss", reasons: ["ad-hoc-never-cached"] } : decideCache(cached, current, {
|
|
128460
128458
|
recompute: opts.recompute,
|
|
@@ -128522,7 +128520,7 @@ function refreshReport(publishedMarkdown, validatedAt, disposition) {
|
|
|
128522
128520
|
function publishAtomically(candidatePath, targetPath) {
|
|
128523
128521
|
const tmpPath = `${targetPath}.tmp`;
|
|
128524
128522
|
try {
|
|
128525
|
-
writeFileSync17(tmpPath,
|
|
128523
|
+
writeFileSync17(tmpPath, readFileSync25(candidatePath));
|
|
128526
128524
|
const fd = openSync9(tmpPath, "r");
|
|
128527
128525
|
try {
|
|
128528
128526
|
fsyncSync2(fd);
|
|
@@ -128532,7 +128530,7 @@ function publishAtomically(candidatePath, targetPath) {
|
|
|
128532
128530
|
renameSync9(tmpPath, targetPath);
|
|
128533
128531
|
} catch (err) {
|
|
128534
128532
|
try {
|
|
128535
|
-
|
|
128533
|
+
rmSync7(tmpPath, { force: true });
|
|
128536
128534
|
} catch {}
|
|
128537
128535
|
throw err;
|
|
128538
128536
|
}
|
|
@@ -128607,7 +128605,7 @@ var init_history_anatomy = __esm(() => {
|
|
|
128607
128605
|
});
|
|
128608
128606
|
|
|
128609
128607
|
// ../../packages/app/src/services/history-anatomy-cli.ts
|
|
128610
|
-
import { existsSync as existsSync29, mkdirSync as mkdirSync21, readFileSync as
|
|
128608
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync21, readFileSync as readFileSync26, writeFileSync as writeFileSync18 } from "fs";
|
|
128611
128609
|
import { homedir as homedir14 } from "os";
|
|
128612
128610
|
import { join as join86 } from "path";
|
|
128613
128611
|
function parseFlags(args) {
|
|
@@ -128654,7 +128652,7 @@ function runCacheCli(argv, deps = {}) {
|
|
|
128654
128652
|
}
|
|
128655
128653
|
let artifact;
|
|
128656
128654
|
try {
|
|
128657
|
-
artifact = JSON.parse(
|
|
128655
|
+
artifact = JSON.parse(readFileSync26(a, "utf8"));
|
|
128658
128656
|
} catch {
|
|
128659
128657
|
return { exitCode: 1, stdout: "", stderr: `could not parse artifact at ${a}
|
|
128660
128658
|
` };
|
|
@@ -128668,7 +128666,7 @@ function runCacheCli(argv, deps = {}) {
|
|
|
128668
128666
|
return { exitCode: 1, stdout: "", stderr: `usage: spur history anatomy check <report.md>
|
|
128669
128667
|
` };
|
|
128670
128668
|
}
|
|
128671
|
-
const result = checkReportStructure(
|
|
128669
|
+
const result = checkReportStructure(readFileSync26(a, "utf8"));
|
|
128672
128670
|
const stdout = `${result.ok ? "PASS" : "FAIL"}
|
|
128673
128671
|
${result.problems.map((p) => `- ${p}
|
|
128674
128672
|
`).join("")}`;
|
|
@@ -128708,7 +128706,7 @@ ${result.problems.map((p) => `- ${p}
|
|
|
128708
128706
|
return { exitCode: 0, stdout: "", stderr: `assert-clean: git unavailable; skipped
|
|
128709
128707
|
` };
|
|
128710
128708
|
}
|
|
128711
|
-
const undeclared = diffPorcelain(
|
|
128709
|
+
const undeclared = diffPorcelain(readFileSync26(f.baseline, "utf8"), now, expects);
|
|
128712
128710
|
if (undeclared.length > 0) {
|
|
128713
128711
|
return {
|
|
128714
128712
|
exitCode: 1,
|
|
@@ -128819,8 +128817,8 @@ ${reasons}`, stderr: "" };
|
|
|
128819
128817
|
};
|
|
128820
128818
|
}
|
|
128821
128819
|
try {
|
|
128822
|
-
const p = JSON.parse(
|
|
128823
|
-
writeFileSync18(f.out, `${stampReport(
|
|
128820
|
+
const p = JSON.parse(readFileSync26(f.provenance, "utf8"));
|
|
128821
|
+
writeFileSync18(f.out, `${stampReport(readFileSync26(f.candidate, "utf8"), p)}
|
|
128824
128822
|
`);
|
|
128825
128823
|
} catch {
|
|
128826
128824
|
return { exitCode: 1, stdout: "", stderr: `stamp: could not read candidate or provenance
|
|
@@ -128840,7 +128838,7 @@ ${reasons}`, stderr: "" };
|
|
|
128840
128838
|
}
|
|
128841
128839
|
try {
|
|
128842
128840
|
const disposition = f.disposition ?? "hit";
|
|
128843
|
-
const refreshed = refreshReport(
|
|
128841
|
+
const refreshed = refreshReport(readFileSync26(f.report, "utf8"), f["validated-at"] ?? new Date().toISOString(), disposition);
|
|
128844
128842
|
writeFileSync18(f.out, refreshed.endsWith(`
|
|
128845
128843
|
`) ? refreshed : `${refreshed}
|
|
128846
128844
|
`);
|
|
@@ -129462,7 +129460,7 @@ var init_transcript = __esm(() => {
|
|
|
129462
129460
|
});
|
|
129463
129461
|
|
|
129464
129462
|
// ../../packages/app/src/services/session-timeline.ts
|
|
129465
|
-
import { readFileSync as
|
|
129463
|
+
import { readFileSync as readFileSync27 } from "fs";
|
|
129466
129464
|
function parseGroups(spec, count) {
|
|
129467
129465
|
let next = 1;
|
|
129468
129466
|
return spec.split(",").map((part) => {
|
|
@@ -129556,7 +129554,7 @@ function runSessionTimelineCli(argv, io) {
|
|
|
129556
129554
|
return 0;
|
|
129557
129555
|
}
|
|
129558
129556
|
try {
|
|
129559
|
-
const lines =
|
|
129557
|
+
const lines = readFileSync27(resolved.path, "utf8").split(`
|
|
129560
129558
|
`);
|
|
129561
129559
|
const timeline = buildTimeline(lines, group);
|
|
129562
129560
|
if (timeline.segments.length === 0) {
|
|
@@ -129920,7 +129918,7 @@ workflow argument is missing.`;
|
|
|
129920
129918
|
});
|
|
129921
129919
|
|
|
129922
129920
|
// ../../packages/app/src/workflow/run-summary-render.ts
|
|
129923
|
-
import { existsSync as existsSync33, mkdirSync as mkdirSync24, readdirSync as readdirSync17, readFileSync as
|
|
129921
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync24, readdirSync as readdirSync17, readFileSync as readFileSync30, writeFileSync as writeFileSync21 } from "fs";
|
|
129924
129922
|
import { join as join105 } from "path";
|
|
129925
129923
|
function renderSummaryMarkdown(summary) {
|
|
129926
129924
|
const line = (r, bold = false) => {
|
|
@@ -130023,7 +130021,7 @@ function gateFromReceipt(cwd, runId) {
|
|
|
130023
130021
|
continue;
|
|
130024
130022
|
sawReceipt = true;
|
|
130025
130023
|
try {
|
|
130026
|
-
const parsed = JSON.parse(
|
|
130024
|
+
const parsed = JSON.parse(readFileSync30(path, "utf8"));
|
|
130027
130025
|
if (parsed.runId !== runId)
|
|
130028
130026
|
continue;
|
|
130029
130027
|
const ms = parsed.gateRuntimeMs;
|
|
@@ -130057,7 +130055,7 @@ var init_run_summary_render = __esm(() => {
|
|
|
130057
130055
|
});
|
|
130058
130056
|
|
|
130059
130057
|
// ../../packages/app/src/workflow/run-summary-cli.ts
|
|
130060
|
-
import { readFileSync as
|
|
130058
|
+
import { readFileSync as readFileSync31 } from "fs";
|
|
130061
130059
|
function runRunSummaryCli(argv, io) {
|
|
130062
130060
|
const { env, write, writeErr, projectsRoot } = io;
|
|
130063
130061
|
let transcript;
|
|
@@ -130095,7 +130093,7 @@ function runRunSummaryCli(argv, io) {
|
|
|
130095
130093
|
const inputs = rollupArgs.map((arg) => {
|
|
130096
130094
|
const eq = arg.indexOf("=");
|
|
130097
130095
|
const [label, file] = eq > 0 ? [arg.slice(0, eq), arg.slice(eq + 1)] : [undefined, arg];
|
|
130098
|
-
const summary = JSON.parse(
|
|
130096
|
+
const summary = JSON.parse(readFileSync31(file, "utf8"));
|
|
130099
130097
|
return { label: label ?? summary.runId ?? file, summary };
|
|
130100
130098
|
});
|
|
130101
130099
|
write(`${renderRollupMarkdown(inputs)}
|
|
@@ -130123,9 +130121,9 @@ function runRunSummaryCli(argv, io) {
|
|
|
130123
130121
|
const inputs = progressArgs.map((arg) => {
|
|
130124
130122
|
const eq = arg.indexOf("=");
|
|
130125
130123
|
const [label, file] = eq > 0 ? [arg.slice(0, eq), arg.slice(eq + 1)] : [undefined, arg];
|
|
130126
|
-
return { label, progress: JSON.parse(
|
|
130124
|
+
return { label, progress: JSON.parse(readFileSync31(file, "utf8")) };
|
|
130127
130125
|
});
|
|
130128
|
-
const { rows, skippedLines } = parseTranscriptRows(resolved.ok ?
|
|
130126
|
+
const { rows, skippedLines } = parseTranscriptRows(resolved.ok ? readFileSync31(resolved.path, "utf8").split(`
|
|
130129
130127
|
`) : []);
|
|
130130
130128
|
const summary = buildRunSummary(rows, inputs, { since, skippedLines });
|
|
130131
130129
|
if (resolved.ok)
|
|
@@ -130181,7 +130179,7 @@ init_loader2();
|
|
|
130181
130179
|
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.5.28+c7a50b3e42c8753b/node_modules/@gobing-ai/ts-infra/dist/application-node.js
|
|
130182
130180
|
init_dist4();
|
|
130183
130181
|
init_dist5();
|
|
130184
|
-
import { appendFileSync as appendFileSync5, mkdirSync as mkdirSync15, readFileSync as
|
|
130182
|
+
import { appendFileSync as appendFileSync5, mkdirSync as mkdirSync15, readFileSync as readFileSync15, statSync as statSync13 } from "fs";
|
|
130185
130183
|
import { dirname as dirname35, join as join69 } from "path";
|
|
130186
130184
|
|
|
130187
130185
|
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.5.28+c7a50b3e42c8753b/node_modules/@gobing-ai/ts-infra/dist/application/index.js
|
|
@@ -133990,7 +133988,7 @@ async function runNodeApplication(options) {
|
|
|
133990
133988
|
let loadedAppConfig;
|
|
133991
133989
|
let yamlBootstrap = {};
|
|
133992
133990
|
if (options.configLoader?.configFile) {
|
|
133993
|
-
const fileContent =
|
|
133991
|
+
const fileContent = readFileSync15(options.configLoader.configFile, "utf-8");
|
|
133994
133992
|
const loaded = loadYamlConfig(options.configLoader, fileContent);
|
|
133995
133993
|
yamlBootstrap = loaded.bootstrapConfig;
|
|
133996
133994
|
loadedAppConfig = loaded.appConfig;
|
|
@@ -138431,7 +138429,7 @@ import { join as join73 } from "path";
|
|
|
138431
138429
|
init_src3();
|
|
138432
138430
|
init_loader2();
|
|
138433
138431
|
init_src2();
|
|
138434
|
-
import { existsSync as existsSync21, readFileSync as
|
|
138432
|
+
import { existsSync as existsSync21, readFileSync as readFileSync17 } from "fs";
|
|
138435
138433
|
import { join as join72 } from "path";
|
|
138436
138434
|
// schemas/section-matrix.schema.json
|
|
138437
138435
|
var section_matrix_schema_default = {
|
|
@@ -139530,13 +139528,13 @@ function loadTemplateBodies(projectRoot, variant) {
|
|
|
139530
139528
|
let bodies = {};
|
|
139531
139529
|
const localPath = join72(projectRoot, ".spur", "tasks", "templates", `${variant}.md`);
|
|
139532
139530
|
if (existsSync21(localPath)) {
|
|
139533
|
-
bodies = extractTemplateBodies(
|
|
139531
|
+
bodies = extractTemplateBodies(readFileSync17(localPath, "utf8"));
|
|
139534
139532
|
} else {
|
|
139535
139533
|
const root = bundledConfigRoot();
|
|
139536
139534
|
if (root !== null) {
|
|
139537
139535
|
const templatePath = join72(root, "templates", "task", `${variant}.md`);
|
|
139538
139536
|
if (existsSync21(templatePath)) {
|
|
139539
|
-
bodies = extractTemplateBodies(
|
|
139537
|
+
bodies = extractTemplateBodies(readFileSync17(templatePath, "utf8"));
|
|
139540
139538
|
}
|
|
139541
139539
|
}
|
|
139542
139540
|
}
|
|
@@ -142249,7 +142247,7 @@ function registerAgentCommand(program, context) {
|
|
|
142249
142247
|
// src/release-ops.ts
|
|
142250
142248
|
init_src();
|
|
142251
142249
|
init_dist5();
|
|
142252
|
-
import { existsSync as existsSync26, readdirSync as readdirSync13, readFileSync as
|
|
142250
|
+
import { existsSync as existsSync26, readdirSync as readdirSync13, readFileSync as readFileSync23 } from "fs";
|
|
142253
142251
|
import { join as join83 } from "path";
|
|
142254
142252
|
|
|
142255
142253
|
// ../../scripts/commands/bundle-plugins.ts
|
|
@@ -142447,7 +142445,7 @@ async function readJson2(path) {
|
|
|
142447
142445
|
function rootWorkspaceGlobs(repoRoot) {
|
|
142448
142446
|
let root;
|
|
142449
142447
|
try {
|
|
142450
|
-
root = JSON.parse(
|
|
142448
|
+
root = JSON.parse(readFileSync23(join83(repoRoot, "package.json"), "utf8"));
|
|
142451
142449
|
} catch {
|
|
142452
142450
|
return [];
|
|
142453
142451
|
}
|
|
@@ -143067,7 +143065,7 @@ async function publishPackage(target, opts = {}) {
|
|
|
143067
143065
|
// ../../packages/app/src/services/pr-review/index.ts
|
|
143068
143066
|
init_src();
|
|
143069
143067
|
import { spawnSync as spawnSync7 } from "child_process";
|
|
143070
|
-
import { existsSync as existsSync27, readFileSync as
|
|
143068
|
+
import { existsSync as existsSync27, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "fs";
|
|
143071
143069
|
import { join as join84, resolve as resolve29 } from "path";
|
|
143072
143070
|
function createSpawnRunner(context = {}) {
|
|
143073
143071
|
return (cmd) => {
|
|
@@ -143214,7 +143212,7 @@ function hasCodeReviewRules(repoRoot) {
|
|
|
143214
143212
|
const agentsPath = join84(repoRoot, "AGENTS.md");
|
|
143215
143213
|
if (!existsSync27(agentsPath))
|
|
143216
143214
|
return false;
|
|
143217
|
-
return /^## Code Review Rules\s*$/m.test(
|
|
143215
|
+
return /^## Code Review Rules\s*$/m.test(readFileSync24(agentsPath, "utf8"));
|
|
143218
143216
|
}
|
|
143219
143217
|
function buildRequestBody(rulesPresent, focus) {
|
|
143220
143218
|
const base = rulesPresent ? "@codex review" : `@codex review ${DEFAULT_FOCUS}`;
|
|
@@ -145619,7 +145617,7 @@ import { createRequire as createRequire3 } from "module";
|
|
|
145619
145617
|
var CLI_CONFIG = {
|
|
145620
145618
|
binaryName: "spur",
|
|
145621
145619
|
binaryLabel: "spur",
|
|
145622
|
-
binaryVersion: "0.4.
|
|
145620
|
+
binaryVersion: "0.4.13",
|
|
145623
145621
|
configDir: ".spur",
|
|
145624
145622
|
configFile: ".spur/config.yaml",
|
|
145625
145623
|
databaseFile: ".spur/spur.db"
|
|
@@ -155430,7 +155428,7 @@ init_dist5();
|
|
|
155430
155428
|
import { homedir as homedir17 } from "os";
|
|
155431
155429
|
import { basename as basename20, join as join94, relative as relative19, resolve as resolve36 } from "path";
|
|
155432
155430
|
// ../server/package.json
|
|
155433
|
-
var version3 = "0.4.
|
|
155431
|
+
var version3 = "0.4.13";
|
|
155434
155432
|
|
|
155435
155433
|
// ../server/src/modules/health/index.ts
|
|
155436
155434
|
var startedAt = Date.now();
|
|
@@ -160175,6 +160173,13 @@ function registerExecCommand(self2, context, options = {}) {
|
|
|
160175
160173
|
`));
|
|
160176
160174
|
return;
|
|
160177
160175
|
}
|
|
160176
|
+
for (const step of plan) {
|
|
160177
|
+
const placeholder = /\{(?:files|paths|workspace)\}/.exec(step.command)?.[0];
|
|
160178
|
+
if (placeholder === undefined)
|
|
160179
|
+
continue;
|
|
160180
|
+
fail(`action "${step.name}" needs ${placeholder} from the light-gate planner; it cannot run via self exec`);
|
|
160181
|
+
return;
|
|
160182
|
+
}
|
|
160178
160183
|
const executor = new NodeProcessExecutor2({ output: { mode: "stream", isTTY: true } });
|
|
160179
160184
|
const results = [];
|
|
160180
160185
|
let exitCode = 0;
|
|
@@ -160477,7 +160482,7 @@ function registerWorkflowCleanCommand(workflow, context) {
|
|
|
160477
160482
|
|
|
160478
160483
|
// ../../packages/app/src/workflow/commit-guard.ts
|
|
160479
160484
|
init_dist5();
|
|
160480
|
-
import { mkdirSync as mkdirSync23, readFileSync as
|
|
160485
|
+
import { mkdirSync as mkdirSync23, readFileSync as readFileSync28, renameSync as renameSync10, writeFileSync as writeFileSync20 } from "fs";
|
|
160481
160486
|
import { join as join100 } from "path";
|
|
160482
160487
|
var COMMIT_GUARD_USAGE = "usage: spur workflow commit-guard start --run <id> | stage --run <id> [--base <sha>] -- <paths\u2026> | check --run <id> [--base <sha>]";
|
|
160483
160488
|
var isBookkeeping = (path) => path === ".spur" || path.startsWith(".spur/");
|
|
@@ -160537,7 +160542,7 @@ function changedSinceBase(base, git) {
|
|
|
160537
160542
|
}
|
|
160538
160543
|
function readTreeStart(run, options) {
|
|
160539
160544
|
try {
|
|
160540
|
-
const parsed = JSON.parse(
|
|
160545
|
+
const parsed = JSON.parse(readFileSync28(at2(options, artifactPath(run)), "utf8"));
|
|
160541
160546
|
if (typeof parsed.head === "string" && Array.isArray(parsed.dirty))
|
|
160542
160547
|
return parsed;
|
|
160543
160548
|
} catch {}
|
|
@@ -160551,7 +160556,7 @@ function runContext(run, options) {
|
|
|
160551
160556
|
let base = options.base ?? "";
|
|
160552
160557
|
if (!base) {
|
|
160553
160558
|
try {
|
|
160554
|
-
const anchored =
|
|
160559
|
+
const anchored = readFileSync28(at2(options, join100(".spur", "run", `${run}-base.sha`)), "utf8").trim();
|
|
160555
160560
|
if (/^[0-9a-f]{7,40}$/i.test(anchored))
|
|
160556
160561
|
base = anchored;
|
|
160557
160562
|
} catch {}
|
|
@@ -160607,7 +160612,7 @@ function conflictingTarget(paths, options, git) {
|
|
|
160607
160612
|
if (unmerged.has(path))
|
|
160608
160613
|
return `${path} (unmerged)`;
|
|
160609
160614
|
try {
|
|
160610
|
-
if (conflictMarkerLine(
|
|
160615
|
+
if (conflictMarkerLine(readFileSync28(at2(options, path), "utf8")))
|
|
160611
160616
|
return `${path} (conflict markers)`;
|
|
160612
160617
|
} catch {}
|
|
160613
160618
|
}
|
|
@@ -161305,7 +161310,7 @@ init_src3();
|
|
|
161305
161310
|
|
|
161306
161311
|
// ../../packages/app/src/workflow/persist-check.ts
|
|
161307
161312
|
init_dist5();
|
|
161308
|
-
import { existsSync as existsSync32, readdirSync as readdirSync16, readFileSync as
|
|
161313
|
+
import { existsSync as existsSync32, readdirSync as readdirSync16, readFileSync as readFileSync29, statSync as statSync19 } from "fs";
|
|
161309
161314
|
import { basename as basename22, dirname as dirname45, isAbsolute as isAbsolute17, join as join103, relative as relative20, resolve as resolve38 } from "path";
|
|
161310
161315
|
var EVIDENCE_DIR = join103(".spur", "memory", "evidence");
|
|
161311
161316
|
var RUN_DIR = join103(".spur", "run");
|
|
@@ -161374,7 +161379,7 @@ function compareTrees(wtRoot, invokeRoot, files, foreignDivergent = new Set) {
|
|
|
161374
161379
|
continue;
|
|
161375
161380
|
}
|
|
161376
161381
|
try {
|
|
161377
|
-
if (
|
|
161382
|
+
if (readFileSync29(join103(wtRoot, rel)).equals(readFileSync29(invPath)))
|
|
161378
161383
|
ok++;
|
|
161379
161384
|
else
|
|
161380
161385
|
divergent.push(rel);
|
|
@@ -161401,7 +161406,7 @@ function readPersistOutSkips(candidates) {
|
|
|
161401
161406
|
if (!existsSync32(cand))
|
|
161402
161407
|
continue;
|
|
161403
161408
|
try {
|
|
161404
|
-
const parsed = JSON.parse(
|
|
161409
|
+
const parsed = JSON.parse(readFileSync29(cand, "utf8"));
|
|
161405
161410
|
if (Array.isArray(parsed.evidenceSkipped)) {
|
|
161406
161411
|
for (const item of parsed.evidenceSkipped) {
|
|
161407
161412
|
if (item.reason === "foreign-divergent" && typeof item.name === "string") {
|
|
@@ -161495,7 +161500,7 @@ function registerWorkflowPersistCommand(workflow, context) {
|
|
|
161495
161500
|
if (from.trim() === "" || options.taskFile.some((taskFile) => taskFile.trim() === ""))
|
|
161496
161501
|
return usage(persistOut);
|
|
161497
161502
|
try {
|
|
161498
|
-
const result = await runPersistOut({ from, taskFiles: options.taskFile });
|
|
161503
|
+
const result = await runPersistOut({ from, taskFiles: options.taskFile, to: context.cwd });
|
|
161499
161504
|
for (const line of result.stdout)
|
|
161500
161505
|
context.output.write(line);
|
|
161501
161506
|
for (const line of result.stderr)
|
|
@@ -162195,7 +162200,7 @@ function registerWorkflowSummaryCommand(workflow, context) {
|
|
|
162195
162200
|
|
|
162196
162201
|
// src/commands/workflow/trace.ts
|
|
162197
162202
|
init_src3();
|
|
162198
|
-
import { closeSync as closeSync10, fstatSync as fstatSync5, openSync as openSync10, readFileSync as
|
|
162203
|
+
import { closeSync as closeSync10, fstatSync as fstatSync5, openSync as openSync10, readFileSync as readFileSync32, readSync as readSync3 } from "fs";
|
|
162199
162204
|
import { join as join106 } from "path";
|
|
162200
162205
|
import { setTimeout as sleep7 } from "timers/promises";
|
|
162201
162206
|
function formatTraceList2(result) {
|
|
@@ -162381,7 +162386,7 @@ async function followRunLog(service, runId, dir, pollMs, write, wait = (ms) => s
|
|
|
162381
162386
|
offset = 0;
|
|
162382
162387
|
if (carried !== "") {
|
|
162383
162388
|
try {
|
|
162384
|
-
const nextText =
|
|
162389
|
+
const nextText = readFileSync32(target, "utf8");
|
|
162385
162390
|
if (nextText.startsWith(carried))
|
|
162386
162391
|
offset = Buffer.byteLength(carried);
|
|
162387
162392
|
} catch {
|