When opened with Ctrl-K, the palette now prepends entries for whatever
is currently focused:
- Focused scratchpad: Delete / Rename (inline form) / Edit (fire-and-
forget zed launch with stdio detached so the TUI is not suspended).
- Focused agent: Rename (inline form) / Close.
- Focused process: Rename / Delete (drops the entry; SIGKILL if alive)
/ Stop (SIGTERM, keep entry) / Restart (same argv).
The rename UX is a single-field inline form that mirrors the existing
spawn-process form, so the modal-input contract is unchanged.
scratchpad.Store grows Delete / Rename / Path so the palette can act
on a pad file by name. focusedPad is plumbed onto uiState ahead of the
scratchpad-focus UI work; until that lands it stays empty and the
scratchpad-context entries simply never surface.
Tested with palette_context_test.go and a new rename_process_via_palette
harness scenario.
The stdin loop's scratchpad-input branch ran before the palette branch
and silently dropped every byte except a handful of app-level chords,
so palette typing and Esc never reached the palette while a pad was
focused. Skip the pad-input branch whenever st.palette != nil.
closePalette also called repaintFocused() on cancel / no-op action
paths, which paints the empty focused-child slot (focusedID == "" while
a pad is focused) and leaves the palette's top border drawn over the
pad. Route those branches through a restoreView helper that picks
repaintFocusedPad when a pad is focused.
Switching from a pad to a child via the palette now clears the pad
focus and wipes the viewport, matching focusProcess's pad-exit path.
Adds a harness scenario (palette_over_scratchpad) that opens a pad,
opens the palette, types a query, and verifies that Esc leaves the
pad correctly repainted with no palette chrome lingering.
Bundles the in-flight work into the first tagged release. See
CHANGELOG.md `[0.0.1] - 2026-05-14` for the full per-change list.
Highlights:
- Sidebar / chrome stability: clamp absolute cursor positioning and
printable bytes to the viewport so long-running TUIs (claude, codex)
can't spray into the right rail; bound tab bar's row clear to the
viewport width so the rail isn't wiped on every tab redraw; flag
scroll escapes (RI/IND/NEL/SU/SD/IL/DL) and clamp `CSI 0/1/2 J`/`K`
to viewport columns.
- Palette: "Spawn process…" form, macros (`sw `, `k `, `sp `), kill
entries mark the focused tab, dead agents drop out of the switch
list.
- Sidebar: split into Processes (session-wide) + Agent Tree
(per-active-agent) sections; relaunch indicator; Ctrl+W/S walks the
combined list, Ctrl+A/D steps tabs.
- MCP: protocol handshake (`initialize`, `tools/list`, `tools/call`,
`ping`), `mcp_injection.kind = cli_override / config_env` so codex
and opencode pick up the server with no file writes, `lifecycle`
help topic and tool-description cleanup-duty pointers.
- Lifecycle: orchestrator-spawned children cascade-killed when the
parent dies; orchestrator-injected prompts end with CR + delayed
Enter so claude submits cleanly.
Codex (Ratatui) emits an 8x RI burst on startup right after setting
DECSTBM. RI at the top of the scroll region scrolls the region down,
and DECSTBM only constrains rows -- so the scroll spans every column
and drags the right-rail session-tree entries down with the main pane.
The chrome cache then hid the clobber because the computed sidebar
frame was unchanged.
The viewport renderer now flags any chunk containing RI / IND / NEL /
SU / SD / IL / DL and OnPTYOut drops the sidebar cache when the flag
is set, so the next drawSidebar repaints over the drift.
Adds unit tests for the new flag and a harness regression scenario
(sidebar_survives_ri_scroll) that fails without the fix.