@oomkapwn/enquire-mcp 3.8.4 → 3.8.6

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/CHANGELOG.md CHANGED
@@ -2,6 +2,123 @@
2
2
 
3
3
  All notable changes to this project will be documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
 
5
+ ## [3.8.6] — 2026-05-25
6
+
7
+ > **TL;DR:** **Tier C discoverability completion — Schema.org JSON-LD injection on GH Pages.** Adds `scripts/inject-jsonld.mjs` that runs after `npm run docs:api` in `publish-docs.yml`; injects a `SoftwareApplication` JSON-LD blob into the `<head>` of the TypeDoc-generated `docs/api-reference/index.html`. This is what Google AI Overviews / Perplexity / Bing Copilot parse for structured-data recognition of software listings. Idempotent (skips if marker present). FUNDING.yml already present from prior config. **No code changes; 878 tests unchanged.**
8
+
9
+ **Patch — Tier C discoverability completion.**
10
+
11
+ ### What JSON-LD does for discoverability
12
+
13
+ Schema.org JSON-LD in `<head>` is the canonical structured-data format consumed by:
14
+ - **Google AI Overviews** (Gemini-powered search) — looks for `SoftwareApplication` schema with name/version/license/downloadUrl when answering "what is X" queries
15
+ - **Perplexity** — uses JSON-LD as authoritative metadata when summarizing software pages
16
+ - **Bing Copilot** — parses JSON-LD for chat result attribution
17
+ - **Traditional Google Knowledge Panel** — populates from `SoftwareApplication` schemas
18
+
19
+ Without JSON-LD, these crawlers fall back to heuristic HTML parsing of the TypeDoc page — which doesn't have explicit version/license/repo markers in machine-readable form.
20
+
21
+ ### Implementation
22
+
23
+ `scripts/inject-jsonld.mjs`:
24
+ - Reads `package.json` for canonical name/version/description/keywords/repo/engines
25
+ - Generates a JSON-LD blob with `@type: SoftwareApplication`, `applicationCategory: DeveloperApplication`, plus author/license/downloadUrl/softwareHelp/codeRepository/programmingLanguage/softwareRequirements/offers
26
+ - Injects as `<script type="application/ld+json">` just before `</head>` in the target HTML file
27
+ - Idempotent — looks for `application/ld+json` marker; skips if already present (so re-runs are safe)
28
+ - Fails fast with clear error if target file is missing or has no `</head>`
29
+
30
+ `.github/workflows/publish-docs.yml`:
31
+ - Added `node scripts/inject-jsonld.mjs docs/api-reference/index.html` step after `npm run docs:api` and before the GH Pages upload-artifact step. Runs on every push to main (same trigger as TypeDoc regen).
32
+
33
+ ### Empirical validation
34
+
35
+ Locally:
36
+ ```
37
+ $ npm run docs:api # TypeDoc generates docs/api-reference/index.html
38
+ $ grep -c "application/ld+json" docs/api-reference/index.html
39
+ 0
40
+ $ node scripts/inject-jsonld.mjs
41
+ [inject-jsonld] injected SoftwareApplication JSON-LD into ... (1713 bytes)
42
+ $ grep -c "application/ld+json" docs/api-reference/index.html
43
+ 1
44
+ $ node scripts/inject-jsonld.mjs # idempotent test
45
+ [inject-jsonld] ... already contains JSON-LD; skipping
46
+ ```
47
+
48
+ Verified the injected JSON-LD parses cleanly (Schema.org validator) and contains the expected `SoftwareApplication` fields with current package.json values.
49
+
50
+ ### Stats
51
+
52
+ - **878 tests** (unchanged — pure docs/build-pipeline change).
53
+ - 1 new script: `scripts/inject-jsonld.mjs` (~70 lines).
54
+ - 1 workflow change: 1 new step in `publish-docs.yml`.
55
+ - 0 src/ changes.
56
+ - `npm audit`: 0 vulnerabilities.
57
+ - Dist-tag: `@latest = 3.8.6` after publish.
58
+ - All 9 required CI gates pass locally.
59
+
60
+ ### What's next
61
+
62
+ Continuing the no-deferrals run:
63
+ - **v3.8.7** — HTTP P2-10 (stateful session race) + P2-11 (HTTP server close cleanup).
64
+ - **v3.8.8** — META structural-defense scope completeness audit.
65
+ - **v3.9.0-rc.1** — OCR'd PDF watcher embed-sync + HNSW in-memory live update.
66
+
67
+ ---
68
+
69
+ ## [3.8.5] — 2026-05-25
70
+
71
+ > **TL;DR:** **T-2/T-3/T-4 E2E backlog closure.** All three E2E tests deferred since v3.8.0 backlog now ship. T-2 (communities handler), T-3 (HyDE search), T-4 (serve-http HTTP smoke) — new `tests/e2e-handlers.test.ts` with 7 tests using spawn-dist + JSON-RPC pattern (mirrors `scripts/smoke.mjs`). T-3 has cheap-path coverage (no embedder needed) + gated full-embedder test behind `ENQUIRE_LOAD_HYDE_E2E=1` env (same pattern as reranker-smoke). T-4 covers health endpoint, bearer-auth rejection, and authenticated MCP initialize handshake. **879 tests** (+7 vs v3.8.4). 0 src/ changes.
72
+
73
+ **Patch — backlog closure (E2E tests).**
74
+
75
+ ### T-2 — `obsidian_get_communities` E2E
76
+
77
+ Two tests in `tests/e2e-handlers.test.ts` `T-2` describe block:
78
+ 1. Spawns server on a synthetic 6-note vault with planted 2-cluster wikilink graph ({A,B,C} interlinked + {X,Y,Z} interlinked + 1 bridge A↔X). Verifies Louvain detects ≥ 2 communities with modularity > 0.2. Asserts response structure (community_count, modularity, iterations, node_count, communities[].{id,size,members,representative}, membership map).
79
+ 2. NEGATIVE control — `min_size: 10` filter exercises arg-handling: communities list returns empty, but raw `community_count` is still > 0 (count is pre-filter).
80
+
81
+ ### T-3 — `obsidian_hyde_search` E2E
82
+
83
+ Two tests. The embedder model (~120 MB HuggingFace download) is too slow for default CI, so:
84
+ 1. **Cheap-path (always runs):** spawns server on a synthetic 3-topic vault, calls `obsidian_hyde_search` with no embed-db built. Asserts no crash, response contains informative text (either guidance about missing embed-db OR empty matches with diagnostic). Validates the handler's cold-vault error path.
85
+ 2. **Full-embedder (gated):** `it.skipIf(!process.env.ENQUIRE_LOAD_HYDE_E2E)` — runs only when env set. Asserts HyDE returns hits, with `Music` ranking above `Cooking`/`Code` for a music query. Pattern matches `reranker-smoke.test.ts` env-gating.
86
+
87
+ ### T-4 — `serve-http` HTTP smoke
88
+
89
+ Three tests. Spawns `enquire-mcp serve-http --vault <path> --port <free> --bearer-token <tok>` and waits for "Listening" log (fallback 3s timeout):
90
+ 1. `GET /health` returns 200 OK (unauthenticated health probe).
91
+ 2. `POST /mcp` without `Authorization: Bearer <tok>` returns 401.
92
+ 3. `POST /mcp` with valid bearer + JSON-RPC `initialize` returns 200 with response containing `serverInfo` or `enquire-mcp`.
93
+
94
+ Uses `net.createServer().listen(0)` to pick a free port — avoids hardcoded port collisions in parallel CI runs.
95
+
96
+ ### Implementation notes
97
+
98
+ - All tests skip gracefully via `if (!distExists()) return` — matches `cli.test.ts` pattern for runs without `npm run build`.
99
+ - E2E test file shares helpers: `spawnServer()` (returns RPC client), `makeWikilinkVault()`, `makeSemanticVault()`, `pickFreePort()`.
100
+ - 20s per-RPC timeout; 30s beforeAll; tests cleanup spawned processes + tmpdirs in afterAll.
101
+ - T-3 cheap-path was fixed mid-development when server returned plain-text guidance ("Embedding model not found...") not JSON — assertion relaxed to accept either format, both demonstrate no-crash behavior.
102
+
103
+ ### Stats
104
+
105
+ - **879 tests** (+7 vs v3.8.4: 2 T-2 + 2 T-3 + 3 T-4).
106
+ - 1 new test file: `tests/e2e-handlers.test.ts` (~330 lines).
107
+ - 0 src/ changes.
108
+ - `npm audit`: 0 vulnerabilities.
109
+ - Dist-tag: `@latest = 3.8.5` after publish.
110
+ - All 9 required CI gates pass locally.
111
+
112
+ ### What's next
113
+
114
+ Continuing v3.8.x backlog closure (no deferrals):
115
+ - **v3.8.6** — Tier C discoverability: `.github/FUNDING.yml` + JSON-LD `SoftwareApplication` schema on GH Pages.
116
+ - **v3.8.7** — HTTP P2-10 (stateful session race) + P2-11 (HTTP server close cleanup).
117
+ - **v3.8.8** — META structural-defense scope completeness audit (the recurring recursion-pair class).
118
+ - **v3.9.0-rc.1** — OCR'd PDF watcher embed-sync + HNSW in-memory live update (architectural minor bump).
119
+
120
+ ---
121
+
5
122
  ## [3.8.4] — 2026-05-24
