# AGENTS.md ## Project overview Cloudflare Agents SDK — a framework for building stateful AI agents on Cloudflare Workers. This is a monorepo containing the core SDK packages, examples, guides, sites, and documentation. ## Repository structure ``` packages/ # Published npm packages (need changesets for changes) agents/ # Core SDK (see packages/agents/AGENTS.md) ai-chat/ # @cloudflare/ai-chat — higher-level AI chat agent hono-agents/ # Hono framework integration codemode/ # @cloudflare/codemode — experimental code generation examples/ # Self-contained demo apps (see examples/AGENTS.md) playground/ # Main showcase app — all SDK features in one UI (uses Kumo design system) mcp/ # MCP server example mcp-client/ # MCP client example ... # ~20 examples total experimental/ # Work-in-progress experiments (not published, no stability guarantees) site/ # Deployed websites agents/ # agents.cloudflare.com (Astro) ai-playground/ # Workers AI playground (React + Vite) guides/ # In-depth pattern tutorials with narrative READMEs (see guides/AGENTS.md) anthropic-patterns/ human-in-the-loop/ openai-sdk/ # Examples using @openai/agents SDK basic/ chess-app/ handoffs/ human-in-the-loop/ ... docs/ # Markdown docs for developers.cloudflare.com (see docs/AGENTS.md) design/ # Architecture and design decision records (see design/AGENTS.md) scripts/ # Repo-wide tooling (typecheck, export checks, update checks) ``` ## Nested AGENTS.md files Some directories have their own AGENTS.md with deeper guidance: | File | Scope | | --------------------------- | ------------------------------------------------------------------------- | | `packages/agents/AGENTS.md` | Core SDK internals — exports, source layout, build, testing, architecture | | `examples/AGENTS.md` | Example conventions — required structure, consistency rules, known issues | | `guides/AGENTS.md` | Guide conventions — how guides differ from examples, README expectations | | `docs/AGENTS.md` | Writing user-facing docs — Diátaxis framework, upstream sync, style | | `design/AGENTS.md` | Design records and RFCs — format, workflow, relationship to docs | ## Setup ```bash npm install # installs all workspaces; postinstall runs patch-package + playwright ``` Node 24+ required. Uses npm workspaces with [Nx](https://nx.dev) for task orchestration, caching, and affected detection. ## Commands Run from the repo root: | Command | What it does | | ---------------------------- | ------------------------------------------------------------------ | | `npm run build` | Builds all packages via Nx (cached, dependency-ordered) | | `npm run check` | Full CI check: sherif + export checks + oxfmt + oxlint + typecheck | | `npm run test` | Runs all tests via Nx (cached) | | `npm run test:react` | Runs Playwright-based React hook tests for agents | | `npm run typecheck` | TypeScript type checking across the repo (custom script) | | `npm run format` | Oxfmt format all files | | `npm run check:exports` | Verifies package.json exports match actual build output | | `npx nx affected -t build` | Build only packages affected by current changes | | `npx nx affected -t test` | Test only packages affected by current changes | | `npx nx run :build` | Build a single project (and its dependencies) | Run an example locally: ```bash cd examples/playground # or any example npm run dev # starts Vite dev server + Workers runtime via @cloudflare/vite-plugin ``` ## Code standards ### TypeScript - Strict mode enabled (`tsconfig.base.json`) - Target: ES2021, module: ES2022, moduleResolution: bundler - `verbatimModuleSyntax: true` — use explicit `import type` for type-only imports - JSX: `react-jsx` ### Linting — Oxlint Config in `.oxlintrc.json`. Plugins: `react`, `jsx-a11y`, `typescript`, `react-hooks`. Key rules: - `no-explicit-any: "error"` — never use `any`, use `unknown` and narrow - `no-unused-vars: "error"` — with `varsIgnorePattern: "^_"` and `argsIgnorePattern: "^_"` - `correctness` category set to `"error"` — catches common mistakes - `jsx-a11y` rules enabled — accessibility violations are errors - `react-hooks/exhaustive-deps: "warn"` — warns on missing hook dependencies Oxlint does **not** handle formatting — Oxfmt does. ### Formatting — Oxfmt - Run `npm run format` or rely on lint-staged (auto-formats on commit via husky) - Config in `.oxfmtrc.json` (`trailingComma: "none"`, `printWidth: 80`) ### Workers conventions - Always TypeScript, always ES modules - `wrangler.jsonc` (not `.toml`) for configuration - All wrangler configs use `compatibility_date: "2026-01-28"` and `compatibility_flags: ["nodejs_compat"]` - Never hardcode secrets — use `wrangler secret put` or `.dev.vars` - No native/FFI dependencies (must run in Workers runtime) ## Testing Tests use **vitest** with `@cloudflare/vitest-pool-workers` for running inside the Workers runtime. ```bash npm run test # agents + ai-chat unit/integration tests npm run test:react # Playwright-based React hook tests (agents package) ``` Test locations: - `packages/agents/src/tests/` — core SDK tests - `packages/agents/src/react-tests/` — React hook tests (Playwright + vitest-browser-react) - `packages/ai-chat/src/tests/` — AI chat tests - `packages/agents/src/tests-d/` — type-level tests (`.test-d.ts`) Each test directory has its own `vitest.config.ts` and (for Workers tests) a `wrangler.jsonc`. ## Contributing ### Changesets Changes to `packages/` that affect the public API or fix bugs need a changeset: ```bash npx changeset # interactive prompt — pick packages, semver bump, description ``` This creates a markdown file in `.changeset/` that gets consumed during release. Examples, guides, and sites don't need changesets. ### Pull request process CI runs on every PR (`npm ci && npm run build && npm run check && npm run test`). All checks must pass. The workflow is in `.github/workflows/pullrequest.yml`. ### Generated files - `env.d.ts` files are generated by `wrangler types` — regenerate with `npx wrangler types` inside the relevant example/package, don't hand-edit - `package-lock.json` — regenerated by `npm install`, don't hand-edit ## Learned Workspace Facts - `packages/shell/` is published as `@cloudflare/shell` — an experimental sandboxed JS execution and filesystem runtime for agents, built on the same dynamic Worker loader machinery as `@cloudflare/codemode`. - To run code against a `Workspace`: import `stateTools` from `@cloudflare/shell/workers` and `DynamicWorkerExecutor`/`resolveProvider` from `@cloudflare/codemode`; use `executor.execute(code, [resolveProvider(stateTools(workspace))])`. ## Learned User Preferences - Keep `Workspace` as a pure durable filesystem — do not embed execution or session logic inside it. Execution is a caller concern wired via `@cloudflare/codemode` + `stateTools`. - When a package boundary feels wrong (e.g., a helper package depending on a larger package just for an adapter), prefer moving the adapter out rather than carrying the dependency. ## Boundaries **Always:** - Run `npm run check` before considering work done - Use `import type` for type-only imports (enforced by `verbatimModuleSyntax`) - Keep examples simple and self-contained — they're user-facing learning material - Use Cloudflare Workers APIs (KV, D1, R2, Durable Objects, etc.) over third-party equivalents - Use Workers AI for LLM calls in examples — not third-party APIs like OpenAI or Anthropic **Ask first:** - Adding new dependencies to `packages/` (these ship to users) - Changing `wrangler.jsonc` compatibility dates across the repo - Modifying CI workflows **Never:** - Hardcode secrets or API keys - Add native/FFI/C-binding dependencies - Use `any` — Oxlint will reject it - Use CommonJS or Service Worker format — ES modules only - Modify `node_modules/` or `dist/` directories - Force push to main