feat(terminal): brand SVG assets + immediate-apply detector
Wires real artwork into the auto-detected tab icon and rewrites the
detector around mapping hits instead of debounce.
Assets
- Adds 21 monochrome SVG imagesets under Assets.xcassets/CommandIcons
(Simple Icons + Lobe Icons), all template-rendered and shipped as
vector so they tint with foregroundStyle and adapt to dark/light.
Coverage: editors (vim, nvim), package managers (npm, pnpm, yarn,
bun), VCS (git, GitHub), build tools (swift, rust, xcode, gradle),
containers (docker, kubernetes, podman), DB REPLs (postgresql,
mysql, sqlite), curl, ClaudeCode, Codex.
Storage / rendering
- TabIconSource gains storageString; assets serialise to "@asset:Name"
while SF Symbols stay bare so the existing IconPicker / persistence
path keeps working unchanged.
- ResolvedTabIcon enum parses the stored string for renderers.
- New TabIconImage view dispatches to Image(systemName:) vs Image(_:)
+ .resizable() based on parse, both branches honour foregroundStyle
and a parent-supplied pointSize so SF Symbol fallbacks and branded
assets land at the same on-screen footprint.
- ShelfSpineView and TerminalTabLabelView swap their inline Image
call for TabIconImage; ShelfMetrics.tabIconPointSize centralises
the spine-side size.
Detector rewrite
- Drops the per-surface debounce timer entirely. Mapping hits apply
immediately; misses leave the tab icon alone (selection-2 keeps the
previously detected icon).
- Unblocks short-lived commands (`git status`, `cd foo`) and TUIs
that overwrite their preexec title before any debounce window
could fire (`codex` jumps straight to the repo name).
- Substring-match path removed — first-token alone now covers every
case in the current map (claude is detected at preexec, the
TUI-set "✳ Claude Code" no-ops via the unchanged guard).
- Idle-prompt suppression is preserved: shape heuristic plus the
per-surface learned-idle set populated from the first title that
arrives after each command_finished.
CommandIconMap
- 21 entries gain assetName: pointing at the new imageset; SF Symbol
remains as the renderer-side fallback when an asset is missing.
- Substring map and its lookup function deleted.