# Contributing (/docs/community/contributing)



> This page is generated from [`CONTRIBUTING.md`](https://github.com/shashikanth-gs/a2a-wrapper/blob/main/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 [#prerequisites]

* [Node.js](https://nodejs.org/) >= 20.0.0
* npm (comes with Node.js)

## Repository Structure [#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](https://docs.npmjs.com/cli/using-npm/workspaces) and built with [Turborepo](https://turbo.build/).

## Getting Started [#getting-started]

```bash
# 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 [#development-commands]

All commands run from the repository root using Turborepo:

```bash
# 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 [#working-on-a-specific-package]

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

```bash
# 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:

```bash
cd packages/core
npm test

cd a2a-copilot
npm test

cd a2a-antigravity
npm test
```

## Creating Changesets [#creating-changesets]

This project uses [Changesets](https://github.com/changesets/changesets) for versioning and changelogs. Every PR that changes package behavior should include a changeset.

```bash
# 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 [#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 [#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-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:
   ```bash
   npx turbo run build test typecheck
   ```

6. Create a changeset for the initial release:
   ```bash
   npx changeset
   ```

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

## Pull Request Process [#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:
   ```bash
   npx turbo run build typecheck test
   ```
4. Create a changeset if your change affects published packages:
   ```bash
   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 [#code-of-conduct]

This project follows the [Contributor Covenant Code of Conduct](https://github.com/shashikanth-gs/a2a-wrapper/blob/main/CODE_OF_CONDUCT.md). Please read it before participating.
