@inerrata-corporation/errata 2.0.6-dev.2511 → 2.0.6-dev.2533
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/README.txt +22 -0
- package/consolidate-worker.mjs +74 -8
- package/errata.mjs +278 -132
- package/package.json +1 -1
- package/pass-worker.mjs +27 -2
package/README.txt
CHANGED
|
@@ -25,6 +25,28 @@ USE
|
|
|
25
25
|
|
|
26
26
|
Dashboard: http://127.0.0.1:7891
|
|
27
27
|
|
|
28
|
+
CODEX
|
|
29
|
+
|
|
30
|
+
errata install-hooks codex # explicit install or upgrade for this workspace
|
|
31
|
+
|
|
32
|
+
Init detects .codex in the project or CODEX_HOME (default ~/.codex). Successful
|
|
33
|
+
errata link flows also refresh detected Codex hooks; --skip-hooks opts out of
|
|
34
|
+
either automatic install. The installer preserves other config and writes its
|
|
35
|
+
Node relay into .codex/hooks/errata-relay.mjs. No curl or Bash dependency.
|
|
36
|
+
|
|
37
|
+
Restart/resume Codex after installing, and review/trust the hooks with /hooks.
|
|
38
|
+
If your Codex build gates hooks, enable [features] codex_hooks = true. Update
|
|
39
|
+
older Codex builds if UserPromptSubmit or tool hooks are unsupported.
|
|
40
|
+
|
|
41
|
+
SessionStart injects .errata/context.md, including startup/resume/compaction.
|
|
42
|
+
UserPromptSubmit and PostToolUse inject it again only when it changes. Tool
|
|
43
|
+
recall and capture remain enabled. Refresh happens at a tool boundary, not
|
|
44
|
+
during model generation. The daemon must be running; unavailable hooks fail
|
|
45
|
+
open. AGENTS.md's file-read instruction remains a useful fallback.
|
|
46
|
+
|
|
47
|
+
The cloud MCP/plugin installer alone does not install this local daemon.
|
|
48
|
+
Install errata and run init in each workspace to enable daemon context.
|
|
49
|
+
|
|
28
50
|
UPDATE
|
|
29
51
|
|
|
30
52
|
errata update # pull the newest build on your channel (npm i -g)
|
package/consolidate-worker.mjs
CHANGED
|
@@ -15322,6 +15322,9 @@ var init_symbol_intent = __esm({
|
|
|
15322
15322
|
});
|
|
15323
15323
|
|
|
15324
15324
|
// ../../packages/shared/src/wire.ts
|
|
15325
|
+
function isAnchorLabelKind(kind) {
|
|
15326
|
+
return typeof kind === "string" && ANCHOR_LABEL_KINDS.includes(kind);
|
|
15327
|
+
}
|
|
15325
15328
|
function anchorVersionAttrs(attrs) {
|
|
15326
15329
|
if (!attrs) return {};
|
|
15327
15330
|
const commit = attrs["observedAtCommit"];
|
|
@@ -15331,7 +15334,24 @@ function anchorVersionAttrs(attrs) {
|
|
|
15331
15334
|
...typeof hash2 === "string" && ANCHOR_BODY_HASH_RE.test(hash2) ? { symbolContentHash: hash2 } : {}
|
|
15332
15335
|
};
|
|
15333
15336
|
}
|
|
15334
|
-
|
|
15337
|
+
function anchorLabelAttrs(attrs) {
|
|
15338
|
+
if (!attrs) return {};
|
|
15339
|
+
const relPath = attrs["labelRelPath"];
|
|
15340
|
+
const qname = attrs["labelQname"];
|
|
15341
|
+
const kind = attrs["labelKind"];
|
|
15342
|
+
const line = attrs["labelLine"];
|
|
15343
|
+
if (typeof relPath !== "string" || !ANCHOR_LABEL_PATH_RE.test(relPath)) return {};
|
|
15344
|
+
if (!isAnchorLabelKind(kind)) return {};
|
|
15345
|
+
const qnameOk = typeof qname === "string" && ANCHOR_LABEL_QNAME_RE.test(qname);
|
|
15346
|
+
if (kind !== "File" && !qnameOk) return {};
|
|
15347
|
+
return {
|
|
15348
|
+
labelRelPath: relPath,
|
|
15349
|
+
labelKind: kind,
|
|
15350
|
+
...kind !== "File" && qnameOk ? { labelQname: qname } : {},
|
|
15351
|
+
...typeof line === "number" && Number.isInteger(line) && line >= 1 && line <= 1e7 ? { labelLine: line } : {}
|
|
15352
|
+
};
|
|
15353
|
+
}
|
|
15354
|
+
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, ANCHOR_SYMBOL_KINDS, ANCHOR_LABEL_KINDS, FILE_ANCHOR_QNAME, ANCHOR_LABEL_PATH_RE, ANCHOR_LABEL_QNAME_RE, CastaliaIngestEdgeSchema, SymbolSummarySidecarSchema, CastaliaIngestPayloadSchema;
|
|
15335
15355
|
var init_wire = __esm({
|
|
15336
15356
|
"../../packages/shared/src/wire.ts"() {
|
|
15337
15357
|
"use strict";
|
|
@@ -15434,6 +15454,22 @@ var init_wire = __esm({
|
|
|
15434
15454
|
});
|
|
15435
15455
|
ANCHOR_COMMIT_SHA_RE = /^[0-9a-f]{7,40}$/;
|
|
15436
15456
|
ANCHOR_BODY_HASH_RE = /^[0-9a-f]{8,64}$/;
|
|
15457
|
+
ANCHOR_SYMBOL_KINDS = [
|
|
15458
|
+
"Function",
|
|
15459
|
+
"Class",
|
|
15460
|
+
"Method",
|
|
15461
|
+
"Module",
|
|
15462
|
+
"Interface",
|
|
15463
|
+
"Const",
|
|
15464
|
+
"Enum",
|
|
15465
|
+
"TypeAlias",
|
|
15466
|
+
"Namespace",
|
|
15467
|
+
"Property"
|
|
15468
|
+
];
|
|
15469
|
+
ANCHOR_LABEL_KINDS = [...ANCHOR_SYMBOL_KINDS, "File"];
|
|
15470
|
+
FILE_ANCHOR_QNAME = "";
|
|
15471
|
+
ANCHOR_LABEL_PATH_RE = /^(?![/])(?![A-Za-z]:)(?!(?:.*\/)?\.\.(?:\/|$))[^\x00-\x1f\x7f\\`]{1,512}$/;
|
|
15472
|
+
ANCHOR_LABEL_QNAME_RE = /^[^\x00-\x1f\x7f`]{1,256}$/;
|
|
15437
15473
|
CastaliaIngestEdgeSchema = external_exports.object({
|
|
15438
15474
|
fromCanonicalId: external_exports.string().min(6).max(160),
|
|
15439
15475
|
toCanonicalId: external_exports.string().min(6).max(160),
|
|
@@ -15453,7 +15489,17 @@ var init_wire = __esm({
|
|
|
15453
15489
|
* classify the anchor current / pre-change; absent ⇒ the pre-versioning
|
|
15454
15490
|
* contract, unverified. Only meaningful on `ANCHORED_AT`. */
|
|
15455
15491
|
observedAtCommit: external_exports.string().regex(ANCHOR_COMMIT_SHA_RE).optional(),
|
|
15456
|
-
symbolContentHash: external_exports.string().regex(ANCHOR_BODY_HASH_RE).optional()
|
|
15492
|
+
symbolContentHash: external_exports.string().regex(ANCHOR_BODY_HASH_RE).optional(),
|
|
15493
|
+
/** PJ-anchor-labels: the READABLE identity of the anchor's target —
|
|
15494
|
+
* repo-relative path, qualified name (absent for a File), kind and line.
|
|
15495
|
+
* Sent only for a project whose owner opted in; the door strips them again
|
|
15496
|
+
* for any project that has not (the daemon's flag is not trusted alone).
|
|
15497
|
+
* Prefixed `label*` so no local edge attr (`anchorLine` lives there
|
|
15498
|
+
* natively) can ride out under a shared key. */
|
|
15499
|
+
labelRelPath: external_exports.string().regex(ANCHOR_LABEL_PATH_RE).optional(),
|
|
15500
|
+
labelQname: external_exports.string().regex(ANCHOR_LABEL_QNAME_RE).optional(),
|
|
15501
|
+
labelKind: external_exports.enum(ANCHOR_LABEL_KINDS).optional(),
|
|
15502
|
+
labelLine: external_exports.number().int().min(1).max(1e7).optional()
|
|
15457
15503
|
}).optional()
|
|
15458
15504
|
});
|
|
15459
15505
|
SymbolSummarySidecarSchema = external_exports.record(
|
|
@@ -19153,19 +19199,39 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19153
19199
|
for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
|
|
19154
19200
|
const target = store.getNode(e.to);
|
|
19155
19201
|
if (!target) continue;
|
|
19202
|
+
if (!isAnchorLabelKind(target.label)) continue;
|
|
19203
|
+
const isFile = target.label === "File";
|
|
19204
|
+
if (isFile && !project.anchorLabels) continue;
|
|
19156
19205
|
const relPath = target.attrs["relPath"];
|
|
19157
|
-
const qname = target.attrs["qname"];
|
|
19206
|
+
const qname = isFile ? FILE_ANCHOR_QNAME : target.attrs["qname"];
|
|
19158
19207
|
if (typeof relPath !== "string" || typeof qname !== "string") continue;
|
|
19159
|
-
if (ignored(relPath) || ignored(qname)) continue;
|
|
19160
|
-
|
|
19208
|
+
if (ignored(relPath) || qname !== "" && ignored(qname)) continue;
|
|
19209
|
+
const line = e.attrs?.["anchorLine"];
|
|
19210
|
+
const wireAttrs = {
|
|
19211
|
+
...anchorVersionAttrs(e.attrs),
|
|
19212
|
+
// PJ-anchor-labels: only for an opted-in project, and only through the
|
|
19213
|
+
// shared projection (invalid path/kind ⇒ no label, never half of one).
|
|
19214
|
+
...project.anchorLabels ? anchorLabelAttrs({
|
|
19215
|
+
labelRelPath: normalizeSymbolPath(relPath),
|
|
19216
|
+
labelKind: target.label,
|
|
19217
|
+
...isFile ? {} : { labelQname: qname },
|
|
19218
|
+
...typeof line === "number" ? { labelLine: line } : {}
|
|
19219
|
+
}) : {}
|
|
19220
|
+
};
|
|
19221
|
+
planned.push({
|
|
19222
|
+
e,
|
|
19223
|
+
target,
|
|
19224
|
+
symId: projectSymbolId(project.salt, project.projectId, relPath, qname, target.label),
|
|
19225
|
+
wireAttrs
|
|
19226
|
+
});
|
|
19161
19227
|
}
|
|
19162
19228
|
if (planned.length === 0) continue;
|
|
19163
19229
|
const dg = digest(
|
|
19164
|
-
planned.map(({
|
|
19230
|
+
planned.map(({ symId, wireAttrs }) => `ANCHORED_AT>${symId}>${JSON.stringify(wireAttrs)}`).sort()
|
|
19165
19231
|
);
|
|
19166
19232
|
if (source.attrs["projectAnchorsContributedDigest"] === dg) continue;
|
|
19167
19233
|
projectAnchorDigests[sourceId] = dg;
|
|
19168
|
-
for (const { e, target, symId } of planned) {
|
|
19234
|
+
for (const { e, target, symId, wireAttrs } of planned) {
|
|
19169
19235
|
if (!contextSeen.has(symId)) {
|
|
19170
19236
|
contextSeen.add(symId);
|
|
19171
19237
|
contextNodes.push({
|
|
@@ -19192,7 +19258,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19192
19258
|
stability: "unstable"
|
|
19193
19259
|
});
|
|
19194
19260
|
}
|
|
19195
|
-
anchorEdges.push({ ...e, from: wireFrom, to: symId, attrs:
|
|
19261
|
+
anchorEdges.push({ ...e, from: wireFrom, to: symId, attrs: wireAttrs });
|
|
19196
19262
|
}
|
|
19197
19263
|
}
|
|
19198
19264
|
}
|
package/errata.mjs
CHANGED
|
@@ -15729,6 +15729,9 @@ function provenanceBand(source) {
|
|
|
15729
15729
|
function isSeedProvenance(source) {
|
|
15730
15730
|
return provenanceBand(source) === "seed";
|
|
15731
15731
|
}
|
|
15732
|
+
function isAnchorLabelKind(kind) {
|
|
15733
|
+
return typeof kind === "string" && ANCHOR_LABEL_KINDS.includes(kind);
|
|
15734
|
+
}
|
|
15732
15735
|
function anchorVersionAttrs(attrs) {
|
|
15733
15736
|
if (!attrs) return {};
|
|
15734
15737
|
const commit = attrs["observedAtCommit"];
|
|
@@ -15738,6 +15741,28 @@ function anchorVersionAttrs(attrs) {
|
|
|
15738
15741
|
...typeof hash2 === "string" && ANCHOR_BODY_HASH_RE.test(hash2) ? { symbolContentHash: hash2 } : {}
|
|
15739
15742
|
};
|
|
15740
15743
|
}
|
|
15744
|
+
function anchorLabelAttrs(attrs) {
|
|
15745
|
+
if (!attrs) return {};
|
|
15746
|
+
const relPath = attrs["labelRelPath"];
|
|
15747
|
+
const qname = attrs["labelQname"];
|
|
15748
|
+
const kind = attrs["labelKind"];
|
|
15749
|
+
const line = attrs["labelLine"];
|
|
15750
|
+
if (typeof relPath !== "string" || !ANCHOR_LABEL_PATH_RE.test(relPath)) return {};
|
|
15751
|
+
if (!isAnchorLabelKind(kind)) return {};
|
|
15752
|
+
const qnameOk = typeof qname === "string" && ANCHOR_LABEL_QNAME_RE.test(qname);
|
|
15753
|
+
if (kind !== "File" && !qnameOk) return {};
|
|
15754
|
+
return {
|
|
15755
|
+
labelRelPath: relPath,
|
|
15756
|
+
labelKind: kind,
|
|
15757
|
+
...kind !== "File" && qnameOk ? { labelQname: qname } : {},
|
|
15758
|
+
...typeof line === "number" && Number.isInteger(line) && line >= 1 && line <= 1e7 ? { labelLine: line } : {}
|
|
15759
|
+
};
|
|
15760
|
+
}
|
|
15761
|
+
function stripAnchorLabels(attrs) {
|
|
15762
|
+
const out2 = { ...attrs };
|
|
15763
|
+
for (const k of ANCHOR_LABEL_KEYS) delete out2[k];
|
|
15764
|
+
return out2;
|
|
15765
|
+
}
|
|
15741
15766
|
function validateCastaliaPayload(p) {
|
|
15742
15767
|
const errors = [];
|
|
15743
15768
|
const labelByCid = /* @__PURE__ */ new Map();
|
|
@@ -15767,7 +15792,7 @@ function summarizeIngestResult(r) {
|
|
|
15767
15792
|
...r.patternReconciliation ? { patternReconciliation: r.patternReconciliation } : {}
|
|
15768
15793
|
};
|
|
15769
15794
|
}
|
|
15770
|
-
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, QUARANTINE_EXTRACTION_SOURCE_PREFIX, MAX_NODES_PER_PAYLOAD, MAX_EDGES_PER_PAYLOAD, CastaliaIngestNodeSchema, RouteContextCountWireSchema, ANCHOR_COMMIT_SHA_RE, ANCHOR_BODY_HASH_RE, CastaliaIngestEdgeSchema, SymbolSummarySidecarSchema, CastaliaIngestPayloadSchema;
|
|
15795
|
+
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, QUARANTINE_EXTRACTION_SOURCE_PREFIX, MAX_NODES_PER_PAYLOAD, MAX_EDGES_PER_PAYLOAD, CastaliaIngestNodeSchema, RouteContextCountWireSchema, ANCHOR_COMMIT_SHA_RE, ANCHOR_BODY_HASH_RE, ANCHOR_SYMBOL_KINDS, ANCHOR_LABEL_KINDS, FILE_ANCHOR_QNAME, ANCHOR_LABEL_PATH_RE, ANCHOR_LABEL_QNAME_RE, ANCHOR_LABEL_KEYS, CastaliaIngestEdgeSchema, SymbolSummarySidecarSchema, CastaliaIngestPayloadSchema;
|
|
15771
15796
|
var init_wire = __esm({
|
|
15772
15797
|
"../../packages/shared/src/wire.ts"() {
|
|
15773
15798
|
"use strict";
|
|
@@ -15873,6 +15898,23 @@ var init_wire = __esm({
|
|
|
15873
15898
|
});
|
|
15874
15899
|
ANCHOR_COMMIT_SHA_RE = /^[0-9a-f]{7,40}$/;
|
|
15875
15900
|
ANCHOR_BODY_HASH_RE = /^[0-9a-f]{8,64}$/;
|
|
15901
|
+
ANCHOR_SYMBOL_KINDS = [
|
|
15902
|
+
"Function",
|
|
15903
|
+
"Class",
|
|
15904
|
+
"Method",
|
|
15905
|
+
"Module",
|
|
15906
|
+
"Interface",
|
|
15907
|
+
"Const",
|
|
15908
|
+
"Enum",
|
|
15909
|
+
"TypeAlias",
|
|
15910
|
+
"Namespace",
|
|
15911
|
+
"Property"
|
|
15912
|
+
];
|
|
15913
|
+
ANCHOR_LABEL_KINDS = [...ANCHOR_SYMBOL_KINDS, "File"];
|
|
15914
|
+
FILE_ANCHOR_QNAME = "";
|
|
15915
|
+
ANCHOR_LABEL_PATH_RE = /^(?![/])(?![A-Za-z]:)(?!(?:.*\/)?\.\.(?:\/|$))[^\x00-\x1f\x7f\\`]{1,512}$/;
|
|
15916
|
+
ANCHOR_LABEL_QNAME_RE = /^[^\x00-\x1f\x7f`]{1,256}$/;
|
|
15917
|
+
ANCHOR_LABEL_KEYS = ["labelRelPath", "labelQname", "labelKind", "labelLine"];
|
|
15876
15918
|
CastaliaIngestEdgeSchema = external_exports.object({
|
|
15877
15919
|
fromCanonicalId: external_exports.string().min(6).max(160),
|
|
15878
15920
|
toCanonicalId: external_exports.string().min(6).max(160),
|
|
@@ -15892,7 +15934,17 @@ var init_wire = __esm({
|
|
|
15892
15934
|
* classify the anchor current / pre-change; absent ⇒ the pre-versioning
|
|
15893
15935
|
* contract, unverified. Only meaningful on `ANCHORED_AT`. */
|
|
15894
15936
|
observedAtCommit: external_exports.string().regex(ANCHOR_COMMIT_SHA_RE).optional(),
|
|
15895
|
-
symbolContentHash: external_exports.string().regex(ANCHOR_BODY_HASH_RE).optional()
|
|
15937
|
+
symbolContentHash: external_exports.string().regex(ANCHOR_BODY_HASH_RE).optional(),
|
|
15938
|
+
/** PJ-anchor-labels: the READABLE identity of the anchor's target —
|
|
15939
|
+
* repo-relative path, qualified name (absent for a File), kind and line.
|
|
15940
|
+
* Sent only for a project whose owner opted in; the door strips them again
|
|
15941
|
+
* for any project that has not (the daemon's flag is not trusted alone).
|
|
15942
|
+
* Prefixed `label*` so no local edge attr (`anchorLine` lives there
|
|
15943
|
+
* natively) can ride out under a shared key. */
|
|
15944
|
+
labelRelPath: external_exports.string().regex(ANCHOR_LABEL_PATH_RE).optional(),
|
|
15945
|
+
labelQname: external_exports.string().regex(ANCHOR_LABEL_QNAME_RE).optional(),
|
|
15946
|
+
labelKind: external_exports.enum(ANCHOR_LABEL_KINDS).optional(),
|
|
15947
|
+
labelLine: external_exports.number().int().min(1).max(1e7).optional()
|
|
15896
15948
|
}).optional()
|
|
15897
15949
|
});
|
|
15898
15950
|
SymbolSummarySidecarSchema = external_exports.record(
|
|
@@ -16716,7 +16768,12 @@ __export(src_exports, {
|
|
|
16716
16768
|
AMBIGUOUS_ALIASES: () => AMBIGUOUS_ALIASES,
|
|
16717
16769
|
ANCHOR_BODY_HASH_RE: () => ANCHOR_BODY_HASH_RE,
|
|
16718
16770
|
ANCHOR_COMMIT_SHA_RE: () => ANCHOR_COMMIT_SHA_RE,
|
|
16771
|
+
ANCHOR_LABEL_KEYS: () => ANCHOR_LABEL_KEYS,
|
|
16772
|
+
ANCHOR_LABEL_KINDS: () => ANCHOR_LABEL_KINDS,
|
|
16773
|
+
ANCHOR_LABEL_PATH_RE: () => ANCHOR_LABEL_PATH_RE,
|
|
16774
|
+
ANCHOR_LABEL_QNAME_RE: () => ANCHOR_LABEL_QNAME_RE,
|
|
16719
16775
|
ANCHOR_REFUSAL_REASONS: () => ANCHOR_REFUSAL_REASONS,
|
|
16776
|
+
ANCHOR_SYMBOL_KINDS: () => ANCHOR_SYMBOL_KINDS,
|
|
16720
16777
|
BELIEF_EDGES: () => BELIEF_EDGES,
|
|
16721
16778
|
BRIDGE_EDGES: () => BRIDGE_EDGES,
|
|
16722
16779
|
CAUSAL_EDGES: () => CAUSAL_EDGES,
|
|
@@ -16739,6 +16796,7 @@ __export(src_exports, {
|
|
|
16739
16796
|
EDGE_RULES: () => EDGE_RULES,
|
|
16740
16797
|
EDGE_WEIGHT: () => EDGE_WEIGHT,
|
|
16741
16798
|
EVIDENCE_EDGES: () => EVIDENCE_EDGES,
|
|
16799
|
+
FILE_ANCHOR_QNAME: () => FILE_ANCHOR_QNAME,
|
|
16742
16800
|
GIT_EDGES: () => GIT_EDGES,
|
|
16743
16801
|
GRAPH_EVENT_VOCABULARIES: () => GRAPH_EVENT_VOCABULARIES,
|
|
16744
16802
|
IDENTITY_EDGES: () => IDENTITY_EDGES,
|
|
@@ -16775,6 +16833,7 @@ __export(src_exports, {
|
|
|
16775
16833
|
VALIDATION_SOURCES: () => VALIDATION_SOURCES,
|
|
16776
16834
|
aliasesLongestFirst: () => aliasesLongestFirst,
|
|
16777
16835
|
allEntities: () => allEntities,
|
|
16836
|
+
anchorLabelAttrs: () => anchorLabelAttrs,
|
|
16778
16837
|
anchorVersionAttrs: () => anchorVersionAttrs,
|
|
16779
16838
|
assertGraphEventVocabulary: () => assertGraphEventVocabulary,
|
|
16780
16839
|
buildSpine: () => buildSpine,
|
|
@@ -16796,6 +16855,7 @@ __export(src_exports, {
|
|
|
16796
16855
|
extractIdentifierTokens: () => extractIdentifierTokens,
|
|
16797
16856
|
genericCanonicalId: () => genericCanonicalId,
|
|
16798
16857
|
identityId: () => identityId,
|
|
16858
|
+
isAnchorLabelKind: () => isAnchorLabelKind,
|
|
16799
16859
|
isCausalProtected: () => isCausalProtected,
|
|
16800
16860
|
isCloudWritableNodeLabel: () => isCloudWritableNodeLabel,
|
|
16801
16861
|
isCodeLabel: () => isCodeLabel,
|
|
@@ -16844,6 +16904,7 @@ __export(src_exports, {
|
|
|
16844
16904
|
sidecarDropBucket: () => sidecarDropBucket,
|
|
16845
16905
|
spineDeps: () => spineDeps,
|
|
16846
16906
|
splitPnpmKey: () => splitPnpmKey,
|
|
16907
|
+
stripAnchorLabels: () => stripAnchorLabels,
|
|
16847
16908
|
substituteSymbolSummaries: () => substituteSymbolSummaries,
|
|
16848
16909
|
summarizeIngestResult: () => summarizeIngestResult,
|
|
16849
16910
|
summaryRejectionReason: () => summaryRejectionReason,
|
|
@@ -24956,7 +25017,10 @@ function toWirePayload(batch, runId) {
|
|
|
24956
25017
|
...typeof e.confidence === "number" ? { confidence: clamp012(e.confidence) } : {},
|
|
24957
25018
|
...perContext ? { perContext } : {},
|
|
24958
25019
|
// PJ-anchor-version: the two opaque version stamps ride on anchors only.
|
|
24959
|
-
...e.type === "ANCHORED_AT" ? anchorVersionAttrs(e.attrs) : {}
|
|
25020
|
+
...e.type === "ANCHORED_AT" ? anchorVersionAttrs(e.attrs) : {},
|
|
25021
|
+
// PJ-anchor-labels: readable labels ride only when the producer set the
|
|
25022
|
+
// `label*` keys, which the daemon does only for an opted-in project.
|
|
25023
|
+
...e.type === "ANCHORED_AT" ? anchorLabelAttrs(e.attrs) : {}
|
|
24960
25024
|
}
|
|
24961
25025
|
};
|
|
24962
25026
|
});
|
|
@@ -51034,15 +51098,14 @@ function recallForTool(store, command, ctx) {
|
|
|
51034
51098
|
${lines.join("\n")}`;
|
|
51035
51099
|
}
|
|
51036
51100
|
function decideContextInject(args2) {
|
|
51037
|
-
const { event,
|
|
51101
|
+
const { event, sessionId, block, lastInjectedHash } = args2;
|
|
51038
51102
|
if (!block) return null;
|
|
51039
51103
|
if (event === "SessionStart") {
|
|
51040
|
-
lastInjectedHash.set(sessionId, block.hash);
|
|
51041
|
-
|
|
51042
|
-
} else if (lastInjectedHash.get(sessionId) === block.hash) {
|
|
51104
|
+
if (sessionId) lastInjectedHash.set(sessionId, block.hash);
|
|
51105
|
+
} else if (sessionId && lastInjectedHash.get(sessionId) === block.hash) {
|
|
51043
51106
|
return null;
|
|
51044
51107
|
} else {
|
|
51045
|
-
lastInjectedHash.set(sessionId, block.hash);
|
|
51108
|
+
if (sessionId) lastInjectedHash.set(sessionId, block.hash);
|
|
51046
51109
|
}
|
|
51047
51110
|
const additionalContext = "The errata daemon has updated your live workspace context. The block below REPLACES any earlier errata context block in this conversation \u2014 treat it as the current source of truth:\n\n" + block.body;
|
|
51048
51111
|
return { hookEventName: event, additionalContext };
|
|
@@ -70832,8 +70895,8 @@ var init_report_render = __esm({
|
|
|
70832
70895
|
|
|
70833
70896
|
// src/cli.ts
|
|
70834
70897
|
init_src6();
|
|
70835
|
-
import { closeSync as closeSync2, existsSync as
|
|
70836
|
-
import { join as
|
|
70898
|
+
import { closeSync as closeSync2, existsSync as existsSync34, openSync as openSync2, readFileSync as readFileSync33, renameSync as renameSync4, statSync as statSync8 } from "node:fs";
|
|
70899
|
+
import { join as join38, resolve as pathResolve2 } from "node:path";
|
|
70837
70900
|
import { spawn as spawn3 } from "node:child_process";
|
|
70838
70901
|
|
|
70839
70902
|
// src/daemon.ts
|
|
@@ -78143,7 +78206,7 @@ function createWatchBreaker(deps) {
|
|
|
78143
78206
|
}
|
|
78144
78207
|
|
|
78145
78208
|
// src/engine.ts
|
|
78146
|
-
var DAEMON_VERSION = true ? "2.0.6-dev.
|
|
78209
|
+
var DAEMON_VERSION = true ? "2.0.6-dev.2533" : "2.0.0-alpha.0";
|
|
78147
78210
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
78148
78211
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
78149
78212
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -81172,19 +81235,39 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
81172
81235
|
for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
|
|
81173
81236
|
const target = store.getNode(e.to);
|
|
81174
81237
|
if (!target) continue;
|
|
81238
|
+
if (!isAnchorLabelKind(target.label)) continue;
|
|
81239
|
+
const isFile = target.label === "File";
|
|
81240
|
+
if (isFile && !project.anchorLabels) continue;
|
|
81175
81241
|
const relPath = target.attrs["relPath"];
|
|
81176
|
-
const qname = target.attrs["qname"];
|
|
81242
|
+
const qname = isFile ? FILE_ANCHOR_QNAME : target.attrs["qname"];
|
|
81177
81243
|
if (typeof relPath !== "string" || typeof qname !== "string") continue;
|
|
81178
|
-
if (ignored(relPath) || ignored(qname)) continue;
|
|
81179
|
-
|
|
81244
|
+
if (ignored(relPath) || qname !== "" && ignored(qname)) continue;
|
|
81245
|
+
const line = e.attrs?.["anchorLine"];
|
|
81246
|
+
const wireAttrs = {
|
|
81247
|
+
...anchorVersionAttrs(e.attrs),
|
|
81248
|
+
// PJ-anchor-labels: only for an opted-in project, and only through the
|
|
81249
|
+
// shared projection (invalid path/kind ⇒ no label, never half of one).
|
|
81250
|
+
...project.anchorLabels ? anchorLabelAttrs({
|
|
81251
|
+
labelRelPath: normalizeSymbolPath(relPath),
|
|
81252
|
+
labelKind: target.label,
|
|
81253
|
+
...isFile ? {} : { labelQname: qname },
|
|
81254
|
+
...typeof line === "number" ? { labelLine: line } : {}
|
|
81255
|
+
}) : {}
|
|
81256
|
+
};
|
|
81257
|
+
planned.push({
|
|
81258
|
+
e,
|
|
81259
|
+
target,
|
|
81260
|
+
symId: projectSymbolId(project.salt, project.projectId, relPath, qname, target.label),
|
|
81261
|
+
wireAttrs
|
|
81262
|
+
});
|
|
81180
81263
|
}
|
|
81181
81264
|
if (planned.length === 0) continue;
|
|
81182
81265
|
const dg = digest(
|
|
81183
|
-
planned.map(({
|
|
81266
|
+
planned.map(({ symId, wireAttrs }) => `ANCHORED_AT>${symId}>${JSON.stringify(wireAttrs)}`).sort()
|
|
81184
81267
|
);
|
|
81185
81268
|
if (source.attrs["projectAnchorsContributedDigest"] === dg) continue;
|
|
81186
81269
|
projectAnchorDigests[sourceId] = dg;
|
|
81187
|
-
for (const { e, target, symId } of planned) {
|
|
81270
|
+
for (const { e, target, symId, wireAttrs } of planned) {
|
|
81188
81271
|
if (!contextSeen.has(symId)) {
|
|
81189
81272
|
contextSeen.add(symId);
|
|
81190
81273
|
contextNodes.push({
|
|
@@ -81211,7 +81294,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
81211
81294
|
stability: "unstable"
|
|
81212
81295
|
});
|
|
81213
81296
|
}
|
|
81214
|
-
anchorEdges.push({ ...e, from: wireFrom, to: symId, attrs:
|
|
81297
|
+
anchorEdges.push({ ...e, from: wireFrom, to: symId, attrs: wireAttrs });
|
|
81215
81298
|
}
|
|
81216
81299
|
}
|
|
81217
81300
|
}
|
|
@@ -81715,7 +81798,7 @@ init_src11();
|
|
|
81715
81798
|
init_src();
|
|
81716
81799
|
init_src11();
|
|
81717
81800
|
var DEFAULT_LIMIT = 50;
|
|
81718
|
-
var
|
|
81801
|
+
var ANCHOR_SYMBOL_KINDS2 = [
|
|
81719
81802
|
"Function",
|
|
81720
81803
|
"Class",
|
|
81721
81804
|
"Method",
|
|
@@ -81736,7 +81819,7 @@ function classifyAnchorVersion(cloudAttrs, localSymbol) {
|
|
|
81736
81819
|
function buildReverseSymbolMap(opts) {
|
|
81737
81820
|
const { store, salt, projectId } = opts;
|
|
81738
81821
|
const reverse = /* @__PURE__ */ new Map();
|
|
81739
|
-
for (const kind of
|
|
81822
|
+
for (const kind of ANCHOR_SYMBOL_KINDS2) {
|
|
81740
81823
|
for (const n of store.findNodeIdentitiesByLabel(kind)) {
|
|
81741
81824
|
const { relPath, qname } = n;
|
|
81742
81825
|
if (relPath === null || qname === null) continue;
|
|
@@ -81746,6 +81829,13 @@ function buildReverseSymbolMap(opts) {
|
|
|
81746
81829
|
if (!reverse.has(twin)) reverse.set(twin, n.id);
|
|
81747
81830
|
}
|
|
81748
81831
|
}
|
|
81832
|
+
for (const n of store.findNodeIdentitiesByLabel("File")) {
|
|
81833
|
+
if (n.relPath === null) continue;
|
|
81834
|
+
const sym = projectSymbolId(salt, projectId, n.relPath, FILE_ANCHOR_QNAME, "File");
|
|
81835
|
+
if (!reverse.has(sym)) reverse.set(sym, n.id);
|
|
81836
|
+
const twin = projectSaltedNodeId(sym, salt);
|
|
81837
|
+
if (!reverse.has(twin)) reverse.set(twin, n.id);
|
|
81838
|
+
}
|
|
81749
81839
|
return reverse;
|
|
81750
81840
|
}
|
|
81751
81841
|
function anchorConfidence(attrs) {
|
|
@@ -84482,12 +84572,21 @@ function withLaunchOrigin(pending) {
|
|
|
84482
84572
|
return LOCAL_BUILD_ENTRY ? { ...pending, localBuildEntry: LOCAL_BUILD_ENTRY } : pending;
|
|
84483
84573
|
}
|
|
84484
84574
|
var projectSymbolSalts = /* @__PURE__ */ new Map();
|
|
84575
|
+
var PROJECT_SALT_REFRESH_MS = 10 * 6e4;
|
|
84485
84576
|
async function resolveProjectSymbolSalt(client, projectId) {
|
|
84486
84577
|
const cached2 = projectSymbolSalts.get(projectId);
|
|
84487
|
-
if (cached2)
|
|
84488
|
-
|
|
84489
|
-
|
|
84490
|
-
|
|
84578
|
+
if (cached2 && Date.now() - cached2.fetchedAt < PROJECT_SALT_REFRESH_MS) {
|
|
84579
|
+
return { projectId, salt: cached2.salt, anchorLabels: cached2.anchorLabels };
|
|
84580
|
+
}
|
|
84581
|
+
try {
|
|
84582
|
+
const res = await client.projectSymbolSalt(projectId);
|
|
84583
|
+
const entry = { salt: res.salt, anchorLabels: res.anchorLabels === true, fetchedAt: Date.now() };
|
|
84584
|
+
projectSymbolSalts.set(projectId, entry);
|
|
84585
|
+
return { projectId, salt: entry.salt, anchorLabels: entry.anchorLabels };
|
|
84586
|
+
} catch (err2) {
|
|
84587
|
+
if (cached2) return { projectId, salt: cached2.salt, anchorLabels: cached2.anchorLabels };
|
|
84588
|
+
throw err2;
|
|
84589
|
+
}
|
|
84491
84590
|
}
|
|
84492
84591
|
var WATERMARK_BATCH = 250;
|
|
84493
84592
|
async function stampBatched(items, stamp) {
|
|
@@ -86612,32 +86711,92 @@ function hookRelayCommand(port, path2) {
|
|
|
86612
86711
|
}
|
|
86613
86712
|
var CODEX_HOOKS_BEGIN = `# >>> errata hooks (errata-managed)`;
|
|
86614
86713
|
var CODEX_HOOKS_END = `# <<< errata hooks`;
|
|
86615
|
-
function buildCodexHooksToml(port) {
|
|
86616
|
-
const
|
|
86617
|
-
const
|
|
86618
|
-
|
|
86619
|
-
[
|
|
86620
|
-
|
|
86621
|
-
|
|
86622
|
-
|
|
86623
|
-
|
|
86624
|
-
|
|
86625
|
-
|
|
86626
|
-
|
|
86627
|
-
[[hooks.
|
|
86628
|
-
|
|
86629
|
-
|
|
86630
|
-
|
|
86631
|
-
|
|
86632
|
-
|
|
86633
|
-
|
|
86634
|
-
|
|
86635
|
-
|
|
86636
|
-
|
|
86637
|
-
|
|
86638
|
-
|
|
86639
|
-
|
|
86714
|
+
function buildCodexHooksToml(port, options) {
|
|
86715
|
+
const platform = options.platform ?? process.platform;
|
|
86716
|
+
const quote = (value) => {
|
|
86717
|
+
if (platform === "win32") {
|
|
86718
|
+
if (/["%\r\n]/.test(value)) throw new Error("Unsupported character in Codex hook path");
|
|
86719
|
+
return '"' + value + '"';
|
|
86720
|
+
}
|
|
86721
|
+
return "'" + value.replace(/'/g, "'\\''") + "'";
|
|
86722
|
+
};
|
|
86723
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Invalid hook port");
|
|
86724
|
+
const command = quote(options.nodePath) + " " + quote(options.relayPath) + " " + port;
|
|
86725
|
+
const handlers = ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostToolUse"].map(
|
|
86726
|
+
(event) => "[[hooks." + event + "]]\n" + (event === "UserPromptSubmit" ? "" : 'matcher = ".*"\n') + "\n[[hooks." + event + '.hooks]]\ntype = "command"\ncommand = ' + JSON.stringify(command) + "\ntimeout = 10\nadditionalContextLimit = 5000\n"
|
|
86727
|
+
);
|
|
86728
|
+
return CODEX_HOOKS_BEGIN + "\n" + handlers.join("\n") + CODEX_HOOKS_END + "\n";
|
|
86729
|
+
}
|
|
86730
|
+
|
|
86731
|
+
// src/codex-hooks.ts
|
|
86732
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync9, readFileSync as readFileSync32, writeFileSync as writeFileSync24 } from "node:fs";
|
|
86733
|
+
import { homedir as homedir7 } from "node:os";
|
|
86734
|
+
import { join as join37 } from "node:path";
|
|
86735
|
+
|
|
86736
|
+
// src/codex-hook-relay.ts
|
|
86737
|
+
var CODEX_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata install-hooks codex
|
|
86738
|
+
import { readFileSync } from 'node:fs';
|
|
86739
|
+
|
|
86740
|
+
try {
|
|
86741
|
+
const payload = JSON.parse(readFileSync(0, 'utf8') || '{}');
|
|
86742
|
+
const port = Number(process.argv[2]);
|
|
86743
|
+
const event = payload.hook_event_name;
|
|
86744
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) process.exit(0);
|
|
86745
|
+
const contexts = [];
|
|
86746
|
+
const post = async (endpoint, relay = false) => {
|
|
86747
|
+
try {
|
|
86748
|
+
const response = await fetch('http://127.0.0.1:' + port + '/api/' + endpoint, {
|
|
86749
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
86750
|
+
body: JSON.stringify(payload), signal: AbortSignal.timeout(2000),
|
|
86751
|
+
});
|
|
86752
|
+
if (!response.ok || !relay) return;
|
|
86753
|
+
const result = await response.json();
|
|
86754
|
+
const context = result.hookSpecificOutput?.additionalContext;
|
|
86755
|
+
if (typeof context === 'string' && context.trim()) contexts.push(context);
|
|
86756
|
+
} catch { /* An unavailable daemon must never block the agent. */ }
|
|
86757
|
+
};
|
|
86758
|
+
if (event === 'PreToolUse' || event === 'PostToolUse') await post('hook', true);
|
|
86759
|
+
if (event === 'PostToolUse') await post('turn');
|
|
86760
|
+
if (['SessionStart', 'UserPromptSubmit', 'PostToolUse'].includes(event)) {
|
|
86761
|
+
// Run after capture, so changes already rendered by the daemon arrive now.
|
|
86762
|
+
// Background extraction finishing later arrives at the next tool boundary.
|
|
86763
|
+
await post('context-inject', true);
|
|
86764
|
+
}
|
|
86765
|
+
if (contexts.length) {
|
|
86766
|
+
process.stdout.write(JSON.stringify({ hookSpecificOutput: {
|
|
86767
|
+
hookEventName: event, additionalContext: contexts.join('\n\n'),
|
|
86768
|
+
} }));
|
|
86769
|
+
}
|
|
86770
|
+
} catch { /* Invalid input is also fail-open. */ }
|
|
86640
86771
|
`;
|
|
86772
|
+
|
|
86773
|
+
// src/codex-hooks.ts
|
|
86774
|
+
function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join37(homedir7(), ".codex")) {
|
|
86775
|
+
return existsSync33(join37(root, ".codex")) || existsSync33(codexHome);
|
|
86776
|
+
}
|
|
86777
|
+
function replaceCodexHooks(existing, block) {
|
|
86778
|
+
const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
86779
|
+
const end = existing.indexOf(CODEX_HOOKS_END);
|
|
86780
|
+
if (begin >= 0 || end >= 0) {
|
|
86781
|
+
if (begin < 0 || end < begin || existing.indexOf(CODEX_HOOKS_BEGIN, begin + CODEX_HOOKS_BEGIN.length) >= 0) {
|
|
86782
|
+
throw new Error(
|
|
86783
|
+
"Incomplete or duplicate errata hooks markers in .codex/config.toml; repair them before reinstalling."
|
|
86784
|
+
);
|
|
86785
|
+
}
|
|
86786
|
+
return existing.slice(0, begin) + block.trimEnd() + existing.slice(end + CODEX_HOOKS_END.length);
|
|
86787
|
+
}
|
|
86788
|
+
return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
|
|
86789
|
+
}
|
|
86790
|
+
function writeCodexHooks(root, port, nodePath = process.execPath) {
|
|
86791
|
+
const dir = join37(root, ".codex");
|
|
86792
|
+
const file2 = join37(dir, "config.toml");
|
|
86793
|
+
const relay = join37(dir, "hooks", "errata-relay.mjs");
|
|
86794
|
+
const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
|
|
86795
|
+
const final = replaceCodexHooks(existsSync33(file2) ? readFileSync32(file2, "utf8") : "", block);
|
|
86796
|
+
mkdirSync9(join37(dir, "hooks"), { recursive: true });
|
|
86797
|
+
writeFileSync24(relay, CODEX_RELAY_SOURCE, "utf8");
|
|
86798
|
+
writeFileSync24(file2, final, "utf8");
|
|
86799
|
+
return file2;
|
|
86641
86800
|
}
|
|
86642
86801
|
|
|
86643
86802
|
// src/opencode-plugin.ts
|
|
@@ -86979,6 +87138,7 @@ Commands:
|
|
|
86979
87138
|
Flags: --project <id> adopt an existing project (fork\u2192upstream);
|
|
86980
87139
|
--remote <name> derive the locator from a non-origin remote;
|
|
86981
87140
|
--name <name> mint a locator-less project; no flags = re-resolve now
|
|
87141
|
+
--skip-hooks leave existing harness configuration unchanged
|
|
86982
87142
|
unlink Detach from the cloud project + disable ambient re-linking
|
|
86983
87143
|
use [<handle>] Set the sticky session active agent the daemon acts as.
|
|
86984
87144
|
No arg lists the agents you can act as + the current one;
|
|
@@ -87044,21 +87204,21 @@ async function cmdInit() {
|
|
|
87044
87204
|
if (!skipHooks) {
|
|
87045
87205
|
console.log("");
|
|
87046
87206
|
console.log("installing harness hooks...");
|
|
87047
|
-
const { existsSync:
|
|
87048
|
-
const { join:
|
|
87207
|
+
const { existsSync: existsSync35 } = await import("node:fs");
|
|
87208
|
+
const { join: join39 } = await import("node:path");
|
|
87049
87209
|
try {
|
|
87050
87210
|
await installClaudeHooks(port);
|
|
87051
87211
|
} catch (err2) {
|
|
87052
87212
|
console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
87053
87213
|
}
|
|
87054
|
-
if (
|
|
87214
|
+
if (existsSync35(join39(ROOT, ".cursor"))) {
|
|
87055
87215
|
try {
|
|
87056
87216
|
await installCursorMcpConfig();
|
|
87057
87217
|
} catch (err2) {
|
|
87058
87218
|
console.warn(` \u26A0\uFE0F Cursor MCP config failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
87059
87219
|
}
|
|
87060
87220
|
}
|
|
87061
|
-
if (
|
|
87221
|
+
if (hasCodexConfig(ROOT)) {
|
|
87062
87222
|
try {
|
|
87063
87223
|
await installCodexHooks(port);
|
|
87064
87224
|
} catch (err2) {
|
|
@@ -87235,9 +87395,9 @@ async function cmdStatus() {
|
|
|
87235
87395
|
console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
|
|
87236
87396
|
console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
|
|
87237
87397
|
}
|
|
87238
|
-
console.log(` graph db: ${
|
|
87239
|
-
console.log(` event log: ${
|
|
87240
|
-
if (
|
|
87398
|
+
console.log(` graph db: ${existsSync34(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
87399
|
+
console.log(` event log: ${existsSync34(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
87400
|
+
if (existsSync34(paths.castalia)) {
|
|
87241
87401
|
try {
|
|
87242
87402
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
|
|
87243
87403
|
const store = openGraphStore2({ path: paths.castalia });
|
|
@@ -87872,6 +88032,7 @@ async function cmdLink(args2) {
|
|
|
87872
88032
|
console.log(
|
|
87873
88033
|
`consents: sync=${d.consents.sync} telemetry=${d.consents.telemetry ? "on" : "off"} packages=${applied.config.consent.contributePackages ? "on" : "off"} structure=${d.consents.structure ? "on" : "off"} history=${d.consents.mineHistory ? applied.profile.linkConsents?.contributeHistory ? "mine+contribute" : "mine" : "off"}`
|
|
87874
88034
|
);
|
|
88035
|
+
await refreshLinkedCodexHooks(args2);
|
|
87875
88036
|
if (applied.wroteIgnore) console.log("wrote .errataignore (starter) \u2014 edit it; it is your hard control");
|
|
87876
88037
|
if (!hasCloudCredential(cfg)) {
|
|
87877
88038
|
console.log(" note: run `errata login` so this daemon can sync under the link and report the history stage.");
|
|
@@ -87912,6 +88073,7 @@ async function cmdLink(args2) {
|
|
|
87912
88073
|
profile.projectId = res.project.id;
|
|
87913
88074
|
profile.projectLocator = profile.repoLocator;
|
|
87914
88075
|
saveProfile(ROOT, profile);
|
|
88076
|
+
await refreshLinkedCodexHooks(args2);
|
|
87915
88077
|
console.log(`linked (adopted): ${profile.repoLocator} \u2192 project ${res.project.id} (${res.project.name})`);
|
|
87916
88078
|
return;
|
|
87917
88079
|
}
|
|
@@ -87921,6 +88083,7 @@ async function cmdLink(args2) {
|
|
|
87921
88083
|
profile.projectId = res.project.id;
|
|
87922
88084
|
delete profile.projectLocator;
|
|
87923
88085
|
saveProfile(ROOT, profile);
|
|
88086
|
+
await refreshLinkedCodexHooks(args2);
|
|
87924
88087
|
console.log(`linked (locator-less): project ${res.project.id} (${res.project.name})`);
|
|
87925
88088
|
return;
|
|
87926
88089
|
}
|
|
@@ -87929,6 +88092,7 @@ async function cmdLink(args2) {
|
|
|
87929
88092
|
delete profile.projectLocator;
|
|
87930
88093
|
const out2 = await ensureProjectLink(ROOT, profile, client);
|
|
87931
88094
|
if (out2.linked) {
|
|
88095
|
+
await refreshLinkedCodexHooks(args2);
|
|
87932
88096
|
console.log(`linked: ${profile.repoLocator} \u2192 project ${out2.projectId}${out2.created ? " (created)" : ""}`);
|
|
87933
88097
|
} else {
|
|
87934
88098
|
console.error(`link failed (${out2.reason})${out2.detail ? `: ${out2.detail}` : ""}`);
|
|
@@ -88135,11 +88299,11 @@ function cmdInstallationProfile(args2) {
|
|
|
88135
88299
|
}
|
|
88136
88300
|
async function cmdReview() {
|
|
88137
88301
|
const paths = workspacePaths(ROOT);
|
|
88138
|
-
if (!
|
|
88302
|
+
if (!existsSync34(paths.reviewQueue)) {
|
|
88139
88303
|
console.log("(review queue empty)");
|
|
88140
88304
|
return;
|
|
88141
88305
|
}
|
|
88142
|
-
const queue = JSON.parse(
|
|
88306
|
+
const queue = JSON.parse(readFileSync33(paths.reviewQueue, "utf8"));
|
|
88143
88307
|
if (queue.length === 0) {
|
|
88144
88308
|
console.log("(review queue empty)");
|
|
88145
88309
|
return;
|
|
@@ -88810,7 +88974,7 @@ async function gatherRepo(store, ws) {
|
|
|
88810
88974
|
};
|
|
88811
88975
|
}
|
|
88812
88976
|
async function gatherReportData(generatedAt) {
|
|
88813
|
-
const { existsSync:
|
|
88977
|
+
const { existsSync: existsSync35 } = await import("node:fs");
|
|
88814
88978
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
|
|
88815
88979
|
const cfg = loadConfig();
|
|
88816
88980
|
const outbound = cfg.consent.sync ? "auto" : "off";
|
|
@@ -88818,7 +88982,7 @@ async function gatherReportData(generatedAt) {
|
|
|
88818
88982
|
for (const ws of listWorkspaces()) {
|
|
88819
88983
|
if (ws.missing) continue;
|
|
88820
88984
|
const dbPath = workspacePaths(ws.path).castalia;
|
|
88821
|
-
if (!
|
|
88985
|
+
if (!existsSync35(dbPath)) continue;
|
|
88822
88986
|
let store = null;
|
|
88823
88987
|
try {
|
|
88824
88988
|
store = openGraphStore2({ path: dbPath });
|
|
@@ -88849,7 +89013,7 @@ async function gatherReportData(generatedAt) {
|
|
|
88849
89013
|
};
|
|
88850
89014
|
}
|
|
88851
89015
|
async function cmdReport(args2) {
|
|
88852
|
-
const { mkdirSync:
|
|
89016
|
+
const { mkdirSync: mkdirSync10, writeFileSync: writeFileSync25 } = await import("node:fs");
|
|
88853
89017
|
const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
|
|
88854
89018
|
const includeFutureVerbs = args2.includes("--future-verbs");
|
|
88855
89019
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -88860,10 +89024,10 @@ async function cmdReport(args2) {
|
|
|
88860
89024
|
process.exit(2);
|
|
88861
89025
|
}
|
|
88862
89026
|
const outDir = workspacePaths(ROOT).configDir;
|
|
88863
|
-
|
|
89027
|
+
mkdirSync10(outDir, { recursive: true });
|
|
88864
89028
|
const files = renderReport2(data, { includeFutureVerbs });
|
|
88865
|
-
for (const f of files)
|
|
88866
|
-
const indexPath =
|
|
89029
|
+
for (const f of files) writeFileSync25(join38(outDir, f.name), f.html, "utf8");
|
|
89030
|
+
const indexPath = join38(outDir, "report.html");
|
|
88867
89031
|
console.log(`report \u2192 ${indexPath}`);
|
|
88868
89032
|
console.log(
|
|
88869
89033
|
` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
|
|
@@ -88983,24 +89147,24 @@ async function cmdInstallHooks(args2) {
|
|
|
88983
89147
|
}
|
|
88984
89148
|
}
|
|
88985
89149
|
async function installOpencodePlugin(port) {
|
|
88986
|
-
const { mkdirSync:
|
|
88987
|
-
const { join:
|
|
88988
|
-
const dir =
|
|
88989
|
-
if (!
|
|
88990
|
-
const file2 =
|
|
88991
|
-
if (
|
|
88992
|
-
const head2 =
|
|
89150
|
+
const { mkdirSync: mkdirSync10, existsSync: existsSync35, readFileSync: readFileSync34, writeFileSync: writeFileSync25 } = await import("node:fs");
|
|
89151
|
+
const { join: join39 } = await import("node:path");
|
|
89152
|
+
const dir = join39(ROOT, ".opencode", "plugin");
|
|
89153
|
+
if (!existsSync35(dir)) mkdirSync10(dir, { recursive: true });
|
|
89154
|
+
const file2 = join39(dir, "inerrata.js");
|
|
89155
|
+
if (existsSync35(file2)) {
|
|
89156
|
+
const head2 = readFileSync34(file2, "utf8").split("\n")[0] ?? "";
|
|
88993
89157
|
if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
|
|
88994
89158
|
console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
|
|
88995
89159
|
process.exit(2);
|
|
88996
89160
|
}
|
|
88997
89161
|
}
|
|
88998
|
-
|
|
88999
|
-
const cfgFile =
|
|
89162
|
+
writeFileSync25(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
|
|
89163
|
+
const cfgFile = join39(ROOT, "opencode.json");
|
|
89000
89164
|
let cfg = { $schema: "https://opencode.ai/config.json" };
|
|
89001
|
-
if (
|
|
89165
|
+
if (existsSync35(cfgFile)) {
|
|
89002
89166
|
try {
|
|
89003
|
-
cfg = JSON.parse(
|
|
89167
|
+
cfg = JSON.parse(readFileSync34(cfgFile, "utf8"));
|
|
89004
89168
|
} catch {
|
|
89005
89169
|
console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
|
|
89006
89170
|
process.exit(2);
|
|
@@ -89011,7 +89175,7 @@ async function installOpencodePlugin(port) {
|
|
|
89011
89175
|
if (!hadErrata) {
|
|
89012
89176
|
const inv = errataMcpInvocation();
|
|
89013
89177
|
cfg.mcp["errata"] = { type: "local", command: [inv.command, ...inv.args] };
|
|
89014
|
-
|
|
89178
|
+
writeFileSync25(cfgFile, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
89015
89179
|
}
|
|
89016
89180
|
console.log(`installed OpenCode plugin \u2192 ${file2}`);
|
|
89017
89181
|
if (hadErrata) console.log(` mcp.errata already present in ${cfgFile} \u2014 left untouched`);
|
|
@@ -89031,15 +89195,15 @@ function errataMcpInvocation() {
|
|
|
89031
89195
|
return { command: cmd2, args: args2 };
|
|
89032
89196
|
}
|
|
89033
89197
|
async function installClaudeHooks(port) {
|
|
89034
|
-
const { mkdirSync:
|
|
89035
|
-
const { join:
|
|
89036
|
-
const dir =
|
|
89037
|
-
if (!
|
|
89038
|
-
const file2 =
|
|
89198
|
+
const { mkdirSync: mkdirSync10, existsSync: existsSync35, readFileSync: readFileSync34, writeFileSync: writeFileSync25 } = await import("node:fs");
|
|
89199
|
+
const { join: join39 } = await import("node:path");
|
|
89200
|
+
const dir = join39(ROOT, ".claude");
|
|
89201
|
+
if (!existsSync35(dir)) mkdirSync10(dir, { recursive: true });
|
|
89202
|
+
const file2 = join39(dir, "settings.json");
|
|
89039
89203
|
let settings = {};
|
|
89040
|
-
if (
|
|
89204
|
+
if (existsSync35(file2)) {
|
|
89041
89205
|
try {
|
|
89042
|
-
settings = JSON.parse(
|
|
89206
|
+
settings = JSON.parse(readFileSync34(file2, "utf8"));
|
|
89043
89207
|
} catch {
|
|
89044
89208
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
89045
89209
|
process.exit(2);
|
|
@@ -89085,10 +89249,10 @@ async function installClaudeHooks(port) {
|
|
|
89085
89249
|
dropErrata(list);
|
|
89086
89250
|
list.push({ hooks: [{ type: "command", command: injectCmd }] });
|
|
89087
89251
|
}
|
|
89088
|
-
|
|
89252
|
+
writeFileSync25(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
89089
89253
|
console.log(`installed Claude Code hooks \u2192 ${file2}`);
|
|
89090
89254
|
await installClaudeMcpConfig();
|
|
89091
|
-
const claudeMd =
|
|
89255
|
+
const claudeMd = join39(ROOT, "CLAUDE.md");
|
|
89092
89256
|
const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
|
|
89093
89257
|
if (recall.kind === "collision") {
|
|
89094
89258
|
console.warn(
|
|
@@ -89100,15 +89264,15 @@ async function installClaudeHooks(port) {
|
|
|
89100
89264
|
console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
|
|
89101
89265
|
}
|
|
89102
89266
|
async function installClaudeMcpConfig() {
|
|
89103
|
-
const { mkdirSync:
|
|
89104
|
-
const { join:
|
|
89105
|
-
const file2 =
|
|
89267
|
+
const { mkdirSync: mkdirSync10, existsSync: existsSync35, readFileSync: readFileSync34, writeFileSync: writeFileSync25 } = await import("node:fs");
|
|
89268
|
+
const { join: join39, dirname: dirname13 } = await import("node:path");
|
|
89269
|
+
const file2 = join39(ROOT, ".mcp.json");
|
|
89106
89270
|
const dir = dirname13(file2);
|
|
89107
|
-
if (!
|
|
89271
|
+
if (!existsSync35(dir)) mkdirSync10(dir, { recursive: true });
|
|
89108
89272
|
let cfg = {};
|
|
89109
|
-
if (
|
|
89273
|
+
if (existsSync35(file2)) {
|
|
89110
89274
|
try {
|
|
89111
|
-
cfg = JSON.parse(
|
|
89275
|
+
cfg = JSON.parse(readFileSync34(file2, "utf8"));
|
|
89112
89276
|
} catch {
|
|
89113
89277
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
89114
89278
|
process.exit(2);
|
|
@@ -89116,21 +89280,21 @@ async function installClaudeMcpConfig() {
|
|
|
89116
89280
|
}
|
|
89117
89281
|
cfg.mcpServers ??= {};
|
|
89118
89282
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
89119
|
-
|
|
89283
|
+
writeFileSync25(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
89120
89284
|
console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
|
|
89121
89285
|
console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
|
|
89122
89286
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
|
|
89123
89287
|
}
|
|
89124
89288
|
async function installCursorMcpConfig() {
|
|
89125
|
-
const { mkdirSync:
|
|
89126
|
-
const { join:
|
|
89127
|
-
const dir =
|
|
89128
|
-
if (!
|
|
89129
|
-
const file2 =
|
|
89289
|
+
const { mkdirSync: mkdirSync10, existsSync: existsSync35, readFileSync: readFileSync34, writeFileSync: writeFileSync25 } = await import("node:fs");
|
|
89290
|
+
const { join: join39 } = await import("node:path");
|
|
89291
|
+
const dir = join39(ROOT, ".cursor");
|
|
89292
|
+
if (!existsSync35(dir)) mkdirSync10(dir, { recursive: true });
|
|
89293
|
+
const file2 = join39(dir, "mcp.json");
|
|
89130
89294
|
let cfg = {};
|
|
89131
|
-
if (
|
|
89295
|
+
if (existsSync35(file2)) {
|
|
89132
89296
|
try {
|
|
89133
|
-
cfg = JSON.parse(
|
|
89297
|
+
cfg = JSON.parse(readFileSync34(file2, "utf8"));
|
|
89134
89298
|
} catch {
|
|
89135
89299
|
console.error(`refusing to overwrite invalid JSON at ${file2}`);
|
|
89136
89300
|
process.exit(2);
|
|
@@ -89138,7 +89302,7 @@ async function installCursorMcpConfig() {
|
|
|
89138
89302
|
}
|
|
89139
89303
|
cfg.mcpServers ??= {};
|
|
89140
89304
|
cfg.mcpServers["errata"] = errataMcpInvocation();
|
|
89141
|
-
|
|
89305
|
+
writeFileSync25(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
89142
89306
|
console.log(`installed Cursor MCP server config \u2192 ${file2}`);
|
|
89143
89307
|
console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
|
|
89144
89308
|
console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
|
|
@@ -89146,39 +89310,21 @@ async function installCursorMcpConfig() {
|
|
|
89146
89310
|
console.log(` \u26A0\uFE0F reload Cursor (Cmd/Ctrl-Shift-P \u2192 "Reload Window") to pick it up.`);
|
|
89147
89311
|
}
|
|
89148
89312
|
async function installCodexHooks(port) {
|
|
89149
|
-
const
|
|
89150
|
-
const { join: join38 } = await import("node:path");
|
|
89151
|
-
const dir = join38(ROOT, ".codex");
|
|
89152
|
-
if (!existsSync34(dir)) mkdirSync9(dir, { recursive: true });
|
|
89153
|
-
const file2 = join38(dir, "config.toml");
|
|
89154
|
-
let existing = "";
|
|
89155
|
-
if (existsSync34(file2)) {
|
|
89156
|
-
existing = readFileSync33(file2, "utf8");
|
|
89157
|
-
const beginIdx = existing.indexOf(CODEX_HOOKS_BEGIN);
|
|
89158
|
-
const endIdx = existing.indexOf(CODEX_HOOKS_END);
|
|
89159
|
-
if (beginIdx >= 0 && endIdx > beginIdx) {
|
|
89160
|
-
existing = existing.slice(0, beginIdx).trimEnd() + existing.slice(endIdx + CODEX_HOOKS_END.length).trimStart();
|
|
89161
|
-
}
|
|
89162
|
-
}
|
|
89163
|
-
const block = buildCodexHooksToml(port);
|
|
89164
|
-
const final = existing.length > 0 && !existing.endsWith("\n") ? `${existing}
|
|
89165
|
-
|
|
89166
|
-
${block}` : existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
|
|
89167
|
-
writeFileSync24(file2, final, "utf8");
|
|
89313
|
+
const file2 = writeCodexHooks(ROOT, port);
|
|
89168
89314
|
console.log(`installed Codex hooks \u2192 ${file2}`);
|
|
89169
|
-
console.log(
|
|
89170
|
-
console.log("");
|
|
89171
|
-
console.log(
|
|
89172
|
-
console.log(
|
|
89173
|
-
console.log("");
|
|
89174
|
-
|
|
89175
|
-
|
|
89176
|
-
|
|
89177
|
-
|
|
89178
|
-
|
|
89179
|
-
|
|
89180
|
-
|
|
89181
|
-
|
|
89315
|
+
console.log(" Context loads on SessionStart/UserPromptSubmit and refreshes after tools when changed.");
|
|
89316
|
+
console.log(" Tool capture and /api/turn harvesting remain enabled.");
|
|
89317
|
+
console.log(" Restart/resume Codex to reload config, then review and trust the hooks with /hooks.");
|
|
89318
|
+
console.log(" If your Codex version gates hooks, enable [features] codex_hooks = true.");
|
|
89319
|
+
console.log(" Older Codex versions may not support every event; update if hooks do not fire.");
|
|
89320
|
+
}
|
|
89321
|
+
async function refreshLinkedCodexHooks(args2) {
|
|
89322
|
+
if (args2.includes("--skip-hooks") || !hasCodexConfig(ROOT)) return;
|
|
89323
|
+
try {
|
|
89324
|
+
await installCodexHooks(resolveHookPort());
|
|
89325
|
+
} catch (err2) {
|
|
89326
|
+
console.warn(` Codex hook refresh failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
89327
|
+
}
|
|
89182
89328
|
}
|
|
89183
89329
|
function printAiderInstructions() {
|
|
89184
89330
|
console.log(`Aider doesn't expose programmatic per-tool hooks, so the`);
|
|
@@ -89508,7 +89654,7 @@ async function cmdDash(args2) {
|
|
|
89508
89654
|
await yieldToLoop2();
|
|
89509
89655
|
try {
|
|
89510
89656
|
const items = selectDurableMemory(handle2.sharedStore, r.engine.profile);
|
|
89511
|
-
const res = bleedRules(
|
|
89657
|
+
const res = bleedRules(join38(r.root, ".claude", "rules"), items);
|
|
89512
89658
|
if (res.written || res.pruned) {
|
|
89513
89659
|
console.log(
|
|
89514
89660
|
`[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -15140,7 +15140,7 @@ var init_symbol_intent = __esm({
|
|
|
15140
15140
|
});
|
|
15141
15141
|
|
|
15142
15142
|
// ../../packages/shared/src/wire.ts
|
|
15143
|
-
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;
|
|
15143
|
+
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, ANCHOR_SYMBOL_KINDS, ANCHOR_LABEL_KINDS, ANCHOR_LABEL_PATH_RE, ANCHOR_LABEL_QNAME_RE, CastaliaIngestEdgeSchema, SymbolSummarySidecarSchema, CastaliaIngestPayloadSchema;
|
|
15144
15144
|
var init_wire = __esm({
|
|
15145
15145
|
"../../packages/shared/src/wire.ts"() {
|
|
15146
15146
|
"use strict";
|
|
@@ -15243,6 +15243,21 @@ var init_wire = __esm({
|
|
|
15243
15243
|
});
|
|
15244
15244
|
ANCHOR_COMMIT_SHA_RE = /^[0-9a-f]{7,40}$/;
|
|
15245
15245
|
ANCHOR_BODY_HASH_RE = /^[0-9a-f]{8,64}$/;
|
|
15246
|
+
ANCHOR_SYMBOL_KINDS = [
|
|
15247
|
+
"Function",
|
|
15248
|
+
"Class",
|
|
15249
|
+
"Method",
|
|
15250
|
+
"Module",
|
|
15251
|
+
"Interface",
|
|
15252
|
+
"Const",
|
|
15253
|
+
"Enum",
|
|
15254
|
+
"TypeAlias",
|
|
15255
|
+
"Namespace",
|
|
15256
|
+
"Property"
|
|
15257
|
+
];
|
|
15258
|
+
ANCHOR_LABEL_KINDS = [...ANCHOR_SYMBOL_KINDS, "File"];
|
|
15259
|
+
ANCHOR_LABEL_PATH_RE = /^(?![/])(?![A-Za-z]:)(?!(?:.*\/)?\.\.(?:\/|$))[^\x00-\x1f\x7f\\`]{1,512}$/;
|
|
15260
|
+
ANCHOR_LABEL_QNAME_RE = /^[^\x00-\x1f\x7f`]{1,256}$/;
|
|
15246
15261
|
CastaliaIngestEdgeSchema = external_exports.object({
|
|
15247
15262
|
fromCanonicalId: external_exports.string().min(6).max(160),
|
|
15248
15263
|
toCanonicalId: external_exports.string().min(6).max(160),
|
|
@@ -15262,7 +15277,17 @@ var init_wire = __esm({
|
|
|
15262
15277
|
* classify the anchor current / pre-change; absent ⇒ the pre-versioning
|
|
15263
15278
|
* contract, unverified. Only meaningful on `ANCHORED_AT`. */
|
|
15264
15279
|
observedAtCommit: external_exports.string().regex(ANCHOR_COMMIT_SHA_RE).optional(),
|
|
15265
|
-
symbolContentHash: external_exports.string().regex(ANCHOR_BODY_HASH_RE).optional()
|
|
15280
|
+
symbolContentHash: external_exports.string().regex(ANCHOR_BODY_HASH_RE).optional(),
|
|
15281
|
+
/** PJ-anchor-labels: the READABLE identity of the anchor's target —
|
|
15282
|
+
* repo-relative path, qualified name (absent for a File), kind and line.
|
|
15283
|
+
* Sent only for a project whose owner opted in; the door strips them again
|
|
15284
|
+
* for any project that has not (the daemon's flag is not trusted alone).
|
|
15285
|
+
* Prefixed `label*` so no local edge attr (`anchorLine` lives there
|
|
15286
|
+
* natively) can ride out under a shared key. */
|
|
15287
|
+
labelRelPath: external_exports.string().regex(ANCHOR_LABEL_PATH_RE).optional(),
|
|
15288
|
+
labelQname: external_exports.string().regex(ANCHOR_LABEL_QNAME_RE).optional(),
|
|
15289
|
+
labelKind: external_exports.enum(ANCHOR_LABEL_KINDS).optional(),
|
|
15290
|
+
labelLine: external_exports.number().int().min(1).max(1e7).optional()
|
|
15266
15291
|
}).optional()
|
|
15267
15292
|
});
|
|
15268
15293
|
SymbolSummarySidecarSchema = external_exports.record(
|