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.10.0.20.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:

  1. Load Definitions: The command invokes loadAgentDefinitions to scan the .agents directory and parse all TypeScript definition files.
  2. Match Agents: It identifies the target agents by matching against either the id field or the displayName property.
  3. Template Processing: For agents utilizing generator-based steps, the CLI converts handleSteps functions into serialized strings suitable for transmission.
  4. Dependency Collection: The system gathers a complete list of all local agent IDs to support server-side validation of spawnableAgents references.

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 to 0.0.1 and increments via cli/scripts/release.ts on each publish.
  • Publisher authentication is mandatory: The publisher field 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.ts endpoint validates all spawnableAgents references against the list of local agent IDs provided in the request body.
  • Atomic multi-agent publishing: The handlePublish function in cli/src/commands/publish.ts supports 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 handleSteps are converted to strings before transmission to common/types/api/agents/publish.ts endpoints.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →