clank

module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 17, 2026 License: AGPL-3.0

README

Clank

previews

Visually editable previews for web & mobile

Clank injects an overlay into your web or mobile apps that allows you to edit them while you're using them.

The fastest way to iterate on apps is by just pointing and explaining.

Clank is for iterating on that last 10% that AI can't solve.

How

Run clank preview to start your dev server with a new agent session, or clank preview --attach to connect an existing Claude, Codex, or OpenCode session.

Mobile app Laptop
Expo Like Expo Go but with agents. Run clank preview: Like expo start, needs mobile app
Web Opens webview + Clank overlay Run clank preview: Runs Next.js, Vite (React, Svelte, Vue, etc.), or any other web server. An editing overlay powered by your own agents, in your own browser.

The mobile app needs a Clank gateway. Pair it with your laptop using clank pair, or use a hosted gateway such as supaclank.com to build without a laptop. The browser overlay and local Expo dev servers require the Clank CLI.

Get started

For web app development, start with the laptop. For mobile Expo app development, start with the mobile app.

Laptop (Clank CLI)

The clank CLI starts its own local Clank gateway, which the browser overlay (or mobile app) connects to.

brew install supaclank/tap/clank
# cd to your project, and run
clank preview # launches your project

the CLI will onboard you the first time with agent preferences and synthesize an initial launch config for your project's dev server.

Mobile app

Connects to any Clank gateway: By default it connects to api.supaclank.com via OIDC, but you can also pair your laptop (clank pair), or just set the gateway URL/IP directly.

image
Get it on Google Play
Mobile demo

https://github.com/user-attachments/assets/e2a9b928-d861-442d-97e1-d1a81880f014

Usage
Overlay UI
Key Action
⌘E / Ctrl+E summon / hide the prompt box
hold ⌘ / Ctrl point at elements to attach them as context
⇪ Caps Lock tap to talk, tap again to transcribe
hold ⇧ Shift prompt box snaps to the cursor

For the mobile overlay: Shake the phone to bring up the floating prompt box, shake again to see chat. The app remains usable. Just move the box around, or hide it.

CLI

Tips & tricks:

Preview any pull request instantly. It reuses your local worktree on-disk if it finds it, otherwise creates one.

clank preview https://github.com/supaclank/web/pull/18

Specify the folder and your dev-server's port for clank preview to forward to it, while getting the correct context:

clank preview . :8080

Attach to an existing agent session

clank preview --attach # opens agent session picker, any of your harnesses

Architecture

flowchart LR
    subgraph clients["Your devices"]
        browser["Browser overlay"]
        terminal["Terminal (clank)"]
        phone["Phone"]
    end

    subgraph gateway_box["Laptop or cloud"]
        gateway["<b>Gateway (clankd)</b><br/>auth · provisioning<br>proxy · previews<br>images · notifications"]
    end

    subgraph host_box["Laptop or sandbox"]
        host["<b>Host (clank-host)</b><br/>sessions · events<br/>credentials · git"]
        agent["Your agent<br/>harness"]
    end

    browser --> gateway
    terminal --> gateway
    phone --> gateway
    gateway --> host
    host --> agent

On a laptop everything runs locally, using your existing agent and git setup. The laptop is your default "sandbox" environment, more info in provisioning & sandboxes.

A multi-tenant gateway that's built to be a dumb relay with minimal user data stored. It provisions sandboxes for the user, authenticates and proxies requests, handles wake/sleep, and some coordination like notifications, images, previews.

The host handles the coding agents, git operations, credentials, keepalive, webhooks. It connects to the agent harnesses via ACP, and needs a persistent dev environment where credentials and all the work is stored, whether it be your laptop or a persistent sandbox.

Gateway
Multi-tenant

The gateway routes requests by user ID, which it acquires via a simple pkg/auth.Authenticator interface.

type Authenticator interface {
    Verify(r *http.Request) (Principal, error)
}

type Principal struct {
    UserID string
    Claims map[string]any
}

This allows the gateway to remain agnostic to your specific auth method.

The only contract is that the request context contains that auth.Principal after verification. Clank provides a simple middleware for that, calling Authenticator's Verify(r) and injecting the principal. Clank also bundles four Authenticators into the auth package: AllowAll, OIDC, StaticBearer, JWTHS256.

Bridge auth

Clank CLI itself implements a mobile<->laptop bridge auth.Authenticator, allowing you to pair your mobile app to your laptop and control your agents from the phone.

Most services today require a central server to mediate this pairing. Clank instead implemented a protocol for this.

For the implementation and spec for this, see docs/bridge-pairing.md.

TL;DR Mobile and laptop exchange their public keys and ensure there was no man-in-the-middle tampering, but they do not encrypt traffic to prevent eavesdropping. No secrets are transmitted over the wire. Encryption is left for your network transport to solve, by e.g. using Tailscale. The protocol is secured by entering a code displayed on the phone using the laptop keyboard, proving access to both devices and the intent to pair them. After pairing, the phone signs each control request, and the laptop accepts requests only from enrolled device keys.
Provisioning & sandboxes

Clank tries to be agnostic to the exact sandbox provider. Each sandbox provider implements a Provisioner interface. The laptop implements a local.Provisioner, and the cloud currently uses flymachine.Provisioner (you own the image, we just require clank-host to be reachable).

Why? Persistent sandboxes

The philosophy: Agents should have access to a full development environment and the context for several projects over time. This is needed for a cloud agent that proactively prioritizes and does work, where you just steer and verify the work.

An ephemeral sandbox becomes a persistent sandbox by mounting volumes that persist the disk state. Different sandbox providers work in different ways, either they have a snapshot API where you have to manage the snapshots yourself, or they do it for you. This is connected to auto-sleeping: Does the provider automatically snapshot disk and shut down? When does that trigger? No running processes? No open TCP connections? A hardcoded timeout? Heartbeat based timeout where you have to call an external API?

All of this requires a lot of complexity on the backend to do reliably because the risk of getting it wrong means:

  • Interrupting the user workflow at the wrong time
  • Letting sandboxes run 24/7 incurring extra cost.

The Provisioner interface abstracts this away from the gateway. Each implementation is different.

This is also set up well for a future where you spin up lightweight microVMs on your own laptop.

note: Clank originally started with Daytona, moved to Fly.io's Sprites, and then migrated to Fly.io Machines. Throughout this the interface hardened, but currently the exact interface is subject to change, since we haven't actually battle-tested it against multiple sandbox providers yet.

End-to-end encryption

TL;DR: Not implemented. Self-hosting is the solution: Users can instead pair their laptop and use something like Tailscale. Companies can self-host on their own infra.

Why? In a multi-tenant environment, having access to every sandbox is a liability. But it's also unavoidable, because you have to provision the machines somehow and you can't really give the keys to your users without also keeping your master key (at least no compute provider allows this).

That said, there is no central database for user session data or code. All of that is handled by the sandbox which you already trust with your credentials. You would have to SSH to each individual sandbox to acquire this data.

Agent harnesses

Clank supports Claude Code, Codex, OpenCode, via ACP. We're probably adding support for Hermes, Gemini, and Pi soon. We still need small adapters for each ACP server, due to versioning, auth, and slight differences.

Previews

Expo projects are detected automatically. For web projects, your connected agent generates .clank/launch.yaml on first run.

For web, clank preview starts or attaches to a dev server and injects the Clank overlay as a <script> tag without changing your source code.

For Expo, clank preview injects a small script that hooks into various React Native APIs.

Local previews stay on your laptop, while hosted previews use an owner-only URL that securely tunnels through the gateway and can be shared or revoked. Easy public tunnel links for your local previews coming soon

The mobile app itself is similar to how Expo Go works under the hood. It loads user apps using the same pre-installed native components that Expo Go has, so Clank and Expo Go apps are compatible. Support for development builds is on the roadmap.

For Expo apps we also append a system prompt, to avoid common pitfalls that agents seem to fall into when developing mobile apps: https://github.com/supaclank/clank/tree/main/internal/agent/guidance.

Voice

Voice is push-to-talk dictation for the preview overlay. Use the browser's Web Speech API or keep audio local with clank-voice, powered by Silero VAD and NVIDIA Parakeet v3. The mobile app runs the same speech-recognition stack on-device.

brew install supaclank/tap/clank-voice # optional, macOS; builds from source (needs Xcode CLT)

Models (~670 MB) download on first use.

Images & attachments

Images and attachments are handled via a minimal blobstore interface, with S3 for cloud deployments, and a LAN one for mobile->laptop transfers.

Roadmap

  • In the future we may use something like https://github.com/superfly/tokenizer (and/or an LLM proxy) for people that don't want to give up real keys, and for 3rd party connections.
  • Ephemeral one-off sandboxes are also on the roadmap for workflows that need the isolation.
  • Public tunnel links for your local previews
  • Support for Expo development builds
  • Create a feature request / suggestion!

Docs

Directories

Path Synopsis
cmd
clank command
clank-auth-stub command
clank-auth-stub is a minimal OAuth 2.0 Authorization Code + PKCE server (RFC 6749 + RFC 7636) for clank dev/testing.
clank-auth-stub is a minimal OAuth 2.0 Authorization Code + PKCE server (RFC 6749 + RFC 7636) for clank dev/testing.
clank-host command
clank-host is the Host plane binary.
clank-host is the Host plane binary.
clankd command
internal
agent
Package agent defines the interface and types for coding agent backends.
Package agent defines the interface and types for coding agent backends.
agent/acp
Package acp adapts Agent Client Protocol (ACP) agents to clank's SessionBackend seam.
Package acp adapts Agent Client Protocol (ACP) agents to clank's SessionBackend seam.
agent/acp/acptest
Package acptest provides an in-process scripted ACP agent for tests: a real agent speaking real JSON-RPC over real pipes through the same SDK clank uses — the protocol-level analog of hosttest.StubBackend.
Package acptest provides an in-process scripted ACP agent for tests: a real agent speaking real JSON-RPC over real pipes through the same SDK clank uses — the protocol-level analog of hosttest.StubBackend.
agent/acptools
Package acptools provisions the pinned ACP adapter packages onto a host.
Package acptools provisions the pinned ACP adapter packages onto a host.
agent/guidance
Package guidance assembles the stack-specific guidance that clank injects as the building agent's system prompt at session start, and materializes the stack's detailed playbook as an on-demand skill in the user's personal skills directory (~/.claude/skills).
Package guidance assembles the stack-specific guidance that clank injects as the building agent's system prompt at session start, and materializes the stack's detailed playbook as an on-demand skill in the user's personal skills directory (~/.claude/skills).
agent/presets
Package presets defines agent presets: named bundles of session config values (mode, model, effort, …) a client applies when creating or steering a session.
Package presets defines agent presets: named bundles of session config values (mode, model, effort, …) a client applies when creating or steering a session.
bridge
Package bridge is the daemon's durable laptop↔phone connection, built on per-device public keys — nothing secret ever crosses the wire.
Package bridge is the daemon's durable laptop↔phone connection, built on per-device public keys — nothing secret ever crosses the wire.
cli/clankcli
Package clankcli provides the root cobra command for the clank binary.
Package clankcli provides the root cobra command for the clank binary.
cli/daemoncli
Package daemoncli provides the cobra commands for managing the Clank daemon.
Package daemoncli provides the cobra commands for managing the Clank daemon.
cloud
Package cloud is the laptop's HTTP client for the user's clank gateway deployment.
Package cloud is the laptop's HTTP client for the user's clank gateway deployment.
daemonclient
Package hubclient is the canonical Go client for talking to clankd's Hub HTTP API.
Package hubclient is the canonical Go client for talking to clankd's Hub HTTP API.
git
Package git provides helpers for interacting with git repositories, focused on worktree and branch management for Clank's session isolation.
Package git provides helpers for interacting with git repositories, focused on worktree and branch management for Clank's session isolation.
host
Package host defines the value types for Clank's Host plane and the host.Service that runs agent backends, owns clones of remote repos, and exposes an HTTP API to the Hub.
Package host defines the value types for Clank's Host plane and the host.Service that runs agent backends, owns clones of remote repos, and exposes an HTTP API to the Hub.
host/client
Package hostclient is the Hub-side handle for talking to a Host.
Package hostclient is the Hub-side handle for talking to a Host.
host/github
Package github holds the host-side GitHub integration: the credential store, the device-flow runtime, the GitHub API client, and the orchestration that combines them for "create a PR from a worktree" requests.
Package github holds the host-side GitHub integration: the credential store, the device-flow runtime, the GitHub API client, and the orchestration that combines them for "create a PR from a worktree" requests.
host/hosttest
Package hosttest provides shared test doubles for wiring an in-process host.Service in end-to-end tests: a stub backend manager standing in for the real opencode/claude process boundary, and a throwaway git repo factory.
Package hosttest provides shared test doubles for wiring an in-process host.Service in end-to-end tests: a stub backend manager standing in for the real opencode/claude process boundary, and a throwaway git repo factory.
host/mux
Package hostmux exposes a *host.Service over HTTP.
Package hostmux exposes a *host.Service over HTTP.
host/petname
Package petname generates short, memorable identifiers in the form adjective-animal-hex4 (e.g.
Package petname generates short, memorable identifiers in the form adjective-animal-hex4 (e.g.
host/preview
Package preview resolves, spawns, and supervises per-worktree development servers on a Clank host.
Package preview resolves, spawns, and supervises per-worktree development servers on a Clank host.
host/store
Package store is the host's local SQLite for session metadata and the primary-agent cache.
Package store is the host's local SQLite for session metadata and the primary-agent cache.
keepalive
Package keepalive sends an "agent is active" signal to a provider- specific Listener whenever a backend event arrives.
Package keepalive sends an "agent is active" signal to a provider- specific Listener whenever a backend event arrives.
keepalive/exit
Package exit implements a keepalive.Listener that shuts the process down after a period of inactivity — the "inactivity-detection (we kill)" listener anticipated by the keepalive package doc.
Package exit implements a keepalive.Listener that shuts the process down after a period of inactivity — the "inactivity-detection (we kill)" listener anticipated by the keepalive package doc.
keepalive/noop
Package noop provides a Listener that does nothing.
Package noop provides a Listener that does nothing.
keepalive/sprites
Package sprites implements a keepalive.Listener backed by the Fly Sprites Tasks API (https://docs.sprites.dev/keeping-sprites-running/).
Package sprites implements a keepalive.Listener backed by the Fly Sprites Tasks API (https://docs.sprites.dev/keeping-sprites-running/).
lannet
Package lannet answers "what address can peers on the local network reach this host at" — shared by the CLI (QR links) and the daemon's bridge listener.
Package lannet answers "what address can peers on the local network reach this host at" — shared by the CLI (QR links) and the daemon's bridge listener.
launchconfig
Package launchconfig loads Clank's project-specific web preview launch files.
Package launchconfig loads Clank's project-specific web preview launch files.
notifier
Package notifier is the host's outbound-notification delivery pipeline.
Package notifier is the host's outbound-notification delivery pipeline.
notifier/noop
Package noop implements notifier.Provider as a logger-only sink.
Package noop implements notifier.Provider as a logger-only sink.
notifier/webhook
Package webhook implements notifier.Provider as an HTTP POST to a configured URL.
Package webhook implements notifier.Provider as an HTTP POST to a configured URL.
repolabel
Package repolabel derives the owner-independent display label for a git repository, used as the `origin_repo` group key on worktree listings.
Package repolabel derives the owner-independent display label for a git repository, used as the `origin_repo` group key on worktree listings.
socketutil
Package socketutil provides safe filesystem operations for Unix domain sockets shared across the clank-host and clankd binaries.
Package socketutil provides safe filesystem operations for Unix domain sockets shared across the clank-host and clankd binaries.
sqlmigrate
Package sqlmigrate applies embedded goose migrations to a SQLite database.
Package sqlmigrate applies embedded goose migrations to a SQLite database.
store
Package store provides SQLite-backed persistence for the provisioner's host registry (the `hosts` table) and push-notification devices (the `devices` table).
Package store provides SQLite-backed persistence for the provisioner's host registry (the `hosts` table) and push-notification devices (the `devices` table).
tui
version
Package version reports the build version shared by every clank binary.
Package version reports the build version shared by every clank binary.
webpreview
Package webpreview is the browser twin of the phone preview: an overlay-injecting reverse proxy that `clank preview` puts in front of a KindWeb dev server (see internal/host/preview), plus the dictation service the overlay's push-to-talk streams into.
Package webpreview is the browser twin of the phone preview: an overlay-injecting reverse proxy that `clank preview` puts in front of a KindWeb dev server (see internal/host/preview), plus the dictation service the overlay's push-to-talk streams into.
pkg
auth
Package auth is the single contract for authenticating inbound HTTP requests in clank.
Package auth is the single contract for authenticating inbound HTTP requests in clank.
blobstore
Package blobstore is a provider-agnostic object-storage layer: a minimal presigned-URL contract plus path-safety primitives, with no knowledge of what the blobs are.
Package blobstore is a provider-agnostic object-storage layer: a minimal presigned-URL contract plus path-safety primitives, with no knowledge of what the blobs are.
gateway
Package gateway is the daemon's single ingress: it authenticates, resolves the user to a persistent host via the provisioner, and reverse-proxies everything else through.
Package gateway is the daemon's single ingress: it authenticates, resolves the user to a persistent host via the provisioner, and reverse-proxies everything else through.
gateway/previewtunnel
Package previewtunnel exposes the preview-app's HTTP transport: a thin wrapper around an stdlib *http.Transport whose DialContext opens a fresh net.Conn to a sprite's internal port via the configured Provisioner.
Package previewtunnel exposes the preview-app's HTTP transport: a thin wrapper around an stdlib *http.Transport whose DialContext opens a fresh net.Conn to a sprite's internal port via the configured Provisioner.
images
Package images is the gateway-side presign service for user image uploads: its own blobstore.Storage (its own bucket) and its own /v1/images route, built on pkg/blobstore.
Package images is the gateway-side presign service for user image uploads: its own blobstore.Storage (its own bucket) and its own /v1/images route, built on pkg/blobstore.
notify
Package notify implements the clankd-side push delivery for host-emitted notifier webhooks.
Package notify implements the clankd-side push delivery for host-emitted notifier webhooks.
preview/routestore
Package routestore is the contract for preview-route persistence.
Package routestore is the contract for preview-route persistence.
preview/routestore/memstore
Package memstore is an in-memory routestore.Store for tests.
Package memstore is an in-memory routestore.Store for tests.
preview/tokens
Package tokens holds the constants and helpers shared between clank-host (which receives a token in the webhook response and returns it to mobile) and clankgw (which mints tokens, resolves them on subdomain requests, and gates visibility).
Package tokens holds the constants and helpers shared between clank-host (which receives a token in the webhook response and returns it to mobile) and clankgw (which mints tokens, resolves them on subdomain requests, and gates visibility).
provisioner
Package provisioner defines the contract between the gateway/hub layers and the cloud-side machinery that owns persistent per-user hosts.
Package provisioner defines the contract between the gateway/hub layers and the cloud-side machinery that owns persistent per-user hosts.
provisioner/flymachines
GetHostByID + OpenInternalConn capability extensions.
GetHostByID + OpenInternalConn capability extensions.
provisioner/flysprites
Sprites-side implementation of the GetHostByID + OpenInternalConn capability extensions on provisioner.Provisioner.
Sprites-side implementation of the GetHostByID + OpenInternalConn capability extensions on provisioner.Provisioner.
provisioner/hoststore
Package hoststore defines the persistence contract used by cloud provisioners (flysprites, flymachines, …) for tracking the per-(userID, provider) host record.
Package hoststore defines the persistence contract used by cloud provisioners (flysprites, flymachines, …) for tracking the per-(userID, provider) host record.
provisioner/local
Local-subprocess implementation of GetHostByID + OpenInternalConn.
Local-subprocess implementation of GetHostByID + OpenInternalConn.
provisioner/transport
Package transport holds RoundTripper helpers shared across provisioners.
Package transport holds RoundTripper helpers shared across provisioners.
provisioner/tunnelclient
Package tunnelclient dials clank-host's GET /tunnel/{port} endpoint and adapts the WebSocket to a net.Conn carrying the raw TCP bytes of a port on the host's loopback.
Package tunnelclient dials clank-host's GET /tunnel/{port} endpoint and adapts the WebSocket to a net.Conn carrying the raw TCP bytes of a port on the host's loopback.

Jump to

Keyboard shortcuts

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