跳到正文
GitHub·· 7 天前AI 评分58

99apps-id 开源终端优先 AI 开发环境 Termigo

99apps-id/termigo

AI 导读

99apps-id 开源了终端优先的 AI 原生开发环境 Termigo,基于 Tauri 2 与 Rust 构建、React 19 前端,集成原生 PTY 终端、代码编辑器、文件浏览器、Git 图形化源码管理和网页预览面板。

正文

Termigo

Terminal-first, AI-native development workspace.

Repository · Features · Getting started · CLI · Credits

platform license no Electron no telemetry CI latest release


Termigo is a lightweight open-source, terminal-first AI-native development environment (ADE) built on Tauri 2 + Rust with a React 19 frontend. A native PTY backend, an agentic AI side-panel that runs against your own keys or fully local models, a code editor, file explorer, source control with a git graph, and a web preview pane, all in one window. No telemetry. No account. Your API keys stay in the OS keychain or with the provider's own CLI.

Termigo is an independent, standalone AI-native development environment maintained by 99apps-id, extended with a Go command-line companion (termi-go) for automation: agent runs, MCP, skills, and project scaffolding.

Features

Terminal

  • Native PTY backend via portable-pty (pwsh, powershell, cmd, zsh, bash, fish)
  • xterm.js with WebGL renderer, multi-tab with background streaming
  • Split panels (horizontal and vertical)
  • Inline search, link detection, true-color
  • Programs that set the terminal title (ssh, htop, a title builtin) name the tab; long-running commands report progress on the taskbar (OSC 9;4)
  • Dev-server URLs printed in a terminal are detected and open in the embedded browser with one click
  • Flow-controlled write path stays responsive under a flood of output (and when the screen is locked), instead of growing an unbounded backlog
  • Drag files from the explorer into a terminal as shell-safe quoted paths
  • Per-tab workspace environments on Windows (Local or WSL distro)
  • Spaces restore tabs, working directories, and split layouts across launches
  • Persist terminal processes across restarts (opt-in): host each leaf's shell inside a named tmux session (Unix) so it survives an app relaunch; the setting is surfaced honestly where tmux isn't available (Windows)

SSH & remote files

  • Connect to remote hosts with ssh-agent, private key, or password auth, directly as a terminal tab (ProxyJump chains supported)
  • First-connect host-key verification (trust-on-first-use with fingerprint pinning): the handshake pauses until you confirm
  • SFTP file explorer: browse, create, rename, delete, upload (drag & drop) and download over the active SSH session
  • Port forwarding (-L) through the session

