seekstone 0.15.0 → 0.15.2

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/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "seekstone",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "mcpName": "io.github.shaqmughal/seekstone",
5
5
  "type": "module",
6
- "description": "The Obsidian MCP server that needs no plugin, no running Obsidian app — and doesn't blow your context window. Filesystem-direct: single-digit-ms search, ~2 KB payloads, 19 tools.",
6
+ "description": "The Obsidian MCP server that needs no plugin, no running Obsidian app — and doesn't blow your context window. Filesystem-direct: single-digit-ms keyword search, ~14 ms local semantic search, ~2 KB payloads, 19 tools.",
7
7
  "keywords": [
8
8
  "obsidian",
9
9
  "obsidian-mcp",
@@ -1,18 +0,0 @@
1
- // src/semantic/config.ts
2
- import { join } from "path";
3
- var DEFAULT_MODEL_ID = "potion-base-8M";
4
- function defaultCacheDir(env, homedir) {
5
- return env.SEEKSTONE_CACHE_DIR || join(homedir, ".cache", "seekstone");
6
- }
7
- function resolveSemanticConfig(env, homedir) {
8
- if (env.SEEKSTONE_SEMANTIC !== "1") return void 0;
9
- const cacheDir = defaultCacheDir(env, homedir);
10
- const modelDir = env.SEEKSTONE_MODEL_PATH || join(cacheDir, "models", DEFAULT_MODEL_ID);
11
- return { modelDir, cacheDir };
12
- }
13
-
14
- export {
15
- defaultCacheDir,
16
- resolveSemanticConfig
17
- };
18
- //# sourceMappingURL=chunk-RRLYVK2X.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/semantic/config.ts"],"sourcesContent":["import { join } from 'node:path';\n\n/**\n * Semantic-search configuration, resolved from env at boot.\n *\n * - `SEEKSTONE_SEMANTIC=1` enables the feature (off by default).\n * - `SEEKSTONE_MODEL_PATH` overrides where the Model2Vec model dir lives;\n * default is `<cache>/models/potion-base-8M`, where `seekstone fetch-model`\n * puts it.\n * - `SEEKSTONE_CACHE_DIR` overrides the cache root (default `~/.cache/seekstone`),\n * which holds both downloaded models and per-vault embedding caches.\n *\n * The server itself NEVER downloads anything — the model is fetched\n * out-of-band by the `fetch-model` subcommand, preserving the zero-network\n * guarantee (no-network.test.ts).\n */\n\nexport const DEFAULT_MODEL_ID = 'potion-base-8M';\n\nexport interface SemanticConfig {\n modelDir: string;\n cacheDir: string;\n}\n\nexport function defaultCacheDir(env: NodeJS.ProcessEnv, homedir: string): string {\n return env.SEEKSTONE_CACHE_DIR || join(homedir, '.cache', 'seekstone');\n}\n\nexport function resolveSemanticConfig(\n env: NodeJS.ProcessEnv,\n homedir: string,\n): SemanticConfig | undefined {\n if (env.SEEKSTONE_SEMANTIC !== '1') return undefined;\n const cacheDir = defaultCacheDir(env, homedir);\n const modelDir = env.SEEKSTONE_MODEL_PATH || join(cacheDir, 'models', DEFAULT_MODEL_ID);\n return { modelDir, cacheDir };\n}\n"],"mappings":";AAAA,SAAS,YAAY;AAiBd,IAAM,mBAAmB;AAOzB,SAAS,gBAAgB,KAAwB,SAAyB;AAC/E,SAAO,IAAI,uBAAuB,KAAK,SAAS,UAAU,WAAW;AACvE;AAEO,SAAS,sBACd,KACA,SAC4B;AAC5B,MAAI,IAAI,uBAAuB,IAAK,QAAO;AAC3C,QAAM,WAAW,gBAAgB,KAAK,OAAO;AAC7C,QAAM,WAAW,IAAI,wBAAwB,KAAK,UAAU,UAAU,gBAAgB;AACtF,SAAO,EAAE,UAAU,SAAS;AAC9B;","names":[]}
@@ -1,81 +0,0 @@
1
- import {
2
- defaultCacheDir
3
- } from "./chunk-RRLYVK2X.js";
4
-
5
- // src/semantic/fetch-model.ts
6
- import { createHash } from "crypto";
7
- import { existsSync } from "fs";
8
- import { mkdir, readFile, writeFile } from "fs/promises";
9
- import { join } from "path";
10
-
11
- // src/semantic/model-manifest.ts
12
- var DEFAULT_MODEL = {
13
- id: "potion-base-8M",
14
- license: "MIT (https://huggingface.co/minishlab/potion-base-8M)",
15
- files: [
16
- {
17
- name: "model.safetensors",
18
- url: "https://huggingface.co/minishlab/potion-base-8M/resolve/main/model.safetensors",
19
- sha256: "f65d0f325faadc1e121c319e2faa41170d3fa07d8c89abd48ca5358d9a223de2",
20
- bytes: 30236760
21
- },
22
- {
23
- name: "tokenizer.json",
24
- url: "https://huggingface.co/minishlab/potion-base-8M/resolve/main/tokenizer.json",
25
- sha256: "e67e803f624fb4d67dea1c730d06e1067e1b14d830e2c2202569e3ef0f70bb50",
26
- bytes: 683666
27
- },
28
- {
29
- name: "config.json",
30
- url: "https://huggingface.co/minishlab/potion-base-8M/resolve/main/config.json",
31
- sha256: "2a6ac0e9aaa356a68a5688070db78fc3a464fefe85d2f06a1905ce3718687553",
32
- bytes: 202
33
- }
34
- ]
35
- };
36
-
37
- // src/semantic/fetch-model.ts
38
- async function runFetchModel(deps) {
39
- const manifest = deps.manifest ?? DEFAULT_MODEL;
40
- const fetchFn = deps.fetchFn ?? fetch;
41
- const destDir = deps.env.SEEKSTONE_MODEL_PATH || join(defaultCacheDir(deps.env, deps.homedir), "models", manifest.id);
42
- const output = [];
43
- output.push(`fetch-model: ${manifest.id} \u2192 ${destDir}`);
44
- try {
45
- await mkdir(destDir, { recursive: true });
46
- let fetched = 0;
47
- let skipped = 0;
48
- for (const file of manifest.files) {
49
- const dest = join(destDir, file.name);
50
- if (existsSync(dest) && sha256(await readFile(dest)) === file.sha256) {
51
- skipped++;
52
- continue;
53
- }
54
- output.push(`fetching ${file.name} (${file.bytes} bytes)\u2026`);
55
- const res = await fetchFn(file.url);
56
- if (!res.ok) throw new Error(`fetch ${file.url} failed: ${res.status}`);
57
- const buf = Buffer.from(await res.arrayBuffer());
58
- const got = sha256(buf);
59
- if (got !== file.sha256) {
60
- throw new Error(`checksum mismatch for ${file.name}: expected ${file.sha256}, got ${got}`);
61
- }
62
- await writeFile(dest, buf);
63
- fetched++;
64
- }
65
- output.push(`\u2713 ${manifest.id}: ${fetched} fetched, ${skipped} already present (verified).`);
66
- output.push(
67
- "Enable semantic search with SEEKSTONE_SEMANTIC=1 in your MCP server config, then restart the session."
68
- );
69
- return { output, exitCode: 0 };
70
- } catch (err) {
71
- output.push(`\u2717 ${err instanceof Error ? err.message : String(err)}`);
72
- return { output, exitCode: 1 };
73
- }
74
- }
75
- function sha256(buf) {
76
- return createHash("sha256").update(buf).digest("hex");
77
- }
78
- export {
79
- runFetchModel
80
- };
81
- //# sourceMappingURL=fetch-model-7TGOJMZL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/semantic/fetch-model.ts","../src/semantic/model-manifest.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { defaultCacheDir } from './config.js';\nimport { DEFAULT_MODEL, type ModelManifest } from './model-manifest.js';\n\n/**\n * `seekstone fetch-model` — the explicit, out-of-band download of the\n * embedding model that semantic search needs. This is a CLI subcommand that\n * exits before any MCP serving starts; the running server never fetches\n * (no-network.test.ts is the guarantee). Files are verified against pinned\n * SHA-256 hashes; already-present matching files are skipped.\n */\n\nexport interface FetchModelResult {\n output: string[];\n exitCode: number;\n}\n\nexport interface FetchModelDeps {\n env: NodeJS.ProcessEnv;\n homedir: string;\n manifest?: ModelManifest;\n fetchFn?: typeof fetch;\n}\n\nexport async function runFetchModel(deps: FetchModelDeps): Promise<FetchModelResult> {\n const manifest = deps.manifest ?? DEFAULT_MODEL;\n const fetchFn = deps.fetchFn ?? fetch;\n const destDir =\n deps.env.SEEKSTONE_MODEL_PATH ||\n join(defaultCacheDir(deps.env, deps.homedir), 'models', manifest.id);\n const output: string[] = [];\n output.push(`fetch-model: ${manifest.id} → ${destDir}`);\n try {\n await mkdir(destDir, { recursive: true });\n let fetched = 0;\n let skipped = 0;\n for (const file of manifest.files) {\n const dest = join(destDir, file.name);\n if (existsSync(dest) && sha256(await readFile(dest)) === file.sha256) {\n skipped++;\n continue;\n }\n output.push(`fetching ${file.name} (${file.bytes} bytes)…`);\n const res = await fetchFn(file.url);\n if (!res.ok) throw new Error(`fetch ${file.url} failed: ${res.status}`);\n const buf = Buffer.from(await res.arrayBuffer());\n const got = sha256(buf);\n if (got !== file.sha256) {\n throw new Error(`checksum mismatch for ${file.name}: expected ${file.sha256}, got ${got}`);\n }\n await writeFile(dest, buf);\n fetched++;\n }\n output.push(`✓ ${manifest.id}: ${fetched} fetched, ${skipped} already present (verified).`);\n output.push(\n 'Enable semantic search with SEEKSTONE_SEMANTIC=1 in your MCP server config, then restart the session.',\n );\n return { output, exitCode: 0 };\n } catch (err) {\n output.push(`✗ ${err instanceof Error ? err.message : String(err)}`);\n return { output, exitCode: 1 };\n }\n}\n\nfunction sha256(buf: Buffer): string {\n return createHash('sha256').update(buf).digest('hex');\n}\n","/**\n * Pinned download manifest for the default embedding model. Used ONLY by the\n * `seekstone fetch-model` subcommand — an explicit, out-of-band CLI action.\n * The MCP server itself never touches the network (no-network.test.ts).\n *\n * Hashes mirror packages/harness/fixtures/models/manifest.json (the harness\n * evals run against the same files).\n */\n\nexport interface ModelFile {\n name: string;\n url: string;\n sha256: string;\n bytes: number;\n}\n\nexport interface ModelManifest {\n id: string;\n license: string;\n files: ModelFile[];\n}\n\nexport const DEFAULT_MODEL: ModelManifest = {\n id: 'potion-base-8M',\n license: 'MIT (https://huggingface.co/minishlab/potion-base-8M)',\n files: [\n {\n name: 'model.safetensors',\n url: 'https://huggingface.co/minishlab/potion-base-8M/resolve/main/model.safetensors',\n sha256: 'f65d0f325faadc1e121c319e2faa41170d3fa07d8c89abd48ca5358d9a223de2',\n bytes: 30236760,\n },\n {\n name: 'tokenizer.json',\n url: 'https://huggingface.co/minishlab/potion-base-8M/resolve/main/tokenizer.json',\n sha256: 'e67e803f624fb4d67dea1c730d06e1067e1b14d830e2c2202569e3ef0f70bb50',\n bytes: 683666,\n },\n {\n name: 'config.json',\n url: 'https://huggingface.co/minishlab/potion-base-8M/resolve/main/config.json',\n sha256: '2a6ac0e9aaa356a68a5688070db78fc3a464fefe85d2f06a1905ce3718687553',\n bytes: 202,\n },\n ],\n};\n"],"mappings":";;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,OAAO,UAAU,iBAAiB;AAC3C,SAAS,YAAY;;;ACmBd,IAAM,gBAA+B;AAAA,EAC1C,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;ADlBA,eAAsB,cAAc,MAAiD;AACnF,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,UACJ,KAAK,IAAI,wBACT,KAAK,gBAAgB,KAAK,KAAK,KAAK,OAAO,GAAG,UAAU,SAAS,EAAE;AACrE,QAAM,SAAmB,CAAC;AAC1B,SAAO,KAAK,gBAAgB,SAAS,EAAE,WAAM,OAAO,EAAE;AACtD,MAAI;AACF,UAAM,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AACxC,QAAI,UAAU;AACd,QAAI,UAAU;AACd,eAAW,QAAQ,SAAS,OAAO;AACjC,YAAM,OAAO,KAAK,SAAS,KAAK,IAAI;AACpC,UAAI,WAAW,IAAI,KAAK,OAAO,MAAM,SAAS,IAAI,CAAC,MAAM,KAAK,QAAQ;AACpE;AACA;AAAA,MACF;AACA,aAAO,KAAK,YAAY,KAAK,IAAI,KAAK,KAAK,KAAK,eAAU;AAC1D,YAAM,MAAM,MAAM,QAAQ,KAAK,GAAG;AAClC,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,SAAS,KAAK,GAAG,YAAY,IAAI,MAAM,EAAE;AACtE,YAAM,MAAM,OAAO,KAAK,MAAM,IAAI,YAAY,CAAC;AAC/C,YAAM,MAAM,OAAO,GAAG;AACtB,UAAI,QAAQ,KAAK,QAAQ;AACvB,cAAM,IAAI,MAAM,yBAAyB,KAAK,IAAI,cAAc,KAAK,MAAM,SAAS,GAAG,EAAE;AAAA,MAC3F;AACA,YAAM,UAAU,MAAM,GAAG;AACzB;AAAA,IACF;AACA,WAAO,KAAK,UAAK,SAAS,EAAE,KAAK,OAAO,aAAa,OAAO,8BAA8B;AAC1F,WAAO;AAAA,MACL;AAAA,IACF;AACA,WAAO,EAAE,QAAQ,UAAU,EAAE;AAAA,EAC/B,SAAS,KAAK;AACZ,WAAO,KAAK,UAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AACnE,WAAO,EAAE,QAAQ,UAAU,EAAE;AAAA,EAC/B;AACF;AAEA,SAAS,OAAO,KAAqB;AACnC,SAAO,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,KAAK;AACtD;","names":[]}