@inerrata-corporation/errata 2.0.2-dev.196 → 2.0.2-dev.201
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/errata.mjs +330 -174
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -47172,12 +47172,12 @@ var init_report_render = __esm({
|
|
|
47172
47172
|
|
|
47173
47173
|
// src/cli.ts
|
|
47174
47174
|
init_src5();
|
|
47175
|
-
import { closeSync as closeSync2, existsSync as
|
|
47176
|
-
import { join as
|
|
47175
|
+
import { closeSync as closeSync2, existsSync as existsSync25, openSync as openSync2, readFileSync as readFileSync23, renameSync as renameSync3, statSync as statSync6 } from "node:fs";
|
|
47176
|
+
import { join as join27 } from "node:path";
|
|
47177
47177
|
import { spawn as spawn3 } from "node:child_process";
|
|
47178
47178
|
|
|
47179
47179
|
// src/daemon.ts
|
|
47180
|
-
import { existsSync as
|
|
47180
|
+
import { existsSync as existsSync20, writeFileSync as writeFileSync16 } from "node:fs";
|
|
47181
47181
|
|
|
47182
47182
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
|
|
47183
47183
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -47757,8 +47757,8 @@ init_config();
|
|
|
47757
47757
|
|
|
47758
47758
|
// src/engine.ts
|
|
47759
47759
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
47760
|
-
import { existsSync as
|
|
47761
|
-
import { join as
|
|
47760
|
+
import { existsSync as existsSync19, statSync as statSync5, appendFileSync as appendFileSync2, readdirSync as readdirSync9, renameSync as renameSync2, readFileSync as readFileSync18, writeFileSync as writeFileSync15 } from "node:fs";
|
|
47761
|
+
import { join as join23, relative as relative6, sep as sep4 } from "node:path";
|
|
47762
47762
|
|
|
47763
47763
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
47764
47764
|
import { stat as statcb } from "fs";
|
|
@@ -50541,6 +50541,147 @@ ${conversation}` }]
|
|
|
50541
50541
|
};
|
|
50542
50542
|
}
|
|
50543
50543
|
|
|
50544
|
+
// src/constraint-backfill.ts
|
|
50545
|
+
init_src4();
|
|
50546
|
+
init_src2();
|
|
50547
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11, readdirSync as readdirSync6, writeFileSync as writeFileSync11 } from "node:fs";
|
|
50548
|
+
import { join as join16 } from "node:path";
|
|
50549
|
+
import { homedir as homedir4 } from "node:os";
|
|
50550
|
+
var BACKFILL_VERSION = 1;
|
|
50551
|
+
var EMPTY = {
|
|
50552
|
+
skipped: true,
|
|
50553
|
+
stamped: 0,
|
|
50554
|
+
detached: 0,
|
|
50555
|
+
reopened: 0,
|
|
50556
|
+
witnessed: 0,
|
|
50557
|
+
cloudTwins: []
|
|
50558
|
+
};
|
|
50559
|
+
function markerPath(configDir) {
|
|
50560
|
+
return join16(configDir, "constraint-backfill.json");
|
|
50561
|
+
}
|
|
50562
|
+
function alreadyDone(configDir) {
|
|
50563
|
+
const p = markerPath(configDir);
|
|
50564
|
+
if (!existsSync13(p)) return false;
|
|
50565
|
+
try {
|
|
50566
|
+
const raw2 = JSON.parse(readFileSync11(p, "utf8"));
|
|
50567
|
+
return raw2?.version === BACKFILL_VERSION;
|
|
50568
|
+
} catch {
|
|
50569
|
+
return false;
|
|
50570
|
+
}
|
|
50571
|
+
}
|
|
50572
|
+
function replay(root) {
|
|
50573
|
+
const statements = /* @__PURE__ */ new Set();
|
|
50574
|
+
const citedByFix = /* @__PURE__ */ new Set();
|
|
50575
|
+
const dir = claudeProjectDir(root, homedir4());
|
|
50576
|
+
if (!existsSync13(dir)) return { statements, citedByFix };
|
|
50577
|
+
let names;
|
|
50578
|
+
try {
|
|
50579
|
+
names = readdirSync6(dir).filter((n) => n.endsWith(".jsonl"));
|
|
50580
|
+
} catch {
|
|
50581
|
+
return { statements, citedByFix };
|
|
50582
|
+
}
|
|
50583
|
+
for (const f of names) {
|
|
50584
|
+
let lines;
|
|
50585
|
+
try {
|
|
50586
|
+
lines = readFileSync11(join16(dir, f), "utf8").split("\n");
|
|
50587
|
+
} catch {
|
|
50588
|
+
continue;
|
|
50589
|
+
}
|
|
50590
|
+
for (const line of lines) {
|
|
50591
|
+
if (!line.trim()) continue;
|
|
50592
|
+
let rec;
|
|
50593
|
+
try {
|
|
50594
|
+
rec = JSON.parse(line);
|
|
50595
|
+
} catch {
|
|
50596
|
+
continue;
|
|
50597
|
+
}
|
|
50598
|
+
if (rec.type !== "assistant" || !Array.isArray(rec.message?.content)) continue;
|
|
50599
|
+
for (const b of rec.message.content) {
|
|
50600
|
+
if (b?.type !== "text" || typeof b.text !== "string") continue;
|
|
50601
|
+
for (const tag of parseInlineTags(b.text)) {
|
|
50602
|
+
if (tag.kind === "constraint" && tag.statement) statements.add(tag.statement);
|
|
50603
|
+
if (tag.kind === "fix") {
|
|
50604
|
+
const t = tag;
|
|
50605
|
+
if (t.handle) citedByFix.add(t.handle);
|
|
50606
|
+
if (t.threadId) citedByFix.add(t.threadId);
|
|
50607
|
+
}
|
|
50608
|
+
}
|
|
50609
|
+
}
|
|
50610
|
+
}
|
|
50611
|
+
}
|
|
50612
|
+
return { statements, citedByFix };
|
|
50613
|
+
}
|
|
50614
|
+
function backfillConstraintKind(store, opts) {
|
|
50615
|
+
if (!opts.force && !opts.dryRun && alreadyDone(opts.configDir)) return EMPTY;
|
|
50616
|
+
const { statements, citedByFix } = replay(opts.root);
|
|
50617
|
+
const report = {
|
|
50618
|
+
skipped: false,
|
|
50619
|
+
stamped: 0,
|
|
50620
|
+
detached: 0,
|
|
50621
|
+
reopened: 0,
|
|
50622
|
+
witnessed: 0,
|
|
50623
|
+
cloudTwins: []
|
|
50624
|
+
};
|
|
50625
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50626
|
+
const work = [];
|
|
50627
|
+
for (const statement of statements) {
|
|
50628
|
+
const id = designProblemId(statement);
|
|
50629
|
+
if (seen.has(id)) continue;
|
|
50630
|
+
seen.add(id);
|
|
50631
|
+
const node2 = store.getNode(id);
|
|
50632
|
+
if (!node2 || node2.label !== "Problem") continue;
|
|
50633
|
+
const isWitnessed = citedByFix.has(priorHandle(node2)) || citedByFix.has(id) || [...citedByFix].some((c) => c && id.startsWith(c));
|
|
50634
|
+
const fabricated = [];
|
|
50635
|
+
for (const e of store.outEdges(id, ["SOLVED_BY"])) {
|
|
50636
|
+
const sol = store.getNode(e.to);
|
|
50637
|
+
if (!sol) continue;
|
|
50638
|
+
const auto = sol.description.startsWith(AUTO_MINT_PREFIX);
|
|
50639
|
+
if (!auto && isWitnessed) report.witnessed++;
|
|
50640
|
+
else fabricated.push(sol.id);
|
|
50641
|
+
}
|
|
50642
|
+
const stamp = node2.attrs["kind"] !== "constraint";
|
|
50643
|
+
if (stamp) report.stamped++;
|
|
50644
|
+
if (fabricated.length > 0) {
|
|
50645
|
+
report.detached += fabricated.length;
|
|
50646
|
+
report.reopened++;
|
|
50647
|
+
}
|
|
50648
|
+
const cloudNodeId = node2.attrs["cloudNodeId"];
|
|
50649
|
+
if (typeof cloudNodeId === "string" && (stamp || fabricated.length > 0)) {
|
|
50650
|
+
report.cloudTwins.push(cloudNodeId);
|
|
50651
|
+
}
|
|
50652
|
+
if (stamp || fabricated.length > 0) work.push({ id, fabricated, stamp });
|
|
50653
|
+
}
|
|
50654
|
+
if (opts.dryRun) return report;
|
|
50655
|
+
store.transaction(() => {
|
|
50656
|
+
for (const w of work) {
|
|
50657
|
+
const node2 = store.getNode(w.id);
|
|
50658
|
+
if (!node2) continue;
|
|
50659
|
+
const attrs = { ...node2.attrs, kind: "constraint" };
|
|
50660
|
+
if (w.fabricated.length > 0) {
|
|
50661
|
+
delete attrs["resolvedAt"];
|
|
50662
|
+
delete attrs["resolvedReason"];
|
|
50663
|
+
}
|
|
50664
|
+
store.updateNode(w.id, { attrs, lastUpdatedAt: opts.now });
|
|
50665
|
+
for (const solId of w.fabricated) {
|
|
50666
|
+
for (const e of store.outEdges(w.id, ["SOLVED_BY"])) {
|
|
50667
|
+
if (e.to === solId) store.closeEdge(e.id, opts.now);
|
|
50668
|
+
}
|
|
50669
|
+
const sol = store.getNode(solId);
|
|
50670
|
+
if (sol?.description.startsWith(AUTO_MINT_PREFIX)) store.closeNode(solId, opts.now);
|
|
50671
|
+
}
|
|
50672
|
+
}
|
|
50673
|
+
});
|
|
50674
|
+
try {
|
|
50675
|
+
writeFileSync11(
|
|
50676
|
+
markerPath(opts.configDir),
|
|
50677
|
+
JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
|
|
50678
|
+
"utf8"
|
|
50679
|
+
);
|
|
50680
|
+
} catch {
|
|
50681
|
+
}
|
|
50682
|
+
return report;
|
|
50683
|
+
}
|
|
50684
|
+
|
|
50544
50685
|
// src/engine.ts
|
|
50545
50686
|
init_symbol_summaries();
|
|
50546
50687
|
init_reconcile();
|
|
@@ -50739,11 +50880,11 @@ init_outbox();
|
|
|
50739
50880
|
init_src8();
|
|
50740
50881
|
init_src();
|
|
50741
50882
|
init_src2();
|
|
50742
|
-
import { readFileSync as
|
|
50743
|
-
import { join as
|
|
50883
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
50884
|
+
import { join as join17 } from "node:path";
|
|
50744
50885
|
function loadClaimIgnorePatterns(workspaceRoot) {
|
|
50745
50886
|
try {
|
|
50746
|
-
return
|
|
50887
|
+
return readFileSync12(join17(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
|
|
50747
50888
|
} catch {
|
|
50748
50889
|
return [];
|
|
50749
50890
|
}
|
|
@@ -51104,22 +51245,22 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
|
|
|
51104
51245
|
}
|
|
51105
51246
|
|
|
51106
51247
|
// src/git-sensor.ts
|
|
51107
|
-
import { existsSync as
|
|
51108
|
-
import { join as
|
|
51248
|
+
import { existsSync as existsSync14, readFileSync as readFileSync13, watch as fsWatch } from "node:fs";
|
|
51249
|
+
import { join as join18 } from "node:path";
|
|
51109
51250
|
function readFirstLine(path2) {
|
|
51110
51251
|
try {
|
|
51111
|
-
return
|
|
51252
|
+
return readFileSync13(path2, "utf8").split(/\r?\n/, 1)[0].trim();
|
|
51112
51253
|
} catch {
|
|
51113
51254
|
return null;
|
|
51114
51255
|
}
|
|
51115
51256
|
}
|
|
51116
51257
|
function readGitRefState(gitDir) {
|
|
51117
|
-
const head2 = readFirstLine(
|
|
51258
|
+
const head2 = readFirstLine(join18(gitDir, "HEAD"));
|
|
51118
51259
|
const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
|
|
51119
51260
|
const branch = m ? m[1] : null;
|
|
51120
51261
|
let sha2 = null;
|
|
51121
51262
|
if (branch) {
|
|
51122
|
-
sha2 = readFirstLine(
|
|
51263
|
+
sha2 = readFirstLine(join18(gitDir, "refs", "heads", branch));
|
|
51123
51264
|
if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
|
|
51124
51265
|
} else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
|
|
51125
51266
|
sha2 = head2;
|
|
@@ -51127,13 +51268,13 @@ function readGitRefState(gitDir) {
|
|
|
51127
51268
|
return {
|
|
51128
51269
|
branch,
|
|
51129
51270
|
sha: sha2,
|
|
51130
|
-
mergeHeadExists:
|
|
51131
|
-
origHeadExists:
|
|
51271
|
+
mergeHeadExists: existsSync14(join18(gitDir, "MERGE_HEAD")),
|
|
51272
|
+
origHeadExists: existsSync14(join18(gitDir, "ORIG_HEAD"))
|
|
51132
51273
|
};
|
|
51133
51274
|
}
|
|
51134
51275
|
function shaFromPackedRefs(gitDir, ref) {
|
|
51135
51276
|
try {
|
|
51136
|
-
for (const line of
|
|
51277
|
+
for (const line of readFileSync13(join18(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
|
|
51137
51278
|
const [sha2, name2] = line.split(/\s+/);
|
|
51138
51279
|
if (name2 === ref && sha2) return sha2;
|
|
51139
51280
|
}
|
|
@@ -51167,7 +51308,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
51167
51308
|
const settle = () => {
|
|
51168
51309
|
if (timer) clearTimeout(timer);
|
|
51169
51310
|
timer = setTimeout(() => {
|
|
51170
|
-
if (
|
|
51311
|
+
if (existsSync14(join18(gitDir, "index.lock"))) {
|
|
51171
51312
|
settle();
|
|
51172
51313
|
return;
|
|
51173
51314
|
}
|
|
@@ -51178,7 +51319,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
51178
51319
|
}, debounceMs);
|
|
51179
51320
|
};
|
|
51180
51321
|
for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
|
|
51181
|
-
const p =
|
|
51322
|
+
const p = join18(gitDir, sub);
|
|
51182
51323
|
try {
|
|
51183
51324
|
watchers.push(fsWatch(p, settle));
|
|
51184
51325
|
} catch {
|
|
@@ -51403,21 +51544,21 @@ var TelemetryRecorder = class {
|
|
|
51403
51544
|
|
|
51404
51545
|
// src/skills.ts
|
|
51405
51546
|
import {
|
|
51406
|
-
existsSync as
|
|
51547
|
+
existsSync as existsSync15,
|
|
51407
51548
|
mkdirSync as mkdirSync6,
|
|
51408
|
-
readFileSync as
|
|
51409
|
-
readdirSync as
|
|
51549
|
+
readFileSync as readFileSync14,
|
|
51550
|
+
readdirSync as readdirSync7,
|
|
51410
51551
|
unlinkSync as unlinkSync2,
|
|
51411
|
-
writeFileSync as
|
|
51552
|
+
writeFileSync as writeFileSync12
|
|
51412
51553
|
} from "node:fs";
|
|
51413
|
-
import { basename as basename4, join as
|
|
51554
|
+
import { basename as basename4, join as join19 } from "node:path";
|
|
51414
51555
|
function skillFileName(id) {
|
|
51415
51556
|
return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
|
|
51416
51557
|
}
|
|
51417
51558
|
function readSkillManifest(manifestPath) {
|
|
51418
|
-
if (!
|
|
51559
|
+
if (!existsSync15(manifestPath)) return [];
|
|
51419
51560
|
try {
|
|
51420
|
-
const parsed = JSON.parse(
|
|
51561
|
+
const parsed = JSON.parse(readFileSync14(manifestPath, "utf8"));
|
|
51421
51562
|
return (parsed.skills ?? []).map((s) => ({
|
|
51422
51563
|
title: s.title ?? "",
|
|
51423
51564
|
layer: s.layer ?? "technique",
|
|
@@ -51433,7 +51574,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
51433
51574
|
const staleDaemon = res.staleDaemon && res.latestDaemonVersion ? { latest: res.latestDaemonVersion } : void 0;
|
|
51434
51575
|
mkdirSync6(paths.skillsDir, { recursive: true });
|
|
51435
51576
|
if (res.skills.length === 0 && pins.length === 0) {
|
|
51436
|
-
const existing =
|
|
51577
|
+
const existing = readdirSync7(paths.skillsDir).filter((f) => f.endsWith(".md"));
|
|
51437
51578
|
if (existing.length > 0) return { written: 0, pruned: 0, ...staleDaemon ? { staleDaemon } : {} };
|
|
51438
51579
|
}
|
|
51439
51580
|
const rows = [];
|
|
@@ -51441,7 +51582,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
51441
51582
|
for (const s of res.skills) {
|
|
51442
51583
|
const fileName = skillFileName(s.id);
|
|
51443
51584
|
keep.add(fileName);
|
|
51444
|
-
|
|
51585
|
+
writeFileSync12(join19(paths.skillsDir, fileName), s.markdown, "utf8");
|
|
51445
51586
|
rows.push({
|
|
51446
51587
|
id: s.id,
|
|
51447
51588
|
title: s.title,
|
|
@@ -51454,7 +51595,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
51454
51595
|
const fileName = skillFileName(p.id);
|
|
51455
51596
|
if (keep.has(fileName)) continue;
|
|
51456
51597
|
keep.add(fileName);
|
|
51457
|
-
|
|
51598
|
+
writeFileSync12(join19(paths.skillsDir, fileName), p.markdown, "utf8");
|
|
51458
51599
|
rows.push({
|
|
51459
51600
|
id: p.id,
|
|
51460
51601
|
title: p.title,
|
|
@@ -51464,17 +51605,17 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
51464
51605
|
});
|
|
51465
51606
|
}
|
|
51466
51607
|
let pruned = 0;
|
|
51467
|
-
for (const f of
|
|
51608
|
+
for (const f of readdirSync7(paths.skillsDir)) {
|
|
51468
51609
|
if (!f.endsWith(".md")) continue;
|
|
51469
51610
|
if (keep.has(basename4(f))) continue;
|
|
51470
51611
|
try {
|
|
51471
|
-
unlinkSync2(
|
|
51612
|
+
unlinkSync2(join19(paths.skillsDir, f));
|
|
51472
51613
|
pruned++;
|
|
51473
51614
|
} catch {
|
|
51474
51615
|
}
|
|
51475
51616
|
}
|
|
51476
51617
|
rows.sort((a, b) => a.id.localeCompare(b.id));
|
|
51477
|
-
|
|
51618
|
+
writeFileSync12(
|
|
51478
51619
|
paths.skillsManifest,
|
|
51479
51620
|
JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
|
|
51480
51621
|
"utf8"
|
|
@@ -51486,22 +51627,22 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
|
|
|
51486
51627
|
init_src2();
|
|
51487
51628
|
import {
|
|
51488
51629
|
cpSync,
|
|
51489
|
-
existsSync as
|
|
51630
|
+
existsSync as existsSync16,
|
|
51490
51631
|
lstatSync,
|
|
51491
51632
|
mkdirSync as mkdirSync7,
|
|
51492
|
-
readFileSync as
|
|
51493
|
-
readdirSync as
|
|
51633
|
+
readFileSync as readFileSync15,
|
|
51634
|
+
readdirSync as readdirSync8,
|
|
51494
51635
|
rmSync as rmSync2,
|
|
51495
51636
|
symlinkSync,
|
|
51496
|
-
writeFileSync as
|
|
51637
|
+
writeFileSync as writeFileSync13
|
|
51497
51638
|
} from "node:fs";
|
|
51498
|
-
import { join as
|
|
51639
|
+
import { join as join20 } from "node:path";
|
|
51499
51640
|
var SKILL_NS = "errata-";
|
|
51500
51641
|
var HARNESS_SKILL_DIRS = [
|
|
51501
|
-
{ configDir: ".claude", skillsDir:
|
|
51642
|
+
{ configDir: ".claude", skillsDir: join20(".claude", "skills") },
|
|
51502
51643
|
// Cursor adopted the standard; its exact project dir is still moving — kept
|
|
51503
51644
|
// best-effort and gated on `.cursor/` presence so we never create it blind.
|
|
51504
|
-
{ configDir: ".cursor", skillsDir:
|
|
51645
|
+
{ configDir: ".cursor", skillsDir: join20(".cursor", "skills") }
|
|
51505
51646
|
];
|
|
51506
51647
|
function skillSlug(title, id) {
|
|
51507
51648
|
const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
|
|
@@ -51546,12 +51687,12 @@ function skillCiteHandle(s) {
|
|
|
51546
51687
|
return priorHandle({ id: s.id, description: s.title });
|
|
51547
51688
|
}
|
|
51548
51689
|
function reconcileNamespaced(dir, keep) {
|
|
51549
|
-
if (!
|
|
51690
|
+
if (!existsSync16(dir)) return 0;
|
|
51550
51691
|
let pruned = 0;
|
|
51551
|
-
for (const name2 of
|
|
51692
|
+
for (const name2 of readdirSync8(dir)) {
|
|
51552
51693
|
if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
|
|
51553
51694
|
try {
|
|
51554
|
-
rmSync2(
|
|
51695
|
+
rmSync2(join20(dir, name2), { recursive: true, force: true });
|
|
51555
51696
|
pruned++;
|
|
51556
51697
|
} catch {
|
|
51557
51698
|
}
|
|
@@ -51560,7 +51701,7 @@ function reconcileNamespaced(dir, keep) {
|
|
|
51560
51701
|
}
|
|
51561
51702
|
function linkOrCopy(linkPath, target) {
|
|
51562
51703
|
try {
|
|
51563
|
-
if (
|
|
51704
|
+
if (existsSync16(linkPath) || safeLstat(linkPath)) rmSync2(linkPath, { recursive: true, force: true });
|
|
51564
51705
|
} catch {
|
|
51565
51706
|
}
|
|
51566
51707
|
try {
|
|
@@ -51581,7 +51722,7 @@ function safeLstat(p) {
|
|
|
51581
51722
|
}
|
|
51582
51723
|
}
|
|
51583
51724
|
function emitAndProjectSkills(root, skills) {
|
|
51584
|
-
const agentsSkillsDir =
|
|
51725
|
+
const agentsSkillsDir = join20(root, ".agents", "skills");
|
|
51585
51726
|
mkdirSync7(agentsSkillsDir, { recursive: true });
|
|
51586
51727
|
const slugs = [];
|
|
51587
51728
|
const keep = /* @__PURE__ */ new Set();
|
|
@@ -51589,7 +51730,7 @@ function emitAndProjectSkills(root, skills) {
|
|
|
51589
51730
|
for (const s of skills) {
|
|
51590
51731
|
let body2;
|
|
51591
51732
|
try {
|
|
51592
|
-
body2 =
|
|
51733
|
+
body2 = readFileSync15(s.bodyPath, "utf8");
|
|
51593
51734
|
} catch {
|
|
51594
51735
|
continue;
|
|
51595
51736
|
}
|
|
@@ -51598,9 +51739,9 @@ function emitAndProjectSkills(root, skills) {
|
|
|
51598
51739
|
keep.add(slug2);
|
|
51599
51740
|
slugs.push(slug2);
|
|
51600
51741
|
const description = deriveDescription(s.title, s.layer, body2);
|
|
51601
|
-
mkdirSync7(
|
|
51602
|
-
|
|
51603
|
-
|
|
51742
|
+
mkdirSync7(join20(agentsSkillsDir, slug2), { recursive: true });
|
|
51743
|
+
writeFileSync13(
|
|
51744
|
+
join20(agentsSkillsDir, slug2, "SKILL.md"),
|
|
51604
51745
|
renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
|
|
51605
51746
|
"utf8"
|
|
51606
51747
|
);
|
|
@@ -51609,11 +51750,11 @@ function emitAndProjectSkills(root, skills) {
|
|
|
51609
51750
|
reconcileNamespaced(agentsSkillsDir, keep);
|
|
51610
51751
|
let projected = 0;
|
|
51611
51752
|
for (const h of HARNESS_SKILL_DIRS) {
|
|
51612
|
-
if (!
|
|
51613
|
-
const dir =
|
|
51753
|
+
if (!existsSync16(join20(root, h.configDir))) continue;
|
|
51754
|
+
const dir = join20(root, h.skillsDir);
|
|
51614
51755
|
mkdirSync7(dir, { recursive: true });
|
|
51615
51756
|
for (const slug2 of slugs) {
|
|
51616
|
-
linkOrCopy(
|
|
51757
|
+
linkOrCopy(join20(dir, slug2), join20(agentsSkillsDir, slug2));
|
|
51617
51758
|
projected++;
|
|
51618
51759
|
}
|
|
51619
51760
|
reconcileNamespaced(dir, keep);
|
|
@@ -51622,15 +51763,15 @@ function emitAndProjectSkills(root, skills) {
|
|
|
51622
51763
|
return { slugs, emitted, projected };
|
|
51623
51764
|
}
|
|
51624
51765
|
function emitInputsFromManifest(erretaDir, manifestPath) {
|
|
51625
|
-
if (!
|
|
51766
|
+
if (!existsSync16(manifestPath)) return [];
|
|
51626
51767
|
try {
|
|
51627
|
-
const parsed = JSON.parse(
|
|
51768
|
+
const parsed = JSON.parse(readFileSync15(manifestPath, "utf8"));
|
|
51628
51769
|
return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
|
|
51629
51770
|
id: s.id,
|
|
51630
51771
|
title: s.title ?? s.id,
|
|
51631
51772
|
layer: s.layer ?? "technique",
|
|
51632
51773
|
confidence: s.confidence ?? 0,
|
|
51633
|
-
bodyPath:
|
|
51774
|
+
bodyPath: join20(erretaDir, s.file)
|
|
51634
51775
|
}));
|
|
51635
51776
|
} catch {
|
|
51636
51777
|
return [];
|
|
@@ -51644,17 +51785,17 @@ var GITIGNORE_LINES = [
|
|
|
51644
51785
|
".cursor/skills/errata-*/"
|
|
51645
51786
|
];
|
|
51646
51787
|
function ensureSkillGitignore(root) {
|
|
51647
|
-
const path2 =
|
|
51788
|
+
const path2 = join20(root, ".gitignore");
|
|
51648
51789
|
let current = "";
|
|
51649
51790
|
try {
|
|
51650
|
-
current =
|
|
51791
|
+
current = existsSync16(path2) ? readFileSync15(path2, "utf8") : "";
|
|
51651
51792
|
} catch {
|
|
51652
51793
|
return;
|
|
51653
51794
|
}
|
|
51654
51795
|
if (current.includes(GITIGNORE_MARK)) return;
|
|
51655
51796
|
const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
|
|
51656
51797
|
try {
|
|
51657
|
-
|
|
51798
|
+
writeFileSync13(path2, `${current}${prefix}
|
|
51658
51799
|
${GITIGNORE_LINES.join("\n")}
|
|
51659
51800
|
`, "utf8");
|
|
51660
51801
|
} catch {
|
|
@@ -51818,20 +51959,20 @@ var CausalBuffer = class {
|
|
|
51818
51959
|
// src/profile.ts
|
|
51819
51960
|
init_src2();
|
|
51820
51961
|
init_paths();
|
|
51821
|
-
import { existsSync as
|
|
51962
|
+
import { existsSync as existsSync18, readFileSync as readFileSync17, writeFileSync as writeFileSync14 } from "node:fs";
|
|
51822
51963
|
import { createHash as createHash12 } from "node:crypto";
|
|
51823
|
-
import { join as
|
|
51964
|
+
import { join as join22 } from "node:path";
|
|
51824
51965
|
|
|
51825
51966
|
// src/git-remote.ts
|
|
51826
51967
|
init_src();
|
|
51827
|
-
import { existsSync as
|
|
51828
|
-
import { isAbsolute as isAbsolute3, join as
|
|
51968
|
+
import { existsSync as existsSync17, readFileSync as readFileSync16, statSync as statSync4 } from "node:fs";
|
|
51969
|
+
import { isAbsolute as isAbsolute3, join as join21, resolve as resolve5 } from "node:path";
|
|
51829
51970
|
function resolveGitDir(root) {
|
|
51830
|
-
const dotGit =
|
|
51971
|
+
const dotGit = join21(root, ".git");
|
|
51831
51972
|
try {
|
|
51832
51973
|
const st = statSync4(dotGit);
|
|
51833
51974
|
if (st.isDirectory()) return dotGit;
|
|
51834
|
-
const m = /^gitdir:\s*(.+?)\s*$/m.exec(
|
|
51975
|
+
const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync16(dotGit, "utf8"));
|
|
51835
51976
|
if (!m) return null;
|
|
51836
51977
|
const dir = m[1];
|
|
51837
51978
|
return isAbsolute3(dir) ? dir : resolve5(root, dir);
|
|
@@ -51840,22 +51981,22 @@ function resolveGitDir(root) {
|
|
|
51840
51981
|
}
|
|
51841
51982
|
}
|
|
51842
51983
|
function gitConfigPath(gitDir) {
|
|
51843
|
-
const commondirFile =
|
|
51844
|
-
if (
|
|
51845
|
-
const common =
|
|
51984
|
+
const commondirFile = join21(gitDir, "commondir");
|
|
51985
|
+
if (existsSync17(commondirFile)) {
|
|
51986
|
+
const common = readFileSync16(commondirFile, "utf8").trim();
|
|
51846
51987
|
const commonDir = isAbsolute3(common) ? common : resolve5(gitDir, common);
|
|
51847
|
-
return
|
|
51988
|
+
return join21(commonDir, "config");
|
|
51848
51989
|
}
|
|
51849
|
-
return
|
|
51990
|
+
return join21(gitDir, "config");
|
|
51850
51991
|
}
|
|
51851
51992
|
function readRemotes(root) {
|
|
51852
51993
|
const gitDir = resolveGitDir(root);
|
|
51853
51994
|
if (!gitDir) return [];
|
|
51854
51995
|
const cfgPath = gitConfigPath(gitDir);
|
|
51855
|
-
if (!
|
|
51996
|
+
if (!existsSync17(cfgPath)) return [];
|
|
51856
51997
|
let txt;
|
|
51857
51998
|
try {
|
|
51858
|
-
txt =
|
|
51999
|
+
txt = readFileSync16(cfgPath, "utf8");
|
|
51859
52000
|
} catch {
|
|
51860
52001
|
return [];
|
|
51861
52002
|
}
|
|
@@ -51887,13 +52028,13 @@ function refreshRepoLocator(root, profile) {
|
|
|
51887
52028
|
}
|
|
51888
52029
|
function loadProfile(root) {
|
|
51889
52030
|
const p = workspacePaths(root);
|
|
51890
|
-
if (!
|
|
51891
|
-
return JSON.parse(
|
|
52031
|
+
if (!existsSync18(p.workspaceJson)) return null;
|
|
52032
|
+
return JSON.parse(readFileSync17(p.workspaceJson, "utf8"));
|
|
51892
52033
|
}
|
|
51893
52034
|
function saveProfile(root, profile) {
|
|
51894
52035
|
const p = workspacePaths(root);
|
|
51895
52036
|
ensureDir(p.configDir);
|
|
51896
|
-
|
|
52037
|
+
writeFileSync14(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
|
|
51897
52038
|
}
|
|
51898
52039
|
function autodetectProfile(root) {
|
|
51899
52040
|
const id = workspaceId(root);
|
|
@@ -51901,10 +52042,10 @@ function autodetectProfile(root) {
|
|
|
51901
52042
|
const p = emptyProfile(id, name2);
|
|
51902
52043
|
const locator = detectRepoLocator(root);
|
|
51903
52044
|
if (locator) p.repoLocator = locator;
|
|
51904
|
-
const pkgPath =
|
|
51905
|
-
if (
|
|
52045
|
+
const pkgPath = join22(root, "package.json");
|
|
52046
|
+
if (existsSync18(pkgPath)) {
|
|
51906
52047
|
try {
|
|
51907
|
-
const pkg = JSON.parse(
|
|
52048
|
+
const pkg = JSON.parse(readFileSync17(pkgPath, "utf8"));
|
|
51908
52049
|
p.languages.push("typescript", "javascript");
|
|
51909
52050
|
const nodeVer = pkg.engines?.node ?? "node";
|
|
51910
52051
|
p.stack.push(`node@${nodeVer}`);
|
|
@@ -51925,10 +52066,10 @@ function autodetectProfile(root) {
|
|
|
51925
52066
|
} catch {
|
|
51926
52067
|
}
|
|
51927
52068
|
}
|
|
51928
|
-
const pyproject =
|
|
51929
|
-
if (
|
|
52069
|
+
const pyproject = join22(root, "pyproject.toml");
|
|
52070
|
+
if (existsSync18(pyproject)) {
|
|
51930
52071
|
try {
|
|
51931
|
-
const txt =
|
|
52072
|
+
const txt = readFileSync17(pyproject, "utf8");
|
|
51932
52073
|
const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
|
|
51933
52074
|
p.languages.push("python");
|
|
51934
52075
|
p.stack.push(`python@${py ?? "3"}`);
|
|
@@ -51939,16 +52080,16 @@ function autodetectProfile(root) {
|
|
|
51939
52080
|
} catch {
|
|
51940
52081
|
}
|
|
51941
52082
|
}
|
|
51942
|
-
const reqs =
|
|
51943
|
-
if (
|
|
52083
|
+
const reqs = join22(root, "requirements.txt");
|
|
52084
|
+
if (existsSync18(reqs)) {
|
|
51944
52085
|
if (!p.languages.includes("python")) p.languages.push("python");
|
|
51945
52086
|
if (!p.stack.includes("python@3")) p.stack.push("python@3");
|
|
51946
52087
|
}
|
|
51947
|
-
if (
|
|
52088
|
+
if (existsSync18(join22(root, "go.mod"))) {
|
|
51948
52089
|
p.languages.push("go");
|
|
51949
52090
|
p.stack.push("go");
|
|
51950
52091
|
}
|
|
51951
|
-
if (
|
|
52092
|
+
if (existsSync18(join22(root, "Cargo.toml"))) {
|
|
51952
52093
|
p.languages.push("rust");
|
|
51953
52094
|
p.stack.push("rust");
|
|
51954
52095
|
}
|
|
@@ -52106,7 +52247,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
52106
52247
|
}
|
|
52107
52248
|
|
|
52108
52249
|
// src/engine.ts
|
|
52109
|
-
var DAEMON_VERSION = true ? "2.0.2-dev.
|
|
52250
|
+
var DAEMON_VERSION = true ? "2.0.2-dev.201" : "2.0.0-alpha.0";
|
|
52110
52251
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
52111
52252
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
52112
52253
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -52116,7 +52257,7 @@ var TURN_REPLAY_LOOKBACK_MS = 7 * 24 * 60 * 6e4;
|
|
|
52116
52257
|
function appendIdentityAudit(path2, record2, line) {
|
|
52117
52258
|
if (!record2.accepted && record2.score <= 0) return;
|
|
52118
52259
|
try {
|
|
52119
|
-
if (
|
|
52260
|
+
if (existsSync19(path2) && statSync5(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
52120
52261
|
renameSync2(path2, `${path2}.1`);
|
|
52121
52262
|
}
|
|
52122
52263
|
appendFileSync2(path2, line);
|
|
@@ -52126,14 +52267,14 @@ function appendIdentityAudit(path2, record2, line) {
|
|
|
52126
52267
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
52127
52268
|
function loadTurnCursors(path2) {
|
|
52128
52269
|
try {
|
|
52129
|
-
return new Map(Object.entries(JSON.parse(
|
|
52270
|
+
return new Map(Object.entries(JSON.parse(readFileSync18(path2, "utf8"))));
|
|
52130
52271
|
} catch {
|
|
52131
52272
|
return /* @__PURE__ */ new Map();
|
|
52132
52273
|
}
|
|
52133
52274
|
}
|
|
52134
52275
|
function saveTurnCursors(path2, cursors) {
|
|
52135
52276
|
try {
|
|
52136
|
-
|
|
52277
|
+
writeFileSync15(path2, JSON.stringify(Object.fromEntries(cursors)), "utf8");
|
|
52137
52278
|
} catch {
|
|
52138
52279
|
}
|
|
52139
52280
|
}
|
|
@@ -52155,7 +52296,7 @@ function gitSourceWatchTargets(root) {
|
|
|
52155
52296
|
["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
|
|
52156
52297
|
{ encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
52157
52298
|
);
|
|
52158
|
-
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(
|
|
52299
|
+
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join23(root, d) + sep4));
|
|
52159
52300
|
} catch {
|
|
52160
52301
|
}
|
|
52161
52302
|
const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
|
|
@@ -52167,19 +52308,19 @@ function gitSourceWatchTargets(root) {
|
|
|
52167
52308
|
if (!f.startsWith(prefix)) continue;
|
|
52168
52309
|
const rest2 = f.slice(prefix.length);
|
|
52169
52310
|
if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
|
|
52170
|
-
else targets.add(
|
|
52311
|
+
else targets.add(join23(root, f));
|
|
52171
52312
|
}
|
|
52172
52313
|
for (const c of children) {
|
|
52173
|
-
if (IGNORED_PATH.test(
|
|
52314
|
+
if (IGNORED_PATH.test(join23(root, c) + sep4)) continue;
|
|
52174
52315
|
if (hasIgnoredChild(c)) addUnder(c);
|
|
52175
|
-
else targets.add(
|
|
52316
|
+
else targets.add(join23(root, c));
|
|
52176
52317
|
}
|
|
52177
52318
|
};
|
|
52178
52319
|
addUnder("");
|
|
52179
52320
|
if (targets.size > 0) return [...targets];
|
|
52180
52321
|
} catch {
|
|
52181
52322
|
}
|
|
52182
|
-
return
|
|
52323
|
+
return readdirSync9(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join23(root, String(e.name)) + sep4)).map((e) => join23(root, String(e.name)));
|
|
52183
52324
|
}
|
|
52184
52325
|
function createWorkspaceEngine(opts) {
|
|
52185
52326
|
const paths = workspacePaths(opts.workspaceRoot);
|
|
@@ -52333,7 +52474,7 @@ function createWorkspaceEngine(opts) {
|
|
|
52333
52474
|
const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
|
|
52334
52475
|
let episodeId2;
|
|
52335
52476
|
if (srcPaths.length > 0) {
|
|
52336
|
-
const abs = srcPaths.map((p) =>
|
|
52477
|
+
const abs = srcPaths.map((p) => join23(opts.workspaceRoot, p));
|
|
52337
52478
|
try {
|
|
52338
52479
|
const r = await runReindexPass(
|
|
52339
52480
|
`git-reindex:${profile.name} (${abs.length} files)`,
|
|
@@ -52369,8 +52510,8 @@ function createWorkspaceEngine(opts) {
|
|
|
52369
52510
|
`[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
|
|
52370
52511
|
);
|
|
52371
52512
|
};
|
|
52372
|
-
const gitDir =
|
|
52373
|
-
if (
|
|
52513
|
+
const gitDir = join23(opts.workspaceRoot, ".git");
|
|
52514
|
+
if (existsSync19(gitDir)) {
|
|
52374
52515
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
52375
52516
|
void handleGitEvent(ev).catch((err2) => {
|
|
52376
52517
|
console.warn("[errata] git event handler failed:", err2);
|
|
@@ -52440,10 +52581,10 @@ function createWorkspaceEngine(opts) {
|
|
|
52440
52581
|
});
|
|
52441
52582
|
doneRender?.();
|
|
52442
52583
|
writeContextFile(opts.workspaceRoot, body2);
|
|
52443
|
-
const target =
|
|
52584
|
+
const target = join23(opts.workspaceRoot, "AGENTS.md");
|
|
52444
52585
|
writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
|
|
52445
52586
|
if (elicit) {
|
|
52446
|
-
writePrimingHandles(
|
|
52587
|
+
writePrimingHandles(join23(paths.configDir, "priming-handles.json"), [
|
|
52447
52588
|
...snapshot.recentProblems.map((r) => r.node),
|
|
52448
52589
|
// Resolved-band handles: the ✓ problem AND its Solution are citable
|
|
52449
52590
|
// (a fix tag on an already-resolved problem no-ops idempotently; the
|
|
@@ -52534,6 +52675,21 @@ function createWorkspaceEngine(opts) {
|
|
|
52534
52675
|
} catch (err2) {
|
|
52535
52676
|
console.warn("[errata] anchor backfill failed:", err2);
|
|
52536
52677
|
}
|
|
52678
|
+
try {
|
|
52679
|
+
const c = backfillConstraintKind(store, {
|
|
52680
|
+
root: opts.workspaceRoot,
|
|
52681
|
+
configDir: paths.configDir,
|
|
52682
|
+
now: Date.now()
|
|
52683
|
+
});
|
|
52684
|
+
if (!c.skipped && (c.stamped > 0 || c.detached > 0)) {
|
|
52685
|
+
console.log(
|
|
52686
|
+
`[errata] constraint backfill: ${c.stamped} design tension(s) marked` + (c.detached > 0 ? `; ${c.detached} fabricated resolution(s) detached, ${c.reopened} reopened` : "") + (c.witnessed > 0 ? `; ${c.witnessed} cited discharge(s) kept` : "") + (c.cloudTwins.length > 0 ? ` \u2014 ${c.cloudTwins.length} already contributed; run scripts/repair-cloud-constraints.ts to repair the cloud twins` : "")
|
|
52687
|
+
);
|
|
52688
|
+
refreshContextNow();
|
|
52689
|
+
}
|
|
52690
|
+
} catch (err2) {
|
|
52691
|
+
console.warn("[errata] constraint backfill failed:", err2);
|
|
52692
|
+
}
|
|
52537
52693
|
const report = runNightlyPipeline(store);
|
|
52538
52694
|
try {
|
|
52539
52695
|
const m = mergeDuplicateProblems(store, { ts: Date.now() });
|
|
@@ -52633,7 +52789,7 @@ function createWorkspaceEngine(opts) {
|
|
|
52633
52789
|
resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
|
|
52634
52790
|
});
|
|
52635
52791
|
};
|
|
52636
|
-
const turnCursorPath =
|
|
52792
|
+
const turnCursorPath = join23(paths.configDir, "turn-cursors.json");
|
|
52637
52793
|
const lastTurnUuid = loadTurnCursors(turnCursorPath);
|
|
52638
52794
|
const sessionLastProblem = /* @__PURE__ */ new Map();
|
|
52639
52795
|
const sessionThreads = /* @__PURE__ */ new Map();
|
|
@@ -52656,7 +52812,7 @@ function createWorkspaceEngine(opts) {
|
|
|
52656
52812
|
const t = Date.now();
|
|
52657
52813
|
let processedTurns = 0;
|
|
52658
52814
|
const elicit = isEdgeElicitationEnabled();
|
|
52659
|
-
const handleMap = elicit ? readPrimingHandles(
|
|
52815
|
+
const handleMap = elicit ? readPrimingHandles(join23(paths.configDir, "priming-handles.json")) : {};
|
|
52660
52816
|
const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
|
|
52661
52817
|
const toRel = (abs) => {
|
|
52662
52818
|
const p = abs.replace(/\\/g, "/");
|
|
@@ -53191,7 +53347,7 @@ function createWorkspaceEngine(opts) {
|
|
|
53191
53347
|
try {
|
|
53192
53348
|
const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
|
|
53193
53349
|
emitAndProjectSkills(opts.workspaceRoot, inputs);
|
|
53194
|
-
writePrimingHandles(
|
|
53350
|
+
writePrimingHandles(join23(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
|
|
53195
53351
|
} catch (err2) {
|
|
53196
53352
|
console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
|
|
53197
53353
|
}
|
|
@@ -53378,7 +53534,7 @@ function createWorkspaceEngine(opts) {
|
|
|
53378
53534
|
console.log(
|
|
53379
53535
|
"[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
|
|
53380
53536
|
);
|
|
53381
|
-
const pending =
|
|
53537
|
+
const pending = existsSync19(paths.outbox) ? readdirSync9(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
|
|
53382
53538
|
return { uploaded: 0, failed: 0, remaining: pending };
|
|
53383
53539
|
}
|
|
53384
53540
|
try {
|
|
@@ -53465,7 +53621,7 @@ async function startDaemon(opts) {
|
|
|
53465
53621
|
reviewUrl: () => webUiUrl + "/review"
|
|
53466
53622
|
});
|
|
53467
53623
|
const writeLockFile = (url2) => {
|
|
53468
|
-
|
|
53624
|
+
writeFileSync16(
|
|
53469
53625
|
engine.paths.daemonLock,
|
|
53470
53626
|
JSON.stringify({ pid: process.pid, webUiUrl: url2, startedAt: Date.now() }),
|
|
53471
53627
|
"utf8"
|
|
@@ -53508,7 +53664,7 @@ async function startDaemon(opts) {
|
|
|
53508
53664
|
);
|
|
53509
53665
|
await engine.stop();
|
|
53510
53666
|
try {
|
|
53511
|
-
if (
|
|
53667
|
+
if (existsSync20(engine.paths.daemonLock)) {
|
|
53512
53668
|
}
|
|
53513
53669
|
} catch {
|
|
53514
53670
|
}
|
|
@@ -53525,16 +53681,16 @@ async function listenServer(fetchFn, port) {
|
|
|
53525
53681
|
|
|
53526
53682
|
// src/registry.ts
|
|
53527
53683
|
init_paths();
|
|
53528
|
-
import { existsSync as
|
|
53529
|
-
import { join as
|
|
53684
|
+
import { existsSync as existsSync21, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "node:fs";
|
|
53685
|
+
import { join as join24 } from "node:path";
|
|
53530
53686
|
function registryPath() {
|
|
53531
|
-
return process.env["ERRATA_REGISTRY_PATH"] ??
|
|
53687
|
+
return process.env["ERRATA_REGISTRY_PATH"] ?? join24(globalDir(), "workspaces.json");
|
|
53532
53688
|
}
|
|
53533
53689
|
function read() {
|
|
53534
53690
|
const p = registryPath();
|
|
53535
|
-
if (!
|
|
53691
|
+
if (!existsSync21(p)) return { version: 1, workspaces: {} };
|
|
53536
53692
|
try {
|
|
53537
|
-
const parsed = JSON.parse(
|
|
53693
|
+
const parsed = JSON.parse(readFileSync19(p, "utf8"));
|
|
53538
53694
|
return { version: 1, workspaces: parsed.workspaces ?? {} };
|
|
53539
53695
|
} catch {
|
|
53540
53696
|
return { version: 1, workspaces: {} };
|
|
@@ -53542,7 +53698,7 @@ function read() {
|
|
|
53542
53698
|
}
|
|
53543
53699
|
function write(reg) {
|
|
53544
53700
|
ensureDir(globalDir());
|
|
53545
|
-
|
|
53701
|
+
writeFileSync17(registryPath(), JSON.stringify(reg, null, 2), "utf8");
|
|
53546
53702
|
}
|
|
53547
53703
|
function registerWorkspace(profile, root, now = Date.now()) {
|
|
53548
53704
|
const reg = read();
|
|
@@ -53559,7 +53715,7 @@ function pruneMissingWorkspaces() {
|
|
|
53559
53715
|
const reg = read();
|
|
53560
53716
|
const removed = [];
|
|
53561
53717
|
for (const [id, entry] of Object.entries(reg.workspaces)) {
|
|
53562
|
-
if (!
|
|
53718
|
+
if (!existsSync21(entry.path)) {
|
|
53563
53719
|
removed.push(entry);
|
|
53564
53720
|
delete reg.workspaces[id];
|
|
53565
53721
|
}
|
|
@@ -53568,13 +53724,13 @@ function pruneMissingWorkspaces() {
|
|
|
53568
53724
|
return removed;
|
|
53569
53725
|
}
|
|
53570
53726
|
function workspaceStatus(entry) {
|
|
53571
|
-
const missing = !
|
|
53727
|
+
const missing = !existsSync21(entry.path);
|
|
53572
53728
|
const lockPath = workspacePaths(entry.path).daemonLock;
|
|
53573
53729
|
let running = false;
|
|
53574
53730
|
let webUiUrl = null;
|
|
53575
|
-
if (
|
|
53731
|
+
if (existsSync21(lockPath)) {
|
|
53576
53732
|
try {
|
|
53577
|
-
const lock = JSON.parse(
|
|
53733
|
+
const lock = JSON.parse(readFileSync19(lockPath, "utf8"));
|
|
53578
53734
|
if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
|
|
53579
53735
|
running = true;
|
|
53580
53736
|
webUiUrl = lock.webUiUrl;
|
|
@@ -53602,7 +53758,7 @@ function pidAlive(pid) {
|
|
|
53602
53758
|
// src/multi.ts
|
|
53603
53759
|
init_dist();
|
|
53604
53760
|
init_src4();
|
|
53605
|
-
import { readFileSync as
|
|
53761
|
+
import { readFileSync as readFileSync22, unlinkSync as unlinkSync3, writeFileSync as writeFileSync18 } from "node:fs";
|
|
53606
53762
|
|
|
53607
53763
|
// src/principle-sync.ts
|
|
53608
53764
|
init_src4();
|
|
@@ -53630,8 +53786,8 @@ init_reconcile();
|
|
|
53630
53786
|
|
|
53631
53787
|
// src/lockfile-auto.ts
|
|
53632
53788
|
init_src();
|
|
53633
|
-
import { existsSync as
|
|
53634
|
-
import { join as
|
|
53789
|
+
import { existsSync as existsSync22, readFileSync as readFileSync20 } from "node:fs";
|
|
53790
|
+
import { join as join25 } from "node:path";
|
|
53635
53791
|
|
|
53636
53792
|
// src/package-index.ts
|
|
53637
53793
|
init_src();
|
|
@@ -53777,11 +53933,11 @@ function runLockfilePass(opts) {
|
|
|
53777
53933
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
53778
53934
|
];
|
|
53779
53935
|
for (const c of candidates) {
|
|
53780
|
-
const p =
|
|
53781
|
-
if (!
|
|
53936
|
+
const p = join25(opts.root, c.file);
|
|
53937
|
+
if (!existsSync22(p)) continue;
|
|
53782
53938
|
let sbom;
|
|
53783
53939
|
try {
|
|
53784
|
-
sbom = c.parse(
|
|
53940
|
+
sbom = c.parse(readFileSync20(p, "utf8"));
|
|
53785
53941
|
} catch {
|
|
53786
53942
|
continue;
|
|
53787
53943
|
}
|
|
@@ -54224,7 +54380,7 @@ var ConsolidateWorker = class {
|
|
|
54224
54380
|
init_paths();
|
|
54225
54381
|
|
|
54226
54382
|
// src/lock.ts
|
|
54227
|
-
import { existsSync as
|
|
54383
|
+
import { existsSync as existsSync23, readFileSync as readFileSync21 } from "node:fs";
|
|
54228
54384
|
function isProcessAlive(pid) {
|
|
54229
54385
|
if (!pid || pid <= 0) return false;
|
|
54230
54386
|
try {
|
|
@@ -54235,9 +54391,9 @@ function isProcessAlive(pid) {
|
|
|
54235
54391
|
}
|
|
54236
54392
|
}
|
|
54237
54393
|
function readDaemonLock(lockPath) {
|
|
54238
|
-
if (!
|
|
54394
|
+
if (!existsSync23(lockPath)) return null;
|
|
54239
54395
|
try {
|
|
54240
|
-
const lock = JSON.parse(
|
|
54396
|
+
const lock = JSON.parse(readFileSync21(lockPath, "utf8"));
|
|
54241
54397
|
return typeof lock.pid === "number" ? lock : null;
|
|
54242
54398
|
} catch {
|
|
54243
54399
|
return null;
|
|
@@ -54479,12 +54635,12 @@ async function reanchorProject(opts) {
|
|
|
54479
54635
|
}
|
|
54480
54636
|
|
|
54481
54637
|
// src/adopt.ts
|
|
54482
|
-
import { existsSync as
|
|
54483
|
-
import { dirname as dirname9, join as
|
|
54638
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
54639
|
+
import { dirname as dirname9, join as join26 } from "node:path";
|
|
54484
54640
|
function findGitRoot(absPath) {
|
|
54485
54641
|
let dir = absPath;
|
|
54486
54642
|
for (let depth = 0; depth < 64; depth++) {
|
|
54487
|
-
if (
|
|
54643
|
+
if (existsSync24(join26(dir, ".git"))) return dir;
|
|
54488
54644
|
const parent = dirname9(dir);
|
|
54489
54645
|
if (parent === dir) return null;
|
|
54490
54646
|
dir = parent;
|
|
@@ -54706,7 +54862,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54706
54862
|
void ambientLinkAll();
|
|
54707
54863
|
app.route(`/ws/${rec.id}`, rec.webApp);
|
|
54708
54864
|
try {
|
|
54709
|
-
|
|
54865
|
+
writeFileSync18(
|
|
54710
54866
|
rec.engine.paths.daemonLock,
|
|
54711
54867
|
JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${rec.id}`, startedAt: Date.now() }),
|
|
54712
54868
|
"utf8"
|
|
@@ -54895,7 +55051,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54895
55051
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
54896
55052
|
try {
|
|
54897
55053
|
ensureDir(globalDir());
|
|
54898
|
-
|
|
55054
|
+
writeFileSync18(
|
|
54899
55055
|
lockPath,
|
|
54900
55056
|
JSON.stringify({ pid: process.pid, webUiUrl: baseUrl, startedAt: Date.now() }),
|
|
54901
55057
|
"utf8"
|
|
@@ -54904,7 +55060,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
54904
55060
|
}
|
|
54905
55061
|
for (const r of records) {
|
|
54906
55062
|
try {
|
|
54907
|
-
|
|
55063
|
+
writeFileSync18(
|
|
54908
55064
|
r.engine.paths.daemonLock,
|
|
54909
55065
|
JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${r.id}`, startedAt: Date.now() }),
|
|
54910
55066
|
"utf8"
|
|
@@ -55372,7 +55528,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
55372
55528
|
},
|
|
55373
55529
|
async stop() {
|
|
55374
55530
|
try {
|
|
55375
|
-
const cur =
|
|
55531
|
+
const cur = readFileSync22(lockPath, "utf8");
|
|
55376
55532
|
if (JSON.parse(cur).pid === process.pid) unlinkSync3(lockPath);
|
|
55377
55533
|
} catch {
|
|
55378
55534
|
}
|
|
@@ -56392,21 +56548,21 @@ async function cmdInit() {
|
|
|
56392
56548
|
if (!skipHooks) {
|
|
56393
56549
|
console.log("");
|
|
56394
56550
|
console.log("installing harness hooks...");
|
|
56395
|
-
const { existsSync:
|
|
56396
|
-
const { join:
|
|
56551
|
+
const { existsSync: existsSync26 } = await import("node:fs");
|
|
56552
|
+
const { join: join28 } = await import("node:path");
|
|
56397
56553
|
try {
|
|
56398
56554
|
await installClaudeHooks(port);
|
|
56399
56555
|
} catch (err2) {
|
|
56400
56556
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
56401
56557
|
}
|
|
56402
|
-
if (
|
|
56558
|
+
if (existsSync26(join28(ROOT, ".cursor"))) {
|
|
56403
56559
|
try {
|
|
56404
56560
|
await installCursorMcpConfig();
|
|
56405
56561
|
} catch (err2) {
|
|
56406
56562
|
console.warn(` \u26A0\uFE0F Cursor MCP config failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
56407
56563
|
}
|
|
56408
56564
|
}
|
|
56409
|
-
if (
|
|
56565
|
+
if (existsSync26(join28(ROOT, ".codex"))) {
|
|
56410
56566
|
try {
|
|
56411
56567
|
await installCodexHooks(port);
|
|
56412
56568
|
} catch (err2) {
|
|
@@ -56563,8 +56719,8 @@ async function cmdStatus() {
|
|
|
56563
56719
|
console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
|
|
56564
56720
|
console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
|
|
56565
56721
|
}
|
|
56566
|
-
console.log(` graph db: ${
|
|
56567
|
-
console.log(` event log: ${
|
|
56722
|
+
console.log(` graph db: ${existsSync25(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
56723
|
+
console.log(` event log: ${existsSync25(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
56568
56724
|
const lockPath = globalDaemonLock();
|
|
56569
56725
|
const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
|
|
56570
56726
|
console.log(
|
|
@@ -57194,11 +57350,11 @@ function cmdInstallationProfile(args2) {
|
|
|
57194
57350
|
}
|
|
57195
57351
|
async function cmdReview() {
|
|
57196
57352
|
const paths = workspacePaths(ROOT);
|
|
57197
|
-
if (!
|
|
57353
|
+
if (!existsSync25(paths.reviewQueue)) {
|
|
57198
57354
|
console.log("(review queue empty)");
|
|
57199
57355
|
return;
|
|
57200
57356
|
}
|
|
57201
|
-
const queue = JSON.parse(
|
|
57357
|
+
const queue = JSON.parse(readFileSync23(paths.reviewQueue, "utf8"));
|
|
57202
57358
|
if (queue.length === 0) {
|
|
57203
57359
|
console.log("(review queue empty)");
|
|
57204
57360
|
return;
|
|
@@ -57869,7 +58025,7 @@ async function gatherRepo(store, ws) {
|
|
|
57869
58025
|
};
|
|
57870
58026
|
}
|
|
57871
58027
|
async function gatherReportData(generatedAt) {
|
|
57872
|
-
const { existsSync:
|
|
58028
|
+
const { existsSync: existsSync26 } = await import("node:fs");
|
|
57873
58029
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
|
|
57874
58030
|
const cfg = loadConfig();
|
|
57875
58031
|
const outbound = cfg.consent.sync ? "auto" : "off";
|
|
@@ -57877,7 +58033,7 @@ async function gatherReportData(generatedAt) {
|
|
|
57877
58033
|
for (const ws of listWorkspaces()) {
|
|
57878
58034
|
if (ws.missing) continue;
|
|
57879
58035
|
const dbPath = workspacePaths(ws.path).castalia;
|
|
57880
|
-
if (!
|
|
58036
|
+
if (!existsSync26(dbPath)) continue;
|
|
57881
58037
|
let store = null;
|
|
57882
58038
|
try {
|
|
57883
58039
|
store = openGraphStore2({ path: dbPath });
|
|
@@ -57908,7 +58064,7 @@ async function gatherReportData(generatedAt) {
|
|
|
57908
58064
|
};
|
|
57909
58065
|
}
|
|
57910
58066
|
async function cmdReport(args2) {
|
|
57911
|
-
const { mkdirSync: mkdirSync8, writeFileSync:
|
|
58067
|
+
const { mkdirSync: mkdirSync8, writeFileSync: writeFileSync19 } = await import("node:fs");
|
|
57912
58068
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
57913
58069
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
57914
58070
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -57921,8 +58077,8 @@ async function cmdReport(args2) {
|
|
|
57921
58077
|
const outDir = workspacePaths(ROOT).configDir;
|
|
57922
58078
|
mkdirSync8(outDir, { recursive: true });
|
|
57923
58079
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
57924
|
-
for (const f of files)
|
|
57925
|
-
const indexPath =
|
|
58080
|
+
for (const f of files) writeFileSync19(join27(outDir, f.name), f.html, "utf8");
|
|
58081
|
+
const indexPath = join27(outDir, "report.html");
|
|
57926
58082
|
console.log(`report \u2192 ${indexPath}`);
|
|
57927
58083
|
console.log(
|
|
57928
58084
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -58040,15 +58196,15 @@ function hookRelayCommand(port, path2) {
|
|
|
58040
58196
|
return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 2 -X POST -H \\"Content-Type: application/json\\" --data-binary @- ${url2} 2>NUL || echo {}"` : `curl -s --connect-timeout 1 --max-time 2 -X POST -H 'Content-Type: application/json' --data-binary @- ${url2} 2>/dev/null || echo '{}'`;
|
|
58041
58197
|
}
|
|
58042
58198
|
async function installClaudeHooks(port) {
|
|
58043
|
-
const { mkdirSync: mkdirSync8, existsSync:
|
|
58044
|
-
const { join:
|
|
58045
|
-
const dir =
|
|
58046
|
-
if (!
|
|
58047
|
-
const file2 =
|
|
58199
|
+
const { mkdirSync: mkdirSync8, existsSync: existsSync26, readFileSync: readFileSync24, writeFileSync: writeFileSync19 } = await import("node:fs");
|
|
58200
|
+
const { join: join28 } = await import("node:path");
|
|
58201
|
+
const dir = join28(ROOT, ".claude");
|
|
58202
|
+
if (!existsSync26(dir)) mkdirSync8(dir, { recursive: true });
|
|
58203
|
+
const file2 = join28(dir, "settings.json");
|
|
58048
58204
|
let settings = {};
|
|
58049
|
-
if (
|
|
58205
|
+
if (existsSync26(file2)) {
|
|
58050
58206
|
try {
|
|
58051
|
-
settings = JSON.parse(
|
|
58207
|
+
settings = JSON.parse(readFileSync24(file2, "utf8"));
|
|
58052
58208
|
} catch {
|
|
58053
58209
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
58054
58210
|
process.exit(2);
|
|
@@ -58094,10 +58250,10 @@ async function installClaudeHooks(port) {
|
|
|
58094
58250
|
dropErrata(list);
|
|
58095
58251
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
58096
58252
|
}
|
|
58097
|
-
|
|
58253
|
+
writeFileSync19(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
58098
58254
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
58099
58255
|
await installClaudeMcpConfig();
|
|
58100
|
-
const claudeMd =
|
|
58256
|
+
const claudeMd = join28(ROOT, "CLAUDE.md");
|
|
58101
58257
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
58102
58258
|
if (recall.kind === "collision") {
|
|
58103
58259
|
console.warn(
|
|
@@ -58109,15 +58265,15 @@ async function installClaudeHooks(port) {
|
|
|
58109
58265
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
58110
58266
|
}
|
|
58111
58267
|
async function installClaudeMcpConfig() {
|
|
58112
|
-
const { mkdirSync: mkdirSync8, existsSync:
|
|
58113
|
-
const { join:
|
|
58114
|
-
const file2 =
|
|
58268
|
+
const { mkdirSync: mkdirSync8, existsSync: existsSync26, readFileSync: readFileSync24, writeFileSync: writeFileSync19 } = await import("node:fs");
|
|
58269
|
+
const { join: join28, dirname: dirname10 } = await import("node:path");
|
|
58270
|
+
const file2 = join28(ROOT, ".mcp.json");
|
|
58115
58271
|
const dir = dirname10(file2);
|
|
58116
|
-
if (!
|
|
58272
|
+
if (!existsSync26(dir)) mkdirSync8(dir, { recursive: true });
|
|
58117
58273
|
let cfg = {};
|
|
58118
|
-
if (
|
|
58274
|
+
if (existsSync26(file2)) {
|
|
58119
58275
|
try {
|
|
58120
|
-
cfg = JSON.parse(
|
|
58276
|
+
cfg = JSON.parse(readFileSync24(file2, "utf8"));
|
|
58121
58277
|
} catch {
|
|
58122
58278
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
58123
58279
|
process.exit(2);
|
|
@@ -58125,21 +58281,21 @@ async function installClaudeMcpConfig() {
|
|
|
58125
58281
|
}
|
|
58126
58282
|
cfg.mcpServers ??= {};
|
|
58127
58283
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
58128
|
-
|
|
58284
|
+
writeFileSync19(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
58129
58285
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
58130
58286
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
58131
58287
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
58132
58288
|
}
|
|
58133
58289
|
async function installCursorMcpConfig() {
|
|
58134
|
-
const { mkdirSync: mkdirSync8, existsSync:
|
|
58135
|
-
const { join:
|
|
58136
|
-
const dir =
|
|
58137
|
-
if (!
|
|
58138
|
-
const file2 =
|
|
58290
|
+
const { mkdirSync: mkdirSync8, existsSync: existsSync26, readFileSync: readFileSync24, writeFileSync: writeFileSync19 } = await import("node:fs");
|
|
58291
|
+
const { join: join28 } = await import("node:path");
|
|
58292
|
+
const dir = join28(ROOT, ".cursor");
|
|
58293
|
+
if (!existsSync26(dir)) mkdirSync8(dir, { recursive: true });
|
|
58294
|
+
const file2 = join28(dir, "mcp.json");
|
|
58139
58295
|
let cfg = {};
|
|
58140
|
-
if (
|
|
58296
|
+
if (existsSync26(file2)) {
|
|
58141
58297
|
try {
|
|
58142
|
-
cfg = JSON.parse(
|
|
58298
|
+
cfg = JSON.parse(readFileSync24(file2, "utf8"));
|
|
58143
58299
|
} catch {
|
|
58144
58300
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
58145
58301
|
process.exit(2);
|
|
@@ -58147,7 +58303,7 @@ async function installCursorMcpConfig() {
|
|
|
58147
58303
|
}
|
|
58148
58304
|
cfg.mcpServers ??= {};
|
|
58149
58305
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
58150
|
-
|
|
58306
|
+
writeFileSync19(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
58151
58307
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
58152
58308
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
58153
58309
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -58155,16 +58311,16 @@ async function installCursorMcpConfig() {
|
|
|
58155
58311
|
console.log(` \u26A0\uFE0F reload Cursor (Cmd/Ctrl-Shift-P \u2192 "Reload Window") to pick it up.`);
|
|
58156
58312
|
}
|
|
58157
58313
|
async function installCodexHooks(port) {
|
|
58158
|
-
const { mkdirSync: mkdirSync8, existsSync:
|
|
58159
|
-
const { join:
|
|
58160
|
-
const dir =
|
|
58161
|
-
if (!
|
|
58162
|
-
const file2 =
|
|
58314
|
+
const { mkdirSync: mkdirSync8, existsSync: existsSync26, readFileSync: readFileSync24, writeFileSync: writeFileSync19 } = await import("node:fs");
|
|
58315
|
+
const { join: join28 } = await import("node:path");
|
|
58316
|
+
const dir = join28(ROOT, ".codex");
|
|
58317
|
+
if (!existsSync26(dir)) mkdirSync8(dir, { recursive: true });
|
|
58318
|
+
const file2 = join28(dir, "config.toml");
|
|
58163
58319
|
const BEGIN = `# >>> errata hooks (errata-managed)`;
|
|
58164
58320
|
const END = `# <<< errata hooks`;
|
|
58165
58321
|
let existing = "";
|
|
58166
|
-
if (
|
|
58167
|
-
existing =
|
|
58322
|
+
if (existsSync26(file2)) {
|
|
58323
|
+
existing = readFileSync24(file2, "utf8");
|
|
58168
58324
|
const beginIdx = existing.indexOf(BEGIN);
|
|
58169
58325
|
const endIdx = existing.indexOf(END);
|
|
58170
58326
|
if (beginIdx >= 0 && endIdx > beginIdx) {
|
|
@@ -58193,7 +58349,7 @@ ${END}
|
|
|
58193
58349
|
const final = existing.length > 0 && !existing.endsWith("\n") ? `${existing}
|
|
58194
58350
|
|
|
58195
58351
|
${block}` : existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
|
|
58196
|
-
|
|
58352
|
+
writeFileSync19(file2, final, "utf8");
|
|
58197
58353
|
console.log(`installed Codex hooks \u2192 ${file2}`);
|
|
58198
58354
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
58199
58355
|
console.log("");
|
|
@@ -58483,7 +58639,7 @@ async function cmdDash(args2) {
|
|
|
58483
58639
|
await yieldToLoop2();
|
|
58484
58640
|
try {
|
|
58485
58641
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile);
|
|
58486
|
-
const res = bleedRules(
|
|
58642
|
+
const res = bleedRules(join27(r.root, ".claude", "rules"), items);
|
|
58487
58643
|
if (res.written || res.pruned) {
|
|
58488
58644
|
console.log(
|
|
58489
58645
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|