AI agent

  • BYOK providers: OpenAI, Anthropic (Claude), Google (Gemini), Groq, xAI (Grok), Cerebras, OpenRouter, DeepSeek, Mistral, plus any OpenAI-compatible endpoint

  • Local / offline: LM Studio, MLX, Ollama

  • Tool context you control. The full toolset is ~125 tools and ~80 KB of JSON Schema on every request. Settings → Agents offers two independent levers: switch off whole optional domains (browser, GitHub, LSP, web, skills, SQL, PDF, images, worktrees, …), and turn on load tools on demand, which sends the coding loop plus a find_tools search and adds a domain when the agent asks for it - measured at 8.0k tokens per request instead of 20.5k, with full capability kept. A tool call for a name that does not exist is answered with the real toolset, a "did you mean" list, and the discovery hint, so the agent corrects itself instead of reporting the capability as missing.

  • Skills. The agent writes reusable procedures for itself in .termigo/skills/<name>/SKILL.md - a deploy sequence, a debugging route that worked, a release checklist - and reads them back in later sessions. This is what makes it better over time rather than merely better informed: memory stops a session starting from zero, a skill means a procedure worked out once never has to be worked out again. Re-saving a name replaces it, so a skill improves with use. Only names and descriptions reach the system prompt; bodies load on demand through use_skill, so a shelf of skills costs almost nothing until one is needed. Plain Markdown with frontmatter, so you can read, edit or delete any of them by hand. find_skill searches every skill library on the machine on demand - your own, and those installed by other agent tools

    • so a large collection stays reachable without any of it sitting in the prompt. Skills written for another agent still parse, and use_skill says so when one calls tools Termigo does not have.
  • Self-maintaining and global memory. The agent records durable project facts in .termigo/memory.md (and machine-wide preferences in ~/.termigo/memory.md) and reads them back in every later session, so build commands, conventions and decisions do not have to be re-explained. Facts are captured two ways: a remember tool the model calls deliberately (visible in the transcript, approval-gated like any workspace write, supporting scope: "project" | "global"), and a failure-aware summary sweep when a session is left behind that extracts failed terminal commands, non-zero exit codes, and tool errors into actionable [GOTCHA] entries. When assembled into system prompts, general facts are relevance-ranked against the active query while all safety-critical gotchas are unconditionally preserved. Your hand-written TERMIGO.md is never rewritten, so you can always tell what you wrote from what the agent inferred, and deleting a line makes it forget. The file is bounded in entry length, entry count and total size, because everything in it costs context on every request. The sweep only runs in the auto-approve modes: in Ask every time, nothing is written without a click.

  • Sub-agents read in parallel with concurrency bounds. Work that means covering a lot of ground: auditing a project, exploring an unfamiliar codebase, reviewing four modules: is split into tasks that run at the same time, each with its own fresh context, and their findings come back together. Tasks can be chained: one that declares depends_on waits for the others and receives what they found, so a task that synthesises can be handed everything the others gathered. A request to study something broad is pinned to this fan-out, because a model asked politely in a prompt to parallelise will ignore it; a narrow request is left alone, and telling it not to use sub-agents is respected.

    Full toolset, held by approval - not read-only. A sub-agent gets the same tools as the main agent (read, search, edit, shell, git, extensions), so it can actually do the job it was given; what keeps that safe is that every mutating, exec or third-party call routes through the same approval queue, so nothing runs without your click. A global concurrency pool (SubagentConcurrencyPool, default limit 4) prevents provider throttling, while hierarchical slot yielding (yieldSlot) prevents parent/child deadlocks. Local subagents isolate their workspace from remote SSH tabs, and transient rate limits retry with exponential backoff. Spawn tools are withheld only at the nesting-depth cap (subagentMaxDepth, default 3), so a sub-agent can delegate to its own sub-agents up to that bound and no further. Alongside the general roster there are focused pentest specialists (pentest-recon, pentest-web, pentest-network) the main agent can dispatch in parallel on one authorized, in-scope target.

  • One reasoning block per run, not one per step. The agent's thinking is collected into a single block that scrolls, instead of a new "Reasoned" label stacking up on every step and pushing the answer off screen. The tool calls it produced stay visible around it, so you can still see what it actually did.

  • Every run writes one line you can read. The app log records, per request: how long context assembly took, the prompt size broken down by what contributed it, the cache hit rate, how many steps were used against the budget, why the run stopped, and the model. When the agent feels slow, that line says which part was slow - an MCP server starting, a large project memory, a cold cache - instead of leaving you to guess. Most of the fixes in recent releases were found by reading it.

  • Searchable chat history. Sessions persist across launches; the session picker filters them by title as you type and, on demand, by what was actually said in the messages.

  • Steer, stop and resume a run. Typing while the agent works queues the message and delivers it when the current run settles, so a correction reaches it instead of being dropped - attachments included. Queued messages are shown with a way to take them back. Stop reaches the work, not just the reply: it kills the command the agent is running rather than leaving a shell going behind a stopped agent, and the transcript then offers to continue. An interrupted tool call is closed out as interrupted rather than erased, so the model can see its work was cut short instead of being shown a past in which it never made the call - and repeating it.

  • The run says why it stopped, and goes on when you ask. One request gets one explicit per-round cap, resolved per model: 500 steps on an API-key model, 10,000 on an OAuth / keyless model (ChatGPT, Claude OAuth, xAI OAuth, Antigravity, GitHub Copilot, Muse), whose real limit is the provider's 5-hour usage window rather than a step count. It is one number every round, so Continue resumes the task on the same cap for that model - never a hidden ladder that quietly lets a paused run go further than the number it showed. A task that needs more depth earns it round by round, one informed click at a time. Two guards sit alongside the budget: the same tool called three times with identical input, and two turns in a row that call no tool at all. The transcript names which one fired, because "it repeated itself" and "it ran out of budget" call for different responses - one is worth a click, the other is worth a sentence of extra detail.

  • It does not die when it outgrows the window. If a request exceeds the model's context window, Termigo learns the real limit from the provider's rejection, compacts the transcript harder, and resumes the SAME run automatically - so a long task keeps going instead of stopping mid-way. A per-session throttle stops it looping when compaction can never fit, and a Try again button stays as the manual fallback.

  • Finished work stops costing tokens. Once a span of history is verified - its changes are saved to git by a checkpoint or commit - the next turn replaces that whole span with a short checkpoint summary (files changed, commands and checks run, a compact diff note) instead of resending the full chat. The model keeps knowing the current state without re-paying for the history that produced it.

  • It survives a dropped connection or an exhausted quota. If the internet drops, the agent pauses and resumes automatically when you're back online; if the provider's quota or credits run out (or a rate limit is hit), the run is preserved so you can top up or wait and click Try again to continue exactly where it left off.

  • Provider quirks heal themselves. A custom endpoint whose "thinking mode" rejects a pinned tool call gets the pin dropped and the same request resent automatically (broad "audit this repo" prompts no longer die on a red card); a long, bursty generation - a report from a thinking-mode model can pause over half a minute between chunks - is given a generous idle bound instead of being killed as stalled, and a genuine mid-stream stall routes to the same auto-retry rather than a dead error card.

  • A run cut off by a restart is recoverable. The transcript is persisted, and when the app reopens the interrupted session is brought back with a Resume row - the round counter is kept, so continuing does not restart the task from scratch. (A deliberate stop or a guard that tripped offers the same continue path.)

  • Grounded RAG and persistent code index. Codebase exploration combines Okapi BM25 lexical ranking with scope-boundary detection and symbol retrieval to locate relevant references swiftly. The BM25 index is cached to disk at .termigo/code-index.json for instantaneous warm startups across sessions. The agent enforces grounding validation before proposing edits: paths and function references must resolve against real workspace files, preventing hallucinated imports or phantom paths.

  • Autonomous execution guards. A loop circuit breaker detects repetitive no-progress iterations early, while command outputs are automatically truncated to prevent massive terminal dumps from saturating the context window. Autonomous harness profiles let you fine-tune agent behavior between cautious interactive pair-programming and unattended autonomous tasks.

  • You can read the request, not infer it. Turn on Capture requests (Settings → Agents → Diagnostics) and an inspector appears in the AI bar holding each request as assembled: the system prompt, the message history after pruning and compaction, and the exact tool set attached on that step - which is usually the answer when the agent ignores a tool you expected it to use, or reaches for one you did not. A rejection names a symptom and the transcript shows the reply; neither shows the three things that decide what actually happens. Captures are kept in memory only, never written to disk, capped at 30, and hold no API keys: the snapshot is taken before the provider SDK attaches credentials.

  • The agent can define its own tools. A command worth repeating is saved as a named tool with {{placeholders}} in .termigo/tools.json and called by name afterwards. It is a command template, not code - running one goes through the same shell safety check, approval tier and remote routing as bash_run, so a custom tool can do nothing the agent could not already do. Arguments are shell-quoted with no raw mode.

  • Agentic workflow: plans, sub-agents, project memory via TERMIGO.md, read, write, edit, multi-edit, grep, glob, move, copy, delete, cross-file literal replace, HTTP fetch, bash with approval gating, background processes (bash_background spawn, bash_wait to block until a build or install finishes, bash_logs to tail, bash_kill to stop), and SSH port forwarding so a service on a remote host becomes reachable locally

  • Tool call auto-repair and parameter normalization. Parameter aliases (query/path on grep/glob, max_results clamping on code_search, string-to-array on replace_in_files) and equivalent tool names (view_file -> read_file, run_command -> bash_run, replace_file_content -> edit) are automatically repaired before validation.

  • Full cross-platform shell execution. Agents execute shell commands directly without sandbox allowlists across bash, zsh, cmd, and PowerShell, with full support for Git worktrees, background processes, and project toolchains.

  • Tool calls are approval-gated; approvals resume the run (including OpenAI-compatible providers such as DeepSeek)

  • Graduated auto-approval. Choose how much the agent may do without stopping: Auto-approve all (the default for a fresh install), Auto-approve edits (file changes in the workspace run, commands and agent hand-offs still ask), or Ask every time. The mode is always visible in the AI status bar, never buried in settings. Crucially it changes only what stops for a click: the path and shell-command safety checks run inside every tool regardless, so no mode can authorise something the safety layer refuses. Read-only tools never asked in the first place.

  • Relay Telegram into the agent. Give a bot its token and message it from your phone: it drives Termigo's own in-app agent and streams live progress (the current step, the loop round, the task checklist and approvals) plus the final answer back, so a task, its edits, approvals and memory all behave exactly as if you had typed in the chat. Configured in Settings - Agents - Telegram relay (the token lives in the OS keychain, never a settings file). The bot answers /status, /help, /query <question>, /run <task>, /stop, /new, /continue, /approve, /model (an interactive provider

    • model picker for the models active in Termigo, including custom endpoints such as StepFun and Qwen/DashScope) and /cost, and shows a live status chip in the AI status bar. Just type a question or task directly - no /query prefix needed. It long-polls from the desktop app, so it is only reachable while Termigo is open.
    • Approvals never hang silently: when the agent needs a click, the bot posts the pending action with Allow session, Allow always, and Deny inline buttons. No more typing /approve without knowing why.
    • Step-cap continuation: /continue (or the inline button) resumes the agent past its per-round cap without leaving Telegram.
    • Custom endpoint models: /model resolves raw model names and endpoint IDs (e.g. step-3.7-flash) to the correct compat ID and persists the choice as the new default. Conversations mirror both ways, and a diagram the agent draws (a fenced Mermaid block) is rasterised and posted as a picture along with any report file it previewed (preview_file), so graphs and finished reports show up on your phone too. While a run is in flight the bot keeps a live "typing..." indicator in the chat (alongside the status / step / todo stream), and messages it injected are never echoed back - the mirror is paused before a Telegram dispatch is submitted, so you never see your own text twice. For headless / always-on deployment (e.g. a VPS running 24/7), see docs/headless-vps.md.
  • Deleting is never delegated. No mode speaks for you here, including Auto-approve all: delete_file always asks, and so does any command that removes files - rm, rmdir, git clean, find -delete, PowerShell's Remove-Item and its aliases - wherever it sits in the line, so pnpm build && rm -rf dist is not read as a build. The gate follows the command rather than the tool name, so a custom tool cannot route around it. Every other change an agent makes can be recovered by reading the file again or from git; a delete of something untracked leaves nothing to read at all, and that asymmetry is worth one click even from someone who has delegated everything else.

  • Agent works on the remote host. When the active terminal is an SSH session, the agent's file tools act on the server: read_file, list_directory, write_file, create_directory, edit, multi_edit, move_file and delete_file all go over SFTP. Windows drive paths (C:\...) still mean this machine, since they cannot mean anything on a POSIX host. grep and glob search the server too, using its own grep and find over a dedicated exec channel rather than walking the tree over SFTP - one command instead of thousands of round trips. Every value interpolated into those commands is single-quoted, so a pattern cannot become a second command. bash_run runs on the server too, from the remote shell's working directory, so the agent can install packages, reload Caddy or bring a compose stack up without you relaying commands. Remote commands are gated by what they do rather than by being remote: under Auto-approve edits, one that only inspects (ls, docker ps, git status) runs, and anything that could change the server stops for a click - as does anything the classifier does not recognise. Under Ask every time all of them ask; under Auto-approve all none do, except one that deletes - that asks on any host, in any mode. replace_in_files, copy_file and bash_background still have no remote form and refuse while a session is open, saying what to use instead rather than quietly acting on your own disk.

  • Tools the agent defines for itself. After running something worth repeating, the agent can save it as a named tool with create_tool, and call it by name from then on. A tool is a shell command template with {{placeholders}}, stored in .termigo/tools.json - not code. Running one goes through the same path bash_run takes, so the shell safety check, the approval tiers and the remote/local routing all apply unchanged: a custom tool can do nothing the agent could not already do. Every argument is shell-quoted on substitution, with no raw mode, so a value can never become a second command.

  • Extension tools. An extension that declares contributes.aiTools in its manifest has those tools offered to the agent as ext__<extension>__<tool>, with the JSON Schema and approval preference it declared. Like MCP tools they never ride along with Auto-approve edits, since that mode is a statement about files in your workspace, not about third-party code.

  • MCP servers. Tools from any configured Model Context Protocol server are offered to the agent alongside the built-in ones, named mcp__<server>__<tool> so their origin stays visible in the transcript. Configure them in .termigo/mcp.json in the workspace, or ~/.termigo/mcp.json for every project, using the standard mcpServers shape:

    {
      "mcpServers": {
        "github": {
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-github"],
          "env": { "GITHUB_TOKEN": "..." }
        }
      }
    }

    A project entry overrides a user entry of the same name, and the same file is read by the Go companion CLI, so a server configured once works in both. MCP tools always ask for approval, including under Auto-approve edits: that mode is a statement about files in this workspace, not about arbitrary third-party actions. A server that fails to start costs only its own tools, not everyone else's. Tools with nullable descriptions (description: null) and dynamic string/int JSON-RPC IDs are handled gracefully, and changing servers in Settings immediately refreshes the active agent tool cache.

  • Database interaction (run_sql, list_sql_connections). The agent can list configured database profiles from the SQL Explorer store and execute queries against saved connections by name (e.g. run_sql with connection: "app_db" or a direct URI). All queries stop for confirmation under the EXEC_TOOLS approval policy, and results are presented in-chat with custom SQL syntax blocks and head-preserved row outputs.

  • Web search, documents, images, clipboard, environment. web_search queries DuckDuckGo through the same SSRF-guarded HTTP path as fetch (no API key needed) and returns the top results - title, URL, snippet - so the agent can answer questions that live outside the workspace. read_pdf extracts the text of a PDF (handles compressed streams, page-by-page, capped) so a report or spec can be read straight into context; scanned/image-only PDFs report that they need OCR. read_image hands an image file to the model as a real visual part, so a screenshot, mockup or diagram on disk can be seen (requires a vision-capable model). clipboard_get / clipboard_set read and replace the clipboard (write asks for approval), and env_get / env_list inspect the process environment read-only - enough to answer "what is PATH?" without a shell round-trip.

  • Artifacts the agent produced stay reachable. Canvases (render_view), previews (open_preview) and files (write_file) land in an Artifacts panel (the layers button in the AI status bar), and each can be reopened - files in the editor, previews and canvases in a preview tab - so something the agent drew or wrote is one click away instead of buried in the transcript.

  • The agent can ask you a question mid-run. ask_user renders a clickable chooser in the chat (2–6 options) and the agent waits for your pick - useful for choosing between approaches or confirming a risky call - instead of guessing and having to redo work.

  • Opt-in post-execution confirmation. When enabled (Settings → Agents → Confirm after mutations), a mutating tool that succeeds pauses the run and asks Keep / Revert before the agent continues; Revert restores the touched paths from git. Off by default so everyday runs stay uninterrupted.

  • Sub-agents can nest - up to a depth you choose. A sub-agent may spawn its own sub-agents (each with the full toolset), capped by the subagentMaxDepth preference (1–5, default 3); at the cap the spawn tools are withheld so recursion cannot loop. A configured sub-agent model that would cost more than the main run falls back to the main model instead. Finished sub-agent runs are persisted to disk and shown with depth and step detail in the run cards.

  • Coding-agent orchestration: spawn an external agent CLI in a terminal (Claude Code, Codex, Gemini, Pi, OpenCode, Grok, Aider, Qwen, Cursor), inspect its output, and send follow-up work through approval-gated tools; activity hooks are enabled for the CLIs that support them

  • User-defined coding-agent CLIs. Register your own agent command in Settings → Agents → Custom coding agents and it becomes a first-class target for spawn_coding_agent and the launch panel the same as the built-ins

  • Composer: prompt snippets via #handle, files via @path, voice input

  • Custom agents with their own system prompt and tool subset

  • Plan mode for multi-step work, generates and confirms before doing

