codesift-mcp 0.8.10 → 0.8.11

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.
Files changed (63) hide show
  1. package/dist/cli/hooks.d.ts.map +1 -1
  2. package/dist/cli/hooks.js +2 -1
  3. package/dist/cli/hooks.js.map +1 -1
  4. package/dist/config.d.ts +1 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +1 -0
  7. package/dist/config.js.map +1 -1
  8. package/dist/register-tools.d.ts.map +1 -1
  9. package/dist/register-tools.js +39 -1
  10. package/dist/register-tools.js.map +1 -1
  11. package/dist/search/model2vec-tokenize.d.ts +22 -0
  12. package/dist/search/model2vec-tokenize.d.ts.map +1 -0
  13. package/dist/search/model2vec-tokenize.js +140 -0
  14. package/dist/search/model2vec-tokenize.js.map +1 -0
  15. package/dist/search/semantic.d.ts.map +1 -1
  16. package/dist/search/semantic.js +7 -0
  17. package/dist/search/semantic.js.map +1 -1
  18. package/dist/search/static-embedding-provider.d.ts +24 -0
  19. package/dist/search/static-embedding-provider.d.ts.map +1 -0
  20. package/dist/search/static-embedding-provider.js +149 -0
  21. package/dist/search/static-embedding-provider.js.map +1 -0
  22. package/dist/storage/_shared.d.ts.map +1 -1
  23. package/dist/storage/_shared.js +4 -1
  24. package/dist/storage/_shared.js.map +1 -1
  25. package/dist/storage/hash-snapshot.d.ts +36 -0
  26. package/dist/storage/hash-snapshot.d.ts.map +1 -0
  27. package/dist/storage/hash-snapshot.js +101 -0
  28. package/dist/storage/hash-snapshot.js.map +1 -0
  29. package/dist/storage/usage-stats.d.ts +8 -0
  30. package/dist/storage/usage-stats.d.ts.map +1 -1
  31. package/dist/storage/usage-stats.js +74 -24
  32. package/dist/storage/usage-stats.js.map +1 -1
  33. package/dist/storage/usage-tracker.d.ts +16 -0
  34. package/dist/storage/usage-tracker.d.ts.map +1 -1
  35. package/dist/storage/usage-tracker.js +23 -3
  36. package/dist/storage/usage-tracker.js.map +1 -1
  37. package/dist/tools/index-tools.d.ts +31 -2
  38. package/dist/tools/index-tools.d.ts.map +1 -1
  39. package/dist/tools/index-tools.js +460 -33
  40. package/dist/tools/index-tools.js.map +1 -1
  41. package/dist/tools/pg-introspect-tools.d.ts +147 -0
  42. package/dist/tools/pg-introspect-tools.d.ts.map +1 -0
  43. package/dist/tools/pg-introspect-tools.js +396 -0
  44. package/dist/tools/pg-introspect-tools.js.map +1 -0
  45. package/dist/types.d.ts +27 -0
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/utils/hf-download-stream.d.ts +21 -0
  48. package/dist/utils/hf-download-stream.d.ts.map +1 -0
  49. package/dist/utils/hf-download-stream.js +101 -0
  50. package/dist/utils/hf-download-stream.js.map +1 -0
  51. package/dist/utils/hf-hub-download.d.ts +8 -0
  52. package/dist/utils/hf-hub-download.d.ts.map +1 -0
  53. package/dist/utils/hf-hub-download.js +149 -0
  54. package/dist/utils/hf-hub-download.js.map +1 -0
  55. package/dist/utils/safetensors-loader.d.ts +9 -0
  56. package/dist/utils/safetensors-loader.d.ts.map +1 -0
  57. package/dist/utils/safetensors-loader.js +95 -0
  58. package/dist/utils/safetensors-loader.js.map +1 -0
  59. package/dist/utils/safetensors-meta-guard.d.ts +7 -0
  60. package/dist/utils/safetensors-meta-guard.d.ts.map +1 -0
  61. package/dist/utils/safetensors-meta-guard.js +50 -0
  62. package/dist/utils/safetensors-meta-guard.js.map +1 -0
  63. package/package.json +3 -1
