# Changelog

This project follows Semantic Versioning-style releases. Before 1.0, releases may include breaking changes.

## Unreleased

- **Breaking / Config:** removed the unused `context.reduction.model_pool` setting and the unused `maintenance.size_check_interval_hours` setting. Context reduction remains deterministic and does not call an auxiliary model; use `context.compaction.model_pool` for LLM-backed durable compaction.
- Runtime / Context reduction: tuned the default byte thresholds to be more prompt-cache friendly while still trimming large stale output. `shell_success_bytes` is now `8000` (was `4000`) and `read_like_output_bytes` is now `4000` (was `2500`); age gates and `min_tool_results_prune` are unchanged.
- Runtime / Loop: loop-mode `Done` exit requests no longer have a machine-enforced verification-status gate. Open TODOs, active subagents, blocked states, and malformed/mixed `Done` batches still prevent automatic completion; verification-like tool results continue to count as progress for stall detection.
- TUI / Navigation: a no-op scroll-down at the bottom no longer re-enables sticky follow mode after the user manually disabled it, preserving manual scroll state.
- TUI / Tool cards: card headers now show one-based block sequence ids (for example `TOOL CALL #12`) so rendered cards can be referenced unambiguously.

- LSP / Python diagnostics: post-tool diagnostics for Python files now have a quick-fallback backend. The default config runs `pyright` LSP as the semantic backend and `ruff check ... --output-format json` as a quick backend; large files (configurable `diagnostics.python.large_file.line_threshold` / `byte_threshold`, default 5000 lines / 250000 bytes) automatically use the quick backend instead of blocking on full semantic analysis, and `run_semantic_when_quick_unavailable: true` keeps semantic diagnostics on large files when no quick backend is configured. New top-level `diagnostics.*` config exposes per-backend command/server selection plus `diagnostics.python.output.*` to bound diagnostics text appended to tool results. See `docs/configuration.md` for the full key reference.
- LSP / Diagnostics output: appended LSP and Ruff diagnostics are now capped to concise priority-ordered blocks (errors and warnings first, then info and hints only when the limit still has room). Clean runs no longer add a redundant status line, and changed diagnostics add only a short `Diagnostics changed: N new, M resolved.` summary when there is an actual delta.
- TUI / Copy: `yy` on a tool card now copies a structured Markdown block (`# Tool call` / `## Arguments` / `## Result` / `## Diff`), and Done rejection cards add a `## Rejection reason` section, so external paste targets keep the same shape Chord renders.
- Runtime / Compaction: `/compact` now schedules in the same background worker as automatic compaction. It can be invoked while a turn is active, shows progress in the background compaction status slot, and applies at the next safe continuation/idle barrier instead of requiring an idle barrier up front.
- Runtime / Loop / Compaction: automatic and manual context compaction now run even when loop mode is enabled, so long-running loop sessions can continue past the context budget. Request-level reduction for new messages still stays off in loop mode for cache stability.
- Runtime / Fast mode: `/fast on` / `/fast off` now also propagate to SubAgents. Existing SubAgent LLM clients are updated immediately; newly created, restored, rehydrated, or model-switched SubAgent clients inherit the current fast-mode state.
- Runtime / Delegated todos: `TodoWrite` now allows multiple `in_progress` items when the active role exposes a `Delegate` workflow, but each in-progress item must use a distinct `active_form` so it clearly maps to one live workstream. Single-in-progress validation remains the rule for roles without `Delegate`.
- TUI / Thinking translation: translations are now persisted to `<session_dir>/thinking_translations.json` keyed by `(message, block)` plus a content-hash check, and restored on the next session resume. Translations are not re-generated when `thinking_translation.target_language` changes — a given thinking block is translated at most once. Translations are still UI-only and not written back into model context.
- TUI / Thinking translation: translation envelope markers accidentally echoed by the translation model, including an unmatched leading `<TRANSLATION>`, are stripped before persistence/restoration/rendering so they cannot be parsed as Markdown HTML blocks and suppress Markdown formatting in the translated card.
- Runtime / Thinking translation: empty, severely truncated, or wrong-target-language responses from the translation model are now treated as a soft failure and trigger the next model in the configured pool instead of producing a clearly broken translation card.
- Runtime / Deny reasons: `Question` / confirmation deny reasons now preserve the user's full text, including internal newlines, in both the tool result returned to the model and the TUI card.
- TUI / Rate-limit sidebar: the codex rate-limit sidebar no longer reuses a provider-scoped inline snapshot across key switches. After a key change, the sidebar shows the new key's cached inline snapshot, that key/account's polled `/wham/usage` snapshot, or nothing until fresh data arrives.
- TUI / Navigation: `gg` and `G` in normal mode now move focus to the first/last viewport card instead of plain scroll-to-edge, matching vim-style focus navigation.
- TUI / Tool cards: header truncation no longer drops live progress suffixes, deleted-file Delete cards keep showing the rejection / completion reason in restored sessions, and toast boundary changes trigger a redraw so the boundary marker stays in sync.
- TUI / Focus restore: late deferred tail-window focus restores are reapplied so the focused card stays in view across redraws.
- Runtime / Context reduction stats: the info-panel `Reduced` line now refreshes after `/compact` or automatic compaction rewrites session history, including while loop mode is active.
- Runtime / Compaction summary: the durable compaction summary section header set is now `## Current User Request` / `## Active Objective` / `## Background Goals` instead of a single `## Goal`. Latest user requests and the most recent Done rejection reason now rank as equal-priority anchors (latest wins by sequence) so a fresh Done rejection cannot be overridden by an older standing constraint. The `## Todo State` section uses explicit `Active/relevant to latest request` / `Completed/background` / `Stale/superseded` subgroups so the post-compaction agent re-evaluates pre-compaction todos against the latest request instead of treating them as authoritative.
- Runtime / Plan execution: plan execution now passes the plan to the LLM as an `@<plan-path>` file mention with the file content attached as a message part, rather than inlining the plan text into the system prompt, so plan size is bounded and the file mention stays consistent with normal references.
- Runtime / SubAgent prompt: SubAgent system prompts now report the full platform string `<goos>/<goarch>` (matching MainAgent), instead of just `<goos>`.
- CLI / Done automation: aligned automatic Done interception across startup, runtime, and TUI flows. Startup/TUI creation/shutdown paths are now easier to test, browser-launch auth planning is testable without executing the browser command, and loop-mode Done exit interception is documented consistently. When `CHORD_PPROF_PORT` is set but invalid, `--continue` / `--resume` / `--worktree` and the rest of startup now still take effect (pprof is silently disabled with a warning) instead of being dropped.
- TUI / Done internals: centralized Done-related UI effect handling and stream-render invalidation, split focused regression tests, and kept rejected/auto-rejected Done completions rendering consistently.
- Config / Auth persistence: unified auth persistence locking with the shared config-mutation lock, and added platform-specific regression coverage for write-lock behavior and named-pipe test portability.
- **Breaking / Permissions:** remembered permission rules now write directly to agent config files instead of separate permissions overlays. Session rules remain in memory, project rules update `<project>/.chord/agents/<role>.yaml`, and global rules update `<config-home>/agents/<role>.yaml`; `/rules` removes persisted rules from the same agent file. The built-in planner now allows `Write` / `Edit` only under `.chord/plans/*` by default. Migration: rules previously written to `<project>/.chord/permissions/<role>.yaml` or `~/.chord/permissions/<role>.yaml` are no longer loaded automatically. On startup, Chord logs a one-shot warning per legacy file it finds so you can manually merge the rules into the corresponding agent config file.
- TUI / Performance: reduced CPU and rendering work for background tabs and long conversations, making scrolling and focus recovery smoother in large sessions. Permission evaluation and tool-definition construction hot paths were also reduced.
- TUI / Delete: Delete tool cards now show the required `reason` in both live and restored sessions, and restored tool cards now prefer persisted status/duration metadata so resumed history matches the completed live display.
- Docs: clarified that agent permissions live in `agents/<role>.yaml` and that confirmation/headless remembered rules update the corresponding agent config file; added `diagnostics` to the top-level config keys table; documented the `thinking_translation.max_chars` preview boundary.

## 0.6.0 - 2026-05-20

- Build / Dependencies: require Go 1.26.3+ for source builds and release artifacts, update direct runtime dependencies to their latest compatible versions, and refresh reachable build-graph indirect dependencies. CI and release workflows read the Go version from `go.mod`, so published binaries are built with the patched Go toolchain.
- Runtime / Context: added deterministic request-time context reduction controls under `context.reduction`, including stale tool-result pruning thresholds and a dedicated reduction model-pool hook, while keeping loop mode unpruned.
- Auth / Runtime: moved OAuth account status authority to `auth.state.yaml`, added the `invalidated` status and `key_invalidated` stream delta, and kept legacy `status` out of `auth.yaml`.
- Runtime / Fast mode: `/fast` now uses provider-native acceleration parameters (`service_tier="fast"` for OpenAI Responses and `speed="fast"` for Anthropic) only when the model's `supports_fast` capability is enabled; `preset: codex` enables it by default, other models opt in explicitly.
- **Breaking / Config:** renamed `context.compact_threshold` to `context.compaction.threshold`; there is no compatibility alias for the old key.
- **Breaking / Config:** removed `context.auto_compact`. Automatic context compaction is now enabled when `context.compaction.threshold > 0`; set `context.compaction.threshold: 0` to disable it.
- **Breaking / Config:** removed `context.compact_model`. Context compaction now only accepts `context.compaction.model_pool` for a dedicated compaction pool; when unset, compaction clones the current agent model pool instead of falling back to a single selected model.
- **Breaking / Headless:** removed the external `tool_result` event from the headless/protocol integration surface. Non-loop `Done` reports now use the dedicated `done_completion` event, while loop-mode `Done` exit requests continue to use `confirm_request` with explicit `done_report` / `done_reason` fields. Ordinary tool results remain internal to the agent/TUI lifecycle and are no longer forwarded to headless clients.
- TUI / IME: automatic input-method switching now only runs when the current Chord tab/window is actually foreground-focused, preventing background tabs' chord/mode transitions from clobbering the active tab's IME. On `FocusMsg`/tab return, Chord now reapplies the configured English IME target when the current mode still requires it.
- CLI / Setup: added a first-run setup wizard for the default `chord` command when global `config.yaml` is missing. The wizard runs on a controlling TTY, writes minimal `config.yaml` plus `auth.yaml` when needed, can complete Codex OAuth login during setup, reuses matching existing credentials when possible, and prints the exact paths it used.
- Runtime / Loop / Done: the `Done` tool now requires a non-empty `report` argument containing the full final completion report. Loop mode uses `Done` as the only exit request path: premature `Done` requests are rejected and returned to the model as tool results, while valid exit requests open a local confirmation dialog showing the report.
- TUI / Done: `Done rejected:` and `Done rejected automatically:` results now both render as rejected completions using the standard failure styling (`✗ Done`) plus a simplified rejected-reason line, so loop auto-rejections are visible in the same way as manual rejections.
- TUI / Clipboard: image paste now de-duplicates same-action `Ctrl+V` / `Cmd+V` key events and terminal `PasteMsg` delivery, preventing occasional double image attachment insertion when terminals emit both paths for one paste.
- Tools / Safety: hardened local file/path safety by centralizing path validation for file-reading/search tools. `Read` and `Grep` now share the same existing-path checks and explicitly reject blocked device-style paths such as standard-stream device files.
- Config / Persistence: hardened config writes used by setup and auth persistence. Initial config creation now uses a config-scoped lock plus temp-file + atomic install flow, and auth/config save paths now share the same atomic-write primitives.
- Worktree: `chord worktree finish` now first merges the target branch into the real worktree branch to surface conflicts there, then squashes the finished worktree state back onto the target branch as a single commit. `--check` now preflights that merge in a temporary worktree without mutating the real worktree or target branch, and `finish` now refuses to start when the real worktree already has an in-progress rebase or merge.
- CLI / Import: added `chord import` support for importing external sessions from Claude Code (`claude`), Codex (`codex`), and OpenCode (`opencode`). Import writes a resumable Chord session plus `import-report.json`; Codex defaults to conservative `auto` tool import, OpenCode defaults to text-only tool import and now handles current `{info, parts}` exports with readable unsupported-tool fallbacks, and Claude defaults to `auto` structured-tool preservation only when compatible.
- TUI / Title alert: when a confirmation or question request arrives while Chord is in the background, the terminal title alert still blinks for attention; after the user focuses the tab/window, the alert stays visible but stops blinking for that pending request.
- TUI / Usage: usage/context updates now invalidate the info-panel render cache, fixing stale `TOKENS` values after context compaction or other usage refresh events.
- Docs: clarified that `chord auth state clean` removes invalid runtime-state entries and matching expired/deactivated OAuth credentials, and updated README highlights to describe background compaction plus `/loop` for long-running tasks.

## 0.5.3 - 2026-05-11

- Runtime/File safety: restored or resumed sessions now rebuild durable `Read` file-state, so later `Edit`/`Write` calls keep the read-before-write safety check without falsely requiring every file to be re-read.
- Runtime/Compaction: when `limit.input` is omitted, automatic compaction and model-pool fallback sizing now reserve the effective requested-output budget from `limit.context`, reducing oversized prompt retries and premature threshold calculations.
- Config/Runtime: project `.chord/config.yaml` now merges through the same path for startup, auth login, and model diagnostics; malformed project config is reported instead of silently ignored, and `stream_retry_rounds` can bound public LLM retry rounds for automation.
- TUI: fixed syntax highlighting for Markdown previews so EOF block markers (ordered lists, headings, and similar line-based syntax) keep the same colour as preceding lines in `Read`/`Write` tool cards and fenced code blocks.
- CLI: replaced the deprecated `chord test-providers` entry point with `chord doctor models`, adding exact `provider/model[@variant]` checks, model-pool audits, all-model/all-pool modes, per-target timeout, single-attempt diagnostics by default with optional `--retry`, fail-fast, JSON output, and model/variant tuning coverage.
- CLI/Doctor: `chord doctor models` now reuses refreshed OAuth credential status across multi-target runs, avoiding stale token reuse and misleading failures.