Code editor

  • CodeMirror 6 with support for TS/JS, Rust, Python, Go, C/C++, Java, HTML/CSS, JSON, Markdown and more
  • Inline AI autocomplete with local model support
  • AI edit diffs, accepted or rejected hunk by hunk
  • Opt-in language server support (diagnostics, navigation, completion, formatting)
  • Rendered Markdown plus image, video, audio, and PDF viewing
  • Vim mode and built-in editor themes (Kanagawa, Catppuccin, Rosé Pine, Dracula, ...)

Source control

  • Stage / unstage hunks, commit (Cmd+Enter / Ctrl+Enter), push with upstream awareness
  • Branch display including detached HEAD state
  • Git history pane with a real commit graph (lane rendering for merges/branches)
  • Commit search and filter, click through to the remote commit page

Explorer & preview

  • Catppuccin icon theme, fuzzy search, keyboard navigation, inline rename, live updates when files change on disk
  • Attach files and selections directly to the AI side-panel
  • Web preview auto-detects local dev servers; external URLs open in a child webview

SQL Explorer

  • Connect to and manage SQLite, PostgreSQL, and MySQL/MariaDB databases
  • Interactive SQL query runner with tabular results and syntax highlighting
  • Seamless AI agent integration via list_sql_connections and run_sql tools
  • Security-first design: all agent database queries require explicit approval under EXEC_TOOLS
  • Normalized CLI binary execution across platforms with Windows CREATE_NO_WINDOW support

Themes & customization

  • Custom themes built in-app, bundled presets, background images with adjustable opacity and blur
  • Editor theme is independent from the app theme
  • Light and dark themes tuned for legible contrast (WCAG-aware muted text, visible control edges, and readable syntax highlighting)
  • Interface language: English or Bahasa Indonesia (Settings › General)
  • Settings backup & restore: export every preference to a JSON file and restore it on another machine (secrets stay in the OS keychain, never in the file)

Getting started

Install

npx termigo          # download, verify and install the build for this machine, then start it
npm i -g termigo     # then just: termigo

The installer has no dependencies and nothing to compile: it picks the right release asset for your OS and architecture, checks it against the SHA-256 GitHub publishes, and installs it. It also installs termigo-go, the Go companion that carries the interactive terminal (termigo-go tui). --dry-run shows what it would do, --format picks a different artifact (npm/termigo/README.md has the full list).

Servers: a release install is safe on a headless VPS, but it is not a replacement for the Xvfb setup in docs/headless-vps.md - xvfb and dbus still have to be present, and two Termigo instances must never share one data directory.

Prerequisites

Run from source

pnpm install
pnpm tauri dev       # development (starts vite + Tauri)
pnpm tauri build     # production bundle (MSI + NSIS on Windows, AppImage + deb on Linux)

