This is a monorepo. Agent and contributor instructions are organized in layers so the
always-loaded set stays small. This root file holds only cross-cutting rules. Area
conventions live in nested AGENTS.md files and in skills. See
How agent instructions are organized at the
bottom.
web/— frontend. The app isweb/mobile(served at/m); shared code is the@agenta/*packages inweb/packages.web/ossandweb/eeare the abandoned desktop app. Seeweb/AGENTS.mdandweb/mobile/AGENTS.md.api/— FastAPI backend (OSS + EE + entrypoints). Seeapi/AGENTS.md.hosting/— docker-compose, railway, local dev stack. Seehosting/AGENTS.md.clients/,sdks/— SDKs and client codegen.docs/— documentation (Docusaurus).examples/,services/— example apps and supporting services.
- Frontend (imports, state, data fetching, styling, React, Fern client):
web/AGENTS.md; the mobile app's own rules:web/mobile/AGENTS.md. - GitButler stacked branches (lane routing, recovery, PR bases): the
gitbutler-stacksskill. - API architecture (layering, domains, endpoints, exceptions, DTOs):
api/AGENTS.md. - Local dev stack run commands:
hosting/AGENTS.md. - Package vs app placement,
@agenta/*packages, package unit tests: theagenta-package-practicesskill. - Testing: docs/designs/testing/README.md.
- Docs writing: the Diátaxis framework digest at
.agents/docs/diataxis/, and thewrite-docsskill for Agenta style, voice, and structure.
Write responses in ASD-STE100 (Simplified Technical English). Keep every technical term the work needs: file names, symbol names, commands, error text, and the words of the domain. Simplify the language around them, not the terms themselves.
- Write short sentences. Put one idea in each sentence.
- Use the active voice. Name who or what does the action.
- Use simple words. Do not use idioms, metaphors, or slang.
- Use one word for one thing. Do not change the word to add variety.
- Write an instruction as a command.
This rule is for responses. Code, comments, commit messages and committed documents keep the conventions in their own sections.
This repo may be in GitButler workspace mode (current branch gitbutler/workspace).
If so, use the but CLI instead of raw git branch/git commit:
but statusshows lanes and unassigned changes;but branch new <name>creates a parallel lane; add--anchor <parent-branch>to stack on a parent.but commit <branch> -m "..."commits the uncommitted changes to that branch. Pre-commit hooks (ruff, prettier, gitleaks) run; if a hook reformats files the commit aborts — just rerun it. Changes belonging to another lane's commits stay unassigned rather than being folded in.but pr newneeds interactive forge auth; usebut push <branch>thengh pr create --head <branch> --base <parent-or-main>instead. For stacked PRs, set--baseto the parent branch so each PR shows only its own diff.but pushprints NOTHING on success. It is not a confirmation — always verify the push landed by comparing SHAs:git ls-remote --heads origin <branch>vsgit rev-parse <branch>. They must match.- To update an already-committed file,
but absorb <path>amends it into the right commit; force-push withbut push <branch> -f. - Recovery:
but oplog listthenbut oplog restore <sha>rewinds the whole workspace (including uncommitted changes) to any prior snapshot. Take abut oplog snapshot -m "..."before anything risky.
Sync a lane by rebasing on main, not by merging main into it — merge commits between branches collapse a GitButler series.
Stacked branches have their own rules, and they are the source of most but pain:
mis-routed hunks, dropped hunks, stale cliIds, collapsed series. Load the
gitbutler-stacks skill before doing any multi-lane work; do not improvise from these
basics.
- Frontend changes: run
pnpm lint-fixwithin thewebfolder. Details:web/AGENTS.md. - API or SDK changes: run
ruff formatthenruff check --fixwithin the SDK or API folder (from the repo root:ruff formatthenruff check). Fix all errors before committing. Details:api/AGENTS.md. - Theme color changes: edit the source of truth
web/oss/src/styles/theme/palette.ts(web/oss/src/styles/theme/is the one part ofweb/ossstill in use), then runpnpm generate:tailwind-tokensin thewebfolder and commit the regenerated files (web/packages/agenta-ui/src/styles/theme-variables.css,web/mobile/src/styles/theme.generated.css,web/oss/src/styles/theme/antd-overrides.generated.ts). Do not hand-edit the generated files.
From the repo root. load-env must match the edition and image you deploy — the env
file and the run.sh flags always agree:
-
OSS + dev →
load-env hosting/docker-compose/oss/.env.oss.dev+run.sh --oss --dev -
OSS + gh →
load-env hosting/docker-compose/oss/.env.oss.gh+run.sh --oss --gh -
EE + dev →
load-env hosting/docker-compose/ee/.env.ee.dev+run.sh --ee --dev -
EE + gh →
load-env hosting/docker-compose/ee/.env.ee.gh+run.sh --ee --gh -
load-env <env-file>— load env vars into the shell (pick the row above). -
bash ./hosting/docker-compose/run.sh <flags> --build— deploy to the local docker-compose stack (--oss/--ee,--dev/--gh;--downto stop,--nuketo drop volumes). Use the SAME edition/image as load-env. -
cd <area> && py-run-tests— run that area's tests, whereareais one ofsdks/python,api, orservices(py-run-tests=uv sync --locked && uv run --no-sync python run-tests.py). -
Postgres is reachable locally with
username:password; EE DB name isagenta_ee_core. -
Tests mint ephemeral accounts + API keys via the admin endpoint
POST /admin/simple/accounts/(withAuthorization: Access AUTH_KEY,create_api_keys/return_api_keys: true). Reuse the fixtures inapi/oss/tests/pytest/utils/accounts.py(foo_account/cls_account/mod_account→{api_url, credentials: "ApiKey ..."}); do not hand-roll account creation.
- For API configuration, add new environment variables to
api/oss/src/utils/env.pyand consume them via the sharedenvobject. Do not callos.getenv(...)directly for application config. Full detail:api/AGENTS.md.
For comprehensive testing documentation, see docs/designs/testing/README.md.
- Hosting: docs/packs/hosting.md
- Testing: docs/packs/testing.md
- If the user provides you with the issue id, title the PR:
[issue-id] fix(frontend): <Title>wherefixis the type (fix, feat, chore, ci, doc, test, using better-branch) andfrontendis the area, which could be API, SDK, frontend, docs, and so on. - For the PR body (structure, before/after, what to cut), the
write-pr-descriptionskill has the full procedure and a worked example.
This repo keeps the always-loaded instruction layer small and pushes scope-specific or procedural guidance into layers that load on demand. All three tools we use (Claude Code, Codex, Cursor) read this structure.
- Root
AGENTS.md(this file): cross-cutting facts only.CLAUDE.mdre-imports it so Claude Code reads the same content. - Nested
<dir>/AGENTS.md(web/,web/mobile/,web/website/,api/,hosting/): area conventions, loaded only when working in that directory. Each has aCLAUDE.mdsymlink so Claude loads it too. - Skills (
.agents/skills/, symlinked into.claude/skills/): procedures and heavy reference, loaded on demand. Discoverable by Codex (.agents/skills) and Claude (the symlink); theSKILL.mdformat is shared across tools. - Tool rules (
.claude/rules/,.cursor/rules/): none are checked in today. If you add one, keep it thin and path-scoped: point to the relevantAGENTS.md, do not duplicate it.
When adding a new instruction, put it at the lowest scope that fits and do not grow this
root file. Splitting a long file into @imports does not save context, so move content
down a level instead. The full model and rationale:
docs/design/agents-md-compartmentalization/playbook.md.