wingthing

module
v0.144.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: MIT

README

wingthing

ci

Persistent, sandboxed agent terminals on machines you control. Use them locally, reattach from your terminal over SSH, or opt into encrypted browser access.

https://github.com/user-attachments/assets/f1f04caf-4b07-4298-ba76-db5b226c38f2

wt terminal --name work              # persistent sandboxed shell
wt terminal --name api -- npm run dev # persistent arbitrary command
wt egg claude --name research        # persistent sandboxed agent
# Ctrl+B Q detaches without stopping it
wt attach                             # list live local sessions
wt attach --select                    # choose interactively
wt attach research                    # names or immutable IDs both work
wt attach research --remote box       # reattach over ordinary SSH

No account or hosted service is required. If you want browser access from anywhere, wt start connects your machine outbound to the optional app.wingthing.ai relay.

Runtime and security domains

The egg is a sandboxed agent session on your machine. Each wt egg <agent> spawns a child process inside an OS-level sandbox (Seatbelt on macOS, user namespaces + seccomp on Linux). Same idea as containers but lighter weight. Filesystem access, network reach, system calls, and resource usage are all controlled.

The wing is the durable runtime on your machine. It owns eggs and their session state even when no client is attached. Local and SSH clients do not need a hosted service. When browser access is enabled, terminal and wing API payloads are application-encrypted (X25519 + AES-GCM) through the relay. The shipped relay forwards ciphertext during normal operation; routing metadata remains visible, and the hosted web client still trusts the service that delivers its JavaScript. See the precise security model.

A roost is a deployment bundle: a wing plus the gateway and web service in one process. Self-host one with wt roost start for a shared workstation, team appliance, or homelab. wingthing.ai offers the gateway/web side as an optional hosted service; it is not required for local or SSH use.

Sandbox

Out of the box, the sandbox is opinionated: CWD is writable, home is read-only, sensitive directories (~/.ssh, ~/.gnupg, ~/.aws, etc.) are denied, and only essential env vars are passed through. A local CONNECT proxy enforces domain-level filtering - agents can only reach their own API, not the entire internet. Claude gets api.anthropic.com, Ollama gets localhost, Gemini gets *.googleapis.com. Agent binaries, config directories, network rules, and env vars are all auto-detected.

Drop an egg.yaml in your project to customize. Configs are additive - you only declare what you're changing from the defaults. Put one at ~/.wingthing/egg.yaml to use it as the default across projects.

# egg.yaml
fs:
  - "ro:~/.ssh"       # overrides the default deny for ~/.ssh
network:
  - "github.com"      # add a domain on top of agent defaults
env:
  - SSH_AUTH_SOCK      # pass SSH agent socket

Use base: none for a blank slate. Use the sandbox builder on the homepage to generate configs visually.

If the machine is already a disposable or access-segregated VM, use --unsandboxed to make that outer VM the boundary. Wingthing still provides the durable PTY, attach, CLI, and MCP control plane, but it does not apply nested filesystem, network, syscall, or resource restrictions. See the sandboxed AI VM recipe.

Native reattach

wt terminal starts a shell or any command in the same durable PTY runtime used for agents. Detach from wt terminal or wt egg with Ctrl+B, then Q. The egg keeps running in its own process session.

wt terminal --name work
wt terminal --name dev-server -- npm run dev
wt egg claude --name research

wt attach                         # list local sessions
wt attach --select                # native interactive picker
wt attach work                    # attach by name or ID
wt attach work --remote box       # `box` comes from ~/.ssh/config

The remote host needs wt installed. SSH keeps ownership of authentication, host verification, bastions, ports, and VPN/tailnet routing. Use --remote-binary /path/to/wt if it is not on the remote PATH.

The local terminal API is also scriptable:

wt session ps --json
wt session read dev-server --json
wt session send dev-server r --enter --json
wt session wait dev-server --contains ready --json
wt session rename dev-server frontend --json
wt session kill frontend --json
wt terminal --name worker --json -- make worker

LLMs and editor clients can use the same local runtime through MCP:

wt mcp stdio --client claude-code

It exposes typed tools for terminal start/list/read/send/wait/rename/stop, persistent agent start, versioned prompt templates, one-shot runs, durable task inspection, bounded loops, and dependency-aware swarms. It is local-user access: no account, browser, or hosted router is involved. Named clients own the sessions they create, and calls are attributed in ~/.wingthing/mcp-audit.log. Optional grants and spawn bounds live in ~/.wingthing/clients.yaml; these guard against accidental same-user interference, not a hostile process that can invoke wt directly. See the agent meta-layer design and the supported-agent evidence matrix.

For an agent running inside an already-isolated VM, register the trusted-host mode explicitly:

claude mcp add wingthing -- wt mcp stdio --client claude-code --unsandboxed
wt egg claude --name claude --unsandboxed -- --permission-mode bypassPermissions

The MCP server reports this mode to the model and records "isolation":"outer-boundary" on every MCP audit entry. The model cannot toggle the mode per tool call.

The opt-in release smoke battery model-swaps Claude Code, Codex, Hermes, and OpenCode onto local Qwen models, runs each directly and through Wingthing, then exercises MCP prompt, saved-prompt, loop, and swarm paths. It asserts exact artifacts rather than trusting exit codes: see live release E2E.

Named prompts are ordinary local assets with immutable content revisions:

wt prompt save review --file review.prompt --variable target --agent codex --cwd "$PWD"
wt prompt list
wt prompt run review --var target=internal/parser

Optional browser access

wt login                   # authenticate with GitHub or Google
wt start                   # background daemon
wt status                  # check it
wt stop                    # stop it

Open app.wingthing.ai to browse your wings, start sessions, and view history. Lock your wing with wt wing lock to require passkey auth before sessions start.

The native CLI can use the same authenticated roster as a wing finder. It then probes each wing through the application-encrypted tunnel, so host and project details do not become relay metadata:

wt wings                    # alias: wt find
wt wings --json

# Keep a separate login/key profile for a private or team roost.
WINGTHING_DIR=~/.wingthing-slide wt login --roost https://roost.example.com
WINGTHING_DIR=~/.wingthing-slide wt wings --roost https://roost.example.com --json

Use --no-probe when only the relay's online wing IDs are needed. Native TOFU identity pins are stored in the selected profile's known_wings.json.

Agents

wt doctor shows what's installed. Swap agents per-session.

Agent CLI
Claude Code claude
Codex codex
Cursor Agent agent
Gemini gemini
Hermes Agent hermes
Ollama ollama (qwen3:4b default)
OpenCode opencode

Install

curl -fsSL https://wingthing.ai/install.sh | sh

Or build from source (Go 1.25+, Node.js):

git clone https://github.com/ehrlich-b/wingthing.git
cd wingthing && make check

Update with wt update.

Self-hosting

Single binary, SQLite, no external deps.

wt roost start             # server + wing, one command
open localhost:8080         # start sessions

For multi-user, add GitHub or Google OAuth env vars. See the docs.

Docs

wingthing.ai/docs

License

MIT

Directories

Path Synopsis
cmd
wt command
internal
egg
mcp
Package mcp exposes a roost's privileged tools as a role-scoped MCP server.
Package mcp exposes a roost's privileged tools as a role-scoped MCP server.
ws
test
mock-agent command
web/canary-agent command
canary-agent is the browser E2E suite's stand-in for an agent CLI.
canary-agent is the browser E2E suite's stand-in for an agent CLI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL