Supersedes #217 (dependabot). Brings the dev toolchain current:
@types/node 25.3→25.9, @typescript-eslint/utils + typescript-eslint
8.56→8.60, esbuild 0.27→0.28, globals 17.3→17.6, jest 30.2→30.4,
jiti 2.6→2.7, obsidian 1.12.2→1.13.0, ts-jest 29.1→29.4.
The typescript-eslint 8.60 and obsidian 1.13.0 type bumps surface new
lint findings; cleared in the follow-up commit.
The worker-thread pool ratified/extended by ADR-104 has never executed a
single request since introduction (v0.5.8b, 22742bd): ConnectionPool's
action-level workerOps gate (tool.vault.search, …) never matched the
operation-level method strings the pool emits (tool.vault, tool.edit, …),
so processWithWorker was unreachable. Independently, the worker built to
dist/workers/workers/semantic-worker.js while WorkerManager loaded
dist/workers/semantic-worker.js — load would have failed anyway.
Verified dead against current main; no CPU-starvation field reports.
Fixing forward was rejected: it would ship an untested concurrency path
that widens the #139 parallel-edit race via a new TOCTOU window for an
unproven perf need (see #197 analysis).
- delete src/workers/semantic-worker.ts, src/utils/worker-manager.ts,
build-worker.js; drop build:worker + the build-worker.js build step
- strip worker wiring from ConnectionPool (retained as a main-thread
bounded queue — the only behaviour that ever ran) and the dead
prepareWorkerContext/workerScript from mcp-server.ts
- ADR-105 records the removal as a partial reversal of ADR-104; ADR-104
stays Accepted (SSE-route deconfliction half, shipped #196, still
governs) with a banner pointing to ADR-105
Behaviour-preserving by construction: the deleted path never ran.
make check green (build + lint 0 errors + 225/225 tests).
PR2 of 2 for #180 (ADR-201). Closes the arbitrary-code-execution vector
reachable through a synced/shared `.base` file.
- Drop `new Function('context', 'with(context){return ${expr}}')` (and its
no-implied-eval eslint-disable) from expression-evaluator.ts.
- Parse with expression-eval@5.0.1 (jsep grammar: no eval/Function/new, no
global scope; member denylist built in). Pinned exact; jsep 0.3.5 is its
audited transitive parser. Both >7d old; npm audit 0 vulns.
- Defense-in-depth AST pre-walk (assertNoForbiddenAccess): rejects
constructor/__proto__/prototype member access (Identifier AND computed
["constructor"] forms) and ThisExpression, independent of the library's
internal list — ADR-201's explicit, tested no-globals property lives in
our code, not a transitive dep.
- createEvalContext and all helpers untouched → behavioural parity.
Differential corpus (tests/bases-expression-evaluator.test.ts, from PR1):
57 EVAL_CASES still green = expression-eval == old new Function for every
realistic Bases construct; the formerly-executing escapes (2/42/99 under
new Function) now fail closed; SECURITY set never reaches a function, the
real global, or a value.
No behavioural change for legitimate `.base` expressions. Breaking only by
design: the RCE vectors, `this`, and prototype-chain access are now
refused. Clears the Obsidian "Dynamic Code Execution" finding.
209/209 tests; build + lint clean. Refs #180, ADR-201
Closes#174. Obsidian source-code review flagged js-yaml (unmaintained) for
replacement. Rewire bases-api.ts's 5 call sites onto yaml-bridge; drop
js-yaml + @types/js-yaml. yaml pinned to 2.8.4 (published 2026-05-02, clears
the project's 7-day supply-chain hold; 2.9.0 was 5 days old). Existing
overrides.yaml reconciled to $yaml so the direct dep governs transitive
resolution. Behaviour-equivalence proven by the differential corpus.
Obsidian source-code review flags builtin-modules as a package to replace.
node:module has exposed builtinModules natively since Node 6.x; esbuild only
used it to externalize Node builtins from the bundle. Behavior-equivalent
swap, devDependency removed.
package.json is now the single source of truth for the plugin description
(as it already effectively is for version). sync-version.mjs propagates it
into manifest.json; mcpb/manifest.json keeps its Claude-Desktop-specific
description and is intentionally not synced.
Adds scripts/set-description.mjs + 'make set-description DESC=...' so neither
JSON file is hand-edited (250-char Obsidian limit enforced).
Rewrites the word-salad description to reality-based copy naming the actual
client and mechanism:
'Give Claude Desktop and other AI assistants semantic access to your notes
through a built-in Model Context Protocol (MCP) server.'
The plugin code already calls APIs introduced in newer Obsidian versions
(FileManager.trashFile in 1.6.6, Workspace.getLeaf in 0.16.0,
Vault.createFolder in 1.4.0, ToggleComponent.setDisabled in 1.2.3,
AbstractTextComponent.setDisabled in 1.2.3, ButtonComponent.setTooltip
in 1.1.0). Declaring minAppVersion 0.15.0 was misleading — anyone
between 0.15 and 1.5 would have the plugin load and then crash at
runtime. Set the floor to 1.6.6 to match the highest API actually used.
After merging the dependabot batch, npm audit still flagged 5
transitive vulns (4 high, 1 moderate). Running npm audit fix lifts
deep deps to patched ranges and resolves all of them — except it
tries to land yaml@2.9.0 which was published 2026-05-11, inside the
7-day hold window.
Added a package.json override to pin yaml to ~2.8.4 (published
2026-05-02, 13 days aged). 2.8.4 already fixes the CVE-flagged
"Stack Overflow via deeply nested YAML collections" (range
2.0.0-2.8.2), and we get the safety of an aged release.
Final state: 0 vulnerabilities, 127/127 tests still green, all
upgrades respect the 7-day rule.
package.json had a stale "Aaron Blumenfeld" that propagated into
mcpb/manifest.json when sync-version ran. The top-level manifest.json
already had the right value (Aaron Bockelie, matching git author).
- Remove async from ~30 methods with no await expressions
- Remove stale await calls at all affected call sites
- Add descriptions to all eslint-disable directive comments
- Replace eslint-disable no-restricted-globals with globalThis.fetch
- Fix sentence case in UI text ("Read-only mode")
- Retain no-deprecated disables with descriptions for MCP SDK Server class
- Bump version to 0.11.11
Fix optional review bot warnings: remove async from methods with no
await expressions, remove await from their call sites, and replace
direct console usage in debug utility with indirect globalThis
reference to avoid no-console eslint-disable comments.
Bump version to 0.11.10.
Remove eslint config overrides that were masking 1,822 strict type errors
flagged by the ObsidianReviewBot. Replace all `any` types with proper
TypeScript interfaces, type guards, and narrowed types across 40 files.
- Strip eslint.config.mts overrides for no-explicit-any, no-unsafe-*
- Add proper interfaces for MCP protocol, Obsidian internals, workers
- Add paramStr/paramNum/paramBool helpers in semantic router
- Fix recursive-copy test expectations
- Remove unused dotenv dependency
- Bump version to 0.11.9
Changes since 0.11.6d:
- Updated all dependencies to latest versions
- Express 4 → 5, Jest 29 → 30, TypeScript 5.2 → 5.9
- Fixed TypeScript 5.9 compatibility issues
- Cleaned up old releases, branches, and PRs
- Fixed Jest warnings for Node.js 25 compatibility
The McpServer high-level API requires Zod schemas for input validation,
which caused the "v3Schema.safeParseAsync is not a function" error.
Reverted to using the low-level Server class with setRequestHandler
pattern which accepts JSON Schema directly.
- Changed imports from McpServer to Server in mcp-server.ts and mcp-server-pool.ts
- Rewrote setupMCPHandlers to use setRequestHandler pattern
- Removed json-schema-to-zod.ts utility (no longer needed)
- Added eslint-disable comments for intentional use of deprecated Server class
The new McpServer API requires Zod schemas instead of JSON Schema.
Added json-schema-to-zod utility to convert schemas at registration time.
- Add zod as direct dependency
- Create jsonSchemaToZod converter utility
- Update tool registration in mcp-server.ts and mcp-server-pool.ts
- Bump version to 0.11.6a