Skip to main content

Agent Projects

An agent that matters deserves the same treatment as code: version control, code review, tests, and a deploy step. An agent project is a git repository where agent specs live as JSON files, and a docana.manifest.json tells the CLI which file maps to which agent in Docana.

Start from the Template

The fastest way in is the template repository — it has the layout, a working example agent, an eval, and CI already wired:

github.com/DocanaAI/docana-agent-template — click "Use this template", clone, run docana login, set your application ID, and docana push -y.

The template also ships an AGENTS.md for AI coding assistants (Claude Code, Cursor, ...), so they follow the validate → diff → push workflow and the agent design rules from docana help ai instead of guessing.

A typical project looks like:

my-project/
├── docana.manifest.json # Maps files to agents in Docana
├── agents/
│ └── main.agent.json # Agent specs (export payloads)
├── routines/
│ └── daily-report.json # Scheduled routines, if you use them
└── evals/
└── eval-*.json # Test cases, synced with the agent

The Manifest

One docana.manifest.json per project. It names your entities, points each at a source file, and records which remote agent each file tracks:

{
"apiVersion": "docana/v1",
"project": {
"name": "my-project",
"applicationId": 42
},
"defaults": { "target": "main" },
"targets": {
"main": { "entities": ["agent:main", "routine:daily-report"] }
},
"entities": {
"agent:main": {
"type": "agent",
"source": "agents/main.agent.json",
"remoteId": "cmly7kpth0019x5c9dyn3hegk",
"agent": {
"pullEvalDir": "evals",
"pushEvalFiles": ["evals/*.json"]
}
},
"routine:daily-report": {
"type": "routine",
"source": "routines/daily-report.json",
"remoteId": "cmohsze35003m21c9mu1jxfwc",
"routine": { "agentRef": "agent:main" }
}
}
}

Field by field:

FieldWhat it does
apiVersionAlways docana/v1.
project.nameA label for the project.
project.applicationIdDefault application for every entity. Override per entity with applicationId, or per command with --app-id.
defaults.targetWhich target plain docana push / pull / validate operate on.
targetsNamed groups of entity keys, so one command deploys a coherent set.
entitiesThe map of everything the project manages. Keys are yours to choose; agent:name and routine:name is the convention.

And per entity:

FieldWhat it does
typeagent or routine.
sourcePath to the JSON file, relative to the manifest.
remoteIdThe entity's ID in Docana. Set it after the first push — it's what lets docana pull and docana agents diff find the deployed version.
applicationIdOverrides project.applicationId for this entity.
agent.pushEvalFilesGlob patterns of eval files to bundle into the agent's test registry on push.
agent.pullEvalDirDirectory where docana pull writes the registry's evals, one file each.
agent.pullEvalFormatspec (default, just the eval spec) or full (name, description, and enabled flag too).
routine.agentRefEntity key of the agent the routine runs on, e.g. "agent:main".

Push, Pull, Validate

The generic commands read the manifest and accept a selector — an entity key, a target name, or a wildcard:

docana push -y # default target
docana push agent:main -y # one entity
docana push --target main -y # a named target
docana push "agent:*" -y # every agent
docana pull # write deployed state back to your files
docana validate # schema-check every source file

docana push updates the agent's working version; users keep talking to the live version until you promote it. Add --publish to do both in one step, once evals pass:

docana push -y --publish

Evals Live in the Repo

With pushEvalFiles set, every push replaces the agent's test registry with the eval files in git — so a pull request that changes a prompt can (and should) also change the tests, and reviewers see both together. pullEvalDir completes the round trip: evals someone added in the UI come back to disk on docana pull.

Each eval file is one scenario:

{
"name": "Stays concise",
"enabled": true,
"evalSpec": {
"steps": [
{ "type": "user", "text": "What are your support hours?" },
{
"type": "smartAssertion",
"expectedOutput": "A short answer that offers further help.",
"evaluationCriteria": "Concise, no fabricated facts.",
"minScore": 7
}
]
}
}

See Testing Agents for what goes into a good test case.

Dev and Production

Don't test against the application your users are on. Two patterns that work well together:

  • Separate applications — iterate against a dev application, and only push to the production one when evals pass.
  • Side-by-side manifests — one manifest per environment, same source files, different applicationId and remoteIds:
docana push -y # dev (docana.manifest.json)
docana push -y --manifest docana.manifest.prod.json # production

CI

Because everything is files plus a CLI, CI is ordinary: validate on every pull request, eval before merge. The template ships a GitHub Actions workflow that does the first part — set DOCANA_API_URL and DOCANA_API_KEY as repository secrets and it runs docana validate "*" on each PR.

Next Steps

  • CLI — everything else the docana command does
  • Testing Agents — the eval concepts behind the test registry
  • Routines — the scheduled runs a routine entity manages
  • Docana MCP — edit these same files with an AI coding assistant that knows your workspace