Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 114 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,96 +1,164 @@
<div align="center">

<img src="apps/web/static/favicon.svg" width="76" height="76" alt="telecode" />

# telecode

**Launch, watch, and steer Claude Code agents on your own machine — from any browser.**

telecode is an open-source, self-hostable command center for coding agents. The agents run on _your_
computer, where your code already is; a responsive web app (an installable PWA — no native app) lets you
launch them, watch them work, and approve each consequential action from your phone or another laptop.
Session content is end-to-end encrypted, so the server in the middle only ever forwards ciphertext.
The agents run on _your_ computer, where your code already is. A responsive web app — an installable PWA,
no native app — lets you launch them, watch them work, and approve each consequential action from your
phone or another laptop. Session content is **end-to-end encrypted**, so the server in the middle only
ever forwards ciphertext.

[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-e8a33d?style=flat-square)](LICENSE)
[![npm: @telecode/cli](https://img.shields.io/npm/v/@telecode/cli?style=flat-square&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@telecode/cli)
[![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?style=flat-square&logo=typescript&logoColor=white)](packages/protocol)
[![SvelteKit](https://img.shields.io/badge/SvelteKit-PWA-FF3E00?style=flat-square&logo=svelte&logoColor=white)](apps/web)
[![Fastify](https://img.shields.io/badge/Fastify-ws_relay-000000?style=flat-square&logo=fastify&logoColor=white)](apps/relay)
[![Claude Agent SDK](https://img.shields.io/badge/Claude-Agent_SDK-D97757?style=flat-square&logo=anthropic&logoColor=white)](packages/daemon)
[![End-to-end encrypted](https://img.shields.io/badge/end--to--end-encrypted-56a585?style=flat-square)](docs/end-to-end-encryption.md)

[Why](#why-its-built-this-way) ·
[Architecture](#architecture) ·
[How it connects](#how-it-connects) ·
[Quick start](#quick-start) ·
[Security](#security--privacy) ·
[Docs](#documentation)

</div>

---

## Why it's built this way

- **Execution stays on your machine.** Agents run locally, with your tools and credentials. There is no
cloud execution — that's a product promise, not a detail.
- **Outbound-only.** Both your machine (the daemon) and your browser dial _out_ to a relay; nothing ever
reaches _into_ your machine. No ports to open, no inbound access.
- **End-to-end encrypted.** Prompts, output, diffs, and transcripts are encrypted in the browser and the
daemon. The relay sees only routing metadata (see the [threat model](docs/threat-model.md)).
- **You hold the gate.** Every consequential tool call pauses for your approval before it runs.
- **Open and self-hostable.** Run the whole thing yourself; the relay is the only piece that could live
elsewhere, and even then it sees only ciphertext.
Remote-control tools for coding agents usually run the agent **in the cloud** and ask you to trust a
closed service with your code and your keys. Telecode inverts that: the agent runs **where your code
already is — your machine** — and the network in the middle is reduced to a dumb, blind courier.

## How it fits together
| Principle | What it means |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **Execution stays on your machine** | Agents run locally, with your tools and credentials. There is no cloud execution — a product promise, not a detail. |
| **Outbound-only** | Both your machine (the daemon) and your browser dial _out_ to a relay; nothing ever reaches _into_ your machine. No ports to open. |
| **End-to-end encrypted** | Prompts, output, diffs, and transcripts are encrypted in the browser and the daemon. The relay sees only routing metadata. |
| **You hold the gate** | Every consequential tool call pauses for your approval before it runs. |
| **Open & self-hostable** | Run the whole thing yourself; the relay is the only piece that could live elsewhere, and even then it sees only ciphertext. |

| Part | Role |
| ---------- | ---------------------------------------------------------------------------------------------- |
| **Daemon** | Runs on your machine via the Claude Agent SDK; spawns and supervises agent sessions. |
| **Relay** | A stateless multiplexer + device/session registry. Forwards ciphertext; never runs agents. |
| **Web** | A SvelteKit PWA: launch sessions, watch the stream, approve tool calls, steer with follow-ups. |
## Architecture

A small TypeScript monorepo: a SvelteKit PWA and a Claude-Agent-SDK daemon talk through a thin Fastify +
`ws` relay, over one shared, zod-validated wire contract.

```mermaid
flowchart LR
subgraph machine["Your machine"]
D["Daemon<br/>(Claude Agent SDK)"]
subgraph machine["💻 Your machine"]
D["Daemon<br/>Claude Agent SDK"]
A["Agent session<br/>your code · tools · keys"]
D -->|"approval gate"| A
end
subgraph cloud["Relay — runs anywhere"]
subgraph cloud["Relay — runs anywhere"]
R["Multiplexer<br/>ciphertext + routing only"]
end
B["Browser / PWA<br/>encrypts + decrypts"]
B["🌐 Browser / PWA<br/>encrypts + decrypts"]

B -->|"dials out · WSS"| R
D -->|"dials out · WSS"| R
R -.->|"end-to-end encrypted"| B
R -.->|"end-to-end encrypted"| D
R -.->|"🔒 end-to-end encrypted"| B
R -.->|"🔒 end-to-end encrypted"| D

classDef ends fill:#3b2f10,stroke:#e8a33d,stroke-width:2px,color:#fff;
class B,D,A ends
```

Both the browser and the daemon **dial out** to the relay — nothing reaches into your machine. The relay
multiplexes encrypted frames between them and can't read any of it; agent work, your code, and your keys
never leave your machine.
| Layer | Package / app | What it owns |
| ------------ | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **Daemon** | `packages/daemon` → `npx @telecode/cli` | Runs on your machine via the Claude Agent SDK; spawns and supervises agent sessions behind the human-in-the-loop approval gate. |
| **Relay** | `apps/relay` · Fastify + `ws` | A stateless multiplexer + device/session registry. Forwards ciphertext, routes by `(user, device)`, never runs agents. |
| **Web** | `apps/web` · SvelteKit PWA | Launch sessions, watch the stream, approve tool calls, steer with follow-ups — from a phone or laptop. |
| **Protocol** | `packages/protocol` | The shared wire contract: zod schemas (one validated `Envelope`) + the WebCrypto E2E helpers. |
| **UI** | `packages/ui` | The shared design system — dark-first tokens + primitives. |

## How it connects

Your laptop sits behind a router with no open ports, so both ends **dial out** to the relay, which only
ever matches a browser to a daemon belonging to the **same user and device**. Two questions matter, and
each has a dedicated, plain-language page:

- **How do we know it's _you_?** You sign in (GitHub OAuth, server-side session), and your machine is
paired with the OAuth Device Grant — where the device is bound to your account **server-side**, so the
client can never claim someone else's. → **[Connecting your machine](docs/connecting-your-machine.md)**
- **How is the content kept private?** A per-session key is exchanged via X25519 ECDH so only your browser
and daemon can read the session; the relay forwards sealed AES-256-GCM frames it has no key to open. →
**[End-to-end encryption](docs/end-to-end-encryption.md)**

## Quick start

1. **Run the daemon** on the machine you want to control — it prints a pairing code. _(The published
`telecode` command is on the way; until then, run it from a clone with `make run` — see
[Getting started](docs/getting-started.md).)_
2. **Open the web app**, sign in, and enter the pairing code to bind the machine to your account.
On the machine you want to control:

```sh
# one-line install (checks Node 22+, installs the telecode command)
curl -fsSL https://telecode.io/install.sh | bash

# …or run it directly with npm
npx @telecode/cli
```

Then:

1. The daemon prints a **pairing code**.
2. Open the web app, **sign in**, and enter the code to bind this machine to your account.
3. **Launch a session**, then approve actions as they come and steer with follow-up messages.

Check a machine's setup any time with `telecode doctor` (Node version, API key, pairing, relay
Check a machine's setup any time with **`telecode doctor`** (Node version, API key, pairing, relay
reachability).

→ Full walkthrough: **[docs/getting-started.md](docs/getting-started.md)**

## Security & privacy

Telecode's trust model is the product. The three pages below explain it end to end, in plain language and
with diagrams:

- **[End-to-end encryption](docs/end-to-end-encryption.md)** — the keys, the handshake, and a message's
round trip; the relay only ever holds ciphertext.
- **[Connecting your machine](docs/connecting-your-machine.md)** — outbound-only connections, sign-in
identity, and how pairing binds a machine to exactly your account.
- **[Threat model](docs/threat-model.md)** — what each part can and cannot see, the approval gate, and how
to verify it yourself. telecode also **[collects nothing by default](docs/telemetry.md)**.

Found a vulnerability? Please report it privately — see the [Security Policy](SECURITY.md).

## Documentation

- [Getting started](docs/getting-started.md) — install, pair, and run your first session.
- [Reconnecting & offline behavior](docs/reconnect-and-offline.md) — what happens on reload, network
drops, and laptop sleep.
- [Self-hosting the relay](docs/self-hosting.md) — run your own relay with Docker.
- [Threat model](docs/threat-model.md) — what each part can and cannot see, and how to verify it.
- [Telemetry & privacy](docs/telemetry.md) — telecode collects nothing by default.
- [Publishing the CLI](docs/publishing.md) — maintainer runbook for shipping the `telecode` command.
Full docs live in **[docs/](docs/README.md)** — start there for the index.

| Doc | Read it for |
| ---------------------------------------------------------- | ------------------------------------------------------- |
| **[Getting started](docs/getting-started.md)** | Install, pair, and run your first session |
| [Connecting your machine](docs/connecting-your-machine.md) | Secure connection + how we know it's you (diagrams) |
| [End-to-end encryption](docs/end-to-end-encryption.md) | How the relay only ever sees ciphertext (diagrams) |
| [Threat model](docs/threat-model.md) | What each part can and cannot see, and how to verify it |
| [Reconnecting & offline](docs/reconnect-and-offline.md) | What happens on reload, network drops, and sleep |
| [Self-hosting the relay](docs/self-hosting.md) | Run your own relay with Docker |
| [Deploying to Azure](docs/deploy-azure.md) | Production runbook (Container Apps + Supabase) |

## Contributing

Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for setup and the change bar, and the
[Code of Conduct](CODE_OF_CONDUCT.md). Found a security issue? Please report it privately per the
[Security Policy](SECURITY.md). Release history lives in the [CHANGELOG](CHANGELOG.md).
[Code of Conduct](CODE_OF_CONDUCT.md). Release history lives in the [CHANGELOG](CHANGELOG.md).

## Development

telecode is a TypeScript monorepo (pnpm workspaces + Turborepo): a SvelteKit web app, a Fastify + `ws`
relay, a Claude Agent SDK daemon, and a shared protocol/crypto package.
Telecode is a TypeScript monorepo (pnpm workspaces + Turborepo). From a clone:

```sh
make setup # install workspace dependencies
make run # start the relay, a local daemon, and the web app
make run # start the relay, a local daemon, and the web app together
make test # run the test suites
make stop # stop the local stack
```

## License

telecode is free software, licensed under the **GNU Affero General Public License v3.0**. See
Telecode is free software, licensed under the **GNU Affero General Public License v3.0**. See
[LICENSE](LICENSE).
55 changes: 40 additions & 15 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
# telecode documentation

Start with the project [README](../README.md) for what telecode is and why. These guides go deeper:

- **[Getting started](./getting-started.md)** — install the daemon, pair a machine, and run your first
session (with `telecode doctor` for preflight).
- **[Reconnecting & offline behavior](./reconnect-and-offline.md)** — why reopen is a reconnect, how
reconnect and laptop sleep/wake are handled, and what doesn't survive a powered-off machine.
- **[Self-hosting the relay](./self-hosting.md)** — run your own relay with Docker so even routing metadata
stays with you.
- **[Deploying to Azure](./deploy-azure.md)** — production runbook: the web app + relay on Azure Container
Apps (Bicep IaC + CI/CD), with Postgres on managed Supabase.
- **[Threat model](./threat-model.md)** — exactly what each part can and cannot see, how the end-to-end
encryption works, and how to verify the relay only sees ciphertext.
- **[Telemetry & privacy](./telemetry.md)** — telecode collects nothing by default; what the self-host-only
Telecode is an open-source, self-hostable command center for Claude Code agents: the agents run on **your**
machine, and you launch, watch, and steer them from any browser — with session content **end-to-end
encrypted**, so the relay in the middle only ever forwards ciphertext.

Start with the [project README](../README.md) for the one-paragraph overview and install steps. These
pages go deeper. Each is self-contained and cross-links the others where concepts meet; the diagrams are
authored in **Mermaid** and render on GitHub.

## Use it

- **[Getting started](getting-started.md)** — install the daemon, pair a machine, and run your first
session, with `telecode doctor` for preflight.
- **[Reconnecting & offline behavior](reconnect-and-offline.md)** — why reopening is a _reconnect_ (never
a restart), how network drops and laptop sleep/wake are handled, and what a powered-off machine can't do.

## Understand it

- **[Connecting your machine](connecting-your-machine.md)** — how your browser reaches a laptop behind a
router with no open ports, and how telecode knows a paired machine belongs to _exactly_ you (sign-in
identity + the device-pairing flow). Plain language, with diagrams.
- **[End-to-end encryption](end-to-end-encryption.md)** — how the relay only ever sees ciphertext: the
keys, the handshake, and a message's round trip — built on X25519 · ECDH · HKDF · AES-256-GCM. Plain
language, with diagrams.
- **[Threat model](threat-model.md)** — the adversary's-eye view: what each part _can_ and _cannot_ see,
the approval gate, and how to verify the relay only ever holds ciphertext.

## Operate it

- **[Self-hosting the relay](self-hosting.md)** — run your own relay with Docker, so even the routing
metadata stays with you.
- **[Deploying to Azure](deploy-azure.md)** — the production runbook: web app + relay on Azure Container
Apps (Bicep IaC + CI/CD), Postgres on managed Supabase.
- **[Telemetry & privacy](telemetry.md)** — telecode collects nothing by default; what the self-host-only
opt-in operational metrics do and don't include.
- **[Publishing the CLI](./publishing.md)** — maintainer runbook for shipping the `telecode` command to
npm.
- **[Publishing the CLI](publishing.md)** — maintainer runbook for shipping the `telecode` command to npm.

---

New to the project? Read **[Connecting your machine](connecting-your-machine.md)** and
**[End-to-end encryption](end-to-end-encryption.md)** together — between them they explain the whole trust
model in plain language.
Loading
Loading