diff --git a/DEPLOY.md b/DEPLOY.md index 6917113..e1299c4 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -1,19 +1,54 @@ -# Deploy +# Deploy the hosted Wingthing coordinator -## Fly.io Setup (one-time) +Wingthing is a typed agent manager for durable agent runs and terminals. This Fly +deployment hosts `wingthing.ai`: identity, the authorized wing directory, key +exchange, connection coordination, the web portal, and the optional encrypted +relay. It does not run users' agents. + +## Deployment boundary + +| Decision | Hosted deployment | +| --- | --- | +| **Execution wing** | A user's laptop, VM, or self-hosted machine selected by `wing_id`; the Fly login and edge processes are coordinators, not execution wings. | +| **Workspace** | An existing path on that selected wing. The hosted service does not create, clone, upload, or synchronize workspaces. | +| **Display** | Direct MCP gives a parent agent semantic runs and persistent PTYs. The hosted browser terminal and control relay require relay entitlement; self-hosted and SSH displays remain separate compatible paths. | +| **Provider credentials** | The execution owner's provider-agent home on the selected wing. Provider tokens and SSH keys do not belong in Fly secrets, MCP arguments, or prompts. | +| **Durable memory** | Gateway account, organization, auth, entitlement, and routing records persist on the login volume. Run/task records, eggs, Wingthing prompt memory, provider history, and project files remain wing-local. Edge processes are stateless. | + +## One-time Fly setup + +From a checkout whose `fly.toml` still targets the intended app and region: ```bash -flyctl apps create wingthing -flyctl volumes create wt_data --region ewr --size 1 -flyctl secrets set WT_JWT_KEY=$(wt keygen) +fly apps create wingthing +fly volumes create wt_data --region ewr --size 1 +fly secrets set WT_JWT_KEY=$(wt keygen) ``` -## Deploy +Configure the OAuth, email, and optional billing secrets required by this hosted +installation. If the login, app, and WebSocket endpoints use separate hosts, set +`WT_APP_HOST` and `WT_WS_HOST` consistently and provision DNS/TLS for each one. +The checked-in production base URL is `https://wingthing.ai`; the application and +wing endpoints are `app.wingthing.ai` and `ws.wingthing.ai`. + +## Promote and deploy + +The public documentation and installer are a versioned contract. Publish and +verify the matching GitHub release before deploying its site: ```bash -flyctl deploy +git tag vX.Y.Z +git push origin vX.Y.Z +gh release view vX.Y.Z +curl -fsSL https://wingthing.ai/install.sh | sh +make deploy ``` -## DNS +`make deploy` runs the documentation/web build, Go tests, binary build, release +command-surface check, and N-1/current compatibility gate before `fly deploy`. It +does not create a GitHub release. Use a full clone with tags so the compatibility +gate can find its published baseline. -Point `wt.ai` to fly: `flyctl certs create wt.ai` +Do not replace this sequence with a bare `fly deploy`. For split login/edge +rollouts, relay policy, DNS, scaling, rollback constraints, and verification, use +the [Fly operations guide](docs/fly-ops.md). diff --git a/README.md b/README.md index eb9c428..56d60cb 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ [](https://github.com/ehrlich-b/wingthing/actions/workflows/ci.yml) -Wingthing is an agent manager for agents. Give Codex, Claude, or another parent -agent one typed control plane for starting and supervising durable agents across -all your machines. A person can inspect or take over the same sessions from a -terminal or browser. +Wingthing is a typed agent manager for durable agent runs and terminals. Give +Codex, Claude, or another parent agent one control plane for starting and +supervising work across all your machines. A person can inspect or take over the +same terminal sessions from a terminal or browser. The agents run where the code and hardware already live. Wingthing keeps their terminals alive, records semantic runs as durable tasks, applies sandbox policy, @@ -133,6 +133,20 @@ person: CLI or browser ----------------/ (inspect or take over) | **Egg** | The per-session execution boundary: process, PTY, sandbox policy, and local control socket. | | **Roost** | The self-hosted bundle started by `wt roost start`: a portal/gateway and an embedded wing in one process. Other wings may register with its gateway. | +### Place every run explicitly + +| Question | Wingthing's contract | +| --- | --- | +| **Execution** | Select the wing that will run the process. Direct remote calls require its `wing_id`; Wingthing never substitutes another wing. | +| **Workspace** | Pass a `cwd` that already exists on that wing. Wingthing does not clone, create, or synchronize repositories. | +| **Display** | Use `agent_run` for semantic status and a final result without a live browser view. Use `agent_start` when the task needs a PTY that a person can attach to from the CLI, SSH, or an entitled/self-hosted browser. | +| **Credentials** | The provider CLI reads credentials from the execution owner's agent home on that wing. Shared hosts separate those homes by owner. Do not put provider tokens or SSH keys in prompts or MCP arguments. | +| **Durable memory** | Wingthing stores task, result, message, and thread records in `~/.wingthing/wt.db`, session state under `~/.wingthing/eggs`, and optional prompt memory under `~/.wingthing/memory`. Provider-native history stays in the provider home. These are wing-local unless the operator arranges replication. | + +`WINGTHING_DIR` changes the `~/.wingthing` state root. A terminal survives client +detachment, but not an unplanned host restart. A run's record and result persist; +an active headless run still depends on the supervising Wingthing process. + `wingthing.ai` is the hosted identity, directory, key-exchange, and connection coordination service—roughly the control plane in a tailnet. It does not run the agents. New free accounts use direct remote MCP; Pro adds the encrypted hosted @@ -329,6 +343,7 @@ Update an installed binary with `wt update`. ## Documentation +- [Agent-facing Wingthing skill](SKILL.md) - [Choose a usage pattern](https://wingthing.ai/patterns) - [Web documentation](https://wingthing.ai/docs) - [Historical LLM-first architecture review](docs/llm-first-review.md) diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..f910c45 --- /dev/null +++ b/SKILL.md @@ -0,0 +1,45 @@ +--- +name: wingthing +description: Use Wingthing's typed control plane to start and supervise coding agents in durable runs or terminals on local and remote wings. +--- + +# Use Wingthing + +## Place the work first + +Before launching, identify: + +- the execution wing; +- an existing `cwd` on that wing; +- whether the human display is a terminal, browser terminal, or no live display; +- which Wingthing owner and provider-agent home supply credentials; and +- which wing holds the task record, provider history, and optional Wingthing memory. + +Wingthing routes control. It does not create or synchronize workspaces, credentials, +or memory across wings. + +## Run safely + +1. Call `wingthing_capabilities` before relying on an operation or agent. +2. On `wt mcp connect`, call `wing_list` and pass the chosen `wing_id` to every + wing-owned operation. Never rely on a current or default remote wing. +3. Call `sandbox_explain` for the selected agent and `cwd` before starting work. +4. Use `agent_run` when the caller needs semantic status and a final result. Keep + its `run_id`, wait with `agent_wait`, and read completion with `agent_result`. +5. Use `agent_start` only when an interactive PTY and later human attachment are + part of the task. Keep its session ID; do not infer semantic completion from + terminal text. +6. Stop or steer only the exact run or session ID returned by the selected wing. + +## Boundaries + +- Put no provider tokens, SSH keys, or other secrets in prompts or MCP arguments. + Authenticate the provider CLI in the execution owner's agent home. +- A terminal survives client detachment. A run's record and result persist, but + active headless execution still requires its supervising Wingthing process. +- Headless runs do not currently have a browser view. Start a terminal when human + takeover is required. +- Direct remote MCP rejects locked wings and never silently switches to the hosted + relay. Use an unlocked authorized wing, SSH, or a self-hosted roost as appropriate. +- Treat `~/.wingthing/wt.db`, `~/.wingthing/memory/`, provider history, and the + workspace as wing-local state unless the operator has arranged replication. diff --git a/docs/fly-ops.md b/docs/fly-ops.md index 81fcfab..da98071 100644 --- a/docs/fly-ops.md +++ b/docs/fly-ops.md @@ -1,5 +1,25 @@ # Fly Operations Guide +Wingthing is a typed agent manager for durable agent runs and terminals. The Fly +fleet hosts its public coordinator: identity, the authorized wing directory, key +exchange, WebRTC signaling, the portal, and the optional encrypted relay. Agents +still execute on a user's selected wing; neither Fly process group is a general +agent host. + +## Placement and durable state + +| Decision | Public Fly deployment | +| --- | --- | +| **Execution wing** | The access-filtered wing explicitly selected by `wing_id`. Login and edge machines coordinate connections but do not substitute themselves as execution targets. | +| **Workspace** | An existing `cwd` on the selected wing. No Fly service clones or synchronizes user repositories or untracked files. | +| **Display** | `agent_run` returns semantic state over direct MCP without a browser view. `agent_start` creates a persistent PTY; hosted browser/control relay is entitlement-gated, while CLI, SSH, and self-hosted displays remain compatible. | +| **Provider credentials** | The execution owner's agent home on the selected wing. Fly secrets are only service credentials such as JWT, OAuth, billing, or internal-node keys—not Claude, Codex, SSH, or other user provider credentials. | +| **Durable memory** | The login volume stores gateway account, organization, auth, entitlement, and routing records. Each wing remains authoritative for its task database, eggs, optional Wingthing memory, provider history, and workspaces. Edge machines are stateless. | + +The public `direct-free` relay policy changes transport entitlement, not ownership +or organization authorization. Existing personal and organization directories, +roles, configured path scopes, grants, and bounds continue to apply at the wing. + ## Architecture Two process groups, one image: @@ -86,7 +106,9 @@ On `direct-free`, the historical billing-free personal and organization upgrade endpoints are disabled, and the account UI does not offer plan mutation. Existing Pro/team entitlements and cancellation paths remain valid; new relay entitlements must be provisioned by the deployment's billing or operator workflow. Legacy and -self-hosted gateways retain their previous self-service behavior. +self-hosted gateways retain their previous self-service behavior. This does not +remove organization membership or wing sharing; it only prevents those endpoints +from granting new hosted-relay entitlement. The public deployment also sets an explicit temporary migration boundary in `fly.toml`. Accounts created on or before that instant retain relay parity while diff --git a/internal/relay/templates/docs.html b/internal/relay/templates/docs.html index 85da349..f9ed1de 100644 --- a/internal/relay/templates/docs.html +++ b/internal/relay/templates/docs.html @@ -54,7 +54,7 @@
wingthing is an agent manager for agents: one typed control plane for durable work across every machine, with human takeover when useful.
+Wingthing is a typed agent manager for durable agent runs and terminals across local and remote wings, with human takeover when useful.
The MCP server lets a parent LLM discover and operate Wingthing without scraping terminal output. Use wt mcp stdio for the same host and wt mcp connect for an explicitly selected remote wing. Use agent_run for semantic task state. Use agent_start when a person should be able to attach to the persistent terminal.
| placement | current contract |
|---|---|
| execution wing | Local stdio executes on its host. Direct remote calls require the selected wing_id. A roost HTTP MCP endpoint controls that roost's built-in wing; Wingthing never silently substitutes a different target. |
| workspace | Pass an existing cwd on the execution wing. Wingthing does not create, clone, upload, or synchronize the repository or its untracked files. |
| display | agent_run has semantic status and a final result but no live browser view. agent_start creates a PTY a person can attach to through the CLI, SSH, or an entitled/self-hosted browser. |
| credentials | The provider CLI uses the execution owner's agent home on that wing. Shared hosts keep those homes separate. Provider tokens and SSH keys do not belong in prompts or MCP arguments. |
| durable memory | Tasks, results, messages, and threads stay in that wing's ~/.wingthing/wt.db; terminal state stays under ~/.wingthing/eggs, optional prompt memory under ~/.wingthing/memory, and provider history in the provider home. WINGTHING_DIR changes the Wingthing state root. None of this is replicated between wings automatically. |
A terminal survives client detachment. A run's record and result persist, but an active headless run still depends on its supervising Wingthing process. Keep the returned run or session ID together with its owning wing for every later operation.