# Changelog

All notable changes to this project 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).

## [Unreleased]

## [0.14.0] - 2026-11-02

### Added
- `CHANGELOG.md` now ships in the npm package, so Pi 1.5.0 can show pi-topping's release notes under "Extension Updates" on the first fresh launch after an update.
- The working loader's response model is followed by its thinking level, with the Nerd Font glyph from pi-topping-statusline's nerd preset (for example `gpt-6.1-sol 󰪟 low`), or the unicode preset's glyph and short name (for example `◑ med`) when it is off. Under a routesense selection the level is the one routesense announced for the request. Otherwise it is the session's level, shown only when the selected model supports reasoning. The level rides on the response model, so it is hidden whenever the response model is: when **Response model** is off, or when the response model only restates the selected model. `off` shows nothing, and the completion marker and response-model footer still show only the model.
- `@underactive/pi-topping-sensei` joins the sibling toppings that pi-topping checks for at startup and offers to install from `/topping-setup`.

### Changed
- Verified compatibility with Pi 1.5.0; development and CI now typecheck and test against it, and the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 1.4.0 to 1.5.0. No runtime behavior changed, the published `peerDependencies` remain `*`, and the minimum supported host remains Pi ≥1.2.0.
- On Pi 1.5.0 the working loader's response model, the response-model footer and the completion marker show the physical model under pi-messages providers such as Radius, including under virtual models, because the host now sets `responseModel` on those messages. pi-topping already preferred that field, so nothing changed here; a response model that only restates the selected model is still hidden, and older hosts are unchanged.
- Depend on `@underactive/pi-topping-primitives` `^0.12.1` (was `^0.10.0`); thinking-level labels now come from `./glyphs` (0.11.0). Nerd Font output is unchanged, while the configured Unicode preset is used when Nerd Font icons are off. 0.12.x only added `./classifier`, which pi-topping does not use.

### Removed
- `nvidia-green.ts` no longer re-exports `isSwitchyardProvider` and `SWITCHYARD_PROVIDER`; import them from `@underactive/pi-topping-primitives/color` instead. `NVIDIA_GREEN_HEX` is still re-exported.

### Fixed
- Under a diffusion provider (Inception Mercury via pi-inceptionlabs), the working loader's output-token count, token rate and activity meter now grow as diffusion frames arrive, instead of staying at `--- tps` until the response ends. Each frame resends the whole answer so far with undecoded regions still noisy, so pi-topping estimates progress from how far the decoded prefix grows between consecutive frames, read from `provider_stream_event`. The exact `usage.output` still replaces the estimate at message end. Only the `inception-diffusion` API is treated as diffusion; other providers are unchanged.
- Under a diffusion provider, the final diffusion frame's forwarded text delta is no longer counted into the token rate on top of the decoded frame, so the live token rate no longer spikes from roughly twice the answer's throughput until the response ends; the message-end token estimate now sums the live and diffusion totals instead of keeping the larger one.
- Under a routesense selection, colors set to the thinking level now follow the level routesense announced for the request. This covers the spinner, activity meter, token rate, response model, response-model footer and completion marker. routesense's virtual models advertise no thinking levels, so Pi reports `off` for the selection and they all showed the `off` color. The prompt box border still uses the session's level, because it is drawn before the request is routed.

## [0.13.0] - 2026-10-21

### Removed
- The fallback that read the output style saved by the retired `pi-topping-insights` extension (`~/.pi/agent/pi-topping-insights/settings.json`) when pi-topping had no `outputStyle` of its own. A missing or invalid `outputStyle` now falls back to `default`, and the old extension's file is ignored. Anyone who still relied on it re-selects the style in `/topping-settings`. `fromLegacyOutputStyle` is gone.

### Changed
- Verified compatibility with Pi 1.4.0; development and CI now typecheck and test against it, and the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 1.3.0 to 1.4.0. No runtime behavior changed, the published `peerDependencies` remain `*`, and the minimum supported host remains Pi ≥1.2.0.
- Depend on `@underactive/pi-topping-primitives` `^0.10.0` (was `^0.8.0`). Nothing it imports changed in between: 0.9.0 added `./env` and `./abort`, which it does not use, and 0.10.0 removed only the `pi-topping-compact` entry names from `./contracts`, which it never referenced. Every topping now asks for the same range, so an install of several shares one copy of the library. No visible change.
- `/topping-setup` install and remove now run the pi that hosts the session (this process's entry script under its runtime, or a compiled pi's own executable) instead of the first `pi` on PATH, so they reach the same agent directory. They fall back to `pi` on PATH only when neither is usable, and on Windows `cmd.exe /c` is used only for that fallback. Spec rejection, exit code 124 and the `[timed out after Nms]` suffix are unchanged. Output is now decoded as UTF-8 across chunk boundaries. Spawning, the kill escalation and `hostBelow` now come from `@underactive/pi-topping-primitives` 0.8.0 (`./process`).
- The spinner frames and their cadence, the control-character sanitisers (`stripControlChars`, `sanitizedText`), the Switchyard provider check and NVIDIA green, and the prompt box's border glyphs now come from `@underactive/pi-topping-primitives` 0.6.0 (`./glyphs`, `./text`, `./color`). Rendered output is unchanged. `format.ts`, `util.ts` and `nvidia-green.ts` re-export them under the same names.
- Thinking-level types, validation and the canonical level list now come from `@underactive/pi-topping-primitives` 0.5.0 (`./models`). Existing imports through `format.ts` and rendered output are unchanged; the shared level list is frozen.
- The `/topping-settings` and `/topping-setup` menus are the shared `@underactive/pi-topping-primitives` 0.4.0 menu (`./menu`) instead of a local copy, and the meter upper bound is handled as a number end to end. Visible changes: the overlay is 90% wide (it was 86%); stepping left from a typed upper bound below the lowest preset now wraps to the highest preset (it used to stall); long labels wrap instead of truncating; Enter on the upper-bound row opens the number editor and Enter on an Elements Order row grabs it, so apply with Enter from any other row (Escape still cancels from anywhere); ungated cycle rows and the upper-bound row no longer draw a checkbox; a typing error shows in a "What this does" block instead of the hints row; the menu's keys can be remapped through pi's keybindings (`pi-topping.menu.*`).
- Settings are read and written by the shared `@underactive/pi-topping-primitives` 0.2.0 settings store. The file path, format and `schemaVersion`-first key order are unchanged; the file is now created 0600 (its directory 0700 when new) and temp files get unique names. `saveSettings` returns a result instead of throwing, and the menu still reports `Failed to save Pi Topping settings` on failure.
- Reads routed-model and embedded-status announcements through the shared contracts from `@underactive/pi-topping-primitives` 0.1.0.
- A malformed embedded-status announcement is now ignored; previously it was read as `embedded: false`.
- Added `@underactive/pi-topping-primitives` as a runtime dependency.
- The activity meter, the token-rate hold and fade, the streaming word counter, the shimmer, the colour fades, elapsed-time formatting and the thinking-level colorizer now come from `@underactive/pi-topping-primitives` 0.3.0 (`./activity` and `./activity-tui`) instead of local copies. Rendered output is unchanged. One edge case: with the activity meter on and Token rate off, the rate is now held in the background, so switching Token rate on mid-turn shows an already-held rate at once instead of waiting for the next sample with new output.

## [0.12.0] - 2026-10-16

### Added
- Explicit `/skill:name` invocations now get a display-only prompt box while Pi expands the skill natively; Pi's `[skill]` entry remains visible beside it.

### Changed
- Verified compatibility with Pi 1.3.0; development and CI now typecheck and test against it, and the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 1.2.0 to 1.3.0. No runtime behavior changed, the published `peerDependencies` remain `*`, and the minimum supported host remains Pi ≥1.2.0.
- **Pi ≥1.2.0 is now required.** Pi 1.2.0 runs the agent-start hook for the run that a custom message starts, which is how the output style reaches a decorated prompt. On an older host pi-topping shows a one-time warning at session start, and output styles do not reach decorated prompts. The published `peerDependencies` remain `*`, as Pi's packaging guide requires for host packages.
- Verified compatibility with Pi 1.2.0; development and CI now typecheck and test against it, and the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 1.1.0 to 1.2.0.
- A decorated prompt is now one custom message that starts the run; the agent-start hook adds the output style's prompt section and hidden reminder to that run, as it does for an undecorated prompt. Previously the prompt box and the reminder were sent as two messages.

### Removed
- Removed the request-time fallback that patched the output-style section onto decorated prompts on hosts before Pi 1.2.0, together with its `context_with_system` handler and helpers. Pi 1.2.0 records the section in the transcript through the agent-start hook.

### Fixed
- On Pi 1.2.0 a decorated prompt under a non-default output style no longer receives the hidden style reminder twice. Pi 1.2.0 adds a message that the agent-start hook returns to runs that a custom message starts, and pi-topping's hook returned the reminder for the run its own reminder message had started. The hook now returns the reminder for a user prompt and for the run pi-topping's prompt box starts, and nothing for runs that other extensions' custom messages start.
- A response model that only respells the selected model is now hidden like other restatements: the model's id, or its display name with or without trailing parenthesized notes, written with other case and separators. For example, a model with the id `qwen38-flash-next-iq2xs_local_256k` and the name `Qwen3.8 Flash Next IQ2_XS (Local)` no longer shows `qwen3.8-flash-next-iq2_xs`. The comparison keeps every digit and allows no other difference. The loader, completion marker, and response-model footer share it.

## [0.11.1] - 2026-10-12

### Changed
- The working loader now subscribes to the `pi-topping-routesense:routed-model` announcement. pi-topping-autorouter was renamed pi-topping-routesense, and its virtual models moved from `litellm-auto/*` to `routesense/*`. Announcements on the old `pi-topping-autorouter:routed-model` channel are no longer read.

### Fixed
- The high-vis prompt box now shows for every output style. A non-default style still adds its hidden reminder, and the prompt section is applied on the model request when the decorated path skips the agent-start hook.

## [0.11.0] - 2026-10-10

### Added
- Added an Output Style section to `/topping-settings` with Default, Explanatory, and Simplified Technical English. A non-default style adds a system-prompt section and a hidden one-line reminder to each prompt, and it also applies in print and RPC modes. Output styles need a host that exposes structured prompt sections (tested on Pi 1.0.3 and 1.1.0) and have no effect on other hosts; the published minimum remains Pi ≥0.84.4.
- Replaces the separate `pi-topping-insights` extension: its Explanatory style is now the Explanatory output style. Until `/topping-settings` is first applied, pi-topping uses the style saved by `pi-topping-insights`; applying the menu saves it to pi-topping's settings. pi-topping has no `/insights` command.
- Added an `Interrupted` completion marker for runs cancelled on Pi ≥1.1.0 (for example with Escape). It always reads `Interrupted`, even with Randomize "Worked" text on, and the word and any border use the warning color. Time, tokens, and other enabled details still appear, resumed sessions show the same marker, and **Show completion marker** controls it. Older hosts show the normal marker; the minimum remains Pi ≥0.84.4.

### Changed
- Verified compatibility with Pi 1.1.0; development and CI now typecheck and test against it, and the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 1.0.3 to 1.1.0. The published `peerDependencies` remain `*`, and the minimum supported host is still Pi ≥0.84.4.
- Consolidated the `OutputStyle` type: separate `section` and `reminder` fields are now a single optional `prompt` object, and removed the unused `OUTPUT_STYLE_LABELS` export.

### Fixed
- Output-styled prompts are now routed through the agent-start hook instead of the prompt-box decorator, so they apply correctly when both the style and prompt decorations are active.
- Removed the Explanatory footer status line that duplicated the output-style indicator already shown in the settings menu.

## [0.10.0] - 2026-10-05

### Added
- The working loader now subscribes to pi-topping-autorouter's `pi-topping-autorouter:routed-model` event-bus announcement and shows the routed physical model as the response model as soon as a request is routed, before the first token arrives. Announcements for `direct` routes (compaction summaries and other extensions' side requests), announcements while no turn is in progress, and malformed payloads are ignored. The announced model follows the usual rules: under a physical selection it is hidden when it resembles the selected model, it slides out or swaps in place like a provider-reported one, a later assistant message without a `responseModel` keeps it, and a provider-reported `responseModel` replaces it. A bare routed id never displaces a provider-reported decorated form of itself (such as a dated name), so continuation announcements between tool calls do not repaint the loader. The completion marker and response-model footer record it too.
- The completion marker can append per-call service-tier counts (e.g. `flex tier ×3`) from raw `provider_stream_event` events for Responses, chat-completions, and Anthropic; calls without a reported tier are excluded, and idle requests are ignored. The Completion Marker “Service tier” toggle is on by default. This requires Pi ≥0.99.0 to expose raw events; the published minimum remains Pi ≥0.84.4.
- pi-ai's Responses stream does not populate `responseModel`, so the working loader now reads served model ids from raw Responses-API `provider_stream_event` payloads and the gateway backend Ramp Router reports in its top-level `provider` field. It displays `<model> via <backend>`, or `via <backend>` alone when the served model restates the selection; without a backend, the usual hide-when-resembling rule applies. The loader, completion marker, and response-model footer share the display. Raw events require Pi ≥0.99.0; the published minimum remains Pi ≥0.84.4.

### Changed
- Under a Pi virtual model such as pi-topping-autorouter's `litellm-auto/auto`, assistant messages without a provider-reported `responseModel` now fall back to the message's `model`, which Pi stamps with the routed physical model, so the loader, completion marker, and footer show that model instead of nothing. Under a virtual selection the resemblance check against the selected model is not applied, since it would also hide a routed model whose id contains the virtual id (such as `openrouter/auto`); only a failed route, which leaves the virtual model's own provider and id on the message, is hidden.
- Verified compatibility with Pi 1.0.3; development and CI now typecheck and test against it, and the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 1.0.0 to 1.0.3. Pi 1.0.1–1.0.3 remove no public API this extension uses. No runtime behavior changes, the published `peerDependencies` remain `*`, and the minimum supported host is still Pi ≥0.84.4.

### Fixed
- Autorouter route announcements now match on exact routed id, so a new physical route updates the loader label instead of being skipped when model strings merely resemble the previous route.

## [0.9.1] - 2026-10-02

### Changed
- Verified compatibility with Pi 1.0.0; development and CI now typecheck and test against it, and the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 0.99.1 to 1.0.0. Pi 1.0.0 removes no public API, and its `tuiMode` now defaults to `"fullscreen"`, which leaves the settings menu, prompt box, working loader, and completion marker unchanged. No runtime behavior changes, the published `peerDependencies` remain `*`, and the minimum supported host is still Pi ≥0.84.4.

## [0.9.0] - 2026-09-30

### Added
- Added a “Token activity monitor upper bound” setting to the “Working” Loader section of `/topping-settings`. It defaults to 80 tps; `←`/`→` cycle through presets spanning 10–1000 tps, and `␣` (Space) accepts a typed whole number from 10–1000. Invalid typed entries show an inline error and keep the editor open without changing the current value, while invalid hand-edited `meterUpperBoundTps` values revert to 80 when settings load.

### Changed
- Token activity monitor levels below full now scale proportionally to the configured upper bound, and full `⣿` appears at or above that bound (80 tps by default), instead of requiring a rate above the previous fixed 40 tps threshold. Set the bound to 40 to approximate the previous look.

### Fixed
- `/topping-settings` value-cycling rows whose labels are truncated in narrow terminals no longer push the menu's right border off the row.

## [0.8.2] - 2026-09-29

### Changed
- Development and CI now typecheck and test against Pi 0.99; the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 0.86.0 to 0.99.1. No runtime behavior changes, the published `peerDependencies` remain `*`, and the minimum supported host is still Pi ≥0.84.4.

## [0.8.1] - 2026-09-25

### Added
- Added a Word Packs toggle to include default/random “Working” text alongside enabled word packs; it is on by default, and is disabled when no word packs are enabled.

### Changed
- The post-settlement response-model footer is now controlled by an independent Options toggle and is disabled by default; its live settings preview reflects the configured color and dimming, while the working-loader response-model toggle remains unchanged.
- While pi-topping-statusline embeds the working loader in its status bar, the loader's response model now slides out tail first from behind its separator over 0.3 seconds when it first appears in a run, matching that bar's embedded-status slide. Elsewhere it still appears all at once, and a different model replacing one already shown still swaps in place.

### Fixed
- A one-time `schemaVersion: 4` migration carries the saved working-loader response-model preference into the independent response-model footer, preserving the previous footer behavior for existing installations.

## [0.8.0] - 2026-09-20

### Changed
- The sibling-topping setup flow is now always on: the `PI_TOPPING_SIBLING_SETUP` feature gate was removed, so the missing-topping notice and the `/topping-setup` command are active by default. `PI_TOPPING_SIBLING_SETUP` no longer has any effect.

## [0.7.2] - 2026-09-20

### Added
- Response-model display in the completion marker. The model captured at settlement is appended after the summary, e.g. `π Gallivanted for 5s (↓ 39 tokens) · test-model`. The Completion Marker section of `/topping-settings` provides visibility, color, and dim controls, defaults the color to `muted`, suppresses models matching the selected model, and remains independent of the working loader's response-model toggle.

### Changed
- The missing-sibling notice now renders as a full-width, rule-bounded transcript entry without Pi's `Warning:` prefix.
- The working loader's response model now uses NVIDIA green (`#84c51a`, matching pi-topping-statusline) whenever Switchyard is the active provider, overriding the configured response-model color for the loader, its post-settlement hold/fade, and the `/topping-settings` preview.
- Development and CI now typecheck and test against Pi 0.86.0; the `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` devDependencies moved from 0.84.4. No runtime behavior changes, the published `peerDependencies` remain `*`, and the minimum supported host is still Pi ≥0.84.4.

### Fixed
- Missing topping notices now use the singular form when exactly one topping extension is missing.

## [0.7.1] - 2026-09-11

### Added
- `/topping-setup` now lists sibling toppings installed through Pi in an "Installed Toppings" section and uninstalls checked rows with `pi remove`; removal rows default off and only packages recorded in Pi's user settings are offered.
- Sibling topping detection now includes `@underactive/pi-topping-moa-fusion` for setup and missing-topping notifications.

### Fixed
- Warning notification borders now use the warning color throughout.

## [0.7.0] - 2026-09-04

### Removed
- Legacy `string[]` menu preview results; preview callbacks must now return `PreviewResult` (use `nextRefreshInMs: 50` for the previous default animation interval).

### Added
- `thinking-level` animated spinner color option (shown as `thinkingLevel`), which defers to Pi's thinking-level-colored indicator.
- `thinking-level` completion marker border color option, which defers to Pi's thinking-level-colored border.
- `thinking-level` user-prompt border color option, which follows the thinking level captured at submission.
- `thinking-level` color options for the token activity monitor, token rate, and response model, which follow Pi's active thinking-level color.
- `text` and `muted` color options for the token activity monitor, token rate, and response model in the working loader.

### Changed
- The settings TUI now displays `thinkingLevel` instead of the internal color sentinel for prompt, animated-spinner, completion-marker border, token activity monitor, token rate, and response model color options.
- Default spinner and prompt-border colors now match the thinking-level presentation Pi 0.85.0 introduced; the theme API this uses is available from Pi 0.84.4.
- Working text no longer includes an ellipsis.
- A one-time `schemaVersion: 2` migration resets saved spinner colors to `thinking-level` and prior-default `borderAccent` prompt borders to `thinking-level`.
- Completion marker border colors now default to `thinking-level`; a one-time `schemaVersion: 3` migration resets previously saved colors to it.
- The `accent` spinner color now sends explicit accent frames, distinct from Pi's default indicator.

### Fixed
- The default animated spinner in the working loader now uses the active thinking-level color, matching the settings preview.

## [0.6.5] - 2026-08-31

### Changed
- Working-text selection no longer rebuilds its candidate pool on every pick, and unchanged response-model values skip reprocessing on each streaming token delta, reducing per-token overhead.

### Fixed
- Response models that merely restate the selected model — including local paths and decorated filenames of it — no longer appear as response-model details.

## [0.6.4] - 2026-08-29

### Added
- Response-model display in the working loader, with visibility, color, permanent-dim, and reorder controls. The sanitized value appears without a label, remains for 3 seconds after settlement, then fades over 0.5 seconds.

### Changed
- The token-rate unit label is now `tps` (was `tok/s`).

### Fixed
- The response model is now picked up from partial assistant messages during streaming, so the loader shows the current model before the turn ends.
- Token counts reported by providers are validated before use: non-finite or negative `usage.output` values are ignored instead of being written into session state.
- The decorated prompt submission is now guarded before the input is claimed as handled; when submission throws, a `Failed to submit prompt` error is shown and the input is not swallowed.
- The post-settlement display of the response model now renders on a persistent status surface instead of the transient working message, so the hold/fade no longer fights the loader, and it clears cleanly on the next turn, session start, and shutdown.

## [0.6.3] - 2026-08-28

### Added
- Blocking extension prompts now replace the animated working loader with a stable dim waiting state and pulse indicator, then resume the configured loader afterward. This state requires Pi ≥0.84.4.
- Page Up/Page Down navigation in the `/topping-settings` menu moves the cursor by a screenful of items.

### Changed
- `/topping-settings` now limits its menu to 75% of the terminal height and scrolls longer settings lists within that space.
- `/topping-settings` menu navigation no longer wraps around; ↑/↓ clamp at the first and last items.

### Fixed
- Reorder rows in `/topping-settings` (e.g. Elements Order) now move correctly when shifted multiple positions with ↑/↓ while grabbed.

## [0.6.2] - 2026-08-23

### Added
- Bundled **Doctor Who** word pack (68 entries, off by default) in the Word Packs section of `/topping-settings`.
- Bundled **Firefly** word pack (31 entries, off by default) in the Word Packs section of `/topping-settings`.
- Bundled **Hitchhiker's Guide** word pack (47 entries, off by default) in the Word Packs section of `/topping-settings`.
- Bundled **The Matrix** word pack (58 entries, off by default) in the Word Packs section of `/topping-settings`.
- Bundled **The Lord of the Rings** word pack (66 entries, off by default) in the Word Packs section of `/topping-settings`.
- Bundled **Portal** word pack (40 entries, off by default) in the Word Packs section of `/topping-settings`.

### Changed
- Star Trek and Star Wars word packs drop generic articles from verb-object phrases (e.g. “Igniting lightsaber”), keeping iconic quotes like “Feeling the Force” intact; Star Wars gains six new entries.

## [0.6.1] - 2026-08-21

### Fixed
- The scrolling `/topping-settings` menu no longer drops a section's heading when the section starts near the window bottom; the window now re-flows so the heading renders with a blank separator above it and its items below, instead of crowding or folding into the previous section.

## [0.6.0] - 2026-08-21

