Symposium Agent Extension Packaging

This guide covers how to set up automated builds and releases for Symposium agent extensions.

What This Workflow Does

The package-agent-extension workflow:

  1. Builds cross-platform binaries - macOS (ARM + x64), Linux (ARM + x64), Windows (x64)
  2. Packages release artifacts - tar.gz for Unix, zip for Windows
  3. Generates extension.json - manifest for the ACP registry with binary name, args, and env vars

For AI Agents

If you're an AI agent setting up an extension, use the agent guide directly:

https://raw.githubusercontent.com/symposium-dev/package-agent-extension/main/AGENT-GUIDE.md

Fetch this URL and follow the instructions to set up automated builds and releases.

Quick Start

Get automated builds and releases working in 5 minutes.

1. Add the Release Workflow

Create .github/workflows/release.yml:

name: Release

on:
  release:
    types: [published]

jobs:
  build:
    permissions:
      contents: write
    uses: symposium-dev/package-agent-extension/.github/workflows/build.yml@v1
    with:
      musl: true
    secrets: inherit

2. Configure Your Cargo.toml

Add symposium metadata to specify how your extension should be spawned:

[package.metadata.symposium]
args = ["--acp"]  # Arguments passed when spawning

See Cargo Metadata for all options.

3. Create a Release

Create a GitHub release (manually or via release-plz) and the workflow will:

  • Build binaries for all 5 platform targets
  • Upload them to the release
  • Generate and upload extension.json

Next Steps

Cargo Metadata

Configure your extension's runtime behavior via [package.metadata.symposium] in Cargo.toml.

All Options

[package]
name = "my-extension"
version = "0.1.0"
description = "An agent extension for X"

[package.metadata.symposium]
binary = "my-ext"              # Binary name (defaults to package name)
args = ["--acp", "--verbose"]  # Arguments passed when spawning
env = { API_KEY = "default" }  # Environment variables

Fields

binary

The name of the binary to build and run. Defaults to the package name.

Use this if your binary name differs from your package name:

[package]
name = "symposium-ferris"

[package.metadata.symposium]
binary = "ferris"  # Build and run "ferris" instead of "symposium-ferris"

args

Arguments passed to the binary when spawned by Symposium:

[package.metadata.symposium]
args = ["--acp", "--verbose"]

env

Environment variables set when spawning:

[package.metadata.symposium]
env = { LOG_LEVEL = "info", FEATURE_FLAG = "enabled" }

For secrets, use extra_env in the workflow instead—see Workflow Inputs.

No Metadata Required

All fields are optional. If you don't specify [package.metadata.symposium], the workflow uses sensible defaults:

  • binary → package name
  • args → empty array
  • env → empty object

Automated Releases with release-plz

release-plz automates version bumping and release creation based on conventional commits. This is the recommended way to manage releases.

How It Works

  1. Push commits to main using conventional commit messages
  2. release-plz creates a PR with version bumps and changelog updates
  3. Merge the PR to trigger a release
  4. release-plz creates a GitHub release
  5. The release triggers the build workflow, which compiles and uploads binaries

Setup

Install release-plz

cargo install release-plz

Initialize

Run this in your repository:

release-plz init

This command:

  • Creates .github/workflows/release-plz.yml
  • Sets up necessary GitHub repository secrets
  • Configures the release workflow

Conventional Commits

release-plz uses conventional commits to determine version bumps:

Commit prefixVersion bumpExample
fix:Patch (0.1.0 → 0.1.1)fix: handle empty input
feat:Minor (0.1.0 → 0.2.0)feat: add new command
feat!: or BREAKING CHANGE:Major (0.1.0 → 1.0.0)feat!: change API

Other prefixes like docs:, chore:, refactor: don't trigger version bumps but are included in the changelog.

Complete Example

With both workflows set up, your release process is:

  1. Make changes with conventional commits:

    git commit -m "feat: add caching support"
    git push origin main
    
  2. release-plz opens a PR bumping version to 0.2.0

  3. Merge the PR

  4. release-plz creates a GitHub release "v0.2.0"

  5. The release triggers the build workflow

  6. Binaries and extension.json are uploaded to the release

Workflow Inputs

The package-agent-extension workflow accepts these inputs:

All Inputs

InputRequiredDefaultDescription
manifestNo./Cargo.tomlPath to Cargo.toml
muslYes-Use musl for Linux builds (static linking)
extra_argsNo[]Additional args to append (JSON array)
extra_envNo{}Additional env vars to merge (JSON object)

manifest

Path to the Cargo.toml file. Use this for workspaces or non-standard layouts:

with:
  manifest: ./crates/my-extension/Cargo.toml
  musl: true

musl

Required. Controls whether Linux builds use musl (static linking) or glibc (dynamic linking).

Recommended: musl: true for maximum portability—binaries work on any Linux system.

Use musl: false only if you need glibc-specific features.

extra_args

Additional arguments appended to the args array from Cargo.toml. Passed as a JSON array string:

with:
  musl: true
  extra_args: '["--feature", "extra"]'

If Cargo.toml has args = ["--acp"] and you pass extra_args: '["--verbose"]', the final args are ["--acp", "--verbose"].

extra_env

Additional environment variables merged with the env object from Cargo.toml. Passed as a JSON object string:

with:
  musl: true
  extra_env: '{"API_KEY": "${{ secrets.API_KEY }}"}'

This is the recommended way to inject secrets—they stay in CI and never appear in Cargo.toml.

If both Cargo.toml and extra_env define the same variable, extra_env wins.

Complete Example

jobs:
  build:
    permissions:
      contents: write
    uses: symposium-dev/package-agent-extension/.github/workflows/build.yml@v1
    with:
      manifest: ./Cargo.toml
      musl: true
      extra_args: '["--verbose"]'
      extra_env: '{"API_KEY": "${{ secrets.API_KEY }}", "DEBUG": "true"}'
    secrets: inherit

Build Targets

The workflow builds for 5 platform targets using native GitHub Actions runners.

Platforms

PlatformTargetRunnerStatic
macOS ARMaarch64-apple-darwinmacos-14No
macOS x64x86_64-apple-darwinmacos-13No
Linux ARMaarch64-unknown-linux-muslubuntu-24.04-armYes
Linux x64x86_64-unknown-linux-muslubuntu-latestYes
Windows x64x86_64-pc-windows-msvcwindows-latestNo

When musl: false, Linux targets use -gnu instead of -musl.

Native ARM Builds

Both macOS and Linux ARM builds use native ARM runners:

  • macOS ARM: macos-14 (Apple Silicon)
  • Linux ARM: ubuntu-24.04-arm (AWS Graviton)

This means no cross-compilation or emulation—builds are fast and reliable.

Static vs Dynamic Linking

Linux with musl produces fully static binaries that work on any Linux system without runtime dependencies.

macOS and Windows use dynamic linking to system libraries, which is standard for those platforms.

Release Artifacts

Each release includes:

FilePlatform
{binary}-macos-aarch64-v{version}.tar.gzmacOS ARM
{binary}-macos-x86_64-v{version}.tar.gzmacOS x64
{binary}-linux-aarch64-v{version}.tar.gzLinux ARM
{binary}-linux-x86_64-v{version}.tar.gzLinux x64
{binary}-windows-x86_64-v{version}.zipWindows x64
extension.jsonManifest for ACP registry

Agent Guide

This page is for AI agents setting up Symposium extensions.

Copy this URL and give it to an AI agent:

https://raw.githubusercontent.com/symposium-dev/package-agent-extension/main/AGENT-GUIDE.md

The agent can fetch this URL and follow the step-by-step instructions to set up:

  1. Cargo.toml metadata
  2. Release workflow
  3. Automated releases with release-plz

View the Guide

The full agent guide is available at: