@saasontools/strauss-kb 0.1.19 → 0.1.20
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/ARCHITECTURE.md +5 -5
- package/README.md +11 -4
- package/dist/{chunk-ZWSCLHG6.js → chunk-EXZQZJU2.js} +2 -2
- package/dist/{chunk-MNQNHYWL.js → chunk-QQLPJO4R.js} +2781 -957
- package/dist/chunk-QQLPJO4R.js.map +1 -0
- package/dist/{chunk-CQBLH7CE.js → chunk-XDH6J6CH.js} +2 -2
- package/dist/cli-main.cjs +2783 -994
- package/dist/cli-main.cjs.map +1 -1
- package/dist/cli-main.js +2 -2
- package/dist/index.cjs +2149 -394
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +470 -96
- package/dist/index.d.ts +470 -96
- package/dist/index.js +38 -83
- package/dist/index.js.map +1 -1
- package/dist/mcp-main.cjs +2779 -990
- package/dist/mcp-main.cjs.map +1 -1
- package/dist/mcp-main.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-MNQNHYWL.js.map +0 -1
- /package/dist/{chunk-ZWSCLHG6.js.map → chunk-EXZQZJU2.js.map} +0 -0
- /package/dist/{chunk-CQBLH7CE.js.map → chunk-XDH6J6CH.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -62,9 +62,58 @@ declare const kbVerifiedEventSchema: z.ZodObject<{
|
|
|
62
62
|
* independent of each other, so every anchor written before they existed stays
|
|
63
63
|
* valid.
|
|
64
64
|
*/
|
|
65
|
+
/**
|
|
66
|
+
* An explicit line range, 1-based and inclusive. Author-owned: a resolver
|
|
67
|
+
* hashes it but never moves it.
|
|
68
|
+
*/
|
|
69
|
+
declare const kbAnchorSpanSchema: z.ZodObject<{
|
|
70
|
+
start: z.ZodNumber;
|
|
71
|
+
end: z.ZodNumber;
|
|
72
|
+
}, z.core.$strict>;
|
|
65
73
|
declare const kbAnchorSchema: z.ZodObject<{
|
|
66
74
|
file: z.ZodString;
|
|
67
75
|
symbol: z.ZodOptional<z.ZodString>;
|
|
76
|
+
span: z.ZodOptional<z.ZodObject<{
|
|
77
|
+
start: z.ZodNumber;
|
|
78
|
+
end: z.ZodNumber;
|
|
79
|
+
}, z.core.$strict>>;
|
|
80
|
+
side: z.ZodOptional<z.ZodEnum<{
|
|
81
|
+
old: "old";
|
|
82
|
+
new: "new";
|
|
83
|
+
}>>;
|
|
84
|
+
repo: z.ZodOptional<z.ZodString>;
|
|
85
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
86
|
+
hash: z.ZodOptional<z.ZodString>;
|
|
87
|
+
hash_kind: z.ZodOptional<z.ZodEnum<{
|
|
88
|
+
raw: "raw";
|
|
89
|
+
ast: "ast";
|
|
90
|
+
}>>;
|
|
91
|
+
resolved_at: z.ZodOptional<z.ZodString>;
|
|
92
|
+
lines: z.ZodOptional<z.ZodNumber>;
|
|
93
|
+
resolver: z.ZodOptional<z.ZodEnum<{
|
|
94
|
+
span: "span";
|
|
95
|
+
"tree-sitter": "tree-sitter";
|
|
96
|
+
regex: "regex";
|
|
97
|
+
}>>;
|
|
98
|
+
}, z.core.$strict>;
|
|
99
|
+
/**
|
|
100
|
+
* The anchor rules a resolver cannot settle for itself.
|
|
101
|
+
*
|
|
102
|
+
* Write-side only, like `kbVerifiedEventSchema`: the frontmatter keeps parsing
|
|
103
|
+
* with `kbAnchorSchema`, so a hand-edited defect is a `kb_validate` finding
|
|
104
|
+
* rather than a record that silently vanishes from `list()`.
|
|
105
|
+
*/
|
|
106
|
+
declare const kbAnchorWriteSchema: z.ZodObject<{
|
|
107
|
+
file: z.ZodString;
|
|
108
|
+
symbol: z.ZodOptional<z.ZodString>;
|
|
109
|
+
span: z.ZodOptional<z.ZodObject<{
|
|
110
|
+
start: z.ZodNumber;
|
|
111
|
+
end: z.ZodNumber;
|
|
112
|
+
}, z.core.$strict>>;
|
|
113
|
+
side: z.ZodOptional<z.ZodEnum<{
|
|
114
|
+
old: "old";
|
|
115
|
+
new: "new";
|
|
116
|
+
}>>;
|
|
68
117
|
repo: z.ZodOptional<z.ZodString>;
|
|
69
118
|
ref: z.ZodOptional<z.ZodString>;
|
|
70
119
|
hash: z.ZodOptional<z.ZodString>;
|
|
@@ -75,6 +124,7 @@ declare const kbAnchorSchema: z.ZodObject<{
|
|
|
75
124
|
resolved_at: z.ZodOptional<z.ZodString>;
|
|
76
125
|
lines: z.ZodOptional<z.ZodNumber>;
|
|
77
126
|
resolver: z.ZodOptional<z.ZodEnum<{
|
|
127
|
+
span: "span";
|
|
78
128
|
"tree-sitter": "tree-sitter";
|
|
79
129
|
regex: "regex";
|
|
80
130
|
}>>;
|
|
@@ -143,6 +193,14 @@ declare const kbRecordFrontmatterSchema: z.ZodObject<{
|
|
|
143
193
|
strauss_anchors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
144
194
|
file: z.ZodString;
|
|
145
195
|
symbol: z.ZodOptional<z.ZodString>;
|
|
196
|
+
span: z.ZodOptional<z.ZodObject<{
|
|
197
|
+
start: z.ZodNumber;
|
|
198
|
+
end: z.ZodNumber;
|
|
199
|
+
}, z.core.$strict>>;
|
|
200
|
+
side: z.ZodOptional<z.ZodEnum<{
|
|
201
|
+
old: "old";
|
|
202
|
+
new: "new";
|
|
203
|
+
}>>;
|
|
146
204
|
repo: z.ZodOptional<z.ZodString>;
|
|
147
205
|
ref: z.ZodOptional<z.ZodString>;
|
|
148
206
|
hash: z.ZodOptional<z.ZodString>;
|
|
@@ -153,6 +211,7 @@ declare const kbRecordFrontmatterSchema: z.ZodObject<{
|
|
|
153
211
|
resolved_at: z.ZodOptional<z.ZodString>;
|
|
154
212
|
lines: z.ZodOptional<z.ZodNumber>;
|
|
155
213
|
resolver: z.ZodOptional<z.ZodEnum<{
|
|
214
|
+
span: "span";
|
|
156
215
|
"tree-sitter": "tree-sitter";
|
|
157
216
|
regex: "regex";
|
|
158
217
|
}>>;
|
|
@@ -193,6 +252,7 @@ declare const kbRecordFrontmatterSchema: z.ZodObject<{
|
|
|
193
252
|
type KbSource = z.infer<typeof kbSourceSchema>;
|
|
194
253
|
type KbActorStamp = z.infer<typeof kbActorStampSchema>;
|
|
195
254
|
type KbVerifiedEvent = z.infer<typeof kbVerifiedEventSchema>;
|
|
255
|
+
type KbAnchorSpan = z.infer<typeof kbAnchorSpanSchema>;
|
|
196
256
|
type KbAnchor = z.infer<typeof kbAnchorSchema>;
|
|
197
257
|
type KbLink = z.infer<typeof kbLinkSchema>;
|
|
198
258
|
type KbRecordFrontmatter = z.infer<typeof kbRecordFrontmatterSchema>;
|
|
@@ -203,9 +263,6 @@ type KbRecord = {
|
|
|
203
263
|
body: string;
|
|
204
264
|
};
|
|
205
265
|
|
|
206
|
-
/** Where bare mirrors live. Overridable so a test never writes to `$HOME`. */
|
|
207
|
-
declare function repoCacheDir(override?: string): string;
|
|
208
|
-
|
|
209
266
|
/**
|
|
210
267
|
* The vocabulary anchor resolution is reported in.
|
|
211
268
|
*
|
|
@@ -219,10 +276,10 @@ type ResolvedSymbol = {
|
|
|
219
276
|
endLine: number;
|
|
220
277
|
};
|
|
221
278
|
/** Which resolver produced a span. Stamped on the anchor. */
|
|
222
|
-
type AnchorResolverName = "tree-sitter" | "regex";
|
|
279
|
+
type AnchorResolverName = "tree-sitter" | "regex" | "span";
|
|
223
280
|
/**
|
|
224
281
|
* A resolver's verdict. `abstain` ("not my language") and `symbol-not-found`
|
|
225
|
-
* ("nothing I recognize declares this")
|
|
282
|
+
* ("nothing I recognize declares this") pass the symbol down the chain;
|
|
226
283
|
* `symbol-ambiguous` and `resolver-unavailable` end it, because neither may be
|
|
227
284
|
* answered by a looser resolver guessing.
|
|
228
285
|
*/
|
|
@@ -235,12 +292,17 @@ type ResolverAttempt = {
|
|
|
235
292
|
} | {
|
|
236
293
|
kind: "abstain";
|
|
237
294
|
};
|
|
295
|
+
/** What the chain already knows when it calls a resolver. */
|
|
296
|
+
type ResolverAttemptOptions = {
|
|
297
|
+
/** A resolver that parsed this file already reported `symbol-not-found`. */
|
|
298
|
+
afterParsedMiss?: boolean;
|
|
299
|
+
};
|
|
238
300
|
interface AnchorResolver {
|
|
239
301
|
name: string;
|
|
240
302
|
/** Loads whatever these files need, before any `resolve` call. Optional. */
|
|
241
303
|
prepare?(files: readonly string[]): Promise<void>;
|
|
242
304
|
/** The richer verdict the chain uses; defaults to `resolve`. */
|
|
243
|
-
attempt?(source: string, symbol: string, file?: string): ResolverAttempt;
|
|
305
|
+
attempt?(source: string, symbol: string, file?: string, options?: ResolverAttemptOptions): ResolverAttempt;
|
|
244
306
|
resolve(source: string, symbol: string, file?: string): ResolvedSymbol | null;
|
|
245
307
|
/**
|
|
246
308
|
* The span's normalised token stream — comments dropped, runs of whitespace
|
|
@@ -267,6 +329,12 @@ type AnchorResolution = {
|
|
|
267
329
|
type AnchorUnresolvedReason = "file-missing" | "symbol-not-found"
|
|
268
330
|
/** More than one definition carries the name, and guessing is not allowed. */
|
|
269
331
|
| "symbol-ambiguous"
|
|
332
|
+
/** The anchor's `span` runs past the end of the file it names. */
|
|
333
|
+
| "span-out-of-range"
|
|
334
|
+
/** `side: "old"` with no usable `ref`, or no such path at the rev. */
|
|
335
|
+
| "ref-unreadable"
|
|
336
|
+
/** The `ref` is not in this clone — a shallow checkout, not deleted code. */
|
|
337
|
+
| "ref-unavailable"
|
|
270
338
|
/** The extension has a grammar, but it would not load. Never a throw. */
|
|
271
339
|
| "resolver-unavailable" | "outside-repo" | "file-too-large" | "file-unreadable"
|
|
272
340
|
/** The remote could not be fetched, or `--offline` found nothing cached. */
|
|
@@ -313,6 +381,8 @@ type KbDriftMovedTo = {
|
|
|
313
381
|
type KbAnchorDriftEntry = {
|
|
314
382
|
file: string;
|
|
315
383
|
symbol?: string;
|
|
384
|
+
/** Set only for `side: "old"`: read at `ref`, never from the working tree. */
|
|
385
|
+
side?: "old";
|
|
316
386
|
state: "match" | "drifted" | "unresolved";
|
|
317
387
|
storedHash: string;
|
|
318
388
|
currentHash?: string;
|
|
@@ -345,6 +415,34 @@ type AnchorRead = {
|
|
|
345
415
|
};
|
|
346
416
|
type AnchorFileReader = (file: string) => Promise<AnchorRead>;
|
|
347
417
|
|
|
418
|
+
/**
|
|
419
|
+
* The committed file an old-side anchor names, at its own `ref` and nowhere
|
|
420
|
+
* else. No history fallback: `side: "old"` asserts one exact tree, so guessing
|
|
421
|
+
* a nearby commit would answer a question the anchor did not ask.
|
|
422
|
+
*
|
|
423
|
+
* A rev this clone does not carry is `ref-unavailable` — unchecked, not
|
|
424
|
+
* `gone`: a shallow checkout is no evidence the code went away.
|
|
425
|
+
*/
|
|
426
|
+
declare function readFileAtRef(repoRoot: string, anchor: {
|
|
427
|
+
file: string;
|
|
428
|
+
ref?: string;
|
|
429
|
+
}): Promise<AnchorRead>;
|
|
430
|
+
/** Where a recovered file came from, so a packet can say how far back it looked. */
|
|
431
|
+
type OldSourceOrigin =
|
|
432
|
+
/** `git cat-file blob <anchor.ref>:<file>` — the rev the record named. */
|
|
433
|
+
{
|
|
434
|
+
kind: "ref";
|
|
435
|
+
ref: string;
|
|
436
|
+
}
|
|
437
|
+
/** The last commit touching the path before `resolved_at`. */
|
|
438
|
+
| {
|
|
439
|
+
kind: "history";
|
|
440
|
+
ref: string;
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
/** Where bare mirrors live. Overridable so a test never writes to `$HOME`. */
|
|
444
|
+
declare function repoCacheDir(override?: string): string;
|
|
445
|
+
|
|
348
446
|
/**
|
|
349
447
|
* A foreign anchor's file at one rev. `ref` absent means the remote's default
|
|
350
448
|
* branch — the "current" side of a ref-pinned comparison.
|
|
@@ -388,6 +486,8 @@ type AnchorDriftOptions = {
|
|
|
388
486
|
concurrency?: number;
|
|
389
487
|
/** Test seam: replaces the disk reader. */
|
|
390
488
|
reader?: AnchorFileReader;
|
|
489
|
+
/** Test seam: replaces the committed-side git read. */
|
|
490
|
+
readAtRef?: typeof readFileAtRef;
|
|
391
491
|
/** Remote resolution of foreign anchors; `offline` keeps a run off the wire. */
|
|
392
492
|
remote?: RemoteOptions;
|
|
393
493
|
/** Test seam: replaces the remote blob reader. */
|
|
@@ -518,9 +618,9 @@ declare function resolveAnchor(source: string, anchor: KbAnchor, resolver?: Anch
|
|
|
518
618
|
* when the anchor names no symbol.
|
|
519
619
|
*
|
|
520
620
|
* `symbol-not-found` falls through (a tags query defines functions and types,
|
|
521
|
-
* not constants or fields)
|
|
522
|
-
*
|
|
523
|
-
*
|
|
621
|
+
* not constants or fields), but a resolver that parsed the file and missed
|
|
622
|
+
* narrows what follows to definition-shaped candidates: never a call site or a
|
|
623
|
+
* bare mention. `symbol-ambiguous` and `resolver-unavailable` end the chain.
|
|
524
624
|
*/
|
|
525
625
|
declare function resolveAnchorSpan(source: string, anchor: KbAnchor, resolvers?: readonly AnchorResolver[]): AnchorResolution;
|
|
526
626
|
/** Loads every chained resolver's per-language assets, once. */
|
|
@@ -968,6 +1068,8 @@ type KbLogReadResult = {
|
|
|
968
1068
|
line: number;
|
|
969
1069
|
text: string;
|
|
970
1070
|
}[];
|
|
1071
|
+
/** Whether the file still carried merge conflict markers. */
|
|
1072
|
+
conflicted: boolean;
|
|
971
1073
|
};
|
|
972
1074
|
declare function parseLog(raw: string): KbLogReadResult;
|
|
973
1075
|
|
|
@@ -1054,6 +1156,13 @@ type KbWriteInput = {
|
|
|
1054
1156
|
/** Replace an existing record rather than failing on the collision. */
|
|
1055
1157
|
overwrite?: boolean;
|
|
1056
1158
|
};
|
|
1159
|
+
/** What a record had to still be for `deleteRecord` to remove it. */
|
|
1160
|
+
type KbDeleteExpectation = {
|
|
1161
|
+
tag: string;
|
|
1162
|
+
statuses: readonly KbRecordStatus[];
|
|
1163
|
+
};
|
|
1164
|
+
/** Whether the delete landed, or the record left that scope first. */
|
|
1165
|
+
type KbDeleteOutcome = "deleted" | "changed-since-listing";
|
|
1057
1166
|
type KbWriteResult = KbRecord & {
|
|
1058
1167
|
/** Whether this write also marked prior records superseded. */
|
|
1059
1168
|
action: "created" | "superseded-prior";
|
|
@@ -1116,6 +1225,9 @@ declare class KbStore {
|
|
|
1116
1225
|
* Wholesale rather than merged: the caller just resolved the anchors it is
|
|
1117
1226
|
* writing, so it holds the complete current set, and a merge would keep
|
|
1118
1227
|
* stale entries the resolution pass deliberately dropped.
|
|
1228
|
+
*
|
|
1229
|
+
* Through the write schema: this is a write, and a defect a hand-edit put in
|
|
1230
|
+
* the frontmatter must not be published back out under an actor stamp.
|
|
1119
1231
|
*/
|
|
1120
1232
|
updateAnchors(bundlePath: string, conceptId: string, anchors: KbAnchor[], actor?: string): Promise<KbRecord>;
|
|
1121
1233
|
/**
|
|
@@ -1140,6 +1252,15 @@ declare class KbStore {
|
|
|
1140
1252
|
supersede(bundlePath: string, conceptId: string, replacementId: string, actor?: string): Promise<KbRecord>;
|
|
1141
1253
|
/** Resolves an open question, stamping who answered and when. */
|
|
1142
1254
|
answer(bundlePath: string, conceptId: string, answer: string, actor?: string, at?: string): Promise<KbRecord>;
|
|
1255
|
+
/**
|
|
1256
|
+
* Removes one record, logged as `sweep`. The only path in this store that
|
|
1257
|
+
* deletes — see the specification for the scope that makes it safe.
|
|
1258
|
+
*
|
|
1259
|
+
* `expected` is re-read and re-checked immediately before the unlink, the
|
|
1260
|
+
* compare-and-swap `mutate` makes: a record retagged or moved out of a
|
|
1261
|
+
* terminal status since the caller listed it is reported, not removed.
|
|
1262
|
+
*/
|
|
1263
|
+
deleteRecord(bundlePath: string, conceptId: string, expected: KbDeleteExpectation, actor?: string): Promise<KbDeleteOutcome>;
|
|
1143
1264
|
/**
|
|
1144
1265
|
* Records matching a text query, each carrying its standing.
|
|
1145
1266
|
*
|
|
@@ -1254,14 +1375,29 @@ declare class KbStore {
|
|
|
1254
1375
|
* and the next reader through here settles it.
|
|
1255
1376
|
*/
|
|
1256
1377
|
readIndex(bundlePath: string): Promise<string>;
|
|
1378
|
+
/**
|
|
1379
|
+
* Drops the derived search index, so the next search rebuilds it.
|
|
1380
|
+
*
|
|
1381
|
+
* `searchBase` re-indexes when a record is newer than the index, which no
|
|
1382
|
+
* deletion makes true — a swept record would stay findable until some other
|
|
1383
|
+
* record was written.
|
|
1384
|
+
*/
|
|
1385
|
+
dropSearchIndex(bundlePath: string): Promise<void>;
|
|
1257
1386
|
/**
|
|
1258
1387
|
* The log, with unparseable lines reported rather than repaired.
|
|
1259
1388
|
*
|
|
1260
1389
|
* The log is the bundle's only artifact that cannot be reconstructed — the
|
|
1261
1390
|
* records rebuild the index, and the code outlives both, but nothing else
|
|
1262
1391
|
* knows which agent touched what. So a bad line is surfaced and left alone.
|
|
1392
|
+
* Conflict markers are read past rather than reported per line.
|
|
1263
1393
|
*/
|
|
1264
1394
|
readLog(bundlePath: string): Promise<ReturnType<typeof parseLog>>;
|
|
1395
|
+
/**
|
|
1396
|
+
* Appends one log entry for a move the store cannot see from one base.
|
|
1397
|
+
* Promotion writes into a target base and has to be legible from the source
|
|
1398
|
+
* base too, where nothing was written.
|
|
1399
|
+
*/
|
|
1400
|
+
note(bundlePath: string, entry: Omit<KbLogEntry, "at">): Promise<void>;
|
|
1265
1401
|
/**
|
|
1266
1402
|
* `markSuperseded`, tolerant of the two ways it legitimately doesn't land:
|
|
1267
1403
|
* a missing target (a broken link, legal per compose.ts) or a CAS conflict
|
|
@@ -1296,7 +1432,8 @@ declare class KbStore {
|
|
|
1296
1432
|
/**
|
|
1297
1433
|
* Declares union merge for the log, so two worktrees writing the same
|
|
1298
1434
|
* bundle interleave their `log.jsonl` lines on merge rather than one
|
|
1299
|
-
* side's appends silently losing to git's ordinary line-level merge
|
|
1435
|
+
* side's appends silently losing to git's ordinary line-level merge — and
|
|
1436
|
+
* marks every store-owned file generated, so GitHub collapses it in a diff.
|
|
1300
1437
|
*
|
|
1301
1438
|
* Called from `record` — every path that appends a log line, not just
|
|
1302
1439
|
* `write` — so a bundle only ever mutated through `setStatus`/`verify`/
|
|
@@ -1309,10 +1446,9 @@ declare class KbStore {
|
|
|
1309
1446
|
* race and created the file between the `readFile` below and this call,
|
|
1310
1447
|
* `wx` fails instead of truncating what that writer just wrote, and the
|
|
1311
1448
|
* failure is swallowed by the catch below same as any other best-effort
|
|
1312
|
-
* miss. A file that exists
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
* entirely (see `hasMergeDeclaration`).
|
|
1449
|
+
* miss. A file that exists gets only the lines it lacks appended, never a
|
|
1450
|
+
* wholesale rewrite; an attribute it already sets — this one's value or a
|
|
1451
|
+
* user's own — is left alone (see `missingGitattributesLines`).
|
|
1316
1452
|
*
|
|
1317
1453
|
* `readFile` failing is `existing === null` only for `ENOENT` — genuinely
|
|
1318
1454
|
* missing. Any other error (a permission problem, a transient `EMFILE`,
|
|
@@ -1323,12 +1459,12 @@ declare class KbStore {
|
|
|
1323
1459
|
* therefore left untouched and reported as a failure like any other.
|
|
1324
1460
|
*
|
|
1325
1461
|
* Two processes racing the append branch — both read a file without the
|
|
1326
|
-
*
|
|
1327
|
-
* `O_APPEND`, so the result is two copies of the same
|
|
1328
|
-
* torn write, and
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1462
|
+
* lines, both append them — is possible and left unguarded: `appendFile` is
|
|
1463
|
+
* `O_APPEND`, so the result is two copies of the same lines rather than a
|
|
1464
|
+
* torn write, and the next call sees a duplicate declaration as "already
|
|
1465
|
+
* declared". A cheap-to-detect, harmless-to-leave residue, not a reason to
|
|
1466
|
+
* add a cross-process lock (see `ARCHITECTURE.md`'s rejection of one for
|
|
1467
|
+
* the same trade on records).
|
|
1332
1468
|
*
|
|
1333
1469
|
* Best-effort, like the log append it precedes: failing to write this
|
|
1334
1470
|
* file must not fail the mutation it guards.
|
|
@@ -1364,9 +1500,15 @@ declare enum Fault {
|
|
|
1364
1500
|
/** Machine-readable discriminant, stable across message rewording. */
|
|
1365
1501
|
declare enum ErrorTypes {
|
|
1366
1502
|
KbRecordAlreadyExists = "KbRecordAlreadyExists",
|
|
1503
|
+
KbClassifyInput = "KbClassifyInput",
|
|
1367
1504
|
KbInvalidConceptId = "KbInvalidConceptId",
|
|
1505
|
+
KbMatchInput = "KbMatchInput",
|
|
1368
1506
|
KbMissingFlagValue = "KbMissingFlagValue",
|
|
1369
1507
|
KbPackBudgetExceeded = "KbPackBudgetExceeded",
|
|
1508
|
+
KbPromoteCollision = "KbPromoteCollision",
|
|
1509
|
+
KbPromoteSelf = "KbPromoteSelf",
|
|
1510
|
+
KbPromoteStanding = "KbPromoteStanding",
|
|
1511
|
+
KbPromoteStopped = "KbPromoteStopped",
|
|
1370
1512
|
KbRecordNotFound = "KbRecordNotFound",
|
|
1371
1513
|
KbSelfVerification = "KbSelfVerification",
|
|
1372
1514
|
KbStampBaselineUnreadable = "KbStampBaselineUnreadable",
|
|
@@ -1460,6 +1602,35 @@ declare class KbMissingFlagValueError extends BaseError {
|
|
|
1460
1602
|
readonly flag: string;
|
|
1461
1603
|
constructor(flag: string);
|
|
1462
1604
|
}
|
|
1605
|
+
/** `classify` invoked with no diff it could read, or one it could not parse. */
|
|
1606
|
+
declare class KbClassifyInputError extends BaseError {
|
|
1607
|
+
readonly reason: string;
|
|
1608
|
+
constructor(reason: string);
|
|
1609
|
+
}
|
|
1610
|
+
/** The target base already holds one of the records. Refused for the whole run. */
|
|
1611
|
+
declare class KbPromoteCollisionError extends BaseError {
|
|
1612
|
+
readonly conceptId: string;
|
|
1613
|
+
readonly to: string;
|
|
1614
|
+
constructor(conceptId: string, to: string);
|
|
1615
|
+
}
|
|
1616
|
+
/** Promotion carries a record's standing, so a withdrawn one may not be copied. */
|
|
1617
|
+
declare class KbPromoteStandingError extends BaseError {
|
|
1618
|
+
readonly conceptId: string;
|
|
1619
|
+
readonly standing: string;
|
|
1620
|
+
constructor(conceptId: string, standing: string);
|
|
1621
|
+
}
|
|
1622
|
+
/** Source and target are the same base: the run would rewrite its own records. */
|
|
1623
|
+
declare class KbPromoteSelfError extends BaseError {
|
|
1624
|
+
readonly to: string;
|
|
1625
|
+
constructor(to: string);
|
|
1626
|
+
}
|
|
1627
|
+
/** A write failed after earlier ones landed; `landed` is what the target now holds. */
|
|
1628
|
+
declare class KbPromoteStoppedError extends BaseError {
|
|
1629
|
+
readonly conceptId: string;
|
|
1630
|
+
readonly landed: string[];
|
|
1631
|
+
readonly reason: string;
|
|
1632
|
+
constructor(conceptId: string, landed: string[], reason: string);
|
|
1633
|
+
}
|
|
1463
1634
|
declare class KbInvalidConceptIdError extends BaseError {
|
|
1464
1635
|
constructor(message: string, details: Record<string, string>);
|
|
1465
1636
|
}
|
|
@@ -1635,6 +1806,14 @@ declare const composeInputSchema: z.ZodObject<{
|
|
|
1635
1806
|
anchors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1636
1807
|
file: z.ZodString;
|
|
1637
1808
|
symbol: z.ZodOptional<z.ZodString>;
|
|
1809
|
+
span: z.ZodOptional<z.ZodObject<{
|
|
1810
|
+
start: z.ZodNumber;
|
|
1811
|
+
end: z.ZodNumber;
|
|
1812
|
+
}, z.core.$strict>>;
|
|
1813
|
+
side: z.ZodOptional<z.ZodEnum<{
|
|
1814
|
+
old: "old";
|
|
1815
|
+
new: "new";
|
|
1816
|
+
}>>;
|
|
1638
1817
|
repo: z.ZodOptional<z.ZodString>;
|
|
1639
1818
|
ref: z.ZodOptional<z.ZodString>;
|
|
1640
1819
|
hash: z.ZodOptional<z.ZodString>;
|
|
@@ -1645,6 +1824,7 @@ declare const composeInputSchema: z.ZodObject<{
|
|
|
1645
1824
|
resolved_at: z.ZodOptional<z.ZodString>;
|
|
1646
1825
|
lines: z.ZodOptional<z.ZodNumber>;
|
|
1647
1826
|
resolver: z.ZodOptional<z.ZodEnum<{
|
|
1827
|
+
span: "span";
|
|
1648
1828
|
"tree-sitter": "tree-sitter";
|
|
1649
1829
|
regex: "regex";
|
|
1650
1830
|
}>>;
|
|
@@ -2021,14 +2201,28 @@ declare function kbJsonSchemas(): Record<string, unknown>;
|
|
|
2021
2201
|
* those, not the base.
|
|
2022
2202
|
*/
|
|
2023
2203
|
type DiffHunk = {
|
|
2024
|
-
/** 1-based, inclusive, in the
|
|
2204
|
+
/** 1-based, inclusive, in the numbering of this hunk's `side`. */
|
|
2025
2205
|
startLine: number;
|
|
2026
2206
|
endLine: number;
|
|
2207
|
+
/**
|
|
2208
|
+
* Which half of the change these lines number; absent means `new`. An
|
|
2209
|
+
* old-side anchor lands here on the caller's word that its `ref` is this
|
|
2210
|
+
* diff's base rev — nothing compares the two.
|
|
2211
|
+
*/
|
|
2212
|
+
side?: "old" | "new";
|
|
2213
|
+
/**
|
|
2214
|
+
* This hunk's own changed lines, markers stripped, where a parser kept them.
|
|
2215
|
+
* Nothing here reads them; a caller classifying content does.
|
|
2216
|
+
*/
|
|
2217
|
+
lines?: string[];
|
|
2027
2218
|
};
|
|
2028
2219
|
type DiffFile = {
|
|
2029
2220
|
/** Repo-relative, matching how anchors are written. */
|
|
2030
2221
|
filePath: string;
|
|
2031
2222
|
hunks: DiffHunk[];
|
|
2223
|
+
/** Where `git diff -M` says this path came from, and how alike the two are. */
|
|
2224
|
+
renamedFrom?: string;
|
|
2225
|
+
similarity?: number;
|
|
2032
2226
|
};
|
|
2033
2227
|
/**
|
|
2034
2228
|
* A symbol resolved to lines. Supplied by whatever the caller uses to index
|
|
@@ -2039,6 +2233,8 @@ type SymbolRange = {
|
|
|
2039
2233
|
symbol: string;
|
|
2040
2234
|
startLine: number;
|
|
2041
2235
|
endLine: number;
|
|
2236
|
+
/** Which side these lines number; absent means `new`, as on a hunk. */
|
|
2237
|
+
side?: "old" | "new";
|
|
2042
2238
|
};
|
|
2043
2239
|
type DiffMatch = {
|
|
2044
2240
|
filePath: string;
|
|
@@ -2059,6 +2255,157 @@ type MatchOptions = {
|
|
|
2059
2255
|
now?: Date;
|
|
2060
2256
|
};
|
|
2061
2257
|
declare function matchToDiff(files: DiffFile[], records: KbRecord[], options?: MatchOptions): DiffMatch[];
|
|
2258
|
+
/** The anchor alone, for a caller that already knows the hunk matched. */
|
|
2259
|
+
declare function anchorOnHunk(record: KbRecord, filePath: string, hunk: DiffHunk, symbolRanges?: readonly SymbolRange[] | SymbolRangeIndex): KbAnchor | undefined;
|
|
2260
|
+
/** Built once by a caller placing many records on many hunks of one diff. */
|
|
2261
|
+
type SymbolRangeIndex = ReadonlyMap<string, SymbolRange[]>;
|
|
2262
|
+
declare function symbolRangeIndex(ranges: readonly SymbolRange[]): SymbolRangeIndex;
|
|
2263
|
+
|
|
2264
|
+
/**
|
|
2265
|
+
* Every operation a knowledge base exposes, defined once.
|
|
2266
|
+
*
|
|
2267
|
+
* The CLI and the MCP server are both projections of this table. Kept apart
|
|
2268
|
+
* they drift within a day — fourteen commands against six tools — which is the
|
|
2269
|
+
* same failure as a schema restated in prose beside the code that enforces it,
|
|
2270
|
+
* one level up. A command added to the table appears in both surfaces or in
|
|
2271
|
+
* neither, and a test asserts exactly that.
|
|
2272
|
+
*
|
|
2273
|
+
* The two differ only in how arguments arrive: MCP passes an object matching
|
|
2274
|
+
* `input`, while the CLI has to turn positional argv into the same object.
|
|
2275
|
+
* `fromArgv` is that adapter and is the only per-surface code a command needs.
|
|
2276
|
+
*
|
|
2277
|
+
* One file per command in this folder; `index.ts` assembles the table.
|
|
2278
|
+
*/
|
|
2279
|
+
type KbCommandContext = {
|
|
2280
|
+
store: KbStore;
|
|
2281
|
+
actor: string;
|
|
2282
|
+
now: () => string;
|
|
2283
|
+
};
|
|
2284
|
+
type KbCommand<Shape extends z.ZodRawShape = z.ZodRawShape> = {
|
|
2285
|
+
/** CLI verb. */
|
|
2286
|
+
name: string;
|
|
2287
|
+
/**
|
|
2288
|
+
* MCP tool name. Absent only for CLI-only plumbing (`sync-instructions`),
|
|
2289
|
+
* which exists to edit files for hooks and instruction blocks rather than to
|
|
2290
|
+
* give an agent a capability — the capability, "get the pinned context
|
|
2291
|
+
* block", is `kb_context`.
|
|
2292
|
+
*/
|
|
2293
|
+
tool?: string;
|
|
2294
|
+
/** Argument spelling for CLI usage output. */
|
|
2295
|
+
usage: string;
|
|
2296
|
+
/** Shown to an agent choosing a tool, so it carries the judgment too. */
|
|
2297
|
+
description: string;
|
|
2298
|
+
input: z.ZodObject<Shape>;
|
|
2299
|
+
/**
|
|
2300
|
+
* Positional argv → the same object MCP receives. `bundleExplicit` says
|
|
2301
|
+
* whether `--bundle` was actually passed, for the one command whose meaning
|
|
2302
|
+
* turns on it: `stamp` with no bundle stamps every pinned base.
|
|
2303
|
+
*/
|
|
2304
|
+
fromArgv(argv: string[], bundlePath: string, stdin: () => Promise<string>, bundleExplicit?: boolean): Promise<unknown> | unknown;
|
|
2305
|
+
run(ctx: KbCommandContext, input: z.infer<z.ZodObject<Shape>>): Promise<unknown>;
|
|
2306
|
+
/**
|
|
2307
|
+
* A human-readable form of the result, for the CLI. Where it exists the CLI
|
|
2308
|
+
* prints it and `--json` asks for the machine shape instead; MCP always gets
|
|
2309
|
+
* the machine shape, since a tool result is parsed rather than read.
|
|
2310
|
+
*
|
|
2311
|
+
* Separate from `run` rather than rendered inside it — as `pack` does, whose
|
|
2312
|
+
* result *is* a document — because a command whose result is a report needs
|
|
2313
|
+
* both forms: the table for a person, and the object for `failsWhen` and for
|
|
2314
|
+
* anything downstream.
|
|
2315
|
+
*/
|
|
2316
|
+
render?(result: unknown): string;
|
|
2317
|
+
/**
|
|
2318
|
+
* Turns a result into a non-zero exit for the CLI. A check that reports a
|
|
2319
|
+
* problem has succeeded as a command and failed as a check, and a shell
|
|
2320
|
+
* caller can only see the difference through the exit code.
|
|
2321
|
+
*
|
|
2322
|
+
* The input comes too, so a command can make the exit conditional on a flag
|
|
2323
|
+
* the caller passed rather than on the result alone.
|
|
2324
|
+
*/
|
|
2325
|
+
failsWhen?(result: unknown, input: z.infer<z.ZodObject<Shape>>): boolean;
|
|
2326
|
+
};
|
|
2327
|
+
|
|
2328
|
+
/** One record on a hunk: enough to decide whether to read it, and no body. */
|
|
2329
|
+
type KbMatchRecord = {
|
|
2330
|
+
conceptId: string;
|
|
2331
|
+
type: string;
|
|
2332
|
+
title: string | null;
|
|
2333
|
+
/** Carried on every entry, so a hit is never handed over as a bare match. */
|
|
2334
|
+
standing: KbStanding;
|
|
2335
|
+
status: KbRecordStatus;
|
|
2336
|
+
/** Where the supersession chain ends. Empty while the record still holds. */
|
|
2337
|
+
supersededBy: string[];
|
|
2338
|
+
materiality?: KbRecordFrontmatter["strauss_materiality"];
|
|
2339
|
+
confidence?: KbRecordFrontmatter["strauss_confidence"];
|
|
2340
|
+
tags?: string[];
|
|
2341
|
+
/** The anchor that put this record on this hunk. */
|
|
2342
|
+
anchor?: KbAnchor;
|
|
2343
|
+
};
|
|
2344
|
+
type KbMatch = {
|
|
2345
|
+
filePath: string;
|
|
2346
|
+
hunk: DiffHunk;
|
|
2347
|
+
/** `symbol` when every record here was placed by a resolved symbol range. */
|
|
2348
|
+
precision: "symbol" | "file";
|
|
2349
|
+
records: KbMatchRecord[];
|
|
2350
|
+
};
|
|
2351
|
+
|
|
2352
|
+
/**
|
|
2353
|
+
* What a reviewer can skim and what they must read, derived from the diff.
|
|
2354
|
+
*
|
|
2355
|
+
* A closed set: a consumer branches on these nine, and a tenth would arrive
|
|
2356
|
+
* unhandled. `source` is the residue — everything no rule claimed.
|
|
2357
|
+
*/
|
|
2358
|
+
declare const KB_CLASSES: readonly ["test", "config", "ci", "docs", "lockfile", "generated", "boilerplate", "rename", "source"];
|
|
2359
|
+
type KbClass = (typeof KB_CLASSES)[number];
|
|
2360
|
+
/** A diff file, plus the head lines a caller could read for it. */
|
|
2361
|
+
type KbClassifyFile = DiffFile & {
|
|
2362
|
+
/** The file's first lines at head. Absent falls back to the diff's own. */
|
|
2363
|
+
header?: string[];
|
|
2364
|
+
};
|
|
2365
|
+
type KbClassifyThresholds = {
|
|
2366
|
+
/** Share of a file's changed lines that must match a boilerplate shape. */
|
|
2367
|
+
boilerplate?: number;
|
|
2368
|
+
/** The `git diff -M` similarity a rename needs before it is called one. */
|
|
2369
|
+
rename?: number;
|
|
2370
|
+
};
|
|
2371
|
+
declare const DEFAULT_THRESHOLDS: Required<KbClassifyThresholds>;
|
|
2372
|
+
type KbClassifyOptions = {
|
|
2373
|
+
/** The base, for the `review:*` overrides. Adjudicated: only current wins. */
|
|
2374
|
+
records?: KbRecord[];
|
|
2375
|
+
/** Without these a symbol anchor covers its whole file rather than a hunk. */
|
|
2376
|
+
symbolRanges?: readonly SymbolRange[];
|
|
2377
|
+
now?: Date;
|
|
2378
|
+
thresholds?: KbClassifyThresholds;
|
|
2379
|
+
};
|
|
2380
|
+
/** The class and the name of the rule that produced it. */
|
|
2381
|
+
type KbVerdict = {
|
|
2382
|
+
class: KbClass;
|
|
2383
|
+
reason: string;
|
|
2384
|
+
};
|
|
2385
|
+
type KbClassifiedHunk = KbVerdict & {
|
|
2386
|
+
startLine: number;
|
|
2387
|
+
endLine: number;
|
|
2388
|
+
};
|
|
2389
|
+
type KbClassifiedFile = KbVerdict & {
|
|
2390
|
+
filePath: string;
|
|
2391
|
+
renamedFrom?: string;
|
|
2392
|
+
/** Present only where some hunk's class differs from the file's. */
|
|
2393
|
+
hunks?: KbClassifiedHunk[];
|
|
2394
|
+
};
|
|
2395
|
+
type KbClassifyResult = {
|
|
2396
|
+
files: KbClassifiedFile[];
|
|
2397
|
+
};
|
|
2398
|
+
|
|
2399
|
+
/**
|
|
2400
|
+
* What kind of change each file carries.
|
|
2401
|
+
*
|
|
2402
|
+
* Every input is in the diff, so nothing here is written down: a class the KB
|
|
2403
|
+
* stored would be a second copy of an answer the patch already gives, and the
|
|
2404
|
+
* two would disagree the first time a rule changed. The one thing a script
|
|
2405
|
+
* cannot derive — "this output is generated, read its input instead" — is a
|
|
2406
|
+
* record, and it wins over the heuristic.
|
|
2407
|
+
*/
|
|
2408
|
+
declare function classifyDiff(files: readonly KbClassifyFile[], options?: KbClassifyOptions): KbClassifiedFile[];
|
|
2062
2409
|
|
|
2063
2410
|
/**
|
|
2064
2411
|
* The edges between records in one bundle, defined once.
|
|
@@ -2196,6 +2543,14 @@ type KbAnchorResolverCounts = {
|
|
|
2196
2543
|
treeSitter: number;
|
|
2197
2544
|
/** Includes anchors stamped before resolvers were named. */
|
|
2198
2545
|
regex: number;
|
|
2546
|
+
/** Author-given line ranges, hashed exactly as written. */
|
|
2547
|
+
span: number;
|
|
2548
|
+
/**
|
|
2549
|
+
* Hashed anchors read at their `ref` rather than the working tree. Counted
|
|
2550
|
+
* beside the resolver buckets and outside `total`: `side` is not a resolver,
|
|
2551
|
+
* and one of these may name a whole file.
|
|
2552
|
+
*/
|
|
2553
|
+
oldSide: number;
|
|
2199
2554
|
};
|
|
2200
2555
|
type KbDoctorOptions = {
|
|
2201
2556
|
/** How far ahead `expiring` looks. */
|
|
@@ -2259,6 +2614,14 @@ declare const decisionInputSchema: z.ZodObject<{
|
|
|
2259
2614
|
anchors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
2260
2615
|
file: z.ZodString;
|
|
2261
2616
|
symbol: z.ZodOptional<z.ZodString>;
|
|
2617
|
+
span: z.ZodOptional<z.ZodObject<{
|
|
2618
|
+
start: z.ZodNumber;
|
|
2619
|
+
end: z.ZodNumber;
|
|
2620
|
+
}, z.core.$strict>>;
|
|
2621
|
+
side: z.ZodOptional<z.ZodEnum<{
|
|
2622
|
+
old: "old";
|
|
2623
|
+
new: "new";
|
|
2624
|
+
}>>;
|
|
2262
2625
|
repo: z.ZodOptional<z.ZodString>;
|
|
2263
2626
|
ref: z.ZodOptional<z.ZodString>;
|
|
2264
2627
|
hash: z.ZodOptional<z.ZodString>;
|
|
@@ -2269,6 +2632,7 @@ declare const decisionInputSchema: z.ZodObject<{
|
|
|
2269
2632
|
resolved_at: z.ZodOptional<z.ZodString>;
|
|
2270
2633
|
lines: z.ZodOptional<z.ZodNumber>;
|
|
2271
2634
|
resolver: z.ZodOptional<z.ZodEnum<{
|
|
2635
|
+
span: "span";
|
|
2272
2636
|
"tree-sitter": "tree-sitter";
|
|
2273
2637
|
regex: "regex";
|
|
2274
2638
|
}>>;
|
|
@@ -2318,90 +2682,100 @@ declare function isNoDecisionRecord(record: KbRecord): boolean;
|
|
|
2318
2682
|
declare function selectDecisions(records: KbRecord[]): KbRecord[];
|
|
2319
2683
|
|
|
2320
2684
|
/**
|
|
2321
|
-
*
|
|
2322
|
-
*
|
|
2323
|
-
* The CLI and the MCP server are both projections of this table. Kept apart
|
|
2324
|
-
* they drift within a day — fourteen commands against six tools — which is the
|
|
2325
|
-
* same failure as a schema restated in prose beside the code that enforces it,
|
|
2326
|
-
* one level up. A command added to the table appears in both surfaces or in
|
|
2327
|
-
* neither, and a test asserts exactly that.
|
|
2328
|
-
*
|
|
2329
|
-
* The two differ only in how arguments arrive: MCP passes an object matching
|
|
2330
|
-
* `input`, while the CLI has to turn positional argv into the same object.
|
|
2331
|
-
* `fromArgv` is that adapter and is the only per-surface code a command needs.
|
|
2685
|
+
* The command table, assembled from one file per command.
|
|
2332
2686
|
*
|
|
2333
|
-
*
|
|
2687
|
+
* Order is the CLI usage listing's order: the write path, the read path,
|
|
2688
|
+
* base housekeeping, the format, and the workspace pin verbs.
|
|
2334
2689
|
*/
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2690
|
+
|
|
2691
|
+
declare const KB_COMMANDS: KbCommand[];
|
|
2692
|
+
declare const KB_COMMANDS_BY_NAME: Map<string, KbCommand>;
|
|
2693
|
+
|
|
2694
|
+
/**
|
|
2695
|
+
* Listing candidates and promoting share one input, and the two need different
|
|
2696
|
+
* arguments. The rule lives here rather than in `run` so both surfaces refuse
|
|
2697
|
+
* the same call: the CLI before it dispatches, MCP before the tool runs.
|
|
2698
|
+
*/
|
|
2699
|
+
declare const promoteInputSchema: z.ZodObject<{
|
|
2700
|
+
bundlePath: z.ZodString;
|
|
2701
|
+
conceptIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
2702
|
+
to: z.ZodOptional<z.ZodString>;
|
|
2703
|
+
source: z.ZodOptional<z.ZodString>;
|
|
2704
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
2705
|
+
list: z.ZodOptional<z.ZodBoolean>;
|
|
2706
|
+
}, z.core.$strip>;
|
|
2707
|
+
/** A typed link the copy does not carry, because its target stayed behind. */
|
|
2708
|
+
type KbDroppedLink = {
|
|
2709
|
+
target: string;
|
|
2710
|
+
rel: string;
|
|
2339
2711
|
};
|
|
2340
|
-
type
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
* turns on it: `stamp` with no bundle stamps every pinned base.
|
|
2359
|
-
*/
|
|
2360
|
-
fromArgv(argv: string[], bundlePath: string, stdin: () => Promise<string>, bundleExplicit?: boolean): Promise<unknown> | unknown;
|
|
2361
|
-
run(ctx: KbCommandContext, input: z.infer<z.ZodObject<Shape>>): Promise<unknown>;
|
|
2362
|
-
/**
|
|
2363
|
-
* A human-readable form of the result, for the CLI. Where it exists the CLI
|
|
2364
|
-
* prints it and `--json` asks for the machine shape instead; MCP always gets
|
|
2365
|
-
* the machine shape, since a tool result is parsed rather than read.
|
|
2366
|
-
*
|
|
2367
|
-
* Separate from `run` rather than rendered inside it — as `pack` does, whose
|
|
2368
|
-
* result *is* a document — because a command whose result is a report needs
|
|
2369
|
-
* both forms: the table for a person, and the object for `failsWhen` and for
|
|
2370
|
-
* anything downstream.
|
|
2371
|
-
*/
|
|
2372
|
-
render?(result: unknown): string;
|
|
2373
|
-
/**
|
|
2374
|
-
* Turns a result into a non-zero exit for the CLI. A check that reports a
|
|
2375
|
-
* problem has succeeded as a command and failed as a check, and a shell
|
|
2376
|
-
* caller can only see the difference through the exit code.
|
|
2377
|
-
*
|
|
2378
|
-
* The input comes too, so a command can make the exit conditional on a flag
|
|
2379
|
-
* the caller passed rather than on the result alone.
|
|
2380
|
-
*/
|
|
2381
|
-
failsWhen?(result: unknown, input: z.infer<z.ZodObject<Shape>>): boolean;
|
|
2712
|
+
type KbPromotedRecord = {
|
|
2713
|
+
conceptId: string;
|
|
2714
|
+
droppedLinks: KbDroppedLink[];
|
|
2715
|
+
};
|
|
2716
|
+
type KbPromoteCandidate = {
|
|
2717
|
+
conceptId: string;
|
|
2718
|
+
type: string;
|
|
2719
|
+
title: string | null;
|
|
2720
|
+
/** The rule that made it a candidate, in the reader's terms. */
|
|
2721
|
+
why: string;
|
|
2722
|
+
};
|
|
2723
|
+
type KbPromoteResult = {
|
|
2724
|
+
mode: "list";
|
|
2725
|
+
candidates: KbPromoteCandidate[];
|
|
2726
|
+
} | {
|
|
2727
|
+
mode: "promote";
|
|
2728
|
+
to: string;
|
|
2729
|
+
promoted: KbPromotedRecord[];
|
|
2382
2730
|
};
|
|
2383
2731
|
|
|
2732
|
+
/** The source entry a promotion adds, replaced rather than repeated on re-promote. */
|
|
2733
|
+
declare const PROMOTION_SOURCE_ID = "promoted";
|
|
2734
|
+
type KbCarriedRecord = {
|
|
2735
|
+
frontmatter: Omit<KbRecordFrontmatter, "type">;
|
|
2736
|
+
body: string;
|
|
2737
|
+
droppedLinks: KbDroppedLink[];
|
|
2738
|
+
};
|
|
2384
2739
|
/**
|
|
2385
|
-
*
|
|
2740
|
+
* One record as the target base should hold it.
|
|
2386
2741
|
*
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2742
|
+
* Frontmatter is carried rather than recomposed: OKF requires a consumer to
|
|
2743
|
+
* preserve keys it does not recognise when round-tripping, and a record written
|
|
2744
|
+
* by another producer would lose them to a rebuild from known fields.
|
|
2745
|
+
*/
|
|
2746
|
+
declare function carry(record: KbRecord, promoted: ReadonlySet<string>, source?: string): KbCarriedRecord;
|
|
2747
|
+
/**
|
|
2748
|
+
* `review` and the `review:<id>` family alike: the target base is not a review
|
|
2749
|
+
* base, so a tag saying which review wrote the record no longer selects
|
|
2750
|
+
* anything there.
|
|
2389
2751
|
*/
|
|
2752
|
+
declare function isReviewTag(tag: string): boolean;
|
|
2390
2753
|
|
|
2391
|
-
|
|
2392
|
-
|
|
2754
|
+
/**
|
|
2755
|
+
* What in a review base is worth keeping once the change merges. Heuristics over
|
|
2756
|
+
* what a reviewer usually wants; a record they cut is still nameable by hand.
|
|
2757
|
+
* A withdrawn record is not among them — `promote` refuses those outright.
|
|
2758
|
+
*/
|
|
2759
|
+
declare function promoteCandidates(bundle: KbRecord[]): KbPromoteCandidate[];
|
|
2393
2760
|
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
/**
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
}
|
|
2401
|
-
/**
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2761
|
+
type KbExportedDecision = {
|
|
2762
|
+
conceptId: string;
|
|
2763
|
+
/** File name within the target directory, `NNNN-<slug>.md`. */
|
|
2764
|
+
file: string;
|
|
2765
|
+
/** The ADR's Status line, as adjudication settled it. */
|
|
2766
|
+
status: string;
|
|
2767
|
+
};
|
|
2768
|
+
/** A file this exporter did not write, holding the name a decision needs. */
|
|
2769
|
+
type KbExportForeignFile = {
|
|
2770
|
+
conceptId: string;
|
|
2771
|
+
file: string;
|
|
2772
|
+
};
|
|
2773
|
+
type KbExportResult = {
|
|
2774
|
+
to: string;
|
|
2775
|
+
format: "madr";
|
|
2776
|
+
exported: KbExportedDecision[];
|
|
2777
|
+
/** Decisions left unwritten because a foreign file already holds their name. */
|
|
2778
|
+
foreign: KbExportForeignFile[];
|
|
2405
2779
|
};
|
|
2406
2780
|
|
|
2407
2781
|
type MovedSearch = {
|
|
@@ -2706,4 +3080,4 @@ declare function parseMarkdownWithFrontmatter<S extends z.ZodType>(text: string,
|
|
|
2706
3080
|
frontmatter: ReturnType<S["safeParse"]>;
|
|
2707
3081
|
};
|
|
2708
3082
|
|
|
2709
|
-
export { type AnchorResolution, type AnchorResolver, type AnchorResolverName, BaseError, CONTEXT_BEGIN, CONTEXT_END, CONTEXT_PROFILES, type ClassifiedAnchor, 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 KbReassessAnchor, type KbReassessDefault, type KbReassessDiff, type KbReassessPacket, 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 KbTagFilter, 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, classifyDrift, 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, matchesTags, mergedContextBudgets, neighbours, pack, parseLog, parseMarkdownWithFrontmatter, pinBase, prepareResolvers, readMergedPins, readPinsLayer, readRemoteAnchors, reassessPacket, regexResolver, renderCatalogLine, renderIndex, renderIndexLine, renderLogEntry, repoCacheDir, resolveAnchor, resolveAnchorSpan, resolveHeads, resolveHits, resolvePinPath, runKbCli, runKbMcpServer, searchBase, selectDecisions, splitMarkdownFrontmatter, stringifyMarkdownWithFrontmatter, syncInstructions, toHookJson, trace, treeSitterLanguages, unifiedDiff, unpinBase, validateBundle };
|
|
3083
|
+
export { type AnchorResolution, type AnchorResolver, type AnchorResolverName, BaseError, CONTEXT_BEGIN, CONTEXT_END, CONTEXT_PROFILES, type ClassifiedAnchor, 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_THRESHOLDS, 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_CLASSES, 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 KbAnchorSpan, type KbBacklink, type KbBacklinksResult, KbBaseFrozenError, type KbCatalogEntry, type KbCatalogResult, type KbClass, type KbClassifiedFile, type KbClassifiedHunk, type KbClassifyFile, KbClassifyInputError, type KbClassifyOptions, type KbClassifyResult, type KbClassifyThresholds, type KbCommand, type KbCommandContext, type KbContextBudgets, type KbContextOptions, type KbContextResult, type KbDoctorCheck, type KbDoctorFinding, type KbDoctorGroup, type KbDoctorOptions, type KbDoctorReport, type KbDoctorThresholds, type KbDroppedLink, type KbEdgeKind, type KbExportForeignFile, type KbExportResult, type KbExportedDecision, 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 KbMatch, type KbMatchRecord, 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 KbPromoteCandidate, KbPromoteCollisionError, type KbPromoteResult, KbPromoteSelfError, KbPromoteStandingError, KbPromoteStoppedError, type KbPromotedRecord, type KbReassessAnchor, type KbReassessDefault, type KbReassessDiff, type KbReassessPacket, 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 KbTagFilter, type KbTraceEdge, type KbTraceOptions, type KbTraceStep, KbUnknownLinkRelError, type KbValidationProblem, type KbValidationSeverity, type KbVerdict, type KbVerifiedEvent, type KbWarning, KbWriteConflictError, type KbWriteInput, LINK_RELS, LOG_FILE, type MatchOptions, NO_DECISION_SLUG, PINS_FILE, PINS_LOCAL_FILE, PIN_LAYERS, PROMOTION_SOURCE_ID, type QmdModule, RECORD_TYPES, type RemoteAnchorState, type RemoteOptions, type RemoteRead, type ResolvedSymbol, type ResolverAttempt, type ResolverAttemptOptions, SEARCH_INDEX_FILE, type SearchHit, type SearchOptions, type SymbolRange, type SymbolRangeIndex, TRACE_EDGES, TreeSitterResolver, adjudicate, anchorFilePath, anchorOnHunk, assertBaseNotFrozen, backlinks, buildContext, carry, catalog, classifyDiff, classifyDrift, composeDecisionRecord, composeInputSchema, composeLinkSchema, composeNoDecisionRecord, composeRecord, contextProfileBudgets, createKbMcpServer, decisionInputSchema, defaultAnchorResolvers, detectAnchorDrift, doctor, edgeNeighbours, ensureGrammar, grammarHints, grammarManifest, grammarsCacheRoot, hashAnchorText, impact, inboundIndex, indexIsStale, isCanonicalRepoUrl, isKbLinkRel, isKbRecordType, isNoDecisionRecord, isReviewTag, kbActorStampSchema, kbAnchorSchema, kbAnchorSpanSchema, kbAnchorWriteSchema, kbConceptIdSchema, kbJsonSchemas, kbLinkSchema, kbLogEntrySchema, kbRecordFrontmatterSchema, kbSourceSchema, kbVerifiedEventSchema, languageForFile, listPins, loadQmd, matchToDiff, matchesTags, mergedContextBudgets, neighbours, pack, parseLog, parseMarkdownWithFrontmatter, pinBase, prepareResolvers, promoteCandidates, promoteInputSchema, readMergedPins, readPinsLayer, readRemoteAnchors, reassessPacket, regexResolver, renderCatalogLine, renderIndex, renderIndexLine, renderLogEntry, repoCacheDir, resolveAnchor, resolveAnchorSpan, resolveHeads, resolveHits, resolvePinPath, runKbCli, runKbMcpServer, searchBase, selectDecisions, splitMarkdownFrontmatter, stringifyMarkdownWithFrontmatter, symbolRangeIndex, syncInstructions, toHookJson, trace, treeSitterLanguages, unifiedDiff, unpinBase, validateBundle };
|