Skip to content

Latest commit

 

History

History
861 lines (563 loc) · 52.7 KB

File metadata and controls

861 lines (563 loc) · 52.7 KB

Termpolis Documentation

The definitive guide to Termpolis — Secure AI-Assisted Development. The local-first multi-agent terminal where Claude, Codex, and Gemini work as a team, coordinated by a dedicated AI conductor, without your source code leaving the machine.

This document covers installation, the AI Security Center, the share-to-Slack/Teams workflow, every feature, every panel, every keyboard shortcut, and the architecture behind the swarm. Screenshots live in ../e2e/screenshots/docs/ and are mirrored to the website at termpolis-web/docs/screenshots/.


Table of Contents

  1. Overview
  2. Installation
  3. First Launch & Welcome Screen
  4. The Sidebar
  5. Terminals
  6. Tab, Split & Grid Views
  7. Settings
  8. Themes
  9. Keybindings
  10. Agent Capability Ratings
  11. Command Palette
  12. Prompt Templates
  13. Workflow Orchestrator
  14. Context Panel
  15. History Search
  16. Conversation Search
  17. Git Panel
  18. AI Agent Profiles
  19. MCP Server
  20. Swarm Dashboard
  21. AI Conductor
  22. Activity Feed
  23. Intervention Controls
  24. Swarm Review Panel
  25. Shared Memory (RAG)
  26. Observability
  27. Status Bar
  28. Troubleshooting
  29. Architecture
  30. Keyboard Shortcut Reference

1. Overview

Welcome screen

Termpolis is a cross-platform desktop terminal manager (Windows, macOS, Linux) built on Electron + React + TypeScript with node-pty powering the underlying shells. It ships as a native app — code signed on Windows, notarized on macOS.

What makes it different:

  • Secure AI-Assisted Development: a built-in AI Security Center (Settings → Security) auto-scans every AI prompt against 70+ secret patterns (AWS, GitHub, Azure, GCP, Stripe, Slack, JWT, PEM, …), enforces Gemini paid-tier mode, keeps a local JSONL audit log, and surfaces per-provider training-disposition facts sourced from live ToS pages. See the Security section.
  • Multi-agent swarm: Claude Code, Codex, and Gemini CLI work together on a task. A dedicated Claude Code instance acts as the conductor.
  • MCP server baked in: AI agents can control Termpolis via Model Context Protocol — open terminals, run commands, send messages.
  • Transparent routing: every subtask shows which agent got it, why, and what it cost.
  • Activity observability: every token, every tool call, every message from every agent is visible in real time.
  • Intervention controls: pause, cancel, or steer any agent mid-task without leaving the feed.
  • Shared memory: a RAG-backed memory store that any agent can read and write via MCP.
  • MCP-native end to end: all three agents speak MCP — no terminal-output bridges, no parser glue, no special-case code paths.
  • Share-ready output: a four-way Copy submenu (Ctrl+Shift+M) — Copy as Code Block, Plain Text, With Command, or PNG Image — turns any terminal selection into a Slack/Teams/PR-ready paste. See Copy for Slack / Teams / PRs.

Everything is built around the idea that you're not writing code alone anymore — you're orchestrating a team, and you need the tools to do it well, securely.

Security Center

The AI Security Center at Settings → Security is the security backbone of Termpolis. Every check runs on the local machine. None of these features send data to Termpolis or any third party.

  • Per-provider training-disposition facts. Live ToS-sourced summaries: Claude (default off), Codex (default off), Gemini paid (excluded), Gemini free OAuth (Google may use prompts, flagged yellow).
  • Auto-scan on every prompt. Once you launch claude, codex, or gemini in a terminal, every Enter and every paste-sized chunk (≥32 bytes) is scanned in main-process memory against 70+ regex rules before it reaches the PTY. Hits are redacted in place, audited as redaction_hit events, and surfaced via a dismissable banner. Catalog covers AWS (access/secret/session), GitHub (classic/fine-grained/OAuth/runner), GitLab, Bitbucket, Azure (Storage, SAS, conn-string, AD client secret, DevOps PAT), GCP (SA JSON, OAuth client), AI providers (OpenAI, Anthropic, Google, HuggingFace, Cohere, Replicate), payments (Stripe, PayPal Braintree, Square), comms (Slack, Discord, Telegram, Twilio, SendGrid, Mailgun, Mailchimp, Postmark), cloud (Cloudflare, DigitalOcean, Heroku, Netlify, Vercel, Fly.io, Render, Pulumi), CI/CD (CircleCI, Travis, Codecov), observability (Sentry DSN, Datadog, New Relic, Rollbar, Honeycomb, Mapbox, Okta, Auth0), package registries (npm, PyPI, Docker Hub), secrets vaults (HashiCorp Vault, Doppler, 1Password Connect), database connection strings (Postgres/MySQL/MongoDB/Redis), HTTP basic-auth URLs, JWTs, PEM/GPG private key blocks, and the .env-style catch-all. Non-AI terminals are not scanned (zero overhead). A manual paste-and-scan box is also available in the Settings panel.
  • Gemini account-mode auto-detection. Reads GEMINI_API_KEY, GOOGLE_API_KEY, GOOGLE_GENAI_USE_GCA, and GOOGLE_APPLICATION_CREDENTIALS+GOOGLE_CLOUD_PROJECT to identify which tier the Gemini CLI will hit (Vertex / Code Assist / Paid API key / Free OAuth).
  • Strict Mode — block free-tier Gemini. When ON, Termpolis intercepts shell-level gemini invocations and refuses to forward them unless paid-tier credentials are detected. Blocked launches are recorded in the audit log as BLOCKED: strict-mode + free-tier.
  • Local JSONL audit log. Every AI-agent terminal launch can be appended to ai-security-audit.jsonl in userData. Append-only, 10 MB rotated. Wipeable from Settings.
  • Legal disclaimer. Apache 2.0 "AS IS". Full disclaimer in TERMS.md §5a and inline in Settings → Security.