VPS / headless: see docs/headless-vps.md for the Xvfb + systemd setup. Always use pnpm tauri build --no-bundle on the server - raw cargo build skips the frontend and produces a non-functional binary.

Checks:

pnpm check-types          # tsc --noEmit
pnpm lint                 # biome lint
pnpm test                 # vitest
pnpm check:commands       # guard: all invoke() names are registered in Rust
cd src-tauri && cargo clippy --all-targets -- -D warnings && cargo nextest run

Windows notes

  • Default shell detection: pwsh.exe (PowerShell 7+) → powershell.exe → cmd.exe
  • WSL is a first-class workspace environment, not a wrapped subprocess

CLI

Termigo ships two separate command-line programs. They do different jobs, and only the first one is installed with the app.

1. Control CLI (Rust, bundled with the app)

Installed alongside the desktop app as termigo. It talks to a running Termigo window over the local control socket:

termigo README.md              # open a file in the running app
termigo README.md --line 42    # open at a line
termigo open README.md         # explicit form of the same thing
termigo ping                   # is the app reachable?
termigo capabilities           # what this build supports
termigo identify               # which window/pane answered
termigo help

It does not know agent, mcp, skill, doctor or init. Those belong to the Go companion below, and asking this binary for them now says so.

2. Go companion (agent and automation)