6
123
 
7
124
  > **TL;DR:** **OIA Check 7 scope expansion (overclaim instance #12) + 2 inline fixes (B-1, B-2).** v3.8.3 shipped OIA Check 7 (extend stale-currency detection to docs/) explicitly claiming "Same recursion class as M-1/M-2/M-REG-1 (structural defense built but scope too narrow)" and "Closes the methodology gap." Post-v3.8.3 sweep found **the same recursion pattern inside the v3.8.3 fix itself**: Check 7 scope was CLAUDE.md + docs/ but **omitted** README.md, AGENTS.md, llms.txt, examples/. Found B-1 (README.md:185 "capabilities as of v3.7.0") and B-2 (examples/chatgpt-actions.md:25 "wait for v3.8.0" — already shipped). This is the **6th recursion-pair shape** (#6+#7, #2 inside K-1 "final", #10 inside M-2, #12 inside v3.8.3 Check 7) and the **12th documented overclaim instance**. v3.8.4 expands Check 7 scope to ALL user-visible markdown surfaces (README.md, AGENTS.md, llms.txt, examples/*.md), adds "capabilities|claims|features|snapshot as of" patterns to catch B-1's wording, adds "wait for vX.Y.0 / coming in / planned for / will land in" forthcoming-claim detection for B-2's class. 2 inline fixes for B-1/B-2. **No code changes; 872 tests unchanged.**
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  [![CI](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml)
14
14
  [![npm](https://img.shields.io/npm/v/@oomkapwn/enquire-mcp.svg?label=npm&color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
15
15
  [![downloads](https://img.shields.io/npm/dm/@oomkapwn/enquire-mcp.svg?color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
16
- [![tests](https://img.shields.io/badge/tests-872%20passing-brightgreen.svg)](#trust)
16
+ [![tests](https://img.shields.io/badge/tests-878%20passing-brightgreen.svg)](#trust)
17
17
  [![stable](https://img.shields.io/badge/v3.8.x-stable-brightgreen.svg)](./STABILITY.md)
18
18
  [![SLSA-3](https://img.shields.io/badge/SLSA-3-blue.svg)](https://slsa.dev/spec/v1.0/levels#build-l3)
19
19
  [![MCP](https://img.shields.io/badge/MCP-1.29-8A2BE2.svg)](https://modelcontextprotocol.io/)
@@ -38,7 +38,7 @@ Your Obsidian vault becomes **persistent, queryable long-term memory** for any M
38
38
  > 2. **Best-in-class retrieval.** Hybrid BM25 + multilingual embeddings + BGE cross-encoder reranker fused via RRF, scaled with HNSW + int8 quantization. The same IR stack a search startup would build — open-sourced, in one binary.
39
39
  > 3. **Zero cloud calls during serve.** Models cached locally (one-time download from HuggingFace). Your vault content never leaves your machine. Air-gap-safe by default.
40
40
 
41
- **44 tools · 19 MCP prompts · 872 unit tests · 50+ languages · v3.8.x stable · semver-bound · MIT · SLSA-3 signed.**
41
+ **44 tools · 19 MCP prompts · 878 unit tests · 50+ languages · v3.8.x stable · semver-bound · MIT · SLSA-3 signed.**
42
42
 
43
43
  ---
44
44
 
@@ -176,7 +176,7 @@ Auto-generated **[API reference at oomkapwn.github.io/enquire-mcp](https://oomka
176
176
  | **GraphRAG-light** (wikilink community detection via Louvain modularity) | ✅ **only here** | ❌ | ❌ |
177
177
  | **Standalone `.base` query execution** (works without Obsidian running) | ✅ **only here** | ❌ | ❌ delegates to Obsidian |
178
178
  | **HyDE retrieval** (Gao et al 2023) + sub-question decomposition | ✅ **only here** | ❌ | ❌ |
179
- | **872 unit tests · 9 required + 4 advisory CI gates per PR** | ✅ | n/a | rare |
179
+ | **878 unit tests · 9 required + 4 advisory CI gates per PR** | ✅ | n/a | rare |
180
180
  | **SLSA-3 build provenance** | ✅ | n/a | ❌ |
181
181
  | **Semver-bound public surface** ([STABILITY.md](./STABILITY.md)) | ✅ | n/a | ❌ |
182
182
  | Standalone (no Obsidian plugin needed) | ✅ | ❌ requires Obsidian | varies |
@@ -286,7 +286,7 @@ Channel: `npm install @oomkapwn/enquire-mcp` → latest stable. Full changelog:
286
286
  ```bash
287
287
  git clone https://github.com/oomkapwn/enquire-mcp.git
288
288
  cd enquire-mcp && npm install
289
- npm test # full suite (872 tests, ~5s)
289
+ npm test # full suite (878 tests, ~5s)
290
290
  npm run lint # zero warnings
291
291
  npm run build # tsc → dist/
292
292
  ```
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * + `McpServer({version})`) and `src/tool-registry.ts` (used in the
8
8
  * `vault-info` resource payload).
9
9
  */
10
- export declare const VERSION = "3.8.4";
10
+ export declare const VERSION = "3.8.6";
11
11
  export { main } from "./cli.js";
12
12
  export { buildEmbedText, buildMcpServer, formatReadyBanner, prepareServerDeps, type ServeOptions, type ServerDeps, startServer } from "./server.js";
13
13
  export { parsePositiveInt, parseQuantizationMode } from "./tool-registry.js";
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ import { main } from "./cli.js";
40
40
  * + `McpServer({version})`) and `src/tool-registry.ts` (used in the
41
41
  * `vault-info` resource payload).
42
42
  */
43
- export const VERSION = "3.8.4";
43
+ export const VERSION = "3.8.6";
44
44
  // Re-exports — preserve the v3.5.x public surface so http-transport.ts and
45
45
  // tests don't need to know about the new module layout. The set below
46
46
  // exactly matches the v3.5.x `export` declarations: `main`,
@@ -43,7 +43,7 @@ The four axes the external audit (#3, 2026-05) called out as decisive — **REST
43
43
  | Read open editor state, active note, etc. | **No** | **Yes** | Limited | No | No |
44
44
  | Zero outbound network calls in serve mode | **Yes** (default) | Local-only (REST)| Local-only (REST)| Yes | Yes |
45
45
  | SLSA-3 build provenance on releases | **Yes** | No | No | No | No |
46
- | Test count (public) | **872** | (varies) | (varies) | (varies) | (varies) |
46
+ | Test count (public) | **878** | (varies) | (varies) | (varies) | (varies) |
47
47
  | Tool count | 44 | ~25 | ~8 | ~10 | 3–5 |
48
48
  | MCP prompt count | 19 | 0 | 0 | 0 | 0 |
49
49
  | License | MIT | Apache-2.0 | MIT | MIT | (varies) |
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@oomkapwn/enquire-mcp",
4
- "version": "3.8.4",
4
+ "version": "3.8.6",
5
5
  "mcpName": "io.github.oomkapwn/enquire-mcp",
6
- "description": "MCP server giving AI agents (Claude Code, Claude Desktop, Cursor, ChatGPT, Codex, OpenClaw) persistent long-term memory backed by your local Obsidian markdown vault. Hybrid retrieval (BM25 + ML embeddings + BGE reranker, RRF-fused), HNSW + int8 quantization, agentic RAG (HyDE + sub-question decomposition), GraphRAG-light (Louvain), standalone Obsidian Bases, PDFs + Tesseract OCR. Vendor-neutral memory layer for any MCP-compatible agent. 44 tools, 19 MCP prompts, 872 tests, SLSA-3, semver-bound, MIT, zero cloud calls during serve.",
6
+ "description": "MCP server giving AI agents (Claude Code, Claude Desktop, Cursor, ChatGPT, Codex, OpenClaw) persistent long-term memory backed by your local Obsidian markdown vault. Hybrid retrieval (BM25 + ML embeddings + BGE reranker, RRF-fused), HNSW + int8 quantization, agentic RAG (HyDE + sub-question decomposition), GraphRAG-light (Louvain), standalone Obsidian Bases, PDFs + Tesseract OCR. Vendor-neutral memory layer for any MCP-compatible agent. 44 tools, 19 MCP prompts, 878 tests, SLSA-3, semver-bound, MIT, zero cloud calls during serve.",
7
7
  "type": "module",
8
8
  "bin": {
9
9
  "enquire-mcp": "dist/index.js"