Copy for Slack / Teams / PRs

The terminal right-click menu has a Copy → submenu with four share-ready actions, plus the Ctrl+Shift+M keybinding (rebindable).

  • Copy as Code Block — wraps the selection (or the visible buffer) in triple-backtick fences. Drop into Slack, Teams, GitHub, GitLab, Notion — any markdown surface.
  • Copy as Plain Text — strips ANSI color escapes and copies clean text. Email-, Jira-, doc-ready.
  • Copy with Command — prepends the last shell command before fencing. Reproducer-ready snippets for bug reports.
  • Copy as Image (PNG) — renders the xterm.js canvas to a PNG with canvas.toBlob, writes via ClipboardItem. Pastes into Slack/Teams/Loom with colors, glyphs, and layout intact.

2. Installation

Download

Grab the latest build from the Termpolis website or directly from GitHub Releases.

Platform File Signed
Windows termpolis-setup-<ver>.exe ✅ Code-signed
macOS (Apple Si) termpolis-<ver>-arm64.dmg ✅ Notarized
macOS (Intel) termpolis-<ver>.dmg ✅ Notarized
Linux termpolis-<ver>.AppImage

Requirements

  • Windows: 10 or 11 (x64)
  • macOS: 11 (Big Sur) or later — Apple Silicon and Intel builds both ship
  • Linux: AppImage runs on any modern glibc distro
  • Disk: ~200 MB
  • RAM: 512 MB minimum; 2 GB recommended when running multiple agents

First run

On first launch, Termpolis creates its data directory:

Platform Path
Windows %APPDATA%\termpolis\
macOS ~/Library/Application Support/termpolis/
Linux ~/.config/termpolis/

Inside you'll find session.json (your workspaces, tabs, and open terminals) and later swarm-memory.jsonl (shared agent memory). Delete either file to reset that layer without losing the app.


3. First Launch & Welcome Screen

Welcome screen — full

The welcome screen is where you start from when no terminals are open. It shows:

  • Quick launch buttons for PowerShell, Bash, Zsh, WSL, plus any AI agent profiles you have.
  • Recent workspaces on the left sidebar.
  • Tips and shortcuts — an at-a-glance primer on the command palette, splits, and the swarm.

Press Ctrl+T (⌘T on macOS) to open the new-terminal modal, or click any launch button to spawn one immediately.


4. The Sidebar

Sidebar — default state

The sidebar is the navigation spine of the app. From top to bottom:

  1. Termpolis logo / brand — click to return to the welcome view.
  2. Workspaces — one row per open workspace. Each workspace is a named container of terminals, preserved across restarts.
  3. Tool buttons — Settings, Git Panel, Workflows, Activity, Swarm — each toggleable.
  4. Collapse / expand — click the chevron at the bottom to hide labels and save space.

Workspaces

Workspaces are the project-level container in Termpolis — think of them as the tabs in a browser, except each one holds a full set of terminals, a split/grid layout, an active agent, a scrollback history, per-workspace settings, and any panels you've left pinned (activity, context, git, swarm). You can run many workspaces side-by-side and switch between them without losing state.

What a workspace owns:

  • Terminals — every open pty in that workspace, with its shell, working directory, label, color, and scrollback buffer.
  • Layout — tab view, split view (the full pane tree), or grid view. Restored exactly on relaunch.
  • Focus — which terminal was active, cursor position, selection.
  • Agent sessions — any Claude Code, Codex, or Gemini runs tied to terminals in the workspace.
  • Panel state — which side panels are open and their size.
  • Per-workspace overrides — if you've changed a setting scoped to this workspace (shell default, font size, etc.).

How workspaces persist. Everything above is written to session.json in the Termpolis data directory (see §2 for the per-platform path) as soon as it changes — so an unclean shutdown still leaves you with last-known-good state. Re-opening the app restores the workspaces in the same order with the same terminals, split layouts, and focus.

Creating a workspace. Use the + Workspace button at the top of the sidebar or the Ctrl+Shift+N shortcut. Each new workspace starts empty; pick a shell to open the first terminal.

Managing workspaces. Right-click any workspace row in the sidebar for:

  • Rename — changes the label in the sidebar and the window title when the workspace is active.
  • Duplicate — creates a new workspace with the same terminal configuration (shell, cwd, label) but fresh, empty pty sessions. Handy when you want to mirror a setup for a second feature branch.
  • Close — removes the workspace. If any terminals in it have live child processes, you'll get a confirmation dialog listing what's still running.
  • Show in file explorer — opens the workspace's working directory in Finder / Explorer / your Linux file manager.

Switching between workspaces. Click a workspace row to activate it. Keyboard users can cycle with Ctrl+Alt+[ / Ctrl+Alt+]. Unsaved terminal output in background workspaces keeps streaming — nothing is paused just because it's not visible.

Workspace root directory. Each workspace has a default working directory that new terminals start in. Set it when you create the workspace, or change it later from Settings → Workspace. Terminals started with the agent launcher or by a workflow step inherit this unless they override it per-terminal.