Lives in cli/ and is not installed by the app. It is two things: a standalone terminal agent that talks to the providers directly, so it runs on a headless box with no webview, and an automation companion that drives a running Termigo over its control socket.

cd cli
go build -o termi-go ./cmd/termigo   # or: go run ./cmd/termigo <args>

Name the binary something other than termigo (for example termi-go), or put it on PATH ahead of the control CLI. Two binaries with the same name is exactly what makes termigo agent list fail confusingly.

./termi-go help

# standalone agent (no desktop app needed)
./termi-go login muse                    # OAuth: xai-oauth, openai-codex, claude-oauth, antigravity, github-copilot, muse
./termi-go ask "summarise this file"     # one prompt
./termi-go code "fix the failing test" --yes   # file/shell/git loop
./termi-go chat                          # Bubble Tea TUI; --continue resumes the last session
./termi-go telegram                      # companion bot
./termi-go service install               # run the bot 24/7 (systemd/launchd/schtasks)

# automation and driving a running Termigo
./termi-go doctor --json                # inspect local tools
./termi-go init <dir>                   # scaffold .termigo/ + TERMIGO.md
./termi-go agent list                   # installed agent providers
./termi-go agent run codex "explain this repo" --access read-only
./termi-go skill create review "Review diffs before commit"
./termi-go mcp list                     # configured MCP servers
./termi-go mcp tools fs                 # list tools of an MCP server
./termi-go config                       # show user configuration

