- Shell 97.3%
- Python 2.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Found during the 5-issue live fleet run on masante-test-repo (#36-40): 1. agent_spawn: the .cmd file lives under $RUN_DIR/meta/<session>.cmd where the session name contains a slash (bullet-owner/repo-c-36) — cp failed silently and the agent got an empty prompt. mkdir -p the dirname first. 2. preflight: a coder whose tmux session DIES (crash/kill) while the issue stays bullet:running was invisible forever — the stall loop only sees LIVE sessions. New sweep: running issue + no coder session = relaunch from committed state, announce it. Live-verified: #36 relaunched, finished, reviewed (verdict bound to the commit, head moved -> automatic re-review fired), integrated. Run result: 5/5 issues done, 5 merges into bullet-develop (incl. one real conflict solved by the conflict-solver agent), gates green, rolling PR #41 mergeable=true. |
||
| .bullet | ||
| docs | ||
| examples | ||
| hermes | ||
| skills/bullet | ||
| tests | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
🔫 bullet
Plug and play autonomous issue→PR fleet. One command to wire a repo, one label to queue an issue, and your issues are automatically done — implemented, reviewed by a second model, gate-checked, and opened as a PR. Max 10 agents. Humans merge.
No server, no database, no framework. Bash + curl + jq + tmux + git worktrees. The forge (Forgejo or GitHub) is the only state store: labels are the state machine.
The loop
queued ──launch──▶ running ──DONE comment──▶ review ──REVIEW: CLEAN/FIXED──▶ done ──gates+push──▶ PR
▲ │ │ │
└── human removes blocked / edits issue ◀─────┘◀── REVIEW: NEEDS-DECISION ────────────────┘ (human merges)
- One action per tick.
bullet tick(cron every 15–30 min, or your AI agent) does preflight → one transition → report line. Crash-safe: every step idempotent, all state in forge labels + git worktrees + tmux sessions. - Who pushes, who merges — the exact boundary:
- Agents (coder/fixer) push only their own issue branch (
issue/N-…). Nothing else. - The orchestrator auto-merges per-issue PRs into
bullet-develop— after the full gate suite ran green on the merged tree. This is the one machine merge. - Humans merge the ONE rolling PR (
bullet-develop→ trunk). No agent or orchestrator ever pushes trunk or merges that PR. Refs #Neverywhere; closing keywords are banned; issues close by human hand.
- Agents (coder/fixer) push only their own issue branch (
- Reviewer is a different model from the coder, fresh session each round, judges the diff against the issue — not the coder's report. Every verdict binds to the commit it examined.
Install & use (30 seconds)
npx skills add EduarD3V/bullet
# any git host (private Forgejo included):
npx skills add https://git.eduard3v.com/EduarD3V/bullet.git
Then, inside your repo, tell your agent:
/bullet solve my issues
The agent resolves the skill (skills/bullet/SKILL.md — the operating manual), runs bullet doctor, and drains the queue tick by tick. First run in a fresh repo: it offers bullet init —
creates .bullet/ (config + per-repo skill), gitignores runtime dirs, and tells you before
creating the five state labels on the forge.
Quickstart (manual, 5 minutes)
# 1. Get bullet (or use npx skills add above — same files)
git clone https://git.eduard3v.com/EduarD3V/bullet.git
export PATH=/path/to/bullet/skills/bullet:$PATH
# 2. Plug into your repo — creates .bullet/ (config + skill), labels, doctor, cron line
export BULLET_TOKEN=<forge token with issues+PR write>
bullet init /path/to/your-repo
# 3. Edit /path/to/your-repo/.bullet/bullet.yaml (gates, models, branches)
bullet doctor /path/to/your-repo
# 4. Wire the cron (printed by init), or let your AI agent run `bullet tick`
*/30 * * * * BULLET_TOKEN=… bullet tick /path/to/your-repo >> /path/to/your-repo/.bullet/logs/tick.log 2>&1
# 5. Label an issue `bullet:queued`. That's it — next tick claims it.
Status anytime: bullet status /path/to/your-repo.
What's inside
| Path | What |
|---|---|
bullet |
entrypoint: init · tick · status · doctor · labels |
skills/bullet/ |
the whole fleet — this dir is what npx skills add installs (self-contained) |
skills/bullet/SKILL.md |
the skill: /bullet solve my issues — agent operating manual |
skills/bullet/law/ |
composable agent law: hard-law, comment-policy, plan-first, gates, budget, refs-not-closes, reviewer-law |
<repo>/.bullet/ |
per-repo home: bullet.yaml (config) · AGENT.md (per-repo agent guide) · state/ meta/ worktrees/ logs/ (runtime, gitignored) |
skills/bullet/orchestrator/ |
one script per phase: init · preflight · launch · monitor · review · publish · status · doctor · labels |
skills/bullet/lib/ |
forge.sh (Forgejo+GitHub API), state.sh (the only label writer), agent.sh, tmux.sh, config.sh, compose.py (prompt assembler) |
skills/bullet/prompts/ |
role prompts: coder, reviewer, fixer — each composed from role + law files |
docs/ |
USE-CASES.md · FEATURES.md · STATE-MACHINE.md · PLUG-AND-PLAY.md |
hermes/bullet-fleet.md |
install as a Hermes skill to let an AI drive bullet |
The 10-agent fleet
agents: in .bullet/bullet.yaml (hard cap 10, enforced per tick). Slots auto-split ~70% coder /
20% reviewer / 10% fixer. Each agent = one tmux session (bullet-<repo>-<role>-<issue>) in one git
worktree (.bullet/worktrees/issue-<N>). The cap is global across repos. See agents/README.md.
Per-repo skill
bullet init writes .bullet/AGENT.md into the target repo: this repo's commands, paths, label
law (including the labels-missing → announce-then-create rule), and operating loop. Any AI
agent that reads the repo can then drive the fleet — cron optional.
Design rules (the scars that shaped them)
- The forge is the database. No state files to corrupt; reconcile = re-read labels.
- One action per tick. Long-running work lives in tmux agents, not in the scheduler.
- Labels written by exactly one thing —
state.sh. Agents comment, they never relabel. - Never silent mutation. Missing labels are announced, then created.
BULLET_DRY_RUN=1rehearses. - Plan-first, comment at four moments, gates before push,
Refs #Nneverfixes #N. - Humans merge. (Set
merge: autoif you really want the fleet to close the loop itself.)
Provenance
Battle-tested law distilled from the gotoi/masante agent loops (40+ unattended runs) and the best open patterns: issue-orchestrator (labels-as-state-machine, gates, human merge), claude-squad (tmux + worktree per agent), vigilante/ariadne (headless CLI agents, isolation).
License
MIT