Files
tty7/Cargo.toml
T
l0ng-ai 649fdef51e Merge branch 'main' into worktree-code-panel
# Conflicts:
#	src/core/config.rs
#	src/ui/mod.rs
#	src/ui/tab_sidebar.rs
#	src/ui/tab_strip.rs
2026-07-24 15:15:08 +08:00

300 lines
14 KiB
TOML

[package]
name = "tty7"
version = "26.7.2"
edition = "2024"
description = "A terminal workbench: shells, persistent sessions, SSH, coding agents — GPU-rendered on Zed's gpui, pure Rust"
repository = "https://github.com/l0ng-ai/tty7"
license = "Apache-2.0"
readme = "README.md"
publish = false
default-run = "tty7"
[[bin]]
name = "tty7"
path = "src/main.rs"
[dependencies]
gpui = { workspace = true }
gpui_platform = { workspace = true }
gpui-component = { workspace = true }
gpui-component-assets = { workspace = true }
anyhow.workspace = true
log.workspace = true
# Smart double-click selection patterns (URL/email/path). Already in the tree
# transitively, so pinning it here adds no new native code.
regex = "1"
smol.workspace = true
smallvec.workspace = true
serde = { workspace = true }
serde_json.workspace = true
# SSH connection-manager data layer (`core::ssh_profile` / `core::keychain`).
# `uuid` mints stable profile ids (v4) and serde-serializes them as strings;
# `sha2` hashes private-key file contents to the sha512-hex account key that
# passphrases are stored under in the OS keychain (per PRD §7.2). Both are already
# in the tree transitively, so pinning them here adds no new native code. `keyring`
# 4.x is the OS credential-vault backend: its default `v1` feature auto-selects the
# platform store (macOS Keychain / Windows Credential Manager / Linux Secret
# Service), so no per-platform feature guards are needed.
uuid = { version = "1", features = ["v4", "serde"] }
sha2 = "0.10"
keyring = "4"
# Theme files. tty7 themes are authored as YAML (`~/.config/tty7/themes/*.yaml`,
# our own schema); `plist` parses imported iTerm2 `.itermcolors` schemes (XML
# plist) so the large iTerm color-scheme ecosystem drops straight in. serde_yaml
# is already in the tree transitively, so it pins no new code; plist is pure Rust.
serde_yaml = "0.9"
plist = "1"
# Clipboard-image paste (`terminal::view`). When the clipboard holds a screenshot
# and a coding-agent TUI (Claude Code &co.) is in the pane, off macOS we stage the
# image to a temp file and paste its path — agents attach an image path the same way
# they do a drag-drop. Windows screenshots arrive as BMP (`CF_DIB`), which agent
# vision won't accept, so we transcode to PNG. `image` is already in the tree via
# gpui's own clipboard code, so pinning it here adds no new native code.
image = "0.25"
# HTTP client for the startup update check (`core::update`): one GET to the
# GitHub releases API to see if a newer version has shipped. `reqwest_client`
# wraps Zed's `zed-reqwest` fork behind gpui's `http_client` trait (re-exported
# as `gpui::http_client`) and manages its own tokio runtime. That reqwest+rustls
# stack is *already* compiled into the tree via `gpui-component-assets`, so this
# pins no new native code — it only exposes what we're already building. Pinned
# to gpui's rev so the shared `http_client`/`zed-reqwest` versions stay aligned.
reqwest_client = { git = "https://github.com/zed-industries/zed", rev = "1d217ee39d381ac101b7cf49d3d22451ac1093fe" }
# Zed's fork of alacritty_terminal — same rev Zed pins. Used by the *client*
# (`terminal::remote`) for the VT parser + grid (`Term`/`ansi::Processor`) that
# renders the mirror. The daemon's PTY itself is driven by `portable-pty` below.
alacritty_terminal = { git = "https://github.com/zed-industries/alacritty", rev = "fcf32feacb367b75ec84dd40f041e4fd411d3cc1" }
# Desktop notifications driven by OSC 9 / OSC 777 escape sequences. Cross-platform;
# the macOS backend uses the deprecated NSUserNotification (weak — a completion
# toast is fine, revisit mac-notification-sys if it proves unusable).
notify-rust = "4"
# Filesystem watcher for live config reload: watches `config.json` and reloads
# `Config` + re-applies the theme without a restart. The code panel (file tree /
# editor, `ui::code`) reuses it to refresh the tree and detect external edits.
notify = "8"
# Code panel (file tree + editor, `ui::code`). `ropey` and `lsp-types` are pinned
# to the exact versions gpui-component uses so its `InputState` rope / LSP
# provider types unify with ours; `ignore` supplies the gitignore matcher chain
# the file tree uses to dim ignored entries (same crate ripgrep uses).
ropey = "=2.0.0-beta.1"
lsp-types = { version = "0.97.0", features = ["proposed"] }
ignore = "0.4"
# `url` does the file-path ↔ `file://` URI conversion for the LSP client
# (percent-encoding, Windows drive letters); already in the tree via gpui.
url = "2"
# Cross-platform PTY for the daemon: a Unix pty on Unix, ConPTY on Windows, behind
# one blocking `Read`/`Write`/`resize` API. This is what lets `daemon::pane` share
# a single code path across platforms instead of hand-rolling fd/ioctl/signal code.
portable-pty = "0.8"
# Native (pure-Rust) SSH client for the daemon's russh session engine
# (`daemon::ssh`). Replaces shelling out to the system `ssh` binary for managed
# connections: it gives us the protocol stack that GUI-hosted auth, host-key
# prompts, in-memory connection reuse, and (later) SFTP / native port-forwarding
# all need. 0.62 folded the old `russh-keys` crate in as `russh::keys` (key
# parsing + ssh-agent client). The async russh session lives on a small tokio
# runtime owned by `daemon::ssh`; the rest of the daemon stays std-threads and
# bridges to it through blocking `Read`/`Write` adapters.
russh = "0.62"
# SFTP client for the native SSH engine (`daemon::ssh::sftp`, Workstream 5).
# Not part of russh proper: `russh-sftp` drives the SFTP subsystem over any
# AsyncRead+AsyncWrite stream, which a russh session channel provides via
# `Channel::into_stream()`. Version-independent of russh (it only needs the
# channel byte stream), so it rides the same tokio runtime `daemon::ssh` owns.
russh-sftp = "2"
# tokio powers only the russh session engine — a single runtime `daemon::ssh`
# owns. The daemon's PTY/reader/writer threads remain std threads and never touch
# it; they cross into async through bounded/unbounded channels (the blocking
# `Read`/`Write` adapters in `daemon::ssh::session`).
tokio = { version = "1", features = [
"rt-multi-thread",
"net",
"io-util",
"sync",
"time",
"macros",
"process",
# `fs` powers the local side of SFTP transfers (`daemon::ssh::sftp`): async
# file/dir IO on the daemon process's own filesystem during upload/download.
"fs",
] }
# SIMD byte search for the OSC tokenizer's Ground/Ignore fast paths — the
# sniffers sit on the full-throughput output stream (100+ MB/s at full drain),
# where a per-byte state machine costs a measurable slice of the reader loop.
# Already in the tree transitively (vte et al.), so this pins no new code.
memchr = "2"
# System tray / menu bar status item (`ui::tray`). Rasterizes the bundled SVG
# logo into the tray bitmap at runtime — gpui's own SVG path only yields a
# tinted alpha mask, not raw RGBA. Pinned to the exact version already in the
# tree via gpui (0.45.x), so this adds no new native code; default features off
# drops the text/font machinery our icon SVGs don't use.
resvg = { version = "0.45", default-features = false }
# The tray icon itself, macOS + Windows: tauri's `tray-icon` (NSStatusItem /
# Shell_NotifyIcon via objc2 / windows-sys, both already in the tree). Linux is
# deliberately NOT on this crate — its Linux backend needs GTK + libappindicator,
# which tty7's AppImage doesn't bundle and the x11/wayland gpui backends don't
# pull. Linux instead uses `ksni` below.
[target.'cfg(any(target_os = "macos", target_os = "windows"))'.dependencies]
tray-icon = "0.24"
# `setsid` (daemon detach) and the macOS foreground-process proc queries are the
# only libc users left, both Unix-only — so the dep is Unix-only too.
[target.'cfg(unix)'.dependencies]
libc = "0.2"
libgssapi = "0.11"
# The Windows GUI⇄daemon transport is loopback TCP, which (unlike a Unix socket)
# any local process can connect to — so the daemon authenticates each connection
# against a random token it writes into the user-private port file. `getrandom`
# is the OS CSPRNG that mints that token; already in the tree transitively, so
# this pins no new code. Windows-only, matching the transport it guards.
[target.'cfg(windows)'.dependencies]
getrandom = "0.3"
# Toolhelp process enumeration + `TerminateProcess`, used by `daemon::winproc` to
# title a pane by its foreground command and to tear down a shell's descendant
# tree on hangup (ConPTY's `kill` only reaches the shell itself). Already in the
# tree via gpui's Windows backend, so this pins no new code. Windows-only.
windows-sys = { version = "0.59", features = [
"Win32_Foundation",
"Win32_System_Console",
"Win32_System_Diagnostics_ToolHelp",
"Win32_System_Threading",
] }
# Embeds `assets/favicon.ico` into the `.exe` so Windows shows the tty7 logo in
# the taskbar / window / Explorer (macOS gets its icon from the `.app` bundle via
# bundle.sh instead). Only needed at build time on Windows — see build.rs.
[target.'cfg(windows)'.build-dependencies]
winresource = "0.1"
# gpui only *reads* the macOS window appearance; it never sets it. We force the
# app appearance to match the active theme (see `ui::theme::sync_native_appearance`)
# so the native traffic-light buttons render in the right light/dark style.
[target.'cfg(target_os = "macos")'.dependencies]
# CFStringTokenizer FFI for dictionary-based CJK word segmentation on
# double-click (`terminal::smart_select`). Already in the tree transitively,
# and it makes jieba unnecessary here — see the non-macos section below.
core-foundation = "0.10"
objc2 = "0.6"
objc2-app-kit = { version = "0.3", features = ["NSApplication", "NSResponder", "NSAppearance", "NSGraphics", "NSImage"] }
# NSData feeds the runtime Dock icon for bare (non-bundled) binaries — see
# `set_dock_icon_for_bare_binary` in main.rs.
objc2-foundation = { version = "0.3", features = ["NSData"] }
# Dictionary-based Chinese word segmentation for double-click selection
# (`terminal::smart_select`), as a *fallback* where the OS has no tokenizer of
# its own. macOS is excluded on purpose: CFStringTokenizer segments Chinese
# about as well (and Japanese/Korean far better) at zero cost, while jieba's
# table costs ~55 MB resident once built and ~2 MB of binary for the embedded
# dictionary. Keeping the dep off macOS means that dictionary isn't even
# linked into the build that can't use it.
[target.'cfg(not(target_os = "macos"))'.dependencies]
jieba-rs = "0.10"
# x11/wayland are the Linux windowing backends; only pull them on Linux. The
# Windows backend (`gpui_windows`) and macOS backend are selected by gpui_platform
# itself via `cfg`, so no feature is needed for them.
[target.'cfg(target_os = "linux")'.dependencies]
gpui_platform = { workspace = true, features = ["x11", "wayland"] }
# Linux tray (`ui::tray`): pure-Rust StatusNotifierItem over DBus (zbus — already
# in the tree). `blocking` + `async-io` gives a synchronous handle without
# requiring the app to own a tokio runtime; ksni runs its own service thread. On
# desktops without an SNI host (bare GNOME without the AppIndicator extension)
# spawning fails and the tray is silently absent — the app is unaffected.
ksni = { version = "0.3.6", default-features = false, features = ["blocking", "async-io"] }
# gpui's `test-support` unlocks `#[gpui::test]` + `TestAppContext`, the headless
# App/Window harness the view/event tests run on. Dev-only: the feature merges
# into test builds and never reaches a release binary.
[dev-dependencies]
gpui = { workspace = true, features = ["test-support"] }
# `test-util` unlocks tokio's paused clock (`start_paused`) so the ssh prompt
# broker's timeout/retry tests run instantly instead of in real time. Dev-only.
tokio = { version = "1", features = ["test-util", "macros", "rt"] }
[lints]
workspace = true
# ---- Standalone workspace mirroring gpui-component's pins so the git/source
# ---- caches are shared and versions stay aligned. ----
[workspace]
members = ["."]
[workspace.package]
edition = "2024"
[workspace.dependencies]
# Our fork's `tty7` branch carries the local customizations tty7 relies on:
# `PopupMenu::with_size` plus the 1px hairline menu separator. The exact commit
# is still pinned by Cargo.lock. For co-developing the UI crate, point these
# back at a sibling checkout: `path = "../gpui-component/crates/{ui,assets}"`.
gpui-component = { path = "../../../../gpui-component/crates/ui", version = "0.5.2", features = ["tree-sitter-languages"] }
gpui-component-assets = { path = "../../../../gpui-component/crates/assets", version = "0.5.1" }
gpui = { git = "https://github.com/zed-industries/zed", rev = "1d217ee39d381ac101b7cf49d3d22451ac1093fe" }
# Base features are cross-platform (`font-kit`, `runtime_shaders` only map to the
# macOS backend; they're no-ops elsewhere). The Linux-only `x11`/`wayland`
# backends are added by the `cfg(target_os = "linux")` dependency entry in the
# package manifest, so they never reach the Windows/macOS builds.
gpui_platform = { git = "https://github.com/zed-industries/zed", rev = "1d217ee39d381ac101b7cf49d3d22451ac1093fe", features = ["font-kit", "runtime_shaders"] }
anyhow = "1"
log = "0.4"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1"
smallvec = "1"
smol = "2"
[patch.crates-io]
# Temporary until upstream russh releases gssapi-with-mic client auth support
# (https://github.com/Eugeny/russh/pull/737) — remove this patch and take the
# crates.io release once it lands. Pinned to an exact rev (never a branch):
# russh is the SSH protocol layer handling user credentials, and a moving
# branch on a third-party fork could change what `cargo update` builds.
russh = { git = "https://github.com/ayamir/russh", rev = "0d1d073350ed823069252075cbf3db9672d5b490" }
[workspace.lints.clippy]
dbg_macro = "deny"
todo = "deny"
type_complexity = "allow"
[profile.dev]
codegen-units = 16
debug = "limited"
split-debuginfo = "unpacked"
[profile.dev.package]
resvg = { opt-level = 3 }
rustybuzz = { opt-level = 3 }
taffy = { opt-level = 3 }
ttf-parser = { opt-level = 3 }
smol = { opt-level = 3 }
gpui = { opt-level = 3 }
gpui_platform = { opt-level = 3 }
gpui_macros = { opt-level = 3 }
# The VT parser + grid run on every PTY byte; at opt-level 0 a `cat bigfile`
# crawls under `cargo dev`.
alacritty_terminal = { opt-level = 3 }
# The render/parse hot path crosses the tty7 ↔ alacritty_terminal ↔ gpui crate
# boundaries, so cross-crate inlining (thin LTO, like Zed ships) buys real
# throughput there; single codegen unit for the same reason.
[profile.release]
lto = "thin"
codegen-units = 1