# drive a running Termigo
./termi-go tui                          # interactive terminal for the app
./termi-go setup                        # store a key, then pick a model
./termi-go models                       # models this Termigo build ships
./termi-go model deepseek-v4-pro        # set the default model
./termi-go settings                     # show the app settings
./termi-go approval ask                 # wait for confirmation on every edit
./termi-go secret deepseek              # store a key (prompted, not echoed)

TUI commands: /model (provider then model), /providers, /settings, /status, /cost, /setup, /key <provider> <key>, /login <provider>, /sessions, /new, /copy [n] (OSC 52), Ctrl+Y copies the last reply. Every turn is saved to <state home>/sessions/*.json, so --continue resumes the last conversation for the workspace and --session <id> a specific one. Configured MCP servers are connected at start and their tools offered under a server__tool name.

  • Auth: login/logout run the vendor OAuth device or PKCE flows and store tokens in the CLI's own 0600 secret file. The Antigravity client pair is stamped into the binary at build time from a repository secret or the git-ignored .env.local, never committed.
  • Providers: Codex, Claude Code, Gemini, Antigravity, Ollama (local). agent run drives Codex, Claude and Gemini in print mode and Ollama over its local HTTP API; a provider with no headless mode is reported rather than launched blind.
  • Provider overrides: providers.<id>.command in ~/.termigo/config.json points at a CLI installed outside PATH; model and endpoint are honoured the same way.
  • Skills: project- and user-scoped SKILL.md folders under .termigo/skills/ and ~/.termigo/skills/
  • MCP: standard mcpServers registry in .termigo/mcp.json, JSON-RPC 2.0 over stdio (initialize, tools/list, tools/call, ping)
  • Driving the app: tui, setup, models, model, settings, approval and secret talk to the running app over its loopback control socket, so they need it open. The app owns the model registry, the settings model and the keychain, so the CLI asks instead of keeping a copy that can drift, and settings are written through the same setters the Settings window uses.
  • API keys: secret hands a key to the running app, which stores it in the OS keychain on macOS and Windows and in secrets.json (mode 0600) in the app data dir on Linux. The CLI keeps no copy and never echoes the value. Credentials for the agent providers above still stay with each provider's own CLI.

See docs/ for the MCP, skills, agents, and architecture guides.

Screenshots

The workspace with a browser tab
The window: the agent auditing a project with a browser tab open beside it, spaces and tabs across the top, and the approval mode always visible in the status bar

The agent working on a remote server over SSH
Connected to a VPS over SSH: the remote /etc filesystem browsable in the explorer beside the local project, and an SSH tab that is an ordinary terminal

AI agent creating tables and opening Excel automatically
AI automation in action: the agent automating spreadsheet creation, structuring data tables, and launching Excel directly from terminal workflows

A terminal running the Antigravity coding agent
A terminal is a full terminal: run any CLI in it - here the Antigravity coding agent in accept-edits mode - interactive and full-colour, beside the local project tree

The New SSH connection dialog
Adding a host: password, private key or ssh-agent, an optional ProxyJump chain and port forwards. Credentials go to the OS keychain, never to a file in the repo

The Extensions manager in Settings
Settings → Extensions: install, enable and update packages - here the Termigo Pentest & RE Kit from a GitHub repo or local zip

Agent harness profiles in Settings
Settings → Harness: pick how the agent is driven - Balanced, Plan first, Verify before finish, Terminal-first, Shorter loop

Picking a model by provider
Picking a model: choose a provider, then a model. Only the providers active in Termigo are offered, and custom endpoints such as StepFun appear too

Telegram relay with a model menu
Telegram relay: message the agent from your phone - just type a question (no /query needed), and /model opens a provider + model picker

Theme picker in Settings
Settings → Themes: pick a palette, or import and create a `.termigo-theme`

Architecture

Two processes. The webview renders and thinks, Rust touches the machine, and the only path between them is invoke() over a command list that CI validates.

graph TD
  classDef ui fill:#e8f0fe,stroke:#3b6fd4,color:#1a2b4a
  classDef ipc fill:#fff4e0,stroke:#d98b00,color:#5a3a00
  classDef rs fill:#e6f4ea,stroke:#2f855a,color:#1c3d28
  classDef os fill:#fce8e8,stroke:#b32d2d,color:#5a1414

  subgraph FE["src/ - React 19 + TypeScript webview"]
    UI["terminal - xterm panes, renderer pool, splits"]
    ED["editor - CodeMirror 6, diffs, LSP client"]
    SCM["explorer, preview, markdown, source control"]
    RMT["ssh tabs and SFTP browser"]
    AI["ai - agent loop, tools, subagents, sessions"]
  end

  IPC{{"IPC boundary - invoke plus streaming Channels, allowlisted in src-tauri/src/lib.rs"}}

  subgraph BE["src-tauri/ - Rust backend"]
    PTY["pty - portable-pty, ConPTY, OSC 7 and 133 shell integration"]
    FSG["fs, git, shell, history"]
    NET["net, browser, sql"]
    REM["ssh, lsp, workspace"]
    SEC["secrets, backup"]
    EXT["mcp, extensions, agent, control"]
  end

  subgraph OS["The machine"]
    SH[("shells and PTYs, local or WSL")]
    FS[("filesystem, git repositories, OS keychain")]
    API[("provider APIs and local LLMs")]
    SRV[("remote hosts over SSH")]
  end

  GO["Go CLI in cli/ - doctor, init, agent run, skill, mcp, config"]

  UI & ED & SCM & RMT & AI --> IPC
  IPC --> PTY & FSG & NET & REM & SEC & EXT
  PTY --> SH
  FSG --> FS
  NET --> API
  REM --> SRV
  GO -->|"control_respond"| EXT

  class UI,ED,SCM,RMT,AI ui
  class IPC ipc
  class PTY,FSG,NET,REM,SEC,EXT rs
  class SH,FS,API,SRV os

Loading

Three things hold that boundary in place rather than a convention:

  • scripts/check-invoke-commands.mjs fails the build if any invoke("cmd") in src/ has no matching entry in the generate_handler! list. An unregistered command does not exist, and a typo in one surfaces at check time instead of at runtime.
  • src/modules/ai/lib/security.ts and src-tauri/src/modules/shell/mod.rs provide an unconstrained, open execution environment with no sandbox or path boundary limitations, supporting Git worktrees and project instructions in USER.md, AGENTS.md, and TERMIGO.md.
  • Capability permissions in src-tauri/capabilities/default.json cover the window, so plugin APIs still need an explicit grant even when a command is registered. Custom commands do not each need an entry there.

The Go CLI is the automation layer: anything useful headlessly lives in cli/internal/ first. The full command catalog, grouped by module, is in docs/architecture/two-process-model.md.

Privacy and safety

  • Local first. Folders, commands, keys, and project context stay on the machine. No telemetry, no account.
  • Keys stay with their owners. Provider credentials live in the provider's own CLI config or the OS keychain.
  • Approval gates. Agent file changes and commands require review/approval; the workspace is the boundary for file operations.
  • MCP is explicit. Servers only run when you configure and connect to them.

Credits

Termigo was originally founded upon core components from Terax by Crynta (Apache-2.0). The initial Tauri/Rust backend, xterm.js terminal integration, CodeMirror editor, and AI pipeline foundations originated in the work of Crynta and the Terax contributors.

The design also draws inspiration from TEDI (by Ilham Riski Wibowo) for its "one window, many tools" direction. No TEDI source code is included in this repository.

License

Apache-2.0.

来源:GitHub · github.com