fleet-agents 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +144 -0
- package/bin/fleet.js +1018 -0
- package/commands/fleet.md +78 -0
- package/package.json +40 -0
- package/prompts/fix.md +46 -0
- package/prompts/research.md +38 -0
- package/prompts/review.md +51 -0
- package/review/README.md +60 -0
- package/review/cli.sh +63 -0
- package/review/coverage.sh +90 -0
- package/review/fix.sh +91 -0
- package/review/lib.sh +258 -0
- package/review/merge.sh +374 -0
- package/review/prompts/fix.md +190 -0
- package/review/prompts/review.md +170 -0
- package/review/review.sh +72 -0
- package/review/sync.sh +15 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Spin up / manage parallel Claude Code agents, each in its own git worktree
|
|
3
|
+
argument-hint: <prompt> | <repo>: <task>; <repo>: <task>... | ls | rm <repo> <task>
|
|
4
|
+
allowed-tools: Bash(fleet:*), Bash(fleet add:*), Bash(fleet ls:*), Bash(fleet rm:*), Bash(fleet kill:*), Bash(fleet skill:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are driving the `fleet` CLI (on PATH) — it creates an isolated git worktree per task
|
|
8
|
+
and launches an interactive `claude` for it (a tmux pane on macOS/Linux, or a separate
|
|
9
|
+
terminal window on Windows). Run it via Bash. Do NOT do the worktree/terminal work yourself.
|
|
10
|
+
|
|
11
|
+
User input: `$ARGUMENTS`
|
|
12
|
+
|
|
13
|
+
## Routing
|
|
14
|
+
|
|
15
|
+
- Empty input, or `ls`/`list`/`status` → run `fleet ls`.
|
|
16
|
+
- `rm`/`remove`/`done <repo> <task>` → `fleet rm <repo> <task> --branch`. This removes that
|
|
17
|
+
worker **and every sub-worker it spawned** (the chain): closes their panes, removes their
|
|
18
|
+
worktrees, deletes branches.
|
|
19
|
+
- `rm self` / `remove self` / "remove this worker" / "remove me" (no repo/task) → run
|
|
20
|
+
`fleet rm --self --branch`. From inside a worker this removes that worker + its sub-worker
|
|
21
|
+
chain (it reads the pane's FLEET_TASK). Only valid inside a worker pane.
|
|
22
|
+
- `kill`/`teardown` → `fleet kill`.
|
|
23
|
+
- `resume …` → `fleet resume …`.
|
|
24
|
+
- Anything else → it's one or more **task launches**. For each, run the **Dispatch decision**.
|
|
25
|
+
|
|
26
|
+
## Dispatch decision (run for EVERY task launch)
|
|
27
|
+
|
|
28
|
+
The user gives a task in plain language (often `<repo>: <what to do>`, or just a prompt;
|
|
29
|
+
multiple tasks separated by `;`/newlines, or a `.md` file path). For each task, decide four
|
|
30
|
+
things, THEN issue one `fleet add`:
|
|
31
|
+
|
|
32
|
+
**1. Repo + slug.** Repo = the name they gave; if none, default to the current repo by
|
|
33
|
+
passing `.`. Only ask if the cwd isn't a git repo or they clearly meant several repos.
|
|
34
|
+
Slug = a short kebab-case name from the description (≤25 chars).
|
|
35
|
+
|
|
36
|
+
**2. Skill** — *you choose it.* Run `fleet skill ls` to see what's registered, then pick the
|
|
37
|
+
single best-fit skill for THIS task, or none:
|
|
38
|
+
- Investigate / trace / "why" / "how does" / audit / debug-only (NO code change wanted)
|
|
39
|
+
→ `research` (it's read-only — only pick it when the user wants understanding, NOT a fix).
|
|
40
|
+
- A user skill whose name/purpose matches the task (e.g. a `refactor` skill for "clean up
|
|
41
|
+
X") → that skill.
|
|
42
|
+
- Nothing fits, or it's a normal implement/fix task → no skill.
|
|
43
|
+
When unsure between a skill and none, prefer none. Briefly say which skill you picked and why.
|
|
44
|
+
|
|
45
|
+
**3. Mode** — how the worker should run:
|
|
46
|
+
- **once** (default) — a one-shot task.
|
|
47
|
+
- **loop** — recurring / polling / monitoring work: "every N min", "keep checking",
|
|
48
|
+
"watch", "babysit the PR", "until CI is green". Seed the worker to start in loop mode.
|
|
49
|
+
- **goal** — a long autonomous push to a definite END-STATE ("keep going until X is done/
|
|
50
|
+
true"). Uses Claude Code's built-in `/goal <condition>`, which sets a Stop hook that
|
|
51
|
+
blocks the worker from stopping until the CONDITION holds (auto-clears when met). Phrase
|
|
52
|
+
the task as the end-state/condition to reach, not an action.
|
|
53
|
+
|
|
54
|
+
**4. Launch** — construct exactly one `fleet add`:
|
|
55
|
+
- once + skill: `fleet add <repo> <slug> "<task>" --skill <name>`
|
|
56
|
+
- once, no skill: `fleet add <repo> <slug> "<task>"` (or a `.md` file path as the prompt)
|
|
57
|
+
- loop: `fleet add <repo> <slug> "/loop <interval-or-blank> <task>"`
|
|
58
|
+
- goal: `fleet add <repo> <slug> "/goal <completion-condition>"` (phrase as end-state)
|
|
59
|
+
For loop/goal, the worker's FIRST message must be the slash command, so do NOT also pass
|
|
60
|
+
`--skill` (it would prepend text before the slash); instead fold any skill guidance into
|
|
61
|
+
the `<task>` text. Append a base branch only if the user named one. Add `--no-worktree`
|
|
62
|
+
only if they want it to run in the repo itself (e.g. read-only research).
|
|
63
|
+
|
|
64
|
+
Launch independent tasks in parallel (multiple `fleet add` calls in one message).
|
|
65
|
+
|
|
66
|
+
## Managing skills
|
|
67
|
+
|
|
68
|
+
If the user asks to register/list/remove skills, use `fleet skill ls | add <name> <file.md>
|
|
69
|
+
| rm <name> | show <name>`.
|
|
70
|
+
|
|
71
|
+
## After launching
|
|
72
|
+
|
|
73
|
+
Report a compact table: `repo/slug` → skill · mode · one-line task. Then remind them:
|
|
74
|
+
- `fleet attach` in a terminal to watch/steer (tmux backend; you can't attach from here).
|
|
75
|
+
- `/fleet ls` for progress, `/fleet rm <repo> <task>` to clean one up when merged.
|
|
76
|
+
|
|
77
|
+
If a `fleet add` fails (e.g. unknown repo), surface the error and suggest a fix rather than
|
|
78
|
+
retrying blindly.
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fleet-agents",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Run multiple Claude Code agents in parallel, each in its own git worktree — tmux on macOS/Linux/WSL, separate terminal windows on Windows.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"fleet": "bin/fleet.js"
|
|
7
|
+
},
|
|
8
|
+
"type": "commonjs",
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"commands/",
|
|
12
|
+
"prompts/",
|
|
13
|
+
"review/",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=16"
|
|
18
|
+
},
|
|
19
|
+
"os": [
|
|
20
|
+
"darwin",
|
|
21
|
+
"linux",
|
|
22
|
+
"win32"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"claude",
|
|
26
|
+
"claude-code",
|
|
27
|
+
"tmux",
|
|
28
|
+
"git-worktree",
|
|
29
|
+
"agents",
|
|
30
|
+
"parallel",
|
|
31
|
+
"ai"
|
|
32
|
+
],
|
|
33
|
+
"homepage": "https://github.com/sanil-23/fleet-agents#readme",
|
|
34
|
+
"bugs": "https://github.com/sanil-23/fleet-agents/issues",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/sanil-23/fleet-agents.git"
|
|
38
|
+
},
|
|
39
|
+
"license": "MIT"
|
|
40
|
+
}
|
package/prompts/fix.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Review-and-fix skill
|
|
2
|
+
|
|
3
|
+
You **finish the work**: review the change, apply the fixes, verify, and commit. A response
|
|
4
|
+
that only *lists* what should be done is a failure. Two phases, both required.
|
|
5
|
+
|
|
6
|
+
## Scope & sanity check
|
|
7
|
+
Work out the change from the task (default: **this branch's diff vs its base**). Check
|
|
8
|
+
`git status` (clean, or only your own work-in-progress), the current branch, and the upstream.
|
|
9
|
+
If the working tree is dirty in a way you didn't expect, **STOP and ask** — never stash or
|
|
10
|
+
discard someone else's work.
|
|
11
|
+
|
|
12
|
+
## Phase 1 — Review & apply fixes
|
|
13
|
+
1. Get the diff + changed files; **read every changed file in full** (context matters — read
|
|
14
|
+
siblings for new files, both paths for moves).
|
|
15
|
+
2. Learn the repo's own standards (`CLAUDE.md` / `AGENTS.md` / configs) and review against the
|
|
16
|
+
axes: correctness, tests, security, design/quality, project standards, docs.
|
|
17
|
+
3. If this is a PR/MR with existing reviewer/bot comments (CodeRabbit, maintainers, inline
|
|
18
|
+
threads), address **every actionable one** — apply it, don't just describe it.
|
|
19
|
+
4. Classify each finding/comment: `actionable-trivial` (fix now) · `actionable-non-trivial`
|
|
20
|
+
(fix if the direction is unambiguous, else defer with a reason) · `already-addressed` ·
|
|
21
|
+
`stale` · `disagree`/`defer-human`/`question` (surface it — never silently dismiss).
|
|
22
|
+
**Re-read the surrounding code before each edit** — state may have drifted since a comment
|
|
23
|
+
was written.
|
|
24
|
+
5. Apply every clearly-directed fix. One logical concern per commit. Don't expand scope.
|
|
25
|
+
|
|
26
|
+
## Phase 2 — Verify & commit
|
|
27
|
+
1. **Detect and run the repo's quality suite** — formatters, typecheck/lint, and tests
|
|
28
|
+
(infer from `package.json` / `Cargo.toml` / `Makefile` / `pyproject.toml` / etc.). Run
|
|
29
|
+
independent suites in parallel; always run the formatter + typecheck when code changed.
|
|
30
|
+
2. If a test fails on an apparent flake, rerun it **once**; if it still fails, STOP and report
|
|
31
|
+
— don't loop.
|
|
32
|
+
3. Commit in **focused commits** (`fix(area): …`, `test(area): …`, `chore: apply formatting`).
|
|
33
|
+
The working tree must be clean before you finish.
|
|
34
|
+
4. If this is a PR/MR and you have push rights, push to update it — plain `git push` to the
|
|
35
|
+
already-configured remote; never invent a different remote or push to `main`. Post any
|
|
36
|
+
deferred / disagree / question items back to the PR so nothing is lost in chat.
|
|
37
|
+
|
|
38
|
+
## Output
|
|
39
|
+
A final report: what was reviewed; each comment/finding → fixed / deferred / disagree with
|
|
40
|
+
`file:line`; a checks table (typecheck / lint / format / tests → pass·fail); the commits made;
|
|
41
|
+
and any outstanding items that need a human.
|
|
42
|
+
|
|
43
|
+
## Guardrails
|
|
44
|
+
Never force-push, push to `main`, skip hooks, amend already-published commits, or run
|
|
45
|
+
destructive git without explicit approval. Never commit secrets. Stop on an unexpected dirty
|
|
46
|
+
tree. Rerun a flake once, then report. Be honest — don't pad with invented issues.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Investigation / debug task — follow this method
|
|
2
|
+
|
|
3
|
+
You are **investigating and debugging — NOT implementing.** Do not modify code, do not
|
|
4
|
+
commit. Your deliverable is a precise findings report. Be thorough and exact; check
|
|
5
|
+
multiple locations before concluding, and prefer reading the real code over guessing.
|
|
6
|
+
|
|
7
|
+
## Method — follow in order
|
|
8
|
+
|
|
9
|
+
1. **Orient by structure first.** `find` the repo tree and `ls` the key directories to
|
|
10
|
+
understand the layout before reading anything (e.g. Rust core in `src/`, React/Tauri app
|
|
11
|
+
in `app/src/`, TS/Node backend). Know where things live first.
|
|
12
|
+
|
|
13
|
+
2. **Locate breadth-first with grep.** Use `grep -rn` (and `-r` / `-n`) across the WHOLE
|
|
14
|
+
repo for the relevant symbols, type/function names, and — crucially — the exact
|
|
15
|
+
user-facing strings/error messages. Cast a wide net; don't anchor on the first directory.
|
|
16
|
+
|
|
17
|
+
3. **Read what grep surfaces and trace the flow END-TO-END.** Open the specific files,
|
|
18
|
+
then follow the data/control flow from entry point → core logic → UI/output across both
|
|
19
|
+
the core and the app layers. Don't stop at the first match — map the whole chain.
|
|
20
|
+
|
|
21
|
+
4. **Pull history + ticket context.** `gh issue view <#>` / `gh pr view <#>` for the
|
|
22
|
+
ticket and reviewer discussion; `git log` / `git show` to see how the code got here and
|
|
23
|
+
what recent PRs (often referenced as "introduced by PR #N") changed.
|
|
24
|
+
|
|
25
|
+
5. **Form a hypothesis, then verify it against the code paths** — not assumptions.
|
|
26
|
+
Reproduce the logic mentally (or via a read-only check / test run) and confirm the exact
|
|
27
|
+
mechanism. Check multiple candidate locations before settling.
|
|
28
|
+
|
|
29
|
+
6. **Report.** Produce a tight findings report:
|
|
30
|
+
- **Root cause** — precise: `file:line` and the exact mechanism.
|
|
31
|
+
- **End-to-end flow** — the chain of files/functions involved, in order.
|
|
32
|
+
- **Evidence** — quote the key code lines.
|
|
33
|
+
- **Symptom origin** — the exact user-facing symptom and where it's produced.
|
|
34
|
+
- **Fix proposal** — what to change and where (do NOT make the change).
|
|
35
|
+
- **Open questions / risks** — anything unverified or worth a second look.
|
|
36
|
+
|
|
37
|
+
If you delegate sub-investigations, have each return precise findings (file:line + the
|
|
38
|
+
mechanism), then synthesize. Stay read-only throughout.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Code review skill
|
|
2
|
+
|
|
3
|
+
You are doing a thorough, CodeRabbit-style code review. This is **READ-ONLY** — do not
|
|
4
|
+
modify code, commit, or push. Produce a precise, honest review with concrete suggested fixes.
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
Work out what to review from the task. If unspecified, review **this branch's diff against
|
|
8
|
+
its base** (`git merge-base` → `git diff <base>...HEAD`); if a PR/MR is named and `gh`/`glab`
|
|
9
|
+
is available, use its diff. Note the added / modified / deleted files.
|
|
10
|
+
|
|
11
|
+
## Method
|
|
12
|
+
1. Get the diff and the full list of changed files.
|
|
13
|
+
2. **Read every changed file in full** — not just the hunks. For new files, read siblings in
|
|
14
|
+
the same directory to learn local conventions; for moves/renames, check both paths.
|
|
15
|
+
Hunk-only reading produces shallow reviews that miss architectural issues.
|
|
16
|
+
3. **Learn the project's own standards** — read `CLAUDE.md` / `AGENTS.md` / `CONTRIBUTING`,
|
|
17
|
+
and the repo's linter/formatter configs, and hold the change to *those* conventions.
|
|
18
|
+
Don't impose external rules the project doesn't follow.
|
|
19
|
+
|
|
20
|
+
## Review axes
|
|
21
|
+
- **Correctness** — logic bugs, off-by-one, null/undefined, async/await misuse, race
|
|
22
|
+
conditions, resource leaks, error propagation and handling.
|
|
23
|
+
- **Tests** — new behavior ships with tests; cover branches and error paths; test behavior
|
|
24
|
+
not implementation; no real network, no time-based flakes.
|
|
25
|
+
- **Security** — credentials/secrets, injection (command / SQL / path traversal / XSS),
|
|
26
|
+
validation at trust boundaries, accidentally committed secret files (`.env`, keys).
|
|
27
|
+
- **Design / quality** — dead code, commented-out blocks, unexplained TODOs, over-abstraction,
|
|
28
|
+
duplication, backwards-compat cruft, "what" comments instead of "why".
|
|
29
|
+
- **Project standards** — whatever the repo's own docs/config require.
|
|
30
|
+
- **Docs / UX** — public APIs and user-facing changes documented; for UI changes, check
|
|
31
|
+
accessibility, keyboard nav, and loading/error/empty states.
|
|
32
|
+
|
|
33
|
+
## Classify each finding
|
|
34
|
+
- **Severity**: `blocker` (must fix) / `major` (should fix) / `minor` / `nitpick` / `question`.
|
|
35
|
+
- **Confidence**: high / medium / low.
|
|
36
|
+
Drop low-confidence minor items — they're noise. Don't repeat what the linter/compiler
|
|
37
|
+
already catches. Don't invent issues to pad the review.
|
|
38
|
+
|
|
39
|
+
## Output
|
|
40
|
+
- A short **walkthrough** (2–4 sentences: what the change does + overall assessment).
|
|
41
|
+
- A **changed-files summary** table.
|
|
42
|
+
- **Actionable findings** grouped by severity. EACH must have `file:line` (or a range) and a
|
|
43
|
+
**concrete before/after suggested fix** — a code block where plausible. "Consider
|
|
44
|
+
refactoring" is not a suggestion.
|
|
45
|
+
- A **nitpicks** list, **questions for the author**, and a **looks-good** section.
|
|
46
|
+
- If a PR/MR is named and you have the CLI for it, you may post the review + inline comments
|
|
47
|
+
and approve / request-changes; otherwise just emit the report.
|
|
48
|
+
|
|
49
|
+
## Guardrails
|
|
50
|
+
Read-only — never edit, commit, or push. Be honest: if it's clean, say so and keep it short.
|
|
51
|
+
Never log secrets or PII in comments.
|
package/review/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# scripts/shortcuts/review
|
|
2
|
+
|
|
3
|
+
Helpers for working through PRs on this repo. Runnable directly — no zshrc
|
|
4
|
+
integration needed.
|
|
5
|
+
|
|
6
|
+
| Script | What it does |
|
|
7
|
+
| ------------ | --------------------------------------------------------------------------------- |
|
|
8
|
+
| `sync.sh` | Fetch PR head, check out as `pr/<num>`, merge `main`, wire push/upstream. |
|
|
9
|
+
| `review.sh` | `sync` + hand off to the `pr-reviewer` agent to review, comment, and approve. |
|
|
10
|
+
| `fix.sh` | `sync` + `pr-reviewer` (apply fixes) + `pr-manager-lite` (commit & push). |
|
|
11
|
+
| `coverage.sh`| `sync` + gather coverage CI context + agent to fix coverage, push, babysit checks.|
|
|
12
|
+
| `merge.sh` | LLM-summarized squash body + filtered Co-authored-by trailers + `gh pr merge`. |
|
|
13
|
+
|
|
14
|
+
## LLM flags
|
|
15
|
+
|
|
16
|
+
- `review` / `fix` / `coverage`: `--agent <tool>` (default `claude`). Picks the
|
|
17
|
+
CLI that drives the agent prompt. An optional trailing positional
|
|
18
|
+
`<extra-prompt>` is appended verbatim to the agent's prompt (e.g.
|
|
19
|
+
`pnpm review fix 123 "focus on the retry logic"`).
|
|
20
|
+
- `merge`: `--summary-llm <tool>` (default `gemini`). The LLM that condenses the PR
|
|
21
|
+
body + commit messages into a concise squash commit body. Use `--summary-llm none`
|
|
22
|
+
to skip summarization and keep the raw PR body.
|
|
23
|
+
|
|
24
|
+
Any tool that accepts `-p "<prompt>"` and prints its response to stdout works.
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
Via pnpm (preferred):
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
pnpm review sync 123
|
|
32
|
+
pnpm review review 123
|
|
33
|
+
pnpm review fix 123
|
|
34
|
+
pnpm review coverage 123
|
|
35
|
+
pnpm review merge 123 # --squash
|
|
36
|
+
pnpm review merge 123 --rebase
|
|
37
|
+
pnpm review --help
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or invoke the scripts directly:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
scripts/shortcuts/review/sync.sh 123
|
|
44
|
+
scripts/shortcuts/review/review.sh 123
|
|
45
|
+
scripts/shortcuts/review/fix.sh 123
|
|
46
|
+
scripts/shortcuts/review/coverage.sh 123
|
|
47
|
+
scripts/shortcuts/review/merge.sh 123
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Config
|
|
51
|
+
|
|
52
|
+
- Repo is derived from the `upstream` remote (falls back to `origin`). Override
|
|
53
|
+
with `REVIEW_REPO=owner/name`.
|
|
54
|
+
- `REVIEW_BANNED_COAUTHOR_RE` overrides the substring regex used to drop
|
|
55
|
+
`Co-authored-by:` entries (default filters copilot / codex / cursor / claude /
|
|
56
|
+
anthropic / openai / chatgpt / `[bot]` / `noreply@github` /
|
|
57
|
+
`users.noreply.github.com`; matched case-insensitively on name or email).
|
|
58
|
+
- Requires `git`, `gh`, `jq`. `review` / `fix` / `coverage` also require the
|
|
59
|
+
agent CLI (default `claude`); `merge` also requires the summary LLM CLI
|
|
60
|
+
(default `gemini`) unless `--summary-llm none`.
|
package/review/cli.sh
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Dispatcher for `pnpm review <cmd> <args…>`.
|
|
3
|
+
# Commands: sync | review | fix | coverage | merge
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
|
|
8
|
+
usage() {
|
|
9
|
+
cat <<EOF
|
|
10
|
+
Usage: pnpm review <command> <pr-number> [args]
|
|
11
|
+
|
|
12
|
+
Commands:
|
|
13
|
+
sync <pr> Check out PR as pr/<num>, merge main, wire remotes
|
|
14
|
+
review <pr> [--agent <tool>] [extra-prompt]
|
|
15
|
+
Sync + pr-reviewer agent (review, comment, approve)
|
|
16
|
+
Default agent: claude
|
|
17
|
+
Trailing extra-prompt is appended to the agent prompt.
|
|
18
|
+
fix <pr> [--agent <tool>] [extra-prompt]
|
|
19
|
+
Sync + pr-reviewer (apply fixes) + pr-manager-lite (push)
|
|
20
|
+
Default agent: claude
|
|
21
|
+
Trailing extra-prompt is appended to the agent prompt.
|
|
22
|
+
coverage <pr> [--agent <tool>] [extra-prompt]
|
|
23
|
+
Sync + gather coverage CI context + agent to fix coverage
|
|
24
|
+
failures, improve coverage, push, and babysit the PR
|
|
25
|
+
Default agent: claude
|
|
26
|
+
Trailing extra-prompt is appended to the agent prompt.
|
|
27
|
+
merge <pr> [--squash|--merge|--rebase] [--dry-run] [--force] [--admin|--auto] [--summary-llm <tool>]
|
|
28
|
+
Merge via gh (default --squash, deletes branch).
|
|
29
|
+
Requires reviewDecision=APPROVED and green required checks
|
|
30
|
+
(mergeStateStatus in CLEAN/UNSTABLE/HAS_HOOKS) — use --force to skip the local gate.
|
|
31
|
+
--admin bypasses branch protection (requires admin rights).
|
|
32
|
+
--auto queues the merge until checks/approvals are satisfied.
|
|
33
|
+
--dry-run prints the squash commit message and exits.
|
|
34
|
+
Default summary LLM: gemini (use 'none' to skip).
|
|
35
|
+
|
|
36
|
+
Env:
|
|
37
|
+
REVIEW_REPO=owner/name Override target repo (default: upstream remote)
|
|
38
|
+
REVIEW_BANNED_COAUTHOR_RE=<regex> Substrings filtered from Co-authored-by lines
|
|
39
|
+
(default includes copilot/codex/cursor/claude/…)
|
|
40
|
+
REVIEW_AGENT_SAFE=1 Run the picked agent CLI bare instead of in
|
|
41
|
+
its "yolo" mode. Default 0 — claude / codex /
|
|
42
|
+
cursor are launched with their skip-permissions
|
|
43
|
+
flag so headless runs don't stall on prompts.
|
|
44
|
+
EOF
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
cmd="${1:-}"
|
|
48
|
+
if [ -z "$cmd" ] || [ "$cmd" = "-h" ] || [ "$cmd" = "--help" ]; then
|
|
49
|
+
usage
|
|
50
|
+
exit 0
|
|
51
|
+
fi
|
|
52
|
+
shift
|
|
53
|
+
|
|
54
|
+
case "$cmd" in
|
|
55
|
+
sync|review|fix|coverage|merge)
|
|
56
|
+
exec "$here/${cmd}.sh" "$@"
|
|
57
|
+
;;
|
|
58
|
+
*)
|
|
59
|
+
echo "[review] unknown command: $cmd" >&2
|
|
60
|
+
usage >&2
|
|
61
|
+
exit 1
|
|
62
|
+
;;
|
|
63
|
+
esac
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# coverage.sh <pr-number> [--agent <tool>] [extra-prompt]
|
|
3
|
+
# Sync the PR locally, gather coverage-related GitHub Actions context, then hand
|
|
4
|
+
# off to an agent to fix coverage gate failures, improve coverage, and babysit
|
|
5
|
+
# the PR until the relevant checks are green or the work is clearly blocked.
|
|
6
|
+
#
|
|
7
|
+
# --agent picks the CLI that drives the work. Default: claude.
|
|
8
|
+
# A trailing positional <extra-prompt> (any free-form text) is appended to the
|
|
9
|
+
# agent's prompt verbatim.
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
# shellcheck source=lib.sh
|
|
14
|
+
source "$here/lib.sh"
|
|
15
|
+
|
|
16
|
+
require git gh jq
|
|
17
|
+
require_pr_number "${1:-}"
|
|
18
|
+
|
|
19
|
+
pr="$1"
|
|
20
|
+
agent="claude"
|
|
21
|
+
extra_prompt=""
|
|
22
|
+
shift
|
|
23
|
+
while [ $# -gt 0 ]; do
|
|
24
|
+
case "$1" in
|
|
25
|
+
--agent) agent="${2:?--agent requires a value}"; shift 2 ;;
|
|
26
|
+
--agent=*) agent="${1#*=}"; shift ;;
|
|
27
|
+
*)
|
|
28
|
+
if [ -n "$extra_prompt" ]; then
|
|
29
|
+
echo "[review] unexpected extra arg: $1 (extra-prompt already set)" >&2
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
extra_prompt="$1"; shift
|
|
33
|
+
;;
|
|
34
|
+
esac
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
require "$agent"
|
|
38
|
+
sync_pr "$pr"
|
|
39
|
+
|
|
40
|
+
coverage_checks=$(gh pr checks "$REVIEW_PR" -R "$REVIEW_REPO_RESOLVED" 2>/dev/null \
|
|
41
|
+
| grep -i 'coverage' || true)
|
|
42
|
+
|
|
43
|
+
# Name of the coverage CI workflow to inspect. Override per-repo with REVIEW_COVERAGE_WORKFLOW.
|
|
44
|
+
COVERAGE_WORKFLOW="${REVIEW_COVERAGE_WORKFLOW:-Coverage}"
|
|
45
|
+
coverage_runs_json=$(gh run list -R "$REVIEW_REPO_RESOLVED" \
|
|
46
|
+
--workflow "$COVERAGE_WORKFLOW" \
|
|
47
|
+
--branch "$REVIEW_HEAD_BRANCH" \
|
|
48
|
+
--limit 5 \
|
|
49
|
+
--json databaseId,status,conclusion,url,createdAt,updatedAt,headSha || echo '[]')
|
|
50
|
+
|
|
51
|
+
coverage_runs_summary=$(printf '%s\n' "$coverage_runs_json" | jq -r '
|
|
52
|
+
if length == 0 then
|
|
53
|
+
"No recent coverage workflow runs found for this branch."
|
|
54
|
+
else
|
|
55
|
+
.[] | "- run=\(.databaseId) status=\(.status) conclusion=\(.conclusion // "n/a") sha=\(.headSha) updated=\(.updatedAt) url=\(.url)"
|
|
56
|
+
end
|
|
57
|
+
')
|
|
58
|
+
|
|
59
|
+
if [ -z "$coverage_checks" ]; then
|
|
60
|
+
coverage_checks="No current coverage-related checks were returned by gh pr checks."
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
prompt="I've already checked out branch pr/$REVIEW_PR with main \
|
|
64
|
+
merged in and upstream tracking set (repo: $REVIEW_REPO_RESOLVED). Focus on the \
|
|
65
|
+
coverage gate for PR #$REVIEW_PR.
|
|
66
|
+
|
|
67
|
+
Current coverage-related PR checks:
|
|
68
|
+
$coverage_checks
|
|
69
|
+
|
|
70
|
+
Recent coverage workflow runs for this branch:
|
|
71
|
+
$coverage_runs_summary
|
|
72
|
+
|
|
73
|
+
Use the GitHub Actions error output for the coverage jobs to identify what is \
|
|
74
|
+
failing. Fix the coverage workflow or scripts if they are broken, improve test \
|
|
75
|
+
coverage as needed to satisfy the gate, run the relevant local checks, and push \
|
|
76
|
+
the fixes back to the PR branch.
|
|
77
|
+
|
|
78
|
+
After pushing, babysit the PR: monitor the coverage and related required checks, \
|
|
79
|
+
investigate any new failures, and keep iterating until the coverage gate is \
|
|
80
|
+
green or you hit a real blocker. If you are blocked, summarize the blocker \
|
|
81
|
+
clearly with the failing check name, exact error, and what remains to fix."
|
|
82
|
+
|
|
83
|
+
if [ -n "$extra_prompt" ]; then
|
|
84
|
+
prompt="${prompt}
|
|
85
|
+
|
|
86
|
+
Additional instructions from the user:
|
|
87
|
+
${extra_prompt}"
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
agent_exec "$agent" "$prompt"
|
package/review/fix.sh
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fix.sh <pr-number> [--agent <tool>] [extra-prompt]
|
|
3
|
+
# Sync the PR locally, then hand a fully-inlined "review + fix + push" prompt
|
|
4
|
+
# to the chosen agent. The prompt is loaded from scripts/shortcuts/review/prompts/fix.md
|
|
5
|
+
# so the workflow is agent-agnostic (no reliance on Claude Code's named
|
|
6
|
+
# subagent registry).
|
|
7
|
+
#
|
|
8
|
+
# --agent picks the CLI that drives the work. Default: claude.
|
|
9
|
+
# A trailing positional <extra-prompt> (any free-form text) is appended to the
|
|
10
|
+
# agent's prompt verbatim.
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
# shellcheck source=lib.sh
|
|
15
|
+
source "$here/lib.sh"
|
|
16
|
+
|
|
17
|
+
require git gh jq
|
|
18
|
+
require_pr_number "${1:-}"
|
|
19
|
+
|
|
20
|
+
pr="$1"
|
|
21
|
+
agent="claude"
|
|
22
|
+
extra_prompt=""
|
|
23
|
+
shift
|
|
24
|
+
while [ $# -gt 0 ]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
--agent) agent="${2:?--agent requires a value}"; shift 2 ;;
|
|
27
|
+
--agent=*) agent="${1#*=}"; shift ;;
|
|
28
|
+
*)
|
|
29
|
+
if [ -n "$extra_prompt" ]; then
|
|
30
|
+
echo "[review] unexpected extra arg: $1 (extra-prompt already set)" >&2
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
extra_prompt="$1"; shift
|
|
34
|
+
;;
|
|
35
|
+
esac
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
require "$agent"
|
|
39
|
+
sync_pr "$pr"
|
|
40
|
+
|
|
41
|
+
if [ "${REVIEW_AUTO_ASSIGN:-1}" = "1" ]; then
|
|
42
|
+
gh_assign_self_pr "$pr" "$REVIEW_REPO_RESOLVED"
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
template="$here/prompts/fix.md"
|
|
46
|
+
if [ ! -f "$template" ]; then
|
|
47
|
+
echo "[review] missing prompt template: $template" >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
if [ "${REVIEW_HAS_CONFLICTS:-0}" = "1" ]; then
|
|
52
|
+
conflict_block="# ⚠️ Merge conflicts to resolve FIRST
|
|
53
|
+
|
|
54
|
+
When the PR branch was merged with current \`main\`, the following files were left with unresolved conflict markers (\`<<<<<<<\` / \`=======\` / \`>>>>>>>\`):
|
|
55
|
+
|
|
56
|
+
$(printf '%s\n' "$REVIEW_CONFLICT_FILES" | sed 's/^/- /')
|
|
57
|
+
|
|
58
|
+
Before doing anything else:
|
|
59
|
+
|
|
60
|
+
1. Read each conflicted file and understand both sides — read surrounding code, recent commits on \`main\`, and the PR's intent before resolving.
|
|
61
|
+
2. Resolve the conflicts by choosing the correct combination of both sides (NOT \`--ours\` / \`--theirs\` blanket strategies and NOT \`git rebase --skip\`).
|
|
62
|
+
3. \`git add\` the resolved files and finish the merge with a clear merge commit: \`git commit --no-edit\` (the conflict-resolution merge message is already staged) — or supply a one-line message if you prefer.
|
|
63
|
+
4. Run formatters / typecheck / tests on the resolved files to confirm nothing regressed.
|
|
64
|
+
|
|
65
|
+
Only after conflicts are cleanly resolved should you proceed to the review/fix workflow below."
|
|
66
|
+
else
|
|
67
|
+
conflict_block=""
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
prompt=$(REVIEW_CONFLICT_BLOCK="$conflict_block" \
|
|
71
|
+
awk -v pr="$REVIEW_PR" -v repo="$REVIEW_REPO_RESOLVED" \
|
|
72
|
+
-v head_repo="$REVIEW_HEAD_REPO" -v head_branch="$REVIEW_HEAD_BRANCH" '
|
|
73
|
+
BEGIN { conflict = ENVIRON["REVIEW_CONFLICT_BLOCK"] }
|
|
74
|
+
{
|
|
75
|
+
gsub(/__PR__/, pr);
|
|
76
|
+
gsub(/__REPO__/, repo);
|
|
77
|
+
gsub(/__HEAD_REPO__/, head_repo);
|
|
78
|
+
gsub(/__HEAD_BRANCH__/, head_branch);
|
|
79
|
+
gsub(/__CONFLICT_BLOCK__/, conflict);
|
|
80
|
+
print
|
|
81
|
+
}
|
|
82
|
+
' "$template")
|
|
83
|
+
|
|
84
|
+
if [ -n "$extra_prompt" ]; then
|
|
85
|
+
prompt="${prompt}
|
|
86
|
+
|
|
87
|
+
# Additional instructions from the user
|
|
88
|
+
${extra_prompt}"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
agent_exec "$agent" "$prompt"
|