@oomkapwn/enquire-mcp 3.10.1 → 3.11.0-rc.10
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 +189 -0
- package/README.ar.md +5 -5
- package/README.es.md +5 -5
- package/README.fr.md +334 -0
- package/README.hi.md +5 -5
- package/README.ja.md +329 -0
- package/README.md +10 -9
- package/README.pt.md +334 -0
- package/README.ru.md +334 -0
- package/README.zh.md +5 -5
- package/SECURITY.md +12 -2
- package/STABILITY.md +4 -2
- package/dist/bases.d.ts.map +1 -1
- package/dist/bases.js +36 -15
- package/dist/bases.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/dql.d.ts.map +1 -1
- package/dist/dql.js +15 -6
- package/dist/dql.js.map +1 -1
- package/dist/embed-db.d.ts +4 -1
- package/dist/embed-db.d.ts.map +1 -1
- package/dist/embed-db.js +4 -1
- package/dist/embed-db.js.map +1 -1
- package/dist/feedback.d.ts +83 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +219 -0
- package/dist/feedback.js.map +1 -0
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +41 -33
- package/dist/frontmatter.js.map +1 -1
- package/dist/fts5.d.ts +4 -1
- package/dist/fts5.d.ts.map +1 -1
- package/dist/fts5.js +14 -2
- package/dist/fts5.js.map +1 -1
- package/dist/hnsw.d.ts.map +1 -1
- package/dist/hnsw.js +7 -3
- package/dist/hnsw.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/name-fold.d.ts +58 -0
- package/dist/name-fold.d.ts.map +1 -1
- package/dist/name-fold.js +70 -0
- package/dist/name-fold.js.map +1 -1
- package/dist/parser.d.ts +20 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +31 -4
- package/dist/parser.js.map +1 -1
- package/dist/retrieval-opts.d.ts +17 -0
- package/dist/retrieval-opts.d.ts.map +1 -1
- package/dist/retrieval-opts.js +19 -0
- package/dist/retrieval-opts.js.map +1 -1
- package/dist/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +18 -3
- package/dist/server.js.map +1 -1
- package/dist/tool-manifest.d.ts +7 -5
- package/dist/tool-manifest.d.ts.map +1 -1
- package/dist/tool-manifest.js +9 -0
- package/dist/tool-manifest.js.map +1 -1
- package/dist/tool-registry.d.ts +21 -0
- package/dist/tool-registry.d.ts.map +1 -1
- package/dist/tool-registry.js +63 -2
- package/dist/tool-registry.js.map +1 -1
- package/dist/tools/meta.d.ts.map +1 -1
- package/dist/tools/meta.js +15 -9
- package/dist/tools/meta.js.map +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +11 -7
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/search.d.ts +12 -0
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +50 -6
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/write.d.ts +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +10 -4
- package/dist/tools/write.js.map +1 -1
- package/dist/watcher.d.ts +13 -0
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +13 -0
- package/dist/watcher.js.map +1 -1
- package/docs/COMPARISON.md +4 -4
- package/docs/api.md +5 -3
- package/package.json +13 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,195 @@
|
|
|
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.11.0-rc.10] — 2026-06-23
|
|
6
|
+
|
|
7
|
+
> **TL;DR:** **rc.9-audit response — the NFC class TRULY closed across the PRODUCER and KEY surfaces (2 HIGH).** A second external audit on the rc.9 commit (re-verified here by a 32-agent adversarial Workflow, 3 skeptics/finding) confirmed all 3 of my rc.9 downgrades — and correctly disputed the rc.9 L-TAG-1 "closed" claim as a **partial fix**: rc.9 hardened the tag *consumer* (compare) side but the *producer* (extraction) side and the frontmatter *key* side were uncovered siblings. **M1 (HIGH) — producer tag regexes dropped `\p{M}` combining marks:** on macOS APFS an NFD inline `#café` (`cafe`+U+0301) was captured as `cafe` BEFORE the rc.9 `nfc()` ran (normalize-after-extraction is too late), corrupting the **persisted FTS5 tag column** and defeating the exact dedup rc.9 added. Three producers — `parser.ts:170` (`TAG_RE`), `tools/meta.ts:221` (byte-identical copy), `bases.ts:652` (ASCII-only — dropped *every* non-Latin tag) — plus the `search.ts` TF-IDF tokenizer (LOW sibling). Fixed by **NFC-normalizing the text BEFORE matching** at every producer (composes the mark into the base letter so the regex captures the full token, and recovers any future combining mark), deduping the copy into a shared exported `INLINE_TAG_RE`, and making the Bases regex Unicode-aware (`\p{L}` + `u`). **H1 (HIGH) — frontmatter KEY lookups not case/NFC-folded:** rc.9 folded the *value* side but `frontmatter[key]` / `key in frontmatter` stayed exact-string at 6 sites (`search` filter_frontmatter, `dql` resolveField, `bases` `==`/`contains`, and `read.ts` `frontmatter_get` + `frontmatter_search` — the last two the auditor itself missed), so a `Status` filter silently missed `status` and an NFC key missed an NFD-on-disk key (Obsidian properties are case-insensitive). Fixed with a shared `lookupFoldedKey` that folds at LOOKUP time (exact-match wins, first-own-key-wins on a fold collision; never destructive at parse time → write fidelity preserved). **Structural defenses (the "improve the audits" ask):** a producer-completeness invariant (behavioral NFD/non-Latin extraction + a static "no ASCII-only `#[A-Za-z]` tag regex" gate) and a key-lookup invariant (`lookupFoldedKey` precedence/collision/NFC units) — converting "did we NFC-normalize at every text-INGEST + identity-KEY boundary?" into self-checking gates (the rc.9 invariant only patrolled the compare SITES). **1350 → 1358 tests** (+8). No API changes. **Re-verified ALREADY_OK (auditor wrong / no action):** M2 (renameNote backlink rewrite already folds via `findBestMatch`/`foldName`), M3 (`clear-cache` already erases `.tmp` — `clearDiskCache` has looped it since rc.36). DoS-cap LOWs (L1/L2: uncapped `search_text` query + `searchText` scan) → rc.11. Documents the rc.9 L-TAG-1 partial as overclaim instance.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **M1 (HIGH) — NFC tag PRODUCER class — `src/parser.ts`, `src/tools/meta.ts`, `src/bases.ts`, `src/tools/search.ts`.** Every inline-tag extractor now NFC-normalizes the body BEFORE applying the regex, so an NFD accented tag composes to its base letter and is captured whole (not truncated at the combining mark). `parser.ts` exports a shared `INLINE_TAG_RE`; `meta.ts` imports it (was a byte-identical copy); `bases.ts` is now Unicode-aware (`\p{L}` + `u`, was ASCII-only). The TF-IDF tokenizer (`search.ts`) NFC-normalizes before tokenizing (symmetry between an NFD body and an NFC query). **On-disk FTS5 indexes built before rc.10 hold the corrupted `cafe`; a reindex (re-run `build-embeddings`/`index` or let the watcher re-touch) heals them — newly-indexed notes self-heal.**
|
|
12
|
+
- **H1 (HIGH) — frontmatter KEY fold — `src/name-fold.ts` (`lookupFoldedKey`) + `search.ts`, `dql.ts`, `bases.ts` (×2), `read.ts` (×2).** Case/NFC-insensitive frontmatter key resolution at lookup time, matching Obsidian's case-insensitive property semantics; exact-key wins, first-own-key wins on a fold collision; the raw key map is never mutated (parse-time fold would corrupt write round-trips). `read.ts` `frontmatter_get`/`frontmatter_search` were the two sites the external audit missed.
|
|
13
|
+
|
|
14
|
+
### Tests / structural defenses
|
|
15
|
+
|
|
16
|
+
- **`tests/name-fold-invariant.test.ts`** — +8: a **producer-completeness** invariant (behavioral: `extractInlineTags` recovers an NFD `#café` + a non-Latin `#日本語`; static: no `src/` tag regex uses an ASCII-only `#[A-Za-z]` lead, + NEGATIVE control) and a **key-lookup** invariant (`lookupFoldedKey` case-insensitive / NFC-insensitive / exact-wins / collision-first-wins / absent). These close the why-missed: the rc.9 invariant patrolled fold-*helper* usage at compare sites and was structurally blind to the producer regex char-class AND the key-lookup path.
|
|
17
|
+
|
|
18
|
+
## [3.11.0-rc.9] — 2026-06-23
|
|
19
|
+
|
|
20
|
+
> **TL;DR:** **External re-audit response (rc.5 report, re-verified against HEAD) — the NFC-tag class + its uncovered value siblings, closed structurally.** An external auditor reviewed the rc.5 commit (0 CRIT / 0 HIGH / 1 MED / 1 LOW / 3 INFO). Per the project's per-item re-verification discipline I re-verified every finding against current HEAD with a 4-lens adversarial Workflow (re-verify + concurrency / full-NFC / semantic-fallback sweeps, 3 skeptics per verdict, 20 agents). Outcome: **1 LOW confirmed real and EXPANDED, 1 MED + 2 INFO downgraded with reasons, + 4 new siblings the auditor missed.** **L-TAG-1 (LOW, real):** tag comparisons lowercased WITHOUT NFC across ~13 sites — an accented `#café` tag stored NFD (macOS) silently failed to match its NFC query form. The rc.46 NFC name-fold class was never generalized to the parallel TAG identity surface (three hand-rolled `#`-strip-then-lowercase helpers bypassed `foldName`). Closed via a shared `foldTag`/`nfcLower`/`nfc` in `name-fold.ts` routed through every tag + frontmatter-value comparison (parser producer, meta/read/write/search/dql/bases), **plus the name-fold inventory invariant extended with the tag signature** (the why-missed root cause: its detector matched only the `.md`-strip shape) + behavioral NFD→NFC tests (dql `FROM #tag`, bases `tag ==`/`status ==`). **New siblings (auditor missed):** DQL `FROM #tag` was NFC-blind even though rc.8 fixed the `WHERE`-value path in the same file; `obsidian_search` `filter_frontmatter` value match + `bases.ts` frontmatter `==`/`contains` were NFC-blind (rc.8 DQL-value siblings on other surfaces). **Rejected/downgraded (documented):** **T-MED-1 (MED → FALSE POSITIVE)** — `applyDiff`/`syncHnswForFile` are fully synchronous, so cross-file watcher events CANNOT interleave (JS run-to-completion); the auditor's proposed mutation queue would be redundant. Instead pinned the real property with `tests/hnsw-sync-critical-section.test.ts` (no `await` in the critical section) + a TSDoc contract. **I-HNSW-1 (INFO → WAI)** — `capacity()` has zero production callers; fixed the fallback to an honest `Infinity` sentinel anyway. **I-COV-1 (INFO, mechanism FALSE)** — the spawned `dist/` child is NOT coverage-instrumented (vitest v8 uses the inspector, not `NODE_V8_COVERAGE`); but re-verification surfaced a *real* adjacent risk (coverage CI job `timeout-minutes: 5` vs the test job's 10 while doing more work) → bumped to 10. Plus stale `peek*Meta` "throws only on…" TSDocs corrected (never-throw since rc.33/34). **1340 → 1350 tests** (+10). No API changes. **⚠️ Scope correction (post-ship, rc.9 external audit):** this closed the NFC-tag class on the CONSUMER side (the fold helpers + comparison sites) — a follow-up external audit on this commit confirmed that but found the class is only PARTIALLY closed: the tag-extraction regex (`parser.ts`/`meta.ts`/`bases.ts`) drops `\p{M}` combining marks, so an NFD inline `#café` is captured as `cafe` BEFORE folding (the producer-side leg), and frontmatter KEYS remain NFC/case-blind (HIGH H1). Full producer-side closure + the frontmatter-key fix land in **rc.10** (the rc.9-audit response). The "closed structurally" phrasing above is scoped to the consumer side.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **NFC-tag class (L-TAG-1) — `src/name-fold.ts` + parser/meta/read/write/search/dql/bases.** New `foldTag(t)` (strip `#` + NFC + lowercase), `nfcLower(v)` (NFC + lowercase, value surface — centralizes the rc.8 DQL-local copy), and `nfc(v)` (NFC only, case-preserving). The parser producer NFC-normalizes stored tags (display case kept) so `collectTags` dedups two Unicode forms to one; every tag comparison + every frontmatter-value comparison routes through the shared helpers. Bases keeps case-sensitivity (NFC-only, per Obsidian Bases semantics); DQL/search keep case-insensitivity (NFC + lowercase, matching their prior `.toLowerCase()` contract).
|
|
25
|
+
- **DQL `FROM #tag` NFC (new sibling) — `src/dql.ts`.** rc.8 NFC-fixed the `WHERE`-value comparators but left the dedicated `#tag` source path on `.toLowerCase()`; now folds via `foldTag`.
|
|
26
|
+
- **`obsidian_search` `filter_frontmatter` value NFC (new sibling) — `src/tools/search.ts`.** `frontmatterScalarEq` NFC-folds both operands (`nfcLower`) — the rc.8 DQL value fix's search-surface sibling.
|
|
27
|
+
- **`.base` frontmatter-value NFC (new sibling) — `src/bases.ts`.** `<key> ==` / `contains` NFC-normalize both sides (case-preserved), parity with the rc.73 path fix + the DQL twin.
|
|
28
|
+
- **`capacity()` honest fallback (I-HNSW-1) — `src/hnsw.ts`.** The `!hasLiveUpdate` fallback returned `maxElements: size` (cap == count → "0 free slots"); now `Number.POSITIVE_INFINITY` (capacity unknown / unbounded). Zero production callers; latent only.
|
|
29
|
+
- **Coverage CI job timeout (I-COV-1 re-verify) — `.github/workflows/ci.yml`.** `coverage` job `timeout-minutes` 5 → 10 (parity with `test`, which does less); removes a latent flake-blocks-release risk on a slow runner.
|
|
30
|
+
- **Stale `peek*Meta` TSDocs — `src/embed-db.ts`, `src/fts5.ts`.** "Throws only on actual SQLite open/read errors" corrected to "never throws — any failure → null" (true since rc.33/34 wrapped `new Database()` in the catch).
|
|
31
|
+
|
|
32
|
+
### Tests / structural defenses
|
|
33
|
+
|
|
34
|
+
- **`tests/name-fold-invariant.test.ts`** — extended with a TAG-signature detector (`#`-strip-then-lowercase, both orderings) + POSITIVE class gate (0 unfolded tag sites in `src/`) + NEGATIVE control + `foldTag`/`nfc` unit tests. Closes the root cause the auditor exploited: the rc.46 inventory invariant's detector was scoped to the note-NAME shape and was structurally blind to the tag surface.
|
|
35
|
+
- **`tests/hnsw-sync-critical-section.test.ts`** (new) — asserts `applyDiff` + `syncHnswForFile` contain no `await` in the shared-state critical section (the real T-MED-1 safety property) + NEGATIVE control. A future `async` refactor that opens a cross-file interleave window now fails CI.
|
|
36
|
+
- Behavioral NFD→NFC nets: dql `FROM #<nfd-tag>`, bases `tag ==`/`taggedWith`/`status ==`/`contains`.
|
|
37
|
+
|
|
38
|
+
## [3.11.0-rc.8] — 2026-06-23
|
|
39
|
+
|
|
40
|
+
> **TL;DR:** **Pre-promotion audit response — 5 confirmed findings (1 MED + 4 LOW), 0 CRIT / 0 HIGH.** Before commissioning the external v3.11.0 → `@latest` audit, I ran a from-scratch state-driven full-project audit (7 lenses, 3-skeptic adversarial verify, 25 agents) on the rc.7 commit. It was exceptionally clean — but the one MED validated running it: a **remotely-triggerable prototype-pollution** in the freshest v3.11.0 surface (`obsidian_mark_useful`). All 5 fixed here. The MED: `FeedbackStore`'s `entries` map was a plain object, so an agent calling `obsidian_mark_useful` with `paths:["__proto__"]` (when `--feedback-weight > 0`, bearer-reachable on serve-http) resolved `entries["__proto__"]` to `Object.prototype` and polluted it process-wide; now a **null-prototype map** (`Object.create(null)`) makes such keys harmless own keys. The 4 LOW: DQL frontmatter-value `=`/`contains` weren't NFC-folded (the rc.69 NFC class's last uncovered sibling — the value surface); `renameNote`'s rc.60 WRITE-1 dest-exclusion was case-sensitive (a case-variant overwrite dest reopened the data-loss on a case-insensitive FS); `CITATION.cff` was stale at v3.9.1 across two stable promotions (now pinned to the latest stable by a new docs-consistency guard); `docs/COMPARISON.md` tied the 46-tool count to "v3.8.x stable" (which had 44). **1336 → 1340 tests** (+4: proto-pollution NEGATIVE control, DQL NFC regression, case-variant-rename regression, CITATION drift guard). No API changes. AUDIT-REQUEST doc for the external pass committed under `docs/audits/`.
|
|
41
|
+
|
|
42
|
+
### Security
|
|
43
|
+
|
|
44
|
+
- **`src/feedback.ts` [MED] — prototype-pollution via `obsidian_mark_useful`.** `FeedbackStore.record()` writes agent-supplied path strings directly as keys of `this.data.entries`. When that map is a plain object, `paths:["__proto__"]` makes `entries["__proto__"]` resolve to `Object.prototype`, and `e.useful += 1` / `e.lastMarked = …` mutate the shared prototype for the whole process (remotely reachable by any bearer-authenticated serve-http client when `--feedback-weight > 0`; the zod `z.array(z.string())` schema does not sanitize string VALUES — the unique tool where agent strings become object keys without `z.record()`'s key-stripping). Fixed by initializing `entries` as a **null-prototype map** (`Object.create(null)`) at both the default-data site and `open()`'s rebuild loop, so `__proto__`/`constructor` become harmless own keys (a note literally named `__proto__.md` still round-trips). NEGATIVE control asserts `record(["__proto__","constructor","Real.md"])` leaves `Object.prototype` unpolluted and stores all three as own keys.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- **`src/dql.ts` [LOW] — DQL frontmatter-value `=` / `!=` / `contains` were not NFC-normalized.** The rc.69 NFC fix covered the virtual `file.name`/`file.path` projections + the predicate literal, but arbitrary frontmatter values flow through `resolveField`'s `default` branch un-normalized, so `WHERE author = "café"` (NFC literal) silently missed an NFD-stored value. Added an `nfcLower` helper and routed both `looseEq`'s string branch and the string-`contains` branch through it (the shared sinks), matching the already-NFC literal. The `name-fold-invariant` couldn't see this — its signature targets note-NAME comparisons, not value equality. Bounded impact (degrades to fewer matches, never wrong/leaked results). +1 regression test (NFD value vs NFC literal, with a non-matching NEGATIVE control).
|
|
49
|
+
- **`src/tools/write.ts` [LOW] — `renameNote` rc.60 WRITE-1 dest-exclusion was case-sensitive.** `isDest = e.absPath === toAbsCheck` compared the on-disk (canonical-case) `e.absPath` against the user-cased `toAbsCheck`, so on a case-insensitive FS a case-variant `to` (e.g. `Posts/Existing.md` for on-disk `posts/existing.md`) wasn't excluded from the backlink-rewrite plan — and with `overwrite=true` + the dest backlinking the source, the plan clobbered the just-moved source (rc.60 data-loss, reopened for that scenario). Now also matches against the realpath-canonical `canonicalToRel` already computed for the privacy check. +1 regression test (case-insensitive-FS-gated, exercised on the macOS CI leg).
|
|
50
|
+
- **`CITATION.cff` [LOW] — version stale at v3.9.1 across two stable promotions.** The file's own contract is "`version` tracks the @latest STABLE line," but it was never bumped at v3.10.0 / v3.10.1 (it's deliberately excluded from `check-version-consistency.mjs`, and no invariant pinned it). Bumped to `version: "3.10.1"` / `date-released: "2026-06-22"`, and added a `docs-consistency.test.ts` **drift guard** asserting `CITATION.cff` version equals the latest STABLE (non-rc) CHANGELOG heading — so the next stable promotion can't forget it.
|
|
51
|
+
- **`docs/COMPARISON.md` [LOW] — 46-tool count tied to the wrong version.** Line 60 said the 46-tool count "is exact for v3.8.x stable" — but v3.8.x had 44 tools (44→45 in v3.10, 45→46 in v3.11.0). `docs-consistency` keeps the NUMBER correct but nothing gated the version LABEL. Decoupled: "…exact as of the current release…".
|
|
52
|
+
|
|
53
|
+
## [3.11.0-rc.7] — 2026-06-23
|
|
54
|
+
|
|
55
|
+
> **TL;DR:** **CI-guard flake hardening — a transient gh-auth blip can no longer block a release.** During the rc.6 ship, `tests/github-metadata-invariant.test.ts`'s "CI GUARD — gh is actually authenticated" test flaked: `gh auth status` makes a network call to validate the token, and it transiently failed on the main-push run (the identical commit had PASSED on the PR run minutes earlier). That failed CI and blocked the rc.6 publish (`release.yml`'s "assert CI green on main" guard correctly refused) until a manual re-run. Same flake-blocks-a-release class as the rc.20 `npm ci` incident. Fix: a bounded retry (`retryUntil`, 3 attempts / 750 ms backoff) around the network-y `gh auth status` + `gh api` calls — recovering a momentary blip **without** masking a genuine auth failure (every attempt must fail before concluding "unavailable"). Test-infra only. **1335 → 1336 tests.**
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- **`tests/github-metadata-invariant.test.ts`** — extracted `ghAuthStatusOnce` / `fetchRepoMetaOnce` and wrapped both in a generic `retryUntil(attempt, ok, attempts, backoffMs, sleep)` helper. `ghIsAvailable()` + `fetchRepoMeta()` now retry **only in a CI/token context** (`CI || GH_TOKEN || GITHUB_TOKEN`), so pure local dev without a token still fails fast (1 attempt, no backoff penalty on every `npm test`). The CI-GUARD reuses the once-computed `available` (no second retry storm) and now fails only after the retry is exhausted — a genuine broken-token regression, not a single transient blip. Synchronous backoff via `Atomics.wait` (no busy-spin).
|
|
60
|
+
|
|
61
|
+
### Tests (1336)
|
|
62
|
+
|
|
63
|
+
- New control (`+1`): `retryUntil recovers a transient blip but still fails a genuine no-auth` — NEGATIVE control proves a truly-unauthenticated gh (every attempt fails) still returns `false` *after exhausting all retries* (the guard still fails loudly); POSITIVE controls prove a fail-twice-then-succeed sequence recovers to `true`, and a first-try success makes exactly one probe (no wasted retries). `sleep` is injected so the controls run instantly.
|
|
64
|
+
|
|
65
|
+
### Notes
|
|
66
|
+
|
|
67
|
+
- Preserves the guard's purpose: it still hard-fails in CI when `GH_TOKEN` is set but `gh` is genuinely unauthenticated (the About/Topics invariants would otherwise silently no-op). Only transient network/API errors are now tolerated. Closes the spawn-task flagged after the rc.6 publish-recovery.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## [3.11.0-rc.6] — 2026-06-23
|
|
72
|
+
|
|
73
|
+
> **TL;DR:** **js-yaml 4 → 5 migration (#275) — the deferred major, done deliberately.** Closes the last open dependabot major. js-yaml@5 is a *behavioral* major in the frontmatter/`.base` area, so this is a real migration, not a bump: (1) v5 no longer coerces YAML timestamps to `Date` — bare dates / timestamps load as **strings** that round-trip FAITHFULLY, which **root-fixes** the rc.58 date-mutation bug (no more silent time-appending) and dissolves the rc.66 midnight/timestamp collision; (2) v5 **`load("")` throws** ("expected a document") where v4 returned `undefined` → `bases.ts parseBase` now guards an empty `.base` body; (3) v5 **does not resolve YAML merge keys (`<<`)** — which is *why* GHSA-h67p-54hq-rp68 is gone at the ROOT in v5, not merely patched; (4) the now-redundant `@types/js-yaml` devDep is **removed** (v5 ships its own types). Scalar resolution (octal/sexagesimal/underscore — the rc.54 contracts) is **identical** on @4 and @5, re-verified. **1333 → 1335 tests.**
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
|
|
77
|
+
- **`js-yaml`** `^4.2.0` → `^5.0.0` (resolved 5.1.0; direct dep; closes dependabot #275). The frontmatter port + `.base` parser run unchanged on v5's `load`/`dump`; behavioral deltas handled below.
|
|
78
|
+
- **Removed `@types/js-yaml`** (devDep) — js-yaml@5 bundles its own type declarations; `tsc` strict builds clean on them.
|
|
79
|
+
- **`src/bases.ts`** `parseBase` guards an empty/whitespace-only `.base` body to `{}` before `load` (v5 `load("")` throws; preserves the v4 `load(body) ?? {}` contract).
|
|
80
|
+
- **`src/frontmatter.ts`** header + `normalizeDateOnly` TSDoc rewritten to v5 reality: dates load as strings (faithful round-trip), `normalizeDateOnly` is now DEFENSIVE-ONLY (fires only for a directly-passed `Date`), merge keys dropped, empty-input throw documented. `parseFrontmatter` is unaffected (its `block !== ""` guard never calls `load` on empty input).
|
|
81
|
+
|
|
82
|
+
### Tests
|
|
83
|
+
|
|
84
|
+
- `tests/frontmatter.test.ts`: the rc.58/rc.66 date contracts re-derived for v5 — an explicit midnight-UTC timestamp is now **preserved verbatim** (no Date coercion → no collapse); a direct-`Date` unit pins `normalizeDateOnly`'s now-defensive midnight branch; a new **merge-key security contract** test pins that `<<` stays a literal key (a future engine that silently re-enables merge-key expansion fails CI). Stale `Date`-era comments refreshed across the suite.
|
|
85
|
+
|
|
86
|
+
### Notes
|
|
87
|
+
|
|
88
|
+
- The whole `js-yaml@4` → `@5` reference sweep landed across SECURITY.md (the `.base` threat-model now states merge keys are removed in v5, not "fixed in v4"), README ×5, `docs/api.md`, `read.ts`/`write.ts`/`bases.ts` TSDoc, and the test comments. `node scripts/check-audit.mjs` is clean on js-yaml@5 (allowlist still empty). The migration was verified on the installed **5.1.0** with a fresh v4-vs-v5 differential (scalar contracts unchanged; the date/merge-key/empty-input deltas are the three handled above) before any code change — the rc.54 differential discipline.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## [3.11.0-rc.5] — 2026-06-23
|
|
93
|
+
|
|
94
|
+
> **TL;DR:** **Dependency majors — the two GO ones, after isolated-worktree evaluation.** Each of the three open dependabot majors was checked out in its own worktree and run through the full gate battery before deciding. **Merged:** `@types/node` 25.9.3 → **26.0.0** (#273 — types-only; `tsc` strict + 1427 tests clean) and `actions/checkout` 6.0.2 → **7.0.0** (#271 — SHA verified against the real v7.0.0 tag; v7's `node24` runtime is supported on our GitHub-hosted runners). **Deferred (NOT merged):** `js-yaml` 4 → **5** (#275) — a genuine behavioral major in the frontmatter/bases area (v5 drops `Date` coercion + merge-key resolution and makes `load("")` throw), breaking 2 pinned contracts; it needs a deliberate migration RC, not an auto-bump. Deps/CI-config only — no source/API change. **1333 tests unchanged.**
|
|
95
|
+
|
|
96
|
+
### Changed
|
|
97
|
+
|
|
98
|
+
- **`@types/node`** `^25.9.3` → `^26.0.0` (dev; closes dependabot #273). Verified in an isolated worktree: `npm ci`, `tsc` (strict + `noUncheckedIndexedAccess`), the full 1427-test suite, and lint all clean — a types-only bump with no runtime surface.
|
|
99
|
+
- **`actions/checkout`** `6.0.2` → `7.0.0` across all 4 workflows (13 pins; closes dependabot #271). Pinned to the verified v7.0.0 commit SHA `9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0`. **Also corrected the `# vN` comment** dependabot left stale — all 13 pins now read `# v7` (the bump had kept `# v6` on the v7 SHA). checkout v7 runs on `node24`, supported by our GitHub-hosted `ubuntu-latest`/`macos-latest` runners.
|
|
100
|
+
|
|
101
|
+
### Notes
|
|
102
|
+
|
|
103
|
+
- **`js-yaml` 5.0.0 (#275) deferred — evaluated, NO-GO as a bump.** A v4-vs-v5 differential + the test suite found four behavioral changes in the project's most-hardened area: (1) timestamps/bare dates load as **strings**, not `Date` (so the rc.58/rc.66 `normalizeDateOnly` date-collapse contract fails); (2) **`load("")` throws** `YAMLException: expected a document` where v4 returned `undefined` (breaks `parseBase`'s `load(body) ?? {}`); (3) **merge keys (`<<`) are no longer resolved** — which is *why* GHSA-h67p-54hq-rp68 is gone in v5 (fixed at the root, not version-bumped); (4) the bump leaves `@types/js-yaml@4` redundant (v5 bundles its own types). 2 pinned tests fail under v5. The upside (v5 removes the Date-mutation root cause and the merge-key advisory at the source) makes it worth a **deliberate migration RC** later — guarding `load("")`, re-deriving the date contracts under string semantics, dropping `@types/js-yaml`, re-running the differential corpus.
|
|
104
|
+
- `node scripts/check-audit.mjs` clean after re-resolution (allowlist still empty).
|
|
105
|
+
- Synced 3 stale `// current X%` coverage annotations in `scripts/check-per-file-coverage.mjs` (OIA Check 6 drift, pre-existing, surfaced when rc.4's coverage run refreshed the summary): `ocr.ts` branches 74.41→71.11, `http-transport.ts` 77.61→75.23, `media.ts` 67.93→69.17. The floors themselves are unchanged.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## [3.11.0-rc.4] — 2026-06-22
|
|
110
|
+
|
|
111
|
+
> **TL;DR:** **Post-rc.1–rc.3 audit response (11-lens adversarial workflow; 0 CRIT / 0 HIGH-code).** The feedback feature re-swept **clean** (provably loss-free / tmp-leak-free); the 45→46 cascade + dep bumps + i18n invariants verified sound. Real findings were concentrated in the **9-language README surface**: (1) **6 broken in-file anchors** across 4 READMEs — incl. a **pre-existing bug in the canonical README.md** (the tests badge linked `#trust`, but "🛡️ Trust" slugs to `️-trust` with a leading variation-selector, so it never resolved), plus README.ru.md's 3 un-localized nav/badge anchors and fr/pt's `#trust`. Fixed to exact github-slugger slugs + a new **anchor-integrity invariant** (`tests/readme-anchor-invariant.test.ts`) that resolves every in-file `(#anchor)` in all 9 READMEs against its heading slugs. (2) **Test-count drift** — the rc.2 translations were born at `1329` and zh/es/hi/ar/AGENTS carried a stale `1311+`; all surfaces synced to the canonical **1333**. (3) the rc.3 CHANGELOG mischaracterized `markdown-it` as a direct dev bump (it is transitive via typedoc). (4) the `prune --help` text omitted the `.feedback.json` family it now erases. (5) the feedback concurrency test was **vacuous** (passed even with serialization removed) → reworked to assert zero tmp-rename collisions, mutation-verified to discriminate. Plus two INFO hardenings on `feedback.ts` (per-write `chmod 0600` defense-in-depth; `record()` entry-count hoisted out of its loop). **1331 → 1333 tests.**
|
|
112
|
+
|
|
113
|
+
### Fixed
|
|
114
|
+
|
|
115
|
+
- **README anchors (HIGH).** All in-file `(#anchor)` links in the 9 READMEs now resolve. `README.md`'s tests badge `#trust` → `#️-trust` (the Trust heading's true slug; pre-existing since the section was added — no gate checked link targets). `README.ru.md` nav/badge `#-quick-start`/`#-use-cases`/`#trust` → localized slugs; `README.fr.md` / `README.pt.md` `#trust` → localized. Verified with `github-slugger` (the exact algorithm GitHub's renderer uses).
|
|
116
|
+
- **Test-count sync (MED/LOW).** Every test-count surface set to the canonical **1333**: `README.md` (badge + stat + table + npm-test), `llms.txt`, `package.json`, `ROADMAP.md`, `docs/COMPARISON.md`; the 8 translations (stat lower-bound `1333+`, fr/ru/pt badges `tests-1333`, ru/fr/pt/ja table + contributing rows); `AGENTS.md` `1311+` → `1333+`. `CLAUDE.md` rc.1 bullet corrected `1313 → 1329` → `1313 → 1331` (the seed of the `1329` propagation).
|
|
117
|
+
- **rc.3 CHANGELOG accuracy (MED).** `markdown-it 14.2.0` reframed as a **transitive** resolution under typedoc's `^14.1.1` range (lockfile-only), not a declared dev-dependency bump.
|
|
118
|
+
- **`prune --help` (LOW).** The `prune` command description now lists `feedback.json` among the erased artifact families, matching `ENQUIRE_CACHE_ARTIFACT` and SECURITY.md's right-to-erasure claim.
|
|
119
|
+
- **feedback concurrency test (MED).** The "serialized writes" test was vacuous (the shared in-memory map made the file coherent regardless of serialization). Reworked to assert **zero** `feedback persist failed` stderr lines — mutation-verified: removing the `persistChain` makes it fail with the exact ENOENT tmp-rename collisions.
|
|
120
|
+
|
|
121
|
+
### Changed
|
|
122
|
+
|
|
123
|
+
- **`src/feedback.ts` (INFO hardenings).** `writeOnce()` re-asserts `chmod 0600` on the landed sidecar after rename (defense-in-depth parity with the fts5/embed-db writers, so SECURITY.md's "0600 sidecar" is an enforced guard, not only writeFile's create-time mode). `record()` hoists the entry count out of its per-path loop (was re-allocating `Object.keys()` per path at the cap).
|
|
124
|
+
- **devDependency** `github-slugger` `^2.0.0` added — the canonical, zero-dependency GitHub slug implementation, used only by the new anchor-integrity invariant. `scripts/check-audit.mjs` clean after the add (allowlist still empty).
|
|
125
|
+
|
|
126
|
+
### Notes
|
|
127
|
+
|
|
128
|
+
- The audit's INFO/verified-clean items are recorded without action: the feedback `FeedbackStore` is sound (serialized persists are loss-free and tmp-leak-free), the 45→46 tool cascade + feedback gating are fully self-consistent, the rc.3 direct dep bumps match package.json + lockfile, and the 9-language numeric/switcher invariants genuinely discriminate.
|
|
129
|
+
- New structural defense: `tests/readme-anchor-invariant.test.ts` (+ NEGATIVE control) closes the anchor-drift class for the i18n surface — a future heading/anchor edit that breaks a link fails CI.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## [3.11.0-rc.3] — 2026-06-22
|
|
134
|
+
|
|
135
|
+
> **TL;DR:** **Dependency hygiene — safe-patch bundle.** Applied the three **direct** non-major dependabot updates: `better-sqlite3` 12.10.1 → **12.11.1**, `vitest` + `@vitest/coverage-v8` → **4.1.9**, `sharp` → **0.35.2**. A fourth (`markdown-it` → **14.2.0**, dependabot #242) is a **transitive** resolution under typedoc's existing `^14.1.1` range — lockfile-only, not a direct dependency. All patch/minor, in-range; `npm audit` clean after re-resolution (no new transitive advisories); full suite green under vitest 4.1.9. Deps only — no source/API change. **1331 tests unchanged.** The 3 **major** dependabot PRs (js-yaml 4→5, @types/node 26, actions/checkout 7) are deliberately **not** included — they need isolated verification and are maintainer-gated.
|
|
136
|
+
|
|
137
|
+
### Changed
|
|
138
|
+
|
|
139
|
+
- **better-sqlite3** `^12.10.1` → `^12.11.1` (optional dep; closes dependabot #274).
|
|
140
|
+
- **@vitest/coverage-v8** + **vitest** `4.1.8` → `4.1.9` (matched dev pair; part of dependabot #272).
|
|
141
|
+
- **sharp** `^0.35.1` → `^0.35.2` (dev; part of dependabot #272).
|
|
142
|
+
- **markdown-it** `14.1.1` → `14.2.0` (**transitive** via typedoc's `^14.1.1` range, resolved on lockfile re-resolution — NOT a declared dependency; closes dependabot #242).
|
|
143
|
+
|
|
144
|
+
### Notes
|
|
145
|
+
|
|
146
|
+
- `node scripts/check-audit.mjs` clean (prod ≥ moderate / dev ≥ high; allowlist still empty). The re-resolution surfaced no new advisories — per the recurring lesson, a dep bump's `npm install` re-resolves the whole tree against the live advisory DB, so the scoped audit gate was run as part of this RC.
|
|
147
|
+
- **Deferred (maintainer's call):** js-yaml 4→5 (⚠️ the project just migrated onto js-yaml@4 in rc.53 — a major needs isolated frontmatter verification), @types/node 26, actions/checkout 7.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## [3.11.0-rc.2] — 2026-06-22
|
|
152
|
+
|
|
153
|
+
> **TL;DR:** **Internationalization round 2 — README now in 9 languages.** Added **Russian** (`README.ru.md`), **Brazilian Portuguese** (`README.pt.md`), **French** (`README.fr.md`), and **Japanese** (`README.ja.md`) alongside English + 中文 + Español + हिन्दी + العربية. Every README carries a **9-way language switcher**; the four new files ship in the npm tarball, and the existing structural guards were extended to cover them. Docs only — no code/API change. **1331 tests unchanged** (the i18n invariants are data-driven, no new `it()`).
|
|
154
|
+
|
|
155
|
+
### Added
|
|
156
|
+
|
|
157
|
+
- **README translations for Russian, Portuguese, French, and Japanese** (`README.ru.md`, `README.pt.md`, `README.fr.md`, `README.ja.md`) — full translations of the English README with badges, links, code blocks, CLI flags, and tool names preserved verbatim; only prose translated. Generated via a 4-agent parallel translation Workflow. With the existing EN/zh/es/hi/ar, enquire's README now covers **9 of the most-spoken languages**.
|
|
158
|
+
- **9-way language switcher** (`[English] · [中文] · [Español] · [हिन्दी] · [العربية] · [Русский] · [Português] · [Français] · [日本語]`) on every README (current language bolded). All four new files in `package.json` `files[]`.
|
|
159
|
+
|
|
160
|
+
### Tests (1331)
|
|
161
|
+
|
|
162
|
+
- The per-language numeric-claim invariant (tools/prompts exact, tests `N+` lower bound) extended to ru/pt/fr/ja — the Russian regex matches `1329+ модульных тестов`, the Japanese the spaced `MCP プロンプト`. The switcher cross-link guard extended from 5 → **9 READMEs** (each links the other 8, bolds itself). Both are data-driven (no new `it()`), so the canonical count stays **1331**.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## [3.11.0-rc.1] — 2026-06-22
|
|
167
|
+
|
|
168
|
+
> **TL;DR:** **Closed-loop retrieval feedback (the "Karpathy loop") — the 46th tool, opt-in.** New `obsidian_mark_useful` (gated by `--feedback-weight <0..1>`, default **0 = OFF**): an agent records which recalled notes actually helped a query; the recorded usefulness then gently boosts those notes in subsequent `obsidian_search` results — a provable no-op at weight 0, mirroring the rc.5 recency boost. State lives in a per-vault cache sidecar (relative paths + counts only — **no note content, no query text**), erased by `prune`. Ships on `@rc`; `@latest` promotion is maintainer-gated. **45 → 46 tools · 1313 → 1331 tests.** No API breaks (additive minor).
|
|
169
|
+
|
|
170
|
+
### Added
|
|
171
|
+
|
|
172
|
+
- **`obsidian_mark_useful` (46th tool, opt-in via `--feedback-weight`)** — closes the retrieval feedback loop. The agent passes the `path`(s) of the search hits that actually helped (or `useful: false` for ones that looked relevant but didn't); the per-note tally feeds a Laplace-smoothed score `useful/(useful+notUseful+1)`.
|
|
173
|
+
- **`--feedback-weight <w>`** (in `addAdvancedRetrievalOptions`, so both `serve` + `serve-http` accept it). When `w > 0`, registers the tool and blends feedback into the fused `obsidian_search` order: `(1-w)·relevanceRank + w·feedbackScore`, applied AFTER recency re-ranking. `w = 0` (default) is a provable no-op — no tool registered, ranking stays purely relevance-driven.
|
|
174
|
+
- New leaf module `src/feedback.ts` (`FeedbackStore` + `defaultFeedbackFile` + `feedbackScore`). The store loads once in `prepareServerDeps` (shared across HTTP sessions so a mark in one session influences the boost in all — an in-session closed loop), persists atomically (tmp + rename), and is capped at `MAX_FEEDBACK_ENTRIES` (100,000) to bound disk growth.
|
|
175
|
+
|
|
176
|
+
### Privacy / security
|
|
177
|
+
|
|
178
|
+
- The feedback sidecar (`<vault-hash>.feedback.json`) holds **only** relative note paths + integer counts + an ISO timestamp — never note content or query text (lower sensitivity than `.fts5.db` / `.embed.db`). `0600`, atomic writes.
|
|
179
|
+
- **Right-to-erasure:** the sidecar matches the `ENQUIRE_CACHE_ARTIFACT` pattern, so a cross-vault `enquire-mcp prune` erases a decommissioned vault's feedback (+ any `.tmp` leftover) — pinned by the erasure-completeness invariant. Preserved across `clear-cache` (user-generated signal, not regenerable cache). New SECURITY.md section "Closed-loop feedback store: data-at-rest posture".
|
|
180
|
+
- **K-3:** `obsidian_mark_useful` is annotated `...WRITE` (honest `readOnlyHint: false`, consistent with the additive `obsidian_append_to_note`) via a named `markUseful` handler. It mutates the feedback STORE, not the vault — so it's gated by `--feedback-weight`, not `--enable-write`.
|
|
181
|
+
- **Pre-ship adversarial audit** (4 lenses × 3-skeptic verify; 0 CRIT/0 HIGH) hardened two `FeedbackStore.persist()` issues before tag: (1) it now creates the cache dir `0700` + chmods it when it's the creator (mirroring the sibling cache writers, so SECURITY.md's "Parent dir mode is 0700" holds even when feedback is the first writer to materialize `<cache>/enquire`); (2) writes are **serialized** behind a per-store promise chain — the store is shared across serve-http sessions and the SDK dispatches concurrently, so unsynchronized writes to the shared `.tmp` could interleave into a torn file that the fail-soft `open()` would silently discard. The 4 translated-README breakdown sentences were also corrected to the 46-tool count. +2 tests (dir-mode + 25-way concurrent-persist).
|
|
182
|
+
|
|
183
|
+
### Tests (1331)
|
|
184
|
+
|
|
185
|
+
- `tests/feedback.test.ts` (+16): the store (open/record/scores/cap/fail-soft/atomic-persist), `defaultFeedbackFile` dir+hash parity with `defaultIndexFile`, prune erasure of the feedback family, and the `searchHybrid` boost — a PROVABLE no-op at weight 0 + a marked note rising at weight 1, each with a NEGATIVE control.
|
|
186
|
+
- Erasure-invariant gains the feedback family (writers ⊆ prune-eraser); K-3 `KNOWN_WRITE_HANDLERS` gains `markUseful`; cli-parity flag count 13 → 14; docs-consistency api.md-math + STABILITY-gating + llms-breakdown regexes extended for the new `feedback` term. **1313 → 1331.**
|
|
187
|
+
|
|
188
|
+
### Count cascade (45 → 46)
|
|
189
|
+
|
|
190
|
+
- `TOOL_MANIFEST` gains a `feedback` kind + `--feedback-weight` gating; STABILITY.md (+ Feedback section), `docs/api.md` (tool table + flag table + count math), README.md + all four translations (zh/es/hi/ar), llms.txt, AGENTS.md, COMPARISON.md, ROADMAP.md all updated to 46. All numeric-claim invariants stay green.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
5
194
|
## [3.10.1] — 2026-06-22
|
|
6
195
|
|
|
7
196
|
> **TL;DR:** **Internationalization — README in the top-5 most-spoken languages.** Added full **Spanish** (`README.es.md`), **Hindi** (`README.hi.md`), and **Arabic** (`README.ar.md`, RTL) translations alongside English + 中文, with a 5-way language switcher on every README, npm `files[]` inclusion, and structural guards (per-language numeric-claim invariants + a switcher cross-link guard). Docs only — no code/API change. **1311 → 1313 tests** (+2 invariants).
|
package/README.ar.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# enquire-mcp
|
|
6
6
|
|
|
7
|
-
<sub>[English](./README.md) · [中文](./README.zh.md) · [Español](./README.es.md) · [हिन्दी](./README.hi.md) ·
|
|
7
|
+
<sub>[English](./README.md) · [中文](./README.zh.md) · [Español](./README.es.md) · [हिन्दी](./README.hi.md) · **العربية** · [Русский](./README.ru.md) · [Português](./README.pt.md) · [Français](./README.fr.md) · [日本語](./README.ja.md)</sub>
|
|
8
8
|
|
|
9
9
|
### أكثر خوادم Obsidian MCP تطوّراً. ذاكرة طويلة الأمد لوكلاء الذكاء الاصطناعي.
|
|
10
10
|
|
|
@@ -54,7 +54,7 @@ claude mcp add obsidian -- npx -y @oomkapwn/enquire-mcp serve --vault ~/Document
|
|
|
54
54
|
> 3. **صفر استدعاءات سحابية أثناء التشغيل.** النماذج مخزّنة محلياً (تنزيل لمرة واحدة من HuggingFace). محتوى مكتبتك لا يغادر جهازك أبداً. آمنة للعمل المعزول (air-gap) افتراضياً.
|
|
55
55
|
> 4. **استدعاء واعٍ بالحداثة.** تُبلّغ كل نتيجة عن عمر الملاحظة؛ وإعادة الترتيب الاختيارية بالحداثة تتيح للوكيل تفضيل المعرفة الحديثة ووسم الحقائق القديمة لإعادة التحقق — حدود "الوعي بالنسيان"، مبنيّة على `mtime` الذي تملكه ملفاتك أصلاً.
|
|
56
56
|
|
|
57
|
-
**
|
|
57
|
+
**46 أداة · 19 موجِّه MCP · 1358+ اختبار وحدة · 50+ لغة · إصدار مستقر v3.10.x · مُقيَّد بالـ semver · MIT · إثبات بناء npm (SLSA L2).**
|
|
58
58
|
|
|
59
59
|
</div>
|
|
60
60
|
|
|
@@ -152,7 +152,7 @@ enquire-mcp doctor --vault <path> # color-coded ✓/⚠/✗ health check
|
|
|
152
152
|
| **MCP بعيد** (HTTP + bearer auth + جلسات ذات حالة) | ✅ | ❌ | جزئي |
|
|
153
153
|
| **MCP أصيل** (Claude · Cursor · ChatGPT · Codex · OpenClaw · أي عميل) | ✅ | ❌ Obsidian فقط | متفاوت |
|
|
154
154
|
| **مرشّح خصوصية** مُتحقَّق منه عند كل مسار بحث + كتابة | ✅ | غير منطبق | ❌ |
|
|
155
|
-
| **
|
|
155
|
+
| **46 أداة إنتاجية** (34 أداة قراءة دائمة + 4 اختيارية + 7 كتابات محكومة + 1 تغذية راجعة) | ✅ | غير منطبق | متفاوت |
|
|
156
156
|
| **GraphRAG-light** (كشف مجتمعات بمعامل Louvain) | ✅ **حصرياً هنا** | ❌ | ❌ |
|
|
157
157
|
| **تنفيذ استعلام `.base` مستقل** (يعمل دون تشغيل Obsidian) | ✅ **حصرياً هنا** | ❌ | ❌ |
|
|
158
158
|
| **استرجاع HyDE** + تفكيك الأسئلة الفرعية | ✅ **حصرياً هنا** | ❌ | ❌ |
|
|
@@ -192,11 +192,11 @@ enquire-mcp doctor --vault <path> # color-coded ✓/⚠/✗ health check
|
|
|
192
192
|
|
|
193
193
|
---
|
|
194
194
|
|
|
195
|
-
## 🛠️ جميع الأدوات الـ
|
|
195
|
+
## 🛠️ جميع الأدوات الـ 46
|
|
196
196
|
|
|
197
197
|
<div dir="rtl" align="right">
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
46 أداة إجمالاً: 34 قراءة دائمة (بما في ذلك المدخل الجامع `obsidian_search`) + 4 اختيارية + 7 كتابات محكومة + 1 تغذية راجعة بحلقة مغلقة. المرجع الكامل في **[docs/api.md](./docs/api.md)**، ويشمل: البحث والاسترجاع، وWikilink والرسم، وFrontmatter وDataview، وCanvas، وObsidian Bases، وPDF + OCR، وكشف المجتمعات، وأدوات الكتابة (تتطلب `--enable-write`) وغيرها.
|
|
200
200
|
|
|
201
201
|
</div>
|
|
202
202
|
|
package/README.es.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# enquire-mcp
|
|
6
6
|
|
|
7
|
-
<sub>[English](./README.md) · [中文](./README.zh.md) · **Español** · [हिन्दी](./README.hi.md) · [العربية](./README.ar.md)</sub>
|
|
7
|
+
<sub>[English](./README.md) · [中文](./README.zh.md) · **Español** · [हिन्दी](./README.hi.md) · [العربية](./README.ar.md) · [Русский](./README.ru.md) · [Português](./README.pt.md) · [Français](./README.fr.md) · [日本語](./README.ja.md)</sub>
|
|
8
8
|
|
|
9
9
|
### El MCP de Obsidian más avanzado. Memoria a largo plazo para agentes de IA.
|
|
10
10
|
|
|
@@ -48,7 +48,7 @@ Tu bóveda de Obsidian se convierte en **memoria a largo plazo persistente y con
|
|
|
48
48
|
> 3. **Cero llamadas a la nube durante el servicio.** Modelos en caché local (una descarga única desde HuggingFace). El contenido de tu bóveda nunca sale de tu máquina. Seguro para entornos aislados por defecto.
|
|
49
49
|
> 4. **Recuperación consciente de la frescura.** Cada resultado informa de la antigüedad de la nota; el reordenamiento por recencia opcional permite que un agente prefiera el conocimiento reciente y marque los hechos obsoletos para reverificación: la frontera consciente del olvido, construida sobre el `mtime` que tus archivos ya tienen.
|
|
50
50
|
|
|
51
|
-
**
|
|
51
|
+
**46 herramientas · 19 prompts MCP · 1358+ pruebas unitarias · 50+ idiomas · v3.10.x estable · ligado a semver · MIT · procedencia de compilación en npm (SLSA L2).**
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -124,7 +124,7 @@ No-objetivos honestos: recurre a otra cosa cuando:
|
|
|
124
124
|
| **MCP remoto** sobre HTTP + autenticación bearer + sesiones con estado | ✅ | ❌ | parcial |
|
|
125
125
|
| **Nativo de MCP** (Claude · Cursor · ChatGPT · Codex · OpenClaw · cualquier cliente) | ✅ | ❌ solo Obsidian | varía |
|
|
126
126
|
| **Filtro de privacidad** verificado en cada ruta de búsqueda + escritura | ✅ | n/d | ❌ |
|
|
127
|
-
| **
|
|
127
|
+
| **46 herramientas de producción** (34 de lectura siempre activas + 4 opcionales + 7 escrituras restringidas + 1 de retroalimentación) | ✅ | n/d | varía |
|
|
128
128
|
| **GraphRAG-light** (detección de comunidades de wikilinks por modularidad de Louvain) | ✅ **solo aquí** | ❌ | ❌ |
|
|
129
129
|
| **Ejecución autónoma de consultas `.base`** (funciona sin Obsidian abierto) | ✅ **solo aquí** | ❌ | ❌ |
|
|
130
130
|
| **Recuperación HyDE** + descomposición en subpreguntas | ✅ **solo aquí** | ❌ | ❌ |
|
|
@@ -156,9 +156,9 @@ Activable por niveles, según lo que necesites:
|
|
|
156
156
|
|
|
157
157
|
---
|
|
158
158
|
|
|
159
|
-
## 🛠️ Las
|
|
159
|
+
## 🛠️ Las 46 herramientas
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
46 herramientas en total: 34 de lectura siempre activas (incl. el paraguas `obsidian_search`) + 4 opcionales + 7 escrituras restringidas + 1 de retroalimentación de bucle cerrado. Referencia completa en **[docs/api.md](./docs/api.md)**, que abarca: búsqueda y recuperación, wikilinks y grafo, frontmatter y Dataview, Canvas, Obsidian Bases, PDF + OCR, detección de comunidades, herramientas de escritura (requieren `--enable-write`), etc.
|
|
162
162
|
|
|
163
163
|
---
|
|
164
164
|
|