Agent workspace manager over Git: isolate, review and consolidate multi-agent changes into a single commit.
Project description
gitagent
Agent workspace manager over Git: isolate, review and consolidate multi-agent changes into a single commit.
gitagent is a lightweight CLI that wraps git worktree so a superagent can spawn isolated subagents, collect their work as proposals (patch + manifest), accept/reject/revise them, and finally produce one clean commit on the real repository — then clean everything up. It never pushes.
Two planes are kept strictly separate:
.git— the source of truth. Untouched untilfinalize, which writes exactly one commit..gitagent/— an ephemeral coordination layer: worktrees, patches, manifests, decisions, audit log. Discardable and reset afterfinalize/abort.
gitagent does not reimplement Git. Proposals are stored as git diff patches plus JSON metadata, never as a second history.
Decision / application split (Option B)
gitagent cleanly separates deciding from applying:
| Command | Role |
|---|---|
accept <pid> |
Record the decision "approved". Does not apply. |
reject <pid> |
Record "rejected". |
revise <pid> |
Send back to the agent (new pid on re-propose). |
integrate |
Apply all accepted proposals onto the integration branch. Detects conflicts. |
finalize |
Calls integrate (if needed) + creates one commit on the current branch. |
So a minimal flow is: accept each → finalize. Run integrate standalone when you want to see conflicts before the final commit.
Install
The PyPI distribution is gawt (the name gitagent on PyPI is a different,
unrelated project). The command it installs is still called gitagent.
# end user (isolated environment)
pipx install gawt
# or
uv tool install gawt
# from GitHub
pipx install "git+https://github.com/david-fm/gawt"
# local development
git clone https://github.com/david-fm/gawt && cd gawt
uv tool install . -e # or: pipx install -e .
Requires Python 3.11+ and a working git on PATH.
Quick start (Option B)
gitagent init
gitagent start --feature "auth-rate-limiting"
# each subagent gets an isolated worktree + ephemeral branch
gitagent spawn --id a_backend --role "implement limiter"
gitagent spawn --id a_tests --role "write tests"
# subagents work in their own folders, then propose (no commit to .git)
gitagent propose --agent a_backend --title "Token bucket limiter" --confidence 0.85
gitagent propose --agent a_tests --title "Limiter tests" --confidence 0.9
# superagent reviews and marks decisions
gitagent proposals
gitagent show p_7f3a
gitagent accept p_7f3a
gitagent revise p_9b2c --feedback "add edge cases"
# ... a_tests re-proposes (a new pid is generated) ...
gitagent accept p_9b2c
# OPTIONAL: pre-flight apply to surface conflicts before committing
gitagent integrate
# consolidate into ONE commit on the current branch, then reset
gitagent finalize --message "feat(auth): add rate limiting with tests"
# → 1 local commit on HEAD, .gitagent reset, no push
Commands
| Command | Description |
|---|---|
init |
Create .gitagent/ and add it to .gitignore. |
start --feature <name> |
Open a session anchored at current HEAD. |
status [--json] |
Show session, agents, proposals, integration state. |
log [--json] |
Append-only audit trail (log.jsonl). |
abort |
Discard everything: remove worktrees/branches, reset .gitagent. |
spawn --id <id> [--base <ref>] [--role ...] |
Create an isolated worktree for a subagent. |
list-agents [--json] |
List agents. |
kill <id> |
Remove an agent's worktree and ephemeral branch. |
propose --agent <id> --title ... [--summary ...] [--confidence 0..1] |
Capture worktree changes as a patch proposal. |
proposals [--json] |
List proposals + review state. |
show <id> |
Show a proposal's diff (color). |
diff <id> |
Print a proposal's raw diff (pipe-friendly, for LLMs). |
accept <id> |
Mark a proposal as accepted (decision only; does not apply). |
reject <id> [--reason ...] |
Reject a proposal (patch not applied). |
revise <id> --feedback ... |
Send a proposal back for another iteration. |
integrate [--json] |
Apply all accepted proposals onto the integration branch; detect conflicts. |
finalize --message ... [--sign] [--no-reset] |
Call integrate + produce one commit on the current branch + reset .gitagent. Never pushes. |
install-skill |
Install the bundled gitagent agent skill into ~/.agents/skills/gitagent. |
How it works
- Isolation:
git worktree addgives every agent its ownHEAD, index and working tree while sharing the object store — ideal for parallelism. - Proposals as patches:
git -C <worktree> diff --cached <base_sha> --binaryis stored aschange.patchand re-applied withgit apply --3wayon the integration worktree. Agent "commits" never pollute the final history. - Integration order = proposal creation order: the first agent to
proposeintegrates first. Plan who proposes first if their change is the "base" others depend on. - Single commit:
finalizedoesgit merge --squash <integration-branch>on the current branch and creates exactly one commit, then removes all worktrees/branches and resets.gitagent(the audit log is kept). - Conflicts: a conflicting patch is marked
conflictatintegratetime — the session stays alive so the superagent canrevise, fix the integration worktree manually (then re-accept+ re-integrate), orabort. - Concurrency: file locks (
fcntl) guard review-state writes;acceptis safe to race (it only marks). - Audit: every event is appended to
.gitagent/log.jsonl(parseable by another agent/LLM). - Dual output: humans get Rich tables;
--jsonanddiffgive raw, pipe-friendly output for orchestration.
Layout
.gitagent/
├── session.json # active session: id, feature, base_sha, state
├── agents/<agent-id>/
│ ├── meta.json # role, worktree path, ephemeral branch, state
│ └── worktree/ # git worktree for this agent
├── proposals/<proposal-id>/
│ ├── manifest.json # agent, base_sha, files, summary, confidence
│ ├── change.patch # git diff of the proposal
│ └── review.json # pending|accepted|integrated|rejected|revise|conflict + feedback
├── integration/worktree/ # integration branch under construction
├── locks/ # fcntl lockfiles for concurrent writes
└── log.jsonl # append-only audit trail
Proposal states: pending → accepted → integrated | conflict | revise | rejected.
Session states: open → integrating → finalized | aborted.
Installing the agent skill
gitagent ships with a skill so any AI agent can use it freely — it teaches another agent the full CLI surface, the Option B decision/application split, conflict resolution recipes, and the supervisor/coder/reviewer patterns.
The skill lives in the repo at skills/gitagent/ (SKILL.md + AGENTS.md) and gets installed into the local opencode skills directory so future agent sessions can load it.
From a gitagent install (pipx / pip / uv tool)
gitagent install-skill
# → installs bundled skill to ~/.agents/skills/gitagent
# → re-run to refresh after upgrading gitagent
From a git clone (developers / source installs)
git clone https://github.com/david-fm/gawt
cd gitagent
make install-skill
# (equivalent to: bash scripts/install-skill.sh)
Manual
cp -R skills/gitagent ~/.agents/skills/
The skill will be available to agents in future sessions. Re-run any of the above commands to refresh the installed copy.
Design principle
finalizenever runsgit push. It produces the local commit and stops. Pushing is entirely the user's responsibility.
License
MIT © David Florez Mazuera
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gawt-0.1.0.tar.gz.
File metadata
- Download URL: gawt-0.1.0.tar.gz
- Upload date:
- Size: 30.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07880f81ea1d82df66f413a1c6c33ee1a726155dcd36b5a3323dacf21db88de2
|
|
| MD5 |
7a0d0d100101f502927edbbb8ddbcaa8
|
|
| BLAKE2b-256 |
08b673c901249ee37ab5a648350bbe6f2da8b9f7c2d1a0502962c29e533dea9a
|
Provenance
The following attestation bundles were made for gawt-0.1.0.tar.gz:
Publisher:
release.yml on david-fm/gawt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gawt-0.1.0.tar.gz -
Subject digest:
07880f81ea1d82df66f413a1c6c33ee1a726155dcd36b5a3323dacf21db88de2 - Sigstore transparency entry: 2099491655
- Sigstore integration time:
-
Permalink:
david-fm/gawt@b7b950dfaeec92c9f915b384e369a2bf8e95e565 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/david-fm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b7b950dfaeec92c9f915b384e369a2bf8e95e565 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gawt-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gawt-0.1.0-py3-none-any.whl
- Upload date:
- Size: 31.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52b557776fe22dc58e3573b2df8d6ff37f5e0b3f5199bf61efbc850d378b5436
|
|
| MD5 |
3d0dac89fe437a4fbbbe0b3add59f827
|
|
| BLAKE2b-256 |
e5467bd2d0ba5cd727e68b68ac673e172b647e4a9a2acb0d864fa8dcb62da0ca
|
Provenance
The following attestation bundles were made for gawt-0.1.0-py3-none-any.whl:
Publisher:
release.yml on david-fm/gawt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gawt-0.1.0-py3-none-any.whl -
Subject digest:
52b557776fe22dc58e3573b2df8d6ff37f5e0b3f5199bf61efbc850d378b5436 - Sigstore transparency entry: 2099492090
- Sigstore integration time:
-
Permalink:
david-fm/gawt@b7b950dfaeec92c9f915b384e369a2bf8e95e565 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/david-fm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b7b950dfaeec92c9f915b384e369a2bf8e95e565 -
Trigger Event:
push
-
Statement type: