EngineConfig.instructions was Vec<PathBuf>, which forces embedders that
compute instructions at runtime to stage content to a disk file just to
satisfy the path API. That has two awkward side-effects:
1. The disk file looks like editable config but gets overwritten on
every launch, confusing for users browsing the install dir.
2. Multi-engine setups need per-engine paths to avoid `rehydrate`
re-reading the wrong session's content across concurrent engines.
Add an `InstructionSource` enum (`File(PathBuf)` / `Inline { name,
content }`) covering both shapes. `render_instructions_block` dispatches:
File sources read disk (original behavior preserved), Inline sources use
the content directly with `name` becoming the `<instructions source=...>`
attribute.
`From<PathBuf> for InstructionSource` is provided so the existing CLI /
runtime call sites upgrade with a single `.into_iter().map(Into::into).
collect()` chain — no behavior change for callers passing paths.
New test `render_instructions_block_handles_inline_source` covers Inline
empty / oversize-truncate / File+Inline mixed-ordering. The 5 existing
`render_instructions_block_*` tests are updated to use `.into()` on
`PathBuf` and continue to assert File-variant behavior.
Deduplicate failures per tool name, clear stale failures when
the same tool succeeds, and cap visible failures at 2 so old
failures don't crowd the sidebar after the task moves on.
Adopt Gemini code-assist review on PR #1831:
- mode_plan: Yellow -> Magenta. Plan chip now contrasts with
status_warning (still Yellow) so the two never visually collide
in the status row.
- status_ready: Reset -> DarkGray. Ready chip now reads as a
distinct subdued accent instead of blending into body text
(which also resolves to Reset on this theme).
No surface change otherwise -- backgrounds and body text still use
Color::Reset to inherit the host terminal's color scheme.
Adds a new selectable theme `terminal` (alongside System / Whale / Whale
Light / Grayscale / Catppuccin / Tokyo Night / Dracula / Gruvbox) that
paints every surface with `Color::Reset` instead of any RGB so the
host terminal's own background, foreground, and palette show through.
The existing `system` theme only chose between two RGB themes (Whale dark
or Whale Light) based on COLORFGBG / macOS appearance — useful, but it
still painted brand-colored RGB surfaces. Users with custom terminal
themes (Solarized, Nord, transparent backgrounds, custom Ghostty/iTerm
schemes) had no way to make the TUI respect their terminal palette.
Implementation:
- New `TERMINAL_UI_THEME` const where every `*_bg` and most text slots
are `Color::Reset`, and accents (mode_agent/yolo/plan, status_working,
status_warning) use ANSI named colors so they also inherit the user's
terminal palette rather than DeepSeek brand RGB.
- `ThemeId::Terminal` plumbed through `from_name` / `name` /
`display_name` / `tagline` / `ui_theme` / `SELECTABLE_THEMES`, and
registered in `normalize_theme_name` with aliases `term`,
`transparent`, `follow-terminal`, `inherit` so existing
user-friendly config strings just work.
- `theme_remap_active(Terminal) → true` so the existing per-cell remap
in `ColorCompatBackend` rewrites every hard-coded palette constant
(`DEEPSEEK_INK`, `DEEPSEEK_SLATE`, `BORDER_COLOR`, `TEXT_BODY`, …) to
`Color::Reset`. Without this, the many render sites that reach for
the named palette constants directly would still paint brand RGB.
- `theme_green` / `theme_red` return `Color::Green` / `Color::Red`
for Terminal so diff "+"/"−" stay green/red but follow the user's
terminal palette.
- `theme_diff_added_bg` / `theme_diff_deleted_bg` return `Color::Reset`
for Terminal — diff highlight is conveyed by foreground color only.
- The new theme is the second entry in `SELECTABLE_THEMES` (right after
System) so it surfaces prominently in the `/theme` picker.
theme_picker tests: the new theme is inserted in row 2 of
`SELECTABLE_THEMES`, which shifts the indices three existing tests
relied on — `arrow_down_previews_next_theme`,
`enter_commits_with_persist_true`, and `digit_jumps_to_row` — so those
expectations are updated to match the new ordering. No production
behavior change in those tests, just index arithmetic.
Default (`theme = "system"`) is unchanged; existing users see no
difference. Users who want full terminal pass-through opt in via
`/theme` or `theme = "terminal"` in settings.toml.
- find_exe(): fall back to known install dirs when PATH lookup fails
(C:\Program Files\PowerShell\7, System32\WindowsPowerShell\v1.0)
- Encoding prefix: use idiomatic [Console]::OutputEncoding for PowerShell
instead of cmd.exe chcp 65001 >NUL
- Execution logging: write exec via <ShellKind> entries to
SHELL_DISPATCHER_LOG when set
- System prompt: use ShellDispatcher detection instead of raw $SHELL
so model knows it has PowerShell and generates native cmdlets
- display_command(): strip PowerShell encoding prefix for display
- Add tests for find_exe PATH + known-dir fallback
Refs #1779
Add `codewhale update --check` so users can compare the installed version with
the latest release without downloading or replacing binaries.
Surface the same release check in `codewhale doctor`, and share release lookup,
mirror handling, timeout, and version comparison logic between update and doctor.
On Windows, stderr cannot be redirected to the log file (no dup2). Suppress verbose CLI logging once the alt-screen is active so eprintln! calls from crate::logging don't leak into the TUI buffer. Also restores verbose logging on all cleanup paths after leaving alt-screen.