@theglitchking/semantic-pages 0.5.0 → 0.6.1

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.
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "semantic-pages-marketplace",
3
+ "owner": {
4
+ "name": "TheGlitchKing",
5
+ "email": "theglitchking@users.noreply.github.com"
6
+ },
7
+ "metadata": {
8
+ "description": "Official marketplace for semantic-pages - Semantic search + knowledge graph MCP server with auto-wiring for .claude/.vault and hit-em-with-the-docs companion",
9
+ "version": "0.6.1"
10
+ },
11
+ "plugins": [
12
+ {
13
+ "name": "semantic-pages",
14
+ "description": "Semantic search + knowledge graph MCP server for markdown vaults. Auto-wires a read/write vault at .claude/.vault, and a read-only docs index at .documentation when hit-em-with-the-docs is also installed.",
15
+ "version": "0.6.1",
16
+ "author": {
17
+ "name": "TheGlitchKing"
18
+ },
19
+ "homepage": "https://github.com/TheGlitchKing/semantic-pages",
20
+ "repository": "https://github.com/TheGlitchKing/semantic-pages.git",
21
+ "license": "MIT",
22
+ "keywords": [
23
+ "mcp",
24
+ "semantic-search",
25
+ "knowledge-graph",
26
+ "markdown",
27
+ "vector-search",
28
+ "embeddings",
29
+ "wikilinks",
30
+ "vault",
31
+ "claude-code"
32
+ ],
33
+ "category": "search",
34
+ "tags": [
35
+ "mcp-server",
36
+ "semantic-search",
37
+ "knowledge-graph",
38
+ "auto-wire"
39
+ ],
40
+ "source": {
41
+ "source": "npm",
42
+ "package": "@theglitchking/semantic-pages"
43
+ },
44
+ "strict": true
45
+ }
46
+ ]
47
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "semantic-pages",
3
+ "description": "Semantic search + knowledge graph MCP server for markdown vaults. Auto-wires a read/write vault at .claude/.vault, and a read-only docs index at .documentation when hit-em-with-the-docs is also installed.",
4
+ "version": "0.6.1",
5
+ "author": {
6
+ "name": "TheGlitchKing",
7
+ "email": "theglitchking@users.noreply.github.com"
8
+ },
9
+ "license": "MIT",
10
+ "homepage": "https://github.com/TheGlitchKing/semantic-pages",
11
+ "repository": "https://github.com/TheGlitchKing/semantic-pages",
12
+ "keywords": [
13
+ "mcp",
14
+ "semantic-search",
15
+ "knowledge-graph",
16
+ "markdown",
17
+ "vector-search",
18
+ "embeddings",
19
+ "wikilinks",
20
+ "vault"
21
+ ]
22
+ }
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -39,6 +39,48 @@ The index is stored in `.semantic-pages-index/` alongside your notes (gitignore
39
39
  - **File Watcher**: Incremental re-indexing on file changes with debounce
40
40
  - **Local Embeddings**: No API key, no network after first model download
41
41
  - **Zero Dependencies Beyond Node**: No Docker, no Python, no Obsidian, no GUI
42
+ - **Auto-Wire**: Installing the Claude Code plugin auto-creates `./.claude/.vault/` and wires it as a read/write MCP server — no manual `.mcp.json` editing required
43
+ - **Sister Plugin Companion**: When [`hit-em-with-the-docs`](https://github.com/TheGlitchKing/hit-em-with-the-docs) is also installed, a second **read-only** MCP server is auto-wired at `./.documentation/` so you can semantically search your docs without risking accidental writes to a tree that hewtd owns
44
+
45
+ ---
46
+
47
+ ## Sister Plugin: hit-em-with-the-docs
48
+
49
+ [`hit-em-with-the-docs`](https://github.com/TheGlitchKing/hit-em-with-the-docs) is the **canonical writer** of `./.documentation/`. It scaffolds, classifies, maintains, and validates docs across 15 domains with a 22-field metadata schema. Semantic Pages is the **canonical reader** — when both plugins are installed, Semantic Pages auto-wires a read-only index of `./.documentation/` so Claude can search it, traverse its wikilinks, and list/read docs without any write primitives exposed. That split keeps hewtd the sole authority for writes while giving you semantic discovery over the result.
50
+
51
+ ### The matrix
52
+
53
+ | `semantic-pages` installed | `hit-em-with-the-docs` installed | Result |
54
+ |---|---|---|
55
+ | ✗ | ✗ | nothing |
56
+ | ✗ | ✓ | hewtd CLI only; `.documentation/` managed but not indexed |
57
+ | ✓ | ✗ | single MCP at `./.claude/.vault` (read/write, auto-created) |
58
+ | ✓ | ✓ | `./.claude/.vault` (read/write) **+** `./.documentation` (read-only) |
59
+
60
+ ### How the auto-wire works
61
+
62
+ Semantic Pages ships a `SessionStart` hook that runs at the start of every Claude Code session and reconciles the project's `.mcp.json`:
63
+
64
+ 1. Always ensures `./.claude/.vault/` exists (creates if missing)
65
+ 2. Always ensures a `semantic-vault` MCP entry pointed at `./.claude/.vault` (read/write — your personal research notes, session artifacts, scratch graph)
66
+ 3. If `hit-em-with-the-docs` is in your enabled plugins **and** `./.documentation/` exists in the current project → adds a `semantic-pages` MCP entry pointed at `./.documentation` with `--read-only` (the 7 write tools are suppressed at the MCP tool list level)
67
+ 4. If either condition stops being true → idempotently removes the `semantic-pages` entry (self-healing when you uninstall hewtd or the docs tree goes away)
68
+
69
+ The hook is a no-op when the computed `.mcp.json` matches what's already on disk, so there's no git churn from repeated session starts. It only touches its own entries — any custom MCP servers you've added (playwright, custom tools, etc.) are left untouched. If you've manually defined a `semantic-pages` entry pointing at a non-`.documentation` path, the hook respects it and leaves it alone.
70
+
71
+ ### Why read-only for `.documentation/`
72
+
73
+ `./.documentation/` is a **managed tree** — hewtd owns the lifecycle (creates files, classifies them, maintains frontmatter, prunes stale entries, checks links). If Semantic Pages also exposed `create_note`, `update_note`, `delete_note`, `move_note`, `update_frontmatter`, `manage_tags`, and `rename_tag` over that tree, you'd have two writers racing over the same schema and hewtd couldn't guarantee its invariants. Read-only gives you semantic discovery without that risk. Your personal `.claude/.vault/` stays fully read/write — hewtd doesn't touch it, so Semantic Pages is the sole writer there and all 21 tools are available.
74
+
75
+ ### The `--read-only` flag
76
+
77
+ The auto-wire uses a new `--read-only` CLI flag (v0.6.0+) that filters out the 7 write tools from the MCP server's tool list at startup. You can use it manually anywhere:
78
+
79
+ ```bash
80
+ semantic-pages --notes ./any-shared-vault --read-only
81
+ ```
82
+
83
+ Only the 14 read tools are exposed (`search_*`, `read_note`, `read_multiple_notes`, `list_notes`, `backlinks`, `forwardlinks`, `graph_path`, `graph_statistics`, `get_frontmatter`, `get_stats`, `reindex`).
42
84
 
43
85
  ---
44
86
 
@@ -120,6 +162,24 @@ npm install --save-dev @theglitchking/semantic-pages
120
162
  }
121
163
  ```
122
164
 
165
+ #### Method E: Claude Code Plugin (Recommended — zero config, auto-wires)
166
+
167
+ This is the easiest path if you use Claude Code and want `.claude/.vault/` + (optionally) `.documentation/` indexed automatically.
168
+
169
+ ```bash
170
+ # Inside a Claude Code session:
171
+ /plugin marketplace add TheGlitchKing/semantic-pages
172
+ /plugin install semantic-pages@semantic-pages-marketplace
173
+ ```
174
+
175
+ What happens next session:
176
+ 1. A `SessionStart` hook runs and ensures `./.claude/.vault/` exists
177
+ 2. Your project's `.mcp.json` gets a `semantic-vault` entry pointed at `./.claude/.vault` (read/write)
178
+ 3. **If** `hit-em-with-the-docs` is also installed **and** `./.documentation/` exists → a second `semantic-pages` entry is added, pointed at `./.documentation` with `--read-only`
179
+ 4. You get 21 tools (14 if the docs server is the one being used) for semantic search, graph traversal, and (for the vault) note CRUD
180
+
181
+ No manual `.mcp.json` editing. Uninstalling the plugin cleanly leaves your existing entries alone on the next session.
182
+
123
183
  ---
124
184
 
125
185
  ### 2. How to Use
@@ -401,31 +461,13 @@ The deployment guide links to the microservices overview, which links to the use
401
461
  semantic-pages --notes ./vault --stats
402
462
  ```
403
463
 
404
- ### Adding Semantic Pages to a Project (30 seconds)
405
- ```bash
406
- # Auto-detects hit-em-with-the-docs and configures one or two vaults
407
- npx @theglitchking/semantic-pages@latest init
408
-
409
- # Then start Claude — it now has 21 (or 42) note tools
410
- claude
411
- ```
412
-
413
- **What `init` does**:
414
- - Detects [hit-em-with-the-docs](https://github.com/TheGlitchKing/hit-em-with-the-docs) by checking for `.documentation/INDEX.md`, `.hewtd.json`, or the `hewtd` binary
415
- - **If detected** → configures two vaults: `semantic-pages → .documentation/` (project docs, search-only) and `semantic-vault → .claude/.vault/` (research notes, read+write). Creates `.claude/.vault/` if absent.
416
- - **If not detected** → configures a single vault: `semantic-pages → ./vault/` (or `--notes <path>` override). Creates the directory if absent.
417
- - Merges into existing `.mcp.json` without clobbering other servers (playwright, etc.)
418
- - Adds index directories to `.gitignore`
419
-
420
- **Manual setup (if preferred)**:
464
+ ### Adding Semantic Pages to a Project (2 minutes)
421
465
  ```bash
422
466
  # Step 1: Create .mcp.json in your project root
423
467
  echo '{
424
- "mcpServers": {
425
- "semantic-pages": {
426
- "command": "npx",
427
- "args": ["-y", "@theglitchking/semantic-pages@latest", "--notes", "./notes"]
428
- }
468
+ "semantic-pages": {
469
+ "command": "npx",
470
+ "args": ["-y", "semantic-pages", "--notes", "./notes"]
429
471
  }
430
472
  }' > .mcp.json
431
473
 
@@ -533,7 +575,7 @@ src/
533
575
 
534
576
  **Frontmatter is optional.** Every note gets a modification timestamp regardless — resolved from frontmatter date fields if present, otherwise from the file's `fs.stat` mtime. When frontmatter fields like `status`, `tier`, `domains`, `load_priority`, or `purpose` are present, they're indexed and exposed through all search tools as filters and score boosters. Plain notes with no frontmatter work exactly as before.
535
577
 
536
- If you want structured frontmatter with a full schema (22 fields, 15 domains, health scoring), [**hit-em-with-the-docs**](https://github.com/TheGlitchKing/hit-em-with-the-docs) is a companion tool that manages docs for Claude Code projects its schema is natively understood by Semantic Pages.
578
+ If you want structured frontmatter with a full schema (22 fields, 15 domains, health scoring), [**hit-em-with-the-docs**](https://github.com/TheGlitchKing/hit-em-with-the-docs) is Semantic Pages' **sister plugin** (see [Sister Plugin: hit-em-with-the-docs](#sister-plugin-hit-em-with-the-docs) above). It manages `./.documentation/` as a writer-owned tree; Semantic Pages auto-wires a read-only index of it when both plugins are installed. All hewtd frontmatter fields are natively understood by the indexer.
537
579
 
538
580
  #### Step 2: Chunk
539
581
  ```
File without changes
package/dist/cli/index.js CHANGED
@@ -2,9 +2,8 @@
2
2
 
3
3
  // src/cli/index.ts
4
4
  import { program } from "commander";
5
- import { resolve, join } from "path";
6
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
7
- import { spawnSync } from "child_process";
5
+ import { resolve } from "path";
6
+ import { existsSync } from "fs";
8
7
  var TOOL_HELP = {
9
8
  // Search
10
9
  search_semantic: {
@@ -199,8 +198,8 @@ function printToolDetail(name) {
199
198
  console.log();
200
199
  }
201
200
  program.name("semantic-pages").description(
202
- "Semantic search + knowledge graph MCP server for markdown files\n\n Auto-configure: semantic-pages init\n Start MCP server: semantic-pages --notes ./vault\n Show vault stats: semantic-pages --notes ./vault --stats\n Force reindex: semantic-pages --notes ./vault --reindex\n List MCP tools: semantic-pages tools\n Tool details: semantic-pages tools search_semantic"
203
- ).version("0.5.0");
201
+ "Semantic search + knowledge graph MCP server for markdown files\n\n Start MCP server: semantic-pages --notes ./vault\n Show vault stats: semantic-pages --notes ./vault --stats\n Force reindex: semantic-pages --notes ./vault --reindex\n List MCP tools: semantic-pages tools\n Tool details: semantic-pages tools search_semantic"
202
+ ).version("0.4.3");
204
203
  program.command("tools [name]").description("List all MCP tools, or show details for a specific tool").action((name) => {
205
204
  if (name) {
206
205
  printToolDetail(name);
@@ -209,7 +208,7 @@ program.command("tools [name]").description("List all MCP tools, or show details
209
208
  }
210
209
  process.exit(0);
211
210
  });
212
- program.command("serve", { isDefault: true }).description("Start the MCP server (default command)").requiredOption("--notes <path>", "Path to markdown notes directory").option("--reindex", "Force full reindex and exit").option("--stats", "Show vault statistics and exit").option("--model <name>", "Embedding model to use (default: all-MiniLM-L6-v2, fast; use nomic-ai/nomic-embed-text-v1.5 for higher quality)").option("--workers <n>", "Number of worker threads for parallel embedding", parseInt).option("--batch-size <n>", "Texts per ONNX forward pass (default: 8)", parseInt).option("--no-quantized", "Use full-precision model instead of quantized (slower, slightly higher quality)").option("--no-watch", "Disable file watcher").action(async (opts) => {
211
+ program.command("serve", { isDefault: true }).description("Start the MCP server (default command)").requiredOption("--notes <path>", "Path to markdown notes directory").option("--reindex", "Force full reindex and exit").option("--stats", "Show vault statistics and exit").option("--read-only", "Suppress write tools (create_note, update_note, delete_note, move_note, update_frontmatter, manage_tags, rename_tag) \u2014 use for shared docs vaults owned by another tool").option("--model <name>", "Embedding model to use (default: all-MiniLM-L6-v2, fast; use nomic-ai/nomic-embed-text-v1.5 for higher quality)").option("--workers <n>", "Number of worker threads for parallel embedding", parseInt).option("--batch-size <n>", "Texts per ONNX forward pass (default: 8)", parseInt).option("--no-quantized", "Use full-precision model instead of quantized (slower, slightly higher quality)").option("--no-watch", "Disable file watcher").action(async (opts) => {
213
212
  const notesPath = resolve(opts.notes);
214
213
  if (!existsSync(notesPath)) {
215
214
  console.error(`Error: notes directory not found: ${notesPath}`);
@@ -243,100 +242,14 @@ program.command("serve", { isDefault: true }).description("Start the MCP server
243
242
  process.exit(0);
244
243
  }
245
244
  const { startServer } = await import("../mcp/server.js");
246
- await startServer(notesPath, { watch: opts.watch, model: opts.model, workers: opts.workers, batchSize: opts.batchSize, quantized: opts.quantized });
247
- });
248
- function detectHewtd(cwd) {
249
- if (existsSync(join(cwd, ".documentation", "INDEX.md"))) return true;
250
- if (existsSync(join(cwd, ".hewtd.json"))) return true;
251
- try {
252
- const r = spawnSync("hewtd", ["--version"], { stdio: "ignore" });
253
- if (r.status === 0) return true;
254
- } catch {
255
- }
256
- return false;
257
- }
258
- function readMcpJson(cwd) {
259
- const mcpPath = join(cwd, ".mcp.json");
260
- if (!existsSync(mcpPath)) return {};
261
- try {
262
- return JSON.parse(readFileSync(mcpPath, "utf8"));
263
- } catch {
264
- console.warn(" \u26A0 Could not parse existing .mcp.json \u2014 will merge carefully.");
265
- return {};
266
- }
267
- }
268
- function writeMcpJson(cwd, config) {
269
- writeFileSync(join(cwd, ".mcp.json"), JSON.stringify(config, null, 2) + "\n", "utf8");
270
- }
271
- function ensureGitignore(cwd, entry) {
272
- const gitignorePath = join(cwd, ".gitignore");
273
- if (existsSync(gitignorePath)) {
274
- const content = readFileSync(gitignorePath, "utf8");
275
- if (!content.includes(entry)) {
276
- writeFileSync(gitignorePath, content.trimEnd() + "\n" + entry + "\n", "utf8");
277
- }
278
- } else {
279
- writeFileSync(gitignorePath, entry + "\n", "utf8");
280
- }
281
- }
282
- function mcpEntry(notesPath) {
283
- return {
284
- type: "stdio",
285
- command: "npx",
286
- args: ["-y", "@theglitchking/semantic-pages@latest", "--notes", notesPath]
287
- };
288
- }
289
- program.command("init").description(
290
- "Auto-configure MCP servers for this project.\nDetects hit-em-with-the-docs and sets up one or two vaults accordingly."
291
- ).option("--notes <path>", "Custom notes path (single-vault fallback only)").option("--cwd <path>", "Project root to configure (default: current directory)").action((opts) => {
292
- const cwd = resolve(opts.cwd || process.cwd());
293
- const hewtd = detectHewtd(cwd);
294
- console.log("\nSemantic Pages \u2014 init\n");
295
- console.log(` Project root : ${cwd}`);
296
- console.log(` hit-em-with-the-docs : ${hewtd ? "\u2705 detected" : "not found"}
297
- `);
298
- const existing = readMcpJson(cwd);
299
- const servers = existing.mcpServers ?? {};
300
- const notesPath = opts.notes || "./vault";
301
- if (hewtd) {
302
- servers["semantic-pages"] = mcpEntry("./.documentation");
303
- servers["semantic-vault"] = mcpEntry("./.claude/.vault");
304
- const vaultDir = join(cwd, ".claude", ".vault");
305
- if (!existsSync(vaultDir)) {
306
- mkdirSync(vaultDir, { recursive: true });
307
- writeFileSync(join(vaultDir, ".gitkeep"), "", "utf8");
308
- console.log(" Created .claude/.vault/");
309
- }
310
- ensureGitignore(cwd, ".documentation/.semantic-pages-index/");
311
- ensureGitignore(cwd, ".claude/.vault/.semantic-pages-index/");
312
- console.log(" Configured semantic-pages \u2192 .documentation/ (project docs, read-only)");
313
- console.log(" Configured semantic-vault \u2192 .claude/.vault/ (research notes, read+write)");
314
- } else {
315
- servers["semantic-pages"] = mcpEntry(notesPath);
316
- const vaultDir = resolve(cwd, notesPath);
317
- if (!existsSync(vaultDir)) {
318
- mkdirSync(vaultDir, { recursive: true });
319
- console.log(` Created ${notesPath}/`);
320
- }
321
- ensureGitignore(cwd, ".semantic-pages-index/");
322
- console.log(` Configured semantic-pages \u2192 ${notesPath}/`);
323
- }
324
- writeMcpJson(cwd, { ...existing, mcpServers: servers });
325
- console.log(" Updated .mcp.json");
326
- console.log(" Updated .gitignore\n");
327
- if (hewtd) {
328
- console.log(" Next steps:");
329
- console.log(" \u2022 Restart Claude \u2014 it will have 42 MCP tools across two vaults");
330
- console.log(" \u2022 Search docs : mcp__semantic-pages__search_hybrid");
331
- console.log(" \u2022 Save research : mcp__semantic-vault__create_note\n");
332
- } else {
333
- console.log(" Next steps:");
334
- console.log(" \u2022 Drop .md files into the vault directory");
335
- console.log(` \u2022 Restart Claude \u2014 it will have 21 MCP tools over ${notesPath}/
336
- `);
337
- console.log(" Tip: install hit-em-with-the-docs for the two-vault setup:");
338
- console.log(" npx @theglitchking/hit-em-with-the-docs init\n");
339
- }
245
+ await startServer(notesPath, {
246
+ watch: opts.watch,
247
+ model: opts.model,
248
+ workers: opts.workers,
249
+ batchSize: opts.batchSize,
250
+ quantized: opts.quantized,
251
+ readOnly: opts.readOnly
252
+ });
340
253
  });
341
254
  program.parse();
342
255
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { program } from \"commander\";\nimport { resolve, join } from \"node:path\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { spawnSync } from \"node:child_process\";\n\nconst TOOL_HELP: Record<string, { description: string; args: string; examples: string[] }> = {\n // Search\n search_semantic: {\n description: \"Vector similarity search — find notes by meaning, not just keywords\",\n args: '{ \"query\": \"string\", \"limit?\": 10 }',\n examples: [\n '{ \"query\": \"microservices architecture\", \"limit\": 5 }',\n '{ \"query\": \"how to deploy to production\" }',\n ],\n },\n search_text: {\n description: \"Full-text keyword or regex search with optional filters\",\n args: '{ \"pattern\": \"string\", \"regex?\": false, \"caseSensitive?\": false, \"pathGlob?\": \"string\", \"tagFilter?\": [\"string\"], \"limit?\": 20 }',\n examples: [\n '{ \"pattern\": \"RabbitMQ\" }',\n '{ \"pattern\": \"OAuth\\\\\\\\d\", \"regex\": true }',\n '{ \"pattern\": \"deploy\", \"pathGlob\": \"devops/**\", \"tagFilter\": [\"kubernetes\"] }',\n ],\n },\n search_graph: {\n description: \"Graph traversal — find notes connected to a concept via wikilinks and tags\",\n args: '{ \"concept\": \"string\", \"maxDepth?\": 2 }',\n examples: [\n '{ \"concept\": \"microservices\" }',\n '{ \"concept\": \"auth\", \"maxDepth\": 3 }',\n ],\n },\n search_hybrid: {\n description: \"Combined semantic + graph search — vector results re-ranked by graph proximity\",\n args: '{ \"query\": \"string\", \"limit?\": 10 }',\n examples: [\n '{ \"query\": \"event driven architecture\", \"limit\": 5 }',\n ],\n },\n\n // Read\n read_note: {\n description: \"Read the full content of a specific note by path\",\n args: '{ \"path\": \"string\" }',\n examples: [\n '{ \"path\": \"project-overview.md\" }',\n '{ \"path\": \"notes/meeting-2024-01-15.md\" }',\n ],\n },\n read_multiple_notes: {\n description: \"Batch read multiple notes in one call\",\n args: '{ \"paths\": [\"string\"] }',\n examples: [\n '{ \"paths\": [\"overview.md\", \"architecture.md\", \"deployment.md\"] }',\n ],\n },\n list_notes: {\n description: \"List all indexed notes with metadata (title, tags, link count)\",\n args: \"{}\",\n examples: [\"{}\"],\n },\n\n // Write\n create_note: {\n description: \"Create a new markdown note with optional YAML frontmatter\",\n args: '{ \"path\": \"string\", \"content\": \"string\", \"frontmatter?\": {} }',\n examples: [\n '{ \"path\": \"new-guide.md\", \"content\": \"# Guide\\\\n\\\\nContent here.\" }',\n '{ \"path\": \"tagged.md\", \"content\": \"Content.\", \"frontmatter\": { \"title\": \"Tagged Note\", \"tags\": [\"test\"] } }',\n ],\n },\n update_note: {\n description: \"Edit note content — overwrite, append, prepend, or patch by heading\",\n args: '{ \"path\": \"string\", \"content\": \"string\", \"mode\": \"overwrite|append|prepend|patch-by-heading\", \"heading?\": \"string\" }',\n examples: [\n '{ \"path\": \"guide.md\", \"content\": \"New content.\", \"mode\": \"overwrite\" }',\n '{ \"path\": \"guide.md\", \"content\": \"\\\\n## Appendix\\\\nExtra info.\", \"mode\": \"append\" }',\n '{ \"path\": \"guide.md\", \"content\": \"Updated architecture section.\", \"mode\": \"patch-by-heading\", \"heading\": \"Architecture\" }',\n ],\n },\n delete_note: {\n description: \"Delete a note permanently (requires confirm=true)\",\n args: '{ \"path\": \"string\", \"confirm\": true }',\n examples: [\n '{ \"path\": \"old-note.md\", \"confirm\": true }',\n '{ \"path\": \"old-note.md\", \"confirm\": false } // returns warning, does not delete',\n ],\n },\n move_note: {\n description: \"Move or rename a note — automatically updates wikilinks across the vault\",\n args: '{ \"from\": \"string\", \"to\": \"string\" }',\n examples: [\n '{ \"from\": \"user-service.md\", \"to\": \"auth-service.md\" }',\n '{ \"from\": \"old/note.md\", \"to\": \"new/location/note.md\" }',\n ],\n },\n\n // Metadata\n get_frontmatter: {\n description: \"Read parsed YAML frontmatter from a note as JSON\",\n args: '{ \"path\": \"string\" }',\n examples: ['{ \"path\": \"project-overview.md\" }'],\n },\n update_frontmatter: {\n description: \"Set or delete YAML frontmatter keys — pass null to delete a key\",\n args: '{ \"path\": \"string\", \"fields\": {} }',\n examples: [\n '{ \"path\": \"note.md\", \"fields\": { \"status\": \"active\", \"priority\": 1 } }',\n '{ \"path\": \"note.md\", \"fields\": { \"deprecated_field\": null } } // deletes the key',\n ],\n },\n manage_tags: {\n description: \"Add, remove, or list tags on a note (frontmatter and inline)\",\n args: '{ \"path\": \"string\", \"action\": \"add|remove|list\", \"tags?\": [\"string\"] }',\n examples: [\n '{ \"path\": \"note.md\", \"action\": \"list\" }',\n '{ \"path\": \"note.md\", \"action\": \"add\", \"tags\": [\"important\", \"reviewed\"] }',\n '{ \"path\": \"note.md\", \"action\": \"remove\", \"tags\": [\"draft\"] }',\n ],\n },\n rename_tag: {\n description: \"Rename a tag across all notes in the vault (frontmatter + inline)\",\n args: '{ \"oldTag\": \"string\", \"newTag\": \"string\" }',\n examples: ['{ \"oldTag\": \"architecture\", \"newTag\": \"arch\" }'],\n },\n\n // Graph\n backlinks: {\n description: \"Find all notes that link TO a given note via [[wikilinks]]\",\n args: '{ \"path\": \"string\" }',\n examples: ['{ \"path\": \"microservices.md\" }'],\n },\n forwardlinks: {\n description: \"Find all notes linked FROM a given note\",\n args: '{ \"path\": \"string\" }',\n examples: ['{ \"path\": \"project-overview.md\" }'],\n },\n graph_path: {\n description: \"Find the shortest path between two notes in the knowledge graph\",\n args: '{ \"from\": \"string\", \"to\": \"string\" }',\n examples: ['{ \"from\": \"project-overview.md\", \"to\": \"user-service.md\" }'],\n },\n graph_statistics: {\n description: \"Knowledge graph stats — most connected nodes, orphans, density\",\n args: \"{}\",\n examples: [\"{}\"],\n },\n\n // System\n get_stats: {\n description: \"Vault and index statistics — note count, chunks, embeddings, graph density\",\n args: \"{}\",\n examples: [\"{}\"],\n },\n reindex: {\n description: \"Force a full reindex of the vault\",\n args: \"{}\",\n examples: [\"{}\"],\n },\n};\n\nconst TOOL_CATEGORIES: Record<string, string[]> = {\n Search: [\"search_semantic\", \"search_text\", \"search_graph\", \"search_hybrid\"],\n Read: [\"read_note\", \"read_multiple_notes\", \"list_notes\"],\n Write: [\"create_note\", \"update_note\", \"delete_note\", \"move_note\"],\n Metadata: [\"get_frontmatter\", \"update_frontmatter\", \"manage_tags\", \"rename_tag\"],\n Graph: [\"backlinks\", \"forwardlinks\", \"graph_path\", \"graph_statistics\"],\n System: [\"get_stats\", \"reindex\"],\n};\n\nfunction printToolList() {\n console.log(\"\\nSemantic Pages — 21 MCP Tools\\n\");\n console.log(\"Usage: These tools are available via MCP when the server is running.\");\n console.log(\" Run `semantic-pages tools <name>` for details on a specific tool.\\n\");\n\n for (const [category, tools] of Object.entries(TOOL_CATEGORIES)) {\n console.log(` ${category}:`);\n for (const name of tools) {\n const tool = TOOL_HELP[name];\n console.log(` ${name.padEnd(24)} ${tool.description}`);\n }\n console.log();\n }\n\n console.log(\"Run `semantic-pages tools <tool-name>` for arguments and examples.\");\n}\n\nfunction printToolDetail(name: string) {\n const tool = TOOL_HELP[name];\n if (!tool) {\n console.error(`Unknown tool: ${name}`);\n console.error(`Run \\`semantic-pages tools\\` to see all available tools.`);\n process.exit(1);\n }\n\n console.log(`\\n ${name}`);\n console.log(` ${\"─\".repeat(name.length)}`);\n console.log(` ${tool.description}\\n`);\n console.log(` Arguments:`);\n console.log(` ${tool.args}\\n`);\n console.log(` Examples:`);\n for (const ex of tool.examples) {\n console.log(` ${ex}`);\n }\n console.log();\n}\n\nprogram\n .name(\"semantic-pages\")\n .description(\n \"Semantic search + knowledge graph MCP server for markdown files\\n\\n\" +\n \" Auto-configure: semantic-pages init\\n\" +\n \" Start MCP server: semantic-pages --notes ./vault\\n\" +\n \" Show vault stats: semantic-pages --notes ./vault --stats\\n\" +\n \" Force reindex: semantic-pages --notes ./vault --reindex\\n\" +\n \" List MCP tools: semantic-pages tools\\n\" +\n \" Tool details: semantic-pages tools search_semantic\"\n )\n .version(\"0.5.0\");\n\nprogram\n .command(\"tools [name]\")\n .description(\"List all MCP tools, or show details for a specific tool\")\n .action((name?: string) => {\n if (name) {\n printToolDetail(name);\n } else {\n printToolList();\n }\n process.exit(0);\n });\n\nprogram\n .command(\"serve\", { isDefault: true })\n .description(\"Start the MCP server (default command)\")\n .requiredOption(\"--notes <path>\", \"Path to markdown notes directory\")\n .option(\"--reindex\", \"Force full reindex and exit\")\n .option(\"--stats\", \"Show vault statistics and exit\")\n .option(\"--model <name>\", \"Embedding model to use (default: all-MiniLM-L6-v2, fast; use nomic-ai/nomic-embed-text-v1.5 for higher quality)\")\n .option(\"--workers <n>\", \"Number of worker threads for parallel embedding\", parseInt)\n .option(\"--batch-size <n>\", \"Texts per ONNX forward pass (default: 8)\", parseInt)\n .option(\"--no-quantized\", \"Use full-precision model instead of quantized (slower, slightly higher quality)\")\n .option(\"--no-watch\", \"Disable file watcher\")\n .action(async (opts) => {\n const notesPath = resolve(opts.notes);\n\n if (!existsSync(notesPath)) {\n console.error(`Error: notes directory not found: ${notesPath}`);\n process.exit(1);\n }\n\n if (opts.stats) {\n const { Indexer } = await import(\"../core/indexer.js\");\n const indexer = new Indexer(notesPath);\n const docs = await indexer.indexAll();\n console.log(`Notes: ${docs.length}`);\n console.log(`Chunks: ${docs.reduce((n: number, d: any) => n + d.chunks.length, 0)}`);\n console.log(`Wikilinks: ${docs.reduce((n: number, d: any) => n + d.wikilinks.length, 0)}`);\n console.log(`Tags: ${new Set(docs.flatMap((d: any) => d.tags)).size} unique`);\n process.exit(0);\n }\n\n if (opts.reindex) {\n const { createServer } = await import(\"../mcp/server.js\");\n await createServer(notesPath, {\n watch: false,\n waitForReady: true,\n model: opts.model,\n workers: opts.workers,\n batchSize: opts.batchSize,\n quantized: opts.quantized,\n onProgress: (embedded, total) => {\n process.stderr.write(`\\rEmbedding ${embedded}/${total} chunks...`);\n },\n });\n process.stderr.write(\"\\n\");\n console.log(\"Reindex complete.\");\n process.exit(0);\n }\n\n // Default: start MCP server on stdio\n const { startServer } = await import(\"../mcp/server.js\");\n await startServer(notesPath, { watch: opts.watch, model: opts.model, workers: opts.workers, batchSize: opts.batchSize, quantized: opts.quantized });\n });\n\n// ─── init command ────────────────────────────────────────────────────────────\n\nfunction detectHewtd(cwd: string): boolean {\n // 1. hit-em-with-the-docs always creates .documentation/INDEX.md\n if (existsSync(join(cwd, \".documentation\", \"INDEX.md\"))) return true;\n // 2. Explicit config file\n if (existsSync(join(cwd, \".hewtd.json\"))) return true;\n // 3. hewtd binary available in PATH\n try {\n const r = spawnSync(\"hewtd\", [\"--version\"], { stdio: \"ignore\" });\n if (r.status === 0) return true;\n } catch {}\n return false;\n}\n\nfunction readMcpJson(cwd: string): Record<string, unknown> {\n const mcpPath = join(cwd, \".mcp.json\");\n if (!existsSync(mcpPath)) return {};\n try {\n return JSON.parse(readFileSync(mcpPath, \"utf8\"));\n } catch {\n console.warn(\" ⚠ Could not parse existing .mcp.json — will merge carefully.\");\n return {};\n }\n}\n\nfunction writeMcpJson(cwd: string, config: Record<string, unknown>): void {\n writeFileSync(join(cwd, \".mcp.json\"), JSON.stringify(config, null, 2) + \"\\n\", \"utf8\");\n}\n\nfunction ensureGitignore(cwd: string, entry: string): void {\n const gitignorePath = join(cwd, \".gitignore\");\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, \"utf8\");\n if (!content.includes(entry)) {\n writeFileSync(gitignorePath, content.trimEnd() + \"\\n\" + entry + \"\\n\", \"utf8\");\n }\n } else {\n writeFileSync(gitignorePath, entry + \"\\n\", \"utf8\");\n }\n}\n\nfunction mcpEntry(notesPath: string) {\n return {\n type: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"@theglitchking/semantic-pages@latest\", \"--notes\", notesPath],\n };\n}\n\nprogram\n .command(\"init\")\n .description(\n \"Auto-configure MCP servers for this project.\\n\" +\n \"Detects hit-em-with-the-docs and sets up one or two vaults accordingly.\"\n )\n .option(\"--notes <path>\", \"Custom notes path (single-vault fallback only)\")\n .option(\"--cwd <path>\", \"Project root to configure (default: current directory)\")\n .action((opts) => {\n const cwd = resolve(opts.cwd || process.cwd());\n const hewtd = detectHewtd(cwd);\n\n console.log(\"\\nSemantic Pages — init\\n\");\n console.log(` Project root : ${cwd}`);\n console.log(` hit-em-with-the-docs : ${hewtd ? \"✅ detected\" : \"not found\"}\\n`);\n\n // Read existing .mcp.json so we don't clobber other servers (e.g. playwright)\n const existing = readMcpJson(cwd);\n const servers: Record<string, unknown> = (existing as any).mcpServers ?? {};\n const notesPath: string = (opts.notes as string) || \"./vault\";\n\n if (hewtd) {\n // Two-vault setup\n servers[\"semantic-pages\"] = mcpEntry(\"./.documentation\");\n servers[\"semantic-vault\"] = mcpEntry(\"./.claude/.vault\");\n\n // Create .claude/.vault/ if absent\n const vaultDir = join(cwd, \".claude\", \".vault\");\n if (!existsSync(vaultDir)) {\n mkdirSync(vaultDir, { recursive: true });\n writeFileSync(join(vaultDir, \".gitkeep\"), \"\", \"utf8\");\n console.log(\" Created .claude/.vault/\");\n }\n\n // Gitignore both indexes\n ensureGitignore(cwd, \".documentation/.semantic-pages-index/\");\n ensureGitignore(cwd, \".claude/.vault/.semantic-pages-index/\");\n\n console.log(\" Configured semantic-pages → .documentation/ (project docs, read-only)\");\n console.log(\" Configured semantic-vault → .claude/.vault/ (research notes, read+write)\");\n } else {\n // Single-vault fallback\n servers[\"semantic-pages\"] = mcpEntry(notesPath);\n\n // Create vault dir if absent\n const vaultDir = resolve(cwd, notesPath);\n if (!existsSync(vaultDir)) {\n mkdirSync(vaultDir, { recursive: true });\n console.log(` Created ${notesPath}/`);\n }\n\n ensureGitignore(cwd, \".semantic-pages-index/\");\n\n console.log(` Configured semantic-pages → ${notesPath}/`);\n }\n\n writeMcpJson(cwd, { ...existing, mcpServers: servers });\n console.log(\" Updated .mcp.json\");\n console.log(\" Updated .gitignore\\n\");\n\n if (hewtd) {\n console.log(\" Next steps:\");\n console.log(\" • Restart Claude — it will have 42 MCP tools across two vaults\");\n console.log(\" • Search docs : mcp__semantic-pages__search_hybrid\");\n console.log(\" • Save research : mcp__semantic-vault__create_note\\n\");\n } else {\n console.log(\" Next steps:\");\n console.log(\" • Drop .md files into the vault directory\");\n console.log(` • Restart Claude — it will have 21 MCP tools over ${notesPath}/\\n`);\n console.log(\" Tip: install hit-em-with-the-docs for the two-vault setup:\");\n console.log(\" npx @theglitchking/hit-em-with-the-docs init\\n\");\n }\n });\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nprogram.parse();\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { program } from \"commander\";\nimport { resolve } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nconst TOOL_HELP: Record<string, { description: string; args: string; examples: string[] }> = {\n // Search\n search_semantic: {\n description: \"Vector similarity search — find notes by meaning, not just keywords\",\n args: '{ \"query\": \"string\", \"limit?\": 10 }',\n examples: [\n '{ \"query\": \"microservices architecture\", \"limit\": 5 }',\n '{ \"query\": \"how to deploy to production\" }',\n ],\n },\n search_text: {\n description: \"Full-text keyword or regex search with optional filters\",\n args: '{ \"pattern\": \"string\", \"regex?\": false, \"caseSensitive?\": false, \"pathGlob?\": \"string\", \"tagFilter?\": [\"string\"], \"limit?\": 20 }',\n examples: [\n '{ \"pattern\": \"RabbitMQ\" }',\n '{ \"pattern\": \"OAuth\\\\\\\\d\", \"regex\": true }',\n '{ \"pattern\": \"deploy\", \"pathGlob\": \"devops/**\", \"tagFilter\": [\"kubernetes\"] }',\n ],\n },\n search_graph: {\n description: \"Graph traversal — find notes connected to a concept via wikilinks and tags\",\n args: '{ \"concept\": \"string\", \"maxDepth?\": 2 }',\n examples: [\n '{ \"concept\": \"microservices\" }',\n '{ \"concept\": \"auth\", \"maxDepth\": 3 }',\n ],\n },\n search_hybrid: {\n description: \"Combined semantic + graph search — vector results re-ranked by graph proximity\",\n args: '{ \"query\": \"string\", \"limit?\": 10 }',\n examples: [\n '{ \"query\": \"event driven architecture\", \"limit\": 5 }',\n ],\n },\n\n // Read\n read_note: {\n description: \"Read the full content of a specific note by path\",\n args: '{ \"path\": \"string\" }',\n examples: [\n '{ \"path\": \"project-overview.md\" }',\n '{ \"path\": \"notes/meeting-2024-01-15.md\" }',\n ],\n },\n read_multiple_notes: {\n description: \"Batch read multiple notes in one call\",\n args: '{ \"paths\": [\"string\"] }',\n examples: [\n '{ \"paths\": [\"overview.md\", \"architecture.md\", \"deployment.md\"] }',\n ],\n },\n list_notes: {\n description: \"List all indexed notes with metadata (title, tags, link count)\",\n args: \"{}\",\n examples: [\"{}\"],\n },\n\n // Write\n create_note: {\n description: \"Create a new markdown note with optional YAML frontmatter\",\n args: '{ \"path\": \"string\", \"content\": \"string\", \"frontmatter?\": {} }',\n examples: [\n '{ \"path\": \"new-guide.md\", \"content\": \"# Guide\\\\n\\\\nContent here.\" }',\n '{ \"path\": \"tagged.md\", \"content\": \"Content.\", \"frontmatter\": { \"title\": \"Tagged Note\", \"tags\": [\"test\"] } }',\n ],\n },\n update_note: {\n description: \"Edit note content — overwrite, append, prepend, or patch by heading\",\n args: '{ \"path\": \"string\", \"content\": \"string\", \"mode\": \"overwrite|append|prepend|patch-by-heading\", \"heading?\": \"string\" }',\n examples: [\n '{ \"path\": \"guide.md\", \"content\": \"New content.\", \"mode\": \"overwrite\" }',\n '{ \"path\": \"guide.md\", \"content\": \"\\\\n## Appendix\\\\nExtra info.\", \"mode\": \"append\" }',\n '{ \"path\": \"guide.md\", \"content\": \"Updated architecture section.\", \"mode\": \"patch-by-heading\", \"heading\": \"Architecture\" }',\n ],\n },\n delete_note: {\n description: \"Delete a note permanently (requires confirm=true)\",\n args: '{ \"path\": \"string\", \"confirm\": true }',\n examples: [\n '{ \"path\": \"old-note.md\", \"confirm\": true }',\n '{ \"path\": \"old-note.md\", \"confirm\": false } // returns warning, does not delete',\n ],\n },\n move_note: {\n description: \"Move or rename a note — automatically updates wikilinks across the vault\",\n args: '{ \"from\": \"string\", \"to\": \"string\" }',\n examples: [\n '{ \"from\": \"user-service.md\", \"to\": \"auth-service.md\" }',\n '{ \"from\": \"old/note.md\", \"to\": \"new/location/note.md\" }',\n ],\n },\n\n // Metadata\n get_frontmatter: {\n description: \"Read parsed YAML frontmatter from a note as JSON\",\n args: '{ \"path\": \"string\" }',\n examples: ['{ \"path\": \"project-overview.md\" }'],\n },\n update_frontmatter: {\n description: \"Set or delete YAML frontmatter keys — pass null to delete a key\",\n args: '{ \"path\": \"string\", \"fields\": {} }',\n examples: [\n '{ \"path\": \"note.md\", \"fields\": { \"status\": \"active\", \"priority\": 1 } }',\n '{ \"path\": \"note.md\", \"fields\": { \"deprecated_field\": null } } // deletes the key',\n ],\n },\n manage_tags: {\n description: \"Add, remove, or list tags on a note (frontmatter and inline)\",\n args: '{ \"path\": \"string\", \"action\": \"add|remove|list\", \"tags?\": [\"string\"] }',\n examples: [\n '{ \"path\": \"note.md\", \"action\": \"list\" }',\n '{ \"path\": \"note.md\", \"action\": \"add\", \"tags\": [\"important\", \"reviewed\"] }',\n '{ \"path\": \"note.md\", \"action\": \"remove\", \"tags\": [\"draft\"] }',\n ],\n },\n rename_tag: {\n description: \"Rename a tag across all notes in the vault (frontmatter + inline)\",\n args: '{ \"oldTag\": \"string\", \"newTag\": \"string\" }',\n examples: ['{ \"oldTag\": \"architecture\", \"newTag\": \"arch\" }'],\n },\n\n // Graph\n backlinks: {\n description: \"Find all notes that link TO a given note via [[wikilinks]]\",\n args: '{ \"path\": \"string\" }',\n examples: ['{ \"path\": \"microservices.md\" }'],\n },\n forwardlinks: {\n description: \"Find all notes linked FROM a given note\",\n args: '{ \"path\": \"string\" }',\n examples: ['{ \"path\": \"project-overview.md\" }'],\n },\n graph_path: {\n description: \"Find the shortest path between two notes in the knowledge graph\",\n args: '{ \"from\": \"string\", \"to\": \"string\" }',\n examples: ['{ \"from\": \"project-overview.md\", \"to\": \"user-service.md\" }'],\n },\n graph_statistics: {\n description: \"Knowledge graph stats — most connected nodes, orphans, density\",\n args: \"{}\",\n examples: [\"{}\"],\n },\n\n // System\n get_stats: {\n description: \"Vault and index statistics — note count, chunks, embeddings, graph density\",\n args: \"{}\",\n examples: [\"{}\"],\n },\n reindex: {\n description: \"Force a full reindex of the vault\",\n args: \"{}\",\n examples: [\"{}\"],\n },\n};\n\nconst TOOL_CATEGORIES: Record<string, string[]> = {\n Search: [\"search_semantic\", \"search_text\", \"search_graph\", \"search_hybrid\"],\n Read: [\"read_note\", \"read_multiple_notes\", \"list_notes\"],\n Write: [\"create_note\", \"update_note\", \"delete_note\", \"move_note\"],\n Metadata: [\"get_frontmatter\", \"update_frontmatter\", \"manage_tags\", \"rename_tag\"],\n Graph: [\"backlinks\", \"forwardlinks\", \"graph_path\", \"graph_statistics\"],\n System: [\"get_stats\", \"reindex\"],\n};\n\nfunction printToolList() {\n console.log(\"\\nSemantic Pages — 21 MCP Tools\\n\");\n console.log(\"Usage: These tools are available via MCP when the server is running.\");\n console.log(\" Run `semantic-pages tools <name>` for details on a specific tool.\\n\");\n\n for (const [category, tools] of Object.entries(TOOL_CATEGORIES)) {\n console.log(` ${category}:`);\n for (const name of tools) {\n const tool = TOOL_HELP[name];\n console.log(` ${name.padEnd(24)} ${tool.description}`);\n }\n console.log();\n }\n\n console.log(\"Run `semantic-pages tools <tool-name>` for arguments and examples.\");\n}\n\nfunction printToolDetail(name: string) {\n const tool = TOOL_HELP[name];\n if (!tool) {\n console.error(`Unknown tool: ${name}`);\n console.error(`Run \\`semantic-pages tools\\` to see all available tools.`);\n process.exit(1);\n }\n\n console.log(`\\n ${name}`);\n console.log(` ${\"─\".repeat(name.length)}`);\n console.log(` ${tool.description}\\n`);\n console.log(` Arguments:`);\n console.log(` ${tool.args}\\n`);\n console.log(` Examples:`);\n for (const ex of tool.examples) {\n console.log(` ${ex}`);\n }\n console.log();\n}\n\nprogram\n .name(\"semantic-pages\")\n .description(\n \"Semantic search + knowledge graph MCP server for markdown files\\n\\n\" +\n \" Start MCP server: semantic-pages --notes ./vault\\n\" +\n \" Show vault stats: semantic-pages --notes ./vault --stats\\n\" +\n \" Force reindex: semantic-pages --notes ./vault --reindex\\n\" +\n \" List MCP tools: semantic-pages tools\\n\" +\n \" Tool details: semantic-pages tools search_semantic\"\n )\n .version(\"0.4.3\");\n\nprogram\n .command(\"tools [name]\")\n .description(\"List all MCP tools, or show details for a specific tool\")\n .action((name?: string) => {\n if (name) {\n printToolDetail(name);\n } else {\n printToolList();\n }\n process.exit(0);\n });\n\nprogram\n .command(\"serve\", { isDefault: true })\n .description(\"Start the MCP server (default command)\")\n .requiredOption(\"--notes <path>\", \"Path to markdown notes directory\")\n .option(\"--reindex\", \"Force full reindex and exit\")\n .option(\"--stats\", \"Show vault statistics and exit\")\n .option(\"--read-only\", \"Suppress write tools (create_note, update_note, delete_note, move_note, update_frontmatter, manage_tags, rename_tag) — use for shared docs vaults owned by another tool\")\n .option(\"--model <name>\", \"Embedding model to use (default: all-MiniLM-L6-v2, fast; use nomic-ai/nomic-embed-text-v1.5 for higher quality)\")\n .option(\"--workers <n>\", \"Number of worker threads for parallel embedding\", parseInt)\n .option(\"--batch-size <n>\", \"Texts per ONNX forward pass (default: 8)\", parseInt)\n .option(\"--no-quantized\", \"Use full-precision model instead of quantized (slower, slightly higher quality)\")\n .option(\"--no-watch\", \"Disable file watcher\")\n .action(async (opts) => {\n const notesPath = resolve(opts.notes);\n\n if (!existsSync(notesPath)) {\n console.error(`Error: notes directory not found: ${notesPath}`);\n process.exit(1);\n }\n\n if (opts.stats) {\n const { Indexer } = await import(\"../core/indexer.js\");\n const indexer = new Indexer(notesPath);\n const docs = await indexer.indexAll();\n console.log(`Notes: ${docs.length}`);\n console.log(`Chunks: ${docs.reduce((n: number, d: any) => n + d.chunks.length, 0)}`);\n console.log(`Wikilinks: ${docs.reduce((n: number, d: any) => n + d.wikilinks.length, 0)}`);\n console.log(`Tags: ${new Set(docs.flatMap((d: any) => d.tags)).size} unique`);\n process.exit(0);\n }\n\n if (opts.reindex) {\n const { createServer } = await import(\"../mcp/server.js\");\n await createServer(notesPath, {\n watch: false,\n waitForReady: true,\n model: opts.model,\n workers: opts.workers,\n batchSize: opts.batchSize,\n quantized: opts.quantized,\n onProgress: (embedded, total) => {\n process.stderr.write(`\\rEmbedding ${embedded}/${total} chunks...`);\n },\n });\n process.stderr.write(\"\\n\");\n console.log(\"Reindex complete.\");\n process.exit(0);\n }\n\n // Default: start MCP server on stdio\n const { startServer } = await import(\"../mcp/server.js\");\n await startServer(notesPath, {\n watch: opts.watch,\n model: opts.model,\n workers: opts.workers,\n batchSize: opts.batchSize,\n quantized: opts.quantized,\n readOnly: opts.readOnly,\n });\n });\n\nprogram.parse();\n"],"mappings":"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","names":[]}
@@ -7,6 +7,7 @@ interface ServerOptions {
7
7
  workers?: number;
8
8
  batchSize?: number;
9
9
  quantized?: boolean;
10
+ readOnly?: boolean;
10
11
  onProgress?: (embedded: number, total: number) => void;
11
12
  }
12
13
  declare function createServer(notesPath: string, options?: ServerOptions): Promise<McpServer>;