File
Blob: AGENTS.md
AGENTS.md
Rules To Remember
- Use Sandbox SDK as the primary abstraction. Do not add an SSH bridge, custom container control plane, or extra proxy layers when
@cloudflare/sandboxalready covers the job. - Preserve the ownership model
user/workspace -> sandboxandlogical terminal tab -> session. Do not collapse those boundaries for convenience.
Naming
- The product name is
ccccocc, always lowercase. - Product framing may say "Cloudflare Containers", but implementation choices should target Sandbox SDK and Cloudflare's native terminal WebSocket path.
Repository Status
- This repo is no longer a blank scaffold. Multi-tab workspace state, reconnect handling, shared-session detection, backup and restore, and Cloudflare Access auth already exist in the live tree.
- Frontend files are under active iteration. Expect unrelated local edits and avoid reverting them.
- Terminal behavior is platform-sensitive. Automated tests help, but reconnect, alternate-screen TUIs, and container lifecycle changes still need manual verification.
Source Of Truth
- The live source tree wins when docs drift.
docs/SPEC.mdis the product and architecture intent.README.mdis the human-facing guide. Keep repo-operating instructions here inAGENTS.md.src/shared/protocol.tsis the shared terminal control contract.src/client/workspace/store.tsandsrc/client/workspace/types.tsown the logical tab and session persistence model.src/worker/auth.tsowns auth mode selection and sandbox ownership derivation.wrangler.jsoncis the runtime binding contract.worker-configuration.d.tsanddist/are generated outputs. Regenerate them; do not hand-edit them.
Working Rules
- Keep edits scoped and minimal.
- Multiple agents may be working in parallel. Do not revert unrelated changes.
- Assume the dev server may already be running. Do not start
npm run devunless the user asks or the task clearly requires it. - Keep the repo single-package unless there is a concrete technical need to change that.
- Prefer explicit code over clever code. Small duplication is acceptable when it keeps session or auth behavior obvious.
- Preserve the split between
src/client,src/worker, andsrc/shared. If both client and worker do not need a type or helper, it probably does not belong insrc/shared. - Prefer direct use of existing
@cloudflare/sandboxAPIs. Do not add another abstraction layer unless the repo has a concrete gap. - Avoid extra control-plane infrastructure. The Sandbox class is already the Durable Object; add more coordination only when there is a clear need.
- Keep the PTY byte path simple. Do not insert avoidable middleware or transform layers between terminal I/O and
proxyTerminal. - For Cloudflare runtime or Sandbox behavior that may have changed, prefer current official Cloudflare docs over memory.
Important Invariants
- The client should identify sandboxes by
workspace, not raw sandbox IDs. The worker derivessandboxId = ${userId}-${workspace}after authentication. - One sandbox exists per user and workspace. One backend session exists per logical in-app terminal tab.
- Refresh persistence is per browser tab or window via
sessionStorage. The persisted model is the tab collection plus active tab, not a single global session ID. - Closing a UI tab detaches from the backend session by default. Do not silently delete sessions unless the UI explicitly says it will.
- Creating a new tab or choosing "New Session" must use explicit session creation semantics. Do not rely on implicit session auto-creation for intended
cwd, environment, or labels. - Sandbox sessions may be silently created with defaults when referenced. Reattaching to a session ID is not proof that the expected shell state still exists.
- Terminal WebSocket behavior is fixed: incoming binary frames are PTY output, incoming text frames are JSON control and status, outgoing binary frames are UTF-8 keystrokes, outgoing text frames are resize messages, and buffered PTY replay may arrive before
ready. ghostty-webshould be initialized once at app startup. Reconnect flows should clear terminal state before replay to avoid duplicate output.- Control-key handling is custom in the terminal adapter path to work around
ghostty-webencoder issues. Preserve that behavior when changing input handling. cwdfor created sessions must stay under/workspace.- Session env vars are sanitized server-side. Labels returned by the session API are client metadata only; the Sandbox SDK does not persist them.
- Dev auth is intentionally localhost-only when Access is not configured. Non-local hosts must reject requests until Access is configured.
- Containers are ephemeral. Without backup and restore or mounted object storage, files, processes, sessions, and shell state disappear on restart or idle eviction.
Validation
npm run typecheckfor most changes. This regeneratesworker-configuration.d.ts.npm testfor unit and worker route coverage.npm run buildwhen changing bundling, routes, runtime bindings, or container wiring.npm run types:generateafter changingwrangler.jsoncor.dev.vars.example.- Use
test/MANUAL_TEST_CHECKLIST.mdfor reconnect, multi-tab, shared-session, resize, paste, and interactive TUI regression checks. - Manual verification is still expected for alternate-screen apps, network interruption recovery, container restart detection, and Cloudflare Access flows.
Quick References
- Product overview and setup:
README.md - Product and architecture intent:
docs/SPEC.md - App shell and workspace UI:
src/client/app.tsx,src/client/components/terminal-workspace.tsx,src/client/components/tab-strip.tsx,src/client/components/session-controls.tsx - Terminal integration:
src/client/terminal/adapter.ts,src/client/terminal/socket.ts,src/client/terminal/use-shared-session-detection.ts - Global styles and theme:
src/client/styles/app.css - UI primitives:
src/client/components/ui/ - Tab and session persistence:
src/client/workspace/store.ts,src/client/workspace/types.ts - Worker routes and lifecycle APIs:
src/worker/index.ts - Auth and sandbox ownership:
src/worker/auth.ts - Shared protocol types:
src/shared/protocol.ts - Container bootstrap:
container/Dockerfile,container/container-shell.sh,container/root.zshrc - Tests and manual checklist:
test/