@yurtsever/capsa 0.1.0-alpha.7 → 0.1.0-alpha.8
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 +3 -2
- package/dist/index.js +457 -190
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2807,8 +2807,8 @@ var require_validate = __commonJS({
|
|
|
2807
2807
|
return data;
|
|
2808
2808
|
}
|
|
2809
2809
|
let expr = data;
|
|
2810
|
-
const
|
|
2811
|
-
for (const segment of
|
|
2810
|
+
const segments4 = jsonPointer.split("/");
|
|
2811
|
+
for (const segment of segments4) {
|
|
2812
2812
|
if (segment) {
|
|
2813
2813
|
data = (0, codegen_1._)`${data}${(0, codegen_1.getProperty)((0, util_1.unescapeJsonPointer)(segment))}`;
|
|
2814
2814
|
expr = (0, codegen_1._)`${expr} && ${data}`;
|
|
@@ -3870,49 +3870,49 @@ var require_fast_uri = __commonJS({
|
|
|
3870
3870
|
schemelessOptions.skipEscape = true;
|
|
3871
3871
|
return serialize(resolved, schemelessOptions);
|
|
3872
3872
|
}
|
|
3873
|
-
function resolveComponent(base,
|
|
3873
|
+
function resolveComponent(base, relative7, options, skipNormalization) {
|
|
3874
3874
|
const target = {};
|
|
3875
3875
|
if (!skipNormalization) {
|
|
3876
3876
|
base = parse3(serialize(base, options), options);
|
|
3877
|
-
|
|
3877
|
+
relative7 = parse3(serialize(relative7, options), options);
|
|
3878
3878
|
}
|
|
3879
3879
|
options = options || {};
|
|
3880
|
-
if (!options.tolerant &&
|
|
3881
|
-
target.scheme =
|
|
3882
|
-
target.userinfo =
|
|
3883
|
-
target.host =
|
|
3884
|
-
target.port =
|
|
3885
|
-
target.path = removeDotSegments(
|
|
3886
|
-
target.query =
|
|
3880
|
+
if (!options.tolerant && relative7.scheme) {
|
|
3881
|
+
target.scheme = relative7.scheme;
|
|
3882
|
+
target.userinfo = relative7.userinfo;
|
|
3883
|
+
target.host = relative7.host;
|
|
3884
|
+
target.port = relative7.port;
|
|
3885
|
+
target.path = removeDotSegments(relative7.path || "");
|
|
3886
|
+
target.query = relative7.query;
|
|
3887
3887
|
} else {
|
|
3888
|
-
if (
|
|
3889
|
-
target.userinfo =
|
|
3890
|
-
target.host =
|
|
3891
|
-
target.port =
|
|
3892
|
-
target.path = removeDotSegments(
|
|
3893
|
-
target.query =
|
|
3888
|
+
if (relative7.userinfo !== void 0 || relative7.host !== void 0 || relative7.port !== void 0) {
|
|
3889
|
+
target.userinfo = relative7.userinfo;
|
|
3890
|
+
target.host = relative7.host;
|
|
3891
|
+
target.port = relative7.port;
|
|
3892
|
+
target.path = removeDotSegments(relative7.path || "");
|
|
3893
|
+
target.query = relative7.query;
|
|
3894
3894
|
} else {
|
|
3895
|
-
if (!
|
|
3895
|
+
if (!relative7.path) {
|
|
3896
3896
|
target.path = base.path;
|
|
3897
|
-
if (
|
|
3898
|
-
target.query =
|
|
3897
|
+
if (relative7.query !== void 0) {
|
|
3898
|
+
target.query = relative7.query;
|
|
3899
3899
|
} else {
|
|
3900
3900
|
target.query = base.query;
|
|
3901
3901
|
}
|
|
3902
3902
|
} else {
|
|
3903
|
-
if (
|
|
3904
|
-
target.path = removeDotSegments(
|
|
3903
|
+
if (relative7.path[0] === "/") {
|
|
3904
|
+
target.path = removeDotSegments(relative7.path);
|
|
3905
3905
|
} else {
|
|
3906
3906
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
3907
|
-
target.path = "/" +
|
|
3907
|
+
target.path = "/" + relative7.path;
|
|
3908
3908
|
} else if (!base.path) {
|
|
3909
|
-
target.path =
|
|
3909
|
+
target.path = relative7.path;
|
|
3910
3910
|
} else {
|
|
3911
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
3911
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative7.path;
|
|
3912
3912
|
}
|
|
3913
3913
|
target.path = removeDotSegments(target.path);
|
|
3914
3914
|
}
|
|
3915
|
-
target.query =
|
|
3915
|
+
target.query = relative7.query;
|
|
3916
3916
|
}
|
|
3917
3917
|
target.userinfo = base.userinfo;
|
|
3918
3918
|
target.host = base.host;
|
|
@@ -3920,7 +3920,7 @@ var require_fast_uri = __commonJS({
|
|
|
3920
3920
|
}
|
|
3921
3921
|
target.scheme = base.scheme;
|
|
3922
3922
|
}
|
|
3923
|
-
target.fragment =
|
|
3923
|
+
target.fragment = relative7.fragment;
|
|
3924
3924
|
return target;
|
|
3925
3925
|
}
|
|
3926
3926
|
function equal(uriA, uriB, options) {
|
|
@@ -4621,15 +4621,15 @@ var require_core = __commonJS({
|
|
|
4621
4621
|
errorsText(errors = this.errors, { separator = ", ", dataVar = "data" } = {}) {
|
|
4622
4622
|
if (!errors || errors.length === 0)
|
|
4623
4623
|
return "No errors";
|
|
4624
|
-
return errors.map((e) => `${dataVar}${e.instancePath} ${e.message}`).reduce((
|
|
4624
|
+
return errors.map((e) => `${dataVar}${e.instancePath} ${e.message}`).reduce((text2, msg) => text2 + separator + msg);
|
|
4625
4625
|
}
|
|
4626
4626
|
$dataMetaSchema(metaSchema, keywordsJsonPointers) {
|
|
4627
4627
|
const rules = this.RULES.all;
|
|
4628
4628
|
metaSchema = JSON.parse(JSON.stringify(metaSchema));
|
|
4629
4629
|
for (const jsonPointer of keywordsJsonPointers) {
|
|
4630
|
-
const
|
|
4630
|
+
const segments4 = jsonPointer.split("/").slice(1);
|
|
4631
4631
|
let keywords = metaSchema;
|
|
4632
|
-
for (const seg of
|
|
4632
|
+
for (const seg of segments4)
|
|
4633
4633
|
keywords = keywords[seg];
|
|
4634
4634
|
for (const key in rules) {
|
|
4635
4635
|
const rule = rules[key];
|
|
@@ -7196,8 +7196,8 @@ var require_dist = __commonJS({
|
|
|
7196
7196
|
});
|
|
7197
7197
|
|
|
7198
7198
|
// src/index.ts
|
|
7199
|
-
import { readFile as
|
|
7200
|
-
import { dirname as
|
|
7199
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
7200
|
+
import { dirname as dirname10, resolve as resolve4 } from "path";
|
|
7201
7201
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7202
7202
|
|
|
7203
7203
|
// ../core/dist/scanner.js
|
|
@@ -7247,7 +7247,7 @@ async function scan(adapters, options = {}) {
|
|
|
7247
7247
|
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
7248
7248
|
const issues = [];
|
|
7249
7249
|
const items = [];
|
|
7250
|
-
const seenItemPaths = /* @__PURE__ */ new
|
|
7250
|
+
const seenItemPaths = /* @__PURE__ */ new Map();
|
|
7251
7251
|
const scannedRoots = [];
|
|
7252
7252
|
const formatAdapters = adapters.filter((a) => !isSourceAdapter(a));
|
|
7253
7253
|
const sourceAdapters = adapters.filter(isSourceAdapter);
|
|
@@ -7259,10 +7259,19 @@ async function scan(adapters, options = {}) {
|
|
|
7259
7259
|
rootSet.add(resolve(r));
|
|
7260
7260
|
}
|
|
7261
7261
|
const roots = [...rootSet].filter((r) => ![...rootSet].some((other) => other !== r && r.startsWith(other + "/")));
|
|
7262
|
-
const addItem = (item) => {
|
|
7263
|
-
|
|
7262
|
+
const addItem = (item, adapterId) => {
|
|
7263
|
+
const owner = seenItemPaths.get(item.path);
|
|
7264
|
+
if (owner !== void 0) {
|
|
7265
|
+
if (owner !== adapterId) {
|
|
7266
|
+
issues.push({
|
|
7267
|
+
path: item.path,
|
|
7268
|
+
adapter: adapterId,
|
|
7269
|
+
message: `claimed by both "${owner}" and "${adapterId}"; kept "${owner}" \u2014 two adapters' conventions overlap here`
|
|
7270
|
+
});
|
|
7271
|
+
}
|
|
7264
7272
|
return;
|
|
7265
|
-
|
|
7273
|
+
}
|
|
7274
|
+
seenItemPaths.set(item.path, adapterId);
|
|
7266
7275
|
items.push(item);
|
|
7267
7276
|
};
|
|
7268
7277
|
const handleEntry = async (entry) => {
|
|
@@ -7281,8 +7290,13 @@ async function scan(adapters, options = {}) {
|
|
|
7281
7290
|
if (!matched)
|
|
7282
7291
|
continue;
|
|
7283
7292
|
try {
|
|
7284
|
-
|
|
7285
|
-
|
|
7293
|
+
const parsed = await adapter.parse(entry, env);
|
|
7294
|
+
const result = Array.isArray(parsed) ? { items: parsed } : parsed;
|
|
7295
|
+
for (const item of result.items)
|
|
7296
|
+
addItem(item, adapter.id);
|
|
7297
|
+
for (const issue2 of result.issues ?? []) {
|
|
7298
|
+
issues.push({ adapter: adapter.id, ...issue2 });
|
|
7299
|
+
}
|
|
7286
7300
|
} catch (err) {
|
|
7287
7301
|
issues.push({
|
|
7288
7302
|
path: entry.absPath,
|
|
@@ -7356,7 +7370,7 @@ async function scan(adapters, options = {}) {
|
|
|
7356
7370
|
for (const adapter of sourceAdapters) {
|
|
7357
7371
|
try {
|
|
7358
7372
|
for (const item of await adapter.collect(root, env))
|
|
7359
|
-
addItem(item);
|
|
7373
|
+
addItem(item, adapter.id);
|
|
7360
7374
|
} catch (err) {
|
|
7361
7375
|
issues.push({
|
|
7362
7376
|
path: root,
|
|
@@ -7414,20 +7428,24 @@ function findProjectRoot(startDir, homeDir) {
|
|
|
7414
7428
|
|
|
7415
7429
|
// ../core/dist/chunk.js
|
|
7416
7430
|
var DEFAULT_MAX_CHARS = 2e3;
|
|
7417
|
-
|
|
7431
|
+
var DEFAULT_MAX_HEADING_LEVEL = 6;
|
|
7432
|
+
function chunkMarkdown(markdown, options = {}) {
|
|
7433
|
+
const maxChars = options.maxChars ?? DEFAULT_MAX_CHARS;
|
|
7434
|
+
const maxHeadingLevel = options.maxHeadingLevel ?? DEFAULT_MAX_HEADING_LEVEL;
|
|
7418
7435
|
const body = parseFrontmatter(markdown).body;
|
|
7419
7436
|
const chunks = [];
|
|
7420
7437
|
const trail = [];
|
|
7421
7438
|
let buffer = [];
|
|
7422
7439
|
let inFence = false;
|
|
7440
|
+
let openPath = [];
|
|
7441
|
+
const path = () => trail.filter((s) => Boolean(s));
|
|
7423
7442
|
const flush = () => {
|
|
7424
|
-
const
|
|
7443
|
+
const text2 = buffer.join("\n").trim();
|
|
7425
7444
|
buffer = [];
|
|
7426
|
-
if (!
|
|
7445
|
+
if (!text2)
|
|
7427
7446
|
return;
|
|
7428
|
-
const
|
|
7429
|
-
|
|
7430
|
-
chunks.push({ index: chunks.length, headingPath, text: part });
|
|
7447
|
+
for (const part of splitLong(text2, maxChars)) {
|
|
7448
|
+
chunks.push({ index: chunks.length, headingPath: openPath, text: part });
|
|
7431
7449
|
}
|
|
7432
7450
|
};
|
|
7433
7451
|
for (const line of body.split(/\r?\n/)) {
|
|
@@ -7435,10 +7453,13 @@ function chunkMarkdown(markdown, maxChars = DEFAULT_MAX_CHARS) {
|
|
|
7435
7453
|
inFence = !inFence;
|
|
7436
7454
|
const heading = !inFence && /^(#{1,6})\s+(.*\S)\s*$/.exec(line);
|
|
7437
7455
|
if (heading) {
|
|
7438
|
-
flush();
|
|
7439
7456
|
const level = heading[1].length;
|
|
7457
|
+
if (level <= maxHeadingLevel)
|
|
7458
|
+
flush();
|
|
7440
7459
|
trail.splice(level - 1);
|
|
7441
7460
|
trail[level - 1] = heading[2];
|
|
7461
|
+
if (buffer.length === 0)
|
|
7462
|
+
openPath = path();
|
|
7442
7463
|
buffer.push(line);
|
|
7443
7464
|
continue;
|
|
7444
7465
|
}
|
|
@@ -7447,25 +7468,58 @@ function chunkMarkdown(markdown, maxChars = DEFAULT_MAX_CHARS) {
|
|
|
7447
7468
|
flush();
|
|
7448
7469
|
return chunks;
|
|
7449
7470
|
}
|
|
7450
|
-
function splitLong(
|
|
7451
|
-
if (
|
|
7452
|
-
return [
|
|
7471
|
+
function splitLong(text2, maxChars) {
|
|
7472
|
+
if (text2.length <= maxChars)
|
|
7473
|
+
return [text2];
|
|
7453
7474
|
const out = [];
|
|
7454
7475
|
let current = "";
|
|
7455
|
-
for (const
|
|
7456
|
-
if (current && current.length +
|
|
7476
|
+
for (const { sep: sep7, piece } of pieces(text2, maxChars)) {
|
|
7477
|
+
if (current && current.length + sep7.length + piece.length > maxChars) {
|
|
7457
7478
|
out.push(current);
|
|
7458
|
-
current =
|
|
7479
|
+
current = piece;
|
|
7459
7480
|
} else {
|
|
7460
|
-
current = current ?
|
|
7461
|
-
|
|
7462
|
-
${para}` : para;
|
|
7481
|
+
current = current ? current + sep7 + piece : piece;
|
|
7463
7482
|
}
|
|
7464
7483
|
}
|
|
7465
7484
|
if (current)
|
|
7466
7485
|
out.push(current);
|
|
7467
7486
|
return out;
|
|
7468
7487
|
}
|
|
7488
|
+
var SENTENCE_BREAK = /(?<=[.!?…]["'’”»)\]]*)(\s+)/;
|
|
7489
|
+
function* pieces(text2, maxChars) {
|
|
7490
|
+
let sep7 = "";
|
|
7491
|
+
for (const para of text2.split(/\n{2,}/)) {
|
|
7492
|
+
if (para.length <= maxChars) {
|
|
7493
|
+
yield { sep: sep7, piece: para };
|
|
7494
|
+
} else {
|
|
7495
|
+
const parts = para.split(SENTENCE_BREAK);
|
|
7496
|
+
for (let i = 0; i < parts.length; i += 2) {
|
|
7497
|
+
yield* cut(parts[i], sep7, maxChars);
|
|
7498
|
+
sep7 = parts[i + 1] ?? "";
|
|
7499
|
+
}
|
|
7500
|
+
}
|
|
7501
|
+
sep7 = "\n\n";
|
|
7502
|
+
}
|
|
7503
|
+
}
|
|
7504
|
+
function* cut(sentence, sep7, maxChars) {
|
|
7505
|
+
let rest = sentence;
|
|
7506
|
+
while (rest.length > maxChars) {
|
|
7507
|
+
const window = rest.slice(0, maxChars + 1);
|
|
7508
|
+
let at = window.lastIndexOf("\n");
|
|
7509
|
+
if (at < maxChars / 2)
|
|
7510
|
+
at = Math.max(at, window.lastIndexOf(" "));
|
|
7511
|
+
if (at <= 0)
|
|
7512
|
+
at = Math.max(maxChars, 1);
|
|
7513
|
+
const piece = rest.slice(0, at).trimEnd();
|
|
7514
|
+
const gap = /^\s*/.exec(rest.slice(piece.length))[0];
|
|
7515
|
+
if (piece)
|
|
7516
|
+
yield { sep: sep7, piece };
|
|
7517
|
+
sep7 = piece ? gap : sep7 + gap;
|
|
7518
|
+
rest = rest.slice(piece.length + gap.length);
|
|
7519
|
+
}
|
|
7520
|
+
if (rest)
|
|
7521
|
+
yield { sep: sep7, piece: rest };
|
|
7522
|
+
}
|
|
7469
7523
|
|
|
7470
7524
|
// ../adapter-claude-skills/dist/index.js
|
|
7471
7525
|
import { readFile } from "fs/promises";
|
|
@@ -7516,10 +7570,10 @@ import { readFile as readFile2 } from "fs/promises";
|
|
|
7516
7570
|
import { basename as basename2, dirname as dirname3, join as join4, relative as relative2 } from "path";
|
|
7517
7571
|
var INSTRUCTION_FILES = /* @__PURE__ */ new Set(["CLAUDE.md", "CLAUDE.local.md", "AGENTS.md"]);
|
|
7518
7572
|
var MAX_DESCRIPTION_LENGTH = 120;
|
|
7519
|
-
function truncate(
|
|
7520
|
-
if (
|
|
7521
|
-
return
|
|
7522
|
-
return
|
|
7573
|
+
function truncate(text2) {
|
|
7574
|
+
if (text2.length <= MAX_DESCRIPTION_LENGTH)
|
|
7575
|
+
return text2;
|
|
7576
|
+
return text2.slice(0, MAX_DESCRIPTION_LENGTH - 1).trimEnd() + "\u2026";
|
|
7523
7577
|
}
|
|
7524
7578
|
function deriveDescription(raw2) {
|
|
7525
7579
|
let firstNonEmpty;
|
|
@@ -7583,8 +7637,8 @@ var LEGACY_FILE = ".cursorrules";
|
|
|
7583
7637
|
var MDC_EXTENSION = ".mdc";
|
|
7584
7638
|
var RULES_MARKER = sep2 + join5(".cursor", "rules") + sep2;
|
|
7585
7639
|
var MAX_DESCRIPTION_LENGTH2 = 120;
|
|
7586
|
-
function firstLine(
|
|
7587
|
-
for (const line of
|
|
7640
|
+
function firstLine(text2) {
|
|
7641
|
+
for (const line of text2.split(/\r?\n/)) {
|
|
7588
7642
|
const trimmed = line.trim();
|
|
7589
7643
|
if (!trimmed)
|
|
7590
7644
|
continue;
|
|
@@ -7958,10 +8012,10 @@ var checkOptionalParameter = (path) => {
|
|
|
7958
8012
|
if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) {
|
|
7959
8013
|
return null;
|
|
7960
8014
|
}
|
|
7961
|
-
const
|
|
8015
|
+
const segments4 = path.split("/");
|
|
7962
8016
|
const results = [];
|
|
7963
8017
|
let basePath = "";
|
|
7964
|
-
|
|
8018
|
+
segments4.forEach((segment) => {
|
|
7965
8019
|
if (segment !== "" && !/\:/.test(segment)) {
|
|
7966
8020
|
basePath += "/" + segment;
|
|
7967
8021
|
} else if (/\:/.test(segment)) {
|
|
@@ -8178,7 +8232,7 @@ var HonoRequest = class {
|
|
|
8178
8232
|
* ```
|
|
8179
8233
|
*/
|
|
8180
8234
|
json() {
|
|
8181
|
-
return this.#cachedBody("text").then((
|
|
8235
|
+
return this.#cachedBody("text").then((text2) => JSON.parse(text2));
|
|
8182
8236
|
}
|
|
8183
8237
|
/**
|
|
8184
8238
|
* `.text()` can parse Request body of type `text/plain`
|
|
@@ -8744,9 +8798,9 @@ var Context = class {
|
|
|
8744
8798
|
* })
|
|
8745
8799
|
* ```
|
|
8746
8800
|
*/
|
|
8747
|
-
text = (
|
|
8748
|
-
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(
|
|
8749
|
-
|
|
8801
|
+
text = (text2, arg, headers) => {
|
|
8802
|
+
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text2) : this.#newResponse(
|
|
8803
|
+
text2,
|
|
8750
8804
|
arg,
|
|
8751
8805
|
setDefaultContentType(TEXT_PLAIN, headers)
|
|
8752
8806
|
);
|
|
@@ -10050,8 +10104,8 @@ function ollamaEmbedder(options = {}) {
|
|
|
10050
10104
|
}
|
|
10051
10105
|
};
|
|
10052
10106
|
}
|
|
10053
|
-
function estimateTokens(
|
|
10054
|
-
return Math.ceil(
|
|
10107
|
+
function estimateTokens(text2) {
|
|
10108
|
+
return Math.ceil(text2.length / 4);
|
|
10055
10109
|
}
|
|
10056
10110
|
|
|
10057
10111
|
// ../index/dist/store.js
|
|
@@ -10074,7 +10128,7 @@ function loadSqlite() {
|
|
|
10074
10128
|
}
|
|
10075
10129
|
var DB_DIR = ".capsa";
|
|
10076
10130
|
var DB_FILE = "index.db";
|
|
10077
|
-
var SCHEMA_VERSION =
|
|
10131
|
+
var SCHEMA_VERSION = 11;
|
|
10078
10132
|
var META_INDEXED_AT = "indexed_at";
|
|
10079
10133
|
var META_INDEX_FAILED_AT = "index_failed_at";
|
|
10080
10134
|
var META_INDEX_ERROR = "index_error";
|
|
@@ -10173,6 +10227,7 @@ var Store = class {
|
|
|
10173
10227
|
status TEXT,
|
|
10174
10228
|
updated_at TEXT,
|
|
10175
10229
|
tags TEXT,
|
|
10230
|
+
metadata TEXT,
|
|
10176
10231
|
origin TEXT NOT NULL DEFAULT 'local',
|
|
10177
10232
|
indexed_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
|
10178
10233
|
);
|
|
@@ -10260,21 +10315,22 @@ var Store = class {
|
|
|
10260
10315
|
this.db.prepare("DELETE FROM items WHERE id = ?").run(id);
|
|
10261
10316
|
}
|
|
10262
10317
|
upsertItem(row) {
|
|
10263
|
-
this.db.prepare(`INSERT INTO items (id, format, kind, name, title, path, rel_path, content_hash, status, updated_at, tags)
|
|
10264
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
10318
|
+
this.db.prepare(`INSERT INTO items (id, format, kind, name, title, path, rel_path, content_hash, status, updated_at, tags, metadata)
|
|
10319
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
10265
10320
|
ON CONFLICT(id) DO UPDATE SET
|
|
10266
10321
|
format = excluded.format, kind = excluded.kind, name = excluded.name,
|
|
10267
10322
|
title = excluded.title,
|
|
10268
10323
|
rel_path = excluded.rel_path, content_hash = excluded.content_hash,
|
|
10269
10324
|
status = excluded.status, updated_at = excluded.updated_at, tags = excluded.tags,
|
|
10270
|
-
|
|
10325
|
+
metadata = excluded.metadata,
|
|
10326
|
+
indexed_at = strftime('%Y-%m-%dT%H:%M:%fZ','now')`).run(row.id, row.format, row.kind, row.name, row.title, row.path, row.rel_path, row.content_hash, row.status, row.updated_at, row.tags, row.metadata);
|
|
10271
10327
|
}
|
|
10272
10328
|
/**
|
|
10273
10329
|
* `text` is what the user sees; `searchText` (chunk + provenance header)
|
|
10274
10330
|
* is what FTS and the embedder see. Falls back to `text` when omitted.
|
|
10275
10331
|
*/
|
|
10276
|
-
insertChunk(itemId, idx, headingPath,
|
|
10277
|
-
const res = this.db.prepare("INSERT INTO chunks (item_id, idx, heading_path, text) VALUES (?, ?, ?, ?)").run(itemId, idx, JSON.stringify(headingPath),
|
|
10332
|
+
insertChunk(itemId, idx, headingPath, text2, embedding, searchText = text2) {
|
|
10333
|
+
const res = this.db.prepare("INSERT INTO chunks (item_id, idx, heading_path, text) VALUES (?, ?, ?, ?)").run(itemId, idx, JSON.stringify(headingPath), text2);
|
|
10278
10334
|
const id = Number(res.lastInsertRowid);
|
|
10279
10335
|
this.db.prepare("INSERT INTO chunks_fts (rowid, text) VALUES (?, ?)").run(id, searchText);
|
|
10280
10336
|
this.db.prepare("INSERT INTO chunks_vec (chunk_id, embedding) VALUES (?, ?)").run(BigInt(id), new Uint8Array(embedding.buffer, embedding.byteOffset, embedding.byteLength));
|
|
@@ -10298,7 +10354,7 @@ var Store = class {
|
|
|
10298
10354
|
return [];
|
|
10299
10355
|
const placeholders = ids.map(() => "?").join(",");
|
|
10300
10356
|
const rows = this.db.prepare(`SELECT c.id, c.item_id, c.idx, c.heading_path, c.text,
|
|
10301
|
-
i.id AS i_id, i.format, i.kind, i.name, i.title, i.path, i.rel_path, i.content_hash, i.status, i.updated_at, i.tags
|
|
10357
|
+
i.id AS i_id, i.format, i.kind, i.name, i.title, i.path, i.rel_path, i.content_hash, i.status, i.updated_at, i.tags, i.metadata
|
|
10302
10358
|
FROM chunks c JOIN items i ON i.id = c.item_id WHERE c.id IN (${placeholders})`).all(...ids);
|
|
10303
10359
|
return rows.map((r) => ({
|
|
10304
10360
|
id: r["id"],
|
|
@@ -10317,7 +10373,8 @@ var Store = class {
|
|
|
10317
10373
|
content_hash: r["content_hash"],
|
|
10318
10374
|
status: r["status"],
|
|
10319
10375
|
updated_at: r["updated_at"],
|
|
10320
|
-
tags: r["tags"]
|
|
10376
|
+
tags: r["tags"],
|
|
10377
|
+
metadata: r["metadata"]
|
|
10321
10378
|
}
|
|
10322
10379
|
}));
|
|
10323
10380
|
}
|
|
@@ -10353,12 +10410,116 @@ var Store = class {
|
|
|
10353
10410
|
|
|
10354
10411
|
// ../index/dist/indexer.js
|
|
10355
10412
|
import { createHash as createHash2 } from "crypto";
|
|
10356
|
-
import { relative as
|
|
10413
|
+
import { relative as relative6 } from "path";
|
|
10414
|
+
|
|
10415
|
+
// ../adapter-documents/dist/index.js
|
|
10416
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
10417
|
+
import { basename as basename4, dirname as dirname7, relative as relative3, sep as sep4 } from "path";
|
|
10418
|
+
var BOOK_DIR = "books";
|
|
10419
|
+
var OUTLINE_FILE = "index.md";
|
|
10420
|
+
var CHAPTER_HEADING_LEVEL = 3;
|
|
10421
|
+
var CHAPTER_MAX_CHARS = 1e3;
|
|
10422
|
+
function segments(relPath) {
|
|
10423
|
+
return relPath.split(/[\\/]/).filter(Boolean);
|
|
10424
|
+
}
|
|
10425
|
+
function documentsAdapter() {
|
|
10426
|
+
return {
|
|
10427
|
+
id: "documents",
|
|
10428
|
+
displayName: "Document",
|
|
10429
|
+
matches(entry) {
|
|
10430
|
+
if (!entry.isFile || !entry.name.toLowerCase().endsWith(".md"))
|
|
10431
|
+
return false;
|
|
10432
|
+
return segments(entry.relPath).slice(0, -1).some((p) => p.toLowerCase() === BOOK_DIR);
|
|
10433
|
+
},
|
|
10434
|
+
async parse(entry, env) {
|
|
10435
|
+
let raw2;
|
|
10436
|
+
try {
|
|
10437
|
+
raw2 = await readFile5(entry.absPath, "utf8");
|
|
10438
|
+
} catch {
|
|
10439
|
+
return { items: [] };
|
|
10440
|
+
}
|
|
10441
|
+
const fm = parseFrontmatter(raw2);
|
|
10442
|
+
const book = fm.data["book"];
|
|
10443
|
+
if (!book) {
|
|
10444
|
+
return {
|
|
10445
|
+
items: [],
|
|
10446
|
+
issues: [
|
|
10447
|
+
{
|
|
10448
|
+
path: entry.absPath,
|
|
10449
|
+
message: `no \`book:\` in frontmatter \u2014 a markdown file under ${BOOK_DIR}/ is a chapter of a document or it is nothing`
|
|
10450
|
+
}
|
|
10451
|
+
]
|
|
10452
|
+
};
|
|
10453
|
+
}
|
|
10454
|
+
const projectRoot = findProjectRoot(dirname7(entry.absPath), env.homeDir);
|
|
10455
|
+
const relPathInProject = relative3(projectRoot, entry.absPath);
|
|
10456
|
+
const outline = entry.name.toLowerCase() === OUTLINE_FILE;
|
|
10457
|
+
const title = fm.data["title"] || firstHeading(fm.body) || basename4(entry.name, ".md");
|
|
10458
|
+
const chapter = fm.data["chapter"];
|
|
10459
|
+
const metadata = {
|
|
10460
|
+
relPathInProject,
|
|
10461
|
+
book,
|
|
10462
|
+
title,
|
|
10463
|
+
...fm.data["author"] ? { author: fm.data["author"] } : {},
|
|
10464
|
+
...chapter ? { chapter: number(chapter) } : {},
|
|
10465
|
+
...pages("printed_pages", fm.data["printed_pages"]),
|
|
10466
|
+
...pages("pdf_pages", fm.data["pdf_pages"])
|
|
10467
|
+
};
|
|
10468
|
+
return {
|
|
10469
|
+
items: [
|
|
10470
|
+
{
|
|
10471
|
+
id: stableId(entry.absPath),
|
|
10472
|
+
format: "documents",
|
|
10473
|
+
formatLabel: outline ? "Outline" : "Document",
|
|
10474
|
+
name: `${basename4(projectRoot)}${sep4}${relPathInProject}`,
|
|
10475
|
+
// What the item calls itself, and what a pinned item's
|
|
10476
|
+
// neighbourhood is searched with: a chapter title alone
|
|
10477
|
+
// ("Conclusion") belongs to nine books at once.
|
|
10478
|
+
description: outline ? `${book} \u2014 Contents` : `${book} \u2014 ${chapterLabel(chapter, title)}`,
|
|
10479
|
+
path: entry.absPath,
|
|
10480
|
+
scope: "project",
|
|
10481
|
+
projectRoot,
|
|
10482
|
+
content: raw2,
|
|
10483
|
+
metadata,
|
|
10484
|
+
knowledge: { kind: outline ? "outline" : "document" },
|
|
10485
|
+
// An outline is delivered whole or not at all — a table of
|
|
10486
|
+
// contents retrieved three lines at a time is noise. Empty, so
|
|
10487
|
+
// the indexer stores it and embeds nothing of it.
|
|
10488
|
+
chunks: outline ? [] : chapterChunks(raw2)
|
|
10489
|
+
}
|
|
10490
|
+
]
|
|
10491
|
+
};
|
|
10492
|
+
}
|
|
10493
|
+
};
|
|
10494
|
+
}
|
|
10495
|
+
function chapterLabel(chapter, title) {
|
|
10496
|
+
return chapter === void 0 || chapter === "" ? title : `Ch. ${chapter} ${title}`;
|
|
10497
|
+
}
|
|
10498
|
+
function chapterChunks(raw2) {
|
|
10499
|
+
return chunkMarkdown(raw2, { maxHeadingLevel: CHAPTER_HEADING_LEVEL, maxChars: CHAPTER_MAX_CHARS });
|
|
10500
|
+
}
|
|
10501
|
+
function pages(key, value) {
|
|
10502
|
+
if (!value)
|
|
10503
|
+
return {};
|
|
10504
|
+
const parts = value.replace(/^\[|\]$/g, "").split(",").map((p) => p.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
10505
|
+
return parts.length ? { [key]: parts.map(number) } : {};
|
|
10506
|
+
}
|
|
10507
|
+
function number(value) {
|
|
10508
|
+
return /^\d+$/.test(value) ? Number(value) : value;
|
|
10509
|
+
}
|
|
10510
|
+
function firstHeading(body) {
|
|
10511
|
+
for (const line of body.split(/\r?\n/)) {
|
|
10512
|
+
const m = /^#{1,6}\s+(.*\S)\s*$/.exec(line.trim());
|
|
10513
|
+
if (m)
|
|
10514
|
+
return m[1];
|
|
10515
|
+
}
|
|
10516
|
+
return void 0;
|
|
10517
|
+
}
|
|
10357
10518
|
|
|
10358
10519
|
// ../adapter-git-log/dist/index.js
|
|
10359
10520
|
import { execFile } from "child_process";
|
|
10360
10521
|
import { existsSync as existsSync2 } from "fs";
|
|
10361
|
-
import { basename as
|
|
10522
|
+
import { basename as basename5, join as join7 } from "path";
|
|
10362
10523
|
import { promisify } from "util";
|
|
10363
10524
|
var execFileAsync = promisify(execFile);
|
|
10364
10525
|
var DEFAULTS = {
|
|
@@ -10461,7 +10622,7 @@ function toItem(root, c, opts) {
|
|
|
10461
10622
|
author: c.author,
|
|
10462
10623
|
subject,
|
|
10463
10624
|
files: c.files,
|
|
10464
|
-
repo:
|
|
10625
|
+
repo: basename5(root)
|
|
10465
10626
|
},
|
|
10466
10627
|
knowledge: {
|
|
10467
10628
|
kind: "commit",
|
|
@@ -10506,18 +10667,27 @@ function conventionalTags(subject) {
|
|
|
10506
10667
|
const tags = [m[1], ...m[2] ? [m[2]] : []];
|
|
10507
10668
|
return tags;
|
|
10508
10669
|
}
|
|
10509
|
-
function firstLine2(
|
|
10510
|
-
return (
|
|
10670
|
+
function firstLine2(text2) {
|
|
10671
|
+
return (text2 ?? "").split("\n").find((l) => l.trim()) ?? "";
|
|
10511
10672
|
}
|
|
10512
10673
|
|
|
10513
10674
|
// ../adapter-runbooks/dist/index.js
|
|
10514
|
-
import { readFile as
|
|
10515
|
-
import { basename as
|
|
10675
|
+
import { readFile as readFile6, stat as stat3 } from "fs/promises";
|
|
10676
|
+
import { basename as basename6, dirname as dirname8, relative as relative4, sep as sep5 } from "path";
|
|
10516
10677
|
var DOC_DIRS = /* @__PURE__ */ new Set(["docs", "doc", "runbooks", "runbook", "wiki", "adr", "decisions"]);
|
|
10517
|
-
var
|
|
10518
|
-
|
|
10678
|
+
var CLAIMED_ELSEWHERE = /* @__PURE__ */ new Set(["skill.md"]);
|
|
10679
|
+
var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["books", "tickets", "issues", "todo", "backlog", "plans", "plan", "roadmap", "milestones", "milestone", "node_modules"]);
|
|
10680
|
+
function segments2(relPath) {
|
|
10519
10681
|
return relPath.split(/[\\/]/).filter(Boolean);
|
|
10520
10682
|
}
|
|
10683
|
+
function kindOf(relPathInProject) {
|
|
10684
|
+
const parts = segments2(relPathInProject).map((p) => p.toLowerCase());
|
|
10685
|
+
if (parts.some((p) => p === "adr" || p === "decisions"))
|
|
10686
|
+
return "decision";
|
|
10687
|
+
if (parts.some((p) => p === "runbooks" || p === "runbook"))
|
|
10688
|
+
return "runbook";
|
|
10689
|
+
return "doc";
|
|
10690
|
+
}
|
|
10521
10691
|
function runbooksAdapter() {
|
|
10522
10692
|
return {
|
|
10523
10693
|
id: "runbooks",
|
|
@@ -10525,7 +10695,9 @@ function runbooksAdapter() {
|
|
|
10525
10695
|
matches(entry) {
|
|
10526
10696
|
if (!entry.isFile || !entry.name.toLowerCase().endsWith(".md"))
|
|
10527
10697
|
return false;
|
|
10528
|
-
|
|
10698
|
+
if (CLAIMED_ELSEWHERE.has(entry.name.toLowerCase()))
|
|
10699
|
+
return false;
|
|
10700
|
+
const parts = segments2(entry.relPath).slice(0, -1);
|
|
10529
10701
|
if (!parts.some((p) => DOC_DIRS.has(p.toLowerCase())))
|
|
10530
10702
|
return false;
|
|
10531
10703
|
return !parts.some((p) => EXCLUDED_DIRS.has(p.toLowerCase()));
|
|
@@ -10534,24 +10706,23 @@ function runbooksAdapter() {
|
|
|
10534
10706
|
let raw2;
|
|
10535
10707
|
let mtime;
|
|
10536
10708
|
try {
|
|
10537
|
-
raw2 = await
|
|
10709
|
+
raw2 = await readFile6(entry.absPath, "utf8");
|
|
10538
10710
|
mtime = (await stat3(entry.absPath)).mtime;
|
|
10539
10711
|
} catch {
|
|
10540
10712
|
return [];
|
|
10541
10713
|
}
|
|
10542
|
-
const projectRoot = findProjectRoot(
|
|
10543
|
-
const relPathInProject =
|
|
10714
|
+
const projectRoot = findProjectRoot(dirname8(entry.absPath), env.homeDir);
|
|
10715
|
+
const relPathInProject = relative4(projectRoot, entry.absPath);
|
|
10544
10716
|
const fm = parseFrontmatter(raw2);
|
|
10545
10717
|
const data = fm.data;
|
|
10546
|
-
const title = data["title"] ||
|
|
10547
|
-
const kindFromPath = segments(relPathInProject).some((p) => ["adr", "decisions"].includes(p.toLowerCase())) ? "decision" : "runbook";
|
|
10718
|
+
const title = data["title"] || firstHeading2(raw2) || basename6(entry.name, ".md");
|
|
10548
10719
|
const tags = parseTags(data["tags"]);
|
|
10549
10720
|
return [
|
|
10550
10721
|
{
|
|
10551
10722
|
id: stableId(entry.absPath),
|
|
10552
10723
|
format: "runbooks",
|
|
10553
10724
|
formatLabel: "Runbook",
|
|
10554
|
-
name: `${
|
|
10725
|
+
name: `${basename6(projectRoot)}${sep5}${relPathInProject}`,
|
|
10555
10726
|
description: title,
|
|
10556
10727
|
path: entry.absPath,
|
|
10557
10728
|
scope: "project",
|
|
@@ -10559,7 +10730,7 @@ function runbooksAdapter() {
|
|
|
10559
10730
|
content: raw2,
|
|
10560
10731
|
metadata: { relPathInProject, title },
|
|
10561
10732
|
knowledge: {
|
|
10562
|
-
kind:
|
|
10733
|
+
kind: kindOf(relPathInProject),
|
|
10563
10734
|
updatedAt: mtime?.toISOString(),
|
|
10564
10735
|
tags
|
|
10565
10736
|
}
|
|
@@ -10574,7 +10745,7 @@ function parseTags(value) {
|
|
|
10574
10745
|
const tags = value.replace(/^\[|\]$/g, "").split(",").map((t) => t.trim()).filter(Boolean);
|
|
10575
10746
|
return tags.length ? tags : void 0;
|
|
10576
10747
|
}
|
|
10577
|
-
function
|
|
10748
|
+
function firstHeading2(raw2) {
|
|
10578
10749
|
for (const line of raw2.split(/\r?\n/)) {
|
|
10579
10750
|
const m = /^#{1,6}\s+(.*\S)\s*$/.exec(line.trim());
|
|
10580
10751
|
if (m)
|
|
@@ -10584,12 +10755,12 @@ function firstHeading(raw2) {
|
|
|
10584
10755
|
}
|
|
10585
10756
|
|
|
10586
10757
|
// ../adapter-tickets/dist/index.js
|
|
10587
|
-
import { readFile as
|
|
10588
|
-
import { basename as
|
|
10758
|
+
import { readFile as readFile7, stat as stat4 } from "fs/promises";
|
|
10759
|
+
import { basename as basename7, dirname as dirname9, relative as relative5, sep as sep6 } from "path";
|
|
10589
10760
|
var TICKET_DIRS = /* @__PURE__ */ new Set(["tickets", "issues", "todo", "backlog"]);
|
|
10590
10761
|
var PLAN_DIRS = /* @__PURE__ */ new Set(["plans", "plan", "roadmap", "milestones", "milestone"]);
|
|
10591
10762
|
var CHECKBOX = /^\s*[-*+]\s+\[( |x|X)\]\s+/gm;
|
|
10592
|
-
function
|
|
10763
|
+
function segments3(relPath) {
|
|
10593
10764
|
return relPath.split(/[\\/]/).filter(Boolean);
|
|
10594
10765
|
}
|
|
10595
10766
|
function deriveStatus(raw2) {
|
|
@@ -10627,33 +10798,33 @@ function ticketsAdapter() {
|
|
|
10627
10798
|
matches(entry) {
|
|
10628
10799
|
if (!entry.isFile || !entry.name.toLowerCase().endsWith(".md"))
|
|
10629
10800
|
return false;
|
|
10630
|
-
const parts =
|
|
10801
|
+
const parts = segments3(entry.relPath).slice(0, -1).map((p) => p.toLowerCase());
|
|
10631
10802
|
return parts.some((p) => TICKET_DIRS.has(p) || PLAN_DIRS.has(p));
|
|
10632
10803
|
},
|
|
10633
10804
|
async parse(entry, env) {
|
|
10634
10805
|
let raw2;
|
|
10635
10806
|
let mtime;
|
|
10636
10807
|
try {
|
|
10637
|
-
raw2 = await
|
|
10808
|
+
raw2 = await readFile7(entry.absPath, "utf8");
|
|
10638
10809
|
mtime = (await stat4(entry.absPath)).mtime;
|
|
10639
10810
|
} catch {
|
|
10640
10811
|
return [];
|
|
10641
10812
|
}
|
|
10642
|
-
const projectRoot = findProjectRoot(
|
|
10643
|
-
const relPathInProject =
|
|
10644
|
-
const isPlan =
|
|
10813
|
+
const projectRoot = findProjectRoot(dirname9(entry.absPath), env.homeDir);
|
|
10814
|
+
const relPathInProject = relative5(projectRoot, entry.absPath);
|
|
10815
|
+
const isPlan = segments3(relPathInProject).slice(0, -1).some((p) => PLAN_DIRS.has(p.toLowerCase()));
|
|
10645
10816
|
const fm = parseFrontmatter(raw2);
|
|
10646
10817
|
const data = fm.data;
|
|
10647
10818
|
const derived2 = deriveStatus(raw2);
|
|
10648
10819
|
const status = normaliseStatus(data["status"]) ?? derived2.status;
|
|
10649
|
-
const title = data["title"] ||
|
|
10820
|
+
const title = data["title"] || firstHeading3(raw2) || basename7(entry.name, ".md");
|
|
10650
10821
|
const tags = parseTags2(data["tags"]);
|
|
10651
10822
|
return [
|
|
10652
10823
|
{
|
|
10653
10824
|
id: stableId(entry.absPath),
|
|
10654
10825
|
format: "tickets",
|
|
10655
10826
|
formatLabel: isPlan ? "Plan" : "Ticket",
|
|
10656
|
-
name: `${
|
|
10827
|
+
name: `${basename7(projectRoot)}${sep6}${relPathInProject}`,
|
|
10657
10828
|
description: title,
|
|
10658
10829
|
path: entry.absPath,
|
|
10659
10830
|
scope: "project",
|
|
@@ -10681,7 +10852,7 @@ function parseTags2(value) {
|
|
|
10681
10852
|
const tags = value.replace(/^\[|\]$/g, "").split(",").map((t) => t.trim()).filter(Boolean);
|
|
10682
10853
|
return tags.length ? tags : void 0;
|
|
10683
10854
|
}
|
|
10684
|
-
function
|
|
10855
|
+
function firstHeading3(raw2) {
|
|
10685
10856
|
for (const line of raw2.split(/\r?\n/)) {
|
|
10686
10857
|
const m = /^#{1,6}\s+(.*\S)\s*$/.exec(line.trim());
|
|
10687
10858
|
if (m)
|
|
@@ -10758,6 +10929,7 @@ function knowledgeAdapters() {
|
|
|
10758
10929
|
cursorRulesAdapter(),
|
|
10759
10930
|
runbooksAdapter(),
|
|
10760
10931
|
ticketsAdapter(),
|
|
10932
|
+
documentsAdapter(),
|
|
10761
10933
|
gitLogAdapter()
|
|
10762
10934
|
];
|
|
10763
10935
|
}
|
|
@@ -10887,7 +11059,7 @@ async function recordDecision(store, embedder, projectRoot, input2) {
|
|
|
10887
11059
|
}
|
|
10888
11060
|
}
|
|
10889
11061
|
async function indexItem(store, embedder, item, projectRoot, hash2, previousId) {
|
|
10890
|
-
const chunks = chunkMarkdown(item.content);
|
|
11062
|
+
const chunks = item.chunks ?? chunkMarkdown(item.content);
|
|
10891
11063
|
const searchTexts = chunks.map((c) => withContext(item, c.headingPath, c.text));
|
|
10892
11064
|
const vectors = searchTexts.length ? await embedder.embed(searchTexts) : [];
|
|
10893
11065
|
if (previousId)
|
|
@@ -10903,26 +11075,27 @@ async function indexItem(store, embedder, item, projectRoot, hash2, previousId)
|
|
|
10903
11075
|
// format has none to give.
|
|
10904
11076
|
title: item.description ?? item.name,
|
|
10905
11077
|
path: item.path,
|
|
10906
|
-
rel_path:
|
|
11078
|
+
rel_path: relative6(projectRoot, item.path),
|
|
10907
11079
|
content_hash: hash2,
|
|
10908
11080
|
status: k?.status ?? null,
|
|
10909
11081
|
updated_at: k?.updatedAt ?? null,
|
|
10910
|
-
tags: k?.tags ? JSON.stringify(k.tags) : null
|
|
11082
|
+
tags: k?.tags ? JSON.stringify(k.tags) : null,
|
|
11083
|
+
metadata: item.metadata ? JSON.stringify(item.metadata) : null
|
|
10911
11084
|
});
|
|
10912
11085
|
chunks.forEach((c, i) => store.insertChunk(item.id, c.index, c.headingPath, c.text, vectors[i], searchTexts[i]));
|
|
10913
11086
|
}
|
|
10914
|
-
function withContext(item, headingPath,
|
|
11087
|
+
function withContext(item, headingPath, text2) {
|
|
10915
11088
|
const kind = item.knowledge?.kind ?? "instruction";
|
|
10916
11089
|
const head = [kind, item.description ?? item.name, ...headingPath].filter(Boolean).join(" \u203A ");
|
|
10917
11090
|
return `${head}
|
|
10918
11091
|
|
|
10919
|
-
${
|
|
11092
|
+
${text2}`;
|
|
10920
11093
|
}
|
|
10921
11094
|
function sha1(s) {
|
|
10922
11095
|
return createHash2("sha1").update(s).digest("hex");
|
|
10923
11096
|
}
|
|
10924
11097
|
function isInside(root, path) {
|
|
10925
|
-
const rel =
|
|
11098
|
+
const rel = relative6(root, path);
|
|
10926
11099
|
return !!rel && !rel.startsWith("..") && !rel.includes(":");
|
|
10927
11100
|
}
|
|
10928
11101
|
|
|
@@ -10943,6 +11116,13 @@ var DEFAULT_WEIGHTS = {
|
|
|
10943
11116
|
plan: 1.05,
|
|
10944
11117
|
ticket: 1,
|
|
10945
11118
|
runbook: 1,
|
|
11119
|
+
// A book is reference, not project knowledge: neutral until the context
|
|
11120
|
+
// log says otherwise. It carries no recency and no status either — see
|
|
11121
|
+
// the documents adapter on what it refuses to claim.
|
|
11122
|
+
document: 1,
|
|
11123
|
+
// Never ranked: an outline has no chunks to rank. The map is total, so
|
|
11124
|
+
// it needs a number; 1.0 is the one that says nothing.
|
|
11125
|
+
outline: 1,
|
|
10946
11126
|
doc: 0.95,
|
|
10947
11127
|
wiki: 0.95,
|
|
10948
11128
|
commit: 0.85
|
|
@@ -10975,15 +11155,19 @@ function rrf(lists, k = DEFAULT_WEIGHTS.rrfK) {
|
|
|
10975
11155
|
|
|
10976
11156
|
// ../index/dist/pin.js
|
|
10977
11157
|
var LEADING_ID = /^([A-Za-z]{1,8}-?\d{1,5}(?:-\d{1,5})?|\d{2,6})(?=[-_.\s]|$)/;
|
|
11158
|
+
var POSITIONAL_KINDS = /* @__PURE__ */ new Set(["document", "outline"]);
|
|
10978
11159
|
function leadingId(relPath) {
|
|
10979
11160
|
const base = relPath.split(/[\\/]/).pop() ?? "";
|
|
10980
11161
|
return LEADING_ID.exec(base)?.[1];
|
|
10981
11162
|
}
|
|
11163
|
+
function pinnableId(item) {
|
|
11164
|
+
return POSITIONAL_KINDS.has(item.kind) ? void 0 : leadingId(item.rel_path);
|
|
11165
|
+
}
|
|
10982
11166
|
function pinnedItems(query, items) {
|
|
10983
11167
|
const q = query.toLowerCase();
|
|
10984
11168
|
const idCount = /* @__PURE__ */ new Map();
|
|
10985
11169
|
for (const item of items) {
|
|
10986
|
-
const id =
|
|
11170
|
+
const id = pinnableId(item)?.toLowerCase();
|
|
10987
11171
|
if (id)
|
|
10988
11172
|
idCount.set(id, (idCount.get(id) ?? 0) + 1);
|
|
10989
11173
|
}
|
|
@@ -10994,7 +11178,7 @@ function pinnedItems(query, items) {
|
|
|
10994
11178
|
out.push(item);
|
|
10995
11179
|
continue;
|
|
10996
11180
|
}
|
|
10997
|
-
const id =
|
|
11181
|
+
const id = pinnableId(item);
|
|
10998
11182
|
if (!id || (idCount.get(id.toLowerCase()) ?? 0) > 1)
|
|
10999
11183
|
continue;
|
|
11000
11184
|
const re = new RegExp(`(^|[^\\w-])${escape2(id)}(?=$|[^\\w-])`, "i");
|
|
@@ -11014,6 +11198,7 @@ async function retrieve(store, embedder, query, options = {}) {
|
|
|
11014
11198
|
const candidates = options.candidates ?? 30;
|
|
11015
11199
|
const weights = options.weights ?? DEFAULT_WEIGHTS;
|
|
11016
11200
|
const minRelative = options.minRelativeScore ?? 0.5;
|
|
11201
|
+
const perItemCap = { ...DEFAULT_PER_ITEM_CAP, ...options.perItemCap };
|
|
11017
11202
|
const perItem = /* @__PURE__ */ new Map();
|
|
11018
11203
|
const chunks = [];
|
|
11019
11204
|
const debug = [];
|
|
@@ -11023,11 +11208,13 @@ async function retrieve(store, embedder, query, options = {}) {
|
|
|
11023
11208
|
for (const c of store.chunksForItem(item.id)) {
|
|
11024
11209
|
const t = estimateTokens(c.text);
|
|
11025
11210
|
const fits = tokens + t <= maxTokens || chunks.length === 0;
|
|
11211
|
+
const metadata = parseMetadata(item.metadata);
|
|
11026
11212
|
if (options.debug) {
|
|
11027
11213
|
debug.push({
|
|
11028
11214
|
chunkId: c.id,
|
|
11029
11215
|
relPath: item.rel_path,
|
|
11030
11216
|
headingPath: JSON.parse(c.heading_path),
|
|
11217
|
+
metadata,
|
|
11031
11218
|
kind: item.kind,
|
|
11032
11219
|
status: item.status,
|
|
11033
11220
|
vecRank: null,
|
|
@@ -11052,7 +11239,8 @@ async function retrieve(store, embedder, query, options = {}) {
|
|
|
11052
11239
|
relPath: item.rel_path,
|
|
11053
11240
|
headingPath: JSON.parse(c.heading_path),
|
|
11054
11241
|
text: c.text,
|
|
11055
|
-
tokens: t
|
|
11242
|
+
tokens: t,
|
|
11243
|
+
...metadata ? { metadata } : {}
|
|
11056
11244
|
});
|
|
11057
11245
|
}
|
|
11058
11246
|
}
|
|
@@ -11086,6 +11274,7 @@ async function retrieve(store, embedder, query, options = {}) {
|
|
|
11086
11274
|
chunkId: c.row.id,
|
|
11087
11275
|
relPath: c.row.item.rel_path,
|
|
11088
11276
|
headingPath: JSON.parse(c.row.heading_path),
|
|
11277
|
+
metadata: parseMetadata(c.row.item.metadata),
|
|
11089
11278
|
kind: c.row.item.kind,
|
|
11090
11279
|
status: c.row.item.status,
|
|
11091
11280
|
vecRank: rankIn(vec, c.row.id),
|
|
@@ -11101,24 +11290,21 @@ async function retrieve(store, embedder, query, options = {}) {
|
|
|
11101
11290
|
}
|
|
11102
11291
|
neighbourhood.push(c);
|
|
11103
11292
|
}
|
|
11104
|
-
const
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
why = "per-item cap";
|
|
11114
|
-
} else if (tokens + estimateTokens(row.text) > neighbourBudget && chunks.length > 0) {
|
|
11115
|
-
why = "budget";
|
|
11116
|
-
}
|
|
11293
|
+
const verdicts = keep(neighbourhood.map((c) => ({
|
|
11294
|
+
itemId: c.row.item_id,
|
|
11295
|
+
kind: c.row.item.kind,
|
|
11296
|
+
score: c.score,
|
|
11297
|
+
tokens: estimateTokens(c.row.text)
|
|
11298
|
+
})), { budget: neighbourBudget, minRelativeScore: neighbourCutoff, perItemCap }, { tokens, chunks: chunks.length, perItem });
|
|
11299
|
+
for (const [i, { row, fusedScore, factor, score }] of neighbourhood.entries()) {
|
|
11300
|
+
const why = verdicts[i];
|
|
11301
|
+
const metadata = parseMetadata(row.item.metadata);
|
|
11117
11302
|
if (options.debug) {
|
|
11118
11303
|
debug.push({
|
|
11119
11304
|
chunkId: row.id,
|
|
11120
11305
|
relPath: row.item.rel_path,
|
|
11121
11306
|
headingPath: JSON.parse(row.heading_path),
|
|
11307
|
+
metadata,
|
|
11122
11308
|
kind: row.item.kind,
|
|
11123
11309
|
status: row.item.status,
|
|
11124
11310
|
vecRank: rankIn(vec, row.id),
|
|
@@ -11133,9 +11319,7 @@ async function retrieve(store, embedder, query, options = {}) {
|
|
|
11133
11319
|
if (why !== "kept")
|
|
11134
11320
|
continue;
|
|
11135
11321
|
const t = estimateTokens(row.text);
|
|
11136
|
-
perItem.set(row.item_id, (perItem.get(row.item_id) ?? 0) + 1);
|
|
11137
11322
|
tokens += t;
|
|
11138
|
-
kept++;
|
|
11139
11323
|
chunks.push({
|
|
11140
11324
|
chunkId: row.id,
|
|
11141
11325
|
score,
|
|
@@ -11145,10 +11329,9 @@ async function retrieve(store, embedder, query, options = {}) {
|
|
|
11145
11329
|
relPath: row.item.rel_path,
|
|
11146
11330
|
headingPath: JSON.parse(row.heading_path),
|
|
11147
11331
|
text: row.text,
|
|
11148
|
-
tokens: t
|
|
11332
|
+
tokens: t,
|
|
11333
|
+
...metadata ? { metadata } : {}
|
|
11149
11334
|
});
|
|
11150
|
-
if (tokens >= neighbourBudget)
|
|
11151
|
-
cut = true;
|
|
11152
11335
|
}
|
|
11153
11336
|
const durationMs = Date.now() - started;
|
|
11154
11337
|
store.logContext({
|
|
@@ -11175,6 +11358,47 @@ async function retrieve(store, embedder, query, options = {}) {
|
|
|
11175
11358
|
...options.debug ? { debug } : {}
|
|
11176
11359
|
};
|
|
11177
11360
|
}
|
|
11361
|
+
var PER_ITEM_CAP = 2;
|
|
11362
|
+
var DOCUMENT_PER_ITEM_CAP = 6;
|
|
11363
|
+
var DEFAULT_PER_ITEM_CAP = {
|
|
11364
|
+
instruction: PER_ITEM_CAP,
|
|
11365
|
+
doc: PER_ITEM_CAP,
|
|
11366
|
+
runbook: PER_ITEM_CAP,
|
|
11367
|
+
ticket: PER_ITEM_CAP,
|
|
11368
|
+
plan: PER_ITEM_CAP,
|
|
11369
|
+
decision: PER_ITEM_CAP,
|
|
11370
|
+
wiki: PER_ITEM_CAP,
|
|
11371
|
+
commit: PER_ITEM_CAP,
|
|
11372
|
+
document: DOCUMENT_PER_ITEM_CAP,
|
|
11373
|
+
// An outline has no chunks; the number is here because the map is total.
|
|
11374
|
+
outline: PER_ITEM_CAP
|
|
11375
|
+
};
|
|
11376
|
+
function keep(candidates, rules, start = { tokens: 0, chunks: 0, perItem: /* @__PURE__ */ new Map() }) {
|
|
11377
|
+
const best = candidates[0]?.score ?? 0;
|
|
11378
|
+
const perItem = new Map(start.perItem);
|
|
11379
|
+
let tokens = start.tokens;
|
|
11380
|
+
let chunks = start.chunks;
|
|
11381
|
+
let kept = 0;
|
|
11382
|
+
let end = tokens >= rules.budget ? "budget" : void 0;
|
|
11383
|
+
return candidates.map((c) => {
|
|
11384
|
+
if (end)
|
|
11385
|
+
return end;
|
|
11386
|
+
if (kept > 0 && c.score < best * rules.minRelativeScore)
|
|
11387
|
+
return end = "cutoff";
|
|
11388
|
+
const taken = perItem.get(c.itemId) ?? 0;
|
|
11389
|
+
if (taken >= (rules.perItemCap[c.kind] ?? PER_ITEM_CAP))
|
|
11390
|
+
return "per-item cap";
|
|
11391
|
+
if (chunks > 0 && tokens + c.tokens > rules.budget)
|
|
11392
|
+
return end = "budget";
|
|
11393
|
+
perItem.set(c.itemId, taken + 1);
|
|
11394
|
+
tokens += c.tokens;
|
|
11395
|
+
chunks++;
|
|
11396
|
+
kept++;
|
|
11397
|
+
if (tokens >= rules.budget)
|
|
11398
|
+
end = "budget";
|
|
11399
|
+
return "kept";
|
|
11400
|
+
});
|
|
11401
|
+
}
|
|
11178
11402
|
function neighbourQuery(query, pinned) {
|
|
11179
11403
|
if (pinned.length === 0)
|
|
11180
11404
|
return query;
|
|
@@ -11188,6 +11412,30 @@ function rankIn(list, id) {
|
|
|
11188
11412
|
const i = list.indexOf(id);
|
|
11189
11413
|
return i === -1 ? null : i + 1;
|
|
11190
11414
|
}
|
|
11415
|
+
function parseMetadata(json2) {
|
|
11416
|
+
if (!json2)
|
|
11417
|
+
return void 0;
|
|
11418
|
+
try {
|
|
11419
|
+
const parsed = JSON.parse(json2);
|
|
11420
|
+
return parsed && typeof parsed === "object" ? parsed : void 0;
|
|
11421
|
+
} catch {
|
|
11422
|
+
return void 0;
|
|
11423
|
+
}
|
|
11424
|
+
}
|
|
11425
|
+
function whereOf(c) {
|
|
11426
|
+
const book = text(c.metadata?.["book"]);
|
|
11427
|
+
if (c.kind !== "document" || !book)
|
|
11428
|
+
return [c.relPath, ...c.headingPath].join(" \u203A ");
|
|
11429
|
+
const title = text(c.metadata?.["title"]);
|
|
11430
|
+
const chapter = text(c.metadata?.["chapter"]);
|
|
11431
|
+
const head = [chapter ? `Ch. ${chapter}` : "", title].filter(Boolean).join(" ");
|
|
11432
|
+
const first = c.headingPath[0];
|
|
11433
|
+
const rest = title && first && first.toLowerCase().includes(title.toLowerCase()) ? c.headingPath.slice(1) : c.headingPath;
|
|
11434
|
+
return [book, head, ...rest].filter(Boolean).join(" \u203A ");
|
|
11435
|
+
}
|
|
11436
|
+
function text(value) {
|
|
11437
|
+
return value === void 0 || value === null ? "" : String(value);
|
|
11438
|
+
}
|
|
11191
11439
|
function formatDebug(result) {
|
|
11192
11440
|
if (!result.debug)
|
|
11193
11441
|
return "";
|
|
@@ -11197,7 +11445,7 @@ function formatDebug(result) {
|
|
|
11197
11445
|
" vec fts factor score keep where"
|
|
11198
11446
|
];
|
|
11199
11447
|
for (const d of result.debug) {
|
|
11200
|
-
const where =
|
|
11448
|
+
const where = whereOf(d).slice(0, 100);
|
|
11201
11449
|
lines.push([
|
|
11202
11450
|
String(d.vecRank ?? "-").padStart(5),
|
|
11203
11451
|
String(d.ftsRank ?? "-").padStart(4),
|
|
@@ -11213,14 +11461,32 @@ function formatContext(result) {
|
|
|
11213
11461
|
if (result.chunks.length === 0)
|
|
11214
11462
|
return "(no relevant project knowledge found)";
|
|
11215
11463
|
return result.chunks.map((c) => {
|
|
11216
|
-
const
|
|
11217
|
-
|
|
11218
|
-
return `### ${where}
|
|
11464
|
+
const meta3 = citation(c) ?? [c.kind, c.status, c.updatedAt?.slice(0, 10)].filter(Boolean).join(", ");
|
|
11465
|
+
return `### ${whereOf(c)}
|
|
11219
11466
|
_${meta3}_
|
|
11220
11467
|
|
|
11221
11468
|
${c.text.trim()}`;
|
|
11222
11469
|
}).join("\n\n");
|
|
11223
11470
|
}
|
|
11471
|
+
function citation(c) {
|
|
11472
|
+
const book = text(c.metadata?.["book"]);
|
|
11473
|
+
if (c.kind !== "document" || !book)
|
|
11474
|
+
return void 0;
|
|
11475
|
+
const title = text(c.metadata?.["title"]);
|
|
11476
|
+
const chapter = text(c.metadata?.["chapter"]);
|
|
11477
|
+
const head = [chapter ? `Ch. ${chapter}` : "", title ? `"${title}"` : ""].filter(Boolean).join(" ");
|
|
11478
|
+
const pp = pageRange(c.metadata?.["printed_pages"]);
|
|
11479
|
+
return [book, text(c.metadata?.["author"]), head, pp ? `pp. ${pp}` : ""].filter(Boolean).join(", ");
|
|
11480
|
+
}
|
|
11481
|
+
function pageRange(value) {
|
|
11482
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
11483
|
+
return void 0;
|
|
11484
|
+
const from = text(value[0]);
|
|
11485
|
+
const to = text(value[value.length - 1]);
|
|
11486
|
+
if (!from)
|
|
11487
|
+
return void 0;
|
|
11488
|
+
return !to || to === from ? from : `${from}\u2013${to}`;
|
|
11489
|
+
}
|
|
11224
11490
|
|
|
11225
11491
|
// ../index/dist/state.js
|
|
11226
11492
|
function projectState(store) {
|
|
@@ -11231,7 +11497,8 @@ function projectState(store) {
|
|
|
11231
11497
|
const live = (i) => (i.kind === "ticket" || i.kind === "plan") && (i.status === "open" || i.status === "in-progress");
|
|
11232
11498
|
const rank = (i) => i.status === "in-progress" ? 0 : 1;
|
|
11233
11499
|
const open2 = items.filter(live).sort((a, b) => rank(a) - rank(b) || a.rel_path.localeCompare(b.rel_path)).map((i) => ({ relPath: i.rel_path, name: i.name, status: i.status ?? "unknown", updatedAt: i.updated_at }));
|
|
11234
|
-
const
|
|
11500
|
+
const STILL = /* @__PURE__ */ new Set(["commit", "document", "outline"]);
|
|
11501
|
+
const recentlyChanged = items.filter((i) => !STILL.has(i.kind)).sort((a, b) => (b.updated_at ?? "").localeCompare(a.updated_at ?? "")).slice(0, 10).map((i) => ({ relPath: i.rel_path, kind: i.kind, updatedAt: i.updated_at }));
|
|
11235
11502
|
const decisions = store.db.prepare("SELECT id, created_at, title FROM decisions ORDER BY id DESC LIMIT 10").all().map((d) => ({ id: d.id, createdAt: d.created_at, title: d.title }));
|
|
11236
11503
|
return { counts, open: open2, recentlyChanged, decisions };
|
|
11237
11504
|
}
|
|
@@ -16823,7 +17090,7 @@ __export(regexes_exports, {
|
|
|
16823
17090
|
nanoid: () => nanoid,
|
|
16824
17091
|
nanoidOfLength: () => nanoidOfLength,
|
|
16825
17092
|
null: () => _null,
|
|
16826
|
-
number: () =>
|
|
17093
|
+
number: () => number2,
|
|
16827
17094
|
rfc5322Email: () => rfc5322Email,
|
|
16828
17095
|
sha1_base64: () => sha1_base64,
|
|
16829
17096
|
sha1_base64url: () => sha1_base64url,
|
|
@@ -16924,7 +17191,7 @@ var string = (params) => {
|
|
|
16924
17191
|
};
|
|
16925
17192
|
var bigint = /^-?\d+n?$/;
|
|
16926
17193
|
var integer = /^-?\d+$/;
|
|
16927
|
-
var
|
|
17194
|
+
var number2 = /^-?\d+(?:\.\d+)?$/;
|
|
16928
17195
|
var boolean = /^(?:true|false)$/i;
|
|
16929
17196
|
var _null = /^null$/i;
|
|
16930
17197
|
var _undefined = /^undefined$/i;
|
|
@@ -18051,7 +18318,7 @@ var $ZodCustomStringFormat = /* @__PURE__ */ $constructor("$ZodCustomStringForma
|
|
|
18051
18318
|
});
|
|
18052
18319
|
var $ZodNumber = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
|
|
18053
18320
|
$ZodType.init(inst, def);
|
|
18054
|
-
inst._zod.pattern =
|
|
18321
|
+
inst._zod.pattern = number2;
|
|
18055
18322
|
inst._zod.parse = (payload, _ctx) => {
|
|
18056
18323
|
if (def.coerce)
|
|
18057
18324
|
try {
|
|
@@ -19128,7 +19395,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
19128
19395
|
if (keyResult instanceof Promise) {
|
|
19129
19396
|
throw new Error("Async schemas not supported in object keys currently");
|
|
19130
19397
|
}
|
|
19131
|
-
const checkNumericKey = typeof key === "string" &&
|
|
19398
|
+
const checkNumericKey = typeof key === "string" && number2.test(key) && keyResult.issues.length;
|
|
19132
19399
|
if (checkNumericKey) {
|
|
19133
19400
|
const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx);
|
|
19134
19401
|
if (retryResult instanceof Promise) {
|
|
@@ -19695,7 +19962,7 @@ function leafPattern(schema) {
|
|
|
19695
19962
|
if (minimum !== void 0 || maximum !== void 0)
|
|
19696
19963
|
return string({ minimum, maximum }).source;
|
|
19697
19964
|
const own2 = schema._zod.pattern;
|
|
19698
|
-
return (isInt && own2 ===
|
|
19965
|
+
return (isInt && own2 === number2 ? integer : own2)?.source;
|
|
19699
19966
|
}
|
|
19700
19967
|
function partPattern(schema) {
|
|
19701
19968
|
const def = schema._zod.def;
|
|
@@ -24193,11 +24460,11 @@ function ko_default() {
|
|
|
24193
24460
|
}
|
|
24194
24461
|
|
|
24195
24462
|
// ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/locales/lt.js
|
|
24196
|
-
var capitalizeFirstCharacter = (
|
|
24197
|
-
return
|
|
24463
|
+
var capitalizeFirstCharacter = (text2) => {
|
|
24464
|
+
return text2.charAt(0).toUpperCase() + text2.slice(1);
|
|
24198
24465
|
};
|
|
24199
|
-
function getUnitTypeFromNumber(
|
|
24200
|
-
const abs = Math.abs(
|
|
24466
|
+
function getUnitTypeFromNumber(number5) {
|
|
24467
|
+
const abs = Math.abs(number5);
|
|
24201
24468
|
const last = abs % 10;
|
|
24202
24469
|
const last2 = abs % 100;
|
|
24203
24470
|
if (last2 >= 11 && last2 <= 19 || last === 0)
|
|
@@ -29169,7 +29436,7 @@ function generateRecordCheck(doc, ctx, schema, accessor) {
|
|
|
29169
29436
|
if (keyFn.definite === false)
|
|
29170
29437
|
ctx.definite = false;
|
|
29171
29438
|
const keyFast = addConstant(ctx, keyFn);
|
|
29172
|
-
const numericConst = addConstant(ctx,
|
|
29439
|
+
const numericConst = addConstant(ctx, number2);
|
|
29173
29440
|
const outKeyVar = newVar(ctx);
|
|
29174
29441
|
emitOwnKeys(doc, ctx, accessor, kVar, (d) => {
|
|
29175
29442
|
d.write(`let ${outKeyVar} = ${keyFast}(${kVar});`);
|
|
@@ -31477,7 +31744,7 @@ function stringifyKeyNames(bySchema, json2, visited) {
|
|
|
31477
31744
|
return rest;
|
|
31478
31745
|
rest.type = "string";
|
|
31479
31746
|
if (!values)
|
|
31480
|
-
rest.pattern = (types.includes("number") ?
|
|
31747
|
+
rest.pattern = (types.includes("number") ? number2 : integer).source;
|
|
31481
31748
|
return rest;
|
|
31482
31749
|
}
|
|
31483
31750
|
var pendingRecords = /* @__PURE__ */ new WeakMap();
|
|
@@ -32379,7 +32646,7 @@ __export(external_exports, {
|
|
|
32379
32646
|
null: () => _null3,
|
|
32380
32647
|
nullable: () => nullable,
|
|
32381
32648
|
nullish: () => nullish2,
|
|
32382
|
-
number: () =>
|
|
32649
|
+
number: () => number3,
|
|
32383
32650
|
object: () => object2,
|
|
32384
32651
|
optional: () => optional,
|
|
32385
32652
|
output: () => output,
|
|
@@ -32592,7 +32859,7 @@ __export(schemas_exports2, {
|
|
|
32592
32859
|
null: () => _null3,
|
|
32593
32860
|
nullable: () => nullable,
|
|
32594
32861
|
nullish: () => nullish2,
|
|
32595
|
-
number: () =>
|
|
32862
|
+
number: () => number3,
|
|
32596
32863
|
object: () => object2,
|
|
32597
32864
|
optional: () => optional,
|
|
32598
32865
|
partialRecord: () => partialRecord,
|
|
@@ -33338,7 +33605,7 @@ var ZodNumber2 = /* @__PURE__ */ $constructor(
|
|
|
33338
33605
|
}
|
|
33339
33606
|
})
|
|
33340
33607
|
);
|
|
33341
|
-
function
|
|
33608
|
+
function number3(params) {
|
|
33342
33609
|
return _number(ZodNumber2, params);
|
|
33343
33610
|
}
|
|
33344
33611
|
var ZodNumberFormat = /* @__PURE__ */ $constructor("ZodNumberFormat", (inst, def) => {
|
|
@@ -34178,7 +34445,7 @@ var stringbool = (...args) => _stringbool({
|
|
|
34178
34445
|
}, ...args);
|
|
34179
34446
|
function json(params) {
|
|
34180
34447
|
const jsonSchema = lazy(() => {
|
|
34181
|
-
return union([string2(params),
|
|
34448
|
+
return union([string2(params), number3(), boolean2(), _null3(), array(jsonSchema), record(string2(), jsonSchema)]);
|
|
34182
34449
|
});
|
|
34183
34450
|
return jsonSchema;
|
|
34184
34451
|
}
|
|
@@ -35022,13 +35289,13 @@ __export(coerce_exports2, {
|
|
|
35022
35289
|
bigint: () => bigint3,
|
|
35023
35290
|
boolean: () => boolean3,
|
|
35024
35291
|
date: () => date4,
|
|
35025
|
-
number: () =>
|
|
35292
|
+
number: () => number4,
|
|
35026
35293
|
string: () => string3
|
|
35027
35294
|
});
|
|
35028
35295
|
function string3(params) {
|
|
35029
35296
|
return _coercedString(ZodString2, params);
|
|
35030
35297
|
}
|
|
35031
|
-
function
|
|
35298
|
+
function number4(params) {
|
|
35032
35299
|
return _coercedNumber(ZodNumber2, params);
|
|
35033
35300
|
}
|
|
35034
35301
|
function boolean3(params) {
|
|
@@ -35047,20 +35314,20 @@ var SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-
|
|
|
35047
35314
|
var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
|
|
35048
35315
|
var JSONRPC_VERSION = "2.0";
|
|
35049
35316
|
var AssertObjectSchema = custom((v) => v !== null && (typeof v === "object" || typeof v === "function"));
|
|
35050
|
-
var ProgressTokenSchema = union([string2(),
|
|
35317
|
+
var ProgressTokenSchema = union([string2(), number3().int()]);
|
|
35051
35318
|
var CursorSchema = string2();
|
|
35052
35319
|
var TaskCreationParamsSchema = looseObject({
|
|
35053
35320
|
/**
|
|
35054
35321
|
* Requested duration in milliseconds to retain task from creation.
|
|
35055
35322
|
*/
|
|
35056
|
-
ttl:
|
|
35323
|
+
ttl: number3().optional(),
|
|
35057
35324
|
/**
|
|
35058
35325
|
* Time in milliseconds to wait between task status requests.
|
|
35059
35326
|
*/
|
|
35060
|
-
pollInterval:
|
|
35327
|
+
pollInterval: number3().optional()
|
|
35061
35328
|
});
|
|
35062
35329
|
var TaskMetadataSchema = object2({
|
|
35063
|
-
ttl:
|
|
35330
|
+
ttl: number3().optional()
|
|
35064
35331
|
});
|
|
35065
35332
|
var RelatedTaskMetadataSchema = object2({
|
|
35066
35333
|
taskId: string2()
|
|
@@ -35115,7 +35382,7 @@ var ResultSchema = looseObject({
|
|
|
35115
35382
|
*/
|
|
35116
35383
|
_meta: RequestMetaSchema.optional()
|
|
35117
35384
|
});
|
|
35118
|
-
var RequestIdSchema = union([string2(),
|
|
35385
|
+
var RequestIdSchema = union([string2(), number3().int()]);
|
|
35119
35386
|
var JSONRPCRequestSchema = object2({
|
|
35120
35387
|
jsonrpc: literal(JSONRPC_VERSION),
|
|
35121
35388
|
id: RequestIdSchema,
|
|
@@ -35151,7 +35418,7 @@ var JSONRPCErrorResponseSchema = object2({
|
|
|
35151
35418
|
/**
|
|
35152
35419
|
* The error type that occurred.
|
|
35153
35420
|
*/
|
|
35154
|
-
code:
|
|
35421
|
+
code: number3().int(),
|
|
35155
35422
|
/**
|
|
35156
35423
|
* A short description of the error. The message SHOULD be limited to a concise single sentence.
|
|
35157
35424
|
*/
|
|
@@ -35450,11 +35717,11 @@ var ProgressSchema = object2({
|
|
|
35450
35717
|
/**
|
|
35451
35718
|
* The progress thus far. This should increase every time progress is made, even if the total is unknown.
|
|
35452
35719
|
*/
|
|
35453
|
-
progress:
|
|
35720
|
+
progress: number3(),
|
|
35454
35721
|
/**
|
|
35455
35722
|
* Total number of items to process (or total progress required), if known.
|
|
35456
35723
|
*/
|
|
35457
|
-
total: optional(
|
|
35724
|
+
total: optional(number3()),
|
|
35458
35725
|
/**
|
|
35459
35726
|
* An optional message describing the current progress.
|
|
35460
35727
|
*/
|
|
@@ -35497,7 +35764,7 @@ var TaskSchema = object2({
|
|
|
35497
35764
|
* Time in milliseconds to keep task results available after completion.
|
|
35498
35765
|
* If null, the task has unlimited lifetime until manually cleaned up.
|
|
35499
35766
|
*/
|
|
35500
|
-
ttl: union([
|
|
35767
|
+
ttl: union([number3(), _null3()]),
|
|
35501
35768
|
/**
|
|
35502
35769
|
* ISO 8601 timestamp when the task was created.
|
|
35503
35770
|
*/
|
|
@@ -35506,7 +35773,7 @@ var TaskSchema = object2({
|
|
|
35506
35773
|
* ISO 8601 timestamp when the task was last updated.
|
|
35507
35774
|
*/
|
|
35508
35775
|
lastUpdatedAt: string2(),
|
|
35509
|
-
pollInterval: optional(
|
|
35776
|
+
pollInterval: optional(number3()),
|
|
35510
35777
|
/**
|
|
35511
35778
|
* Optional diagnostic message for failed tasks or other status information.
|
|
35512
35779
|
*/
|
|
@@ -35591,7 +35858,7 @@ var AnnotationsSchema = object2({
|
|
|
35591
35858
|
/**
|
|
35592
35859
|
* Importance hint for the resource, from 0 (least) to 1 (most).
|
|
35593
35860
|
*/
|
|
35594
|
-
priority:
|
|
35861
|
+
priority: number3().min(0).max(1).optional(),
|
|
35595
35862
|
/**
|
|
35596
35863
|
* ISO 8601 timestamp for the most recent modification.
|
|
35597
35864
|
*/
|
|
@@ -35619,7 +35886,7 @@ var ResourceSchema = object2({
|
|
|
35619
35886
|
*
|
|
35620
35887
|
* This can be used by Hosts to display file sizes and estimate context window usage.
|
|
35621
35888
|
*/
|
|
35622
|
-
size: optional(
|
|
35889
|
+
size: optional(number3()),
|
|
35623
35890
|
/**
|
|
35624
35891
|
* Optional annotations for the client.
|
|
35625
35892
|
*/
|
|
@@ -36042,7 +36309,7 @@ var ListChangedOptionsBaseSchema = object2({
|
|
|
36042
36309
|
*
|
|
36043
36310
|
* @default 300
|
|
36044
36311
|
*/
|
|
36045
|
-
debounceMs:
|
|
36312
|
+
debounceMs: number3().int().nonnegative().default(300)
|
|
36046
36313
|
});
|
|
36047
36314
|
var LoggingLevelSchema = _enum2(["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"]);
|
|
36048
36315
|
var SetLevelRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
@@ -36087,15 +36354,15 @@ var ModelPreferencesSchema = object2({
|
|
|
36087
36354
|
/**
|
|
36088
36355
|
* How much to prioritize cost when selecting a model.
|
|
36089
36356
|
*/
|
|
36090
|
-
costPriority:
|
|
36357
|
+
costPriority: number3().min(0).max(1).optional(),
|
|
36091
36358
|
/**
|
|
36092
36359
|
* How much to prioritize sampling speed (latency) when selecting a model.
|
|
36093
36360
|
*/
|
|
36094
|
-
speedPriority:
|
|
36361
|
+
speedPriority: number3().min(0).max(1).optional(),
|
|
36095
36362
|
/**
|
|
36096
36363
|
* How much to prioritize intelligence and capabilities when selecting a model.
|
|
36097
36364
|
*/
|
|
36098
|
-
intelligencePriority:
|
|
36365
|
+
intelligencePriority: number3().min(0).max(1).optional()
|
|
36099
36366
|
});
|
|
36100
36367
|
var ToolChoiceSchema = object2({
|
|
36101
36368
|
/**
|
|
@@ -36153,13 +36420,13 @@ var CreateMessageRequestParamsSchema = TaskAugmentedRequestParamsSchema.extend({
|
|
|
36153
36420
|
* declares ClientCapabilities.sampling.context. These values may be removed in future spec releases.
|
|
36154
36421
|
*/
|
|
36155
36422
|
includeContext: _enum2(["none", "thisServer", "allServers"]).optional(),
|
|
36156
|
-
temperature:
|
|
36423
|
+
temperature: number3().optional(),
|
|
36157
36424
|
/**
|
|
36158
36425
|
* The requested maximum number of tokens to sample (to prevent runaway completions).
|
|
36159
36426
|
*
|
|
36160
36427
|
* The client MAY choose to sample fewer tokens than the requested maximum.
|
|
36161
36428
|
*/
|
|
36162
|
-
maxTokens:
|
|
36429
|
+
maxTokens: number3().int(),
|
|
36163
36430
|
stopSequences: array(string2()).optional(),
|
|
36164
36431
|
/**
|
|
36165
36432
|
* Optional metadata to pass through to the LLM provider. The format of this metadata is provider-specific.
|
|
@@ -36236,8 +36503,8 @@ var StringSchemaSchema = object2({
|
|
|
36236
36503
|
type: literal("string"),
|
|
36237
36504
|
title: string2().optional(),
|
|
36238
36505
|
description: string2().optional(),
|
|
36239
|
-
minLength:
|
|
36240
|
-
maxLength:
|
|
36506
|
+
minLength: number3().optional(),
|
|
36507
|
+
maxLength: number3().optional(),
|
|
36241
36508
|
format: _enum2(["email", "uri", "date", "date-time"]).optional(),
|
|
36242
36509
|
default: string2().optional()
|
|
36243
36510
|
});
|
|
@@ -36245,9 +36512,9 @@ var NumberSchemaSchema = object2({
|
|
|
36245
36512
|
type: _enum2(["number", "integer"]),
|
|
36246
36513
|
title: string2().optional(),
|
|
36247
36514
|
description: string2().optional(),
|
|
36248
|
-
minimum:
|
|
36249
|
-
maximum:
|
|
36250
|
-
default:
|
|
36515
|
+
minimum: number3().optional(),
|
|
36516
|
+
maximum: number3().optional(),
|
|
36517
|
+
default: number3().optional()
|
|
36251
36518
|
});
|
|
36252
36519
|
var UntitledSingleSelectEnumSchemaSchema = object2({
|
|
36253
36520
|
type: literal("string"),
|
|
@@ -36279,8 +36546,8 @@ var UntitledMultiSelectEnumSchemaSchema = object2({
|
|
|
36279
36546
|
type: literal("array"),
|
|
36280
36547
|
title: string2().optional(),
|
|
36281
36548
|
description: string2().optional(),
|
|
36282
|
-
minItems:
|
|
36283
|
-
maxItems:
|
|
36549
|
+
minItems: number3().optional(),
|
|
36550
|
+
maxItems: number3().optional(),
|
|
36284
36551
|
items: object2({
|
|
36285
36552
|
type: literal("string"),
|
|
36286
36553
|
enum: array(string2())
|
|
@@ -36291,8 +36558,8 @@ var TitledMultiSelectEnumSchemaSchema = object2({
|
|
|
36291
36558
|
type: literal("array"),
|
|
36292
36559
|
title: string2().optional(),
|
|
36293
36560
|
description: string2().optional(),
|
|
36294
|
-
minItems:
|
|
36295
|
-
maxItems:
|
|
36561
|
+
minItems: number3().optional(),
|
|
36562
|
+
maxItems: number3().optional(),
|
|
36296
36563
|
items: object2({
|
|
36297
36564
|
anyOf: array(object2({
|
|
36298
36565
|
const: string2(),
|
|
@@ -36373,7 +36640,7 @@ var ElicitResultSchema = ResultSchema.extend({
|
|
|
36373
36640
|
* Per MCP spec, content is "typically omitted" for decline/cancel actions.
|
|
36374
36641
|
* We normalize null to undefined for leniency while maintaining type compatibility.
|
|
36375
36642
|
*/
|
|
36376
|
-
content: preprocess((val) => val === null ? void 0 : val, record(string2(), union([string2(),
|
|
36643
|
+
content: preprocess((val) => val === null ? void 0 : val, record(string2(), union([string2(), number3(), boolean2(), array(string2())])).optional())
|
|
36377
36644
|
});
|
|
36378
36645
|
var ResourceTemplateReferenceSchema = object2({
|
|
36379
36646
|
type: literal("ref/resource"),
|
|
@@ -36436,7 +36703,7 @@ var CompleteResultSchema = ResultSchema.extend({
|
|
|
36436
36703
|
/**
|
|
36437
36704
|
* The total number of completion options available. This can exceed the number of values actually sent in the response.
|
|
36438
36705
|
*/
|
|
36439
|
-
total: optional(
|
|
36706
|
+
total: optional(number3().int()),
|
|
36440
36707
|
/**
|
|
36441
36708
|
* Indicates whether there are additional completion options beyond those provided in the current response, even if the exact total is unknown.
|
|
36442
36709
|
*/
|
|
@@ -40537,13 +40804,13 @@ function createCapsaServer(options) {
|
|
|
40537
40804
|
const ensureFresh = freshener(options, embedder);
|
|
40538
40805
|
server.registerTool("get_context", {
|
|
40539
40806
|
title: "Get project context",
|
|
40540
|
-
description:
|
|
40807
|
+
description: 'Return the smallest set of project knowledge (runbooks, tickets, plans, decisions, instruction files) relevant to a task. Call this before starting work on a task; pass the task as you understand it. Answers are markdown: each passage has a `###` heading saying where it is from and an italic line under it. For a chapter of an indexed book that line is its citation \u2014 `_<book>, <author>, Ch. <n> "<title>", pp. <from>\u2013<to>_` \u2014 so quote the book, the chapter and the printed pages when you use the passage, rather than the file it was read from.',
|
|
40541
40808
|
inputSchema: {
|
|
40542
40809
|
task: external_exports.string().describe("The task or question, in one or two sentences"),
|
|
40543
40810
|
// 3000 is a ceiling on a ceiling: retrieval stops at the relevance
|
|
40544
40811
|
// cliff long before it fills a budget, so a larger number only ever
|
|
40545
40812
|
// buys a longer tail of near-misses.
|
|
40546
|
-
maxTokens: external_exports.number().int().min(200).max(3e3).optional().describe("Token budget, default 1500")
|
|
40813
|
+
maxTokens: external_exports.number().int().min(200).max(3e3).optional().describe("Token budget, default 1500. Raise it when this project is a library of reference documents rather than a codebase: a book section runs several hundred tokens, so 1500 is a handful of them.")
|
|
40547
40814
|
}
|
|
40548
40815
|
}, async ({ task, maxTokens }) => {
|
|
40549
40816
|
const freshness = await ensureFresh();
|
|
@@ -40573,10 +40840,10 @@ _capsa: ${result.chunks.length} chunks, ~${result.tokensEst} tokens, ${result.du
|
|
|
40573
40840
|
const store = openStore(options.projectRoot, embedder);
|
|
40574
40841
|
try {
|
|
40575
40842
|
const caveat = caveats(freshness);
|
|
40576
|
-
const
|
|
40843
|
+
const text2 = formatState(projectState(store)) + (caveat ? `
|
|
40577
40844
|
|
|
40578
40845
|
_${caveat}_` : "");
|
|
40579
|
-
return { content: [{ type: "text", text }] };
|
|
40846
|
+
return { content: [{ type: "text", text: text2 }] };
|
|
40580
40847
|
} finally {
|
|
40581
40848
|
store.close();
|
|
40582
40849
|
}
|
|
@@ -40771,8 +41038,8 @@ agent explicitly records.
|
|
|
40771
41038
|
`;
|
|
40772
41039
|
async function readVersion() {
|
|
40773
41040
|
try {
|
|
40774
|
-
const pkgPath = resolve4(
|
|
40775
|
-
const pkg = JSON.parse(await
|
|
41041
|
+
const pkgPath = resolve4(dirname10(fileURLToPath2(import.meta.url)), "../package.json");
|
|
41042
|
+
const pkg = JSON.parse(await readFile8(pkgPath, "utf8"));
|
|
40776
41043
|
const version2 = pkg.version;
|
|
40777
41044
|
return typeof version2 === "string" ? version2 : "unknown";
|
|
40778
41045
|
} catch {
|