@saasontools/strauss-kb 0.1.18 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-IOIUS26S.js → chunk-CQBLH7CE.js} +2 -2
- package/dist/{chunk-GSOTMWZZ.js → chunk-MNQNHYWL.js} +150 -51
- package/dist/chunk-MNQNHYWL.js.map +1 -0
- package/dist/{chunk-ROGVYSMV.js → chunk-ZWSCLHG6.js} +2 -2
- package/dist/cli-main.cjs +148 -50
- package/dist/cli-main.cjs.map +1 -1
- package/dist/cli-main.js +2 -2
- package/dist/index.cjs +150 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -6
- package/dist/index.d.ts +41 -6
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-main.cjs +148 -50
- package/dist/mcp-main.cjs.map +1 -1
- package/dist/mcp-main.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-GSOTMWZZ.js.map +0 -1
- /package/dist/{chunk-IOIUS26S.js.map → chunk-CQBLH7CE.js.map} +0 -0
- /package/dist/{chunk-ROGVYSMV.js.map → chunk-ZWSCLHG6.js.map} +0 -0
package/dist/cli-main.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -123,6 +123,7 @@ __export(index_exports, {
|
|
|
123
123
|
listPins: () => listPins,
|
|
124
124
|
loadQmd: () => loadQmd,
|
|
125
125
|
matchToDiff: () => matchToDiff,
|
|
126
|
+
matchesTags: () => matchesTags,
|
|
126
127
|
mergedContextBudgets: () => mergedContextBudgets,
|
|
127
128
|
neighbours: () => neighbours,
|
|
128
129
|
pack: () => pack,
|
|
@@ -2733,6 +2734,13 @@ function typeRank(record) {
|
|
|
2733
2734
|
return index2 === -1 ? TYPE_PRIORITY.length : index2;
|
|
2734
2735
|
}
|
|
2735
2736
|
|
|
2737
|
+
// src/kb-tags.ts
|
|
2738
|
+
function matchesTags(record, filter) {
|
|
2739
|
+
if (!filter.tags?.length && !filter.excludeTags?.length) return true;
|
|
2740
|
+
const carried = new Set(record.frontmatter.tags ?? []);
|
|
2741
|
+
return (filter.tags ?? []).every((tag) => carried.has(tag)) && !(filter.excludeTags ?? []).some((tag) => carried.has(tag));
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2736
2744
|
// src/catalog.ts
|
|
2737
2745
|
var EMPTY_STANDINGS = {
|
|
2738
2746
|
current: 0,
|
|
@@ -2743,7 +2751,7 @@ var EMPTY_STANDINGS = {
|
|
|
2743
2751
|
};
|
|
2744
2752
|
function catalog(bundle, options = {}) {
|
|
2745
2753
|
const wanted = options.type ? bundle.filter((record) => record.frontmatter.type === options.type) : bundle;
|
|
2746
|
-
const entries = adjudicate(wanted, bundle, options.now ?? /* @__PURE__ */ new Date()).map((hit) => ({
|
|
2754
|
+
const entries = adjudicate(wanted, bundle, options.now ?? /* @__PURE__ */ new Date()).filter((hit) => matchesTags(hit.record, options)).map((hit) => ({
|
|
2747
2755
|
conceptId: hit.record.conceptId,
|
|
2748
2756
|
type: hit.record.frontmatter.type,
|
|
2749
2757
|
title: hit.record.frontmatter.title ?? null,
|
|
@@ -3016,13 +3024,16 @@ var KbStore = class {
|
|
|
3016
3024
|
return this.parse(conceptId2, raw);
|
|
3017
3025
|
}
|
|
3018
3026
|
/**
|
|
3019
|
-
* Every record in the bundle, optionally narrowed to one type
|
|
3027
|
+
* Every record in the bundle, optionally narrowed to one type and to the
|
|
3028
|
+
* records carrying every tag in `filter.tags`. Selection only — `excludeTags`
|
|
3029
|
+
* is not taken here, because `query`, `catalog` and `load` read through this
|
|
3030
|
+
* and must adjudicate over the whole base.
|
|
3020
3031
|
*
|
|
3021
3032
|
* A file that fails to parse is skipped and logged rather than thrown: one
|
|
3022
3033
|
* malformed record — hand-edited, or written by a producer we don't know —
|
|
3023
3034
|
* must not make the whole bundle unreadable.
|
|
3024
3035
|
*/
|
|
3025
|
-
async list(bundlePath2, type) {
|
|
3036
|
+
async list(bundlePath2, type, filter = {}) {
|
|
3026
3037
|
const root = this.root(bundlePath2);
|
|
3027
3038
|
let names;
|
|
3028
3039
|
try {
|
|
@@ -3036,7 +3047,9 @@ var KbStore = class {
|
|
|
3036
3047
|
DEFAULT_IO_CONCURRENCY,
|
|
3037
3048
|
async ({ name, conceptId: conceptId2 }) => this.parse(conceptId2, await (0, import_promises6.readFile)((0, import_node_path7.join)(root, name), "utf8"))
|
|
3038
3049
|
);
|
|
3039
|
-
return records.filter(
|
|
3050
|
+
return records.filter(
|
|
3051
|
+
(record) => record !== null && matchesTags(record, filter)
|
|
3052
|
+
);
|
|
3040
3053
|
}
|
|
3041
3054
|
/**
|
|
3042
3055
|
* Moves a record's status, preserving everything else.
|
|
@@ -3176,9 +3189,10 @@ ${answer}
|
|
|
3176
3189
|
/* @__PURE__ */ new Date(),
|
|
3177
3190
|
await this.detectDrift(narrowed, options.repoRoot)
|
|
3178
3191
|
);
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3192
|
+
const kept = adjudicated.filter((hit) => matchesTags(hit.record, options));
|
|
3193
|
+
if (options.includeNonCurrent) return kept;
|
|
3194
|
+
const present = new Set(kept.map((hit) => hit.record.conceptId));
|
|
3195
|
+
return kept.filter(
|
|
3182
3196
|
(hit) => hit.standing !== "superseded" || !hit.heads.some((head) => present.has(head.conceptId))
|
|
3183
3197
|
);
|
|
3184
3198
|
}
|
|
@@ -3281,14 +3295,17 @@ ${answer}
|
|
|
3281
3295
|
/* @__PURE__ */ new Date(),
|
|
3282
3296
|
await this.detectDrift(wanted, options.repoRoot)
|
|
3283
3297
|
);
|
|
3284
|
-
const
|
|
3285
|
-
|
|
3298
|
+
const kept = adjudicated.filter(
|
|
3299
|
+
(hit) => matchesTags(hit.record, { excludeTags: options.excludeTags })
|
|
3300
|
+
);
|
|
3301
|
+
const records = kept.filter((hit) => hit.standing !== "superseded");
|
|
3302
|
+
const superseded = kept.filter((hit) => hit.standing === "superseded").map(stub);
|
|
3286
3303
|
const approxTokens2 = records.reduce((total, hit) => total + estimateTokens(hit.record), 0) + superseded.reduce((total, entry) => total + estimateStubTokens(entry), 0);
|
|
3287
3304
|
const bundleDigestValue = bundleDigest(records, superseded);
|
|
3288
3305
|
if (!options.all && approxTokens2 > budgetTokens) {
|
|
3289
3306
|
return {
|
|
3290
3307
|
loaded: false,
|
|
3291
|
-
recordCount:
|
|
3308
|
+
recordCount: kept.length,
|
|
3292
3309
|
approxTokens: approxTokens2,
|
|
3293
3310
|
budgetTokens,
|
|
3294
3311
|
message: refusalMessage({
|
|
@@ -3301,7 +3318,7 @@ ${answer}
|
|
|
3301
3318
|
}
|
|
3302
3319
|
return {
|
|
3303
3320
|
loaded: true,
|
|
3304
|
-
recordCount:
|
|
3321
|
+
recordCount: kept.length,
|
|
3305
3322
|
tokensLoaded: approxTokens2,
|
|
3306
3323
|
budgetTokens: options.all ? null : budgetTokens,
|
|
3307
3324
|
records,
|
|
@@ -3788,14 +3805,17 @@ function asBudgets(value) {
|
|
|
3788
3805
|
if (value === null || typeof value !== "object") return {};
|
|
3789
3806
|
const table2 = value;
|
|
3790
3807
|
const pick = (key2, min) => {
|
|
3791
|
-
const
|
|
3792
|
-
return typeof
|
|
3808
|
+
const raw2 = table2[key2];
|
|
3809
|
+
return typeof raw2 === "number" && Number.isInteger(raw2) && raw2 >= min ? raw2 : void 0;
|
|
3793
3810
|
};
|
|
3794
3811
|
const budgetTokens = pick("budgetTokens", 1);
|
|
3795
3812
|
const fullUnderTokens = pick("fullUnderTokens", 0);
|
|
3813
|
+
const raw = table2["excludeTags"];
|
|
3814
|
+
const excludeTags = Array.isArray(raw) ? raw.filter((tag) => typeof tag === "string" && tag !== "") : void 0;
|
|
3796
3815
|
return {
|
|
3797
3816
|
...budgetTokens ? { budgetTokens } : {},
|
|
3798
|
-
...fullUnderTokens !== void 0 ? { fullUnderTokens } : {}
|
|
3817
|
+
...fullUnderTokens !== void 0 ? { fullUnderTokens } : {},
|
|
3818
|
+
...excludeTags ? { excludeTags } : {}
|
|
3799
3819
|
};
|
|
3800
3820
|
}
|
|
3801
3821
|
function contextProfileBudgets(manifest, profile) {
|
|
@@ -4111,7 +4131,7 @@ function preamble() {
|
|
|
4111
4131
|
"tokens."
|
|
4112
4132
|
].join("\n");
|
|
4113
4133
|
}
|
|
4114
|
-
async function renderBase(store, path, absolutePath, fullUnderTokens, pinMode, budgetTokens) {
|
|
4134
|
+
async function renderBase(store, path, absolutePath, fullUnderTokens, pinMode, budgetTokens, excludeTags) {
|
|
4115
4135
|
const bundle = await store.list(absolutePath);
|
|
4116
4136
|
if (bundle.length === 0) {
|
|
4117
4137
|
return {
|
|
@@ -4125,7 +4145,8 @@ async function renderBase(store, path, absolutePath, fullUnderTokens, pinMode, b
|
|
|
4125
4145
|
let degradedFrom;
|
|
4126
4146
|
if (fullCap > 0) {
|
|
4127
4147
|
const full = await store.load(absolutePath, {
|
|
4128
|
-
budgetTokens: fullCap
|
|
4148
|
+
budgetTokens: fullCap,
|
|
4149
|
+
excludeTags
|
|
4129
4150
|
});
|
|
4130
4151
|
if (!full.loaded && pinMode === "full") {
|
|
4131
4152
|
degradedFrom = { approxTokens: full.approxTokens };
|
|
@@ -4155,7 +4176,9 @@ async function renderBase(store, path, absolutePath, fullUnderTokens, pinMode, b
|
|
|
4155
4176
|
};
|
|
4156
4177
|
}
|
|
4157
4178
|
}
|
|
4158
|
-
const adjudicated = adjudicate(bundle, bundle)
|
|
4179
|
+
const adjudicated = adjudicate(bundle, bundle).filter(
|
|
4180
|
+
(hit) => matchesTags(hit.record, { excludeTags })
|
|
4181
|
+
);
|
|
4159
4182
|
const lines = adjudicated.filter((hit) => hit.standing !== "superseded").map((hit) => renderIndexLine(hit.record));
|
|
4160
4183
|
const superseded = adjudicated.filter((hit) => hit.standing === "superseded").map(
|
|
4161
4184
|
(hit) => `- \`${hit.record.conceptId}\` \u2192 superseded by ${hit.heads.map((head) => `\`${head.conceptId}\``).join(", ") || "(missing replacement)"}`
|
|
@@ -4176,6 +4199,7 @@ async function buildContext(store, workspaceDir, options = {}) {
|
|
|
4176
4199
|
const fromManifest = mergedContextBudgets(merged, options.profile);
|
|
4177
4200
|
budgetTokens = options.budgetTokens ?? fromManifest.budgetTokens ?? builtin.budgetTokens ?? DEFAULT_CONTEXT_BUDGET;
|
|
4178
4201
|
fullUnderTokens = options.fullUnderTokens ?? fromManifest.fullUnderTokens ?? builtin.fullUnderTokens ?? 0;
|
|
4202
|
+
const excludeTags = options.excludeTags ?? fromManifest.excludeTags ?? builtin.excludeTags ?? [];
|
|
4179
4203
|
const pins = merged.pins.filter(
|
|
4180
4204
|
(pin) => !pin.profiles?.length || !options.profile || pin.profiles.includes(options.profile)
|
|
4181
4205
|
);
|
|
@@ -4196,7 +4220,8 @@ async function buildContext(store, workspaceDir, options = {}) {
|
|
|
4196
4220
|
pin.absolutePath,
|
|
4197
4221
|
fullUnderTokens,
|
|
4198
4222
|
pin.mode,
|
|
4199
|
-
budgetTokens
|
|
4223
|
+
budgetTokens,
|
|
4224
|
+
excludeTags
|
|
4200
4225
|
),
|
|
4201
4226
|
frozen: pin.frozen === true
|
|
4202
4227
|
}))
|
|
@@ -4857,6 +4882,9 @@ var import_zod9 = require("zod");
|
|
|
4857
4882
|
var import_zod8 = require("zod");
|
|
4858
4883
|
var bundlePath = import_zod8.z.string().min(1).describe("Absolute path to the knowledge base directory.");
|
|
4859
4884
|
var conceptId = import_zod8.z.string().min(1).describe("e.g. decision.cursor-v2");
|
|
4885
|
+
var TAGS = import_zod8.z.array(import_zod8.z.string().min(1)).optional().describe(
|
|
4886
|
+
"Keep only records carrying every one of these frontmatter tags. Matched exactly."
|
|
4887
|
+
);
|
|
4860
4888
|
var REPO_ROOT = import_zod8.z.string().min(1).optional().describe(
|
|
4861
4889
|
"Where the anchored source lives, for the drift check. Defaults to the working directory."
|
|
4862
4890
|
);
|
|
@@ -4878,6 +4906,41 @@ function argvFlag(argv, name) {
|
|
|
4878
4906
|
}
|
|
4879
4907
|
return value;
|
|
4880
4908
|
}
|
|
4909
|
+
function argvFlags(argv, name) {
|
|
4910
|
+
const values = [];
|
|
4911
|
+
for (const [at2, arg] of argv.entries()) {
|
|
4912
|
+
if (arg.startsWith(`${name}=`)) {
|
|
4913
|
+
const value = arg.slice(name.length + 1);
|
|
4914
|
+
if (!value) throw new KbMissingFlagValueError(name);
|
|
4915
|
+
values.push(value);
|
|
4916
|
+
} else if (arg === name) {
|
|
4917
|
+
const value = argv[at2 + 1];
|
|
4918
|
+
if (value === void 0 || value.startsWith("--")) {
|
|
4919
|
+
throw new KbMissingFlagValueError(name);
|
|
4920
|
+
}
|
|
4921
|
+
values.push(value);
|
|
4922
|
+
}
|
|
4923
|
+
}
|
|
4924
|
+
return values;
|
|
4925
|
+
}
|
|
4926
|
+
function argvWithout(argv, ...names) {
|
|
4927
|
+
const kept = [];
|
|
4928
|
+
for (let at2 = 0; at2 < argv.length; at2 += 1) {
|
|
4929
|
+
const arg = argv[at2];
|
|
4930
|
+
if (names.some((name) => arg.startsWith(`${name}=`))) continue;
|
|
4931
|
+
if (names.includes(arg)) {
|
|
4932
|
+
at2 += 1;
|
|
4933
|
+
continue;
|
|
4934
|
+
}
|
|
4935
|
+
kept.push(arg);
|
|
4936
|
+
}
|
|
4937
|
+
return kept;
|
|
4938
|
+
}
|
|
4939
|
+
function argvPositional(argv, ...names) {
|
|
4940
|
+
return argvWithout(argv.slice(1), ...names).find(
|
|
4941
|
+
(arg) => !arg.startsWith("--")
|
|
4942
|
+
);
|
|
4943
|
+
}
|
|
4881
4944
|
|
|
4882
4945
|
// src/commands/anchor-resolve.ts
|
|
4883
4946
|
function resolverSummary(results) {
|
|
@@ -5194,25 +5257,39 @@ var import_zod12 = require("zod");
|
|
|
5194
5257
|
var catalogCommand = define({
|
|
5195
5258
|
name: "catalog",
|
|
5196
5259
|
tool: "kb_catalog",
|
|
5197
|
-
usage: "catalog [type]",
|
|
5260
|
+
usage: "catalog [type] [--tag T]...",
|
|
5198
5261
|
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.",
|
|
5199
5262
|
input: import_zod12.z.object({
|
|
5200
5263
|
bundlePath,
|
|
5201
|
-
type: import_zod12.z.enum(KB_RECORD_TYPES).optional()
|
|
5202
|
-
|
|
5203
|
-
fromArgv: (argv, path) => ({
|
|
5204
|
-
bundlePath: path,
|
|
5205
|
-
...argv[1] && !argv[1].startsWith("--") ? { type: argv[1] } : {}
|
|
5264
|
+
type: import_zod12.z.enum(KB_RECORD_TYPES).optional(),
|
|
5265
|
+
tags: TAGS
|
|
5206
5266
|
}),
|
|
5207
|
-
|
|
5208
|
-
|
|
5267
|
+
fromArgv: (argv, path) => {
|
|
5268
|
+
const tags = argvFlags(argv, "--tag");
|
|
5269
|
+
const type = argvPositional(argv, "--tag");
|
|
5270
|
+
return {
|
|
5271
|
+
bundlePath: path,
|
|
5272
|
+
...type ? { type } : {},
|
|
5273
|
+
...tags.length ? { tags } : {}
|
|
5274
|
+
};
|
|
5275
|
+
},
|
|
5276
|
+
run: async ({ store }, { bundlePath: path, type, tags }) => render(
|
|
5277
|
+
await store.catalog(path, {
|
|
5278
|
+
...type ? { type } : {},
|
|
5279
|
+
...tags ? { tags } : {}
|
|
5280
|
+
}),
|
|
5209
5281
|
path,
|
|
5210
|
-
type
|
|
5282
|
+
type,
|
|
5283
|
+
tags
|
|
5211
5284
|
)
|
|
5212
5285
|
});
|
|
5213
|
-
function render(result, bundle, type) {
|
|
5286
|
+
function render(result, bundle, type, tags) {
|
|
5287
|
+
const narrowed = [
|
|
5288
|
+
...type ? [type] : [],
|
|
5289
|
+
...tags?.length ? [`tags: ${tags.join(", ")}`] : []
|
|
5290
|
+
].join(" \xB7 ");
|
|
5214
5291
|
const lines = [
|
|
5215
|
-
`# KB Catalog${
|
|
5292
|
+
`# KB Catalog${narrowed ? ` \u2014 ${narrowed}` : ""}`,
|
|
5216
5293
|
`bundle: ${bundle}`,
|
|
5217
5294
|
`${count(result.recordCount, "record")}: ${standingCounts(result)}`
|
|
5218
5295
|
];
|
|
@@ -5224,7 +5301,7 @@ function render(result, bundle, type) {
|
|
|
5224
5301
|
lines.push("");
|
|
5225
5302
|
if (!result.entries.length) {
|
|
5226
5303
|
lines.push(
|
|
5227
|
-
|
|
5304
|
+
narrowed ? `(no records matching ${narrowed})` : "(no records \u2014 this base is empty)"
|
|
5228
5305
|
);
|
|
5229
5306
|
} else {
|
|
5230
5307
|
for (const entry of result.entries) lines.push(renderCatalogLine(entry));
|
|
@@ -5257,7 +5334,7 @@ var import_zod13 = require("zod");
|
|
|
5257
5334
|
var contextCommand = define({
|
|
5258
5335
|
name: "context",
|
|
5259
5336
|
tool: "kb_context",
|
|
5260
|
-
usage: "context [--profile NAME] [--budget N] [--full-under N] [--format json] [--event NAME]",
|
|
5337
|
+
usage: "context [--profile NAME] [--budget N] [--full-under N] [--exclude-tag T]... [--format json] [--event NAME]",
|
|
5261
5338
|
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.",
|
|
5262
5339
|
input: import_zod13.z.object({
|
|
5263
5340
|
budgetTokens: import_zod13.z.number().int().positive().optional().describe(
|
|
@@ -5269,6 +5346,9 @@ var contextCommand = define({
|
|
|
5269
5346
|
profile: import_zod13.z.string().optional().describe(
|
|
5270
5347
|
"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."
|
|
5271
5348
|
),
|
|
5349
|
+
excludeTags: import_zod13.z.array(import_zod13.z.string().min(1)).optional().describe(
|
|
5350
|
+
"Frontmatter tags whose records stay out of the block. The base stays pinned and stays readable by tool; resolved like the budgets."
|
|
5351
|
+
),
|
|
5272
5352
|
format: import_zod13.z.enum(["markdown", "json"]).optional().describe(
|
|
5273
5353
|
"CLI envelope for hook protocols that require strict JSON on stdout. MCP callers omit this \u2014 the block itself is identical."
|
|
5274
5354
|
),
|
|
@@ -5282,19 +5362,22 @@ var contextCommand = define({
|
|
|
5282
5362
|
const profile = argvFlag(argv, "--profile");
|
|
5283
5363
|
const format = argvFlag(argv, "--format");
|
|
5284
5364
|
const event = argvFlag(argv, "--event");
|
|
5365
|
+
const excludeTags = argvFlags(argv, "--exclude-tag");
|
|
5285
5366
|
return {
|
|
5286
5367
|
...budget ? { budgetTokens: Number(budget) } : {},
|
|
5287
5368
|
...fullUnder ? { fullUnderTokens: Number(fullUnder) } : {},
|
|
5288
5369
|
...profile ? { profile } : {},
|
|
5370
|
+
...excludeTags.length ? { excludeTags } : {},
|
|
5289
5371
|
...format ? { format } : {},
|
|
5290
5372
|
...event ? { event } : {}
|
|
5291
5373
|
};
|
|
5292
5374
|
},
|
|
5293
|
-
run: async ({ store }, { budgetTokens, fullUnderTokens, profile, format, event }) => {
|
|
5375
|
+
run: async ({ store }, { budgetTokens, fullUnderTokens, profile, excludeTags, format, event }) => {
|
|
5294
5376
|
const result = await buildContext(store, process.cwd(), {
|
|
5295
5377
|
...budgetTokens ? { budgetTokens } : {},
|
|
5296
5378
|
...fullUnderTokens ? { fullUnderTokens } : {},
|
|
5297
5379
|
...profile ? { profile } : {},
|
|
5380
|
+
...excludeTags ? { excludeTags } : {},
|
|
5298
5381
|
// Degradations — a full pin that could not fit, a refused block — go
|
|
5299
5382
|
// to stderr as well as into the block itself: stderr is diagnostics on
|
|
5300
5383
|
// both surfaces (hooks discard it, MCP logs it), so an operator can
|
|
@@ -6095,17 +6178,31 @@ var import_zod17 = require("zod");
|
|
|
6095
6178
|
var listCommand = define({
|
|
6096
6179
|
name: "list",
|
|
6097
6180
|
tool: "kb_list",
|
|
6098
|
-
usage: "list [type]",
|
|
6099
|
-
description: "Every record, optionally one type. For enumerating; use kb_query for a question.",
|
|
6100
|
-
input: import_zod17.z.object({
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6181
|
+
usage: "list [type] [--tag T]...",
|
|
6182
|
+
description: "Every record, optionally one type or tag. For enumerating; use kb_query for a question.",
|
|
6183
|
+
input: import_zod17.z.object({
|
|
6184
|
+
bundlePath,
|
|
6185
|
+
type: import_zod17.z.enum(KB_RECORD_TYPES).optional(),
|
|
6186
|
+
tags: TAGS
|
|
6187
|
+
}),
|
|
6188
|
+
fromArgv: (argv, path) => {
|
|
6189
|
+
const tags = argvFlags(argv, "--tag");
|
|
6190
|
+
const type = argvPositional(argv, "--tag");
|
|
6191
|
+
return {
|
|
6192
|
+
bundlePath: path,
|
|
6193
|
+
...type ? { type } : {},
|
|
6194
|
+
...tags.length ? { tags } : {}
|
|
6195
|
+
};
|
|
6196
|
+
},
|
|
6197
|
+
run: async ({ store }, { bundlePath: path, type, tags }) => (await store.list(path, type, { ...tags ? { tags } : {} })).map(
|
|
6198
|
+
(record) => ({
|
|
6199
|
+
conceptId: record.conceptId,
|
|
6200
|
+
title: record.frontmatter.title ?? null,
|
|
6201
|
+
description: record.frontmatter.description ?? null,
|
|
6202
|
+
status: record.frontmatter.strauss_status,
|
|
6203
|
+
anchors: record.frontmatter.strauss_anchors ?? []
|
|
6204
|
+
})
|
|
6205
|
+
)
|
|
6109
6206
|
});
|
|
6110
6207
|
|
|
6111
6208
|
// src/commands/load.ts
|
|
@@ -6356,31 +6453,33 @@ var import_zod24 = require("zod");
|
|
|
6356
6453
|
var queryCommand = define({
|
|
6357
6454
|
name: "query",
|
|
6358
6455
|
tool: "kb_query",
|
|
6359
|
-
usage: "query <text...> [--repo-root PATH]",
|
|
6456
|
+
usage: "query <text...> [--tag T]... [--repo-root PATH]",
|
|
6360
6457
|
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.",
|
|
6361
6458
|
input: import_zod24.z.object({
|
|
6362
6459
|
bundlePath,
|
|
6363
6460
|
text: import_zod24.z.string().optional(),
|
|
6364
6461
|
type: import_zod24.z.enum(KB_RECORD_TYPES).optional(),
|
|
6365
6462
|
includeNonCurrent: import_zod24.z.boolean().optional(),
|
|
6463
|
+
tags: TAGS,
|
|
6366
6464
|
repoRoot: REPO_ROOT
|
|
6367
6465
|
}),
|
|
6368
|
-
//
|
|
6466
|
+
// Both are flags, so neither's value may fall into the search text.
|
|
6369
6467
|
fromArgv: (argv, path) => {
|
|
6370
6468
|
const repoRoot = argvFlag(argv, "--repo-root");
|
|
6371
|
-
const
|
|
6372
|
-
const
|
|
6373
|
-
if (flag !== -1) words.splice(flag, 2);
|
|
6469
|
+
const tags = argvFlags(argv, "--tag");
|
|
6470
|
+
const words = argvWithout(argv.slice(1), "--repo-root", "--tag");
|
|
6374
6471
|
return {
|
|
6375
6472
|
bundlePath: path,
|
|
6376
6473
|
text: words.join(" ").trim(),
|
|
6377
6474
|
includeNonCurrent: true,
|
|
6475
|
+
...tags.length ? { tags } : {},
|
|
6378
6476
|
...repoRoot !== void 0 ? { repoRoot } : {}
|
|
6379
6477
|
};
|
|
6380
6478
|
},
|
|
6381
|
-
run: async ({ store }, { bundlePath: path, text, type, includeNonCurrent, repoRoot }) => (await store.query(path, text ?? "", {
|
|
6479
|
+
run: async ({ store }, { bundlePath: path, text, type, includeNonCurrent, tags, repoRoot }) => (await store.query(path, text ?? "", {
|
|
6382
6480
|
...type ? { type } : {},
|
|
6383
6481
|
includeNonCurrent: includeNonCurrent === true,
|
|
6482
|
+
...tags ? { tags } : {},
|
|
6384
6483
|
...repoRoot !== void 0 ? { repoRoot } : {}
|
|
6385
6484
|
})).map((hit) => ({
|
|
6386
6485
|
conceptId: hit.record.conceptId,
|
|
@@ -6795,7 +6894,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
6795
6894
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6796
6895
|
|
|
6797
6896
|
// src/version.ts
|
|
6798
|
-
var VERSION = true ? "0.1.
|
|
6897
|
+
var VERSION = true ? "0.1.19" : "0.0.0-dev";
|
|
6799
6898
|
|
|
6800
6899
|
// src/mcp.ts
|
|
6801
6900
|
function createKbMcpServer() {
|
|
@@ -7039,6 +7138,7 @@ function usage() {
|
|
|
7039
7138
|
listPins,
|
|
7040
7139
|
loadQmd,
|
|
7041
7140
|
matchToDiff,
|
|
7141
|
+
matchesTags,
|
|
7042
7142
|
mergedContextBudgets,
|
|
7043
7143
|
neighbours,
|
|
7044
7144
|
pack,
|