@inerrata-corporation/errata 2.0.0-dev.35 → 2.0.0-dev.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/consolidate-worker.mjs +33 -2
- package/errata.mjs +639 -231
- package/package.json +1 -1
- package/pass-worker.mjs +33 -2
package/errata.mjs
CHANGED
|
@@ -15268,6 +15268,85 @@ var init_edge_rules = __esm({
|
|
|
15268
15268
|
}
|
|
15269
15269
|
});
|
|
15270
15270
|
|
|
15271
|
+
// ../../packages/shared/src/symbol-intent.ts
|
|
15272
|
+
function extractIdentifierTokens(text) {
|
|
15273
|
+
const out2 = [];
|
|
15274
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15275
|
+
for (const m of text.matchAll(TOKEN_RE2)) {
|
|
15276
|
+
if (!seen.has(m[0])) {
|
|
15277
|
+
seen.add(m[0]);
|
|
15278
|
+
out2.push(m[0]);
|
|
15279
|
+
}
|
|
15280
|
+
}
|
|
15281
|
+
return out2;
|
|
15282
|
+
}
|
|
15283
|
+
function summaryRejectionReason(summary, isKnownToken) {
|
|
15284
|
+
if (!summary.trim()) return "empty summary";
|
|
15285
|
+
if (summary.length > MAX_SYMBOL_SUMMARY_CHARS) return "summary too long";
|
|
15286
|
+
if (PATH_SHAPE_RE.test(summary)) return "contains a path shape";
|
|
15287
|
+
if (QUOTED_LITERAL_RE.test(summary.replace(CONTRACTION_RE, "$1$2")))
|
|
15288
|
+
return "contains a quoted literal";
|
|
15289
|
+
for (const tok of extractIdentifierTokens(summary)) {
|
|
15290
|
+
if (isKnownToken(tok)) return `contains verbatim identifier '${tok}'`;
|
|
15291
|
+
if (tok.includes(".")) {
|
|
15292
|
+
const segs = tok.split(".");
|
|
15293
|
+
for (let i2 = 0; i2 < segs.length; i2++) {
|
|
15294
|
+
let span = "";
|
|
15295
|
+
for (let j = i2; j < segs.length; j++) {
|
|
15296
|
+
span = span ? `${span}.${segs[j]}` : segs[j];
|
|
15297
|
+
if (span !== tok && span && isKnownToken(span))
|
|
15298
|
+
return `contains verbatim identifier '${span}'`;
|
|
15299
|
+
}
|
|
15300
|
+
}
|
|
15301
|
+
}
|
|
15302
|
+
}
|
|
15303
|
+
return null;
|
|
15304
|
+
}
|
|
15305
|
+
function substituteSymbolSummaries(text, summaryByToken) {
|
|
15306
|
+
if (summaryByToken.size === 0) return text;
|
|
15307
|
+
const present = extractIdentifierTokens(text).filter((t) => summaryByToken.has(t));
|
|
15308
|
+
present.sort((a, b) => b.length - a.length);
|
|
15309
|
+
let out2 = text;
|
|
15310
|
+
for (const key of present) {
|
|
15311
|
+
const re = new RegExp(`(?<![A-Za-z0-9_$.])${escapeRe2(key)}(?![A-Za-z0-9_$])`, "g");
|
|
15312
|
+
out2 = out2.replace(re, summaryByToken.get(key));
|
|
15313
|
+
}
|
|
15314
|
+
return out2;
|
|
15315
|
+
}
|
|
15316
|
+
function vetSidecarSummaries(sidecar) {
|
|
15317
|
+
if (!sidecar) return null;
|
|
15318
|
+
const keys = new Set(Object.keys(sidecar));
|
|
15319
|
+
if (keys.size === 0 || keys.size > MAX_SIDECAR_SYMBOLS) return null;
|
|
15320
|
+
const clean = /* @__PURE__ */ new Map();
|
|
15321
|
+
for (const [symbol2, entry] of Object.entries(sidecar)) {
|
|
15322
|
+
if (!entry || typeof entry.summary !== "string") continue;
|
|
15323
|
+
if (summaryRejectionReason(entry.summary, (t) => keys.has(t)) !== null) continue;
|
|
15324
|
+
clean.set(symbol2, entry.summary);
|
|
15325
|
+
}
|
|
15326
|
+
return clean.size > 0 ? clean : null;
|
|
15327
|
+
}
|
|
15328
|
+
var SYMBOL_SUMMARY_KINDS, MAX_SYMBOL_SUMMARY_CHARS, MAX_SIDECAR_SYMBOLS, TOKEN_RE2, RE_RESERVED, escapeRe2, PATH_SHAPE_RE, CONTRACTION_RE, QUOTED_LITERAL_RE;
|
|
15329
|
+
var init_symbol_intent = __esm({
|
|
15330
|
+
"../../packages/shared/src/symbol-intent.ts"() {
|
|
15331
|
+
"use strict";
|
|
15332
|
+
SYMBOL_SUMMARY_KINDS = [
|
|
15333
|
+
"function",
|
|
15334
|
+
"method",
|
|
15335
|
+
"class",
|
|
15336
|
+
"interface",
|
|
15337
|
+
"constant"
|
|
15338
|
+
];
|
|
15339
|
+
MAX_SYMBOL_SUMMARY_CHARS = 300;
|
|
15340
|
+
MAX_SIDECAR_SYMBOLS = 200;
|
|
15341
|
+
TOKEN_RE2 = /[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*/g;
|
|
15342
|
+
RE_RESERVED = /[.*+?^${}()|[\]\\]/g;
|
|
15343
|
+
escapeRe2 = (s) => s.replace(RE_RESERVED, "\\$&");
|
|
15344
|
+
PATH_SHAPE_RE = /[\w.~-]+[/\\][\w.$~-]+/;
|
|
15345
|
+
CONTRACTION_RE = /([A-Za-z])'([A-Za-z])/g;
|
|
15346
|
+
QUOTED_LITERAL_RE = /"[^"]+"|'[^']+'|`[^`]+`/;
|
|
15347
|
+
}
|
|
15348
|
+
});
|
|
15349
|
+
|
|
15271
15350
|
// ../../packages/shared/src/wire.ts
|
|
15272
15351
|
function provenanceBand(source) {
|
|
15273
15352
|
switch (source) {
|
|
@@ -15317,13 +15396,14 @@ function summarizeIngestResult(r) {
|
|
|
15317
15396
|
...r.patternReconciliation ? { patternReconciliation: r.patternReconciliation } : {}
|
|
15318
15397
|
};
|
|
15319
15398
|
}
|
|
15320
|
-
var CLOUD_NODE_LABELS, CLOUD_EDGE_TYPES, INGEST_SOURCES, INGEST_EXTRACTION_SOURCES, MAX_NODES_PER_PAYLOAD, MAX_EDGES_PER_PAYLOAD, CastaliaIngestNodeSchema, RouteContextCountWireSchema, CastaliaIngestEdgeSchema, CastaliaIngestPayloadSchema;
|
|
15399
|
+
var CLOUD_NODE_LABELS, CLOUD_EDGE_TYPES, INGEST_SOURCES, INGEST_EXTRACTION_SOURCES, MAX_NODES_PER_PAYLOAD, MAX_EDGES_PER_PAYLOAD, CastaliaIngestNodeSchema, RouteContextCountWireSchema, CastaliaIngestEdgeSchema, SymbolSummarySidecarSchema, CastaliaIngestPayloadSchema;
|
|
15321
15400
|
var init_wire = __esm({
|
|
15322
15401
|
"../../packages/shared/src/wire.ts"() {
|
|
15323
15402
|
"use strict";
|
|
15324
15403
|
init_zod();
|
|
15325
15404
|
init_castalia();
|
|
15326
15405
|
init_edge_rules();
|
|
15406
|
+
init_symbol_intent();
|
|
15327
15407
|
CLOUD_NODE_LABELS = [
|
|
15328
15408
|
...SEMANTIC_NODE_LABELS,
|
|
15329
15409
|
...CONTEXT_NODE_LABELS
|
|
@@ -15373,12 +15453,24 @@ var init_wire = __esm({
|
|
|
15373
15453
|
perContext: external_exports.record(external_exports.string(), RouteContextCountWireSchema).optional()
|
|
15374
15454
|
}).optional()
|
|
15375
15455
|
});
|
|
15456
|
+
SymbolSummarySidecarSchema = external_exports.record(
|
|
15457
|
+
external_exports.string().min(1).max(160),
|
|
15458
|
+
external_exports.object({
|
|
15459
|
+
kind: external_exports.enum(SYMBOL_SUMMARY_KINDS),
|
|
15460
|
+
summary: external_exports.string().min(1).max(MAX_SYMBOL_SUMMARY_CHARS)
|
|
15461
|
+
})
|
|
15462
|
+
).refine((m) => Object.keys(m).length <= MAX_SIDECAR_SYMBOLS, {
|
|
15463
|
+
message: `symbolSummaries sidecar exceeds ${MAX_SIDECAR_SYMBOLS} entries`
|
|
15464
|
+
});
|
|
15376
15465
|
CastaliaIngestPayloadSchema = external_exports.object({
|
|
15377
15466
|
/** Client-supplied UUID — one batch; pairs with the payload digest for replay. */
|
|
15378
15467
|
runId: external_exports.string().uuid(),
|
|
15379
15468
|
source: external_exports.enum(INGEST_SOURCES),
|
|
15380
15469
|
nodes: external_exports.array(CastaliaIngestNodeSchema).max(1e3),
|
|
15381
|
-
edges: external_exports.array(CastaliaIngestEdgeSchema).max(5e3)
|
|
15470
|
+
edges: external_exports.array(CastaliaIngestEdgeSchema).max(5e3),
|
|
15471
|
+
/** Optional symbol→intent-summary sidecar (PP-symbol-intent). Only symbols
|
|
15472
|
+
* present in this payload's node text; server re-vets no-verbatim. */
|
|
15473
|
+
symbolSummaries: SymbolSummarySidecarSchema.optional()
|
|
15382
15474
|
});
|
|
15383
15475
|
}
|
|
15384
15476
|
});
|
|
@@ -15443,12 +15535,16 @@ __export(src_exports, {
|
|
|
15443
15535
|
JUSTIFICATION_EDGES: () => JUSTIFICATION_EDGES,
|
|
15444
15536
|
MAX_EDGES_PER_PAYLOAD: () => MAX_EDGES_PER_PAYLOAD,
|
|
15445
15537
|
MAX_NODES_PER_PAYLOAD: () => MAX_NODES_PER_PAYLOAD,
|
|
15538
|
+
MAX_SIDECAR_SYMBOLS: () => MAX_SIDECAR_SYMBOLS,
|
|
15539
|
+
MAX_SYMBOL_SUMMARY_CHARS: () => MAX_SYMBOL_SUMMARY_CHARS,
|
|
15446
15540
|
PAGERANK_EXCLUSIONS: () => PAGERANK_EXCLUSIONS,
|
|
15447
15541
|
PROBLEM_RESOLUTION: () => PROBLEM_RESOLUTION,
|
|
15448
15542
|
RESOLUTION_EDGES: () => RESOLUTION_EDGES,
|
|
15449
15543
|
RouteContextCountWireSchema: () => RouteContextCountWireSchema,
|
|
15450
15544
|
SEMANTIC_NODE_LABELS: () => SEMANTIC_NODE_LABELS,
|
|
15451
15545
|
STRUCTURAL_EDGES: () => STRUCTURAL_EDGES,
|
|
15546
|
+
SYMBOL_SUMMARY_KINDS: () => SYMBOL_SUMMARY_KINDS,
|
|
15547
|
+
SymbolSummarySidecarSchema: () => SymbolSummarySidecarSchema,
|
|
15452
15548
|
TAXONOMY_EDGES: () => TAXONOMY_EDGES,
|
|
15453
15549
|
TRANSFER_EDGES: () => TRANSFER_EDGES,
|
|
15454
15550
|
TRIAGE_EDGES: () => TRIAGE_EDGES,
|
|
@@ -15468,6 +15564,7 @@ __export(src_exports, {
|
|
|
15468
15564
|
detectStance: () => detectStance,
|
|
15469
15565
|
digest: () => digest,
|
|
15470
15566
|
errorSignatureEqual: () => errorSignatureEqual,
|
|
15567
|
+
extractIdentifierTokens: () => extractIdentifierTokens,
|
|
15471
15568
|
genericCanonicalId: () => genericCanonicalId,
|
|
15472
15569
|
identityId: () => identityId,
|
|
15473
15570
|
isCausalProtected: () => isCausalProtected,
|
|
@@ -15493,9 +15590,12 @@ __export(src_exports, {
|
|
|
15493
15590
|
resolveCanonicalId: () => resolveCanonicalId,
|
|
15494
15591
|
sha256: () => sha256,
|
|
15495
15592
|
sha256Short: () => sha256Short,
|
|
15593
|
+
substituteSymbolSummaries: () => substituteSymbolSummaries,
|
|
15496
15594
|
summarizeIngestResult: () => summarizeIngestResult,
|
|
15595
|
+
summaryRejectionReason: () => summaryRejectionReason,
|
|
15497
15596
|
toCloudAttrs: () => toCloudAttrs,
|
|
15498
|
-
validateCastaliaPayload: () => validateCastaliaPayload
|
|
15597
|
+
validateCastaliaPayload: () => validateCastaliaPayload,
|
|
15598
|
+
vetSidecarSummaries: () => vetSidecarSummaries
|
|
15499
15599
|
});
|
|
15500
15600
|
var init_src = __esm({
|
|
15501
15601
|
"../../packages/shared/src/index.ts"() {
|
|
@@ -15504,6 +15604,7 @@ var init_src = __esm({
|
|
|
15504
15604
|
init_identity();
|
|
15505
15605
|
init_wire();
|
|
15506
15606
|
init_edge_rules();
|
|
15607
|
+
init_symbol_intent();
|
|
15507
15608
|
init_hash();
|
|
15508
15609
|
init_error_signature();
|
|
15509
15610
|
init_canonicalize();
|
|
@@ -17246,7 +17347,7 @@ function buildPackageIndex(store) {
|
|
|
17246
17347
|
}
|
|
17247
17348
|
return idx;
|
|
17248
17349
|
}
|
|
17249
|
-
function
|
|
17350
|
+
function escapeRe3(s) {
|
|
17250
17351
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
17251
17352
|
}
|
|
17252
17353
|
function matchPackagesInText(text, index) {
|
|
@@ -17256,7 +17357,7 @@ function matchPackagesInText(text, index) {
|
|
|
17256
17357
|
for (const [key, node2] of index) {
|
|
17257
17358
|
if (key.length < MIN_NAME_LEN) continue;
|
|
17258
17359
|
if (!hay.includes(key)) continue;
|
|
17259
|
-
const esc3 =
|
|
17360
|
+
const esc3 = escapeRe3(key);
|
|
17260
17361
|
const bounded = new RegExp(`(?<![\\w@/.\\-])${esc3}(?![\\w])`);
|
|
17261
17362
|
if (!bounded.test(hay)) continue;
|
|
17262
17363
|
const verMatch = new RegExp(`${esc3}\\s*@?\\s*v?(\\d+(?:\\.\\d+){0,2})\\b`).exec(hay);
|
|
@@ -20507,6 +20608,38 @@ var init_oauth = __esm({
|
|
|
20507
20608
|
|
|
20508
20609
|
// ../../packages/cloud-client/src/client.ts
|
|
20509
20610
|
import { randomUUID } from "node:crypto";
|
|
20611
|
+
function wirePerContext(value) {
|
|
20612
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
20613
|
+
const out2 = {};
|
|
20614
|
+
for (const [bucket, entry] of Object.entries(value)) {
|
|
20615
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
20616
|
+
const e = entry;
|
|
20617
|
+
const confirmed = asWireCount(e["confirmed"]);
|
|
20618
|
+
if (confirmed === null) continue;
|
|
20619
|
+
const independent = asWireCount(e["independent"]);
|
|
20620
|
+
const inferredIndependent = asWireCount(e["inferredIndependent"]);
|
|
20621
|
+
out2[bucket] = {
|
|
20622
|
+
confirmed,
|
|
20623
|
+
...independent !== null ? { independent } : {},
|
|
20624
|
+
...inferredIndependent !== null ? { inferredIndependent } : {}
|
|
20625
|
+
};
|
|
20626
|
+
}
|
|
20627
|
+
return Object.keys(out2).length > 0 ? out2 : null;
|
|
20628
|
+
}
|
|
20629
|
+
function sidecarForNodes(sidecar, nodes) {
|
|
20630
|
+
if (!sidecar) return void 0;
|
|
20631
|
+
const present = /* @__PURE__ */ new Set();
|
|
20632
|
+
for (const n of nodes) for (const tok of extractIdentifierTokens(n.description)) present.add(tok);
|
|
20633
|
+
const filtered = {};
|
|
20634
|
+
let count = 0;
|
|
20635
|
+
for (const [symbol2, entry] of Object.entries(sidecar)) {
|
|
20636
|
+
if (present.has(symbol2)) {
|
|
20637
|
+
filtered[symbol2] = entry;
|
|
20638
|
+
count++;
|
|
20639
|
+
}
|
|
20640
|
+
}
|
|
20641
|
+
return count > 0 ? filtered : void 0;
|
|
20642
|
+
}
|
|
20510
20643
|
function toWirePayload(batch, runId) {
|
|
20511
20644
|
const nodes = batch.nodes.map((n) => ({
|
|
20512
20645
|
canonicalId: n.id,
|
|
@@ -20517,15 +20650,20 @@ function toWirePayload(batch, runId) {
|
|
|
20517
20650
|
attrs: n.attrs ?? {},
|
|
20518
20651
|
extractionSource: n.extractionSource
|
|
20519
20652
|
}));
|
|
20520
|
-
const edges = batch.edges.map((e) =>
|
|
20521
|
-
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20528
|
-
|
|
20653
|
+
const edges = batch.edges.map((e) => {
|
|
20654
|
+
const perContext = wirePerContext(e.attrs?.["perContext"]);
|
|
20655
|
+
return {
|
|
20656
|
+
fromCanonicalId: e.from,
|
|
20657
|
+
toCanonicalId: e.to,
|
|
20658
|
+
type: e.type,
|
|
20659
|
+
attrs: {
|
|
20660
|
+
...typeof e.confidence === "number" ? { confidence: clamp012(e.confidence) } : {},
|
|
20661
|
+
...perContext ? { perContext } : {}
|
|
20662
|
+
}
|
|
20663
|
+
};
|
|
20664
|
+
});
|
|
20665
|
+
const symbolSummaries = sidecarForNodes(batch.symbolSummaries, nodes);
|
|
20666
|
+
return { runId, source: "daemon", nodes, edges, ...symbolSummaries ? { symbolSummaries } : {} };
|
|
20529
20667
|
}
|
|
20530
20668
|
function clamp012(x) {
|
|
20531
20669
|
return Math.max(0, Math.min(1, x));
|
|
@@ -20536,12 +20674,13 @@ function chunkArray(items, size) {
|
|
|
20536
20674
|
for (let i2 = 0; i2 < items.length; i2 += size) out2.push(items.slice(i2, i2 + size));
|
|
20537
20675
|
return out2;
|
|
20538
20676
|
}
|
|
20539
|
-
var INGEST_NODE_CHUNK, CloudClient, CloudError;
|
|
20677
|
+
var asWireCount, INGEST_NODE_CHUNK, CloudClient, CloudError;
|
|
20540
20678
|
var init_client = __esm({
|
|
20541
20679
|
"../../packages/cloud-client/src/client.ts"() {
|
|
20542
20680
|
"use strict";
|
|
20543
20681
|
init_oauth();
|
|
20544
20682
|
init_src();
|
|
20683
|
+
asWireCount = (n) => typeof n === "number" && Number.isFinite(n) && n >= 0 ? Math.floor(n) : null;
|
|
20545
20684
|
INGEST_NODE_CHUNK = 25;
|
|
20546
20685
|
CloudClient = class {
|
|
20547
20686
|
baseUrl;
|
|
@@ -23939,21 +24078,32 @@ function isDistinctiveIdentifier(name2) {
|
|
|
23939
24078
|
if (/^[A-Z]/.test(name2) && name2.length >= 4) return true;
|
|
23940
24079
|
return name2.length >= 8;
|
|
23941
24080
|
}
|
|
23942
|
-
function buildSymbolLexicon(store) {
|
|
24081
|
+
function buildSymbolLexicon(store, summariesByBodyHash2) {
|
|
23943
24082
|
const lex = /* @__PURE__ */ new Map();
|
|
24083
|
+
const candidates = [];
|
|
23944
24084
|
for (const [label, kind] of SYMBOL_LABELS) {
|
|
23945
24085
|
for (const n of store.findNodesByLabel(label)) {
|
|
24086
|
+
const bodyHash = typeof n.attrs["bodyHash"] === "string" ? n.attrs["bodyHash"] : void 0;
|
|
24087
|
+
const summary = bodyHash ? summariesByBodyHash2?.get(bodyHash) : void 0;
|
|
23946
24088
|
for (const name2 of [n.description, String(n.attrs["qname"] ?? "")]) {
|
|
23947
|
-
if (name2 && isDistinctiveIdentifier(name2))
|
|
24089
|
+
if (name2 && isDistinctiveIdentifier(name2)) {
|
|
24090
|
+
if (!lex.has(name2)) lex.set(name2, { kind });
|
|
24091
|
+
if (summary) candidates.push([name2, summary]);
|
|
24092
|
+
}
|
|
23948
24093
|
}
|
|
23949
24094
|
}
|
|
23950
24095
|
}
|
|
24096
|
+
for (const [name2, summary] of candidates) {
|
|
24097
|
+
if (summaryRejectionReason(summary, (tok) => lex.has(tok)) === null) {
|
|
24098
|
+
lex.get(name2).summary = summary;
|
|
24099
|
+
}
|
|
24100
|
+
}
|
|
23951
24101
|
return lex;
|
|
23952
24102
|
}
|
|
23953
24103
|
function generalizeSymbols(text, lexicon, level = 1) {
|
|
23954
24104
|
const present = [];
|
|
23955
24105
|
const seen = /* @__PURE__ */ new Set();
|
|
23956
|
-
for (const m of text.matchAll(
|
|
24106
|
+
for (const m of text.matchAll(TOKEN_RE3)) {
|
|
23957
24107
|
const tok = m[0];
|
|
23958
24108
|
if (!seen.has(tok) && lexicon.has(tok)) {
|
|
23959
24109
|
seen.add(tok);
|
|
@@ -23963,17 +24113,19 @@ function generalizeSymbols(text, lexicon, level = 1) {
|
|
|
23963
24113
|
present.sort((a, b) => b.length - a.length);
|
|
23964
24114
|
let out2 = text;
|
|
23965
24115
|
for (const key of present) {
|
|
23966
|
-
const
|
|
23967
|
-
const
|
|
24116
|
+
const entry = lexicon.get(key);
|
|
24117
|
+
const phrase = level === 1 && entry.summary ? entry.summary : KIND_PHRASE[entry.kind][level === 1 ? "l1" : "l2"];
|
|
24118
|
+
const re = new RegExp(`(?<![A-Za-z0-9_$.])${escapeRe4(key)}(?![A-Za-z0-9_$])`, "g");
|
|
23968
24119
|
out2 = out2.replace(re, phrase);
|
|
23969
24120
|
}
|
|
23970
24121
|
return generalize(out2, { level }).text;
|
|
23971
24122
|
}
|
|
23972
|
-
var SYMBOL_LABELS, KIND_PHRASE,
|
|
24123
|
+
var SYMBOL_LABELS, KIND_PHRASE, RE_RESERVED2, escapeRe4, TOKEN_RE3;
|
|
23973
24124
|
var init_generalize_graph = __esm({
|
|
23974
24125
|
"src/generalize-graph.ts"() {
|
|
23975
24126
|
"use strict";
|
|
23976
24127
|
init_src8();
|
|
24128
|
+
init_src();
|
|
23977
24129
|
SYMBOL_LABELS = [
|
|
23978
24130
|
["Function", "function"],
|
|
23979
24131
|
["Method", "method"],
|
|
@@ -23988,9 +24140,9 @@ var init_generalize_graph = __esm({
|
|
|
23988
24140
|
interface: { l1: "an interface", l2: "an interface" },
|
|
23989
24141
|
constant: { l1: "a constant", l2: "a value" }
|
|
23990
24142
|
};
|
|
23991
|
-
|
|
23992
|
-
|
|
23993
|
-
|
|
24143
|
+
RE_RESERVED2 = /[.*+?^${}()|[\]\\]/g;
|
|
24144
|
+
escapeRe4 = (s) => s.replace(RE_RESERVED2, "\\$&");
|
|
24145
|
+
TOKEN_RE3 = /[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*/g;
|
|
23994
24146
|
}
|
|
23995
24147
|
});
|
|
23996
24148
|
|
|
@@ -24095,7 +24247,7 @@ async function dualAugment(opts) {
|
|
|
24095
24247
|
let seedProvenance = "local";
|
|
24096
24248
|
const calls = [];
|
|
24097
24249
|
try {
|
|
24098
|
-
const lexicon = buildSymbolLexicon(store);
|
|
24250
|
+
const lexicon = buildSymbolLexicon(store, opts.summaries);
|
|
24099
24251
|
const hardIds = [.../* @__PURE__ */ new Set([...seedNode ? [seedNode.id] : [], ...localHits.map((h) => h.id)])].filter((nid) => {
|
|
24100
24252
|
const n = seedNode && nid === seedNode.id ? seedNode : store.getNode(nid);
|
|
24101
24253
|
return !!n && isHardBridge(n);
|
|
@@ -25920,6 +26072,177 @@ var init_src10 = __esm({
|
|
|
25920
26072
|
}
|
|
25921
26073
|
});
|
|
25922
26074
|
|
|
26075
|
+
// src/symbol-summaries.ts
|
|
26076
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
26077
|
+
import { join as join6 } from "node:path";
|
|
26078
|
+
function symbolSummariesPath(configDir) {
|
|
26079
|
+
return join6(configDir, "symbol-summaries.json");
|
|
26080
|
+
}
|
|
26081
|
+
function loadSymbolSummaryCache(configDir) {
|
|
26082
|
+
const p = symbolSummariesPath(configDir);
|
|
26083
|
+
if (existsSync7(p)) {
|
|
26084
|
+
try {
|
|
26085
|
+
const raw2 = JSON.parse(readFileSync5(p, "utf8"));
|
|
26086
|
+
if (raw2 && raw2.version === 1 && raw2.entries && typeof raw2.entries === "object") {
|
|
26087
|
+
return { version: 1, entries: raw2.entries };
|
|
26088
|
+
}
|
|
26089
|
+
} catch {
|
|
26090
|
+
}
|
|
26091
|
+
}
|
|
26092
|
+
return { version: 1, entries: {} };
|
|
26093
|
+
}
|
|
26094
|
+
function saveSymbolSummaryCache(configDir, cache) {
|
|
26095
|
+
writeFileSync6(symbolSummariesPath(configDir), JSON.stringify(cache, null, 2), "utf8");
|
|
26096
|
+
}
|
|
26097
|
+
function summariesByBodyHash(cache) {
|
|
26098
|
+
const m = /* @__PURE__ */ new Map();
|
|
26099
|
+
for (const [bodyHash, e] of Object.entries(cache.entries)) {
|
|
26100
|
+
if (!e.rejected && typeof e.summary === "string" && e.summary.trim()) m.set(bodyHash, e.summary);
|
|
26101
|
+
}
|
|
26102
|
+
return m;
|
|
26103
|
+
}
|
|
26104
|
+
function parseSummaryJson(text, expected) {
|
|
26105
|
+
const start2 = text.indexOf("[");
|
|
26106
|
+
const end = text.lastIndexOf("]");
|
|
26107
|
+
if (start2 < 0 || end <= start2) return new Array(expected).fill(null);
|
|
26108
|
+
let arr;
|
|
26109
|
+
try {
|
|
26110
|
+
arr = JSON.parse(text.slice(start2, end + 1));
|
|
26111
|
+
} catch {
|
|
26112
|
+
return new Array(expected).fill(null);
|
|
26113
|
+
}
|
|
26114
|
+
if (!Array.isArray(arr)) return new Array(expected).fill(null);
|
|
26115
|
+
const out2 = [];
|
|
26116
|
+
for (let i2 = 0; i2 < expected; i2++) {
|
|
26117
|
+
const v = arr[i2];
|
|
26118
|
+
out2.push(typeof v === "string" && v.trim() ? v.trim().slice(0, MAX_SYMBOL_SUMMARY_CHARS) : null);
|
|
26119
|
+
}
|
|
26120
|
+
return out2;
|
|
26121
|
+
}
|
|
26122
|
+
function haikuIntentSummarizer(apiKey) {
|
|
26123
|
+
if (!apiKey) return void 0;
|
|
26124
|
+
return async (symbols) => {
|
|
26125
|
+
try {
|
|
26126
|
+
const listing = symbols.map(
|
|
26127
|
+
(s, i2) => `### ${i2 + 1}. kind: ${s.kind}
|
|
26128
|
+
name: ${s.name}
|
|
26129
|
+
${s.snippet ? `\`\`\`
|
|
26130
|
+
${s.snippet}
|
|
26131
|
+
\`\`\`` : "(no source available \u2014 describe from the name)"}`
|
|
26132
|
+
).join("\n\n");
|
|
26133
|
+
const resp = await fetch("https://api.anthropic.com/v1/messages", {
|
|
26134
|
+
method: "POST",
|
|
26135
|
+
headers: {
|
|
26136
|
+
"x-api-key": apiKey,
|
|
26137
|
+
"anthropic-version": "2023-06-01",
|
|
26138
|
+
"content-type": "application/json"
|
|
26139
|
+
},
|
|
26140
|
+
body: JSON.stringify({
|
|
26141
|
+
model: SUMMARY_MODEL,
|
|
26142
|
+
max_tokens: 2e3,
|
|
26143
|
+
messages: [{ role: "user", content: `${SUMMARY_PROMPT}
|
|
26144
|
+
|
|
26145
|
+
SYMBOLS:
|
|
26146
|
+
${listing}` }]
|
|
26147
|
+
})
|
|
26148
|
+
});
|
|
26149
|
+
if (!resp.ok) return symbols.map(() => null);
|
|
26150
|
+
const json2 = await resp.json();
|
|
26151
|
+
return parseSummaryJson(json2.content?.find((c) => c.type === "text")?.text ?? "", symbols.length);
|
|
26152
|
+
} catch {
|
|
26153
|
+
return symbols.map(() => null);
|
|
26154
|
+
}
|
|
26155
|
+
};
|
|
26156
|
+
}
|
|
26157
|
+
function envIntentSummarizer() {
|
|
26158
|
+
if (process.env["ERRATA_SYMBOL_SUMMARIES"] !== "1") return void 0;
|
|
26159
|
+
return haikuIntentSummarizer(process.env["ANTHROPIC_API_KEY"] ?? null);
|
|
26160
|
+
}
|
|
26161
|
+
function readSnippet(workspaceRoot, attrs) {
|
|
26162
|
+
const relPath = attrs["relPath"];
|
|
26163
|
+
const startByte = attrs["startByte"];
|
|
26164
|
+
const endByte = attrs["endByte"];
|
|
26165
|
+
if (typeof relPath !== "string" || typeof startByte !== "number" || typeof endByte !== "number") {
|
|
26166
|
+
return void 0;
|
|
26167
|
+
}
|
|
26168
|
+
try {
|
|
26169
|
+
const buf = readFileSync5(join6(workspaceRoot, ...relPath.split("/")));
|
|
26170
|
+
const slice = buf.subarray(Math.max(0, startByte), Math.min(buf.length, endByte));
|
|
26171
|
+
const text = slice.toString("utf8");
|
|
26172
|
+
return text.length > MAX_SNIPPET_CHARS ? text.slice(0, MAX_SNIPPET_CHARS) : text;
|
|
26173
|
+
} catch {
|
|
26174
|
+
return void 0;
|
|
26175
|
+
}
|
|
26176
|
+
}
|
|
26177
|
+
async function runSymbolSummarySweep(store, workspaceRoot, configDir, summarizer, opts = {}) {
|
|
26178
|
+
const maxSymbols = opts.maxSymbols ?? DEFAULT_MAX_SYMBOLS_PER_SWEEP;
|
|
26179
|
+
const batchSize = Math.max(1, opts.batchSize ?? DEFAULT_BATCH_SIZE);
|
|
26180
|
+
const cache = loadSymbolSummaryCache(configDir);
|
|
26181
|
+
const candidates = [];
|
|
26182
|
+
const seen = /* @__PURE__ */ new Set();
|
|
26183
|
+
for (const [label, kind] of SUMMARY_LABELS) {
|
|
26184
|
+
for (const n of store.findNodesByLabel(label)) {
|
|
26185
|
+
const bodyHash = n.attrs["bodyHash"];
|
|
26186
|
+
if (typeof bodyHash !== "string" || !bodyHash || seen.has(bodyHash)) continue;
|
|
26187
|
+
if (cache.entries[bodyHash]) continue;
|
|
26188
|
+
const name2 = n.description;
|
|
26189
|
+
if (!name2 || !isDistinctiveIdentifier(name2)) continue;
|
|
26190
|
+
seen.add(bodyHash);
|
|
26191
|
+
const snippet = readSnippet(workspaceRoot, n.attrs);
|
|
26192
|
+
candidates.push({ bodyHash, name: name2, kind, ...snippet ? { snippet } : {} });
|
|
26193
|
+
}
|
|
26194
|
+
}
|
|
26195
|
+
const todo = candidates.slice(0, maxSymbols);
|
|
26196
|
+
const remaining = candidates.length - todo.length;
|
|
26197
|
+
if (todo.length === 0) return { generated: 0, rejected: 0, remaining };
|
|
26198
|
+
const lexicon = buildSymbolLexicon(store);
|
|
26199
|
+
const isKnown = (tok) => lexicon.has(tok);
|
|
26200
|
+
let generated = 0;
|
|
26201
|
+
let rejected = 0;
|
|
26202
|
+
for (let i2 = 0; i2 < todo.length; i2 += batchSize) {
|
|
26203
|
+
const batch = todo.slice(i2, i2 + batchSize);
|
|
26204
|
+
const phrases = await summarizer(batch);
|
|
26205
|
+
const now = Date.now();
|
|
26206
|
+
for (let j = 0; j < batch.length; j++) {
|
|
26207
|
+
const sym = batch[j];
|
|
26208
|
+
const phrase = phrases[j];
|
|
26209
|
+
if (phrase == null) continue;
|
|
26210
|
+
if (summaryRejectionReason(phrase, isKnown) === null) {
|
|
26211
|
+
cache.entries[sym.bodyHash] = { summary: phrase, model: SUMMARY_MODEL, createdAt: now };
|
|
26212
|
+
generated++;
|
|
26213
|
+
} else {
|
|
26214
|
+
cache.entries[sym.bodyHash] = { rejected: true, model: SUMMARY_MODEL, createdAt: now };
|
|
26215
|
+
rejected++;
|
|
26216
|
+
}
|
|
26217
|
+
}
|
|
26218
|
+
saveSymbolSummaryCache(configDir, cache);
|
|
26219
|
+
}
|
|
26220
|
+
return { generated, rejected, remaining };
|
|
26221
|
+
}
|
|
26222
|
+
var SUMMARY_LABELS, MAX_SNIPPET_CHARS, DEFAULT_MAX_SYMBOLS_PER_SWEEP, DEFAULT_BATCH_SIZE, SUMMARY_MODEL, SUMMARY_PROMPT;
|
|
26223
|
+
var init_symbol_summaries = __esm({
|
|
26224
|
+
"src/symbol-summaries.ts"() {
|
|
26225
|
+
"use strict";
|
|
26226
|
+
init_src();
|
|
26227
|
+
init_generalize_graph();
|
|
26228
|
+
SUMMARY_LABELS = [
|
|
26229
|
+
["Function", "function"],
|
|
26230
|
+
["Method", "method"],
|
|
26231
|
+
["Class", "class"]
|
|
26232
|
+
];
|
|
26233
|
+
MAX_SNIPPET_CHARS = 1500;
|
|
26234
|
+
DEFAULT_MAX_SYMBOLS_PER_SWEEP = 64;
|
|
26235
|
+
DEFAULT_BATCH_SIZE = 16;
|
|
26236
|
+
SUMMARY_MODEL = "claude-haiku-4-5-20251001";
|
|
26237
|
+
SUMMARY_PROMPT = `For each code symbol below, write ONE short English phrase stating its intent/role, shaped like "a <kind> that <does what>" (e.g. "a function that binds the server's listen port").
|
|
26238
|
+
HARD RULES \u2014 a violating phrase is discarded:
|
|
26239
|
+
- NEVER include any identifier, symbol name, variable, type name, file path, or module name from the code \u2014 describe meaning in plain English words only.
|
|
26240
|
+
- NEVER include quoted strings, literals, numbers copied from the code, or code syntax.
|
|
26241
|
+
- One phrase per symbol, under 200 characters, lowercase start, no trailing period.
|
|
26242
|
+
Output a JSON array of strings, one per symbol in the SAME ORDER (use null for a symbol you cannot describe). Output JSON only, no prose.`;
|
|
26243
|
+
}
|
|
26244
|
+
});
|
|
26245
|
+
|
|
25923
26246
|
// ../../packages/indexer/src/simhash.ts
|
|
25924
26247
|
function fnv1a64(s) {
|
|
25925
26248
|
let h = FNV_OFFSET;
|
|
@@ -26143,9 +26466,9 @@ var init_identity2 = __esm({
|
|
|
26143
26466
|
});
|
|
26144
26467
|
|
|
26145
26468
|
// ../../packages/indexer/src/pipeline.ts
|
|
26146
|
-
import { appendFileSync, readFileSync as
|
|
26469
|
+
import { appendFileSync, readFileSync as readFileSync6, statSync } from "node:fs";
|
|
26147
26470
|
import { readdir } from "node:fs/promises";
|
|
26148
|
-
import { extname, join as
|
|
26471
|
+
import { extname, join as join7, relative as relative2, sep } from "node:path";
|
|
26149
26472
|
import { createHash as createHash3 } from "node:crypto";
|
|
26150
26473
|
import { execFileSync } from "node:child_process";
|
|
26151
26474
|
function nowTs() {
|
|
@@ -26261,7 +26584,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
26261
26584
|
for (const rel of [...changedRelPaths]) {
|
|
26262
26585
|
let h;
|
|
26263
26586
|
try {
|
|
26264
|
-
h = createHash3("sha256").update(
|
|
26587
|
+
h = createHash3("sha256").update(readFileSync6(join7(rootPath, rel))).digest("hex");
|
|
26265
26588
|
} catch {
|
|
26266
26589
|
continue;
|
|
26267
26590
|
}
|
|
@@ -26308,13 +26631,13 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
|
|
|
26308
26631
|
let parsedFiles = 0;
|
|
26309
26632
|
for (const rel of changedRelPaths) {
|
|
26310
26633
|
if (parsedFiles++ > 0) await new Promise((r2) => setImmediate(r2));
|
|
26311
|
-
const abs =
|
|
26634
|
+
const abs = join7(rootPath, ...rel.split("/"));
|
|
26312
26635
|
const ext = extname(abs).toLowerCase();
|
|
26313
26636
|
const provider = providers.find((p) => p.fileExtensions.includes(ext));
|
|
26314
26637
|
if (!provider) continue;
|
|
26315
26638
|
let symbols;
|
|
26316
26639
|
try {
|
|
26317
|
-
symbols = provider.extractSymbols(
|
|
26640
|
+
symbols = provider.extractSymbols(readFileSync6(abs, "utf8"), abs);
|
|
26318
26641
|
} catch {
|
|
26319
26642
|
continue;
|
|
26320
26643
|
}
|
|
@@ -26614,7 +26937,7 @@ async function runIndexer(store, opts) {
|
|
|
26614
26937
|
report.filesSkipped++;
|
|
26615
26938
|
continue;
|
|
26616
26939
|
}
|
|
26617
|
-
source =
|
|
26940
|
+
source = readFileSync6(f.absPath, "utf8");
|
|
26618
26941
|
} catch {
|
|
26619
26942
|
report.filesSkipped++;
|
|
26620
26943
|
continue;
|
|
@@ -26666,7 +26989,7 @@ async function runIndexer(store, opts) {
|
|
|
26666
26989
|
const depth = fileNode.relPath.split("/").length;
|
|
26667
26990
|
if (depth !== 3) continue;
|
|
26668
26991
|
try {
|
|
26669
|
-
const pkg = JSON.parse(
|
|
26992
|
+
const pkg = JSON.parse(readFileSync6(fileNode.absPath, "utf8"));
|
|
26670
26993
|
if (!pkg.name) continue;
|
|
26671
26994
|
const pkgDir = fileNode.relPath.replace(/\/package\.json$/, "");
|
|
26672
26995
|
const candidates = [
|
|
@@ -27048,7 +27371,7 @@ async function scan(root, current, ignores, providers, out2) {
|
|
|
27048
27371
|
for (const ent of entries) {
|
|
27049
27372
|
if (ignores.has(ent.name)) continue;
|
|
27050
27373
|
if (ent.name.startsWith(".") && ent.name !== ".") continue;
|
|
27051
|
-
const abs =
|
|
27374
|
+
const abs = join7(current, ent.name);
|
|
27052
27375
|
if (ent.isDirectory()) {
|
|
27053
27376
|
await scan(root, abs, ignores, providers, out2);
|
|
27054
27377
|
} else if (ent.isFile()) {
|
|
@@ -27094,7 +27417,7 @@ function gitListFiles(root, ignores, providers) {
|
|
|
27094
27417
|
if (segs.some((s) => ignores.has(s) || s.startsWith(".") && s.length > 1)) {
|
|
27095
27418
|
continue;
|
|
27096
27419
|
}
|
|
27097
|
-
const abs =
|
|
27420
|
+
const abs = join7(root, rel);
|
|
27098
27421
|
let size;
|
|
27099
27422
|
try {
|
|
27100
27423
|
size = statSync(abs).size;
|
|
@@ -27117,7 +27440,7 @@ function upsertFile(store, id, f, workspaceId2) {
|
|
|
27117
27440
|
const now = nowTs();
|
|
27118
27441
|
let contentHash;
|
|
27119
27442
|
try {
|
|
27120
|
-
contentHash = createHash3("sha256").update(
|
|
27443
|
+
contentHash = createHash3("sha256").update(readFileSync6(f.absPath)).digest("hex");
|
|
27121
27444
|
} catch {
|
|
27122
27445
|
}
|
|
27123
27446
|
const node2 = {
|
|
@@ -31479,8 +31802,8 @@ ${JSON.stringify(symbolNames, null, 2)}`);
|
|
|
31479
31802
|
|
|
31480
31803
|
// ../../packages/indexer/src/languages/tree-sitter-loader.ts
|
|
31481
31804
|
import { fileURLToPath } from "node:url";
|
|
31482
|
-
import { dirname as dirname4, join as
|
|
31483
|
-
import { existsSync as
|
|
31805
|
+
import { dirname as dirname4, join as join8 } from "node:path";
|
|
31806
|
+
import { existsSync as existsSync8, readdirSync as readdirSync2 } from "node:fs";
|
|
31484
31807
|
import { createRequire as createRequire2 } from "node:module";
|
|
31485
31808
|
function entryDir() {
|
|
31486
31809
|
try {
|
|
@@ -31494,27 +31817,27 @@ function entryDir() {
|
|
|
31494
31817
|
}
|
|
31495
31818
|
function findWasmDir() {
|
|
31496
31819
|
const here = entryDir();
|
|
31497
|
-
const seaWasm =
|
|
31498
|
-
if (
|
|
31820
|
+
const seaWasm = join8(here, "resources", "wasm");
|
|
31821
|
+
if (existsSync8(join8(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
|
|
31499
31822
|
let dir = here;
|
|
31500
31823
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
31501
|
-
const flat =
|
|
31824
|
+
const flat = join8(
|
|
31502
31825
|
dir,
|
|
31503
31826
|
"node_modules",
|
|
31504
31827
|
"@vscode",
|
|
31505
31828
|
"tree-sitter-wasm",
|
|
31506
31829
|
"wasm"
|
|
31507
31830
|
);
|
|
31508
|
-
if (
|
|
31831
|
+
if (existsSync8(join8(flat, "tree-sitter-typescript.wasm"))) return flat;
|
|
31509
31832
|
dir = dirname4(dir);
|
|
31510
31833
|
}
|
|
31511
31834
|
let root = here;
|
|
31512
31835
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
31513
|
-
const pnpmDir =
|
|
31514
|
-
if (
|
|
31836
|
+
const pnpmDir = join8(root, "node_modules", ".pnpm");
|
|
31837
|
+
if (existsSync8(pnpmDir)) {
|
|
31515
31838
|
for (const entry of readdirSync2(pnpmDir)) {
|
|
31516
31839
|
if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
|
|
31517
|
-
const candidate =
|
|
31840
|
+
const candidate = join8(
|
|
31518
31841
|
pnpmDir,
|
|
31519
31842
|
entry,
|
|
31520
31843
|
"node_modules",
|
|
@@ -31522,7 +31845,7 @@ function findWasmDir() {
|
|
|
31522
31845
|
"tree-sitter-wasm",
|
|
31523
31846
|
"wasm"
|
|
31524
31847
|
);
|
|
31525
|
-
if (
|
|
31848
|
+
if (existsSync8(join8(candidate, "tree-sitter-typescript.wasm"))) {
|
|
31526
31849
|
return candidate;
|
|
31527
31850
|
}
|
|
31528
31851
|
}
|
|
@@ -31536,27 +31859,27 @@ function findWasmDir() {
|
|
|
31536
31859
|
}
|
|
31537
31860
|
function findRuntimeDir() {
|
|
31538
31861
|
const here = entryDir();
|
|
31539
|
-
const seaRuntime =
|
|
31540
|
-
if (
|
|
31862
|
+
const seaRuntime = join8(here, "resources", "wasm");
|
|
31863
|
+
if (existsSync8(join8(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
|
|
31541
31864
|
let dir = here;
|
|
31542
31865
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
31543
|
-
const flat =
|
|
31544
|
-
if (
|
|
31866
|
+
const flat = join8(dir, "node_modules", "web-tree-sitter");
|
|
31867
|
+
if (existsSync8(join8(flat, "web-tree-sitter.wasm"))) return flat;
|
|
31545
31868
|
dir = dirname4(dir);
|
|
31546
31869
|
}
|
|
31547
31870
|
let root = here;
|
|
31548
31871
|
for (let i2 = 0; i2 < 6; i2++) {
|
|
31549
|
-
const pnpmDir =
|
|
31550
|
-
if (
|
|
31872
|
+
const pnpmDir = join8(root, "node_modules", ".pnpm");
|
|
31873
|
+
if (existsSync8(pnpmDir)) {
|
|
31551
31874
|
for (const entry of readdirSync2(pnpmDir)) {
|
|
31552
31875
|
if (entry.startsWith("web-tree-sitter@")) {
|
|
31553
|
-
const candidate =
|
|
31876
|
+
const candidate = join8(
|
|
31554
31877
|
pnpmDir,
|
|
31555
31878
|
entry,
|
|
31556
31879
|
"node_modules",
|
|
31557
31880
|
"web-tree-sitter"
|
|
31558
31881
|
);
|
|
31559
|
-
if (
|
|
31882
|
+
if (existsSync8(join8(candidate, "web-tree-sitter.wasm"))) {
|
|
31560
31883
|
return candidate;
|
|
31561
31884
|
}
|
|
31562
31885
|
}
|
|
@@ -31573,7 +31896,7 @@ async function loadWebTreeSitter() {
|
|
|
31573
31896
|
void err2;
|
|
31574
31897
|
}
|
|
31575
31898
|
const here = entryDir();
|
|
31576
|
-
const seaResourceBase =
|
|
31899
|
+
const seaResourceBase = join8(here, "resources", "_resolve.js");
|
|
31577
31900
|
const resourceRequire = createRequire2(seaResourceBase);
|
|
31578
31901
|
return resourceRequire("web-tree-sitter");
|
|
31579
31902
|
}
|
|
@@ -31588,9 +31911,9 @@ async function ensureTreeSitterReady() {
|
|
|
31588
31911
|
await Parser2.init({
|
|
31589
31912
|
locateFile: (name2) => {
|
|
31590
31913
|
if (name2 === "tree-sitter.wasm" || name2 === "web-tree-sitter.wasm") {
|
|
31591
|
-
return
|
|
31914
|
+
return join8(runtime, name2);
|
|
31592
31915
|
}
|
|
31593
|
-
return
|
|
31916
|
+
return join8(grammars, name2);
|
|
31594
31917
|
}
|
|
31595
31918
|
});
|
|
31596
31919
|
})();
|
|
@@ -31602,7 +31925,7 @@ async function loadGrammar(name2) {
|
|
|
31602
31925
|
if (cached2) return cached2;
|
|
31603
31926
|
if (!languageClass) throw new Error("tree-sitter not initialized");
|
|
31604
31927
|
const grammars = findWasmDir();
|
|
31605
|
-
const lang = await languageClass.load(
|
|
31928
|
+
const lang = await languageClass.load(join8(grammars, `${name2}.wasm`));
|
|
31606
31929
|
grammarCache.set(name2, lang);
|
|
31607
31930
|
return lang;
|
|
31608
31931
|
}
|
|
@@ -34504,7 +34827,7 @@ var init_src11 = __esm({
|
|
|
34504
34827
|
// src/reconcile.ts
|
|
34505
34828
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
34506
34829
|
import { readdirSync as readdirSync3, statSync as statSync2 } from "node:fs";
|
|
34507
|
-
import { join as
|
|
34830
|
+
import { join as join9, relative as relative3, sep as sep2 } from "node:path";
|
|
34508
34831
|
function gitSourceFiles(root) {
|
|
34509
34832
|
let stdout;
|
|
34510
34833
|
try {
|
|
@@ -34519,7 +34842,7 @@ function gitSourceFiles(root) {
|
|
|
34519
34842
|
const out2 = [];
|
|
34520
34843
|
for (const rel of stdout.split("\0")) {
|
|
34521
34844
|
if (!rel || !SOURCE_RE.test(rel)) continue;
|
|
34522
|
-
const abs =
|
|
34845
|
+
const abs = join9(root, rel);
|
|
34523
34846
|
if (IGNORED.test(abs)) continue;
|
|
34524
34847
|
out2.push(abs);
|
|
34525
34848
|
}
|
|
@@ -34534,7 +34857,7 @@ function* walkSource(dir) {
|
|
|
34534
34857
|
}
|
|
34535
34858
|
for (const e of entries) {
|
|
34536
34859
|
const name2 = String(e.name);
|
|
34537
|
-
const full =
|
|
34860
|
+
const full = join9(dir, name2);
|
|
34538
34861
|
if (IGNORED.test(full)) continue;
|
|
34539
34862
|
if (e.isDirectory()) yield* walkSource(full);
|
|
34540
34863
|
else if (SOURCE_RE.test(name2)) yield full;
|
|
@@ -34612,7 +34935,7 @@ __export(mcp_exports, {
|
|
|
34612
34935
|
runTool: () => runTool,
|
|
34613
34936
|
searchGraph: () => searchGraph
|
|
34614
34937
|
});
|
|
34615
|
-
import { existsSync as
|
|
34938
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
34616
34939
|
import { resolve } from "node:path";
|
|
34617
34940
|
function collectEnrichmentPulls(store, opts = {}) {
|
|
34618
34941
|
const pending = store.findNodesByLabel("Solution").filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
|
|
@@ -34725,10 +35048,10 @@ function showNode(store, node2, maxLines) {
|
|
|
34725
35048
|
if (!relPath) return { found: false, reason: "no file owner for node" };
|
|
34726
35049
|
const workspaceRoot = process.cwd();
|
|
34727
35050
|
const absPath = resolve(workspaceRoot, relPath);
|
|
34728
|
-
if (!
|
|
35051
|
+
if (!existsSync9(absPath)) {
|
|
34729
35052
|
return { found: false, reason: `file not found on disk: ${absPath}` };
|
|
34730
35053
|
}
|
|
34731
|
-
const source =
|
|
35054
|
+
const source = readFileSync7(absPath, "utf8");
|
|
34732
35055
|
const attrs = node2.attrs;
|
|
34733
35056
|
let startByte = attrs["bodyStartByte"] ?? attrs["startByte"];
|
|
34734
35057
|
let endByte = attrs["bodyEndByte"] ?? attrs["endByte"];
|
|
@@ -34941,7 +35264,20 @@ function buildToolContext() {
|
|
|
34941
35264
|
async function runMcpServer(workspaceRoot) {
|
|
34942
35265
|
const paths = workspacePaths(workspaceRoot);
|
|
34943
35266
|
const store = openGraphStore({ path: paths.castalia });
|
|
34944
|
-
|
|
35267
|
+
let summariesMemo = null;
|
|
35268
|
+
const symbolSummaries = () => {
|
|
35269
|
+
const now = Date.now();
|
|
35270
|
+
if (!summariesMemo || now - summariesMemo.at > 6e4) {
|
|
35271
|
+
let map2 = /* @__PURE__ */ new Map();
|
|
35272
|
+
try {
|
|
35273
|
+
map2 = summariesByBodyHash(loadSymbolSummaryCache(paths.configDir));
|
|
35274
|
+
} catch {
|
|
35275
|
+
}
|
|
35276
|
+
summariesMemo = { at: now, map: map2 };
|
|
35277
|
+
}
|
|
35278
|
+
return summariesMemo.map;
|
|
35279
|
+
};
|
|
35280
|
+
const handle2 = createMcpHandler(store, { ...buildToolContext(), symbolSummaries });
|
|
34945
35281
|
process.stdin.setEncoding("utf8");
|
|
34946
35282
|
let buffer = "";
|
|
34947
35283
|
process.stdin.on("data", (chunk) => {
|
|
@@ -34980,6 +35316,7 @@ var init_mcp = __esm({
|
|
|
34980
35316
|
init_src2();
|
|
34981
35317
|
init_src10();
|
|
34982
35318
|
init_paths();
|
|
35319
|
+
init_symbol_summaries();
|
|
34983
35320
|
init_webui();
|
|
34984
35321
|
init_reconcile();
|
|
34985
35322
|
init_agent_signals();
|
|
@@ -35052,7 +35389,14 @@ var init_mcp = __esm({
|
|
|
35052
35389
|
score: h.pageRank,
|
|
35053
35390
|
hops: 0
|
|
35054
35391
|
}));
|
|
35055
|
-
const dual = await dualAugment({
|
|
35392
|
+
const dual = await dualAugment({
|
|
35393
|
+
store,
|
|
35394
|
+
cloud: ctx.cloud,
|
|
35395
|
+
localHits,
|
|
35396
|
+
queryText: query,
|
|
35397
|
+
limit,
|
|
35398
|
+
...ctx.symbolSummaries ? { summaries: ctx.symbolSummaries() } : {}
|
|
35399
|
+
});
|
|
35056
35400
|
if (dual.status === "merged") {
|
|
35057
35401
|
return {
|
|
35058
35402
|
query,
|
|
@@ -35217,7 +35561,8 @@ var init_mcp = __esm({
|
|
|
35217
35561
|
cloud: ctx.cloud,
|
|
35218
35562
|
localHits,
|
|
35219
35563
|
seedNode,
|
|
35220
|
-
limit: args2["limit"] != null ? Number(args2["limit"]) : 20
|
|
35564
|
+
limit: args2["limit"] != null ? Number(args2["limit"]) : 20,
|
|
35565
|
+
...ctx.symbolSummaries ? { summaries: ctx.symbolSummaries() } : {}
|
|
35221
35566
|
});
|
|
35222
35567
|
if (dual.status === "merged") {
|
|
35223
35568
|
return {
|
|
@@ -35732,7 +36077,14 @@ var init_mcp = __esm({
|
|
|
35732
36077
|
score: h.score,
|
|
35733
36078
|
hops: 0
|
|
35734
36079
|
}));
|
|
35735
|
-
const dual = await dualAugment({
|
|
36080
|
+
const dual = await dualAugment({
|
|
36081
|
+
store,
|
|
36082
|
+
cloud: ctx.cloud,
|
|
36083
|
+
localHits,
|
|
36084
|
+
seedNode: node2,
|
|
36085
|
+
limit,
|
|
36086
|
+
...ctx.symbolSummaries ? { summaries: ctx.symbolSummaries() } : {}
|
|
36087
|
+
});
|
|
35736
36088
|
if (dual.status === "merged") {
|
|
35737
36089
|
return {
|
|
35738
36090
|
seedId: id,
|
|
@@ -35923,7 +36275,7 @@ var init_mcp = __esm({
|
|
|
35923
36275
|
inputSchema: { type: "object", properties: {} },
|
|
35924
36276
|
handler: () => {
|
|
35925
36277
|
const path2 = sharedStorePath();
|
|
35926
|
-
if (!
|
|
36278
|
+
if (!existsSync9(path2)) return { count: 0, pending: [] };
|
|
35927
36279
|
const shared = openGraphStore({ path: path2 });
|
|
35928
36280
|
try {
|
|
35929
36281
|
const pending = pendingAbstractions(shared);
|
|
@@ -35954,7 +36306,7 @@ var init_mcp = __esm({
|
|
|
35954
36306
|
},
|
|
35955
36307
|
handler: (args2) => {
|
|
35956
36308
|
const path2 = sharedStorePath();
|
|
35957
|
-
if (!
|
|
36309
|
+
if (!existsSync9(path2)) return { count: 0, routes: [] };
|
|
35958
36310
|
const shared = openGraphStore({ path: path2 });
|
|
35959
36311
|
try {
|
|
35960
36312
|
const result = triageOf(shared, {
|
|
@@ -36339,8 +36691,8 @@ __export(vfile_exports, {
|
|
|
36339
36691
|
resolvePath: () => resolvePath,
|
|
36340
36692
|
segmentsOf: () => segmentsOf
|
|
36341
36693
|
});
|
|
36342
|
-
import { writeFileSync as
|
|
36343
|
-
import { join as
|
|
36694
|
+
import { writeFileSync as writeFileSync7 } from "node:fs";
|
|
36695
|
+
import { join as join10, resolve as resolve2, sep as sep3 } from "node:path";
|
|
36344
36696
|
function segmentsOf(rawPath) {
|
|
36345
36697
|
let p = rawPath.replace(/\\/g, "/");
|
|
36346
36698
|
p = p.replace(/^.*\.errata\/g\//, "").replace(/^\/?g\//, "").replace(/^\/+/, "");
|
|
@@ -36414,14 +36766,14 @@ async function renderVFile(rawPath, store, ctx = {}) {
|
|
|
36414
36766
|
}
|
|
36415
36767
|
async function materializeVFile(rawPath, workspaceRoot, store, ctx = {}) {
|
|
36416
36768
|
const segs = segmentsOf(rawPath);
|
|
36417
|
-
const gRoot =
|
|
36769
|
+
const gRoot = join10(workspaceRoot, ".errata", "g");
|
|
36418
36770
|
const abs = resolve2(gRoot, ...segs.length ? segs : ["index"]);
|
|
36419
36771
|
if (abs !== gRoot && !abs.startsWith(gRoot + sep3)) {
|
|
36420
36772
|
throw new Error(`refusing to materialize outside .errata/g: ${rawPath}`);
|
|
36421
36773
|
}
|
|
36422
36774
|
const text = await renderVFile(rawPath, store, ctx);
|
|
36423
36775
|
ensureParent(abs);
|
|
36424
|
-
|
|
36776
|
+
writeFileSync7(abs, text, "utf8");
|
|
36425
36777
|
return abs;
|
|
36426
36778
|
}
|
|
36427
36779
|
async function materializeOverview(workspaceRoot, store, ctx = {}) {
|
|
@@ -36506,25 +36858,25 @@ the tool surface; the path is the thin, composable channel.
|
|
|
36506
36858
|
|
|
36507
36859
|
// src/outbox.ts
|
|
36508
36860
|
import {
|
|
36509
|
-
existsSync as
|
|
36861
|
+
existsSync as existsSync10,
|
|
36510
36862
|
readdirSync as readdirSync4,
|
|
36511
|
-
readFileSync as
|
|
36863
|
+
readFileSync as readFileSync8,
|
|
36512
36864
|
renameSync,
|
|
36513
36865
|
unlinkSync,
|
|
36514
|
-
writeFileSync as
|
|
36866
|
+
writeFileSync as writeFileSync8
|
|
36515
36867
|
} from "node:fs";
|
|
36516
|
-
import { join as
|
|
36868
|
+
import { join as join11 } from "node:path";
|
|
36517
36869
|
import { createHash as createHash11 } from "node:crypto";
|
|
36518
36870
|
function enqueueOutbox(paths, payload) {
|
|
36519
36871
|
ensureDir(paths.outbox);
|
|
36520
36872
|
const id = createHash11("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
|
|
36521
|
-
const file2 =
|
|
36522
|
-
|
|
36873
|
+
const file2 = join11(paths.outbox, `${Date.now()}-${id}.json`);
|
|
36874
|
+
writeFileSync8(file2, JSON.stringify(payload, null, 2), "utf8");
|
|
36523
36875
|
return file2;
|
|
36524
36876
|
}
|
|
36525
36877
|
async function flushOutbox(paths, client, store) {
|
|
36526
36878
|
ensureDir(paths.outbox);
|
|
36527
|
-
const entries =
|
|
36879
|
+
const entries = existsSync10(paths.outbox) ? readdirSync4(paths.outbox) : [];
|
|
36528
36880
|
let uploaded = 0;
|
|
36529
36881
|
let failed = 0;
|
|
36530
36882
|
const quarantine = (abs, reason) => {
|
|
@@ -36535,10 +36887,10 @@ async function flushOutbox(paths, client, store) {
|
|
|
36535
36887
|
}
|
|
36536
36888
|
};
|
|
36537
36889
|
for (const f of entries.filter((e) => e.endsWith(".json")).sort()) {
|
|
36538
|
-
const abs =
|
|
36890
|
+
const abs = join11(paths.outbox, f);
|
|
36539
36891
|
let payload;
|
|
36540
36892
|
try {
|
|
36541
|
-
payload = JSON.parse(
|
|
36893
|
+
payload = JSON.parse(readFileSync8(abs, "utf8"));
|
|
36542
36894
|
} catch {
|
|
36543
36895
|
failed++;
|
|
36544
36896
|
quarantine(abs, "unparseable JSON");
|
|
@@ -36566,7 +36918,7 @@ async function flushOutbox(paths, client, store) {
|
|
|
36566
36918
|
}
|
|
36567
36919
|
}
|
|
36568
36920
|
}
|
|
36569
|
-
const remainingFiles =
|
|
36921
|
+
const remainingFiles = existsSync10(paths.outbox) ? readdirSync4(paths.outbox).filter((e) => e.endsWith(".json")) : [];
|
|
36570
36922
|
return { uploaded, failed, remaining: remainingFiles.length };
|
|
36571
36923
|
}
|
|
36572
36924
|
var init_outbox = __esm({
|
|
@@ -36585,7 +36937,7 @@ __export(webui_exports, {
|
|
|
36585
36937
|
findFileByPath: () => findFileByPath,
|
|
36586
36938
|
recallForFile: () => recallForFile
|
|
36587
36939
|
});
|
|
36588
|
-
import { join as
|
|
36940
|
+
import { join as join12 } from "node:path";
|
|
36589
36941
|
function fileUriToFsPath(raw2) {
|
|
36590
36942
|
let p = raw2.replace(/^file:\/\//, "").replace(/\\/g, "/");
|
|
36591
36943
|
if (/^\/[A-Za-z]:/.test(p)) p = p.slice(1);
|
|
@@ -36946,7 +37298,7 @@ function buildWebUi(deps) {
|
|
|
36946
37298
|
} catch {
|
|
36947
37299
|
return c.json({});
|
|
36948
37300
|
}
|
|
36949
|
-
const block = readManagedBlockWithHash(
|
|
37301
|
+
const block = readManagedBlockWithHash(join12(deps.paths.root, "AGENTS.md"));
|
|
36950
37302
|
const decision = decideContextInject({
|
|
36951
37303
|
event: String(body2["hook_event_name"] ?? "UserPromptSubmit"),
|
|
36952
37304
|
source: String(body2["source"] ?? ""),
|
|
@@ -37548,12 +37900,12 @@ var init_report_render = __esm({
|
|
|
37548
37900
|
|
|
37549
37901
|
// src/cli.ts
|
|
37550
37902
|
init_src5();
|
|
37551
|
-
import { closeSync as closeSync2, existsSync as
|
|
37552
|
-
import { join as
|
|
37903
|
+
import { closeSync as closeSync2, existsSync as existsSync20, openSync as openSync2, readFileSync as readFileSync19, renameSync as renameSync3, statSync as statSync5 } from "node:fs";
|
|
37904
|
+
import { join as join23 } from "node:path";
|
|
37553
37905
|
import { spawn as spawn3 } from "node:child_process";
|
|
37554
37906
|
|
|
37555
37907
|
// src/daemon.ts
|
|
37556
|
-
import { existsSync as
|
|
37908
|
+
import { existsSync as existsSync16, writeFileSync as writeFileSync13 } from "node:fs";
|
|
37557
37909
|
|
|
37558
37910
|
// ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
|
|
37559
37911
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -38133,8 +38485,8 @@ init_config();
|
|
|
38133
38485
|
|
|
38134
38486
|
// src/engine.ts
|
|
38135
38487
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
38136
|
-
import { existsSync as
|
|
38137
|
-
import { join as
|
|
38488
|
+
import { existsSync as existsSync15, statSync as statSync4, appendFileSync as appendFileSync2, readdirSync as readdirSync7, renameSync as renameSync2, readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "node:fs";
|
|
38489
|
+
import { join as join20, relative as relative6, sep as sep4 } from "node:path";
|
|
38138
38490
|
|
|
38139
38491
|
// ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
|
|
38140
38492
|
import { stat as statcb } from "fs";
|
|
@@ -39996,8 +40348,8 @@ init_src10();
|
|
|
39996
40348
|
init_review2();
|
|
39997
40349
|
|
|
39998
40350
|
// src/turn.ts
|
|
39999
|
-
import { closeSync, existsSync as
|
|
40000
|
-
import { basename as basename3, dirname as dirname7, join as
|
|
40351
|
+
import { closeSync, existsSync as existsSync11, fstatSync, openSync, readdirSync as readdirSync5, readSync, statSync as statSync3 } from "node:fs";
|
|
40352
|
+
import { basename as basename3, dirname as dirname7, join as join15 } from "node:path";
|
|
40001
40353
|
import { homedir as homedir3 } from "node:os";
|
|
40002
40354
|
function readTail(path2, maxBytes) {
|
|
40003
40355
|
let fd;
|
|
@@ -40106,11 +40458,11 @@ function turnsSince(turns, mark) {
|
|
|
40106
40458
|
return at >= 0 ? turns.slice(at + 1) : turns;
|
|
40107
40459
|
}
|
|
40108
40460
|
function claudeProjectDir(cwd, home = homedir3()) {
|
|
40109
|
-
return
|
|
40461
|
+
return join15(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
|
|
40110
40462
|
}
|
|
40111
40463
|
function recentTranscripts(cwd, opts = {}) {
|
|
40112
40464
|
const dir = claudeProjectDir(cwd, opts.home ?? homedir3());
|
|
40113
|
-
if (!
|
|
40465
|
+
if (!existsSync11(dir)) return [];
|
|
40114
40466
|
let names;
|
|
40115
40467
|
try {
|
|
40116
40468
|
names = readdirSync5(dir);
|
|
@@ -40121,7 +40473,7 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
40121
40473
|
const refs = [];
|
|
40122
40474
|
for (const name2 of names) {
|
|
40123
40475
|
if (!name2.endsWith(".jsonl")) continue;
|
|
40124
|
-
const path2 =
|
|
40476
|
+
const path2 = join15(dir, name2);
|
|
40125
40477
|
let mtimeMs;
|
|
40126
40478
|
try {
|
|
40127
40479
|
mtimeMs = statSync3(path2).mtimeMs;
|
|
@@ -40136,8 +40488,8 @@ function recentTranscripts(cwd, opts = {}) {
|
|
|
40136
40488
|
}
|
|
40137
40489
|
function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
40138
40490
|
if (!mainTranscriptPath || !sessionId) return [];
|
|
40139
|
-
const dir =
|
|
40140
|
-
if (!
|
|
40491
|
+
const dir = join15(dirname7(mainTranscriptPath), sessionId, "subagents");
|
|
40492
|
+
if (!existsSync11(dir)) return [];
|
|
40141
40493
|
let names;
|
|
40142
40494
|
try {
|
|
40143
40495
|
names = readdirSync5(dir);
|
|
@@ -40147,7 +40499,7 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
|
40147
40499
|
const refs = [];
|
|
40148
40500
|
for (const name2 of names) {
|
|
40149
40501
|
if (!name2.endsWith(".jsonl")) continue;
|
|
40150
|
-
const path2 =
|
|
40502
|
+
const path2 = join15(dir, name2);
|
|
40151
40503
|
let mtimeMs;
|
|
40152
40504
|
try {
|
|
40153
40505
|
mtimeMs = statSync3(path2).mtimeMs;
|
|
@@ -40164,7 +40516,7 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
|
|
|
40164
40516
|
init_src();
|
|
40165
40517
|
init_src2();
|
|
40166
40518
|
init_agent_signals();
|
|
40167
|
-
import { readFileSync as
|
|
40519
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
40168
40520
|
var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
|
|
40169
40521
|
var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
|
|
40170
40522
|
var HANDLE_RE = /\[([a-z0-9][\w-]{0,40})\]|((?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})/gi;
|
|
@@ -40414,13 +40766,13 @@ function writePrimingHandles(path2, nodes, now = Date.now()) {
|
|
|
40414
40766
|
entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
|
|
40415
40767
|
entries.length = HANDLE_MAP_MAX;
|
|
40416
40768
|
}
|
|
40417
|
-
|
|
40769
|
+
writeFileSync9(path2, JSON.stringify(Object.fromEntries(entries)));
|
|
40418
40770
|
} catch {
|
|
40419
40771
|
}
|
|
40420
40772
|
}
|
|
40421
40773
|
function readPrimingHandles(path2) {
|
|
40422
40774
|
try {
|
|
40423
|
-
return JSON.parse(
|
|
40775
|
+
return JSON.parse(readFileSync9(path2, "utf8"));
|
|
40424
40776
|
} catch {
|
|
40425
40777
|
return {};
|
|
40426
40778
|
}
|
|
@@ -40676,6 +41028,7 @@ ${conversation}` }]
|
|
|
40676
41028
|
}
|
|
40677
41029
|
|
|
40678
41030
|
// src/engine.ts
|
|
41031
|
+
init_symbol_summaries();
|
|
40679
41032
|
init_reconcile();
|
|
40680
41033
|
|
|
40681
41034
|
// src/episode.ts
|
|
@@ -40872,11 +41225,11 @@ init_outbox();
|
|
|
40872
41225
|
init_src8();
|
|
40873
41226
|
init_src();
|
|
40874
41227
|
init_src2();
|
|
40875
|
-
import { readFileSync as
|
|
40876
|
-
import { join as
|
|
41228
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
41229
|
+
import { join as join16 } from "node:path";
|
|
40877
41230
|
function loadClaimIgnorePatterns(workspaceRoot) {
|
|
40878
41231
|
try {
|
|
40879
|
-
return
|
|
41232
|
+
return readFileSync10(join16(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
|
|
40880
41233
|
} catch {
|
|
40881
41234
|
return [];
|
|
40882
41235
|
}
|
|
@@ -41067,13 +41420,21 @@ function isSyncableRoute(edge2, shared, triage, ignorePatterns = []) {
|
|
|
41067
41420
|
function generalizeRouteForSync(edge2, level) {
|
|
41068
41421
|
const disc = edge2.attrs["discriminator"];
|
|
41069
41422
|
const local = edge2.attrs["perContext"] ?? {};
|
|
41070
|
-
const
|
|
41071
|
-
for (const [b, c] of Object.entries(local))
|
|
41423
|
+
const perContext = {};
|
|
41424
|
+
for (const [b, c] of Object.entries(local)) {
|
|
41425
|
+
const independent = c.independent ?? c.contributors?.length;
|
|
41426
|
+
const inferredIndependent = c.inferredIndependent ?? c.inferredContributors?.length;
|
|
41427
|
+
perContext[b] = {
|
|
41428
|
+
confirmed: c.confirmed,
|
|
41429
|
+
...typeof independent === "number" && independent > 0 ? { independent } : {},
|
|
41430
|
+
...typeof inferredIndependent === "number" && inferredIndependent > 0 ? { inferredIndependent } : {}
|
|
41431
|
+
};
|
|
41432
|
+
}
|
|
41072
41433
|
return {
|
|
41073
41434
|
...edge2,
|
|
41074
41435
|
attrs: {
|
|
41075
41436
|
driftKind: edge2.attrs["driftKind"],
|
|
41076
|
-
perContext
|
|
41437
|
+
perContext,
|
|
41077
41438
|
provisional: false,
|
|
41078
41439
|
...typeof disc === "string" && disc.trim() ? { discriminator: generalize(disc, { level }).text } : {}
|
|
41079
41440
|
},
|
|
@@ -41168,22 +41529,22 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
|
|
|
41168
41529
|
}
|
|
41169
41530
|
|
|
41170
41531
|
// src/git-sensor.ts
|
|
41171
|
-
import { existsSync as
|
|
41172
|
-
import { join as
|
|
41532
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11, watch as fsWatch } from "node:fs";
|
|
41533
|
+
import { join as join17 } from "node:path";
|
|
41173
41534
|
function readFirstLine(path2) {
|
|
41174
41535
|
try {
|
|
41175
|
-
return
|
|
41536
|
+
return readFileSync11(path2, "utf8").split(/\r?\n/, 1)[0].trim();
|
|
41176
41537
|
} catch {
|
|
41177
41538
|
return null;
|
|
41178
41539
|
}
|
|
41179
41540
|
}
|
|
41180
41541
|
function readGitRefState(gitDir) {
|
|
41181
|
-
const head2 = readFirstLine(
|
|
41542
|
+
const head2 = readFirstLine(join17(gitDir, "HEAD"));
|
|
41182
41543
|
const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
|
|
41183
41544
|
const branch = m ? m[1] : null;
|
|
41184
41545
|
let sha2 = null;
|
|
41185
41546
|
if (branch) {
|
|
41186
|
-
sha2 = readFirstLine(
|
|
41547
|
+
sha2 = readFirstLine(join17(gitDir, "refs", "heads", branch));
|
|
41187
41548
|
if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
|
|
41188
41549
|
} else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
|
|
41189
41550
|
sha2 = head2;
|
|
@@ -41191,13 +41552,13 @@ function readGitRefState(gitDir) {
|
|
|
41191
41552
|
return {
|
|
41192
41553
|
branch,
|
|
41193
41554
|
sha: sha2,
|
|
41194
|
-
mergeHeadExists:
|
|
41195
|
-
origHeadExists:
|
|
41555
|
+
mergeHeadExists: existsSync12(join17(gitDir, "MERGE_HEAD")),
|
|
41556
|
+
origHeadExists: existsSync12(join17(gitDir, "ORIG_HEAD"))
|
|
41196
41557
|
};
|
|
41197
41558
|
}
|
|
41198
41559
|
function shaFromPackedRefs(gitDir, ref) {
|
|
41199
41560
|
try {
|
|
41200
|
-
for (const line of
|
|
41561
|
+
for (const line of readFileSync11(join17(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
|
|
41201
41562
|
const [sha2, name2] = line.split(/\s+/);
|
|
41202
41563
|
if (name2 === ref && sha2) return sha2;
|
|
41203
41564
|
}
|
|
@@ -41231,7 +41592,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
41231
41592
|
const settle = () => {
|
|
41232
41593
|
if (timer) clearTimeout(timer);
|
|
41233
41594
|
timer = setTimeout(() => {
|
|
41234
|
-
if (
|
|
41595
|
+
if (existsSync12(join17(gitDir, "index.lock"))) {
|
|
41235
41596
|
settle();
|
|
41236
41597
|
return;
|
|
41237
41598
|
}
|
|
@@ -41242,7 +41603,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
|
|
|
41242
41603
|
}, debounceMs);
|
|
41243
41604
|
};
|
|
41244
41605
|
for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
|
|
41245
|
-
const p =
|
|
41606
|
+
const p = join17(gitDir, sub);
|
|
41246
41607
|
try {
|
|
41247
41608
|
watchers.push(fsWatch(p, settle));
|
|
41248
41609
|
} catch {
|
|
@@ -41467,21 +41828,21 @@ var TelemetryRecorder = class {
|
|
|
41467
41828
|
|
|
41468
41829
|
// src/skills.ts
|
|
41469
41830
|
import {
|
|
41470
|
-
existsSync as
|
|
41831
|
+
existsSync as existsSync13,
|
|
41471
41832
|
mkdirSync as mkdirSync5,
|
|
41472
|
-
readFileSync as
|
|
41833
|
+
readFileSync as readFileSync12,
|
|
41473
41834
|
readdirSync as readdirSync6,
|
|
41474
41835
|
unlinkSync as unlinkSync2,
|
|
41475
|
-
writeFileSync as
|
|
41836
|
+
writeFileSync as writeFileSync10
|
|
41476
41837
|
} from "node:fs";
|
|
41477
|
-
import { basename as basename4, join as
|
|
41838
|
+
import { basename as basename4, join as join18 } from "node:path";
|
|
41478
41839
|
function skillFileName(id) {
|
|
41479
41840
|
return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
|
|
41480
41841
|
}
|
|
41481
41842
|
function readSkillManifest(manifestPath) {
|
|
41482
|
-
if (!
|
|
41843
|
+
if (!existsSync13(manifestPath)) return [];
|
|
41483
41844
|
try {
|
|
41484
|
-
const parsed = JSON.parse(
|
|
41845
|
+
const parsed = JSON.parse(readFileSync12(manifestPath, "utf8"));
|
|
41485
41846
|
return (parsed.skills ?? []).map((s) => ({
|
|
41486
41847
|
title: s.title ?? "",
|
|
41487
41848
|
layer: s.layer ?? "technique",
|
|
@@ -41504,7 +41865,7 @@ async function syncSkills(paths, client, seed) {
|
|
|
41504
41865
|
for (const s of res.skills) {
|
|
41505
41866
|
const fileName = skillFileName(s.id);
|
|
41506
41867
|
keep.add(fileName);
|
|
41507
|
-
|
|
41868
|
+
writeFileSync10(join18(paths.skillsDir, fileName), s.markdown, "utf8");
|
|
41508
41869
|
rows.push({
|
|
41509
41870
|
id: s.id,
|
|
41510
41871
|
title: s.title,
|
|
@@ -41518,13 +41879,13 @@ async function syncSkills(paths, client, seed) {
|
|
|
41518
41879
|
if (!f.endsWith(".md")) continue;
|
|
41519
41880
|
if (keep.has(basename4(f))) continue;
|
|
41520
41881
|
try {
|
|
41521
|
-
unlinkSync2(
|
|
41882
|
+
unlinkSync2(join18(paths.skillsDir, f));
|
|
41522
41883
|
pruned++;
|
|
41523
41884
|
} catch {
|
|
41524
41885
|
}
|
|
41525
41886
|
}
|
|
41526
41887
|
rows.sort((a, b) => a.id.localeCompare(b.id));
|
|
41527
|
-
|
|
41888
|
+
writeFileSync10(
|
|
41528
41889
|
paths.skillsManifest,
|
|
41529
41890
|
JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
|
|
41530
41891
|
"utf8"
|
|
@@ -41661,30 +42022,30 @@ var CausalBuffer = class {
|
|
|
41661
42022
|
// src/profile.ts
|
|
41662
42023
|
init_src2();
|
|
41663
42024
|
init_paths();
|
|
41664
|
-
import { existsSync as
|
|
42025
|
+
import { existsSync as existsSync14, readFileSync as readFileSync13, writeFileSync as writeFileSync11 } from "node:fs";
|
|
41665
42026
|
import { createHash as createHash12 } from "node:crypto";
|
|
41666
|
-
import { join as
|
|
42027
|
+
import { join as join19 } from "node:path";
|
|
41667
42028
|
function workspaceId(root) {
|
|
41668
42029
|
return "wp_" + createHash12("sha256").update(root).digest("hex").slice(0, 12);
|
|
41669
42030
|
}
|
|
41670
42031
|
function loadProfile(root) {
|
|
41671
42032
|
const p = workspacePaths(root);
|
|
41672
|
-
if (!
|
|
41673
|
-
return JSON.parse(
|
|
42033
|
+
if (!existsSync14(p.workspaceJson)) return null;
|
|
42034
|
+
return JSON.parse(readFileSync13(p.workspaceJson, "utf8"));
|
|
41674
42035
|
}
|
|
41675
42036
|
function saveProfile(root, profile) {
|
|
41676
42037
|
const p = workspacePaths(root);
|
|
41677
42038
|
ensureDir(p.configDir);
|
|
41678
|
-
|
|
42039
|
+
writeFileSync11(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
|
|
41679
42040
|
}
|
|
41680
42041
|
function autodetectProfile(root) {
|
|
41681
42042
|
const id = workspaceId(root);
|
|
41682
42043
|
const name2 = root.split(/[\\/]/).filter(Boolean).pop() ?? "workspace";
|
|
41683
42044
|
const p = emptyProfile(id, name2);
|
|
41684
|
-
const pkgPath =
|
|
41685
|
-
if (
|
|
42045
|
+
const pkgPath = join19(root, "package.json");
|
|
42046
|
+
if (existsSync14(pkgPath)) {
|
|
41686
42047
|
try {
|
|
41687
|
-
const pkg = JSON.parse(
|
|
42048
|
+
const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
|
|
41688
42049
|
p.languages.push("typescript", "javascript");
|
|
41689
42050
|
const nodeVer = pkg.engines?.node ?? "node";
|
|
41690
42051
|
p.stack.push(`node@${nodeVer}`);
|
|
@@ -41705,10 +42066,10 @@ function autodetectProfile(root) {
|
|
|
41705
42066
|
} catch {
|
|
41706
42067
|
}
|
|
41707
42068
|
}
|
|
41708
|
-
const pyproject =
|
|
41709
|
-
if (
|
|
42069
|
+
const pyproject = join19(root, "pyproject.toml");
|
|
42070
|
+
if (existsSync14(pyproject)) {
|
|
41710
42071
|
try {
|
|
41711
|
-
const txt =
|
|
42072
|
+
const txt = readFileSync13(pyproject, "utf8");
|
|
41712
42073
|
const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
|
|
41713
42074
|
p.languages.push("python");
|
|
41714
42075
|
p.stack.push(`python@${py ?? "3"}`);
|
|
@@ -41719,16 +42080,16 @@ function autodetectProfile(root) {
|
|
|
41719
42080
|
} catch {
|
|
41720
42081
|
}
|
|
41721
42082
|
}
|
|
41722
|
-
const reqs =
|
|
41723
|
-
if (
|
|
42083
|
+
const reqs = join19(root, "requirements.txt");
|
|
42084
|
+
if (existsSync14(reqs)) {
|
|
41724
42085
|
if (!p.languages.includes("python")) p.languages.push("python");
|
|
41725
42086
|
if (!p.stack.includes("python@3")) p.stack.push("python@3");
|
|
41726
42087
|
}
|
|
41727
|
-
if (
|
|
42088
|
+
if (existsSync14(join19(root, "go.mod"))) {
|
|
41728
42089
|
p.languages.push("go");
|
|
41729
42090
|
p.stack.push("go");
|
|
41730
42091
|
}
|
|
41731
|
-
if (
|
|
42092
|
+
if (existsSync14(join19(root, "Cargo.toml"))) {
|
|
41732
42093
|
p.languages.push("rust");
|
|
41733
42094
|
p.stack.push("rust");
|
|
41734
42095
|
}
|
|
@@ -41886,7 +42247,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
|
|
|
41886
42247
|
}
|
|
41887
42248
|
|
|
41888
42249
|
// src/engine.ts
|
|
41889
|
-
var DAEMON_VERSION = true ? "2.0.0-dev.
|
|
42250
|
+
var DAEMON_VERSION = true ? "2.0.0-dev.37" : "2.0.0-alpha.0";
|
|
41890
42251
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
41891
42252
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
41892
42253
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -41896,7 +42257,7 @@ var TURN_REPLAY_LOOKBACK_MS = 7 * 24 * 60 * 6e4;
|
|
|
41896
42257
|
function appendIdentityAudit(path2, record2, line) {
|
|
41897
42258
|
if (!record2.accepted && record2.score <= 0) return;
|
|
41898
42259
|
try {
|
|
41899
|
-
if (
|
|
42260
|
+
if (existsSync15(path2) && statSync4(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
|
|
41900
42261
|
renameSync2(path2, `${path2}.1`);
|
|
41901
42262
|
}
|
|
41902
42263
|
appendFileSync2(path2, line);
|
|
@@ -41906,14 +42267,14 @@ function appendIdentityAudit(path2, record2, line) {
|
|
|
41906
42267
|
var yieldToLoop = () => new Promise((r) => setImmediate(r));
|
|
41907
42268
|
function loadTurnCursors(path2) {
|
|
41908
42269
|
try {
|
|
41909
|
-
return new Map(Object.entries(JSON.parse(
|
|
42270
|
+
return new Map(Object.entries(JSON.parse(readFileSync14(path2, "utf8"))));
|
|
41910
42271
|
} catch {
|
|
41911
42272
|
return /* @__PURE__ */ new Map();
|
|
41912
42273
|
}
|
|
41913
42274
|
}
|
|
41914
42275
|
function saveTurnCursors(path2, cursors) {
|
|
41915
42276
|
try {
|
|
41916
|
-
|
|
42277
|
+
writeFileSync12(path2, JSON.stringify(Object.fromEntries(cursors)), "utf8");
|
|
41917
42278
|
} catch {
|
|
41918
42279
|
}
|
|
41919
42280
|
}
|
|
@@ -41935,7 +42296,7 @@ function gitSourceWatchTargets(root) {
|
|
|
41935
42296
|
["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
|
|
41936
42297
|
{ encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
|
|
41937
42298
|
);
|
|
41938
|
-
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(
|
|
42299
|
+
ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join20(root, d) + sep4));
|
|
41939
42300
|
} catch {
|
|
41940
42301
|
}
|
|
41941
42302
|
const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
|
|
@@ -41947,19 +42308,19 @@ function gitSourceWatchTargets(root) {
|
|
|
41947
42308
|
if (!f.startsWith(prefix)) continue;
|
|
41948
42309
|
const rest2 = f.slice(prefix.length);
|
|
41949
42310
|
if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
|
|
41950
|
-
else targets.add(
|
|
42311
|
+
else targets.add(join20(root, f));
|
|
41951
42312
|
}
|
|
41952
42313
|
for (const c of children) {
|
|
41953
|
-
if (IGNORED_PATH.test(
|
|
42314
|
+
if (IGNORED_PATH.test(join20(root, c) + sep4)) continue;
|
|
41954
42315
|
if (hasIgnoredChild(c)) addUnder(c);
|
|
41955
|
-
else targets.add(
|
|
42316
|
+
else targets.add(join20(root, c));
|
|
41956
42317
|
}
|
|
41957
42318
|
};
|
|
41958
42319
|
addUnder("");
|
|
41959
42320
|
if (targets.size > 0) return [...targets];
|
|
41960
42321
|
} catch {
|
|
41961
42322
|
}
|
|
41962
|
-
return readdirSync7(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(
|
|
42323
|
+
return readdirSync7(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join20(root, String(e.name)) + sep4)).map((e) => join20(root, String(e.name)));
|
|
41963
42324
|
}
|
|
41964
42325
|
function createWorkspaceEngine(opts) {
|
|
41965
42326
|
const paths = workspacePaths(opts.workspaceRoot);
|
|
@@ -42111,7 +42472,7 @@ function createWorkspaceEngine(opts) {
|
|
|
42111
42472
|
const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
|
|
42112
42473
|
let episodeId2;
|
|
42113
42474
|
if (srcPaths.length > 0) {
|
|
42114
|
-
const abs = srcPaths.map((p) =>
|
|
42475
|
+
const abs = srcPaths.map((p) => join20(opts.workspaceRoot, p));
|
|
42115
42476
|
try {
|
|
42116
42477
|
const r = await runReindexPass(
|
|
42117
42478
|
`git-reindex:${profile.name} (${abs.length} files)`,
|
|
@@ -42142,8 +42503,8 @@ function createWorkspaceEngine(opts) {
|
|
|
42142
42503
|
`[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
|
|
42143
42504
|
);
|
|
42144
42505
|
};
|
|
42145
|
-
const gitDir =
|
|
42146
|
-
if (
|
|
42506
|
+
const gitDir = join20(opts.workspaceRoot, ".git");
|
|
42507
|
+
if (existsSync15(gitDir)) {
|
|
42147
42508
|
stopGit = startGitSensor(gitDir, (ev) => {
|
|
42148
42509
|
void handleGitEvent(ev);
|
|
42149
42510
|
});
|
|
@@ -42209,10 +42570,10 @@ function createWorkspaceEngine(opts) {
|
|
|
42209
42570
|
...pendingUpdate ? { pendingUpdate } : {}
|
|
42210
42571
|
});
|
|
42211
42572
|
doneRender?.();
|
|
42212
|
-
const target =
|
|
42573
|
+
const target = join20(opts.workspaceRoot, "AGENTS.md");
|
|
42213
42574
|
writeManagedBlock(target, { body: body2 });
|
|
42214
42575
|
if (elicit) {
|
|
42215
|
-
writePrimingHandles(
|
|
42576
|
+
writePrimingHandles(join20(paths.configDir, "priming-handles.json"), [
|
|
42216
42577
|
...snapshot.recentProblems.map((r) => r.node),
|
|
42217
42578
|
// Resolved-band handles: the ✓ problem AND its Solution are citable
|
|
42218
42579
|
// (a fix tag on an already-resolved problem no-ops idempotently; the
|
|
@@ -42382,7 +42743,7 @@ function createWorkspaceEngine(opts) {
|
|
|
42382
42743
|
resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
|
|
42383
42744
|
});
|
|
42384
42745
|
};
|
|
42385
|
-
const turnCursorPath =
|
|
42746
|
+
const turnCursorPath = join20(paths.configDir, "turn-cursors.json");
|
|
42386
42747
|
const lastTurnUuid = loadTurnCursors(turnCursorPath);
|
|
42387
42748
|
const sessionLastProblem = /* @__PURE__ */ new Map();
|
|
42388
42749
|
const sessionThreads = /* @__PURE__ */ new Map();
|
|
@@ -42405,7 +42766,7 @@ function createWorkspaceEngine(opts) {
|
|
|
42405
42766
|
const t = Date.now();
|
|
42406
42767
|
let processedTurns = 0;
|
|
42407
42768
|
const elicit = isEdgeElicitationEnabled();
|
|
42408
|
-
const handleMap = elicit ? readPrimingHandles(
|
|
42769
|
+
const handleMap = elicit ? readPrimingHandles(join20(paths.configDir, "priming-handles.json")) : {};
|
|
42409
42770
|
const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
|
|
42410
42771
|
const toRel = (abs) => {
|
|
42411
42772
|
const p = abs.replace(/\\/g, "/");
|
|
@@ -42922,7 +43283,21 @@ function createWorkspaceEngine(opts) {
|
|
|
42922
43283
|
return report;
|
|
42923
43284
|
},
|
|
42924
43285
|
async nightly() {
|
|
42925
|
-
|
|
43286
|
+
const report = (await runNightly()).report;
|
|
43287
|
+
const summarizer = opts.intentSummarizer ?? envIntentSummarizer();
|
|
43288
|
+
if (summarizer) {
|
|
43289
|
+
try {
|
|
43290
|
+
const s = await runSymbolSummarySweep(store, opts.workspaceRoot, paths.configDir, summarizer);
|
|
43291
|
+
if (s.generated > 0 || s.rejected > 0) {
|
|
43292
|
+
console.log(
|
|
43293
|
+
`[errata] symbol summaries: +${s.generated}${s.rejected > 0 ? ` (${s.rejected} rejected by no-verbatim check)` : ""}${s.remaining > 0 ? `, ${s.remaining} pending` : ""}`
|
|
43294
|
+
);
|
|
43295
|
+
}
|
|
43296
|
+
} catch (err2) {
|
|
43297
|
+
console.warn("[errata] symbol summary sweep failed:", err2 instanceof Error ? err2.message : err2);
|
|
43298
|
+
}
|
|
43299
|
+
}
|
|
43300
|
+
return report;
|
|
42926
43301
|
},
|
|
42927
43302
|
async embedSettled() {
|
|
42928
43303
|
try {
|
|
@@ -43010,7 +43385,7 @@ function createWorkspaceEngine(opts) {
|
|
|
43010
43385
|
console.log(
|
|
43011
43386
|
"[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
|
|
43012
43387
|
);
|
|
43013
|
-
const pending =
|
|
43388
|
+
const pending = existsSync15(paths.outbox) ? readdirSync7(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
|
|
43014
43389
|
return { uploaded: 0, failed: 0, remaining: pending };
|
|
43015
43390
|
}
|
|
43016
43391
|
try {
|
|
@@ -43097,7 +43472,7 @@ async function startDaemon(opts) {
|
|
|
43097
43472
|
reviewUrl: () => webUiUrl + "/review"
|
|
43098
43473
|
});
|
|
43099
43474
|
const writeLockFile = (url2) => {
|
|
43100
|
-
|
|
43475
|
+
writeFileSync13(
|
|
43101
43476
|
engine.paths.daemonLock,
|
|
43102
43477
|
JSON.stringify({ pid: process.pid, webUiUrl: url2, startedAt: Date.now() }),
|
|
43103
43478
|
"utf8"
|
|
@@ -43140,7 +43515,7 @@ async function startDaemon(opts) {
|
|
|
43140
43515
|
);
|
|
43141
43516
|
await engine.stop();
|
|
43142
43517
|
try {
|
|
43143
|
-
if (
|
|
43518
|
+
if (existsSync16(engine.paths.daemonLock)) {
|
|
43144
43519
|
}
|
|
43145
43520
|
} catch {
|
|
43146
43521
|
}
|
|
@@ -43157,16 +43532,16 @@ async function listenServer(fetchFn, port) {
|
|
|
43157
43532
|
|
|
43158
43533
|
// src/registry.ts
|
|
43159
43534
|
init_paths();
|
|
43160
|
-
import { existsSync as
|
|
43161
|
-
import { join as
|
|
43535
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15, writeFileSync as writeFileSync14 } from "node:fs";
|
|
43536
|
+
import { join as join21 } from "node:path";
|
|
43162
43537
|
function registryPath() {
|
|
43163
|
-
return process.env["ERRATA_REGISTRY_PATH"] ??
|
|
43538
|
+
return process.env["ERRATA_REGISTRY_PATH"] ?? join21(globalDir(), "workspaces.json");
|
|
43164
43539
|
}
|
|
43165
43540
|
function read() {
|
|
43166
43541
|
const p = registryPath();
|
|
43167
|
-
if (!
|
|
43542
|
+
if (!existsSync17(p)) return { version: 1, workspaces: {} };
|
|
43168
43543
|
try {
|
|
43169
|
-
const parsed = JSON.parse(
|
|
43544
|
+
const parsed = JSON.parse(readFileSync15(p, "utf8"));
|
|
43170
43545
|
return { version: 1, workspaces: parsed.workspaces ?? {} };
|
|
43171
43546
|
} catch {
|
|
43172
43547
|
return { version: 1, workspaces: {} };
|
|
@@ -43174,7 +43549,7 @@ function read() {
|
|
|
43174
43549
|
}
|
|
43175
43550
|
function write(reg) {
|
|
43176
43551
|
ensureDir(globalDir());
|
|
43177
|
-
|
|
43552
|
+
writeFileSync14(registryPath(), JSON.stringify(reg, null, 2), "utf8");
|
|
43178
43553
|
}
|
|
43179
43554
|
function registerWorkspace(profile, root, now = Date.now()) {
|
|
43180
43555
|
const reg = read();
|
|
@@ -43191,7 +43566,7 @@ function pruneMissingWorkspaces() {
|
|
|
43191
43566
|
const reg = read();
|
|
43192
43567
|
const removed = [];
|
|
43193
43568
|
for (const [id, entry] of Object.entries(reg.workspaces)) {
|
|
43194
|
-
if (!
|
|
43569
|
+
if (!existsSync17(entry.path)) {
|
|
43195
43570
|
removed.push(entry);
|
|
43196
43571
|
delete reg.workspaces[id];
|
|
43197
43572
|
}
|
|
@@ -43200,13 +43575,13 @@ function pruneMissingWorkspaces() {
|
|
|
43200
43575
|
return removed;
|
|
43201
43576
|
}
|
|
43202
43577
|
function workspaceStatus(entry) {
|
|
43203
|
-
const missing = !
|
|
43578
|
+
const missing = !existsSync17(entry.path);
|
|
43204
43579
|
const lockPath = workspacePaths(entry.path).daemonLock;
|
|
43205
43580
|
let running = false;
|
|
43206
43581
|
let webUiUrl = null;
|
|
43207
|
-
if (
|
|
43582
|
+
if (existsSync17(lockPath)) {
|
|
43208
43583
|
try {
|
|
43209
|
-
const lock = JSON.parse(
|
|
43584
|
+
const lock = JSON.parse(readFileSync15(lockPath, "utf8"));
|
|
43210
43585
|
if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
|
|
43211
43586
|
running = true;
|
|
43212
43587
|
webUiUrl = lock.webUiUrl;
|
|
@@ -43234,7 +43609,7 @@ function pidAlive(pid) {
|
|
|
43234
43609
|
// src/multi.ts
|
|
43235
43610
|
init_dist();
|
|
43236
43611
|
init_src4();
|
|
43237
|
-
import { readFileSync as
|
|
43612
|
+
import { readFileSync as readFileSync18, unlinkSync as unlinkSync3, writeFileSync as writeFileSync15 } from "node:fs";
|
|
43238
43613
|
|
|
43239
43614
|
// src/principle-sync.ts
|
|
43240
43615
|
init_src4();
|
|
@@ -43261,8 +43636,8 @@ async function syncPrinciples(store, cloud, opts) {
|
|
|
43261
43636
|
init_reconcile();
|
|
43262
43637
|
|
|
43263
43638
|
// src/lockfile-auto.ts
|
|
43264
|
-
import { existsSync as
|
|
43265
|
-
import { join as
|
|
43639
|
+
import { existsSync as existsSync18, readFileSync as readFileSync16 } from "node:fs";
|
|
43640
|
+
import { join as join22 } from "node:path";
|
|
43266
43641
|
|
|
43267
43642
|
// src/package-index.ts
|
|
43268
43643
|
init_src();
|
|
@@ -43526,11 +43901,11 @@ function runLockfilePass(opts) {
|
|
|
43526
43901
|
{ file: "package-lock.json", parse: parsePackageLockJson }
|
|
43527
43902
|
];
|
|
43528
43903
|
for (const c of candidates) {
|
|
43529
|
-
const p =
|
|
43530
|
-
if (!
|
|
43904
|
+
const p = join22(opts.root, c.file);
|
|
43905
|
+
if (!existsSync18(p)) continue;
|
|
43531
43906
|
let sbom;
|
|
43532
43907
|
try {
|
|
43533
|
-
sbom = c.parse(
|
|
43908
|
+
sbom = c.parse(readFileSync16(p, "utf8"));
|
|
43534
43909
|
} catch {
|
|
43535
43910
|
continue;
|
|
43536
43911
|
}
|
|
@@ -43685,6 +44060,27 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
43685
44060
|
}
|
|
43686
44061
|
}
|
|
43687
44062
|
if (nodes.length === 0 && anchorEdges.length === 0) return null;
|
|
44063
|
+
let symbolSummaries;
|
|
44064
|
+
if (opts.lexicon && opts.lexicon.size > 0 && nodes.length > 0) {
|
|
44065
|
+
const lexicon = opts.lexicon;
|
|
44066
|
+
const isKnown = (tok) => lexicon.has(tok);
|
|
44067
|
+
const sidecar = {};
|
|
44068
|
+
let count = 0;
|
|
44069
|
+
outer: for (const n of nodes) {
|
|
44070
|
+
if (!INSTANCE_LABELS.includes(n.label)) continue;
|
|
44071
|
+
for (const tok of extractIdentifierTokens(n.description)) {
|
|
44072
|
+
if (sidecar[tok]) continue;
|
|
44073
|
+
const entry = lexicon.get(tok);
|
|
44074
|
+
if (!entry?.summary) continue;
|
|
44075
|
+
const scrubbed = generalize(entry.summary, { level }).text.trim();
|
|
44076
|
+
if (!scrubbed || summaryRejectionReason(scrubbed, isKnown) !== null) continue;
|
|
44077
|
+
if (count >= MAX_SIDECAR_SYMBOLS) break outer;
|
|
44078
|
+
sidecar[tok] = { kind: entry.kind, summary: scrubbed };
|
|
44079
|
+
count++;
|
|
44080
|
+
}
|
|
44081
|
+
}
|
|
44082
|
+
if (count > 0) symbolSummaries = sidecar;
|
|
44083
|
+
}
|
|
43688
44084
|
const edges = [];
|
|
43689
44085
|
for (const id of seen) {
|
|
43690
44086
|
for (const e of store.outEdges(id, [...INSTANCE_EDGES])) {
|
|
@@ -43699,12 +44095,17 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
43699
44095
|
// co-locates the few Language/Package stubs with the first instance chunk,
|
|
43700
44096
|
// maximizing in-payload endpoint resolution.
|
|
43701
44097
|
nodes: [...contextNodes, ...nodes],
|
|
43702
|
-
edges
|
|
44098
|
+
edges,
|
|
44099
|
+
// Spread-if-present: an absent sidecar keeps `base` — and therefore the
|
|
44100
|
+
// payloadDigest — byte-identical to the pre-sidecar batch (backward compat).
|
|
44101
|
+
...symbolSummaries ? { symbolSummaries } : {}
|
|
43703
44102
|
};
|
|
43704
44103
|
return { ...base, payloadDigest: digest(base), anchorDigests };
|
|
43705
44104
|
}
|
|
43706
44105
|
|
|
43707
44106
|
// src/multi.ts
|
|
44107
|
+
init_generalize_graph();
|
|
44108
|
+
init_symbol_summaries();
|
|
43708
44109
|
init_webui();
|
|
43709
44110
|
|
|
43710
44111
|
// src/consolidate-worker-client.ts
|
|
@@ -43780,7 +44181,7 @@ var ConsolidateWorker = class {
|
|
|
43780
44181
|
init_paths();
|
|
43781
44182
|
|
|
43782
44183
|
// src/lock.ts
|
|
43783
|
-
import { existsSync as
|
|
44184
|
+
import { existsSync as existsSync19, readFileSync as readFileSync17 } from "node:fs";
|
|
43784
44185
|
function isProcessAlive(pid) {
|
|
43785
44186
|
if (!pid || pid <= 0) return false;
|
|
43786
44187
|
try {
|
|
@@ -43791,9 +44192,9 @@ function isProcessAlive(pid) {
|
|
|
43791
44192
|
}
|
|
43792
44193
|
}
|
|
43793
44194
|
function readDaemonLock(lockPath) {
|
|
43794
|
-
if (!
|
|
44195
|
+
if (!existsSync19(lockPath)) return null;
|
|
43795
44196
|
try {
|
|
43796
|
-
const lock = JSON.parse(
|
|
44197
|
+
const lock = JSON.parse(readFileSync17(lockPath, "utf8"));
|
|
43797
44198
|
return typeof lock.pid === "number" ? lock : null;
|
|
43798
44199
|
} catch {
|
|
43799
44200
|
return null;
|
|
@@ -44041,7 +44442,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
44041
44442
|
records.push(rec);
|
|
44042
44443
|
app.route(`/ws/${rec.id}`, rec.webApp);
|
|
44043
44444
|
try {
|
|
44044
|
-
|
|
44445
|
+
writeFileSync15(
|
|
44045
44446
|
rec.engine.paths.daemonLock,
|
|
44046
44447
|
JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${rec.id}`, startedAt: Date.now() }),
|
|
44047
44448
|
"utf8"
|
|
@@ -44224,7 +44625,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
44224
44625
|
baseUrl = `http://127.0.0.1:${port}`;
|
|
44225
44626
|
try {
|
|
44226
44627
|
ensureDir(globalDir());
|
|
44227
|
-
|
|
44628
|
+
writeFileSync15(
|
|
44228
44629
|
lockPath,
|
|
44229
44630
|
JSON.stringify({ pid: process.pid, webUiUrl: baseUrl, startedAt: Date.now() }),
|
|
44230
44631
|
"utf8"
|
|
@@ -44233,7 +44634,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
44233
44634
|
}
|
|
44234
44635
|
for (const r of records) {
|
|
44235
44636
|
try {
|
|
44236
|
-
|
|
44637
|
+
writeFileSync15(
|
|
44237
44638
|
r.engine.paths.daemonLock,
|
|
44238
44639
|
JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${r.id}`, startedAt: Date.now() }),
|
|
44239
44640
|
"utf8"
|
|
@@ -44445,8 +44846,15 @@ async function startMultiDaemon(opts = {}) {
|
|
|
44445
44846
|
const res = await client.ingest(context);
|
|
44446
44847
|
uploaded += res.accepted;
|
|
44447
44848
|
}
|
|
44849
|
+
let lexicon;
|
|
44850
|
+
try {
|
|
44851
|
+
const summaries = summariesByBodyHash(loadSymbolSummaryCache(r.engine.paths.configDir));
|
|
44852
|
+
if (summaries.size > 0) lexicon = buildSymbolLexicon(store, summaries);
|
|
44853
|
+
} catch {
|
|
44854
|
+
}
|
|
44448
44855
|
const instances = buildInstanceIngest(store, r.engine.profile, DAEMON_VERSION, ignore, {
|
|
44449
|
-
includePackages: cfg2.consent.contributePackages
|
|
44856
|
+
includePackages: cfg2.consent.contributePackages,
|
|
44857
|
+
...lexicon ? { lexicon } : {}
|
|
44450
44858
|
});
|
|
44451
44859
|
if (instances) {
|
|
44452
44860
|
const res = await client.ingest(instances);
|
|
@@ -44529,7 +44937,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
44529
44937
|
},
|
|
44530
44938
|
async stop() {
|
|
44531
44939
|
try {
|
|
44532
|
-
const cur =
|
|
44940
|
+
const cur = readFileSync18(lockPath, "utf8");
|
|
44533
44941
|
if (JSON.parse(cur).pid === process.pid) unlinkSync3(lockPath);
|
|
44534
44942
|
} catch {
|
|
44535
44943
|
}
|
|
@@ -44983,21 +45391,21 @@ async function cmdInit() {
|
|
|
44983
45391
|
if (!skipHooks) {
|
|
44984
45392
|
console.log("");
|
|
44985
45393
|
console.log("installing harness hooks...");
|
|
44986
|
-
const { existsSync:
|
|
44987
|
-
const { join:
|
|
45394
|
+
const { existsSync: existsSync21 } = await import("node:fs");
|
|
45395
|
+
const { join: join24 } = await import("node:path");
|
|
44988
45396
|
try {
|
|
44989
45397
|
await installClaudeHooks(port);
|
|
44990
45398
|
} catch (err2) {
|
|
44991
45399
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
44992
45400
|
}
|
|
44993
|
-
if (
|
|
45401
|
+
if (existsSync21(join24(ROOT, ".cursor"))) {
|
|
44994
45402
|
try {
|
|
44995
45403
|
await installCursorMcpConfig();
|
|
44996
45404
|
} catch (err2) {
|
|
44997
45405
|
console.warn(` \u26A0\uFE0F Cursor MCP config failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
44998
45406
|
}
|
|
44999
45407
|
}
|
|
45000
|
-
if (
|
|
45408
|
+
if (existsSync21(join24(ROOT, ".codex"))) {
|
|
45001
45409
|
try {
|
|
45002
45410
|
await installCodexHooks(port);
|
|
45003
45411
|
} catch (err2) {
|
|
@@ -45114,8 +45522,8 @@ async function cmdStatus() {
|
|
|
45114
45522
|
console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
|
|
45115
45523
|
console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
|
|
45116
45524
|
}
|
|
45117
|
-
console.log(` graph db: ${
|
|
45118
|
-
console.log(` event log: ${
|
|
45525
|
+
console.log(` graph db: ${existsSync20(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
45526
|
+
console.log(` event log: ${existsSync20(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
45119
45527
|
const lockPath = globalDaemonLock();
|
|
45120
45528
|
const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
|
|
45121
45529
|
console.log(
|
|
@@ -45411,11 +45819,11 @@ async function cmdLogout() {
|
|
|
45411
45819
|
}
|
|
45412
45820
|
async function cmdReview() {
|
|
45413
45821
|
const paths = workspacePaths(ROOT);
|
|
45414
|
-
if (!
|
|
45822
|
+
if (!existsSync20(paths.reviewQueue)) {
|
|
45415
45823
|
console.log("(review queue empty)");
|
|
45416
45824
|
return;
|
|
45417
45825
|
}
|
|
45418
|
-
const queue = JSON.parse(
|
|
45826
|
+
const queue = JSON.parse(readFileSync19(paths.reviewQueue, "utf8"));
|
|
45419
45827
|
if (queue.length === 0) {
|
|
45420
45828
|
console.log("(review queue empty)");
|
|
45421
45829
|
return;
|
|
@@ -46045,7 +46453,7 @@ async function gatherRepo(store, ws) {
|
|
|
46045
46453
|
};
|
|
46046
46454
|
}
|
|
46047
46455
|
async function gatherReportData(generatedAt) {
|
|
46048
|
-
const { existsSync:
|
|
46456
|
+
const { existsSync: existsSync21 } = await import("node:fs");
|
|
46049
46457
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
|
|
46050
46458
|
const cfg = loadConfig();
|
|
46051
46459
|
const outbound = cfg.consent.sync ? "auto" : "off";
|
|
@@ -46053,7 +46461,7 @@ async function gatherReportData(generatedAt) {
|
|
|
46053
46461
|
for (const ws of listWorkspaces()) {
|
|
46054
46462
|
if (ws.missing) continue;
|
|
46055
46463
|
const dbPath = workspacePaths(ws.path).castalia;
|
|
46056
|
-
if (!
|
|
46464
|
+
if (!existsSync21(dbPath)) continue;
|
|
46057
46465
|
let store = null;
|
|
46058
46466
|
try {
|
|
46059
46467
|
store = openGraphStore2({ path: dbPath });
|
|
@@ -46084,7 +46492,7 @@ async function gatherReportData(generatedAt) {
|
|
|
46084
46492
|
};
|
|
46085
46493
|
}
|
|
46086
46494
|
async function cmdReport(args2) {
|
|
46087
|
-
const { mkdirSync: mkdirSync6, writeFileSync:
|
|
46495
|
+
const { mkdirSync: mkdirSync6, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
46088
46496
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
46089
46497
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
46090
46498
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -46097,8 +46505,8 @@ async function cmdReport(args2) {
|
|
|
46097
46505
|
const outDir = workspacePaths(ROOT).configDir;
|
|
46098
46506
|
mkdirSync6(outDir, { recursive: true });
|
|
46099
46507
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
46100
|
-
for (const f of files)
|
|
46101
|
-
const indexPath =
|
|
46508
|
+
for (const f of files) writeFileSync16(join23(outDir, f.name), f.html, "utf8");
|
|
46509
|
+
const indexPath = join23(outDir, "report.html");
|
|
46102
46510
|
console.log(`report \u2192 ${indexPath}`);
|
|
46103
46511
|
console.log(` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`);
|
|
46104
46512
|
console.log(` open: file://${indexPath.replace(/\\/g, "/")}`);
|
|
@@ -46218,15 +46626,15 @@ function hookRelayCommand(port, path2) {
|
|
|
46218
46626
|
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 '{}'`;
|
|
46219
46627
|
}
|
|
46220
46628
|
async function installClaudeHooks(port) {
|
|
46221
|
-
const { mkdirSync: mkdirSync6, existsSync:
|
|
46222
|
-
const { join:
|
|
46223
|
-
const dir =
|
|
46224
|
-
if (!
|
|
46225
|
-
const file2 =
|
|
46629
|
+
const { mkdirSync: mkdirSync6, existsSync: existsSync21, readFileSync: readFileSync20, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
46630
|
+
const { join: join24 } = await import("node:path");
|
|
46631
|
+
const dir = join24(ROOT, ".claude");
|
|
46632
|
+
if (!existsSync21(dir)) mkdirSync6(dir, { recursive: true });
|
|
46633
|
+
const file2 = join24(dir, "settings.json");
|
|
46226
46634
|
let settings = {};
|
|
46227
|
-
if (
|
|
46635
|
+
if (existsSync21(file2)) {
|
|
46228
46636
|
try {
|
|
46229
|
-
settings = JSON.parse(
|
|
46637
|
+
settings = JSON.parse(readFileSync20(file2, "utf8"));
|
|
46230
46638
|
} catch {
|
|
46231
46639
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
46232
46640
|
process.exit(2);
|
|
@@ -46271,21 +46679,21 @@ async function installClaudeHooks(port) {
|
|
|
46271
46679
|
dropErrata(list);
|
|
46272
46680
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
46273
46681
|
}
|
|
46274
|
-
|
|
46682
|
+
writeFileSync16(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
46275
46683
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
46276
46684
|
await installClaudeMcpConfig();
|
|
46277
46685
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
46278
46686
|
}
|
|
46279
46687
|
async function installClaudeMcpConfig() {
|
|
46280
|
-
const { mkdirSync: mkdirSync6, existsSync:
|
|
46281
|
-
const { join:
|
|
46282
|
-
const file2 =
|
|
46688
|
+
const { mkdirSync: mkdirSync6, existsSync: existsSync21, readFileSync: readFileSync20, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
46689
|
+
const { join: join24, dirname: dirname8 } = await import("node:path");
|
|
46690
|
+
const file2 = join24(ROOT, ".mcp.json");
|
|
46283
46691
|
const dir = dirname8(file2);
|
|
46284
|
-
if (!
|
|
46692
|
+
if (!existsSync21(dir)) mkdirSync6(dir, { recursive: true });
|
|
46285
46693
|
let cfg = {};
|
|
46286
|
-
if (
|
|
46694
|
+
if (existsSync21(file2)) {
|
|
46287
46695
|
try {
|
|
46288
|
-
cfg = JSON.parse(
|
|
46696
|
+
cfg = JSON.parse(readFileSync20(file2, "utf8"));
|
|
46289
46697
|
} catch {
|
|
46290
46698
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
46291
46699
|
process.exit(2);
|
|
@@ -46293,21 +46701,21 @@ async function installClaudeMcpConfig() {
|
|
|
46293
46701
|
}
|
|
46294
46702
|
cfg.mcpServers ??= {};
|
|
46295
46703
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
46296
|
-
|
|
46704
|
+
writeFileSync16(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
46297
46705
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
46298
46706
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
46299
46707
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
46300
46708
|
}
|
|
46301
46709
|
async function installCursorMcpConfig() {
|
|
46302
|
-
const { mkdirSync: mkdirSync6, existsSync:
|
|
46303
|
-
const { join:
|
|
46304
|
-
const dir =
|
|
46305
|
-
if (!
|
|
46306
|
-
const file2 =
|
|
46710
|
+
const { mkdirSync: mkdirSync6, existsSync: existsSync21, readFileSync: readFileSync20, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
46711
|
+
const { join: join24 } = await import("node:path");
|
|
46712
|
+
const dir = join24(ROOT, ".cursor");
|
|
46713
|
+
if (!existsSync21(dir)) mkdirSync6(dir, { recursive: true });
|
|
46714
|
+
const file2 = join24(dir, "mcp.json");
|
|
46307
46715
|
let cfg = {};
|
|
46308
|
-
if (
|
|
46716
|
+
if (existsSync21(file2)) {
|
|
46309
46717
|
try {
|
|
46310
|
-
cfg = JSON.parse(
|
|
46718
|
+
cfg = JSON.parse(readFileSync20(file2, "utf8"));
|
|
46311
46719
|
} catch {
|
|
46312
46720
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
46313
46721
|
process.exit(2);
|
|
@@ -46315,7 +46723,7 @@ async function installCursorMcpConfig() {
|
|
|
46315
46723
|
}
|
|
46316
46724
|
cfg.mcpServers ??= {};
|
|
46317
46725
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
46318
|
-
|
|
46726
|
+
writeFileSync16(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
46319
46727
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
46320
46728
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
46321
46729
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -46323,16 +46731,16 @@ async function installCursorMcpConfig() {
|
|
|
46323
46731
|
console.log(` \u26A0\uFE0F reload Cursor (Cmd/Ctrl-Shift-P \u2192 "Reload Window") to pick it up.`);
|
|
46324
46732
|
}
|
|
46325
46733
|
async function installCodexHooks(port) {
|
|
46326
|
-
const { mkdirSync: mkdirSync6, existsSync:
|
|
46327
|
-
const { join:
|
|
46328
|
-
const dir =
|
|
46329
|
-
if (!
|
|
46330
|
-
const file2 =
|
|
46734
|
+
const { mkdirSync: mkdirSync6, existsSync: existsSync21, readFileSync: readFileSync20, writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
46735
|
+
const { join: join24 } = await import("node:path");
|
|
46736
|
+
const dir = join24(ROOT, ".codex");
|
|
46737
|
+
if (!existsSync21(dir)) mkdirSync6(dir, { recursive: true });
|
|
46738
|
+
const file2 = join24(dir, "config.toml");
|
|
46331
46739
|
const BEGIN = `# >>> errata hooks (errata-managed)`;
|
|
46332
46740
|
const END = `# <<< errata hooks`;
|
|
46333
46741
|
let existing = "";
|
|
46334
|
-
if (
|
|
46335
|
-
existing =
|
|
46742
|
+
if (existsSync21(file2)) {
|
|
46743
|
+
existing = readFileSync20(file2, "utf8");
|
|
46336
46744
|
const beginIdx = existing.indexOf(BEGIN);
|
|
46337
46745
|
const endIdx = existing.indexOf(END);
|
|
46338
46746
|
if (beginIdx >= 0 && endIdx > beginIdx) {
|
|
@@ -46361,7 +46769,7 @@ ${END}
|
|
|
46361
46769
|
const final = existing.length > 0 && !existing.endsWith("\n") ? `${existing}
|
|
46362
46770
|
|
|
46363
46771
|
${block}` : existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
|
|
46364
|
-
|
|
46772
|
+
writeFileSync16(file2, final, "utf8");
|
|
46365
46773
|
console.log(`installed Codex hooks \u2192 ${file2}`);
|
|
46366
46774
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
46367
46775
|
console.log("");
|
|
@@ -46624,7 +47032,7 @@ async function cmdDash(args2) {
|
|
|
46624
47032
|
await yieldToLoop2();
|
|
46625
47033
|
try {
|
|
46626
47034
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile);
|
|
46627
|
-
const res = bleedRules(
|
|
47035
|
+
const res = bleedRules(join23(r.root, ".claude", "rules"), items);
|
|
46628
47036
|
if (res.written || res.pruned) {
|
|
46629
47037
|
console.log(
|
|
46630
47038
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|