a2a-wrapper logoa2a-wrapper
Community

Contributing

How to set up the monorepo, run tests, create changesets, add a new wrapper, and open a pull request.

This page is generated from CONTRIBUTING.md and stays in sync with the repository.

Thanks for your interest in contributing! This is a monorepo containing multiple packages — this guide covers how to work across all of them.

Prerequisites

  • Node.js >= 20.0.0
  • npm (comes with Node.js)

Repository Structure

a2a-wrapper/
├── packages/
│   └── core/              # @a2a-wrapper/core — shared infrastructure
├── a2a-claude/            # a2a-claude — Claude wrapper
├── a2a-copilot/           # a2a-copilot — GitHub Copilot SDK wrapper
├── a2a-opencode/          # a2a-opencode — OpenCode wrapper
├── a2a-codex/             # a2a-codex — OpenAI Codex SDK wrapper
├── a2a-antigravity/       # a2a-antigravity — Google Antigravity SDK wrapper
├── turbo.json             # Turborepo task pipeline
├── .changeset/            # Changesets versioning config
└── package.json           # Root workspace config
  • packages/core/ — shared library (@a2a-wrapper/core): logging, config loading, event publishing, server factory, session management, CLI scaffold
  • a2a-claude/ — A2A wrapper for Claude
  • a2a-copilot/ — A2A wrapper for GitHub Copilot SDK
  • a2a-opencode/ — A2A wrapper for OpenCode
  • a2a-codex/ — A2A wrapper for OpenAI Codex SDK
  • a2a-antigravity/ — A2A wrapper for Google Antigravity SDK using a private Python subprocess

All packages are managed via npm workspaces and built with Turborepo.

Getting Started

# Clone the repository
git clone https://github.com/shashikanth-gs/a2a-wrapper.git
cd a2a-wrapper

# Install dependencies for all packages (from the repo root)
npm install

# Build all packages so @a2a-wrapper/core is compiled to dist/
# (dist/ is git-ignored and is NOT produced by `npm install`)
npx turbo run build

A single npm install at the root resolves dependencies for every package and hoists shared ones. Note that npm install does not compile anything — @a2a-wrapper/core is consumed from its built dist/ output, so run npx turbo run build before running any package or example.

Development Commands

All commands run from the repository root using Turborepo:

# Build all packages (core builds first, then wrappers in parallel)
npx turbo run build

# Run tests across all packages
npx turbo run test

# Type-check all packages
npx turbo run typecheck

# Clean build artifacts
npx turbo run clean

Turborepo caches build outputs — unchanged packages are skipped on subsequent runs.

Working on a Specific Package

You can scope Turborepo to a single package with --filter:

# Build only core
npx turbo run build --filter=@a2a-wrapper/core

# Test only a2a-copilot
npx turbo run test --filter=a2a-copilot

# Build a2a-opencode and its dependencies
npx turbo run build --filter=a2a-opencode...

# Test only a2a-antigravity
npx turbo run test --filter=a2a-antigravity

Or work directly inside a package directory:

cd packages/core
npm test

cd a2a-copilot
npm test

cd a2a-antigravity
npm test

Creating Changesets

This project uses Changesets for versioning and changelogs. Every PR that changes package behavior should include a changeset.

# Create a new changeset (interactive prompt)
npx changeset

The CLI will ask you:

  1. Which packages were affected
  2. The semver bump type (patch / minor / major)
  3. A summary of the change

This creates a markdown file in .changeset/ — commit it with your PR.

When to create a changeset

  • Bug fixes → patch
  • New features (backward-compatible) → minor
  • Breaking changes → major
  • Documentation-only or CI-only changes → no changeset needed

Release Process

Once a PR is merged to main, three things happen automatically:

  1. CI re-validates main (build, typecheck, test).
  2. Canary publish — once CI succeeds, every affected package is published to npm under the canary dist-tag with a snapshot version like 1.8.0-canary-20260812070958. Install one with npm install <package>@canary. This never touches main — the snapshot version bump happens only in the CI runner and is discarded, so pending changesets are left intact.
  3. Version Packages PR — the Changesets bot opens/updates a PR on main that batches all pending changesets into real version bumps and CHANGELOG entries.

When a maintainer merges the Version Packages PR, the release workflow checks whether a release is ready (no pending changesets and at least one package version not yet published) and, if so, waits for manual approval via the release GitHub Environment before running npx changeset publish under the latest dist-tag and creating GitHub releases.

So npm install <package> always gets the latest approved stable release, while npm install <package>@canary gets the most recent merge to main.

Both the canary and stable-release publish steps live in the single .github/workflows/publish.yml file, as separate jobs. This is required, not stylistic: npm Trusted Publishing allows exactly one trusted publisher per package, bound to one workflow filename, so every path that can call npm publish for these packages has to originate from that one file. version.yml (the Version Packages PR bot) is a separate file because it never publishes to npm.

Adding a New Wrapper

Adding a new A2A wrapper (e.g. a2a-claude) requires no changes to the root config or core package:

  1. Create a directory at the repo root following the a2a-<name> naming convention:

    a2a-claude/
    ├── package.json
    ├── tsconfig.json
    ├── src/
    │   ├── index.ts
    │   ├── cli.ts
    │   ├── server/
    │   │   └── index.ts          # Thin delegate to core's createA2AServer
    │   └── claude/
    │       ├── executor.ts       # Implements A2AExecutor
    │       ├── session-manager.ts
    │       └── config/
    │           ├── types.ts      # Extends BaseAgentConfig
    │           └── defaults.ts
    └── agents/
        └── example/
            └── config.json
  2. In package.json, set:

    • name to a2a-<name>
    • @a2a-wrapper/core as a dependency ("*")
    • publishConfig.access to "public"
    • A build, test, and typecheck script
  3. Implement the A2AExecutor interface from @a2a-wrapper/core and wire it up with createCli().

    src/server/index.ts must be a thin delegate to core's createA2AServer() — do not hand-roll Express routing, agent card building, or event publishing. All A2A protocol wiring (agent card, JSON-RPC/REST transports, v1.0/v0.3 version negotiation) lives in @a2a-wrapper/core on purpose, so every wrapper gets protocol updates for free. Follow the pattern in any existing a2a-*/src/server/index.ts — call createA2AServer(config, executorFactory, options) and use registerRoutes for wrapper-specific endpoints only.

  4. Run npm install at the repo root to link the new package.

  5. Verify everything works:

    npx turbo run build test typecheck
  6. Create a changeset for the initial release:

    npx changeset

The a2a-* workspace glob in the root package.json automatically picks up the new directory — no config edits needed.

Pull Request Process

  1. Fork the repo and create a feature branch from main.
  2. Make your changes and add tests where appropriate.
  3. Run the full build and test suite:
    npx turbo run build typecheck test
  4. Create a changeset if your change affects published packages:
    npx changeset
  5. Open a pull request against main. CI will build and test across Node.js 20 and 22.
  6. Address review feedback and ensure CI passes.

Code of Conduct

This project follows the Contributor Covenant Code of Conduct. Please read it before participating.

On this page