Skip to content

saaskit-dev/Free

Repository files navigation

Free

Free makes a remote machine available to an ACP-capable editor as if it were a local ACP agent. It owns the product surface around the relay Worker, native ACP bridge, machine host, account authorization, and remote operational tooling.

@saaskit-dev/acp-runtime remains the local SDK dependency. Free should import only the public runtime API from that package; relay, bridge, host, daemon, and Worker behavior belong in this repository.

Install

Install the latest CLI as a Bun-compiled binary:

curl -fsSL https://free.saaskit.app/install | bash

The binary installer downloads the current GitHub latest release asset for your platform, installs the unified free CLI to ~/.local/bin/free, then runs free login by default.

Useful binary install flags:

  • --no-login installs only the free CLI.
  • --force-login refreshes browser login and re-enables this machine.
  • --relay-env local signs in against the local relay.
  • --relay-url <ws-url> uses a custom relay.

Install from source when developing the installer or packaging path:

curl -fsSL https://raw.githubusercontent.com/saaskit-dev/Free/main/scripts/install.sh | bash

The source installer clones Free and acp-runtime, builds the required local packages, packs Free, installs the resulting CLI globally with npm, then runs free login by default.

Useful source install flags:

  • --no-login installs only the free CLI.
  • --force-login refreshes browser login and re-enables this machine.
  • --relay-url <ws-url> uses a non-default relay.
  • --ref <git-ref> installs a specific Free branch, tag, or commit.

For a local checkout:

./scripts/install.sh

CLI

The installed package exposes free:

free login
free logout
free status
free session list
free session close <session-id>

The normal user flow is:

  1. Install the unified free CLI.
  2. Run free login on each machine that should be available.
  3. Check availability with free status.

Hosts are registered in the relay control plane. Offline hosts can still appear in discovery using their last known metadata, but only currently connected hosts are selectable for a new route.

Architecture

The user-facing path is:

Editor ACP client -> free bridge run -> Relay Worker -> local Free host -> acp-runtime -> Agent

The relay control plane stores account, client, host, grant, session binding, and last-known host metadata in D1. Relay memory is limited to live transport state such as active WebSocket routes, heartbeats, reconnect windows, pending frames, and in-flight waiters.

See docs/remote-acp.md and docs/relay-invariants.md for the detailed relay and trust-boundary rules.

Development

Use the maintained make targets:

make help
make install
make build
make test
make verify

Common relay commands:

make relay-dev
make relay-deploy-dry-run
make relay-migrate-remote
make relay-deploy
make remote-prod-smoke

make build builds the local ../acp-runtime dependency and then Free. make verify runs typecheck, tests, package creation, install smoke, and relay deploy dry-run. See docs/verification-matrix.md for the maintained verification layers and the manual real-chain checks required for Workbench, Zed, host lifecycle, and session recovery changes.

Cloudflare Deployment

Free separates the public product surface from the relay/API surface.

  • Workbench Web: the product UI. Deploy the Expo Web export to Cloudflare Pages, for example https://free.saaskit.app.
  • Relay/API: the Worker that owns WebSocket ACP, API, OAuth exchange, D1, and Durable Object state. Deploy it to a separate Worker domain, for example https://free-relay.saaskit.app.

Deploy the relay Worker:

make relay-migrate-remote
make relay-deploy

make relay-deploy deploys the Worker custom domain free-relay.saaskit.app by default. Override RELAY_DOMAIN only for a custom relay deployment.

Set these Worker secrets before using GitHub OAuth online:

pnpm --dir relay exec wrangler secret put ACP_RELAY_GITHUB_CLIENT_SECRET
pnpm --dir relay exec wrangler secret put ACP_RELAY_ACCOUNT_SESSION_PRIVATE_KEY

Set these Worker variables in relay/wrangler.jsonc or the Cloudflare dashboard:

ACP_RELAY_GITHUB_CLIENT_ID
ACP_RELAY_ACCOUNT_SESSION_KEY_ID
ACP_RELAY_ACCOUNT_SESSION_PUBLIC_KEYS
ACP_RELAY_WORKBENCH_ORIGIN=https://free.saaskit.app

Deploy Workbench Web after setting the public origins:

EXPO_PUBLIC_RELAY_URL=https://free-relay.saaskit.app \
EXPO_PUBLIC_WORKBENCH_ORIGIN=https://free.saaskit.app \
WORKBENCH_PAGES_PROJECT=free-app \
make workbench-deploy

GitHub Actions deployment

.github/workflows/deploy-cloudflare.yml runs verification for pull requests and branches. On main it deploys the relay Worker first, then deploys Workbench Web.

Configure these GitHub Actions secrets before enabling automatic deployment:

CLOUDFLARE_ACCOUNT_ID

The deploy jobs run on the local macOS self-hosted runner and use that runner's authenticated Wrangler OAuth session for remote D1 migrations, Worker deployment, and Pages deployment. The workflow uses these defaults:

ACP_RUNTIME_REPO_URL=https://github.com/saaskit-dev/acp-runtime.git
RELAY_DOMAIN=free-relay.saaskit.app
EXPO_PUBLIC_RELAY_URL=https://free-relay.saaskit.app
EXPO_PUBLIC_WORKBENCH_ORIGIN=https://free.saaskit.app
WORKBENCH_PAGES_PROJECT=free-app

The workflow checkout also clones the pinned acp-runtime ref from .acp-runtime-ref into ../acp-runtime, matching the local development layout.

GitHub OAuth callback URLs should belong to Workbench, not the relay Worker:

https://free.saaskit.app/login/callback
http://127.0.0.1:8790/login/callback

The relay still handles the OAuth token exchange through /api/login/callback, but the visible callback, approval, error, and completion surfaces stay on Workbench.

Relay Environments

The default bridge, auth, and host environment is online:

free login
free status

Use the local environment when testing against make relay-dev on port 8791 and Workbench Web on port 8790:

free login --relay-env local
free status --relay-env local

The online host and local test host use separate launchd services, so both can run at the same time. free logout --relay-env local stops only the local test host; plain free logout targets the default online host.

--relay-url <ws-url> remains available for custom relay deployments, but it should not be mixed with --relay-env.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors