baton-handoff 1.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. baton_handoff-1.5.2/LICENSE +21 -0
  2. baton_handoff-1.5.2/PKG-INFO +111 -0
  3. baton_handoff-1.5.2/README.md +81 -0
  4. baton_handoff-1.5.2/pyproject.toml +50 -0
  5. baton_handoff-1.5.2/setup.cfg +4 -0
  6. baton_handoff-1.5.2/src/baton/__init__.py +3 -0
  7. baton_handoff-1.5.2/src/baton/__main__.py +3 -0
  8. baton_handoff-1.5.2/src/baton/cli.py +920 -0
  9. baton_handoff-1.5.2/src/baton/config.py +133 -0
  10. baton_handoff-1.5.2/src/baton/demo.py +129 -0
  11. baton_handoff-1.5.2/src/baton/importer.py +136 -0
  12. baton_handoff-1.5.2/src/baton/mcp.py +341 -0
  13. baton_handoff-1.5.2/src/baton/metrics.py +223 -0
  14. baton_handoff-1.5.2/src/baton/policies.py +132 -0
  15. baton_handoff-1.5.2/src/baton/render.py +134 -0
  16. baton_handoff-1.5.2/src/baton/sandbox.py +217 -0
  17. baton_handoff-1.5.2/src/baton/schema.py +45 -0
  18. baton_handoff-1.5.2/src/baton/serve.py +247 -0
  19. baton_handoff-1.5.2/src/baton/skill/SKILL.md +86 -0
  20. baton_handoff-1.5.2/src/baton/store.py +438 -0
  21. baton_handoff-1.5.2/src/baton_handoff.egg-info/PKG-INFO +111 -0
  22. baton_handoff-1.5.2/src/baton_handoff.egg-info/SOURCES.txt +36 -0
  23. baton_handoff-1.5.2/src/baton_handoff.egg-info/dependency_links.txt +1 -0
  24. baton_handoff-1.5.2/src/baton_handoff.egg-info/entry_points.txt +3 -0
  25. baton_handoff-1.5.2/src/baton_handoff.egg-info/top_level.txt +1 -0
  26. baton_handoff-1.5.2/tests/test_board.py +337 -0
  27. baton_handoff-1.5.2/tests/test_demo.py +54 -0
  28. baton_handoff-1.5.2/tests/test_docs.py +44 -0
  29. baton_handoff-1.5.2/tests/test_format.py +85 -0
  30. baton_handoff-1.5.2/tests/test_hardening.py +311 -0
  31. baton_handoff-1.5.2/tests/test_mcp.py +173 -0
  32. baton_handoff-1.5.2/tests/test_metrics_serve.py +139 -0
  33. baton_handoff-1.5.2/tests/test_release.py +136 -0
  34. baton_handoff-1.5.2/tests/test_report.py +70 -0
  35. baton_handoff-1.5.2/tests/test_sandbox.py +139 -0
  36. baton_handoff-1.5.2/tests/test_v11.py +146 -0
  37. baton_handoff-1.5.2/tests/test_v13.py +163 -0
  38. baton_handoff-1.5.2/tests/test_worktree.py +87 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gonçalo Faria
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.4
2
+ Name: baton-handoff
3
+ Version: 1.5.2
4
+ Summary: A file-based, append-only coordination board for AI agents building software together
5
+ Author: Gonçalo Faria
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/TheKathan/baton
8
+ Project-URL: Documentation, https://github.com/TheKathan/baton/tree/main/docs
9
+ Project-URL: Source, https://github.com/TheKathan/baton
10
+ Project-URL: Issues, https://github.com/TheKathan/baton/issues
11
+ Project-URL: Changelog, https://github.com/TheKathan/baton/blob/main/CHANGELOG.md
12
+ Keywords: ai-agents,coordination,multi-agent,handoff,cli,mcp,claude-code
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
24
+ Classifier: Topic :: Software Development
25
+ Classifier: Topic :: Software Development :: Build Tools
26
+ Requires-Python: >=3.11
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Dynamic: license-file
30
+
31
+ <p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/TheKathan/baton/main/assets/banner-dark.svg"><img alt="baton: hand-offs for AI agents that build software together" src="https://raw.githubusercontent.com/TheKathan/baton/main/assets/banner-light.svg" width="720"></picture></p>
32
+
33
+ <p align="center">
34
+ <a href="https://github.com/TheKathan/baton/actions/workflows/test.yml"><img alt="tests" src="https://github.com/TheKathan/baton/actions/workflows/test.yml/badge.svg"></a>
35
+ <img alt="latest release" src="https://img.shields.io/github/v/release/TheKathan/baton">
36
+ <img alt="license" src="https://img.shields.io/github/license/TheKathan/baton">
37
+ <img alt="Python 3.11+" src="https://img.shields.io/badge/python-%E2%89%A5%203.11-3776AB">
38
+ <img alt="dependencies: none" src="https://img.shields.io/badge/dependencies-none-brightgreen">
39
+ </p>
40
+
41
+ **Your AI agents can't say "done" while another agent's question is still open.**
42
+
43
+ baton is a shared board in your repo where coding agents ask questions, agree on contracts and hand work over. It checks every entry when it is written and keeps the record in git, so you review it in the pull request. One CLI, plain files, no server, any agent that runs a shell.
44
+
45
+ <p align="center"><img alt="A real coding agent, acting as backend, runs baton handoff and is refused because frontend's question Q-001 (which route serves the health check?) is unanswered; it reads the refusal, answers and closes Q-001, and the hand-off goes through as H-002 without --force. Trimmed and captioned; the agent's output is unchanged" src="https://raw.githubusercontent.com/TheKathan/baton/main/assets/agent-demo.gif" width="800"><br><sub>A real agent (Claude Code), unscripted, trimmed and captioned: refused while a question is open, it answers and hands off.</sub></p>
46
+
47
+ ## Try it in 60 seconds
48
+
49
+ With baton [installed](#install), paste this into a terminal. It replays the recording in a scratch folder:
50
+
51
+ ```bash
52
+ mkdir baton-try && cd baton-try && git init -q
53
+ baton init --roles frontend,backend,qa
54
+ baton post Q --as frontend --to backend --title "Which route serves health?" "For the status page."
55
+ baton handoff --as backend --phase S1-A --state DONE --to qa --title "S1-A backend" "Health endpoint done."
56
+ baton reply Q-001 --as backend --close "Use GET /api/health."
57
+ baton handoff --as backend --phase S1-A --state DONE --to qa --title "S1-A backend" "Health endpoint done."
58
+ ```
59
+
60
+ The first hand-off is refused (`answer first: baton show Q-001, then baton reply …`) and nothing is written; after the reply it goes through as `H-002`. Or just run `baton demo` for a narrated replay on a temporary board; without installing anything, `uvx baton-handoff demo`.
61
+
62
+ ## Why baton
63
+
64
+ - **No half-done hand-offs.** An agent can't report done while a question to it is still open.
65
+ - **Decisions don't get lost.** Questions, contracts, decisions and blockers are typed entries in git, readable by humans and reviewable in a PR.
66
+ - **Cheap to read.** Each agent sees only what is new for it: a few thousand tokens, not the whole board.
67
+ - **Any agent.** Claude Code, Codex, Cursor or anything that runs a shell command.
68
+ - **Nothing to run.** No server, no database, no dependencies.
69
+
70
+ On a real project, moving from a hand-written board to baton cut a sprint's board from up to ~139k tokens to ~10k and ended id collisions. [See the evidence](docs/why-baton.md).
71
+
72
+ ## What it's for
73
+
74
+ | Use | What you get |
75
+ |---|---|
76
+ | **Agents side by side on your machine** | One board for every agent, even across git worktrees. |
77
+ | **One issue per sandbox** | Each task gets its own board, which ships with the PR. [Sandbox mode](docs/sandbox.md) |
78
+ | **Your team's rules** | Policies refuse or flag entries that skip what your team expects. [Policies](docs/policies.md) |
79
+ | **CI on GitHub** | Actions that run a task's board around your agent and check it on the PR: [setup-baton](https://github.com/marketplace/actions/setup-baton-cli), [baton-task](https://github.com/marketplace/actions/baton-task-board), [baton-check](https://github.com/marketplace/actions/baton-pr-check) on the GitHub Marketplace. [How to use them](docs/sandbox.md#with-github-actions) |
80
+ | **Keeping an eye on the work** | A local dashboard and metrics: who is blocked, what is stale. [Commands](docs/commands.md) |
81
+
82
+ ## How it works
83
+
84
+ <p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/TheKathan/baton/main/assets/how-it-works-animated-dark.svg"><img alt="How baton works, as a conversation where every message is a typed entry in an append-only log: frontend asks backend which route serves the health check (Q-001); backend's hand-off to qa is refused and nothing is appended, because Q-001 is unanswered; backend answers, and the hand-off goes through as H-002, so qa takes over" src="https://raw.githubusercontent.com/TheKathan/baton/main/assets/how-it-works-animated-light.svg" width="720"></picture></p>
85
+
86
+ Agents run `baton`. Each write appends one event to a log in `.baton/` under a lock, and readable views are generated from it. [More on how it works](docs/how-it-works.md).
87
+
88
+ ## Install
89
+
90
+ baton is on PyPI as `baton-handoff` and installs the `baton` command. It needs Python 3.11 or newer on macOS or Linux; macOS ships Python 3.9, so `uv` is the easiest route: it fetches a recent Python for you.
91
+
92
+ ```bash
93
+ uv tool install baton-handoff
94
+ ```
95
+
96
+ `pipx install baton-handoff` works too, and the [getting started guide](docs/getting-started.md) shows it, then how to set up your agents.
97
+
98
+ ## Documentation
99
+
100
+ - [Getting started](docs/getting-started.md): install, try it, set up your agents, troubleshooting
101
+ - [Why baton](docs/why-baton.md): evidence, how it compares, FAQ
102
+ - [How it works](docs/how-it-works.md): files, worktrees, stability, limits
103
+ - [Sandbox mode](docs/sandbox.md): one board per task
104
+ - [Commands](docs/commands.md): every command and flag, and the MCP tools
105
+ - [Policies](docs/policies.md) · [Configuration](docs/configuration.md) · [Board format](docs/FORMAT.md)
106
+
107
+ ## Contribute
108
+
109
+ Bugs, questions and ideas go to [issues](https://github.com/TheKathan/baton/issues), and pull requests are welcome: see [CONTRIBUTING](CONTRIBUTING.md) and the [code of conduct](CODE_OF_CONDUCT.md). If baton helps your agents, a star helps others find it.
110
+
111
+ [CHANGELOG](CHANGELOG.md) · [SECURITY](SECURITY.md) · [LICENSE](LICENSE) (MIT)
@@ -0,0 +1,81 @@
1
+ <p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/TheKathan/baton/main/assets/banner-dark.svg"><img alt="baton: hand-offs for AI agents that build software together" src="https://raw.githubusercontent.com/TheKathan/baton/main/assets/banner-light.svg" width="720"></picture></p>
2
+
3
+ <p align="center">
4
+ <a href="https://github.com/TheKathan/baton/actions/workflows/test.yml"><img alt="tests" src="https://github.com/TheKathan/baton/actions/workflows/test.yml/badge.svg"></a>
5
+ <img alt="latest release" src="https://img.shields.io/github/v/release/TheKathan/baton">
6
+ <img alt="license" src="https://img.shields.io/github/license/TheKathan/baton">
7
+ <img alt="Python 3.11+" src="https://img.shields.io/badge/python-%E2%89%A5%203.11-3776AB">
8
+ <img alt="dependencies: none" src="https://img.shields.io/badge/dependencies-none-brightgreen">
9
+ </p>
10
+
11
+ **Your AI agents can't say "done" while another agent's question is still open.**
12
+
13
+ baton is a shared board in your repo where coding agents ask questions, agree on contracts and hand work over. It checks every entry when it is written and keeps the record in git, so you review it in the pull request. One CLI, plain files, no server, any agent that runs a shell.
14
+
15
+ <p align="center"><img alt="A real coding agent, acting as backend, runs baton handoff and is refused because frontend's question Q-001 (which route serves the health check?) is unanswered; it reads the refusal, answers and closes Q-001, and the hand-off goes through as H-002 without --force. Trimmed and captioned; the agent's output is unchanged" src="https://raw.githubusercontent.com/TheKathan/baton/main/assets/agent-demo.gif" width="800"><br><sub>A real agent (Claude Code), unscripted, trimmed and captioned: refused while a question is open, it answers and hands off.</sub></p>
16
+
17
+ ## Try it in 60 seconds
18
+
19
+ With baton [installed](#install), paste this into a terminal. It replays the recording in a scratch folder:
20
+
21
+ ```bash
22
+ mkdir baton-try && cd baton-try && git init -q
23
+ baton init --roles frontend,backend,qa
24
+ baton post Q --as frontend --to backend --title "Which route serves health?" "For the status page."
25
+ baton handoff --as backend --phase S1-A --state DONE --to qa --title "S1-A backend" "Health endpoint done."
26
+ baton reply Q-001 --as backend --close "Use GET /api/health."
27
+ baton handoff --as backend --phase S1-A --state DONE --to qa --title "S1-A backend" "Health endpoint done."
28
+ ```
29
+
30
+ The first hand-off is refused (`answer first: baton show Q-001, then baton reply …`) and nothing is written; after the reply it goes through as `H-002`. Or just run `baton demo` for a narrated replay on a temporary board; without installing anything, `uvx baton-handoff demo`.
31
+
32
+ ## Why baton
33
+
34
+ - **No half-done hand-offs.** An agent can't report done while a question to it is still open.
35
+ - **Decisions don't get lost.** Questions, contracts, decisions and blockers are typed entries in git, readable by humans and reviewable in a PR.
36
+ - **Cheap to read.** Each agent sees only what is new for it: a few thousand tokens, not the whole board.
37
+ - **Any agent.** Claude Code, Codex, Cursor or anything that runs a shell command.
38
+ - **Nothing to run.** No server, no database, no dependencies.
39
+
40
+ On a real project, moving from a hand-written board to baton cut a sprint's board from up to ~139k tokens to ~10k and ended id collisions. [See the evidence](docs/why-baton.md).
41
+
42
+ ## What it's for
43
+
44
+ | Use | What you get |
45
+ |---|---|
46
+ | **Agents side by side on your machine** | One board for every agent, even across git worktrees. |
47
+ | **One issue per sandbox** | Each task gets its own board, which ships with the PR. [Sandbox mode](docs/sandbox.md) |
48
+ | **Your team's rules** | Policies refuse or flag entries that skip what your team expects. [Policies](docs/policies.md) |
49
+ | **CI on GitHub** | Actions that run a task's board around your agent and check it on the PR: [setup-baton](https://github.com/marketplace/actions/setup-baton-cli), [baton-task](https://github.com/marketplace/actions/baton-task-board), [baton-check](https://github.com/marketplace/actions/baton-pr-check) on the GitHub Marketplace. [How to use them](docs/sandbox.md#with-github-actions) |
50
+ | **Keeping an eye on the work** | A local dashboard and metrics: who is blocked, what is stale. [Commands](docs/commands.md) |
51
+
52
+ ## How it works
53
+
54
+ <p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/TheKathan/baton/main/assets/how-it-works-animated-dark.svg"><img alt="How baton works, as a conversation where every message is a typed entry in an append-only log: frontend asks backend which route serves the health check (Q-001); backend's hand-off to qa is refused and nothing is appended, because Q-001 is unanswered; backend answers, and the hand-off goes through as H-002, so qa takes over" src="https://raw.githubusercontent.com/TheKathan/baton/main/assets/how-it-works-animated-light.svg" width="720"></picture></p>
55
+
56
+ Agents run `baton`. Each write appends one event to a log in `.baton/` under a lock, and readable views are generated from it. [More on how it works](docs/how-it-works.md).
57
+
58
+ ## Install
59
+
60
+ baton is on PyPI as `baton-handoff` and installs the `baton` command. It needs Python 3.11 or newer on macOS or Linux; macOS ships Python 3.9, so `uv` is the easiest route: it fetches a recent Python for you.
61
+
62
+ ```bash
63
+ uv tool install baton-handoff
64
+ ```
65
+
66
+ `pipx install baton-handoff` works too, and the [getting started guide](docs/getting-started.md) shows it, then how to set up your agents.
67
+
68
+ ## Documentation
69
+
70
+ - [Getting started](docs/getting-started.md): install, try it, set up your agents, troubleshooting
71
+ - [Why baton](docs/why-baton.md): evidence, how it compares, FAQ
72
+ - [How it works](docs/how-it-works.md): files, worktrees, stability, limits
73
+ - [Sandbox mode](docs/sandbox.md): one board per task
74
+ - [Commands](docs/commands.md): every command and flag, and the MCP tools
75
+ - [Policies](docs/policies.md) · [Configuration](docs/configuration.md) · [Board format](docs/FORMAT.md)
76
+
77
+ ## Contribute
78
+
79
+ Bugs, questions and ideas go to [issues](https://github.com/TheKathan/baton/issues), and pull requests are welcome: see [CONTRIBUTING](CONTRIBUTING.md) and the [code of conduct](CODE_OF_CONDUCT.md). If baton helps your agents, a star helps others find it.
80
+
81
+ [CHANGELOG](CHANGELOG.md) · [SECURITY](SECURITY.md) · [LICENSE](LICENSE) (MIT)
@@ -0,0 +1,50 @@
1
+ [project]
2
+ name = "baton-handoff"
3
+ dynamic = ["version"]
4
+ description = "A file-based, append-only coordination board for AI agents building software together"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ authors = [{ name = "Gonçalo Faria" }]
10
+ keywords = ["ai-agents", "coordination", "multi-agent", "handoff", "cli", "mcp", "claude-code"]
11
+ classifiers = [
12
+ "Development Status :: 4 - Beta",
13
+ "Environment :: Console",
14
+ "Intended Audience :: Developers",
15
+ "Operating System :: MacOS",
16
+ "Operating System :: POSIX :: Linux",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
23
+ "Topic :: Software Development",
24
+ "Topic :: Software Development :: Build Tools",
25
+ ]
26
+ dependencies = []
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/TheKathan/baton"
30
+ Documentation = "https://github.com/TheKathan/baton/tree/main/docs"
31
+ Source = "https://github.com/TheKathan/baton"
32
+ Issues = "https://github.com/TheKathan/baton/issues"
33
+ Changelog = "https://github.com/TheKathan/baton/blob/main/CHANGELOG.md"
34
+
35
+ [project.scripts]
36
+ baton = "baton.cli:main"
37
+ baton-handoff = "baton.cli:main"
38
+
39
+ [build-system]
40
+ requires = ["setuptools>=77"]
41
+ build-backend = "setuptools.build_meta"
42
+
43
+ [tool.setuptools.packages.find]
44
+ where = ["src"]
45
+
46
+ [tool.setuptools.dynamic]
47
+ version = { attr = "baton.__version__" }
48
+
49
+ [tool.setuptools.package-data]
50
+ baton = ["skill/*.md"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """baton: a file-based coordination board for AI agents."""
2
+
3
+ __version__ = "1.5.2"
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main()