release · v0.10.1

The v0.8.1 → v0.10.1 jump.

npm hadn't seen a release since v0.8.1 (January 2026). v0.10.1 consolidates 4 generations of never-published work: v0.9.1 (audit), v0.9.2 (hardening), v0.10.0 (claude-code alignment), v0.10.1 (patch). Here's what actually changes for you.

security · 01

Sandbox hardened. 5 escape vectors closed.

The sandbox is significantly harder to escape now.

Before (v0.8.1)
Now (v0.10.1)
this.constructor.constructor("…")() chain open
Blocked by the static analyzer (US-002)
git config / update-ref / reflog allowed
Blocklisted — no more persistent compromise via core.sshCommand (US-003)
No symlink guard
isSymbolicLink() + realpath check on every entry, plus depth cap (US-004)
TOCTOU race between validate + open
Path validation re-resolves at open() time (US-005)
DISTILL_LEGACY_EXECUTOR env-var bypass
Removed — QuickJS WASM is the only executor, no user-facing toggle
integration · 02

Native Claude Code. Real parallelism.

This is the biggest functional gain — Distill now speaks the real language of Claude Code:

  • annotations.readOnlyHint declared → Claude Code now dispatches auto_optimize + smart_file_read in parallel with other read-only tools on the same turn. Measurable wall-clock gain on multi-tool turns.
  • _meta['anthropic/alwaysLoad'] = true correctly emitted on all 3 tools → no ToolSearch deferral, the tools are present from turn 1.
  • structuredContent removed from the wire → Claude Code was stashing it in mcpMeta, which is never sent to the Anthropic API. Pure wasted bandwidth, now gone.
  • New: PreCompact hook + [DISTILL:COMPRESSED ratio=X.XX method=<name>] marker → your compressed regions are preserved verbatim during Claude Code's autocompact. Opt-in via DISTILL_COMPRESSED_MARKERS=1.
codebase · 03

Leaner. More honest.

  • ~3,600 LOC of dead code removed (import-graph + knip): analyze-context.ts, dynamic-loader.ts, session-tracker.ts, toon-serializer.ts, the entire @distill/ui package, the entire @distill/shared package, src/middleware/ (313 LOC of useless dispatch chain), etc.
  • CI with 5 parallel blocking jobs: lint, typecheck, test+coverage, build, knip. No more continue-on-error: true.
  • Enforced coverage floors: lines 70%, branches 56%, functions 70%, statements 69% (raised by +1pt in v0.9.2). CI fails below.
  • Documentation verified citation-by-citation: 11 claude-code mechanisms each anchored to claude-code/<path>:<line> in CLAUDE.md, with a re-verify command.
patch · 04

Bugs fixed. v0.10.1.

  • code_execute({ code: 'console.log("x")' }) no longer crashes with "Cannot read properties of undefined (reading 'match')". A console.log without return now yields success: true, tokensUsed: 0, output: "(no output)".
  • smart_file_read skeleton no longer emits export async async createServer(...) on async TS functions.
invariants · 05

What stayed. By design.

  • The 3 tools (auto_optimize, smart_file_read, code_execute) keep exactly the same signature.
  • Compression algorithm, AST parsers, sandbox engine are unchanged.
  • No breaking change for v0.8.1 users on the API surface.
verdict

Distill does the same thing as v0.8.1, but faster (native parallelism), safer (5 escape vectors closed), less noisy (docs + codebase aligned with reality), and with an autocompact hook that doesn't exist anywhere else in the MCP ecosystem.

next

Ready to upgrade?

One command to update. Zero breaking change.

Distill - Save 98% LLM Tokens with Smart Context Compression