### Added
- Added word packs: custom working-text packs from `~/.pi/agent/pi-topping/word-packs.json`, with per-pack settings, validation, and matching completion-marker tenses. Word packs default off; preferences persist while a pack is unavailable.
- Added modular bundled word packs under `wordpacks/` — SimCity, Star Trek, and Star Wars, all off by default — managed in a new Word Packs section of `/topping-settings`. SimCity phrases are vendored from [svenstaro/genact](https://github.com/svenstaro/genact), specifically [`data/simcity.txt`](https://github.com/svenstaro/genact/blob/master/data/simcity.txt), under its verified MIT license.
- “Marker style” setting in `/topping-settings` cycling the decorated completion marker between `elite` (default; trailing dashes taper off after the summary) and `bookend` (dashes fill the remaining width to a closing corner glyph).

### Fixed
- Completion markers now use the matching past-tense entry for the final working text instead of an unrelated random entry, including word-pack selections.
- Decorated completion markers now span the full terminal width instead of starting one column in.
- The settings menu overlay sizes to 86% of the terminal width (was a fixed 76 columns), and section previews render at the overlay's inner width so they are no longer truncated or misaligned on wide terminals.

## [0.5.1] - 2026-08-11

### Fixed
- Inputs submitted while Pi is working (steer / `Alt+Enter` follow-up) now pass through undecorated so Pi's native `Steering:` / `Follow-up:` queue rows render again ([#2](https://github.com/underactive/pi-topping/issues/2)). Re-sending them via `sendMessage(deliverAs)` bypasses Pi's queue UI state, so mid-turn prompts skip the high-vis box until Pi exposes a queue-aware path.

## [0.5.0] - 2026-08-06

### Added
- Configurable Completion Marker border style with `none`, `double`, `single`, `rounded`, and `heavy` choices; `none` keeps the existing undecorated marker.
- Completion Marker border color setting with the same `accent`, `border`, `borderAccent`, `success`, `error`, and `warning` choices as the User Prompt border color.
- All color settings (prompt border, completion marker border, animated spinner, token activity monitor, and token rate) now offer `accent`, `border`, `borderAccent`, `success`, `error`, and `warning` choices.
- Added an `Invert shimmer` setting that keeps the working text at the default text color and sweeps a dimmed gradient across it.
- Prompt decorators now show the active provider/model in the lower-right border, with independent Provider and Model visibility toggles in `/topping-settings`.
- "Token rate color" setting in `/topping-settings`, defaulting to `warning`.
- "Token rate dimmed" setting in `/topping-settings` that renders the `N tps` segment with the terminal dim attribute, matching the token activity monitor's dim toggle.
- Live output-token throughput in the working loader, displayed by default as a warning-colored `N tps` segment with a "Token rate" toggle and reorder row. Active rates below 1,000 are padded to three characters so updates do not shift the other segments; larger rates may shift later segments. When inactive, the segment shows a dim `--- tps` placeholder. The rate holds full brightness for 1.5 seconds, then fades through five theme-aware shades to the dim text color over the next 0.25 seconds before returning to the placeholder; a new count restores full brightness and restarts the cycle.

### Changed
- `/topping-settings` now marks the selected row with `❯` (was `▸`) and highlights the whole row with the theme's `selectedBg` color, instead of coloring only the marker glyph.
- The working loader now joins adjacent elapsed time, output token, and token-rate details with `·` separators without surrounding parentheses; separated details do not retain dangling separators.
- New installations now default to this working-loader order: spinner, activity word, token activity monitor, token rate, elapsed time, then output tokens.
- The token activity monitor now defaults to right-to-left movement.
- `/topping-settings` now describes prompt decoration, working-loader features/order, and completion-marker settings.
- User Prompt border color now defaults to `borderAccent`.

### Fixed
- Settings menu labels and titles now use visible width when truncating, keeping box-drawing layouts aligned.
- Provider and model labels now strip control and Unicode formatting characters before rendering.
- Settings previews now require strict boolean values.
- Removed the warning-only fade wrapper, added safe fallback rendering for non-truecolor themes, and hardened preview cycle-value conversion.

## [0.4.0] - 2026-07-30

### Added
- “Border style” setting in `/topping-settings` cycling the high-vis prompt box between `double` (default), `single`, `rounded`, and `heavy` box-drawing character sets.
- “Elements Order” section in `/topping-settings` that reorders the working loader's spinner, activity word, token activity monitor, elapsed time, and output tokens. Press `␣` to grab a row and `↑`/`↓` to move it; the live preview follows along and the order persists as `loaderOrder` in `settings.json`.
- “Text shimmer speed” setting in `/topping-settings` offering `Slow`, `Normal`, and `Fast`, where slow halves and fast doubles the sweep velocity. Only the sweep scales: the band keeps its default pace across the padding on either side of the word, so the pause between one shimmer and the next stays the same at every speed.
- Reusable `reorderGroup` rows in `menu.ts`: grabbed rows consume up/down so they cannot escape their group, and the group's order is published as a comma-joined id list in the menu result.
- Mid-turn input count in the completion marker: steers and `Alt+Enter` follow-ups submitted while Pi is working are tallied and shown as e.g. `π Galloped for 37s (↓ 2.7k tokens · 4 mid-turn inputs)`, with a “Mid-turn inputs” toggle in `/topping-settings`.

### Changed
- The spinner is drawn inside the working message (with pi's own indicator hidden) whenever it is not the first element, since pi's `Loader` always prepends its indicator. The session ticker clamps to the 80ms frame interval in that case so the spinner keeps animating.
- Elapsed time and output tokens now collapse into a single `(3s · ↓ 84 tokens)` parenthetical only while adjacent, and render as separate `(3s)` / `(↓ 84 tokens)` groups once another element is placed between them.

### Fixed
- Steering or following up while Pi is working no longer resets the elapsed timer and token count mid-turn; the working loader and completion marker now report the whole working span.

## [0.3.1] - 2026-07-28

### Fixed
- High-vis prompt decoration now preserves steering and follow-up delivery for messages submitted while Pi is working.

## [0.3.0] - 2026-07-21

### Added
- High-vis prompt box wraps each normal user prompt with a `π` title bar and submission timestamp, toggleable via `/topping-settings`.
- Cycle-value menu items for color (`accent`/`border`/`borderAccent`) and scroll direction (left-to-right/right-to-left) settings, navigable with left/right arrow keys.
- Context-aware live preview that follows the active setting section — prompt box, loader configuration, or completion marker — so each setting shows its own preview without scrolling away.
- Configurable spinner color, activity-meter color, shimmer sweep direction, and meter scroll direction via `/topping-settings`.
- Nerd Font icon (``) toggleable alongside the classic `π` symbol for both the prompt box and completion marker.
- Token consumption tracking appended to the completion marker, e.g. `(↓ 949 tokens)`.
- “Token activity monitor dimmed” toggle that applies the ANSI dim attribute to reduce meter brightness by roughly 50%.
- Settings menu scrolls automatically when there are more items than the terminal height can fit.

### Changed
- Completion marker format to `π Whisked for 2s (↓ 55 tokens)` — parentheses replace the `·` separator, icon stays in text color, the rest dimmed.
- Shimmer sweep supports left-to-right and right-to-left directions, matching the meter scroll direction.
- Menu border brackets changed from `[`/`]` to `┥`/`┝` for a cleaner look.
- Settings menu preview now schedules its own refresh per render instead of animating on a fixed interval — static previews render once, animated ones (loader, prompt-box timestamp) declare their own delay. The reusable `menu.ts` preview callback may now return a `PreviewResult` in addition to a plain `string[]`.
- The session's internal ticker now runs only as fast as the enabled decorations require, instead of always ticking at the 50ms shimmer interval.
- Prompt box preview rendering is memoized per terminal width.

### Fixed
- Preview no longer jumps in height when scrolling between the tall prompt-box preview and the single-line loader/completion previews — blank padding rows keep the layout stable.

## [0.2.1] - 2026-07-17

### Changed

- Bump version to 0.2.1

## [0.2.0] - 2026-07-16

### Added

- Durable completion marker appended after each finished turn, e.g. `π Baked for 6m 41s` — a fresh random word plus the turn's total elapsed time, rendered with `π` in the theme's primary text color and the rest dimmed. It's a TUI-only transcript entry that never enters LLM context.
- Seventh independent setting, "Show completion marker", toggleable via `/topping-settings` (on by default)

### Fixed

- `format.ts`: Token counts near a unit boundary (e.g. 999,999) no longer render as "1000k" — they promote to the next unit ("1.0M") instead.
- `menu.ts`: A zero-item settings menu can now be dismissed with Enter (apply), Escape, or Ctrl+C instead of swallowing key input and returning early.
- `settings.ts`: Non-boolean leaf values in `settings.json` no longer override boolean toggle defaults; only properly-typed boolean leaves are applied.

## [0.1.1] - 2026-07-14

### Fixed

- Use wildcard (`"*"`) peer dependency ranges for pi core packages per pi package spec
- Add missing `@earendil-works/pi-tui` peer dependency
- Point README demo image at raw GitHub URL so it renders on npmjs.com

## [0.1.0] - 2026-07-14

### Added

- Shimmering randomized activity word replacing the default "Working..." loader
- Theme-aware light-sweep shimmer across the activity word
- Eight-column scrolling token-activity meter using braille characters
- Live elapsed timer (`Xm YYs`) counting from prompt submission
- Live output-token estimate (`↓ N tokens`) with per-message reconciliation
- Fresh word on each tool call to keep long tool loops feeling alive
- `/topping-settings` command with box-drawing toggle menu and live preview
- Six independent settings: animated spinner, text shimmer, activity meter, word substitution, elapsed time, output tokens
- Settings persistence to `~/.pi/agent/pi-topping/settings.json`
- Reusable `menu.ts` toggle-menu component for other Pi extensions
- Full test suite covering rendering, meter behavior, timer resets, settings, and menu wiring
