@saasontools/strauss-kb 0.1.21 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/{chunk-XBZ7G5R5.js → chunk-AEO5U42S.js} +3849 -3602
- package/dist/chunk-AEO5U42S.js.map +1 -0
- package/dist/{chunk-VXWN62HT.js → chunk-DVSPHL4B.js} +2 -2
- package/dist/{chunk-WVJULVGY.js → chunk-TSE4YQEG.js} +2 -2
- package/dist/cli-main.cjs +1433 -1194
- package/dist/cli-main.cjs.map +1 -1
- package/dist/cli-main.js +2 -2
- package/dist/index.cjs +421 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +293 -17
- package/dist/index.d.ts +293 -17
- package/dist/index.js +17 -3
- package/dist/mcp-main.cjs +1433 -1194
- package/dist/mcp-main.cjs.map +1 -1
- package/dist/mcp-main.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-XBZ7G5R5.js.map +0 -1
- /package/dist/{chunk-VXWN62HT.js.map → chunk-DVSPHL4B.js.map} +0 -0
- /package/dist/{chunk-WVJULVGY.js.map → chunk-TSE4YQEG.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -60,6 +60,7 @@ __export(index_exports, {
|
|
|
60
60
|
KB_RECORD_STATUSES: () => KB_RECORD_STATUSES,
|
|
61
61
|
KB_RECORD_TYPES: () => KB_RECORD_TYPES,
|
|
62
62
|
KB_SLUG_PATTERN: () => KB_SLUG_PATTERN,
|
|
63
|
+
KbAnchorSetDuplicateError: () => KbAnchorSetDuplicateError,
|
|
63
64
|
KbBaseFrozenError: () => KbBaseFrozenError,
|
|
64
65
|
KbClassifyInputError: () => KbClassifyInputError,
|
|
65
66
|
KbInvalidConceptIdError: () => KbInvalidConceptIdError,
|
|
@@ -90,6 +91,8 @@ __export(index_exports, {
|
|
|
90
91
|
adjudicate: () => adjudicate,
|
|
91
92
|
anchorFilePath: () => anchorFilePath,
|
|
92
93
|
anchorOnHunk: () => anchorOnHunk,
|
|
94
|
+
anchorSetInputSchema: () => anchorSetInputSchema,
|
|
95
|
+
applyAnchorSet: () => applyAnchorSet,
|
|
93
96
|
assertBaseNotFrozen: () => assertBaseNotFrozen,
|
|
94
97
|
backlinks: () => backlinks,
|
|
95
98
|
buildContext: () => buildContext,
|
|
@@ -123,19 +126,23 @@ __export(index_exports, {
|
|
|
123
126
|
isNoDecisionRecord: () => isNoDecisionRecord,
|
|
124
127
|
isReviewTag: () => isReviewTag,
|
|
125
128
|
kbActorStampSchema: () => kbActorStampSchema,
|
|
129
|
+
kbAnchorLocatorSchema: () => kbAnchorLocatorSchema,
|
|
126
130
|
kbAnchorSchema: () => kbAnchorSchema,
|
|
127
131
|
kbAnchorSpanSchema: () => kbAnchorSpanSchema,
|
|
128
132
|
kbAnchorWriteSchema: () => kbAnchorWriteSchema,
|
|
129
133
|
kbConceptIdSchema: () => kbConceptIdSchema,
|
|
130
134
|
kbJsonSchemas: () => kbJsonSchemas,
|
|
131
135
|
kbLinkSchema: () => kbLinkSchema,
|
|
136
|
+
kbLogAnchorChangeSchema: () => kbLogAnchorChangeSchema,
|
|
132
137
|
kbLogEntrySchema: () => kbLogEntrySchema,
|
|
138
|
+
kbLogEntryWriteSchema: () => kbLogEntryWriteSchema,
|
|
133
139
|
kbRecordFrontmatterSchema: () => kbRecordFrontmatterSchema,
|
|
134
140
|
kbSourceSchema: () => kbSourceSchema,
|
|
135
141
|
kbVerifiedEventSchema: () => kbVerifiedEventSchema,
|
|
136
142
|
languageForFile: () => languageForFile,
|
|
137
143
|
listPins: () => listPins,
|
|
138
144
|
loadQmd: () => loadQmd,
|
|
145
|
+
locatorOf: () => locatorOf,
|
|
139
146
|
matchToDiff: () => matchToDiff,
|
|
140
147
|
matchesTags: () => matchesTags,
|
|
141
148
|
mergedContextBudgets: () => mergedContextBudgets,
|
|
@@ -347,6 +354,14 @@ var kbAnchorWriteSchema = kbAnchorSchema.superRefine((anchor, ctx) => {
|
|
|
347
354
|
});
|
|
348
355
|
}
|
|
349
356
|
});
|
|
357
|
+
var kbAnchorLocatorSchema = kbAnchorSchema.pick({
|
|
358
|
+
file: true,
|
|
359
|
+
symbol: true,
|
|
360
|
+
span: true,
|
|
361
|
+
side: true,
|
|
362
|
+
repo: true,
|
|
363
|
+
ref: true
|
|
364
|
+
});
|
|
350
365
|
var kbLinkSchema = import_zod.z.object({
|
|
351
366
|
target: import_zod.z.string().min(1),
|
|
352
367
|
rel: import_zod.z.string().min(1)
|
|
@@ -433,6 +448,7 @@ var Fault = /* @__PURE__ */ ((Fault2) => {
|
|
|
433
448
|
})(Fault || {});
|
|
434
449
|
var ErrorTypes = /* @__PURE__ */ ((ErrorTypes2) => {
|
|
435
450
|
ErrorTypes2["KbRecordAlreadyExists"] = "KbRecordAlreadyExists";
|
|
451
|
+
ErrorTypes2["KbAnchorSetDuplicate"] = "KbAnchorSetDuplicate";
|
|
436
452
|
ErrorTypes2["KbClassifyInput"] = "KbClassifyInput";
|
|
437
453
|
ErrorTypes2["KbFlagConflict"] = "KbFlagConflict";
|
|
438
454
|
ErrorTypes2["KbInvalidActor"] = "KbInvalidActor";
|
|
@@ -2653,7 +2669,12 @@ var import_node_path6 = require("path");
|
|
|
2653
2669
|
// src/kb-log.ts
|
|
2654
2670
|
var import_zod3 = require("zod");
|
|
2655
2671
|
var LOG_FILE = "log.jsonl";
|
|
2656
|
-
var
|
|
2672
|
+
var kbLogAnchorChangeSchema = import_zod3.z.object({
|
|
2673
|
+
op: import_zod3.z.enum(["move", "add", "drop"]),
|
|
2674
|
+
from: kbAnchorLocatorSchema.optional(),
|
|
2675
|
+
to: kbAnchorLocatorSchema.optional()
|
|
2676
|
+
}).strict();
|
|
2677
|
+
var kbLogEntryFields = import_zod3.z.object({
|
|
2657
2678
|
// Validated, not just `min(1)`: `at` is a sort key (see `parseLog`
|
|
2658
2679
|
// below), and a value that isn't actually chronological — a Unix
|
|
2659
2680
|
// timestamp, a human-typed date, garbage — would sort wrong without
|
|
@@ -2670,10 +2691,20 @@ var kbLogEntrySchema = import_zod3.z.object({
|
|
|
2670
2691
|
* The operation's other end, where it has one: a second concept id for
|
|
2671
2692
|
* supersession, the other base's path for promotion.
|
|
2672
2693
|
*/
|
|
2673
|
-
target: import_zod3.z.string().min(1).optional()
|
|
2674
|
-
|
|
2694
|
+
target: import_zod3.z.string().min(1).optional(),
|
|
2695
|
+
/**
|
|
2696
|
+
* Why the operation was performed, where the operation demands one.
|
|
2697
|
+
* `anchor-set` does: a pointer moved by a reader is only auditable if
|
|
2698
|
+
* the reading is recorded beside it.
|
|
2699
|
+
*/
|
|
2700
|
+
reason: import_zod3.z.string().min(1).optional(),
|
|
2701
|
+
/** What `anchor-set` changed, derived from the record before and after. */
|
|
2702
|
+
anchors: import_zod3.z.array(kbLogAnchorChangeSchema).optional()
|
|
2703
|
+
});
|
|
2704
|
+
var kbLogEntrySchema = kbLogEntryFields.passthrough();
|
|
2705
|
+
var kbLogEntryWriteSchema = kbLogEntryFields.strict();
|
|
2675
2706
|
function renderLogEntry(entry) {
|
|
2676
|
-
return `${JSON.stringify(
|
|
2707
|
+
return `${JSON.stringify(kbLogEntryWriteSchema.parse(entry))}
|
|
2677
2708
|
`;
|
|
2678
2709
|
}
|
|
2679
2710
|
var CONFLICT_MARKER = /^(<{7}|\|{7}|={7}|>{7})/;
|
|
@@ -3506,23 +3537,31 @@ var KbStore = class {
|
|
|
3506
3537
|
);
|
|
3507
3538
|
}
|
|
3508
3539
|
/**
|
|
3509
|
-
* Replaces a record's anchors
|
|
3510
|
-
*
|
|
3511
|
-
*
|
|
3512
|
-
*
|
|
3513
|
-
* stale entries the resolution pass deliberately dropped.
|
|
3514
|
-
*
|
|
3515
|
-
* Through the write schema: this is a write, and a defect a hand-edit put in
|
|
3516
|
-
* the frontmatter must not be published back out under an actor stamp.
|
|
3540
|
+
* Replaces a record's anchors, preserving everything else. An array is the
|
|
3541
|
+
* whole set; a function is a patch and runs inside the mutation, against
|
|
3542
|
+
* the anchors the record holds then — see
|
|
3543
|
+
* `decision.anchor-update-patch-inside-mutation`.
|
|
3517
3544
|
*/
|
|
3518
3545
|
async updateAnchors(bundlePath2, conceptId2, anchors, actor = "unknown") {
|
|
3519
3546
|
assertActor(actor);
|
|
3520
|
-
|
|
3547
|
+
let entry = {
|
|
3548
|
+
operation: "anchor-resolve",
|
|
3549
|
+
by: actor
|
|
3550
|
+
};
|
|
3521
3551
|
return this.mutate(
|
|
3522
3552
|
bundlePath2,
|
|
3523
3553
|
conceptId2,
|
|
3524
|
-
(frontmatter) =>
|
|
3525
|
-
|
|
3554
|
+
(frontmatter) => {
|
|
3555
|
+
const write = typeof anchors === "function" ? anchors(frontmatter.strauss_anchors ?? []) : { anchors };
|
|
3556
|
+
if (write.log) entry = { ...write.log, by: actor };
|
|
3557
|
+
return {
|
|
3558
|
+
...frontmatter,
|
|
3559
|
+
strauss_anchors: write.anchors.map(
|
|
3560
|
+
(anchor) => kbAnchorWriteSchema.parse(anchor)
|
|
3561
|
+
)
|
|
3562
|
+
};
|
|
3563
|
+
},
|
|
3564
|
+
() => entry
|
|
3526
3565
|
);
|
|
3527
3566
|
}
|
|
3528
3567
|
/**
|
|
@@ -3976,7 +4015,10 @@ ${answer}
|
|
|
3976
4015
|
throw new KbWriteConflictError(conceptId2);
|
|
3977
4016
|
}
|
|
3978
4017
|
await this.publish(target, contents, true, conceptId2);
|
|
3979
|
-
await this.record(this.root(bundlePath2), {
|
|
4018
|
+
await this.record(this.root(bundlePath2), {
|
|
4019
|
+
...typeof entry === "function" ? entry() : entry,
|
|
4020
|
+
conceptId: conceptId2
|
|
4021
|
+
});
|
|
3980
4022
|
return { conceptId: conceptId2, frontmatter, body };
|
|
3981
4023
|
}
|
|
3982
4024
|
/**
|
|
@@ -4193,6 +4235,107 @@ function assertActor(actor, { named = false } = {}) {
|
|
|
4193
4235
|
|
|
4194
4236
|
// src/compose.ts
|
|
4195
4237
|
var import_zod4 = require("zod");
|
|
4238
|
+
|
|
4239
|
+
// src/anchors/errors.ts
|
|
4240
|
+
function locatorText(locator) {
|
|
4241
|
+
const span2 = locator.span ? `:${locator.span.start}-${locator.span.end}` : "";
|
|
4242
|
+
const symbol = locator.symbol ? `:${cap(locator.symbol)}` : "";
|
|
4243
|
+
const repo = locator.repo ? `${cap(locator.repo)}@` : "";
|
|
4244
|
+
const ref = locator.ref ? `@${cap(locator.ref)}` : "";
|
|
4245
|
+
return `${repo}${cap(locator.file)}${symbol}${span2}${ref}`;
|
|
4246
|
+
}
|
|
4247
|
+
var FIELD_CAP = 120;
|
|
4248
|
+
function cap(value) {
|
|
4249
|
+
return value.length > FIELD_CAP ? `${value.slice(0, FIELD_CAP - 1)}\u2026` : value;
|
|
4250
|
+
}
|
|
4251
|
+
var KbAnchorSetDuplicateError = class extends BaseError {
|
|
4252
|
+
constructor(locator) {
|
|
4253
|
+
super({
|
|
4254
|
+
message: `kb: ${locator} appears twice in this set \u2014 a record holds each pointer once`,
|
|
4255
|
+
errorType: "KbAnchorSetDuplicate" /* KbAnchorSetDuplicate */,
|
|
4256
|
+
code: 400,
|
|
4257
|
+
fault: "User" /* User */,
|
|
4258
|
+
retriable: false,
|
|
4259
|
+
reportToUser: true,
|
|
4260
|
+
details: { locator, action: "refused" }
|
|
4261
|
+
});
|
|
4262
|
+
this.locator = locator;
|
|
4263
|
+
}
|
|
4264
|
+
locator;
|
|
4265
|
+
};
|
|
4266
|
+
|
|
4267
|
+
// src/anchors/apply.ts
|
|
4268
|
+
var LOCATOR_FIELDS = [
|
|
4269
|
+
"file",
|
|
4270
|
+
"symbol",
|
|
4271
|
+
"span",
|
|
4272
|
+
"side",
|
|
4273
|
+
"repo",
|
|
4274
|
+
"ref"
|
|
4275
|
+
];
|
|
4276
|
+
function applyAnchorSet(current, incoming) {
|
|
4277
|
+
const anchors = incoming.map((anchor) => ({ ...anchor }));
|
|
4278
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4279
|
+
for (const anchor of anchors) {
|
|
4280
|
+
const key2 = locatorKey(anchor);
|
|
4281
|
+
if (seen.has(key2)) {
|
|
4282
|
+
throw new KbAnchorSetDuplicateError(locatorText(locatorOf(anchor)));
|
|
4283
|
+
}
|
|
4284
|
+
seen.add(key2);
|
|
4285
|
+
}
|
|
4286
|
+
return { anchors, changes: diff(current, anchors) };
|
|
4287
|
+
}
|
|
4288
|
+
function diff(current, next) {
|
|
4289
|
+
const before = new Map(
|
|
4290
|
+
current.filter((anchor) => anchor.hash).map((a) => [a.hash, a])
|
|
4291
|
+
);
|
|
4292
|
+
const beforeLocators = new Map(current.map((a) => [locatorKey(a), a]));
|
|
4293
|
+
const afterLocators = new Set(next.map((anchor) => locatorKey(anchor)));
|
|
4294
|
+
const moved = /* @__PURE__ */ new Set();
|
|
4295
|
+
const changes = [];
|
|
4296
|
+
for (const anchor of next) {
|
|
4297
|
+
const source = anchor.hash ? before.get(anchor.hash) : void 0;
|
|
4298
|
+
if (source) {
|
|
4299
|
+
if (locatorKey(source) === locatorKey(anchor)) continue;
|
|
4300
|
+
moved.add(locatorKey(source));
|
|
4301
|
+
changes.push({
|
|
4302
|
+
op: "move",
|
|
4303
|
+
from: locatorOf(source),
|
|
4304
|
+
to: locatorOf(anchor)
|
|
4305
|
+
});
|
|
4306
|
+
continue;
|
|
4307
|
+
}
|
|
4308
|
+
if (beforeLocators.has(locatorKey(anchor))) continue;
|
|
4309
|
+
changes.push({ op: "add", to: locatorOf(anchor) });
|
|
4310
|
+
}
|
|
4311
|
+
for (const anchor of current) {
|
|
4312
|
+
const key2 = locatorKey(anchor);
|
|
4313
|
+
if (afterLocators.has(key2) || moved.has(key2)) continue;
|
|
4314
|
+
changes.push({ op: "drop", from: locatorOf(anchor) });
|
|
4315
|
+
}
|
|
4316
|
+
return changes;
|
|
4317
|
+
}
|
|
4318
|
+
function locatorOf(anchor) {
|
|
4319
|
+
return kbAnchorLocatorSchema.parse(
|
|
4320
|
+
Object.fromEntries(
|
|
4321
|
+
LOCATOR_FIELDS.flatMap(
|
|
4322
|
+
(field) => anchor[field] === void 0 ? [] : [[field, anchor[field]]]
|
|
4323
|
+
)
|
|
4324
|
+
)
|
|
4325
|
+
);
|
|
4326
|
+
}
|
|
4327
|
+
function locatorKey(anchor) {
|
|
4328
|
+
return JSON.stringify([
|
|
4329
|
+
anchor.file,
|
|
4330
|
+
anchor.symbol ?? "",
|
|
4331
|
+
anchor.span ? `${anchor.span.start}-${anchor.span.end}` : "",
|
|
4332
|
+
anchor.side ?? "new",
|
|
4333
|
+
anchor.repo === void 0 ? "" : normalizeRepoUrl(anchor.repo),
|
|
4334
|
+
anchor.ref ?? ""
|
|
4335
|
+
]);
|
|
4336
|
+
}
|
|
4337
|
+
|
|
4338
|
+
// src/compose.ts
|
|
4196
4339
|
var composeLinkSchema = import_zod4.z.object({
|
|
4197
4340
|
target: kbConceptIdSchema,
|
|
4198
4341
|
rel: import_zod4.z.enum(KB_LINK_RELS)
|
|
@@ -4264,7 +4407,9 @@ function composeRecord(type, input, writtenBy, writtenAt) {
|
|
|
4264
4407
|
strauss_status: spec.initialStatus
|
|
4265
4408
|
};
|
|
4266
4409
|
if (parsed.stale_after) frontmatter.stale_after = parsed.stale_after;
|
|
4267
|
-
if (parsed.anchors?.length)
|
|
4410
|
+
if (parsed.anchors?.length) {
|
|
4411
|
+
frontmatter.strauss_anchors = applyAnchorSet([], parsed.anchors).anchors;
|
|
4412
|
+
}
|
|
4268
4413
|
if (parsed.verify?.length) frontmatter.strauss_verify = parsed.verify;
|
|
4269
4414
|
if (parsed.tags?.length) frontmatter.tags = parsed.tags;
|
|
4270
4415
|
if (parsed.sources?.length) frontmatter.sources = parsed.sources;
|
|
@@ -5959,14 +6104,117 @@ async function readSources(anchors, root, offline) {
|
|
|
5959
6104
|
return sources;
|
|
5960
6105
|
}
|
|
5961
6106
|
|
|
5962
|
-
// src/commands/
|
|
6107
|
+
// src/commands/anchor-set/model.ts
|
|
5963
6108
|
var import_zod10 = require("zod");
|
|
6109
|
+
var anchorSetInputSchema = import_zod10.z.object({
|
|
6110
|
+
reason: import_zod10.z.string().refine((text) => text.trim().length > 0, {
|
|
6111
|
+
message: "reason must say what was reviewed"
|
|
6112
|
+
}).describe(
|
|
6113
|
+
"What the reviewer read that makes these the right pointers. Recorded in the log."
|
|
6114
|
+
),
|
|
6115
|
+
anchors: import_zod10.z.array(kbAnchorWriteSchema).min(1).describe(
|
|
6116
|
+
"The complete new anchor set. Carry an anchor's hash forward to keep drift visible until the new code is read."
|
|
6117
|
+
)
|
|
6118
|
+
}).strict();
|
|
6119
|
+
var anchorSetCommandInput = import_zod10.z.object({
|
|
6120
|
+
bundlePath,
|
|
6121
|
+
conceptId,
|
|
6122
|
+
input: anchorSetInputSchema,
|
|
6123
|
+
resolve: import_zod10.z.boolean().optional().describe(
|
|
6124
|
+
"Also resolve and stamp every anchor against the current code, as anchor-resolve --rebaseline does."
|
|
6125
|
+
),
|
|
6126
|
+
repoRoot: import_zod10.z.string().min(1).optional().describe(
|
|
6127
|
+
"Where the anchored source lives, for resolve. Defaults to the working directory."
|
|
6128
|
+
),
|
|
6129
|
+
offline: import_zod10.z.boolean().optional().describe("With resolve, read foreign anchors from the repo cache only.")
|
|
6130
|
+
});
|
|
6131
|
+
|
|
6132
|
+
// src/commands/anchor-set/command.ts
|
|
6133
|
+
var NOTE = "pointers only: nothing was resolved or verified. Run anchor-resolve to check the new pointers, --rebaseline to accept the code, or pass resolve to do both here.";
|
|
6134
|
+
var STAMPED_NOTE = "pointers set and stamped against the current code. Not verification: run verify separately if someone reviewed it.";
|
|
6135
|
+
var anchorSetCommand = define({
|
|
6136
|
+
name: "anchor-set",
|
|
6137
|
+
tool: "kb_anchor_set",
|
|
6138
|
+
usage: "anchor-set <concept-id> [--resolve] [--repo-root <path>] [--offline] < anchors.json",
|
|
6139
|
+
description: "Set a record's code anchors after a reviewed refactor, with a reason. The array is the whole set. With resolve, every anchor is stamped against the current code in the same call; without it, run kb_anchor_resolve next. Recorded in the log, never verification.",
|
|
6140
|
+
input: anchorSetCommandInput,
|
|
6141
|
+
fromArgv: async (argv, path, stdin) => ({
|
|
6142
|
+
bundlePath: path,
|
|
6143
|
+
conceptId: argv[1],
|
|
6144
|
+
input: JSON.parse(await stdin()),
|
|
6145
|
+
resolve: argv.includes("--resolve"),
|
|
6146
|
+
repoRoot: argvFlag(argv, "--repo-root"),
|
|
6147
|
+
offline: argv.includes("--offline")
|
|
6148
|
+
}),
|
|
6149
|
+
run: async (ctx, { bundlePath: path, conceptId: id, input, resolve: resolve7, repoRoot, offline }) => {
|
|
6150
|
+
const { store, actor } = ctx;
|
|
6151
|
+
await assertBaseNotFrozen(process.cwd(), path);
|
|
6152
|
+
let applied;
|
|
6153
|
+
const record = await store.updateAnchors(
|
|
6154
|
+
path,
|
|
6155
|
+
id,
|
|
6156
|
+
(current) => {
|
|
6157
|
+
applied = applyAnchorSet(current, input.anchors);
|
|
6158
|
+
return {
|
|
6159
|
+
anchors: applied.anchors,
|
|
6160
|
+
log: {
|
|
6161
|
+
operation: "anchor-set",
|
|
6162
|
+
reason: input.reason,
|
|
6163
|
+
anchors: applied.changes
|
|
6164
|
+
}
|
|
6165
|
+
};
|
|
6166
|
+
},
|
|
6167
|
+
actor
|
|
6168
|
+
);
|
|
6169
|
+
const changes = applied?.changes ?? [];
|
|
6170
|
+
if (!resolve7) {
|
|
6171
|
+
return {
|
|
6172
|
+
conceptId: id,
|
|
6173
|
+
reason: input.reason,
|
|
6174
|
+
changes,
|
|
6175
|
+
anchors: record.frontmatter.strauss_anchors ?? [],
|
|
6176
|
+
baseline: "unchanged",
|
|
6177
|
+
note: NOTE
|
|
6178
|
+
};
|
|
6179
|
+
}
|
|
6180
|
+
const resolved = await anchorResolveCommand.run(
|
|
6181
|
+
ctx,
|
|
6182
|
+
anchorResolveCommand.input.parse({
|
|
6183
|
+
bundlePath: path,
|
|
6184
|
+
conceptId: id,
|
|
6185
|
+
rebaseline: true,
|
|
6186
|
+
...repoRoot ? { repoRoot } : {},
|
|
6187
|
+
...offline ? { offline } : {}
|
|
6188
|
+
})
|
|
6189
|
+
);
|
|
6190
|
+
const after = await store.read(path, id);
|
|
6191
|
+
return {
|
|
6192
|
+
conceptId: id,
|
|
6193
|
+
reason: input.reason,
|
|
6194
|
+
changes,
|
|
6195
|
+
anchors: after?.frontmatter.strauss_anchors ?? [],
|
|
6196
|
+
baseline: "stamped",
|
|
6197
|
+
resolved: resolved.results,
|
|
6198
|
+
note: STAMPED_NOTE
|
|
6199
|
+
};
|
|
6200
|
+
},
|
|
6201
|
+
// With `resolve`, a pointer that names nothing is a failed set, not a
|
|
6202
|
+
// finding to read later. A remote nothing could reach was never checked, so
|
|
6203
|
+
// it does not fail — the same line anchor-resolve draws.
|
|
6204
|
+
failsWhen: (result) => (result.resolved ?? []).some((entry) => {
|
|
6205
|
+
const { state, reason } = entry;
|
|
6206
|
+
return state === "unresolved" && !isUncheckedReason(reason);
|
|
6207
|
+
})
|
|
6208
|
+
});
|
|
6209
|
+
|
|
6210
|
+
// src/commands/answer.ts
|
|
6211
|
+
var import_zod11 = require("zod");
|
|
5964
6212
|
var answerCommand = define({
|
|
5965
6213
|
name: "answer",
|
|
5966
6214
|
tool: "kb_answer",
|
|
5967
6215
|
usage: "answer <concept-id> <answer...>",
|
|
5968
6216
|
description: "Resolve an open question: set status, stamp who and when, append an Answer section. If the answer overturns a decision or assumption, supersede that record explicitly.",
|
|
5969
|
-
input:
|
|
6217
|
+
input: import_zod11.z.object({ bundlePath, conceptId, answer: import_zod11.z.string().min(1) }),
|
|
5970
6218
|
fromArgv: (argv, path) => ({
|
|
5971
6219
|
bundlePath: path,
|
|
5972
6220
|
conceptId: argv[1],
|
|
@@ -5980,27 +6228,27 @@ var answerCommand = define({
|
|
|
5980
6228
|
});
|
|
5981
6229
|
|
|
5982
6230
|
// src/commands/backlinks.ts
|
|
5983
|
-
var
|
|
6231
|
+
var import_zod12 = require("zod");
|
|
5984
6232
|
var backlinksCommand = define({
|
|
5985
6233
|
name: "backlinks",
|
|
5986
6234
|
tool: "kb_backlinks",
|
|
5987
6235
|
usage: "backlinks <concept-id>",
|
|
5988
6236
|
description: "Who points at this record: every inbound typed causal link (`strauss_links`), one hop, every rel including `related_to`, each with its rel and the standing of the record that made it. Use it when you need the exact edges \u2014 reviewing or renaming a record.",
|
|
5989
|
-
input:
|
|
6237
|
+
input: import_zod12.z.object({ bundlePath, conceptId }),
|
|
5990
6238
|
fromArgv: (argv, path) => ({ bundlePath: path, conceptId: argv[1] }),
|
|
5991
6239
|
run: async ({ store }, { bundlePath: path, conceptId: id }) => store.backlinks(path, id)
|
|
5992
6240
|
});
|
|
5993
6241
|
|
|
5994
6242
|
// src/commands/catalog.ts
|
|
5995
|
-
var
|
|
6243
|
+
var import_zod13 = require("zod");
|
|
5996
6244
|
var catalogCommand = define({
|
|
5997
6245
|
name: "catalog",
|
|
5998
6246
|
tool: "kb_catalog",
|
|
5999
6247
|
usage: "catalog [type] [--tag T]...",
|
|
6000
6248
|
description: "Lists every record as one line \u2014 concept id, type, title, standing, and a stale flag \u2014 at roughly thirty tokens each. Pick this over kb_load once kb_load refuses: kb_catalog never refuses. Superseded records show only their replacement; fetch bodies with kb_load, kb_pack, kb_query, or kb_trace.",
|
|
6001
|
-
input:
|
|
6249
|
+
input: import_zod13.z.object({
|
|
6002
6250
|
bundlePath,
|
|
6003
|
-
type:
|
|
6251
|
+
type: import_zod13.z.enum(KB_RECORD_TYPES).optional(),
|
|
6004
6252
|
tags: TAGS
|
|
6005
6253
|
}),
|
|
6006
6254
|
fromArgv: (argv, path) => {
|
|
@@ -6072,7 +6320,7 @@ function count(value, noun) {
|
|
|
6072
6320
|
var import_node_buffer = require("buffer");
|
|
6073
6321
|
var import_promises10 = require("fs/promises");
|
|
6074
6322
|
var import_node_path12 = require("path");
|
|
6075
|
-
var
|
|
6323
|
+
var import_zod16 = require("zod");
|
|
6076
6324
|
|
|
6077
6325
|
// src/drift/moved.ts
|
|
6078
6326
|
var import_promises9 = require("fs/promises");
|
|
@@ -6409,7 +6657,7 @@ function claimOf(record) {
|
|
|
6409
6657
|
}
|
|
6410
6658
|
|
|
6411
6659
|
// src/commands/match/command.ts
|
|
6412
|
-
var
|
|
6660
|
+
var import_zod15 = require("zod");
|
|
6413
6661
|
|
|
6414
6662
|
// src/commands/match/errors.ts
|
|
6415
6663
|
var KbMatchInputError = class extends BaseError {
|
|
@@ -6429,21 +6677,21 @@ var KbMatchInputError = class extends BaseError {
|
|
|
6429
6677
|
};
|
|
6430
6678
|
|
|
6431
6679
|
// src/commands/match/model.ts
|
|
6432
|
-
var
|
|
6433
|
-
var diffHunkSchema =
|
|
6434
|
-
startLine:
|
|
6435
|
-
endLine:
|
|
6436
|
-
side:
|
|
6680
|
+
var import_zod14 = require("zod");
|
|
6681
|
+
var diffHunkSchema = import_zod14.z.object({
|
|
6682
|
+
startLine: import_zod14.z.number().int().positive(),
|
|
6683
|
+
endLine: import_zod14.z.number().int().positive(),
|
|
6684
|
+
side: import_zod14.z.enum(["old", "new"]).optional()
|
|
6437
6685
|
}).passthrough();
|
|
6438
|
-
var diffFileSchema =
|
|
6439
|
-
filePath:
|
|
6440
|
-
hunks:
|
|
6686
|
+
var diffFileSchema = import_zod14.z.object({
|
|
6687
|
+
filePath: import_zod14.z.string().min(1).describe("Repo-relative, spelled the way anchors are."),
|
|
6688
|
+
hunks: import_zod14.z.array(diffHunkSchema)
|
|
6441
6689
|
});
|
|
6442
|
-
var symbolRangeSchema =
|
|
6443
|
-
file:
|
|
6444
|
-
symbol:
|
|
6445
|
-
startLine:
|
|
6446
|
-
endLine:
|
|
6690
|
+
var symbolRangeSchema = import_zod14.z.object({
|
|
6691
|
+
file: import_zod14.z.string().min(1),
|
|
6692
|
+
symbol: import_zod14.z.string().min(1),
|
|
6693
|
+
startLine: import_zod14.z.number().int().positive(),
|
|
6694
|
+
endLine: import_zod14.z.number().int().positive()
|
|
6447
6695
|
});
|
|
6448
6696
|
|
|
6449
6697
|
// src/commands/match/parse-unified-diff.ts
|
|
@@ -6692,17 +6940,17 @@ var matchCommand = define({
|
|
|
6692
6940
|
tool: "kb_match",
|
|
6693
6941
|
usage: "match --git <base>..<head> | --stdin [--repo-root <path>] [--offline] [--include-non-current]",
|
|
6694
6942
|
description: "Which records sit on each changed hunk: the anchored records per file range, current first, each with its standing and the anchor that matched. kb_load hands over a whole base; this narrows a diff. Symbol ranges resolve from repoRoot when omitted; non-current records need includeNonCurrent.",
|
|
6695
|
-
input:
|
|
6943
|
+
input: import_zod15.z.object({
|
|
6696
6944
|
bundlePath,
|
|
6697
|
-
files:
|
|
6698
|
-
symbolRanges:
|
|
6945
|
+
files: import_zod15.z.array(diffFileSchema).describe("The changed files, each with its post-change line ranges."),
|
|
6946
|
+
symbolRanges: import_zod15.z.array(symbolRangeSchema).optional().describe(
|
|
6699
6947
|
"Symbol spans the caller already has. Resolved from repoRoot when omitted."
|
|
6700
6948
|
),
|
|
6701
6949
|
repoRoot: REPO_ROOT,
|
|
6702
|
-
offline:
|
|
6950
|
+
offline: import_zod15.z.boolean().optional().describe(
|
|
6703
6951
|
"Resolve symbol ranges from what is already on disk, never fetching a grammar."
|
|
6704
6952
|
),
|
|
6705
|
-
includeNonCurrent:
|
|
6953
|
+
includeNonCurrent: import_zod15.z.boolean().optional().describe(
|
|
6706
6954
|
"Return superseded, rejected and unsettled records too, each carrying its standing."
|
|
6707
6955
|
)
|
|
6708
6956
|
}),
|
|
@@ -6716,11 +6964,11 @@ var matchCommand = define({
|
|
|
6716
6964
|
...argv.includes("--include-non-current") ? { includeNonCurrent: true } : {}
|
|
6717
6965
|
};
|
|
6718
6966
|
if (range !== void 0) {
|
|
6719
|
-
const
|
|
6720
|
-
if (!
|
|
6721
|
-
throw new KbMatchInputError(`--git ${range} ${REFUSED[
|
|
6967
|
+
const diff2 = await readRangeDiff(repoRoot ?? process.cwd(), range);
|
|
6968
|
+
if (!diff2.ok) {
|
|
6969
|
+
throw new KbMatchInputError(`--git ${range} ${REFUSED[diff2.reason]}`);
|
|
6722
6970
|
}
|
|
6723
|
-
return { ...base2, files: parseUnifiedDiff(
|
|
6971
|
+
return { ...base2, files: parseUnifiedDiff(diff2.text) };
|
|
6724
6972
|
}
|
|
6725
6973
|
if (!argv.includes("--stdin")) {
|
|
6726
6974
|
throw new KbMatchInputError(
|
|
@@ -6806,22 +7054,22 @@ function project(match, ranges, all) {
|
|
|
6806
7054
|
|
|
6807
7055
|
// src/commands/classify.ts
|
|
6808
7056
|
var classifyFileSchema = diffFileSchema.extend({
|
|
6809
|
-
hunks:
|
|
6810
|
-
diffHunkSchema.extend({ lines:
|
|
7057
|
+
hunks: import_zod16.z.array(
|
|
7058
|
+
diffHunkSchema.extend({ lines: import_zod16.z.array(import_zod16.z.string()).optional() })
|
|
6811
7059
|
),
|
|
6812
|
-
renamedFrom:
|
|
6813
|
-
similarity:
|
|
7060
|
+
renamedFrom: import_zod16.z.string().min(1).optional().describe("Where `git diff -M` says the path came from."),
|
|
7061
|
+
similarity: import_zod16.z.number().min(0).max(100).optional()
|
|
6814
7062
|
});
|
|
6815
7063
|
var classifyCommand = define({
|
|
6816
7064
|
name: "classify",
|
|
6817
7065
|
tool: "kb_classify",
|
|
6818
7066
|
usage: "classify --git <base>..<head> | --stdin [--repo-root <path>] [--offline]",
|
|
6819
7067
|
description: "What kind of change each file carries: test, config, ci, docs, lockfile, generated, boilerplate, rename or source, with the rule that decided it. Derived from the diff and never stored; a `review:generated`, `review:boilerplate` or `review:move` fact anchored on a file overrides the heuristic. kb_match says what sits on a hunk; this says whether to read it.",
|
|
6820
|
-
input:
|
|
7068
|
+
input: import_zod16.z.object({
|
|
6821
7069
|
bundlePath,
|
|
6822
|
-
files:
|
|
7070
|
+
files: import_zod16.z.array(classifyFileSchema).describe("The changed files, each with its line ranges."),
|
|
6823
7071
|
repoRoot: REPO_ROOT,
|
|
6824
|
-
offline:
|
|
7072
|
+
offline: import_zod16.z.boolean().optional().describe(
|
|
6825
7073
|
"Resolve symbol ranges from what is already on disk, never fetching a grammar."
|
|
6826
7074
|
)
|
|
6827
7075
|
}),
|
|
@@ -6834,15 +7082,15 @@ var classifyCommand = define({
|
|
|
6834
7082
|
...argv.includes("--offline") ? { offline: true } : {}
|
|
6835
7083
|
};
|
|
6836
7084
|
if (range !== void 0) {
|
|
6837
|
-
const
|
|
6838
|
-
if (!
|
|
7085
|
+
const diff2 = await readRangeDiff(repoRoot ?? process.cwd(), range);
|
|
7086
|
+
if (!diff2.ok) {
|
|
6839
7087
|
throw new KbClassifyInputError(
|
|
6840
|
-
`--git ${range} ${REFUSED2[
|
|
7088
|
+
`--git ${range} ${REFUSED2[diff2.reason]}`
|
|
6841
7089
|
);
|
|
6842
7090
|
}
|
|
6843
7091
|
return {
|
|
6844
7092
|
...base2,
|
|
6845
|
-
files: parseUnifiedDiff(
|
|
7093
|
+
files: parseUnifiedDiff(diff2.text, {
|
|
6846
7094
|
keepEmpty: true,
|
|
6847
7095
|
withLines: true
|
|
6848
7096
|
})
|
|
@@ -6932,29 +7180,29 @@ function renderClassify(result) {
|
|
|
6932
7180
|
}
|
|
6933
7181
|
|
|
6934
7182
|
// src/commands/context.ts
|
|
6935
|
-
var
|
|
7183
|
+
var import_zod17 = require("zod");
|
|
6936
7184
|
var contextCommand = define({
|
|
6937
7185
|
name: "context",
|
|
6938
7186
|
tool: "kb_context",
|
|
6939
7187
|
usage: "context [--profile NAME] [--budget N] [--full-under N] [--exclude-tag T]... [--format json] [--event NAME]",
|
|
6940
7188
|
description: "Index block of pinned bases (ids, titles, standing) for injection at context birth. Takes no bundlePath \u2014 reads the workspace pin manifests. Empty when nothing is pinned; refuses over budget rather than truncating. Budget precedence: flags, then the manifest `context[profile]` over `context.default`, then the built-in profile, then package defaults.",
|
|
6941
|
-
input:
|
|
6942
|
-
budgetTokens:
|
|
7189
|
+
input: import_zod17.z.object({
|
|
7190
|
+
budgetTokens: import_zod17.z.number().int().positive().optional().describe(
|
|
6943
7191
|
"Ceiling on the whole emitted block; past it the command refuses with a list of bases rather than truncating. Defaults to 4000."
|
|
6944
7192
|
),
|
|
6945
|
-
fullUnderTokens:
|
|
7193
|
+
fullUnderTokens: import_zod17.z.number().int().positive().optional().describe(
|
|
6946
7194
|
"Per-base rendering threshold, applied before the budget: a base whose complete load fits under this arrives as full records instead of index lines, and the whole block still answers to budgetTokens. Off by default \u2014 index-only is the safe default at a context birth, because injected bodies outlive the qualifiers on them; the session-start profile opts tiny bases in at 1500."
|
|
6947
7195
|
),
|
|
6948
|
-
profile:
|
|
7196
|
+
profile: import_zod17.z.string().optional().describe(
|
|
6949
7197
|
"Named budget set: built-ins are session-start (full-under 1500), compact and turn (budget 2500); the manifests' `context` tables override per repo. Unknown names fall through to defaults rather than failing."
|
|
6950
7198
|
),
|
|
6951
|
-
excludeTags:
|
|
7199
|
+
excludeTags: import_zod17.z.array(import_zod17.z.string().min(1)).optional().describe(
|
|
6952
7200
|
"Frontmatter tags whose records stay out of the block. The base stays pinned and stays readable by tool; resolved like the budgets."
|
|
6953
7201
|
),
|
|
6954
|
-
format:
|
|
7202
|
+
format: import_zod17.z.enum(["markdown", "json"]).optional().describe(
|
|
6955
7203
|
"CLI envelope for hook protocols that require strict JSON on stdout. MCP callers omit this \u2014 the block itself is identical."
|
|
6956
7204
|
),
|
|
6957
|
-
event:
|
|
7205
|
+
event: import_zod17.z.string().optional().describe(
|
|
6958
7206
|
"hookEventName stamped into the JSON envelope. Only meaningful with format=json."
|
|
6959
7207
|
)
|
|
6960
7208
|
}),
|
|
@@ -6993,20 +7241,20 @@ var contextCommand = define({
|
|
|
6993
7241
|
});
|
|
6994
7242
|
|
|
6995
7243
|
// src/commands/doctor.ts
|
|
6996
|
-
var
|
|
7244
|
+
var import_zod19 = require("zod");
|
|
6997
7245
|
|
|
6998
7246
|
// src/commands/reassess.ts
|
|
6999
|
-
var
|
|
7247
|
+
var import_zod18 = require("zod");
|
|
7000
7248
|
var reassessCommand = define({
|
|
7001
7249
|
name: "reassess",
|
|
7002
7250
|
tool: "kb_reassess",
|
|
7003
7251
|
usage: "reassess <concept-id> [--repo-root <path>] [--with-diff]",
|
|
7004
7252
|
description: "One drifted record, as something to judge: its claim, each anchor's drift class, the old-vs-new span diff, and the records that depend on it. Formatting-only drift is dropped. Empty when there is nothing to reassess. Writes: relocates moved anchors, keeping their hash; never verifies, supersedes, or changes standing.",
|
|
7005
|
-
input:
|
|
7253
|
+
input: import_zod18.z.object({
|
|
7006
7254
|
bundlePath,
|
|
7007
7255
|
conceptId,
|
|
7008
7256
|
repoRoot: REPO_ROOT,
|
|
7009
|
-
withDiff:
|
|
7257
|
+
withDiff: import_zod18.z.boolean().optional().describe(
|
|
7010
7258
|
"Recover each anchor's committed span and render the diff. Reads git history."
|
|
7011
7259
|
)
|
|
7012
7260
|
}),
|
|
@@ -7151,13 +7399,13 @@ function at(file, symbol) {
|
|
|
7151
7399
|
}
|
|
7152
7400
|
|
|
7153
7401
|
// src/commands/doctor.ts
|
|
7154
|
-
var days = (what, fallback) =>
|
|
7402
|
+
var days = (what, fallback) => import_zod19.z.number().int().positive().optional().describe(`${what} Defaults to ${fallback}.`);
|
|
7155
7403
|
var doctorCommand = define({
|
|
7156
7404
|
name: "doctor",
|
|
7157
7405
|
tool: "kb_doctor",
|
|
7158
7406
|
usage: "doctor [--expiring-days N] [--unverified-days N] [--aging-days N] [--repo-root PATH] [--offline] [--strict] [--drifted [--with-diff]]",
|
|
7159
7407
|
description: "Read-only health sweep: expired, expiring, unverified, aging, orphaned, broken-supersession, superseded-but-cited, drifted and unchecked anchors. Every group is reported even when empty; nothing is written or re-stamped. `drifted` narrows it to a reassessment packet per drifted record, `with_diff` adding each anchor's old-vs-new span.",
|
|
7160
|
-
input:
|
|
7408
|
+
input: import_zod19.z.object({
|
|
7161
7409
|
bundlePath,
|
|
7162
7410
|
repoRoot: REPO_ROOT,
|
|
7163
7411
|
expiringDays: days(
|
|
@@ -7172,16 +7420,16 @@ var doctorCommand = define({
|
|
|
7172
7420
|
"How long a record may stay `open` or `proposed` before `aging` reports it, in days.",
|
|
7173
7421
|
DEFAULT_AGING_DAYS
|
|
7174
7422
|
),
|
|
7175
|
-
offline:
|
|
7423
|
+
offline: import_zod19.z.boolean().optional().describe(
|
|
7176
7424
|
"Read foreign anchors from the local repo cache only, never fetching."
|
|
7177
7425
|
),
|
|
7178
|
-
strict:
|
|
7426
|
+
strict: import_zod19.z.boolean().optional().describe(
|
|
7179
7427
|
"Turn an expired record into a non-zero exit for the CLI. No effect on the report itself."
|
|
7180
7428
|
),
|
|
7181
|
-
drifted:
|
|
7429
|
+
drifted: import_zod19.z.boolean().optional().describe(
|
|
7182
7430
|
"Report only drift, as a reassessment packet per record: claim, per-anchor class, and what depends on it."
|
|
7183
7431
|
),
|
|
7184
|
-
withDiff:
|
|
7432
|
+
withDiff: import_zod19.z.boolean().optional().describe(
|
|
7185
7433
|
"With `drifted`: recover each anchor's committed span and render the old-vs-new diff. Reads git history."
|
|
7186
7434
|
)
|
|
7187
7435
|
}),
|
|
@@ -7358,7 +7606,7 @@ function renderPackets(result) {
|
|
|
7358
7606
|
// src/commands/export.ts
|
|
7359
7607
|
var import_promises11 = require("fs/promises");
|
|
7360
7608
|
var import_node_path13 = require("path");
|
|
7361
|
-
var
|
|
7609
|
+
var import_zod20 = require("zod");
|
|
7362
7610
|
var NUMBERED = /^(\d{4})-(.+)\.md$/;
|
|
7363
7611
|
var MARKER = "<!-- strauss-kb export: ";
|
|
7364
7612
|
var exportCommand = define({
|
|
@@ -7366,10 +7614,10 @@ var exportCommand = define({
|
|
|
7366
7614
|
tool: "kb_export",
|
|
7367
7615
|
usage: "export --format madr --to <dir>",
|
|
7368
7616
|
description: "Write the base's decisions out as numbered MADR files, one per decision, for a repository that keeps ADRs of its own. Numbering is by slug, so a re-run rewrites its own files in place. A superseded decision is exported with what replaced it.",
|
|
7369
|
-
input:
|
|
7617
|
+
input: import_zod20.z.object({
|
|
7370
7618
|
bundlePath,
|
|
7371
|
-
format:
|
|
7372
|
-
to:
|
|
7619
|
+
format: import_zod20.z.enum(["madr"]).describe("Output layout. `madr` is the only one so far."),
|
|
7620
|
+
to: import_zod20.z.string().min(1).describe("Directory the ADR files are written into.")
|
|
7373
7621
|
}),
|
|
7374
7622
|
fromArgv: (argv, path) => ({
|
|
7375
7623
|
bundlePath: path,
|
|
@@ -7491,19 +7739,19 @@ function bodySections(body) {
|
|
|
7491
7739
|
}
|
|
7492
7740
|
|
|
7493
7741
|
// src/commands/impact.ts
|
|
7494
|
-
var
|
|
7742
|
+
var import_zod21 = require("zod");
|
|
7495
7743
|
var impactCommand = define({
|
|
7496
7744
|
name: "impact",
|
|
7497
7745
|
tool: "kb_impact",
|
|
7498
7746
|
usage: "impact <concept-id> [--depth N] [--rels a,b]",
|
|
7499
7747
|
description: "What breaks if this record changes: its transitive set of dependants, each with its standing. Each rel declares which of its ends depends on the other, and the walk follows each rel in its own direction. Naming `related_to` or an unknown rel in `rels` is an error. kb_backlinks gives one flat hop.",
|
|
7500
|
-
input:
|
|
7748
|
+
input: import_zod21.z.object({
|
|
7501
7749
|
bundlePath,
|
|
7502
7750
|
conceptId,
|
|
7503
|
-
depth:
|
|
7751
|
+
depth: import_zod21.z.number().int().positive().optional().describe(
|
|
7504
7752
|
"Hops out from the record. Unbounded when omitted; a walk this cuts reports truncated: true."
|
|
7505
7753
|
),
|
|
7506
|
-
rels:
|
|
7754
|
+
rels: import_zod21.z.array(import_zod21.z.enum(KB_CAUSAL_LINK_RELS)).optional().describe(
|
|
7507
7755
|
"Narrow which rels the walk follows. Defaults to every rel that carries a dependence \u2014 all but related_to."
|
|
7508
7756
|
)
|
|
7509
7757
|
}),
|
|
@@ -7524,15 +7772,15 @@ var impactCommand = define({
|
|
|
7524
7772
|
});
|
|
7525
7773
|
|
|
7526
7774
|
// src/commands/list.ts
|
|
7527
|
-
var
|
|
7775
|
+
var import_zod22 = require("zod");
|
|
7528
7776
|
var listCommand = define({
|
|
7529
7777
|
name: "list",
|
|
7530
7778
|
tool: "kb_list",
|
|
7531
7779
|
usage: "list [type] [--tag T]...",
|
|
7532
7780
|
description: "Every record, optionally one type or tag. For enumerating; use kb_query for a question.",
|
|
7533
|
-
input:
|
|
7781
|
+
input: import_zod22.z.object({
|
|
7534
7782
|
bundlePath,
|
|
7535
|
-
type:
|
|
7783
|
+
type: import_zod22.z.enum(KB_RECORD_TYPES).optional(),
|
|
7536
7784
|
tags: TAGS
|
|
7537
7785
|
}),
|
|
7538
7786
|
fromArgv: (argv, path) => {
|
|
@@ -7556,17 +7804,17 @@ var listCommand = define({
|
|
|
7556
7804
|
});
|
|
7557
7805
|
|
|
7558
7806
|
// src/commands/load.ts
|
|
7559
|
-
var
|
|
7807
|
+
var import_zod23 = require("zod");
|
|
7560
7808
|
var loadCommand = define({
|
|
7561
7809
|
name: "load",
|
|
7562
7810
|
tool: "kb_load",
|
|
7563
7811
|
usage: "load [type] [--budget N | --all] [--repo-root PATH]",
|
|
7564
7812
|
description: "Load the whole base, each record with its standing \u2014 call it first, at the point of use, since compaction drops it. Superseded records arrive as stubs; kb_trace has the history. Over budget it refuses: kb_catalog, then kb_pack, or narrow with `type`; `all` bypasses. Never read record files directly \u2014 only kb_* tools resolve supersession. `digest` stamps the base's content, so hooks know when to reload.",
|
|
7565
|
-
input:
|
|
7813
|
+
input: import_zod23.z.object({
|
|
7566
7814
|
bundlePath,
|
|
7567
|
-
type:
|
|
7568
|
-
budgetTokens:
|
|
7569
|
-
all:
|
|
7815
|
+
type: import_zod23.z.enum(KB_RECORD_TYPES).optional(),
|
|
7816
|
+
budgetTokens: import_zod23.z.number().int().positive().optional().describe("Approximate token ceiling. Defaults to 25000."),
|
|
7817
|
+
all: import_zod23.z.boolean().optional().describe(
|
|
7570
7818
|
"Loads the entire base regardless of size, bypassing the token budget; mutually exclusive with budgetTokens."
|
|
7571
7819
|
),
|
|
7572
7820
|
repoRoot: REPO_ROOT
|
|
@@ -7608,25 +7856,25 @@ var loadCommand = define({
|
|
|
7608
7856
|
});
|
|
7609
7857
|
|
|
7610
7858
|
// src/commands/log.ts
|
|
7611
|
-
var
|
|
7859
|
+
var import_zod24 = require("zod");
|
|
7612
7860
|
var logCommand = define({
|
|
7613
7861
|
name: "log",
|
|
7614
7862
|
tool: "kb_log",
|
|
7615
7863
|
usage: "log",
|
|
7616
7864
|
description: "Who touched what, and when. Append-only; malformed lines are reported, never repaired.",
|
|
7617
|
-
input:
|
|
7865
|
+
input: import_zod24.z.object({ bundlePath }),
|
|
7618
7866
|
fromArgv: (_argv, path) => ({ bundlePath: path }),
|
|
7619
7867
|
run: ({ store }, { bundlePath: path }) => store.readLog(path)
|
|
7620
7868
|
});
|
|
7621
7869
|
|
|
7622
7870
|
// src/commands/no-decision.ts
|
|
7623
|
-
var
|
|
7871
|
+
var import_zod25 = require("zod");
|
|
7624
7872
|
var noDecisionCommand = define({
|
|
7625
7873
|
name: "no-decision",
|
|
7626
7874
|
tool: "kb_no_decision",
|
|
7627
7875
|
usage: "no-decision <reason...>",
|
|
7628
7876
|
description: "Record in one sentence that a piece of work had nothing to decide. Idempotent.",
|
|
7629
|
-
input:
|
|
7877
|
+
input: import_zod25.z.object({ bundlePath, reason: import_zod25.z.string().min(1) }),
|
|
7630
7878
|
fromArgv: (argv, path) => ({
|
|
7631
7879
|
bundlePath: path,
|
|
7632
7880
|
reason: argv.slice(1).join(" ").trim()
|
|
@@ -7643,20 +7891,20 @@ var noDecisionCommand = define({
|
|
|
7643
7891
|
});
|
|
7644
7892
|
|
|
7645
7893
|
// src/commands/pack.ts
|
|
7646
|
-
var
|
|
7894
|
+
var import_zod26 = require("zod");
|
|
7647
7895
|
var packCommand = define({
|
|
7648
7896
|
name: "pack",
|
|
7649
7897
|
tool: "kb_pack",
|
|
7650
7898
|
usage: "pack <conceptId> [--hops N] [--max-nodes N] [--budget N]",
|
|
7651
7899
|
description: "Bounded neighbourhood around one record: within `hops`, ranked, cut to `maxNodes`, with every cut record named under Excluded. Use when the base is over kb_load's budget and the work centres on a record you can name. Refuses over budget rather than truncating. Everything below the header is byte-stable across runs. Resolves supersession like kb_load.",
|
|
7652
|
-
input:
|
|
7900
|
+
input: import_zod26.z.object({
|
|
7653
7901
|
bundlePath,
|
|
7654
7902
|
conceptId,
|
|
7655
|
-
hops:
|
|
7656
|
-
maxNodes:
|
|
7903
|
+
hops: import_zod26.z.number().int().positive().optional().describe("How far from the root the walk may reach. Defaults to 2."),
|
|
7904
|
+
maxNodes: import_zod26.z.number().int().positive().optional().describe(
|
|
7657
7905
|
"How many records the pack may hold, root included. Defaults to 20."
|
|
7658
7906
|
),
|
|
7659
|
-
budgetTokens:
|
|
7907
|
+
budgetTokens: import_zod26.z.number().int().positive().optional().describe(
|
|
7660
7908
|
"Approximate token ceiling over what is actually emitted. Defaults to 25000."
|
|
7661
7909
|
)
|
|
7662
7910
|
}),
|
|
@@ -7743,22 +7991,22 @@ function warningLabel(warning) {
|
|
|
7743
7991
|
}
|
|
7744
7992
|
|
|
7745
7993
|
// src/commands/pin.ts
|
|
7746
|
-
var
|
|
7994
|
+
var import_zod27 = require("zod");
|
|
7747
7995
|
var pinCommand = define({
|
|
7748
7996
|
name: "pin",
|
|
7749
7997
|
tool: "kb_pin",
|
|
7750
7998
|
usage: "pin [bundle-path] [--mode full|index] [--profiles a,b] [--local|--user] [--frozen|--unfreeze]",
|
|
7751
7999
|
description: "Pin a base into a workspace manifest so kb_context surfaces it. Layers, nearest wins: project `.strauss/kb-pins.json` (default), `--local` (personal, gitignored), `--user` (`~/.strauss`). Idempotent; `--mode full|index`, `--profiles`, `--frozen`/`--unfreeze` update only those fields. A path with no records pins with a warning. Never touches the base itself.",
|
|
7752
|
-
input:
|
|
8000
|
+
input: import_zod27.z.object({
|
|
7753
8001
|
bundlePath,
|
|
7754
|
-
mode:
|
|
8002
|
+
mode: import_zod27.z.enum(["full", "index"]).optional().describe(
|
|
7755
8003
|
"full: always emit this base's records whole (still under the block budget); index: never upgrade. Absent: the profile's full-under threshold decides."
|
|
7756
8004
|
),
|
|
7757
|
-
profiles:
|
|
7758
|
-
layer:
|
|
8005
|
+
profiles: import_zod27.z.array(import_zod27.z.string()).optional().describe("Context profiles this pin surfaces in. Absent: all of them."),
|
|
8006
|
+
layer: import_zod27.z.enum(["project", "local", "user"]).optional().describe(
|
|
7759
8007
|
"Which manifest to write: project (committed, default), local (personal, gitignored), user (~/.strauss, every workspace)."
|
|
7760
8008
|
),
|
|
7761
|
-
frozen:
|
|
8009
|
+
frozen: import_zod27.z.boolean().optional().describe(
|
|
7762
8010
|
"true: the base is concluded \u2014 writes against it refuse while pinned. false: lift a freeze."
|
|
7763
8011
|
)
|
|
7764
8012
|
}),
|
|
@@ -7787,13 +8035,13 @@ var pinCommand = define({
|
|
|
7787
8035
|
});
|
|
7788
8036
|
|
|
7789
8037
|
// src/commands/pins.ts
|
|
7790
|
-
var
|
|
8038
|
+
var import_zod28 = require("zod");
|
|
7791
8039
|
var pinsCommand = define({
|
|
7792
8040
|
name: "pins",
|
|
7793
8041
|
tool: "kb_pins",
|
|
7794
8042
|
usage: "pins",
|
|
7795
8043
|
description: "Every pinned base across the manifest layers, with its layer and whether it resolves to records. Takes no bundlePath.",
|
|
7796
|
-
input:
|
|
8044
|
+
input: import_zod28.z.object({}),
|
|
7797
8045
|
fromArgv: () => ({}),
|
|
7798
8046
|
run: ({ store }) => listPins(store, process.cwd())
|
|
7799
8047
|
});
|
|
@@ -7929,16 +8177,16 @@ function recordType(conceptId2) {
|
|
|
7929
8177
|
}
|
|
7930
8178
|
|
|
7931
8179
|
// src/commands/promote/model.ts
|
|
7932
|
-
var
|
|
7933
|
-
var promoteInputSchema =
|
|
8180
|
+
var import_zod29 = require("zod");
|
|
8181
|
+
var promoteInputSchema = import_zod29.z.object({
|
|
7934
8182
|
bundlePath,
|
|
7935
|
-
conceptIds:
|
|
7936
|
-
to:
|
|
7937
|
-
source:
|
|
8183
|
+
conceptIds: import_zod29.z.array(conceptId).max(64).optional().describe("Records to copy into the target base. Omit with `list`."),
|
|
8184
|
+
to: import_zod29.z.string().min(1).optional().describe("Absolute path to the base being promoted into."),
|
|
8185
|
+
source: import_zod29.z.string().min(1).optional().describe(
|
|
7938
8186
|
"Where the promotion came from, usually the pull request URL. Recorded on each copy as a source."
|
|
7939
8187
|
),
|
|
7940
|
-
force:
|
|
7941
|
-
list:
|
|
8188
|
+
force: import_zod29.z.boolean().optional().describe("Overwrite a record the target base already holds."),
|
|
8189
|
+
list: import_zod29.z.boolean().optional().describe("List the source base's candidates instead of promoting.")
|
|
7942
8190
|
}).refine((input) => input.list === true || input.to !== void 0, {
|
|
7943
8191
|
message: "promote needs a target base \u2014 pass --to <bundle>, or --list",
|
|
7944
8192
|
path: ["to"]
|
|
@@ -8075,17 +8323,17 @@ function renderPromote(result) {
|
|
|
8075
8323
|
}
|
|
8076
8324
|
|
|
8077
8325
|
// src/commands/query.ts
|
|
8078
|
-
var
|
|
8326
|
+
var import_zod30 = require("zod");
|
|
8079
8327
|
var queryCommand = define({
|
|
8080
8328
|
name: "query",
|
|
8081
8329
|
tool: "kb_query",
|
|
8082
8330
|
usage: "query <text...> [--tag T]... [--repo-root PATH]",
|
|
8083
8331
|
description: "Search; every hit carries its standing. Flagged, never filtered: a superseded hit returns with its replacement, a rejected one is marked. Prefer kb_load when the base fits its budget \u2014 a full read beats search. Results are volatile: place them at the tail, not the cached prefix. Never read record files directly.",
|
|
8084
|
-
input:
|
|
8332
|
+
input: import_zod30.z.object({
|
|
8085
8333
|
bundlePath,
|
|
8086
|
-
text:
|
|
8087
|
-
type:
|
|
8088
|
-
includeNonCurrent:
|
|
8334
|
+
text: import_zod30.z.string().optional(),
|
|
8335
|
+
type: import_zod30.z.enum(KB_RECORD_TYPES).optional(),
|
|
8336
|
+
includeNonCurrent: import_zod30.z.boolean().optional(),
|
|
8089
8337
|
tags: TAGS,
|
|
8090
8338
|
repoRoot: REPO_ROOT
|
|
8091
8339
|
}),
|
|
@@ -8119,43 +8367,43 @@ var queryCommand = define({
|
|
|
8119
8367
|
});
|
|
8120
8368
|
|
|
8121
8369
|
// src/commands/read-index.ts
|
|
8122
|
-
var
|
|
8370
|
+
var import_zod31 = require("zod");
|
|
8123
8371
|
var readIndexCommand = define({
|
|
8124
8372
|
name: "index",
|
|
8125
8373
|
tool: "kb_index",
|
|
8126
8374
|
usage: "index",
|
|
8127
8375
|
description: "The index \u2014 title, type, status, description per record \u2014 rebuilt if stale. Cheapest re-orientation after compaction: call it (or kb_context) first, then kb_load or fetch by id.",
|
|
8128
|
-
input:
|
|
8376
|
+
input: import_zod31.z.object({ bundlePath }),
|
|
8129
8377
|
fromArgv: (_argv, path) => ({ bundlePath: path }),
|
|
8130
8378
|
run: ({ store }, { bundlePath: path }) => store.readIndex(path)
|
|
8131
8379
|
});
|
|
8132
8380
|
|
|
8133
8381
|
// src/commands/schema.ts
|
|
8134
|
-
var
|
|
8382
|
+
var import_zod32 = require("zod");
|
|
8135
8383
|
var schemaCommand = define({
|
|
8136
8384
|
name: "schema",
|
|
8137
8385
|
tool: "kb_schema",
|
|
8138
8386
|
usage: "schema",
|
|
8139
8387
|
description: "JSON Schema for frontmatter, write input, and log entries, generated from the enforcing code.",
|
|
8140
|
-
input:
|
|
8388
|
+
input: import_zod32.z.object({}),
|
|
8141
8389
|
fromArgv: () => ({}),
|
|
8142
8390
|
run: () => Promise.resolve(kbJsonSchemas())
|
|
8143
8391
|
});
|
|
8144
8392
|
|
|
8145
8393
|
// src/commands/stamp.ts
|
|
8146
8394
|
var import_promises12 = require("fs/promises");
|
|
8147
|
-
var
|
|
8395
|
+
var import_zod33 = require("zod");
|
|
8148
8396
|
var DIGEST = /^[0-9a-f]{64}$/;
|
|
8149
8397
|
var stampCommand = define({
|
|
8150
8398
|
name: "stamp",
|
|
8151
8399
|
tool: "kb_stamp",
|
|
8152
8400
|
usage: "stamp [--bundle PATH] [--since DIGEST|FILE]",
|
|
8153
8401
|
description: "Content stamp of a base \u2014 `load`'s digest, record counts, per-record digests, how many records have drifted anchors \u2014 without any bodies. Takes no bundlePath to stamp every pinned base. With `since`, reports only the bases that moved, naming the changed ids. Reads, never writes.",
|
|
8154
|
-
input:
|
|
8155
|
-
bundlePath:
|
|
8402
|
+
input: import_zod33.z.object({
|
|
8403
|
+
bundlePath: import_zod33.z.string().min(1).optional().describe(
|
|
8156
8404
|
"Absolute path to one knowledge base. Omit to stamp every pinned base."
|
|
8157
8405
|
),
|
|
8158
|
-
since:
|
|
8406
|
+
since: import_zod33.z.string().min(1).optional().describe(
|
|
8159
8407
|
"Prior digest, or path to a prior `stamp --json`; only moved bases return, with changed ids when the baseline is a file."
|
|
8160
8408
|
)
|
|
8161
8409
|
}),
|
|
@@ -8241,16 +8489,16 @@ async function readBaseline(since) {
|
|
|
8241
8489
|
}
|
|
8242
8490
|
|
|
8243
8491
|
// src/commands/status.ts
|
|
8244
|
-
var
|
|
8492
|
+
var import_zod34 = require("zod");
|
|
8245
8493
|
var statusCommand = define({
|
|
8246
8494
|
name: "status",
|
|
8247
8495
|
tool: "kb_status",
|
|
8248
8496
|
usage: "status <concept-id> <status>",
|
|
8249
8497
|
description: "Move a record's status. Compare-and-swap: a concurrent change fails instead of being overwritten.",
|
|
8250
|
-
input:
|
|
8498
|
+
input: import_zod34.z.object({
|
|
8251
8499
|
bundlePath,
|
|
8252
8500
|
conceptId,
|
|
8253
|
-
status:
|
|
8501
|
+
status: import_zod34.z.enum(KB_RECORD_STATUSES)
|
|
8254
8502
|
}),
|
|
8255
8503
|
fromArgv: (argv, path) => ({
|
|
8256
8504
|
bundlePath: path,
|
|
@@ -8265,13 +8513,13 @@ var statusCommand = define({
|
|
|
8265
8513
|
});
|
|
8266
8514
|
|
|
8267
8515
|
// src/commands/supersede.ts
|
|
8268
|
-
var
|
|
8516
|
+
var import_zod35 = require("zod");
|
|
8269
8517
|
var supersedeCommand = define({
|
|
8270
8518
|
name: "supersede",
|
|
8271
8519
|
tool: "kb_supersede",
|
|
8272
8520
|
usage: "supersede <concept-id> <replacement-id>",
|
|
8273
8521
|
description: "Mark a record superseded by another, linked in both directions. Use instead of editing a record whose meaning changed.",
|
|
8274
|
-
input:
|
|
8522
|
+
input: import_zod35.z.object({ bundlePath, conceptId, replacementId: conceptId }),
|
|
8275
8523
|
fromArgv: (argv, path) => ({
|
|
8276
8524
|
bundlePath: path,
|
|
8277
8525
|
conceptId: argv[1],
|
|
@@ -8285,7 +8533,7 @@ var supersedeCommand = define({
|
|
|
8285
8533
|
});
|
|
8286
8534
|
|
|
8287
8535
|
// src/commands/sweep.ts
|
|
8288
|
-
var
|
|
8536
|
+
var import_zod36 = require("zod");
|
|
8289
8537
|
var TERMINAL = [
|
|
8290
8538
|
"resolved",
|
|
8291
8539
|
"rejected",
|
|
@@ -8296,15 +8544,15 @@ var sweepCommand = define({
|
|
|
8296
8544
|
tool: "kb_sweep",
|
|
8297
8545
|
usage: "sweep --tag <tag> --terminal [--dry-run]",
|
|
8298
8546
|
description: "Delete tagged records that are resolved, rejected or superseded. Refuses without --tag, keeps any record a surviving record still points at, and logs each deletion.",
|
|
8299
|
-
input:
|
|
8547
|
+
input: import_zod36.z.object({
|
|
8300
8548
|
bundlePath,
|
|
8301
|
-
tag:
|
|
8302
|
-
terminal:
|
|
8549
|
+
tag: import_zod36.z.string({ error: "sweep needs --tag: it never sweeps a whole base" }).min(1).describe("Only records carrying this tag are considered."),
|
|
8550
|
+
terminal: import_zod36.z.literal(true, {
|
|
8303
8551
|
error: "sweep needs --terminal: it deletes only settled records"
|
|
8304
8552
|
}).describe(
|
|
8305
8553
|
"Required. Names the only scope sweep deletes: resolved, rejected and superseded records."
|
|
8306
8554
|
),
|
|
8307
|
-
dryRun:
|
|
8555
|
+
dryRun: import_zod36.z.boolean().optional().describe("Report what would go, and delete nothing.")
|
|
8308
8556
|
}),
|
|
8309
8557
|
fromArgv: (argv, path) => ({
|
|
8310
8558
|
bundlePath: path,
|
|
@@ -8421,16 +8669,16 @@ function renderSweep(result) {
|
|
|
8421
8669
|
}
|
|
8422
8670
|
|
|
8423
8671
|
// src/commands/sync-instructions.ts
|
|
8424
|
-
var
|
|
8672
|
+
var import_zod37 = require("zod");
|
|
8425
8673
|
var syncInstructionsCommand = define({
|
|
8426
8674
|
name: "sync-instructions",
|
|
8427
8675
|
usage: "sync-instructions <file> [--profile NAME] [--budget N] [--full-under N]",
|
|
8428
8676
|
description: "CLI-only: plant the kb_context block between sentinel comments in AGENTS.md or CLAUDE.md, idempotently.",
|
|
8429
|
-
input:
|
|
8430
|
-
file:
|
|
8431
|
-
budgetTokens:
|
|
8432
|
-
fullUnderTokens:
|
|
8433
|
-
profile:
|
|
8677
|
+
input: import_zod37.z.object({
|
|
8678
|
+
file: import_zod37.z.string().min(1).describe("The instruction file to edit in place."),
|
|
8679
|
+
budgetTokens: import_zod37.z.number().int().positive().optional(),
|
|
8680
|
+
fullUnderTokens: import_zod37.z.number().int().positive().optional(),
|
|
8681
|
+
profile: import_zod37.z.string().optional()
|
|
8434
8682
|
}),
|
|
8435
8683
|
fromArgv: (argv) => {
|
|
8436
8684
|
const budget = argvFlag(argv, "--budget");
|
|
@@ -8456,17 +8704,17 @@ var syncInstructionsCommand = define({
|
|
|
8456
8704
|
});
|
|
8457
8705
|
|
|
8458
8706
|
// src/commands/trace.ts
|
|
8459
|
-
var
|
|
8707
|
+
var import_zod38 = require("zod");
|
|
8460
8708
|
var traceCommand = define({
|
|
8461
8709
|
name: "trace",
|
|
8462
8710
|
tool: "kb_trace",
|
|
8463
8711
|
usage: "trace <concept-id> [edges...]",
|
|
8464
8712
|
description: 'Timeline of how a position was reached, ordered by write time, following supersession, shared anchors and shared sources. Includes rejected, draft and superseded records \u2014 in a history they are the content. For "why is it like this"; kb_load answers "what holds now".',
|
|
8465
|
-
input:
|
|
8713
|
+
input: import_zod38.z.object({
|
|
8466
8714
|
bundlePath,
|
|
8467
8715
|
conceptId,
|
|
8468
|
-
edges:
|
|
8469
|
-
depth:
|
|
8716
|
+
edges: import_zod38.z.array(import_zod38.z.enum(TRACE_EDGES)).optional(),
|
|
8717
|
+
depth: import_zod38.z.number().int().positive().optional()
|
|
8470
8718
|
}),
|
|
8471
8719
|
fromArgv: (argv, path) => ({
|
|
8472
8720
|
bundlePath: path,
|
|
@@ -8488,37 +8736,37 @@ var traceCommand = define({
|
|
|
8488
8736
|
});
|
|
8489
8737
|
|
|
8490
8738
|
// src/commands/types.ts
|
|
8491
|
-
var
|
|
8739
|
+
var import_zod39 = require("zod");
|
|
8492
8740
|
var typesCommand = define({
|
|
8493
8741
|
name: "types",
|
|
8494
8742
|
tool: "kb_types",
|
|
8495
8743
|
usage: "types",
|
|
8496
8744
|
description: "The twelve record types with their purpose, body sections, and starting status. Read this before writing rather than guessing headings \u2014 a section the type does not define is rejected.",
|
|
8497
|
-
input:
|
|
8745
|
+
input: import_zod39.z.object({}),
|
|
8498
8746
|
fromArgv: () => ({}),
|
|
8499
8747
|
run: () => Promise.resolve(RECORD_TYPES)
|
|
8500
8748
|
});
|
|
8501
8749
|
|
|
8502
8750
|
// src/commands/unpin.ts
|
|
8503
|
-
var
|
|
8751
|
+
var import_zod40 = require("zod");
|
|
8504
8752
|
var unpinCommand = define({
|
|
8505
8753
|
name: "unpin",
|
|
8506
8754
|
tool: "kb_unpin",
|
|
8507
8755
|
usage: "unpin [bundle-path]",
|
|
8508
8756
|
description: "Remove a base from every manifest layer that holds it. Reports the layers touched.",
|
|
8509
|
-
input:
|
|
8757
|
+
input: import_zod40.z.object({ bundlePath }),
|
|
8510
8758
|
fromArgv: (argv, path) => ({ bundlePath: argv[1] ?? path }),
|
|
8511
8759
|
run: (_ctx, { bundlePath: path }) => unpinBase(process.cwd(), path)
|
|
8512
8760
|
});
|
|
8513
8761
|
|
|
8514
8762
|
// src/commands/validate.ts
|
|
8515
|
-
var
|
|
8763
|
+
var import_zod41 = require("zod");
|
|
8516
8764
|
var validateCommand = define({
|
|
8517
8765
|
name: "validate",
|
|
8518
8766
|
tool: "kb_validate",
|
|
8519
8767
|
usage: "validate",
|
|
8520
8768
|
description: "Check pointers no single record can see: supersession links that disagree between the two records, typed causal links, and assumptions that cite sources. Each finding carries a severity: errors fail the exit code, warnings do not.",
|
|
8521
|
-
input:
|
|
8769
|
+
input: import_zod41.z.object({ bundlePath }),
|
|
8522
8770
|
fromArgv: (_argv, path) => ({ bundlePath: path }),
|
|
8523
8771
|
run: async ({ store }, { bundlePath: path }) => validateBundle(await store.list(path)),
|
|
8524
8772
|
// Warnings never fail the exit code; every other severity does.
|
|
@@ -8528,16 +8776,16 @@ var validateCommand = define({
|
|
|
8528
8776
|
});
|
|
8529
8777
|
|
|
8530
8778
|
// src/commands/verify.ts
|
|
8531
|
-
var
|
|
8779
|
+
var import_zod42 = require("zod");
|
|
8532
8780
|
var verifyCommand = define({
|
|
8533
8781
|
name: "verify",
|
|
8534
8782
|
tool: "kb_verify",
|
|
8535
8783
|
usage: "verify <concept-id> --note <text>",
|
|
8536
8784
|
description: "Append a verified[] event: who checked, when, and what was found. Append-only. A record's own generator is refused unless the actor is `human:`-prefixed.",
|
|
8537
|
-
input:
|
|
8785
|
+
input: import_zod42.z.object({
|
|
8538
8786
|
bundlePath,
|
|
8539
8787
|
conceptId,
|
|
8540
|
-
note:
|
|
8788
|
+
note: import_zod42.z.string().refine((s) => s.trim().length > 0, {
|
|
8541
8789
|
message: "note must say what the check found"
|
|
8542
8790
|
})
|
|
8543
8791
|
}),
|
|
@@ -8557,15 +8805,15 @@ var verifyCommand = define({
|
|
|
8557
8805
|
});
|
|
8558
8806
|
|
|
8559
8807
|
// src/commands/write.ts
|
|
8560
|
-
var
|
|
8808
|
+
var import_zod43 = require("zod");
|
|
8561
8809
|
var writeCommand = define({
|
|
8562
8810
|
name: "write",
|
|
8563
8811
|
tool: "kb_write",
|
|
8564
8812
|
usage: "write <type> < record.json",
|
|
8565
8813
|
description: "Write one record. Search first \u2014 a duplicate concept id is rejected, not overwritten; kb_types lists each type's sections. An unsourced claim is an `assumption` with assumption: true, never a vague `fact`. Conflicting records get a `risk`, `open-question`, or superseding `decision`. Prefer a new short record over overloading one. Never delete; supersede.",
|
|
8566
|
-
input:
|
|
8814
|
+
input: import_zod43.z.object({
|
|
8567
8815
|
bundlePath,
|
|
8568
|
-
type:
|
|
8816
|
+
type: import_zod43.z.enum(KB_RECORD_TYPES),
|
|
8569
8817
|
input: composeInputSchema
|
|
8570
8818
|
}),
|
|
8571
8819
|
fromArgv: async (argv, path, stdin) => ({
|
|
@@ -8589,13 +8837,13 @@ var writeCommand = define({
|
|
|
8589
8837
|
});
|
|
8590
8838
|
|
|
8591
8839
|
// src/commands/write-decision.ts
|
|
8592
|
-
var
|
|
8840
|
+
var import_zod44 = require("zod");
|
|
8593
8841
|
var writeDecisionCommand = define({
|
|
8594
8842
|
name: "write-decision",
|
|
8595
8843
|
tool: "kb_write_decision",
|
|
8596
8844
|
usage: "write-decision < decision.json",
|
|
8597
8845
|
description: "Write a decision, with `alternative` (what was rejected and why) and `impact` as fields. Record one when a later reader would otherwise simplify the constraint away; skip when the diff already answers it. `sources` for material read, `anchors` for code, `relatedConceptIds` for records.",
|
|
8598
|
-
input:
|
|
8846
|
+
input: import_zod44.z.object({ bundlePath, input: decisionInputSchema }),
|
|
8599
8847
|
fromArgv: async (_argv, path, stdin) => ({
|
|
8600
8848
|
bundlePath: path,
|
|
8601
8849
|
input: JSON.parse(await stdin())
|
|
@@ -8625,6 +8873,7 @@ var KB_COMMANDS = [
|
|
|
8625
8873
|
answerCommand,
|
|
8626
8874
|
verifyCommand,
|
|
8627
8875
|
anchorResolveCommand,
|
|
8876
|
+
anchorSetCommand,
|
|
8628
8877
|
reassessCommand,
|
|
8629
8878
|
promoteCommand,
|
|
8630
8879
|
loadCommand,
|
|
@@ -8661,7 +8910,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
8661
8910
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
8662
8911
|
|
|
8663
8912
|
// src/version.ts
|
|
8664
|
-
var VERSION = true ? "0.1.
|
|
8913
|
+
var VERSION = true ? "0.1.22" : "0.0.0-dev";
|
|
8665
8914
|
|
|
8666
8915
|
// src/mcp.ts
|
|
8667
8916
|
function createKbMcpServer() {
|
|
@@ -8842,6 +9091,7 @@ function usage() {
|
|
|
8842
9091
|
KB_RECORD_STATUSES,
|
|
8843
9092
|
KB_RECORD_TYPES,
|
|
8844
9093
|
KB_SLUG_PATTERN,
|
|
9094
|
+
KbAnchorSetDuplicateError,
|
|
8845
9095
|
KbBaseFrozenError,
|
|
8846
9096
|
KbClassifyInputError,
|
|
8847
9097
|
KbInvalidConceptIdError,
|
|
@@ -8872,6 +9122,8 @@ function usage() {
|
|
|
8872
9122
|
adjudicate,
|
|
8873
9123
|
anchorFilePath,
|
|
8874
9124
|
anchorOnHunk,
|
|
9125
|
+
anchorSetInputSchema,
|
|
9126
|
+
applyAnchorSet,
|
|
8875
9127
|
assertBaseNotFrozen,
|
|
8876
9128
|
backlinks,
|
|
8877
9129
|
buildContext,
|
|
@@ -8905,19 +9157,23 @@ function usage() {
|
|
|
8905
9157
|
isNoDecisionRecord,
|
|
8906
9158
|
isReviewTag,
|
|
8907
9159
|
kbActorStampSchema,
|
|
9160
|
+
kbAnchorLocatorSchema,
|
|
8908
9161
|
kbAnchorSchema,
|
|
8909
9162
|
kbAnchorSpanSchema,
|
|
8910
9163
|
kbAnchorWriteSchema,
|
|
8911
9164
|
kbConceptIdSchema,
|
|
8912
9165
|
kbJsonSchemas,
|
|
8913
9166
|
kbLinkSchema,
|
|
9167
|
+
kbLogAnchorChangeSchema,
|
|
8914
9168
|
kbLogEntrySchema,
|
|
9169
|
+
kbLogEntryWriteSchema,
|
|
8915
9170
|
kbRecordFrontmatterSchema,
|
|
8916
9171
|
kbSourceSchema,
|
|
8917
9172
|
kbVerifiedEventSchema,
|
|
8918
9173
|
languageForFile,
|
|
8919
9174
|
listPins,
|
|
8920
9175
|
loadQmd,
|
|
9176
|
+
locatorOf,
|
|
8921
9177
|
matchToDiff,
|
|
8922
9178
|
matchesTags,
|
|
8923
9179
|
mergedContextBudgets,
|