Baton is a CLI for managing private agent instructions per project.
It keeps your personal specs in a private GitHub repository, clones them into ~/.baton, and exposes them inside working repositories through a .baton-specs symlink. Baton also injects a temporary reminder block into AGENTS.md so local coding agents know to read .baton-specs/README.md.
- For users:
- Node.js 18+
git- GitHub CLI (
gh) authenticated with the account that should ownbaton-specs
- For development and release builds:
Install from npm:
npm install -g baton-devThe installed command is:
batonTo work on the project itself:
bun installRun the CLI during development with:
bun run index.ts <command>Standalone binaries can also be distributed through GitHub releases.
-
Bootstrap the private specs repo:
baton sync --create
-
Register a project:
baton add my-project ~/code/my-project -
Touch a working repository:
cd ~/code/my-project baton touch
-
Edit your private specs in
.baton-specs/. -
Sync changes back to GitHub:
baton sync
Bootstraps or synchronizes the private baton-specs repository.
--createensureshttps://github.com/<gh-user>/baton-specsexists and clones it into~/.baton- commits pending changes in
~/.batonwhen needed - pulls and pushes the current branch
Registers a project inside ~/.baton.
- if a path is provided, Baton reads the repository’s
originURL - if a URL is provided, it must be an exact GitHub repository URL
- Baton creates
~/.baton/<id>/baton.jsonand~/.baton/<id>/README.md
Activates specs inside the current git repository.
- creates
.baton-specsas a symlink to~/.baton/<id> - adds
.baton-specsto.git/info/exclude - ensures
AGENTS.mdcontains exactly one Baton block - installs
pre-commitandpost-commithooks so the Baton block is not committed
If id is omitted, Baton matches the current repo by normalized origin URL.
Runs a script from the current project’s baton.json.
- resolves the project from the touched-repo mapping first
- falls back to matching the repository
originURL if the repo has not been touched - runs in the current working directory
Lists registered projects and any touched repositories known to local Baton state.
Touched repositories get this temporary block:
<!-- baton:start -->
You must read `.baton-specs/README.md`
<!-- baton:end -->Baton is intentionally strict here:
- it preserves non-Baton
AGENTS.mdcontent - it rejects malformed or duplicate Baton blocks instead of silently rewriting them
- the pre-commit hook strips the Baton block from the staged
AGENTS.mdonly - the post-commit hook restores the Baton block in the worktree
Example private specs repo:
~/.baton/
my-project/
baton.json
README.md
CODESTYLE.md
Working repository after baton touch:
repo/
.baton-specs -> ~/.baton/my-project
AGENTS.md
Run the test suite with:
bun testRun type checking with:
bunx tsc --noEmitBuild the npm CLI bundle with:
npm run buildBuild a standalone executable for the current platform with:
npm run build-executableRecommended release flow:
npm run release:checkThat runs type-checking, tests, the production build, and npm pack --dry-run.
To publish to npm manually:
npm run release:npmTo create the release commit and git tag manually:
npm run release:gitTo do both in sequence:
npm run releaseNotes:
release:gitpushes to the current checked-out branch, not a hardcoded branch name.- The npm package name is
baton-dev, while the installed binary name isbaton. npm publishrequires that thebaton-devpackage name is available or that you have permission to publish it.- GitHub Actions do not publish to npm.
- GitHub Actions only build release binaries and attach them to GitHub releases for pushed version tags.
- Baton stores canonical project specs in
~/.baton; working repositories only get symlinks. - Baton local state lives in
~/.baton/.baton-local/and is excluded from git. - For the full behavior contract, see SPEC.md.