@viloforge/vfkb 0.2.3 → 0.4.0
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/broadcast.js +134 -0
- package/dist/bundles/vfkb-mcp.mjs +106 -39
- package/dist/bundles/vfkb.mjs +545 -177
- package/dist/cli.js +86 -5
- package/dist/doctor.js +35 -0
- package/dist/engine.js +80 -5
- package/dist/init.js +1 -1
- package/dist/journal.js +207 -0
- package/dist/storage.js +10 -1
- package/package.json +1 -1
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// ADR-0063 §3 — `vfkb broadcast`: write one cross-repo record fact into each
|
|
2
|
+
// target repo's brain, through the engine, stamping mechanically what the v1
|
|
3
|
+
// convention leaves to discipline (the `cross-repo` tag, the CROSS-REPO marker
|
|
4
|
+
// with origin + date). Refusals are per-target and loud — a partial broadcast
|
|
5
|
+
// must be visible, never silent — and the writer NEVER commits the target
|
|
6
|
+
// (§4: the entry rides the target's own ADR-0033 discipline).
|
|
7
|
+
import { execFileSync } from 'node:child_process';
|
|
8
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
9
|
+
import { basename, join, resolve } from 'node:path';
|
|
10
|
+
import { addEntry } from './engine.js';
|
|
11
|
+
import { writeManifest } from './manifest.js';
|
|
12
|
+
import { defaultProject } from './storage.js';
|
|
13
|
+
import { SCHEMA_VERSION } from './version.js';
|
|
14
|
+
/** The resident-pin tags a broadcast record must never carry (ADR-0063 §1). */
|
|
15
|
+
const FORBIDDEN_TAGS = new Set(['handoff', 'next']);
|
|
16
|
+
function targetBrainDir(target) {
|
|
17
|
+
const abs = resolve(target);
|
|
18
|
+
return basename(abs) === '.vfkb' ? abs : join(abs, '.vfkb');
|
|
19
|
+
}
|
|
20
|
+
function gitPosture(repoDir) {
|
|
21
|
+
const git = (...a) => execFileSync('git', ['-C', repoDir, ...a], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
22
|
+
try {
|
|
23
|
+
const branch = git('rev-parse', '--abbrev-ref', 'HEAD');
|
|
24
|
+
const parked = branch === 'main' || branch === 'master';
|
|
25
|
+
return `uncommitted; target on ${branch}${parked ? ' (parked — rides until a topic-branch brain commit)' : ''}`;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// rev-parse HEAD fails on a repo with no commits yet — distinguish that
|
|
29
|
+
// from "not a repo at all" (review finding: unborn HEAD was misreported).
|
|
30
|
+
try {
|
|
31
|
+
if (git('rev-parse', '--is-inside-work-tree') === 'true') {
|
|
32
|
+
return 'uncommitted; target git repository on an unborn branch (no commits yet)';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
/* fall through */
|
|
37
|
+
}
|
|
38
|
+
return 'uncommitted; target not a git repository';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Broadcast one record to N target brains. Origin is derived from the INVOKING
|
|
43
|
+
* repo's project label, captured before any env switching. Targets without a
|
|
44
|
+
* brain are refused (never bootstrap a wire-less brain — ADR-0063 §3): no
|
|
45
|
+
* `entries.jsonl` means wire-less; a wired brain merely missing its
|
|
46
|
+
* `manifest.json` (plugin-born, vfkb#193) is healed, visibly. Brains whose
|
|
47
|
+
* schema the running engine does not support are refused (promoting doctor's
|
|
48
|
+
* diagnostic to a hard refusal).
|
|
49
|
+
*/
|
|
50
|
+
export function broadcast(text, targets, opts = {}) {
|
|
51
|
+
const origin = defaultProject();
|
|
52
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
53
|
+
const extraTags = opts.tags ?? [];
|
|
54
|
+
for (const t of extraTags) {
|
|
55
|
+
if (FORBIDDEN_TAGS.has(t)) {
|
|
56
|
+
throw new Error(`broadcast: tag '${t}' is forbidden on cross-repo records — it claims the resident's ADR-0049 continuity pin (ADR-0063 §1)`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const op = (opts.op || 'OPERATION').toUpperCase();
|
|
60
|
+
// No-double-stamp applies only to a COMPLETE marker (op + date + origin) —
|
|
61
|
+
// a bare "CROSS-REPO " prefix must not waive the stamping this command
|
|
62
|
+
// exists to mechanize (review finding: the loose prefix test let a record
|
|
63
|
+
// land with no origin and no date, the ADR-0051 §3 quiet-success shape).
|
|
64
|
+
const MARKER = /^CROSS-REPO \S+ \(\d{4}-\d{2}-\d{2}, from [^)]+\):/;
|
|
65
|
+
const stamped = MARKER.test(text) ? text : `CROSS-REPO ${op} (${date}, from ${origin}): ${text}`;
|
|
66
|
+
const results = [];
|
|
67
|
+
const written = new Set();
|
|
68
|
+
for (const target of targets) {
|
|
69
|
+
const brain = targetBrainDir(target);
|
|
70
|
+
// "Exactly one record per affected repo" (ADR-0063 §1) also holds across
|
|
71
|
+
// path spellings of the same target within one broadcast.
|
|
72
|
+
if (written.has(brain)) {
|
|
73
|
+
results.push({ target, ok: false, reason: 'duplicate target (already written in this broadcast)' });
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const repoDir = resolve(brain, '..');
|
|
77
|
+
const manifestPath = join(brain, 'manifest.json');
|
|
78
|
+
let healed = false;
|
|
79
|
+
if (!existsSync(manifestPath)) {
|
|
80
|
+
// §3's rule is "never bootstrap a WIRE-LESS brain". A brain with a live
|
|
81
|
+
// entries.jsonl is wired — the manifest is just missing because only
|
|
82
|
+
// `vfkb init` ever writes it (plugin-born brains, vfkb#193). Heal it
|
|
83
|
+
// (engine-written stamp) instead of refusing; refuse only when there are
|
|
84
|
+
// no entries at all, which is the true wire-less case.
|
|
85
|
+
if (!existsSync(join(brain, 'entries.jsonl'))) {
|
|
86
|
+
results.push({ target, ok: false, reason: `no brain (no entries.jsonl in ${brain}) — never bootstrap a wire-less brain (ADR-0063 §3)` });
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
writeManifest(brain);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
// Per-target and loud, never a thrown abort — a heal failure on one
|
|
94
|
+
// target must not swallow the rest of a partial broadcast.
|
|
95
|
+
results.push({ target, ok: false, reason: `manifest heal failed: ${err.message}` });
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
healed = true;
|
|
99
|
+
}
|
|
100
|
+
let schema;
|
|
101
|
+
try {
|
|
102
|
+
schema = JSON.parse(readFileSync(manifestPath, 'utf8')).schema_version;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
results.push({ target, ok: false, reason: 'unreadable manifest.json' });
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (schema !== SCHEMA_VERSION) {
|
|
109
|
+
results.push({ target, ok: false, reason: `brain schema ${JSON.stringify(schema)} unsupported by engine schema v${SCHEMA_VERSION}` });
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
// brainDir() resolves VFKB_DATA_DIR fresh on every call (the RFC-013/033
|
|
113
|
+
// verified transport), so an env swap scopes the engine write to the target.
|
|
114
|
+
const prev = process.env.VFKB_DATA_DIR;
|
|
115
|
+
try {
|
|
116
|
+
process.env.VFKB_DATA_DIR = brain;
|
|
117
|
+
const e = addEntry('fact', stamped, { role: 'executor', tags: [...new Set(['cross-repo', ...extraTags])] });
|
|
118
|
+
written.add(brain);
|
|
119
|
+
results.push({ target, ok: true, id: e.id, posture: gitPosture(repoDir), ...(healed ? { healed } : {}) });
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
// healed still reported on failure — the manifest stamp happened even
|
|
123
|
+
// though the record did not land (heal is never silent).
|
|
124
|
+
results.push({ target, ok: false, reason: err.message, ...(healed ? { healed } : {}) });
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
if (prev === undefined)
|
|
128
|
+
delete process.env.VFKB_DATA_DIR;
|
|
129
|
+
else
|
|
130
|
+
process.env.VFKB_DATA_DIR = prev;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return results;
|
|
134
|
+
}
|
|
@@ -3648,49 +3648,49 @@ var require_fast_uri = __commonJS({
|
|
|
3648
3648
|
schemelessOptions.skipEscape = true;
|
|
3649
3649
|
return serialize(resolved, schemelessOptions);
|
|
3650
3650
|
}
|
|
3651
|
-
function resolveComponent(base,
|
|
3651
|
+
function resolveComponent(base, relative2, options, skipNormalization) {
|
|
3652
3652
|
const target = {};
|
|
3653
3653
|
if (!skipNormalization) {
|
|
3654
3654
|
base = parse3(serialize(base, options), options);
|
|
3655
|
-
|
|
3655
|
+
relative2 = parse3(serialize(relative2, options), options);
|
|
3656
3656
|
}
|
|
3657
3657
|
options = options || {};
|
|
3658
|
-
if (!options.tolerant &&
|
|
3659
|
-
target.scheme =
|
|
3660
|
-
target.userinfo =
|
|
3661
|
-
target.host =
|
|
3662
|
-
target.port =
|
|
3663
|
-
target.path = removeDotSegments(
|
|
3664
|
-
target.query =
|
|
3658
|
+
if (!options.tolerant && relative2.scheme) {
|
|
3659
|
+
target.scheme = relative2.scheme;
|
|
3660
|
+
target.userinfo = relative2.userinfo;
|
|
3661
|
+
target.host = relative2.host;
|
|
3662
|
+
target.port = relative2.port;
|
|
3663
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
3664
|
+
target.query = relative2.query;
|
|
3665
3665
|
} else {
|
|
3666
|
-
if (
|
|
3667
|
-
target.userinfo =
|
|
3668
|
-
target.host =
|
|
3669
|
-
target.port =
|
|
3670
|
-
target.path = removeDotSegments(
|
|
3671
|
-
target.query =
|
|
3666
|
+
if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
|
|
3667
|
+
target.userinfo = relative2.userinfo;
|
|
3668
|
+
target.host = relative2.host;
|
|
3669
|
+
target.port = relative2.port;
|
|
3670
|
+
target.path = removeDotSegments(relative2.path || "");
|
|
3671
|
+
target.query = relative2.query;
|
|
3672
3672
|
} else {
|
|
3673
|
-
if (!
|
|
3673
|
+
if (!relative2.path) {
|
|
3674
3674
|
target.path = base.path;
|
|
3675
|
-
if (
|
|
3676
|
-
target.query =
|
|
3675
|
+
if (relative2.query !== void 0) {
|
|
3676
|
+
target.query = relative2.query;
|
|
3677
3677
|
} else {
|
|
3678
3678
|
target.query = base.query;
|
|
3679
3679
|
}
|
|
3680
3680
|
} else {
|
|
3681
|
-
if (
|
|
3682
|
-
target.path = removeDotSegments(
|
|
3681
|
+
if (relative2.path[0] === "/") {
|
|
3682
|
+
target.path = removeDotSegments(relative2.path);
|
|
3683
3683
|
} else {
|
|
3684
3684
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
3685
|
-
target.path = "/" +
|
|
3685
|
+
target.path = "/" + relative2.path;
|
|
3686
3686
|
} else if (!base.path) {
|
|
3687
|
-
target.path =
|
|
3687
|
+
target.path = relative2.path;
|
|
3688
3688
|
} else {
|
|
3689
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
3689
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
|
|
3690
3690
|
}
|
|
3691
3691
|
target.path = removeDotSegments(target.path);
|
|
3692
3692
|
}
|
|
3693
|
-
target.query =
|
|
3693
|
+
target.query = relative2.query;
|
|
3694
3694
|
}
|
|
3695
3695
|
target.userinfo = base.userinfo;
|
|
3696
3696
|
target.host = base.host;
|
|
@@ -3698,7 +3698,7 @@ var require_fast_uri = __commonJS({
|
|
|
3698
3698
|
}
|
|
3699
3699
|
target.scheme = base.scheme;
|
|
3700
3700
|
}
|
|
3701
|
-
target.fragment =
|
|
3701
|
+
target.fragment = relative2.fragment;
|
|
3702
3702
|
return target;
|
|
3703
3703
|
}
|
|
3704
3704
|
function equal(uriA, uriB, options) {
|
|
@@ -30956,7 +30956,7 @@ var StdioServerTransport = class {
|
|
|
30956
30956
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
30957
30957
|
|
|
30958
30958
|
// src/storage.ts
|
|
30959
|
-
import { basename, dirname, join as
|
|
30959
|
+
import { basename, dirname as dirname2, join as join4, resolve } from "node:path";
|
|
30960
30960
|
import { homedir } from "node:os";
|
|
30961
30961
|
import { createHash } from "node:crypto";
|
|
30962
30962
|
|
|
@@ -31154,6 +31154,23 @@ function storageBackend() {
|
|
|
31154
31154
|
return current;
|
|
31155
31155
|
}
|
|
31156
31156
|
|
|
31157
|
+
// src/journal.ts
|
|
31158
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
31159
|
+
import { dirname, join as join3, relative, sep } from "node:path";
|
|
31160
|
+
var walPath = (brain) => join3(brain, ".journal", "wal.jsonl");
|
|
31161
|
+
function journalAppend(brain, rec) {
|
|
31162
|
+
if (process.env.VFKB_NO_JOURNAL) return;
|
|
31163
|
+
try {
|
|
31164
|
+
mkdirSync3(join3(brain, ".journal"), { recursive: true });
|
|
31165
|
+
appendFileSync2(walPath(brain), JSON.stringify(rec) + "\n", "utf8");
|
|
31166
|
+
} catch (err) {
|
|
31167
|
+
process.stderr.write(
|
|
31168
|
+
`vfkb: journal mirror failed (primary append proceeds unprotected): ${err.message}
|
|
31169
|
+
`
|
|
31170
|
+
);
|
|
31171
|
+
}
|
|
31172
|
+
}
|
|
31173
|
+
|
|
31157
31174
|
// src/validate.ts
|
|
31158
31175
|
var ROLE = external_exports.enum(["architect", "pm", "executor", "judge", "human", "init", "import"]);
|
|
31159
31176
|
var PROV_STATUS = external_exports.enum(["verified", "unverified", "stale", "expired"]);
|
|
@@ -31205,7 +31222,7 @@ function isTombstone(r) {
|
|
|
31205
31222
|
return r.deleted === true;
|
|
31206
31223
|
}
|
|
31207
31224
|
function brainDir() {
|
|
31208
|
-
return process.env.VFKB_DATA_DIR || process.env.VFKB_DIR ||
|
|
31225
|
+
return process.env.VFKB_DATA_DIR || process.env.VFKB_DIR || join4(homedir(), ".vfkb");
|
|
31209
31226
|
}
|
|
31210
31227
|
function defaultProject() {
|
|
31211
31228
|
const raw = (() => {
|
|
@@ -31214,7 +31231,7 @@ function defaultProject() {
|
|
|
31214
31231
|
if (explicit) {
|
|
31215
31232
|
const abs = resolve(explicit);
|
|
31216
31233
|
const name = basename(abs);
|
|
31217
|
-
return name.startsWith(".") ? basename(
|
|
31234
|
+
return name.startsWith(".") ? basename(dirname2(abs)) : name;
|
|
31218
31235
|
}
|
|
31219
31236
|
const root = process.env.CLAUDE_PROJECT_DIR;
|
|
31220
31237
|
if (root) return basename(resolve(root));
|
|
@@ -31223,7 +31240,9 @@ function defaultProject() {
|
|
|
31223
31240
|
return raw.replace(/["<>&]/g, "") || "spike";
|
|
31224
31241
|
}
|
|
31225
31242
|
function appendRecord(rec) {
|
|
31226
|
-
storageBackend()
|
|
31243
|
+
const be = storageBackend();
|
|
31244
|
+
if (be.name === "jsonl-fs") journalAppend(be.location(), rec);
|
|
31245
|
+
be.append(rec);
|
|
31227
31246
|
writeMeta();
|
|
31228
31247
|
}
|
|
31229
31248
|
function withExclusive(fn) {
|
|
@@ -31387,15 +31406,15 @@ function assertNoSecrets(text2) {
|
|
|
31387
31406
|
}
|
|
31388
31407
|
|
|
31389
31408
|
// src/counters.ts
|
|
31390
|
-
import { appendFileSync as
|
|
31391
|
-
import { join as
|
|
31409
|
+
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync4, existsSync as existsSync3 } from "node:fs";
|
|
31410
|
+
import { join as join5 } from "node:path";
|
|
31392
31411
|
function signalsFile() {
|
|
31393
|
-
return
|
|
31412
|
+
return join5(brainDir(), ".signals", "counters.jsonl");
|
|
31394
31413
|
}
|
|
31395
31414
|
function readSignals() {
|
|
31396
31415
|
const f = signalsFile();
|
|
31397
|
-
if (!
|
|
31398
|
-
return
|
|
31416
|
+
if (!existsSync3(f)) return [];
|
|
31417
|
+
return readFileSync4(f, "utf8").split("\n").filter((l) => l.trim().length > 0).map((l) => JSON.parse(l));
|
|
31399
31418
|
}
|
|
31400
31419
|
function tally(entryId, signals = readSignals()) {
|
|
31401
31420
|
let helpful = 0;
|
|
@@ -31740,6 +31759,22 @@ function latestHandoff(all = readAll(), today = nowIso().slice(0, 10), supersede
|
|
|
31740
31759
|
}
|
|
31741
31760
|
return latest;
|
|
31742
31761
|
}
|
|
31762
|
+
var CROSS_REPO_PIN_CAP_CHARS = 2e3;
|
|
31763
|
+
function latestCrossRepo(all = readAll(), today = nowIso().slice(0, 10), superseded = supersededIds(all)) {
|
|
31764
|
+
let latest = null;
|
|
31765
|
+
for (const e of all) {
|
|
31766
|
+
if (!e.tags.includes("cross-repo")) continue;
|
|
31767
|
+
if (e.tags.includes("handoff") || e.tags.includes("next")) continue;
|
|
31768
|
+
if (!isInjectable(e, today, superseded)) continue;
|
|
31769
|
+
if (!latest) {
|
|
31770
|
+
latest = e;
|
|
31771
|
+
continue;
|
|
31772
|
+
}
|
|
31773
|
+
const cmp = e.updated.localeCompare(latest.updated) || e.created.localeCompare(latest.created);
|
|
31774
|
+
if (cmp >= 0) latest = e;
|
|
31775
|
+
}
|
|
31776
|
+
return latest;
|
|
31777
|
+
}
|
|
31743
31778
|
function renderContextBundle(project = defaultProject(), budget = SESSION_BUDGET_CHARS) {
|
|
31744
31779
|
const all = readAll();
|
|
31745
31780
|
const today = nowIso().slice(0, 10);
|
|
@@ -31767,25 +31802,57 @@ function renderContextBundle(project = defaultProject(), budget = SESSION_BUDGET
|
|
|
31767
31802
|
body += `## Last handoff
|
|
31768
31803
|
- [${handoff.type} ${trustGlyph(handoff)}] ${text2}
|
|
31769
31804
|
|
|
31805
|
+
`;
|
|
31806
|
+
}
|
|
31807
|
+
const crossRepo = latestCrossRepo(all, today, superseded);
|
|
31808
|
+
if (crossRepo && !constitutionalIds.has(crossRepo.id)) {
|
|
31809
|
+
const text2 = crossRepo.text.length > CROSS_REPO_PIN_CAP_CHARS ? `${crossRepo.text.slice(0, CROSS_REPO_PIN_CAP_CHARS)}\u2026 (truncated \u2014 kb_get ${crossRepo.id} for the rest)` : crossRepo.text;
|
|
31810
|
+
body += `## Cross-repo operations
|
|
31811
|
+
- [${crossRepo.type} ${trustGlyph(crossRepo)}] ${text2}
|
|
31812
|
+
|
|
31770
31813
|
`;
|
|
31771
31814
|
}
|
|
31772
31815
|
body += renderContextMap() + "\n\n";
|
|
31816
|
+
const kept = [];
|
|
31817
|
+
let keptLen = 0;
|
|
31773
31818
|
let dropped = 0;
|
|
31819
|
+
const fixedLen = () => header.length + body.length + footer.length;
|
|
31774
31820
|
for (const e of injectable) {
|
|
31775
31821
|
if (constitutionalIds.has(e.id)) continue;
|
|
31776
31822
|
if (handoff && e.id === handoff.id) continue;
|
|
31823
|
+
if (crossRepo && e.id === crossRepo.id) continue;
|
|
31777
31824
|
const line2 = `- [${e.type} ${trustGlyph(e)}] ${e.text}
|
|
31778
31825
|
`;
|
|
31779
|
-
if (
|
|
31826
|
+
if (fixedLen() + keptLen + line2.length > budget) {
|
|
31780
31827
|
dropped++;
|
|
31781
31828
|
continue;
|
|
31782
31829
|
}
|
|
31783
|
-
|
|
31830
|
+
kept.push(line2);
|
|
31831
|
+
keptLen += line2.length;
|
|
31784
31832
|
}
|
|
31785
31833
|
if (dropped > 0) {
|
|
31786
|
-
const note =
|
|
31834
|
+
const note = () => `(+ ${dropped} lower-ranked entries omitted for the ${budget}-char budget \u2014 kb_search / kb_list pulls them)
|
|
31787
31835
|
`;
|
|
31788
|
-
|
|
31836
|
+
const evicted = [];
|
|
31837
|
+
while (kept.length > 0 && fixedLen() + keptLen + note().length > budget) {
|
|
31838
|
+
const line2 = kept.pop();
|
|
31839
|
+
keptLen -= line2.length;
|
|
31840
|
+
evicted.push(line2);
|
|
31841
|
+
dropped++;
|
|
31842
|
+
}
|
|
31843
|
+
if (fixedLen() + keptLen + note().length <= budget) {
|
|
31844
|
+
body += kept.join("") + note();
|
|
31845
|
+
} else {
|
|
31846
|
+
while (evicted.length > 0) {
|
|
31847
|
+
const line2 = evicted.pop();
|
|
31848
|
+
kept.push(line2);
|
|
31849
|
+
keptLen += line2.length;
|
|
31850
|
+
dropped--;
|
|
31851
|
+
}
|
|
31852
|
+
body += kept.join("");
|
|
31853
|
+
}
|
|
31854
|
+
} else {
|
|
31855
|
+
body += kept.join("");
|
|
31789
31856
|
}
|
|
31790
31857
|
return header + body + footer;
|
|
31791
31858
|
}
|
|
@@ -31940,7 +32007,7 @@ function queryExplained(opts = {}) {
|
|
|
31940
32007
|
}
|
|
31941
32008
|
|
|
31942
32009
|
// src/version.ts
|
|
31943
|
-
var ENGINE_VERSION = true ? "0.
|
|
32010
|
+
var ENGINE_VERSION = true ? "0.4.0" : ownPackageVersion();
|
|
31944
32011
|
|
|
31945
32012
|
// src/mcp-server.ts
|
|
31946
32013
|
var SEARCH_DEFAULT_LIMIT = 25;
|