From 4ba8bf44d0b7e0c52fb83796a9a540936c88c8cd Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Tue, 11 Aug 2026 00:35:44 +0800 Subject: [PATCH] docs: add a Mintlify documentation site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- README.md | 7 +- README.zh-CN.md | 5 +- docs/agents/orchestration.mdx | 103 +++++++++ docs/agents/overview.mdx | 107 +++++++++ docs/agents/sessions.mdx | 60 +++++ docs/agents/status.mdx | 83 +++++++ docs/cli/agent-skill.mdx | 84 +++++++ docs/cli/overview.mdx | 147 +++++++++++++ docs/cli/reference.mdx | 253 ++++++++++++++++++++++ docs/customization/fonts.mdx | 75 +++++++ docs/customization/keybindings.mdx | 94 ++++++++ docs/customization/settings.mdx | 86 ++++++++ docs/customization/themes.mdx | 113 ++++++++++ docs/docs.json | 142 ++++++++++++ docs/favicon.ico | Bin 0 -> 13679 bytes docs/features.md | 158 -------------- docs/features.zh-CN.md | 150 ------------- docs/getting-started/concepts.mdx | 108 +++++++++ docs/getting-started/first-launch.mdx | 126 +++++++++++ docs/getting-started/installation.mdx | 151 +++++++++++++ docs/git/diffs.mdx | 48 ++++ docs/git/source-control.mdx | 86 ++++++++ docs/git/worktrees.mdx | 56 +++++ docs/images/hero.webp | Bin 0 -> 183922 bytes docs/images/placeholder.svg | 12 + docs/index.mdx | 105 +++++++++ docs/logo/logo.svg | 6 + docs/reference/configuration.mdx | 183 ++++++++++++++++ docs/reference/keyboard-shortcuts.mdx | 103 +++++++++ docs/reference/privacy.mdx | 60 +++++ docs/reference/shell-integration.mdx | 73 +++++++ docs/reference/troubleshooting.mdx | 137 ++++++++++++ docs/reference/updates.mdx | 97 +++++++++ docs/remote/port-forwarding.mdx | 61 ++++++ docs/remote/sftp.mdx | 48 ++++ docs/remote/ssh.mdx | 115 ++++++++++ docs/remote/workspaces.mdx | 114 ++++++++++ docs/terminal/history.mdx | 57 +++++ docs/terminal/links.mdx | 51 +++++ docs/terminal/mouse-and-scrolling.mdx | 69 ++++++ docs/terminal/prompt.mdx | 130 +++++++++++ docs/terminal/selection-and-clipboard.mdx | 62 ++++++ docs/window/command-palette.mdx | 58 +++++ docs/window/search.mdx | 50 +++++ docs/window/side-panel.mdx | 66 ++++++ docs/window/sidebar.mdx | 76 +++++++ docs/window/tabs-and-splits.mdx | 99 +++++++++ 47 files changed, 3763 insertions(+), 311 deletions(-) create mode 100644 docs/agents/orchestration.mdx create mode 100644 docs/agents/overview.mdx create mode 100644 docs/agents/sessions.mdx create mode 100644 docs/agents/status.mdx create mode 100644 docs/cli/agent-skill.mdx create mode 100644 docs/cli/overview.mdx create mode 100644 docs/cli/reference.mdx create mode 100644 docs/customization/fonts.mdx create mode 100644 docs/customization/keybindings.mdx create mode 100644 docs/customization/settings.mdx create mode 100644 docs/customization/themes.mdx create mode 100644 docs/docs.json create mode 100644 docs/favicon.ico delete mode 100644 docs/features.md delete mode 100644 docs/features.zh-CN.md create mode 100644 docs/getting-started/concepts.mdx create mode 100644 docs/getting-started/first-launch.mdx create mode 100644 docs/getting-started/installation.mdx create mode 100644 docs/git/diffs.mdx create mode 100644 docs/git/source-control.mdx create mode 100644 docs/git/worktrees.mdx create mode 100644 docs/images/hero.webp create mode 100644 docs/images/placeholder.svg create mode 100644 docs/index.mdx create mode 100644 docs/logo/logo.svg create mode 100644 docs/reference/configuration.mdx create mode 100644 docs/reference/keyboard-shortcuts.mdx create mode 100644 docs/reference/privacy.mdx create mode 100644 docs/reference/shell-integration.mdx create mode 100644 docs/reference/troubleshooting.mdx create mode 100644 docs/reference/updates.mdx create mode 100644 docs/remote/port-forwarding.mdx create mode 100644 docs/remote/sftp.mdx create mode 100644 docs/remote/ssh.mdx create mode 100644 docs/remote/workspaces.mdx create mode 100644 docs/terminal/history.mdx create mode 100644 docs/terminal/links.mdx create mode 100644 docs/terminal/mouse-and-scrolling.mdx create mode 100644 docs/terminal/prompt.mdx create mode 100644 docs/terminal/selection-and-clipboard.mdx create mode 100644 docs/window/command-palette.mdx create mode 100644 docs/window/search.mdx create mode 100644 docs/window/side-panel.mdx create mode 100644 docs/window/sidebar.mdx create mode 100644 docs/window/tabs-and-splits.mdx diff --git a/README.md b/README.md index c9430037..0ba8a115 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,11 @@ Native builds for each platform on [**Releases**](https://github.com/l0ng-ai/tty | **CLI + Skills** | bundled `tty7` CLI · [agent skill](skills/tty7/SKILL.md) · pane/workspace control · real PTY commands · output, process, port, and agent status | | **SSH** | native russh stack: profiles with keychain secrets · SFTP panel · port forwarding · jump hosts · one-time, unprivileged `tty7-server` install | -Terminal and keybinding reference: [docs/features.md](docs/features.md). The agent-facing CLI -interface is documented in [skills/tty7/SKILL.md](skills/tty7/SKILL.md). +Full documentation lives in [**`docs/`**](docs/) — +[keyboard shortcuts](docs/reference/keyboard-shortcuts.mdx) · +[config.json](docs/reference/configuration.mdx) · +[CLI reference](docs/cli/reference.mdx). The agent-facing CLI interface is also +documented in [skills/tty7/SKILL.md](skills/tty7/SKILL.md). Install the skill with: diff --git a/README.zh-CN.md b/README.zh-CN.md index e7ca60fd..56a5ab7a 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -54,7 +54,10 @@ | **CLI + Skills** | 安装包自带 `tty7` CLI · [agent skill](skills/tty7/SKILL.md) · pane/工作区控制 · 真实 PTY 命令 · 输出、进程、端口和 agent 状态 | | **SSH** | 原生 russh 栈:profile 凭据进 keychain · SFTP 面板 · 端口转发 · 跳板机 · 一次无 sudo 安装 `tty7-server` | -终端和快捷键参考:[docs/features.zh-CN.md](docs/features.zh-CN.md)。面向 agent 的 CLI 接口见 +完整文档在 [**`docs/`**](docs/)(英文)—— +[快捷键](docs/reference/keyboard-shortcuts.mdx) · +[config.json](docs/reference/configuration.mdx) · +[CLI 参考](docs/cli/reference.mdx)。面向 agent 的 CLI 接口另见 [skills/tty7/SKILL.md](skills/tty7/SKILL.md)。 通过以下命令安装 skill: diff --git a/docs/agents/orchestration.mdx b/docs/agents/orchestration.mdx new file mode 100644 index 00000000..eae1acc6 --- /dev/null +++ b/docs/agents/orchestration.mdx @@ -0,0 +1,103 @@ +--- +title: "Orchestrating agents" +description: "One agent opening a pane for another, waiting on it, and reading the result." +--- + +Once an agent's status is a thing a program can ask about, one agent can run +another. tty7 gives that loop a primitive instead of leaving it to screen +scraping. + +## The loop + +```bash +# 1. give the worker a pane +PANE=$(tty7 split --v) + +# 2. hand it a task +tty7 send "$PANE" 'claude -p "add tests for the parser"' --enter + +# 3. sleep until it needs you or finishes +tty7 wait "$PANE" --until waiting,done --changed --timeout 600 + +# 4. read what happened +tty7 capture "$PANE" --plain + +# 5. clean up +tty7 pane close "$PANE" +``` + +That is the whole shape. The interesting step is the third. + +## `tty7 wait` + +```bash +tty7 wait [%PANE] [--until STATE,…] [--changed] [--timeout SECS] [--interval MS] +``` + +Blocks until the pane's agent reaches one of the states you named. + +| Flag | Default | | +|---|---|---| +| `--until` | `waiting,done,exit` | Which states end the wait: `idle`, `working`, `waiting`, `done`, `exit` | +| `--changed` | off | Ignore the state the pane was *already* in — only wake on one it moved into after the wait began | +| `--timeout` | none | Give up after this many seconds, exiting 124 | +| `--interval` | 500 ms | How often to poll | + +Exit codes are made for scripts: + +| Code | Meaning | +|---|---| +| `0` | A state you asked for was reached | +| `124` | Timed out — the `timeout(1)` convention, so "not yet" is distinguishable from "broken" | +| `1` | The worker died first; the JSON says `"status": "exit"` | + +The reply carries the agent's own message and its native session id, so a +wake-up is directly actionable. + +### Why `--changed` matters + +The status the server keeps is a **level, not an event**. `done` stands until +the next turn begins; `waiting` stands until the agent moves again. + +So a `wait` issued immediately after a `send` can answer with the *previous* +turn's state, before the worker has even read the input. `--changed` refuses the +state the pane was already in, which is what every round after the first needs. +Without it, the JSON's `stale` flag tells you whether that happened. + +## Watching everything at once + +```bash +tty7 agents # every agent on the machine: pane, agent, status, message +tty7 agents --json # the same, parseable +``` + +If you are an agent yourself, you are in that list too. + +## The Claude Code skill + +**Settings → Agents** has a switch that installs +`~/.claude/skills/tty7-orchestration` — a skill teaching a *primary* Claude Code +agent this whole delegation loop: open a worker pane, send it one bounded task, +`wait` on it, answer what it asks, collect the result, close the pane. + +It is a skill rather than a global instruction on purpose. Only its one-line +description rides in context until something reaches for it, and worker agents +never inherit orchestration authority. + +Uninstalling removes the file tty7 wrote and refuses to touch one it did not, so +a hand-written skill that happens to share the directory name survives. + +## Rules of the road + + + The panes on a machine are somebody's real work, and some of them are other + agents mid-task. Treat anything you did not create as read-only. + + +- **Never `send` into a pane you did not open.** Check `tty7 agents` first. +- **Never close a pane, tab, or workspace you did not create.** +- **Never `server stop` or `server restart`.** Every pane on the machine dies + with it. +- **Clean up what you did create** — `tty7 pane close %83` when you are done. + +The full agent-facing contract is in [the skill](/cli/agent-skill). diff --git a/docs/agents/overview.mdx b/docs/agents/overview.mdx new file mode 100644 index 00000000..903c94a6 --- /dev/null +++ b/docs/agents/overview.mdx @@ -0,0 +1,107 @@ +--- +title: "Coding agents" +description: "What tty7 does around Claude Code, Codex, and 16 others — without ever wrapping them." +--- + +tty7 recognises coding agents running in a pane and builds around them. It does +not wrap them, proxy them, or replace their interface: the agent you start is +the agent you get, running in a normal PTY, with its own UI. tty7 adds the +things a terminal is in a position to add — who is running where, what they +need, and what changed. + + + Agent sessions in the tty7 sidebar + + +## Which agents + +Eighteen CLIs are recognised on sight, by the command running in the pane: + +| Agent | Command | +|---|---| +| Claude Code | `claude`, `claude-code` | +| Codex | `codex`, `codex-cli` | +| Gemini | `gemini`, `gemini-cli` | +| Copilot | `copilot` | +| Cursor | `cursor-agent` | +| Amp | `amp` | +| OpenCode | `opencode` | +| Aider | `aider`, `aider-chat` | +| Goose | `goose` | +| Droid | `droid` | +| Grok | `grok` | +| Qwen Code | `qwen`, `qwen-code` | +| Auggie | `auggie` | +| Hermes | `hermes` | +| Vibe | `vibe`, `vibe-acp` | +| Antigravity | `agy`, `antigravity` | +| Pi | `pi` | +| Oh My Pi | `omp` | + +Detection sees through the usual disguises: a full path, a `.cmd` or `.exe` on +Windows, leading environment assignments, and an interpreter in front +(`node .../claude/cli.js`). + +### Your own wrapper + +If you launch agents through a wrapper script, map its name to an agent in +`config.json`: + +```json +{ + "agent_commands": { + "cc": "claude", + "work": "codex" + } +} +``` + +The key is your command's name; the value is one of the slugs above (`claude`, +`codex`, `gemini`, `aider`, `amp`, `opencode`, `copilot`, `cursor`, `goose`, +`droid`, `pi`, `auggie`, `hermes`, `vibe`, `antigravity`, `grok`, `qwen`, +`omp`). + +## What you get for free + +Just by running an agent in a pane: + + + + The tab chip and sidebar row show which agent runs where, so ten tabs stay + legible. + + + The branch and working-tree diff on the row, refreshed as the agent works. + + + A pane lost to a reboot relaunches the conversation, carrying its original + flags. [More →](/agents/sessions) + + + Palette commands that hand the current selection or the repo's `git diff` to + the running agent as a prompt. + + + +## What needs a hook + +Live status — **working**, **needs your input**, **done** — comes from the agent +itself, over a channel tty7 installs into that agent's configuration. It powers +the status dots, the notifications, the tray icon, and `tty7 wait`. + +Installing takes one click per agent under **Settings → Agents**. +[Status and notifications →](/agents/status) + +## Where to go next + + + + Hooks, status dots, the tray icon. + + + Resume, fork, and copying a session id. + + + One agent driving another with `tty7 wait`. + + diff --git a/docs/agents/sessions.mdx b/docs/agents/sessions.mdx new file mode 100644 index 00000000..7f70818f --- /dev/null +++ b/docs/agents/sessions.mdx @@ -0,0 +1,60 @@ +--- +title: "Agent sessions" +description: "Resuming a conversation after a reboot, forking a live one, and getting at the session id." +--- + +Coding agents keep their own conversation history, addressed by a session id. +Because tty7's hooks learn that id, it can do three things with it. + +## Resume after a restart + +When the server goes away — a reboot, a crash, a deliberate restart — the shells +go with it. Panes that were running an agent relaunch the conversation on +restore instead of coming back to a bare prompt: + +```bash +claude --dangerously-skip-permissions --resume 8f3c… +``` + +The original launch flags are replayed, so the pane comes back the way you +started it, not the way the defaults would. + +Supported for Claude Code, Codex, Gemini, OpenCode, Amp, Cursor, Copilot, Grok, +Pi, and Oh My Pi. Turn it off with `restore_agent_sessions: false`. + + + Resume needs the agent's hooks installed, since the session id comes from + them. [Installing hooks →](/agents/status) + + +## Fork a live session + +Forking branches a running conversation into a second, independent one. The +original keeps going untouched; both continue separately from the same history. + +Right-click a **pane** to fork into a split — the menu offers a placement — +or right-click the **tab or sidebar row** to open the fork in a new tab. + +| Agent | What tty7 runs | +|---|---| +| Claude Code | `claude --resume --fork-session` | +| Codex | `codex fork ` | +| Grok | `grok --resume --fork-session` | +| OpenCode | `opencode --session --fork` | +| Oh My Pi | `omp --fork ` | + +It is the agent's own fork command, run in a new pane — nothing is copied by +tty7 itself. + + + A fork duplicates the whole transcript in the agent's session store, so + forking repeatedly costs real disk. A pane on a + [remote machine](/remote/workspaces) cannot fork, because the command would + run against the local agent. + + +## Copy the session id + +**Copy Session ID** — in the pane's right-click menu, beside *Copy Working +Directory*, and in the command palette — puts the agent's native id on the +clipboard. Paste it into `codex resume`, a bug report, or another tool. diff --git a/docs/agents/status.mdx b/docs/agents/status.mdx new file mode 100644 index 00000000..d9799e53 --- /dev/null +++ b/docs/agents/status.mdx @@ -0,0 +1,83 @@ +--- +title: "Status and notifications" +description: "Installing the hooks, reading the dots, and being told when an agent needs you." +--- + +An agent working for two minutes and an agent that stopped ninety seconds ago +waiting for permission look identical from outside. tty7 fixes that by letting +the agent say which one it is. + +## Installing the hooks + +**Settings → Agents** lists every agent that can report status, with an +**Install** button beside each: + +| Agent | | +|---|---| +| Claude Code · Codex · Copilot · OpenCode · Pi · Grok · Oh My Pi | Hooks available | +| Gemini · Aider · Amp · Cursor · Goose · Droid · Auggie · Hermes · Vibe · Antigravity · Qwen Code | Detected and labelled, but no status channel yet | + +Installing writes into that agent's own configuration directory and can be +undone from the same row — the button becomes **Uninstall**, and reads +**Outdated** with an **Update** when tty7 ships a newer hook. + + + The hooks only do anything inside tty7. Running the same agent in another + terminal is unaffected. + + +Connected [remote machines](/remote/workspaces) get their own row, so an agent +running on a dev box reports status to the window you are watching it from. + +## The status dot + +Every tab chip and sidebar row carries a dot: + +| Dot | Meaning | +|---|---| +| 🔵 **Blue** | Working | +| 🟠 **Amber** | Needs your input — a permission prompt, a question | +| 🟢 **Green** | Done with this turn | + + + Agent status dots + + +The same three states are what `tty7 agents` reports as `running` / `waiting` / +`idle`, and what [`tty7 wait`](/agents/orchestration) blocks on. + +## Notifications + +Two, both following your **Settings → Window & Tabs → Notifications** policy: + +- **"needs your permission…"** the moment an agent blocks on you +- **"finished after 42s"** at the end of a turn + +Which means that by default — *When unfocused* — you are told the instant you +are the bottleneck, and left alone while you are watching. + +## The tray icon + +tty7 keeps a status item in the system tray (menu bar on macOS). It flips to an +attention state the moment *any* agent anywhere needs input, so you can see it +without the window in front of you. + +Its menu lists every agent pane with its brand avatar and status dot — click one +to reveal it — and also holds the notification policy switch and **Quit and Stop +Server…**. + +Turn it off with **Settings → Window & Tabs → Show tray icon** +(`show_tray_icon: false`). + +## Sending an agent some context + +Two command-palette entries hand what is in front of you to the agent running in +the pane, as a ready-made prompt: + +| Command | Sends | +|---|---| +| **Agent: Send Selection** | The current terminal selection | +| **Agent: Send Git Diff for Review** | The repository's `git diff` | + +If nothing recognisable is running, tty7 says *"No running coding agent found"* +rather than typing into your shell. diff --git a/docs/cli/agent-skill.mdx b/docs/cli/agent-skill.mdx new file mode 100644 index 00000000..12697ffc --- /dev/null +++ b/docs/cli/agent-skill.mdx @@ -0,0 +1,84 @@ +--- +title: "The agent skill" +description: "Teaching a coding agent to use tty7 properly — including when not to." +--- + +The CLI is only half of the story. An agent has to know *when* reaching for a +pane beats running a command, and — more importantly — which panes it must not +touch. That is what the skill is for. + +## Installing it + +```bash +npx skills add l0ng-ai/tty7 +``` + +The source lives at +[`skills/tty7/`](https://github.com/l0ng-ai/tty7/tree/main/skills/tty7) in the +repository: a `SKILL.md` and a full command reference. + + + This is separate from the **orchestration** skill installed from **Settings → + Agents**, which teaches a *primary* agent to delegate to worker agents. This + one teaches any agent to drive tty7 at all. + [Orchestration →](/agents/orchestration) + + +## What it teaches + +### When to use a pane instead of a plain command + +The Bash-style tool an agent already has is right for anything that starts, does +its job, and exits. A pane is right when: + +- **It should not block.** A dev server, a watcher, `tail -f`, a long test run. +- **It is interactive or stateful.** A REPL, `ssh`, a database shell — anything + where you send, read, then send again. A pane keeps the session alive between + turns; a one-shot call cannot. +- **It needs a real TTY.** Programs that detect a pipe and change behaviour — + colour, progress bars, TUIs, `top`, raw mode. +- **The user should be able to watch.** Anything in a pane shows up live in + their window. That is often the whole point. +- **You are being asked about something you did not start.** "What's running in + that pane?", "why is port 3000 taken?", "what are my agents doing?" + +### The safety rules + + + The panes on this machine are the user's real work, and some of them are other + coding agents mid-task. Anything the agent did not create is read-only. + + +- **Never `send` into a pane you did not open.** Keystrokes land in the middle + of whatever is happening there. Check `tty7 agents` first. +- **Never close a pane, tab, or workspace you did not create.** +- **Never `server stop` or `server restart`.** Every pane on the machine dies + with the server, including yours. +- **Never `tty7 server start` on your own initiative** when `doctor` says the + server is unreachable — starting one the user did not ask for changes what + their GUI attaches to. Tell them instead. +- **Clean up what you did create.** `tty7 pane close %83` when the scratch pane + is done with. + +### The reliable idioms + +Rather than screen-scraping, the skill points agents at the primitives that +actually answer the question: + +```bash +# is it finished? — when only the depth-0 shell is left, yes +tty7 procs %83 --json + +# the answer, not the view +tty7 send "$PANE" 'cargo test > /tmp/t.log 2>&1; echo $? > /tmp/t.rc' --enter + +# wake up exactly when the other agent needs something +tty7 wait %3 --until waiting,done --changed --timeout 600 +``` + +## For humans writing their own tooling + +The same material is worth reading even if you are not an agent — it is the +shortest description of how to use tty7 as a job runner. Start with the +[CLI overview](/cli/overview), then the +[command reference](/cli/reference). diff --git a/docs/cli/overview.mdx b/docs/cli/overview.mdx new file mode 100644 index 00000000..ac1c7336 --- /dev/null +++ b/docs/cli/overview.mdx @@ -0,0 +1,147 @@ +--- +title: "The tty7 command" +description: "Driving the workbench from a script, a Makefile, or another agent." +--- + +`tty7` is a thin, non-interactive client of the tty7 server. Every verb runs and +exits; `--json` makes the output machine-readable. **The GUI does not have to be +running** — the server is what owns the panes. + +It ships inside every installer and is put on PATH at launch, so it works from +any terminal on the machine. [Installation →](/getting-started/installation#the-tty7-command) + +## Start with `doctor` + +```bash +tty7 doctor +``` + +One table that answers everything you need before doing anything else: whether a +server is reachable, whether its wire dialect matches this binary, and whether +`TTY7_CONFIG_DIR` / `TTY7_WS` / `TTY7_PANE` are set — that is, whether you are +running *inside* a tty7 pane. + +Being inside a pane matters because the address-taking verbs (`split`, `send`, +`capture`, `procs`, `pane close`) default to `$TTY7_PANE`, and `run --keep` +files its pane into `$TTY7_WS`. Outside one you must name a target, and the +error says so rather than guessing. + +## Addresses + +| Shape | Means | Stable? | +|---|---|---| +| `%42` | A pane | **Yes** — a pane keeps its id for its whole life | +| `@7` | A tab, numbered across the whole machine in tree order | **No** — it shifts whenever any workspace or tab appears or disappears | +| `api` · `76698a44` · a full UUID | A workspace, by name, unique id prefix, or id | Yes | + +Re-resolve `@N` immediately before using it. Pane and workspace ids are safe to +remember. + +## Two ways to run something + +### Blocking, with a real exit code + +```bash +tty7 run -- cargo test # streams to stdout, exits with cargo's code +tty7 run --cwd /path -- make +tty7 run --keep -- cargo build # leaves the pane behind as a new tab +``` + +The closest thing to running the command yourself — the difference is that it +gets a real PTY (so colour, progress bars, and TUIs behave), and that you can +watch it happen in the window. + + + Everything after `--` belongs to the child: `tty7 run -- cargo test --keep` + passes `--keep` to cargo, not to tty7. + + +### Non-blocking: a pane you talk to over time + +This is the one worth reaching for. Get a pane, give it work, come back. + +```bash +PANE=$(tty7 split --v) # or --h; prints "%83" +tty7 send "$PANE" 'npm run dev' --enter +# ... later +tty7 capture "$PANE" --plain +tty7 pane close "$PANE" +``` + +If you are not inside a tty7 pane there is nothing to split, so make your own +place to work: + +```bash +tty7 new --json /path/to/repo # {"id": "...", "pane": 83} +``` + +## Reading a pane + +```bash +tty7 capture %83 --plain +``` + +`capture` returns what the server stored. Without `--plain` that is the raw +bytes, escapes and all. With `--plain` those bytes are replayed through a real +terminal grid and you get the text that produced — which is not the same as +stripping escapes yourself: + +- A line the shell wrapped at the pane width comes back as **one** line +- A progress bar that rewrote itself with `\r` reads as its **final** value +- Cursor addressing puts text **where the program put it**, so a TUI's screen + lands where it was drawn + +Use `--plain` whenever a human would want to read the output. + + + A screen is a rectangle. Whatever scrolled off the top is gone, and an exit + code was never on it. When you want the *answer* rather than the *view*, have + the shell write it somewhere clean: + + ```bash + tty7 send "$PANE" 'cargo test > /tmp/t.log 2>&1; echo $? > /tmp/t.rc' --enter + ``` + + +## Knowing when something finished + +```bash +tty7 procs %83 +``` + +The process tree inside the pane, indented by depth, with `*` on the foreground +process — plus the ports those processes are listening on. **When the only entry +left is the depth-0 shell, the command is done.** That is far more reliable than +grepping the screen for a sentinel that can wrap or echo twice. + +For agents specifically, use [`tty7 wait`](/agents/orchestration) instead of +polling. + +## Looking around + +```bash +tty7 ls # every workspace: tabs, panes, who's attached +tty7 ws tree api # one workspace as a tree +tty7 pane ls --all # every pane, including orphans no workspace holds +tty7 agents # every coding agent and its status +tty7 status # server pid, uptime, pane count, build, socket +tty7 machine ls # this machine plus any linked remotes +tty7 events # stream server events until interrupted +``` + +`--json` on any of them, `-q` to suppress success output (errors still print). + +## Remote machines + +```bash +tty7 -m devbox ls +tty7 -m devbox run -- cargo test +``` + +`-m` routes over a link the local server already holds. It will not dial a fresh +connection — connect from the GUI first. +[Remote workspaces →](/remote/workspaces) + + + Every verb, flag, and JSON shape. + diff --git a/docs/cli/reference.mdx b/docs/cli/reference.mdx new file mode 100644 index 00000000..254abd98 --- /dev/null +++ b/docs/cli/reference.mdx @@ -0,0 +1,253 @@ +--- +title: "Command reference" +description: "Every verb, its flags, and the JSON it emits under --json." +--- + +## Global flags + +Accepted anywhere on the line, before or after the subcommand. + +| Flag | Effect | +|---|---| +| `-m, --machine ` | Route to a linked machine over the local server's existing link. Matches the full link key (`me@devbox:22`) or the bare host (`devbox`). SSH links only; a down link, or a jump/proxy chain, is refused with a reason rather than dialled fresh. | +| `--json` | One JSON object on stdout instead of the human table. | +| `-q, --quiet` | No output on success. Errors still go to stderr. | + +## Environment + +Set inside every tty7 pane, inherited by anything launched from one. + +| Variable | Meaning | +|---|---| +| `TTY7_PANE` | This pane's id, e.g. `71` or `%71` (both accepted). Default target of `split`, `send`, `capture`, `procs`, `pane close`. | +| `TTY7_WS` | This pane's workspace id. Default for `run --keep`, `tab new`, `ws tree`. | +| `TTY7_CONFIG_DIR` | The server's config dir — how the CLI finds the right server. You never pass a socket path. | + +Outside a tty7 shell, address-taking verbs fail with +`not inside a tty7 shell — pass an explicit %pane/@tab/workspace`. + +## Exit codes + +| Code | Meaning | +|---|---| +| `0` | Success | +| `1` | The command failed; one line on stderr, prefixed `tty7:` | +| `2` | Usage error — unknown verb, missing argument, bad type | +| `124` | `tty7 wait` timed out (the `timeout(1)` convention) | +| `141` | Unix only: the reader hung up — piping into `head -1`, say — and SIGPIPE ended it, exactly as it ends `cat`. Not a failure. Windows reports 0 for the same thing, having no signal to imitate. | +| *other* | Only from `tty7 run`, which passes the child's exit code through | + +If `run` cannot learn the child's code it prints a note to stderr and exits 1 +with `"exit_code_known": false` in the JSON — that is how you tell a real 1 from +a stand-in. + +## Top-level verbs + +### `tty7 ls` + +Same as `ws ls`. Table: `WORKSPACE NAME TABS PANES ATTACHED`. +JSON: `{"workspaces":[{"id","name","tabs","panes","attached"}]}`. + +`ATTACHED` names the host holding the workspace — a GUI window, or another +client — and is `-` when nobody is. + +### `tty7 run [--keep] [--cwd DIR] [--ws WORKSPACE] -- CMD...` + +Spawns a pane running `CMD`, streams its output to stdout, waits, and exits with +its code. The command must come after `--`. + +- `--keep` leaves the pane alive as a new tab afterwards. Needs a workspace, so + it requires `--ws` or `$TTY7_WS` — without one it is an error, not a silent + fallback. +- `--cwd` sets the working directory. `--ws` also sets the pane's `TTY7_WS`. +- Interrupting `run` can leave the pane behind as an orphan — see + `pane ls --all`. + +JSON: `{"pane","exit","exit_code_known","kept"}`, printed **after** the streamed +output. The combined stream is not valid JSON — read the last line. + +### `tty7 new [PATH] [--open]` + +Creates a workspace plus its first tab and shell, at `PATH` if given. Prints the +workspace id. JSON: `{"id","pane","opened"}`. + +`--open` also puts a window on it, if a GUI is running on this machine. Without +it the workspace still appears in the switcher; it just waits to be opened. + +### `tty7 split [%PANE] (--v|--h) [--ratio R]` + +Alias of `pane split`. Splits `%PANE` (default `$TTY7_PANE`), spawning a shell +in the same cwd. Exactly one axis is required — `--v`/`--vertical` puts the new +pane below, `--h`/`--horizontal` to the right. `--ratio` (default `0.5`) is the +share kept by the *existing* pane. Prints `%NN`. JSON: `{"pane"}`. + +### `tty7 send [%PANE] TEXT [--enter]` + +Types `TEXT` into the pane as keystrokes; `--enter` appends CR. With one +argument the text is the argument and the pane comes from `$TTY7_PANE` — but a +lone `%42` is rejected as a missing-text error rather than typed. +JSON: `{"pane","sent","enter"}`. + +### `tty7 capture [%PANE] [--plain] [--scrollback]` + +The pane's replay. Two independent choices: + +**How much** — the newest scrollback segment by default, the whole ring with +`--scrollback`. The ring splits into segments on resize, so for a pane that was +never resized the two are identical. + +**In what form** — without `--plain`, the stored bytes with ANSI escapes intact, +decoded as UTF-8 (invalid bytes become U+FFFD). With `--plain`, those bytes +replayed through a terminal grid and printed as the text they produced. + +Either way it is a snapshot, not a stream: it collects the replay, settles for +~300 ms, and returns. Call it again for a newer one. +JSON: `{"pane","text"}`. + +### `tty7 procs [%PANE]` + +The process tree inside the pane, indented by depth, `*` on the foreground +process — then a second table of ports those processes are listening on. Prints +`nothing running in this pane` when both are empty. + +JSON: `{"procs":[{"pid","name","depth","foreground"}],"ports":[{"port","pid","name"}]}`. + +### `tty7 agents` + +Every pane running a recognised coding agent. Table: +`PANE AGENT STATUS MESSAGE`, status one of `running` / `waiting` / `idle`. +JSON: `{"agents":[...]}`. + +### `tty7 wait [%PANE] [--until STATE,…] [--changed] [--timeout SECS] [--interval MS]` + +Blocks until the pane's agent reaches one of the named states. + +| Flag | Default | | +|---|---|---| +| `--until` | `waiting,done,exit` | `idle`, `working`, `waiting`, `done`, `exit` | +| `--changed` | off | Only wake on a state the pane moved into *after* the wait began | +| `--timeout` | none | Give up after N seconds, exiting `124` | +| `--interval` | `500` | Poll interval in ms (50–3,600,000) | + +The reply carries the agent's message and native session id. The JSON's `stale` +flag says whether the answer might belong to the previous turn. +[Orchestration →](/agents/orchestration) + +### `tty7 events` + +Streams server events until interrupted, one per line — pane exits, agent status +changes, workspace preemption, layout deltas. `--json` makes it NDJSON. Blocks +forever; run it with a timeout or in the background. + +### `tty7 status` + +Same as `server status`: pid, uptime, pane count, dialect versions, build, +socket path. JSON is the `ServerStatus` object itself (`pid`, `uptime_secs`, +`panes`, `control_version`, `protocol_version`, `build`, `socket`). + +### `tty7 doctor` + +The install check: the three environment variables, whether the server answers, +whether its control and protocol versions match this binary, pid/uptime/panes, +and how many machine links exist. Adds a note when you are not inside a tty7 +shell. + +JSON: `{"context":{"config_dir","workspace","pane"},"server":{"reachable","dialect_ok","build","status","routes"}}` +— the context fields are booleans, not values. + +## `ws` — workspaces + +Address a workspace by name, by full id, or by a unique id prefix (the 8-char +prefix `tty7 ls` prints). An ambiguous name or prefix is an error that lists the +candidates. + +| Command | Effect | JSON | +|---|---|---| +| `ws ls` | Every workspace | `{"workspaces":[...]}` | +| `ws tree [WORKSPACE]` | One workspace as a tree: tabs, split axes and ratios, panes with cwds | The whole workspace object: `{"id","name","last_active","tabs":[{"id","name","sidebar_group","root",…}]}` | +| `ws new [NAME]` | An empty workspace (no tab, no pane) | `{"id","name"}` | +| `ws rename WORKSPACE NAME` | Name or rename | `{"id","name"}` | +| `ws rm WORKSPACE` | Delete the workspace | `{"removed"}` | +| `ws attach WORKSPACE` | Become its controlling client | `{"attached","took_over_from"}` | +| `ws detach WORKSPACE` | Let go without interrupting anything | `{"detached"}` | + + + `ws rm` does **not** kill the panes it held — they keep running as orphans + with no workspace. Find them with `pane ls --all` and close them one by one. + + +Prefer `tty7 new ` over `ws new` when you want something usable: `ws new` +leaves an empty workspace you then have to populate, while `tty7 new --json` +hands back both ids at once. + +The `root` node in `ws tree --json` is externally tagged, so a leaf is +`{"Leaf":{"pane":31}}` and a split is `{"Split":{"axis","ratio","a","b"}}` with +`a`/`b` nested the same way. + +## `tab` — tabs + +`@N` numbers tabs across the **whole machine** in tree order, densely from `@1`. +The numbering shifts whenever any workspace or tab is created or removed, so +resolve it immediately before use. A full tab UUID also works: `@`. + +| Command | Effect | JSON | +|---|---|---| +| `tab ls [WORKSPACE]` | Tabs of a workspace | `{"workspace","tabs":[{"ordinal","id","name","label","agent","group","panes":[…]}]}` | +| `tab new [WORKSPACE] [--cwd DIR]` | Add a tab with a fresh shell | `{"tab","pane"}` | +| `tab close @TAB` | Close the tab and every pane in it | `{"closed"}` | +| `tab rename @TAB NAME` | Name or rename | `{"tab","name"}` | +| `tab move @TAB INDEX` | Reposition within its workspace | `{"tab","to"}` | + +`GROUP` is the heading the GUI's sidebar files the tab under, shown by its last +segment. Read-only from here: with the default repo grouping the GUI recomputes +it from the tab's working directory. + +`label` falls back through the best evidence available — the name if someone set +one, else the agent running there, else the last segment of the cwd, else the +foreground process. `name` stays literal, so a script can tell a real name from +a stand-in. + +## `pane` — panes + +| Command | Effect | JSON | +|---|---|---| +| `pane ls [WORKSPACE]` | Panes with their workspace, tab, cwd, live flag | `{"panes":[…]}` | +| `pane ls --all` | The server's whole pane registry, including orphans | `{"panes":[…],"orphans":N}` | +| `pane split …` | Identical to top-level `split` | `{"pane"}` | +| `pane close [%PANE]` | Close the pane; its shell is hung up | `{"closed"}` | + +`--all` is the one that shows leaks. Each entry is +`{"pane","workspace","orphan","owner","title","cwd","live"}`: `owner` is +`tty7-cli` for panes this CLI spawned, and `orphan: true` means no workspace +holds it. An interrupted `run` and a removed workspace both leave orphans here. + +`title` is usually the running command — `claude`, `nvim`, `cargo` — which makes +`pane ls --all --json` a quick way to find "the pane running X". + +## `machine` — remotes + +`machine ls` lists the local machine plus every link the server holds: +`MACHINE KIND CONNECTED`. JSON: `{"machines":[{"key","kind","connected"}]}`. + +## `server` — the daemon + +| Command | Effect | +|---|---| +| `server status` | Same as `tty7 status` | +| `server logs` | Tail the server log; prints the path, and says so when logging was never enabled (`TTY7_LOG=info` before the server starts) | +| `server start` | Bring up a server on this machine | +| `server stop` | Stop it — **every pane on the machine dies** | +| `server restart` | Stop, then start — same consequence | + + + Do not run `start`, `stop`, or `restart` on someone else's behalf. They change + or destroy what the user's GUI is attached to. + + +## Not implemented yet + +These parse and then exit 1 with an explanation: + +- `ws stop` — the control dialect has no workspace-stop request yet +- `machine connect` / `machine disconnect` — use the GUI's connection manager +- bare `tty7 ` (launch or focus the GUI) diff --git a/docs/customization/fonts.mdx b/docs/customization/fonts.mdx new file mode 100644 index 00000000..544fc5ba --- /dev/null +++ b/docs/customization/fonts.mdx @@ -0,0 +1,75 @@ +--- +title: "Fonts" +description: "The bundled default, fallback chains, ligatures, and why CJK needs a word." +--- + +**Settings → Appearance → Typography** covers the everyday choices; the rest is +`config.json`. + +| Setting | Default | | +|---|---|---| +| **Font family** | Hack | Picked from fonts installed on your system | +| **Font size** | 15 px | The terminal grid | +| **Interface font size** | 16 px | Everything outside the grid (12–24) | +| **Line height** | 1.4 | A multiple of the font size | +| **Bold font** / **Italic font** | — | Distinct faces, when you want them | +| **Font ligatures** | off | Contextual alternates stay off unless you ask | + +## Hack is bundled + +The default font ships inside the binary. It renders identically on every +machine without relying on a system install, so a fresh laptop looks like the +one you set up last year. + +## Fallbacks + +`font_family` is the primary face; `font_fallbacks` is an ordered list tried in +turn for anything the primary lacks. + +```json +{ + "font_family": "JetBrains Mono", + "font_fallbacks": ["Maple Mono NF CN", "PingFang SC", "Apple Color Emoji"] +} +``` + +The defaults name faces the host OS actually ships — PingFang SC and Apple Color +Emoji on macOS, Microsoft YaHei and Segoe UI Emoji on Windows, Noto on Linux. +Those stock names are appended to whatever list you write, too, so a +`config.json` copied from another platform still resolves. + +## OpenType features + +`font_features` passes tags straight through to the shaper: + +```json +{ + "font_features": { "calt": true, "liga": 1, "ss01": true, "zero": false } +} +``` + +A tag must be four alphanumeric characters; `true`/`false` map to `1`/`0`. +Anything malformed is skipped with a log line rather than failing the whole +config. + +## CJK and the two-column grid + + + A cell is one advance of the primary face, and a wide (CJK) character is + pinned to exactly two of them. A CJK fallback sits flush in its slot only if + its ideographs advance **twice** the primary's Latin advance. + + +Bundled Hack advances 0.60205em, so a two-column slot is 1.2041em — while every +stock CJK face (Microsoft YaHei, PingFang SC, Noto Sans CJK) advances 1.0em. +Those glyphs get left-aligned in the slot, leaving a ~0.2em gap on the right of +every character. + +[Maple Mono NF CN](https://github.com/subframe7536/maple-font) is tried first on +every platform for exactly this reason: 0.6em Latin, 1.2em CJK, an exact +two-cell fit against Hack. It is referenced by name only, never bundled (~20 MB +per weight) — install it and tty7 picks it up with no config change. + +If you want CJK set *tight* rather than merely even, change the **primary** face +instead. One that advances 0.5em — Sarasa Mono SC, say — makes two columns +exactly 1.0em. diff --git a/docs/customization/keybindings.mdx b/docs/customization/keybindings.mdx new file mode 100644 index 00000000..84386b0c --- /dev/null +++ b/docs/customization/keybindings.mdx @@ -0,0 +1,94 @@ +--- +title: "Keybindings" +description: "Rebinding anything, chord sequences, and the tmux preset." +--- + +**Settings → Keybindings** (⌘ ,) lists every shortcut in the app, +grouped the same way the command palette is. + +## Rebinding + +Click a shortcut and press the new keys. It saves after a brief pause. + +| | | +|---|---| +| Press keys | Set the binding | +| Press more keys | Chain a sequence — ⌃ B then X | +| Esc | Cancel | +| | Remove the last key — or, pressed first, reset the shortcut to its default | + +**Restore all defaults** at the bottom undoes every rebinding at once. There is +no undo for that one. + + + Rebinding a shortcut + + +## Actions with no default key + +Some actions ship deliberately unbound, because there is no obvious key left to +take: pane resize and swap, workspace selection, most git commands, SFTP, and +the panel tabs. They are all in the command palette, and all bindable here. + +## Editing `config.json` instead + +```json +{ + "keybindings": { + "SplitRight": "cmd-d", + "ResizePaneLeft": "ctrl-alt-left", + "ToggleSftp": "cmd-shift-u" + } +} +``` + +The syntax is modifiers joined by `-`, then the key. Chords are separated by a +space. + +| Token | Means | +|---|---| +| `secondary` | on macOS, Ctrl elsewhere | +| `cmd` · `ctrl` · `alt` · `shift` | Literal modifiers | +| `ctrl-b n` | A two-key sequence | + +An unknown action name or an invalid keystroke is skipped with a warning in the +log rather than breaking the rest of your bindings. + +The full action list is on the [keyboard shortcuts](/reference/keyboard-shortcuts) +page. + +## The tmux preset + +**Settings → Keybindings → Preset → tmux** remaps pane and tab actions onto a +prefix — ⌃ B by default, changeable in the **Prefix** field beside +it. + +| | | +|---|---| +| ⌃ B C · X | New tab · close tab | +| ⌃ B % · " | Split right · split down | +| ⌃ B ←→↑↓ | Move focus | +| ⌃ B ⌃ ←→↑↓ | Resize the pane | +| ⌃ B O · ; | Next pane · previous pane | +| ⌃ B { · } | Swap with the previous · next pane | +| ⌃ B Z | Zoom the pane | +| ⌃ B N · P | Next tab · previous tab | +| ⌃ B 19 | Jump to a tab | + +Two details that make it livable: + +- A **bare prefix** reaches the shell after about a second, so ⌃ B + still works as "back one character" when you meant it. +- **Prefix plus an unbound key** is passed straight through to the terminal, so + a tmux binding you did not remap still lands in whatever is running. + +## Some non-obvious defaults + +| | | +|---|---| +| ⇧ ⏎ · ⌥ ⏎ | Insert a newline at the prompt instead of submitting (`InsertNewline`) | +| ⌘ ⇧ ⏎ | Zoom the focused pane | +| ⌘ ⇧ E | Toggle the code panel | +| ⌘ ⇧ R | Restart the SSH session in this pane | +| ⌘ ⇧ O | Workspace switcher | +| ⌘ ⇧ N | New workspace | diff --git a/docs/customization/settings.mdx b/docs/customization/settings.mdx new file mode 100644 index 00000000..a260f6eb --- /dev/null +++ b/docs/customization/settings.mdx @@ -0,0 +1,86 @@ +--- +title: "Settings" +description: "What lives in each section, and how the settings file works." +--- + +⌘ , opens Settings. There is a search box at the top that matches +setting names *and* keywords, which is usually faster than remembering which +section something is in. + + + tty7 Settings + + +## The eight sections + + + + Theme, sync with system, typography, cursor, transparency, language. + + + Shell and start directory, scrollback and scrolling, mouse, bell, per-pane + history. + + + Prompt features, selection & clipboard, keyboard (Option as Meta), links. + + + Hosts, defaults, security, and every per-profile field. + + + Hook installation per agent and per machine, the orchestration skill, the + CLI on PATH. + + + Startup window, tab bar position and grouping, notifications, tray icon. + + + Every shortcut, the tmux preset, the prefix. + + + Version, update channel, and the updater. + + + +## The settings file + +Everything the Settings window writes goes to one file: + +| | | +|---|---| +| macOS / Linux | `~/.config/tty7/config.json` | +| Windows | `%APPDATA%\tty7\config.json` | + +Set `TTY7_CONFIG_DIR` to point the whole directory — config, themes, state — +somewhere else. + +You can edit the file by hand; a handful of options exist only there. See the +[configuration reference](/reference/configuration) for every key, its type, and +its default. + +### How it handles mistakes + +The file is written atomically, and read forgivingly: + +- **A missing key** means the default — you only have to write what you change. +- **An out-of-range number** is clamped into its band, not rejected. +- **An unrecognised enum value** falls back to the default with a log line, + rather than failing the whole file. +- **An unparseable file** is not overwritten. tty7 starts on defaults, keeps a + copy at `config.json.corrupt`, and says so in the log. + + + A UTF-8 BOM at the start of the file is tolerated, which matters if you edited + it in a Windows editor. + + +## Language + +**Settings → Appearance → Language** switches the interface between English, +简体中文, and 日本語. The choice is explicit — the system language is never +inferred — and CLI output stays English regardless, so agent and script +integrations keep a stable surface. + +```json +{ "gui_language": "zh-CN" } +``` diff --git a/docs/customization/themes.mdx b/docs/customization/themes.mdx new file mode 100644 index 00000000..06774279 --- /dev/null +++ b/docs/customization/themes.mdx @@ -0,0 +1,113 @@ +--- +title: "Themes" +description: "Nine built-ins, your own YAML themes, iTerm2 imports, and a colour editor." +--- + +**Settings → Appearance → Theme** — or **Change Theme…** in the command +palette — opens the theme picker. + +## Built in + +| Light | Dark | +|---|---| +| Light *(default)* · One Light · Catppuccin Latte · Rosé Pine Dawn | Dark · Dracula · Harbor · One Dark Pro · Rosé Pine | + + + The tty7 theme picker + + +## Following the system + +Turn on **Sync with system** and pick a theme for each appearance. tty7 follows +the OS live — no restart, no reload. + +```json +{ + "theme_follow_system": true, + "theme_preset_light": "one_light", + "theme_preset_dark": "dracula" +} +``` + +## Legible bright colours + +Some palettes put a bright ANSI colour so close to their own background that it +disappears. **Legible bright colors** (on by default) brightens or darkens those +just enough to be readable. Turn it off with `theme_legible_palette: false` if +you want the palette exactly as authored. + +## Transparency + +**Settings → Appearance → Transparency**: + +| | | +|---|---| +| **Opacity** | 0.2–1.0, applied to every theme. *Follow theme* hands the decision back to the theme's own `opacity`. | +| **Blur** | Blurs whatever is behind a translucent window (macOS). | +| **Background material** | Windows only: *Auto*, *Blur*, *Mica*, *Mica Alt*, *Acrylic*, *Off*. Only the presets your Windows build supports are listed. | + +## Writing your own + +**Open themes folder** in Settings takes you to: + +| | | +|---|---| +| macOS / Linux | `~/.config/tty7/themes/` | +| Windows | `%APPDATA%\tty7\themes\` | + +Drop a `.yaml` file in and it appears in the picker. The file name is the +theme's id; `name` is what is shown. + +```yaml +name: "Midnight" +background: "#0d1117" +foreground: "#c9d1d9" +accent: "#3fdd8c" +cursor: "#3fdd8c" +selection: "#264f78" +opacity: 0.95 +blur: true +ansi: + normal: ["#484f58", "#ff7b72", "#3fb950", "#d29922", "#58a6ff", "#bc8cff", "#39c5cf", "#b1bac4"] + bright: ["#6e7681", "#ffa198", "#56d364", "#e3b341", "#79c0ff", "#d2a8ff", "#56d4dd", "#f0f6fc"] +``` + +Everything except `background`, `foreground`, `accent`, and `ansi` is optional. + +### Gradients and images + +`background` also takes two colours: + +```yaml +background: { top: "#0d1117", bottom: "#161b22" } +# or +background: { left: "#0d1117", right: "#161b22" } +``` + +And a theme can carry an image behind the terminal: + +```yaml +background_image: + path: "/Users/me/Pictures/wall.jpg" + opacity: 0.25 +``` + +The Settings panel has a picker for both, so you rarely have to write this by +hand. + +## Editing in the app + +Select a built-in theme and hit **Duplicate to edit** — built-ins are read-only, +so the editor works on your copy. From there you get every colour, including the +sixteen ANSI slots, plus the background image controls. Changes are written back +to your themes folder as YAML. + +## Importing from iTerm2 + +Drop an `.itermcolors` file into the themes folder and tty7 reads it directly — +no conversion step. + + + A theme file tty7 could not load is listed in Settings under **Not loaded from + the themes folder**, with the reason, rather than silently ignored. + diff --git a/docs/docs.json b/docs/docs.json new file mode 100644 index 00000000..762af9e8 --- /dev/null +++ b/docs/docs.json @@ -0,0 +1,142 @@ +{ + "$schema": "https://mintlify.com/docs.json", + "theme": "mint", + "name": "tty7", + "description": "A terminal workbench: persistent sessions, remote work, agents.", + "colors": { + "primary": "#0FA968", + "light": "#3FDD8C", + "dark": "#0FA968" + }, + "favicon": "/favicon.ico", + "logo": { + "light": "/logo/logo.svg", + "dark": "/logo/logo.svg", + "href": "https://github.com/l0ng-ai/tty7" + }, + "navigation": { + "tabs": [ + { + "tab": "Documentation", + "groups": [ + { + "group": "Getting started", + "pages": [ + "index", + "getting-started/installation", + "getting-started/first-launch", + "getting-started/concepts" + ] + }, + { + "group": "The window", + "pages": [ + "window/tabs-and-splits", + "window/sidebar", + "window/command-palette", + "window/search", + "window/side-panel" + ] + }, + { + "group": "The terminal", + "pages": [ + "terminal/prompt", + "terminal/history", + "terminal/selection-and-clipboard", + "terminal/links", + "terminal/mouse-and-scrolling" + ] + }, + { + "group": "Coding agents", + "pages": [ + "agents/overview", + "agents/status", + "agents/sessions", + "agents/orchestration" + ] + }, + { + "group": "Remote work", + "pages": [ + "remote/ssh", + "remote/sftp", + "remote/port-forwarding", + "remote/workspaces" + ] + }, + { + "group": "Git", + "pages": [ + "git/source-control", + "git/diffs", + "git/worktrees" + ] + }, + { + "group": "Customization", + "pages": [ + "customization/settings", + "customization/themes", + "customization/fonts", + "customization/keybindings" + ] + } + ] + }, + { + "tab": "CLI", + "groups": [ + { + "group": "The tty7 command", + "pages": [ + "cli/overview", + "cli/reference", + "cli/agent-skill" + ] + } + ] + }, + { + "tab": "Reference", + "groups": [ + { + "group": "Reference", + "pages": [ + "reference/configuration", + "reference/keyboard-shortcuts", + "reference/shell-integration", + "reference/updates", + "reference/privacy", + "reference/troubleshooting" + ] + } + ] + } + ] + }, + "navbar": { + "links": [ + { + "label": "GitHub", + "href": "https://github.com/l0ng-ai/tty7" + }, + { + "label": "Discord", + "href": "https://discord.gg/s3dethqz2V" + } + ], + "primary": { + "type": "button", + "label": "Download", + "href": "https://github.com/l0ng-ai/tty7/releases" + } + }, + "footer": { + "socials": { + "github": "https://github.com/l0ng-ai/tty7", + "discord": "https://discord.gg/s3dethqz2V" + } + } +} diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f4cbfc6dde0c123ea941be5fe73f7ea9cf8866cd GIT binary patch literal 13679 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 literal 0 HcmV?d00001 diff --git a/docs/features.md b/docs/features.md deleted file mode 100644 index 7310b805..00000000 --- a/docs/features.md +++ /dev/null @@ -1,158 +0,0 @@ -# Features - -English · [简体中文](features.zh-CN.md) - -## Input - -- **Ghost suggestions** — your history completes the whole line as you type; to accept -- **Explained tab completion** — every flag and subcommand with its description, for ~100 common commands; when tty7 has nothing to offer the Tab falls through to your shell's own completion, and the whole feature can be turned off (Settings → Input → Prompt, or `tab_completion` in `config.json`) -- **Syntax highlighting** — as you type, nothing to install -- **Fuzzy history search** — ⌃ R shows what you ran, where, and whether it failed; turn it off (Settings → Input → Prompt, or `history_search` in `config.json`) and ⌃ R goes to your shell instead, so an fzf / percol binding keeps working -- **History from day one** — your existing shell history works as-is and carries across sessions -- **Line editing** — click to place the caret, mouse selection, word motion, undo -- **Multi-line editing** — wrapped and multi-line commands edit in place; the grid shifts to keep the caret visible. ⇧ ⏎ · ⌥ ⏎ insert a newline instead of submitting (rebindable as `InsertNewline`); a plain submits the whole buffer - -## In the window - -- **Tabs & splits** — always open in the current directory -- **Rearrange splits by dragging** — hover a pane and a small grip appears along its top edge; drag it over the layout to put the pane somewhere else in the tab. Dropping on a pane's side goes in beside it — taking an equal share of the row or column it joins, or splitting that pane in half when the side faces across the layout rather than along it — dropping on its middle trades the two panes' places, and carrying it past a pane's outer side — the one facing the window rather than another pane — makes it a full-width or full-height band beside everything else, sized to an even share of what that side already holds — so a pane in the middle of a 2×2 becomes a full-height third column in one drag. The landing lights up while you drag, and only ever lights up when the drop would really change the layout -- **Repo-grouped sidebar** — the left tab sidebar groups rows under a header per git repository, non-repo tabs in a trailing *Scratch* section; branch switches and in-repo `cd`s never move a row (`sidebar_grouping` in `config.json`: `repo` default, `none` for a flat list) -- **Command palette** ⌘ P · scrollback search ⌘ F -- **⌘/Ctrl-click links** (⌘ on macOS, Ctrl on Windows/Linux) · desktop notifications · copy on select (opt-in, Settings → Input → Selection & clipboard) -- **Smart double-click selection** — double-click grabs the whole URL, file path, bracket/quote pair, or dictionary-segmented CJK word under the cursor; Shift-click extends a selection (toggle in Settings → Input → Selection & clipboard; word separators via `word_separators` in `config.json`) -- **Nine themes, plus your own** — YAML seed themes with solid, gradient, or image backgrounds; iTerm2 `.itermcolors` import; in-app color editor with a background-image picker -- **Sync with system** — Settings → Appearance; pick separate light and dark themes and tty7 follows the OS appearance live (`theme_follow_system`, `theme_preset_light` / `theme_preset_dark` in `config.json`) -- **Window opacity & blur** — Settings → Appearance → Transparency; applies to every theme, *Follow theme* returns to the theme's own `opacity` / `blur` -- **CJK / IME input** -- **Windows Explorer menu** — the installer offers *Add “Open in tty7” to the folder context menu* as a setup task, off by default, and the uninstaller always takes it back out. Writing shell verbs is an install-time decision, so there is no runtime setting; a portable-zip install can do it itself with `tty7-app.exe --register-explorer-menu` (or `--unregister-explorer-menu`). Either way the keys land under `HKCU`, so only your own Windows account is affected - -## Fonts - -- **Hack is bundled** — it ships inside the binary, so the default renders identically everywhere without relying on a system install -- **Primary + ordered fallbacks** — `font_family` and `font_fallbacks` in `config.json`; optional `font_family_bold` / `font_family_italic` for distinct faces, and `font_features` to pass OpenType features through (contextual ligatures stay off unless you ask for them) -- **Platform-aware defaults** — the fallback list names faces the host OS actually ships (PingFang SC / Apple Color Emoji on macOS, Microsoft YaHei / Segoe UI Emoji on Windows, Noto on Linux). Those stock names are appended to a hand-written list too, so a `config.json` written on another platform still resolves - -### CJK and the two-column grid - -A cell is one advance of the primary face, and a wide (CJK) character is pinned -to exactly two of them. A CJK fallback therefore sits flush in its slot only if -its ideographs advance **twice** the primary's Latin advance. - -Bundled Hack advances 0.60205em, so a two-column slot is 1.2041em — while every -stock CJK face (Microsoft YaHei, PingFang SC, Noto Sans CJK) advances 1.0em. -Those glyphs get left-aligned in the slot and the leftover ~0.2em lands as a gap -on the right of every character. - -[Maple Mono NF CN](https://github.com/subframe7536/maple-font) is tried first on -every platform for exactly this reason — 0.6em Latin, 1.2em CJK, an exact -two-cell fit against Hack. It is referenced by name only, never bundled (~20MB -per weight): install it and tty7 picks it up with no config change. - -For CJK set *tight* rather than merely even, change the primary face instead — -one that advances 0.5em (Sarasa Mono SC, say) makes two columns exactly 1.0em. - -## Coding agents - -tty7 recognizes third-party coding agents running in a pane (Claude Code, -Codex, Gemini CLI, Aider, Amp, OpenCode, and 12 more) and adds around them — -it never wraps or replaces the agent. - -- **Brand avatars** — the tab chip / sidebar row shows which agent runs where; custom wrappers map in via `agent_commands` in `config.json` -- **Status dot** — working (blue) / needs your input (amber) / done (green), driven by agent-reported events over an OSC channel; Settings → Agents installs the hooks that feed it (Claude Code, Codex, Copilot CLI, OpenCode, Pi, Grok Build, Oh My Pi) -- **Notifications** — "needs your permission…" the moment an agent blocks on you, and "finished after Ns" per turn, honoring your notification policy -- **Branch at a glance** — each sidebar row shows its pane's git branch and working-tree diff (`+N −M`), refreshed on `cd` and when a command finishes; clicking the counts opens the diff overlay, and turning that off (Settings → Window & Tabs, or `sidebar_diff_preview: false` in `config.json`) keeps the readout while making it non-clickable -- **Session resume** — panes lost to a reboot re-launch their agent conversation on restore, carrying the original launch flags (`claude --dangerously-skip-permissions --resume …`) (`restore_agent_sessions`, on by default) -- **Fork session** — branch a live agent conversation into a second, independent one by shelling the agent's own fork command (`codex fork `, `claude --resume --fork-session`, also OpenCode, Grok Build, and Oh My Pi); the original is untouched and both continue separately. Right-click a pane to pick a split placement, or right-click the tab / sidebar row to open the fork in a new tab. Needs the agent's hooks installed, since the fork targets the session id they report; a remote pane can't fork, because the command would run against the local agent — and note a fork copies the whole transcript, so repeated forking costs real disk in the agent's own session store -- **Copy Session ID** — put the agent's native session id on the clipboard, beside *Copy Working Directory*, for pasting into `codex resume`, a bug report, or another tool -- **Context feed** — palette commands send the current selection or the repo's `git diff` to the running agent as a ready-made prompt -- **Tray icon** — a system tray / menu bar item that flips to an attention state the moment any agent needs your input; its menu lists every agent pane (brand avatar + status dot, click to reveal), switches the notification policy, and offers *Quit and Stop Server…* alongside the plain session-keeping quit (`show_tray_icon`, on by default) -- **`tty7 wait`** — the CLI's orchestration primitive: block until a pane's agent needs input or finishes its turn (`tty7 wait %3 --until waiting,done --changed --timeout 600`, exit 124 on timeout), so one agent can sleep until its peer blocks on a permission prompt instead of screen-scraping — then `tty7 capture %3 --plain` to read the result. The agent status is a level, not an event, so `--changed` ignores the state the pane was already in when the wait began; without it, the JSON's `stale` flag says whether the answer might belong to the previous turn -- **`tty7` on PATH** — the CLI ships inside every installer and is put on PATH at launch, so a script or a coding agent can drive tty7 from any terminal. Inside a tty7 pane it works regardless, since panes inherit the app's environment. On Unix it is a symlink into whichever of `/opt/homebrew/bin`, `/usr/local/bin`, `~/.local/bin`, `~/bin`, `~/.cargo/bin` your PATH already covers; on Windows the install directory is appended to your user PATH, and the uninstaller takes it back out. A `tty7` you installed yourself is left alone, never replaced. Off via Settings → Agents or `install_cli_on_path: false` in `config.json` - -## SSH - -A native Rust SSH stack (russh) is the **only** path — profiles, credentials, -and SFTP without shelling out to `ssh`. There is no system-ssh compat mode. - -- **QuickConnect** — type `user@host[:port]` in the palette and connect; IPv6 `[::1]:port` supported -- **Saved profiles** — full connection config with passwords / passphrases in the OS keychain, never on disk -- **`~/.ssh/config` aliases** — type one to connect (resolved natively — common fields, best-effort — over russh), or import them as profiles in Settings -- **GUI auth** — in-pane sheets for password, key passphrase, 2FA, and host-key confirmation (new vs. changed) -- **Built-in SFTP** — a slide-in file panel: browse, upload / download, rename / delete / chmod, drag to Finder -- **Port forwarding** — Local / Remote / Dynamic, preconfigured or added live, plus ⌘/Ctrl-click `localhost:PORT` to auto-forward -- **Jump hosts & proxies** — multi-hop via profile references or `ProxyJump`, ProxyCommand, SOCKS5 / HTTP - -| Entry point | Connects via | -|---|---| -| Saved profiles · QuickConnect · typed `user@host[:port]` | Native russh — SFTP · keychain · GUI auth · L/R/D forwards | -| `~/.ssh/config` aliases | Resolved natively, then russh (`Match`/canonicalize/GSSAPI unsupported — no fallback) | - -## Keybindings - -Keys are shown in macOS notation — on Windows and Linux, read as -Ctrl. The essentials: - -| | | -|---|---| -| ⌘ T · ⌘ W · ⌘ ⇧ T | new tab · close tab · reopen closed tab | -| ⌘ 1⌘ 9 | jump to tab 1–9 | -| ⌃ ⇥ · ⌃ ⇧ ⇥ | hold to walk the switcher forwards · backwards; it commits when you let go | -| ⌘ D · ⌘ ⇧ D | split right · split down | -| ⌘ ] · ⌘ [ | next pane · previous pane | -| ⌘ ⌥ ←→↑↓ | focus the pane in that direction | -| ⌘ ⏎ · ⌘ ⇧ ⏎ | toggle fullscreen · zoom pane | -| ⌘ K | clear scrollback | -| ⌘ P | command palette | -| ⌘ F | search the scrollback | -| ⌃ R | fuzzy-search shell history | -| ⌘ + · ⌘ − · ⌘ 0 | font size up · down · reset | -| + wheel | zoom the font by scrolling over a terminal | - -**Settings → Keybindings** (⌘ ,) lists every shortcut. Click one, -press the new keys (Esc cancels, Backspace resets to -default), and it takes effect immediately. Pane resize and swap have no default -keys — bind them here or run them from the command palette. - -**tmux preset** — remaps pane/tab actions onto a prefix (default ⌃ B): -⌃ B C opens a tab, ⌃ B % splits, -⌃ B then an arrow moves focus. A bare prefix reaches the shell after -a brief pause; `prefix` + an unbound key passes straight through. - -## Performance notes - -- The PTY is read at device speed and parsed in large batches, off the render path -- Hot paths are lock-free — a big `cat` never waits on drawing -- The server buffers up to 16 MiB ahead of the window before backpressure applies - -## macOS privacy - -Panes are forked from the bundled executable, so macOS attributes a program's -request for a protected resource to tty7.app. tty7 declares the matching TCC -usage strings (camera, microphone, contacts, calendar, reminders, photos, -location, local network, Bluetooth, speech recognition, Apple Events, system -administration) so that program gets the normal one-time prompt instead of -being denied outright with no prompt at all. - -Not covered by usage strings: - -- **Full Disk Access** — Apple defines no usage-string key for it. Reaching - `~/Library/Mail`, `~/Library/Messages`, `~/Library/Safari` or - `~/Library/Containers` needs a manual grant in System Settings. - -Declaring a usage string is not the same as holding the permission: tty7.app -itself is granted none of these resources. Every prompt you see belongs to -whatever you ran in the pane, and you can revoke it under Privacy & Security. - -## Localization - -The GUI ships English, Simplified Chinese and Japanese strings. Pick one in -Settings → Appearance → Language, or in `config.json`: - -```json -{ "gui_language": "zh-CN" } -``` - -`en`, `zh-CN` and `ja-JP` are the only accepted values; anything else falls back -to `en`. -The choice is explicit — the system language is never inferred. CLI output stays -English so agent and script integrations keep a stable, predictable surface. diff --git a/docs/features.zh-CN.md b/docs/features.zh-CN.md deleted file mode 100644 index abeda9e7..00000000 --- a/docs/features.zh-CN.md +++ /dev/null @@ -1,150 +0,0 @@ -# 功能 - -[English](features.md) · 简体中文 - -## 输入 - -- **影子建议** —— 边打字边用你的历史补全整条命令, 接受 -- **带说明的 Tab 补全** —— 每个 flag、每个子命令都带说明,覆盖约 100 个常用命令;tty7 没有候选时 Tab 自动交给 shell 自己的补全,整个功能也可关闭(设置 → 输入 → 提示符,或 `config.json` 里的 `tab_completion`) -- **语法高亮** —— 边打边亮,什么都不用装 -- **模糊历史搜索** —— ⌃ R 看到每条命令在哪跑的、什么时候、有没有失败;关掉它(设置 → 输入 → 提示符,或 `config.json` 里的 `history_search`)后 ⌃ R 直接交给 shell,你绑的 fzf / percol 照常可用 -- **历史开箱即用** —— 你已有的 shell 历史直接生效,并跨会话延续 -- **行编辑** —— 点击定位光标、鼠标选区、词级移动、撤销 -- **多行编辑** —— 折行和多行命令原地编辑;网格自动上移,光标始终可见。⇧ ⏎ · ⌥ ⏎ 插入换行而不提交(可改绑,动作名 `InsertNewline`),单独按 提交整个缓冲区 - -## 窗口 - -- **标签页与分屏** —— 永远开在当前目录 -- **拖动重排分屏** —— 鼠标移到某个 pane 上,它顶边中间会浮出一个小抓手;拖着它在布局里走,就能把这个 pane 挪到标签页内的别处。落在某个 pane 的某一侧=插到它旁边:那一侧要是朝着同一排的邻居,就并入那一排、和它们等分;要是横着切过这一排(没有排可并),才是把那个 pane 一分为二、自己占住那一半。落在它正中=两个 pane 互换位置;继续推到某个 pane 朝着窗口那一侧的外缘(不是朝着另一个 pane 的那侧)=变成贴着窗口某一边、跨满整行或整列的一条,宽度按那条轴上已有的份数均分 —— 2×2 里的一个 pane 一次拖动就能变成通高的第三列(各占三分之一),而不是独占半屏。拖动过程中落点会高亮,且只有当这一放确实会改变布局时才会亮 -- **侧栏按仓库分组** —— 左侧标签栏按 git 仓库分组、每组一个标题行,不在仓库里的标签归入末尾的 *草稿* 组;切分支、仓库内 `cd` 都不会挪动行(`config.json` 的 `sidebar_grouping`:默认 `repo`,`none` 恢复扁平列表) -- **命令面板** ⌘ P · scrollback 搜索 ⌘ F -- **⌘ 点击打开链接** · 桌面通知 · 划选即复制(可选,设置 → 输入 → 选择与剪贴板) -- **智能双击选中** —— 双击直接选中整条 URL、文件路径、括号/引号对,中文按词典分词出词;Shift 点击扩展选区(设置 → 输入 → 选择与剪贴板可开关;分隔符用 `config.json` 的 `word_separators` 配置) -- **9 套主题,也能自定义** — YAML 种子主题,背景支持纯色、渐变或图片;可导入 iTerm2 `.itermcolors`;应用内颜色编辑器带背景图选择 -- **跟随系统外观** — 设置 → 外观;分别选好浅色和深色主题,tty7 随系统深浅模式实时切换(`config.json` 中的 `theme_follow_system`、`theme_preset_light` / `theme_preset_dark`) -- **窗口透明与模糊** — 设置 → 外观 → 透明度;对所有主题生效,*跟随主题* 恢复主题自带的 `opacity` / `blur` -- **CJK / 输入法输入** -- **Windows 资源管理器右键菜单** —— 安装程序提供 *Add “Open in tty7” to the folder context menu* 这个安装任务,默认不勾选,卸载时一律移除。写 shell verb 是安装期的决定,所以没有运行时开关;用 portable zip 的话可以自己执行 `tty7-app.exe --register-explorer-menu`(或 `--unregister-explorer-menu`)。两种方式写入的键都在 `HKCU` 下,只影响你自己的 Windows 账户 - -## 字体 - -- **内置 Hack** —— 打包进二进制,默认配置在各平台渲染完全一致,不依赖系统安装 -- **主字体 + 有序 fallback** —— `config.json` 里的 `font_family` 和 `font_fallbacks`;可选 `font_family_bold` / `font_family_italic` 指定独立字面,`font_features` 透传 OpenType 特性(上下文连字默认关闭) -- **默认列表按平台分支** —— fallback 只写宿主系统真正自带的字体(macOS 用 PingFang SC / Apple Color Emoji,Windows 用 Microsoft YaHei / Segoe UI Emoji,Linux 用 Noto)。这些名字也会追加到你手写的列表后面,所以在别的平台写出来的 `config.json` 一样能落地 - -### 中文与两列网格 - -一个格子等于主字体的一个 advance,宽字符(CJK)被钉死在正好两格上。所以中文 -fallback 只有在**汉字 advance 等于主字体西文 advance 的两倍**时,才能严丝合缝地 -填满自己的槽。 - -内置 Hack 的 advance 是 0.60205em,两格就是 1.2041em —— 而系统自带的中文字体 -(Microsoft YaHei、PingFang SC、Noto Sans CJK)全都是 1.0em。这些字形在槽里左 -对齐,多出来的约 0.2em 就变成每个字右边的一道空隙。 - -[Maple Mono NF CN](https://github.com/subframe7536/maple-font) 在所有平台都排在 -第一位正是因为这个 —— 西文 0.6em、中文 1.2em,对上 Hack 正好两格。它只按名字引 -用,不打包(每字重约 20MB):装上即生效,不用改配置。 - -想让中文排得**紧**而不只是均匀,要换的是主字体:选一个 advance 为 0.5em 的 -(比如 Sarasa Mono SC 更纱黑体等宽),两格就正好 1.0em。 - -## Coding agent - -tty7 能识别 pane 里跑着的第三方 coding agent(Claude Code、Codex、Gemini CLI、 -Aider、Amp、OpenCode 等共 18 个)并在其外围加功能 —— 绝不包裹或替代 agent 本身。 - -- **品牌头像** —— 标签 chip / 侧栏行显示每个 pane 跑的是哪个 agent;自定义包装命令可通过 `config.json` 的 `agent_commands` 映射 -- **状态点** —— 工作中(蓝)/ 等你输入(琥珀)/ 完成(绿),由 agent 自己上报的 OSC 事件驱动;在 设置 → Agents 一键装好对应 hooks(Claude Code、Codex、Copilot CLI、OpenCode、Pi、Grok Build、Oh My Pi) -- **通知** —— agent 卡在等你批准的那一刻弹 "needs your permission…",每轮结束弹 "finished after Ns",遵循你的通知策略 -- **一眼看分支** —— 侧栏每行显示该 pane 的 git 分支和工作区改动(`+N −M`),`cd` 或命令跑完时自动刷新;点改动数字会打开 diff 浮层,关掉它(设置 → 窗口与标签页,或 `config.json` 的 `sidebar_diff_preview: false`)分支和数字照常显示,只是不再可点 -- **会话恢复** —— 重启后无法重连的 pane 会自动续上 agent 对话,并带上原始启动 flags(`claude --dangerously-skip-permissions --resume …`;`restore_agent_sessions`,默认开启) -- **Fork 会话** —— 直接调 agent 自己的 fork 命令(`codex fork `、`claude --resume --fork-session`,OpenCode、Grok Build 和 Oh My Pi 同样支持),把当前对话分叉成一个独立会话;原会话原封不动,两边各自往下走。在 pane 上右键可选择分屏位置,在标签 / 侧栏行上右键则直接开新标签。需要先装好该 agent 的 hooks(fork 认的是 hooks 上报的 session id);远程 pane 不能 fork,因为命令会跑在本机的 agent 上;另外 fork 会整份复制对话历史,反复 fork 会在 agent 自己的会话目录里占掉不少磁盘 -- **复制会话 ID** —— 把 agent 的原生 session id 复制到剪贴板,就在 *复制工作目录* 旁边,方便粘进 `codex resume`、bug 报告或别的工具 -- **上下文回填** —— 面板命令把当前选区或仓库 `git diff` 打包成 prompt 直接喂给正在跑的 agent -- **托盘图标** —— 系统托盘 / 菜单栏常驻图标,任何 agent 等你输入时立即切换为提醒态;菜单列出所有 agent pane(品牌头像 + 状态点,点击直达)、可切换通知策略,并在保留会话的普通退出之外提供 *退出并停止服务器…*(`show_tray_icon`,默认开启) -- **`tty7 wait`** —— CLI 的编排原语:阻塞到某个 pane 的 agent 等待输入或完成一轮(`tty7 wait %3 --until waiting,done --changed --timeout 600`,超时退出码 124),让一个 agent 睡到同伴卡在权限确认的那一刻,而不是抓屏猜——然后 `tty7 capture %3 --plain` 收结果。agent 状态是电平不是边沿,所以 `--changed` 会忽略 wait 开始时 pane 本来就处在的那个状态;不加它的话,JSON 里的 `stale` 标记会告诉你这个答案是不是上一轮留下的 -- **`tty7` 上 PATH** —— CLI 随每个安装包一起发布,启动时自动放到 PATH 上,脚本和 coding agent 在任何终端里都能驱动 tty7。tty7 自己的 pane 里则一定可用,因为 pane 继承 app 的环境。Unix 上是往 `/opt/homebrew/bin`、`/usr/local/bin`、`~/.local/bin`、`~/bin`、`~/.cargo/bin` 中你 PATH 已经覆盖的那个目录里放一个软链;Windows 上是把安装目录追加到用户 PATH,卸载时再摘掉。你自己装的 `tty7` 一律保持原样,不会被覆盖。关掉:设置 → Agents,或 `config.json` 里 `install_cli_on_path: false` - -## SSH - -**唯一**路径就是原生 Rust SSH 栈(russh)—— profile、凭据、SFTP 全部内置, -不 shell 出 `ssh`,也没有系统 ssh 兼容模式。 - -- **QuickConnect** —— 面板里打 `user@host[:port]` 回车即连;支持 IPv6 `[::1]:port` -- **保存 profile** —— 完整连接配置,密码 / passphrase 进 OS keychain,不落盘 -- **`~/.ssh/config` alias** —— 直接输入 alias 即连(原生解析常用字段,尽力而为,走 russh),也可在设置页一键导入为 profile -- **GUI 认证** —— pane 内 sheet 输入密码、私钥 passphrase、2FA,并确认主机密钥(新主机 vs 已变更) -- **内置 SFTP** —— 滑入式文件面板:浏览、上传 / 下载、重命名 / 删除 / chmod,可拖进 Finder -- **端口转发** —— Local / Remote / Dynamic,预配置或运行时增删,外加 ⌘ 点击 `localhost:PORT` 一键转发 -- **跳板与代理** —— 经 profile 引用或 `ProxyJump` 多跳、ProxyCommand、SOCKS5 / HTTP - -| 入口 | 连接方式 | -|---|---| -| 保存 profile · QuickConnect · 输入 `user@host[:port]` | 原生 russh —— SFTP · keychain · GUI 认证 · L/R/D 转发 | -| `~/.ssh/config` alias | 原生解析后走 russh(`Match`/canonicalize/GSSAPI 不支持,且无回退) | - -## 快捷键 - -下表按 macOS 记法书写 —— 在 Windows 和 Linux 上,把 读作 -Ctrl。最常用的几个: - -| | | -|---|---| -| ⌘ T · ⌘ W · ⌘ ⇧ T | 新建标签页 · 关闭标签页 · 恢复关闭的标签页 | -| ⌘ 1⌘ 9 | 跳到第 1–9 个标签页 | -| ⌃ ⇥ · ⌃ ⇧ ⇥ | 按住不放在切换面板里向后 · 向前走,松手即切换 | -| ⌘ D · ⌘ ⇧ D | 向右分屏 · 向下分屏 | -| ⌘ ] · ⌘ [ | 下一个窗格 · 上一个窗格 | -| ⌘ ⌥ ←→↑↓ | 按方向切换焦点窗格 | -| ⌘ ⏎ · ⌘ ⇧ ⏎ | 切换全屏 · 缩放窗格 | -| ⌘ K | 清除 scrollback | -| ⌘ P | 命令面板 | -| ⌘ F | 搜索 scrollback | -| ⌃ R | 模糊搜索 shell 历史 | -| ⌘ + · ⌘ − · ⌘ 0 | 字号增大 · 减小 · 重置 | -| + 滚轮 | 在终端上滚动缩放字号,演示时随手放大 | - -**设置 → 按键绑定**(⌘ ,)列出全部快捷键。点一行、按下新键即可 -(Esc 取消,Backspace 恢复默认),改完立即生效。窗格缩放与 -交换默认不绑定键 —— 在这里绑定,或从命令面板执行。 - -**tmux 预设** —— 把窗格/标签页操作映射到前缀键(默认 ⌃ B): -⌃ B C 新建标签页,⌃ B % 分屏, -⌃ B 接方向键切换焦点。单独按前缀键会在短暂延迟后送达 shell, -`前缀` + 未绑定的键原样透传给终端。 - -## 性能说明 - -- 以设备速度读取 PTY,在渲染路径之外成批解析 -- 热路径全程无锁 —— 再大的 `cat` 也不会阻塞在渲染上 -- 触发背压前,服务器最多可领先窗口缓冲 16 MiB - -## macOS 隐私 - -窗格是从 app bundle 里的可执行文件 fork 出来的,所以程序申请受保护资源时, -macOS 会把这次请求算到 tty7.app 头上。tty7 声明了对应的 TCC usage strings -(摄像头、麦克风、通讯录、日历、提醒、照片、定位、本地网络、蓝牙、语音识别、 -Apple Events、系统管理),这样程序才能正常弹出一次性授权窗口,而不是连弹窗都 -没有就被直接拒绝。 - -不受 usage strings 覆盖的: - -- **完全磁盘访问** —— 苹果没有为它定义 usage-string 键。要读写 - `~/Library/Mail`、`~/Library/Messages`、`~/Library/Safari` 或 - `~/Library/Containers`,需要在「系统设置」中手动授权。 - -声明 usage string 不等于持有权限:tty7.app 自己一项都没有拿到。你看到的每个 -授权弹窗都属于你在窗格里运行的那个程序,也可以在「隐私与安全性」中撤销。 - -## 本地化 - -GUI 目前提供英文、简体中文和日文三套文案。在「设置 → 外观 → 语言」中选择,或直接改 -`config.json`: - -```json -{ "gui_language": "zh-CN" } -``` - -只接受 `en`、`zh-CN` 和 `ja-JP` 三个值,其它值一律回落到 `en`。语言必须显式指定,不会 -去猜系统语言。CLI 输出保持英文,保证 agent、脚本和开发者工作流的输出稳定可预测。 diff --git a/docs/getting-started/concepts.mdx b/docs/getting-started/concepts.mdx new file mode 100644 index 00000000..1f6bb2ec --- /dev/null +++ b/docs/getting-started/concepts.mdx @@ -0,0 +1,108 @@ +--- +title: "Core concepts" +description: "Workspaces, tabs, panes — and the background server that owns them all." +--- + +Four words explain most of tty7. Three of them you can see; the fourth is the +reason the other three survive a reboot. + +## Pane + +A **pane** is one terminal: one shell (or one program) attached to one PTY. It +is the only thing in tty7 that actually runs something. + +Panes have stable ids — `%42` — for their whole life. That id is what the +[CLI](/cli/overview) addresses, and what `$TTY7_PANE` holds inside the pane +itself. + +## Tab + +A **tab** is a layout of panes. One pane to start with; split it and the tab +holds two, arranged in rows and columns you can drag around. + +Tabs appear in the sidebar (or the top strip, if you move it there). A tab's +label is the best evidence tty7 has: a name you set, else the coding agent +running in it, else the last segment of its working directory. + +## Workspace + +A **workspace** is a named set of tabs — a project, usually. One window shows +one workspace at a time, and ⌘ ⇧ O opens the switcher to move between +them or open a second window on another one. + +Workspaces are how tty7 keeps ten repositories from becoming forty +indistinguishable tabs. They also travel: a workspace on a remote machine is +still a workspace, opened from the same switcher. + + + The tty7 workspace switcher + + +## The server + +Here is the part that matters. **The window does not own your shells — a +background server does.** + +Quitting tty7 closes the window and leaves that server running. Your build keeps +building, your agent keeps working, your SSH session stays up. Open tty7 again +and it reattaches to exactly what was there. + +This is also why: + +- **`tty7` works from any terminal.** The CLI talks to the same server. The GUI + does not have to be running at all. +- **A crash is not a catastrophe.** Panes come back showing what was on them: + a capped tail of each pane's output is kept on disk and handed to the pane + that reopens on its id. +- **Stopping is explicit.** *Quit and Stop Server…* in the tray menu is the only + ordinary way to end everything, and it warns you first. + + + Restarting the server ends every process in every pane on that machine — + shells, agents, and SSH sessions alike. Layouts are kept and come back with + fresh shells. Never do it on someone else's behalf without asking. + + +### What survives what + +| | Close a tab | Quit tty7 | Stop the server | Reboot | +|---|:--:|:--:|:--:|:--:| +| The shell keeps running | ✗ | ✓ | ✗ | ✗ | +| The layout comes back | ✗ | ✓ | ✓ | ✓ | +| What was on screen comes back | ✗ | ✓ | ✓ | ✓ 1 | +| A supported agent session resumes | ✗ | ✓ | ✓ | ✓ | + +1 A capped tail of each pane, restored once. See +[session restore](/reference/troubleshooting#panes-came-back-empty). + +## Machines + +Everything above exists per **machine**. Your laptop is one; a dev box you +connect to over SSH is another, with its own server, its own workspaces, and its +own panes. + +The switcher lists them together, and the CLI reaches them with `-m`: + +```bash +tty7 -m devbox ls +``` + +Remote panes run on the remote machine — the files, the repository, the git +data, and the process tree are all over there. +[Remote workspaces →](/remote/workspaces) + +## The three environment variables + +Every pane exports these, and anything you launch from one inherits them: + +| Variable | What it holds | +|---|---| +| `TTY7_PANE` | This pane's id — the default target of `tty7 split`, `send`, `capture`, `procs`. | +| `TTY7_WS` | This pane's workspace id. | +| `TTY7_CONFIG_DIR` | The config directory, which is how the CLI finds the right server. | + +`echo $TTY7_PANE` is the fastest way to tell whether you are inside tty7 at all. + + + Those ids are the whole interface. The CLI page starts there. + diff --git a/docs/getting-started/first-launch.mdx b/docs/getting-started/first-launch.mdx new file mode 100644 index 00000000..cb83ceb7 --- /dev/null +++ b/docs/getting-started/first-launch.mdx @@ -0,0 +1,126 @@ +--- +title: "First launch" +description: "The handful of settings worth changing before you start working." +--- + +Open tty7 and you get a window with one tab and one shell, and a tab sidebar +down the left. Everything below is optional — but these are the settings people +end up changing anyway, so they are worth five minutes now. + +Open Settings with ⌘ , (Ctrl , on Windows and Linux), or +from the command palette (⌘ P → *Settings*). + + + tty7 Settings + + +## 1. Pick a theme + +**Settings → Appearance → Theme.** Nine themes ship built in — Light, One Light, +Catppuccin Latte, Rosé Pine Dawn, Dark, Dracula, Harbor, One Dark Pro, and +Rosé Pine. The default is **Light**. + +Turn on **Sync with system** to pick a light theme and a dark theme separately; +tty7 then follows the OS appearance live. + +Transparency lives on the same page, under **Transparency** — opacity applies to +every theme, and *Follow theme* hands the decision back to the theme's own +setting. On Windows there is also a **Background material** picker (Mica, +Acrylic, and friends). + +[More about themes →](/customization/themes) + +## 2. Choose your shell + +**Settings → Terminal → Shell.** Leave **Program** empty to use the platform +default. Otherwise it takes an executable name on PATH or an absolute path +(`zsh`, `fish`, `pwsh`, `nu`, `/opt/homebrew/bin/bash`), plus space-separated +**Arguments** — `-l` for a login shell, say. + +**Start in** decides what a *fresh* shell opens in: tty7's launch directory +(the default), your home folder, or a fixed path. New tabs and splits keep +inheriting the active pane's directory either way. + +## 3. macOS only: decide what Option does + +**Settings → Input → Keyboard → Option (⌥) acts as Meta.** + +Off (the default), ⌥ B types `∫`, which is what macOS has always +done. On, it sends the escape chord shells expect, so ⌥ B moves back +a word and ⌥ ⌫ deletes one. Turn it on if you live in readline; +leave it off if you type accented characters. + +## 4. If you use coding agents, install the hooks + +**Settings → Agents.** tty7 detects 18 coding CLIs by process name on its own — +you get brand avatars and tab labels for free. The *status dots*, the "needs +your permission" notifications, and `tty7 wait` all need one more thing: a small +hook the agent calls to report what it is doing. + +Click **Install** next to Claude Code, Codex, Copilot CLI, OpenCode, Pi, Grok +Build, or Oh My Pi. It writes into that agent's own config directory and can be +removed from the same row. + +[More about agents →](/agents/status) + +## 5. Know what Quit does + +Plain **Quit** closes the window and leaves the background server running. +Your shells, builds, and agent turns keep going, and reopening tty7 reattaches +to them. + +To actually stop everything, use **Quit and Stop Server…** from the tray icon's +menu. It says so plainly before it does it: anything still running in your +shells is terminated, while your tabs and layout are kept and reopen with fresh +shells. + + + This is why there is no tmux in the picture. The persistence is not a feature + of your shell setup — it belongs to the server underneath. + [Core concepts →](/getting-started/concepts) + + +## 6. Tune the notifications + +**Settings → Window & Tabs → Notifications.** By default tty7 posts a desktop +notification when a foreground command that ran longer than 10 seconds +finishes — but only while the window is unfocused. Set **Notify on command +finish** to *Never* or *Always*, and move the threshold if 10 seconds is the +wrong number for your work. + +Agent notifications ("needs your permission…", "finished after 42s") follow the +same policy. + +## 7. Coming from tmux? + +**Settings → Keybindings → Preset → tmux** remaps pane and tab actions onto a +prefix, ⌃ B by default. ⌃ B C opens a tab, +⌃ B % splits, ⌃ B then an arrow moves focus. + +A bare prefix reaches the shell after about a second, and prefix plus an unbound +key passes straight through — so a tmux binding you did not remap still lands in +whatever is running. + +[More about keybindings →](/customization/keybindings) + +## Where things live + +| | macOS / Linux | Windows | +|---|---|---| +| Settings file | `~/.config/tty7/config.json` | `%APPDATA%\tty7\config.json` | +| Custom themes | `~/.config/tty7/themes/` | `%APPDATA%\tty7\themes\` | + +Everything in the Settings window writes to `config.json`, and you can edit it +by hand instead — see the [configuration reference](/reference/configuration). +Set `TTY7_CONFIG_DIR` to move the whole directory somewhere else. + +## Next + + + + Workspaces, tabs, panes, and the server that owns them. + + + Suggestions, completion, and history search — the part you touch most. + + diff --git a/docs/getting-started/installation.mdx b/docs/getting-started/installation.mdx new file mode 100644 index 00000000..4f5f3e59 --- /dev/null +++ b/docs/getting-started/installation.mdx @@ -0,0 +1,151 @@ +--- +title: "Installation" +description: "Native builds for macOS, Windows, and Linux — plus building from source." +--- + +Every release publishes native builds on +[**GitHub Releases**](https://github.com/l0ng-ai/tty7/releases). There is no +runtime to install first: fonts are embedded in the binary, and the Linux +AppImage bundles its own X11/Wayland/font libraries. + + + + Download the DMG that matches your Mac and drag **tty7** into Applications. + + | Mac | File | + |---|---| + | Apple silicon (M1 and later) | `tty7--macos-arm64.dmg` | + | Intel | `tty7--macos-x86_64.dmg` | + + Builds are signed with a Developer ID certificate and notarized by Apple, so + Gatekeeper opens them without a right-click dance. + + + Builds are produced on macOS 14 and macOS 15. macOS 14 (Sonoma) or later + is the tested range. + + + + + Two shapes, both x86-64: + + | File | Use it when | + |---|---| + | `tty7--windows-x86_64-setup.exe` | You want a normal install with Start-menu entries and an uninstaller. | + | `tty7--windows-x86_64.zip` | You want it portable — unzip anywhere and run `tty7-app.exe`. | + + The installer offers one optional setup task, off by default: **Add "Open in + tty7" to the folder context menu**. It writes shell verbs under `HKCU`, so + only your own Windows account is affected, and the uninstaller always takes + them back out. + + A portable install can add or remove the same entries itself: + + ```powershell + tty7-app.exe --register-explorer-menu + tty7-app.exe --unregister-explorer-menu + ``` + + + The Windows package also carries a Linux `tty7-server` binary so a WSL + distro can be served locally instead of downloading one. See + [Remote workspaces](/remote/workspaces). + + + + + | File | Use it when | + |---|---| + | `tty7--linux-x86_64.AppImage` | Almost always. `chmod +x` and run — the X11, Wayland, xkb, and font libraries are bundled, so it works on Fedora, Arch, Debian and friends, not just Ubuntu. | + | `tty7--linux-x86_64.tar.gz` | You would rather unpack the plain binary and place it yourself. | + + ```bash + chmod +x tty7-*-linux-x86_64.AppImage + ./tty7-*-linux-x86_64.AppImage + ``` + + + +## The `tty7` command + +Every installer ships the `tty7` CLI beside the app, and the app puts it on your +PATH the first time it launches. That is what lets a script — or a coding agent +in some other terminal — open panes and read them back. + +- **On Unix** it is a symlink into whichever of `/opt/homebrew/bin`, + `/usr/local/bin`, `~/.local/bin`, `~/bin`, or `~/.cargo/bin` your PATH already + covers. +- **On Windows** the install directory is appended to your user PATH, and the + uninstaller removes it again. + +A `tty7` you installed yourself — a `cargo install` build, a package manager's +copy — is never replaced. To turn the whole thing off, uncheck **Settings → +Agents → Install the tty7 command on PATH**. + + + Inside a tty7 pane the CLI works regardless of PATH, because panes inherit the + app's environment. + + +## Updating + +tty7 checks for updates every six hours and can update itself: **Settings → +About → Check now**, then **Update and relaunch**. Releases are downloaded and +verified in the background so applying one is just a restart. + +Pick **Stable** or **Nightly** under **Settings → About → Update channel**. See +[Updates and channels](/reference/updates) for what each feed publishes and how +switching behaves. + +## Building from source + +You need a stable Rust toolchain. The build is a plain `cargo build`; the app +binary is `tty7-app`. + + + + ```bash + git clone https://github.com/l0ng-ai/tty7 + cd tty7 + cargo build --release + ``` + + + gpui resolves its X11/Wayland/font backends through `pkg-config` at build + time, so the development packages have to be present: + + ```bash + sudo apt-get install -y pkg-config cmake clang \ + libxkbcommon-dev libxkbcommon-x11-dev \ + libfontconfig1-dev libfreetype6-dev \ + libwayland-dev libx11-dev libxcb1-dev \ + libzstd-dev libssl-dev libkrb5-dev + cargo build --release + ``` + + + + + A source build does not update itself, and it will not replace an installed + copy's server. If you run both, see + [Troubleshooting](/reference/troubleshooting). + + +## Uninstalling + + + + Quit tty7 (use **Quit and Stop Server** from the tray menu so the background + server stops too), then drag the app to the Trash. Your settings live in + `~/.config/tty7` and are left alone; delete that folder to remove them. + + + Use **Add or remove programs**. The uninstaller removes the PATH entry and + any Explorer context-menu keys it added. Settings live in + `%APPDATA%\tty7`. + + + Delete the AppImage or the unpacked directory. Settings live in + `~/.config/tty7`. + + diff --git a/docs/git/diffs.mdx b/docs/git/diffs.mdx new file mode 100644 index 00000000..5c2441f3 --- /dev/null +++ b/docs/git/diffs.mdx @@ -0,0 +1,48 @@ +--- +title: "Diffs" +description: "The diff overlay: side-by-side or unified, from the sidebar or the panel." +--- + +## Opening one + +| From | How | +|---|---| +| The sidebar | Click a row's `+N −M` counts | +| Source Control | **Open Changes** on a file, or click the row | +| History | Click a file inside a commit's detail view | + +The overlay covers the window; Esc closes it. + + + The tty7 diff overlay + + +## Side-by-side or unified + +**Toggle Unified / Side-by-Side Diff** in the command palette switches between +the two. The choice is global — one setting for every diff, the same call VS +Code's `diffEditor.renderSideBySide` makes — and persists as `diff_view` in +`config.json`. + +## What it shows + +- Every changed file, with its status and `+N −M` +- **Untracked files** as a preview of their contents, up to 4 MB — past that the + card says the read failed rather than showing a silently cut-off file +- A commit's files, when the diff came from the history + +Two limits keep a huge diff from becoming a huge wait: + +| Limit | Value | What happens | +|---|---|---| +| Files rendered | 300 | *"Showing the first 300 of N changes."* | +| Lines before auto-collapse | 400 per file | Big files start collapsed; expand the ones you care about | + +Both are stated in the overlay when they apply — nothing is dropped silently. + +## Turning the sidebar shortcut off + +If you would rather the sidebar's counts not be clickable, turn off **Settings → +Window & Tabs → Open diff preview from sidebar counts** +(`sidebar_diff_preview: false`). The branch and counts stay on the row; they +just stop opening the overlay. diff --git a/docs/git/source-control.mdx b/docs/git/source-control.mdx new file mode 100644 index 00000000..da3f23f2 --- /dev/null +++ b/docs/git/source-control.mdx @@ -0,0 +1,86 @@ +--- +title: "Source control" +description: "Stage, commit, branch, and push from the panel beside your terminal." +--- + +The **Source Control** tab of the [side panel](/window/side-panel) (⌘ J) +is a full git client for whichever repository the focused pane is in. It follows +the pane: `cd` into another repository and the panel switches with you. + + + The tty7 source control panel + + +## Changes + +Files are grouped by what git thinks of them: + +| Group | | +|---|---| +| **Merge Changes** | Conflicts, with *Resolve Conflict* and *Mark as Resolved* | +| **Staged Changes** | What the next commit will contain | +| **Changes** | Modified but not staged | +| **Untracked** | New files | + +Each row has **Stage Changes**, **Unstage Changes**, **Discard Changes**, and +**Open Changes** — which opens the [diff](/git/diffs). Group-level *Stage All*, +*Unstage All*, and *Discard All* sit on the headers, and the destructive ones +confirm first. + +## Committing + +Write the message in the box at the top and pick a commit action: + +| | | +|---|---| +| **Commit** | Commit what is staged | +| **Commit All** | Stage everything, then commit | +| **Commit (Amend)** | Replace the last commit — confirms first, because anyone who already has it has to reconcile | +| **Commit & Push** | Commit, then push | +| **Commit & Sync** | Commit, then pull and push | + +⌘ ⏎ commits while the caret is in the message box. **Stash All** is +there too. + +## Branches and remotes + +| | | +|---|---| +| **Checkout to…** | Switch branches, with a search box; offers **Stash & Switch** when the tree is dirty | +| **Create Branch…** | From here, or from any commit in the history | +| **Publish Branch** | For a branch with no upstream yet | +| **Sync Changes** | Pull, then push | +| **Push** · **Pull** · **Fetch** | Individually | + +All of these are also in the command palette under **Git**, so they are +bindable. + +When a repository is mid-operation — merging, rebasing, cherry-picking, +reverting, bisecting, applying — the panel says so instead of pretending +everything is normal. + +## History + +**Git: Toggle Commit History** (or the *History* section header) opens the +commit graph: branches drawn as lanes, a filter box, **Current Branch** or +**All Branches**, and *Load more* at the bottom. + +Click a commit for its detail view — message, parents, and the files it touched, +each openable as a diff. From a commit's menu: + +| | | +|---|---| +| **Checkout Commit** · **Create Branch Here…** | Move to it | +| **Cherry Pick** · **Revert Commit** | Apply or undo it here | +| **Reset (Soft / Mixed / Hard)** | Move the branch to it — Hard confirms, since commits after it fall off the branch and uncommitted changes are discarded | +| **Copy Commit SHA** | | + +The history section starts collapsed and remembers whether you opened it +(`scm_graph_expanded`). + +## In the sidebar + +You do not have to open the panel to know where you stand: every +[sidebar row](/window/sidebar) carries its pane's branch and a `+N −M` count of +the working tree, refreshed on `cd` and when a command finishes. Clicking the +counts opens the diff overlay. diff --git a/docs/git/worktrees.mdx b/docs/git/worktrees.mdx new file mode 100644 index 00000000..74d33edb --- /dev/null +++ b/docs/git/worktrees.mdx @@ -0,0 +1,56 @@ +--- +title: "Worktrees" +description: "An isolated checkout on a fresh branch, in one dialog and one tab." +--- + +Running two agents on the same repository at once means they fight over the +working tree. A git worktree is the fix, and tty7 makes it a single dialog. + +## Creating one + +**New Worktree Tab…** — in the command palette, the tab's right-click menu, and +the application menu — asks three things: + +| Field | Default | +|---|---| +| **Worktree Name** | A fresh name that does not collide with an existing branch or directory | +| **New Branch** | The same name, editable | +| **Start From** | The branch you are currently on | + +Each field opens on a suggestion you can accept or type straight over. + + + Creating a worktree + + +Confirm and tty7 creates the worktree, opens a tab in it, and starts a shell +there. The [sidebar](/window/sidebar) files it under the same repository group as +its parent, on its own branch. + +## Where they go + +Worktrees land inside the repository, under: + +``` +/.tty7/worktrees/ +``` + +`/.tty7/.gitignore` is created with `*` in it the first time, so the +directory never shows up as an untracked mess in your own repository. + +## Removing one + +Closing a worktree tab offers to remove the worktree with it: + +- **Clean tree** — *Remove Worktree* or *Keep*. +- **Dirty tree** — the dialog says so, and removing requires the explicit + *Discard Changes & Remove*. + +Nothing is removed silently, and *Keep* leaves the worktree on disk for `git +worktree list` to find later. + + + Pair this with [agent sessions](/agents/sessions): a worktree per agent means + two Claude Codes can work on the same repository without stepping on each + other's files. + diff --git a/docs/images/hero.webp b/docs/images/hero.webp new file mode 100644 index 0000000000000000000000000000000000000000..416a5a417d20d47e74b22bc60658c8b374d2f413 GIT binary patch literal 183922 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%0Ar3WtS&eVi<}0onv2VP{+-m#?5sBq{>+ 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 + + + + + + + + + screenshot coming soon + tty7 docs + diff --git a/docs/index.mdx b/docs/index.mdx new file mode 100644 index 00000000..d70cc602 --- /dev/null +++ b/docs/index.mdx @@ -0,0 +1,105 @@ +--- +title: "tty7" +sidebarTitle: "Introduction" +description: "A terminal workbench: persistent sessions, remote work, agents." +mode: "wide" +--- + + + tty7 showing a sidebar of agent sessions across several repositories + + +tty7 is a terminal you can leave running. Close the window, reboot the machine, +walk to a different laptop — the shells you started are still there, and so are +the coding agents you left working in them. + +It is written in Rust, renders on the GPU through Zed's +[gpui](https://github.com/zed-industries/zed), and parses VT with Alacritty's +terminal core. In practice that means roughly twice the throughput of Alacritty, +Ghostty, or Kitty on a big `cat`, and a frame rate that does not fall over when +something floods the screen. + +## What makes it different + + + + A background server owns your shells, not the window. Quit tty7 and your + builds keep building. No tmux to learn or configure. + + + Ghost suggestions from your history, tab completion that explains each flag, + syntax highlighting, click-to-place-caret, real multi-line editing. + + + 18 coding CLIs are recognised on sight. Per-pane status dots, notifications + when one needs you, git context, and session resume after a reboot. + + + A native Rust SSH stack with profiles, SFTP, and port forwarding — plus + remote workspaces where files, repos, and panes all stay on the far machine. + + + Branch and diff counts on every sidebar row, a source control panel, a diff + overlay, and worktrees in one dialog. + + + A bundled `tty7` CLI that opens panes, sends keys, reads screens, and blocks + until an agent needs you — so scripts and agents can drive the workbench. + + + +## Start here + + + + Native builds for macOS, Windows, and Linux. + [Installation →](/getting-started/installation) + + + Five minutes of settings that pay for themselves. + [First launch →](/getting-started/first-launch) + + + Workspace, tab, pane — and the server underneath them. + [Core concepts →](/getting-started/concepts) + + + +## How fast, exactly + +Same machine, same day, same 155×40 grid — Apple M1 Pro, macOS 26.3.1, +five-run averages. + +| | **tty7** | Alacritty | Ghostty | Kitty | +|---|---:|---:|---:|---:| +| Plaintext I/O — 11 MB `cat` (lower is better) | **95 ms** | 239 ms | 179 ms | 185 ms | +| [DOOM-fire](https://github.com/const-void/DOOM-fire-zig) frame rate (higher is better) | **888 fps** | 485 fps | 552 fps | 617 fps | +| Cold-launch memory | 116 MB 1 | 105 MB | 128 MB | 130 MB | + +1 GUI 105 MB plus the persistent server at 11 MB. + +The methodology and a one-command reproduction live in +[`scripts/bench/`](https://github.com/l0ng-ai/tty7/tree/main/scripts/bench). + +Three decisions account for most of it: + +- **The PTY is read at device speed** and parsed in large batches, off the + render path — so drawing never throttles reading. +- **The hot paths are lock-free.** A big `cat` never waits on the renderer. +- **The server buffers up to 16 MiB** ahead of the window before backpressure + applies, which is enough that a flood finishes writing while the window is + still catching up. + +## Getting help + + + + Ask a question, show what you built. + + + Bugs and feature requests. + + + Everything that shipped, release by release. + + diff --git a/docs/logo/logo.svg b/docs/logo/logo.svg new file mode 100644 index 00000000..0ec488f2 --- /dev/null +++ b/docs/logo/logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/docs/reference/configuration.mdx b/docs/reference/configuration.mdx new file mode 100644 index 00000000..81851282 --- /dev/null +++ b/docs/reference/configuration.mdx @@ -0,0 +1,183 @@ +--- +title: "config.json" +description: "Every key tty7 reads, its type, and its default." +--- + +| | | +|---|---| +| macOS / Linux | `~/.config/tty7/config.json` | +| Windows | `%APPDATA%\tty7\config.json` | +| Override the whole directory | `TTY7_CONFIG_DIR` | + +Every key is optional — a missing one means its default, so you only write what +you change. Out-of-range numbers are clamped rather than rejected, and an +unrecognised enum value falls back to the default with a log line instead of +failing the file. + +```json +{ + "font_family": "JetBrains Mono", + "font_size": 14, + "theme_follow_system": true, + "theme_preset_light": "one_light", + "theme_preset_dark": "dracula", + "macos_option_as_alt": true, + "scrollback_limit": 50000 +} +``` + +## Typography + +| Key | Type | Default | | +|---|---|---|---| +| `font_family` | string | `"Hack"` | Primary face. Hack is bundled. | +| `font_fallbacks` | string[] | platform list | Ordered fallbacks. Stock platform faces are appended to whatever you write. | +| `font_family_bold` | string | — | A distinct bold face. | +| `font_family_italic` | string | — | A distinct italic face. | +| `font_features` | object | — | OpenType tags, e.g. `{"calt": true, "liga": 1}`. Four alphanumeric characters per tag. | +| `font_size` | number | `15` | Terminal text size in px (4–256). | +| `line_height` | number | `1.4` | Multiple of the font size (0.5–4). | +| `ui_font_size` | number | `16` | The interface's root size in px (12–24). | + +[More about fonts →](/customization/fonts) + +## Theme and window + +| Key | Type | Default | | +|---|---|---|---| +| `theme_preset` | string | `"light"` | Active theme id. | +| `theme_follow_system` | bool | `false` | Follow the OS appearance. | +| `theme_preset_light` | string | `"light"` | Used when following the system. | +| `theme_preset_dark` | string | `"dark"` | Used when following the system. | +| `theme_legible_palette` | bool | `true` | Brighten or darken bright ANSI colours that would be unreadable on the background. | +| `window_opacity` | number | — | 0.2–1.0. Unset means "follow the theme". | +| `window_blur` | bool | — | Blur behind a translucent window (macOS). Unset means "follow the theme". | +| `window_backdrop` | enum | `"auto"` | Windows only: `auto`, `blur`, `mica`, `mica-alt`, `acrylic`, `off`. | +| `dim_inactive_panes` | bool | `true` | Dim panes that are not focused. | +| `startup_mode` | enum | `"normal"` | `normal`, `maximized`, `fullscreen`. | +| `remember_window_size` | bool | `true` | Reopen at the last size and position. | +| `restore_session` | bool | `true` | Reopen the last window's tabs, splits, and directories. | +| `gui_language` | enum | `"en"` | `en`, `zh-CN`, `ja-JP`. Anything else falls back to `en`. | + +Built-in theme ids: `light`, `one_light`, `catppuccin_latte`, `rose_pine_dawn`, +`dark`, `dracula`, `harbor`, `one_dark_pro`, `rose_pine`. Your own themes take +their id from the file name. [More about themes →](/customization/themes) + +## Tabs, sidebar, panels + +| Key | Type | Default | | +|---|---|---|---| +| `tab_bar_position` | enum | `"left"` | `left` (sidebar) or `top` (strip). | +| `new_tab_position` | enum | `"after-current"` | Or `end`. | +| `sidebar_grouping` | enum | `"repo"` | Or `none` for a flat list. | +| `sidebar_diff_preview` | bool | `true` | Clicking a row's `+N −M` opens the diff overlay. | +| `sidebar_width` | number | `220` | Pixels (100–2000). | +| `sidebar_collapsed` | bool | `false` | | +| `right_panel_visible` | bool | `false` | | +| `right_panel_width` | number | `260` | Pixels (100–2000). | +| `right_panel_tab` | enum | `"info"` | `info`, `changes`, `files`. | +| `diff_view` | enum | `"split"` | Or `unified`. Global, not per file. | +| `scm_graph_expanded` | bool | `false` | Whether the history section starts open. | +| `show_tray_icon` | bool | `true` | The tray / menu bar status item. | + +## Terminal + +| Key | Type | Default | | +|---|---|---|---| +| `shell` | object | — | `{"program": "fish", "args": ["-l"]}`. Unset uses the platform default. | +| `working_directory` | object | `{"strategy":"inherit"}` | `strategy` is `inherit`, `home`, or `custom`; `path` is used when custom. | +| `env` | object | `{}` | Extra environment variables for every pane. | +| `scrollback_limit` | number | `10000` | Lines per pane (100–100,000). New panes only. | +| `cursor_style` | enum | `"block"` | `block`, `bar`, `underline`. | +| `cursor_blink` | bool | `true` | | +| `bell` | enum | `"visual"` | `none`, `visual`, `audible`, `both`. | +| `per_pane_history` | bool | `false` | Give each pane its own shell history file. | + +## Mouse and scrolling + +| Key | Type | Default | | +|---|---|---|---| +| `mouse_scroll_multiplier` | number | `1.0` | 0.1–10. | +| `smooth_scroll` | bool | `true` | Ease each wheel notch. Trackpads unaffected. | +| `mouse_reporting` | bool | `true` | Let full-screen apps handle clicks and scrolling. | +| `mouse_hide_while_typing` | bool | `true` | | +| `focus_follows_mouse` | bool | `false` | | + +## Input and clipboard + +| Key | Type | Default | | +|---|---|---|---| +| `tab_completion` | bool | `true` | tty7's completion menu on . Off hands the key to the shell. | +| `history_search` | bool | `true` | tty7's fuzzy history on ⌃ R. Off hands the key to the shell. | +| `smart_select` | bool | `true` | Double-click grabs URLs, paths, bracket pairs, CJK words. | +| `word_separators` | string | see below | Characters that end a word. Used when smart selection is off. | +| `copy_on_select` | bool | `false` | | +| `clipboard_trim_trailing_spaces` | bool | `false` | | +| `macos_option_as_alt` | bool | `false` | +key sends the escape chord instead of typing a special character. | +| `keybindings` | object | `{}` | `{"SplitRight": "cmd-d"}`. [Syntax →](/customization/keybindings) | +| `keybinding_preset` | string | `"default"` | Or `"tmux"`. | +| `prefix` | string | `"ctrl-b"` | The tmux preset's prefix. | + +The default `word_separators` are a comma, a box-drawing bar, a backtick, a +pipe, a colon, both quote characters, a space, the six bracket characters, the +angle brackets, and a tab: + +```json +{ "word_separators": ",│`|:\"' ()[]{}<>\t" } +``` + +## Links + +| Key | Type | Default | | +|---|---|---|---| +| `link_url` | bool | `true` | Underline and open URLs on ⌘/Ctrl-click. | +| `link_file_command` | string | — | Command for file links. `{path}`, `{line}`, `{column}` are substituted; a flag whose value is missing is dropped. | +| `ssh_loopback_forward` | bool | `false` | Open `localhost:PORT` links through a temporary forward when the pane is in SSH. | + +## Notifications + +| Key | Type | Default | | +|---|---|---|---| +| `notify_on_command_finish` | enum | `"unfocused"` | `never`, `unfocused`, `always`. | +| `notify_threshold_secs` | number | `10` | How long a command must run to qualify (1–3600). | + +## Agents + +| Key | Type | Default | | +|---|---|---|---| +| `agent_commands` | object | `{}` | Map a wrapper command to an agent slug: `{"cc": "claude"}`. | +| `restore_agent_sessions` | bool | `true` | Relaunch an agent conversation when a lost pane is restored. | +| `install_cli_on_path` | bool | `true` | Put the bundled `tty7` command on PATH at launch. | + +[Agent slugs →](/agents/overview#your-own-wrapper) + +## SSH + +| Key | Type | Default | | +|---|---|---|---| +| `ssh_profiles` | array | `[]` | Managed from **Settings → SSH**. Secrets live in the OS keychain, never here. | +| `verify_host_keys` | bool | `true` | | +| `ssh_warn_on_close` | bool | `false` | Confirm before closing a live connection. | + +## Updates and network + +| Key | Type | Default | | +|---|---|---|---| +| `check_for_updates` | bool | `true` | | +| `update_channel` | enum | `"stable"` | Or `nightly`. | +| `auto_download_updates` | bool | `true` | Fetch and verify in the background so installing is a restart. Packages are ~25–30 MB and a check happens every six hours. | +| `http_proxy` | string | — | For tty7's *own* traffic only — update checks, downloads, remote-server installs. `http://…` or `socks5://…`. Programs in a pane are unaffected. | + +[Updates →](/reference/updates) + +## Keys tty7 manages itself + +`ssh_profile_frecency` and `command_frecency` record how often and how recently +you use a profile or command, so the pickers can rank them. They are written by +the app; there is no reason to edit them. + + + If the file cannot be parsed, tty7 starts on defaults, keeps your original at + `config.json.corrupt`, and logs the reason. It never silently overwrites what + you wrote. + diff --git a/docs/reference/keyboard-shortcuts.mdx b/docs/reference/keyboard-shortcuts.mdx new file mode 100644 index 00000000..495e2445 --- /dev/null +++ b/docs/reference/keyboard-shortcuts.mdx @@ -0,0 +1,103 @@ +--- +title: "Keyboard shortcuts" +description: "Every default binding, plus the action names for rebinding." +--- + +**Settings → Keybindings** (⌘ ,) is the live version of this page — +it shows what *your* copy is bound to. This is the shipped default. + +## Tabs and workspaces + +| Action | macOS | Windows / Linux | +|---|---|---| +| New Tab | ⌘ T | Ctrl ⇧ T | +| Close Pane / Tab | ⌘ W | Ctrl ⇧ W | +| Reopen Closed Tab | ⌘ ⇧ T | Alt ⇧ T | +| Next Tab · Previous Tab | ⌃ ⇥ · ⌃ ⇧ ⇥ | same | +| Go to Tab 1–9 | ⌘ 1⌘ 9 | Alt 1Alt 9 | +| New Workspace | ⌘ ⇧ N | Ctrl ⇧ N | +| Switch Workspace | ⌘ ⇧ O | Ctrl ⇧ O | + +## Panes + +| Action | macOS | Windows / Linux | +|---|---|---| +| Split Right | ⌘ D | Ctrl ⇧ D | +| Split Down | ⌘ ⇧ D | Ctrl Alt ⇧ D | +| Next Pane · Previous Pane | ⌘ ] · ⌘ [ | Ctrl ⇧ ] · Ctrl ⇧ [ | +| Focus Pane Left / Right / Up / Down | ⌘ ⌥ ←→↑↓ | Alt ←→↑↓ | +| Zoom Pane | ⌘ ⇧ ⏎ | Ctrl ⇧ ⏎ | +| Enter Full Screen | ⌘ ⏎ | F11 | + +## View + +| Action | macOS | Windows / Linux | +|---|---|---| +| Command Palette | ⌘ P | Ctrl ⇧ P | +| Toggle Left Sidebar | ⌘ B | Ctrl ⇧ B | +| Toggle Right Panel | ⌘ J | Ctrl ⇧ J | +| Toggle Code Panel | ⌘ ⇧ E | Ctrl ⇧ E | +| Font Size Up · Down · Reset | ⌘ + · ⌘ − · ⌘ 0 | Ctrl + · Ctrl − · Ctrl 0 | +| Zoom the font | + wheel | Ctrl + wheel | + +## Terminal + +| Action | macOS | Windows / Linux | +|---|---|---| +| Find in Terminal | ⌘ F | Ctrl ⇧ F | +| Find Next · Previous | ⌘ G · ⌘ ⇧ G | F3 · ⇧ F3 | +| Clear Scrollback | ⌘ K | Ctrl ⇧ K | +| Copy · Paste | ⌘ C · ⌘ V | Ctrl ⇧ C · Ctrl ⇧ V · ⇧ Insert | +| Insert Newline (at the prompt) | ⇧ ⏎ · ⌥ ⏎ | same | +| Fuzzy history search | ⌃ R | same | +| Accept ghost suggestion | | same | +| Completion menu | | same | + +## Git and SSH + +| Action | macOS | Windows / Linux | +|---|---|---| +| Commit (caret in the message box) | ⌘ ⏎ | Ctrl ⏎ | +| Save (in the editor) | ⌘ S | Ctrl S | +| Restart SSH Session | ⌘ ⇧ R | Ctrl ⇧ R | + +## Application + +| Action | macOS | Windows / Linux | +|---|---|---| +| Settings | ⌘ , | Ctrl , | +| Keyboard Shortcuts | ⌘ / | — | +| Hide tty7 · Hide Others · Minimize | ⌘ H · ⌘ ⌥ H · ⌘ M | — | +| Quit | ⌘ Q | Ctrl ⇧ Q | + +## Actions with no default key + +All of these are in the command palette, and all are bindable under **Settings → +Keybindings**: + +| Group | Actions | +|---|---| +| Tabs | `RenameTab` · `NewWorktreeTab` · `CloseOtherTabs` · `CloseTabsToTheRight` · `CopyWorkingDirectory` · `MarkTabUnread` · `ToggleTabSidebar` | +| Panes | `ResizePaneLeft/Right/Up/Down` · `SwapPaneNext` · `SwapPanePrev` | +| Workspaces | `SelectWorkspace1`…`SelectWorkspace9` · `RenameWorkspace` · `StopWorkspace` · `DeleteWorkspace` | +| Agents | `ForkAgentSession` (+ `Right` / `Left` / `Down` / `Up`) · `CopyAgentSessionId` | +| Git | `ScmStageAll` · `ScmUnstageAll` · `ScmDiscardAll` · `ScmCommitAmend` · `ScmRefresh` · `ScmSync` · `ScmPush` · `ScmPull` · `ScmFetch` · `ScmCheckoutBranch` · `ScmCreateBranch` · `ScmToggleGraph` · `ToggleDiffViewMode` | +| Panels | `ShowRightPanelInfo` · `ShowRightPanelChanges` · `ShowRightPanelFiles` | +| SSH | `ToggleSftp` · `ShowSshForwards` · `OpenSshProfiles` | +| Application | `About` · `CheckForUpdates` · `OpenDocumentation` · `OpenDiscord` · `ReportIssue` · `ShowAll` · `ZoomWindow` | + +## Rebinding syntax + +```json +{ + "keybindings": { + "ResizePaneLeft": "ctrl-alt-left", + "ToggleSftp": "secondary-shift-u", + "ScmSync": "ctrl-b s" + } +} +``` + +`secondary` means on macOS and Ctrl elsewhere. A space +separates the steps of a chord. +[More →](/customization/keybindings) diff --git a/docs/reference/privacy.mdx b/docs/reference/privacy.mdx new file mode 100644 index 00000000..9b405502 --- /dev/null +++ b/docs/reference/privacy.mdx @@ -0,0 +1,60 @@ +--- +title: "Privacy and permissions" +description: "What macOS asks you, why, and what tty7 itself holds." +--- + +## Why macOS asks tty7 for permission + +Panes are forked from tty7's own bundled executable, so when a program you run +asks macOS for a protected resource, macOS attributes the request to **tty7.app** +— not to the program. + +If tty7 declared no usage strings, that request would be **denied outright with +no prompt at all**, and the program would look broken for no visible reason. + +So tty7 declares the matching usage strings, and you get the normal one-time +prompt: + + + + Camera · microphone · Bluetooth · location · motion + + + Contacts · calendars · reminders · photo library + + + Local network · Apple Events · speech recognition · system administration + + + + + **Declaring a usage string is not the same as holding the permission.** + tty7.app itself is granted none of these. Every prompt you see belongs to + whatever you ran in the pane, and you can revoke it under **System Settings → + Privacy & Security**. + + +### Full Disk Access + +Apple defines no usage-string key for it. Reaching `~/Library/Mail`, +`~/Library/Messages`, `~/Library/Safari`, or `~/Library/Containers` needs a +manual grant in **System Settings → Privacy & Security → Full Disk Access**. + +## What leaves your machine + +| | | +|---|---| +| **Update checks** | A request to the GitHub releases API every six hours, plus the download when you accept one. Turn it off with `check_for_updates: false`. | +| **Remote server installs** | Downloading a `tty7-server` binary for a machine you connected to — or, for WSL, copying the one already bundled with your install. | +| **Everything else** | Nothing. There is no telemetry, no analytics, and no account. | + +Both of the above honour `http_proxy`. [Updates →](/reference/updates#proxies) + +## What is stored, and where + +| | | +|---|---| +| Settings, themes, window state | `~/.config/tty7/` (`%APPDATA%\tty7\` on Windows) | +| SSH passwords and key passphrases | The **OS keychain** — never `config.json`, never plain text on disk | +| Pane scrollback tails | `/scrollback/*.bin`, mode `0600` on Unix and behind the config directory's ACL on Windows. 256 KiB per pane, kept only until something can no longer ask for it: closing a pane deletes its file at once, a restore consumes it, and a periodic pass collects the rest. | +| Shell history | Your shell's own file, exactly as before — unless you turned on per-pane history, which merges back into it. | diff --git a/docs/reference/shell-integration.mdx b/docs/reference/shell-integration.mdx new file mode 100644 index 00000000..9e732d29 --- /dev/null +++ b/docs/reference/shell-integration.mdx @@ -0,0 +1,73 @@ +--- +title: "Shell integration" +description: "What tty7 injects into your shell, and what it buys you." +--- + +A terminal that only sees bytes cannot tell a prompt from output, or a finished +command from a hung one. tty7's shell integration closes that gap: the shell +reports where prompts begin, what was submitted, what it exited with, and where +it is. + +**You do not install it.** It is injected when the pane's shell starts, and +removes itself from the equation if you run the same shell elsewhere. + +## Which shells + +| Shell | How it is injected | +|---|---| +| **zsh** | A throwaway `ZDOTDIR` whose files source yours first, then tty7's. Your `TTY7_USER_ZDOTDIR` is preserved. | +| **bash** | An rcfile that sources your own first. | +| **fish** | A `-C` init command. | +| **PowerShell** | An encoded init command that wraps your existing `prompt` function and PSReadLine's line reader. | +| **WSL** *(Windows)* | The distro's shell is bootstrapped with the same scripts. | +| **Remote panes** | The same three POSIX shells, bootstrapped over the SSH connection. Toggle per profile with **Settings → SSH → Session → Shell integration**. | + +`TTY7_SHELL_INTEGRATION` is set once it is active, and guards against a second +injection when shells nest. + + + A shell launched with custom arguments is left alone for bash and PowerShell, + because tty7's injection would conflict with the flags you chose. + + +## What it reports + +| Signal | Sequence | Used for | +|---|---|---| +| Prompt begins / input begins | `OSC 133;A`, `133;B` | The [prompt layer](/terminal/prompt): suggestions, completion, multi-line editing | +| Command submitted | `OSC 133;C` | Knowing a command is running; agent detection on Windows, where ConPTY exposes no foreground process group | +| Command finished, with exit code | `OSC 133;D` | The "finished after 42s" notification, failure marks in [history](/terminal/history) | +| Working directory | `OSC 7` | New tabs and splits opening in the right place, the sidebar's repo grouping, the git branch readout | +| Editing mode (vi / emacs) | `OSC 133;V` | Matching tty7's key handling to your shell's mode | +| Window title | `OSC 0` | Tab labels | + +## What turns off without it + +Run a shell tty7 does not integrate with, and everything below still works — +it just falls back to less precise sources: + +- Ghost suggestions, the completion menu, and ⌃ R's fuzzy history +- "Command finished" notifications and the failure marks in history search +- Exact working-directory tracking (tty7 falls back to inspecting the process) + +Panes, splits, scrollback, search, SSH, and the CLI are unaffected. + +## Per-pane history + +When `per_pane_history` is on, the integration is also what makes it work. It +runs *after* your own rc file — which is the only reason it can: `$HISTFILE` is +yours to set, wherever you like, and nothing outside the shell knew where it +pointed until then. + +The sequence is: seed the pane's private file from your real history so it does +not start blank, record how much was seeded, repoint `$HISTFILE`, and merge +everything past that mark back when the pane closes. + +[More about history →](/terminal/history#one-history-or-one-per-pane) + +## Remote shells + +For a remote workspace or an SSH pane, the same scripts are sent over the +connection at login, so a remote pane reports its cwd, exit codes, and prompt +marks exactly like a local one. Turn it off for a particular host under that +profile's **Advanced → Session**. diff --git a/docs/reference/troubleshooting.mdx b/docs/reference/troubleshooting.mdx new file mode 100644 index 00000000..e06c3746 --- /dev/null +++ b/docs/reference/troubleshooting.mdx @@ -0,0 +1,137 @@ +--- +title: "Troubleshooting" +description: "The things that go wrong, and what they actually mean." +--- + +## Start here + +```bash +tty7 doctor +``` + +One table: whether the server is reachable, whether its wire dialect matches +your binary, the three environment variables, pid/uptime/panes, and how many +machine links exist. Most of what follows is a specific answer this gives you. + +## `tty7: command not found` + +The CLI is put on PATH the first time the app launches. If it is missing: + +- Check **Settings → Agents → Install the tty7 command on PATH** is on. +- On Unix it symlinks into whichever of `/opt/homebrew/bin`, `/usr/local/bin`, + `~/.local/bin`, `~/bin`, `~/.cargo/bin` your PATH already covers — if none of + those are on your PATH, add one. +- On Windows the install directory is appended to your user PATH, which needs a + new shell to take effect. +- A `tty7` you installed yourself is never replaced, so an old one earlier in + PATH will win. + +Inside a tty7 pane it works regardless, since panes inherit the app's +environment. + +## The server is unreachable + +`tty7 doctor` says so, and the GUI cannot open panes. + +Start it with `tty7 server start`. If you are an agent or a script, +**do not** — tell the user instead. Starting a server they did not ask for +changes what their GUI attaches to. + +For logs: + +```bash +TTY7_LOG=info # must be set before the server starts +tty7 server logs +``` + +## Panes came back empty + +A crash, a `kill -9`, or a reboot takes the shells with it — that part is +unavoidable. The *screens* should come back: tty7 keeps a capped tail of each +pane's output (256 KiB) and hands it to the pane that reopens on that id. + +It is consumed once. If a pane was restored, then closed, then reopened, the +second time there is nothing left to restore — that is by design, not a bug. + +## "The background server is still running <build>" + +tty7 updated in place, so the app is new and your panes are still served by the +previous build. Restarting the server picks up the new one and **ends every +process in every pane**. There is no hurry — do it when your panes are idle. +[Updates →](/reference/updates) + +## A remote machine will not connect + +| Message | What it means | +|---|---| +| *"running an old tty7 server that this copy cannot talk to"* | The server there predates your client's protocol. Let tty7 update it — this ends every session on that machine. | +| *"running a newer tty7 server than this copy"* | Update tty7 here instead, or replace the server there. | +| *"answered, but not as a tty7 server"* | Something else is listening, or the binary is not what tty7 expects. | +| *"tty7 no longer has a way to reach <machine>"* | The SSH link dropped. Reconnect from the switcher. | + +`tty7 -m ` never dials a fresh connection by design — it uses a link +the local server already holds. Connect from the GUI first. + +## or ⌃ R is not doing what I expect + +Both are switches, and turning one off hands the key straight back to your +shell: + +- **Settings → Input → Prompt → Tab completion** +- **Settings → Input → Prompt → History search** + +If they do nothing at all in a particular pane, the shell there probably has no +[shell integration](/reference/shell-integration) — nushell, elvish, xonsh and +friends run fine but do not get the prompt layer. + +## ⌥ B types `∫` instead of moving a word + +That is macOS's default. Turn on **Settings → Input → Keyboard → Option (⌥) acts +as Meta**. + +## CJK characters have a gap on the right + +Your CJK fallback advances 1.0em while the primary face advances 0.60205em, so +the glyph does not fill its two-column slot. Install +[Maple Mono NF CN](https://github.com/subframe7536/maple-font) — it is already +first in the fallback chain and fits Hack exactly — or change the primary face. +[The full explanation →](/customization/fonts#cjk-and-the-two-column-grid) + +## A theme in my themes folder is not showing up + +Settings lists it under **Not loaded from the themes folder**, with the reason. +Usually a missing required key: `background`, `foreground`, `accent`, and `ansi` +(with eight `normal` and eight `bright` entries) are all mandatory. + +## My `config.json` edits did nothing + +If the file cannot be parsed, tty7 starts on defaults and keeps your original at +`config.json.corrupt` — check for that file. Otherwise: + +- An out-of-range number is **clamped**, not applied literally. +- An unrecognised enum value falls back to the default with a log line. +- `scrollback_limit` applies to **new** panes only. +- An unknown action name in `keybindings` is skipped with a warning. + +## Selecting text inside vim / less selects the app's own thing + +Hold while dragging to keep the gesture local, or turn off +**Settings → Terminal → Mouse → Report mouse to apps**. + +## `tty7 capture … | head -1` printed a Rust panic + +An old build's behaviour when the reader hangs up. The data you asked for still +arrived. On such a build, redirect to a file and slice the file instead of +piping into `head`. Current builds exit `141` on Unix, which is exactly what +`cat` does. + +## Still stuck + + + + Ask — someone has probably hit it. + + + Include `tty7 doctor` output and your platform. + + diff --git a/docs/reference/updates.mdx b/docs/reference/updates.mdx new file mode 100644 index 00000000..fc877fda --- /dev/null +++ b/docs/reference/updates.mdx @@ -0,0 +1,97 @@ +--- +title: "Updates" +description: "How tty7 updates itself, and what the two channels mean." +--- + +**Settings → About** is where everything lives: the version you are on, the +channel you follow, and the button that installs what is waiting. + +## How it works + + + + tty7 checks at launch and every six hours after that. Turn it off entirely + with `check_for_updates: false`, or check on demand with **Check now**. + + + A found release is fetched and verified before you are asked to do anything + — which turns "spend five minutes downloading" into "press restart". + Nothing is ever *installed* without an explicit choice; the staged package + waits in Settings. + + Turn this off on a metered connection: the packages run 25–30 MB. + (`auto_download_updates: false`) + + + A dedicated `tty7-updater` helper verifies the release checksum, the bundle + version, and — on macOS — the code-signing requirement, before replacing the + installation. If the relaunch fails, it puts the previous copy back. + + + +Declining an update defers it rather than retiring it; it comes back later. + +## Channels + +**Settings → About → Update channel.** + +| | | +|---|---| +| **Stable** *(default)* | Published releases. Reads `/releases/latest`, which excludes prereleases. | +| **Nightly** | Rebuilt from the latest code every night — newer, but not release-tested. Reads the rolling `nightly` tag. | + +The channel is a property of your **installation**, not something inferred from +how version numbers sort. Neither feed can hand the other an update, so a +Nightly is never walked back onto Stable by an update it did not ask for, and an +installation only changes channel when you change it. + +Switching channels invalidates what the old feed produced: the staged package, +the deferred prompt, and any transfer still in flight. + + + A stable release outranks every dated build of its core version, which is how + switching back to Stable *graduates* rather than downgrades. + + +## Platform notes + + + + The new GUI reuses a running local server when its wire protocol is + compatible, so your shells survive the update. An incompatible server keeps + its shells too and raises an explicit keep-or-restart prompt. + + + Windows cannot replace a running daemon's image, so the install path stops + the service first — and the dialog says so before you agree. + + An all-users `C:\Program Files` install cannot be updated in place and keeps + the release-page fallback instead. Running Setup as the signed-in user would + either install a second copy beside the real one, or put a bare UAC prompt + in front of someone whose GUI just vanished. + + + AppImage and tarball installs are replaced by downloading the new file. + + + +## "The background server is still running <build>" + +If Settings tells you this, tty7 was updated in place: the app is the new build, +but your panes are still served by the previous one. Restarting the server picks +up the new one — **and ends every process running in your panes**, shells, +agents, and SSH sessions alike. + +There is no hurry. Pick a moment when your panes are idle. + +## Proxies + +Update checks and downloads resolve a proxy from, in order: + +1. `http_proxy` in `config.json` — `http://127.0.0.1:7890` or + `socks5://127.0.0.1:1080` +2. The platform system proxy (Windows registry, macOS `SCDynamicStore`) +3. `HTTP_PROXY` / `HTTPS_PROXY` / `ALL_PROXY` + +Programs running in a pane are deliberately unaffected — they inherit their +proxy from their own environment, as in any other terminal. diff --git a/docs/remote/port-forwarding.mdx b/docs/remote/port-forwarding.mdx new file mode 100644 index 00000000..b23cbc95 --- /dev/null +++ b/docs/remote/port-forwarding.mdx @@ -0,0 +1,61 @@ +--- +title: "Port forwarding" +description: "Local, remote, and dynamic forwards — preconfigured or added mid-session." +--- + +## The three kinds + +| | What it does | +|---|---| +| **Local** (`L`) | A port on this machine reaches a service on the remote side | +| **Remote** (`R`) | A port on the remote machine reaches a service here | +| **Dynamic** (`D`) | A SOCKS proxy on this machine, routed through the connection | + +## Adding one to a profile + +**Settings → SSH →** a profile **→ Port forwarding → + Add rule**. Rules saved +here open with the connection, every time. + +A Local or Remote rule needs a listen port and a target; a Dynamic rule needs +only the listen port. An incomplete rule tells you so rather than being saved +half-configured. + +Each rule takes an optional description — *"what it's for"* — because six months +later `8080 → 3000` explains nothing. + +## Adding one mid-session + +*SSH: Port Forwarding* in the command palette opens the **Forwards** panel for +the current connection. Add a rule there and it starts immediately; remove it +and it stops. These live only as long as the session unless you save them into +the profile. + + + The forwards panel + + +## The one-click shortcut + +-clicking a `localhost:PORT` link inside an SSH pane can open a +temporary forward for exactly that port and then open the browser — turn on +**Settings → Input → Links → Forward SSH loopback links**. + +That is the right tool for "let me look at this dev server once". For something +you use every day, put it in the profile. + +## Jump hosts and proxies + +Multi-hop connections are configured per profile: + +- **Jump host** — point at another saved profile, or use a `ProxyJump` chain +- **ProxyCommand** — an arbitrary transport command, with `%h`, `%p`, `%r` + substituted +- **SOCKS5 proxy** / **HTTP proxy** — `host:port`, under **Advanced → Proxies** + + + These proxy settings are for reaching the SSH server. tty7's *own* network + traffic — update checks, release downloads, remote-server installs — uses + `http_proxy` in `config.json`, the system proxy, or the `HTTP_PROXY` family. + Programs running in a pane are unaffected either way; they inherit their proxy + from their own environment, as in any terminal. + diff --git a/docs/remote/sftp.mdx b/docs/remote/sftp.mdx new file mode 100644 index 00000000..b7963868 --- /dev/null +++ b/docs/remote/sftp.mdx @@ -0,0 +1,48 @@ +--- +title: "SFTP" +description: "A file browser for the machine on the other end of the connection." +--- + +While a pane is in an SSH session, *SSH: Remote Files* (command palette) slides +a file panel in over it. It is a real SFTP client on the same connection — no +second login, no second password. + + + The tty7 SFTP panel + + +## Browsing + +The panel opens on the remote home directory. **Go to Shell Directory** in the +overflow menu jumps it to wherever the pane's shell currently is, which is +usually where you actually want to be. + +Right-click a row for **Open**, **Follow Symlink**, **Rename**, **chmod…**, and +delete. The overflow menu adds **New Folder**, **New File**, **Upload…**, and +**Refresh**. + +## Transferring + +| Direction | How | +|---|---| +| Download | Drag a file out of the panel into Finder or Explorer | +| Upload | **Upload…**, or drag files into the panel | + +Uploads are written under a temporary name and renamed into place at the end, so +a half-finished file never looks like a finished one. A name that is already +taken asks before replacing. + +**Transfer History** in the overflow menu shows every transfer with its +progress, and lets you cancel one in flight. The panel header summarises what is +happening — *"2 transferring · 64%"*. + +## Permissions + +**chmod…** takes an octal mode (`755`, `600`). The current mode is shown in the +row's editor before you change it. + + + For files in a [remote workspace](/remote/workspaces) you can often skip SFTP + entirely — the Files panel reads and writes across the link directly, and the + built-in editor saves back to the remote machine. + diff --git a/docs/remote/ssh.mdx b/docs/remote/ssh.mdx new file mode 100644 index 00000000..ed44a8ab --- /dev/null +++ b/docs/remote/ssh.mdx @@ -0,0 +1,115 @@ +--- +title: "SSH" +description: "A native Rust SSH stack: quick connects, saved profiles, keychain credentials, jump hosts." +--- + +tty7 speaks SSH itself, over [russh](https://github.com/Eugeny/russh). It never +shells out to the `ssh` binary, and there is no compatibility mode that does. + +That is what makes the rest possible: credentials in the OS keychain, +[SFTP](/remote/sftp) in a side panel, [port forwards](/remote/port-forwarding) +you can add mid-session, and authentication prompts drawn as sheets in the pane +instead of a password echoing into your shell. + + + Connecting over SSH in tty7 + + +## Four ways to connect + + + + Open the palette (⌘ P) and type an address. IPv6 works with + brackets. + + ``` + me@devbox + me@devbox:2222 + me@[2001:db8::1]:22 + ``` + + + + Profiles live in **Settings → SSH → Hosts**. Start typing the name in the + palette, or open the *SSH: Manage Profiles…* command. + + + + Type an alias you already have and tty7 resolves it natively — common fields, + best effort — then connects over russh. **Settings → SSH → Import from + ~/.ssh/config** turns aliases into real profiles. + + + `Match`, `canonicalize*`, and GSSAPI directives are not supported, and + there is no fallback to the system `ssh` when one appears. + + + + + The same connection can host whole workspaces on the far machine rather than + a single shell. [Remote workspaces →](/remote/workspaces) + + + +## Profiles + +**Settings → SSH → Hosts** holds the full connection config. The basics: + +| Field | | +|---|---| +| **Name** | A label for this connection | +| **Host** | Hostname or IP | +| **User** | Login user — blank resolves at connect time | +| **Auth** | *Auto* (tries every applicable method), *Password*, *Key*, *Agent*, or *2FA* | +| **Jump host** | Another profile, or a `ProxyJump` chain | +| **Port forwarding** | Rules opened with the connection | + +**Defaults** at the top of the list is inherited by every host, so a setting you +want everywhere is set once. + +Passwords and key passphrases go in the **OS keychain**, never in +`config.json` and never on disk in plain text. **Forget Password** in a +profile's menu removes the stored one. + +### Advanced + +Behind **Advanced** on a profile, grouped: + +| Group | Fields | +|---|---| +| **Authentication** | Identity files (one path per line, `%h`/`%r` expand), agent forwarding | +| **Proxies** | ProxyCommand (`%h`/`%p`/`%r` substituted), SOCKS5 proxy, HTTP proxy | +| **Algorithms** | KEX algorithms, ciphers, MACs, host-key algorithms, compression | +| **Connection** | Keepalive interval and count, connect timeout, X11 forwarding | +| **Session** | Shell integration, login scripts, skip banner | + +Everything blank means "the library default", so you only fill in what you +actually need to override. + +## Authentication prompts + +Password, key passphrase, and 2FA prompts appear as sheets inside the pane, with +a **Remember (keychain)** option where it makes sense. + +## Host keys + +Host keys are verified against `known_hosts` by default. A first connection asks +you to confirm the fingerprint; a **changed** key is a much louder prompt that +makes you type `yes` to override, because that is what a changed key deserves. + +**Settings → SSH → Security → Verify host keys** turns verification off +entirely. It is on for a reason. + +Also under Security: **Warn before closing** a live connection, off by default. + +## Reconnecting + +⌘ ⇧ R — or *SSH: Reconnect* in the palette — restarts the session in +the current pane. Useful after a laptop sleeps or a network changes. + +## What is not supported + +- No fallback to the system `ssh` binary +- No `Match`, `canonicalize*`, or GSSAPI directives from `~/.ssh/config` +- Kerberos `gssapi-with-mic` is offered by the desktop app for managed + connections, but is not part of the `~/.ssh/config` resolution path diff --git a/docs/remote/workspaces.mdx b/docs/remote/workspaces.mdx new file mode 100644 index 00000000..ff24780d --- /dev/null +++ b/docs/remote/workspaces.mdx @@ -0,0 +1,114 @@ +--- +title: "Remote workspaces" +description: "Whole workspaces hosted on another machine — files, repos, panes, and git all stay over there." +--- + +An SSH pane runs one shell on a remote machine. A **remote workspace** goes +further: tty7 runs a server on the far machine, and the whole workbench points +at it. Tabs, splits, the file tree, the git panel, the diff overlay, the process +list — all of it is the remote machine's, rendered here. + +Nothing is synced or copied. The repository stays where it is. + + + A remote workspace in tty7 + + +## Connecting + + + + ⌘ ⇧ O. Machines are listed alongside your local workspaces — + *This Computer* first, then every saved SSH profile and, on Windows, every + WSL distribution. + + + tty7 connects over the same SSH stack as everything else, so profiles, + keychain credentials, and jump hosts all apply. + + + The first connection asks: + + > tty7 will write its server binary to *devbox* so this machine can host + > workspaces there. Nothing else on *devbox* is touched, and no sudo is + > used. + + It shows the exact path, version, size, source, and SHA-256 before you + agree. Later upgrades on that machine install silently. + + + From then on the machine's workspaces are in the switcher, and a new one + opens like a local one. + + + +## What gets installed + +| | | +|---|---| +| **What** | A single static `tty7-server` binary | +| **Where** | `~/.local/share/tty7/bin/tty7-server-cp` | +| **Privileges** | None. No sudo, nothing outside your home directory | +| **Hosts** | Linux, x86-64 or aarch64 | + +The binary is named after the wire dialect it speaks, so a client and a server +that disagree never quietly half-work — tty7 installs the matching one instead. + +On Windows, a WSL distribution is handed the Linux server the installer already +shipped, so a WSL workspace needs no network access at all. + +## Reattaching + +Remote workspaces are the point at which persistence pays off twice: the panes +survive on the remote machine whether or not your laptop is awake, and you can +reattach from a different client entirely. + +A strip along the top of the window says what the connection is doing — +*connecting*, *reconnecting (attempt 3)*, *disconnected*, or *taken over by +someone else*. Reconnection is automatic; a workspace another client has claimed +says so by name rather than fighting over it. + +## Keeping the server current + +Two dialogs you may meet: + + + + The machine is serving sessions from a build whose protocol this client + cannot speak. tty7 has already installed a matching server, but the one + already running is the one your sessions are on. **Update Server** replaces + it and **ends every session it is hosting** — including ones this window is + not showing. Cancel leaves the machine exactly as it is. + + + Same consequence, deliberately: every shell on that machine ends. Workspaces + and layouts are kept and come back with fresh shells. + + + + + Both of these end other people's work if the machine is shared. tty7 spells + out what will happen before either one runs — read it. + + +## What a remote pane cannot do + +- **Fork an agent session.** The fork command would run against the *local* + agent, so tty7 does not offer it. +- **Move very large files through the Files panel.** Drag-and-drop across the + link is capped at what one control frame can carry; past that the panel tells + you to use [SFTP](/remote/sftp). + +## From the CLI + +```bash +tty7 machine ls # this machine plus every link the server holds +tty7 -m devbox ls # route any command to a linked machine +tty7 -m devbox run -- cargo test +``` + +`-m` matches the full link key (`me@devbox:22`) or just the host. It uses a link +the local server *already* holds — it will not dial a fresh connection, and it +says so rather than guessing. Connect from the switcher first. + +[CLI overview →](/cli/overview) diff --git a/docs/terminal/history.mdx b/docs/terminal/history.mdx new file mode 100644 index 00000000..4b3f1433 --- /dev/null +++ b/docs/terminal/history.mdx @@ -0,0 +1,57 @@ +--- +title: "History" +description: "Fuzzy history search, and whether each pane gets its own." +--- + +## Fuzzy search with ⌃ R + +⌃ R opens a fuzzy search over what you have actually run. Type any +fragment — the letters do not have to be adjacent — and the list narrows. + +Each row carries the context the plain shell version throws away: + +- **where** you ran it, so `npm run dev` from three repositories is three + distinct entries +- **when**, as a relative time +- **whether it failed**, from the exit code + +Ranking mixes frequency with recency, and commands you ran in the *current* +directory are pushed up — the thing you want is usually the thing you last did +here. + + + Fuzzy history search + + + puts the command on the prompt. Esc closes without +touching it. + +### Handing ⌃ R back + +If you already have an fzf, percol, atuin or McFly binding you like, turn off +**Settings → Input → Prompt → History search** (`history_search: false`). +⌃ R then goes to the shell, and whatever you bound there keeps +working. + +## Where the history comes from + +Your existing shell history file, as-is. Nothing is imported or converted, there +is no separate store to warm up, and a history written outside tty7 shows up +immediately. + +## One history, or one per pane + +By default every pane shares your shell's history file, which is what a terminal +has always done: a command typed in one pane is available in the next. + +**Settings → Terminal → Give each pane its own shell history** +(`per_pane_history: true`) changes that. Each pane gets a private history file: + +- **seeded** from your real history when the pane opens, so it is not blank +- **merged back** into your real history when the pane closes, so nothing typed + is lost + +Useful when several agents or several tasks are running side by side and you do +not want their commands interleaved in your key. Off by default, +because someone who has not asked for it would experience the change as their +history mysteriously forgetting the other window. diff --git a/docs/terminal/links.mdx b/docs/terminal/links.mdx new file mode 100644 index 00000000..0b8c3d34 --- /dev/null +++ b/docs/terminal/links.mdx @@ -0,0 +1,51 @@ +--- +title: "Links" +description: "Opening URLs, files, and localhost ports straight out of the terminal." +--- + +Hold (Ctrl on Windows and Linux) and links under the +pointer underline; click to open one. + +## URLs + +Anything that looks like a URL is detected, including one the shell wrapped +across two lines — tty7 stitches it back together before opening it. + +Turn detection off with **Settings → Input → Links → Detect URLs** +(`link_url: false`). + +## Files + +A file path in the output — a compiler error, a test failure, a `grep -n` hit — +opens in your default application for that file type. + +To send it somewhere specific instead, set **Settings → Input → Links → Open +files with**. The command runs with placeholders substituted: + +``` +code --goto {path}:{line}:{column} +zed {path}:{line} +herdr edit {path} --line={line} +``` + +`{path}`, `{line}`, and `{column}` are filled in from the link. A flag whose +value is not available is dropped rather than passed empty — so +`--line={line}` simply disappears when the link had no line number. Leave the +field blank to go back to the default application. + +The same setting is `link_file_command` in `config.json`. + +## localhost ports + +-clicking `localhost:3000` opens it in your browser, which is only +useful if the server is on this machine. + +When the pane is inside an SSH session it usually is not. Turn on **Settings → +Input → Links → Forward SSH loopback links** (`ssh_loopback_forward: true`) and +tty7 opens a temporary port forward through that connection first, so the link +reaches the server on the remote machine. + + + For a forward you want to keep, set one up properly instead — + [port forwarding](/remote/port-forwarding). + diff --git a/docs/terminal/mouse-and-scrolling.mdx b/docs/terminal/mouse-and-scrolling.mdx new file mode 100644 index 00000000..fa842da3 --- /dev/null +++ b/docs/terminal/mouse-and-scrolling.mdx @@ -0,0 +1,69 @@ +--- +title: "Mouse, scrolling, and the bell" +description: "How the pointer, the wheel, and ^G behave — and how to change each." +--- + +## Scrolling + +The wheel and trackpad scroll the pane's scrollback. All of it lives under +**Settings → Terminal → Scrolling**: + +| Setting | Default | What it does | +|---|---|---| +| **Scrollback** | 10,000 lines | How much history each pane keeps, up to 100,000. Applies to new panes. | +| **Scroll speed** | 1.0 | A multiplier on wheel scrolling (0.1–10). | +| **Smooth scrolling** | On | Eases each wheel notch into place over a few frames instead of jumping the whole way. Trackpads scroll continuously already and are unaffected. | + + plus the wheel zooms the font instead of scrolling. + +## The pointer + +Under **Settings → Terminal → Mouse**: + +| Setting | Default | What it does | +|---|---|---| +| **Focus follows mouse** | Off | Hovering a pane focuses it without a click. | +| **Hide mouse while typing** | On | The pointer disappears as you type and returns on the next move. | +| **Report mouse to apps** | On | Full-screen programs — vim, tmux, `htop` — get clicks and scroll events themselves. Hold to keep a gesture local and select text instead. | + + + If selecting text inside `vim` or `less` grabs the app's own selection instead + of yours, hold while you drag. + + +## Font size + +| | | +|---|---| +| ⌘ + · ⌘ − | Bigger · smaller | +| ⌘ 0 | Back to the configured size | +| + wheel | Zoom by scrolling over a terminal | + +The base size is **Settings → Appearance → Typography → Font size**, 15 px by +default. The rest of the interface has its own size — **Interface font size**, +16 px, adjustable from 12 to 24 — so you can scale the chrome without touching +the terminal grid, or the other way round. + +## The bell + +**Settings → Terminal → Bell → Terminal bell** decides what `^G` does: + +| Mode | Behaviour | +|---|---| +| **Off** | Nothing | +| **Visual** *(default)* | A brief flash | +| **Audible** | The system sound | +| **Both** | Flash and sound | + +## Command-finished notifications + +**Settings → Window & Tabs → Notifications** posts a desktop notification when a +foreground command finishes: + +- **Notify on command finish** — *Never*, *When unfocused* (default), or + *Always* +- **Notify threshold** — how long a command has to run to qualify, 10 seconds by + default + +Coding agents use the same policy for their own notifications. +[Agent status →](/agents/status) diff --git a/docs/terminal/prompt.mdx b/docs/terminal/prompt.mdx new file mode 100644 index 00000000..e430c190 --- /dev/null +++ b/docs/terminal/prompt.mdx @@ -0,0 +1,130 @@ +--- +title: "The prompt" +description: "Ghost suggestions, tab completion that explains itself, syntax highlighting, and real multi-line editing." +--- + +tty7 puts an editor at the shell prompt. Nothing to install, no plugin to source +— the moment a supported shell starts in a pane, the prompt behaves like this. + + + The tty7 prompt + + +## Ghost suggestions + +As you type, the rest of the line is filled in from your history, greyed out +ahead of the cursor. + +| | | +|---|---| +| | Accept the whole suggestion | +| Keep typing | The suggestion narrows | +| Esc or anything that does not match | It disappears | + +Your existing shell history is what feeds it — there is no separate database to +build up first, and it carries across sessions and reboots. + +## Tab completion, with descriptions + + opens a completion menu that knows what it is offering: + +- **Commands** from your PATH and your shell's builtins +- **Files and directories**, with `cd`, `pushd`, `popd`, and `rmdir` offering + directories only +- **Flags and subcommands** with their descriptions, for about 100 common + commands — `git`, `cargo`, `docker`, `kubectl`, `npm`, `brew` and the rest +- **Values** where a flag only takes certain ones + + + Explained tab completion + + +When tty7 has nothing useful to offer, the falls through to your +shell's own completion, so a carefully configured zsh setup is not lost. + +To hand back to the shell entirely, turn off **Settings → Input → +Prompt → Tab completion** (`tab_completion` in `config.json`). + +## Syntax highlighting + +The line you are typing is coloured as you type it: the command, its flags, its +arguments, paths, quoted strings, operators, comments. It is a fast tokenizer, +not a shell parser — it never changes what gets run. + +## Line editing + +The prompt behaves like a text field, because it is one: + +- **Click to place the caret** anywhere in the line +- **Select with the mouse**, drag to extend +- **Word motion** and word delete +- **Undo** + +Everything readline does still works — this sits on top, it does not replace it. + + + On macOS, turn on **Settings → Input → Keyboard → Option (⌥) acts as Meta** if + you want ⌥ B / ⌥ F to move by word instead of typing + `∫` and `ƒ`. + + +## Typing with an IME + +Pinyin, Kana, Hangul and the rest work in a pane the way they do in a text +field: the composition is drawn in place at the cursor and only the committed +text reaches the program. + +Two rules decide who gets a keystroke: + +- **A plain printable key goes to the IME.** A key held with , + , fn, or does not — those are chords, not + characters. +- **A program that asks for every key gets every key.** When something turns on + the kitty keyboard protocol's report-all-keys mode, the IME steps aside so the + program sees raw input. + + + On macOS with **Option (⌥) acts as Meta** turned on, chords + bypass the IME entirely, so ⌥ B reaches your shell as meta-b + instead of being eaten as a dead key. + + +Rendering CJK well is a separate question — see +[fonts and the two-column grid](/customization/fonts#cjk-and-the-two-column-grid). + +## Multi-line commands + +A command that wraps, or one you deliberately break across lines, edits in +place. The grid shifts to keep the caret visible instead of scrolling the whole +screen away. + +| | | +|---|---| +| ⇧ ⏎ · ⌥ ⏎ | Insert a newline instead of submitting | +| | Submit the whole buffer, however many lines it is | + +The newline key is rebindable as `InsertNewline` under **Settings → +Keybindings**. + +## Which shells + +The prompt features arrive through tty7's shell integration, which is injected +automatically — nothing to add to your rc file — for **zsh**, **bash**, +**fish**, **PowerShell**, and **WSL**. Other shells (nushell, elvish, xonsh, and +the rest) run perfectly well in a pane; they simply do not get the prompt layer. + +The integration is also what reports the working directory, the exit code of +each command, and where prompts begin — which is what the sidebar's branch +readout, the "command finished" notification, and `tty7 procs` are built on. + +[How shell integration works →](/reference/shell-integration) + +## Turning it off + +Both prompt features are switches, and turning one off hands its key straight +back to the shell: + +| Setting | Key it releases | +|---|---| +| **Settings → Input → Prompt → Tab completion** | → your shell's completion | +| **Settings → Input → Prompt → History search** | ⌃ R → your shell's reverse-i-search, or your fzf binding | diff --git a/docs/terminal/selection-and-clipboard.mdx b/docs/terminal/selection-and-clipboard.mdx new file mode 100644 index 00000000..30856770 --- /dev/null +++ b/docs/terminal/selection-and-clipboard.mdx @@ -0,0 +1,62 @@ +--- +title: "Selection and clipboard" +description: "Smart double-click, copy on select, and the settings around them." +--- + +## Selecting + +| | | +|---|---| +| Drag | Select a range | +| Double-click | Select the thing under the cursor — see below | +| Triple-click | Select the line | +| -click | Extend the current selection to where you clicked | +| ⌘ A *(macOS)* | Select all — also in the right-click menu and the command palette on every platform | + +### Smart double-click + +A double-click does not just grab a word bounded by spaces. It works out what +you are pointing at: + +| Under the cursor | What you get | +|---|---| +| A URL | The whole URL — including one the shell wrapped across two lines | +| A file path | The whole path | +| An email address | The whole address | +| A bracket or quote | The matching pair, and everything between them | +| CJK text | The word, segmented by dictionary rather than by character | + +Turn it off with **Settings → Input → Selection & clipboard → Smart selection**. +With it off, double-click falls back to plain word selection using the +`word_separators` list from `config.json` — by default: + +``` +,│`|:"' ()[]{}<>⇥ +``` + +## Copying and pasting + +| | macOS | Windows / Linux | +|---|---|---| +| Copy | ⌘ C | Ctrl ⇧ C | +| Paste | ⌘ V | Ctrl ⇧ V · ⇧ Insert | + +Two settings shape what lands where, both under **Settings → Input → Selection +& clipboard**: + + + + Selecting with the mouse copies immediately, no ⌘ C. Off by + default. + + + Strips trailing whitespace from every copied line — useful when copying out + of a TUI that pads to the pane width. Off by default. + + + + + Pasting multiple lines sends them as typed input, exactly as any terminal + does. If the shell supports bracketed paste it will treat the block as one + paste rather than running each line. + diff --git a/docs/window/command-palette.mdx b/docs/window/command-palette.mdx new file mode 100644 index 00000000..154eb289 --- /dev/null +++ b/docs/window/command-palette.mdx @@ -0,0 +1,58 @@ +--- +title: "Command palette" +description: "One key for every action in the app — including the ones with no shortcut." +--- + +⌘ P opens the command palette. Type to filter, + to move, to run. + +Every action tty7 can perform is in here, whether or not it has a keybinding — +which makes it the fastest way to reach the ones that deliberately ship unbound, +like pane resize and swap. + + + The tty7 command palette + + +## What is in it + +Results are grouped, and the groups are the map of the app: + +| Group | Examples | +|---|---| +| **Tabs & Panes** | New Tab · New Worktree Tab… · Split Right · Zoom Pane · Focus Pane Left · Resize Pane Up · Swap Pane Next · Reopen Closed Tab · Copy Working Directory · Fork Session | +| **Workspaces** | New Workspace · Switch Workspace… · Rename Workspace… · Stop Workspace… · Delete Workspace… | +| **View** | Show/Hide Left Sidebar · Show/Hide Right Panel · Show Code Panel · Tab Bar: Move to Top · Right Panel: Info / Changes / Files · Change Theme… · Enter Full Screen · Toggle Unified / Side-by-Side Diff | +| **Git** | Commit · Stage All Changes · Unstage All · Discard All · Checkout to… · Create Branch… · Sync · Push · Pull · Fetch · Toggle Commit History | +| **Terminal** | Clear Scrollback · Find in Terminal… · Find Next / Previous · Copy · Cut · Paste · Select All | +| **SSH** | Add Connection… · Manage Profiles… · Reconnect · Remote Files · Port Forwarding | +| **Agents** | Send Selection · Send Git Diff for Review · Copy Session ID | +| **Application** | Settings… · Keyboard Shortcuts · Check for Updates… · Documentation · Join the Discord · Report an Issue… · Restart Server… | + +Entries that do something destructive say so under the name — *Delete +Workspace…* is subtitled "ends its shells and forgets the layout", *Restart +Server…* is "ends every running shell; layout is kept". + +## Connecting from the palette + +Type an SSH address and the palette offers to connect to it: + +``` +me@devbox +me@devbox:2222 +[::1]:22 +``` + +Saved profiles and `~/.ssh/config` aliases show up the same way — start typing +the name. [SSH →](/remote/ssh) + +## Sending context to an agent + +Two palette commands hand what is in front of you to the coding agent running in +the pane, as a ready-made prompt: + +- **Agent: Send Selection** — the current selection. +- **Agent: Send Git Diff for Review** — the repository's `git diff`. + +If no agent is running, tty7 says so rather than typing into your shell. +[Agents →](/agents/overview) diff --git a/docs/window/search.mdx b/docs/window/search.mdx new file mode 100644 index 00000000..ad4d4f81 --- /dev/null +++ b/docs/window/search.mdx @@ -0,0 +1,50 @@ +--- +title: "Search" +description: "Finding text in the scrollback, and everything else the search boxes cover." +--- + +## In the terminal + +⌘ F opens the find bar over the focused pane and searches its whole +scrollback, not just the visible screen. + +| | | +|---|---| +| · ⌘ G | Next match | +| ⇧ ⏎ · ⌘ ⇧ G | Previous match | +| Esc | Close the find bar | + +Two toggles sit in the bar: + +- **Match case** — off by default, so a lowercase query matches anything. +- **Use regular expression** — the query becomes a regex. An invalid pattern is + shown as an error rather than silently matching nothing. + +Matches are highlighted in place and the view scrolls to each one as you step +through. On Windows and Linux the shortcuts are Ctrl ⇧ F to open, +F3 and ⇧ F3 to step. + + + Searching the scrollback + + + + How much there is to search is **Settings → Terminal → Scrolling → + Scrollback** — 10,000 lines per pane by default, up to 100,000. The change + applies to new panes. + + +## Everywhere else + +tty7 leans on the same pattern in a lot of places. All of them are +type-to-filter, no button to press: + +| Where | What it searches | +|---|---| +| ⌘ P | Commands — and SSH addresses you type in full | +| ⌘ ⇧ O | Workspaces, tabs, and machines | +| ⌃ R | Your shell history, fuzzily — [see History](/terminal/history) | +| Settings search box | Every setting, by name and by keyword | +| Files panel | Files under the workspace root | +| Theme picker | Built-in and custom themes | +| Font picker | Fonts installed on your system | diff --git a/docs/window/side-panel.mdx b/docs/window/side-panel.mdx new file mode 100644 index 00000000..11bacee7 --- /dev/null +++ b/docs/window/side-panel.mdx @@ -0,0 +1,66 @@ +--- +title: "The side panel" +description: "Info, Source Control, and Files — plus the built-in editor." +--- + +⌘ J opens a panel on the right of the window with three tabs. It is +hidden by default; whichever tab you leave it on is where it opens next time. + + + The tty7 side panel + + +## Info + +Everything tty7 knows about the focused pane, in one column: + +| Section | What it shows | +|---|---| +| **Session** | working directory, shell, SSH connection, git branch, `+N −M` changes, and the coding agent with its status (idle / working / waiting / done) | +| **Processes** | the process tree inside the pane, with the foreground process marked | +| **Ports** | every port those processes are listening on | + +The working directory row has **Reveal in Finder** / **Open Folder** beside it. +The ports section is the quickest answer to "what is this pane serving, and +where" — the same data `tty7 procs` prints. + +## Source Control + +The git panel for the focused pane's repository: staged changes, unstaged +changes, untracked files, and merge conflicts, each in its own group. Write a +message, commit, and push without leaving the window. + +[Source control →](/git/source-control) + +## Files + +A file tree rooted at the pane's working directory, with git status decorations +on every row and a search box at the top. + +- **Click a file** to open it in the built-in editor. +- **Drag a file out** to Finder or Explorer to copy it there. +- **Drag files in** from the desktop to copy them into the folder under the + cursor. A folder row takes them itself, a file row stands in for the folder + holding it, and the empty space below the tree means the top of it. Folders + come in whole, the executable bit survives, and a name that is already taken + is asked about rather than replaced. + +Both directions work over a [remote workspace](/remote/workspaces) too, reading +on one machine and writing on the other, up to the size one control frame can +carry — past that the panel tells you to use [SFTP](/remote/sftp). + +## The editor + +⌘ ⇧ E toggles the code panel; clicking a file in the Files tab opens +it there. It is a real editor — syntax highlighting, line and column readout, +wrap toggle, and a Markdown preview — meant for the edit you would otherwise +have opened `vim` for. + +| | | +|---|---| +| ⌘ S | Save | +| Esc | Back to the terminal | + +Files are watched on disk: a change underneath you is picked up, and closing +with unsaved edits asks before discarding them. Files over 4 MB and anything +that looks binary are refused with a note rather than opened badly. diff --git a/docs/window/sidebar.mdx b/docs/window/sidebar.mdx new file mode 100644 index 00000000..9b49e427 --- /dev/null +++ b/docs/window/sidebar.mdx @@ -0,0 +1,76 @@ +--- +title: "The sidebar" +description: "Tabs grouped by repository, with branch, diff counts, and agent status on every row." +--- + +The left sidebar is tty7's tab bar, and it is the default because a vertical row +has room for things a horizontal chip does not: the repository a tab belongs to, +the branch it is on, how much has changed there, and what a coding agent in it +is doing. + +⌘ B shows and hides it. Drag its right edge to resize. + + + The tty7 tab sidebar + + +## Grouped by repository + +Rows sit under a header per git repository, with everything else collected in a +trailing **Scratch** section. The grouping follows the tab's working directory, +not its history — switching branches or `cd`-ing around inside a repository +never moves a row out from under its header. + +**Settings → Window & Tabs → Sidebar grouping** switches between *By repo* (the +default) and *Flat*. + +## What a row tells you + + + + A brand avatar when a coding agent is in the tab, plus a status dot — + blue for working, amber for needs-your-input, green for done. + + + The pane's git branch, refreshed on `cd` and whenever a command finishes. + + + The working-tree diff as `+N −M`. Click the counts to open the + [diff overlay](/git/diffs). + + + An unread marker on tabs that produced output while you were elsewhere. + *Mark as Unread* is in the right-click menu. + + + +If you would rather the counts not be clickable, turn off **Settings → Window & +Tabs → Open diff preview from sidebar counts**. The branch and the numbers stay; +they simply stop opening the overlay. + +## Rearranging + +Drag a row to reorder it, or drag a whole group header to move the group. +Dropping a row into another group moves the tab there. + +## Naming + +Almost no tab has a name of its own, so the label falls back through the best +evidence available, in order: + +1. a name you set (right-click → **Rename Tab…**) +2. the coding agent running in the tab — "Claude Code" +3. the last segment of the working directory +4. the foreground process + +That order is also what `tty7 tab ls` reports as `label`, with `name` left +literal so a script can tell a real name from a stand-in. + +## The switcher + +⌘ ⇧ O opens the workspace switcher: every workspace on every machine +you are connected to on the left, that workspace's tabs on the right. Type to +filter both, to cross into the tab column, to open. + +From here you can also rename a workspace, open one in a new window, stop one, +or connect to a machine you have a profile for. diff --git a/docs/window/tabs-and-splits.mdx b/docs/window/tabs-and-splits.mdx new file mode 100644 index 00000000..423fe05d --- /dev/null +++ b/docs/window/tabs-and-splits.mdx @@ -0,0 +1,99 @@ +--- +title: "Tabs and splits" +description: "Opening, arranging, and rearranging the panes in a tab." +--- + + + Keys are written in macOS notation. On Windows and Linux, read as + Ctrl ⇧ for most window actions — the exact chords are on the + [keyboard shortcuts](/reference/keyboard-shortcuts) page. + + +## Tabs + +| | | +|---|---| +| ⌘ T | New tab | +| ⌘ W | Close the tab (or the focused pane, if the tab has more than one) | +| ⌘ ⇧ T | Reopen the tab you just closed | +| ⌘ 1⌘ 9 | Jump to tab 1–9 | +| ⌃ ⇥ · ⌃ ⇧ ⇥ | Hold to walk the switcher forwards or backwards; it commits when you let go | + +A new tab always opens in the current pane's directory. Where it lands in the +list is **Settings → Window & Tabs → New tab position** — *After current* by +default, or *At end*. + +Right-click a tab for the rest: rename, close others, close to the right, copy +the working directory, mark unread, and — when a coding agent is running there — +fork its session. + +## Splits + +| | | +|---|---| +| ⌘ D | Split right | +| ⌘ ⇧ D | Split down | +| ⌘ ] · ⌘ [ | Next pane · previous pane | +| ⌘ ⌥ ← → ↑ ↓ | Focus the pane in that direction | +| ⌘ ⇧ ⏎ | Zoom the focused pane to fill the tab | +| ⌘ ⏎ | Fullscreen the window | + +A split inherits the current pane's working directory, so splitting inside a +repository keeps you in the repository. + +Resizing and swapping panes have no default keys — bind them under **Settings → +Keybindings**, or run them from the command palette (*Resize Pane Left*, *Swap +Pane Next*, and friends). + +Inactive panes are dimmed slightly so the focused one is obvious. Turn that off +with **Settings → Appearance → Dim inactive panes**. + +## Rearranging by dragging + +Hover a pane and a small grip appears along its top edge. Drag it to move that +pane somewhere else in the tab. + + + Dragging a pane to a new position + + +Where you drop it decides what happens: + + + + The pane goes in **beside** that one. If it is facing a neighbour in the + same row or column, it joins that row and takes an equal share of it. Only + when it faces across the layout — where there is no row to join — does it + split that pane in half. + + + The two panes **trade places**. + + + The band beyond the outermost edge — the side facing the window rather than + another pane — makes the dragged pane a full-width or full-height band + beside everything else, sized to an even share of what that side already + holds. A pane in the middle of a 2×2 becomes a full-height *third* column in + one drag, rather than taking half the window. + + + +The landing lights up while you drag, and only ever lights up when the drop +would actually change the layout. + +## Closing something that is busy + +Closing a pane or tab with a command still running asks first, and says what is +running: *"cargo is still running. Closing ends it."* When a coding agent is +mid-turn it says that instead — *"Claude Code is still working. Closing ends its +turn."* + +## Where the tabs live + +**Settings → Window & Tabs → Tab bar position** puts tabs in a vertical sidebar +on the left (the default) or a horizontal strip on top. The sidebar has room for +things a strip does not — git branch, diff counts, agent status — so most of +[its own page](/window/sidebar) is about that. + +⌘ B toggles the sidebar; ⌘ J toggles the +[side panel](/window/side-panel) on the right.