@@ -0,0 +1,149 @@
1
+ // HuggingFace Hub model-file download + local cache utility.
2
+ // Atomic write: streams to <final>.tmp.<pid>.<seq>, then renames.
3
+ // Cache hit: returns immediately if the final path already exists.
4
+ // Concurrency: concurrent calls for the same finalPath share one download.
5
+ import { mkdir, rename, unlink } from "node:fs/promises";
6
+ import { existsSync, statSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { pumpToFile } from "./hf-download-stream.js";
9
+ export const MAX_DOWNLOAD_BYTES = 500 * 1024 * 1024; // 500 MB
10
+ export const DOWNLOAD_TIMEOUT_MS = 30_000;
11
+ const HF_BASE = "https://huggingface.co";
12
+ // CRITICAL-1 fix: monotonic counter for unique tmp paths within the process
13
+ let tmpSeq = 0;
14
+ // CRITICAL-1 fix: in-process dedup — second concurrent call for same file awaits first
15
+ const inflight = new Map();
16
+ function slugify(modelId) {
17
+ // Injective: percent-encode "%" and "/" so any two distinct modelIds produce distinct slugs.
18
+ // "%" → "%25" first (must come before the "/" encoding), "/" → "%2F".
19
+ // Result is FS-safe on all major platforms and human-readable.
20
+ return modelId.replaceAll("%", "%25").replaceAll("/", "%2F");
21
+ }
22
+ function validateInput(modelId, filename) {
23
+ if (!modelId || !modelId.trim())
24
+ throw new Error("ensureModelFile: modelId must not be empty");
25
+ if (!filename || !filename.trim())
26
+ throw new Error("ensureModelFile: filename must not be empty");
27
+ if (modelId.includes("..") || modelId.startsWith("/"))
28
+ throw new Error(`ensureModelFile: invalid modelId — path traversal rejected: "${modelId}"`);
29
+ if (filename.includes("..") || filename.startsWith("/"))
30
+ throw new Error(`ensureModelFile: invalid filename — path traversal rejected: "${filename}"`);
31
+ // FIX-1: model files are root-level; "/" in filename would silently create un-mkdir'd subpaths
32
+ if (filename.includes("/"))
33
+ throw new Error(`ensureModelFile: invalid filename — must not contain path separators: "${filename}"`);
34
+ }
35
+ /** Returns true when `path` exists AND has size > 0. */
36
+ function isCacheValid(path) {
37
+ if (!existsSync(path))
38
+ return false;
39
+ try {
40
+ return statSync(path).size > 0;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ async function downloadToCache(modelId, filename, cacheDir, opts) {
47
+ validateInput(modelId, filename);
48
+ const slug = slugify(modelId);
49
+ const modelDir = join(cacheDir, slug);
50
+ const finalPath = join(modelDir, filename);
51
+ // FIX-4: cache hit only valid when file is non-empty
52
+ if (isCacheValid(finalPath)) {
53
+ return finalPath;
54
+ }
55
+ await mkdir(modelDir, { recursive: true });
56
+ const url = `${HF_BASE}/${modelId}/resolve/main/${filename}`;
57
+ const timeoutMs = opts?.timeoutMs ?? DOWNLOAD_TIMEOUT_MS;
58
+ const maxBytes = opts?.maxBytes ?? MAX_DOWNLOAD_BYTES;
59
+ const inactivityMs = opts?.inactivityMs;
60
+ // Use a manual AbortController so we can cancel ONLY the connect phase (headers).
61
+ // AbortSignal.timeout() would bound the entire response consumption including body
62
+ // streaming, which breaks large-but-active downloads that take >timeoutMs total.
63
+ // Instead: fire the timer before fetch(), clear it immediately after headers arrive,
64
+ // and rely on pumpToFile's per-chunk inactivity logic for the body phase.
65
+ const ctrl = new AbortController();
66
+ const connectTimer = setTimeout(() => ctrl.abort(new Error(`ensureModelFile: connect timeout after ${timeoutMs}ms — ${url}`)), timeoutMs);
67
+ let response;
68
+ try {
69
+ response = await fetch(url, { signal: ctrl.signal });
70
+ }
71
+ finally {
72
+ // Headers received (or fetch rejected) — connect phase is done, cancel timer.
73
+ clearTimeout(connectTimer);
74
+ }
75
+ if (!response.ok) {
76
+ throw new Error(`ensureModelFile: HTTP ${response.status} ${response.statusText} — failed to download ${url}`);
77
+ }
78
+ // FIX-3: if fetch auto-decompressed the body, content-length reflects the compressed size.
79
+ // In that case, skip both the pre-check and the completeness verification.
80
+ const contentEncoding = response.headers.get("content-encoding");
81
+ const isCompressed = contentEncoding !== null &&
82
+ contentEncoding.toLowerCase() !== "identity";
83
+ // Cap check via content-length header (before reading body)
84
+ const contentLengthHeader = response.headers.get("content-length");
85
+ let contentLength = null;
86
+ if (!isCompressed && contentLengthHeader !== null) {
87
+ const bytes = parseInt(contentLengthHeader, 10);
88
+ if (!isNaN(bytes)) {
89
+ if (bytes > maxBytes) {
90
+ throw new Error(`ensureModelFile: content-length ${bytes} exceeds 500 MB cap (${maxBytes} bytes) for ${url}`);
91
+ }
92
+ contentLength = bytes;
93
+ }
94
+ }
95
+ const body = response.body;
96
+ if (!body)
97
+ throw new Error(`ensureModelFile: response body is null for ${url}`);
98
+ // CRITICAL-1 fix: unique tmp path using pid + monotonic sequence
99
+ const tmpPath = `${finalPath}.tmp.${process.pid}.${++tmpSeq}`;
100
+ try {
101
+ const bytesWritten = await pumpToFile(body, tmpPath, {
102
+ maxBytes,
103
+ expectedLength: contentLength,
104
+ url,
105
+ ...(inactivityMs !== undefined && { inactivityMs }),
106
+ });
107
+ // Model/tokenizer files are never legitimately empty — treat 0-byte result as a
108
+ // download failure so the caller re-downloads rather than caching a useless file.
109
+ if (bytesWritten === 0) {
110
+ throw new Error(`ensureModelFile: empty download (0 bytes) — ${url}`);
111
+ }
112
+ await rename(tmpPath, finalPath);
113
+ }
114
+ catch (err) {
115
+ // Clean up partial / tmp file before rethrowing
116
+ try {
117
+ await unlink(tmpPath);
118
+ }
119
+ catch { /* already gone */ }
120
+ const msg = err instanceof Error ? err.message : String(err);
121
+ if (err instanceof Error && err.message.includes("ensureModelFile:"))
122
+ throw err;
123
+ throw new Error(`ensureModelFile: download failed — ${msg}`, { cause: err });
124
+ }
125
+ return finalPath;
126
+ }
127
+ export async function ensureModelFile(modelId, filename, cacheDir, opts) {
128
+ // Fast-path validation (throws synchronously via rejected promise before map lookup)
129
+ validateInput(modelId, filename);
130
+ const slug = slugify(modelId);
131
+ const modelDir = join(cacheDir, slug);
132
+ const finalPath = join(modelDir, filename);
133
+ // FIX-4: cache hit only valid when file is non-empty
134
+ if (isCacheValid(finalPath)) {
135
+ return finalPath;
136
+ }
137
+ // CRITICAL-1 fix: deduplicate concurrent in-process downloads for the same file
138
+ const existing = inflight.get(finalPath);
139
+ if (existing)
140
+ return existing;
141
+ let promise;
142
+ promise = downloadToCache(modelId, filename, cacheDir, opts).finally(() => {
143
+ if (inflight.get(finalPath) === promise)
144
+ inflight.delete(finalPath);
145
+ });
146
+ inflight.set(finalPath, promise);
147
+ return promise;
148
+ }
149
+ //# sourceMappingURL=hf-hub-download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hf-hub-download.js","sourceRoot":"","sources":["../../src/utils/hf-hub-download.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare const HOST_IS_LE: boolean;
2
+ export interface SafetensorEntry {
3
+ name: string;
4
+ shape: [number, number];
5
+ data: Float32Array;
6
+ }
7
+ export declare function parseSafetensors(buffer: Uint8Array): SafetensorEntry[];
8
+ export declare function getTensor(parsed: SafetensorEntry[], name: string): SafetensorEntry;
9
+ //# sourceMappingURL=safetensors-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safetensors-loader.d.ts","sourceRoot":"","sources":["../../src/utils/safetensors-loader.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,UAAU,SAAuD,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,IAAI,EAAE,YAAY,CAAC;CACpB;AAID,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,eAAe,EAAE,CAoGtE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAIlF"}
@@ -0,0 +1,95 @@
1
+ // Pure, no-I/O safetensors parser.
2
+ // Spec: 8-byte u64-LE header length | JSON header | binary payload
3
+ // Only F32 dtype is supported; shape must be [rows, cols].
4
+ import { isValidMeta } from "./safetensors-meta-guard.js";
5
+ const MAX_HEADER_BYTES = 100 * 1024 * 1024; // 100 MB sanity cap
6
+ const HEADER_PREFIX_BYTES = 8;
7
+ // FINDING-1: safetensors mandates little-endian byte order. Float32Array on a
8
+ // big-endian host would silently mis-read bytes. We detect endianness once at
9
+ // module load and fail fast on BE hosts. The false branch is untestable on LE
10
+ // hosts (reviewer-accepted pattern for platform guards).
11
+ export const HOST_IS_LE = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;
12
+ export function parseSafetensors(buffer) {
13
+ if (!HOST_IS_LE)
14
+ throw new Error("safetensors: big-endian host architectures are not supported");
15
+ if (buffer.byteLength < HEADER_PREFIX_BYTES)
16
+ throw new Error("safetensors: buffer too small to contain header length field");
17
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
18
+ const headerLenBig = view.getBigUint64(0, true);
19
+ if (headerLenBig > BigInt(MAX_HEADER_BYTES))
20
+ throw new Error(`safetensors: header length ${headerLenBig} exceeds sanity cap of ${MAX_HEADER_BYTES} bytes`);
21
+ const headerLen = Number(headerLenBig);
22
+ if (HEADER_PREFIX_BYTES + headerLen > buffer.byteLength)
23
+ throw new Error(`safetensors: header length ${headerLen} exceeds file size (${buffer.byteLength} bytes)`);
24
+ const headerText = new TextDecoder().decode(buffer.subarray(HEADER_PREFIX_BYTES, HEADER_PREFIX_BYTES + headerLen));
25
+ let raw;
26
+ try {
27
+ raw = JSON.parse(headerText);
28
+ }
29
+ catch (err) {
30
+ const msg = err instanceof Error ? err.message : String(err);
31
+ throw new Error(`safetensors: malformed JSON header — parse error: ${msg}`);
32
+ }
33
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
34
+ throw new Error("safetensors: header JSON must be a plain object");
35
+ const payloadStart = HEADER_PREFIX_BYTES + headerLen;
36
+ const spans = [];
37
+ for (const [key, value] of Object.entries(raw)) {
38
+ if (key === "__metadata__")
39
+ continue;
40
+ const meta = isValidMeta(key, value);
41
+ if (meta.dtype !== "F32")
42
+ throw new Error(`safetensors: unsupported dtype "${meta.dtype}" for tensor "${key}" — only F32 is supported`);
43
+ const [rows, cols] = meta.shape;
44
+ const [offsetStart, offsetEnd] = meta.data_offsets;
45
+ // CRITICAL-1: guard rows*cols overflow
46
+ const product = rows * cols;
47
+ if (!Number.isSafeInteger(product))
48
+ throw new Error(`safetensors: tensor "${key}" shape [${rows}, ${cols}] causes shape overflow`);
49
+ // CRITICAL-1: alignment and span/shape consistency
50
+ const byteSpan = offsetEnd - offsetStart;
51
+ if (byteSpan % 4 !== 0)
52
+ throw new Error(`safetensors: tensor "${key}" byte span ${byteSpan} is not aligned to 4 bytes`);
53
+ const elementCount = byteSpan / 4;
54
+ if (elementCount !== product)
55
+ throw new Error(`safetensors: tensor "${key}" span/shape mismatch — span has ${elementCount} F32 elements but shape [${rows}, ${cols}] requires ${product}`);
56
+ const absStart = payloadStart + offsetStart;
57
+ const absEnd = payloadStart + offsetEnd;
58
+ // FINDING-3: absEnd must be a safe integer (guards against offsetStart or
59
+ // offsetEnd near MAX_SAFE_INTEGER causing arithmetic imprecision).
60
+ if (!Number.isSafeInteger(absEnd))
61
+ throw new Error(`safetensors: tensor "${key}" data_offsets produce an absEnd value (${absEnd}) that is not a safe integer`);
62
+ if (absEnd > buffer.byteLength)
63
+ throw new Error(`safetensors: data_offsets [${offsetStart}, ${offsetEnd}] for tensor "${key}" exceed buffer bounds`);
64
+ spans.push({ absStart, absEnd, key, rows, cols, elementCount });
65
+ }
66
+ // FINDING-2: O(N log N) overlap check — sort by start, single linear scan.
67
+ // Zero-length spans (absStart === absEnd) cannot overlap anything; exclude them.
68
+ const nonEmpty = spans.filter((s) => s.absStart < s.absEnd);
69
+ nonEmpty.sort((a, b) => a.absStart - b.absStart);
70
+ for (let i = 1; i < nonEmpty.length; i++) {
71
+ const prev = nonEmpty[i - 1];
72
+ const curr = nonEmpty[i];
73
+ if (curr.absStart < prev.absEnd)
74
+ throw new Error(`safetensors: tensor "${curr.key}" byte range [${curr.absStart}, ${curr.absEnd}) overlapping with tensor "${prev.key}" [${prev.absStart}, ${prev.absEnd})`);
75
+ }
76
+ // Second pass (original order): build entries with zero-copy or fallback.
77
+ const entries = [];
78
+ for (const { absStart, absEnd, key, rows, cols, elementCount } of spans) {
79
+ const byteSpan = absEnd - absStart;
80
+ // WARNING: zero-copy when aligned; slice-copy fallback for misaligned byteOffset
81
+ const byteOffset = buffer.byteOffset + absStart;
82
+ const data = byteOffset % 4 === 0
83
+ ? new Float32Array(buffer.buffer, byteOffset, elementCount)
84
+ : new Float32Array(buffer.buffer.slice(byteOffset, byteOffset + byteSpan));
85
+ entries.push({ name: key, shape: [rows, cols], data });
86
+ }
87
+ return entries;
88
+ }
89
+ export function getTensor(parsed, name) {
90
+ const entry = parsed.find((e) => e.name === name);
91
+ if (!entry)
92
+ throw new Error(`safetensors: tensor "${name}" not found in parsed entries`);
93
+ return entry;
94
+ }
95
+ //# sourceMappingURL=safetensors-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safetensors-loader.js","sourceRoot":"","sources":["../../src/utils/safetensors-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface RawTensorMeta {
2
+ dtype: string;
3
+ shape: number[];
4
+ data_offsets: [number, number];
5
+ }
6
+ export declare function isValidMeta(key: string, value: unknown): RawTensorMeta;
7
+ //# sourceMappingURL=safetensors-meta-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safetensors-meta-guard.d.ts","sourceRoot":"","sources":["../../src/utils/safetensors-meta-guard.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,aAAa,CA8EtE"}
@@ -0,0 +1,50 @@
1
+ // Validation guard for a single safetensors tensor-meta entry.
2
+ // Extracted from safetensors-loader.ts to keep that file ≤100 executable lines.
3
+ export function isValidMeta(key, value) {
4
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
5
+ throw new Error(`safetensors: tensor meta for "${key}" must be a non-null object`);
6
+ }
7
+ const v = value;
8
+ if (typeof v["dtype"] !== "string") {
9
+ throw new Error(`safetensors: tensor "${key}" meta.dtype must be a string`);
10
+ }
11
+ const shape = v["shape"];
12
+ if (!Array.isArray(shape) ||
13
+ shape.length !== 2 ||
14
+ typeof shape[0] !== "number" ||
15
+ typeof shape[1] !== "number") {
16
+ throw new Error(`safetensors: tensor "${key}" meta.shape must be a 2-element array of numbers`);
17
+ }
18
+ // CRITICAL-2: reject NaN, Infinity, and non-integer floats in shape
19
+ if (!Number.isInteger(shape[0]) || shape[0] < 0 || !Number.isInteger(shape[1]) || shape[1] < 0) {
20
+ throw new Error(`safetensors: tensor "${key}" meta.shape must be integers >= 0`);
21
+ }
22
+ const offsets = v["data_offsets"];
23
+ if (!Array.isArray(offsets) ||
24
+ offsets.length !== 2 ||
25
+ typeof offsets[0] !== "number" ||
26
+ typeof offsets[1] !== "number") {
27
+ throw new Error(`safetensors: tensor "${key}" meta.data_offsets must be a 2-element array of numbers`);
28
+ }
29
+ // CRITICAL-2 / FINDING-3: reject NaN, Infinity, non-integer floats, and
30
+ // unsafe integers (> Number.MAX_SAFE_INTEGER) in data_offsets.
31
+ // isSafeInteger subsumes isInteger: it rejects NaN, Infinity, floats, AND
32
+ // values outside ±2^53-1 where integer arithmetic loses precision.
33
+ if (!(Number.isSafeInteger(offsets[0]) && offsets[0] >= 0) ||
34
+ !(Number.isSafeInteger(offsets[1]) && offsets[1] >= 0)) {
35
+ throw new Error(`safetensors: tensor "${key}" meta.data_offsets must be integers >= 0`);
36
+ }
37
+ const [offsetStart, offsetEnd] = offsets;
38
+ if (offsetStart < 0) {
39
+ throw new Error(`safetensors: tensor "${key}" data_offsets[${offsetStart}, ${offsetEnd}]: offsetStart must be >= 0`);
40
+ }
41
+ if (offsetEnd < offsetStart) {
42
+ throw new Error(`safetensors: tensor "${key}" data_offsets[${offsetStart}, ${offsetEnd}]: offsetEnd must be >= offsetStart`);
43
+ }
44
+ return {
45
+ dtype: v["dtype"],
46
+ shape: shape,
47
+ data_offsets: [offsetStart, offsetEnd],
48
+ };
49
+ }
50
+ //# sourceMappingURL=safetensors-meta-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safetensors-meta-guard.js","sourceRoot":"","sources":["../../src/utils/safetensors-meta-guard.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,gFAAgF;AAQhF,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,KAAc;IACrD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CACb,iCAAiC,GAAG,6BAA6B,CAClE,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAG,KAAgC,CAAC;IAE3C,IAAI,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,+BAA+B,CAC3D,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IACzB,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,KAAK,CAAC,MAAM,KAAK,CAAC;QAClB,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ;QAC5B,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,EAC5B,CAAC;QACD,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,mDAAmD,CAC/E,CAAC;IACJ,CAAC;IAED,oEAAoE;IACpE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/F,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,oCAAoC,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC;IAClC,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QACvB,OAAO,CAAC,MAAM,KAAK,CAAC;QACpB,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ;QAC9B,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ,EAC9B,CAAC;QACD,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,0DAA0D,CACtF,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,+DAA+D;IAC/D,0EAA0E;IAC1E,mEAAmE;IACnE,IACE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAK,OAAO,CAAC,CAAC,CAAY,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAK,OAAO,CAAC,CAAC,CAAY,IAAI,CAAC,CAAC,EAClE,CAAC;QACD,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,2CAA2C,CACvE,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG,OAA2B,CAAC;IAE7D,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,kBAAkB,WAAW,KAAK,SAAS,6BAA6B,CACpG,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,GAAG,WAAW,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,kBAAkB,WAAW,KAAK,SAAS,qCAAqC,CAC5G,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,OAAO,CAAW;QAC3B,KAAK,EAAE,KAAiB;QACxB,YAAY,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;KACvC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codesift-mcp",
3
- "version": "0.8.10",
3
+ "version": "0.8.11",
4
4
  "description": "MCP server for code intelligence — 146 tools for symbol search, call graph, semantic search, route tracing, community detection, LSP bridge, secret detection, conversation search, and Hono framework intelligence",
5
5
  "license": "BSL-1.1",
6
6
  "author": "Greg Laskowski",
@@ -48,11 +48,13 @@
48
48
  "@anthropic-ai/sdk": "^0.70.0",
49
49
  "@huggingface/transformers": "^3.0.0",
50
50
  "openai": "^6.0.0",
51
+ "pg": "^8.12.0",
51
52
  "voyageai": "^0.2.1",
52
53
  "yaml": "^2.7.0"
53
54
  },
54
55
  "devDependencies": {
55
56
  "@types/node": "^22.0.0",
57
+ "@types/pg": "^8.11.0",
56
58
  "@types/picomatch": "^4.0.2",
57
59
  "@vitest/coverage-v8": "^3.0.0",
58
60
  "ajv": "^8.18.0",