How workspaces differ from workflows. Workspaces are long-lived containers that own state across restarts; workflows are pipelines of steps the app executes for you. A workspace is the room you're working in; a workflow is a job that runs inside it. A workflow never rearranges your terminals — it runs its steps, streams their output, and records the result. See §13.


5. Terminals

New terminal modal

Every pane in Termpolis is a full pty-backed terminal powered by node-pty. That means xterm-compatible escapes, real TTY semantics, signal forwarding — not a shim.

Creating a terminal

Ctrl+T opens the new-terminal modal (shown above). Pick:

  • Shell: PowerShell 7, Windows PowerShell, CMD, Bash, Zsh, Fish, WSL — whatever your system has.
  • Working directory: defaults to the workspace root; override per-terminal.
  • Agent profile (optional): launches with an AI CLI already running. See AI Agent Profiles.
  • Label + color: helps you tell terminals apart in split view.

Running terminal

Terminal running

Once running, the terminal supports:

  • Copy on selection (configurable), paste via Ctrl+Shift+V / ⌘V.
  • Mouse scroll, link clicks (Ctrl+Click to open), image rendering via Sixel when the shell emits it.
  • Full 256-color + truecolor palettes.
  • Right-click for a context menu: copy, paste, clear, split, close.

Close confirmation

Closing a terminal that has an active process prompts for confirmation. This protects against accidental loss of long-running tasks like model downloads, build jobs, or agent sessions.


6. Tab, Split & Grid Views

Tab view with multiple terminals

Terminals are arranged inside a workspace in one of three view modes:

Tab view (default)

Split view

Each terminal gets a tab. Click a tab to focus, drag to reorder, middle-click to close. Ctrl+1Ctrl+9 jumps to the Nth tab.

Split view

Splits are horizontal or vertical — recursive, so you can split a split. Drag the divider to resize.

Keyboard shortcuts:

  • Ctrl+\ — split horizontally
  • Ctrl+Shift+\ — split vertically
  • Alt+Arrow — focus adjacent pane
  • Ctrl+Shift+W — close focused pane

Grid view

Turns open terminals into a grid — great for watching 4 or 6 agents at once. Sizes auto-fit the window.

View mode toggle

The top-right toolbar has three buttons: Tab View, Split View, Grid View. Your choice is remembered per workspace.


7. Settings

Settings panel

Open with the gear icon in the sidebar, or press Ctrl+,. The settings panel slides in from the right. Tabs across the top group the settings:

  • Themes — color palette, syntax, and terminal colors.
  • Keybindings — every shortcut is rebindable.
  • Agent Capability — score each AI model across 10 capability categories, influencing swarm routing.
  • Shells — default shell per OS, custom shell commands, startup arguments.
  • Behavior — confirm on close, copy on select, scrollback size, cursor style, font.
  • Advanced — experimental flags, telemetry (off by default), log levels.

Changes save immediately. There is no "apply" button — edits are persisted to settings.json in your data directory.


Voice Dictation

Talk instead of type. Transcription uses Groq's cloud Whisper API — your recorded audio is sent to Groq for transcription. It is off by default and opt-in; turn it on in Settings → Voice and connect a Groq API key.

Engine. Transcription runs on Groq's hosted Whisper API (whisper-large-v3-turbo by default; whisper-large-v3 is selectable for maximum accuracy). The call happens in Termpolis's main process, so your API key never enters the renderer — it is validated when you connect and stored encrypted in your OS keychain (Windows DPAPI / macOS Keychain / Linux libsecret), never in settings or logs. Groq is fast (~200–300 ms for a short clip) and cheap: the free tier covers everyday dictation, and paid is about $0.04 per hour of audio.

How to use it.

  • Hold Ctrl+Shift+L and speak; release to send (true push-to-talk). Prefer hands-free? Switch to tap-to-start / tap-to-stop under Activation. The hotkey is rebindable.
  • Wait for the "Listening…" badge, then speak normally. Level doesn't matter much — the model handles quiet and loud speech — but it does need to actually hear words.
  • In an AI-agent terminal (Claude · Codex · Gemini) your words are sent straight to the agent as a prompt — the agent absorbs minor mis-hearings, so just talk naturally. (Optionally auto-submit so the prompt sends the moment you finish.)
  • In a plain shell the transcript is inserted but never run automatically — you review it and press Enter yourself, so a mis-heard command is never executed for you.
  • When dictation ends the caret returns to the terminal so you can keep typing or dictate again without clicking back in.

"No speech detected." If the microphone captured silence or no clear speech, Termpolis shows a brief "No speech detected" notice and does nothing — it will never inject a guessed phrase when it didn't actually hear you. (This is what eliminates the old "I'm sorry, what is that?" phantom transcripts: on no-speech audio a speech model invents filler, so Termpolis gates that out at the source — and silence is never sent to Groq, since the speech/noise gate runs locally first.) Just hold the key, speak, and release again. To improve capture, speak after the badge appears and reduce background noise; the model itself is robust to volume.

Privacy & reliability. Only the few seconds you actually dictate are sent, and only to Groq — never your files, terminal output, or other context. By default Groq does not train on or retain API audio; for the hardened setup, enable Zero Data Retention in your Groq console (the Connect dialog links you straight there). The transcript Groq returns is re-scanned by the secret scanner before it's injected, the same as anything else you send to an agent. If transcription fails, the red error bar tells you what went wrong — usually a missing/invalid key (Settings → Voice) or no internet connection.


8. Themes

Themes picker

Termpolis ships with a curated set of dark themes tuned for long coding sessions: Termpolis Dark (default), Dracula, Solarized Dark, Nord, Gruvbox Dark, Tokyo Night, Monokai. Each applies to:

  • The terminal background, foreground, and ANSI palette.
  • The app chrome (sidebar, status bar, title bar).
  • Syntax highlighting inside AI conversation panels.

You can import any VS Code theme JSON via the Import theme button. The parser maps VS Code tokenColors to xterm colors automatically.


9. Keybindings

Keybindings settings

Every user-facing action has a keybinding. The Keybindings tab lists them grouped by category (Navigation, Terminals, View, Agents, Swarm, Git). To rebind:

  1. Click the current binding.
  2. Press the new combo. The modal shows conflicts inline.
  3. Press Save or Reset to restore default.

Bindings are platform-aware — Ctrl becomes on macOS automatically. Conflicts across OS are flagged.

See §30 for the complete default list.


10. Agent Capability Ratings

Agent capability ratings

The heart of smart swarm routing. This tab lets you score each agent (Claude Code, Codex, Gemini CLI) across 10 categories:

  1. Refactoring
  2. Testing
  3. Documentation
  4. Code review
  5. DevOps / Infra
  6. Debugging
  7. Frontend
  8. Backend / API
  9. Data / SQL
  10. Bulk / long-running

Scores are 0–100. Defaults reflect model-family strengths as of release. You can tune them to match your own experience — the conductor uses these weights when it decides who gets what subtask.

The Token Cost column is a relative indicator ($, $$, $$$) used for cost-aware routing.


11. Command Palette

Command palette

Ctrl+K (or ⌘K) opens the command palette. Everything you can do from a menu is here, plus a lot that isn't:

Filtered command palette

Type to filter:

  • Actions — "launch claude", "split horizontal", "clear terminal".
  • Workspaces — "switch to ~/work/frontend".
  • Recent commands — from your terminal history.
  • Files — with results ranked by edit recency in the current workspace.

Fuzzy matching is weighted, and exact matches always float to the top. Press Enter to execute, Esc to close, / to navigate.


12. Prompt Templates

Prompt templates

A library of reusable prompts you send to agents. Open with Ctrl+Shift+P.

Built-in templates include:

  • Explain this code
  • Write tests for this
  • Refactor for readability
  • Find security issues
  • Document this API
  • Code review — strict

Each template supports {{variables}} that are filled from the current selection, the focused terminal's working directory, or free-form input. Add your own with the + New template button; they're saved to prompt-templates.json in your data directory.


13. Workflow Orchestrator

Workflow designer

A workflow is an ordered pipeline of steps that Termpolis runs for you. Open the Workflows section in the sidebar and press the inline + (Start Workflow) to author one on a blank canvas. Every saved workflow appears as a row in that section — press it to open the run view.

Steps

Four kinds, in any order:

  • Command — a shell line (inline or a script file) on a real terminal, with its own shell and timeout.
  • Agent — launches Claude Code, OpenAI Codex, or Gemini CLI on a prompt and waits for it to finish.
  • Skill — calls one of Termpolis's own tools: code search, memory, git.
  • Controlwait, branch, loop, or notify.

Each step takes an optional when gate and an optional continue even if this step fails. Later steps read earlier results (${steps.build.exitCode}, a step's captured output) inside gates, branch conditions, loop guards, and notify messages. Expressions run through a small, pure, sandboxed evaluator — never eval.

Availability, categories, and inputs

Workflow designer — availability, category, and inputs

  • AvailabilityProject stores the workflow in <repo>/.termpolis/workflows/<id>.yml and shows it only in that repo. Global stores it in your Termpolis data directory and offers it in every project. Switching availability moves the file between the two stores; scope is derived from where the file lives and is never written into the YAML, so moving a .yml by hand re-scopes it.
  • Category — a free-text label (Build, Release/Nightly, …). The sidebar files every workflow with that label into a collapsible folder; uncategorized workflows stay at the top level.
  • Inputs — named values the workflow asks for before it runs. Each has a name, an optional label and description, an optional default, and a required flag. Termpolis collects them in the run view and keeps Run locked until every required input is filled. Reference them as ${inputs.NAME} in any step field, gate, branch, or loop condition.

A global workflow always runs against the directory you're standing in, so ${project.cwd}, ${project.name}, and ${project.branch} resolve to the repo you're actually in — one workflow, reused everywhere, parameterized by inputs.

Triggers

Give a workflow a trigger and it stops needing you:

  • Manual — only when you press Run.
  • Schedule — a real cron expression (0 2 * * *, or @daily) in your local time, with an optional catch-up for a run missed while the app was closed.
  • Git commit — fires when a new commit lands on the checked-out branch, optionally narrowed to one branch. This is the post-commit hook: lint, test, or hand the diff to an agent.
  • Git push — watches the remote-tracking ref for a chosen remote and branch.
  • File change — a debounced recursive watch you can narrow to specific paths.

Triggers survive restarts, and a triggered run takes the exact same path as pressing Run — including the workspace-trust gate, so an untrusted folder never fires. A global workflow arms in every project the app has open, and each project keeps its own trigger state, so a commit in one repo only fires that repo's run.

Watching a run

The run view streams each step's output live, marks it succeeded, failed, or skipped, and shows how long it took. Cancel mid-run and every in-flight step is torn down cleanly. Run history is appended to .termpolis/workflows/runs/<workflowId>.jsonl next to the store the workflow came from.


14. Context Panel

Context panel

Ctrl+Shift+E toggles the context panel. It shows what's "in scope" right now:

  • Current git branch, ahead/behind counts, dirty state.
  • Focused terminal, working directory, running command.
  • Active agent session (if any) with a live token count.
  • Recent files edited in the workspace.
  • Pins — anything you've pinned from the activity feed or the memory store.

The context panel is also the pane agents read from when you ask "what am I looking at?" — it's explicit context sharing, not implicit slurp.


15. History Search

History search

Ctrl+Shift+H opens terminal history search. It spans every terminal you've ever opened in Termpolis, not just the current shell's history file. Search by:

  • Command
  • Working directory
  • Exit code (e.g. find all failures)
  • Time range
  • Shell type

Click a result to copy, re-run in the focused terminal, or pin to context.


16. Conversation Search

Conversation search

Ctrl+Shift+I opens conversation search — the AI-session equivalent of history search. Search across every agent session Termpolis has recorded:

  • Filter by agent (Claude / Codex / Gemini).
  • Filter by kind (prompt, tool call, tool result, error).
  • Full-text search with highlighting.
  • Time range.

Each hit deep-links into the original session so you can reopen it, re-prompt, or copy a successful flow.


17. Git Panel

Git panel

Sidebar button or Ctrl+Shift+G. The Git panel is a lightweight GUI for what you usually do at the CLI:

  • Current branch, ahead / behind counts.
  • Staged and unstaged sections with file-by-file diff inline.
  • Commits — graph view of the last 50 commits on the current branch.
  • Actions — stage/unstage, commit (with message input), push, pull, fetch, stash, create branch, switch branch.
  • AI-assisted commit message — click the ✨ next to the message input, and an agent drafts a message from the staged diff.

Every action runs as a real git command in a spawned process — no reimplementation — so you can always drop to the CLI and see the same state.


18. AI Agent Profiles

Launch any AI CLI as a profiled terminal: Claude Code, Codex, Gemini CLI. Profiles come pre-configured with:

  • The correct shell + startup command.
  • A color + label for visual distinction.
  • An MCP bootstrap so the agent can control Termpolis.
  • A distinct working directory if you want one.

Custom profiles take any command — if it's in your PATH, you can profile it. Add them in Settings → Agents.


19. MCP Server

Termpolis ships an MCP (Model Context Protocol) server so AI agents can control the app from inside a conversation. It listens on http://localhost:48211 by default (port configurable).

Available tools (17 total)

Tool Description
list_terminals Enumerate open terminals with IDs, labels, cwd
open_terminal Spawn a new terminal with a given shell + cwd
close_terminal Close a terminal by ID
focus_terminal Bring a terminal to the foreground
send_input Send raw text + control chars to a terminal
read_buffer Read the last N lines of a terminal's output
wait_for_prompt Wait until a terminal emits a regex match
list_workspaces Enumerate workspaces
switch_workspace Change active workspace
git_status JSON summary of the current repo
broadcast_message Send a swarm-wide notification
get_session_id Returns the calling session's opaque ID
post_activity Push an AgentActivity event into the feed
memory_write Persist a labeled memory entry into the shared store
memory_search RAG search across shared memory (semantic + keyword)
memory_list List recent memory entries

The server is authenticated via a per-launch token that lives in ~/.termpolis/mcp-token — agents read it at startup. Misuse resistance includes tight origin checks, rate limits, and an audit log.


20. Swarm Dashboard

Swarm dashboard

Ctrl+Shift+S opens the swarm dashboard — the nerve center for multi-agent work.

Agents tab

Swarm agents tab

Shows every agent currently registered with the swarm:

  • Status — idle, working, blocked, error.
  • Active task — what it's doing right now.
  • Token usage — running total per agent.
  • Capability chips — the categories this agent was chosen for.

Click an agent row to jump to its terminal.

Tasks tab

Swarm tasks tab

The complete task DAG for the current swarm run. Each task shows:

  • Title, assignee, depends-on, blocks.
  • Status (queued, running, waiting for review, done, failed).
  • Duration + estimated token cost.
  • A one-line summary of what was produced when complete.

Dependency arrows let you see at a glance which tasks are parallelizable and which are on the critical path.

Messages tab

Swarm messages tab

A live stream of every message the conductor sends, every broadcast, every handoff. Think of it as the "Slack channel" for your agent team — useful for debugging, reviewing, or understanding exactly how a decision was made.


21. AI Conductor

The conductor is a dedicated Claude Code instance that runs as a separate agent with a system prompt purpose-built for orchestration. It:

  1. Reads your initial task description.
  2. Calls memory_search on shared memory to find relevant prior work.
  3. Decomposes the task into subtasks.
  4. For each subtask, picks the best-fit agent using capability scores, current load, and cost.
  5. Delegates via MCP post_activity + send_input.
  6. Watches the activity feed for progress, errors, and completion signals.
  7. Decides when to merge partial results, when to re-plan, and when to declare done.

The conductor is not keyword matching — it reasons with the same capability as any frontier model, because it is one. You can open its terminal and see its thinking live.

Starting a swarm

Start swarm wizard

Click Start Swarm in the dashboard. The wizard asks for:

  • Task description — natural language, as detailed as you want.
  • Agents to include — defaults to all three.
  • Budget — optional soft cap on token spend.
  • Working directory — defaults to current workspace.

Click Start. The conductor spins up, reads the task, and the dashboard populates with subtasks within seconds.


22. Activity Feed

Activity feed

The activity feed is the observability layer for every agent, every session. Open it from the sidebar (Ctrl+Shift+A) or from any terminal's context menu.

Event types

  • message — text output from the agent.
  • tool_call — when an agent invokes a tool (with args).
  • tool_result — the result of a tool call.
  • token_update — token usage deltas.
  • compaction — when an agent compacts context.
  • error — agent or tool error.
  • status_change — idle → working, etc.
  • mcp_audit — every MCP request + response.

Filters

Three filter rows: search (full-text), kind (dropdown), agent type (dropdown). All combine.

Scoped vs global

Open the feed from a terminal and it's scoped to that terminal's session. Open it from the sidebar and it shows every agent across every session. Scope is visible in the header: "Agent Activity (terminal)" or "Agent Activity".

Pinning

Right-click any event → Pin. Pinned events appear at the top of the Context Panel until you unpin them. Great for "this tool call is the thing I'm tracking".


23. Intervention Controls

Every scoped Activity Feed includes a row of intervention controls above the event list:

  • Pause — sends ESC (0x1B) to the agent's pty, which most CLIs interpret as "cancel current input".
  • Cancel — sends a single Ctrl+C (0x03).
  • Interrupt — sends a double Ctrl+C (0x03 0x03), which Claude Code and Codex treat as a hard stop.
  • Steer — a text input with a send button. Type a new instruction and the agent receives it directly at the prompt.

The rationale: every agent is a pty, so writing control characters or text to its stdin is the fastest, most reliable way to take over. No new IPC surface — just the pty API we already have.

Each intervention is also logged as an event in the feed (status_change), so you have an audit trail of every mid-flight correction you made.


24. Swarm Review Panel

When a task is configured to require review before handing off (default for code-review tasks, optionally enabled for others), the conductor pauses and opens the Swarm Review Panel.

The panel shows:

  • The task title and assignee's output.
  • A diff (if the task produced file changes).
  • Three buttons: Approve, Request Changes, Reject.
  • An optional comment field.

Approve hands off to the downstream task. Request Changes reassigns to the same agent with your comment appended. Reject drops the output and re-plans.


25. Persistent Memory — the growing brain

A local, cross-agent memory store that never forgets and feeds itself, so every agent can semantically recall past work instead of you re-explaining context each session.

What's in it

  • Past AI conversations — Claude Code (~/.claude/projects/**), Codex (~/.codex/sessions/**), and Gemini (~/.gemini/tmp/**) transcripts are parsed, noise-stripped (tool calls / reasoning / system prompts removed), chunked, and embedded.
  • Your repo's code — git-tracked files (so node_modules/dist are excluded), chunked by line-window. The indexer reuses the same sensitive-file denylist as the read watcher, so .env, keys, and cloud credentials are never embedded.

How it works

  • Embeddings are local & offline. A bundled bge-small-en-v1.5 model (q8, 384-dim, MIT) runs in-process via onnxruntime-web (WASM) — no Ollama, no server, and zero native binaries in the installer. If the model is absent, search degrades gracefully to keyword matching.
  • Shared across all three agents over the MCP server (memory_search / memory_write / memory_list). One store backs Claude/Codex/Gemini, so a fact one learns is instantly available to the others.
  • Durable across restarts, updates, and reinstalls. Stored as JSONL in Termpolis's app-data folder — %APPDATA%\Termpolis\swarm-memory.jsonl on Windows, ~/Library/Application Support/Termpolis/ on macOS, ~/.config/Termpolis/ on Linux (plain text, hand-editable) — and reloaded with embeddings at startup. Because it lives in your user profile, not the install folder, it survives app updates and even an uninstall/reinstall (the uninstaller leaves app data in place). A ~100k-chunk hot window is kept in RAM for vector search; the on-disk log retains everything written.
  • Feeds itself. A background indexer runs ~10 s after launch and every 30 min, ingesting new sessions. Ingestion is idempotent (content-hash dedup), so steady-state runs only embed genuinely new chunks.
  • Pre-context primer. memory:build-primer pulls the most relevant memories for a query and formats a shell-paste-safe block that can be injected as an agent's first input — so it starts already knowing the context (the token-saver).
  • Current-directory precedence. The primer leads with context for the project you're standing in — past conversations from this repo first, then its code/notes — and anything from other projects is appended under a "may NOT apply" label. Ingested chunks are tagged with their project (derived from the transcript cwd / repo root), legacy chunks get back-tagged on the next indexer pass, and memory_search accepts a project filter so agents can scope recall themselves.

Using the Memory panel

Open the panel with Ctrl+Shift+M, or from Settings → AI Memory → Open the Memory panel. From there you can:

  • See what's stored — the number of remembered chunks (and how many sit in the in-RAM hot window for fast search).
  • Search — type what you're working on and hit Search for a semantic lookup across your past conversations and indexed code.
  • Inject primer — type a topic and click Inject primer to paste the most relevant memories straight into the active agent's terminal, so it starts already knowing the context. This is the token-saver: you stop re-explaining background every session.
  • Index this repo's code — pull the current project's git-tracked files into memory on demand (.env/keys are always skipped). Conversations index themselves automatically; code indexing is opt-in per repo so you decide what's searchable.
  • Cross-machine sync — click Choose a synced folder… and point it at a folder you already sync (OneDrive, Google Drive, Dropbox, iCloud, Syncthing…). Each device writes its own shard and the union becomes one shared brain — no Termpolis server involved. Optionally set a passphrase to encrypt the synced data at rest (AES-256-GCM) so the cloud provider only ever sees ciphertext; use the same passphrase on every device. (For Google Drive, use "mirror" mode so the files stay on local disk.)

Why it matters: when Claude figures out how your auth module works, Codex doesn't need to re-discover it, and you stop burning 20–50k tokens re-pasting context every session. The store is plain-text JSONL in your app-data folder (see above), readable and hand-editable.


26. Observability

Termpolis ships with a full observability stack for AI work — the "watchers" system. It's a lightweight in-process event bus that watches for:

  • Token pressure — when an agent is approaching compaction.
  • Stuck sessions — when an agent has been silent for > N seconds.
  • Error cascades — repeated errors in a short window.
  • Redundancy — two agents doing overlapping work.
  • Efficiency — the token-cost-per-task rolling average.

Watchers can surface alerts in the status bar, in the activity feed, or fire a system notification. Thresholds are tunable in settings.


27. Status Bar

Status bar

The bottom strip shows, left to right:

  • Active workspace + git branch (click to switch).
  • Focused terminal's shell type + cwd.
  • Active agent summary — how many are working, how many idle.
  • Swarm status — if a run is active, shows progress %.
  • Token counter — session total across all agents.
  • Notifications — watcher alerts live here.
  • MCP server indicator — green when healthy.

28. Troubleshooting

Found a bug that isn't here? Open an issue on GitHub → Include your OS + version, Termpolis version (Settings → About), and the most recent entries from ~/.termpolis/logs/ — that's usually enough to reproduce the problem.

Installation & first-run

Windows: "Windows protected your PC" SmartScreen warning. Click More infoRun anyway. Termpolis is code-signed (SSL.com), but newly signed builds need reputation time before SmartScreen stops flagging them. The warning disappears once enough people download the release.

macOS: "Termpolis is damaged and can't be opened." This means Gatekeeper couldn't verify the signature — usually a partial download. Re-download the DMG from GitHub Releases, verify the file size matches, and mount again. If it still fails, open System Settings → Privacy & Security, scroll to the bottom, and click Open Anyway next to the Termpolis entry.

macOS: "Permission denied" when launching a terminal. Grant Termpolis Full Disk Access in System Settings → Privacy & Security → Full Disk Access. Re-launch after granting.

Linux: AppImage won't run. Mark it executable: chmod +x Termpolis-*.AppImage. On systems with hardened FUSE, extract and run the inner binary: ./Termpolis-*.AppImage --appimage-extract && ./squashfs-root/termpolis.

Data directory didn't appear. Termpolis creates the data directory on first run — make sure you actually clicked "Open" rather than dismissing the first-launch dialog. Paths by platform: %APPDATA%\termpolis\ (Windows), ~/Library/Application Support/termpolis/ (macOS), ~/.config/termpolis/ (Linux).

Terminals

Terminal won't start. Check the shell path in Settings → Shells. On Windows, PowerShell 7 lives at C:\Program Files\PowerShell\7\pwsh.exe; WSL needs wsl.exe on PATH. On macOS, if /bin/zsh gives "permission denied", re-grant Termpolis Full Disk Access (above) — launchd blocks unsigned/unapproved apps from spawning shells by default.

Terminal hangs on first prompt. Your shell's startup files (.bashrc, .zshrc, powershell $PROFILE) may be waiting on input or hitting a slow network check. Open the shell outside Termpolis to confirm; the fix is in your dotfiles, not the app.

Output looks garbled / escape codes show as text. The shell detected a non-TTY environment. Make sure the Agent profile field is empty if you're launching a plain shell (some agent launchers set TERM=dumb). Resetting via Settings → Shells → Reset defaults fixes most cases.

Copy/paste shortcuts don't work. On Windows/Linux, use Ctrl+Shift+C / Ctrl+Shift+V inside terminals (bare Ctrl+C sends SIGINT). On macOS, ⌘C/⌘V work as expected everywhere.

Font looks wrong / icons are boxes. The app ships with its own icon font, but if it failed to load (usually due to an override in Settings → Themes), re-select a built-in theme or run Reset theme from Settings → Themes.

Agents & CLI tools

Agent launch button fails silently. The CLI isn't on your PATH. Open any shell in Termpolis and run claude --version (or codex, gemini) to confirm. On macOS, GUI-launched apps don't always inherit $PATH from your shell — restart Termpolis after updating ~/.zprofile (not just ~/.zshrc), or relaunch from Terminal with open -a Termpolis so the shell PATH is inherited.

Wrong claude / codex binary runs. If you've installed the CLI via multiple package managers (Homebrew, npm, cargo), PATH order decides the winner. Use which claude to see which one Termpolis will launch. Override per-agent in Settings → Agents.

Agent exits with "API key not set". Each agent's env vars come from the login shell, not from a .env file in your workspace. export ANTHROPIC_API_KEY=... in ~/.zprofile / ~/.bash_profile / PowerShell $PROFILE, then relaunch Termpolis.

Swarm, MCP, and memory

MCP indicator in status bar is red. The MCP server failed to start. Look at ~/.termpolis/logs/mcp.log. Common causes:

  • Port 48211 already in use. Another instance of Termpolis (or an old crashed one) still owns the port. Kill any stray termpolis processes, or change the port in Settings → Advanced.
  • Firewall blocking localhost. Rare but possible. Add an exception for termpolis.exe / the Termpolis binary.
  • Token file write failed. ~/.termpolis/mcp-token couldn't be written due to permissions. Fix the directory permissions (chmod 700 ~/.termpolis).

Swarm conductor doesn't launch. The conductor spawns a Claude Code child process that needs claude on PATH (see agent troubleshooting above). Watch ~/.termpolis/logs/conductor.log for its startup output.

Swarm hangs mid-task / agents stop posting activity. Open Activity Feed — if the agent is still running but not emitting events, its MCP connection may have dropped. Use Pause → Reset session in the Swarm Dashboard to recover. If a specific agent repeatedly drops, its MCP token probably expired — restart Termpolis to issue fresh tokens.

Memory search returns nothing. Embeddings now run in-process via a bundled offline model (bge-small-en-v1.5) — no Ollama or any server required. If semantic results are missing, the embedding model failed to load on this machine; keyword-only matching still works as a fallback, and writes always succeed.

Updates & performance

Update notification appears but the update doesn't install. The auto-updater needs write access to the app bundle. On Windows, run the installer manually from GitHub Releases if the in-app updater fails. On macOS, drag the new DMG contents over the existing app (it'll prompt for admin). On Linux, download and replace the AppImage.

App is slow to start / very high memory. A corrupted session file occasionally causes runaway restoration. Back up session.json in your data directory, then delete it and relaunch — you lose restored workspace state but the app is back to a clean baseline.

Terminal scrollback is sluggish. The default xterm scrollback is 10,000 lines. If you've pasted very large logs, scrolling slows down. Settings → Terminals → Clear scrollback resets without restarting.

Session corruption & reset

App opens to a blank screen. Sign of a broken session.json. Close Termpolis, rename session.json in the data directory, relaunch — the app creates a fresh session. Your workspaces will be empty but the app is usable again; the old file is preserved if you want to diff it later.

Reset everything. Close Termpolis, delete the entire data directory (see §2), relaunch. This wipes workspaces, settings, themes, prompt templates, custom workflows, swarm history, and memory — start from a clean slate.

Reporting a bug

If none of the above fixes your problem, open an issue. Please include:

  1. OS + version (e.g., Windows 11 23H2, macOS 14.3, Ubuntu 22.04).
  2. Termpolis version (Settings → About).
  3. Steps to reproduce — as minimal as you can make them.
  4. Relevant log tail from ~/.termpolis/logs/ (the main log, plus mcp.log or conductor.log if the issue involves swarm/MCP).
  5. A screenshot or short screen recording if it's a UI bug.

29. Architecture

┌─────────────────────────────────────────────────────┐
│  Renderer (React)                                   │
│  ├── Sidebar, Terminals, Panels                     │
│  ├── Activity Feed (observability UI)               │
│  ├── Swarm Dashboard + Conductor view               │
│  └── IPC client → window.termpolis bridge           │
└──────────────────┬──────────────────────────────────┘
                   │  Electron IPC
┌──────────────────▼──────────────────────────────────┐
│  Main process (Node)                                │
│  ├── Terminal manager (node-pty)                    │
│  ├── Session persistence (session.json)             │
│  ├── Git adapter                                    │
│  ├── MCP server (HTTP, 18 tools)                    │
│  ├── Swarm memory (JSONL + embeddings)              │
│  ├── AI conductor (spawns Claude Code as a child)   │
│  └── Watchers (event bus + alerts)                  │
└──────────────────┬──────────────────────────────────┘
                   │  localhost:48211 (MCP)
┌──────────────────▼──────────────────────────────────┐
│  AI agents (Claude, Codex, Gemini)                  │
│  Each in its own pty-backed terminal                │
└─────────────────────────────────────────────────────┘

Tech stack:

  • Electron 29, React 18, TypeScript 5, Vite 5 (electron-vite)
  • node-pty for terminals, xterm.js for rendering
  • Vitest for unit tests (2100+ tests, >90% line coverage)
  • Playwright for E2E + screenshot captures
  • electron-builder for packaging, Azure Trusted Signing for Windows, notarytool for macOS

30. Keyboard Shortcut Reference

All shortcuts are rebindable in Settings → Keybindings. Defaults:

Action Windows / Linux macOS
New terminal Ctrl+T ⌘T
Close focused terminal Ctrl+W ⌘W
Next tab Ctrl+Tab ⌘]
Previous tab Ctrl+Shift+Tab ⌘[
Jump to tab N Ctrl+1…9 ⌘1…9
Split horizontal Ctrl+\ ⌘\
Split vertical Ctrl+Shift+\ ⌘⇧\
Focus adjacent pane Alt+Arrow ⌥Arrow
Command palette Ctrl+K ⌘K
Settings Ctrl+, ⌘,
Prompt templates Ctrl+Shift+P ⌘⇧P
Workflow templates Sidebar → Workflows Sidebar → Workflows
Context panel Ctrl+Shift+E ⌘⇧E
History search Ctrl+Shift+H ⌘⇧H
Conversation search Ctrl+Shift+I ⌘⇧I
Git panel Ctrl+Shift+G ⌘⇧G
Activity feed Ctrl+Shift+A ⌘⇧A
Swarm dashboard Ctrl+Shift+S ⌘⇧S
New workspace Ctrl+Shift+N ⌘⇧N
Copy Ctrl+C (selection) ⌘C
Paste Ctrl+Shift+V ⌘V
Clear terminal Ctrl+L ⌘K* in shell
Zoom in / out Ctrl+= / Ctrl+- ⌘= / ⌘-
Reset zoom Ctrl+0 ⌘0

Final note

Termpolis is under active development. If you hit a rough edge, open an issue at github.com/codedev-david/termpolis. If it's useful to you, consider sponsoring the project.

— David