@inerrata-corporation/errata 2.0.6-dev.2330 → 2.0.6-dev.2494
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 +1678 -2
- package/errata.mjs +132 -43
- package/package.json +1 -1
- package/pass-worker.mjs +1 -1
package/consolidate-worker.mjs
CHANGED
|
@@ -378,6 +378,9 @@ import { createHash } from "node:crypto";
|
|
|
378
378
|
function sha256(input) {
|
|
379
379
|
return createHash("sha256").update(input).digest("hex");
|
|
380
380
|
}
|
|
381
|
+
function sha256Short(input, n = 8) {
|
|
382
|
+
return sha256(input).slice(0, n);
|
|
383
|
+
}
|
|
381
384
|
function canonicalJSON(value) {
|
|
382
385
|
if (value === null || typeof value !== "object") {
|
|
383
386
|
return JSON.stringify(value);
|
|
@@ -813,6 +816,12 @@ function identityId(input) {
|
|
|
813
816
|
);
|
|
814
817
|
}
|
|
815
818
|
}
|
|
819
|
+
function genericCanonicalId(prefix, content) {
|
|
820
|
+
return `${prefix}_${digest(content)}`.slice(0, 56);
|
|
821
|
+
}
|
|
822
|
+
function languageCanonicalId(name) {
|
|
823
|
+
return genericCanonicalId("Language", { name: name.trim().toLowerCase() });
|
|
824
|
+
}
|
|
816
825
|
var DESIGN_PROBLEM_PREFIX, DESIGN_PROBLEM_ID_LENGTH, DIAGNOSTIC_PROBLEM_PREFIX, DIAGNOSTIC_HASH_LENGTH, TRIAGE_PREFIX, TRIAGE_ID_LENGTH;
|
|
817
826
|
var init_identity = __esm({
|
|
818
827
|
"../../packages/shared/src/identity.ts"() {
|
|
@@ -15250,7 +15259,49 @@ var init_edge_rules = __esm({
|
|
|
15250
15259
|
});
|
|
15251
15260
|
|
|
15252
15261
|
// ../../packages/shared/src/symbol-intent.ts
|
|
15253
|
-
|
|
15262
|
+
function extractIdentifierTokens(text) {
|
|
15263
|
+
const out = [];
|
|
15264
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15265
|
+
for (const m of text.matchAll(TOKEN_RE2)) {
|
|
15266
|
+
if (!seen.has(m[0])) {
|
|
15267
|
+
seen.add(m[0]);
|
|
15268
|
+
out.push(m[0]);
|
|
15269
|
+
}
|
|
15270
|
+
}
|
|
15271
|
+
return out;
|
|
15272
|
+
}
|
|
15273
|
+
function sidecarDropBucket(reason) {
|
|
15274
|
+
if (reason === null) return null;
|
|
15275
|
+
if (reason === "empty summary") return "empty";
|
|
15276
|
+
if (reason === "summary too long") return "too_long";
|
|
15277
|
+
if (reason === "contains a path shape") return "path_shape";
|
|
15278
|
+
if (reason === "contains a quoted literal") return "quoted_literal";
|
|
15279
|
+
if (reason.startsWith("contains verbatim identifier")) return "verbatim_identifier";
|
|
15280
|
+
return "other";
|
|
15281
|
+
}
|
|
15282
|
+
function summaryRejectionReason(summary, isKnownToken) {
|
|
15283
|
+
if (!summary.trim()) return "empty summary";
|
|
15284
|
+
if (summary.length > MAX_SYMBOL_SUMMARY_CHARS) return "summary too long";
|
|
15285
|
+
if (PATH_SHAPE_RE.test(summary)) return "contains a path shape";
|
|
15286
|
+
if (QUOTED_LITERAL_RE.test(summary.replace(CONTRACTION_RE, "$1$2")))
|
|
15287
|
+
return "contains a quoted literal";
|
|
15288
|
+
for (const tok of extractIdentifierTokens(summary)) {
|
|
15289
|
+
if (isKnownToken(tok)) return `contains verbatim identifier '${tok}'`;
|
|
15290
|
+
if (tok.includes(".")) {
|
|
15291
|
+
const segs = tok.split(".");
|
|
15292
|
+
for (let i = 0; i < segs.length; i++) {
|
|
15293
|
+
let span = "";
|
|
15294
|
+
for (let j = i; j < segs.length; j++) {
|
|
15295
|
+
span = span ? `${span}.${segs[j]}` : segs[j];
|
|
15296
|
+
if (span !== tok && span && isKnownToken(span))
|
|
15297
|
+
return `contains verbatim identifier '${span}'`;
|
|
15298
|
+
}
|
|
15299
|
+
}
|
|
15300
|
+
}
|
|
15301
|
+
}
|
|
15302
|
+
return null;
|
|
15303
|
+
}
|
|
15304
|
+
var SYMBOL_SUMMARY_KINDS, MAX_SYMBOL_SUMMARY_CHARS, MAX_SIDECAR_SYMBOLS, TOKEN_RE2, PATH_SHAPE_RE, CONTRACTION_RE, QUOTED_LITERAL_RE;
|
|
15254
15305
|
var init_symbol_intent = __esm({
|
|
15255
15306
|
"../../packages/shared/src/symbol-intent.ts"() {
|
|
15256
15307
|
"use strict";
|
|
@@ -15263,10 +15314,23 @@ var init_symbol_intent = __esm({
|
|
|
15263
15314
|
];
|
|
15264
15315
|
MAX_SYMBOL_SUMMARY_CHARS = 300;
|
|
15265
15316
|
MAX_SIDECAR_SYMBOLS = 200;
|
|
15317
|
+
TOKEN_RE2 = /[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*/g;
|
|
15318
|
+
PATH_SHAPE_RE = /[\w.~-]+[/\\][\w.$~-]+/;
|
|
15319
|
+
CONTRACTION_RE = /([A-Za-z])'([A-Za-z])/g;
|
|
15320
|
+
QUOTED_LITERAL_RE = /"[^"]+"|'[^']+'|`[^`]+`/;
|
|
15266
15321
|
}
|
|
15267
15322
|
});
|
|
15268
15323
|
|
|
15269
15324
|
// ../../packages/shared/src/wire.ts
|
|
15325
|
+
function anchorVersionAttrs(attrs) {
|
|
15326
|
+
if (!attrs) return {};
|
|
15327
|
+
const commit = attrs["observedAtCommit"];
|
|
15328
|
+
const hash2 = attrs["symbolContentHash"];
|
|
15329
|
+
return {
|
|
15330
|
+
...typeof commit === "string" && ANCHOR_COMMIT_SHA_RE.test(commit) ? { observedAtCommit: commit } : {},
|
|
15331
|
+
...typeof hash2 === "string" && ANCHOR_BODY_HASH_RE.test(hash2) ? { symbolContentHash: hash2 } : {}
|
|
15332
|
+
};
|
|
15333
|
+
}
|
|
15270
15334
|
var CLOUD_NODE_LABELS, CLOUD_WRITABLE_NODE_LABELS, PROJECT_ONLY_NODE_LABELS, PROJECT_ONLY_NODE_LABEL_SET, PROJECT_ONLY_EDGE_TYPES, PROJECT_ONLY_EDGE_TYPE_SET, CLOUD_WRITABLE_NODE_LABEL_SET, CLOUD_EDGE_TYPES, INGEST_SOURCES, INGEST_EXTRACTION_SOURCES, CastaliaIngestNodeSchema, RouteContextCountWireSchema, ANCHOR_COMMIT_SHA_RE, ANCHOR_BODY_HASH_RE, CastaliaIngestEdgeSchema, SymbolSummarySidecarSchema, CastaliaIngestPayloadSchema;
|
|
15271
15335
|
var init_wire = __esm({
|
|
15272
15336
|
"../../packages/shared/src/wire.ts"() {
|
|
@@ -15355,7 +15419,7 @@ var init_wire = __esm({
|
|
|
15355
15419
|
/** Org-membrane (M2): the daemon's anchor tag — it owns the lockfile, so it
|
|
15356
15420
|
* knows which packages are private. The door does NOT trust a `public` claim
|
|
15357
15421
|
* blindly (it re-confirms on the spine); absent ⇒ unknown ⇒ fail-closed to
|
|
15358
|
-
* org-private.
|
|
15422
|
+
* org-private. Ignored only where ORG_MEMBRANE_ENABLED=false (default ON). */
|
|
15359
15423
|
anchorVisibility: external_exports.enum(["public", "private"]).optional(),
|
|
15360
15424
|
/** The spine-resolvable anchor id backing a `public` tag (OM-anchor-tag): a
|
|
15361
15425
|
* Package purl or `languageCanonicalId`. The door validates THIS on the
|
|
@@ -15440,6 +15504,17 @@ var init_repo_locator = __esm({
|
|
|
15440
15504
|
});
|
|
15441
15505
|
|
|
15442
15506
|
// ../../packages/shared/src/project-symbol.ts
|
|
15507
|
+
import { createHmac } from "node:crypto";
|
|
15508
|
+
function normalizeSymbolPath(relPath) {
|
|
15509
|
+
return relPath.replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\.\//, "").replace(/^\//, "");
|
|
15510
|
+
}
|
|
15511
|
+
function projectSymbolId(projectSalt, projectId, relPath, qname, kind) {
|
|
15512
|
+
const path = normalizeSymbolPath(relPath);
|
|
15513
|
+
return `sym_${createHmac("sha256", projectSalt).update(`${projectId}:${path}:${qname}:${kind}`).digest("hex").slice(0, 24)}`;
|
|
15514
|
+
}
|
|
15515
|
+
function isMembraneSaltedId(id) {
|
|
15516
|
+
return typeof id === "string" && /^(orgn_|teamn_|projn_)/.test(id);
|
|
15517
|
+
}
|
|
15443
15518
|
var init_project_symbol = __esm({
|
|
15444
15519
|
"../../packages/shared/src/project-symbol.ts"() {
|
|
15445
15520
|
"use strict";
|
|
@@ -16894,6 +16969,7 @@ init_src();
|
|
|
16894
16969
|
|
|
16895
16970
|
// ../../packages/local-graph/src/design-problem.ts
|
|
16896
16971
|
var RECURRENCE_DEBOUNCE_MS = 60 * 60 * 1e3;
|
|
16972
|
+
var AUTO_MINT_PREFIX = "addressed by an edit to ";
|
|
16897
16973
|
|
|
16898
16974
|
// ../../packages/local-graph/src/intent.ts
|
|
16899
16975
|
init_src();
|
|
@@ -17002,6 +17078,9 @@ function percolate(l1, l2, opts) {
|
|
|
17002
17078
|
init_src();
|
|
17003
17079
|
init_src2();
|
|
17004
17080
|
|
|
17081
|
+
// ../../packages/math/src/constants.ts
|
|
17082
|
+
var NEMORI_DEDUP_COSINE = 0.88;
|
|
17083
|
+
|
|
17005
17084
|
// ../../packages/math/src/triage.ts
|
|
17006
17085
|
var TRIAGE_GLOBAL_BUCKET = "*";
|
|
17007
17086
|
function triageContextBuckets(ctx) {
|
|
@@ -17661,6 +17740,1593 @@ function findStrandedSymbols(store) {
|
|
|
17661
17740
|
return stranded;
|
|
17662
17741
|
}
|
|
17663
17742
|
|
|
17743
|
+
// src/package-index.ts
|
|
17744
|
+
init_src();
|
|
17745
|
+
function buildContextIngest(store, profile, daemonVersion, ignorePatterns = [], opts = {}) {
|
|
17746
|
+
const labels = opts.includePackages === false ? ["Language"] : ["Package", "Language"];
|
|
17747
|
+
const ignored = (s) => ignorePatterns.length > 0 && ignorePatterns.some((p) => s.toLowerCase().includes(p));
|
|
17748
|
+
const nodes = [];
|
|
17749
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17750
|
+
const localIdByWireId = {};
|
|
17751
|
+
for (const label of labels) {
|
|
17752
|
+
for (const n of store.findNodesByLabel(label)) {
|
|
17753
|
+
if (n.attrs["source"] === "cloud") continue;
|
|
17754
|
+
if (ignored(n.description) || ignored(String(n.attrs["name"] ?? ""))) continue;
|
|
17755
|
+
if (typeof n.attrs["contributedAtSeq"] === "number") continue;
|
|
17756
|
+
nodes.push({
|
|
17757
|
+
...n,
|
|
17758
|
+
// Language wire id = the shared `languageCanonicalId` (warming-spine
|
|
17759
|
+
// parity, EE-cloud-anchors) — the local `lang:<name>` id is internal.
|
|
17760
|
+
// Package ids are already the purl (= the cross-stratum canonicalId).
|
|
17761
|
+
id: label === "Language" ? languageCanonicalId(String(n.attrs["name"] ?? "").trim() || n.description) : n.id,
|
|
17762
|
+
embedding: [],
|
|
17763
|
+
// No `version` attr on the wire: the purl already encodes the resolved
|
|
17764
|
+
// version, and the door's temporal guard rejects ANY `attrs.version` as
|
|
17765
|
+
// bi-temporal bookkeeping (ingest-temporal-guard.ts) — shipping it 422s
|
|
17766
|
+
// the whole batch. `resolved` still travels (range-vs-lockfile signal).
|
|
17767
|
+
attrs: label === "Package" ? {
|
|
17768
|
+
purl: n.attrs["purl"],
|
|
17769
|
+
name: n.attrs["name"],
|
|
17770
|
+
ecosystem: n.attrs["ecosystem"],
|
|
17771
|
+
resolved: n.attrs["resolved"]
|
|
17772
|
+
} : { name: n.attrs["name"] },
|
|
17773
|
+
// OM-anchor-tag: context stubs are self-anchored — the wire id IS the
|
|
17774
|
+
// spine key (purl / languageCanonicalId). The door re-confirms on the
|
|
17775
|
+
// public spine; a private-registry or workspace package never confirms
|
|
17776
|
+
// and fails closed to org, exactly as an untagged one would.
|
|
17777
|
+
anchorVisibility: "public"
|
|
17778
|
+
});
|
|
17779
|
+
seen.add(n.id);
|
|
17780
|
+
localIdByWireId[nodes[nodes.length - 1].id] = n.id;
|
|
17781
|
+
}
|
|
17782
|
+
}
|
|
17783
|
+
if (nodes.length === 0) return null;
|
|
17784
|
+
const edges = [];
|
|
17785
|
+
for (const id of seen) {
|
|
17786
|
+
for (const e of store.outEdges(id, ["DEPENDS_ON"])) {
|
|
17787
|
+
if (seen.has(e.to)) edges.push({ ...e, attrs: {} });
|
|
17788
|
+
}
|
|
17789
|
+
}
|
|
17790
|
+
const base = {
|
|
17791
|
+
daemonVersion,
|
|
17792
|
+
// Origin key (= project, the salted `wp_…`) — the door stamps it onto created
|
|
17793
|
+
// nodes as `authoringProject`, arming the evidence channels' cross-origin gate
|
|
17794
|
+
// (EE-corrob-live: without it every node is fail-open to self-corroboration).
|
|
17795
|
+
...profile.id ? { originProject: profile.id } : {},
|
|
17796
|
+
profile: { stack: profile.stack, languages: profile.languages, domains: profile.domains },
|
|
17797
|
+
nodes,
|
|
17798
|
+
edges
|
|
17799
|
+
};
|
|
17800
|
+
return { ...base, payloadDigest: digest(base), localIds: [...seen], localIdByWireId };
|
|
17801
|
+
}
|
|
17802
|
+
|
|
17803
|
+
// src/instance-ingest.ts
|
|
17804
|
+
init_src();
|
|
17805
|
+
init_src2();
|
|
17806
|
+
|
|
17807
|
+
// ../../packages/privacy-edge/src/ontology.ts
|
|
17808
|
+
var DEFAULT_ONTOLOGY = {
|
|
17809
|
+
email: { l1: "an email address", l2: "an email address" },
|
|
17810
|
+
ip: { l1: "an IP address", l2: "an IP address" },
|
|
17811
|
+
path: { l1: "a path", l2: "a path" },
|
|
17812
|
+
file: { l1: "a file", l2: "a path" },
|
|
17813
|
+
credential: "neutralize",
|
|
17814
|
+
uuid: { l1: "an identifier", l2: "an identifier" },
|
|
17815
|
+
hash: { l1: "a hash", l2: "a value" },
|
|
17816
|
+
date: { l1: "a date", l2: "a date" },
|
|
17817
|
+
// real values come from date-shapes
|
|
17818
|
+
person: { l1: "a contributor", l2: "someone" },
|
|
17819
|
+
org: { l1: "a company", l2: "an organization" }
|
|
17820
|
+
};
|
|
17821
|
+
function generalizePhrase(cls, level) {
|
|
17822
|
+
const rule = DEFAULT_ONTOLOGY[cls];
|
|
17823
|
+
if (rule === "neutralize") return "[redacted:credential]";
|
|
17824
|
+
return level === 1 ? rule.l1 : rule.l2;
|
|
17825
|
+
}
|
|
17826
|
+
|
|
17827
|
+
// ../../packages/privacy-edge/src/date-shapes.ts
|
|
17828
|
+
function seasonFor(month) {
|
|
17829
|
+
if (month <= 4) return "early";
|
|
17830
|
+
if (month <= 8) return "mid";
|
|
17831
|
+
return "late";
|
|
17832
|
+
}
|
|
17833
|
+
var MONTHS = {
|
|
17834
|
+
jan: 1,
|
|
17835
|
+
feb: 2,
|
|
17836
|
+
mar: 3,
|
|
17837
|
+
apr: 4,
|
|
17838
|
+
may: 5,
|
|
17839
|
+
jun: 6,
|
|
17840
|
+
jul: 7,
|
|
17841
|
+
aug: 8,
|
|
17842
|
+
sep: 9,
|
|
17843
|
+
oct: 10,
|
|
17844
|
+
nov: 11,
|
|
17845
|
+
dec: 12
|
|
17846
|
+
};
|
|
17847
|
+
function generalizeDates(text, level) {
|
|
17848
|
+
const yearOnly = level === 2;
|
|
17849
|
+
let out = text;
|
|
17850
|
+
out = out.replace(
|
|
17851
|
+
/\b(\d{4})-(\d{2})-(\d{2})\b/g,
|
|
17852
|
+
(_m, y, mo) => yearOnly ? y : `${seasonFor(Number(mo))} ${y}`
|
|
17853
|
+
);
|
|
17854
|
+
out = out.replace(/\b(\d{1,2})\/(\d{1,2})\/(\d{4})\b/g, (_m, mo, _d, y) => {
|
|
17855
|
+
const m = Number(mo);
|
|
17856
|
+
if (yearOnly || m < 1 || m > 12) return y;
|
|
17857
|
+
return `${seasonFor(m)} ${y}`;
|
|
17858
|
+
});
|
|
17859
|
+
out = out.replace(
|
|
17860
|
+
/\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*\.?\s+(\d{4})\b/gi,
|
|
17861
|
+
(_m, mon, y) => {
|
|
17862
|
+
const monNum = MONTHS[mon.slice(0, 3).toLowerCase()];
|
|
17863
|
+
return yearOnly || !monNum ? y : `${seasonFor(monNum)} ${y}`;
|
|
17864
|
+
}
|
|
17865
|
+
);
|
|
17866
|
+
return out;
|
|
17867
|
+
}
|
|
17868
|
+
|
|
17869
|
+
// ../../packages/canonical/src/scrub.ts
|
|
17870
|
+
init_src();
|
|
17871
|
+
var API_KEY_PATTERNS = [
|
|
17872
|
+
{ name: "sk-ant-key", re: /\bsk-ant-[a-zA-Z0-9_\-]{30,}\b/g },
|
|
17873
|
+
{ name: "openai-key", re: /\bsk-[a-zA-Z0-9_\-]{30,}\b/g },
|
|
17874
|
+
{ name: "github-pat", re: /\bgh[psour]_[A-Za-z0-9]{36,}\b/g },
|
|
17875
|
+
{ name: "aws-key", re: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
17876
|
+
{ name: "google-key", re: /\bAIza[0-9A-Za-z\-_]{35}\b/g },
|
|
17877
|
+
{ name: "stripe-key", re: /\b(sk|pk)_(test|live)_[0-9a-zA-Z]{24,}\b/g },
|
|
17878
|
+
{ name: "bearer", re: /\bBearer\s+[A-Za-z0-9_\-\.]{16,}\b/gi }
|
|
17879
|
+
];
|
|
17880
|
+
var EMAIL_RE = /\b[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}\b/g;
|
|
17881
|
+
var IPV4_RE = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
|
|
17882
|
+
var IPV6_RE = /\b(?:[A-Fa-f0-9]{1,4}:){2,7}[A-Fa-f0-9:]{1,4}\b/g;
|
|
17883
|
+
var WIN_PATH_RE = /\b[A-Za-z]:[\\/](?![\\/])(?:[^\\/\s"']+[\\/])*[^\\/\s"']*/g;
|
|
17884
|
+
var WIN_UNC_RE = /\\\\[A-Za-z0-9_\-]+\\[A-Za-z0-9_\-$]+(?:\\[^\\\s"']+)*/g;
|
|
17885
|
+
var POSIX_USER_PATH_RE = /\/(?:Users|home)\/[A-Za-z0-9_\-\.]+(?:\/[^"'\s)]+)*/g;
|
|
17886
|
+
var LONG_HASH_RE = /\b[a-fA-F0-9]{24,}\b/g;
|
|
17887
|
+
var UUID_RE = /\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/g;
|
|
17888
|
+
function scrub(input) {
|
|
17889
|
+
let text = input;
|
|
17890
|
+
const found = [];
|
|
17891
|
+
const bump = (kind, replaced) => {
|
|
17892
|
+
const ex = found.find((f) => f.kind === kind && f.replaced === replaced);
|
|
17893
|
+
if (ex) ex.count++;
|
|
17894
|
+
else found.push({ kind, replaced, count: 1 });
|
|
17895
|
+
};
|
|
17896
|
+
for (const p of API_KEY_PATTERNS) {
|
|
17897
|
+
text = text.replace(p.re, (m) => {
|
|
17898
|
+
const id = sha256Short(m, 6);
|
|
17899
|
+
bump("api-key", `<api-key:${id}>`);
|
|
17900
|
+
return `<api-key:${id}>`;
|
|
17901
|
+
});
|
|
17902
|
+
}
|
|
17903
|
+
text = text.replace(EMAIL_RE, (m) => {
|
|
17904
|
+
const id = sha256Short(m, 6);
|
|
17905
|
+
bump("email", `<email:${id}>`);
|
|
17906
|
+
return `<email:${id}>`;
|
|
17907
|
+
});
|
|
17908
|
+
text = text.replace(WIN_UNC_RE, (m) => {
|
|
17909
|
+
const id = sha256Short(m, 6);
|
|
17910
|
+
bump("windows-path", `<unc:${id}>`);
|
|
17911
|
+
return `<unc:${id}>`;
|
|
17912
|
+
});
|
|
17913
|
+
text = text.replace(WIN_PATH_RE, (m) => {
|
|
17914
|
+
const file2 = m.split(/[\\/]/).pop() ?? "";
|
|
17915
|
+
const id = sha256Short(m, 6);
|
|
17916
|
+
const repl = file2 && file2.includes(".") ? `<path:${id}>/${file2}` : `<path:${id}>`;
|
|
17917
|
+
bump("absolute-path", repl);
|
|
17918
|
+
return repl;
|
|
17919
|
+
});
|
|
17920
|
+
text = text.replace(POSIX_USER_PATH_RE, (m) => {
|
|
17921
|
+
const file2 = m.split("/").pop() ?? "";
|
|
17922
|
+
const id = sha256Short(m, 6);
|
|
17923
|
+
const repl = file2 && file2.includes(".") ? `<path:${id}>/${file2}` : `<path:${id}>`;
|
|
17924
|
+
bump("home-dir", repl);
|
|
17925
|
+
return repl;
|
|
17926
|
+
});
|
|
17927
|
+
text = text.replace(IPV4_RE, (m) => {
|
|
17928
|
+
bump("ipv4", "<ipv4>");
|
|
17929
|
+
return "<ipv4>";
|
|
17930
|
+
});
|
|
17931
|
+
text = text.replace(IPV6_RE, (m) => {
|
|
17932
|
+
bump("ipv6", "<ipv6>");
|
|
17933
|
+
return "<ipv6>";
|
|
17934
|
+
});
|
|
17935
|
+
text = text.replace(UUID_RE, (m) => {
|
|
17936
|
+
bump("uuid", "<uuid>");
|
|
17937
|
+
return "<uuid>";
|
|
17938
|
+
});
|
|
17939
|
+
text = text.replace(LONG_HASH_RE, (m) => {
|
|
17940
|
+
bump("long-hash", "<hash>");
|
|
17941
|
+
return "<hash>";
|
|
17942
|
+
});
|
|
17943
|
+
return { text, report: { found } };
|
|
17944
|
+
}
|
|
17945
|
+
|
|
17946
|
+
// ../../packages/privacy-edge/src/self-reference.ts
|
|
17947
|
+
var L = "(?<![A-Za-z0-9])";
|
|
17948
|
+
var R = "(?![A-Za-z0-9])";
|
|
17949
|
+
var esc2 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
17950
|
+
function locatorTerms(loc, full, part) {
|
|
17951
|
+
if (!loc) return;
|
|
17952
|
+
full.add(loc);
|
|
17953
|
+
const segs = loc.split("/").filter(Boolean);
|
|
17954
|
+
if (segs.length >= 2) {
|
|
17955
|
+
part.add(segs[segs.length - 1]);
|
|
17956
|
+
part.add(segs[segs.length - 2]);
|
|
17957
|
+
}
|
|
17958
|
+
}
|
|
17959
|
+
function scrubSelfReferences(text, project) {
|
|
17960
|
+
let out = text;
|
|
17961
|
+
out = out.replace(
|
|
17962
|
+
/\b(MRs?|PRs?|merge requests?|pull requests?|issues?|tickets?)\s+#?[0-9]+\b/gi,
|
|
17963
|
+
(_m, kind) => {
|
|
17964
|
+
const k = kind.toLowerCase();
|
|
17965
|
+
if (k.startsWith("p")) return "a pull request";
|
|
17966
|
+
if (k.startsWith("i")) return "an issue";
|
|
17967
|
+
if (k.startsWith("t")) return "a ticket";
|
|
17968
|
+
return "a merge request";
|
|
17969
|
+
}
|
|
17970
|
+
).replace(new RegExp(`${L}![0-9]{1,6}(?![0-9])`, "g"), "a merge request").replace(new RegExp(`(?<![A-Za-z0-9#])#[0-9]{2,6}(?![0-9])`, "g"), "an issue");
|
|
17971
|
+
const full = /* @__PURE__ */ new Set();
|
|
17972
|
+
const part = /* @__PURE__ */ new Set();
|
|
17973
|
+
locatorTerms(project.repoLocator, full, part);
|
|
17974
|
+
for (const a of project.aliases ?? []) locatorTerms(a, full, part);
|
|
17975
|
+
if (project.name) part.add(project.name);
|
|
17976
|
+
for (const a of project.aka ?? []) part.add(a);
|
|
17977
|
+
const ordered = [
|
|
17978
|
+
...[...full].map((t) => ({ t, repl: "the repository" })),
|
|
17979
|
+
...[...part].map((t) => ({ t, repl: "the project" }))
|
|
17980
|
+
].filter((x) => x.t && x.t.length >= 2).sort((a, b) => b.t.length - a.t.length);
|
|
17981
|
+
for (const { t, repl } of ordered) {
|
|
17982
|
+
out = out.replace(new RegExp(`${L}${esc2(t)}${R}`, "gi"), repl);
|
|
17983
|
+
}
|
|
17984
|
+
out = out.replace(/\b(the|a|an|its|our|this)\s+the\s+(project|repository)\b/gi, "the $2");
|
|
17985
|
+
return out;
|
|
17986
|
+
}
|
|
17987
|
+
|
|
17988
|
+
// ../../packages/privacy-edge/src/generalize.ts
|
|
17989
|
+
var TOKEN_RULES = [
|
|
17990
|
+
{ re: /<api-key:[0-9a-f]+>/gi, cls: "credential" },
|
|
17991
|
+
{ re: /<email:[0-9a-f]+>/gi, cls: "email" },
|
|
17992
|
+
{ re: /<unc:[0-9a-f]+>/gi, cls: "path" },
|
|
17993
|
+
{ re: /<path:[0-9a-f]+>\/[^\s)"']+/gi, cls: "file" },
|
|
17994
|
+
// path + preserved filename
|
|
17995
|
+
{ re: /<path:[0-9a-f]+>/gi, cls: "path" },
|
|
17996
|
+
{ re: /<ipv4>|<ipv6>/gi, cls: "ip" },
|
|
17997
|
+
{ re: /<uuid>/gi, cls: "uuid" },
|
|
17998
|
+
{ re: /<hash>/gi, cls: "hash" }
|
|
17999
|
+
];
|
|
18000
|
+
function generalize(text, opts = {}) {
|
|
18001
|
+
const level = opts.level ?? 1;
|
|
18002
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18003
|
+
let out = generalizeDates(text, level);
|
|
18004
|
+
out = scrub(out).text;
|
|
18005
|
+
for (const { re, cls } of TOKEN_RULES) {
|
|
18006
|
+
out = out.replace(re, () => {
|
|
18007
|
+
seen.add(cls);
|
|
18008
|
+
return generalizePhrase(cls, level);
|
|
18009
|
+
});
|
|
18010
|
+
}
|
|
18011
|
+
if (opts.project) out = scrubSelfReferences(out, opts.project);
|
|
18012
|
+
return { text: out, report: { level, classes: [...seen] } };
|
|
18013
|
+
}
|
|
18014
|
+
|
|
18015
|
+
// src/instance-ingest.ts
|
|
18016
|
+
init_src();
|
|
18017
|
+
|
|
18018
|
+
// src/contribution-ready.ts
|
|
18019
|
+
function cosine2(a, b) {
|
|
18020
|
+
if (a.length === 0 || a.length !== b.length) return 0;
|
|
18021
|
+
let dot = 0;
|
|
18022
|
+
let na = 0;
|
|
18023
|
+
let nb = 0;
|
|
18024
|
+
for (let i = 0; i < a.length; i++) {
|
|
18025
|
+
dot += a[i] * b[i];
|
|
18026
|
+
na += a[i] * a[i];
|
|
18027
|
+
nb += b[i] * b[i];
|
|
18028
|
+
}
|
|
18029
|
+
return na === 0 || nb === 0 ? 0 : dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
18030
|
+
}
|
|
18031
|
+
function noveltyAgainst(node, neighbors, opts = {}) {
|
|
18032
|
+
const floor = opts.dedupCosine ?? NEMORI_DEDUP_COSINE;
|
|
18033
|
+
const emb = node.embedding ?? [];
|
|
18034
|
+
if (emb.length === 0) {
|
|
18035
|
+
return { ready: true, surprise: 1, topCosine: 0, reason: "no-embedding (fidelity-first)" };
|
|
18036
|
+
}
|
|
18037
|
+
let topCosine = 0;
|
|
18038
|
+
for (const other of neighbors) {
|
|
18039
|
+
if (other.id === node.id) continue;
|
|
18040
|
+
const oe = other.embedding ?? [];
|
|
18041
|
+
if (oe.length !== emb.length) continue;
|
|
18042
|
+
const c = cosine2(emb, oe);
|
|
18043
|
+
if (c > topCosine) topCosine = c;
|
|
18044
|
+
}
|
|
18045
|
+
const ready = topCosine < floor;
|
|
18046
|
+
return {
|
|
18047
|
+
ready,
|
|
18048
|
+
surprise: 1 - topCosine,
|
|
18049
|
+
topCosine,
|
|
18050
|
+
reason: ready ? "novel (not a near-duplicate)" : "near-duplicate of a reference node"
|
|
18051
|
+
};
|
|
18052
|
+
}
|
|
18053
|
+
|
|
18054
|
+
// src/profile.ts
|
|
18055
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
18056
|
+
init_src2();
|
|
18057
|
+
|
|
18058
|
+
// ../../node_modules/.pnpm/env-paths@3.0.0/node_modules/env-paths/index.js
|
|
18059
|
+
import os from "node:os";
|
|
18060
|
+
import process3 from "node:process";
|
|
18061
|
+
var homedir = os.homedir();
|
|
18062
|
+
var tmpdir = os.tmpdir();
|
|
18063
|
+
var { env } = process3;
|
|
18064
|
+
|
|
18065
|
+
// src/git-remote.ts
|
|
18066
|
+
init_src();
|
|
18067
|
+
|
|
18068
|
+
// src/profile.ts
|
|
18069
|
+
function sessionOriginKey(sessionId) {
|
|
18070
|
+
if (!sessionId) return void 0;
|
|
18071
|
+
return "ws_" + createHash2("sha256").update(sessionId).digest("hex").slice(0, 12);
|
|
18072
|
+
}
|
|
18073
|
+
|
|
18074
|
+
// src/public-symbols.ts
|
|
18075
|
+
import { readFileSync, readdirSync, existsSync } from "node:fs";
|
|
18076
|
+
import { join } from "node:path";
|
|
18077
|
+
var HEAD_BYTES = 8 * 1024;
|
|
18078
|
+
var INDEX_TTL_MS = 10 * 60 * 1e3;
|
|
18079
|
+
var MIN_SYMBOL_LEN = 4;
|
|
18080
|
+
function isNameShapedSymbol(name) {
|
|
18081
|
+
return /[A-Z0-9_$]/.test(name);
|
|
18082
|
+
}
|
|
18083
|
+
var NAMED_IMPORT_RE = /import\s+(?:type\s+)?(.+?)\s+from\s+['"]([^'"]+)['"]/g;
|
|
18084
|
+
var REQUIRE_RE = /(?:const|let|var)\s+(.+?)\s*=\s*require\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
18085
|
+
function isBareExternal(spec, internalNames) {
|
|
18086
|
+
if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("node:")) return false;
|
|
18087
|
+
const pkg = spec.startsWith("@") ? spec.split("/").slice(0, 2).join("/") : spec.split("/")[0];
|
|
18088
|
+
return !internalNames.has(pkg);
|
|
18089
|
+
}
|
|
18090
|
+
function bindingNames(clause) {
|
|
18091
|
+
const names = [];
|
|
18092
|
+
const braced = /\{([^}]*)\}/.exec(clause);
|
|
18093
|
+
if (braced) {
|
|
18094
|
+
for (const part of braced[1].split(",")) {
|
|
18095
|
+
const local = part.split(/\s+as\s+/).pop()?.trim();
|
|
18096
|
+
if (local && /^[A-Za-z_$][\w$]*$/.test(local)) names.push(local);
|
|
18097
|
+
}
|
|
18098
|
+
}
|
|
18099
|
+
const ns = /\*\s+as\s+([A-Za-z_$][\w$]*)/.exec(clause);
|
|
18100
|
+
if (ns) names.push(ns[1]);
|
|
18101
|
+
const head = clause.replace(/\{[^}]*\}/, "").replace(/\*\s+as\s+[A-Za-z_$][\w$]*/, "");
|
|
18102
|
+
const def = /(?:^|,)\s*([A-Za-z_$][\w$]*)\s*(?:,|$)/.exec(head.trim());
|
|
18103
|
+
if (def) names.push(def[1]);
|
|
18104
|
+
return names;
|
|
18105
|
+
}
|
|
18106
|
+
function internalPackageNames(workspaceRoot) {
|
|
18107
|
+
const names = /* @__PURE__ */ new Set();
|
|
18108
|
+
const tryRead = (dir) => {
|
|
18109
|
+
const pj = join(dir, "package.json");
|
|
18110
|
+
if (!existsSync(pj)) return;
|
|
18111
|
+
try {
|
|
18112
|
+
const name = JSON.parse(readFileSync(pj, "utf8")).name;
|
|
18113
|
+
if (typeof name === "string" && name.length > 0) names.add(name);
|
|
18114
|
+
} catch {
|
|
18115
|
+
}
|
|
18116
|
+
};
|
|
18117
|
+
tryRead(workspaceRoot);
|
|
18118
|
+
for (const group of ["packages", "apps"]) {
|
|
18119
|
+
const groupDir = join(workspaceRoot, group);
|
|
18120
|
+
if (!existsSync(groupDir)) continue;
|
|
18121
|
+
try {
|
|
18122
|
+
for (const entry of readdirSync(groupDir)) tryRead(join(groupDir, entry));
|
|
18123
|
+
} catch {
|
|
18124
|
+
}
|
|
18125
|
+
}
|
|
18126
|
+
return names;
|
|
18127
|
+
}
|
|
18128
|
+
var cache = /* @__PURE__ */ new Map();
|
|
18129
|
+
function publicSymbolIndex(store, workspaceRoot, deps = {}) {
|
|
18130
|
+
const now = deps.nowMs ?? Date.now();
|
|
18131
|
+
const cached2 = cache.get(workspaceRoot);
|
|
18132
|
+
if (cached2 && now - cached2.builtAt < INDEX_TTL_MS) return cached2;
|
|
18133
|
+
const readHead = deps.readHead ?? ((absPath) => {
|
|
18134
|
+
try {
|
|
18135
|
+
return readFileSync(absPath, "utf8").slice(0, HEAD_BYTES);
|
|
18136
|
+
} catch {
|
|
18137
|
+
return "";
|
|
18138
|
+
}
|
|
18139
|
+
});
|
|
18140
|
+
const internal = internalPackageNames(workspaceRoot);
|
|
18141
|
+
const bareModules = /* @__PURE__ */ new Set();
|
|
18142
|
+
for (const mod of store.findNodesByLabel("Module")) {
|
|
18143
|
+
if (isBareExternal(mod.description, internal)) bareModules.add(mod.id);
|
|
18144
|
+
}
|
|
18145
|
+
const files = /* @__PURE__ */ new Set();
|
|
18146
|
+
for (const modId of bareModules) {
|
|
18147
|
+
for (const e of store.inEdges(modId, ["IMPORTS"])) {
|
|
18148
|
+
const f = store.getNode(e.from);
|
|
18149
|
+
const rel = f?.attrs["relPath"];
|
|
18150
|
+
if (f && f.validTo == null && typeof rel === "string") files.add(rel);
|
|
18151
|
+
}
|
|
18152
|
+
}
|
|
18153
|
+
const symbols = /* @__PURE__ */ new Set();
|
|
18154
|
+
for (const rel of files) {
|
|
18155
|
+
const head = readHead(join(workspaceRoot, rel));
|
|
18156
|
+
if (!head) continue;
|
|
18157
|
+
for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
|
|
18158
|
+
re.lastIndex = 0;
|
|
18159
|
+
for (const m of head.matchAll(re)) {
|
|
18160
|
+
if (!isBareExternal(m[2], internal)) continue;
|
|
18161
|
+
for (const name of bindingNames(m[1])) {
|
|
18162
|
+
if (name.length >= MIN_SYMBOL_LEN && isNameShapedSymbol(name)) symbols.add(name);
|
|
18163
|
+
}
|
|
18164
|
+
}
|
|
18165
|
+
}
|
|
18166
|
+
}
|
|
18167
|
+
const index = { symbols, builtAt: now };
|
|
18168
|
+
cache.set(workspaceRoot, index);
|
|
18169
|
+
return index;
|
|
18170
|
+
}
|
|
18171
|
+
var PRESERVED_SYMBOLS_CAP = 8;
|
|
18172
|
+
function preservedSymbolsFor(description, index) {
|
|
18173
|
+
const out = [];
|
|
18174
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18175
|
+
for (const m of description.matchAll(/[A-Za-z_$][\w$]{3,}/g)) {
|
|
18176
|
+
const tok = m[0];
|
|
18177
|
+
if (seen.has(tok) || !index.symbols.has(tok)) continue;
|
|
18178
|
+
seen.add(tok);
|
|
18179
|
+
out.push(tok);
|
|
18180
|
+
if (out.length >= PRESERVED_SYMBOLS_CAP) break;
|
|
18181
|
+
}
|
|
18182
|
+
return out;
|
|
18183
|
+
}
|
|
18184
|
+
function internalSymbolsFor(description, lexiconHas, publicIndex) {
|
|
18185
|
+
const out = [];
|
|
18186
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18187
|
+
for (const m of description.matchAll(/[A-Za-z_$][\w$]{2,}(?:\.[A-Za-z_$][\w$]+)*/g)) {
|
|
18188
|
+
const tok = m[0];
|
|
18189
|
+
if (seen.has(tok)) continue;
|
|
18190
|
+
seen.add(tok);
|
|
18191
|
+
if (!lexiconHas(tok)) continue;
|
|
18192
|
+
if (publicIndex?.symbols.has(tok)) continue;
|
|
18193
|
+
out.push(tok);
|
|
18194
|
+
if (out.length >= PRESERVED_SYMBOLS_CAP) break;
|
|
18195
|
+
}
|
|
18196
|
+
return out;
|
|
18197
|
+
}
|
|
18198
|
+
|
|
18199
|
+
// src/generalize-graph.ts
|
|
18200
|
+
init_src();
|
|
18201
|
+
|
|
18202
|
+
// src/derive-summary.ts
|
|
18203
|
+
var NAME_DERIVED_ENABLED = true;
|
|
18204
|
+
var KIND_ARTICLE = {
|
|
18205
|
+
function: "a",
|
|
18206
|
+
method: "a",
|
|
18207
|
+
class: "a",
|
|
18208
|
+
interface: "an",
|
|
18209
|
+
constant: "a"
|
|
18210
|
+
};
|
|
18211
|
+
var lead = (kind) => `${KIND_ARTICLE[kind]} ${kind}`;
|
|
18212
|
+
var MAX_PAYLOAD_CHARS = 56;
|
|
18213
|
+
var DANGLING = /* @__PURE__ */ new Set([
|
|
18214
|
+
"a",
|
|
18215
|
+
"an",
|
|
18216
|
+
"the",
|
|
18217
|
+
"and",
|
|
18218
|
+
"or",
|
|
18219
|
+
"but",
|
|
18220
|
+
"of",
|
|
18221
|
+
"to",
|
|
18222
|
+
"in",
|
|
18223
|
+
"on",
|
|
18224
|
+
"at",
|
|
18225
|
+
"by",
|
|
18226
|
+
"for",
|
|
18227
|
+
"from",
|
|
18228
|
+
"with",
|
|
18229
|
+
"into",
|
|
18230
|
+
"onto",
|
|
18231
|
+
"over",
|
|
18232
|
+
"under",
|
|
18233
|
+
"as",
|
|
18234
|
+
"that",
|
|
18235
|
+
"which",
|
|
18236
|
+
"when",
|
|
18237
|
+
"while",
|
|
18238
|
+
"if",
|
|
18239
|
+
"so",
|
|
18240
|
+
"then",
|
|
18241
|
+
"than",
|
|
18242
|
+
"its",
|
|
18243
|
+
"their",
|
|
18244
|
+
"this",
|
|
18245
|
+
"these",
|
|
18246
|
+
"those",
|
|
18247
|
+
"is",
|
|
18248
|
+
"are",
|
|
18249
|
+
"was",
|
|
18250
|
+
"be",
|
|
18251
|
+
"been",
|
|
18252
|
+
"not",
|
|
18253
|
+
"no",
|
|
18254
|
+
"per",
|
|
18255
|
+
"via",
|
|
18256
|
+
"up",
|
|
18257
|
+
"out",
|
|
18258
|
+
"off",
|
|
18259
|
+
"about",
|
|
18260
|
+
"after",
|
|
18261
|
+
"before",
|
|
18262
|
+
"during",
|
|
18263
|
+
"without",
|
|
18264
|
+
"within",
|
|
18265
|
+
"against",
|
|
18266
|
+
"between",
|
|
18267
|
+
"through",
|
|
18268
|
+
"across",
|
|
18269
|
+
"upon"
|
|
18270
|
+
]);
|
|
18271
|
+
var VERBS = /* @__PURE__ */ new Set([
|
|
18272
|
+
"accept",
|
|
18273
|
+
"add",
|
|
18274
|
+
"advance",
|
|
18275
|
+
"allow",
|
|
18276
|
+
"apply",
|
|
18277
|
+
"assert",
|
|
18278
|
+
"attach",
|
|
18279
|
+
"bind",
|
|
18280
|
+
"build",
|
|
18281
|
+
"bump",
|
|
18282
|
+
"cache",
|
|
18283
|
+
"call",
|
|
18284
|
+
"cap",
|
|
18285
|
+
"carry",
|
|
18286
|
+
"check",
|
|
18287
|
+
"choose",
|
|
18288
|
+
"clamp",
|
|
18289
|
+
"classify",
|
|
18290
|
+
"clean",
|
|
18291
|
+
"clear",
|
|
18292
|
+
"close",
|
|
18293
|
+
"collapse",
|
|
18294
|
+
"collect",
|
|
18295
|
+
"compare",
|
|
18296
|
+
"compute",
|
|
18297
|
+
"connect",
|
|
18298
|
+
"contain",
|
|
18299
|
+
"convert",
|
|
18300
|
+
"count",
|
|
18301
|
+
"cover",
|
|
18302
|
+
"create",
|
|
18303
|
+
"decide",
|
|
18304
|
+
"declare",
|
|
18305
|
+
"decode",
|
|
18306
|
+
"define",
|
|
18307
|
+
"delete",
|
|
18308
|
+
"demote",
|
|
18309
|
+
"derive",
|
|
18310
|
+
"describe",
|
|
18311
|
+
"detach",
|
|
18312
|
+
"detect",
|
|
18313
|
+
"determine",
|
|
18314
|
+
"disable",
|
|
18315
|
+
"drain",
|
|
18316
|
+
"drop",
|
|
18317
|
+
"emit",
|
|
18318
|
+
"enable",
|
|
18319
|
+
"encode",
|
|
18320
|
+
"ensure",
|
|
18321
|
+
"enqueue",
|
|
18322
|
+
"evaluate",
|
|
18323
|
+
"expand",
|
|
18324
|
+
"expose",
|
|
18325
|
+
"extend",
|
|
18326
|
+
"extract",
|
|
18327
|
+
"fetch",
|
|
18328
|
+
"fill",
|
|
18329
|
+
"filter",
|
|
18330
|
+
"find",
|
|
18331
|
+
"fire",
|
|
18332
|
+
"fix",
|
|
18333
|
+
"flag",
|
|
18334
|
+
"flatten",
|
|
18335
|
+
"flip",
|
|
18336
|
+
"flush",
|
|
18337
|
+
"fold",
|
|
18338
|
+
"format",
|
|
18339
|
+
"gate",
|
|
18340
|
+
"gather",
|
|
18341
|
+
"generate",
|
|
18342
|
+
"get",
|
|
18343
|
+
"give",
|
|
18344
|
+
"grant",
|
|
18345
|
+
"guard",
|
|
18346
|
+
"handle",
|
|
18347
|
+
"hash",
|
|
18348
|
+
"hide",
|
|
18349
|
+
"hold",
|
|
18350
|
+
"hook",
|
|
18351
|
+
"index",
|
|
18352
|
+
"infer",
|
|
18353
|
+
"initialize",
|
|
18354
|
+
"insert",
|
|
18355
|
+
"inspect",
|
|
18356
|
+
"join",
|
|
18357
|
+
"keep",
|
|
18358
|
+
"limit",
|
|
18359
|
+
"link",
|
|
18360
|
+
"list",
|
|
18361
|
+
"load",
|
|
18362
|
+
"locate",
|
|
18363
|
+
"log",
|
|
18364
|
+
"make",
|
|
18365
|
+
"map",
|
|
18366
|
+
"mark",
|
|
18367
|
+
"match",
|
|
18368
|
+
"materialize",
|
|
18369
|
+
"measure",
|
|
18370
|
+
"merge",
|
|
18371
|
+
"mint",
|
|
18372
|
+
"mount",
|
|
18373
|
+
"move",
|
|
18374
|
+
"name",
|
|
18375
|
+
"normalize",
|
|
18376
|
+
"note",
|
|
18377
|
+
"observe",
|
|
18378
|
+
"open",
|
|
18379
|
+
"package",
|
|
18380
|
+
"parse",
|
|
18381
|
+
"persist",
|
|
18382
|
+
"pick",
|
|
18383
|
+
"pop",
|
|
18384
|
+
"populate",
|
|
18385
|
+
"prepare",
|
|
18386
|
+
"produce",
|
|
18387
|
+
"promote",
|
|
18388
|
+
"prune",
|
|
18389
|
+
"publish",
|
|
18390
|
+
"pull",
|
|
18391
|
+
"push",
|
|
18392
|
+
"query",
|
|
18393
|
+
"queue",
|
|
18394
|
+
"raise",
|
|
18395
|
+
"rank",
|
|
18396
|
+
"read",
|
|
18397
|
+
"rebuild",
|
|
18398
|
+
"record",
|
|
18399
|
+
"recover",
|
|
18400
|
+
"redact",
|
|
18401
|
+
"reduce",
|
|
18402
|
+
"refresh",
|
|
18403
|
+
"register",
|
|
18404
|
+
"reject",
|
|
18405
|
+
"release",
|
|
18406
|
+
"remove",
|
|
18407
|
+
"rename",
|
|
18408
|
+
"render",
|
|
18409
|
+
"repair",
|
|
18410
|
+
"replace",
|
|
18411
|
+
"replay",
|
|
18412
|
+
"report",
|
|
18413
|
+
"represent",
|
|
18414
|
+
"require",
|
|
18415
|
+
"reset",
|
|
18416
|
+
"resolve",
|
|
18417
|
+
"restore",
|
|
18418
|
+
"retire",
|
|
18419
|
+
"retry",
|
|
18420
|
+
"return",
|
|
18421
|
+
"reveal",
|
|
18422
|
+
"revive",
|
|
18423
|
+
"rewrite",
|
|
18424
|
+
"route",
|
|
18425
|
+
"run",
|
|
18426
|
+
"sanitize",
|
|
18427
|
+
"save",
|
|
18428
|
+
"scan",
|
|
18429
|
+
"schedule",
|
|
18430
|
+
"score",
|
|
18431
|
+
"scrub",
|
|
18432
|
+
"seed",
|
|
18433
|
+
"select",
|
|
18434
|
+
"send",
|
|
18435
|
+
"serialize",
|
|
18436
|
+
"serve",
|
|
18437
|
+
"set",
|
|
18438
|
+
"show",
|
|
18439
|
+
"sign",
|
|
18440
|
+
"skip",
|
|
18441
|
+
"sort",
|
|
18442
|
+
"split",
|
|
18443
|
+
"stamp",
|
|
18444
|
+
"start",
|
|
18445
|
+
"stop",
|
|
18446
|
+
"store",
|
|
18447
|
+
"strip",
|
|
18448
|
+
"summarize",
|
|
18449
|
+
"supply",
|
|
18450
|
+
"suppress",
|
|
18451
|
+
"sweep",
|
|
18452
|
+
"switch",
|
|
18453
|
+
"sync",
|
|
18454
|
+
"tag",
|
|
18455
|
+
"take",
|
|
18456
|
+
"test",
|
|
18457
|
+
"throw",
|
|
18458
|
+
"toggle",
|
|
18459
|
+
"touch",
|
|
18460
|
+
"trace",
|
|
18461
|
+
"track",
|
|
18462
|
+
"transform",
|
|
18463
|
+
"translate",
|
|
18464
|
+
"traverse",
|
|
18465
|
+
"trigger",
|
|
18466
|
+
"trim",
|
|
18467
|
+
"turn",
|
|
18468
|
+
"unwrap",
|
|
18469
|
+
"update",
|
|
18470
|
+
"upsert",
|
|
18471
|
+
"validate",
|
|
18472
|
+
"verify",
|
|
18473
|
+
"walk",
|
|
18474
|
+
"warn",
|
|
18475
|
+
"watch",
|
|
18476
|
+
"wire",
|
|
18477
|
+
"wrap",
|
|
18478
|
+
"write",
|
|
18479
|
+
"yield"
|
|
18480
|
+
]);
|
|
18481
|
+
function inflect(verb) {
|
|
18482
|
+
if (/(?:s|x|ch|sh|z)$/.test(verb)) return `${verb}es`;
|
|
18483
|
+
if (/[^aeiou]y$/.test(verb)) return `${verb.slice(0, -1)}ies`;
|
|
18484
|
+
return `${verb}s`;
|
|
18485
|
+
}
|
|
18486
|
+
function deinflect(word) {
|
|
18487
|
+
if (word.endsWith("ies") && VERBS.has(`${word.slice(0, -3)}y`)) return `${word.slice(0, -3)}y`;
|
|
18488
|
+
if (word.endsWith("es") && VERBS.has(word.slice(0, -2))) return word.slice(0, -2);
|
|
18489
|
+
if (word.endsWith("s") && VERBS.has(word.slice(0, -1))) return word.slice(0, -1);
|
|
18490
|
+
return null;
|
|
18491
|
+
}
|
|
18492
|
+
function verbHead(word) {
|
|
18493
|
+
const w = word.toLowerCase().replace(/[^a-z]/g, "");
|
|
18494
|
+
if (!w) return null;
|
|
18495
|
+
if (VERBS.has(w)) return inflect(w);
|
|
18496
|
+
return deinflect(w) !== null ? w : null;
|
|
18497
|
+
}
|
|
18498
|
+
var tidy = (s) => s.replace(/\s+/g, " ").replace(/\s+([,.;:])/g, "$1").replace(/[\s,;:.]+$/, "").trim();
|
|
18499
|
+
function identifierWords(name) {
|
|
18500
|
+
return name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/[_$]+/g, " ").toLowerCase().split(/\s+/).filter(Boolean);
|
|
18501
|
+
}
|
|
18502
|
+
function clipClause(text) {
|
|
18503
|
+
let t = tidy(text.split(/\s+[—–-]\s+|[:;(]|,|\s+(?:and|or|plus)\s+|\s\+\s/)[0] ?? "");
|
|
18504
|
+
if (t.length > MAX_PAYLOAD_CHARS) {
|
|
18505
|
+
const cut = t.slice(0, MAX_PAYLOAD_CHARS).lastIndexOf(" ");
|
|
18506
|
+
if (cut <= 20) return null;
|
|
18507
|
+
t = tidy(t.slice(0, cut));
|
|
18508
|
+
}
|
|
18509
|
+
const words = t.split(/\s+/);
|
|
18510
|
+
while (words.length > 0 && DANGLING.has(words[words.length - 1].toLowerCase().replace(/[^a-z]/g, ""))) {
|
|
18511
|
+
words.pop();
|
|
18512
|
+
}
|
|
18513
|
+
const out = tidy(words.join(" "));
|
|
18514
|
+
return out.length >= 12 && out.split(/\s+/).length >= 2 ? out : null;
|
|
18515
|
+
}
|
|
18516
|
+
function firstSentence(doc) {
|
|
18517
|
+
const clean = doc.replace(/^[\s*/]+/gm, " ").replace(/\s+/g, " ").trim();
|
|
18518
|
+
const m = clean.match(/^(.{10,400}?[.!?])(\s|$)/);
|
|
18519
|
+
return (m ? m[1] : clean).slice(0, 280);
|
|
18520
|
+
}
|
|
18521
|
+
function stripUnshippable(sentence) {
|
|
18522
|
+
return sentence.replace(/`[^`]*`|"[^"]*"|'[^']{2,}'/g, " ").replace(/[\w.~-]+[/\\][\w.$~-]+/g, " ").replace(/\([^)]*\)/g, " ");
|
|
18523
|
+
}
|
|
18524
|
+
function summaryFromDoc(doc, kind) {
|
|
18525
|
+
const clipped = clipClause(stripUnshippable(firstSentence(doc)).replace(/^[^A-Za-z]+/, ""));
|
|
18526
|
+
if (clipped === null) return null;
|
|
18527
|
+
const words = clipped.split(/\s+/);
|
|
18528
|
+
const verb = verbHead(words[0]);
|
|
18529
|
+
if (verb !== null && words.length > 1) {
|
|
18530
|
+
return tidy(`${lead(kind)} that ${verb} ${words.slice(1).join(" ")}`);
|
|
18531
|
+
}
|
|
18532
|
+
if (verb !== null) return null;
|
|
18533
|
+
const noun = clipped.replace(/^(?:the|a|an)\s+/i, "");
|
|
18534
|
+
return tidy(`${lead(kind)} for ${noun.charAt(0).toLowerCase()}${noun.slice(1)}`);
|
|
18535
|
+
}
|
|
18536
|
+
var VERB_PHRASE_KINDS = /* @__PURE__ */ new Set(["function", "method"]);
|
|
18537
|
+
function summaryFromName(name, kind) {
|
|
18538
|
+
if (!NAME_DERIVED_ENABLED) return null;
|
|
18539
|
+
const words = identifierWords(name);
|
|
18540
|
+
while (words.length > 1 && DANGLING.has(words[words.length - 1])) words.pop();
|
|
18541
|
+
if (words.length === 0) return null;
|
|
18542
|
+
const verb = VERB_PHRASE_KINDS.has(kind) ? verbHead(words[0]) : null;
|
|
18543
|
+
const rest = words.slice(1).join(" ");
|
|
18544
|
+
const phrase = verb !== null && rest ? `${lead(kind)} that ${verb} the ${rest}` : verb !== null ? null : `${lead(kind)} for the ${words.join(" ")}`;
|
|
18545
|
+
if (phrase === null) return null;
|
|
18546
|
+
const trimmed = tidy(phrase);
|
|
18547
|
+
return trimmed.length <= MAX_PAYLOAD_CHARS + 24 ? trimmed : null;
|
|
18548
|
+
}
|
|
18549
|
+
function summaryCandidates(name, kind, doc) {
|
|
18550
|
+
const candidates = [];
|
|
18551
|
+
const fromDoc = doc ? summaryFromDoc(doc, kind) : null;
|
|
18552
|
+
if (fromDoc !== null) candidates.push(fromDoc);
|
|
18553
|
+
const fromName = summaryFromName(name, kind);
|
|
18554
|
+
if (fromName !== null && fromName !== fromDoc) candidates.push(fromName);
|
|
18555
|
+
return candidates;
|
|
18556
|
+
}
|
|
18557
|
+
|
|
18558
|
+
// src/generalize-graph.ts
|
|
18559
|
+
var SYMBOL_LABELS = [
|
|
18560
|
+
["Function", "function"],
|
|
18561
|
+
["Method", "method"],
|
|
18562
|
+
["Class", "class"],
|
|
18563
|
+
["Interface", "interface"],
|
|
18564
|
+
["Const", "constant"]
|
|
18565
|
+
];
|
|
18566
|
+
var BUILTIN_TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
18567
|
+
"Array",
|
|
18568
|
+
"Boolean",
|
|
18569
|
+
"Buffer",
|
|
18570
|
+
"Date",
|
|
18571
|
+
"Error",
|
|
18572
|
+
"Function",
|
|
18573
|
+
"Map",
|
|
18574
|
+
"Math",
|
|
18575
|
+
"Number",
|
|
18576
|
+
"Object",
|
|
18577
|
+
"Promise",
|
|
18578
|
+
"Proxy",
|
|
18579
|
+
"RegExp",
|
|
18580
|
+
"Set",
|
|
18581
|
+
"String",
|
|
18582
|
+
"Symbol",
|
|
18583
|
+
"WeakMap",
|
|
18584
|
+
"WeakSet",
|
|
18585
|
+
"TypeError",
|
|
18586
|
+
"RangeError",
|
|
18587
|
+
"SyntaxError",
|
|
18588
|
+
"URL",
|
|
18589
|
+
"Request",
|
|
18590
|
+
"Response",
|
|
18591
|
+
"Headers"
|
|
18592
|
+
]);
|
|
18593
|
+
function isDistinctiveIdentifier(name) {
|
|
18594
|
+
if (name.length < 3) return false;
|
|
18595
|
+
if (/[\s:]/.test(name)) return false;
|
|
18596
|
+
if (BUILTIN_TYPE_NAMES.has(name)) return false;
|
|
18597
|
+
if (name.includes(".") || name.includes("_") || /\d/.test(name)) return true;
|
|
18598
|
+
if (/[a-z][A-Z]/.test(name)) return true;
|
|
18599
|
+
if (/^[A-Z]/.test(name) && /[a-z]/.test(name) && name.length >= 4) return true;
|
|
18600
|
+
return false;
|
|
18601
|
+
}
|
|
18602
|
+
var DOC_COMMENT_KINDS = /* @__PURE__ */ new Set(["docstring", "explanation"]);
|
|
18603
|
+
var MAX_DOC_CHARS = 600;
|
|
18604
|
+
function buildDocIndex(store) {
|
|
18605
|
+
const byName = /* @__PURE__ */ new Map();
|
|
18606
|
+
for (const c of store.findNodesByLabel("Comment")) {
|
|
18607
|
+
const name = c.attrs["attachedTo"];
|
|
18608
|
+
const kind = c.attrs["kind"];
|
|
18609
|
+
if (typeof name !== "string" || !name) continue;
|
|
18610
|
+
if (typeof kind !== "string" || !DOC_COMMENT_KINDS.has(kind)) continue;
|
|
18611
|
+
const text = typeof c.attrs["text"] === "string" ? c.attrs["text"] : c.description;
|
|
18612
|
+
if (!text?.trim()) continue;
|
|
18613
|
+
if (!byName.has(name)) byName.set(name, text.trim().slice(0, MAX_DOC_CHARS));
|
|
18614
|
+
}
|
|
18615
|
+
return byName;
|
|
18616
|
+
}
|
|
18617
|
+
function buildSymbolLexicon(store) {
|
|
18618
|
+
const lex = /* @__PURE__ */ new Map();
|
|
18619
|
+
const docs = buildDocIndex(store);
|
|
18620
|
+
const candidates = [];
|
|
18621
|
+
for (const [label, kind] of SYMBOL_LABELS) {
|
|
18622
|
+
for (const n of store.findNodesByLabel(label)) {
|
|
18623
|
+
const qname = String(n.attrs["qname"] ?? "");
|
|
18624
|
+
const doc = (n.description ? docs.get(n.description) : void 0) ?? (qname ? docs.get(qname) : void 0);
|
|
18625
|
+
for (const name of [n.description, qname]) {
|
|
18626
|
+
if (name && isDistinctiveIdentifier(name) && !lex.has(name)) {
|
|
18627
|
+
lex.set(name, { kind });
|
|
18628
|
+
candidates.push([name, kind, doc]);
|
|
18629
|
+
}
|
|
18630
|
+
}
|
|
18631
|
+
}
|
|
18632
|
+
}
|
|
18633
|
+
const isKnown = (tok) => lex.has(tok);
|
|
18634
|
+
for (const [name, kind, doc] of candidates) {
|
|
18635
|
+
for (const phrase of summaryCandidates(name, kind, doc)) {
|
|
18636
|
+
if (summaryRejectionReason(phrase, isKnown) === null) {
|
|
18637
|
+
lex.get(name).summary = phrase;
|
|
18638
|
+
break;
|
|
18639
|
+
}
|
|
18640
|
+
}
|
|
18641
|
+
}
|
|
18642
|
+
return lex;
|
|
18643
|
+
}
|
|
18644
|
+
var RE_RESERVED = /[.*+?^${}()|[\]\\]/g;
|
|
18645
|
+
var escapeRe2 = (s) => s.replace(RE_RESERVED, "\\$&");
|
|
18646
|
+
var RE_LEADING_ARTICLE = /^(?:an?|the)\s/i;
|
|
18647
|
+
function replaceWithPhrase(text, before, escapedKey, after, phrase) {
|
|
18648
|
+
if (!RE_LEADING_ARTICLE.test(phrase)) {
|
|
18649
|
+
return text.replace(new RegExp(`${before}${escapedKey}${after}`, "g"), phrase);
|
|
18650
|
+
}
|
|
18651
|
+
const re = new RegExp(`${before}${String.raw`(?:(An|an|A|a|The|the)\s+)?`}${escapedKey}${after}`, "g");
|
|
18652
|
+
return text.replace(
|
|
18653
|
+
re,
|
|
18654
|
+
(_match, article) => article !== void 0 && /^[A-Z]/.test(article) ? phrase.charAt(0).toUpperCase() + phrase.slice(1) : phrase
|
|
18655
|
+
);
|
|
18656
|
+
}
|
|
18657
|
+
function isBareMatchableStem(stem) {
|
|
18658
|
+
return stem.length >= 5 && /^[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)+$/.test(stem);
|
|
18659
|
+
}
|
|
18660
|
+
var CONVENTION_FILENAMES = /* @__PURE__ */ new Set([
|
|
18661
|
+
"package.json",
|
|
18662
|
+
"package-lock.json",
|
|
18663
|
+
"pnpm-lock.yaml",
|
|
18664
|
+
"pnpm-workspace.yaml",
|
|
18665
|
+
"yarn.lock",
|
|
18666
|
+
"tsconfig.json",
|
|
18667
|
+
"tsconfig.base.json",
|
|
18668
|
+
"turbo.json",
|
|
18669
|
+
"README.md",
|
|
18670
|
+
"LICENSE",
|
|
18671
|
+
"CHANGELOG.md",
|
|
18672
|
+
"CONTRIBUTING.md",
|
|
18673
|
+
// agent-config conventions — as cross-repo universal as README.md by 2026
|
|
18674
|
+
"AGENTS.md",
|
|
18675
|
+
"CLAUDE.md",
|
|
18676
|
+
"Dockerfile",
|
|
18677
|
+
"docker-compose.yml",
|
|
18678
|
+
".gitignore",
|
|
18679
|
+
".env",
|
|
18680
|
+
".env.example",
|
|
18681
|
+
"index.ts",
|
|
18682
|
+
"index.js",
|
|
18683
|
+
"index.tsx",
|
|
18684
|
+
"index.mjs"
|
|
18685
|
+
]);
|
|
18686
|
+
var CONVENTION_BASENAME_MIN_FILES = 3;
|
|
18687
|
+
var CONVENTION_STEMS = /* @__PURE__ */ new Set([
|
|
18688
|
+
"well-known",
|
|
18689
|
+
"read-only",
|
|
18690
|
+
"type-safe",
|
|
18691
|
+
"end-to-end",
|
|
18692
|
+
"fail-open",
|
|
18693
|
+
"fail-closed",
|
|
18694
|
+
"up-to-date",
|
|
18695
|
+
"server-side",
|
|
18696
|
+
"client-side",
|
|
18697
|
+
"cross-origin",
|
|
18698
|
+
"same-origin",
|
|
18699
|
+
"well-formed",
|
|
18700
|
+
"first-class",
|
|
18701
|
+
"in-memory",
|
|
18702
|
+
"single-page",
|
|
18703
|
+
"use-case",
|
|
18704
|
+
"out-of-band"
|
|
18705
|
+
]);
|
|
18706
|
+
function buildFileLexicon(store) {
|
|
18707
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
18708
|
+
const byBasename = /* @__PURE__ */ new Map();
|
|
18709
|
+
const byStem = /* @__PURE__ */ new Map();
|
|
18710
|
+
const basenameCount = /* @__PURE__ */ new Map();
|
|
18711
|
+
const stemRelPaths = /* @__PURE__ */ new Map();
|
|
18712
|
+
const entries = [];
|
|
18713
|
+
for (const n of store.findNodesByLabel("File")) {
|
|
18714
|
+
const relPath = typeof n.attrs["relPath"] === "string" && n.attrs["relPath"].length > 0 ? n.attrs["relPath"] : n.description;
|
|
18715
|
+
if (!relPath) continue;
|
|
18716
|
+
const basename = relPath.split("/").pop();
|
|
18717
|
+
if (!basename.includes(".")) continue;
|
|
18718
|
+
entries.push({ relPath, basename });
|
|
18719
|
+
basenameCount.set(basename, (basenameCount.get(basename) ?? 0) + 1);
|
|
18720
|
+
const stem = basename.slice(0, basename.indexOf("."));
|
|
18721
|
+
if (isBareMatchableStem(stem)) {
|
|
18722
|
+
let s = stemRelPaths.get(stem);
|
|
18723
|
+
if (!s) stemRelPaths.set(stem, s = /* @__PURE__ */ new Set());
|
|
18724
|
+
s.add(relPath);
|
|
18725
|
+
}
|
|
18726
|
+
}
|
|
18727
|
+
for (const { relPath, basename } of entries) {
|
|
18728
|
+
const entry = { relPath };
|
|
18729
|
+
if (relPath !== basename) byKey.set(relPath, entry);
|
|
18730
|
+
const conventional = CONVENTION_FILENAMES.has(basename) || (basenameCount.get(basename) ?? 0) >= CONVENTION_BASENAME_MIN_FILES;
|
|
18731
|
+
if (!conventional && !byKey.has(basename)) byKey.set(basename, entry);
|
|
18732
|
+
const list = byBasename.get(basename);
|
|
18733
|
+
if (list) list.push(entry);
|
|
18734
|
+
else byBasename.set(basename, [entry]);
|
|
18735
|
+
const stem = basename.slice(0, basename.indexOf("."));
|
|
18736
|
+
if (isBareMatchableStem(stem) && !CONVENTION_STEMS.has(stem) && !byStem.has(stem)) {
|
|
18737
|
+
const dirStems = new Set(
|
|
18738
|
+
[...stemRelPaths.get(stem) ?? []].map((p) => {
|
|
18739
|
+
const bn = p.split("/").pop();
|
|
18740
|
+
return p.slice(0, p.length - bn.length) + bn.slice(0, bn.indexOf("."));
|
|
18741
|
+
})
|
|
18742
|
+
);
|
|
18743
|
+
if (dirStems.size === 1) byStem.set(stem, entry);
|
|
18744
|
+
}
|
|
18745
|
+
}
|
|
18746
|
+
return { byKey, byBasename, byStem };
|
|
18747
|
+
}
|
|
18748
|
+
var FILE_TOKEN_RE = /(?:[A-Za-z0-9_.-]+\/)*[A-Za-z0-9_-][A-Za-z0-9_.-]*\.[A-Za-z0-9]+/g;
|
|
18749
|
+
function resolveFileToken(token, lexicon) {
|
|
18750
|
+
const exact = lexicon.byKey.get(token);
|
|
18751
|
+
if (exact) return exact;
|
|
18752
|
+
if (!token.includes("/")) return null;
|
|
18753
|
+
const basename = token.split("/").pop();
|
|
18754
|
+
for (const entry of lexicon.byBasename.get(basename) ?? []) {
|
|
18755
|
+
if (entry.relPath === token || entry.relPath.endsWith(`/${token}`)) return entry;
|
|
18756
|
+
}
|
|
18757
|
+
return null;
|
|
18758
|
+
}
|
|
18759
|
+
function internalFilesFor(description, lexicon) {
|
|
18760
|
+
const out = [];
|
|
18761
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18762
|
+
for (const m of description.matchAll(FILE_TOKEN_RE)) {
|
|
18763
|
+
const tok = m[0];
|
|
18764
|
+
if (seen.has(tok)) continue;
|
|
18765
|
+
seen.add(tok);
|
|
18766
|
+
if (resolveFileToken(tok, lexicon)) out.push(tok);
|
|
18767
|
+
}
|
|
18768
|
+
return out;
|
|
18769
|
+
}
|
|
18770
|
+
function fileRolePhrase(relPath, level = 1) {
|
|
18771
|
+
if (level !== 1) return "a file";
|
|
18772
|
+
if (/\.(test|spec)\.|__tests__\/|(?:^|\/)e2e\//.test(relPath)) return "a test file";
|
|
18773
|
+
if (/(?:^|\/)scripts?\//.test(relPath)) return "a script";
|
|
18774
|
+
if (/\.md$/i.test(relPath)) return "a documentation file";
|
|
18775
|
+
if (/\.(json|ya?ml|toml|env)$/i.test(relPath)) return "a config file";
|
|
18776
|
+
return "a source file";
|
|
18777
|
+
}
|
|
18778
|
+
var STEM_TOKEN_RE = /[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)+/g;
|
|
18779
|
+
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
18780
|
+
"ts",
|
|
18781
|
+
"tsx",
|
|
18782
|
+
"js",
|
|
18783
|
+
"jsx",
|
|
18784
|
+
"mjs",
|
|
18785
|
+
"cjs",
|
|
18786
|
+
"py",
|
|
18787
|
+
"go",
|
|
18788
|
+
"rs",
|
|
18789
|
+
"java",
|
|
18790
|
+
"kt",
|
|
18791
|
+
"rb",
|
|
18792
|
+
"c",
|
|
18793
|
+
"h",
|
|
18794
|
+
"cc",
|
|
18795
|
+
"cpp",
|
|
18796
|
+
"hpp",
|
|
18797
|
+
"cs",
|
|
18798
|
+
"php",
|
|
18799
|
+
"swift",
|
|
18800
|
+
"scala",
|
|
18801
|
+
"sh",
|
|
18802
|
+
"ps1",
|
|
18803
|
+
"sql",
|
|
18804
|
+
"css",
|
|
18805
|
+
"scss",
|
|
18806
|
+
"html",
|
|
18807
|
+
"vue",
|
|
18808
|
+
"svelte",
|
|
18809
|
+
"md",
|
|
18810
|
+
"json",
|
|
18811
|
+
"yaml",
|
|
18812
|
+
"yml",
|
|
18813
|
+
"toml",
|
|
18814
|
+
"ini",
|
|
18815
|
+
"env",
|
|
18816
|
+
"cypher"
|
|
18817
|
+
]);
|
|
18818
|
+
function isSourceFileToken(token) {
|
|
18819
|
+
const basename = token.split(/[/\\]/).pop() ?? token;
|
|
18820
|
+
if (CONVENTION_FILENAMES.has(basename)) return false;
|
|
18821
|
+
const ext = basename.split(".").pop();
|
|
18822
|
+
return ext !== void 0 && SOURCE_EXTENSIONS.has(ext.toLowerCase());
|
|
18823
|
+
}
|
|
18824
|
+
function generalizeFileRefs(text, fileLexicon, level = 1) {
|
|
18825
|
+
let out = text;
|
|
18826
|
+
let lexiconMisses = 0;
|
|
18827
|
+
const files = [];
|
|
18828
|
+
const seenFiles = /* @__PURE__ */ new Set();
|
|
18829
|
+
for (const m of out.matchAll(FILE_TOKEN_RE)) {
|
|
18830
|
+
const tok = m[0];
|
|
18831
|
+
if (seenFiles.has(tok)) continue;
|
|
18832
|
+
seenFiles.add(tok);
|
|
18833
|
+
const entry = resolveFileToken(tok, fileLexicon);
|
|
18834
|
+
if (entry) files.push([tok, entry]);
|
|
18835
|
+
else if (isSourceFileToken(tok)) lexiconMisses++;
|
|
18836
|
+
}
|
|
18837
|
+
files.sort((a, b) => b[0].length - a[0].length);
|
|
18838
|
+
for (const [tok, entry] of files) {
|
|
18839
|
+
out = replaceWithPhrase(
|
|
18840
|
+
out,
|
|
18841
|
+
"(?<![\\w$/\\\\.-])",
|
|
18842
|
+
escapeRe2(tok),
|
|
18843
|
+
"(?![\\w$-])",
|
|
18844
|
+
fileRolePhrase(entry.relPath, level)
|
|
18845
|
+
);
|
|
18846
|
+
}
|
|
18847
|
+
const stems = [];
|
|
18848
|
+
const seenStems = /* @__PURE__ */ new Set();
|
|
18849
|
+
for (const m of out.matchAll(STEM_TOKEN_RE)) {
|
|
18850
|
+
const tok = m[0];
|
|
18851
|
+
if (seenStems.has(tok)) continue;
|
|
18852
|
+
seenStems.add(tok);
|
|
18853
|
+
const entry = fileLexicon.byStem.get(tok);
|
|
18854
|
+
if (entry) stems.push([tok, entry]);
|
|
18855
|
+
}
|
|
18856
|
+
stems.sort((a, b) => b[0].length - a[0].length);
|
|
18857
|
+
for (const [tok, entry] of stems) {
|
|
18858
|
+
out = replaceWithPhrase(
|
|
18859
|
+
out,
|
|
18860
|
+
"(?<![\\w$/\\\\.-])",
|
|
18861
|
+
escapeRe2(tok),
|
|
18862
|
+
"(?![\\w$/\\\\.-])",
|
|
18863
|
+
fileRolePhrase(entry.relPath, level)
|
|
18864
|
+
);
|
|
18865
|
+
}
|
|
18866
|
+
return { text: out, substitutions: files.length + stems.length, lexiconMisses };
|
|
18867
|
+
}
|
|
18868
|
+
|
|
18869
|
+
// src/instance-ingest.ts
|
|
18870
|
+
var INSTANCE_LABELS = ["Problem", "Solution", "RootCause"];
|
|
18871
|
+
var INSTANCE_EDGES = ["CAUSED_BY", "SOLVED_BY"];
|
|
18872
|
+
var ANCHOR_EDGES = ["OCCURS_IN", "DEPENDS_ON", "PERTAIN_TO", "CONCERNS"];
|
|
18873
|
+
var ANCHOR_TARGET_LABELS = ["Language", "Package", "Domain", "Component"];
|
|
18874
|
+
function stripCodebaseScope(scope) {
|
|
18875
|
+
const s = { ...scope ?? {} };
|
|
18876
|
+
delete s["codebase"];
|
|
18877
|
+
return s;
|
|
18878
|
+
}
|
|
18879
|
+
function contributedWireId(n) {
|
|
18880
|
+
const cloudId = n.attrs["cloudNodeId"];
|
|
18881
|
+
return isMembraneSaltedId(cloudId) ? cloudId : n.id;
|
|
18882
|
+
}
|
|
18883
|
+
var WIRE_CANONICAL_ID_MIN = 6;
|
|
18884
|
+
var SHIP_TERMINAL_REFUSALS = 3;
|
|
18885
|
+
function refusalFingerprint(reason, description) {
|
|
18886
|
+
return digest(`${reason}\0${description}`);
|
|
18887
|
+
}
|
|
18888
|
+
function isRetryableRefusal(reason) {
|
|
18889
|
+
return /\bretry\b/i.test(reason);
|
|
18890
|
+
}
|
|
18891
|
+
function isTerminallyRefused(n) {
|
|
18892
|
+
const reason = String(n.attrs["shipRefusedReason"] ?? "");
|
|
18893
|
+
return typeof n.attrs["shipRefusedCount"] === "number" && n.attrs["shipRefusedCount"] >= SHIP_TERMINAL_REFUSALS && !isRetryableRefusal(reason) && n.attrs["shipRefusedFingerprint"] === refusalFingerprint(reason, n.description);
|
|
18894
|
+
}
|
|
18895
|
+
function unshippableReason(canonical, label) {
|
|
18896
|
+
void label;
|
|
18897
|
+
if (canonical.length < WIRE_CANONICAL_ID_MIN) {
|
|
18898
|
+
return `canonicalId "${canonical}" is ${canonical.length} chars; the door requires >= ${WIRE_CANONICAL_ID_MIN}`;
|
|
18899
|
+
}
|
|
18900
|
+
return null;
|
|
18901
|
+
}
|
|
18902
|
+
function wireContextId(n) {
|
|
18903
|
+
if (n.label === "Language" && n.attrs["source"] !== "cloud") {
|
|
18904
|
+
const name = String(n.attrs["name"] ?? "").trim() || n.description.trim() || n.id.replace(/^lang:/, "");
|
|
18905
|
+
return languageCanonicalId(name);
|
|
18906
|
+
}
|
|
18907
|
+
if (n.label === "Domain" && n.attrs["source"] !== "cloud") {
|
|
18908
|
+
return String(n.attrs["canonicalId"] ?? n.id);
|
|
18909
|
+
}
|
|
18910
|
+
if (n.label === "Component" && n.attrs["source"] !== "cloud") {
|
|
18911
|
+
return String(n.attrs["canonicalId"] ?? n.id);
|
|
18912
|
+
}
|
|
18913
|
+
return n.id;
|
|
18914
|
+
}
|
|
18915
|
+
function langAnchor(t) {
|
|
18916
|
+
const name = String(t.attrs["name"] ?? "").trim() || t.description.trim() || t.id.replace(/^lang:/, "").trim();
|
|
18917
|
+
return name ? `lang:${name.toLowerCase()}` : void 0;
|
|
18918
|
+
}
|
|
18919
|
+
function shareableContext(n, wireId) {
|
|
18920
|
+
const attrs = n.label === "Package" ? {
|
|
18921
|
+
// No `version` attr: the purl encodes it, and the door's temporal
|
|
18922
|
+
// guard 422s any `attrs.version` (mirrors buildContextIngest).
|
|
18923
|
+
purl: n.attrs["purl"],
|
|
18924
|
+
name: n.attrs["name"],
|
|
18925
|
+
ecosystem: n.attrs["ecosystem"],
|
|
18926
|
+
resolved: n.attrs["resolved"]
|
|
18927
|
+
} : n.label === "Domain" ? { name: n.description, canonicalId: n.attrs["canonicalId"] } : n.label === "Component" ? { name: n.attrs["name"], canonicalId: n.attrs["canonicalId"] } : { name: n.attrs["name"] };
|
|
18928
|
+
return {
|
|
18929
|
+
...n,
|
|
18930
|
+
id: wireId,
|
|
18931
|
+
embedding: [],
|
|
18932
|
+
attrs,
|
|
18933
|
+
...n.label === "Package" ? { anchorVisibility: "public" } : {},
|
|
18934
|
+
...n.label === "Language" && langAnchor(n) ? { anchorVisibility: "public", anchor: langAnchor(n) } : {},
|
|
18935
|
+
// A Component stub claims itself by slug (OM-agent-anchors) — the door
|
|
18936
|
+
// confirms only against an EXISTING public Component of that slug, so an
|
|
18937
|
+
// org-internal component name never crosses (fails closed to org).
|
|
18938
|
+
...n.label === "Component" ? { anchorVisibility: "public", anchor: `component:${wireId}` } : {}
|
|
18939
|
+
};
|
|
18940
|
+
}
|
|
18941
|
+
function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [], opts = {}) {
|
|
18942
|
+
const level = opts.level ?? 1;
|
|
18943
|
+
const noveltyOpts = opts.dedupCosine != null ? { dedupCosine: opts.dedupCosine } : {};
|
|
18944
|
+
const ignored = (text) => ignorePatterns.length > 0 && ignorePatterns.some((p) => text.toLowerCase().includes(p));
|
|
18945
|
+
const originSessionOf = (n) => {
|
|
18946
|
+
const key = sessionOriginKey(n.attrs["sources"]?.[0]);
|
|
18947
|
+
return key ? { originSession: key } : {};
|
|
18948
|
+
};
|
|
18949
|
+
const symbolIndex = opts.workspaceRoot ? publicSymbolIndex(store, opts.workspaceRoot) : null;
|
|
18950
|
+
const ownLexicon = opts.lexicon ?? buildSymbolLexicon(store);
|
|
18951
|
+
const projectIdentity = {
|
|
18952
|
+
...profile.name ? { name: profile.name } : {},
|
|
18953
|
+
...profile.repoLocator ? { repoLocator: profile.repoLocator } : {},
|
|
18954
|
+
...profile.repoLocatorAliases ? { aliases: profile.repoLocatorAliases } : {},
|
|
18955
|
+
...profile.aka ? { aka: profile.aka } : {}
|
|
18956
|
+
};
|
|
18957
|
+
const fileLexicon = buildFileLexicon(store);
|
|
18958
|
+
const shareable = (n) => {
|
|
18959
|
+
const preserved = symbolIndex ? preservedSymbolsFor(n.description, symbolIndex) : [];
|
|
18960
|
+
const fileRefs = generalizeFileRefs(n.description, fileLexicon, level);
|
|
18961
|
+
const fileScrubbed = fileRefs.text;
|
|
18962
|
+
composition.fileRefsSubstituted += fileRefs.substitutions;
|
|
18963
|
+
composition.fileRefLexiconMisses += fileRefs.lexiconMisses;
|
|
18964
|
+
const generalized = generalize(fileScrubbed, { level, project: projectIdentity });
|
|
18965
|
+
const shippedText = generalized.text;
|
|
18966
|
+
if (generalized.report.classes.length > 0) composition.privacyRewritten++;
|
|
18967
|
+
const internalSyms = internalSymbolsFor(shippedText, (t) => ownLexicon.has(t), symbolIndex);
|
|
18968
|
+
const internalFiles = internalFilesFor(shippedText, fileLexicon);
|
|
18969
|
+
const internal = [.../* @__PURE__ */ new Set([...internalFiles, ...internalSyms])].slice(
|
|
18970
|
+
0,
|
|
18971
|
+
PRESERVED_SYMBOLS_CAP
|
|
18972
|
+
);
|
|
18973
|
+
return {
|
|
18974
|
+
...n,
|
|
18975
|
+
description: shippedText,
|
|
18976
|
+
embedding: [],
|
|
18977
|
+
...originSessionOf(n),
|
|
18978
|
+
attrs: {
|
|
18979
|
+
scope: stripCodebaseScope(n.attrs["scope"]),
|
|
18980
|
+
...n.attrs["kind"] ? { kind: n.attrs["kind"] } : {},
|
|
18981
|
+
...n.attrs["resolvedAs"] ? { resolvedAs: n.attrs["resolvedAs"] } : {},
|
|
18982
|
+
...preserved.length > 0 ? { preservedSymbols: preserved } : {},
|
|
18983
|
+
...internal.length > 0 ? { internalSymbols: internal } : {}
|
|
18984
|
+
}
|
|
18985
|
+
};
|
|
18986
|
+
};
|
|
18987
|
+
const nodes = [];
|
|
18988
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18989
|
+
const walked = /* @__PURE__ */ new Set();
|
|
18990
|
+
const shippedById = /* @__PURE__ */ new Map();
|
|
18991
|
+
const anchorSources = /* @__PURE__ */ new Set();
|
|
18992
|
+
const semanticEndpoints = /* @__PURE__ */ new Map();
|
|
18993
|
+
const includedByLabel = /* @__PURE__ */ new Map();
|
|
18994
|
+
const composition = {
|
|
18995
|
+
candidates: 0,
|
|
18996
|
+
shipped: 0,
|
|
18997
|
+
cloudSourced: 0,
|
|
18998
|
+
falsePositive: 0,
|
|
18999
|
+
ignored: 0,
|
|
19000
|
+
watermarked: 0,
|
|
19001
|
+
autoMint: 0,
|
|
19002
|
+
notNovel: 0,
|
|
19003
|
+
unshippable: 0,
|
|
19004
|
+
heldOrphans: 0,
|
|
19005
|
+
terminalRefused: 0,
|
|
19006
|
+
privacyRewritten: 0,
|
|
19007
|
+
sidecarDropped: 0,
|
|
19008
|
+
sidecarDropReasons: {},
|
|
19009
|
+
sidecarTruncatedAtCap: 0,
|
|
19010
|
+
sidecarNoLexicon: 0,
|
|
19011
|
+
sidecarNoSummary: 0,
|
|
19012
|
+
fileRefsSubstituted: 0,
|
|
19013
|
+
fileRefLexiconMisses: 0
|
|
19014
|
+
};
|
|
19015
|
+
for (const label of INSTANCE_LABELS) {
|
|
19016
|
+
const ref = [];
|
|
19017
|
+
includedByLabel.set(label, ref);
|
|
19018
|
+
const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...opts.sharedStore.findNodesByLabel(label)] : store.findNodesByLabel(label);
|
|
19019
|
+
for (const n of population) {
|
|
19020
|
+
if (seen.has(n.id)) continue;
|
|
19021
|
+
if (walked.has(n.id)) continue;
|
|
19022
|
+
walked.add(n.id);
|
|
19023
|
+
composition.candidates++;
|
|
19024
|
+
if (n.attrs["source"] === "cloud") {
|
|
19025
|
+
composition.cloudSourced++;
|
|
19026
|
+
continue;
|
|
19027
|
+
}
|
|
19028
|
+
if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) {
|
|
19029
|
+
composition.falsePositive++;
|
|
19030
|
+
continue;
|
|
19031
|
+
}
|
|
19032
|
+
if (ignored(n.description)) {
|
|
19033
|
+
composition.ignored++;
|
|
19034
|
+
continue;
|
|
19035
|
+
}
|
|
19036
|
+
const contributedAtSeq = n.attrs["contributedAtSeq"];
|
|
19037
|
+
if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
|
|
19038
|
+
composition.watermarked++;
|
|
19039
|
+
anchorSources.add(n.id);
|
|
19040
|
+
semanticEndpoints.set(n.id, contributedWireId(n));
|
|
19041
|
+
continue;
|
|
19042
|
+
}
|
|
19043
|
+
if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) {
|
|
19044
|
+
composition.autoMint++;
|
|
19045
|
+
continue;
|
|
19046
|
+
}
|
|
19047
|
+
if (isTerminallyRefused(n)) {
|
|
19048
|
+
composition.terminalRefused++;
|
|
19049
|
+
continue;
|
|
19050
|
+
}
|
|
19051
|
+
if (!noveltyAgainst(n, ref, noveltyOpts).ready) {
|
|
19052
|
+
composition.notNovel++;
|
|
19053
|
+
continue;
|
|
19054
|
+
}
|
|
19055
|
+
const reject = unshippableReason(n.id, n.label);
|
|
19056
|
+
if (reject) {
|
|
19057
|
+
console.warn(`[errata] skipping unshippable node ${n.id} (${n.label}): ${reject}`);
|
|
19058
|
+
composition.unshippable++;
|
|
19059
|
+
continue;
|
|
19060
|
+
}
|
|
19061
|
+
ref.push(n);
|
|
19062
|
+
const wireNode = shareable(n);
|
|
19063
|
+
nodes.push(wireNode);
|
|
19064
|
+
shippedById.set(n.id, wireNode);
|
|
19065
|
+
seen.add(n.id);
|
|
19066
|
+
anchorSources.add(n.id);
|
|
19067
|
+
semanticEndpoints.set(n.id, n.id);
|
|
19068
|
+
}
|
|
19069
|
+
}
|
|
19070
|
+
for (const n of nodes) {
|
|
19071
|
+
if (!INSTANCE_LABELS.includes(n.label)) {
|
|
19072
|
+
throw new Error(`buildInstanceIngest: refusing to ship non-instance ${n.id} (${n.label}) \u2014 C7 invariant`);
|
|
19073
|
+
}
|
|
19074
|
+
}
|
|
19075
|
+
const anchorEdges = [];
|
|
19076
|
+
const contextNodes = [];
|
|
19077
|
+
const contextSeen = /* @__PURE__ */ new Set();
|
|
19078
|
+
const anchorDigests = {};
|
|
19079
|
+
for (const sourceId of anchorSources) {
|
|
19080
|
+
const targets = [];
|
|
19081
|
+
for (const e of store.outEdges(sourceId, [...ANCHOR_EDGES])) {
|
|
19082
|
+
const t = store.getNode(e.to);
|
|
19083
|
+
if (!t || !ANCHOR_TARGET_LABELS.includes(t.label)) continue;
|
|
19084
|
+
if (e.type === "OCCURS_IN" && t.label !== "Language") continue;
|
|
19085
|
+
if (e.type === "DEPENDS_ON" && t.label !== "Package") continue;
|
|
19086
|
+
if (e.type === "PERTAIN_TO" && t.label !== "Domain") continue;
|
|
19087
|
+
if (e.type === "CONCERNS" && t.label !== "Component") continue;
|
|
19088
|
+
if ((t.label === "Package" || t.label === "Component") && opts.includePackages !== true) continue;
|
|
19089
|
+
if (ignored(t.description) || ignored(String(t.attrs["name"] ?? ""))) continue;
|
|
19090
|
+
targets.push({ e, t, wireId: wireContextId(t) });
|
|
19091
|
+
}
|
|
19092
|
+
if (targets.length === 0) continue;
|
|
19093
|
+
const shipped = shippedById.get(sourceId);
|
|
19094
|
+
if (shipped) {
|
|
19095
|
+
const anchors = (label) => targets.filter((x) => x.t.label === label).map(
|
|
19096
|
+
(x) => label === "Language" ? langAnchor(x.t) : label === "Component" ? `component:${x.wireId}` : x.wireId
|
|
19097
|
+
).filter((a) => a != null).sort();
|
|
19098
|
+
const anchor = anchors("Package")[0] ?? anchors("Component")[0] ?? anchors("Language")[0];
|
|
19099
|
+
if (anchor) {
|
|
19100
|
+
shipped.anchorVisibility = "public";
|
|
19101
|
+
shipped.anchor = anchor;
|
|
19102
|
+
}
|
|
19103
|
+
}
|
|
19104
|
+
const dg = digest(targets.map(({ e, wireId }) => `${e.type}>${wireId}`).sort());
|
|
19105
|
+
const sourceNode = store.getNode(sourceId);
|
|
19106
|
+
if (sourceNode?.attrs["anchorsContributedDigest"] === dg) continue;
|
|
19107
|
+
anchorDigests[sourceId] = dg;
|
|
19108
|
+
const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode);
|
|
19109
|
+
for (const { e, t, wireId } of targets) {
|
|
19110
|
+
const reject = unshippableReason(wireId, t.label);
|
|
19111
|
+
if (reject) {
|
|
19112
|
+
console.warn(`[errata] skipping unshippable anchor ${wireId} (${t.label}): ${reject}`);
|
|
19113
|
+
continue;
|
|
19114
|
+
}
|
|
19115
|
+
anchorEdges.push({ ...e, from: wireFrom, to: wireId, attrs: {} });
|
|
19116
|
+
if (t.attrs["source"] === "cloud" || contextSeen.has(wireId)) continue;
|
|
19117
|
+
contextSeen.add(wireId);
|
|
19118
|
+
contextNodes.push(shareableContext(t, wireId));
|
|
19119
|
+
}
|
|
19120
|
+
}
|
|
19121
|
+
const primaryLang = (profile.languages ?? []).map((l) => String(l).trim().toLowerCase()).filter(Boolean)[0];
|
|
19122
|
+
if (primaryLang) {
|
|
19123
|
+
for (const shipped of shippedById.values()) {
|
|
19124
|
+
if (!shipped.anchorVisibility) {
|
|
19125
|
+
shipped.anchorVisibility = "public";
|
|
19126
|
+
shipped.anchor = `lang:${primaryLang}`;
|
|
19127
|
+
}
|
|
19128
|
+
}
|
|
19129
|
+
}
|
|
19130
|
+
const project = opts.project;
|
|
19131
|
+
const projectAnchorDigests = {};
|
|
19132
|
+
if (project) {
|
|
19133
|
+
const now = Date.now();
|
|
19134
|
+
for (const sourceId of anchorSources) {
|
|
19135
|
+
const source = store.getNode(sourceId);
|
|
19136
|
+
if (!source) continue;
|
|
19137
|
+
const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source);
|
|
19138
|
+
const planned = [];
|
|
19139
|
+
for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
|
|
19140
|
+
const target = store.getNode(e.to);
|
|
19141
|
+
if (!target) continue;
|
|
19142
|
+
const relPath = target.attrs["relPath"];
|
|
19143
|
+
const qname = target.attrs["qname"];
|
|
19144
|
+
if (typeof relPath !== "string" || typeof qname !== "string") continue;
|
|
19145
|
+
if (ignored(relPath) || ignored(qname)) continue;
|
|
19146
|
+
planned.push({ e, target, symId: projectSymbolId(project.salt, project.projectId, relPath, qname, target.label) });
|
|
19147
|
+
}
|
|
19148
|
+
if (planned.length === 0) continue;
|
|
19149
|
+
const dg = digest(
|
|
19150
|
+
planned.map(({ e, symId }) => `ANCHORED_AT>${symId}>${JSON.stringify(anchorVersionAttrs(e.attrs))}`).sort()
|
|
19151
|
+
);
|
|
19152
|
+
if (source.attrs["projectAnchorsContributedDigest"] === dg) continue;
|
|
19153
|
+
projectAnchorDigests[sourceId] = dg;
|
|
19154
|
+
for (const { e, target, symId } of planned) {
|
|
19155
|
+
if (!contextSeen.has(symId)) {
|
|
19156
|
+
contextSeen.add(symId);
|
|
19157
|
+
contextNodes.push({
|
|
19158
|
+
id: symId,
|
|
19159
|
+
label: "Symbol",
|
|
19160
|
+
// The id IS the description: there is nothing that can be said about an
|
|
19161
|
+
// opaque symbol without disclosing it, and the wire requires a non-empty
|
|
19162
|
+
// string. It must never carry the name or the path.
|
|
19163
|
+
description: symId,
|
|
19164
|
+
// `kind` is coarse (Function/Class/…) — shape, not identity.
|
|
19165
|
+
attrs: { kind: target.label },
|
|
19166
|
+
embedding: [],
|
|
19167
|
+
extractionConfidence: 1,
|
|
19168
|
+
extractionSource: "daemon-extracted",
|
|
19169
|
+
cumulativeSurprise: 0,
|
|
19170
|
+
peakSurprise: 0,
|
|
19171
|
+
cumulativeHits: 0,
|
|
19172
|
+
lastUpdatedAt: now,
|
|
19173
|
+
createdAt: now,
|
|
19174
|
+
memoryTier: "short-term",
|
|
19175
|
+
pageRank: 0,
|
|
19176
|
+
isLandmark: false,
|
|
19177
|
+
community: null,
|
|
19178
|
+
stability: "unstable"
|
|
19179
|
+
});
|
|
19180
|
+
}
|
|
19181
|
+
anchorEdges.push({ ...e, from: wireFrom, to: symId, attrs: anchorVersionAttrs(e.attrs) });
|
|
19182
|
+
}
|
|
19183
|
+
}
|
|
19184
|
+
}
|
|
19185
|
+
const edges = [];
|
|
19186
|
+
const semanticEdgeDigests = {};
|
|
19187
|
+
for (const [sourceId, wireFrom] of semanticEndpoints) {
|
|
19188
|
+
const rawOuts = [
|
|
19189
|
+
...store.outEdges(sourceId, [...INSTANCE_EDGES]),
|
|
19190
|
+
...opts.sharedStore?.outEdges(sourceId, [...INSTANCE_EDGES]) ?? []
|
|
19191
|
+
];
|
|
19192
|
+
const dedup = /* @__PURE__ */ new Map();
|
|
19193
|
+
for (const e of rawOuts) dedup.set(`${e.type}>${e.to}`, e);
|
|
19194
|
+
const outs = [...dedup.values()].map((e) => ({ e, wireTo: semanticEndpoints.get(e.to) })).filter((x) => x.wireTo != null);
|
|
19195
|
+
if (outs.length === 0) continue;
|
|
19196
|
+
const dg = digest(outs.map(({ e, wireTo }) => `${e.type}>${wireTo}`).sort());
|
|
19197
|
+
const owner = store.getNode(sourceId) ?? opts.sharedStore?.getNode(sourceId);
|
|
19198
|
+
const digestSkip = owner?.attrs["semanticEdgesContributedDigest"] === dg;
|
|
19199
|
+
if (!digestSkip) semanticEdgeDigests[sourceId] = dg;
|
|
19200
|
+
for (const { e, wireTo } of outs) {
|
|
19201
|
+
if (digestSkip && !shippedById.has(e.to)) continue;
|
|
19202
|
+
edges.push({ ...e, from: wireFrom, to: wireTo, attrs: {} });
|
|
19203
|
+
}
|
|
19204
|
+
}
|
|
19205
|
+
if (nodes.length === 0 && anchorEdges.length === 0 && edges.length === 0) {
|
|
19206
|
+
opts.onComposition?.(composition);
|
|
19207
|
+
return null;
|
|
19208
|
+
}
|
|
19209
|
+
let symbolSummaries;
|
|
19210
|
+
if (!opts.lexicon || opts.lexicon.size === 0) composition.sidecarNoLexicon = 1;
|
|
19211
|
+
if (opts.lexicon && opts.lexicon.size > 0 && nodes.length > 0) {
|
|
19212
|
+
const lexicon = opts.lexicon;
|
|
19213
|
+
const isKnown = (tok) => lexicon.has(tok);
|
|
19214
|
+
const sidecar = {};
|
|
19215
|
+
let count = 0;
|
|
19216
|
+
outer: for (const n of nodes) {
|
|
19217
|
+
if (!INSTANCE_LABELS.includes(n.label)) continue;
|
|
19218
|
+
for (const tok of extractIdentifierTokens(n.description)) {
|
|
19219
|
+
if (sidecar[tok]) continue;
|
|
19220
|
+
const entry = lexicon.get(tok);
|
|
19221
|
+
if (!entry) continue;
|
|
19222
|
+
if (!entry.summary) {
|
|
19223
|
+
composition.sidecarNoSummary++;
|
|
19224
|
+
continue;
|
|
19225
|
+
}
|
|
19226
|
+
const scrubbed = generalize(entry.summary, { level, project: projectIdentity }).text.trim();
|
|
19227
|
+
const dropBucket = !scrubbed ? "empty" : sidecarDropBucket(summaryRejectionReason(scrubbed, isKnown));
|
|
19228
|
+
if (dropBucket !== null) {
|
|
19229
|
+
composition.sidecarDropped++;
|
|
19230
|
+
composition.sidecarDropReasons[dropBucket] = (composition.sidecarDropReasons[dropBucket] ?? 0) + 1;
|
|
19231
|
+
continue;
|
|
19232
|
+
}
|
|
19233
|
+
if (count >= MAX_SIDECAR_SYMBOLS) {
|
|
19234
|
+
composition.sidecarTruncatedAtCap = 1;
|
|
19235
|
+
break outer;
|
|
19236
|
+
}
|
|
19237
|
+
sidecar[tok] = { kind: entry.kind, summary: scrubbed };
|
|
19238
|
+
count++;
|
|
19239
|
+
}
|
|
19240
|
+
}
|
|
19241
|
+
if (count > 0) symbolSummaries = sidecar;
|
|
19242
|
+
}
|
|
19243
|
+
edges.push(...anchorEdges);
|
|
19244
|
+
const bindingEndpoints = /* @__PURE__ */ new Set();
|
|
19245
|
+
for (const e of edges) {
|
|
19246
|
+
if (e.type === "CAUSED_BY" || e.type === "SOLVED_BY") {
|
|
19247
|
+
bindingEndpoints.add(e.from);
|
|
19248
|
+
bindingEndpoints.add(e.to);
|
|
19249
|
+
}
|
|
19250
|
+
}
|
|
19251
|
+
const heldOrphans = /* @__PURE__ */ new Set();
|
|
19252
|
+
for (const wn of nodes) {
|
|
19253
|
+
if (wn.label !== "RootCause" && wn.label !== "Solution") continue;
|
|
19254
|
+
const src = store.getNode(wn.id) ?? opts.sharedStore?.getNode(wn.id);
|
|
19255
|
+
if (typeof src?.attrs["contributedAtSeq"] === "number") continue;
|
|
19256
|
+
if (bindingEndpoints.has(wn.id)) continue;
|
|
19257
|
+
heldOrphans.add(wn.id);
|
|
19258
|
+
}
|
|
19259
|
+
const shippableNodes = heldOrphans.size === 0 ? nodes : nodes.filter((n) => !heldOrphans.has(n.id));
|
|
19260
|
+
const shippableEdges = heldOrphans.size === 0 ? edges : edges.filter((e) => !heldOrphans.has(e.from) && !heldOrphans.has(e.to));
|
|
19261
|
+
for (const id of heldOrphans) {
|
|
19262
|
+
delete anchorDigests[id];
|
|
19263
|
+
delete semanticEdgeDigests[id];
|
|
19264
|
+
delete projectAnchorDigests[id];
|
|
19265
|
+
}
|
|
19266
|
+
if (heldOrphans.size > 0) {
|
|
19267
|
+
console.warn(
|
|
19268
|
+
`[errata] held ${heldOrphans.size} causal-orphan node(s) \u2014 no shippable binding edge this drain (VS-orphan-gate)`
|
|
19269
|
+
);
|
|
19270
|
+
}
|
|
19271
|
+
composition.heldOrphans = heldOrphans.size;
|
|
19272
|
+
composition.shipped = shippableNodes.length;
|
|
19273
|
+
if (shippableNodes.length === 0 && shippableEdges.length === 0) {
|
|
19274
|
+
opts.onComposition?.(composition);
|
|
19275
|
+
return null;
|
|
19276
|
+
}
|
|
19277
|
+
const base = {
|
|
19278
|
+
daemonVersion,
|
|
19279
|
+
// Origin key (= project, the salted `wp_…`) — the door stamps it onto created
|
|
19280
|
+
// nodes as `authoringProject`, arming the evidence channels' cross-origin gate
|
|
19281
|
+
// (EE-corrob-live: this is the MAIN semantic drain; without the stamp every
|
|
19282
|
+
// Problem/Solution lands fail-open to self-corroboration).
|
|
19283
|
+
...profile.id ? { originProject: profile.id } : {},
|
|
19284
|
+
profile: { stack: profile.stack, languages: profile.languages, domains: profile.domains },
|
|
19285
|
+
// Context nodes FIRST: a chunked drain (cloud-client, 25-node chunks) then
|
|
19286
|
+
// co-locates the few Language/Package stubs with the first instance chunk,
|
|
19287
|
+
// maximizing in-payload endpoint resolution.
|
|
19288
|
+
nodes: [...contextNodes, ...shippableNodes],
|
|
19289
|
+
edges: shippableEdges,
|
|
19290
|
+
// Spread-if-present: an absent sidecar keeps `base` — and therefore the
|
|
19291
|
+
// payloadDigest — byte-identical to the pre-sidecar batch (backward compat).
|
|
19292
|
+
...symbolSummaries ? { symbolSummaries } : {}
|
|
19293
|
+
};
|
|
19294
|
+
opts.onComposition?.(composition);
|
|
19295
|
+
return { ...base, payloadDigest: digest(base), anchorDigests, semanticEdgeDigests, projectAnchorDigests, composition };
|
|
19296
|
+
}
|
|
19297
|
+
|
|
19298
|
+
// src/drain-build.ts
|
|
19299
|
+
function buildDrainContext(store, input) {
|
|
19300
|
+
return buildContextIngest(store, input.profile, input.daemonVersion, input.ignorePatterns, {
|
|
19301
|
+
...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {}
|
|
19302
|
+
});
|
|
19303
|
+
}
|
|
19304
|
+
function buildDrainInstances(store, sharedStore, input) {
|
|
19305
|
+
let lexicon;
|
|
19306
|
+
let lexiconError;
|
|
19307
|
+
try {
|
|
19308
|
+
lexicon = buildSymbolLexicon(store);
|
|
19309
|
+
} catch (err) {
|
|
19310
|
+
lexiconError = err instanceof Error ? err.message : String(err);
|
|
19311
|
+
}
|
|
19312
|
+
let composition = null;
|
|
19313
|
+
const batch = buildInstanceIngest(store, input.profile, input.daemonVersion, input.ignorePatterns, {
|
|
19314
|
+
...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {},
|
|
19315
|
+
workspaceRoot: input.workspaceRoot,
|
|
19316
|
+
sharedStore,
|
|
19317
|
+
onComposition: (c) => {
|
|
19318
|
+
composition = c;
|
|
19319
|
+
},
|
|
19320
|
+
...lexicon ? { lexicon } : {},
|
|
19321
|
+
...input.project ? { project: input.project } : {}
|
|
19322
|
+
});
|
|
19323
|
+
return {
|
|
19324
|
+
batch,
|
|
19325
|
+
composition: composition ?? batch?.composition ?? null,
|
|
19326
|
+
...lexiconError ? { lexiconError } : {}
|
|
19327
|
+
};
|
|
19328
|
+
}
|
|
19329
|
+
|
|
17664
19330
|
// src/consolidate-worker.ts
|
|
17665
19331
|
var stores = /* @__PURE__ */ new Map();
|
|
17666
19332
|
function storeAt(path) {
|
|
@@ -17709,6 +19375,16 @@ function runPass(msg) {
|
|
|
17709
19375
|
if (!msg.castaliaPath) throw new Error("strandedCount: castaliaPath required");
|
|
17710
19376
|
return findStrandedSymbols(storeAt(msg.castaliaPath)).length;
|
|
17711
19377
|
}
|
|
19378
|
+
case "drainContext": {
|
|
19379
|
+
if (!msg.castaliaPath) throw new Error("drainContext: castaliaPath required");
|
|
19380
|
+
if (!msg.drain) throw new Error("drainContext: drain input required");
|
|
19381
|
+
return buildDrainContext(storeAt(msg.castaliaPath), msg.drain);
|
|
19382
|
+
}
|
|
19383
|
+
case "drainInstances": {
|
|
19384
|
+
if (!msg.castaliaPath) throw new Error("drainInstances: castaliaPath required");
|
|
19385
|
+
if (!msg.drain) throw new Error("drainInstances: drain input required");
|
|
19386
|
+
return buildDrainInstances(storeAt(msg.castaliaPath), shared, msg.drain);
|
|
19387
|
+
}
|
|
17712
19388
|
default:
|
|
17713
19389
|
throw new Error(`unknown consolidation pass: ${msg.kind}`);
|
|
17714
19390
|
}
|