@jigyasudham/veto 2.9.0 → 3.1.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/README.md +83 -4
- package/dist/cli/statusline.d.ts +9 -0
- package/dist/cli/statusline.d.ts.map +1 -1
- package/dist/cli/statusline.js +59 -3
- package/dist/cli/statusline.js.map +1 -1
- package/dist/cli.js +166 -5
- package/dist/cli.js.map +1 -1
- package/dist/memory/config.d.ts +10 -0
- package/dist/memory/config.d.ts.map +1 -1
- package/dist/memory/config.js +48 -8
- package/dist/memory/config.js.map +1 -1
- package/dist/memory/local.d.ts.map +1 -1
- package/dist/memory/local.js +32 -10
- package/dist/memory/local.js.map +1 -1
- package/dist/server/handlers/core.d.ts.map +1 -1
- package/dist/server/handlers/core.js +14 -1
- package/dist/server/handlers/core.js.map +1 -1
- package/dist/server/handlers/session.d.ts.map +1 -1
- package/dist/server/handlers/session.js +51 -2
- package/dist/server/handlers/session.js.map +1 -1
- package/dist/tools/definitions.d.ts +23 -3
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +11 -3
- package/dist/tools/definitions.js.map +1 -1
- package/dist/transcripts/adapters/claude.d.ts +27 -0
- package/dist/transcripts/adapters/claude.d.ts.map +1 -0
- package/dist/transcripts/adapters/claude.js +194 -0
- package/dist/transcripts/adapters/claude.js.map +1 -0
- package/dist/transcripts/archive.d.ts +23 -0
- package/dist/transcripts/archive.d.ts.map +1 -0
- package/dist/transcripts/archive.js +101 -0
- package/dist/transcripts/archive.js.map +1 -0
- package/dist/transcripts/cache.d.ts +66 -0
- package/dist/transcripts/cache.d.ts.map +1 -0
- package/dist/transcripts/cache.js +0 -0
- package/dist/transcripts/cache.js.map +1 -0
- package/dist/transcripts/chunk.d.ts +26 -0
- package/dist/transcripts/chunk.d.ts.map +1 -0
- package/dist/transcripts/chunk.js +54 -0
- package/dist/transcripts/chunk.js.map +1 -0
- package/dist/transcripts/config.d.ts +52 -0
- package/dist/transcripts/config.d.ts.map +1 -0
- package/dist/transcripts/config.js +135 -0
- package/dist/transcripts/config.js.map +1 -0
- package/dist/transcripts/embed.d.ts +58 -0
- package/dist/transcripts/embed.d.ts.map +1 -0
- package/dist/transcripts/embed.js +303 -0
- package/dist/transcripts/embed.js.map +1 -0
- package/dist/transcripts/expand.d.ts +20 -0
- package/dist/transcripts/expand.d.ts.map +1 -0
- package/dist/transcripts/expand.js +97 -0
- package/dist/transcripts/expand.js.map +1 -0
- package/dist/transcripts/ingest.d.ts +17 -0
- package/dist/transcripts/ingest.d.ts.map +1 -0
- package/dist/transcripts/ingest.js +120 -0
- package/dist/transcripts/ingest.js.map +1 -0
- package/dist/transcripts/manage.d.ts +42 -0
- package/dist/transcripts/manage.d.ts.map +1 -0
- package/dist/transcripts/manage.js +123 -0
- package/dist/transcripts/manage.js.map +1 -0
- package/dist/transcripts/mapping.d.ts +23 -0
- package/dist/transcripts/mapping.d.ts.map +1 -0
- package/dist/transcripts/mapping.js +42 -0
- package/dist/transcripts/mapping.js.map +1 -0
- package/dist/transcripts/mask.d.ts +26 -0
- package/dist/transcripts/mask.d.ts.map +1 -0
- package/dist/transcripts/mask.js +121 -0
- package/dist/transcripts/mask.js.map +1 -0
- package/dist/transcripts/on-save.d.ts +12 -0
- package/dist/transcripts/on-save.d.ts.map +1 -0
- package/dist/transcripts/on-save.js +37 -0
- package/dist/transcripts/on-save.js.map +1 -0
- package/dist/transcripts/pyramid.d.ts +38 -0
- package/dist/transcripts/pyramid.d.ts.map +1 -0
- package/dist/transcripts/pyramid.js +113 -0
- package/dist/transcripts/pyramid.js.map +1 -0
- package/dist/transcripts/recall.d.ts +46 -0
- package/dist/transcripts/recall.d.ts.map +1 -0
- package/dist/transcripts/recall.js +107 -0
- package/dist/transcripts/recall.js.map +1 -0
- package/dist/transcripts/schema.d.ts +79 -0
- package/dist/transcripts/schema.d.ts.map +1 -0
- package/dist/transcripts/schema.js +178 -0
- package/dist/transcripts/schema.js.map +1 -0
- package/dist/transcripts/search.d.ts +57 -0
- package/dist/transcripts/search.d.ts.map +1 -0
- package/dist/transcripts/search.js +332 -0
- package/dist/transcripts/search.js.map +1 -0
- package/dist/transcripts/store.d.ts +21 -0
- package/dist/transcripts/store.d.ts.map +1 -0
- package/dist/transcripts/store.js +105 -0
- package/dist/transcripts/store.js.map +1 -0
- package/dist/transcripts/toc.d.ts +18 -0
- package/dist/transcripts/toc.d.ts.map +1 -0
- package/dist/transcripts/toc.js +96 -0
- package/dist/transcripts/toc.js.map +1 -0
- package/dist/transcripts/tokenize.d.ts +14 -0
- package/dist/transcripts/tokenize.d.ts.map +1 -0
- package/dist/transcripts/tokenize.js +70 -0
- package/dist/transcripts/tokenize.js.map +1 -0
- package/dist/transcripts/vectors.d.ts +40 -0
- package/dist/transcripts/vectors.d.ts.map +1 -0
- package/dist/transcripts/vectors.js +203 -0
- package/dist/transcripts/vectors.js.map +1 -0
- package/package.json +3 -2
- package/server.json +2 -2
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Shared tokenizer — the single source of truth for the portable index.
|
|
2
|
+
//
|
|
3
|
+
// The one correctness property the whole search layer hangs on: index-time and
|
|
4
|
+
// query-time tokenization are the SAME function. The FTS5 design broke this
|
|
5
|
+
// subtly (toFtsQuery kept `foo/bar.ts` whole, FTS5's unicode61 re-split it
|
|
6
|
+
// inside the quotes), which is why this file exists instead of two ad-hoc
|
|
7
|
+
// paths. Property-tested in tests/transcripts/tokenize.test.ts: every token
|
|
8
|
+
// emitted at index time finds its document when fed back as a query.
|
|
9
|
+
//
|
|
10
|
+
// No stemming — this corpus is identifiers, paths, and error strings, where
|
|
11
|
+
// porter folding costs more than it buys (`E404` must survive intact).
|
|
12
|
+
// Sub-token expansion (step 3 below) buys the recall stemming was buying.
|
|
13
|
+
// Keep letters, digits, and the identifier/path glue chars; split on the rest.
|
|
14
|
+
const SPLIT = /[^\p{L}\p{N}_\-./@+]+/u;
|
|
15
|
+
// Sub-token boundaries inside a kept token: the glue chars…
|
|
16
|
+
const SEP = /[_\-./@+]+/;
|
|
17
|
+
// …and camelCase humps, detected before lowercasing.
|
|
18
|
+
const CAMEL = /(?<=[\p{Ll}\p{N}])(?=\p{Lu})|(?<=\p{Lu})(?=\p{Lu}\p{Ll})/u;
|
|
19
|
+
// Masked-secret residue and inline blobs: long pure-hex, or long base64-ish
|
|
20
|
+
// runs that actually look like data (digits + mixed case or padding) rather
|
|
21
|
+
// than a long camelCase identifier. They bloat postings and are never searched.
|
|
22
|
+
const HEXY = /^[0-9a-fA-F]{32,}$/;
|
|
23
|
+
const B64_CHARS = /^[A-Za-z0-9+/=]{32,}$/;
|
|
24
|
+
function isBlob(tok) {
|
|
25
|
+
if (tok.length > 64)
|
|
26
|
+
return true;
|
|
27
|
+
if (HEXY.test(tok))
|
|
28
|
+
return true;
|
|
29
|
+
return B64_CHARS.test(tok) && /\d/.test(tok) && (/[+/=]/.test(tok) || (/[a-z]/.test(tok) && /[A-Z]/.test(tok)));
|
|
30
|
+
}
|
|
31
|
+
/** Sub-token expansion on by default; the ingest benchmark measures both ways. */
|
|
32
|
+
export const SUBTOKENS_DEFAULT = true;
|
|
33
|
+
/**
|
|
34
|
+
* Tokenize text for indexing or querying — always the same function.
|
|
35
|
+
*
|
|
36
|
+
* 1. Split on anything that is not a letter, digit, or `_ - . / @ +`.
|
|
37
|
+
* 2. Emit each token lowercased.
|
|
38
|
+
* 3. When it looks compound, also emit its lowercased sub-tokens:
|
|
39
|
+
* `normalizeProjectDir` → normalizeprojectdir, normalize, project, dir;
|
|
40
|
+
* `src/transcripts/search.ts` → the full path, src, transcripts, search, ts.
|
|
41
|
+
* 4. Drop blobs (see isBlob) and tokens with no letter or digit at all.
|
|
42
|
+
*/
|
|
43
|
+
export function tokenize(text, subtokens = SUBTOKENS_DEFAULT) {
|
|
44
|
+
const out = [];
|
|
45
|
+
for (const raw of text.split(SPLIT)) {
|
|
46
|
+
if (!raw || !/[\p{L}\p{N}]/u.test(raw) || isBlob(raw))
|
|
47
|
+
continue;
|
|
48
|
+
const whole = raw.toLowerCase();
|
|
49
|
+
out.push(whole);
|
|
50
|
+
if (!subtokens)
|
|
51
|
+
continue;
|
|
52
|
+
// Two granularities, both emitted: separator segments AND their camel
|
|
53
|
+
// parts. Needed for symmetry — a lowercased emitted token re-splits by
|
|
54
|
+
// separators only (its camel humps are gone), so those segment-level
|
|
55
|
+
// tokens must exist in the index too.
|
|
56
|
+
for (const seg of raw.split(SEP)) {
|
|
57
|
+
const s = seg.toLowerCase();
|
|
58
|
+
const ok = (t) => t && /[\p{L}\p{N}]/u.test(t) && !isBlob(t);
|
|
59
|
+
if (s !== whole && ok(s))
|
|
60
|
+
out.push(s);
|
|
61
|
+
for (const part of seg.split(CAMEL)) {
|
|
62
|
+
const p = part.toLowerCase();
|
|
63
|
+
if (p !== s && p !== whole && ok(p))
|
|
64
|
+
out.push(p);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=tokenize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../../src/transcripts/tokenize.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,0EAA0E;AAC1E,4EAA4E;AAC5E,qEAAqE;AACrE,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,0EAA0E;AAE1E,+EAA+E;AAC/E,MAAM,KAAK,GAAG,wBAAwB,CAAC;AACvC,4DAA4D;AAC5D,MAAM,GAAG,GAAG,YAAY,CAAC;AACzB,qDAAqD;AACrD,MAAM,KAAK,GAAG,2DAA2D,CAAC;AAE1E,4EAA4E;AAC5E,4EAA4E;AAC5E,gFAAgF;AAChF,MAAM,IAAI,GAAG,oBAAoB,CAAC;AAClC,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAE1C,SAAS,MAAM,CAAC,GAAW;IACzB,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAClH,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAEtC;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,YAAqB,iBAAiB;IAC3E,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC;YAAE,SAAS;QAChE,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,IAAI,CAAC,SAAS;YAAE,SAAS;QACzB,sEAAsE;QACtE,uEAAuE;QACvE,qEAAqE;QACrE,sCAAsC;QACtC,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACrE,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;oBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type EmbedStatus = 'embedded' | 'already_embedded' | 'unavailable' | 'not_found' | 'error';
|
|
2
|
+
export type EmbedResult = {
|
|
3
|
+
status: EmbedStatus;
|
|
4
|
+
docs?: number;
|
|
5
|
+
chunks?: number;
|
|
6
|
+
reason?: string;
|
|
7
|
+
};
|
|
8
|
+
/** Read a stored row back into signed values for scoring. */
|
|
9
|
+
export declare function dequantizeToInt8(bytes: Uint8Array): Int8Array;
|
|
10
|
+
/**
|
|
11
|
+
* Build chunk vectors for one archive's indexed docs. Idempotent, and a no-op
|
|
12
|
+
* when the model is not installed — the caller degrades to BM25 rather than
|
|
13
|
+
* failing (condition A2).
|
|
14
|
+
*/
|
|
15
|
+
export declare function embedArchive(archiveId: string): EmbedResult;
|
|
16
|
+
/** `chunkIndex` is the window that won — used only to aim a snippet at the
|
|
17
|
+
* right part of a long event. Chunks never surface as results (C6). */
|
|
18
|
+
export type VectorHit = {
|
|
19
|
+
docId: number;
|
|
20
|
+
chunkIndex: number;
|
|
21
|
+
score: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Score every stored chunk against `query` and return the best score per doc.
|
|
25
|
+
*
|
|
26
|
+
* Max-sim, not mean: an event is relevant if ANY of its windows is, which is
|
|
27
|
+
* the entire point of chunking. Dedup to docs happens here so nothing outside
|
|
28
|
+
* this module ever sees a chunk (C6).
|
|
29
|
+
*/
|
|
30
|
+
export declare function searchVectors(query: string, opts?: {
|
|
31
|
+
projectDir?: string;
|
|
32
|
+
sourceSessionId?: string;
|
|
33
|
+
limit?: number;
|
|
34
|
+
}): VectorHit[];
|
|
35
|
+
/** Rows currently stored, for budget measurement and tests. */
|
|
36
|
+
export declare function vectorStats(): {
|
|
37
|
+
chunks: number;
|
|
38
|
+
bytes: number;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=vectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vectors.d.ts","sourceRoot":"","sources":["../../src/transcripts/vectors.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,kBAAkB,GAAG,aAAa,GAAG,WAAW,GAAG,OAAO,CAAC;AAClG,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AA2BnG,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CAE7D;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAuD3D;AAED;wEACwE;AACxE,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3E,SAAS,EAAE,CAgFb;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAM/D"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// Chunk vectors: build, store, and query (VERSION-3 item 6, Phase B).
|
|
2
|
+
//
|
|
3
|
+
// Separated from embed.ts on purpose — that file is pure inference against a
|
|
4
|
+
// pinned contract, this one owns storage and lifecycle. It is also separate
|
|
5
|
+
// from ingest.ts: parsing must never depend on the model being installed, so
|
|
6
|
+
// vectors have their own marker (`archives.chunker_version` + `embed_model`)
|
|
7
|
+
// and are backfilled lazily. Installing the model later costs an embed pass,
|
|
8
|
+
// not a re-parse; removing it leaves search working on BM25 alone.
|
|
9
|
+
//
|
|
10
|
+
// Quantization note: cosine similarity is invariant to a positive per-vector
|
|
11
|
+
// scalar, so the dequantization scale cancels and is never stored. What IS
|
|
12
|
+
// stored is the int8 vector's own L2 norm, so scoring is a dot product and a
|
|
13
|
+
// divide.
|
|
14
|
+
import { getTranscriptsDb } from './store.js';
|
|
15
|
+
import { EMPTY_SCORE, getDocCache, getVectorCache, resetCaches, scopeMask, scoreScratch } from './cache.js';
|
|
16
|
+
import { CHUNKER_VERSION, chunkText } from './chunk.js';
|
|
17
|
+
import { embed, embeddingsAvailable, modelProvenance } from './embed.js';
|
|
18
|
+
/** Identifies which model produced stored vectors; a change forces a rebuild. */
|
|
19
|
+
function modelTag() {
|
|
20
|
+
const { model_id, revision } = modelProvenance();
|
|
21
|
+
return `${model_id}@${revision}`;
|
|
22
|
+
}
|
|
23
|
+
/** Per-vector symmetric int8. The scale is deliberately discarded (see above). */
|
|
24
|
+
function quantize(vec) {
|
|
25
|
+
let max = 0;
|
|
26
|
+
for (const v of vec) {
|
|
27
|
+
const a = Math.abs(v);
|
|
28
|
+
if (a > max)
|
|
29
|
+
max = a;
|
|
30
|
+
}
|
|
31
|
+
const scale = max === 0 ? 1 : max / 127;
|
|
32
|
+
const bytes = new Uint8Array(vec.length);
|
|
33
|
+
let sumSq = 0;
|
|
34
|
+
for (let i = 0; i < vec.length; i += 1) {
|
|
35
|
+
let q = Math.round(vec[i] / scale);
|
|
36
|
+
if (q > 127)
|
|
37
|
+
q = 127;
|
|
38
|
+
if (q < -127)
|
|
39
|
+
q = -127;
|
|
40
|
+
sumSq += q * q;
|
|
41
|
+
// Int8 stored in a byte: two's complement, unpacked on read.
|
|
42
|
+
bytes[i] = q < 0 ? q + 256 : q;
|
|
43
|
+
}
|
|
44
|
+
return { bytes, norm: Math.sqrt(sumSq) };
|
|
45
|
+
}
|
|
46
|
+
/** Read a stored row back into signed values for scoring. */
|
|
47
|
+
export function dequantizeToInt8(bytes) {
|
|
48
|
+
return new Int8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
49
|
+
}
|
|
50
|
+
function needsEmbedding(row, tag) {
|
|
51
|
+
return row.chunker_version !== CHUNKER_VERSION || row.embed_model !== tag;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build chunk vectors for one archive's indexed docs. Idempotent, and a no-op
|
|
55
|
+
* when the model is not installed — the caller degrades to BM25 rather than
|
|
56
|
+
* failing (condition A2).
|
|
57
|
+
*/
|
|
58
|
+
export function embedArchive(archiveId) {
|
|
59
|
+
try {
|
|
60
|
+
if (!embeddingsAvailable())
|
|
61
|
+
return { status: 'unavailable' };
|
|
62
|
+
const db = getTranscriptsDb();
|
|
63
|
+
const row = db.prepare(`SELECT * FROM archives WHERE id = ?`).get(archiveId);
|
|
64
|
+
if (!row)
|
|
65
|
+
return { status: 'not_found' };
|
|
66
|
+
const tag = modelTag();
|
|
67
|
+
if (!needsEmbedding(row, tag))
|
|
68
|
+
return { status: 'already_embedded' };
|
|
69
|
+
// Only indexed, searchable docs get vectors — the same set BM25 covers,
|
|
70
|
+
// read with their masked text (C3: masked text is the only text there is).
|
|
71
|
+
const docs = db.prepare(`SELECT d.id AS doc_id, e.text AS text
|
|
72
|
+
FROM search_docs d JOIN events e ON e.id = d.event_id
|
|
73
|
+
WHERE d.archive_id = ?`).all(archiveId);
|
|
74
|
+
const insVec = db.prepare(`INSERT INTO search_vectors (doc_id, chunk_index, vec, norm) VALUES (?, ?, ?, ?)`);
|
|
75
|
+
let chunks = 0;
|
|
76
|
+
db.exec('BEGIN');
|
|
77
|
+
try {
|
|
78
|
+
db.prepare(`DELETE FROM search_vectors WHERE doc_id IN (SELECT id FROM search_docs WHERE archive_id = ?)`).run(archiveId);
|
|
79
|
+
for (const d of docs) {
|
|
80
|
+
const text = d.text ?? '';
|
|
81
|
+
if (!text.trim())
|
|
82
|
+
continue;
|
|
83
|
+
for (const c of chunkText(text)) {
|
|
84
|
+
const { bytes, norm } = quantize(embed(c.text));
|
|
85
|
+
// A zero-norm chunk (no in-vocabulary tokens) can never win a cosine
|
|
86
|
+
// and would divide by zero at query time; storing it is pure cost.
|
|
87
|
+
if (norm === 0)
|
|
88
|
+
continue;
|
|
89
|
+
insVec.run(d.doc_id, c.index, bytes, norm);
|
|
90
|
+
chunks += 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
db.prepare(`UPDATE archives SET chunker_version = ?, embed_model = ? WHERE id = ?`)
|
|
94
|
+
.run(CHUNKER_VERSION, tag, archiveId);
|
|
95
|
+
db.exec('COMMIT');
|
|
96
|
+
resetCaches();
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
db.exec('ROLLBACK');
|
|
100
|
+
throw e;
|
|
101
|
+
}
|
|
102
|
+
return { status: 'embedded', docs: docs.length, chunks };
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
return { status: 'error', reason: e instanceof Error ? e.message : String(e) };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Score every stored chunk against `query` and return the best score per doc.
|
|
110
|
+
*
|
|
111
|
+
* Max-sim, not mean: an event is relevant if ANY of its windows is, which is
|
|
112
|
+
* the entire point of chunking. Dedup to docs happens here so nothing outside
|
|
113
|
+
* this module ever sees a chunk (C6).
|
|
114
|
+
*/
|
|
115
|
+
export function searchVectors(query, opts = {}) {
|
|
116
|
+
if (!embeddingsAvailable())
|
|
117
|
+
return [];
|
|
118
|
+
const db = getTranscriptsDb();
|
|
119
|
+
const qv = embed(query);
|
|
120
|
+
let qNorm = 0;
|
|
121
|
+
for (const v of qv)
|
|
122
|
+
qNorm += v * v;
|
|
123
|
+
qNorm = Math.sqrt(qNorm);
|
|
124
|
+
if (qNorm === 0)
|
|
125
|
+
return [];
|
|
126
|
+
// Brute-force scan, but over a cached flat Int8Array rather than freshly
|
|
127
|
+
// materialized rows. Measured at 27,070 chunks: the arithmetic is ~12 ms and
|
|
128
|
+
// the SQL/Buffer marshalling it replaces was ~60 ms, every query. A full
|
|
129
|
+
// scan is still the right algorithm — it cannot lose recall the way ANN
|
|
130
|
+
// would — it just must not re-read the table each time.
|
|
131
|
+
const cache = getVectorCache();
|
|
132
|
+
if (cache.count === 0 || cache.dim !== qv.length)
|
|
133
|
+
return [];
|
|
134
|
+
const docs = getDocCache();
|
|
135
|
+
const mask = scopeMask(docs, opts);
|
|
136
|
+
const { data, norms, docIds, chunkIdx, dim } = cache;
|
|
137
|
+
// Best-per-document is accumulated in flat arrays indexed by doc id, not a
|
|
138
|
+
// Map. At 108k chunks the Map get/set pair was a six-figure allocation-heavy
|
|
139
|
+
// operation count on the hot path; this is two typed-array writes. `touched`
|
|
140
|
+
// records which ids were written so the result scan stays proportional to
|
|
141
|
+
// matches rather than to the id space.
|
|
142
|
+
const { score: bestScore, chunk: bestChunk } = scoreScratch(docs.maxId);
|
|
143
|
+
const touched = [];
|
|
144
|
+
// Single pass, full dot product per in-scope chunk.
|
|
145
|
+
//
|
|
146
|
+
// A two-pass scheme was tried and MEASURED SLOWER (170 ms vs 131 ms at 108k
|
|
147
|
+
// chunks): score a PCA prefix, bound the tail by Cauchy-Schwarz, skip chunks
|
|
148
|
+
// whose best possible score cannot reach the cutoff. It is exact, but the
|
|
149
|
+
// bound is far too loose here — the tail retains enough norm that almost
|
|
150
|
+
// nothing prunes, so it paid for the prefix and the bookkeeping and skipped
|
|
151
|
+
// little. Recorded so it is not re-attempted on intuition.
|
|
152
|
+
const limit = Math.min(Math.max(opts.limit ?? 10, 1), 50);
|
|
153
|
+
for (let c = 0; c < cache.count; c += 1) {
|
|
154
|
+
const docId = docIds[c];
|
|
155
|
+
if (mask && mask[docId] !== 1)
|
|
156
|
+
continue;
|
|
157
|
+
const norm = norms[c];
|
|
158
|
+
if (norm === 0)
|
|
159
|
+
continue;
|
|
160
|
+
const base = c * dim;
|
|
161
|
+
// Unrolled by 8. Separate accumulations, not one chained sum: `dot +=
|
|
162
|
+
// a+b+...+h` would add the eight products together first and change the
|
|
163
|
+
// summation order.
|
|
164
|
+
let dot = 0;
|
|
165
|
+
let i = 0;
|
|
166
|
+
for (; i + 8 <= dim; i += 8) {
|
|
167
|
+
const b = base + i;
|
|
168
|
+
dot += qv[i] * data[b];
|
|
169
|
+
dot += qv[i + 1] * data[b + 1];
|
|
170
|
+
dot += qv[i + 2] * data[b + 2];
|
|
171
|
+
dot += qv[i + 3] * data[b + 3];
|
|
172
|
+
dot += qv[i + 4] * data[b + 4];
|
|
173
|
+
dot += qv[i + 5] * data[b + 5];
|
|
174
|
+
dot += qv[i + 6] * data[b + 6];
|
|
175
|
+
dot += qv[i + 7] * data[b + 7];
|
|
176
|
+
}
|
|
177
|
+
for (; i < dim; i += 1)
|
|
178
|
+
dot += qv[i] * data[base + i];
|
|
179
|
+
const score = dot / (qNorm * norm);
|
|
180
|
+
if (score > bestScore[docId]) {
|
|
181
|
+
if (bestScore[docId] === EMPTY_SCORE)
|
|
182
|
+
touched.push(docId);
|
|
183
|
+
bestScore[docId] = score;
|
|
184
|
+
bestChunk[docId] = chunkIdx[c];
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const out = touched
|
|
188
|
+
.map(docId => ({ docId, chunkIndex: bestChunk[docId], score: bestScore[docId] }))
|
|
189
|
+
.sort((a, b) => b.score - a.score)
|
|
190
|
+
.slice(0, limit);
|
|
191
|
+
// The scratch buffers are shared and handed back dirty; clear exactly what
|
|
192
|
+
// was written so the next query sees a clean slate without a full zero-fill.
|
|
193
|
+
for (const docId of touched)
|
|
194
|
+
bestScore[docId] = EMPTY_SCORE;
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
/** Rows currently stored, for budget measurement and tests. */
|
|
198
|
+
export function vectorStats() {
|
|
199
|
+
const db = getTranscriptsDb();
|
|
200
|
+
const r = db.prepare(`SELECT COUNT(*) AS chunks, COALESCE(SUM(LENGTH(vec)), 0) AS bytes FROM search_vectors`).get();
|
|
201
|
+
return { chunks: Number(r.chunks), bytes: Number(r.bytes) };
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=vectors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vectors.js","sourceRoot":"","sources":["../../src/transcripts/vectors.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,6EAA6E;AAC7E,mEAAmE;AACnE,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,UAAU;AAEV,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5G,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMzE,iFAAiF;AACjF,SAAS,QAAQ;IACf,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,eAAe,EAAE,CAAC;IACjD,OAAO,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC;AACnC,CAAC;AAED,kFAAkF;AAClF,SAAS,QAAQ,CAAC,GAAiB;IACjC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,CAAC,GAAG,GAAG;YAAE,GAAG,GAAG,CAAC,CAAC;IAAC,CAAC;IACrE,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;IAExC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAE,GAAG,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,GAAG;YAAE,CAAC,GAAG,GAAG,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,GAAG;YAAE,CAAC,GAAG,CAAC,GAAG,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,6DAA6D;QAC7D,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,cAAc,CAAC,GAAe,EAAE,GAAW;IAClD,OAAO,GAAG,CAAC,eAAe,KAAK,eAAe,IAAI,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC;AAC5E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,IAAI,CAAC;QACH,IAAI,CAAC,mBAAmB,EAAE;YAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QAC7D,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,GAAG,CAAC,SAAS,CAA2B,CAAC;QACvG,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QAEzC,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC;QACvB,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;QAErE,wEAAwE;QACxE,2EAA2E;QAC3E,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACrB;;+BAEyB,CAC1B,CAAC,GAAG,CAAC,SAAS,CAA8C,CAAC;QAE9D,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CACvB,iFAAiF,CAClF,CAAC;QAEF,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,EAAE,CAAC,OAAO,CACR,8FAA8F,CAC/F,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAEjB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBAAE,SAAS;gBAC3B,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;oBAChC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;oBAChD,qEAAqE;oBACrE,mEAAmE;oBACnE,IAAI,IAAI,KAAK,CAAC;wBAAE,SAAS;oBACzB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;oBAC3C,MAAM,IAAI,CAAC,CAAC;gBACd,CAAC;YACH,CAAC;YAED,EAAE,CAAC,OAAO,CAAC,uEAAuE,CAAC;iBAChF,GAAG,CAAC,eAAe,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;YACxC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClB,WAAW,EAAE,CAAC;QAChB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACpB,MAAM,CAAC,CAAC;QACV,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC3D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACjF,CAAC;AACH,CAAC;AAMD;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,OAA0E,EAAE;IAE5E,IAAI,CAAC,mBAAmB,EAAE;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAE9B,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE3B,yEAAyE;IACzE,6EAA6E;IAC7E,yEAAyE;IACzE,wEAAwE;IACxE,wDAAwD;IACxD,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAC5D,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAEnC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IAErD,2EAA2E;IAC3E,6EAA6E;IAC7E,6EAA6E;IAC7E,0EAA0E;IAC1E,uCAAuC;IACvC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxE,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,oDAAoD;IACpD,EAAE;IACF,4EAA4E;IAC5E,6EAA6E;IAC7E,0EAA0E;IAC1E,yEAAyE;IACzE,4EAA4E;IAC5E,2DAA2D;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;QACzB,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,SAAS;QACxC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,IAAI,IAAI,KAAK,CAAC;YAAE,SAAS;QACzB,MAAM,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;QACrB,sEAAsE;QACtE,wEAAwE;QACxE,mBAAmB;QACnB,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YACnB,GAAG,IAAI,EAAE,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;YACzB,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACjC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACjC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACjC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACjC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACjC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACjC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;QACnC,CAAC;QACD,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC;YAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAE,CAAC;QACxD,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,GAAG,SAAS,CAAC,KAAK,CAAE,EAAE,CAAC;YAC9B,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,WAAW;gBAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1D,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;YACzB,SAAS,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,OAAO;SAChB,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,KAAK,CAAE,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAE,EAAE,CAAC,CAAC;SAClF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEnB,2EAA2E;IAC3E,6EAA6E;IAC7E,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,SAAS,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC;IAC5D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,WAAW;IACzB,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAC9B,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAClB,uFAAuF,CACxF,CAAC,GAAG,EAAuC,CAAC;IAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jigyasudham/veto",
|
|
3
3
|
"mcpName": "io.github.jigyasudham/veto",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.1.0",
|
|
5
5
|
"description": "93 agentic tools. 49 specialists. Every major AI CLI. Self-learning. Zero extra cost on subscriptions.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"type": "module",
|
|
28
28
|
"engines": {
|
|
29
|
-
"node": ">=22.
|
|
29
|
+
"node": ">=22.13.0 <23.0.0 || >=23.4.0"
|
|
30
30
|
},
|
|
31
31
|
"bin": {
|
|
32
32
|
"veto": "dist/cli.js",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"test:coverage": "vitest run --coverage"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
+
"@jigyasudham/veto-model": "1.0.0",
|
|
51
52
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
52
53
|
"web-tree-sitter": "^0.26.9",
|
|
53
54
|
"zod": "^4.4.3"
|
package/server.json
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
10
|
"websiteUrl": "https://github.com/jigyasudham/veto#readme",
|
|
11
|
-
"version": "
|
|
11
|
+
"version": "3.1.0",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "@jigyasudham/veto",
|
|
17
|
-
"version": "
|
|
17
|
+
"version": "3.1.0",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
}
|