| contract | All work on agent-os — the Cloudflare-native 'tiny OS for an agent' side project Ronit is building between Apr 25, 2026 and his Wordware start date (May 27, 2026). Scope: architecture, RPC/Loader experiments, Ink TUI work, BYO-CF deploy flow, Pipedream Connect integration, repo state, and any blog/Twitter artifacts (vhs recordings). Scope ends when Ronit is onboarded at Wordware or explicitly shelves the project. |
|---|---|
| short_description | Cloudflare-native agent-OS, BYO-CF, Pipedream-brokered credentials, TUI-first |
A tiny operating system for an agent. Cloudflare-native, terminal-driven, deploys itself into the user's own CF account. No central server, no SaaS swamp — each install is its own tenant on its own substrate.
Kernel = Durable Object (per-user supervisor, SQLite-backed)
Sandbox = two tiers (Worker Loader isolates + containerized Linux)
FS = R2 bucket, FUSE-mounted into sandbox
Creds = Pipedream Connect (per-call token mint, sandbox never sees a token)
Client = Ink TUI installed from npm
The agent's primary action is writing and running code, not calling primitive tools. The kernel — not Anthropic, not me — owns your durable state. A handful of direct tools (read_file, write_file, web_search, process_attachment, etc.) are the model's hands; the bulk of agent work happens inside exec_code (Worker Loader JS) and computer_bash / computer_use (containerized Linux with full POSIX, network, persistent FS).
Status: side project, alpha. Hard deadline May 27, 2026 (Wordware start). Deployed and usable from a single TUI client; no public auth/signup flow.
┌────────────────────────┐ WSS ┌──────────────────────────────────┐
│ Ink TUI (Node, npm) │ ◀────────────▶ │ Kernel Worker + Kernel DO │
│ hibernatable WS │ │ ─ AIChatAgent (Vercel AI SDK) │
│ HIL approval rail │ │ ─ SQLite (threads, runs, tool │
│ conflict resolver │ │ calls, sandbox audit) │
│ attach / sites / cmds │ │ ─ R2 binding (HOME) │
└────────────────────────┘ └─────────────┬────────────────────┘
│
┌─────────────┼─────────────────────┐
▼ ▼ ▼
Worker Loader @cloudflare/sandbox Browser binding
(exec_code) (computer_bash, (puppeteer-via-
computer_use, BrowserBridge)
computer_expose_port)
│
R2 mounted at /r2/<prefix>
via s3fs FUSE
Two sandbox tiers, picked by tool:
exec_code→ Worker Loader. Cheap, fast cold start, pure JS, network viaenv.PROXY(Pipedream-credentialed). Default for data munging, single-shot API calls, file transforms.computer_bash/computer_use→ containerized Linux via@cloudflare/sandbox. Heavier cold start; full bash, Python, package install, GUI via Xvfb, port exposure. Default when the work needs unix tools or a long-running process.
One FS, two views:
- Kernel-side tools (
read_fileetc.) read/write R2 directly via theHOMEbinding. - Sandbox-side bash sees the same bytes at
/r2/<prefix>via s3fs FUSE mounts. Reads stream from R2; writes propagate back.
Credentials never reach the sandbox. Outbound HTTP from sandboxed code goes through Pipedream Connect: agent calls env.PROXY.fetch("https://api.linear.app/...", { headers: { "x-pd-account-id": "apn_..." }}), the kernel-side proxy mints a per-call token and routes through Pipedream's OAuth proxy. Sandbox sees an account id, never an OAuth token.
Sites and previews on a custom domain. Anything under r2://sites/<slug>/ serves publicly at https://<your-host>/sites/<slug>/. The computer_expose_port tool publishes a sandbox port at <port>-<sandboxName>-<token>.<your-host> via a wildcard route — both rely on a domain you own being on Cloudflare. See apps/kernel/README.md for the wildcard SSL one-level-only constraint.
| Tool | Purpose |
|---|---|
read_file / write_file / list_files / find_files / delete_file / move_file |
R2 file ops, scoped to known prefixes |
get_signed_url |
Short-lived presigned R2 URL for sharing |
exec_code |
Run JS in a Worker Loader sandbox; streams logs |
computer_bash |
Run a bash command in the container sandbox |
computer_use |
Drive a desktop session (Xvfb + screenshot + click/type) |
computer_expose_port |
Publish a sandbox port as a public URL |
computer_destroy |
Tear down a named sandbox container |
web_search |
Parallel API search |
web_fetch |
URL → markdown (Firecrawl) |
process_attachment |
PDF/image → structured markdown via Claude Sonnet 4.6 |
The TUI surfaces an HIL approval rail for tools tagged needsApproval: true and a conflict resolver for merge conflicts during file-system writes (see feat/fs-versioning). Otherwise interaction is chat-first, Claude-Code-shaped: the model decides when to write code; the user never invokes tools by name.
apps/
kernel/ Cloudflare Worker — DO, sandbox DO, FS, tools, proxy, HTTP routes
cli/ Ink TUI — published as `agent-os` on npm
packages/
protocol/ Wire types shared between kernel and TUI
models/ Drizzle schemas + migrations for the kernel DO's SQLite
apps/kernel/README.md covers deploy + secrets + sandbox preview URLs + agent conventions in operational detail.
The project is BYO-Cloudflare: there's no central agent-os service. You deploy the kernel into your own CF account and the TUI talks to it.
# 1. Clone + install
git clone git@github.com:rtpa25/agent-os.git
cd agent-os
pnpm install
# 2. Deploy the kernel into your own CF account.
# Follow apps/kernel/README.md — wrangler login, create R2 bucket,
# set secrets (Anthropic key, Pipedream, R2 token, Firecrawl, Parallel),
# optionally wire a wildcard for sandbox preview URLs.
cd apps/kernel
pnpm run deploy
# 3. Run the TUI against your deployed kernel.
cd ../cli
pnpm dev # or: pnpm build && node dist/cli.jsThere's no public agent-os init flow yet (the BYO-CF wizard from the original spec). For now: hand-roll the kernel deploy following the kernel README, then point the TUI at your worker URL.
pnpm install # install everything
pnpm check-types # typecheck the whole monorepo
pnpm lint # oxlint
pnpm fmt # oxfmt
# Kernel
cd apps/kernel
pnpm run deploy # production deploy via wrangler
pnpm wrangler tail # stream prod logs
# CLI
cd apps/cli
pnpm dev # tsx watch against the published kerneltsx watch doesn't work for the CLI (Ink's stdin handling restarts on every keystroke); the dev script uses plain tsx.
Lint/format is oxlint + oxfmt. Not Prettier/ESLint.
Cloudflare Workers · Durable Objects (SQLite-backed) · Worker Loader · @cloudflare/sandbox (containerized Linux) · R2 · Hibernatable WebSockets · Vercel AI SDK + @ai-sdk/anthropic · isomorphic-git · zod · Ink + commander + ws · Drizzle ORM · esbuild · pnpm + Turborepo · oxlint + oxfmt.
External services: Anthropic via AI Gateway · Pipedream Connect · Parallel API · Firecrawl.
OSS — license terms TBD before public release. Not yet on npm; not yet publicly announced.
Substrate patterns (Worker Loader hosting, RpcTarget capability boundaries, per-call credential injection) draw on Cloudflare's own self-syncing-agent reference implementation.