## 0.5.2 - 2026-05-11

- Worktree: `chord worktree finish` now supports `--check`, which runs a temporary isolated rebase preflight so you can see whether the worktree would finish cleanly without mutating the real worktree or leaving it mid-rebase on conflicts.
- **Breaking:** renamed the model-visible command tool from `Bash` to `Shell`. There is no runtime alias or compatibility mapping: update permission rules (`permission.Shell`), hook tool filters, skills `allowed_tools`, imported/saved structured tool calls, headless/tool-event consumers, gateways, and any saved prompts or integrations that refer to the old `Bash` tool name before upgrading.
- TUI: strengthened Ghostty/cmux post-focus recovery for tab/refocus artifacts. The late `post-focus-settle-fallback` pass now revalidates terminal size before replaying the frame, reducing cases where stale horizontal separator lines or other residual cells survive the first focus-restore redraw.
- TUI: renamed the sidebar/info-panel file list from `EDITED FILES` to `CHANGED FILES`; files deleted by new `Delete` tool results now render with a strikethrough filename and no fake `-1` line-count stat.
- TUI: `Write` tool cards now show the written file content as a numbered, syntax-highlighted preview, sharing the same first-10-lines default and space-to-expand behavior as `Read` cards.
- TUI: aligned default shortcuts across modes: `Ctrl+P` is now reserved for the model selector (removed Insert-mode history binding); message directory/tree moved from `Ctrl+J` to `Ctrl+T`; and the default `Ctrl+F` “attach image path from input” binding is removed (configure `insert_attach_file` if you still want it).
- Runtime/LLM retry: API `402` quota/payment exhaustion errors now behave like per-key rate limits: Chord cools down the exhausted key, tries other configured keys for the same model before fallback, and avoids repeatedly retrying the same depleted key.
- Tools/Safety: refined non-interactive Shell/Spawn guardrails so plain stdin reads such as shell `read`/`select` observe EOF instead of being rejected before execution, while terminal/TTY-dependent commands remain blocked.
- Runtime/Codex rate limits: provider usage polling now inherits the application context, so shutdown/cancel paths stop pending Codex usage refreshes instead of letting them wait on a detached background context.
- Auth/Codex: browser and device-code login HTTP requests now inherit the CLI command context, so Ctrl+C or parent shutdown can cancel in-flight device-code and token-exchange requests promptly.

## 0.5.1 - 2026-05-09

- Runtime/TUI: added manual MCP server control for `manual: true` servers. Chord now exposes `/mcp` (`status`, `enable`, `disable`) plus an MCP selector in the TUI (`Ctrl+O`) so on-demand servers can be connected or disconnected at runtime. Auto-start servers remain read-only, and the selector stays open while MCP state updates stream in.
- Runtime: fixed initial LLM client not being configured with the builder agent's model pool. Previously, when multiple models were configured, retries would only rotate through API keys on the first model without falling back to other models. The initial client now properly includes all models from the builder agent's pool, so failures correctly trigger model-level fallback.
- TUI: fixed Ghostty/cmux stale-cell artifacts after focus/resize recovery. The focus-resize freeze path now serializes the drawn screen buffer as a full frame that preserves trailing spaces, instead of relying on string-level end-of-line clearing or post-render padding.
- TUI: upgraded the Bubble Tea rendering stack to newer compatible releases (`bubbletea/v2` 2.0.6, `bubbles/v2` 2.1.0, `lipgloss/v2` 2.0.3, plus newer `ultraviolet` and `x/ansi`) to pick up renderer and terminal-behavior fixes.
- TUI: Write tool card no longer shows a diff preview. The result now displays a clear line and byte count summary (`Successfully wrote N lines, N bytes`) instead of extracting added lines from a unified diff, eliminating the misleading "only a few lines shown" display for full-file writes.
- TUI: removed the pre-read + diff generation pipeline from the Write tool. Write tool results no longer carry `Diff`, `DiffAdded`, or `DiffRemoved` metadata. Edit tool results continue to show diffs as before.
- Write tool `Execute` now reports the line count in addition to byte count in its success message.
- Runtime/Codex rate limits: when active Responses WS streams run without fresh `rate_limits` events, Chord now proactively wakes Codex polling so RATE LIMIT/usage panels stay current instead of showing stale windows.
- Thinking translation: when a translation model returns a semantically empty result, Chord now keeps trying the next model in the configured model pool before giving up, instead of treating the empty translation as a hard failure on the first model.
- Tools/Safety: Bash and Spawn now reject high-confidence interactive shell commands before execution and run with explicit non-interactive environment defaults (for example disabling git credential/editor prompts) to reduce hang risk.
- Tools/Process lifecycle: timeout/cancel shutdown now escalates from graceful terminate to force-kill for process groups after a grace period, preventing stubborn child processes from leaving Bash/Spawn calls stuck.

