mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 00:02:23 +00:00
tty7: a GPU-rendered, daemon-backed terminal in pure Rust
tty7 is split into two Rust processes: a persistent daemon that owns the shells and a GPU-rendered client that talks to it over a local socket. Because the shells live in the daemon, quitting and reopening the app leaves the session intact — detach and reattach, no tmux required. - Persistent sessions — the daemon holds the PTYs and child processes, so closing a window or swapping in a new build never takes a shell down. - Performance — an 11 MB `cat` completes in 95 ms and DOOM-fire renders at 888 fps; the daemon drains the PTY at device speed off the render path. - Shell-aware — new tabs and splits open in the current working directory; zsh, bash, fish, and PowerShell are set up automatically. - Enhanced prompt — inline completion, syntax highlighting, history, and in-terminal search, with rich flag/subcommand signatures for common tools. - Tabs, resizable splits, a command palette, click-to-open links, desktop notifications, eight themes, and CJK/IME input. Native builds for macOS, Windows, and Linux. Built on Zed's gpui and Alacritty's VT core.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
# `cargo dev` — run the app against a throwaway config directory (`.tty7-dev/`)
|
||||
# instead of the real `~/.config/tty7/`, so debugging never clobbers your live
|
||||
# config/session/history. Extra args pass through, e.g. `cargo dev -- --foo`.
|
||||
[alias]
|
||||
dev = "run -- --config-dir .tty7-dev"
|
||||
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Questions & ideas
|
||||
url: https://github.com/l0ng-ai/tty7/discussions
|
||||
about: Not sure it's a bug? Want to discuss an idea first? Start a discussion.
|
||||
- name: Security vulnerabilities
|
||||
url: https://github.com/l0ng-ai/tty7/security/advisories/new
|
||||
about: Please report security issues privately, not as public issues.
|
||||
@@ -0,0 +1,43 @@
|
||||
name: Issue
|
||||
description: Report a bug or suggest an improvement
|
||||
body:
|
||||
- type: dropdown
|
||||
id: kind
|
||||
attributes:
|
||||
label: Type
|
||||
options:
|
||||
- Bug — something doesn't work as expected
|
||||
- Idea — suggest an improvement or new capability
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: detail
|
||||
attributes:
|
||||
label: What's going on?
|
||||
description: >
|
||||
For a bug: what you did, what you saw, and what you expected instead.
|
||||
For an idea: the problem it solves and how it should behave.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: tty7 version (bugs)
|
||||
placeholder: v0.2.0
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: Platform (bugs)
|
||||
options:
|
||||
- macOS (Apple Silicon)
|
||||
- macOS (Intel)
|
||||
- Windows
|
||||
- Linux
|
||||
- type: textarea
|
||||
id: extra
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: >
|
||||
Screenshots or recordings, the exact command / escape sequence that
|
||||
triggers it, the shell you were using, or the TUI app (vim, htop, …)
|
||||
and its version if one is involved.
|
||||
@@ -0,0 +1,22 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Rust crates.io dependencies (git deps like gpui / alacritty_terminal are
|
||||
# pinned by hand and won't be touched here).
|
||||
- package-ecosystem: cargo
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
open-pull-requests-limit: 5
|
||||
commit-message:
|
||||
prefix: "deps"
|
||||
groups:
|
||||
cargo-minor-patch:
|
||||
update-types: ["minor", "patch"]
|
||||
|
||||
# GitHub Actions used by the CI and release workflows.
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
commit-message:
|
||||
prefix: "ci"
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# Usage: bundle-linux.sh <target-triple> <arch-label>
|
||||
# Package the release binary into a tarball:
|
||||
# dist/tty7-<version>-linux-<arch>.tar.gz
|
||||
#
|
||||
# Fonts and the app icon are embedded via include_bytes!, so the archive is the
|
||||
# stripped executable plus a sibling completions/ dir (loaded at runtime — see
|
||||
# terminal::signature) and the license/readme. gpui's x11/wayland backends still
|
||||
# dynamic-link the usual system libs at runtime — see the README's Linux
|
||||
# build-dependency list — so this is an unsigned build, not a
|
||||
# portable AppImage.
|
||||
set -euo pipefail
|
||||
|
||||
TARGET="$1"
|
||||
ARCH="$2"
|
||||
VERSION="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')"
|
||||
NAME="tty7-${VERSION}-linux-${ARCH}"
|
||||
STAGE="dist/${NAME}"
|
||||
|
||||
rm -rf dist
|
||||
mkdir -p "$STAGE"
|
||||
|
||||
cp "target/${TARGET}/release/tty7" "$STAGE/tty7"
|
||||
chmod +x "$STAGE/tty7"
|
||||
# Release builds keep symbols (thin LTO, no profile strip); drop them here so
|
||||
# the archive isn't ~100 MB of debug info.
|
||||
strip "$STAGE/tty7" || echo "⚠️ strip unavailable — shipping unstripped binary"
|
||||
mkdir -p "$STAGE/completions"
|
||||
cp assets/completions/*.json "$STAGE/completions/"
|
||||
cp LICENSE "$STAGE/LICENSE"
|
||||
cp README.md "$STAGE/README.md"
|
||||
|
||||
tar -C dist -czf "dist/${NAME}.tar.gz" "$NAME"
|
||||
rm -rf "$STAGE"
|
||||
echo "✅ dist/${NAME}.tar.gz"
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
#!/bin/bash
|
||||
# Usage: bundle-macos.sh <target-triple> <arch-label>
|
||||
# Package the release binary into dist/tty7.app and wrap it in a
|
||||
# drag-to-Applications DMG: dist/tty7-<version>-macos-<arch>.dmg.
|
||||
#
|
||||
# Signing posture is chosen from the environment:
|
||||
# * Developer ID secrets present (APPLE_SIGNING_IDENTITY + APPLE_CERTIFICATE)
|
||||
# -> hardened-runtime signature, then notarize + staple. Passes Gatekeeper.
|
||||
# * Otherwise -> adhoc signature, same as before. Fine for local dev, but the
|
||||
# OS will quarantine it on other machines.
|
||||
set -euo pipefail
|
||||
|
||||
TARGET="$1"
|
||||
ARCH="$2"
|
||||
VERSION="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')"
|
||||
APP="dist/tty7.app"
|
||||
|
||||
rm -rf dist
|
||||
mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
|
||||
cp "target/${TARGET}/release/tty7" "$APP/Contents/MacOS/tty7"
|
||||
chmod +x "$APP/Contents/MacOS/tty7"
|
||||
cp assets/tty7.icns "$APP/Contents/Resources/tty7.icns"
|
||||
# Completion signatures are loaded at runtime (not embedded), resolved relative
|
||||
# to the executable as ../Resources/completions — see terminal::signature.
|
||||
mkdir -p "$APP/Contents/Resources/completions"
|
||||
cp assets/completions/*.json "$APP/Contents/Resources/completions/"
|
||||
printf 'APPL????' > "$APP/Contents/PkgInfo"
|
||||
|
||||
cat > "$APP/Contents/Info.plist" <<PLIST
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key><string>tty7</string>
|
||||
<key>CFBundleDisplayName</key><string>tty7</string>
|
||||
<key>CFBundleIdentifier</key><string>com.github.tty7</string>
|
||||
<key>CFBundleVersion</key><string>${VERSION}</string>
|
||||
<key>CFBundleShortVersionString</key><string>${VERSION}</string>
|
||||
<key>CFBundleExecutable</key><string>tty7</string>
|
||||
<key>CFBundleIconFile</key><string>tty7</string>
|
||||
<key>CFBundlePackageType</key><string>APPL</string>
|
||||
<key>NSHighResolutionCapable</key><true/>
|
||||
<key>NSPrincipalClass</key><string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
|
||||
SIGN_ID="${APPLE_SIGNING_IDENTITY:-}"
|
||||
|
||||
if [[ -n "$SIGN_ID" && -n "${APPLE_CERTIFICATE:-}" ]]; then
|
||||
# ---- Developer ID signing ------------------------------------------------
|
||||
# Import the cert into a throwaway keychain so we never touch the login one.
|
||||
KEYCHAIN="${RUNNER_TEMP:-/tmp}/tty7-sign.keychain-db"
|
||||
CERT_PATH="${RUNNER_TEMP:-/tmp}/tty7-cert.p12"
|
||||
KEYCHAIN_PASSWORD="${KEYCHAIN_PASSWORD:-tty7-ci}"
|
||||
# Scrub the decoded cert + temp keychain on any exit path.
|
||||
cleanup() {
|
||||
security delete-keychain "$KEYCHAIN" >/dev/null 2>&1 || true
|
||||
rm -f "$CERT_PATH"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
|
||||
security set-keychain-settings -lut 21600 "$KEYCHAIN"
|
||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN"
|
||||
echo "$APPLE_CERTIFICATE" | base64 --decode > "$CERT_PATH"
|
||||
security import "$CERT_PATH" -P "${APPLE_CERTIFICATE_PASSWORD:-}" \
|
||||
-A -t cert -f pkcs12 -k "$KEYCHAIN"
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: \
|
||||
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN" >/dev/null
|
||||
security list-keychains -d user -s "$KEYCHAIN" login.keychain
|
||||
|
||||
# Hardened runtime forbids JIT / unsigned executable memory by default; the
|
||||
# GPU/Metal path gpui uses needs them, so grant them explicitly or the
|
||||
# notarized build crashes on launch.
|
||||
ENTITLEMENTS="dist/entitlements.plist"
|
||||
cat > "$ENTITLEMENTS" <<'ENT'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key><true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key><true/>
|
||||
</dict>
|
||||
</plist>
|
||||
ENT
|
||||
|
||||
# Sign inner-out: the executable first, then the bundle.
|
||||
codesign --force --options runtime --timestamp --entitlements "$ENTITLEMENTS" \
|
||||
--sign "$SIGN_ID" "$APP/Contents/MacOS/tty7"
|
||||
codesign --force --options runtime --timestamp --entitlements "$ENTITLEMENTS" \
|
||||
--sign "$SIGN_ID" "$APP"
|
||||
codesign --verify --strict --verbose=2 "$APP"
|
||||
|
||||
# ---- Notarization --------------------------------------------------------
|
||||
if [[ -n "${APPLE_ID:-}" && -n "${APPLE_PASSWORD:-}" && -n "${APPLE_TEAM_ID:-}" ]]; then
|
||||
# Submit a zip of the .app; on success staple the ticket onto the bundle
|
||||
# so it validates offline (the distributed zip below then carries it).
|
||||
ditto -c -k --keepParent "$APP" "dist/notarize.zip"
|
||||
xcrun notarytool submit "dist/notarize.zip" \
|
||||
--apple-id "$APPLE_ID" --password "$APPLE_PASSWORD" \
|
||||
--team-id "$APPLE_TEAM_ID" --wait
|
||||
xcrun stapler staple "$APP"
|
||||
rm -f "dist/notarize.zip"
|
||||
echo "✅ signed + notarized + stapled"
|
||||
else
|
||||
echo "⚠️ signed with Developer ID but notarization secrets missing — skipping notarize"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ no Developer ID secrets — adhoc signing (won't pass Gatekeeper on other machines)"
|
||||
codesign --force --deep --sign - "$APP"
|
||||
fi
|
||||
|
||||
# Package the (now stapled) bundle as a drag-to-Applications DMG.
|
||||
DMG="dist/tty7-${VERSION}-macos-${ARCH}.dmg"
|
||||
STAGE="dist/dmg-stage"
|
||||
rm -rf "$STAGE"
|
||||
mkdir "$STAGE"
|
||||
cp -R "$APP" "$STAGE/"
|
||||
ln -s /Applications "$STAGE/Applications"
|
||||
hdiutil create -volname "tty7" -srcfolder "$STAGE" -ov -format UDZO "$DMG"
|
||||
rm -rf "$STAGE"
|
||||
if [[ -n "$SIGN_ID" && -n "${APPLE_CERTIFICATE:-}" ]]; then
|
||||
codesign --force --timestamp --sign "$SIGN_ID" "$DMG"
|
||||
fi
|
||||
echo "✅ $DMG"
|
||||
@@ -0,0 +1,29 @@
|
||||
# Usage: bundle-windows.ps1 <target-triple> <arch-label>
|
||||
# Package the release binary into a zip:
|
||||
# dist/tty7-<version>-windows-<arch>.zip
|
||||
#
|
||||
# Fonts are embedded via include_bytes! and the app icon is compiled into the
|
||||
# executable as a resource (see build.rs). So the archive is tty7.exe plus a
|
||||
# sibling completions\ dir (loaded at runtime — see terminal::signature) and the
|
||||
# license/readme. This is an unsigned build — SmartScreen will
|
||||
# warn on first launch.
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$Target = $args[0]
|
||||
$Arch = $args[1]
|
||||
$Version = (Select-String -Path Cargo.toml -Pattern '^version\s*=\s*"([^"]+)"').Matches[0].Groups[1].Value
|
||||
$Name = "tty7-$Version-windows-$Arch"
|
||||
$Stage = "dist/$Name"
|
||||
|
||||
Remove-Item -Recurse -Force dist -ErrorAction SilentlyContinue
|
||||
New-Item -ItemType Directory -Force -Path $Stage | Out-Null
|
||||
|
||||
Copy-Item "target/$Target/release/tty7.exe" "$Stage/tty7.exe"
|
||||
New-Item -ItemType Directory -Force -Path "$Stage/completions" | Out-Null
|
||||
Copy-Item "assets/completions/*.json" "$Stage/completions/"
|
||||
Copy-Item LICENSE "$Stage/LICENSE.txt"
|
||||
Copy-Item README.md "$Stage/README.md"
|
||||
|
||||
Compress-Archive -Path "$Stage/*" -DestinationPath "dist/$Name.zip" -Force
|
||||
Remove-Item -Recurse -Force $Stage
|
||||
Write-Host "OK dist/$Name.zip"
|
||||
@@ -0,0 +1,67 @@
|
||||
name: CI
|
||||
|
||||
# Compile + test on every push/PR. The Windows and Linux jobs are the
|
||||
# compile-feedback loop for the platform-specific code a macOS dev machine
|
||||
# never builds (`cfg(windows)` transport / process detach / config dir,
|
||||
# the Linux `/proc` queries, the x11/wayland gpui backends). The macOS job
|
||||
# guards against regressing the original target.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
fmt:
|
||||
name: rustfmt
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt
|
||||
- run: cargo fmt --check
|
||||
|
||||
build:
|
||||
name: build & test (${{ matrix.target }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: macos-14
|
||||
target: aarch64-apple-darwin
|
||||
- runner: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
- runner: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout tty7
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# gpui-component is a git dependency (see Cargo.toml), so no sibling
|
||||
# checkout is needed. The Windows backend (gpui_windows + DirectWrite/D3D)
|
||||
# ships with the windows-latest runner's SDK — no extra system deps.
|
||||
|
||||
# gpui's Linux backends need the x11/wayland/xkb/font dev packages at
|
||||
# build time (build scripts resolve them via pkg-config). Same set the
|
||||
# README documents for building from source on Linux.
|
||||
- name: Install Linux system dependencies
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
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
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Build
|
||||
run: cargo build --target ${{ matrix.target }}
|
||||
|
||||
- name: Test
|
||||
run: cargo test --target ${{ matrix.target }}
|
||||
@@ -0,0 +1,105 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["v*"]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: macos-14
|
||||
os: macos
|
||||
arch: arm64
|
||||
target: aarch64-apple-darwin
|
||||
# macos-13 was retired; macos-15-intel is the remaining hosted x86_64 image.
|
||||
- runner: macos-15-intel
|
||||
os: macos
|
||||
arch: x86_64
|
||||
target: x86_64-apple-darwin
|
||||
- runner: windows-latest
|
||||
os: windows
|
||||
arch: x86_64
|
||||
target: x86_64-pc-windows-msvc
|
||||
- runner: ubuntu-latest
|
||||
os: linux
|
||||
arch: x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout tty7
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: tty7
|
||||
|
||||
# gpui-component is pulled as a git dependency (see Cargo.toml's patch
|
||||
# section), so no sibling checkout is needed.
|
||||
|
||||
# gpui's Linux backends resolve the x11/wayland/xkb/font dev packages via
|
||||
# pkg-config at build time — the same set the README documents for
|
||||
# building from source on Linux.
|
||||
- name: Install Linux system dependencies
|
||||
if: matrix.os == 'linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
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
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: tty7
|
||||
|
||||
- name: Build
|
||||
working-directory: tty7
|
||||
run: cargo build --release --target ${{ matrix.target }}
|
||||
|
||||
# ---- Packaging: one step per OS ----------------------------------------
|
||||
# macOS gets a signed + notarized drag-to-Applications DMG. Windows and
|
||||
# Linux are unsigned archives of the self-contained binary
|
||||
# (fonts are embedded via include_bytes!; the Windows icon is compiled in
|
||||
# via build.rs).
|
||||
- name: Bundle macOS DMG
|
||||
if: matrix.os == 'macos'
|
||||
working-directory: tty7
|
||||
env:
|
||||
# macOS code signing — the cert is imported into a throwaway keychain.
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
# Notarization — required for Developer ID builds to pass Gatekeeper.
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
run: bash .github/scripts/bundle-macos.sh "${{ matrix.target }}" "${{ matrix.arch }}"
|
||||
|
||||
- name: Package Linux tarball
|
||||
if: matrix.os == 'linux'
|
||||
working-directory: tty7
|
||||
run: bash .github/scripts/bundle-linux.sh "${{ matrix.target }}" "${{ matrix.arch }}"
|
||||
|
||||
- name: Package Windows zip
|
||||
if: matrix.os == 'windows'
|
||||
working-directory: tty7
|
||||
shell: pwsh
|
||||
run: '& ./.github/scripts/bundle-windows.ps1 "${{ matrix.target }}" "${{ matrix.arch }}"'
|
||||
|
||||
- name: Release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
tty7/dist/*.dmg
|
||||
tty7/dist/*.tar.gz
|
||||
tty7/dist/*.zip
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/target
|
||||
/dist
|
||||
.DS_Store
|
||||
|
||||
# Local dev-tool state — kept out of the repo but retained on disk.
|
||||
/CLAUDE.md
|
||||
/AUDIT.md
|
||||
.brooks-lint-history.json
|
||||
openwiki/.last-update.json
|
||||
|
||||
# dev-build throwaway config dir (cargo dev)
|
||||
.tty7-dev/
|
||||
|
||||
# Claude Code agent worktrees (transient)
|
||||
.claude/worktrees/
|
||||
|
||||
# local scratch notes (never committed)
|
||||
/todo.md
|
||||
|
||||
# local freeze-forensics helper — kept on disk, not shipped
|
||||
/scripts/diagnose-freeze.sh
|
||||
|
||||
# benchmark harness work dir + generated fixtures (scripts/bench/)
|
||||
.bench/
|
||||
/big.log
|
||||
@@ -0,0 +1,87 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to tty7 are documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- PowerShell shell integration: `powershell.exe` and `pwsh` now emit the OSC 133
|
||||
semantic-prompt marks and OSC 7 cwd that zsh/bash/fish already do, injected
|
||||
via `-EncodedCommand` after the user's profile loads (their config is never
|
||||
touched). This turns on the inline line editor at the PowerShell prompt — so
|
||||
clicking positions the caret and new tabs/splits inherit the working
|
||||
directory — which is what previously made mouse clicks a no-op at the prompt
|
||||
on Windows.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Windows shell integration never engaged even for the default shell: detection
|
||||
keyed off `portable-pty`'s `get_shell()`, which reports `%ComSpec%` (cmd.exe)
|
||||
regardless of what's actually spawned, so the PowerShell default was mistaken
|
||||
for an unsupported shell. It now resolves to `powershell.exe` directly.
|
||||
|
||||
## [0.2.0] - 2026-07-04
|
||||
|
||||
### Added
|
||||
|
||||
- Underline styles: undercurl, double, dotted, and dashed underlines render distinctly.
|
||||
- `config.json` hot reload — edits apply to the running app without a restart.
|
||||
- Desktop notifications driven by OSC 9 / OSC 777 escape sequences.
|
||||
- Kitty keyboard protocol (CSI u progressive enhancement) for TUI apps like Neovim and Helix.
|
||||
- Shell integration for bash and fish, alongside the existing zsh support.
|
||||
- Windows support: cross-platform daemon, PowerShell as the default shell, embedded app icon.
|
||||
- Linux support: builds against gpui's x11/wayland backends, `/proc`-based foreground cwd + pane-title tracking, Linux CI job, and documented build dependencies.
|
||||
- Downloadable builds for every platform: the release workflow now packages and uploads all four targets — signed/notarized macOS DMGs (arm64 + x86_64) plus unsigned archives for Windows (`.zip`) and Linux (`.tar.gz`), each via its own `.github/scripts/bundle-<os>` script.
|
||||
- Settings UI: terminal / appearance / behavior options are configurable from the GUI, with a searchable font-family dropdown and a wider theme gallery.
|
||||
- Configurable default shell.
|
||||
|
||||
### Changed
|
||||
|
||||
- Project renamed to **tty7**.
|
||||
- macOS releases ship as drag-to-Applications DMGs instead of zips, and the
|
||||
Intel build moved to the `macos-15-intel` runner (`macos-13` was retired,
|
||||
which had silently kept x86_64 assets from ever publishing).
|
||||
- Pixel-smooth scrollback: scrolling carries a sub-line fraction and shifts the paint instead of jumping whole lines.
|
||||
- Smoother scrolling on dense screens: glyph shaping is batched and wakeups are coalesced.
|
||||
- CJK-dense screens paint ~2.4× faster: consecutive wide glyphs batch into single shaped runs (two columns per glyph) instead of painting cell-by-cell; the grid snapshot buffer is reused across frames and the selection/search overlay scans are skipped when nothing is highlighted. Release builds now use thin LTO.
|
||||
- Type-ahead is integrated into the line editor instead of being stranded on zle's line.
|
||||
- New tabs open next to the active tab instead of at the end.
|
||||
- Terminal throughput ~12× faster (11 MB `cat`: ~2.0 s → ~0.16 s; DOOM-fire: ~47 fps → ~920 fps, both at 155×40 on an M1 Pro — now ahead of Alacritty/Ghostty on the same machine): the daemon's replay ring is a `VecDeque` so a full ring no longer memmoves 8 MiB per ~1 KiB PTY read, and the per-connection writer coalesces queued `Output` frames (≤256 KiB) so a flood reaches the client as a few large frames instead of thousands of tiny ones. A backpressure gate (4 MiB high-water) pauses the PTY reader while the client catches up, so a runaway `yes` can't grow daemon memory without bound. `TTY7_TRACE=1` prints per-second reader-loop accounting on both sides for future diagnosis.
|
||||
- Second throughput pass, another ~1.4× on bulk output (11 MB `cat`: ~160 ms → ~100 ms; sustained plaintext drain 124 → 148 MB/s, vs ~170 MB/s for a raw do-nothing PTY reader on the same machine; DOOM-fire is unchanged — it is producer-bound at ~96 MB/s): the backpressure high-water grows to 16 MiB so a big burst drains at PTY speed while the client parses in its own time; daemon⇄GUI socket buffers grow from macOS's 8 KiB default to 256 KiB; the client applies consecutive `Output` frames as one batched parser pass (one term-lock + wakeup per burst, latency-free — the batch never waits for unarrived bytes); the shared OSC tokenizer skips Ground/Ignore runs with SIMD `memchr`; the gate's hot path is a lock-free atomic (previously a Mutex plus an unconditional `notify_all` per socket write); and the four threads on the interactive output path ask macOS for `USER_INTERACTIVE` QoS to stay off the efficiency cores (`TTY7_NO_QOS=1` opts out).
|
||||
|
||||
### Fixed
|
||||
|
||||
- A long `--config-dir` path crashed the GUI at startup ("path must be shorter than SUN_LEN"): when `<config>/daemon.sock` would exceed the OS socket-path limit (104 bytes on macOS), the endpoint now falls back to a short per-user path keyed by a stable hash of the config dir ($XDG_RUNTIME_DIR, else the OS temp dir). Short paths keep the original layout, so existing daemons stay reachable.
|
||||
- Typing right after a command finished could leave a stray echoed character plus zsh's reverse-video `%` in the scrollback: the "command finished" mark (OSC 133;D) is now emitted the instant the command exits — prepended ahead of the user's precmd hooks (zsh/bash) — instead of after slow prompt frameworks (oh-my-zsh git status, conda), so the local input editor takes keystrokes back hundreds of milliseconds sooner.
|
||||
- Typing while a command was still running stranded those keystrokes on zle's line at the next prompt — un-editable and double-drawn under the line editor's overlay. Type-ahead adoption (wipe the shell's line, seed the editor) now runs at every prompt, not just the shell's first, and the wipe waits until zle is actually reading (the live `133;B` mark) so it is consumed silently instead of being kernel-echoed into the scrollback as a literal `^U`.
|
||||
- Typing ahead of a fast command left kernel-echoed debris in the scrollback (`ls` plus zsh's reverse-video `%`). Reconstructable gap input is now held client-side for up to 150 ms: a command that finishes inside the window hands the keystrokes straight to the line editor with the PTY untouched — zero echo; a longer command (or one reading stdin) gets the bytes released verbatim, so REPLs and password prompts still work.
|
||||
- fish shell integration silently never installed, so fish users got no prompt marks or cwd tracking.
|
||||
- **Security:** pasted clipboard content is stripped of ESC bytes, closing a bracketed-paste escape that could inject auto-executing commands.
|
||||
- Crash when copying/cutting right after a forward word/line delete left a stale selection anchor.
|
||||
- `Ctrl+Alt+<letter>` was indistinguishable from `Ctrl+<letter>` because the legacy key encoder dropped the Alt ESC prefix.
|
||||
- Plain Enter/Tab/Backspace were wrongly CSI-u-encoded at the kitty-keyboard DISAMBIGUATE level, which could wedge the shell after a crashed TUI.
|
||||
- No-op edits (e.g. Backspace at the start of the line) no longer swallow the first undo.
|
||||
- OSC scanners (daemon-side and notification-side) dropped a well-formed sequence that directly followed an unterminated one.
|
||||
- Daemon pane teardown is hardened: process-group kill, bounded join, dead panes are reclaimed.
|
||||
- New shells default to `$HOME` when launched from the app bundle with cwd `/`.
|
||||
|
||||
## [0.1.0] - 2026-06-30
|
||||
|
||||
Initial release.
|
||||
|
||||
- Sessions live in a persistent daemon and survive window close / app restart.
|
||||
- GPU-rendered terminal grid on [gpui], backed by Zed's `alacritty_terminal` fork.
|
||||
- Tabs and pane splits (split right/down, maximize, focus movement).
|
||||
- Command palette with fuzzy search over every action.
|
||||
- Smart line editing: inline completion, syntax highlighting, history, in-terminal search.
|
||||
- zsh shell integration (OSC 7 cwd + OSC 133 prompt marks) via a throwaway `ZDOTDIR`.
|
||||
- Native macOS light/dark themes that follow the system appearance.
|
||||
|
||||
[Unreleased]: https://github.com/l0ng-ai/tty7/compare/v0.2.0...HEAD
|
||||
[0.2.0]: https://github.com/l0ng-ai/tty7/compare/v0.1.0...v0.2.0
|
||||
[0.1.0]: https://github.com/l0ng-ai/tty7/releases/tag/v0.1.0
|
||||
[gpui]: https://github.com/zed-industries/zed
|
||||
Generated
+9188
File diff suppressed because it is too large
Load Diff
+163
@@ -0,0 +1,163 @@
|
||||
[package]
|
||||
name = "tty7"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
description = "A terminal built on Zed's gpui that never loses your session — daemon-backed, shell-aware"
|
||||
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
|
||||
smol.workspace = true
|
||||
smallvec.workspace = true
|
||||
serde = { workspace = true }
|
||||
serde_json.workspace = true
|
||||
|
||||
# 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.
|
||||
notify = "8"
|
||||
|
||||
# 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"
|
||||
|
||||
# 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"
|
||||
|
||||
# `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"
|
||||
|
||||
# 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_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]
|
||||
objc2 = "0.6"
|
||||
objc2-app-kit = { version = "0.3", features = ["NSApplication", "NSResponder", "NSAppearance"] }
|
||||
|
||||
# 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"] }
|
||||
|
||||
# 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"] }
|
||||
|
||||
[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 = { git = "https://github.com/l0ng-ai/gpui-component", branch = "tty7", version = "0.5.2" }
|
||||
gpui-component-assets = { git = "https://github.com/l0ng-ai/gpui-component", branch = "tty7", 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"
|
||||
|
||||
[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
|
||||
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2026 l0ng-ai
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
<div align="center">
|
||||
|
||||
<img src="assets/app-icon.svg" alt="tty7" width="88" height="88" />
|
||||
|
||||
### tty7
|
||||
|
||||
**A blazing-fast terminal in pure Rust — GPU-rendered, and built around the prompt.**
|
||||
|
||||
<sub>GPU rendering on Zed's gpui · VT core from Alacritty</sub>
|
||||
|
||||
<br />
|
||||
|
||||
[](https://github.com/l0ng-ai/tty7/actions/workflows/ci.yml)
|
||||
[](https://github.com/l0ng-ai/tty7/releases)
|
||||
[](LICENSE)
|
||||
|
||||
[**Install**](#-install) · [**Benchmarks**](#-benchmarks) · [**Shortcuts**](#️-shortcuts) · [**Contributing**](#-contributing)
|
||||
|
||||
<sub>English · [简体中文](README.zh-CN.md)</sub>
|
||||
|
||||
<br />
|
||||
|
||||
<img src="docs/screenshot.jpg" alt="tty7" width="820" />
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
tty7 is a terminal that puts speed and the prompt first. Every frame renders on
|
||||
the GPU, output drains faster than any terminal we've measured — an 11 MB `cat`
|
||||
in **95 ms** — and the prompt itself does real work: inline completion, syntax
|
||||
highlighting, and flag-by-flag hints for the commands you type all day. Pure
|
||||
Rust, native on macOS, Windows, and Linux, zero configuration to get there.
|
||||
|
||||
- ⚡ **Fastest in its class** — an 11 MB `cat` completes in **95 ms**, versus
|
||||
179–239 ms for Alacritty/Ghostty/Kitty; DOOM-fire renders at **888 fps**
|
||||
against their 485–617. Same machine, same grid; the harness is in the repo
|
||||
([benchmarks](#-benchmarks)).
|
||||
- ⌨️ **A prompt that helps you type** — inline completion, syntax highlighting,
|
||||
history, and in-terminal search, right where you're working. Type
|
||||
`git commit --`, `kubectl`, or `npm` and every flag and subcommand shows up
|
||||
with its description — rich signatures for ~100 common commands, generated
|
||||
from Fig's spec corpus.
|
||||
- 🧠 **Shell-aware, zero config** — new tabs and splits open in the current
|
||||
working directory, and path completion always follows where you are. zsh,
|
||||
bash, fish, and PowerShell are wired up automatically.
|
||||
- 🔌 **Sessions that survive** — shells run in a background daemon, so closing a
|
||||
window, quitting the app, or swapping in a new build never takes a shell down.
|
||||
Detach and reattach, no tmux.
|
||||
|
||||
Also included: tabs (drag to reorder, inline rename, number keys to switch) and
|
||||
resizable splits, a command palette, click-to-open links, desktop notifications,
|
||||
and focus-follows-mouse. Eight built-in themes from light to dark, with the
|
||||
native window chrome following the one you pick, plus CJK/IME input.
|
||||
|
||||
Native builds for macOS, Windows, and Linux — every release ships all three.
|
||||
|
||||
<br />
|
||||
|
||||
<div align="center">
|
||||
|
||||
**[Download the latest release ▶](https://github.com/l0ng-ai/tty7/releases/latest)**
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
## 📊 Benchmarks
|
||||
|
||||
All four terminals measured back-to-back on the same machine, same day, same
|
||||
155×40 grid — Apple M1 Pro, macOS 26.3.1, five-run averages (2026-07-04):
|
||||
|
||||
| | **tty7** | Alacritty | Ghostty | Kitty |
|
||||
|---|---:|---:|---:|---:|
|
||||
| Plaintext IO — 11 MB `cat` <sub>(lower = better)</sub> | **95 ms** | 239 ms | 179 ms | 185 ms |
|
||||
| [DOOM-fire](https://github.com/const-void/DOOM-fire-zig) frame rate <sub>(higher = better)</sub> | **888 fps** | 485 fps | 552 fps | 617 fps |
|
||||
| Cold-launch memory | 116 MB¹ | 105 MB | 128 MB | 130 MB |
|
||||
|
||||
<sub>¹ GUI 105 MB + the persistent daemon 11 MB.</sub>
|
||||
|
||||
tty7 reads the PTY at device speed and parses it in large batches off the render
|
||||
path, and the hot paths are lock-free — so a big `cat` never waits on drawing.
|
||||
(That's also what the background daemon buys you: it can run up to 16 MiB ahead
|
||||
of the window before backpressure applies.)
|
||||
|
||||
Methodology (how each terminal is driven, grid fairness, known pitfalls) and
|
||||
one-command reproduction live in [`scripts/bench/`](scripts/bench/README.md) —
|
||||
run it yourself.
|
||||
|
||||
## 🚀 Install
|
||||
|
||||
Grab the build for your platform from [**Releases**](https://github.com/l0ng-ai/tty7/releases):
|
||||
|
||||
- **macOS** — `tty7-<version>-macos-arm64.dmg` (Apple Silicon) or `…-x86_64.dmg`
|
||||
(Intel); open it and drag `tty7.app` into Applications.
|
||||
- **Windows** — `…-windows-x86_64.zip`; unzip and run `tty7.exe`.
|
||||
- **Linux** — `…-linux-x86_64.tar.gz`; extract and run `./tty7` (needs the usual
|
||||
x11/wayland runtime libraries).
|
||||
|
||||
## ⌨️ Shortcuts
|
||||
|
||||
Keys are shown in macOS notation — on Windows and Linux, read <kbd>⌘</kbd> as
|
||||
<kbd>Ctrl</kbd>. Open Settings with <kbd>⌘ ,</kbd> to browse or remap them all.
|
||||
The essentials:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| <kbd>⌘ T</kbd> · <kbd>⌘ W</kbd> · <kbd>⌘ ⇧ T</kbd> | new tab · close tab · reopen closed tab |
|
||||
| <kbd>⌘ D</kbd> · <kbd>⌘ ⇧ D</kbd> | split right · split down |
|
||||
| <kbd>⌘ ]</kbd> · <kbd>⌘ [</kbd> | next pane · previous pane |
|
||||
| <kbd>⌘ ⏎</kbd> | maximize / restore the pane |
|
||||
| <kbd>⌘ P</kbd> | command palette |
|
||||
| <kbd>⌘ F</kbd> | search the scrollback |
|
||||
| <kbd>⌃ R</kbd> | reverse-search shell history |
|
||||
| <kbd>⌘ +</kbd> · <kbd>⌘ −</kbd> · <kbd>⌘ 0</kbd> | font size up · down · reset |
|
||||
|
||||
The full list — and any overrides — lives in **Settings → Keybindings**.
|
||||
|
||||
## 💭 Built with & inspired by
|
||||
|
||||
- [gpui](https://github.com/zed-industries/zed) — Zed's GPU-accelerated UI framework
|
||||
- [`alacritty_terminal`](https://github.com/zed-industries/alacritty) (Zed's fork) — VT emulator, grid, and PTY
|
||||
- [gpui-component](https://github.com/longbridge/gpui-component) — UI widgets, via a [pinned fork](https://github.com/l0ng-ai/gpui-component/tree/tty7)
|
||||
- [tmux](https://github.com/tmux/tmux) — the inspiration for the persistent-daemon design
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Bug reports and PRs are welcome. Security issues go through
|
||||
[SECURITY.md](SECURITY.md); notable changes land in the
|
||||
[CHANGELOG](CHANGELOG.md).
|
||||
|
||||
## 📝 License
|
||||
|
||||
[Apache License 2.0](LICENSE) · © 2026 l0ng-ai
|
||||
|
||||
<br />
|
||||
|
||||
<div align="center">
|
||||
|
||||
<img src="assets/app-icon.svg" alt="" width="28" height="28" />
|
||||
|
||||
<sub><b>tty7</b> — a blazing-fast terminal in pure Rust, GPU-rendered and built around the prompt.</sub>
|
||||
|
||||
</div>
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
<div align="center">
|
||||
|
||||
<img src="assets/app-icon.svg" alt="tty7" width="88" height="88" />
|
||||
|
||||
### tty7
|
||||
|
||||
**纯 Rust 打造的高性能终端 —— GPU 渲染,专注打磨提示符体验。**
|
||||
|
||||
<sub>GPU 渲染基于 Zed 的 gpui · VT 内核来自 Alacritty</sub>
|
||||
|
||||
<br />
|
||||
|
||||
[](https://github.com/l0ng-ai/tty7/actions/workflows/ci.yml)
|
||||
[](https://github.com/l0ng-ai/tty7/releases)
|
||||
[](LICENSE)
|
||||
|
||||
[**安装**](#-安装) · [**基准测试**](#-基准测试) · [**快捷键**](#️-快捷键) · [**参与贡献**](#-参与贡献)
|
||||
|
||||
<sub>[English](README.md) · 简体中文</sub>
|
||||
|
||||
<br />
|
||||
|
||||
<img src="docs/screenshot.jpg" alt="tty7" width="820" />
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
tty7 只看重两件事:性能,以及顺手的提示符。它由 GPU 渲染,输出吞吐快过我们
|
||||
测过的所有终端 —— 11 MB 的 `cat` 仅需 **95 ms**;提示符也经过重新设计:内联
|
||||
补全、语法高亮,常用命令会逐个列出 flag 及其说明。纯 Rust 编写,macOS、
|
||||
Windows、Linux 均为原生构建,零配置即可上手。
|
||||
|
||||
- ⚡ **同类里最快** —— 11 MB 的 `cat` 只花 **95 ms**,Alacritty/Ghostty/Kitty
|
||||
要 179–239 ms;DOOM-fire 跑到 **888 fps**,它们在 485–617 之间。同一台机器、
|
||||
同一网格测出来的,脚本就在仓库里(见[基准测试](#-基准测试))。
|
||||
- ⌨️ **更好用的提示符** —— 内联补全、语法高亮、历史记录、终端内搜索,就在你
|
||||
输入命令的地方。输入 `git commit --`、`kubectl` 或 `npm`,每个 flag 和子命令
|
||||
都会带着说明一并列出 —— 覆盖约 100 个常用命令,数据取自 Fig 的语料。
|
||||
- 🧠 **懂 shell,零配置** —— 新标签页和分屏都开在当前目录,路径补全也始终跟随
|
||||
你所在的位置。zsh、bash、fish、PowerShell 均自动接入,开箱即用。
|
||||
- 🔌 **会话不中断** —— shell 运行在后台守护进程中,关窗口、退应用、乃至换上新
|
||||
版程序,都不会中断任何一个 shell。随时断开,随时接回,无需 tmux。
|
||||
|
||||
其余该有的也没落下:标签页(拖拽重排、双击重命名、数字键切换)、可拖动分隔线
|
||||
调节比例的分屏、命令面板、点击打开链接、桌面通知、焦点随鼠标移动。内置 8 套
|
||||
主题(由浅及深),系统标题栏的明暗跟随所选主题;CJK 与输入法组合输入也一并
|
||||
支持。
|
||||
|
||||
macOS、Windows、Linux 三个平台都有原生构建,每个 release 一起打出。
|
||||
|
||||
<br />
|
||||
|
||||
<div align="center">
|
||||
|
||||
**[下载最新版本 ▶](https://github.com/l0ng-ai/tty7/releases/latest)**
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
## 📊 基准测试
|
||||
|
||||
四款终端在同一台机器上一口气测完,网格统一为 155×40 —— Apple M1 Pro,
|
||||
macOS 26.3.1,取五次运行的平均值(2026-07-04):
|
||||
|
||||
| | **tty7** | Alacritty | Ghostty | Kitty |
|
||||
|---|---:|---:|---:|---:|
|
||||
| 纯文本 IO —— 11 MB `cat` <sub>(越低越好)</sub> | **95 ms** | 239 ms | 179 ms | 185 ms |
|
||||
| [DOOM-fire](https://github.com/const-void/DOOM-fire-zig) 帧率 <sub>(越高越好)</sub> | **888 fps** | 485 fps | 552 fps | 617 fps |
|
||||
| 冷启动内存 | 116 MB¹ | 105 MB | 128 MB | 130 MB |
|
||||
|
||||
<sub>¹ GUI 105 MB + 常驻守护进程 11 MB。</sub>
|
||||
|
||||
tty7 以设备速度读取 PTY,并在渲染路径之外成批解析输出,热路径全程无锁 ——
|
||||
再大的 `cat` 也不会阻塞在渲染上。(后台守护进程亦服务于此:触发背压前,它最多
|
||||
可领先窗口 16 MiB。)
|
||||
|
||||
测试方法(每款终端怎么驱动、网格是否公平、有哪些坑)连同一键复现脚本,都放在
|
||||
[`scripts/bench/`](scripts/bench/README.md),欢迎自己跑一遍。
|
||||
|
||||
## 🚀 安装
|
||||
|
||||
到 [**Releases**](https://github.com/l0ng-ai/tty7/releases) 下载对应平台的构建:
|
||||
|
||||
- **macOS** —— `tty7-<version>-macos-arm64.dmg`(Apple Silicon)或 `…-x86_64.dmg`
|
||||
(Intel);打开后把 `tty7.app` 拖进「应用程序」即可。
|
||||
- **Windows** —— `…-windows-x86_64.zip`;解压后运行 `tty7.exe`。
|
||||
- **Linux** —— `…-linux-x86_64.tar.gz`;解压后运行 `./tty7`(需要常见的
|
||||
x11/wayland 运行时库)。
|
||||
|
||||
## ⌨️ 快捷键
|
||||
|
||||
下表按 macOS 记法书写 —— 在 Windows 和 Linux 上,把 <kbd>⌘</kbd> 读作
|
||||
<kbd>Ctrl</kbd>。按 <kbd>⌘ ,</kbd> 打开设置,可查看或重新映射全部键位。最常用的几个:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| <kbd>⌘ T</kbd> · <kbd>⌘ W</kbd> · <kbd>⌘ ⇧ T</kbd> | 新建标签页 · 关闭标签页 · 恢复关闭的标签页 |
|
||||
| <kbd>⌘ D</kbd> · <kbd>⌘ ⇧ D</kbd> | 向右分屏 · 向下分屏 |
|
||||
| <kbd>⌘ ]</kbd> · <kbd>⌘ [</kbd> | 下一个窗格 · 上一个窗格 |
|
||||
| <kbd>⌘ ⏎</kbd> | 最大化 / 还原窗格 |
|
||||
| <kbd>⌘ P</kbd> | 命令面板 |
|
||||
| <kbd>⌘ F</kbd> | 搜索回滚缓冲区 |
|
||||
| <kbd>⌃ R</kbd> | 反向搜索 shell 历史 |
|
||||
| <kbd>⌘ +</kbd> · <kbd>⌘ −</kbd> · <kbd>⌘ 0</kbd> | 字号增大 · 减小 · 重置 |
|
||||
|
||||
完整列表(以及你改过的自定义键位)在 **Settings → Keybindings**。
|
||||
|
||||
## 💭 站在这些之上
|
||||
|
||||
- [gpui](https://github.com/zed-industries/zed) —— Zed 的 GPU 加速 UI 框架
|
||||
- [`alacritty_terminal`](https://github.com/zed-industries/alacritty)(Zed 的 fork)—— VT 模拟器、网格与 PTY
|
||||
- [gpui-component](https://github.com/longbridge/gpui-component) —— UI 组件,经由一个[固定版本的 fork](https://github.com/l0ng-ai/gpui-component/tree/tty7)
|
||||
- [tmux](https://github.com/tmux/tmux) —— 常驻守护进程设计的灵感来源
|
||||
|
||||
## 🤝 参与贡献
|
||||
|
||||
欢迎提 bug 和 PR。安全问题请走 [SECURITY.md](SECURITY.md);重要改动都记在
|
||||
[CHANGELOG](CHANGELOG.md)。
|
||||
|
||||
## 📝 许可证
|
||||
|
||||
[Apache License 2.0](LICENSE) · © 2026 l0ng-ai
|
||||
|
||||
<br />
|
||||
|
||||
<div align="center">
|
||||
|
||||
<img src="assets/app-icon.svg" alt="" width="28" height="28" />
|
||||
|
||||
<sub><b>tty7</b> —— 纯 Rust 打造的高性能终端,GPU 渲染,专注打磨提示符体验。</sub>
|
||||
|
||||
</div>
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported versions
|
||||
|
||||
Only the latest release receives security fixes.
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
Please report vulnerabilities **privately** — do not open a public issue.
|
||||
|
||||
Use [GitHub private vulnerability reporting](https://github.com/l0ng-ai/tty7/security/advisories/new)
|
||||
— "Report a vulnerability" under the repository's **Security** tab.
|
||||
|
||||
You should get an initial response within a few days. Please include a
|
||||
reproduction if you can — a byte sequence, a clipboard payload, or a shell
|
||||
snippet is ideal.
|
||||
|
||||
## Scope notes
|
||||
|
||||
A terminal emulator's attack surface is unusual: untrusted input arrives as
|
||||
escape sequences from anything you `cat`, `ssh`, or paste. Reports in these
|
||||
areas are especially valuable:
|
||||
|
||||
- Escape-sequence parsing (VT/OSC/CSI handling, including the daemon-side
|
||||
scanners).
|
||||
- Clipboard and paste handling (e.g. bracketed-paste escapes).
|
||||
- Shell-integration scripts and the `ZDOTDIR` bootstrap.
|
||||
- The daemon's Unix socket / named pipe protocol and its process lifecycle.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="8" y="8" width="104" height="104" rx="24" fill="#ff8a5c"/>
|
||||
<rect x="26" y="32" width="68" height="56" rx="13" fill="none" stroke="#0d1117" stroke-width="6"/>
|
||||
<line x1="26" y1="49" x2="94" y2="49" stroke="#0d1117" stroke-width="4" opacity="0.7"/>
|
||||
<rect x="60" y="60" width="12" height="20" rx="2.5" fill="#0d1117"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 427 B |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"Composer Command","options":[],"args":[],"subcommands":[],"name":"composer"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"An extensible, customizable, free/libre text editor — and more","options":[{"names":["--batch"],"description":"Do not do interactive display; implies -q","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--chdir"],"description":"Change to directory","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--daemon","--bg-daemon"],"description":"Start a server in the background","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--fg-daemon"],"description":"Start a server in the foreground","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--version"],"description":"Display Emacs version information and exit","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--help"],"description":"Display help and exit","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-q","--no-init-file"],"description":"Do not load an init file","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-nl","--no-shared-memory"],"description":"Do not use shared memory","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--no-site-file","-nsl"],"description":"Do not load the site-wide startup file","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--no-desktop"],"description":"Do not load a saved desktop","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-Q","--quick"],"description":"Similar to \"-q --no-site-file --no-splash\", Also, avoid processing X resources","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--no-splash"],"description":"Do not display a splash screen during start-u","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--debug-init"],"description":"Enable Emacs Lisp debugger during the processing of the user init file ~/.emacs. This is useful for debugging problems in the init file","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-u","--user"],"description":"Load user's init file","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-t","--terminal"],"description":"Use specified file as the terminal instead of using stdin/stdout. This must be the first argument specified in the command line","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--file","--find-file","--visit"],"description":"The same as specifying file directly as an argument","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"subcommands":[],"name":"emacs"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"Improved top (interactive process viewer)","options":[{"names":["--help","-h"],"description":"Show help for htop","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--no-color","-C"],"description":"Use a monochrome color scheme","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--delay","-d"],"description":"Delay between updates, in tenths of sec","args":[{"name":"delay","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[{"names":["10"],"description":null},{"names":["1"],"description":null},{"names":["60"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--filter","-F"],"description":"Filter commands","args":[{"name":"filter","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--highlight-changes","-H"],"description":"Highlight new and old processes","args":[{"name":"delay","description":"Delay between updates of highlights, in tenths of sec","optional":true,"variadic":false,"template":[],"suggestions":[{"names":["10"],"description":null},{"names":["1"],"description":null},{"names":["60"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--no-mouse","-M"],"description":"Disable the mouse","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--pid","-p"],"description":"Show only the given PIDs","args":[{"name":"PID","description":null,"optional":false,"variadic":true,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--sort-key","-s"],"description":"Sort by COLUMN in list view","args":[{"name":"column","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--tree","-t"],"description":"Show the tree view","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--user","-u"],"description":"Show only processes for a given user (or $USER)","args":[{"name":"user","description":null,"optional":true,"variadic":false,"template":[],"suggestions":[{"names":["$USER"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--no-unicode","-U"],"description":"Do not use unicode but plain ASCII","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--version","-V"],"description":"Print version info","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[],"subcommands":[],"name":"htop"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"Switch between Kubernetes-contexts","options":[{"names":["--help","-h"],"description":"Show help for kubectx","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--current","-c"],"description":"Show current context","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--unset","-u"],"description":"Unset the current context","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-d"],"description":"Delete context","args":[{"name":"context","description":null,"optional":false,"variadic":true,"template":[],"suggestions":[],"generators":[{"script":["kubectx"]}]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"context","description":null,"optional":true,"variadic":false,"template":[],"suggestions":[],"generators":[{"script":["bash","-c","kubectx | grep -v $(kubectx -c)"]},{"script":["kubectx","-c"]}]}],"subcommands":[],"name":"kubectx"}
|
||||
@@ -0,0 +1 @@
|
||||
{"description":"Switch between Kubernetes-namespaces","options":[{"names":["--help","-h"],"description":"Show help for kubens","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--current","-c"],"description":"Show current namespace","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"namespace","description":null,"optional":true,"variadic":false,"template":[],"suggestions":[],"generators":[{"script":["bash","-c","kubens | grep -v $(kubens -c)"]},{"script":["kubens","-c"]}]}],"subcommands":[],"name":"kubens"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"Next.js CLI to start, build and export your application","options":[{"names":["-h","--help"],"description":"Output usage information","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-v","--version"],"description":"Output the version number","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[],"subcommands":[{"names":["build"],"description":"Create an optimized production build of your application","hidden":false,"icon":"https://nextjs.org/static/favicon/favicon-16x16.png","options":[{"names":["--profile"],"description":"Enable production profiling","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--debug"],"description":"Enable more verbose build output","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"dir","description":"Represent the directory of the Next.js application","optional":true,"variadic":false,"template":["folders"],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["dev"],"description":"Start the application in development mode","hidden":false,"icon":"https://nextjs.org/static/favicon/favicon-16x16.png","options":[{"names":["-p","--port"],"description":"A port number on which to start the application","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-H","--hostname"],"description":"Hostname on which to start the application","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"dir","description":"Represent the directory of the Next.js application","optional":true,"variadic":false,"template":["folders"],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["start"],"description":"Start the application in production mode","hidden":false,"icon":"https://nextjs.org/static/favicon/favicon-16x16.png","options":[{"names":["-p","--port"],"description":"A port number on which to start the application","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-H","--hostname"],"description":"Hostname on which to start the application","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"dir","description":"Represent the directory of the Next.js application","optional":true,"variadic":false,"template":["folders"],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["export"],"description":"Exports the application for production deployment","hidden":false,"icon":"https://nextjs.org/static/favicon/favicon-16x16.png","options":[{"names":["-s"],"description":"Do not print any messages to console","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"dir","description":"Represent the directory of the Next.js application","optional":true,"variadic":false,"template":["folders"],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["telemetry"],"description":"Allows you to control Next.js' telemetry collection","hidden":false,"icon":"https://nextjs.org/static/favicon/favicon-16x16.png","options":[],"args":[{"name":"status","description":"Turn Next.js' telemetry collection on or off","optional":false,"variadic":false,"template":[],"suggestions":[{"names":["enable"],"description":"Enable Next.js' telemetry collection"},{"names":["disable"],"description":"Disable Next.js' telemetry collection"}],"generators":[]}],"subcommands":[]}],"name":"next"}
|
||||
@@ -0,0 +1 @@
|
||||
{"description":"CLI interface for Angular","options":[{"names":["--version"],"description":"View your Angular CLI version","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[],"subcommands":[{"names":["new"],"description":"Create a new Angular app","hidden":false,"options":[{"names":["--create-application"],"description":"Create a default application?","args":[{"name":"project","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[{"names":["true"],"description":null},{"names":["false"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"name","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["generate"],"description":"Generate new files","hidden":false,"options":[],"args":[{"name":"schematic","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"subcommands":[{"names":["application"],"description":"Generates a new application","hidden":false,"options":[{"names":["--style"],"description":null,"args":[{"name":"extension","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[{"names":["css"],"description":null},{"names":["scss"],"description":null},{"names":["sass"],"description":null},{"names":["less"],"description":null},{"names":["styl"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"name","description":"Name of the new app","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["component"],"description":"Generate a new component","hidden":false,"options":[{"names":["--project"],"description":"Project name","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[{"script":["ng","config","projects"]}]}],"required":false,"repeatable":false,"hidden":false},{"names":["--change-detection","-c"],"description":"The change detection strategy to use","args":[{"name":"strategy","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[{"names":["Default"],"description":null},{"names":["OnPush"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--display-block","-b"],"description":"Add :host block to styles","args":[{"name":"boolean","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[{"names":["true"],"description":null},{"names":["false"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--flat"],"description":"Create at the top level","args":[{"name":"boolean","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[{"names":["true"],"description":null},{"names":["false"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"name","description":"Component name","optional":true,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["library"],"description":"Generates a new library","hidden":false,"options":[],"args":[{"name":"name","description":null,"optional":true,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["class"],"description":"Generates a class","hidden":false,"options":[{"names":["--project"],"description":"Project name","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[{"script":["ng","config","projects"]}]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"name","description":null,"optional":true,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"subcommands":[]}]},{"names":["version"],"description":"View your Angular CLI version (update for Angular 14+)","hidden":false,"options":[],"args":[],"subcommands":[]}],"name":"ng"}
|
||||
@@ -0,0 +1 @@
|
||||
{"description":"Run the node interpreter","options":[{"names":["-e","--eval=..."],"description":"Evaluate script","args":[{"name":null,"description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--watch"],"description":"Watch input files","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--watch-path"],"description":"Specify a watch directory or file","args":[{"name":"path","description":null,"optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":true,"hidden":false},{"names":["--watch-preserve-output"],"description":"Disable the clearing of the console when watch mode restarts the process","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--env-file"],"description":"Specify a file containing environment variables","args":[{"name":"path","description":null,"optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":true,"hidden":false},{"names":["-p","--print"],"description":"Evaluate script and print result","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-c","--check"],"description":"Syntax check script without executing","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-v","--version"],"description":"Print Node.js version","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-i","--interactive"],"description":"Always enter the REPL even if stdin does not appear to be a terminal","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-h","--help"],"description":"Print node command line options (currently set)","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--inspect"],"description":"Activate inspector on host:port (default: 127.0.0.1:9229)","args":[{"name":"[host:]port","description":null,"optional":true,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--preserve-symlinks"],"description":"Follows symlinks to directories when examining source code and templates for translation strings","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"node script","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"subcommands":[],"name":"node"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"Run the PHP interpreter","options":[],"args":[],"subcommands":[],"name":"php"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"","options":[{"names":["--version","-V"],"description":"Output the version number","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--help","-h"],"description":"Display help for command","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[],"subcommands":[{"names":["test"],"description":"Run tests with Playwright Test","hidden":false,"options":[{"names":["-g"],"description":"Run the test with the title","args":[{"name":"title","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["--headed"],"description":"Run tests in headed browsers","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--help","-h"],"description":"Display help for command","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"tests","description":"Test files to run","optional":true,"variadic":true,"template":["filepaths","folders"],"suggestions":[],"generators":[]}],"subcommands":[]},{"names":["install"],"description":"Running without arguments will install default browsers","hidden":false,"options":[{"names":["--with-deps"],"description":"Install system dependencies for browsers","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["--help","-h"],"description":"Display help for command","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"browsers","description":"Browser to install","optional":true,"variadic":true,"template":[],"suggestions":[{"names":["chromium"],"description":null},{"names":["chrome"],"description":null},{"names":["chrome-beta"],"description":null},{"names":["msedge"],"description":null},{"names":["msedge-beta"],"description":null},{"names":["msedge-dev"],"description":null},{"names":["firefox"],"description":null},{"names":["webkit"],"description":null}],"generators":[]}],"subcommands":[]}],"name":"playwright"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"Ruby on Rails CLI","icon":"https://avatars.githubusercontent.com/u/4223?s=48&v=4","options":[],"args":[],"subcommands":[],"name":"rails"}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"A ruby build program with capabilities similar to make","icon":"https://avatars.githubusercontent.com/u/210414?s=48&v=4","options":[{"names":["-n","--dry-run"],"description":"Do a dry run without executing actions","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-h","-H","--help"],"description":"Display this help message","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-I","--libdir"],"description":"Include LIBDIR in the search path for required modules","args":[{"name":"LIBDIR","description":null,"optional":false,"variadic":false,"template":["folders"],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-P","--prereqs"],"description":"Display the tasks and dependencies, then exit","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-q","--quiet"],"description":"Do not log messages to standard output","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-f","--rakefile"],"description":"Use FILE as the rakefile","args":[{"name":"FILE","description":null,"optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-r","--require"],"description":"Require MODULE before executing rakefile","args":[{"name":"MODULE","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-s","--silent"],"description":"Like --quiet, but also suppresses the 'in directory' announcement","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-T","--tasks"],"description":"Display the tasks and dependencies, then exit","args":[{"name":"pattern","description":null,"optional":true,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-t","--trace"],"description":"Turn on invoke/execute tracing, enable full backtrace","args":[{"name":"output","description":null,"optional":true,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-v","--verbose"],"description":"Log message to standard output (default)","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-V","--version"],"description":"Display the program version","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"targets","description":null,"optional":true,"variadic":true,"template":[],"suggestions":[],"generators":[{"script":["rake","--tasks","--silent"]}]}],"subcommands":[],"name":"rake"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"description":"Execute a command as the superuser or another user","options":[{"names":["-g","--group"],"description":"Run command as the specified group name or ID","args":[{"name":"group","description":"Group name or ID","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-h","--help"],"description":"Display help message and exit","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-u","--user"],"description":"Run command as specified user name or ID","args":[{"name":"user","description":"User name or ID","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"command","description":"Command to run with elevated permissions","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"subcommands":[],"name":"sudo"}
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user