# Changelog

## 0.1.35

### Added
- **Direct File Reading via `filePath` in `context_lens_code` (#128)**: Enabled `context_lens_code` to directly read files from disk when `code` is omitted, eliminating token-costly redundant `read_file` roundtrips before skeletonization. Added file size limit (`MAX_DIRECT_READ_BYTES` = 1 MiB), directory guard, and automated language detection (`detectLanguageFromPath`).

### Fixed
- **Client CSS Fallback Theme Tokens (#128)**: Removed hardcoded `#ffffff` fallback in `.cl-btn-primary` within `lib/client.js`, strictly adhering to canonical DSH theme tokens and clearing the preflight warning.

### Documentation
- **On-Demand Architecture & Settings Clarification (#128)**: Realigned `README.md` (EN, RU, ZH) with on-demand tool execution model, documented direct file reading parameters, and clarified `autoCompressThreshold` usage in `context_lens_log`. Documented Section 11 *On-Demand Semantic Execution & Direct File Reading Contract* in `docs/design/DESIGN.md`.

## 0.1.34

### Fixed
- **Relative Focus Pattern Matching for Absolute File Paths (#125)**: Resolved an issue where relative focus patterns and directory names (e.g. `src`, `lib/foo.ts`, `./src`, `/src`) failed to match absolute file paths (e.g. `/repo/src/a.js`) in `context_lens_code`, causing focused files to be skeletonized. Implemented boundary-checked directory segment matching and leading `./` normalization in `lib/tools.js` with zero false positives for partial folder collisions (`my-src` vs `src`).

## 0.1.33

### Fixed
- **Ghost Theme Tokens Replaced with Canonical DSH Tokens (#122)**: Replaced truncated `--dsw-alias-label-primary-invert` with canonical `--dsw-alias-label-primary-inverted`. Removed ghost token references `--dsw-alias-color-danger-bg` and `--dsw-alias-state-error-border` from `.cl-error-box` styles, normalizing background and border definitions to canonical `color-mix` expressions based on `--dsw-alias-state-error-primary`. Added automated theme guard validating all client CSS tokens against the canonical DSH design system.

## 0.1.32

### Fixed
- **Dead Test-Only Exports Pruned (#115)**: Removed `resetFocusBySession` and `getFocusBySessionSize` from `lib/tools.js`. Test suites now interact solely with the public `clearFocus()` API and verify true LRU cache behavior instead of inspecting private state.
- **Session Focus Isolation & Runtime Metadata (#104)**: Documented `focusBySession` LRU cache architecture and lifecycle semantics. Extended `sessionKey` resolution to extract session identifiers from runtime execution metadata (`meta.conversationId`, `meta.conversation_id`, and `meta.session.sessionId`), preventing unintended fallback to the shared `'__default__'` session bucket. Implemented proper LRU access refreshes (`delete` + `set`) in `getFocus()`.

## 0.1.31

### Fixed
- **Client ConfigForm Read and Mutation Protocol (#111)**: Realigned `lib/client.js` with DSH 0.2 `ConfigForm` lifecycle contract. Reads settings from `snap.value` (with backwards compatibility fallback for `snap.values`), isolates the 3 schema fields (`compressionMode`, `astSkeletonMaxDepth`, `autoCompressThreshold`), and writes updates per-field via `scope.mutate([{ type: 'set', key, value }])` or `scope.set(key, value)`, eliminating the non-existent `scope.update` call and preventing schema pollution under the plugin namespace.
- **Accordion Accessibility and Keyboard Navigation (#112)**: Replaced non-interactive `div` accordion header with a semantic `<button type="button">`, adding `aria-expanded` and `aria-controls` referencing the unique body ID (`cl-body-${NS}`). Added `:focus-visible` styling for accessible keyboard navigation.
- **DSH Canonical Theme Tokens (#113)**: Replaced 6 non-existent theme variables (`--dsw-alias-border-primary`, `--dsw-alias-btn-primary-bg`, `--dsw-alias-accent-primary`, `--dsw-alias-btn-primary-color`, `--dsw-alias-text-contrast`, `--dsw-alias-state-error-bg`) with canonical DSH tokens (`--dsw-alias-border-l1`/`l2`, `--dsw-alias-brand-primary`/`invert`, `--dsw-alias-color-danger-bg`/`color-mix`).

## 0.1.30

### Fixed
- **Schemastery Volatile Boxes Unwrapped (#102)**: Ensured `plainConfig` wraps initial `readConfig` and effect teardown assignments, preventing raw Schemastery Volatile boxes `{ get: [Function] }` from reaching tool consumers (`astSkeletonMaxDepth`, `compressionMode`, `autoCompressThreshold`) and preventing `NaN` / `[object Object]` comparisons.
- **Active Live Settings Cache Refresh (#103)**: Implemented local `cachedLiveSettings` that actively refreshes upon `settings/document-updated` events, eliminating empty listener stub and avoiding repeated synchronous `describe()` lookups on each tool execution.
- **Pruned Dead Code (#114, #105)**: Removed unreachable `else if (typeof sctx.settings.get === 'function')` fallback in `readLiveSettings` and pruned unused module-level variable `lastActiveSession` and its assignments in `lib/tools.js`.


## 0.1.29

### Fixed
- **DSH 0.2.0-rc.2 List Slot Compatibility (#108, GH #3)**: Starting with DSH 0.2.0-rc.2, `plugins.item` became a list slot requiring `options.id`. Provided both `options.id` and `options.key` for `plugins.item` for dual compatibility, kept `options.key` for keyed slot `plugins.row.config`, and wrapped slot registration inside the `inject` callback with `try / catch` to eliminate uncaught boot exceptions.

## 0.1.28

### Fixed
- **Peer gate on DSH 0.2.0-rc.1** (#58): DSH skips a profile bundle whose `peerDependencies` exclude the running version, so this plugin was absent from the profile with no error in the UI. Every `@deepseek-ai/dsh-*` peer now names both the 0.1.7-rc.2 and 0.2.0-rc.1 lines, because semver does not admit a prerelease of the next minor into a range that does not name it.

## 0.1.27

### Fixed
- **Peer gate on DSH 0.2.0-rc.1** (#58): DSH skips a profile bundle whose `peerDependencies` exclude the running version, so this plugin was absent from the profile with no error in the UI. Every `@deepseek-ai/dsh-*` peer now names both the 0.1.7-rc.2 and 0.2.0-rc.1 lines, because semver does not admit a prerelease of the next minor into a range that does not name it.

All notable changes to `@goodandready/dsh-context-lens` will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.26] - 2026-09-26

### Changed
- **Narrowed to Semantic Compression (#96)**: Delegated context budgeting, token counting, tool result pruning, and long result spilling to DSH core (>= 0.1.5-rc.3). Removed lib/tokens/, session budget calculations, and token savings telemetry.
- **Consolidated Agent Tools (#96)**: Streamlined tool footprint to exactly two tools:
  - context_lens_code: multi-language AST code skeletonization and session path focus management (ction: 'skeleton' | 'focus' | 'get_focus' | 'clear_focus').
  - context_lens_log: intelligent test and build log condenser (preserving failures, stack traces, and test summary; collapses passing runs to concise summary; discriminates test/build logs from plain commands in auto mode).
- **Streamlined UI & Removed Dead Routes (#96)**: Removed duplicate sidebar tabs, conversation utilities header chip, self-updater, and obsolete HTTP endpoints (/status, /compress-preview, /clear-focus). Retained clean settings card in DSH Settings with client-side interactive preview.

## [0.1.25] - 2026-09-25

### Fixed
- **SettingsForms modern API adapter (#66)**: removed legacy call to nonexistent `sctx.settings.register` preventing crash on DSH 0.1.7-rc.1 core. Implemented `SettingsForms` adapter with `configure({ auto: false })`, live reading via `describe()` / `get()`, dynamic updates via `settings/document-updated`, and full cleanup on effect disposal.

## [0.1.24] - 2026-09-24

### Performance
- **Optimized log auto-compression**: replaced string array allocation `split('\n').length > 100` with zero-allocation early-exit `hasAtLeastLines(text, 101)` scan, delivering ~55x faster checks on large log outputs (#85).
- **Fast-path ANSI stripping**: added immediate fast-path return in `cleanAnsi` for strings without `\u001b` and cached cleaned lines during log compression to eliminate duplicate regex execution (#88).

### Security
- **Hardened `/dsh-context-lens/status` route**: enforced HTTP `GET` method (`405 Method Not Allowed` on other methods) and verified trusted source via `isTrustedRequest` (`403 Forbidden` on untrusted origins), closing cross-site telemetry leak (#87).

### Fixed
- **Prevented session memory leak**: `clearFocus(key)` now explicitly deletes the session key from `focusBySession`, and enforced a maximum capacity limit (`MAX_FOCUS_SESSIONS = 500`) with LRU eviction (#86).
- **Sanitized focus paths and fixed matching**: filtered out empty and whitespace strings in `context_lens_focus`, and implemented strict path segment matching in `isPathFocused()` to prevent false compression bypass (#89).

## 0.1.23

### Fixed
- Settings no longer wait on the removed settingsScope service. The client uses configForms (#90).

## [0.1.22] - 2026-09-19

### Fixed
- **Settings reachable again on the plugin's own page**: the current DSH core
  (0.1.6-alpha.2) renders a plugin's configuration page only for entries registered
  in the plugin-list seat `plugins.item` — that is how `dsh-agentrouter` and
  `dsh-agent-orchestrator` show their settings, while the row seat and the legacy
  card alone leave the page without the form. The view-aware card is now registered
  there too (`id: 'dsh-context-lens'`, order 60, static label); `plugins.row.config`
  and `settings.plugin.item` stay as fallbacks.

## [0.1.21] - 2026-09-19

### Fixed
- **Settings reachable again**: the card registered into `settings.plugin.item`, a
  slot the current DSH core (0.1.6-alpha.2) no longer renders, so the settings were
  unreachable. The surface now registers into the Plugins page row seat
  `plugins.row.config`, keyed `@goodandready/dsh-context-lens#dsh-context-lens`
  (`rowConfigKey(package, rowId)`): the plugin's row gains a configure control whose
  page is the settings form (`view: 'page'`, without our header and card chrome —
  the host page draws the title, icon, crumb and padding) plus a one-line state for
  `view: 'summary'`. The legacy seat stays registered as a fallback for older cores.
- Guard `test/row-seat.test.mjs`: row key against `package.json` and
  `cordis.patch.yml`, seat order (row seat first, legacy seat kept), bare page
  render and no duplicate `settings.section`.

## [0.1.20] - 2026-09-18

### Fixed
- **UI Slot Registration Error Diagnostics (#76)**: Replaced silent/empty `catch` blocks in `lib/client.js` for `sidebar.right.pane.tab`, `conversation.session.header.utilities`, and `betterSidebar` slot registrations with descriptive `console.warn` diagnostic logs. Added explicit fallback intention comments for locale snapshot handling.

### Refactored
- **Tracker Dead Code Cleanup (#77)**: Removed redundant, test-only `clearHistory` export from `lib/tokens/tracker.js`. History clearing is canonically and safely handled by `reset()`.

### Documentation
- **Keep a Changelog Standardization (#74)**: Extracted chronological release notes (`## Changed in v...`) from `README.md`, `README.ru.md`, and `README.zh.md` into centralized `CHANGELOG.md`. Consolidated all product feature documentation into comprehensive thematic sections. Included `CHANGELOG.md` in package distribution manifest (`package.json` files list).

## [0.1.18] - 2026-09-17

### Fixed
- **AI Tool ContentBlock Format (GH #2 / Gitea #71)**: Fixed output formatting across all 5 AI tools (`context_lens_status`, `context_lens_compress_preview`, `context_lens_skeletonize`, `context_lens_track`, `context_lens_clear_focus`). All tools now return structured `ContentBlock[]` arrays (`[{ type: 'text', text: ... }]`) instead of raw JSON strings, preventing session-poisoning `TypeError: content.some is not a function` exceptions in `@deepseek-ai/dsh-llm`.
- **HTTP Parameter Validation (#70)**: Replaced silent error swallows with explicit 400 Bad Request responses and diagnostic warning logging when parsing malformed URL queries or invalid session parameters.

### Added
- **In-App One-Click Auto-Updater (#61)**: Added standard updater module (`lib/updater.js`) with `/api/dsh-context-lens/update` endpoint and an in-app update banner with version badge and update button in the settings card.

### Security
- **HTTP Endpoint Hardening (#62, #63)**: 
  - `/clear-focus` strictly requires `POST` method (returns 405 on GET) and validates loopback / same-origin trusted source (403 on untrusted).
  - `/compress-preview` strictly requires `POST`, verifies loopback / same-origin, caps request body at 256KB (413 on exceed), and validates `maxLines` parameter (clamped between 1 and 5000).

### Changed
- **UI Design System & Theme Alignment (#67, #68)**: Replaced text fallback chevron `▼` with an animated SVG 14x14 icon with smooth 180° rotation. Removed all hardcoded `rgba()` values in favor of DeepSeek Harness `--dsw-alias-*` theme variables.
- **Settings & Cordis Lifecycle (#64, #66)**: Injected `settingsScope` directly into client plugin dependencies and removed foreign `lanSettings` fallback. Wrapped settings and locale registrations in `ctx.effect` with disposable cleanups.
- **Code Decomposition (#69)**: Modularized server half into `lib/http.js`, `lib/tools.js`, `lib/updater.js`, and a compact `lib/index.js`.
- **Repository Hygiene (#65)**: Purged internal agent artifacts (`AGENTS.md`, `index.md`, `docs/plans/`) from tracked git tree and updated `.gitignore`.

## [0.1.17] - 2026-09-15

### Added
- **Focus Management UI**: Added active session focus path chips (`focus.paths`) and an instant "Clear focus" button in `StatusPanel`.
- **Configurable Budget Alert Threshold**: Added `budgetAlertPercent` (50–99%, default 90%) to `Config` and the settings card, allowing customizable budget alert levels.
- **Expanded AST Syntax**: Added pure regex AST skeletonization for C/C++ (`class`, methods, `#include`) and SQL DDL (`CREATE/ALTER TABLE`, `INDEX`).

### Changed
- **Multi-Language Standard**: Client bundle now strictly contains only canonical English (`en`) and Chinese (`zh`) dictionaries. Russian translations are provided externally via `dsh-russian-lang`.

## [0.1.16] - 2026-09-13

### Added
- **UI Error Boundary**: Wrapped visual components (`PluginCard`, `LensTab`, `StatusPanel`) in native React error boundaries with retry buttons, preventing parent crashes and React Error 310.
- **Reactive Settings Synchronization**: Added support for reading settings snapshots via `scope.getSnapshot()` and reactive subscriptions via `scope.subscribe()`.

### Changed
- **ClineBot Unified Style**: Migrated UI classes to the unified `.cl-*` design system with `--dsw-alias-*` CSS tokens.
- **Input Validation**: Added defensive input validation across all compression, skeletonization, and tracking functions.

## [0.1.15] - 2026-09-11

### Added
- **Native DSH Right Sidebar**: Added support for DeepSeek Harness 0.1.5-alpha.1+ native right sidebar via `ctx.sidebarRightTabs` and `sidebar.right.pane.tab` slot.

### Changed
- **Sidebar Coexistence**: Preserved legacy `dsh-better-sidebar` integration with deterministic, non-conflicting IDs (`@goodandready/dsh-context-lens` vs `dsh-context-lens:tab`) and graceful fallback across all 4 layouts.

## [0.1.14] - 2026-09-09

### Added
- **AST Multiline Signatures**: Added multiline function and method signature parsing for TypeScript, JavaScript, Rust, and Go.
- **Reset Tool**: Added `context_lens_reset` tool to reset token tracker statistics and compression history.

### Changed
- **Adaptive Polling**: Header chip pauses polling on hidden browser tabs (`visibilitychange`) and polls actively (4s) only when the popover is open.
- **Settings Atomicity**: Added atomic settings patch saving in `PluginCard`.

## [0.1.13] - 2026-09-07

### Fixed
- **Cordis Proxy Safety**: Guarded optional `betterSidebar` tab registration via `ctx.inject(['betterSidebar'], ...)` instead of direct property access on Cordis context proxy.
- **Settings Scope Guard**: Protected `_ctx.settingsScope` access in `PluginCard` with try/catch to avoid proxy errors on older hosts.

## [0.1.12] - 2026-09-05

### Changed
- **Component Refactoring**: Extracted shared `StatusPanel` component reused by `LensTab` and the `HeaderChip` popover.

## [0.1.11] - 2026-09-03

### Fixed
- **Audit Fixes**: Auto-compress honors configured `compressionMode`, `budgetLimit` halts token accumulation once exceeded, focus state is tracked per-session (`sessionId`), and Python imports are properly retained.

## [0.1.10] - 2026-08-30

### Added
- **Session Header Chip**: Registered header chip in `conversation.session.header.utilities` (`order: 7`) with interactive dropdown popover showing live token savings, budget progress, and recent operations.

## [0.1.9] - 2026-08-25

### Changed
- **Compatibility**: Removed obsolete kernel modules from client injects for DSH 0.1.2-rc.1.

## [0.1.8] - 2026-08-20

### Fixed
- **Tool Arguments**: Supported both `text` and `log` parameter names in `context_lens_compress_log`.
- **Tracker & Parsing**: Fixed cross-platform path resolution on Windows, dynamic `budgetLimit` propagation, ANSI terminal escape sequence stripping, and Rust `pub async fn` syntax support.