## 0.5.0 - 2026-05-08

- Config: agent configs now use `mode: main` for MainAgent roles and `mode: subagent` for SubAgents. `sub_agent` and `sub` are also accepted as SubAgent aliases; empty or other values behave as `main`. Hook `agent_kind` filters use `main`/`subagent`.
- CLI: added `chord import` support for importing external sessions from Claude Code (`claude`), Codex (`codex`), and OpenCode (`opencode`). Import writes a resumable Chord session plus `import-report.json`; Codex defaults to conservative `auto` tool import, OpenCode defaults to text-only tool import, and Claude defaults to `auto`.
- Runtime: added request-time model compatibility normalization to safely replay or downgrade provider-specific history payloads (Anthropic signed thinking and structured tools) when switching providers/models.
- Runtime: fixed a potential hang when a tool batch/turn is cancelled while waiting for the shared streaming tool execution quota. Chord now emits a cancelled tool result so pending tool calls resolve and the UI cannot get stuck.
- TUI: fixed running tool/Bash spinner animation to advance one frame per visual animation tick instead of sampling wall-clock time, eliminating deterministic skipped frames and uneven rotation; background-active sessions now keep the same visual spinner cadence as foreground sessions while retaining slower content flushes.
- TUI: fixed `/models` pool switching while the agent is busy. Selecting a pool from the TUI selector now submits the switch immediately to the main event loop, so queued user messages pick up the new pool at the next actual request boundary instead of waiting for another draft send or full idle.
- Worktree: improved `chord worktree finish` failure ergonomics. If the target worktree already has a rebase in progress, `finish` now exits early with an explicit recovery hint instead of attempting a nested rebase. When rebase conflicts occur, the error message now includes step-by-step recovery commands (`git status`, `git rebase --show-current-patch`, then `--skip` / `--continue` / `--abort`) plus a best-effort redundant-commit hint from `git cherry -v` to help identify likely skip-safe patches.
- TUI: when Chord is running in the background, the terminal title now shows a one-shot `✅` completion marker when the focused agent transitions from busy to idle; the marker is cleared on focus.
- TUI: fixed THINKING card ordering when reasoning output is followed quickly by assistant text. Chord now closes and flushes pending thinking before emitting the first text chunk, and ignores late reasoning deltas after text has started so THINKING no longer appears below the answer body.
- TUI: fixed an occasional duplicate horizontal rule above the input separator. When the viewport was pinned to the bottom and the last block was a card style with `MarginBottom(1)` (assistant / user / thinking / tool / compaction), the card's transparent marginBottom row formed a colour step against the dim card-bg padBottom row above it, which read as a second rule on top of the input separator. The vertical margin band now inherits the card bg across the padded width while horizontal margins stay transparent.

## 0.4.0 - 2026-05-07

