@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/mcp-main.cjs
CHANGED
|
@@ -2178,14 +2178,17 @@ function asBudgets(value) {
|
|
|
2178
2178
|
if (value === null || typeof value !== "object") return {};
|
|
2179
2179
|
const table2 = value;
|
|
2180
2180
|
const pick = (key, min) => {
|
|
2181
|
-
const
|
|
2182
|
-
return typeof
|
|
2181
|
+
const raw2 = table2[key];
|
|
2182
|
+
return typeof raw2 === "number" && Number.isInteger(raw2) && raw2 >= min ? raw2 : void 0;
|
|
2183
2183
|
};
|
|
2184
2184
|
const budgetTokens = pick("budgetTokens", 1);
|
|
2185
2185
|
const fullUnderTokens = pick("fullUnderTokens", 0);
|
|
2186
|
+
const raw = table2["excludeTags"];
|
|
2187
|
+
const excludeTags = Array.isArray(raw) ? raw.filter((tag) => typeof tag === "string" && tag !== "") : void 0;
|
|
2186
2188
|
return {
|
|
2187
2189
|
...budgetTokens ? { budgetTokens } : {},
|
|
2188
|
-
...fullUnderTokens !== void 0 ? { fullUnderTokens } : {}
|
|
2190
|
+
...fullUnderTokens !== void 0 ? { fullUnderTokens } : {},
|
|
2191
|
+
...excludeTags ? { excludeTags } : {}
|
|
2189
2192
|
};
|
|
2190
2193
|
}
|
|
2191
2194
|
function contextProfileBudgets(manifest, profile) {
|
|
@@ -2472,6 +2475,9 @@ async function unpinBase(workspaceDir, bundlePath2) {
|
|
|
2472
2475
|
var import_zod6 = require("zod");
|
|
2473
2476
|
var bundlePath = import_zod6.z.string().min(1).describe("Absolute path to the knowledge base directory.");
|
|
2474
2477
|
var conceptId = import_zod6.z.string().min(1).describe("e.g. decision.cursor-v2");
|
|
2478
|
+
var TAGS = import_zod6.z.array(import_zod6.z.string().min(1)).optional().describe(
|
|
2479
|
+
"Keep only records carrying every one of these frontmatter tags. Matched exactly."
|
|
2480
|
+
);
|
|
2475
2481
|
var REPO_ROOT = import_zod6.z.string().min(1).optional().describe(
|
|
2476
2482
|
"Where the anchored source lives, for the drift check. Defaults to the working directory."
|
|
2477
2483
|
);
|
|
@@ -2493,6 +2499,41 @@ function argvFlag(argv, name) {
|
|
|
2493
2499
|
}
|
|
2494
2500
|
return value;
|
|
2495
2501
|
}
|
|
2502
|
+
function argvFlags(argv, name) {
|
|
2503
|
+
const values = [];
|
|
2504
|
+
for (const [at2, arg] of argv.entries()) {
|
|
2505
|
+
if (arg.startsWith(`${name}=`)) {
|
|
2506
|
+
const value = arg.slice(name.length + 1);
|
|
2507
|
+
if (!value) throw new KbMissingFlagValueError(name);
|
|
2508
|
+
values.push(value);
|
|
2509
|
+
} else if (arg === name) {
|
|
2510
|
+
const value = argv[at2 + 1];
|
|
2511
|
+
if (value === void 0 || value.startsWith("--")) {
|
|
2512
|
+
throw new KbMissingFlagValueError(name);
|
|
2513
|
+
}
|
|
2514
|
+
values.push(value);
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
return values;
|
|
2518
|
+
}
|
|
2519
|
+
function argvWithout(argv, ...names) {
|
|
2520
|
+
const kept = [];
|
|
2521
|
+
for (let at2 = 0; at2 < argv.length; at2 += 1) {
|
|
2522
|
+
const arg = argv[at2];
|
|
2523
|
+
if (names.some((name) => arg.startsWith(`${name}=`))) continue;
|
|
2524
|
+
if (names.includes(arg)) {
|
|
2525
|
+
at2 += 1;
|
|
2526
|
+
continue;
|
|
2527
|
+
}
|
|
2528
|
+
kept.push(arg);
|
|
2529
|
+
}
|
|
2530
|
+
return kept;
|
|
2531
|
+
}
|
|
2532
|
+
function argvPositional(argv, ...names) {
|
|
2533
|
+
return argvWithout(argv.slice(1), ...names).find(
|
|
2534
|
+
(arg) => !arg.startsWith("--")
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2496
2537
|
|
|
2497
2538
|
// src/commands/anchor-resolve.ts
|
|
2498
2539
|
function resolverSummary(results) {
|
|
@@ -2925,6 +2966,13 @@ function successors(record, byId) {
|
|
|
2925
2966
|
return { records, missing: missing2 };
|
|
2926
2967
|
}
|
|
2927
2968
|
|
|
2969
|
+
// src/kb-tags.ts
|
|
2970
|
+
function matchesTags(record, filter) {
|
|
2971
|
+
if (!filter.tags?.length && !filter.excludeTags?.length) return true;
|
|
2972
|
+
const carried = new Set(record.frontmatter.tags ?? []);
|
|
2973
|
+
return (filter.tags ?? []).every((tag) => carried.has(tag)) && !(filter.excludeTags ?? []).some((tag) => carried.has(tag));
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2928
2976
|
// src/catalog.ts
|
|
2929
2977
|
var EMPTY_STANDINGS = {
|
|
2930
2978
|
current: 0,
|
|
@@ -2935,7 +2983,7 @@ var EMPTY_STANDINGS = {
|
|
|
2935
2983
|
};
|
|
2936
2984
|
function catalog(bundle, options = {}) {
|
|
2937
2985
|
const wanted = options.type ? bundle.filter((record) => record.frontmatter.type === options.type) : bundle;
|
|
2938
|
-
const entries = adjudicate(wanted, bundle, options.now ?? /* @__PURE__ */ new Date()).map((hit) => ({
|
|
2986
|
+
const entries = adjudicate(wanted, bundle, options.now ?? /* @__PURE__ */ new Date()).filter((hit) => matchesTags(hit.record, options)).map((hit) => ({
|
|
2939
2987
|
conceptId: hit.record.conceptId,
|
|
2940
2988
|
type: hit.record.frontmatter.type,
|
|
2941
2989
|
title: hit.record.frontmatter.title ?? null,
|
|
@@ -2975,25 +3023,39 @@ function renderCatalogLine(entry) {
|
|
|
2975
3023
|
var catalogCommand = define({
|
|
2976
3024
|
name: "catalog",
|
|
2977
3025
|
tool: "kb_catalog",
|
|
2978
|
-
usage: "catalog [type]",
|
|
3026
|
+
usage: "catalog [type] [--tag T]...",
|
|
2979
3027
|
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.",
|
|
2980
3028
|
input: import_zod10.z.object({
|
|
2981
3029
|
bundlePath,
|
|
2982
|
-
type: import_zod10.z.enum(KB_RECORD_TYPES).optional()
|
|
2983
|
-
|
|
2984
|
-
fromArgv: (argv, path) => ({
|
|
2985
|
-
bundlePath: path,
|
|
2986
|
-
...argv[1] && !argv[1].startsWith("--") ? { type: argv[1] } : {}
|
|
3030
|
+
type: import_zod10.z.enum(KB_RECORD_TYPES).optional(),
|
|
3031
|
+
tags: TAGS
|
|
2987
3032
|
}),
|
|
2988
|
-
|
|
2989
|
-
|
|
3033
|
+
fromArgv: (argv, path) => {
|
|
3034
|
+
const tags = argvFlags(argv, "--tag");
|
|
3035
|
+
const type = argvPositional(argv, "--tag");
|
|
3036
|
+
return {
|
|
3037
|
+
bundlePath: path,
|
|
3038
|
+
...type ? { type } : {},
|
|
3039
|
+
...tags.length ? { tags } : {}
|
|
3040
|
+
};
|
|
3041
|
+
},
|
|
3042
|
+
run: async ({ store }, { bundlePath: path, type, tags }) => render(
|
|
3043
|
+
await store.catalog(path, {
|
|
3044
|
+
...type ? { type } : {},
|
|
3045
|
+
...tags ? { tags } : {}
|
|
3046
|
+
}),
|
|
2990
3047
|
path,
|
|
2991
|
-
type
|
|
3048
|
+
type,
|
|
3049
|
+
tags
|
|
2992
3050
|
)
|
|
2993
3051
|
});
|
|
2994
|
-
function render(result, bundle, type) {
|
|
3052
|
+
function render(result, bundle, type, tags) {
|
|
3053
|
+
const narrowed = [
|
|
3054
|
+
...type ? [type] : [],
|
|
3055
|
+
...tags?.length ? [`tags: ${tags.join(", ")}`] : []
|
|
3056
|
+
].join(" \xB7 ");
|
|
2995
3057
|
const lines = [
|
|
2996
|
-
`# KB Catalog${
|
|
3058
|
+
`# KB Catalog${narrowed ? ` \u2014 ${narrowed}` : ""}`,
|
|
2997
3059
|
`bundle: ${bundle}`,
|
|
2998
3060
|
`${count(result.recordCount, "record")}: ${standingCounts(result)}`
|
|
2999
3061
|
];
|
|
@@ -3005,7 +3067,7 @@ function render(result, bundle, type) {
|
|
|
3005
3067
|
lines.push("");
|
|
3006
3068
|
if (!result.entries.length) {
|
|
3007
3069
|
lines.push(
|
|
3008
|
-
|
|
3070
|
+
narrowed ? `(no records matching ${narrowed})` : "(no records \u2014 this base is empty)"
|
|
3009
3071
|
);
|
|
3010
3072
|
} else {
|
|
3011
3073
|
for (const entry of result.entries) lines.push(renderCatalogLine(entry));
|
|
@@ -3092,7 +3154,7 @@ function preamble() {
|
|
|
3092
3154
|
"tokens."
|
|
3093
3155
|
].join("\n");
|
|
3094
3156
|
}
|
|
3095
|
-
async function renderBase(store, path, absolutePath, fullUnderTokens, pinMode, budgetTokens) {
|
|
3157
|
+
async function renderBase(store, path, absolutePath, fullUnderTokens, pinMode, budgetTokens, excludeTags) {
|
|
3096
3158
|
const bundle = await store.list(absolutePath);
|
|
3097
3159
|
if (bundle.length === 0) {
|
|
3098
3160
|
return {
|
|
@@ -3106,7 +3168,8 @@ async function renderBase(store, path, absolutePath, fullUnderTokens, pinMode, b
|
|
|
3106
3168
|
let degradedFrom;
|
|
3107
3169
|
if (fullCap > 0) {
|
|
3108
3170
|
const full = await store.load(absolutePath, {
|
|
3109
|
-
budgetTokens: fullCap
|
|
3171
|
+
budgetTokens: fullCap,
|
|
3172
|
+
excludeTags
|
|
3110
3173
|
});
|
|
3111
3174
|
if (!full.loaded && pinMode === "full") {
|
|
3112
3175
|
degradedFrom = { approxTokens: full.approxTokens };
|
|
@@ -3136,7 +3199,9 @@ async function renderBase(store, path, absolutePath, fullUnderTokens, pinMode, b
|
|
|
3136
3199
|
};
|
|
3137
3200
|
}
|
|
3138
3201
|
}
|
|
3139
|
-
const adjudicated = adjudicate(bundle, bundle)
|
|
3202
|
+
const adjudicated = adjudicate(bundle, bundle).filter(
|
|
3203
|
+
(hit) => matchesTags(hit.record, { excludeTags })
|
|
3204
|
+
);
|
|
3140
3205
|
const lines = adjudicated.filter((hit) => hit.standing !== "superseded").map((hit) => renderIndexLine(hit.record));
|
|
3141
3206
|
const superseded = adjudicated.filter((hit) => hit.standing === "superseded").map(
|
|
3142
3207
|
(hit) => `- \`${hit.record.conceptId}\` \u2192 superseded by ${hit.heads.map((head) => `\`${head.conceptId}\``).join(", ") || "(missing replacement)"}`
|
|
@@ -3157,6 +3222,7 @@ async function buildContext(store, workspaceDir, options = {}) {
|
|
|
3157
3222
|
const fromManifest = mergedContextBudgets(merged, options.profile);
|
|
3158
3223
|
budgetTokens = options.budgetTokens ?? fromManifest.budgetTokens ?? builtin.budgetTokens ?? DEFAULT_CONTEXT_BUDGET;
|
|
3159
3224
|
fullUnderTokens = options.fullUnderTokens ?? fromManifest.fullUnderTokens ?? builtin.fullUnderTokens ?? 0;
|
|
3225
|
+
const excludeTags = options.excludeTags ?? fromManifest.excludeTags ?? builtin.excludeTags ?? [];
|
|
3160
3226
|
const pins = merged.pins.filter(
|
|
3161
3227
|
(pin) => !pin.profiles?.length || !options.profile || pin.profiles.includes(options.profile)
|
|
3162
3228
|
);
|
|
@@ -3177,7 +3243,8 @@ async function buildContext(store, workspaceDir, options = {}) {
|
|
|
3177
3243
|
pin.absolutePath,
|
|
3178
3244
|
fullUnderTokens,
|
|
3179
3245
|
pin.mode,
|
|
3180
|
-
budgetTokens
|
|
3246
|
+
budgetTokens,
|
|
3247
|
+
excludeTags
|
|
3181
3248
|
),
|
|
3182
3249
|
frozen: pin.frozen === true
|
|
3183
3250
|
}))
|
|
@@ -3298,7 +3365,7 @@ ${CONTEXT_END}` : null;
|
|
|
3298
3365
|
var contextCommand = define({
|
|
3299
3366
|
name: "context",
|
|
3300
3367
|
tool: "kb_context",
|
|
3301
|
-
usage: "context [--profile NAME] [--budget N] [--full-under N] [--format json] [--event NAME]",
|
|
3368
|
+
usage: "context [--profile NAME] [--budget N] [--full-under N] [--exclude-tag T]... [--format json] [--event NAME]",
|
|
3302
3369
|
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.",
|
|
3303
3370
|
input: import_zod11.z.object({
|
|
3304
3371
|
budgetTokens: import_zod11.z.number().int().positive().optional().describe(
|
|
@@ -3310,6 +3377,9 @@ var contextCommand = define({
|
|
|
3310
3377
|
profile: import_zod11.z.string().optional().describe(
|
|
3311
3378
|
"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."
|
|
3312
3379
|
),
|
|
3380
|
+
excludeTags: import_zod11.z.array(import_zod11.z.string().min(1)).optional().describe(
|
|
3381
|
+
"Frontmatter tags whose records stay out of the block. The base stays pinned and stays readable by tool; resolved like the budgets."
|
|
3382
|
+
),
|
|
3313
3383
|
format: import_zod11.z.enum(["markdown", "json"]).optional().describe(
|
|
3314
3384
|
"CLI envelope for hook protocols that require strict JSON on stdout. MCP callers omit this \u2014 the block itself is identical."
|
|
3315
3385
|
),
|
|
@@ -3323,19 +3393,22 @@ var contextCommand = define({
|
|
|
3323
3393
|
const profile = argvFlag(argv, "--profile");
|
|
3324
3394
|
const format = argvFlag(argv, "--format");
|
|
3325
3395
|
const event = argvFlag(argv, "--event");
|
|
3396
|
+
const excludeTags = argvFlags(argv, "--exclude-tag");
|
|
3326
3397
|
return {
|
|
3327
3398
|
...budget ? { budgetTokens: Number(budget) } : {},
|
|
3328
3399
|
...fullUnder ? { fullUnderTokens: Number(fullUnder) } : {},
|
|
3329
3400
|
...profile ? { profile } : {},
|
|
3401
|
+
...excludeTags.length ? { excludeTags } : {},
|
|
3330
3402
|
...format ? { format } : {},
|
|
3331
3403
|
...event ? { event } : {}
|
|
3332
3404
|
};
|
|
3333
3405
|
},
|
|
3334
|
-
run: async ({ store }, { budgetTokens, fullUnderTokens, profile, format, event }) => {
|
|
3406
|
+
run: async ({ store }, { budgetTokens, fullUnderTokens, profile, excludeTags, format, event }) => {
|
|
3335
3407
|
const result = await buildContext(store, process.cwd(), {
|
|
3336
3408
|
...budgetTokens ? { budgetTokens } : {},
|
|
3337
3409
|
...fullUnderTokens ? { fullUnderTokens } : {},
|
|
3338
3410
|
...profile ? { profile } : {},
|
|
3411
|
+
...excludeTags ? { excludeTags } : {},
|
|
3339
3412
|
// Degradations — a full pin that could not fit, a refused block — go
|
|
3340
3413
|
// to stderr as well as into the block itself: stderr is diagnostics on
|
|
3341
3414
|
// both surfaces (hooks discard it, MCP logs it), so an operator can
|
|
@@ -4616,17 +4689,31 @@ var import_zod15 = require("zod");
|
|
|
4616
4689
|
var listCommand = define({
|
|
4617
4690
|
name: "list",
|
|
4618
4691
|
tool: "kb_list",
|
|
4619
|
-
usage: "list [type]",
|
|
4620
|
-
description: "Every record, optionally one type. For enumerating; use kb_query for a question.",
|
|
4621
|
-
input: import_zod15.z.object({
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4692
|
+
usage: "list [type] [--tag T]...",
|
|
4693
|
+
description: "Every record, optionally one type or tag. For enumerating; use kb_query for a question.",
|
|
4694
|
+
input: import_zod15.z.object({
|
|
4695
|
+
bundlePath,
|
|
4696
|
+
type: import_zod15.z.enum(KB_RECORD_TYPES).optional(),
|
|
4697
|
+
tags: TAGS
|
|
4698
|
+
}),
|
|
4699
|
+
fromArgv: (argv, path) => {
|
|
4700
|
+
const tags = argvFlags(argv, "--tag");
|
|
4701
|
+
const type = argvPositional(argv, "--tag");
|
|
4702
|
+
return {
|
|
4703
|
+
bundlePath: path,
|
|
4704
|
+
...type ? { type } : {},
|
|
4705
|
+
...tags.length ? { tags } : {}
|
|
4706
|
+
};
|
|
4707
|
+
},
|
|
4708
|
+
run: async ({ store }, { bundlePath: path, type, tags }) => (await store.list(path, type, { ...tags ? { tags } : {} })).map(
|
|
4709
|
+
(record) => ({
|
|
4710
|
+
conceptId: record.conceptId,
|
|
4711
|
+
title: record.frontmatter.title ?? null,
|
|
4712
|
+
description: record.frontmatter.description ?? null,
|
|
4713
|
+
status: record.frontmatter.strauss_status,
|
|
4714
|
+
anchors: record.frontmatter.strauss_anchors ?? []
|
|
4715
|
+
})
|
|
4716
|
+
)
|
|
4630
4717
|
});
|
|
4631
4718
|
|
|
4632
4719
|
// src/commands/load.ts
|
|
@@ -4877,31 +4964,33 @@ var import_zod22 = require("zod");
|
|
|
4877
4964
|
var queryCommand = define({
|
|
4878
4965
|
name: "query",
|
|
4879
4966
|
tool: "kb_query",
|
|
4880
|
-
usage: "query <text...> [--repo-root PATH]",
|
|
4967
|
+
usage: "query <text...> [--tag T]... [--repo-root PATH]",
|
|
4881
4968
|
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.",
|
|
4882
4969
|
input: import_zod22.z.object({
|
|
4883
4970
|
bundlePath,
|
|
4884
4971
|
text: import_zod22.z.string().optional(),
|
|
4885
4972
|
type: import_zod22.z.enum(KB_RECORD_TYPES).optional(),
|
|
4886
4973
|
includeNonCurrent: import_zod22.z.boolean().optional(),
|
|
4974
|
+
tags: TAGS,
|
|
4887
4975
|
repoRoot: REPO_ROOT
|
|
4888
4976
|
}),
|
|
4889
|
-
//
|
|
4977
|
+
// Both are flags, so neither's value may fall into the search text.
|
|
4890
4978
|
fromArgv: (argv, path) => {
|
|
4891
4979
|
const repoRoot = argvFlag(argv, "--repo-root");
|
|
4892
|
-
const
|
|
4893
|
-
const
|
|
4894
|
-
if (flag !== -1) words.splice(flag, 2);
|
|
4980
|
+
const tags = argvFlags(argv, "--tag");
|
|
4981
|
+
const words = argvWithout(argv.slice(1), "--repo-root", "--tag");
|
|
4895
4982
|
return {
|
|
4896
4983
|
bundlePath: path,
|
|
4897
4984
|
text: words.join(" ").trim(),
|
|
4898
4985
|
includeNonCurrent: true,
|
|
4986
|
+
...tags.length ? { tags } : {},
|
|
4899
4987
|
...repoRoot !== void 0 ? { repoRoot } : {}
|
|
4900
4988
|
};
|
|
4901
4989
|
},
|
|
4902
|
-
run: async ({ store }, { bundlePath: path, text, type, includeNonCurrent, repoRoot }) => (await store.query(path, text ?? "", {
|
|
4990
|
+
run: async ({ store }, { bundlePath: path, text, type, includeNonCurrent, tags, repoRoot }) => (await store.query(path, text ?? "", {
|
|
4903
4991
|
...type ? { type } : {},
|
|
4904
4992
|
includeNonCurrent: includeNonCurrent === true,
|
|
4993
|
+
...tags ? { tags } : {},
|
|
4905
4994
|
...repoRoot !== void 0 ? { repoRoot } : {}
|
|
4906
4995
|
})).map((hit) => ({
|
|
4907
4996
|
conceptId: hit.record.conceptId,
|
|
@@ -5900,13 +5989,16 @@ var KbStore = class {
|
|
|
5900
5989
|
return this.parse(conceptId2, raw);
|
|
5901
5990
|
}
|
|
5902
5991
|
/**
|
|
5903
|
-
* Every record in the bundle, optionally narrowed to one type
|
|
5992
|
+
* Every record in the bundle, optionally narrowed to one type and to the
|
|
5993
|
+
* records carrying every tag in `filter.tags`. Selection only — `excludeTags`
|
|
5994
|
+
* is not taken here, because `query`, `catalog` and `load` read through this
|
|
5995
|
+
* and must adjudicate over the whole base.
|
|
5904
5996
|
*
|
|
5905
5997
|
* A file that fails to parse is skipped and logged rather than thrown: one
|
|
5906
5998
|
* malformed record — hand-edited, or written by a producer we don't know —
|
|
5907
5999
|
* must not make the whole bundle unreadable.
|
|
5908
6000
|
*/
|
|
5909
|
-
async list(bundlePath2, type) {
|
|
6001
|
+
async list(bundlePath2, type, filter = {}) {
|
|
5910
6002
|
const root = this.root(bundlePath2);
|
|
5911
6003
|
let names;
|
|
5912
6004
|
try {
|
|
@@ -5920,7 +6012,9 @@ var KbStore = class {
|
|
|
5920
6012
|
DEFAULT_IO_CONCURRENCY,
|
|
5921
6013
|
async ({ name, conceptId: conceptId2 }) => this.parse(conceptId2, await (0, import_promises10.readFile)((0, import_node_path11.join)(root, name), "utf8"))
|
|
5922
6014
|
);
|
|
5923
|
-
return records.filter(
|
|
6015
|
+
return records.filter(
|
|
6016
|
+
(record) => record !== null && matchesTags(record, filter)
|
|
6017
|
+
);
|
|
5924
6018
|
}
|
|
5925
6019
|
/**
|
|
5926
6020
|
* Moves a record's status, preserving everything else.
|
|
@@ -6060,9 +6154,10 @@ ${answer}
|
|
|
6060
6154
|
/* @__PURE__ */ new Date(),
|
|
6061
6155
|
await this.detectDrift(narrowed, options.repoRoot)
|
|
6062
6156
|
);
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6157
|
+
const kept = adjudicated.filter((hit) => matchesTags(hit.record, options));
|
|
6158
|
+
if (options.includeNonCurrent) return kept;
|
|
6159
|
+
const present = new Set(kept.map((hit) => hit.record.conceptId));
|
|
6160
|
+
return kept.filter(
|
|
6066
6161
|
(hit) => hit.standing !== "superseded" || !hit.heads.some((head) => present.has(head.conceptId))
|
|
6067
6162
|
);
|
|
6068
6163
|
}
|
|
@@ -6165,14 +6260,17 @@ ${answer}
|
|
|
6165
6260
|
/* @__PURE__ */ new Date(),
|
|
6166
6261
|
await this.detectDrift(wanted, options.repoRoot)
|
|
6167
6262
|
);
|
|
6168
|
-
const
|
|
6169
|
-
|
|
6263
|
+
const kept = adjudicated.filter(
|
|
6264
|
+
(hit) => matchesTags(hit.record, { excludeTags: options.excludeTags })
|
|
6265
|
+
);
|
|
6266
|
+
const records = kept.filter((hit) => hit.standing !== "superseded");
|
|
6267
|
+
const superseded = kept.filter((hit) => hit.standing === "superseded").map(stub);
|
|
6170
6268
|
const approxTokens2 = records.reduce((total, hit) => total + estimateTokens(hit.record), 0) + superseded.reduce((total, entry) => total + estimateStubTokens(entry), 0);
|
|
6171
6269
|
const bundleDigestValue = bundleDigest(records, superseded);
|
|
6172
6270
|
if (!options.all && approxTokens2 > budgetTokens) {
|
|
6173
6271
|
return {
|
|
6174
6272
|
loaded: false,
|
|
6175
|
-
recordCount:
|
|
6273
|
+
recordCount: kept.length,
|
|
6176
6274
|
approxTokens: approxTokens2,
|
|
6177
6275
|
budgetTokens,
|
|
6178
6276
|
message: refusalMessage({
|
|
@@ -6185,7 +6283,7 @@ ${answer}
|
|
|
6185
6283
|
}
|
|
6186
6284
|
return {
|
|
6187
6285
|
loaded: true,
|
|
6188
|
-
recordCount:
|
|
6286
|
+
recordCount: kept.length,
|
|
6189
6287
|
tokensLoaded: approxTokens2,
|
|
6190
6288
|
budgetTokens: options.all ? null : budgetTokens,
|
|
6191
6289
|
records,
|
|
@@ -6546,7 +6644,7 @@ function normalizeActor(id) {
|
|
|
6546
6644
|
}
|
|
6547
6645
|
|
|
6548
6646
|
// src/version.ts
|
|
6549
|
-
var VERSION = true ? "0.1.
|
|
6647
|
+
var VERSION = true ? "0.1.19" : "0.0.0-dev";
|
|
6550
6648
|
|
|
6551
6649
|
// src/mcp.ts
|
|
6552
6650
|
function createKbMcpServer() {
|