@inerrata-corporation/errata 2.0.2-dev.282 → 2.0.2-dev.295
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 +246 -158
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -21283,13 +21283,10 @@ function renderSnapshot(s) {
|
|
|
21283
21283
|
const lines = [];
|
|
21284
21284
|
lines.push("## Errata context");
|
|
21285
21285
|
lines.push("");
|
|
21286
|
-
lines.push("### \u270D\uFE0F CAPTURE PROTOCOL \u2014
|
|
21286
|
+
lines.push("### \u270D\uFE0F CAPTURE PROTOCOL \u2014 tags are the record");
|
|
21287
21287
|
lines.push(
|
|
21288
|
-
"errata
|
|
21288
|
+
"errata records ONLY inline tags: `[!one line]` for every problem you state, `(fix:[id])` when your edit fixed a shown problem. Untagged prose is silently lost \u2014 tag as you write (no fences), we filter downstream."
|
|
21289
21289
|
);
|
|
21290
|
-
lines.push("- `[!one line]` \u2014 EVERY problem you notice or report (a bug you read past, an audit/review finding, anything you call out)");
|
|
21291
|
-
lines.push("- `(fix:[id])` \u2014 your edit fixed a problem errata showed you (ids appear in the priors below / in file priors)");
|
|
21292
|
-
lines.push("Tag every one you state \u2014 we filter downstream, so don't self-censor or batch. This is the witness only you can give; untagged, it's lost.");
|
|
21293
21290
|
lines.push("");
|
|
21294
21291
|
lines.push(SEARCH_IMPERATIVE_HEADER);
|
|
21295
21292
|
lines.push(SEARCH_IMPERATIVE_BODY);
|
|
@@ -21474,15 +21471,24 @@ function dropLowestUnit(s) {
|
|
|
21474
21471
|
case "skills":
|
|
21475
21472
|
if (s.skills.length) return s.skills.pop(), true;
|
|
21476
21473
|
break;
|
|
21474
|
+
case "motifsOverFloor":
|
|
21475
|
+
if (s.motifs.length > MOTIF_FLOOR) return s.motifs.pop(), true;
|
|
21476
|
+
break;
|
|
21477
21477
|
case "motifs":
|
|
21478
21478
|
if (s.motifs.length) return s.motifs.pop(), true;
|
|
21479
21479
|
break;
|
|
21480
21480
|
case "workingFile":
|
|
21481
21481
|
if (s.workingFile) return delete s.workingFile, true;
|
|
21482
21482
|
break;
|
|
21483
|
+
case "remoteOverFloor":
|
|
21484
|
+
if (s.remote && s.remote.length > REMOTE_FLOOR) return s.remote.pop(), true;
|
|
21485
|
+
break;
|
|
21483
21486
|
case "remote":
|
|
21484
21487
|
if (s.remote && s.remote.length) return s.remote.pop(), true;
|
|
21485
21488
|
break;
|
|
21489
|
+
case "recentProblemsOverFloor":
|
|
21490
|
+
if (s.recentProblems.length > PROBLEM_FLOOR) return s.recentProblems.pop(), true;
|
|
21491
|
+
break;
|
|
21486
21492
|
case "recentResolved":
|
|
21487
21493
|
if (s.recentResolved.length) return s.recentResolved.pop(), true;
|
|
21488
21494
|
break;
|
|
@@ -21541,7 +21547,7 @@ _${dropped} lower-priority item${dropped === 1 ? "" : "s"} omitted to fit the pa
|
|
|
21541
21547
|
}
|
|
21542
21548
|
return { body: body2, snapshot, dropped };
|
|
21543
21549
|
}
|
|
21544
|
-
var RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, EVICTION_ORDER, DEFAULT_AGENT_CONTEXT_BUDGET;
|
|
21550
|
+
var RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
|
|
21545
21551
|
var init_render = __esm({
|
|
21546
21552
|
"../../packages/context-writer/src/render.ts"() {
|
|
21547
21553
|
"use strict";
|
|
@@ -21556,9 +21562,19 @@ ${RECALL_FIRST_BODY}`;
|
|
|
21556
21562
|
SEARCH_IMPERATIVE_BODY = "Everything below is a budgeted, top-of-head slice of a much larger graph. Any prior id below is a live burst seed: `errata.burst` it (or read `.errata/g/burst/<id>`) to pull its wider neighborhood \u2014 causes, fixes, siblings. When a prior is adjacent-but-not-quite, or none fit, that gap is exactly when to search deeper before solving cold: a stuck search is itself a signal that routes help to you.";
|
|
21557
21563
|
EVICTION_ORDER = [
|
|
21558
21564
|
"skills",
|
|
21559
|
-
|
|
21565
|
+
// Collective floors (EE-evidence-live): motifs/remote trim to a FLOOR here and
|
|
21566
|
+
// fully drain only near the very end. The unfloored order zeroed them on every
|
|
21567
|
+
// render (~44 units dropped per block, live 8-01), which starved §5.4 at the
|
|
21568
|
+
// source: every witness channel (corroborate/refute) fires only on a prior the
|
|
21569
|
+
// agent was SHOWN, the self-gate correctly refuses same-session cites, so a
|
|
21570
|
+
// surface showing ONLY the session's own problems produces zero evidence by
|
|
21571
|
+
// construction — corroborationCount was 0 across all 1,785 cloud nodes while
|
|
21572
|
+
// the transport, parser and gate all worked. Same shape as the needsRevisit
|
|
21573
|
+
// inversion below: the budget optimized one objective and silently killed
|
|
21574
|
+
// another channel's entire input.
|
|
21575
|
+
"motifsOverFloor",
|
|
21560
21576
|
"workingFile",
|
|
21561
|
-
"
|
|
21577
|
+
"remoteOverFloor",
|
|
21562
21578
|
// Resolved priors are jumping-off points, not live defects — under a tight
|
|
21563
21579
|
// budget they drop before anything open/actionable.
|
|
21564
21580
|
"recentResolved",
|
|
@@ -21575,8 +21591,17 @@ ${RECALL_FIRST_BODY}`;
|
|
|
21575
21591
|
// about something ALREADY closed; a live prior is the substrate every link verb
|
|
21576
21592
|
// needs. Problems outrank it now.
|
|
21577
21593
|
"needsRevisit",
|
|
21594
|
+
// Problems trim to a floor before the collective floors give way: a starved
|
|
21595
|
+
// budget keeps a few of BOTH (own problems to act on, cross-session priors to
|
|
21596
|
+
// witness against) rather than all of one and none of the other.
|
|
21597
|
+
"recentProblemsOverFloor",
|
|
21598
|
+
"motifs",
|
|
21599
|
+
"remote",
|
|
21578
21600
|
"recentProblems"
|
|
21579
21601
|
];
|
|
21602
|
+
MOTIF_FLOOR = 2;
|
|
21603
|
+
REMOTE_FLOOR = 3;
|
|
21604
|
+
PROBLEM_FLOOR = 4;
|
|
21580
21605
|
DEFAULT_AGENT_CONTEXT_BUDGET = 9e3;
|
|
21581
21606
|
}
|
|
21582
21607
|
});
|
|
@@ -25496,61 +25521,36 @@ function buildFileRecallInstruction(referent = "\u2026") {
|
|
|
25496
25521
|
}
|
|
25497
25522
|
function triageBullet(ref) {
|
|
25498
25523
|
return [
|
|
25499
|
-
" \u2022 you diagnosed a
|
|
25500
|
-
"
|
|
25501
|
-
"
|
|
25502
|
-
|
|
25503
|
-
" a task rejects <- await fn() has no try/finally, so a rejection never decrements running].",
|
|
25504
|
-
" \xB7 chain it as deep as you actually diagnosed: [!symptom <- cause <- root cause] \u2014 every",
|
|
25505
|
-
" ` <- ` is a link we record, and the RIGHTMOST is the reusable root cause (the node other",
|
|
25506
|
-
" agents find). Stop at the deepest mechanism you're sure of; don't guess a link.",
|
|
25507
|
-
" When symptom and cause turn up FAR APART \u2014 the cause lands turns later, several problems",
|
|
25508
|
-
" in play \u2014 name the thread instead: [!#slug the symptom] once, then (cause:#slug the",
|
|
25509
|
-
" mechanism) binds to it however far away (same slug, your choice of word). Explaining a",
|
|
25510
|
-
` problem we SHOWED you? bind by its handle/id: (cause:[${ref}] \u2026) / (cause:#dprob_\u2026 \u2026).`
|
|
25524
|
+
" \u2022 you diagnosed a cause \u2014 fold the chain into the flag with <- (caused-by), deepest",
|
|
25525
|
+
" sure mechanism rightmost: [!symptom <- cause <- root cause]. Symptom and cause far",
|
|
25526
|
+
" apart? open a thread [!#slug symptom] \u2026 later bind (cause:#slug mechanism);",
|
|
25527
|
+
` explaining a problem we SHOWED you \u2192 (cause:[${ref}] \u2026)`
|
|
25511
25528
|
].join("\n");
|
|
25512
25529
|
}
|
|
25513
25530
|
function linkBullet(ref) {
|
|
25514
25531
|
return [
|
|
25515
|
-
|
|
25516
|
-
|
|
25517
|
-
|
|
25518
|
-
|
|
25519
|
-
|
|
25520
|
-
|
|
25521
|
-
` \xB7 (
|
|
25522
|
-
" Aim for ~3 DIFFERENT relevant priors; one link is weak, three triangulate it.",
|
|
25523
|
-
` \xB7 ${TAG_EXAMPLE.pattern()} \u2014 name the general shape it instantiates (e.g. (pattern: unbounded`,
|
|
25524
|
-
" queue growth under backpressure)) \u2014 this works with NO code anchor, and two agents naming",
|
|
25525
|
-
" the same pattern converge on one node. Cite a shown Pattern by handle: (pattern:[handle]).",
|
|
25526
|
-
` \xB7 ${TAG_EXAMPLE.package()} \u2014 the PUBLIC PACKAGE the problem is about, even when this`,
|
|
25527
|
-
" workspace doesn't depend on it (e.g. (package: chokidar), (package: pypi/requests)) \u2014 a",
|
|
25528
|
-
" public-registry anchor lets the knowledge cross to the collective; internal names stay private.",
|
|
25529
|
-
` \xB7 ${TAG_EXAMPLE.component()} \u2014 the framework/product-level UNIT it concerns when it's not a`,
|
|
25530
|
-
" package or a language (e.g. (component: React Router), (component: V8 Isolate)).",
|
|
25531
|
-
` \xB7 (aids:[${ref}],\u2026) \u2014 your FIX could also help these other, even unrelated, problems.`,
|
|
25532
|
-
" A hypothesis, not a claim \u2014 it's recorded as may-resolve and checked by whoever tries it.",
|
|
25533
|
-
` \xB7 when your fix relates to a PRIOR solution you were primed with (a problem's`,
|
|
25534
|
-
` "already solved by" line): (builds-on:[${ref}]) if you layer on it \xB7 (supersedes:[${ref}])`,
|
|
25535
|
-
" if you replace it \xB7 (alternative:[h]) if it's a different approach \u2014 pick one. This is the",
|
|
25536
|
-
" only way N solutions on one problem stop being a flat bag."
|
|
25532
|
+
" \u2022 link what you flag:",
|
|
25533
|
+
` \xB7 (instance:[${ref}],[another],[a-third]) \u2014 priors it instantiates; ~3 DIFFERENT ones triangulate`,
|
|
25534
|
+
" \xB7 (pattern:[handle]) \u2014 cite a shown Pattern",
|
|
25535
|
+
` \xB7 ${TAG_EXAMPLE.package()} \u2014 the PUBLIC package it's about, dependency or not`,
|
|
25536
|
+
` \xB7 ${TAG_EXAMPLE.component()} \u2014 the framework/product unit`,
|
|
25537
|
+
` \xB7 (aids:[${ref}],\u2026) \u2014 other problems your fix might also resolve (hypothesis)`,
|
|
25538
|
+
` \xB7 your fix vs a shown solution: (builds-on:[${ref}]) \xB7 (supersedes:[${ref}]) \xB7 (alternative:[h]) \u2014 pick one`
|
|
25537
25539
|
].join("\n");
|
|
25538
25540
|
}
|
|
25539
25541
|
function attemptBullet() {
|
|
25540
25542
|
return [
|
|
25541
|
-
|
|
25542
|
-
`
|
|
25543
|
-
|
|
25544
|
-
" Failed attempts are knowledge \u2014 they rule out a path. Add #slug to bind to a named",
|
|
25545
|
-
" thread: (tried:#slug \u2026) / (failed:#slug \u2026)."
|
|
25543
|
+
` \u2022 attempting an approach / an attempt failed \u2192 ${TAG_EXAMPLE.tried()} \xB7`,
|
|
25544
|
+
` ${TAG_EXAMPLE.failed()} \u2014 a failed attempt is knowledge;`,
|
|
25545
|
+
" bind to a thread with (tried:#slug \u2026) / (failed:#slug \u2026)"
|
|
25546
25546
|
].join("\n");
|
|
25547
25547
|
}
|
|
25548
25548
|
function buildAgentInstruction(opts = {}) {
|
|
25549
25549
|
const signals = opts.signals ?? ["prior", "problem", "domain", "fix", "constraint", "triage", "attempt", "link"];
|
|
25550
25550
|
const ref = opts.referent ?? "its-handle";
|
|
25551
25551
|
const token = (s) => s === "problem" ? TAG_EXAMPLE.problem() : s === "constraint" ? TAG_EXAMPLE.constraint() : s === "attempt" ? TAG_EXAMPLE.tried() : s === "domain" ? TAG_EXAMPLE.domain() : s === "link" ? TAG_EXAMPLE.pattern() : TAG_EXAMPLE[s](ref);
|
|
25552
|
-
const head2 = `We tag the priors we show you with a short handle like [${opts.handleExample ?? "chokidar-glob"}].
|
|
25553
|
-
const tail = "Mid-turn text (between tool calls) can be dropped by the harness \u2014
|
|
25552
|
+
const head2 = `We tag the priors we show you with a short handle like [${opts.handleExample ?? "chokidar-glob"}]. Tags are the ONLY signal recorded \u2014 anything you state but don't tag is silently lost. Weave each tag inline in your prose as you state it (no fences or backticks, no extra calls); tag everything, we filter downstream:`;
|
|
25553
|
+
const tail = "Mid-turn text (between tool calls) can be dropped by the harness \u2014 RESTATE every tag in your turn-final message; the final message is what reliably survives.";
|
|
25554
25554
|
return [
|
|
25555
25555
|
head2,
|
|
25556
25556
|
...signals.map(
|
|
@@ -25608,12 +25608,12 @@ var init_agent_signals = __esm({
|
|
|
25608
25608
|
aids: (ref) => `(aids:[${ref}])`
|
|
25609
25609
|
};
|
|
25610
25610
|
GLOSS = {
|
|
25611
|
-
prior: "a prior
|
|
25612
|
-
problem: "you
|
|
25613
|
-
fix: "your edit
|
|
25614
|
-
constraint: "
|
|
25615
|
-
triage: "you diagnosed a
|
|
25616
|
-
attempt: "
|
|
25611
|
+
prior: "a shown prior helped, or you work in a primed language/package",
|
|
25612
|
+
problem: "a problem you notice or report \u2014 any bug, finding, or thing wrong; about specific code? name the file: [!what's wrong @ src/file.ts:42]",
|
|
25613
|
+
fix: "your edit fixed a PROBLEM we showed you; for one you flagged yourself: (fix: what you changed) \u2014 a fix resolves a stated problem, completing routine work is not a fix",
|
|
25614
|
+
constraint: "a design decision forced by conflicting requirements or constraints \u2014 tag the tension, especially when your fix makes it 'only look' resolved",
|
|
25615
|
+
triage: "you diagnosed a cause \u2014 fold the chain into the flag with <- (caused-by), deepest sure mechanism rightmost",
|
|
25616
|
+
attempt: "attempting an approach / an attempt failed \u2014 a failed attempt is knowledge, it rules out a path",
|
|
25617
25617
|
// DOMAIN — promoted to a FIRST-CLASS signal (was nested inside linkBullet, whose
|
|
25618
25618
|
// lead-in gates on "a problem you flagged resembles prior knowledge"). Naming the
|
|
25619
25619
|
// area a problem is about is unconditional and has nothing to do with recognizing
|
|
@@ -25629,7 +25629,10 @@ var init_agent_signals = __esm({
|
|
|
25629
25629
|
// contribution, so stating the general area reads as vague restatement — exactly
|
|
25630
25630
|
// when it matters most, because precise wording is what makes a problem
|
|
25631
25631
|
// unfindable to anyone who doesn't already share it.
|
|
25632
|
-
|
|
25632
|
+
// Sim note (2026-08-02 shrink): domain emission held 4/4 with just the trigger
|
|
25633
|
+
// clause; the pattern convergence hook now rides here too (it fell 0/4 when it
|
|
25634
|
+
// only appeared in the link bullet's tail).
|
|
25635
|
+
domain: "a problem with no single file \u2014 name the area it's about (Title Case). Also name the general shape it instantiates: (pattern: the shape) \u2014 needs no code anchor, and two agents naming the same shape converge on one node",
|
|
25633
25636
|
link: "the problem you flagged is an instance of priors/abstractions you can name \u2014 (instance:[h1],[h2],\u2026) / (pattern: \u2026) / (aids:[h]); rendered whole via linkBullet"
|
|
25634
25637
|
};
|
|
25635
25638
|
}
|
|
@@ -47137,6 +47140,69 @@ var init_webui = __esm({
|
|
|
47137
47140
|
}
|
|
47138
47141
|
});
|
|
47139
47142
|
|
|
47143
|
+
// src/witness-ledger.ts
|
|
47144
|
+
var witness_ledger_exports = {};
|
|
47145
|
+
__export(witness_ledger_exports, {
|
|
47146
|
+
appendWitnessLedger: () => appendWitnessLedger,
|
|
47147
|
+
readWitnessLedger: () => readWitnessLedger,
|
|
47148
|
+
summarizeWitnessLedger: () => summarizeWitnessLedger,
|
|
47149
|
+
witnessLedgerPath: () => witnessLedgerPath
|
|
47150
|
+
});
|
|
47151
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync20, readFileSync as readFileSync20, writeFileSync as writeFileSync17 } from "node:fs";
|
|
47152
|
+
import { join as join25 } from "node:path";
|
|
47153
|
+
function witnessLedgerPath(configDir) {
|
|
47154
|
+
return join25(configDir, "witness-ledger.jsonl");
|
|
47155
|
+
}
|
|
47156
|
+
function appendWitnessLedger(configDir, entry) {
|
|
47157
|
+
const path2 = witnessLedgerPath(configDir);
|
|
47158
|
+
try {
|
|
47159
|
+
appendFileSync2(path2, JSON.stringify(entry) + "\n");
|
|
47160
|
+
const lines = readFileSync20(path2, "utf8").split("\n").filter(Boolean);
|
|
47161
|
+
if (lines.length > LEDGER_MAX_LINES) {
|
|
47162
|
+
writeFileSync17(path2, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
|
|
47163
|
+
}
|
|
47164
|
+
} catch {
|
|
47165
|
+
}
|
|
47166
|
+
}
|
|
47167
|
+
function readWitnessLedger(configDir) {
|
|
47168
|
+
const path2 = witnessLedgerPath(configDir);
|
|
47169
|
+
if (!existsSync20(path2)) return [];
|
|
47170
|
+
try {
|
|
47171
|
+
return readFileSync20(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
|
|
47172
|
+
} catch {
|
|
47173
|
+
return [];
|
|
47174
|
+
}
|
|
47175
|
+
}
|
|
47176
|
+
function summarizeWitnessLedger(configDir, nowMs) {
|
|
47177
|
+
const entries = readWitnessLedger(configDir);
|
|
47178
|
+
if (entries.length === 0) return [];
|
|
47179
|
+
const byChannel = /* @__PURE__ */ new Map();
|
|
47180
|
+
for (const e of entries) {
|
|
47181
|
+
const c = byChannel.get(e.channel) ?? { recorded: 0, selfSkipped: 0, selfGated: 0, unmatched: 0, lastTs: 0 };
|
|
47182
|
+
c.recorded += e.recorded ?? 0;
|
|
47183
|
+
c.selfSkipped += e.clientSelfSkipped ?? 0;
|
|
47184
|
+
c.selfGated += e.selfGated ?? 0;
|
|
47185
|
+
c.unmatched += e.unmatched ?? 0;
|
|
47186
|
+
c.lastTs = Math.max(c.lastTs, e.ts);
|
|
47187
|
+
byChannel.set(e.channel, c);
|
|
47188
|
+
}
|
|
47189
|
+
const out2 = [];
|
|
47190
|
+
for (const [channel, c] of byChannel) {
|
|
47191
|
+
const ageH = Math.round((nowMs - c.lastTs) / 36e5);
|
|
47192
|
+
out2.push(
|
|
47193
|
+
`${channel}: recorded ${c.recorded} \xB7 self-gated ${c.selfSkipped + c.selfGated} \xB7 unmatched ${c.unmatched} \xB7 last activity ${ageH}h ago`
|
|
47194
|
+
);
|
|
47195
|
+
}
|
|
47196
|
+
return out2;
|
|
47197
|
+
}
|
|
47198
|
+
var LEDGER_MAX_LINES;
|
|
47199
|
+
var init_witness_ledger = __esm({
|
|
47200
|
+
"src/witness-ledger.ts"() {
|
|
47201
|
+
"use strict";
|
|
47202
|
+
LEDGER_MAX_LINES = 500;
|
|
47203
|
+
}
|
|
47204
|
+
});
|
|
47205
|
+
|
|
47140
47206
|
// src/report-render.ts
|
|
47141
47207
|
var report_render_exports = {};
|
|
47142
47208
|
__export(report_render_exports, {
|
|
@@ -47528,12 +47594,12 @@ var init_report_render = __esm({
|
|
|
47528
47594
|
|
|
47529
47595
|
// src/cli.ts
|
|
47530
47596
|
init_src5();
|
|
47531
|
-
import { closeSync as closeSync2, existsSync as
|
|
47532
|
-
import { join as
|
|
47597
|
+
import { closeSync as closeSync2, existsSync as existsSync27, openSync as openSync2, readFileSync as readFileSync26, renameSync as renameSync4, statSync as statSync6 } from "node:fs";
|
|
47598
|
+
import { join as join30 } from "node:path";
|
|
47533
47599
|
import { spawn as spawn3 } from "node:child_process";
|
|
47534
47600
|
|
|
47535
47601
|
// src/daemon.ts
|
|
47536
|
-
import { existsSync as
|
|
47602
|
+
import { existsSync as existsSync22, writeFileSync as writeFileSync19 } from "node:fs";
|
|
47537
47603
|
|
|
47538
47604
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
|
|
47539
47605
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -48113,8 +48179,8 @@ init_config();
|
|
|
48113
48179
|
|
|
48114
48180
|
// src/engine.ts
|
|
48115
48181
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
48116
|
-
import { existsSync as
|
|
48117
|
-
import { join as
|
|
48182
|
+
import { existsSync as existsSync21, statSync as statSync5, appendFileSync as appendFileSync3, readdirSync as readdirSync9, renameSync as renameSync3, readFileSync as readFileSync21, writeFileSync as writeFileSync18 } from "node:fs";
|
|
48183
|
+
import { join as join26, relative as relative6, sep as sep4 } from "node:path";
|
|
48118
48184
|
|
|
48119
48185
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
48120
48186
|
import { stat as statcb } from "fs";
|
|
@@ -52560,6 +52626,9 @@ function retireWitnesses(queue, channel, settledKeys) {
|
|
|
52560
52626
|
return queue.filter((w) => !(w.channel === channel && settledKeys.has(w.witnessKey)));
|
|
52561
52627
|
}
|
|
52562
52628
|
|
|
52629
|
+
// src/engine.ts
|
|
52630
|
+
init_witness_ledger();
|
|
52631
|
+
|
|
52563
52632
|
// src/causal.ts
|
|
52564
52633
|
var SUPPRESSORS = [
|
|
52565
52634
|
{ kind: "ts-nocheck", re: /@ts-nocheck\b/g },
|
|
@@ -52812,7 +52881,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
52812
52881
|
}
|
|
52813
52882
|
|
|
52814
52883
|
// src/engine.ts
|
|
52815
|
-
var DAEMON_VERSION = true ? "2.0.2-dev.
|
|
52884
|
+
var DAEMON_VERSION = true ? "2.0.2-dev.295" : "2.0.0-alpha.0";
|
|
52816
52885
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
52817
52886
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
52818
52887
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -52822,17 +52891,17 @@ var TURN_REPLAY_LOOKBACK_MS = 7 * 24 * 60 * 6e4;
|
|
|
52822
52891
|
function appendIdentityAudit(path2, record2, line) {
|
|
52823
52892
|
if (!record2.accepted && record2.score <= 0) return;
|
|
52824
52893
|
try {
|
|
52825
|
-
if (
|
|
52894
|
+
if (existsSync21(path2) && statSync5(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
52826
52895
|
renameSync3(path2, `${path2}.1`);
|
|
52827
52896
|
}
|
|
52828
|
-
|
|
52897
|
+
appendFileSync3(path2, line);
|
|
52829
52898
|
} catch {
|
|
52830
52899
|
}
|
|
52831
52900
|
}
|
|
52832
52901
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
52833
52902
|
function loadTurnCursors(path2) {
|
|
52834
52903
|
try {
|
|
52835
|
-
const raw2 = JSON.parse(
|
|
52904
|
+
const raw2 = JSON.parse(readFileSync21(path2, "utf8"));
|
|
52836
52905
|
return new Map(
|
|
52837
52906
|
Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
|
|
52838
52907
|
);
|
|
@@ -52842,7 +52911,7 @@ function loadTurnCursors(path2) {
|
|
|
52842
52911
|
}
|
|
52843
52912
|
function loadTurnOffsets(path2) {
|
|
52844
52913
|
try {
|
|
52845
|
-
const raw2 = JSON.parse(
|
|
52914
|
+
const raw2 = JSON.parse(readFileSync21(path2, "utf8"));
|
|
52846
52915
|
const out2 = /* @__PURE__ */ new Map();
|
|
52847
52916
|
for (const [k, v] of Object.entries(raw2)) {
|
|
52848
52917
|
const off = typeof v === "object" && v !== null ? v.offset : void 0;
|
|
@@ -52858,7 +52927,7 @@ function saveTurnCursors(path2, cursors, offsets) {
|
|
|
52858
52927
|
const merged = {};
|
|
52859
52928
|
for (const [k, uuid3] of cursors) merged[k] = { uuid: uuid3, offset: offsets.get(k) ?? 0 };
|
|
52860
52929
|
for (const [k, offset] of offsets) if (!merged[k]) merged[k] = { uuid: "", offset };
|
|
52861
|
-
|
|
52930
|
+
writeFileSync18(path2, JSON.stringify(merged), "utf8");
|
|
52862
52931
|
} catch {
|
|
52863
52932
|
}
|
|
52864
52933
|
}
|
|
@@ -52880,7 +52949,7 @@ function gitSourceWatchTargets(root) {
|
|
|
52880
52949
|
["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
|
|
52881
52950
|
{ encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
52882
52951
|
);
|
|
52883
|
-
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(
|
|
52952
|
+
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join26(root, d) + sep4));
|
|
52884
52953
|
} catch {
|
|
52885
52954
|
}
|
|
52886
52955
|
const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
|
|
@@ -52892,19 +52961,19 @@ function gitSourceWatchTargets(root) {
|
|
|
52892
52961
|
if (!f.startsWith(prefix)) continue;
|
|
52893
52962
|
const rest2 = f.slice(prefix.length);
|
|
52894
52963
|
if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
|
|
52895
|
-
else targets.add(
|
|
52964
|
+
else targets.add(join26(root, f));
|
|
52896
52965
|
}
|
|
52897
52966
|
for (const c of children) {
|
|
52898
|
-
if (IGNORED_PATH.test(
|
|
52967
|
+
if (IGNORED_PATH.test(join26(root, c) + sep4)) continue;
|
|
52899
52968
|
if (hasIgnoredChild(c)) addUnder(c);
|
|
52900
|
-
else targets.add(
|
|
52969
|
+
else targets.add(join26(root, c));
|
|
52901
52970
|
}
|
|
52902
52971
|
};
|
|
52903
52972
|
addUnder("");
|
|
52904
52973
|
if (targets.size > 0) return [...targets];
|
|
52905
52974
|
} catch {
|
|
52906
52975
|
}
|
|
52907
|
-
return readdirSync9(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(
|
|
52976
|
+
return readdirSync9(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join26(root, String(e.name)) + sep4)).map((e) => join26(root, String(e.name)));
|
|
52908
52977
|
}
|
|
52909
52978
|
function createWorkspaceEngine(opts) {
|
|
52910
52979
|
const paths = workspacePaths(opts.workspaceRoot);
|
|
@@ -53062,7 +53131,7 @@ function createWorkspaceEngine(opts) {
|
|
|
53062
53131
|
const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
|
|
53063
53132
|
let episodeId2;
|
|
53064
53133
|
if (srcPaths.length > 0) {
|
|
53065
|
-
const abs = srcPaths.map((p) =>
|
|
53134
|
+
const abs = srcPaths.map((p) => join26(opts.workspaceRoot, p));
|
|
53066
53135
|
try {
|
|
53067
53136
|
const r = await runReindexPass(
|
|
53068
53137
|
`git-reindex:${profile.name} (${abs.length} files)`,
|
|
@@ -53098,8 +53167,8 @@ function createWorkspaceEngine(opts) {
|
|
|
53098
53167
|
`[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
|
|
53099
53168
|
);
|
|
53100
53169
|
};
|
|
53101
|
-
const gitDir =
|
|
53102
|
-
if (
|
|
53170
|
+
const gitDir = join26(opts.workspaceRoot, ".git");
|
|
53171
|
+
if (existsSync21(gitDir)) {
|
|
53103
53172
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
53104
53173
|
void handleGitEvent(ev).catch((err2) => {
|
|
53105
53174
|
console.warn("[errata] git event handler failed:", err2);
|
|
@@ -53169,10 +53238,10 @@ function createWorkspaceEngine(opts) {
|
|
|
53169
53238
|
});
|
|
53170
53239
|
doneRender?.();
|
|
53171
53240
|
writeContextFile(opts.workspaceRoot, body2);
|
|
53172
|
-
const target =
|
|
53241
|
+
const target = join26(opts.workspaceRoot, "AGENTS.md");
|
|
53173
53242
|
writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
|
|
53174
53243
|
if (elicit) {
|
|
53175
|
-
writePrimingHandles(
|
|
53244
|
+
writePrimingHandles(join26(paths.configDir, "priming-handles.json"), [
|
|
53176
53245
|
...snapshot.recentProblems.map((r) => r.node),
|
|
53177
53246
|
// Resolved-band handles: the ✓ problem AND its Solution are citable
|
|
53178
53247
|
// (a fix tag on an already-resolved problem no-ops idempotently; the
|
|
@@ -53202,7 +53271,7 @@ function createWorkspaceEngine(opts) {
|
|
|
53202
53271
|
remoteInFlight = true;
|
|
53203
53272
|
lastRemoteAt = now;
|
|
53204
53273
|
try {
|
|
53205
|
-
const norm = (xs) => (xs ?? []).map((t) => t.trim().toLowerCase().replace(/[@\s].*$/, "")).filter(Boolean);
|
|
53274
|
+
const norm = (xs) => (xs ?? []).map((t) => t.trim().toLowerCase().replace(/(?!^)[@\s].*$/, "")).filter(Boolean);
|
|
53206
53275
|
const seed = store.findNodesByLabel("Problem").sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 6).map((p) => p.id);
|
|
53207
53276
|
const q = {
|
|
53208
53277
|
stack: norm(profile.stack),
|
|
@@ -53388,7 +53457,7 @@ function createWorkspaceEngine(opts) {
|
|
|
53388
53457
|
resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
|
|
53389
53458
|
});
|
|
53390
53459
|
};
|
|
53391
|
-
const turnCursorPath =
|
|
53460
|
+
const turnCursorPath = join26(paths.configDir, "turn-cursors.json");
|
|
53392
53461
|
const lastTurnUuid = loadTurnCursors(turnCursorPath);
|
|
53393
53462
|
const turnOffset = loadTurnOffsets(turnCursorPath);
|
|
53394
53463
|
const sessionLastProblem = /* @__PURE__ */ new Map();
|
|
@@ -53412,7 +53481,7 @@ function createWorkspaceEngine(opts) {
|
|
|
53412
53481
|
const t = Date.now();
|
|
53413
53482
|
let processedTurns = 0;
|
|
53414
53483
|
const elicit = isEdgeElicitationEnabled();
|
|
53415
|
-
const handleMap = elicit ? readPrimingHandles(
|
|
53484
|
+
const handleMap = elicit ? readPrimingHandles(join26(paths.configDir, "priming-handles.json")) : {};
|
|
53416
53485
|
const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
|
|
53417
53486
|
const toRel = (abs) => {
|
|
53418
53487
|
const p = abs.replace(/\\/g, "/");
|
|
@@ -53803,6 +53872,15 @@ function createWorkspaceEngine(opts) {
|
|
|
53803
53872
|
console.log(
|
|
53804
53873
|
`[errata] ${channel}: ${formatDisposition({ recorded, unmatched, duplicate, selfGated })}` + (queued.length > 0 ? ` (incl. ${queued.length} replayed)` : "")
|
|
53805
53874
|
);
|
|
53875
|
+
appendWitnessLedger(paths.configDir, {
|
|
53876
|
+
ts: Date.now(),
|
|
53877
|
+
channel,
|
|
53878
|
+
recorded,
|
|
53879
|
+
unmatched,
|
|
53880
|
+
duplicate,
|
|
53881
|
+
selfGated,
|
|
53882
|
+
parked: pendingFor(witnessQueue, channel).length
|
|
53883
|
+
});
|
|
53806
53884
|
};
|
|
53807
53885
|
if (typeof cloud.reportContradictions === "function") {
|
|
53808
53886
|
await sendWitnesses(
|
|
@@ -53819,7 +53897,10 @@ function createWorkspaceEngine(opts) {
|
|
|
53819
53897
|
if (typeof cloud.reportCorroborations === "function") {
|
|
53820
53898
|
const emit = plan.corroborations.filter((c) => !mintedHere(c.nodeId));
|
|
53821
53899
|
const skipped = plan.corroborations.length - emit.length;
|
|
53822
|
-
if (skipped > 0)
|
|
53900
|
+
if (skipped > 0) {
|
|
53901
|
+
console.log(`[errata] corroborate: ${skipped} skipped (this session authored the node)`);
|
|
53902
|
+
appendWitnessLedger(paths.configDir, { ts: Date.now(), channel: "corroborate", clientSelfSkipped: skipped });
|
|
53903
|
+
}
|
|
53823
53904
|
await sendWitnesses(
|
|
53824
53905
|
"corroborate",
|
|
53825
53906
|
emit,
|
|
@@ -54021,7 +54102,7 @@ function createWorkspaceEngine(opts) {
|
|
|
54021
54102
|
try {
|
|
54022
54103
|
const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
|
|
54023
54104
|
emitAndProjectSkills(opts.workspaceRoot, inputs);
|
|
54024
|
-
writePrimingHandles(
|
|
54105
|
+
writePrimingHandles(join26(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
|
|
54025
54106
|
} catch (err2) {
|
|
54026
54107
|
console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
|
|
54027
54108
|
}
|
|
@@ -54208,7 +54289,7 @@ function createWorkspaceEngine(opts) {
|
|
|
54208
54289
|
console.log(
|
|
54209
54290
|
"[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
|
|
54210
54291
|
);
|
|
54211
|
-
const pending =
|
|
54292
|
+
const pending = existsSync21(paths.outbox) ? readdirSync9(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
|
|
54212
54293
|
return { uploaded: 0, failed: 0, remaining: pending };
|
|
54213
54294
|
}
|
|
54214
54295
|
try {
|
|
@@ -54295,7 +54376,7 @@ async function startDaemon(opts) {
|
|
|
54295
54376
|
reviewUrl: () => webUiUrl + "/review"
|
|
54296
54377
|
});
|
|
54297
54378
|
const writeLockFile = (url2) => {
|
|
54298
|
-
|
|
54379
|
+
writeFileSync19(
|
|
54299
54380
|
engine.paths.daemonLock,
|
|
54300
54381
|
JSON.stringify({ pid: process.pid, webUiUrl: url2, startedAt: Date.now() }),
|
|
54301
54382
|
"utf8"
|
|
@@ -54338,7 +54419,7 @@ async function startDaemon(opts) {
|
|
|
54338
54419
|
);
|
|
54339
54420
|
await engine.stop();
|
|
54340
54421
|
try {
|
|
54341
|
-
if (
|
|
54422
|
+
if (existsSync22(engine.paths.daemonLock)) {
|
|
54342
54423
|
}
|
|
54343
54424
|
} catch {
|
|
54344
54425
|
}
|
|
@@ -54355,16 +54436,16 @@ async function listenServer(fetchFn, port) {
|
|
|
54355
54436
|
|
|
54356
54437
|
// src/registry.ts
|
|
54357
54438
|
init_paths();
|
|
54358
|
-
import { existsSync as
|
|
54359
|
-
import { join as
|
|
54439
|
+
import { existsSync as existsSync23, readFileSync as readFileSync22, writeFileSync as writeFileSync20 } from "node:fs";
|
|
54440
|
+
import { join as join27 } from "node:path";
|
|
54360
54441
|
function registryPath() {
|
|
54361
|
-
return process.env["ERRATA_REGISTRY_PATH"] ??
|
|
54442
|
+
return process.env["ERRATA_REGISTRY_PATH"] ?? join27(globalDir(), "workspaces.json");
|
|
54362
54443
|
}
|
|
54363
54444
|
function read() {
|
|
54364
54445
|
const p = registryPath();
|
|
54365
|
-
if (!
|
|
54446
|
+
if (!existsSync23(p)) return { version: 1, workspaces: {} };
|
|
54366
54447
|
try {
|
|
54367
|
-
const parsed = JSON.parse(
|
|
54448
|
+
const parsed = JSON.parse(readFileSync22(p, "utf8"));
|
|
54368
54449
|
return { version: 1, workspaces: parsed.workspaces ?? {} };
|
|
54369
54450
|
} catch {
|
|
54370
54451
|
return { version: 1, workspaces: {} };
|
|
@@ -54372,7 +54453,7 @@ function read() {
|
|
|
54372
54453
|
}
|
|
54373
54454
|
function write(reg) {
|
|
54374
54455
|
ensureDir(globalDir());
|
|
54375
|
-
|
|
54456
|
+
writeFileSync20(registryPath(), JSON.stringify(reg, null, 2), "utf8");
|
|
54376
54457
|
}
|
|
54377
54458
|
function registerWorkspace(profile, root, now = Date.now()) {
|
|
54378
54459
|
const reg = read();
|
|
@@ -54389,7 +54470,7 @@ function pruneMissingWorkspaces() {
|
|
|
54389
54470
|
const reg = read();
|
|
54390
54471
|
const removed = [];
|
|
54391
54472
|
for (const [id, entry] of Object.entries(reg.workspaces)) {
|
|
54392
|
-
if (!
|
|
54473
|
+
if (!existsSync23(entry.path)) {
|
|
54393
54474
|
removed.push(entry);
|
|
54394
54475
|
delete reg.workspaces[id];
|
|
54395
54476
|
}
|
|
@@ -54398,13 +54479,13 @@ function pruneMissingWorkspaces() {
|
|
|
54398
54479
|
return removed;
|
|
54399
54480
|
}
|
|
54400
54481
|
function workspaceStatus(entry) {
|
|
54401
|
-
const missing = !
|
|
54482
|
+
const missing = !existsSync23(entry.path);
|
|
54402
54483
|
const lockPath = workspacePaths(entry.path).daemonLock;
|
|
54403
54484
|
let running = false;
|
|
54404
54485
|
let webUiUrl = null;
|
|
54405
|
-
if (
|
|
54486
|
+
if (existsSync23(lockPath)) {
|
|
54406
54487
|
try {
|
|
54407
|
-
const lock = JSON.parse(
|
|
54488
|
+
const lock = JSON.parse(readFileSync22(lockPath, "utf8"));
|
|
54408
54489
|
if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
|
|
54409
54490
|
running = true;
|
|
54410
54491
|
webUiUrl = lock.webUiUrl;
|
|
@@ -54432,7 +54513,7 @@ function pidAlive(pid) {
|
|
|
54432
54513
|
// src/multi.ts
|
|
54433
54514
|
init_dist();
|
|
54434
54515
|
init_src4();
|
|
54435
|
-
import { readFileSync as
|
|
54516
|
+
import { readFileSync as readFileSync25, unlinkSync as unlinkSync3, writeFileSync as writeFileSync21 } from "node:fs";
|
|
54436
54517
|
|
|
54437
54518
|
// src/principle-sync.ts
|
|
54438
54519
|
init_src4();
|
|
@@ -54460,8 +54541,8 @@ init_reconcile();
|
|
|
54460
54541
|
|
|
54461
54542
|
// src/lockfile-auto.ts
|
|
54462
54543
|
init_src();
|
|
54463
|
-
import { existsSync as
|
|
54464
|
-
import { join as
|
|
54544
|
+
import { existsSync as existsSync24, readFileSync as readFileSync23 } from "node:fs";
|
|
54545
|
+
import { join as join28 } from "node:path";
|
|
54465
54546
|
|
|
54466
54547
|
// src/package-index.ts
|
|
54467
54548
|
init_src();
|
|
@@ -54610,11 +54691,11 @@ function runLockfilePass(opts) {
|
|
|
54610
54691
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
54611
54692
|
];
|
|
54612
54693
|
for (const c of candidates) {
|
|
54613
|
-
const p =
|
|
54614
|
-
if (!
|
|
54694
|
+
const p = join28(opts.root, c.file);
|
|
54695
|
+
if (!existsSync24(p)) continue;
|
|
54615
54696
|
let sbom;
|
|
54616
54697
|
try {
|
|
54617
|
-
sbom = c.parse(
|
|
54698
|
+
sbom = c.parse(readFileSync23(p, "utf8"));
|
|
54618
54699
|
} catch {
|
|
54619
54700
|
continue;
|
|
54620
54701
|
}
|
|
@@ -55062,7 +55143,7 @@ var ConsolidateWorker = class {
|
|
|
55062
55143
|
init_paths();
|
|
55063
55144
|
|
|
55064
55145
|
// src/lock.ts
|
|
55065
|
-
import { existsSync as
|
|
55146
|
+
import { existsSync as existsSync25, readFileSync as readFileSync24 } from "node:fs";
|
|
55066
55147
|
function isProcessAlive(pid) {
|
|
55067
55148
|
if (!pid || pid <= 0) return false;
|
|
55068
55149
|
try {
|
|
@@ -55073,9 +55154,9 @@ function isProcessAlive(pid) {
|
|
|
55073
55154
|
}
|
|
55074
55155
|
}
|
|
55075
55156
|
function readDaemonLock(lockPath) {
|
|
55076
|
-
if (!
|
|
55157
|
+
if (!existsSync25(lockPath)) return null;
|
|
55077
55158
|
try {
|
|
55078
|
-
const lock = JSON.parse(
|
|
55159
|
+
const lock = JSON.parse(readFileSync24(lockPath, "utf8"));
|
|
55079
55160
|
return typeof lock.pid === "number" ? lock : null;
|
|
55080
55161
|
} catch {
|
|
55081
55162
|
return null;
|
|
@@ -55354,12 +55435,12 @@ async function reanchorProject(opts) {
|
|
|
55354
55435
|
}
|
|
55355
55436
|
|
|
55356
55437
|
// src/adopt.ts
|
|
55357
|
-
import { existsSync as
|
|
55358
|
-
import { dirname as dirname10, join as
|
|
55438
|
+
import { existsSync as existsSync26 } from "node:fs";
|
|
55439
|
+
import { dirname as dirname10, join as join29 } from "node:path";
|
|
55359
55440
|
function findGitRoot(absPath) {
|
|
55360
55441
|
let dir = absPath;
|
|
55361
55442
|
for (let depth = 0; depth < 64; depth++) {
|
|
55362
|
-
if (
|
|
55443
|
+
if (existsSync26(join29(dir, ".git"))) return dir;
|
|
55363
55444
|
const parent = dirname10(dir);
|
|
55364
55445
|
if (parent === dir) return null;
|
|
55365
55446
|
dir = parent;
|
|
@@ -55608,7 +55689,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
55608
55689
|
void ambientLinkAll();
|
|
55609
55690
|
app.route(`/ws/${rec.id}`, rec.webApp);
|
|
55610
55691
|
try {
|
|
55611
|
-
|
|
55692
|
+
writeFileSync21(
|
|
55612
55693
|
rec.engine.paths.daemonLock,
|
|
55613
55694
|
JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${rec.id}`, startedAt: Date.now() }),
|
|
55614
55695
|
"utf8"
|
|
@@ -55797,7 +55878,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
55797
55878
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
55798
55879
|
try {
|
|
55799
55880
|
ensureDir(globalDir());
|
|
55800
|
-
|
|
55881
|
+
writeFileSync21(
|
|
55801
55882
|
lockPath,
|
|
55802
55883
|
JSON.stringify({ pid: process.pid, webUiUrl: baseUrl, startedAt: Date.now() }),
|
|
55803
55884
|
"utf8"
|
|
@@ -55806,7 +55887,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
55806
55887
|
}
|
|
55807
55888
|
for (const r of records) {
|
|
55808
55889
|
try {
|
|
55809
|
-
|
|
55890
|
+
writeFileSync21(
|
|
55810
55891
|
r.engine.paths.daemonLock,
|
|
55811
55892
|
JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${r.id}`, startedAt: Date.now() }),
|
|
55812
55893
|
"utf8"
|
|
@@ -56304,7 +56385,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
56304
56385
|
},
|
|
56305
56386
|
async stop() {
|
|
56306
56387
|
try {
|
|
56307
|
-
const cur =
|
|
56388
|
+
const cur = readFileSync25(lockPath, "utf8");
|
|
56308
56389
|
if (JSON.parse(cur).pid === process.pid) unlinkSync3(lockPath);
|
|
56309
56390
|
} catch {
|
|
56310
56391
|
}
|
|
@@ -57321,21 +57402,21 @@ async function cmdInit() {
|
|
|
57321
57402
|
if (!skipHooks) {
|
|
57322
57403
|
console.log("");
|
|
57323
57404
|
console.log("installing harness hooks...");
|
|
57324
|
-
const { existsSync:
|
|
57325
|
-
const { join:
|
|
57405
|
+
const { existsSync: existsSync28 } = await import("node:fs");
|
|
57406
|
+
const { join: join31 } = await import("node:path");
|
|
57326
57407
|
try {
|
|
57327
57408
|
await installClaudeHooks(port);
|
|
57328
57409
|
} catch (err2) {
|
|
57329
57410
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
57330
57411
|
}
|
|
57331
|
-
if (
|
|
57412
|
+
if (existsSync28(join31(ROOT, ".cursor"))) {
|
|
57332
57413
|
try {
|
|
57333
57414
|
await installCursorMcpConfig();
|
|
57334
57415
|
} catch (err2) {
|
|
57335
57416
|
console.warn(` \u26A0\uFE0F Cursor MCP config failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
57336
57417
|
}
|
|
57337
57418
|
}
|
|
57338
|
-
if (
|
|
57419
|
+
if (existsSync28(join31(ROOT, ".codex"))) {
|
|
57339
57420
|
try {
|
|
57340
57421
|
await installCodexHooks(port);
|
|
57341
57422
|
} catch (err2) {
|
|
@@ -57492,9 +57573,9 @@ async function cmdStatus() {
|
|
|
57492
57573
|
console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
|
|
57493
57574
|
console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
|
|
57494
57575
|
}
|
|
57495
|
-
console.log(` graph db: ${
|
|
57496
|
-
console.log(` event log: ${
|
|
57497
|
-
if (
|
|
57576
|
+
console.log(` graph db: ${existsSync27(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
57577
|
+
console.log(` event log: ${existsSync27(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
57578
|
+
if (existsSync27(paths.castalia)) {
|
|
57498
57579
|
try {
|
|
57499
57580
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
|
|
57500
57581
|
const store = openGraphStore2({ path: paths.castalia });
|
|
@@ -57526,6 +57607,13 @@ async function cmdStatus() {
|
|
|
57526
57607
|
} catch {
|
|
57527
57608
|
}
|
|
57528
57609
|
}
|
|
57610
|
+
try {
|
|
57611
|
+
const { summarizeWitnessLedger: summarizeWitnessLedger2 } = await Promise.resolve().then(() => (init_witness_ledger(), witness_ledger_exports));
|
|
57612
|
+
const lines = summarizeWitnessLedger2(paths.configDir, Date.now());
|
|
57613
|
+
if (lines.length === 0) console.log(" evidence: no witness activity ledgered yet (corroborate/contradict have never fired here)");
|
|
57614
|
+
else for (const l of lines) console.log(` evidence: ${l}`);
|
|
57615
|
+
} catch {
|
|
57616
|
+
}
|
|
57529
57617
|
const lockPath = globalDaemonLock();
|
|
57530
57618
|
const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
|
|
57531
57619
|
console.log(
|
|
@@ -58168,11 +58256,11 @@ function cmdInstallationProfile(args2) {
|
|
|
58168
58256
|
}
|
|
58169
58257
|
async function cmdReview() {
|
|
58170
58258
|
const paths = workspacePaths(ROOT);
|
|
58171
|
-
if (!
|
|
58259
|
+
if (!existsSync27(paths.reviewQueue)) {
|
|
58172
58260
|
console.log("(review queue empty)");
|
|
58173
58261
|
return;
|
|
58174
58262
|
}
|
|
58175
|
-
const queue = JSON.parse(
|
|
58263
|
+
const queue = JSON.parse(readFileSync26(paths.reviewQueue, "utf8"));
|
|
58176
58264
|
if (queue.length === 0) {
|
|
58177
58265
|
console.log("(review queue empty)");
|
|
58178
58266
|
return;
|
|
@@ -58843,7 +58931,7 @@ async function gatherRepo(store, ws) {
|
|
|
58843
58931
|
};
|
|
58844
58932
|
}
|
|
58845
58933
|
async function gatherReportData(generatedAt) {
|
|
58846
|
-
const { existsSync:
|
|
58934
|
+
const { existsSync: existsSync28 } = await import("node:fs");
|
|
58847
58935
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
|
|
58848
58936
|
const cfg = loadConfig();
|
|
58849
58937
|
const outbound = cfg.consent.sync ? "auto" : "off";
|
|
@@ -58851,7 +58939,7 @@ async function gatherReportData(generatedAt) {
|
|
|
58851
58939
|
for (const ws of listWorkspaces()) {
|
|
58852
58940
|
if (ws.missing) continue;
|
|
58853
58941
|
const dbPath = workspacePaths(ws.path).castalia;
|
|
58854
|
-
if (!
|
|
58942
|
+
if (!existsSync28(dbPath)) continue;
|
|
58855
58943
|
let store = null;
|
|
58856
58944
|
try {
|
|
58857
58945
|
store = openGraphStore2({ path: dbPath });
|
|
@@ -58882,7 +58970,7 @@ async function gatherReportData(generatedAt) {
|
|
|
58882
58970
|
};
|
|
58883
58971
|
}
|
|
58884
58972
|
async function cmdReport(args2) {
|
|
58885
|
-
const { mkdirSync: mkdirSync8, writeFileSync:
|
|
58973
|
+
const { mkdirSync: mkdirSync8, writeFileSync: writeFileSync22 } = await import("node:fs");
|
|
58886
58974
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
58887
58975
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
58888
58976
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -58895,8 +58983,8 @@ async function cmdReport(args2) {
|
|
|
58895
58983
|
const outDir = workspacePaths(ROOT).configDir;
|
|
58896
58984
|
mkdirSync8(outDir, { recursive: true });
|
|
58897
58985
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
58898
|
-
for (const f of files)
|
|
58899
|
-
const indexPath =
|
|
58986
|
+
for (const f of files) writeFileSync22(join30(outDir, f.name), f.html, "utf8");
|
|
58987
|
+
const indexPath = join30(outDir, "report.html");
|
|
58900
58988
|
console.log(`report \u2192 ${indexPath}`);
|
|
58901
58989
|
console.log(
|
|
58902
58990
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -59014,15 +59102,15 @@ function hookRelayCommand(port, path2) {
|
|
|
59014
59102
|
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 '{}'`;
|
|
59015
59103
|
}
|
|
59016
59104
|
async function installClaudeHooks(port) {
|
|
59017
|
-
const { mkdirSync: mkdirSync8, existsSync:
|
|
59018
|
-
const { join:
|
|
59019
|
-
const dir =
|
|
59020
|
-
if (!
|
|
59021
|
-
const file2 =
|
|
59105
|
+
const { mkdirSync: mkdirSync8, existsSync: existsSync28, readFileSync: readFileSync27, writeFileSync: writeFileSync22 } = await import("node:fs");
|
|
59106
|
+
const { join: join31 } = await import("node:path");
|
|
59107
|
+
const dir = join31(ROOT, ".claude");
|
|
59108
|
+
if (!existsSync28(dir)) mkdirSync8(dir, { recursive: true });
|
|
59109
|
+
const file2 = join31(dir, "settings.json");
|
|
59022
59110
|
let settings = {};
|
|
59023
|
-
if (
|
|
59111
|
+
if (existsSync28(file2)) {
|
|
59024
59112
|
try {
|
|
59025
|
-
settings = JSON.parse(
|
|
59113
|
+
settings = JSON.parse(readFileSync27(file2, "utf8"));
|
|
59026
59114
|
} catch {
|
|
59027
59115
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
59028
59116
|
process.exit(2);
|
|
@@ -59068,10 +59156,10 @@ async function installClaudeHooks(port) {
|
|
|
59068
59156
|
dropErrata(list);
|
|
59069
59157
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
59070
59158
|
}
|
|
59071
|
-
|
|
59159
|
+
writeFileSync22(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
59072
59160
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
59073
59161
|
await installClaudeMcpConfig();
|
|
59074
|
-
const claudeMd =
|
|
59162
|
+
const claudeMd = join31(ROOT, "CLAUDE.md");
|
|
59075
59163
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
59076
59164
|
if (recall.kind === "collision") {
|
|
59077
59165
|
console.warn(
|
|
@@ -59083,15 +59171,15 @@ async function installClaudeHooks(port) {
|
|
|
59083
59171
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
59084
59172
|
}
|
|
59085
59173
|
async function installClaudeMcpConfig() {
|
|
59086
|
-
const { mkdirSync: mkdirSync8, existsSync:
|
|
59087
|
-
const { join:
|
|
59088
|
-
const file2 =
|
|
59174
|
+
const { mkdirSync: mkdirSync8, existsSync: existsSync28, readFileSync: readFileSync27, writeFileSync: writeFileSync22 } = await import("node:fs");
|
|
59175
|
+
const { join: join31, dirname: dirname11 } = await import("node:path");
|
|
59176
|
+
const file2 = join31(ROOT, ".mcp.json");
|
|
59089
59177
|
const dir = dirname11(file2);
|
|
59090
|
-
if (!
|
|
59178
|
+
if (!existsSync28(dir)) mkdirSync8(dir, { recursive: true });
|
|
59091
59179
|
let cfg = {};
|
|
59092
|
-
if (
|
|
59180
|
+
if (existsSync28(file2)) {
|
|
59093
59181
|
try {
|
|
59094
|
-
cfg = JSON.parse(
|
|
59182
|
+
cfg = JSON.parse(readFileSync27(file2, "utf8"));
|
|
59095
59183
|
} catch {
|
|
59096
59184
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
59097
59185
|
process.exit(2);
|
|
@@ -59099,21 +59187,21 @@ async function installClaudeMcpConfig() {
|
|
|
59099
59187
|
}
|
|
59100
59188
|
cfg.mcpServers ??= {};
|
|
59101
59189
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
59102
|
-
|
|
59190
|
+
writeFileSync22(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
59103
59191
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
59104
59192
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
59105
59193
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
59106
59194
|
}
|
|
59107
59195
|
async function installCursorMcpConfig() {
|
|
59108
|
-
const { mkdirSync: mkdirSync8, existsSync:
|
|
59109
|
-
const { join:
|
|
59110
|
-
const dir =
|
|
59111
|
-
if (!
|
|
59112
|
-
const file2 =
|
|
59196
|
+
const { mkdirSync: mkdirSync8, existsSync: existsSync28, readFileSync: readFileSync27, writeFileSync: writeFileSync22 } = await import("node:fs");
|
|
59197
|
+
const { join: join31 } = await import("node:path");
|
|
59198
|
+
const dir = join31(ROOT, ".cursor");
|
|
59199
|
+
if (!existsSync28(dir)) mkdirSync8(dir, { recursive: true });
|
|
59200
|
+
const file2 = join31(dir, "mcp.json");
|
|
59113
59201
|
let cfg = {};
|
|
59114
|
-
if (
|
|
59202
|
+
if (existsSync28(file2)) {
|
|
59115
59203
|
try {
|
|
59116
|
-
cfg = JSON.parse(
|
|
59204
|
+
cfg = JSON.parse(readFileSync27(file2, "utf8"));
|
|
59117
59205
|
} catch {
|
|
59118
59206
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
59119
59207
|
process.exit(2);
|
|
@@ -59121,7 +59209,7 @@ async function installCursorMcpConfig() {
|
|
|
59121
59209
|
}
|
|
59122
59210
|
cfg.mcpServers ??= {};
|
|
59123
59211
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
59124
|
-
|
|
59212
|
+
writeFileSync22(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
59125
59213
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
59126
59214
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
59127
59215
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -59129,16 +59217,16 @@ async function installCursorMcpConfig() {
|
|
|
59129
59217
|
console.log(` \u26A0\uFE0F reload Cursor (Cmd/Ctrl-Shift-P \u2192 "Reload Window") to pick it up.`);
|
|
59130
59218
|
}
|
|
59131
59219
|
async function installCodexHooks(port) {
|
|
59132
|
-
const { mkdirSync: mkdirSync8, existsSync:
|
|
59133
|
-
const { join:
|
|
59134
|
-
const dir =
|
|
59135
|
-
if (!
|
|
59136
|
-
const file2 =
|
|
59220
|
+
const { mkdirSync: mkdirSync8, existsSync: existsSync28, readFileSync: readFileSync27, writeFileSync: writeFileSync22 } = await import("node:fs");
|
|
59221
|
+
const { join: join31 } = await import("node:path");
|
|
59222
|
+
const dir = join31(ROOT, ".codex");
|
|
59223
|
+
if (!existsSync28(dir)) mkdirSync8(dir, { recursive: true });
|
|
59224
|
+
const file2 = join31(dir, "config.toml");
|
|
59137
59225
|
const BEGIN = `# >>> errata hooks (errata-managed)`;
|
|
59138
59226
|
const END = `# <<< errata hooks`;
|
|
59139
59227
|
let existing = "";
|
|
59140
|
-
if (
|
|
59141
|
-
existing =
|
|
59228
|
+
if (existsSync28(file2)) {
|
|
59229
|
+
existing = readFileSync27(file2, "utf8");
|
|
59142
59230
|
const beginIdx = existing.indexOf(BEGIN);
|
|
59143
59231
|
const endIdx = existing.indexOf(END);
|
|
59144
59232
|
if (beginIdx >= 0 && endIdx > beginIdx) {
|
|
@@ -59167,7 +59255,7 @@ ${END}
|
|
|
59167
59255
|
const final = existing.length > 0 && !existing.endsWith("\n") ? `${existing}
|
|
59168
59256
|
|
|
59169
59257
|
${block}` : existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
|
|
59170
|
-
|
|
59258
|
+
writeFileSync22(file2, final, "utf8");
|
|
59171
59259
|
console.log(`installed Codex hooks \u2192 ${file2}`);
|
|
59172
59260
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
59173
59261
|
console.log("");
|
|
@@ -59481,7 +59569,7 @@ async function cmdDash(args2) {
|
|
|
59481
59569
|
await yieldToLoop2();
|
|
59482
59570
|
try {
|
|
59483
59571
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile);
|
|
59484
|
-
const res = bleedRules(
|
|
59572
|
+
const res = bleedRules(join30(r.root, ".claude", "rules"), items);
|
|
59485
59573
|
if (res.written || res.pruned) {
|
|
59486
59574
|
console.log(
|
|
59487
59575
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|