- Added `--worktree [name]` to both the default TUI command and `chord headless` for creating or entering a chord-managed git worktree at startup. Worktrees live under `<state-dir>/worktrees/<repo-id>/<slug>` with branch `chord/<slug>` (or `<branch_prefix><slug>` when `worktree.branch_prefix` is configured); each worktree gets its own ProjectKey so sessions, runtime cache, and exports are isolated automatically. `--worktree` may be combined with `--continue` / `--resume` to act on the worktree's own session history. Auto-named when the value is empty (`task-YYYYMMDD-HHMMSS`); a branch already attached to a worktree is reused (fast resume). Headless `ready` event payload now carries `worktree: { name, branch, path, repo_root }` when launched with `--worktree`.
- Added `chord worktree` command group: `list` (chord-managed worktrees of the current repo, sorted by recency) and `remove <name>` (deletes the worktree directory and the worktree's sessions/cache/exports while preserving the branch by default; use `--delete-branch` to delete only-if-merged or `--force` for unconditional removal of dirty trees and the branch). Creating/entering a worktree is a startup-level action and lives on the `chord --worktree` flag, not under `chord worktree`; for "enter and continue", use `chord --worktree <name> --continue`.
- Added `chord resume <session-id>`: locates the chord-managed worktree (or main repo) the session belongs to, switches into it, and resumes — complements `chord -r <id>`, which only resumes within the current project.
- Added `worktree.branch_prefix` to `config.yaml`: overrides the default `chord/` prefix used for branch names and `git worktree list --porcelain` filtering. Empty falls back to `chord/`; trailing `/` is appended automatically; values that would produce malformed git refs (leading `/` or `-`, `..`, `//`, whitespace, or non-`[a-zA-Z0-9._/-]` characters) are rejected at startup.
- Extended per-session `session-meta.json` with `repo_id`, `repo_root`, `worktree_name`, `worktree_branch`, `worktree_path`, and `is_main_worktree`. Existing sessions remain compatible; metadata files containing only worktree fields are now correctly recognized.
- Added Google Gemini as a first-class provider (`type: generate-content`, `api_url` ending in `/models`); supports streaming text/tool/thinking output, multimodal inline images, function-calling tools, and Gemini-shaped error responses with `Retry-After` handling.
- Fixed local-only slash commands (`/export`, `/models`) so they always run on the main agent's event loop instead of from the TUI input goroutine. Previously, submitting one of these while an LLM call was retrying could clear the active turn mid-flight, leaving the UI stuck in a "busy" state with no way to cancel; the cancel-busy key path now also recovers gracefully when the agent reports no active turn.
- Fixed slash completion dropdown so scrolling with arrow keys keeps the selected command visible when the list exceeds 8 entries.
- Fixed `/new` so it clears the sidebar EDITED FILES section instead of preserving the previous session's file list.

## 0.3.0 - 2026-05-07

- Added runtime model pools:
  - **Breaking:** agent model configuration must now reference one or more top-level `model_pools` from `config.yaml`; the previous flat per-agent `models` list is no longer accepted. Internally, `AgentConfig.Models` is now a `map[string][]string` (pool name → ordered model refs).
  - Every agent must define at least one pool. Pool names are user-defined and not reserved (for example, `default`, `base`, `fast`, and `strong` are all valid). When no pool is explicitly selected, Chord falls back to the **first** pool in the agent's `model_pools: [...]` list.
  - Agents can reuse globally-defined pools via `model_pools`; inline `models` and `model_pools` are mutually exclusive in agent config. Runtime pool policy now tracks the current model pool, per-agent overrides, and last-picked state with per-project persistence.
  - The `/model` command is replaced by `/models` with `status`, `<pool>`, and `--agent <name> <pool>` subcommands. The TUI selector now chooses pools instead of individual models.
  - Model pool selections made while the agent is busy are submitted to the main event loop immediately. The current in-flight request keeps its existing client snapshot, while queued user messages and other later request boundaries pick up the new pool without waiting for another draft send or full idle. Pending-switch failures now flow through the TUI update loop instead of mutating view state from a background goroutine.
- Added build identity metadata to diagnostics and startup logs. `chord --version`, diagnostics bundles, and TUI dumps now include or expose build/VCS/runtime details such as commit, dirty state, build time when injected, VCS time, Go version, and executable mtime. MCP client info continues to use the bare application version string.
- Fixed SKILLS sidebar state: failed `Skill` tool calls no longer appear as loaded/green, unknown skills are hidden until discovered, and the legacy "(loaded)" suffix is removed.
- Fixed Codex RATE LIMIT panel behavior: reset countdowns no longer stick at "1s" after expiry; when a window reaches its reset timestamp the timer is hidden and Chord triggers a best-effort usage refresh so the next window appears promptly.
- Fixed deferred TUI diagnostics/export status cards so cards queued during assistant streaming appear as soon as the current assistant block finishes instead of waiting until the agent becomes idle.
- Fixed `Cmd+V` clipboard text paste in permission-confirmation edit and deny-reason inputs.

## 0.2.0 - 2026-05-05

- Refactored the TUI render-cache layout so `viewCacheState` contains only draw-loop caches that are safe to bulk reset, while animation/ticker/local-shell/startup-transcript bookkeeping lives in a separate runtime state and survives `invalidateDrawCaches`. The cache invalidator remains a struct re-zero (preserving the `cachedMainSearchBlockIndex = -1` invariant) instead of an 80-line list of per-field assignments. Removed the unused `cachedDirKey`, `cachedHelpKey`, `cachedStatusActivitiesKey`, `cachedStatusChordDisplay`, and `cachedStatusSessionSwitchKey` fields, grouped the five `renderSlashCache*` fields into a `slashRenderCache` substruct (`m.slashCache`), and consolidated the duplicated `renderVersion / renderCacheWidth / renderCacheText / renderCacheValid` quartet on `OverlayList` and `OverlayTable` into a shared `widthKeyedRenderCache` embedded in both.
- Refactored the `agent.AgentForTUI` interface into focused sub-interfaces (`MessageSender`, `PromptResolver`, `ModelSelector`, `SessionController`, `SubAgentInspector`, `LoopController`, `RoleController`, `UsageReporter`, `KeyHealthReporter`, `CompactionController`, `PlanExecutor`) and recomposed `AgentForTUI` from them. Existing implementations (`MainAgent`, headless adapters, in-tree TUI test stubs) and consumers continue to satisfy the composite without changes; new TUI consumers should target the smaller surface they actually need.
- Refactored `MainAgent.Shutdown` from one ~170-line phase into discrete helpers — `cancelActiveWork`, `closeSubAgentMCPServers`, and `buildShutdownSnapshot` — leaving the top-level method at ~92 lines and making each phase independently auditable for ordering and budget handling.
- Removed the unused `tools.TruncateOutput` dead-code wrapper; all internal callers already use `TruncateOutputWithOptions`. Out-of-tree callers must switch to `TruncateOutputWithOptions(output, sessionDir, tools.TruncateOptions{})` for the previous default behavior.

- Improved Pyright LSP setup: Chord now automatically discovers project-local `.venv`, `venv`, and `env` interpreters using the current platform's virtualenv layout (Unix `bin/python`, including WSL; Windows `Scripts\python.exe`) when no Python interpreter is configured, normalizes relative `python.pythonPath`, `python.defaultInterpreterPath`, and `python.venvPath` against the LSP root, and returns section-specific workspace settings so pyright-langserver can read `python` configuration correctly. Breaking change: LSP `options` consumed through `workspace/configuration` must now be shaped by section for every LSP server, not just Pyright; for Pyright, use nested keys like `python` and `python.analysis` rather than legacy flat top-level keys.
- Removed the deprecated headless `notification` envelope type: dropped `protocol.TypeNotification` and `protocol.NotificationPayload`, and removed `"notification"` from the headless subscription allowlist. No code path emitted this envelope anymore; gateways should render the user-visible ready/idle state from the `idle` envelope.
- Replaced the previous `slog`-style logging adapter with direct `golog` usage across the runtime. Logs are now plain golog text output with direct caller attribution; the previous pseudo-structured `level=... msg=... key=value` formatting and default logger `With(...)` context fields are no longer emitted automatically.
- Fixed `ee`/fork editing for image messages so images restored from session history by path are reloaded and included when the edited user message is sent again.
- Fixed TUI tool-card rendering so tool arguments/results are shown as terminal-safe plain text: ANSI/control sequences are escaped, Markdown-looking generic tool output is no longer auto-rendered as Markdown, large collapsed Bash results avoid wrapping hidden tails, and collapsed hidden-line hints no longer double-count the first hidden line.
- Removed obsolete pre-1.0 compatibility paths and dead code across compaction, LLM session handling, LSP test-only helpers, tools, and TUI internals. This cleanup deletes the unused `ResetResponsesSession` / legacy responses-session reset chain, removes the old synchronous compaction fallback path, moves test-only helpers into `_test.go`, deduplicates fallback-summary rendering, finishes centralizing tool-name handling on `tools.NameXxx` constants, and keeps plan-execution session switches aligned with the active provider/session identifier lifecycle.
- Fixed long-session TUI transcript clipping where late updates to older background status cards could undercount transcript height after spill/hydrate recovery, making the bottom rows or even several final cards unreachable.
- Removed the deprecated `blockers_remaining` field from the SubAgent `Complete` tool arguments and `CompletionEnvelope`; SubAgents must report non-blocking caveats via `remaining_limitations` and signal true blockers through the Escalate or `blocked` mailbox path instead of `Complete`.
- Unified SubAgent artifact representation: mailbox messages, durable task records, per-instance meta files, and the in-memory runtime state now reference artifacts via a single `ArtifactRef` / `[]ArtifactRef` shape; removed the parallel `artifact_ids` / `artifact_rel_paths` / `artifact_type` fields and the related legacy adapter.
- Replaced remaining hard-coded tool-name string literals (`Read` / `Write` / `Edit` / `Delete` / `Grep` / `Glob`) across TUI rendering, search, hooks, agent execution paths, and edit tracking with the centralized `tools.NameXxx` constants.
- Removed the unused deprecated `skill.Loader.Scan()` helper; remaining callers already use `ScanMeta` plus on-demand `Load`.
- Improved MCP initialize handshake metadata so runtime-managed MCP clients now send the build-time Chord version instead of a stale hardcoded version, while preserving the default `mcp.NewClient` / `NewPendingManager` / `NewManager` convenience APIs and adding explicit `WithClientInfo` variants for callers that need custom handshake identity.
- Centralized local tool traits used by TUI expansion and compaction (`Read` / `Grep` / `Glob` / `WebFetch` vs file-mutating tools) into `internal/tools/tool_traits.go` to reduce scattered string-driven branching.
- Removed the legacy `ProviderConfig.UpdatePolledRateLimitSnapshot` test-compat wrapper in favor of explicit credential-index updates via `UpdatePolledRateLimitSnapshotForCredentialIndex`.
- Added structured SubAgent completion handoff with files changed, verification run, remaining limitations, risks, follow-up recommendations, and artifact references.
- Fixed TUI tool cards so queued badges and wrapped content keep consistent right-side padding.
- Added session-scoped `SaveArtifact` and `ReadArtifact` tools for SubAgent handoff artifacts, with persistence through mailbox, task registry, snapshots, and session restore.
- Improved SubAgent coordination snapshots to surface recent completion metadata, artifact references, write scope, and suspected stalls.
- Fixed TUI transcript viewport drift that could accumulate in long sessions, clipping the last card/padding and causing mouse selection to hit the wrong rows.
- Fixed TUI transcript mouse selection copy so drag-selected text keeps the final character when copied with `Cmd+C`, and documented transcript copying behavior.
- Improved loop verification continuations so `verify` assessments inject a dedicated `LOOP VERIFY` notice with explicit verification guidance, and documented `/loop on [target]`.
- Fixed LSP sidebar diagnostics so clean post-edit self-reviews persist `0E/0W` snapshots and clear stale errors after syntax issues are resolved.
- Fixed TUI card background artifacts around emoji, variation selectors, and ZWJ graphemes by aligning wrapping, padding, and truncation with the viewport grapheme-width calculation.
- Improved TUI tool-call file path display so local-path tools such as `Read`, `Write`, `Edit`, `Delete`, `Grep`, and `Glob`, along with existing visible path-bearing Bash metadata, show paths relative to the active project root when possible, including after session resume/startup restore and spill/hydrate recovery, while keeping external paths absolute.
- Improved AGENTS.md handling by adding stable system-prompt framing only when repository guidance exists, while keeping AGENTS.md contents in the session `<system-reminder>` context layer.
- Fixed sticky fallback model variants so pinned fallback requests preserve their own `@variant` and do not leak the primary model variant into variantless fallback runs.
- Fixed categorized loop blocked messages rendering as unnamed status cards.
- Fixed Ghostty/tab focus-restore artifacts by tracking transcript/layout changes that occur while the terminal is backgrounded, forcing a host redraw after focus-settle when those background changes are observed, and recording background-dirty plus input-separator diagnostics to make any remaining stale-display cases easier to investigate.
- Fixed Ghostty/cmux stale display where separator lines could appear duplicated after rapid scroll/resize/layout changes; Chord now clears to end-of-line per rendered row in those terminals to avoid leftover cells.
- Improved queued tool call badges so they keep right-side padding and hide when the tool header is too narrow.
- Improved TUI markdown rendering caches for assistant/thinking streams, compaction summaries, and status cards.
- Fixed collapsed tool result hidden-line counts for markdown-like output.
- Fixed headless idle events so Chord emits a single `idle` envelope instead of also sending a duplicate ready `notification` envelope; gateways should render the idle state themselves.

- Fixed compaction follow-up behavior in three related cases: preserved/restored terminal titles now ignore compaction-summary pollution more reliably across old and newly compacted sessions; auto-compaction continuation no longer emits duplicate idle transitions when a barrier apply fails; and active title animation now always re-synchronizes the terminal-title ticker before resuming spinner-driven activity.
- Changed automatic (usage/threshold-driven) compaction continuation: after the durable summary is applied the agent now proactively spawns a fresh LLM turn on the compacted context so the work keeps progressing, instead of going idle until the user prompts again. Manual `/compact` continues to return to idle. Sessions running in loop mode advance the loop state when the auto-continue fires.
- Improved session preview/title correctness after compaction by persisting explicit metadata in `usage-summary.json` and session summaries (`*_is_compaction_summary` flags) instead of inferring compaction from text content. Breaking change: sessions created/compacted by older versions may still show polluted titles/previews until they are compacted again with this version.

## 0.1.0 - 2026-04-29

- Initial public release of Chord.
- Added the terminal coding agent with local-first runtime, Vim-like navigation, session management, model/provider configuration, tool execution, LSP integration, image input, and headless control support.
- Added cross-platform release builds for macOS, Linux, and Windows.
