repomoot 0.2.0__tar.gz → 0.3.0__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.
- repomoot-0.3.0/PKG-INFO +271 -0
- repomoot-0.3.0/README.md +239 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/__init__.py +1 -1
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/adapters/claude_code/install.py +120 -9
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/cli/fmt.py +82 -6
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/cli/main.py +860 -84
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/client/http.py +57 -25
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/core/cards.py +49 -13
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/core/db.py +17 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/core/lifecycle.py +2 -0
- repomoot-0.3.0/repomoot/core/outbound.py +39 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/core/service.py +780 -26
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/server/app.py +211 -21
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/server/run.py +1 -1
- repomoot-0.3.0/repomoot/server/ui.html +374 -0
- repomoot-0.3.0/repomoot.egg-info/PKG-INFO +271 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot.egg-info/SOURCES.txt +2 -0
- repomoot-0.3.0/tests/test_cli.py +251 -0
- repomoot-0.3.0/tests/test_demo_flow.py +677 -0
- repomoot-0.2.0/PKG-INFO +0 -189
- repomoot-0.2.0/README.md +0 -157
- repomoot-0.2.0/repomoot/server/ui.html +0 -182
- repomoot-0.2.0/repomoot.egg-info/PKG-INFO +0 -189
- repomoot-0.2.0/tests/test_demo_flow.py +0 -243
- {repomoot-0.2.0 → repomoot-0.3.0}/LICENSE +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/NOTICE +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/pyproject.toml +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/adapters/__init__.py +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/adapters/claude_code/__init__.py +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/cli/__init__.py +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/client/__init__.py +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/config.py +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/core/__init__.py +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot/server/__init__.py +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot.egg-info/dependency_links.txt +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot.egg-info/entry_points.txt +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot.egg-info/requires.txt +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/repomoot.egg-info/top_level.txt +0 -0
- {repomoot-0.2.0 → repomoot-0.3.0}/setup.cfg +0 -0
repomoot-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: repomoot
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Requests between AI coding agents that own different repositories, with consumer acceptance and owner escalation
|
|
5
|
+
Author: SimeonAr
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/dev-bude/repomoot
|
|
8
|
+
Project-URL: Repository, https://github.com/dev-bude/repomoot
|
|
9
|
+
Project-URL: Issues, https://github.com/dev-bude/repomoot/issues
|
|
10
|
+
Project-URL: Protocol, https://github.com/dev-bude/repomoot/blob/main/PROTOCOL.md
|
|
11
|
+
Project-URL: Security, https://github.com/dev-bude/repomoot/blob/main/SECURITY.md
|
|
12
|
+
Keywords: ai-agents,claude-code,codex,multi-agent,request-lifecycle
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Framework :: FastAPI
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Version Control
|
|
21
|
+
Requires-Python: >=3.12
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
License-File: NOTICE
|
|
25
|
+
Requires-Dist: fastapi>=0.110
|
|
26
|
+
Requires-Dist: uvicorn>=0.29
|
|
27
|
+
Requires-Dist: typer>=0.12
|
|
28
|
+
Requires-Dist: httpx>=0.27
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
# Repomoot
|
|
34
|
+
|
|
35
|
+
**Requests between AI coding agents that own different repositories — with consumer acceptance
|
|
36
|
+
and owner escalation.**
|
|
37
|
+
|
|
38
|
+
When several coding agents (Claude Code, Codex, Gemini CLI, your own) work on related
|
|
39
|
+
repositories, there is no working channel between them: you become the courier, the product
|
|
40
|
+
owner and the referee, and the history disappears with every `/clear`. Repomoot gives the agents a
|
|
41
|
+
shared lane for *requests* — "I need X from your repository" — with a lifecycle that ends when the
|
|
42
|
+
**consumer** has verified the result in its own context, a **Product Owner** role for the decisions
|
|
43
|
+
owners must not make alone, and a durable, searchable history.
|
|
44
|
+
|
|
45
|
+
It is not shared memory, not an orchestrator and not a task board. Agents keep their own runtime,
|
|
46
|
+
context and tools. Repomoot owns requests, messages, artifacts, decisions and events.
|
|
47
|
+
|
|
48
|
+
## How it works
|
|
49
|
+
|
|
50
|
+
- A local daemon holds the state (SQLite) and serves an HTTP API. The CLI `repomoot` is a thin
|
|
51
|
+
client and starts the daemon on demand; you never have to start it yourself
|
|
52
|
+
(`repomoot daemon start|stop|restart` exists for when you want to).
|
|
53
|
+
- Agents talk to it through `repomoot` from their own shell tool — nothing else is required from a
|
|
54
|
+
runtime. The rules an agent follows (the *protocol card*) are owned by Repomoot and handed to the
|
|
55
|
+
agent at `repomoot connect`; the Claude Code adapter adds a thin skill and hooks that fetch it.
|
|
56
|
+
- The lifecycle: `open → discussion → proposal → implementation → delivery → evaluation → closed`,
|
|
57
|
+
with `question`, `bug`, `change`, `review`, `notice`, `task` and `decision` variants. See
|
|
58
|
+
[PROTOCOL.md](https://github.com/dev-bude/repomoot/blob/main/PROTOCOL.md) — the protocol is documented separately from the code (CC-BY-4.0) and
|
|
59
|
+
maps onto A2A task states and MCP Tasks.
|
|
60
|
+
- If no Product Owner session is present, a product question stays in the chat of the agent
|
|
61
|
+
that needs it, with the option to hand it over to the PO later.
|
|
62
|
+
|
|
63
|
+
Status: 0.3, early (alpha). Local mode works end to end — see [WALKTHROUGH.md](https://github.com/dev-bude/repomoot/blob/main/WALKTHROUGH.md) for one real
|
|
64
|
+
request followed from the user's instruction to the consumer's evaluation. No MCP surface, no
|
|
65
|
+
CI/ephemeral mode yet. Code: Apache-2.0.
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
Repomoot is a command-line tool, so install it into its own environment:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
pipx install repomoot # or: uv tool install repomoot
|
|
73
|
+
repomoot --version
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Either one puts `repomoot` on your PATH and keeps its dependencies away from your projects.
|
|
77
|
+
Plain `pip install repomoot` works too, inside a virtualenv of your own. Python 3.12+.
|
|
78
|
+
|
|
79
|
+
Then install the Claude Code adapter (it prints what it will write and asks first):
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
repomoot install --runtime claude-code --hooks
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
That adds a 3-line pointer to `~/.claude/CLAUDE.md`, a `/repomoot` skill, and hooks that call
|
|
86
|
+
`repomoot` by its absolute path — so the agents find it whatever their PATH looks like. If `repomoot`
|
|
87
|
+
is not on PATH, it also puts a small launcher into a user folder that is (`%LOCALAPPDATA%\Microsoft\WindowsApps`
|
|
88
|
+
on Windows, `~/.local/bin` or `~/bin` elsewhere).
|
|
89
|
+
`repomoot uninstall` reverts the adapter. You can also ask an agent to install it: with no terminal
|
|
90
|
+
to confirm in, the command prints what it would write and stops; the agent shows you the list and
|
|
91
|
+
repeats it with `--yes` once you agree.
|
|
92
|
+
|
|
93
|
+
Other runtimes: `repomoot install --runtime codex --dir <project>` writes the card into `AGENTS.md`
|
|
94
|
+
(`gemini` → `GEMINI.md`, `cursor` → `.cursorrules`); `repomoot protocol` prints it.
|
|
95
|
+
|
|
96
|
+
<details>
|
|
97
|
+
<summary>From source (for working on Repomoot itself)</summary>
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
git clone https://github.com/dev-bude/repomoot.git && cd repomoot
|
|
101
|
+
python -m venv .venv
|
|
102
|
+
.venv/bin/pip install -e ".[dev]" # Windows: .venv\Scripts\python -m pip install -e ".[dev]"
|
|
103
|
+
.venv/bin/python -m pytest -q # Windows: .venv\Scripts\python -m pytest -q
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The `repomoot` command then lives in `.venv/bin` (Windows: `.venv\Scripts`); add it to your PATH to
|
|
107
|
+
type commands yourself. See [CONTRIBUTING.md](https://github.com/dev-bude/repomoot/blob/main/CONTRIBUTING.md).
|
|
108
|
+
|
|
109
|
+
</details>
|
|
110
|
+
|
|
111
|
+
## First steps
|
|
112
|
+
|
|
113
|
+
Open one Claude Code session per repository (VS Code windows or terminals). In the chat, once per
|
|
114
|
+
folder — it is remembered:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
/repomoot connect # in each repository: registers this repo's agent (name = folder) and connects
|
|
118
|
+
/repomoot po # in the folder with your product notes: the Product Owner (optional, one at a time)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
These commands run in the hook with **your** authority before the agent sees them — agents cannot
|
|
122
|
+
register themselves. From then on every new session, `/clear` or resume in a registered folder (or
|
|
123
|
+
in a git worktree of that repository) reconnects by itself; a session the daemon dropped after a
|
|
124
|
+
long pause reconnects on its next command.
|
|
125
|
+
|
|
126
|
+
Then you talk to the agents as usual — and, if there is a PO, tell the PO in plain words how the
|
|
127
|
+
work should go ("pro orders, engine implements; preview hook first"). The agents keep
|
|
128
|
+
`repomoot watch` running in the background, which wakes a session as soon as something arrives for
|
|
129
|
+
it, so they pick up requests, report progress and answer each other without you relaying. The PO
|
|
130
|
+
assigns work and gives the go-ahead itself; settings that are yours (checking a direction, stop
|
|
131
|
+
words, its own policy, removing an agent) it proposes, and Repomoot shows you one line it wrote
|
|
132
|
+
itself, for example `check everything pro sends to engine before it is delivered` — you answer:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
/repomoot yes # or /repomoot no; with several waiting: /repomoot yes <id>
|
|
136
|
+
/repomoot ui # the live request tree in the browser
|
|
137
|
+
/repomoot confirm <id> # only when asked: a decision reserved for you that an agent recorded
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
A session working on its own repository plans and works by itself as usual; its task list is
|
|
141
|
+
shared with Repomoot (`repomoot plan set / start / done --note / note`; Claude Code hooks mirror the
|
|
142
|
+
task tool as a fallback), and the reports it writes to you are kept in a journal (`repomoot journal`) —
|
|
143
|
+
so the PO and the dashboard always show each session's plan, what is done and what it reported,
|
|
144
|
+
instead of it scrolling away in the chat.
|
|
145
|
+
|
|
146
|
+
Under the hood the agents use the CLI (`repomoot req new / progress / propose / deliver / evaluate /
|
|
147
|
+
ask-po / decide`, each reply prints `next:`); dependencies between agents are inferred from the
|
|
148
|
+
requests they send. Everything is also available from your terminal
|
|
149
|
+
(`repomoot agents`, `repomoot req show req_0001`, ...). `repomoot --help`, `repomoot <cmd> --help`;
|
|
150
|
+
every command accepts `--json`. Exit codes: 0 ok, 1 other error, 2 bad arguments,
|
|
151
|
+
3 not connected, 4 forbidden, bad transition or conflict, 5 not found, 6 daemon unavailable or bad token. A `wait` that times out is not
|
|
152
|
+
an error: exit 0, `"timeout": true` in `--json`.
|
|
153
|
+
|
|
154
|
+
## When something looks stuck
|
|
155
|
+
|
|
156
|
+
- An agent "went quiet": it finished a step without `repomoot watch` in the background, so nothing
|
|
157
|
+
woke it. Type `/repomoot inbox` in that session — the hook injects what is new and the agent
|
|
158
|
+
continues. `repomoot agents` shows which sessions are watching.
|
|
159
|
+
- A `wait` that ends with "no new events" is not a broken link: nothing arrived yet.
|
|
160
|
+
- A folder that is not a git repository (say, a scratch folder holding worktrees of two repos) is
|
|
161
|
+
never registered as a new agent by `/repomoot connect`; the reply names the agents whose copies
|
|
162
|
+
are inside — `/repomoot connect <agent>` works there as that agent.
|
|
163
|
+
- `/repomoot status` in any session shows who is online; `repomoot agents` from the terminal too.
|
|
164
|
+
- Two sessions in one folder: give the second one a name, `repomoot connect --session two`.
|
|
165
|
+
- The Product Owner owns only the folder it was registered in, never the projects under it: a session
|
|
166
|
+
in an unregistered subfolder is not connected until you type `/repomoot connect` there.
|
|
167
|
+
- Registering everything from one terminal, without opening a session in each folder:
|
|
168
|
+
`repomoot agents add gridlib --repo ../gridlib`, `repomoot agents add po --kind po --repo ../notes`.
|
|
169
|
+
A directory attached by mistake is detached with `repomoot agents set NAME --remove-repo DIR`
|
|
170
|
+
(sessions opened there end; requests are kept). An agent registered by mistake (offline, no requests)
|
|
171
|
+
is removed with `repomoot agents remove NAME` or the × next to it in the dashboard (`repomoot ui`).
|
|
172
|
+
- State lives in `~/.repomoot/` (`REPOMOOT_HOME`), port 7771 (`REPOMOOT_PORT`); delete the folder to
|
|
173
|
+
start from scratch (stop the daemon first: `repomoot daemon stop`).
|
|
174
|
+
|
|
175
|
+
## One file for the workspace
|
|
176
|
+
|
|
177
|
+
`repomoot workspace export` writes the whole setup — agents, their directories, dependencies, stop
|
|
178
|
+
words, the PO's policy, gates — to `repomoot.toml` (directories relative to the file). On another
|
|
179
|
+
machine, or after starting from scratch, `repomoot workspace apply` (your terminal only; `--dry-run`
|
|
180
|
+
shows what would change) registers what the file describes. It only adds: removing an agent, a
|
|
181
|
+
directory or a gate stays an explicit command.
|
|
182
|
+
|
|
183
|
+
```toml
|
|
184
|
+
[agents.engine]
|
|
185
|
+
kind = "project"
|
|
186
|
+
repos = ["engine"]
|
|
187
|
+
|
|
188
|
+
[agents.pro]
|
|
189
|
+
kind = "project"
|
|
190
|
+
repos = ["pro"]
|
|
191
|
+
depends_on = ["engine"]
|
|
192
|
+
deny = ["InternalBilling"]
|
|
193
|
+
|
|
194
|
+
[agents.po]
|
|
195
|
+
kind = "po"
|
|
196
|
+
repos = ["notes"]
|
|
197
|
+
|
|
198
|
+
[[gates]]
|
|
199
|
+
from = "pro"
|
|
200
|
+
to = "engine"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Looking back
|
|
204
|
+
|
|
205
|
+
- `repomoot summary --since 8h` — what happened and what waits for you, in a few lines.
|
|
206
|
+
- `repomoot log --since 2d [--agent engine]` — every event, oldest first.
|
|
207
|
+
- `repomoot po decisions [--since 7d]` — the decisions: question, answer, reason, who decided.
|
|
208
|
+
- `repomoot po history engine` — what an agent was asked for, what it delivered (commit, tests), how
|
|
209
|
+
the requesters judged it, what it ordered, the decisions that concern it.
|
|
210
|
+
- `repomoot journal [--agent engine]` — the reports the sessions wrote to you.
|
|
211
|
+
|
|
212
|
+
These are yours and the PO's; an agent's own `log` shows only what it was told.
|
|
213
|
+
|
|
214
|
+
## Checked directions and stop words
|
|
215
|
+
|
|
216
|
+
Text that looks like a secret (cloud keys, tokens, private keys, `password = ...`) is refused for
|
|
217
|
+
everyone and never stored. Stop words keep an agent's internal names inside it:
|
|
218
|
+
`repomoot agents set paid --deny InternalBilling --deny "re:acme\.corp"` — any request, reply or
|
|
219
|
+
artifact of `paid` that mentions one is refused. A gate puts a direction under your eye:
|
|
220
|
+
`repomoot gate paid lib` — what `paid` sends to `lib` waits for you: `/repomoot held` lists it,
|
|
221
|
+
`/repomoot release <id>` delivers it as written, `/repomoot drop <id>` discards it. Useful between a
|
|
222
|
+
private and a public repository, or between any two parts you want to watch. This guards what the
|
|
223
|
+
sessions say to each other; what each session can read or push is up to Claude Code's own
|
|
224
|
+
permissions and your git credentials.
|
|
225
|
+
|
|
226
|
+
## Principals
|
|
227
|
+
|
|
228
|
+
- **Daemon token** (`~/.repomoot/token`): every local client. Lets a session act as an *already
|
|
229
|
+
registered* agent from that agent's own repository directory.
|
|
230
|
+
- **Human token** (`~/.repomoot/human.token`): registering, editing and removing agents, gates and
|
|
231
|
+
stop words, the PO policy, releasing held messages, confirming decisions reserved for the user,
|
|
232
|
+
speaking as an agent (`--as`). The CLI sends it only from an interactive terminal, from the chat
|
|
233
|
+
commands you type (`/repomoot ...`, handled by the hook before the agent sees them) or via
|
|
234
|
+
`REPOMOOT_HUMAN_TOKEN` (CI). An agent that records "the user's decision" on a kind the policy
|
|
235
|
+
reserves for the user (breaking change, scope, conflict, budget) does not close anything: it waits
|
|
236
|
+
for your `/repomoot confirm`.
|
|
237
|
+
- The token file is readable by any process of your OS user, so this keeps honest agents and
|
|
238
|
+
injected instructions from acting as you; it is not a wall against an agent that deliberately
|
|
239
|
+
reads the file. Claude Code's own permissions (deny reads of `~/.repomoot/human.token`) are that wall.
|
|
240
|
+
- Agents see only the requests they are a party of (the PO sees all); search follows the same rule.
|
|
241
|
+
|
|
242
|
+
State lives in `~/.repomoot/` (`REPOMOOT_HOME`); port 7771 (`REPOMOOT_PORT`). Trust model and data
|
|
243
|
+
notes: [SECURITY.md](https://github.com/dev-bude/repomoot/blob/main/SECURITY.md).
|
|
244
|
+
|
|
245
|
+
## Reading on
|
|
246
|
+
|
|
247
|
+
- [WALKTHROUGH.md](https://github.com/dev-bude/repomoot/blob/main/WALKTHROUGH.md) — how a request flows, step by step, with real output.
|
|
248
|
+
- [PROTOCOL.md](https://github.com/dev-bude/repomoot/blob/main/PROTOCOL.md) — lifecycle, roles, artifacts, mapping to A2A / MCP Tasks.
|
|
249
|
+
- [SECURITY.md](https://github.com/dev-bude/repomoot/blob/main/SECURITY.md) — trust model, data, what the adapter writes.
|
|
250
|
+
- [CONTRIBUTING.md](https://github.com/dev-bude/repomoot/blob/main/CONTRIBUTING.md) — how to set up, what is worth working on, house rules.
|
|
251
|
+
|
|
252
|
+
## Layout
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
repomoot/core db, lifecycle, cards (instruction texts), service (all rules)
|
|
256
|
+
repomoot/server FastAPI daemon: HTTP API, async long-poll and SSE events
|
|
257
|
+
repomoot/client HTTP client, session files, human principal, daemon autostart
|
|
258
|
+
repomoot/cli typer CLI + text rendering (quotes and sanitizes other agents' text)
|
|
259
|
+
repomoot/adapters claude_code: install/uninstall, skill, hooks
|
|
260
|
+
tests/ the walkthrough's flow and the rules, through the API
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Tests: `python -m pytest -q`.
|
|
264
|
+
|
|
265
|
+
## Licence
|
|
266
|
+
|
|
267
|
+
Code: Apache-2.0 ([LICENSE](https://github.com/dev-bude/repomoot/blob/main/LICENSE), [NOTICE](https://github.com/dev-bude/repomoot/blob/main/NOTICE)). The protocol description
|
|
268
|
+
([PROTOCOL.md](https://github.com/dev-bude/repomoot/blob/main/PROTOCOL.md)): CC BY 4.0.
|
|
269
|
+
|
|
270
|
+
Claude Code, Codex, Gemini CLI and Cursor are products of their respective owners; Repomoot is an
|
|
271
|
+
independent project and is not affiliated with or endorsed by any of them.
|
repomoot-0.3.0/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Repomoot
|
|
2
|
+
|
|
3
|
+
**Requests between AI coding agents that own different repositories — with consumer acceptance
|
|
4
|
+
and owner escalation.**
|
|
5
|
+
|
|
6
|
+
When several coding agents (Claude Code, Codex, Gemini CLI, your own) work on related
|
|
7
|
+
repositories, there is no working channel between them: you become the courier, the product
|
|
8
|
+
owner and the referee, and the history disappears with every `/clear`. Repomoot gives the agents a
|
|
9
|
+
shared lane for *requests* — "I need X from your repository" — with a lifecycle that ends when the
|
|
10
|
+
**consumer** has verified the result in its own context, a **Product Owner** role for the decisions
|
|
11
|
+
owners must not make alone, and a durable, searchable history.
|
|
12
|
+
|
|
13
|
+
It is not shared memory, not an orchestrator and not a task board. Agents keep their own runtime,
|
|
14
|
+
context and tools. Repomoot owns requests, messages, artifacts, decisions and events.
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
- A local daemon holds the state (SQLite) and serves an HTTP API. The CLI `repomoot` is a thin
|
|
19
|
+
client and starts the daemon on demand; you never have to start it yourself
|
|
20
|
+
(`repomoot daemon start|stop|restart` exists for when you want to).
|
|
21
|
+
- Agents talk to it through `repomoot` from their own shell tool — nothing else is required from a
|
|
22
|
+
runtime. The rules an agent follows (the *protocol card*) are owned by Repomoot and handed to the
|
|
23
|
+
agent at `repomoot connect`; the Claude Code adapter adds a thin skill and hooks that fetch it.
|
|
24
|
+
- The lifecycle: `open → discussion → proposal → implementation → delivery → evaluation → closed`,
|
|
25
|
+
with `question`, `bug`, `change`, `review`, `notice`, `task` and `decision` variants. See
|
|
26
|
+
[PROTOCOL.md](https://github.com/dev-bude/repomoot/blob/main/PROTOCOL.md) — the protocol is documented separately from the code (CC-BY-4.0) and
|
|
27
|
+
maps onto A2A task states and MCP Tasks.
|
|
28
|
+
- If no Product Owner session is present, a product question stays in the chat of the agent
|
|
29
|
+
that needs it, with the option to hand it over to the PO later.
|
|
30
|
+
|
|
31
|
+
Status: 0.3, early (alpha). Local mode works end to end — see [WALKTHROUGH.md](https://github.com/dev-bude/repomoot/blob/main/WALKTHROUGH.md) for one real
|
|
32
|
+
request followed from the user's instruction to the consumer's evaluation. No MCP surface, no
|
|
33
|
+
CI/ephemeral mode yet. Code: Apache-2.0.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
Repomoot is a command-line tool, so install it into its own environment:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
pipx install repomoot # or: uv tool install repomoot
|
|
41
|
+
repomoot --version
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Either one puts `repomoot` on your PATH and keeps its dependencies away from your projects.
|
|
45
|
+
Plain `pip install repomoot` works too, inside a virtualenv of your own. Python 3.12+.
|
|
46
|
+
|
|
47
|
+
Then install the Claude Code adapter (it prints what it will write and asks first):
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
repomoot install --runtime claude-code --hooks
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
That adds a 3-line pointer to `~/.claude/CLAUDE.md`, a `/repomoot` skill, and hooks that call
|
|
54
|
+
`repomoot` by its absolute path — so the agents find it whatever their PATH looks like. If `repomoot`
|
|
55
|
+
is not on PATH, it also puts a small launcher into a user folder that is (`%LOCALAPPDATA%\Microsoft\WindowsApps`
|
|
56
|
+
on Windows, `~/.local/bin` or `~/bin` elsewhere).
|
|
57
|
+
`repomoot uninstall` reverts the adapter. You can also ask an agent to install it: with no terminal
|
|
58
|
+
to confirm in, the command prints what it would write and stops; the agent shows you the list and
|
|
59
|
+
repeats it with `--yes` once you agree.
|
|
60
|
+
|
|
61
|
+
Other runtimes: `repomoot install --runtime codex --dir <project>` writes the card into `AGENTS.md`
|
|
62
|
+
(`gemini` → `GEMINI.md`, `cursor` → `.cursorrules`); `repomoot protocol` prints it.
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary>From source (for working on Repomoot itself)</summary>
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
git clone https://github.com/dev-bude/repomoot.git && cd repomoot
|
|
69
|
+
python -m venv .venv
|
|
70
|
+
.venv/bin/pip install -e ".[dev]" # Windows: .venv\Scripts\python -m pip install -e ".[dev]"
|
|
71
|
+
.venv/bin/python -m pytest -q # Windows: .venv\Scripts\python -m pytest -q
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The `repomoot` command then lives in `.venv/bin` (Windows: `.venv\Scripts`); add it to your PATH to
|
|
75
|
+
type commands yourself. See [CONTRIBUTING.md](https://github.com/dev-bude/repomoot/blob/main/CONTRIBUTING.md).
|
|
76
|
+
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
## First steps
|
|
80
|
+
|
|
81
|
+
Open one Claude Code session per repository (VS Code windows or terminals). In the chat, once per
|
|
82
|
+
folder — it is remembered:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
/repomoot connect # in each repository: registers this repo's agent (name = folder) and connects
|
|
86
|
+
/repomoot po # in the folder with your product notes: the Product Owner (optional, one at a time)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
These commands run in the hook with **your** authority before the agent sees them — agents cannot
|
|
90
|
+
register themselves. From then on every new session, `/clear` or resume in a registered folder (or
|
|
91
|
+
in a git worktree of that repository) reconnects by itself; a session the daemon dropped after a
|
|
92
|
+
long pause reconnects on its next command.
|
|
93
|
+
|
|
94
|
+
Then you talk to the agents as usual — and, if there is a PO, tell the PO in plain words how the
|
|
95
|
+
work should go ("pro orders, engine implements; preview hook first"). The agents keep
|
|
96
|
+
`repomoot watch` running in the background, which wakes a session as soon as something arrives for
|
|
97
|
+
it, so they pick up requests, report progress and answer each other without you relaying. The PO
|
|
98
|
+
assigns work and gives the go-ahead itself; settings that are yours (checking a direction, stop
|
|
99
|
+
words, its own policy, removing an agent) it proposes, and Repomoot shows you one line it wrote
|
|
100
|
+
itself, for example `check everything pro sends to engine before it is delivered` — you answer:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
/repomoot yes # or /repomoot no; with several waiting: /repomoot yes <id>
|
|
104
|
+
/repomoot ui # the live request tree in the browser
|
|
105
|
+
/repomoot confirm <id> # only when asked: a decision reserved for you that an agent recorded
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
A session working on its own repository plans and works by itself as usual; its task list is
|
|
109
|
+
shared with Repomoot (`repomoot plan set / start / done --note / note`; Claude Code hooks mirror the
|
|
110
|
+
task tool as a fallback), and the reports it writes to you are kept in a journal (`repomoot journal`) —
|
|
111
|
+
so the PO and the dashboard always show each session's plan, what is done and what it reported,
|
|
112
|
+
instead of it scrolling away in the chat.
|
|
113
|
+
|
|
114
|
+
Under the hood the agents use the CLI (`repomoot req new / progress / propose / deliver / evaluate /
|
|
115
|
+
ask-po / decide`, each reply prints `next:`); dependencies between agents are inferred from the
|
|
116
|
+
requests they send. Everything is also available from your terminal
|
|
117
|
+
(`repomoot agents`, `repomoot req show req_0001`, ...). `repomoot --help`, `repomoot <cmd> --help`;
|
|
118
|
+
every command accepts `--json`. Exit codes: 0 ok, 1 other error, 2 bad arguments,
|
|
119
|
+
3 not connected, 4 forbidden, bad transition or conflict, 5 not found, 6 daemon unavailable or bad token. A `wait` that times out is not
|
|
120
|
+
an error: exit 0, `"timeout": true` in `--json`.
|
|
121
|
+
|
|
122
|
+
## When something looks stuck
|
|
123
|
+
|
|
124
|
+
- An agent "went quiet": it finished a step without `repomoot watch` in the background, so nothing
|
|
125
|
+
woke it. Type `/repomoot inbox` in that session — the hook injects what is new and the agent
|
|
126
|
+
continues. `repomoot agents` shows which sessions are watching.
|
|
127
|
+
- A `wait` that ends with "no new events" is not a broken link: nothing arrived yet.
|
|
128
|
+
- A folder that is not a git repository (say, a scratch folder holding worktrees of two repos) is
|
|
129
|
+
never registered as a new agent by `/repomoot connect`; the reply names the agents whose copies
|
|
130
|
+
are inside — `/repomoot connect <agent>` works there as that agent.
|
|
131
|
+
- `/repomoot status` in any session shows who is online; `repomoot agents` from the terminal too.
|
|
132
|
+
- Two sessions in one folder: give the second one a name, `repomoot connect --session two`.
|
|
133
|
+
- The Product Owner owns only the folder it was registered in, never the projects under it: a session
|
|
134
|
+
in an unregistered subfolder is not connected until you type `/repomoot connect` there.
|
|
135
|
+
- Registering everything from one terminal, without opening a session in each folder:
|
|
136
|
+
`repomoot agents add gridlib --repo ../gridlib`, `repomoot agents add po --kind po --repo ../notes`.
|
|
137
|
+
A directory attached by mistake is detached with `repomoot agents set NAME --remove-repo DIR`
|
|
138
|
+
(sessions opened there end; requests are kept). An agent registered by mistake (offline, no requests)
|
|
139
|
+
is removed with `repomoot agents remove NAME` or the × next to it in the dashboard (`repomoot ui`).
|
|
140
|
+
- State lives in `~/.repomoot/` (`REPOMOOT_HOME`), port 7771 (`REPOMOOT_PORT`); delete the folder to
|
|
141
|
+
start from scratch (stop the daemon first: `repomoot daemon stop`).
|
|
142
|
+
|
|
143
|
+
## One file for the workspace
|
|
144
|
+
|
|
145
|
+
`repomoot workspace export` writes the whole setup — agents, their directories, dependencies, stop
|
|
146
|
+
words, the PO's policy, gates — to `repomoot.toml` (directories relative to the file). On another
|
|
147
|
+
machine, or after starting from scratch, `repomoot workspace apply` (your terminal only; `--dry-run`
|
|
148
|
+
shows what would change) registers what the file describes. It only adds: removing an agent, a
|
|
149
|
+
directory or a gate stays an explicit command.
|
|
150
|
+
|
|
151
|
+
```toml
|
|
152
|
+
[agents.engine]
|
|
153
|
+
kind = "project"
|
|
154
|
+
repos = ["engine"]
|
|
155
|
+
|
|
156
|
+
[agents.pro]
|
|
157
|
+
kind = "project"
|
|
158
|
+
repos = ["pro"]
|
|
159
|
+
depends_on = ["engine"]
|
|
160
|
+
deny = ["InternalBilling"]
|
|
161
|
+
|
|
162
|
+
[agents.po]
|
|
163
|
+
kind = "po"
|
|
164
|
+
repos = ["notes"]
|
|
165
|
+
|
|
166
|
+
[[gates]]
|
|
167
|
+
from = "pro"
|
|
168
|
+
to = "engine"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Looking back
|
|
172
|
+
|
|
173
|
+
- `repomoot summary --since 8h` — what happened and what waits for you, in a few lines.
|
|
174
|
+
- `repomoot log --since 2d [--agent engine]` — every event, oldest first.
|
|
175
|
+
- `repomoot po decisions [--since 7d]` — the decisions: question, answer, reason, who decided.
|
|
176
|
+
- `repomoot po history engine` — what an agent was asked for, what it delivered (commit, tests), how
|
|
177
|
+
the requesters judged it, what it ordered, the decisions that concern it.
|
|
178
|
+
- `repomoot journal [--agent engine]` — the reports the sessions wrote to you.
|
|
179
|
+
|
|
180
|
+
These are yours and the PO's; an agent's own `log` shows only what it was told.
|
|
181
|
+
|
|
182
|
+
## Checked directions and stop words
|
|
183
|
+
|
|
184
|
+
Text that looks like a secret (cloud keys, tokens, private keys, `password = ...`) is refused for
|
|
185
|
+
everyone and never stored. Stop words keep an agent's internal names inside it:
|
|
186
|
+
`repomoot agents set paid --deny InternalBilling --deny "re:acme\.corp"` — any request, reply or
|
|
187
|
+
artifact of `paid` that mentions one is refused. A gate puts a direction under your eye:
|
|
188
|
+
`repomoot gate paid lib` — what `paid` sends to `lib` waits for you: `/repomoot held` lists it,
|
|
189
|
+
`/repomoot release <id>` delivers it as written, `/repomoot drop <id>` discards it. Useful between a
|
|
190
|
+
private and a public repository, or between any two parts you want to watch. This guards what the
|
|
191
|
+
sessions say to each other; what each session can read or push is up to Claude Code's own
|
|
192
|
+
permissions and your git credentials.
|
|
193
|
+
|
|
194
|
+
## Principals
|
|
195
|
+
|
|
196
|
+
- **Daemon token** (`~/.repomoot/token`): every local client. Lets a session act as an *already
|
|
197
|
+
registered* agent from that agent's own repository directory.
|
|
198
|
+
- **Human token** (`~/.repomoot/human.token`): registering, editing and removing agents, gates and
|
|
199
|
+
stop words, the PO policy, releasing held messages, confirming decisions reserved for the user,
|
|
200
|
+
speaking as an agent (`--as`). The CLI sends it only from an interactive terminal, from the chat
|
|
201
|
+
commands you type (`/repomoot ...`, handled by the hook before the agent sees them) or via
|
|
202
|
+
`REPOMOOT_HUMAN_TOKEN` (CI). An agent that records "the user's decision" on a kind the policy
|
|
203
|
+
reserves for the user (breaking change, scope, conflict, budget) does not close anything: it waits
|
|
204
|
+
for your `/repomoot confirm`.
|
|
205
|
+
- The token file is readable by any process of your OS user, so this keeps honest agents and
|
|
206
|
+
injected instructions from acting as you; it is not a wall against an agent that deliberately
|
|
207
|
+
reads the file. Claude Code's own permissions (deny reads of `~/.repomoot/human.token`) are that wall.
|
|
208
|
+
- Agents see only the requests they are a party of (the PO sees all); search follows the same rule.
|
|
209
|
+
|
|
210
|
+
State lives in `~/.repomoot/` (`REPOMOOT_HOME`); port 7771 (`REPOMOOT_PORT`). Trust model and data
|
|
211
|
+
notes: [SECURITY.md](https://github.com/dev-bude/repomoot/blob/main/SECURITY.md).
|
|
212
|
+
|
|
213
|
+
## Reading on
|
|
214
|
+
|
|
215
|
+
- [WALKTHROUGH.md](https://github.com/dev-bude/repomoot/blob/main/WALKTHROUGH.md) — how a request flows, step by step, with real output.
|
|
216
|
+
- [PROTOCOL.md](https://github.com/dev-bude/repomoot/blob/main/PROTOCOL.md) — lifecycle, roles, artifacts, mapping to A2A / MCP Tasks.
|
|
217
|
+
- [SECURITY.md](https://github.com/dev-bude/repomoot/blob/main/SECURITY.md) — trust model, data, what the adapter writes.
|
|
218
|
+
- [CONTRIBUTING.md](https://github.com/dev-bude/repomoot/blob/main/CONTRIBUTING.md) — how to set up, what is worth working on, house rules.
|
|
219
|
+
|
|
220
|
+
## Layout
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
repomoot/core db, lifecycle, cards (instruction texts), service (all rules)
|
|
224
|
+
repomoot/server FastAPI daemon: HTTP API, async long-poll and SSE events
|
|
225
|
+
repomoot/client HTTP client, session files, human principal, daemon autostart
|
|
226
|
+
repomoot/cli typer CLI + text rendering (quotes and sanitizes other agents' text)
|
|
227
|
+
repomoot/adapters claude_code: install/uninstall, skill, hooks
|
|
228
|
+
tests/ the walkthrough's flow and the rules, through the API
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Tests: `python -m pytest -q`.
|
|
232
|
+
|
|
233
|
+
## Licence
|
|
234
|
+
|
|
235
|
+
Code: Apache-2.0 ([LICENSE](https://github.com/dev-bude/repomoot/blob/main/LICENSE), [NOTICE](https://github.com/dev-bude/repomoot/blob/main/NOTICE)). The protocol description
|
|
236
|
+
([PROTOCOL.md](https://github.com/dev-bude/repomoot/blob/main/PROTOCOL.md)): CC BY 4.0.
|
|
237
|
+
|
|
238
|
+
Claude Code, Codex, Gemini CLI and Cursor are products of their respective owners; Repomoot is an
|
|
239
|
+
independent project and is not affiliated with or endorsed by any of them.
|