`sidebar_grouping` gains a third, opt-in mode, `repo-or-directory`: group by repository home as before, and when the repo probe has landed and answered "not a repo", group under the cwd itself instead of filing every such tab under Scratch. A probe that has not run yet resolves to no decision, so a tab keeps the group it already has rather than bouncing through Scratch mid-probe. The decision lives in one `resolved_group` free function shared by the per-frame key derivation and spawn-time seeding.
The default (`repo`) and flat modes behave exactly as before, and an unknown value in an existing config still degrades to `repo`.
Knock-on: `machine_mirror::subject_path_of` names a window after its most common group, so in the new mode a window of plain shells takes its name from the most common directory rather than from the first pane's cwd.
Closes#620.
Found by driving a dev instance and measuring what an idle window costs.
Two of them were frame loops that never stopped. A `Head` diff overlay
calls itself stale when the cached git status disagrees with the snapshot
on screen, and every landed probe wakes that check by touching the cache
— but the read published its counts and left the branch behind, so a
branch switched outside tty7 made the disagreement permanent: two `git`
processes a lap, forever, with `refreshing…` pinned to the header and an
idle window at 7% of a core. And the home page asked for a frame sixty
times a second to change one glyph's opacity twice, which made a window
with nothing open in it eight times more expensive than one running a
shell. Both now settle: the diff read publishes the branch it found, and
the home cursor flips a bool on a timer the way the terminal's own does.
The rest:
- The tab sidebar and the right panel each capped themselves at half the
window and knew nothing about the other, so together they could take
all of it — 260 points of terminal on a 720-point window. Both now cap
at whichever binds harder: half the window, or what is left after the
terminal's floor and the other panel's floor. The same cap bounds the
drag, so a panel dragged to its limit stays where it was dropped.
- Only a HEAD diff may correct the sidebar's counts. Those numbers mean
`git diff --numstat HEAD`; an unstaged or staged patch answers a
smaller question, so opening an untracked file from the Source Control
panel took the staged lines off the total on the click.
- An untracked row in the diff overlay had no click target, and once
focused could not be left — the breadcrumb looks the path up in
`files`, where an untracked file has no entry. Both ends fixed.
- A new pane keeps the name its directory was reached by. `cwd()` alone
loses it: the shell falls back to `getcwd()`, so `/tmp/x` became
`/private/tmp/x` in every tab opened from the first. `PWD` carries it,
and POSIX has the shell discard a `PWD` that names the wrong
directory, so this can correct the name and cannot invent one.
- The settings search now sees into the Keybindings page, which is
generated from the binding table rather than the static index — so
searching for a feature finds its shortcut, and the page filters to
the matches. Closes#444.
- The settings reading column is centred rather than pinned to the nav:
on a window as wide as the display it was made for, 640 points of
settings sat beside 1600 points of nothing.
- `New Workspace…` takes the ellipsis its three sibling actions already
carry — it opens a form asking for a name and a host.
Every fix has a test. The re-probe loop is pinned end-to-end with
`render_probe::draws() == 0` against a real repository, confirmed to
fail on the old behaviour before it was kept.
* feat(right-panel): give the Info tab rows that do what they show
The panel's Session table rendered every fact the same inert way, and its
two actions sat in a strip of their own under the whole list — unlabelled,
four rows below the path they acted on. Rows now carry their own shape:
`changes` is the sidebar's green-and-red `+N −M` and opens the same diff
overlay under the same setting, an agent wears the same status dot its tab
does, and what a row can do appears at the end of it on hover, in the strip
Source Control rows already use. A port row hands over its address instead
of leaving it to be retyped, and the lit panel tile closes the panel the way
every other activity bar does.
* fix(right-panel): answer for the row the pointer is actually on
Review of #531 found the new rows promising more than they could keep.
Port rows keyed their element id on the port alone, but a port is only
unique with its pid — a pre-forking server puts one row per worker on
screen, and gpui handed them a single interactive state, so a click on
one lit the tooltip and the pressed fill on all of them.
The `changes` counts were read off `Tab::git_status`, which resolves a
split tab to its *first* leaf, while the click target came from
`detail_pane`, which resolves it to the *last focused* one. Inert text
could disagree harmlessly; a button could not, and clicking `+2 −0`
opened another pane's repository. Both now come from the pane the rest
of the rows describe.
A port is only `localhost` if localhost reaches it. `lsof`'s bind
address was parsed and dropped, so a server on `172.17.0.1:8080` was
offered as `localhost:8080` — a refused connection, or somebody else's
service. `PortEntry` carries the address (`serde(default)`, so an older
daemon still answers), and the wildcard and loopback binds keep the
`localhost` spelling anyone would type.
The browser tile hung off `remote_context()` — where the *shell* is —
though the ports come from the pane's own process tree either way. It
hid the tile on the one pane where it works, a `ssh -L` forward listening
on this machine. It is about the host now.
The action strip is opaque and pinned to the row's right edge, so on the
working-directory row it covered the leaf that the head-first elision
exists to preserve. The value holds that width back for good rather than
on hover: taking it on hover would re-elide the path under the pointer,
which is the pixel-shifting the strip is absolutely positioned to avoid.
Also: the counts were `flex_1`, so the whole rest of the line was the
button and empty space underlined numbers it was nowhere near; the agent
pip was pinned in pixels inside rem-sized text and slid off its line at
any interface scale but 100%, and drew Waiting as a thin ring where the
tab strip punches a hole in a filled dot — one rule, two dialects; the
panel-toggle chrome tile, which on macOS lives inside the panel it
closes, still dropped focus into the destroyed element and left ⌘J
dead; and `scm/detail.rs` kept a third copy of `ROW_INSET`.
---------
Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
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>