@saasontools/strauss-kb 0.1.16 → 0.1.17

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/dist/index.d.cts CHANGED
@@ -48,7 +48,7 @@ declare const kbVerifiedEventSchema: z.ZodObject<{
48
48
  * Symbolic on purpose. These are written while the code is still moving: a
49
49
  * `line: 379` recorded at minute five is wrong by minute forty, but
50
50
  * `OrderService.cancel` survives every edit that does not rename it. Once the
51
- * change settles, a resolution pass (`anchor-resolver.ts`) stamps `hash`,
51
+ * change settles, a resolution pass (`anchor-resolver/`) stamps `hash`,
52
52
  * `resolved_at`, and `lines`; drift detection later re-resolves and compares.
53
53
  *
54
54
  * `hash` is prefixed with the algorithm so a future one can coexist with
@@ -70,6 +70,10 @@ declare const kbAnchorSchema: z.ZodObject<{
70
70
  hash: z.ZodOptional<z.ZodString>;
71
71
  resolved_at: z.ZodOptional<z.ZodString>;
72
72
  lines: z.ZodOptional<z.ZodNumber>;
73
+ resolver: z.ZodOptional<z.ZodEnum<{
74
+ "tree-sitter": "tree-sitter";
75
+ regex: "regex";
76
+ }>>;
73
77
  }, z.core.$strict>;
74
78
  /**
75
79
  * One typed causal edge, as the frontmatter stores it.
@@ -140,6 +144,10 @@ declare const kbRecordFrontmatterSchema: z.ZodObject<{
140
144
  hash: z.ZodOptional<z.ZodString>;
141
145
  resolved_at: z.ZodOptional<z.ZodString>;
142
146
  lines: z.ZodOptional<z.ZodNumber>;
147
+ resolver: z.ZodOptional<z.ZodEnum<{
148
+ "tree-sitter": "tree-sitter";
149
+ regex: "regex";
150
+ }>>;
143
151
  }, z.core.$strict>>>;
144
152
  strauss_verify: z.ZodOptional<z.ZodArray<z.ZodString>>;
145
153
  strauss_links: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -202,12 +210,46 @@ type ResolvedSymbol = {
202
210
  startLine: number;
203
211
  endLine: number;
204
212
  };
213
+ /** Which resolver produced a span. Stamped on the anchor. */
214
+ type AnchorResolverName = "tree-sitter" | "regex";
215
+ /**
216
+ * A resolver's verdict. `abstain` ("not my language") and `symbol-not-found`
217
+ * ("nothing I recognize declares this") both pass the symbol down the chain;
218
+ * `symbol-ambiguous` and `resolver-unavailable` end it, because neither may be
219
+ * answered by a looser resolver guessing.
220
+ */
221
+ type ResolverAttempt = {
222
+ kind: "resolved";
223
+ span: ResolvedSymbol;
224
+ } | {
225
+ kind: "unresolved";
226
+ reason: "symbol-not-found" | "symbol-ambiguous" | "resolver-unavailable";
227
+ } | {
228
+ kind: "abstain";
229
+ };
205
230
  interface AnchorResolver {
206
231
  name: string;
207
- resolve(source: string, symbol: string): ResolvedSymbol | null;
232
+ /** Loads whatever these files need, before any `resolve` call. Optional. */
233
+ prepare?(files: readonly string[]): Promise<void>;
234
+ /** The richer verdict the chain uses; defaults to `resolve`. */
235
+ attempt?(source: string, symbol: string, file?: string): ResolverAttempt;
236
+ resolve(source: string, symbol: string, file?: string): ResolvedSymbol | null;
208
237
  }
238
+ /** A resolved span, and which resolver produced it. */
239
+ type AnchorResolution = {
240
+ ok: true;
241
+ span: ResolvedSymbol;
242
+ resolver?: AnchorResolverName;
243
+ } | {
244
+ ok: false;
245
+ reason: AnchorUnresolvedReason;
246
+ };
209
247
  /** Why an anchor could not be compared. Never an error — always a finding. */
210
- type AnchorUnresolvedReason = "file-missing" | "symbol-not-found" | "outside-repo" | "file-too-large" | "file-unreadable"
248
+ type AnchorUnresolvedReason = "file-missing" | "symbol-not-found"
249
+ /** More than one definition carries the name, and guessing is not allowed. */
250
+ | "symbol-ambiguous"
251
+ /** The extension has a grammar, but it would not load. Never a throw. */
252
+ | "resolver-unavailable" | "outside-repo" | "file-too-large" | "file-unreadable"
211
253
  /** The remote could not be fetched, or `--offline` found nothing cached. */
212
254
  | "remote-unreachable"
213
255
  /** The anchor's `ref` is not on the remote any more. */
@@ -218,6 +260,12 @@ type AnchorUnresolvedReason = "file-missing" | "symbol-not-found" | "outside-rep
218
260
  | "ref-invalid"
219
261
  /** The anchor's `repo` is not a remote we will fetch from. */
220
262
  | "repo-invalid";
263
+ /**
264
+ * A hash that changed because a more precise resolver took over, not because
265
+ * the code did. Reported as drift so nothing is restamped silently, and
266
+ * accepted by `--rebaseline` like any other.
267
+ */
268
+ type AnchorDriftReason = "resolver-changed";
221
269
  /**
222
270
  * How a ref-pinned foreign anchor stands. `drifted-on-default` is the one a
223
271
  * working-tree anchor has no equivalent of: the evidence is still true at the
@@ -232,7 +280,9 @@ type KbAnchorDriftEntry = {
232
280
  currentHash?: string;
233
281
  /** `null` when the anchor recorded no `lines` — size unknown, not zero. */
234
282
  diffSize: number | null;
235
- reason?: AnchorUnresolvedReason;
283
+ reason?: AnchorUnresolvedReason | AnchorDriftReason;
284
+ /** Which resolver produced `currentHash`. Absent for a whole-file anchor. */
285
+ resolver?: AnchorResolverName;
236
286
  /** Set only when the anchor was resolved against another repository. */
237
287
  repo?: string;
238
288
  remoteState?: RemoteAnchorState;
@@ -282,7 +332,10 @@ declare function readRemoteAnchors(wants: readonly RemoteWant[], options?: Remot
282
332
 
283
333
  type AnchorDriftOptions = {
284
334
  repoRoot?: string;
335
+ /** Single resolver, no chain. Convenience for tests. */
285
336
  resolver?: AnchorResolver;
337
+ /** The chain, tried in order. Defaults to tree-sitter then regex. */
338
+ resolvers?: readonly AnchorResolver[];
286
339
  concurrency?: number;
287
340
  /** Test seam: replaces the disk reader. */
288
341
  reader?: AnchorFileReader;
@@ -325,6 +378,69 @@ declare function anchorFilePath(repoRoot: string, file: string): string | null;
325
378
  */
326
379
  declare function isCanonicalRepoUrl(value: string): boolean;
327
380
 
381
+ declare const grammarManifestSchema: z.ZodObject<{
382
+ webTreeSitter: z.ZodString;
383
+ linguist: z.ZodObject<{
384
+ tag: z.ZodString;
385
+ commit: z.ZodString;
386
+ }, z.core.$strip>;
387
+ packs: z.ZodRecord<z.ZodString, z.ZodObject<{
388
+ package: z.ZodString;
389
+ wasm: z.ZodObject<{
390
+ url: z.ZodString;
391
+ sha256: z.ZodString;
392
+ bytes: z.ZodNumber;
393
+ }, z.core.$strip>;
394
+ tags: z.ZodArray<z.ZodObject<{
395
+ url: z.ZodString;
396
+ sha256: z.ZodString;
397
+ }, z.core.$strip>>;
398
+ license: z.ZodString;
399
+ extensions: z.ZodArray<z.ZodString>;
400
+ }, z.core.$strip>>;
401
+ }, z.core.$strip>;
402
+ type GrammarManifest = z.infer<typeof grammarManifestSchema>;
403
+ /** A grammar and the query that runs over it, both verified, both on disk. */
404
+ type Grammar = {
405
+ /** Path to the cached WASM. */
406
+ wasm: string;
407
+ /** The pack's tags parts as one query, or `undefined` where it declares none. */
408
+ query: string | undefined;
409
+ };
410
+ /** Where a grammar comes from and whether it may be fetched at all. */
411
+ type GrammarOptions = {
412
+ /** Cache root; defaults to `STRAUSS_KB_GRAMMARS_DIR` then `~/.strauss/grammars`. */
413
+ cacheRoot?: string;
414
+ /** Replaces the scheme and host of every manifest URL. For tests and mirrors. */
415
+ baseUrl?: string;
416
+ /** Cache only, never the network — what `--offline` passes down. */
417
+ offline?: boolean;
418
+ fetchTimeoutMs?: number;
419
+ /** Where the download lines go. Defaults to stderr, never stdout. */
420
+ log?: (line: string) => void;
421
+ };
422
+
423
+ /**
424
+ * The shipped `grammars/manifest.json`: the URL, hash and extensions of every
425
+ * language pack. Read once per process.
426
+ */
427
+ declare function grammarManifest(): GrammarManifest;
428
+
429
+ /** Where downloaded grammars live. Overridable so a test never writes to `$HOME`. */
430
+ declare function grammarsCacheRoot(override?: string): string;
431
+
432
+ /**
433
+ * Both halves of a verified pack (cached WASM path, tags query text), each
434
+ * downloaded once. `null` on any refused, disabled or mismatched part is what
435
+ * the resolver reports as `resolver-unavailable`; a miss is not remembered.
436
+ */
437
+ declare function ensureGrammar(language: string, options?: GrammarOptions): Promise<Grammar | null>;
438
+ /**
439
+ * One line per grammar this process could not use, for the doctor and
440
+ * anchor-resolve reports. The only place a repair is spelled out.
441
+ */
442
+ declare function grammarHints(): string[];
443
+
328
444
  /**
329
445
  * v1 heuristic resolver. A dotted symbol like `OrderService.cancel` matches on
330
446
  * its last segment, with the parent used to scope the search: a candidate
@@ -348,6 +464,25 @@ declare function hashAnchorText(text: string): string;
348
464
  * whole-file anchor's `lines` one larger than the file.
349
465
  */
350
466
  declare function resolveAnchor(source: string, anchor: KbAnchor, resolver?: AnchorResolver): ResolvedSymbol | null;
467
+ /**
468
+ * Walks the resolver chain: tree-sitter, then regex, then a whole-file span
469
+ * when the anchor names no symbol.
470
+ *
471
+ * `symbol-not-found` falls through (a tags query defines functions and types,
472
+ * not constants or fields) and the anchor records the resolver that answered.
473
+ * `symbol-ambiguous` and `resolver-unavailable` end the chain: one would be
474
+ * settled by guessing, the other would trade a precise span for a guessed one.
475
+ */
476
+ declare function resolveAnchorSpan(source: string, anchor: KbAnchor, resolvers?: readonly AnchorResolver[]): AnchorResolution;
477
+ /** Loads every chained resolver's per-language assets, once. */
478
+ declare function prepareResolvers(resolvers: readonly AnchorResolver[], files: readonly string[]): Promise<void>;
479
+ /**
480
+ * The read-path chain. A fresh tree-sitter resolver per call, so its parse
481
+ * cache lives exactly as long as the run that owns it. `offline` rides down to
482
+ * grammar loading: a run that may not reach the network uses the cache or
483
+ * reports `resolver-unavailable`.
484
+ */
485
+ declare function defaultAnchorResolvers(grammars?: GrammarOptions): AnchorResolver[];
351
486
 
352
487
  /**
353
488
  * Why a matched record must not be read as a plain answer.
@@ -1237,6 +1372,59 @@ declare class KbInvalidConceptIdError extends BaseError {
1237
1372
  constructor(message: string, details: Record<string, string>);
1238
1373
  }
1239
1374
 
1375
+ /**
1376
+ * Grammar for a path, or `undefined` when the extension has none — or when the
1377
+ * pinned grammar release ships no tags query for it, so the regex heuristic
1378
+ * keeps those files, as before the resolver existed.
1379
+ */
1380
+ declare function languageForFile(file: string): string | undefined;
1381
+ /** Every language the resolver can resolve in: a grammar and a tags query. */
1382
+ declare function treeSitterLanguages(): string[];
1383
+
1384
+ type TreeSitterStats = {
1385
+ parses: number;
1386
+ cacheHits: number;
1387
+ };
1388
+ /** Where both halves of a pack come from, and whether they may be fetched. */
1389
+ type TreeSitterOptions = GrammarOptions;
1390
+ declare class TreeSitterResolver implements AnchorResolver {
1391
+ readonly name = "tree-sitter";
1392
+ private readonly grammars;
1393
+ private readonly loaded;
1394
+ private readonly trees;
1395
+ private parser;
1396
+ private initialized;
1397
+ /** Cache effectiveness, for tests and for the latency numbers. */
1398
+ readonly stats: TreeSitterStats;
1399
+ constructor(options?: TreeSitterOptions);
1400
+ /**
1401
+ * Loads the grammars these files need, once per language per process,
1402
+ * downloading each one on first use.
1403
+ *
1404
+ * A grammar that will not load is remembered as unavailable rather than
1405
+ * retried per anchor, and never throws: an unobtainable WASM is a finding.
1406
+ */
1407
+ prepare(files: readonly string[]): Promise<void>;
1408
+ /**
1409
+ * An unobtainable grammar, one this runtime refuses, and a query that will
1410
+ * not compile are three faults with three repairs; all are reported through
1411
+ * the grammars module so every hint has one home.
1412
+ */
1413
+ private load;
1414
+ /**
1415
+ * Abstains on an extension with no grammar so the regex resolver gets a
1416
+ * turn; reports `resolver-unavailable` when the grammar exists in principle
1417
+ * but could not be loaded, because falling back there would silently trade a
1418
+ * precise span for a guessed one.
1419
+ */
1420
+ attempt(source: string, symbol: string, file?: string): ResolverAttempt;
1421
+ resolve(source: string, symbol: string, file?: string): ResolvedSymbol | null;
1422
+ /** Parsed trees are keyed by content hash, so an unchanged file parses once. */
1423
+ private parse;
1424
+ /** Drops cached trees. Grammars stay loaded — they are immutable. */
1425
+ reset(): void;
1426
+ }
1427
+
1240
1428
  /**
1241
1429
  * What each record type is for, and the shape of its body.
1242
1430
  *
@@ -1334,6 +1522,10 @@ declare const composeInputSchema: z.ZodObject<{
1334
1522
  hash: z.ZodOptional<z.ZodString>;
1335
1523
  resolved_at: z.ZodOptional<z.ZodString>;
1336
1524
  lines: z.ZodOptional<z.ZodNumber>;
1525
+ resolver: z.ZodOptional<z.ZodEnum<{
1526
+ "tree-sitter": "tree-sitter";
1527
+ regex: "regex";
1528
+ }>>;
1337
1529
  }, z.core.$strict>>>;
1338
1530
  sources: z.ZodOptional<z.ZodArray<z.ZodObject<{
1339
1531
  id: z.ZodString;
@@ -1857,6 +2049,19 @@ type KbDoctorReport = {
1857
2049
  groups: KbDoctorGroup[];
1858
2050
  findingCount: number;
1859
2051
  healthy: boolean;
2052
+ /**
2053
+ * Anchors carrying a hash, by the resolver that produced it. A heuristic
2054
+ * span is weaker evidence than a parsed one, so a base still leaning on the
2055
+ * regex resolver is worth re-resolving. Not a finding: a regex-stamped
2056
+ * anchor is not broken.
2057
+ */
2058
+ anchorResolvers: KbAnchorResolverCounts;
2059
+ };
2060
+ type KbAnchorResolverCounts = {
2061
+ total: number;
2062
+ treeSitter: number;
2063
+ /** Includes anchors stamped before resolvers were named. */
2064
+ regex: number;
1860
2065
  };
1861
2066
  type KbDoctorOptions = {
1862
2067
  /** How far ahead `expiring` looks. */
@@ -1925,6 +2130,10 @@ declare const decisionInputSchema: z.ZodObject<{
1925
2130
  hash: z.ZodOptional<z.ZodString>;
1926
2131
  resolved_at: z.ZodOptional<z.ZodString>;
1927
2132
  lines: z.ZodOptional<z.ZodNumber>;
2133
+ resolver: z.ZodOptional<z.ZodEnum<{
2134
+ "tree-sitter": "tree-sitter";
2135
+ regex: "regex";
2136
+ }>>;
1928
2137
  }, z.core.$strict>>>;
1929
2138
  verify: z.ZodOptional<z.ZodArray<z.ZodString>>;
1930
2139
  relatedConceptIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -2176,4 +2385,4 @@ declare function parseMarkdownWithFrontmatter<S extends z.ZodType>(text: string,
2176
2385
  frontmatter: ReturnType<S["safeParse"]>;
2177
2386
  };
2178
2387
 
2179
- export { type AnchorResolver, BaseError, CONTEXT_BEGIN, CONTEXT_END, CONTEXT_PROFILES, type ComposeInput, type ComposeLink, type ComposedRecord, DECISION_TYPE, DEFAULT_AGING_DAYS, DEFAULT_EXPIRING_DAYS, DEFAULT_LOAD_BUDGET, DEFAULT_PACK_HOPS, DEFAULT_PACK_MAX_NODES, DEFAULT_TYPED_LINK_RELS, DEFAULT_UNVERIFIED_DAYS, type DecisionInput, type DiffFile, type DiffHunk, type DiffMatch, type ErrorDetails, type ErrorProps, ErrorTypes, Fault, INDEX_FILE, KB_CAUSAL_LINK_RELS, KB_COMMANDS, KB_COMMANDS_BY_NAME, KB_CONCEPT_ID_PATTERN, KB_CONFIDENCES, KB_DIR, KB_DOCTOR_CHECKS, KB_EDGE_KINDS, KB_LINK_RELS, KB_MATERIALITIES, KB_RECORD_STATUSES, KB_RECORD_TYPES, KB_SLUG_PATTERN, type KbActorStamp, type KbAdjudicated, type KbAnchor, type KbAnchorDriftEntry, type KbBacklink, type KbBacklinksResult, KbBaseFrozenError, type KbCatalogEntry, type KbCatalogResult, type KbCommand, type KbCommandContext, type KbContextBudgets, type KbContextOptions, type KbContextResult, type KbDoctorCheck, type KbDoctorFinding, type KbDoctorGroup, type KbDoctorOptions, type KbDoctorReport, type KbDoctorThresholds, type KbEdgeKind, type KbImpactOptions, type KbImpactResult, type KbImpactedRecord, type KbInboundEdge, KbInvalidConceptIdError, type KbLink, type KbLinkEdge, type KbLinkRel, type KbLinkRelSpec, type KbLoadResult, type KbLogEntry, type KbLogReadResult, type KbLogger, type KbMergedPin, type KbMergedPins, KbMissingFlagValueError, type KbNeighbour, KbPackBudgetExceededError, type KbPackOptions, type KbPackResult, type KbPackedRecord, type KbPin, type KbPinLayer, type KbPinOptions, type KbPinResult, type KbPinStatus, KbPinsMalformedError, type KbPinsManifest, type KbRecord, KbRecordAlreadyExistsError, type KbRecordFrontmatter, KbRecordNotFoundError, type KbRecordStatus, type KbRecordType, type KbRecordTypeSpec, type KbSearchLogger, KbSelfVerificationError, type KbSource, type KbStanding, KbStore, type KbSupersededStub, type KbSyncResult, type KbTraceEdge, type KbTraceOptions, type KbTraceStep, KbUnknownLinkRelError, type KbValidationProblem, type KbValidationSeverity, type KbVerifiedEvent, type KbWarning, KbWriteConflictError, type KbWriteInput, LINK_RELS, LOG_FILE, type MatchOptions, NO_DECISION_SLUG, PINS_FILE, PINS_LOCAL_FILE, PIN_LAYERS, type QmdModule, RECORD_TYPES, type RemoteAnchorState, type RemoteOptions, type RemoteRead, type ResolvedSymbol, SEARCH_INDEX_FILE, type SearchHit, type SearchOptions, type SymbolRange, TRACE_EDGES, adjudicate, anchorFilePath, assertBaseNotFrozen, backlinks, buildContext, catalog, composeDecisionRecord, composeInputSchema, composeLinkSchema, composeNoDecisionRecord, composeRecord, contextProfileBudgets, createKbMcpServer, decisionInputSchema, detectAnchorDrift, doctor, edgeNeighbours, hashAnchorText, impact, inboundIndex, indexIsStale, isCanonicalRepoUrl, isKbLinkRel, isKbRecordType, isNoDecisionRecord, kbActorStampSchema, kbAnchorSchema, kbConceptIdSchema, kbJsonSchemas, kbLinkSchema, kbLogEntrySchema, kbRecordFrontmatterSchema, kbSourceSchema, kbVerifiedEventSchema, listPins, loadQmd, matchToDiff, mergedContextBudgets, neighbours, pack, parseLog, parseMarkdownWithFrontmatter, pinBase, readMergedPins, readPinsLayer, readRemoteAnchors, regexResolver, renderCatalogLine, renderIndex, renderIndexLine, renderLogEntry, repoCacheDir, resolveAnchor, resolveHeads, resolveHits, resolvePinPath, runKbCli, runKbMcpServer, searchBase, selectDecisions, splitMarkdownFrontmatter, stringifyMarkdownWithFrontmatter, syncInstructions, toHookJson, trace, unpinBase, validateBundle };
2388
+ export { type AnchorResolution, type AnchorResolver, type AnchorResolverName, BaseError, CONTEXT_BEGIN, CONTEXT_END, CONTEXT_PROFILES, type ComposeInput, type ComposeLink, type ComposedRecord, DECISION_TYPE, DEFAULT_AGING_DAYS, DEFAULT_EXPIRING_DAYS, DEFAULT_LOAD_BUDGET, DEFAULT_PACK_HOPS, DEFAULT_PACK_MAX_NODES, DEFAULT_TYPED_LINK_RELS, DEFAULT_UNVERIFIED_DAYS, type DecisionInput, type DiffFile, type DiffHunk, type DiffMatch, type ErrorDetails, type ErrorProps, ErrorTypes, Fault, type Grammar, type GrammarManifest, type GrammarOptions, INDEX_FILE, KB_CAUSAL_LINK_RELS, KB_COMMANDS, KB_COMMANDS_BY_NAME, KB_CONCEPT_ID_PATTERN, KB_CONFIDENCES, KB_DIR, KB_DOCTOR_CHECKS, KB_EDGE_KINDS, KB_LINK_RELS, KB_MATERIALITIES, KB_RECORD_STATUSES, KB_RECORD_TYPES, KB_SLUG_PATTERN, type KbActorStamp, type KbAdjudicated, type KbAnchor, type KbAnchorDriftEntry, type KbBacklink, type KbBacklinksResult, KbBaseFrozenError, type KbCatalogEntry, type KbCatalogResult, type KbCommand, type KbCommandContext, type KbContextBudgets, type KbContextOptions, type KbContextResult, type KbDoctorCheck, type KbDoctorFinding, type KbDoctorGroup, type KbDoctorOptions, type KbDoctorReport, type KbDoctorThresholds, type KbEdgeKind, type KbImpactOptions, type KbImpactResult, type KbImpactedRecord, type KbInboundEdge, KbInvalidConceptIdError, type KbLink, type KbLinkEdge, type KbLinkRel, type KbLinkRelSpec, type KbLoadResult, type KbLogEntry, type KbLogReadResult, type KbLogger, type KbMergedPin, type KbMergedPins, KbMissingFlagValueError, type KbNeighbour, KbPackBudgetExceededError, type KbPackOptions, type KbPackResult, type KbPackedRecord, type KbPin, type KbPinLayer, type KbPinOptions, type KbPinResult, type KbPinStatus, KbPinsMalformedError, type KbPinsManifest, type KbRecord, KbRecordAlreadyExistsError, type KbRecordFrontmatter, KbRecordNotFoundError, type KbRecordStatus, type KbRecordType, type KbRecordTypeSpec, type KbSearchLogger, KbSelfVerificationError, type KbSource, type KbStanding, KbStore, type KbSupersededStub, type KbSyncResult, type KbTraceEdge, type KbTraceOptions, type KbTraceStep, KbUnknownLinkRelError, type KbValidationProblem, type KbValidationSeverity, type KbVerifiedEvent, type KbWarning, KbWriteConflictError, type KbWriteInput, LINK_RELS, LOG_FILE, type MatchOptions, NO_DECISION_SLUG, PINS_FILE, PINS_LOCAL_FILE, PIN_LAYERS, type QmdModule, RECORD_TYPES, type RemoteAnchorState, type RemoteOptions, type RemoteRead, type ResolvedSymbol, type ResolverAttempt, SEARCH_INDEX_FILE, type SearchHit, type SearchOptions, type SymbolRange, TRACE_EDGES, TreeSitterResolver, adjudicate, anchorFilePath, assertBaseNotFrozen, backlinks, buildContext, catalog, composeDecisionRecord, composeInputSchema, composeLinkSchema, composeNoDecisionRecord, composeRecord, contextProfileBudgets, createKbMcpServer, decisionInputSchema, defaultAnchorResolvers, detectAnchorDrift, doctor, edgeNeighbours, ensureGrammar, grammarHints, grammarManifest, grammarsCacheRoot, hashAnchorText, impact, inboundIndex, indexIsStale, isCanonicalRepoUrl, isKbLinkRel, isKbRecordType, isNoDecisionRecord, kbActorStampSchema, kbAnchorSchema, kbConceptIdSchema, kbJsonSchemas, kbLinkSchema, kbLogEntrySchema, kbRecordFrontmatterSchema, kbSourceSchema, kbVerifiedEventSchema, languageForFile, listPins, loadQmd, matchToDiff, mergedContextBudgets, neighbours, pack, parseLog, parseMarkdownWithFrontmatter, pinBase, prepareResolvers, readMergedPins, readPinsLayer, readRemoteAnchors, regexResolver, renderCatalogLine, renderIndex, renderIndexLine, renderLogEntry, repoCacheDir, resolveAnchor, resolveAnchorSpan, resolveHeads, resolveHits, resolvePinPath, runKbCli, runKbMcpServer, searchBase, selectDecisions, splitMarkdownFrontmatter, stringifyMarkdownWithFrontmatter, syncInstructions, toHookJson, trace, treeSitterLanguages, unpinBase, validateBundle };
package/dist/index.d.ts CHANGED
@@ -48,7 +48,7 @@ declare const kbVerifiedEventSchema: z.ZodObject<{
48
48
  * Symbolic on purpose. These are written while the code is still moving: a
49
49
  * `line: 379` recorded at minute five is wrong by minute forty, but
50
50
  * `OrderService.cancel` survives every edit that does not rename it. Once the
51
- * change settles, a resolution pass (`anchor-resolver.ts`) stamps `hash`,
51
+ * change settles, a resolution pass (`anchor-resolver/`) stamps `hash`,
52
52
  * `resolved_at`, and `lines`; drift detection later re-resolves and compares.
53
53
  *
54
54
  * `hash` is prefixed with the algorithm so a future one can coexist with
@@ -70,6 +70,10 @@ declare const kbAnchorSchema: z.ZodObject<{
70
70
  hash: z.ZodOptional<z.ZodString>;
71
71
  resolved_at: z.ZodOptional<z.ZodString>;
72
72
  lines: z.ZodOptional<z.ZodNumber>;
73
+ resolver: z.ZodOptional<z.ZodEnum<{
74
+ "tree-sitter": "tree-sitter";
75
+ regex: "regex";
76
+ }>>;
73
77
  }, z.core.$strict>;
74
78
  /**
75
79
  * One typed causal edge, as the frontmatter stores it.
@@ -140,6 +144,10 @@ declare const kbRecordFrontmatterSchema: z.ZodObject<{
140
144
  hash: z.ZodOptional<z.ZodString>;
141
145
  resolved_at: z.ZodOptional<z.ZodString>;
142
146
  lines: z.ZodOptional<z.ZodNumber>;
147
+ resolver: z.ZodOptional<z.ZodEnum<{
148
+ "tree-sitter": "tree-sitter";
149
+ regex: "regex";
150
+ }>>;
143
151
  }, z.core.$strict>>>;
144
152
  strauss_verify: z.ZodOptional<z.ZodArray<z.ZodString>>;
145
153
  strauss_links: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -202,12 +210,46 @@ type ResolvedSymbol = {
202
210
  startLine: number;
203
211
  endLine: number;
204
212
  };
213
+ /** Which resolver produced a span. Stamped on the anchor. */
214
+ type AnchorResolverName = "tree-sitter" | "regex";
215
+ /**
216
+ * A resolver's verdict. `abstain` ("not my language") and `symbol-not-found`
217
+ * ("nothing I recognize declares this") both pass the symbol down the chain;
218
+ * `symbol-ambiguous` and `resolver-unavailable` end it, because neither may be
219
+ * answered by a looser resolver guessing.
220
+ */
221
+ type ResolverAttempt = {
222
+ kind: "resolved";
223
+ span: ResolvedSymbol;
224
+ } | {
225
+ kind: "unresolved";
226
+ reason: "symbol-not-found" | "symbol-ambiguous" | "resolver-unavailable";
227
+ } | {
228
+ kind: "abstain";
229
+ };
205
230
  interface AnchorResolver {
206
231
  name: string;
207
- resolve(source: string, symbol: string): ResolvedSymbol | null;
232
+ /** Loads whatever these files need, before any `resolve` call. Optional. */
233
+ prepare?(files: readonly string[]): Promise<void>;
234
+ /** The richer verdict the chain uses; defaults to `resolve`. */
235
+ attempt?(source: string, symbol: string, file?: string): ResolverAttempt;
236
+ resolve(source: string, symbol: string, file?: string): ResolvedSymbol | null;
208
237
  }
238
+ /** A resolved span, and which resolver produced it. */
239
+ type AnchorResolution = {
240
+ ok: true;
241
+ span: ResolvedSymbol;
242
+ resolver?: AnchorResolverName;
243
+ } | {
244
+ ok: false;
245
+ reason: AnchorUnresolvedReason;
246
+ };
209
247
  /** Why an anchor could not be compared. Never an error — always a finding. */
210
- type AnchorUnresolvedReason = "file-missing" | "symbol-not-found" | "outside-repo" | "file-too-large" | "file-unreadable"
248
+ type AnchorUnresolvedReason = "file-missing" | "symbol-not-found"
249
+ /** More than one definition carries the name, and guessing is not allowed. */
250
+ | "symbol-ambiguous"
251
+ /** The extension has a grammar, but it would not load. Never a throw. */
252
+ | "resolver-unavailable" | "outside-repo" | "file-too-large" | "file-unreadable"
211
253
  /** The remote could not be fetched, or `--offline` found nothing cached. */
212
254
  | "remote-unreachable"
213
255
  /** The anchor's `ref` is not on the remote any more. */
@@ -218,6 +260,12 @@ type AnchorUnresolvedReason = "file-missing" | "symbol-not-found" | "outside-rep
218
260
  | "ref-invalid"
219
261
  /** The anchor's `repo` is not a remote we will fetch from. */
220
262
  | "repo-invalid";
263
+ /**
264
+ * A hash that changed because a more precise resolver took over, not because
265
+ * the code did. Reported as drift so nothing is restamped silently, and
266
+ * accepted by `--rebaseline` like any other.
267
+ */
268
+ type AnchorDriftReason = "resolver-changed";
221
269
  /**
222
270
  * How a ref-pinned foreign anchor stands. `drifted-on-default` is the one a
223
271
  * working-tree anchor has no equivalent of: the evidence is still true at the
@@ -232,7 +280,9 @@ type KbAnchorDriftEntry = {
232
280
  currentHash?: string;
233
281
  /** `null` when the anchor recorded no `lines` — size unknown, not zero. */
234
282
  diffSize: number | null;
235
- reason?: AnchorUnresolvedReason;
283
+ reason?: AnchorUnresolvedReason | AnchorDriftReason;
284
+ /** Which resolver produced `currentHash`. Absent for a whole-file anchor. */
285
+ resolver?: AnchorResolverName;
236
286
  /** Set only when the anchor was resolved against another repository. */
237
287
  repo?: string;
238
288
  remoteState?: RemoteAnchorState;
@@ -282,7 +332,10 @@ declare function readRemoteAnchors(wants: readonly RemoteWant[], options?: Remot
282
332
 
283
333
  type AnchorDriftOptions = {
284
334
  repoRoot?: string;
335
+ /** Single resolver, no chain. Convenience for tests. */
285
336
  resolver?: AnchorResolver;
337
+ /** The chain, tried in order. Defaults to tree-sitter then regex. */
338
+ resolvers?: readonly AnchorResolver[];
286
339
  concurrency?: number;
287
340
  /** Test seam: replaces the disk reader. */
288
341
  reader?: AnchorFileReader;
@@ -325,6 +378,69 @@ declare function anchorFilePath(repoRoot: string, file: string): string | null;
325
378
  */
326
379
  declare function isCanonicalRepoUrl(value: string): boolean;
327
380
 
381
+ declare const grammarManifestSchema: z.ZodObject<{
382
+ webTreeSitter: z.ZodString;
383
+ linguist: z.ZodObject<{
384
+ tag: z.ZodString;
385
+ commit: z.ZodString;
386
+ }, z.core.$strip>;
387
+ packs: z.ZodRecord<z.ZodString, z.ZodObject<{
388
+ package: z.ZodString;
389
+ wasm: z.ZodObject<{
390
+ url: z.ZodString;
391
+ sha256: z.ZodString;
392
+ bytes: z.ZodNumber;
393
+ }, z.core.$strip>;
394
+ tags: z.ZodArray<z.ZodObject<{
395
+ url: z.ZodString;
396
+ sha256: z.ZodString;
397
+ }, z.core.$strip>>;
398
+ license: z.ZodString;
399
+ extensions: z.ZodArray<z.ZodString>;
400
+ }, z.core.$strip>>;
401
+ }, z.core.$strip>;
402
+ type GrammarManifest = z.infer<typeof grammarManifestSchema>;
403
+ /** A grammar and the query that runs over it, both verified, both on disk. */
404
+ type Grammar = {
405
+ /** Path to the cached WASM. */
406
+ wasm: string;
407
+ /** The pack's tags parts as one query, or `undefined` where it declares none. */
408
+ query: string | undefined;
409
+ };
410
+ /** Where a grammar comes from and whether it may be fetched at all. */
411
+ type GrammarOptions = {
412
+ /** Cache root; defaults to `STRAUSS_KB_GRAMMARS_DIR` then `~/.strauss/grammars`. */
413
+ cacheRoot?: string;
414
+ /** Replaces the scheme and host of every manifest URL. For tests and mirrors. */
415
+ baseUrl?: string;
416
+ /** Cache only, never the network — what `--offline` passes down. */
417
+ offline?: boolean;
418
+ fetchTimeoutMs?: number;
419
+ /** Where the download lines go. Defaults to stderr, never stdout. */
420
+ log?: (line: string) => void;
421
+ };
422
+
423
+ /**
424
+ * The shipped `grammars/manifest.json`: the URL, hash and extensions of every
425
+ * language pack. Read once per process.
426
+ */
427
+ declare function grammarManifest(): GrammarManifest;
428
+
429
+ /** Where downloaded grammars live. Overridable so a test never writes to `$HOME`. */
430
+ declare function grammarsCacheRoot(override?: string): string;
431
+
432
+ /**
433
+ * Both halves of a verified pack (cached WASM path, tags query text), each
434
+ * downloaded once. `null` on any refused, disabled or mismatched part is what
435
+ * the resolver reports as `resolver-unavailable`; a miss is not remembered.
436
+ */
437
+ declare function ensureGrammar(language: string, options?: GrammarOptions): Promise<Grammar | null>;
438
+ /**
439
+ * One line per grammar this process could not use, for the doctor and
440
+ * anchor-resolve reports. The only place a repair is spelled out.
441
+ */
442
+ declare function grammarHints(): string[];
443
+
328
444
  /**
329
445
  * v1 heuristic resolver. A dotted symbol like `OrderService.cancel` matches on
330
446
  * its last segment, with the parent used to scope the search: a candidate
@@ -348,6 +464,25 @@ declare function hashAnchorText(text: string): string;
348
464
  * whole-file anchor's `lines` one larger than the file.
349
465
  */
350
466
  declare function resolveAnchor(source: string, anchor: KbAnchor, resolver?: AnchorResolver): ResolvedSymbol | null;
467
+ /**
468
+ * Walks the resolver chain: tree-sitter, then regex, then a whole-file span
469
+ * when the anchor names no symbol.
470
+ *
471
+ * `symbol-not-found` falls through (a tags query defines functions and types,
472
+ * not constants or fields) and the anchor records the resolver that answered.
473
+ * `symbol-ambiguous` and `resolver-unavailable` end the chain: one would be
474
+ * settled by guessing, the other would trade a precise span for a guessed one.
475
+ */
476
+ declare function resolveAnchorSpan(source: string, anchor: KbAnchor, resolvers?: readonly AnchorResolver[]): AnchorResolution;
477
+ /** Loads every chained resolver's per-language assets, once. */
478
+ declare function prepareResolvers(resolvers: readonly AnchorResolver[], files: readonly string[]): Promise<void>;
479
+ /**
480
+ * The read-path chain. A fresh tree-sitter resolver per call, so its parse
481
+ * cache lives exactly as long as the run that owns it. `offline` rides down to
482
+ * grammar loading: a run that may not reach the network uses the cache or
483
+ * reports `resolver-unavailable`.
484
+ */
485
+ declare function defaultAnchorResolvers(grammars?: GrammarOptions): AnchorResolver[];
351
486
 
352
487
  /**
353
488
  * Why a matched record must not be read as a plain answer.
@@ -1237,6 +1372,59 @@ declare class KbInvalidConceptIdError extends BaseError {
1237
1372
  constructor(message: string, details: Record<string, string>);
1238
1373
  }
1239
1374
 
1375
+ /**
1376
+ * Grammar for a path, or `undefined` when the extension has none — or when the
1377
+ * pinned grammar release ships no tags query for it, so the regex heuristic
1378
+ * keeps those files, as before the resolver existed.
1379
+ */
1380
+ declare function languageForFile(file: string): string | undefined;
1381
+ /** Every language the resolver can resolve in: a grammar and a tags query. */
1382
+ declare function treeSitterLanguages(): string[];
1383
+
1384
+ type TreeSitterStats = {
1385
+ parses: number;
1386
+ cacheHits: number;
1387
+ };
1388
+ /** Where both halves of a pack come from, and whether they may be fetched. */
1389
+ type TreeSitterOptions = GrammarOptions;
1390
+ declare class TreeSitterResolver implements AnchorResolver {
1391
+ readonly name = "tree-sitter";
1392
+ private readonly grammars;
1393
+ private readonly loaded;
1394
+ private readonly trees;
1395
+ private parser;
1396
+ private initialized;
1397
+ /** Cache effectiveness, for tests and for the latency numbers. */
1398
+ readonly stats: TreeSitterStats;
1399
+ constructor(options?: TreeSitterOptions);
1400
+ /**
1401
+ * Loads the grammars these files need, once per language per process,
1402
+ * downloading each one on first use.
1403
+ *
1404
+ * A grammar that will not load is remembered as unavailable rather than
1405
+ * retried per anchor, and never throws: an unobtainable WASM is a finding.
1406
+ */
1407
+ prepare(files: readonly string[]): Promise<void>;
1408
+ /**
1409
+ * An unobtainable grammar, one this runtime refuses, and a query that will
1410
+ * not compile are three faults with three repairs; all are reported through
1411
+ * the grammars module so every hint has one home.
1412
+ */
1413
+ private load;
1414
+ /**
1415
+ * Abstains on an extension with no grammar so the regex resolver gets a
1416
+ * turn; reports `resolver-unavailable` when the grammar exists in principle
1417
+ * but could not be loaded, because falling back there would silently trade a
1418
+ * precise span for a guessed one.
1419
+ */
1420
+ attempt(source: string, symbol: string, file?: string): ResolverAttempt;
1421
+ resolve(source: string, symbol: string, file?: string): ResolvedSymbol | null;
1422
+ /** Parsed trees are keyed by content hash, so an unchanged file parses once. */
1423
+ private parse;
1424
+ /** Drops cached trees. Grammars stay loaded — they are immutable. */
1425
+ reset(): void;
1426
+ }
1427
+
1240
1428
  /**
1241
1429
  * What each record type is for, and the shape of its body.
1242
1430
  *
@@ -1334,6 +1522,10 @@ declare const composeInputSchema: z.ZodObject<{
1334
1522
  hash: z.ZodOptional<z.ZodString>;
1335
1523
  resolved_at: z.ZodOptional<z.ZodString>;
1336
1524
  lines: z.ZodOptional<z.ZodNumber>;
1525
+ resolver: z.ZodOptional<z.ZodEnum<{
1526
+ "tree-sitter": "tree-sitter";
1527
+ regex: "regex";
1528
+ }>>;
1337
1529
  }, z.core.$strict>>>;
1338
1530
  sources: z.ZodOptional<z.ZodArray<z.ZodObject<{
1339
1531
  id: z.ZodString;
@@ -1857,6 +2049,19 @@ type KbDoctorReport = {
1857
2049
  groups: KbDoctorGroup[];
1858
2050
  findingCount: number;
1859
2051
  healthy: boolean;
2052
+ /**
2053
+ * Anchors carrying a hash, by the resolver that produced it. A heuristic
2054
+ * span is weaker evidence than a parsed one, so a base still leaning on the
2055
+ * regex resolver is worth re-resolving. Not a finding: a regex-stamped
2056
+ * anchor is not broken.
2057
+ */
2058
+ anchorResolvers: KbAnchorResolverCounts;
2059
+ };
2060
+ type KbAnchorResolverCounts = {
2061
+ total: number;
2062
+ treeSitter: number;
2063
+ /** Includes anchors stamped before resolvers were named. */
2064
+ regex: number;
1860
2065
  };
1861
2066
  type KbDoctorOptions = {
1862
2067
  /** How far ahead `expiring` looks. */
@@ -1925,6 +2130,10 @@ declare const decisionInputSchema: z.ZodObject<{
1925
2130
  hash: z.ZodOptional<z.ZodString>;
1926
2131
  resolved_at: z.ZodOptional<z.ZodString>;
1927
2132
  lines: z.ZodOptional<z.ZodNumber>;
2133
+ resolver: z.ZodOptional<z.ZodEnum<{
2134
+ "tree-sitter": "tree-sitter";
2135
+ regex: "regex";
2136
+ }>>;
1928
2137
  }, z.core.$strict>>>;
1929
2138
  verify: z.ZodOptional<z.ZodArray<z.ZodString>>;
1930
2139
  relatedConceptIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -2176,4 +2385,4 @@ declare function parseMarkdownWithFrontmatter<S extends z.ZodType>(text: string,
2176
2385
  frontmatter: ReturnType<S["safeParse"]>;
2177
2386
  };
2178
2387
 
2179
- export { type AnchorResolver, BaseError, CONTEXT_BEGIN, CONTEXT_END, CONTEXT_PROFILES, type ComposeInput, type ComposeLink, type ComposedRecord, DECISION_TYPE, DEFAULT_AGING_DAYS, DEFAULT_EXPIRING_DAYS, DEFAULT_LOAD_BUDGET, DEFAULT_PACK_HOPS, DEFAULT_PACK_MAX_NODES, DEFAULT_TYPED_LINK_RELS, DEFAULT_UNVERIFIED_DAYS, type DecisionInput, type DiffFile, type DiffHunk, type DiffMatch, type ErrorDetails, type ErrorProps, ErrorTypes, Fault, INDEX_FILE, KB_CAUSAL_LINK_RELS, KB_COMMANDS, KB_COMMANDS_BY_NAME, KB_CONCEPT_ID_PATTERN, KB_CONFIDENCES, KB_DIR, KB_DOCTOR_CHECKS, KB_EDGE_KINDS, KB_LINK_RELS, KB_MATERIALITIES, KB_RECORD_STATUSES, KB_RECORD_TYPES, KB_SLUG_PATTERN, type KbActorStamp, type KbAdjudicated, type KbAnchor, type KbAnchorDriftEntry, type KbBacklink, type KbBacklinksResult, KbBaseFrozenError, type KbCatalogEntry, type KbCatalogResult, type KbCommand, type KbCommandContext, type KbContextBudgets, type KbContextOptions, type KbContextResult, type KbDoctorCheck, type KbDoctorFinding, type KbDoctorGroup, type KbDoctorOptions, type KbDoctorReport, type KbDoctorThresholds, type KbEdgeKind, type KbImpactOptions, type KbImpactResult, type KbImpactedRecord, type KbInboundEdge, KbInvalidConceptIdError, type KbLink, type KbLinkEdge, type KbLinkRel, type KbLinkRelSpec, type KbLoadResult, type KbLogEntry, type KbLogReadResult, type KbLogger, type KbMergedPin, type KbMergedPins, KbMissingFlagValueError, type KbNeighbour, KbPackBudgetExceededError, type KbPackOptions, type KbPackResult, type KbPackedRecord, type KbPin, type KbPinLayer, type KbPinOptions, type KbPinResult, type KbPinStatus, KbPinsMalformedError, type KbPinsManifest, type KbRecord, KbRecordAlreadyExistsError, type KbRecordFrontmatter, KbRecordNotFoundError, type KbRecordStatus, type KbRecordType, type KbRecordTypeSpec, type KbSearchLogger, KbSelfVerificationError, type KbSource, type KbStanding, KbStore, type KbSupersededStub, type KbSyncResult, type KbTraceEdge, type KbTraceOptions, type KbTraceStep, KbUnknownLinkRelError, type KbValidationProblem, type KbValidationSeverity, type KbVerifiedEvent, type KbWarning, KbWriteConflictError, type KbWriteInput, LINK_RELS, LOG_FILE, type MatchOptions, NO_DECISION_SLUG, PINS_FILE, PINS_LOCAL_FILE, PIN_LAYERS, type QmdModule, RECORD_TYPES, type RemoteAnchorState, type RemoteOptions, type RemoteRead, type ResolvedSymbol, SEARCH_INDEX_FILE, type SearchHit, type SearchOptions, type SymbolRange, TRACE_EDGES, adjudicate, anchorFilePath, assertBaseNotFrozen, backlinks, buildContext, catalog, composeDecisionRecord, composeInputSchema, composeLinkSchema, composeNoDecisionRecord, composeRecord, contextProfileBudgets, createKbMcpServer, decisionInputSchema, detectAnchorDrift, doctor, edgeNeighbours, hashAnchorText, impact, inboundIndex, indexIsStale, isCanonicalRepoUrl, isKbLinkRel, isKbRecordType, isNoDecisionRecord, kbActorStampSchema, kbAnchorSchema, kbConceptIdSchema, kbJsonSchemas, kbLinkSchema, kbLogEntrySchema, kbRecordFrontmatterSchema, kbSourceSchema, kbVerifiedEventSchema, listPins, loadQmd, matchToDiff, mergedContextBudgets, neighbours, pack, parseLog, parseMarkdownWithFrontmatter, pinBase, readMergedPins, readPinsLayer, readRemoteAnchors, regexResolver, renderCatalogLine, renderIndex, renderIndexLine, renderLogEntry, repoCacheDir, resolveAnchor, resolveHeads, resolveHits, resolvePinPath, runKbCli, runKbMcpServer, searchBase, selectDecisions, splitMarkdownFrontmatter, stringifyMarkdownWithFrontmatter, syncInstructions, toHookJson, trace, unpinBase, validateBundle };
2388
+ export { type AnchorResolution, type AnchorResolver, type AnchorResolverName, BaseError, CONTEXT_BEGIN, CONTEXT_END, CONTEXT_PROFILES, type ComposeInput, type ComposeLink, type ComposedRecord, DECISION_TYPE, DEFAULT_AGING_DAYS, DEFAULT_EXPIRING_DAYS, DEFAULT_LOAD_BUDGET, DEFAULT_PACK_HOPS, DEFAULT_PACK_MAX_NODES, DEFAULT_TYPED_LINK_RELS, DEFAULT_UNVERIFIED_DAYS, type DecisionInput, type DiffFile, type DiffHunk, type DiffMatch, type ErrorDetails, type ErrorProps, ErrorTypes, Fault, type Grammar, type GrammarManifest, type GrammarOptions, INDEX_FILE, KB_CAUSAL_LINK_RELS, KB_COMMANDS, KB_COMMANDS_BY_NAME, KB_CONCEPT_ID_PATTERN, KB_CONFIDENCES, KB_DIR, KB_DOCTOR_CHECKS, KB_EDGE_KINDS, KB_LINK_RELS, KB_MATERIALITIES, KB_RECORD_STATUSES, KB_RECORD_TYPES, KB_SLUG_PATTERN, type KbActorStamp, type KbAdjudicated, type KbAnchor, type KbAnchorDriftEntry, type KbBacklink, type KbBacklinksResult, KbBaseFrozenError, type KbCatalogEntry, type KbCatalogResult, type KbCommand, type KbCommandContext, type KbContextBudgets, type KbContextOptions, type KbContextResult, type KbDoctorCheck, type KbDoctorFinding, type KbDoctorGroup, type KbDoctorOptions, type KbDoctorReport, type KbDoctorThresholds, type KbEdgeKind, type KbImpactOptions, type KbImpactResult, type KbImpactedRecord, type KbInboundEdge, KbInvalidConceptIdError, type KbLink, type KbLinkEdge, type KbLinkRel, type KbLinkRelSpec, type KbLoadResult, type KbLogEntry, type KbLogReadResult, type KbLogger, type KbMergedPin, type KbMergedPins, KbMissingFlagValueError, type KbNeighbour, KbPackBudgetExceededError, type KbPackOptions, type KbPackResult, type KbPackedRecord, type KbPin, type KbPinLayer, type KbPinOptions, type KbPinResult, type KbPinStatus, KbPinsMalformedError, type KbPinsManifest, type KbRecord, KbRecordAlreadyExistsError, type KbRecordFrontmatter, KbRecordNotFoundError, type KbRecordStatus, type KbRecordType, type KbRecordTypeSpec, type KbSearchLogger, KbSelfVerificationError, type KbSource, type KbStanding, KbStore, type KbSupersededStub, type KbSyncResult, type KbTraceEdge, type KbTraceOptions, type KbTraceStep, KbUnknownLinkRelError, type KbValidationProblem, type KbValidationSeverity, type KbVerifiedEvent, type KbWarning, KbWriteConflictError, type KbWriteInput, LINK_RELS, LOG_FILE, type MatchOptions, NO_DECISION_SLUG, PINS_FILE, PINS_LOCAL_FILE, PIN_LAYERS, type QmdModule, RECORD_TYPES, type RemoteAnchorState, type RemoteOptions, type RemoteRead, type ResolvedSymbol, type ResolverAttempt, SEARCH_INDEX_FILE, type SearchHit, type SearchOptions, type SymbolRange, TRACE_EDGES, TreeSitterResolver, adjudicate, anchorFilePath, assertBaseNotFrozen, backlinks, buildContext, catalog, composeDecisionRecord, composeInputSchema, composeLinkSchema, composeNoDecisionRecord, composeRecord, contextProfileBudgets, createKbMcpServer, decisionInputSchema, defaultAnchorResolvers, detectAnchorDrift, doctor, edgeNeighbours, ensureGrammar, grammarHints, grammarManifest, grammarsCacheRoot, hashAnchorText, impact, inboundIndex, indexIsStale, isCanonicalRepoUrl, isKbLinkRel, isKbRecordType, isNoDecisionRecord, kbActorStampSchema, kbAnchorSchema, kbConceptIdSchema, kbJsonSchemas, kbLinkSchema, kbLogEntrySchema, kbRecordFrontmatterSchema, kbSourceSchema, kbVerifiedEventSchema, languageForFile, listPins, loadQmd, matchToDiff, mergedContextBudgets, neighbours, pack, parseLog, parseMarkdownWithFrontmatter, pinBase, prepareResolvers, readMergedPins, readPinsLayer, readRemoteAnchors, regexResolver, renderCatalogLine, renderIndex, renderIndexLine, renderLogEntry, repoCacheDir, resolveAnchor, resolveAnchorSpan, resolveHeads, resolveHits, resolvePinPath, runKbCli, runKbMcpServer, searchBase, selectDecisions, splitMarkdownFrontmatter, stringifyMarkdownWithFrontmatter, syncInstructions, toHookJson, trace, treeSitterLanguages, unpinBase, validateBundle };