Repository navigation
v0.2.1 — 2026-04-25
Release Notes
Hotfix release closing 4 GitHub issues filed against v0.2.0, with scope expanded mid-flight to incorporate 2 audit-driven fixes (M6: 7 additional unguarded daemon handlers under #5; M7: request-side camelCase mismatch under #19). All 6 fixes were confirmed reproducible at their respective starting commits and fixed at root cause with new in-process integration tests pinning the bug shape. No regressions: full 964/964 matrix (730 exhaustive + 234 language-command) green across every fix commit; cargo clippy --workspace --all-features --tests -- -D warnings clean.
Fixed
- #5 (security, Unix-side path traversal):
tldr-daemonIPC handlers (secrets,vuln) now route every caller-supplied absolute path throughtldr_core::validate_file_pathbefore any filesystem read, refusing requests for paths outside the active project root withBAD_REQUEST. Pre-fix, the handlers accepted anyis_absolute()path verbatim, which on a daemon already running could be exploited to extract/Users/<other>/.aws/credentials-shaped secrets. The Windows TCP unauthenticated listener portion of #5 remains an open design question (multi-user daemon sharing semantics) and is deferred to v0.3.0. (commit 00ee2dc) - #11:
tldr vuln --format sarifand--format jsonnow correctly labelDeserializationfindings as deserialization (CWE-502) — pre-fix, the wildcard match arm_ => VulnType::SqlInjectionatcrates/tldr-cli/src/commands/remaining/vuln.rs:645-651silently mislabeled them as SQL injection (CWE-89).Ssrfwas affected by the same wildcard and is now correctly mapped to CWE-918. The match is exhaustive — futuretldr_core::security::vuln::VulnTypevariants will fail to compile until they are mapped, preventing the same bug pattern from recurring. (commit 181f929) - #12:
tldr-mcpnow speaks JSON-RPC 2.0 + MCP 2024-11-05 lifecycle correctly. Three sub-bugs fixed in one commit: (a)JsonRpcRequest.idis nowOption<Value>with#[serde(default)]so notification frames (noid) deserialize cleanly; (b) the dispatcher now suppresses all response emission whenidisNone, per JSON-RPC 2.0 §4.1 ("a server MUST NOT reply to a notification"); (c) the canonical methodnotifications/initializedis routed (the legacy bareinitializedtypo was a v0.1.x scaffold mistake — never spec-correct in any MCP draft — and was removed rather than kept as an alias to avoid masking client bugs in the wider ecosystem). (commit 1620b6d) - #19 (filed by @etal37):
tldr-mcp'sinitializeresponse now emitsprotocolVersionandserverInfoin camelCase per the MCP 2024-11-05 wire spec. Pre-fix,InitializeResultserialized snake_case (protocol_version,server_info) which Claude Code and other spec-compliant clients reject during the lifecycle handshake — the user-facing failure was "Claude Code cannot connect to tldr-mcp". A recursive scan of the day-one handshake responses (initialize+tools/list) now returns zero snake_case keys outside JSON Schema property declarations underinputSchema.properties(which are user-defined argument names extracted by tool handlers, not MCP-defined wire fields). (commit 2726358) - #5 (security, broader handler audit): Audit of
crates/tldr-daemon/src/handlers/{ast,flow,quality}.rsfound 7 additional unguarded path arguments using the sameis_absolute → acceptpattern as the original #5 fix. Each was wired throughtldr_core::validate_file_pathwithBAD_REQUESTmapping. Affected handlers:imports,cfg,dfg,slice,complexity,smells,maintainability. Reproduction tests incrates/tldr-daemon/tests/handler_path_traversal_audit_test.rsconfirm canary file content no longer leaks (canary substringcanary_xyz_42previously appeared inImportInfo.module,CfgInfo.function,DfgInfo.function,ComplexityMetrics.functionresponse fields). (commit b988c42) - #19 (broader request-side audit): Beyond the response-side
InitializeResultrename, audit ofcrates/tldr-mcp/src/protocol.rsfoundInitializeParamswas silently droppingprotocolVersionandclientInfofrom spec-compliant client requests because the request-side struct lacked#[serde(rename_all = "camelCase")]. With#[serde(default)]on every field, missing-key errors degraded toNone— Claude Code's day-1 handshake completed but the server's announced-protocol-version and client-info diagnostics became dead code. Now applied via struct-levelrename_allattribute (future-proof against new fields silently regressing). (commit 4204616)
Notes
cargo install tldr-cliandcargo install tldr-cli --features semanticcontinue to work as in v0.2.0 — no new install-time requirements.- The 4 binary targets (aarch64-apple-darwin, x86_64-apple-darwin, x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu) are built automatically by cargo-dist via
.github/workflows/release.ymlon thev0.2.1tag. - The original triage produced 4 fix milestones (M1–M4); the broader audit milestones M6 + M7 were dispatched after M5's release prep when latent flags surfaced during M1's and M4's work were promoted into the v0.2.1 scope rather than deferred to v0.2.2. Total v0.2.1 fixes shipped: 6 (4 originally-triaged + 2 audit-discovered).
Download tldr-cli 0.2.1
| File | Platform | Checksum |
|---|---|---|
| tldr-cli-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| tldr-cli-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| tldr-cli-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| tldr-cli-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |