Skip to main content
Your Cadenya setup can live in your repository as YAML: a 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:
A file holds the same 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 few rules shape every bundle:
  1. A file’s external ID comes from externalId, then metadata.externalId, then the filename. Renaming a file without an explicit external ID changes its identity, so the plan shows a delete and a create.
  2. A child directory takes its parent’s filename: the variations of agents/petstore-agent.yaml live in agents/petstore-agent/.
  3. Resources in the same bundle refer to each other by external ID, such as external_id:petstore for a Tool Set or external_id:frontend/fetch-form-state for one of its tools.
  4. An Agent file takes state: published or state: draft. A published Agent needs at least one variation in the bundle.
  5. A missing type directory means you want none of that type. Remove agents/, and apply deletes every Agent in the bundle.
The CLI’s bundle guide lists every field for Tool Sets, tools, memory layers, memory entries, Agents, variations, and Widgets.

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:
A host can be exact (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:
The result is RESULT_TRUSTED once the host is on the list.

Validate, plan, and apply

Three commands take the files from your repository to your workspace:
Run them from the repository root, or point them at it with -C path/to/repo. A plan for the Petstore example looks like this (log lines trimmed):
Every resource in the bundle gets an update on every apply, so a plan right after an apply lists each one as 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 label bundle_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:
  1. 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.
  2. 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.
  3. An empty .cadenya/ means “delete the whole bundle”, so apply refuses it unless you pass --allow-empty.
Changing the bundle key starts a new, empty bundle. The resources you applied before keep the old label, and the new key leaves them alone.
Give each repository its own bundle key, and read every delete line in the plan before you apply.

Apply from GitHub Actions

The cadenya-config-loader Action downloads a pinned CLI release (its version 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
The workspace and the bundle key come from 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.