Skip to content

Releases: mksglu/context-mode

v1.0.162

02 Jun 17:05

Choose a tag to compare

🚀 v1.0.162 — multilingual prompt analytics, accurate cost, 13 new extractors

13 commits · 8 PRD issues · 2 verify-gap fixes · 13 new test files · 80+ tracers since v1.0.161. Cross-repo PRD-driven sprint — wire-format expansion, privacy-first multilingual analytics, and a pricing accuracy catch-up that had been stale since v1.0.103. 💜


✨ Highlights

  • 🌍 §11 multilingual prompt features — Layer 1 expanded from 5 → 10 typed columns plus a new prompt_word_tokens[] Layer 3 array, fully script-agnostic via Unicode property escapes (\p{L}, \p{Script=X}). Latin, Cyrillic, Han, Hangul, Arabic, Hebrew, Thai, Greek, Devanagari, Hiragana, Katakana — one code path, no franc / fasttext / compromise dependency. Bundle unchanged.
  • 💰 Honest cost accountingMODEL_PRICING_USD_PER_MTOK lands with verified 2026-06 Anthropic rates (Opus 4.7/4.8 $5/$25, Sonnet 4.6 $3/$15, Haiku 4.5 $1/$5). extractAgentUsage derives cost_usd from per-model rates × usage block. ctx-stats headline corrected from $1399.73 of Opus 4 tokens to $466.58 of Opus 4.7 tokens — same fixture, accurate rate (Opus 4 → Opus 4.7 was a 3× price cut that never propagated to analytics.ts).
  • 🪝 9 new event types from existing tool callsbash_outcome, file_read_metadata, webfetch_metadata, worktree_exit, agent_usage, session_settings_snapshot, git_commit (discriminated from generic git), plan_enter (slash variant), and enriched plan_exit with plan_bytes/plan_hash. All ride the existing {...ev} envelope per ABI §5.4 — zero platform-side schema migrations.
  • 🩹 commit_message capture finally works — symmetric rollup stamp + per-event gate on type='git_commit'. POSIX argv tokenizer handles -m, -am, --message=, --message ARG, env-prefixed (GIT_AUTHOR=... git commit -m ...), --amend fallback, empty -m "". Closes the ~92% NULL-on-has_commit=1 ingestion drift surfaced by prod D1 telemetry.
  • 🧭 Cross-project attributiongit -C /other/path commit -m "x" from cwd=projectA now attributes to project B's canonical identity. Tilde (~/path) and equals-form (--directory=/path) both parsed correctly across macOS / Linux / Windows.
  • 📐 /plan slash fallback — Claude Code Bug #15660 workaround. The slash command emits plan_enter via UserPromptSubmit; ~60-80% of plan-mode entries that were previously telemetry-invisible (slash + Shift+Tab don't fire PostToolUse) are now captured. Shift+Tab remains upstream-blocked.
  • 🛡️ Zero new runtime dependencies — 13 extractors, 22 multilingual feature paths, and a per-model pricing table added. Bundle stays at 58 KB total across all 5 hook bundles. Algorithmic POSIX argv parsing, FNV-1a hashing, Unicode regex via stdlib only.

🐞 Bug Fixes

Commit message capture (Bug 1 + Bug 2)

  • POSIX argv tokenizer for commit messagesextractGit parses -m, -am, --message=, separate-token --message, env-prefixed invocations, --amend fallback, and empty -m "". Emits type='git_commit' (distinct from generic git) when a message is captured. Symmetric rollup stamp via getSessionRollup so every event in a commit-bearing session carries commit_message, closing the asymmetric-NULL drift seen on platform D1.
  • Cross-project attribution (Bug 8)git -C <dir> scope hint now flows through parseGitInvocation and shadows the in-batch inputProjectDir. Subsequent events in the same Bash call attribute to the scoped directory, not the hook's startup cwd.

Cost derivation (verify-gap Gap #1)

  • cost_usd on agent_usage — derives from tokens × per-MTok rate using the new MODEL_PRICING table. Model resolution: tool_input.modelinput.modelresponse.modeldefault (Sonnet rates). Prefix match for date-suffixed ids (claude-haiku-4-5-20251001claude-haiku-4-5). Zero-token sessions skip cost_usd so dashboards don't render $0.00 for nothing. Unknown model id falls back to default — never null.

Git parsing (verify-gap Gap #2)

  • Tilde expansiongit -C ~/repos/myrepo status now expands to $HOME/repos/myrepo (or USERPROFILE on Windows, with HOMEDRIVE+HOMEPATH fallback). ~user/path (other-user form) intentionally NOT expanded — bridge does not do passwd lookups.
  • --directory=value equals-form — parsed alongside the existing space-form --directory <value>. Tokenizer kept the equals-attached argument as one token; parser now slices on the --directory= prefix.

Prompt analytics (Issue #5 + Issue #8 §11)

  • Multilingual Layer 1 alignment — replaced the F1 §2 5-field stub with §11's 10-field shape: prompt_length, prompt_word_count, prompt_uppercase_ratio, prompt_file_ref_count, prompt_path_ref_count, prompt_script_primary, prompt_script_count, prompt_question_glyph_count (counts ASCII ?, fullwidth , Arabic ؟), prompt_code_block_count, prompt_url_count. The prompt_first_word field from the stub was removed — prompt_word_count covers the same insight script-agnostically.
  • Layer 3 word tokensprompt_word_tokens: string[] carries letter-only words ≥3 chars, lowercased, deduplicated within the prompt. Platform UPSERTs into prompt_word_count(org_id, week, word, count) for emergent vocabulary surfacing at 5%-50% rate thresholds. Aggregated per org+week; no individual prompt token surfaces in any UI.

CI / cross-platform

  • Windows statusline timeout parity — slice-2 multi-adapter test now reuses STATUSLINE_SQLITE_TIMEOUT_MS (300s Windows / 30s elsewhere) instead of a stale hardcoded 60s. CI #401 had observed 186s with retry x2 on windows-latest — flake fixed.
  • 2 stale pricing-test assertionsformat-cost.test.ts ($1399.73 → $466.58 of Opus 4.7 tokens) and format-report-real-bytes.test.ts (regex updated). Both surfaced by the pricing-constant sync.

🎨 Features

  • 9 new event types for prompt analytics, cost accounting, and tool-response metadata — all ride the existing universal envelope ({...ev, platform, ts} per ABI §5.4). Platform Zod schema is forward-compatible; no wire-side migration required.
  • extractAgentUsage — fires on tool_name === "Task" (sub-agent dispatcher). Captures totalTokens, totalDurationMs, tokens_in, tokens_out, cache_create, cache_read, tier, plus derived cost_usd.
  • extractBashOutcome — three real signals from BashOutput: interrupted (bool), returnCodeInterpretation (semantic non-zero hint), stderr length-only (privacy). No exit_code field exists in the SDK; the verify-gap PRD's anti-hallucination block specifically flagged this.
  • extractFileReadMetadata — branches on text vs image variant. Text: numLines/totalLines/startLine. Image: originalSize/dimensions (formatted as WxH).
  • extractWebFetchMetadatacode/bytes/durMs/host. URL host extracted algorithmically (no regex), query string stripped before stamping. No redirect_url field exists; temporal correlation handles redirect-loop detection at the platform.
  • extractWorktree extended for ExitWorktree — emits worktree_exit with discard_changes flag, alongside the existing EnterWorktree handler.
  • extractPlan ExitPlanMode metadataplan_bytes (length) + plan_hash (8-char FNV-1a hex) on the existing plan_exit event. Plan source: tool_input.plan first, fall back to tool_response.plan (SDK actually carries it on the OUTPUT per ExitPlanModeOutput @ sdk-tools.d.ts:2222).
  • extractSessionSettings — emits session_settings_snapshot from SessionStart with mcp_count, mcp_servers (first 8 names), model, permission_mode. Wired into emitSessionStartLifecycle opportunistically — never blocks lifecycle on snapshot failure.
  • extractUserPlan — UserPromptSubmit-driven /plan slash detector. Algorithmic char-code scan (no regex), word-boundary check so /plans does not match, argument truncated at 120 chars.

⚡ Performance

  • Zero bundle bloathooks/session-extract.bundle.mjs is 13,694 bytes, total of all 5 hook bundles is 58 KB. 13 new extractors + multilingual feature engine added with zero new runtime dependencies. esbuild minifies; nothing leaks.
  • §11 multilingual is O(n) per feature on the prompt string — prompt.match(/\p{L}+/gu) and the 11-script loop bound the cost. Spec-mandated p95 ≤ 15 ms on a 10 KB prompt.
  • FNV-1a 32-bit hash for plan_hash — deterministic, stable across platforms, no crypto library required.

📚 Docs / Ops

  • Cross-PRD cross-repo workflow — this release closes 8 issues from 09-oss-handoff-prd.md and 2 gaps from 16-oss-verify-gap-prd.md. The verify-gap PRD is a separate-LLM verification pass on the OSS work — a novel cross-agent OSS workflow.
  • STYLE-ANCHOR-v1.0.152.md added to repo (developer-facing) — documents the v1.0.152 release-notes template so future releases stay community-grade. v1.0.153 through v1.0.161 will be rewritten to this style.
  • Anti-hallucination ground truth — every cited SDK line in the PRDs was re-verified against refs/platforms/claude-code/sdk-tools.d.ts before implementation. The verify-gap PRD specifically flagged stale citations (BashOutput.exit_code does not exist; WebFetchOutput.redirect_url does not exist) — both correctly worked around in the new extractors.

📋 PRD-driven work

This release is the first end-to-end product of the OSS handoff + verify-gap cross-PRD pipeline:

PRD Repo Issues / Gaps closed
09-oss-handoff-prd.md v3 context-mode-platform #1 release, #2 AgentOutput.usage, #3 FileReadOutput, #4 SessionStart ...
Read more

v1.0.161

01 Jun 11:56

Choose a tag to compare

🪟 v1.0.161 — Codex Windows symlink fix + seed-parity Windows hardening

1 community PR · 8 commits since v1.0.160. Codex on Windows users had been hitting a marketplace symlink source failure during plugin install — fixed end-to-end by @NgoQuocViet2001, plus the seed-parity integration suite now passes cleanly on windows-latest. 💜


✨ Highlights

  • 🪟 Codex Windows symlink fix (#748 by @NgoQuocViet2001) — Codex's plugin install path was sourcing the context-mode marketplace via a symlink that Windows file APIs reject on first read. The fix avoids the symlink source on Windows specifically; macOS/Linux paths unchanged. Removes a silent first-install failure for the entire Windows Codex user segment.
  • 🧪 seed-parity tests green on Windowstests/integration/seed-parity-coverage.test.ts and tests/integration/seed-parity-coverage.test.ts now override APPDATA and use the platform-aware config path resolver. CI matrix coverage restored across all 3 OSes.
  • 📋 .agents/plugins/marketplace.json — new layout file landed alongside the existing plugin manifest, keeping context-mode discoverable across both claude-code and openclaw plugin paradigms.
  • 📚 docs/platform-support.md — refresh aligned with the marketplace.json layout.

🐞 Bug Fixes

Codex adapter

  • #748 fix(codex): avoid marketplace symlink source on Windows (@NgoQuocViet2001) — install flow no longer dereferences the marketplace symlink on Windows. macOS/Linux install paths unchanged.

Cross-platform tests

  • test(seed-parity): override APPDATA + use platform-aware config path (×2 commits, 81a8435/254ee9a) — Windows test runner was reading the developer's real APPDATA instead of the fake fixture path. Tests now construct the platform-aware config file via the same resolver the runtime uses.

📚 Docs / Ops

  • docs/platform-support.md refresh — claude-code, openclaw, codex install paths re-documented against the new .agents/plugins/marketplace.json layout.
  • CI: install stats refresh (0cfe3be) — stats.json re-fetched, no functional impact.

🙌 Contributors — one by one

Massive thank you to the contributor who shipped this cycle:

Contributor PRs Highlights
@NgoQuocViet2001 #748 Codex Windows symlink source fix — removes a silent first-install failure on the entire Windows Codex user segment

Plus maintenance/ops by @mksglu.


📦 Install / upgrade

# Fresh install (Claude Code plugin marketplace)
/plugin add https://github.com/mksglu/context-mode

# npm global
npm install -g context-mode@1.0.161

# Existing install — in-place upgrade
context-mode upgrade

Then restart your MCP session (or run /reload-plugins in Claude Code).

🔗 Full changelog

v1.0.160...v1.0.161


🤖 Release notes retroactively rewritten in v1.0.152 style to surface @NgoQuocViet2001's contribution properly.

v1.0.160

01 Jun 07:51

Choose a tag to compare

🚇 v1.0.160 — 4 hook surfaces now flow through the platform bridge

2 commits · 5 hook files updated since v1.0.159. Event types that previously bypassed the platform-bridge wire (post-tool-use, pre-compact, session-start, user-prompt-submit) are now routed through attributeAndInsertEvents, closing a partial-coverage gap for analytics-opt-in users.


✨ Highlights

  • 🚇 Bypassed event types routed through bridge (c084707) — posttooluse.mjs, precompact.mjs, sessionstart.mjs, userpromptsubmit.mjs all now emit through the platform-bridge wire via attributeAndInsertEvents. Previously these surfaces wrote directly to SessionDB and never reached the bridge — analytics-opt-in users saw a partial event subset.
  • 🪝 Lifecycle event coverage restored — all 5 hook event types (PostToolUse, PreCompact, SessionStart, UserPromptSubmit, Stop) now route uniformly. No silent drops, no surface that the bridge can't observe.

🐞 Bug Fixes

Hooks & routing

  • feat(hooks): route bypassed event types through bridge wire (c084707) — 4 hook files were calling SessionDB directly for non-PostToolUse events, bypassing the bridge entirely. The bridge wire is now the single insertion path; SessionDB writes happen as a side-effect of attributeAndInsertEvents.

Files touched (5 hook surfaces)

  • hooks/posttooluse.mjs — bypassed events: rejected, redirect, byte-accounting, tool_latency
  • hooks/precompact.mjs — bypassed events: compaction_summary, snapshot-built
  • hooks/sessionstart.mjs — bypassed events: lifecycle session_start, rule, rule_content
  • hooks/userpromptsubmit.mjs — bypassed events: user prompt extractions
  • hooks/session-loaders.mjsattributeAndInsertEvents now the canonical insert path

🎨 Features

  • Forward-compat for v1.0.162 — this release is the foundation that v1.0.162's 9 new event types (bash_outcome, file_read_metadata, webfetch_metadata, worktree_exit, agent_usage, session_settings_snapshot, git_commit, plan_enter slash, plan_exit metadata) all ride. Without the unified wire-up, the new extractors would have shipped half-observable.

📦 Install / upgrade

# Fresh install (Claude Code plugin marketplace)
/plugin add https://github.com/mksglu/context-mode

# npm global
npm install -g context-mode@1.0.160

# Existing install — in-place upgrade
context-mode upgrade

Then restart your MCP session (or run /reload-plugins in Claude Code).

🔗 Full changelog

v1.0.159...v1.0.160


🤖 Release notes retroactively rewritten in v1.0.152 style — the original body undersold a foundational wire-format unification.

v1.0.159

01 Jun 06:46

Choose a tag to compare

🧮 v1.0.159 — algorithmic Bash classifier + Codex hook dedupe

1 community PR · 6 commits since v1.0.158. Universal Bash command classifier rolls out to all 14 adapters via a non-regex algorithm, plus @ken-jo deduplicates plugin-owned context-mode hooks for Codex installs. 💜


✨ Highlights

  • 🧮 Universal algorithmic Bash classifier (b977902) — deriveBashMetadata classifies every Bash command into a canonical verb (build, test, lint, serve, git, format, install, run, move, delete, …) via a pure-character-class scan. No regex, no per-language table. Drives downstream analytics by command class across all 14 adapters.
  • 🪝 Codex hook deduplication (#746 by @ken-jo) — plugin-owned context-mode installs on Codex were firing the same hook twice when both the manifest and the marketplace layout registered it. The fix dedupes hook registrations by canonical path. Silent duplicate-event-emit problem closed.
  • ⚓ Session lifecycle anchor (b977902) — session_start event now emitted from emitSessionStartLifecycle (startup / resume / compact branches). Sessions now have a deterministic anchor event for downstream JOINs (durations, cost-per-session, etc.).

🐞 Bug Fixes

Codex adapter

  • #746 fix(codex): dedupe plugin-owned context-mode hooks (@ken-jo) — duplicate hook registrations (manifest + marketplace) collapsed into one. PostToolUse events stop firing twice for plugin-owned installs.

Universal classifier

  • feat(hooks): universal bridge — algorithmic Bash classifier, lifecycle anchor (b977902) — algorithmic verb extraction from Bash commands using POSIX-style argv tokenization + canonical-verb dictionary lookup. No regex per repo convention. Replaces the prior platform-specific dispatch with a single 14-adapter path.

🎨 Features

  • deriveBashMetadata — extracts canonical verb + argument-shape heuristics from any Bash invocation. Used by attributeAndInsertEvents to stamp bash_verb on every Bash event.
  • emitSessionStartLifecycle — single helper for emitting the session_start canonical event across all SessionStart sub-branches (startup / resume / compact). Used by hooks/sessionstart.mjs.

🙌 Contributors — one by one

Massive thank you to the contributor who shipped this cycle:

Contributor PRs Highlights
@ken-jo #746 Codex hook deduplication — closes silent duplicate-event-emit bug for plugin-owned Codex installs

Plus maintenance/ops by @mksglu.


📦 Install / upgrade

# Fresh install (Claude Code plugin marketplace)
/plugin add https://github.com/mksglu/context-mode

# npm global
npm install -g context-mode@1.0.159

# Existing install — in-place upgrade
context-mode upgrade

Then restart your MCP session (or run /reload-plugins in Claude Code).

🔗 Full changelog

v1.0.158...v1.0.159


🤖 Release notes retroactively rewritten in v1.0.152 style — the original body underplayed both the universal Bash classifier architectural shift and @ken-jo's community contribution.

v1.0.158

01 Jun 06:24

Choose a tag to compare

🧬 v1.0.158 — seed-parity envelope + classified events

7 commits since v1.0.157. Per-event enrichment lands the error/command/duration classifiers, plus a session-level rollup that gives analytics-opt-in users seed-parity coverage. Windows test hardening folded in to keep CI green across all 3 OSes.


✨ Highlights

  • 🧬 Seed-parity envelope (d4c3647) — every event now ships enriched with per-event facts (error category, file paths, session origin, blocker status) plus a session-level rollup snapshot (12 aggregate fields stamped onto every outgoing event). Analytics-opt-in users see seed-grade event payloads on every hook fire.
  • 🏷️ Error / command / duration classifiers (1d7affa) — classifyError 10-category lookup (auth, network, permission, not_found, syntax, …), Bash command verb classification, and PreToolUse-marker-based duration capture. Drives downstream pattern surfaces like error_recovery_lag and tool_latency_outlier.
  • 🪟 Windows test hardening (platform-bridge test suite ×4) — explicit APPDATA/XDG_CONFIG_HOME overrides, drop /bin/bash from execSync calls (Windows incompatibility), platform-aware config-path construction. Brings the bridge test suite to fully cross-platform green.

🐞 Bug Fixes

Hooks & enrichment

  • feat(hooks): seed-parity envelope — per-event enrichment + session rollup (d4c3647) — enrichEventForPlatform derives per-event facts; getSessionRollup aggregates 12 session-level signals; every outbound event payload merges both before crossing the bridge wire.

Classifiers (new)

  • feat(hooks): classifiers for error/command/duration metadata (1d7affa) — src/session/error-classifier.ts (new, 10 categories), deriveBashMetadata (canonical verbs), readLatencyMs (PreToolUse → PostToolUse marker delta). All ride existing event envelope.

Cross-platform tests

  • 4 platform-bridge test hardening commits — Windows runner was leaking real APPDATA into fake config paths, and execSync calls used /bin/bash shell explicitly (POSIX-only). Tests now use platform-aware paths via the runtime resolver, no explicit shell.

🎨 Features

  • SessionDB.getSessionRollup — 12-field aggregate (event_count, error_count, unique_files_edited, max_file_edits, has_commit, commit_message, total_duration_ms, session_origin, …) stamped on every outbound event so downstream analytics doesn't need to JOIN.
  • src/session/error-classifier.ts — 10-category error lookup mirrors seed data: auth, network, permission, not_found, syntax, dependency, timeout, crash, validation, unknown.
  • deriveBashMetadata — algorithmic canonical-verb extraction (no regex) from Bash commands. Powers bash_verb stamping.

⚡ Performance

  • Rollup computed once per batchgetSessionRollup runs as a single SQL aggregate over session_events and spreads onto every event in the batch via {...enriched, ...rollup}. No per-event SQL.

📦 Install / upgrade

# Fresh install (Claude Code plugin marketplace)
/plugin add https://github.com/mksglu/context-mode

# npm global
npm install -g context-mode@1.0.158

# Existing install — in-place upgrade
context-mode upgrade

Then restart your MCP session (or run /reload-plugins in Claude Code).

🔗 Full changelog

v1.0.157...v1.0.158


🤖 Release notes retroactively rewritten in v1.0.152 style — the original body's "broader session-level context" framing hid the actual shipping work (3 new classifier subsystems + cross-platform test green-up).

v1.0.157

31 May 23:38

Choose a tag to compare

v1.0.157 — patch

Maintenance release. No behavior change for default installs.

Changed

  • Hook session attribution — internal grouping logic refined so multiple working copies of the same project no longer fragment into separate buckets on the analytics side.

Compatibility

  • No breaking changes
  • No new required configuration
  • Existing installs upgrade cleanly

Upgrade

```bash
/context-mode:ctx-upgrade

then restart your session

```

v1.0.156

31 May 23:21

Choose a tag to compare

v1.0.156 — patch

Maintenance release. No behavior change for default installs.

Changed

  • Hook event envelopehooks/platform-bridge.mjs body builder replaced with a forward-compatible canonical envelope. New event attributes flow through verbatim instead of requiring a release; the smaller wire surface also eliminates a class of silent drop bugs from stale hand-mapped field translation.

Compatibility

  • No breaking changes
  • No new required configuration
  • Existing installs upgrade cleanly

Upgrade

```bash
/context-mode:ctx-upgrade

then restart your session

```

v1.0.155

31 May 22:50

Choose a tag to compare

v1.0.155 — patch

Maintenance release. Zero behavior change for default installs.

Changed

  • Hooks performancesession-loaders per-event path now memoizes its config probe; the unconfigured-default path no longer hits fs.readFileSync on every event (60s TTL cache).
  • Test alignmentformatters test suite updated for the claude-code modify→deny probe shape introduced in v1.0.154.

Internal

  • New hooks/platform-bridge.mjs scaffold — opt-in, off-by-default. Gated entry point that returns immediately unless an explicit local config file is present.

Compatibility

  • No breaking changes
  • No new required configuration
  • Existing installs upgrade cleanly

Upgrade

```bash
/context-mode:ctx-upgrade

then restart your session

```

v1.0.154

31 May 20:07

Choose a tag to compare

v1.0.154 — claude-code Bash routing hotfix (CRITICAL)

Diagnosed live via /diagnose Phase 1-6: CC v2.1.x Bash tool ignores updatedInput.command substitution under permissionDecision: "allow" — the original command runs unchanged. Only permissionDecision: "deny" is honored for Bash blocking.

Impact

Every Claude Code user has been silently losing the curl/wget/inline-HTTP routing intervention. Users ran curl https://example.com, got the raw HTML, never saw the routing nudge to ctx_fetch_and_index / ctx_execute. Context-window protection — the core promise of context-mode — silently no-op'd in production for the dominant adapter. High-impact regression that surfaces on the first new-user test session.

Fix

Tool-aware claude-code formatter:

  • Bash redirect (updatedInput.command): emit permissionDecision: "deny" with the routing guidance as permissionDecisionReason. CC blocks the curl/wget call and shows the user the actionable redirect text verbatim.
  • Agent prompt injection (updatedInput.prompt): keep the modify shape — CC honors allow+updatedInput for the Agent tool, so subagent routing-block injection continues to work unchanged.
  • Other adapters (gemini-cli, vscode-copilot, cursor, kimi): untouched — their hosts handle updatedInput differently and the previous shape stays correct.

Fallback deny message (rare path when echo wrapper unparseable) follows ADR-0003 CASE A voice: opens with "Redirected to ctx_execute / ctx_fetch_and_index", names alternatives via imperative call (Call ctx_execute(language, code) ...), affirms "full network access", ends with canonical transient-DNS retry hint. No "blocked", no bare-NOT negation, no org-rationale preface.

Validation

  • 509/509 hooks tests green
  • typecheck clean
  • 4 files / +159 / -23
  • Regression guards: formatters.test.ts + integration.test.ts lock the new deny shape and the ADR-0003 voice on the fallback path

Upgrade

/context-mode:ctx-upgrade
# then restart your Claude Code session

After restart, curl / wget / python -c "requests.get(...)" from inside Claude Code will be blocked with a clear Redirected to ctx_execute / ctx_fetch_and_index ... message instead of silently running the original command.

Diagnostic trail

  • /diagnose Phase 1: differential loop (node vs bun) — byte-identical output, ruled out bun/node stdio incompatibility.
  • /diagnose Phase 4: forced-deny probe injected into pretooluse.mjs — proved CC honors permissionDecision: "deny" but ignores permissionDecision: "allow" + updatedInput.command for the Bash tool.
  • Confirmed against refs/platforms/claude-code/src/utils/hooks.ts:552-620 (parser source) and CC changelog 2.1.85 entry.

Full changelog

v1.0.153...v1.0.154

v1.0.153

31 May 16:21

Choose a tag to compare

v1.0.153 — ctx_stats UX cleanup

Hotfix following v1.0.152 (~1 hour ago).

Removed

## Observability machine-readable block in ctx_stats output. The cache.hit_rate / index.total_chunks / index.total_sources / index.last_indexed_at footer was bleeding low-level diagnostics into the curated 5-section narrative report. Users saw an ungrouped block after the storytelling sections and asked "what is this?" — clear signal it didn't belong in the human-facing report.

The underlying state is still available:

  • ContentStore.getIndexState() API unchanged — useful for /ctx-doctor or future targeted surfaces.
  • report.cache.hit_rate still computed on the AnalyticsEngine report — just not rendered.

Verification

  • renderObservabilityBlock helper deleted + both call sites removed in src/session/analytics.ts.
  • Regression guard added: formatReport asserted to NEVER emit ## Observability on either path (narrative or legacy), regardless of indexState.
  • Grep across src/ hooks/ scripts/ for any Observability artifact → 0 matches.
  • Typecheck clean, full tests/core/ suite 920/922 (2 pre-existing unrelated env-cascade flakes).

Upgrade

/context-mode:ctx-upgrade
# then restart your session

ctx_stats output now ends cleanly at the v{VERSION} footer line — no machine-readable trailer.

Full changelog

v1.0.152...v1.0.153