* feat(search): replace the command palette with tabbed Search Everywhere
The palette was one flat list that every new kind of row had to be squeezed
into: tabs and SSH hosts rode along as "Switch to Tab: …" and "SSH: …"
commands, and the only way to narrow to one kind was a magic seed word.
Search Everywhere splits it into sources behind one trait — All, Actions,
Terminals, Hosts — each with its own empty-query layout and ranking. The All
tab shows each source's top rows, ordered by best match, with a row that
opens the full tab. Tab / Shift-Tab walk the tabs and keep the query.
- Terminals lists every open tab of every workspace (reusing the switcher's
tab rows) and jumps to it wherever it lives, plus the shells and agents.
- Hosts replaces the separate "Add Connection" input: a typed address or
full `ssh …` line offers to connect.
- Fixes Return doing nothing after a search that found nothing, or when the
search opens pre-filtered: gpui-component re-picks the row from a stale
frame; the delegate now re-arms the first row.
- Fixes `ssh -p 2222 me@box` being offered as a quick-connect address with
user `ssh -p 2222 me`.
The keymap action stays `TogglePalette` so custom bindings keep working.
* feat(search): a Sessions tab to resume past agent sessions
Search Everywhere gains a Sessions tab listing the Claude Code and Codex
sessions on this computer, read from ~/.claude/projects and
~/.codex/sessions ($CODEX_HOME). Sessions that ran in the focused tab's
directory lead; the All tab offers the last three of them before anything
is typed. Return opens a new tab in the session's directory and runs the
agent's resume command with its configured launch flags.
- Only each transcript's head and tail are read, off the window thread,
and cached by path, size and mtime: ~170ms cold for 50 sessions,
under 1ms warm. The search opens on the cached list and fills in.
- Titles: /rename name, then the agent's own title (ai-title, Codex's
session_index.jsonl), then the first thing typed, skipping harness
injections. Codex rollouts it ran for itself (subagent/internal) and
sessions never asked anything are left out.
- A session whose directory is gone is refused with a notice rather than
resumed where the agent cannot find it.
A forward could only be removed, so pointing one local port at another
remote target meant deleting the rule and retyping the other one (#439).
Forward rules gain an `enabled` flag (serde default on, so saved profiles
and older peers keep every rule live) and the daemon a SetForwardEnabled
op for panes and workspaces. Off releases the listener and keeps the
entry; on rebinds it from the rule it was made from, and is refused by
name when another switched-on forward of the same owner holds the port.
The Ports panel and the Settings rules editor each get a switch; a
switch flipped in the panel on a rule from a saved host is written back
to that host.
Closes#439
Every placeholder frame in docs/ now shows a real capture of the current
build: 20 screenshots plus two short looping clips (prompt editor, pane
drag). The README and the docs home page link a one-minute tour covering
agent status across repos, one agent driving another through the CLI,
the prompt editor, diffs, pane dragging, and sessions surviving a quit.
A remote workspace's ports were never listed. The pane lives in the
peer's registry and QueryProcs asks this machine's daemon, which has
never heard of it, so the answer was an empty list — indistinguishable
on screen from a pane serving nothing. Add a control request so the peer
answers instead, gated on a feature so an older server says "I cannot
tell you" rather than "nothing is listening".
With the ports visible, the forward becomes something the user should
not have to think about: a port opens on a click, and a new one is
forwarded unasked, at the same number where that number is free here.
The watch runs with the panel shut, which is when a port appearing is
most worth saying something about.
Ports and Forwards were two sections that never mentioned each other; a
row is now a port, and the forward is where that row says it comes out.
Adding one by hand asks for one number instead of five fields, with the
rest of the ssh -L grammar one disclosure away.
Claude-Session: https://claude.ai/code/session_01TPXrptp2rCGKjXaz4xE3Lq
Audited every page under docs/ against the source. Fixes for what the
code actually does:
- agents: the status vocabulary is idle/working/waiting/done, not
running/waiting/idle; hook rows grow a separate Uninstall button; the
Settings table labels read "Copilot CLI" and "Grok Build"; Copy Session
ID lives in the tab's context menu, not the pane's
- cli: `pane ls --all` reports the owning workspace id, not "tty7-cli";
document bare `tty7 [PATH]` as the GUI launcher it is instead of listing
it as unimplemented; note `active_tab` and the `diagnostics` array; wait
also defaults to $TTY7_PANE
- git: the branch dropdown is a plain list with no search box and no
stash-and-switch, and checkout is not a palette command; quote the diff
overlay's own overflow notice rather than the sidebar's
- window: the unread marker tracks a finished agent turn, not any output;
rows cannot be dragged across groups; the sidebar and `tty7 tab ls`
resolve labels differently; drop Toggle Commit History and Checkout to
from the palette's Git group; ~/.ssh/config aliases are not palette
entries
- terminal: Ctrl+R dedups by command text and shows no directory; Esc does
not dismiss a ghost suggestion; document Cmd+Enter
- remote: GSSAPI is an ordinary Auth choice, not a managed-connection-only
mechanism
- fonts: Maple Mono NF CN leads the chain on Windows and Linux only; list
the real per-platform defaults
- settings paths: the three Links settings and per-pane history were filed
under the wrong sections
38 pages under docs/, written against the source rather than the README:
config keys and their clamps from core::config, default keybindings from
ui::keymap, every CLI verb and flag from tty7-cli, agent aliases and
hook/fork/resume support from core::cli_agent, and Settings paths taken
from the actual en-US strings.
docs/features.md and its zh-CN translation are retired — everything in
them now lives in a page of its own, plus the two things they carried
that nothing else did (IME input, the performance notes). README and
README.zh-CN point at docs/ instead.
Screenshots and videos are placeholders for now: docs/images/placeholder.svg
with a caption naming what each shot should be.
Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>