Agent Versioning and Publishing in Codebuff: A Complete Technical Guide
Agent versioning and publishing in Codebuff is fully automated through the CLI publish command, which increments semantic versions automatically and uploads agent definitions to the registry via the /api/v1/agents/publish endpoint.
Codebuff provides a streamlined workflow for agent versioning and publishing that treats agents as version-controlled components living in the .agents directory. This article examines the complete technical process—from the AgentDefinition schema to the server-side validation logic that governs how agents are published and versioned in the Codebuff ecosystem.
Understanding the Agent Versioning Model
The AgentDefinition Interface
Every agent in Codebuff is defined by the AgentDefinition interface located in agents/types/agent-definition.ts. This TypeScript declaration establishes the contract for agent metadata, including the optional version field.
The interface defines version as an optional string. When omitted, Codebuff assumes a default value of 0.0.1. This design choice allows developers to publish agents without manually managing version numbers, as the framework handles automatic incrementing during the publish lifecycle.
Automatic Version Incrementing
The logic responsible for calculating the next version number resides in cli/scripts/release.ts. When a publish operation succeeds, this script implements a patch-level bump (incrementing the third digit in semantic versioning format). This ensures that each subsequent publish operation produces a monotonically increasing version string (e.g., 0.0.1 → 0.0.2 → 0.0.3) without requiring manual edits to the source definition.
The Publishing Pipeline
CLI Command Execution and Local Processing
The entry point for publishing is implemented in cli/src/commands/publish.ts through the handlePublish function. When a developer executes codebuff publish <agent-id>, the CLI performs several preparatory steps before contacting the server:
- Load Definitions: The command invokes
loadAgentDefinitionsto scan the.agentsdirectory and parse all TypeScript definition files. - Match Agents: It identifies the target agents by matching against either the
idfield or thedisplayNameproperty. - Template Processing: For agents utilizing generator-based steps, the CLI converts
handleStepsfunctions into serialized strings suitable for transmission. - Dependency Collection: The system gathers a complete list of all local agent IDs to support server-side validation of
spawnableAgentsreferences.
After processing, the CLI constructs the payload and transmits it via apiClient.publish.
API Request Schema and Server Validation
The network contract between CLI and backend is strictly defined in common/types/api/agents/publish.ts. The request body sent to POST /api/v1/agents/publish contains two critical components:
- An array of raw agent definitions (the complete agent objects after template processing)
- A comprehensive list of local agent IDs used for dependency resolution
On the server side, the route handler in web/src/api/agents/publish/route.ts executes the validation and storage logic. This endpoint verifies that the publisher field exists and that the authenticated user has appropriate access rights. It then resolves any local dependencies referenced in spawnableAgents and, upon successful validation, assigns the new version number by incrementing the previously stored version for that specific publisher and agent ID combination.
The server response includes the publisherId and an array of published agent metadata ({ id, version, displayName }), which the CLI formats into a human-readable success message.
Practical Implementation Examples
Defining an Agent with Optional Versioning
// agents/definitions/my-agent.ts
import { AgentDefinition } from '../../agents/types/agent-definition';
export const definition: AgentDefinition = {
id: 'quick-summarizer',
displayName: 'Quick Summarizer',
publisher: 'my-organization', // Required for publishing
model: 'anthropic/claude-opus-4.6',
instructionsPrompt: 'Summarize the user\'s text in ≤ 2 sentences.',
// version field omitted - will default to 0.0.1 and auto-increment
};
Publishing via CLI Command
# Publish a single agent
$ codebuff publish quick-summarizer
✅ Published: my-organization/quick-summarizer@0.0.2
# Publish multiple agents simultaneously
$ codebuff publish agent-one agent-two agent-three
✅ Published 3 agents under publisher: my-organization
Programmatic Publishing
import { handlePublish } from '../cli/src/commands/publish';
async function deployAgents() {
const result = await handlePublish(['quick-summarizer']);
if (result.success) {
console.log(`Publisher: ${result.publisherId}`);
result.agents?.forEach(agent => {
console.log(`✅ ${agent.id}@${agent.version} published successfully`);
});
} else {
console.error('Publish failed:', result.error);
if (result.hint) console.info('Hint:', result.hint);
}
}
Summary
- Version defaults are automatic: If omitted in
agents/types/agent-definition.ts, the version defaults to0.0.1and increments viacli/scripts/release.tson each publish. - Publisher authentication is mandatory: The
publisherfield must be present in the agent definition, and the CLI validates access rights before transmission. - Dependency resolution is server-side: The
web/src/api/agents/publish/route.tsendpoint validates allspawnableAgentsreferences against the list of local agent IDs provided in the request body. - Atomic multi-agent publishing: The
handlePublishfunction incli/src/commands/publish.tssupports publishing multiple agents in a single operation, with the API returning distinct version numbers for each. - Template serialization occurs client-side: Handlebars-style generators in
handleStepsare converted to strings before transmission tocommon/types/api/agents/publish.tsendpoints.
Frequently Asked Questions
What happens if I omit the version field in my agent definition?
Codebuff automatically assigns version 0.0.1 as specified in agents/types/agent-definition.ts. During the publish workflow, cli/scripts/release.ts calculates the next patch version, ensuring the registry receives an incremented version (e.g., 0.0.2) without requiring manual file edits.
How does Codebuff validate agent dependencies during publishing?
The CLI collects all local agent IDs and includes them in the request payload defined in common/types/api/agents/publish.ts. The server route web/src/api/agents/publish/route.ts cross-references these IDs against any agents listed in the spawnableAgents array, ensuring all dependencies are either already published or available in the current publish batch.
Can I publish multiple agents in a single command?
Yes. The handlePublish function in cli/src/commands/publish.ts accepts an array of agent identifiers. It processes each definition sequentially, bundles them into a single API request to /api/v1/agents/publish, and returns a consolidated result containing version numbers for all successfully published agents.
Where does the version bump logic execute?
The version increment logic resides in cli/scripts/release.ts. This module determines the next semantic version by reading the current registry state and calculating the appropriate patch increment before the CLI displays the final version string to the developer.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →