- Changes panel: a working file opens in a CodeMirror editor with its diff
inline (DiffEditor.tsx, @codemirror/merge, lazy-loaded); Changes folds the
unchanged lines, Whole file shows them; side by side at 50/50 and full
width; a Revert per block; original from HEAD or the branch's merge base
(`mergeBase` on GET /git/changes?range=branch)
- Every diff: green = line added whole, red = removed whole, blue = edited
in place (--diff-mod)
- History drawn as a commit graph (#58: `parents` on GET /git/log,
--date-order; lib/commitGraph.ts)
- Per-workspace never-stage list, drawn orange in the Files tree (--kept);
closed Terminal rows past three deleted
- Status bar plan quota for Claude (per account) and Codex
(GET /api/pricing/quota, server/lib/quota.js); compact hover panel that
stays open, Refresh button with a spinner
- Settings → Appearance holds language, theme and pet; Ctrl+Shift+C copies;
compact sidebar navigation and short session times
- EditorModal loads once per path (a parent re-render no longer reloads the
file over the user's typing), refuses Save after a failed load, opens a
truncated (>256 KB) file read-only, and asks before overwriting a file
that changed on disk or could not be re-read.
- Settings/Hooks editors unset only keys from the snapshot taken at Edit,
warn when the file changed underneath, keep a renamed key's value, and
refuse a new key named like a redacted one (env) or a read-only hook
event, which used to replace the secret/hooks.
- Project scope shows its resolved folder and is disabled inside the
plugin cache. Account-profile, pricing-row and pet deletes confirm;
two-click actions disarm after 3 s; unsaved drafts ask before closing.
- Search indexes every Claude Code / Codex sub-tab, opens it via ?tab= and
scrolls to + highlights the row; the active config tab is in the URL.
- General splits into General / Data / About; Pricing moves to a Cost
group with one shared load; config tabs group as Content / Extensions /
Config with arrow-key roving; Promise.allSettled per tab.
- Data: browser-preferences export/import (allowlisted keys), per-section
reset, housekeeping dry-run first, clear-all behind a typed phrase.
Server: purge days must be a whole number >= 1 (INVALID_PURGE_DAYS) and
dry_run returns exactly what the real run would delete.
- Alerts can be edited; webhooks/alerts/remote-source failures toast;
copies go through copyText; modals get dialog roles and useDialog.
- Sagi: Ctrl/Cmd+B only when shown and not typing, default spot clear of
row controls, arrow keys move it, reduced motion honoured; the dead
/run launch link goes to the workspace.
Settings -> Pet (/settings/pet, PetSettings.tsx): show/hide, speech
bubbles, size with a live preview, and the pet grid - Sagi, featured
codex-pets.net pets (downloaded on first pick), your own (deletable) -
with image upload and .codex-pet.zip import. The Sagi block leaves
General; the mascot menu's Pet settings opens the page. PetMenu and the
page share components/Sagi/usePets.ts.