cadenya.yaml for settings, and a .cadenya/ directory with one file per resource. The CLI compares those files with your workspace, then creates, updates, and deletes until the two match.
So the setup goes through code review like everything else. No more “who changed the prompt?”
Settings
cadenya.yaml sits at the root of your repository:
cadenya.yaml
The file takes those four keys and nothing else (validation rejects a fifth, typo or not). Flags and environment variables beat the file:
--workspace-id or CADENYA_WORKSPACE_ID, --base-url or CADENYA_BASE_URL, and --resource-dir. So CADENYA_WORKSPACE_ID points the same files at another workspace. With no workspace set anywhere, the CLI falls back to its stored default.
Keep the API key out of cadenya.yaml. The CLI reads it from CADENYA_API_KEY.
Resource files
Each resource gets one YAML file, in the directory for its type:metadata and spec the API takes, written as YAML. Here’s a variation that picks its model and gets a Tool Set:
.cadenya/agents/petstore-agent/default.yaml
- A file’s external ID comes from
externalId, thenmetadata.externalId, then the filename. Renaming a file without an explicit external ID changes its identity, so the plan shows a delete and a create. - A child directory takes its parent’s filename: the variations of
agents/petstore-agent.yamllive inagents/petstore-agent/. - Resources in the same bundle refer to each other by external ID, such as
external_id:petstorefor a Tool Set orexternal_id:frontend/fetch-form-statefor one of its tools. - An Agent file takes
state: publishedorstate: draft. A published Agent needs at least one variation in the bundle. - A missing type directory means you want none of that type. Remove
agents/, and apply deletes every Agent in the bundle.
Trusted endpoints
Config files don’t touch trusted endpoints. Cadenya sends Tool Set requests only to hosts your account trusts, and that list lives on the account, not in your repository. So trust each host your Tool Sets call before you apply:api.stripe.com, with an optional port) or a wildcard for exactly one label: *.example.com covers api.example.com but not example.com itself. One entry covers every workspace. Every account also trusts free.cadenya.com, the server behind Cadenya’s onboarding examples.
To check a URL before you apply:
RESULT_TRUSTED once the host is on the list.
Validate, plan, and apply
Three commands take the files from your repository to your workspace:-C path/to/repo. A plan for the Petstore example looks like this (log lines trimmed):
update. That’s expected. It isn’t drift.
If a request fails, apply stops and reports what finished. Fix the cause and run it again: each run plans from what’s in your workspace now.
Bundle keys
Every resource apply writes gets the labelbundle_key=<your bundle key>. Plan and apply list everything with that label and compare it with .cadenya/.
Anything that carries your bundle key and has no file gets deleted on the next apply. That’s how you delete a resource: remove its file and apply. It’s also why two repositories can’t share a key. Each one would delete the other’s resources, one apply at a time.
The label also keeps apply away from everything else in your workspace:
- Apply never adopts a resource without your label. If an external ID you’re about to create already exists outside the bundle, the plan fails and names it.
- Apply never deletes a resource that something outside the bundle still uses, such as a Tool Set that another variation assigns. The plan names the resource in the way.
- An empty
.cadenya/means “delete the whole bundle”, so apply refuses it unless you pass--allow-empty.
Apply from GitHub Actions
The cadenya-config-loader Action downloads a pinned CLI release (itsversion input picks which), checks the checksum, and runs the same commands. This workflow plans on every pull request and applies on every push to main:
.github/workflows/cadenya.yaml
cadenya.yaml, so the workflow doesn’t repeat them. Inputs such as workspace-id and bundle-key override the file, and allow-empty: 'true' is the Action’s --allow-empty. On a pull request, the plan job prints the operations in its log, so you see every delete before it happens.
Starting a new project from a coding agent? Set up Cadenya from a coding agent puts these files and the API key together.