mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 08:02:24 +00:00
9cac4b863b1bec6db94de830fd3fceefc6146ddc
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9ca3319239 |
feat(agents): fork an agent session and copy its session id (#241)
* feat(agents): fork an agent session, and copy its session id A coding-agent conversation is a single thread: to try a risky direction you either lose the one that got you there, or you don't try it. Every agent tty7 resumes already knows how to branch — `codex fork <id>`, `claude --resume <id> --fork-session`, `opencode --session <id> --fork`, `grok --resume <id> --fork-session` — but nothing in tty7 reached them, so the capability was invisible from the terminal that already knows every pane's session id. Fork is a per-agent capability beside the existing resume table (`CLIAgent::fork_command`), not a Codex special case: it is the same `match self` shape, it reuses the same id validation and the same launch-flag replay, and four installed agents qualify today. Every command was checked against that CLI's own `--help`; agents with no fork tty7 could verify return `None` and are never offered the action, since a guessed flag shape would only ever produce a usage error in the pane. Flag replay needed one correctness fix to survive this. A forked pane's own argv *is* a fork command, so relaunching it would replay the stale subcommand and id (`codex fork <old>` → an old id as a positional prompt) or double the modifier (`--fork-session --fork-session`). `codex fork` now sheds its subcommand exactly as `codex resume` did, and `--fork-session` / `--fork` join their agents' stale session-targeting lists. That also settles restore: a forked pane restores through `resume_command`, which now drops the fork flag — a restart continues the fork rather than branching it again. Placement follows where the user asked from. A pane-level ask is spatial, so the pane right-click menu offers Split Right / Left / Down / Up (pane splits gained a `before` slot for the Left/Up half, which the tree had no way to express). A tab-level ask isn't, so the tab context menu — inherited verbatim by the sidebar rows, which is where the request came from — opens the fork in a new tab with no placement question. The bare action behind the palette, the File menu and Settings → Keybindings takes the tab-level meaning. The three ways a fork can't run all surface rather than no-op: no session id yet (hooks not installed) and a remote pane (the command would shell the *local* agent) render the row disabled instead of hiding it, so the capability stays discoverable, and the action paths that have no row to grey out say so in a notification. Forking mid-turn is allowed but announced — agents fork from the persisted transcript, so the turn in flight is absent from the copy — and the parent is untouched either way. Copy Session ID sits beside Copy Working Directory. Codex has no copy-or-duplicate subcommand, so "copy the session" is the id: paste it into `codex resume`, a bug report, or another tool. Deliberately not built: any reading or writing of an agent's own session files. tty7's exposure stays the public CLI contract plus the hook payload's session id, so a change to Codex's rollout format or its version-numbered SQLite index costs at most a visible shell error. Forked tabs also look exactly like their parent, by decision — "Rename Tab" is the answer. Closes #211 * no-mistakes(review): perf(terminal): compute fork menu enablement at menu-open time * no-mistakes(document): docs: correct fork action surfaces, label, and remote limits * fix(agents): label forking the same for every agent The fork row said "Branch Session" on Claude Code and "Fork Session" everywhere else, on the strength of a source comment claiming "Claude Code calls it branching". It does not. `claude --help` documents the flag as `--fork-session`, described as "When resuming, create a new session ID instead of reusing the original"; the only occurrences of "branch" in its help are an unrelated git-branch review option. The claim came from otty's own UI wording, which I mistook for Claude's vocabulary and then wrote into the source as fact — so the comment goes with the special case rather than being left behind as a false statement about someone else's tool. The split was also inconsistent with itself: Grok takes the identical `--fork-session` flag and was already labelled "Fork Session". Every agent that has the capability calls it forking — `codex fork`, `--fork-session` on Claude Code and Grok, `--fork` on OpenCode — so one wording covers all four. `fork_label` keeps returning `Option<&'static str>`: it is still the UI's single capability gate (`None` = no verified fork command, no row offered), and per-agent wording stays expressible should one ever genuinely diverge. Generated commands are untouched — the existing table test still pins `claude --resume <id> --fork-session` and the other three verbatim. Also drops the two doc sentences that promised the per-agent label, and the stale "Branch Session" mentions left in comments; no occurrence survives anywhere in the tree. * no-mistakes(review): fix(agents): fork the pane the tab menu row named * no-mistakes(document): rewrap fork menu comment after label unification * fix(agents): repoint Pi's token-gate comment after the rebase Rebasing #211 onto #240 moved the session-id token gate out of resume_command and into the shared session_command_flags helper, so Pi's comment pointing at "the token gate above" no longer names anything. Comment only; the gate itself is unchanged. * no-mistakes(document): correct fork placement rationale in menus and changelog * chore: untrack AGENTS.md per gitignore dev-tool convention tty7 keeps agent-memory files out of the repo: `/CLAUDE.md` is already ignored, and on disk it is a symlink to `AGENTS.md`, so tracking the target defeated the convention. Ignore `/AGENTS.md` alongside it and drop the tracked copy; the file stays on disk, where the notes belong. --------- Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> |
||
|
|
208454e202 |
feat(remote): remote workspaces — a window that is one machine
Split the framework-free half of tty7 into `tty7-core` and add a headless
`tty7-server` built on it, so a workspace's filesystem, git and session state
can live on another machine while the GUI stays where it is.
- `crates/tty7-core`: wire protocol, session daemon, PTY, native SSH engine and
the domain model, with no gpui dependency. Module paths are unchanged.
- `crates/tty7-server`: the same daemon with no GUI attached, linked fully
static against musl and pushed onto the remote box. One dependency, on
purpose — a second one the GUI also needs belongs in core.
- `Host` trait + `HostId`/`HostRegistry`: every fs/git/watch call a workspace
makes goes through the machine it belongs to. `LocalHost` answers on this
box, `RemoteHost` over a routed control connection.
- `ui::host_ops`: the GUI's single door to a `Host`. Host calls block, so all
of them run on the background executor with the result landed on the UI
thread; de-duplication, staleness and error reporting live here rather than
at each call site. Enforced by a CI grep.
- Connect flow: home page → pick a configured SSH host → the machine's own
workspace list → a window bound to one workspace on it. Workspace switcher
groups by machine, this computer included.
- CI: static musl builds of `tty7-server` for x86_64/aarch64 via
cargo-zigbuild, a host-boundary grep, and version stamping factored out of
the nightly workflow. Both new jobs are non-required so branch protection
does not wedge open PRs.
Design and the interface contract it was built to are in
`docs/2026-07-27-remote-workspace-{design,impl-contract}.md`.
|
||
|
|
4e97253b53 |
fix(cwd): never run local filesystem operations on a remote pane's cwd
A remote pane's OSC 7 reports a path in the remote's namespace. The git-status probe, path completion, link resolution, the git-diff and worktree shell-outs, session persistence and cwd inheritance all took it as a local path. Nothing gated this. `refresh_git_status`'s doc claimed remote panes have no cwd, but that holds only *before* the remote shell's OSC 7 arrives — after it, a native-SSH pane's remote path was fed to a local `git`, with only `Path::exists()` incidentally saving it. That guard is weakest exactly where it matters: on Windows `/home/me/proj` is not an invalid path but a drive-relative one resolving to `C:\home\me\proj`, so a machine that has such a directory would report an unrelated repo's branch and diff as the pane's own. Correctness must not rest on that collision never happening. Add `TerminalView::local_cwd()` — the pane's cwd only when the pane is not remote — and route every local filesystem/Command consumer through it. Cwd inheritance for new tabs and splits is gated too: an inherited cwd wins over every fallback in `initial_working_directory`, so a remote path reached the spawn as a Win32 working directory. Deliberately unchanged: `tab_cwd`, so "Copy Working Directory" still copies a remote pane's remote path, which is what it is for. Not fixed here: on a remote pane, path completion falls back to tty7's own directory and link resolution stops matching relative paths. Both degrade rather than mislead now; sourcing either from the remote is a separate piece of work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
5e7a3240ad | chore(tooling): add repomix config for AI-friendly repo packing | ||
|
|
22e1ab1694 |
tty7: a GPU-rendered, daemon-backed terminal in pure Rust
tty7 is split into two Rust processes: a persistent daemon that owns the shells and a GPU-rendered client that talks to it over a local socket. Because the shells live in the daemon, quitting and reopening the app leaves the session intact — detach and reattach, no tmux required. - Persistent sessions — the daemon holds the PTYs and child processes, so closing a window or swapping in a new build never takes a shell down. - Performance — an 11 MB `cat` completes in 95 ms and DOOM-fire renders at 888 fps; the daemon drains the PTY at device speed off the render path. - Shell-aware — new tabs and splits open in the current working directory; zsh, bash, fish, and PowerShell are set up automatically. - Enhanced prompt — inline completion, syntax highlighting, history, and in-terminal search, with rich flag/subcommand signatures for common tools. - Tabs, resizable splits, a command palette, click-to-open links, desktop notifications, eight themes, and CJK/IME input. Native builds for macOS, Windows, and Linux. Built on Zed's gpui and Alacritty's VT core. |