@muggleai/works 4.11.3 → 4.12.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/dist/{chunk-7WRAMBOS.js → chunk-2DVZ2LYO.js} +7 -2
- package/dist/{chunk-AYWLYB3F.js → chunk-I4VLYJ7M.js} +45 -12
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/scripts/ensure-electron-app.sh +29 -4
- package/dist/plugin/skills/_shared/github-cli-recipes/line-comments-for-review.md +8 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/loop-user-identity.md +9 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/pr-edit.md +8 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/pr-metadata.md +12 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/push-to-branch.md +10 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/reply-line-comment.md +10 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/submitted-reviews.md +15 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/top-level-comment.md +7 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/unresolved-threads.md +33 -0
- package/dist/plugin/skills/_shared/github-cli-recipes/verify-working-tree.md +17 -0
- package/dist/plugin/skills/_shared/github-cli-recipes.md +20 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers/allow-list.md +53 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers/classify.md +48 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers/reply-routing.md +40 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers.md +8 -146
- package/dist/plugin/skills/_shared/telemetry-events/muggle-do-cycle.md +25 -0
- package/dist/plugin/skills/_shared/telemetry-events/muggle-do-escalation.md +19 -0
- package/dist/plugin/skills/_shared/telemetry-events/muggle-do-resolve-reminder.md +19 -0
- package/dist/plugin/skills/_shared/telemetry-events/pr-followup-bootstrap.md +20 -0
- package/dist/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +23 -0
- package/dist/plugin/skills/_shared/telemetry-events.md +15 -0
- package/dist/plugin/skills/do/address-reviews.md +137 -0
- package/dist/plugin/skills/do/build.md +5 -5
- package/dist/plugin/skills/do/open-prs/forward.md +80 -0
- package/dist/plugin/skills/do/open-prs/update.md +54 -0
- package/dist/plugin/skills/do/open-prs.md +6 -102
- package/dist/plugin/skills/do/per-comment-replies.md +61 -0
- package/dist/plugin/skills/do/resolve-reminder.md +70 -0
- package/dist/plugin/skills/muggle-do/SKILL.md +41 -45
- package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +25 -0
- package/dist/plugin/skills/muggle-pr-followup/SKILL.md +21 -43
- package/dist/plugin/skills/muggle-pr-followup/bootstrap.md +88 -0
- package/dist/plugin/skills/muggle-pr-followup/contract.md +44 -161
- package/dist/plugin/skills/muggle-pr-followup/output-templates/bootstrap.md +42 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/escalation.md +32 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/help.md +17 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/inline-reply.md +17 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/resolve-reminder.md +12 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates/watcher-log.md +21 -0
- package/dist/plugin/skills/muggle-pr-followup/output-templates.md +14 -0
- package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +104 -0
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +3 -3
- package/dist/release-manifest.json +4 -4
- package/dist/{src-NJUUHKPW.js → src-ARTTHWNP.js} +1 -1
- package/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/scripts/ensure-electron-app.sh +29 -4
- package/plugin/skills/_shared/github-cli-recipes/line-comments-for-review.md +8 -0
- package/plugin/skills/_shared/github-cli-recipes/loop-user-identity.md +9 -0
- package/plugin/skills/_shared/github-cli-recipes/pr-edit.md +8 -0
- package/plugin/skills/_shared/github-cli-recipes/pr-metadata.md +12 -0
- package/plugin/skills/_shared/github-cli-recipes/push-to-branch.md +10 -0
- package/plugin/skills/_shared/github-cli-recipes/reply-line-comment.md +10 -0
- package/plugin/skills/_shared/github-cli-recipes/submitted-reviews.md +15 -0
- package/plugin/skills/_shared/github-cli-recipes/top-level-comment.md +7 -0
- package/plugin/skills/_shared/github-cli-recipes/unresolved-threads.md +33 -0
- package/plugin/skills/_shared/github-cli-recipes/verify-working-tree.md +17 -0
- package/plugin/skills/_shared/github-cli-recipes.md +20 -0
- package/plugin/skills/_shared/pr-followup-helpers/allow-list.md +53 -0
- package/plugin/skills/_shared/pr-followup-helpers/classify.md +48 -0
- package/plugin/skills/_shared/pr-followup-helpers/reply-routing.md +40 -0
- package/plugin/skills/_shared/pr-followup-helpers.md +8 -146
- package/plugin/skills/_shared/telemetry-events/muggle-do-cycle.md +25 -0
- package/plugin/skills/_shared/telemetry-events/muggle-do-escalation.md +19 -0
- package/plugin/skills/_shared/telemetry-events/muggle-do-resolve-reminder.md +19 -0
- package/plugin/skills/_shared/telemetry-events/pr-followup-bootstrap.md +20 -0
- package/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +23 -0
- package/plugin/skills/_shared/telemetry-events.md +15 -0
- package/plugin/skills/do/address-reviews.md +137 -0
- package/plugin/skills/do/build.md +5 -5
- package/plugin/skills/do/open-prs/forward.md +80 -0
- package/plugin/skills/do/open-prs/update.md +54 -0
- package/plugin/skills/do/open-prs.md +6 -102
- package/plugin/skills/do/per-comment-replies.md +61 -0
- package/plugin/skills/do/resolve-reminder.md +70 -0
- package/plugin/skills/muggle-do/SKILL.md +41 -45
- package/plugin/skills/muggle-pr-followup/CLAUDE.md +25 -0
- package/plugin/skills/muggle-pr-followup/SKILL.md +21 -43
- package/plugin/skills/muggle-pr-followup/bootstrap.md +88 -0
- package/plugin/skills/muggle-pr-followup/contract.md +44 -161
- package/plugin/skills/muggle-pr-followup/output-templates/bootstrap.md +42 -0
- package/plugin/skills/muggle-pr-followup/output-templates/escalation.md +32 -0
- package/plugin/skills/muggle-pr-followup/output-templates/help.md +17 -0
- package/plugin/skills/muggle-pr-followup/output-templates/inline-reply.md +17 -0
- package/plugin/skills/muggle-pr-followup/output-templates/resolve-reminder.md +12 -0
- package/plugin/skills/muggle-pr-followup/output-templates/watcher-log.md +21 -0
- package/plugin/skills/muggle-pr-followup/output-templates.md +14 -0
- package/plugin/skills/muggle-pr-followup/state-schemas.md +104 -0
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +3 -3
- package/scripts/postinstall.mjs +36 -5
|
@@ -1,72 +1,68 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-do
|
|
3
|
-
description: Unified Muggle AI workflow entry point. Use when user types muggle do or asks for autonomous implementation to PR.
|
|
3
|
+
description: Unified Muggle AI workflow entry point. Use when user types muggle do or asks for autonomous implementation to PR. Also handles the `address-reviews` directive (dispatched by the muggle-pr-followup watcher when new submitted reviews land on a PR).
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Muggle Test Do
|
|
8
8
|
|
|
9
|
-
> Telemetry first step: see [
|
|
9
|
+
> Telemetry first step: see [`../_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-do"`.
|
|
10
10
|
|
|
11
|
-
Runs an autonomous dev cycle from requirements to PR. **Fire and review:**
|
|
11
|
+
Runs an autonomous dev cycle from requirements to PR. **Fire and review:** user answers one pre-flight questionnaire, then walks away. The [muggle-pr-followup](../muggle-pr-followup/SKILL.md) watcher invokes `/muggle-do` again with the *address-reviews* directive when new reviews land.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Forward pipeline (fresh feature)
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
15
|
+
| # | Stage | File |
|
|
16
|
+
| :- | :---- | :--- |
|
|
17
|
+
| 1 | Pre-flight (only user-facing stage) | [`../do/pre-flight.md`](../do/pre-flight.md) |
|
|
18
|
+
| 2 | Requirements | [`../do/requirements.md`](../do/requirements.md) |
|
|
19
|
+
| 3 | Build | [`../do/build.md`](../do/build.md) |
|
|
20
|
+
| 4 | Impact analysis | [`../do/impact-analysis.md`](../do/impact-analysis.md) |
|
|
21
|
+
| 5 | Unit tests | [`../do/unit-tests.md`](../do/unit-tests.md) |
|
|
22
|
+
| 6 | E2E acceptance | [`../do/e2e-acceptance.md`](../do/e2e-acceptance.md) |
|
|
23
|
+
| 7 | Create or update PR | [`../do/open-prs.md`](../do/open-prs.md) |
|
|
24
|
+
| 8 | Hand off to watcher | [`../muggle-pr-followup/SKILL.md`](../muggle-pr-followup/SKILL.md) |
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
Stage 7 dispatches one watcher per opened PR as its last action.
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
| :- | :---- | :--- | :----------- |
|
|
23
|
-
| 1 | Pre-flight | [../do/pre-flight.md](../do/pre-flight.md) | **Yes — one consolidated turn** |
|
|
24
|
-
| 2 | Requirements | [../do/requirements.md](../do/requirements.md) | No |
|
|
25
|
-
| 3 | Build | [../do/build.md](../do/build.md) | No |
|
|
26
|
-
| 4 | Impact analysis | [../do/impact-analysis.md](../do/impact-analysis.md) | No |
|
|
27
|
-
| 5 | Unit tests | [../do/unit-tests.md](../do/unit-tests.md) | No |
|
|
28
|
-
| 6 | E2E acceptance | [../do/e2e-acceptance.md](../do/e2e-acceptance.md) | No |
|
|
29
|
-
| 7 | Open PR | [../do/open-prs.md](../do/open-prs.md) | No |
|
|
30
|
-
| 8 | PR follow-up | [../muggle-pr-followup/SKILL.md](../muggle-pr-followup/SKILL.md) (generic) — invoked with muggle-do's cycle declaration | **Yes — only on ambiguous reviews** |
|
|
28
|
+
## Address-reviews flow
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
When invoked with the directive (PR URL + slug + review ids), routes to [`../do/address-reviews.md`](../do/address-reviews.md). Shares stages 3–6 + walkthrough with the forward pipeline; skips pre-flight, requirements, and PR creation. See the orchestrator for the cycle's exact step order, classification rules, and respawn logic.
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
## Input routing
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
Inspect `$ARGUMENTS` in this order:
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
1. **Address-reviews** — input contains a `github.com/.../pull/<n>` URL **and** one or more integers ≥ 100000000 (review id shape) → [`../do/address-reviews.md`](../do/address-reviews.md). Programmatic; never ask.
|
|
37
|
+
2. **Empty / `help` / `menu` / `?`** → menu + session selector.
|
|
38
|
+
3. **Task automation** (perform an action on a website) → `muggle:muggle-do-task`.
|
|
39
|
+
4. **Otherwise** → forward pipeline at Stage 1.
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
When in doubt between #3 and #4, ask one question.
|
|
43
42
|
|
|
44
|
-
##
|
|
45
|
-
|
|
46
|
-
Treat `$ARGUMENTS` as the user command:
|
|
43
|
+
## Preferences
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- **Feature development** (build / fix / refactor code) → start or resume a dev-cycle session.
|
|
45
|
+
| Preference | Gate |
|
|
46
|
+
| :--------- | :--- |
|
|
47
|
+
| `autoE2ETest` | Stage 6 — run E2E every cycle (default `always`), or fold into pre-flight |
|
|
52
48
|
|
|
53
|
-
|
|
49
|
+
`autoUseWorktree`, `autoRebase`, `autoCreatePR`, `autoCleanup` fire from per-stage files.
|
|
54
50
|
|
|
55
51
|
## Session model
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
`.muggle-do/sessions/<slug>/`. Schemas: [`../muggle-pr-followup/state-schemas.md`](../muggle-pr-followup/state-schemas.md).
|
|
58
54
|
|
|
59
|
-
| File |
|
|
60
|
-
| :--- |
|
|
61
|
-
| `state.md` | Stage 1
|
|
62
|
-
| `iterations/<NNN>.md` | Every stage |
|
|
63
|
-
| `requirements.md` | Stage 2
|
|
64
|
-
| `prs.json`, `last_seen.json`, `followup.log` | Stage
|
|
65
|
-
| `result.md` | Stage 7 (seeded),
|
|
55
|
+
| File | Owner |
|
|
56
|
+
| :--- | :---- |
|
|
57
|
+
| `state.md` | Stage 1 or bootstrap |
|
|
58
|
+
| `iterations/<NNN>.md` | Every stage |
|
|
59
|
+
| `requirements.md` | Stage 2 (forward only) |
|
|
60
|
+
| `prs.json`, `last_seen.json`, `followup.log` | Stage 7 / watcher / `/muggle-do` |
|
|
61
|
+
| `result.md` | Stage 7 (seeded), terminal tick (finalized) |
|
|
66
62
|
|
|
67
63
|
## Guardrails
|
|
68
64
|
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
65
|
+
- Stage 1 is the only user-facing forward stage. Stages 2–7 don't ask mid-cycle; blocker → pre-flight bug.
|
|
66
|
+
- Same stage failing 3× → escalate.
|
|
67
|
+
- 3 cycle iterations reach E2E with failures → ship with `[E2E FAILING]`.
|
|
68
|
+
- Address-reviews escalation (ambiguous or design-adjustment) does not block the watcher; user resolves on GitHub.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# muggle-pr-followup — folder TOC
|
|
2
|
+
|
|
3
|
+
This folder holds the watcher loop for PR review follow-ups. The watcher is a **dumb pipe**: it polls for new submitted reviews and dispatches `/muggle-do` when there are any. Cycle execution, classification, replies, and escalation all live in `/muggle-do`'s address-reviews mode — see [stage-8 design](../../../../muggle-ai-brain/architecture/2026-05-08-muggle-do-pr-comment-loop-design.md) for the architectural rationale.
|
|
4
|
+
|
|
5
|
+
## Files in this folder
|
|
6
|
+
|
|
7
|
+
- [`SKILL.md`](SKILL.md) — public entry. Smart-inference routing between bootstrap mode (URL input) and tick mode (slug + PR number). Read first.
|
|
8
|
+
- [`bootstrap.md`](bootstrap.md) — the bootstrap procedure (one-shot non-interactive seed + watcher dispatch).
|
|
9
|
+
- [`contract.md`](contract.md) — the watcher per-tick procedure (poll → dispatch → exit).
|
|
10
|
+
- [`state-schemas.md`](state-schemas.md) — canonical JSON shapes of session state files.
|
|
11
|
+
- [`output-templates.md`](output-templates.md) — TOC of message templates; per-group files in `output-templates/`.
|
|
12
|
+
|
|
13
|
+
## Cross-folder dependencies
|
|
14
|
+
|
|
15
|
+
Shared with other skills, under `../_shared/`:
|
|
16
|
+
|
|
17
|
+
- [`pr-followup-helpers.md`](../_shared/pr-followup-helpers.md) — TOC of allow-list / reply-routing / classify; per-section files in `_shared/pr-followup-helpers/`. Called by `/muggle-do`, not by this folder.
|
|
18
|
+
- [`telemetry-emit.md`](../_shared/telemetry-emit.md) — how to emit a telemetry event.
|
|
19
|
+
- [`telemetry-events.md`](../_shared/telemetry-events.md) — TOC of canonical event shapes; per-event files in `_shared/telemetry-events/`.
|
|
20
|
+
- [`github-cli-recipes.md`](../_shared/github-cli-recipes.md) — TOC of reusable `gh` / `git` snippets; per-recipe files in `_shared/github-cli-recipes/`.
|
|
21
|
+
|
|
22
|
+
Caller-specific, under `../do/`:
|
|
23
|
+
|
|
24
|
+
- [`open-prs.md`](../do/open-prs.md) — TOC for the create-or-update PR stage; per-mode files in `do/open-prs/`.
|
|
25
|
+
- [`resolve-reminder.md`](../do/resolve-reminder.md) — `/muggle-do`'s post-replies stage that posts the resolve-reminder top-level comment.
|
|
@@ -1,59 +1,37 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-pr-followup
|
|
3
|
-
description:
|
|
3
|
+
description: Watcher loop for PR review follow-ups. Polls one PR for new submitted reviews and dispatches `/muggle-do` (address-reviews mode) when there are any. A dumb pipe — no classification, no cycle execution, no replies. Use `/loop 1m /muggle:muggle-pr-followup <slug> <pr-number>` for ongoing polling, or `/muggle:muggle-pr-followup <pr-url>` to bootstrap a fresh watcher on an existing PR.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# muggle-pr-followup
|
|
8
8
|
|
|
9
|
-
> Telemetry first step: see [
|
|
9
|
+
> Telemetry first step: see [`../_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-pr-followup"`.
|
|
10
10
|
|
|
11
|
-
A
|
|
11
|
+
A watcher that babysits one open PR's review thread. Polls for new submitted reviews; when any land, hands them off to `/muggle-do` and exits. `/muggle-do` is the executor — it classifies the reviews, runs the work, pushes, replies per comment, and respawns the watcher.
|
|
12
12
|
|
|
13
|
-
**
|
|
13
|
+
**The watcher is a dumb pipe.** It does not classify reviews, iterate cycles, post replies, or escalate. All of that lives in `/muggle-do`. See [stage-8 design](../../../../muggle-ai-brain/architecture/2026-05-08-muggle-do-pr-comment-loop-design.md) for the rationale.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
**Per-PR isolation.** One watcher per PR. Multi-PR work runs N independent watchers.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
## Routing
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
- One argument → ambiguous; list PRs under that slug, exit.
|
|
21
|
-
- Two arguments → resolve and run one tick.
|
|
19
|
+
The skill recognizes two modes by inspecting `$ARGUMENTS` and falling back to on-disk state. It never runs procedure inline — it identifies the mode and routes to the appropriate procedure file.
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
| Input | On-disk check | Mode |
|
|
22
|
+
| :---- | :------------ | :--- |
|
|
23
|
+
| First arg matches `https?://github\.com/[^/]+/[^/]+/pull/\d+` | — | **bootstrap** → [`bootstrap.md`](bootstrap.md) |
|
|
24
|
+
| `<slug> <pr-number>` | session dir for `<slug>` exists | **tick** → [`contract.md`](contract.md) |
|
|
25
|
+
| `<slug> <pr-number>` | session dir missing | **error:** "no session at `<path>`; pass a PR URL to start one" |
|
|
26
|
+
| `<pr-number>` alone | exactly one existing session contains it | **tick** for that PR |
|
|
27
|
+
| `<pr-number>` alone | zero or multiple matches | **error:** ambiguous; list candidates and exit |
|
|
28
|
+
| empty / `help` / `?` | — | **help:** list active loops per [`output-templates/help.md`](output-templates/help.md) |
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
Bootstrap accepts two optional trailing flags:
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
- `--slug=<name>` — override the default `<repo>-pr<n>` slug
|
|
33
|
+
- `--resume` — opt in to reusing an existing session slot (default is refuse on conflict)
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
## Folder TOC
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
"cycleName": "muggle-do dev cycle",
|
|
34
|
-
"steps": [
|
|
35
|
-
{ "stage": 3, "file": "../do/build.md" },
|
|
36
|
-
{ "stage": 4, "file": "../do/impact-analysis.md" },
|
|
37
|
-
{ "stage": 5, "file": "../do/unit-tests.md" },
|
|
38
|
-
{ "stage": 6, "file": "../do/e2e-acceptance.md" },
|
|
39
|
-
{ "name": "post-walkthrough", "skill": "muggle-pr-visual-walkthrough", "mode": "A" }
|
|
40
|
-
],
|
|
41
|
-
"pushHandler": "git push origin <branch>"
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
The cycle's job: read the amended `requirements.md`, run each declared step, push to the existing branch. The cycle returns one of `pushed | escalated | failed`. The skill doesn't care what's inside the steps — it just iterates them, captures the outcome, and writes a reply summary referencing the new SHA.
|
|
46
|
-
|
|
47
|
-
Callers without a `cycle.json` are rejected with `no cycle declared — caller must seed cycle.json at dispatch time`.
|
|
48
|
-
|
|
49
|
-
## Subagent dispatch (optional)
|
|
50
|
-
|
|
51
|
-
A caller may declare `"useSubagent": true` in `cycle.json`. When set, the implementation cycle runs as a separate Claude subagent rather than inline in the loop's tick — gives stronger isolation per PR but adds overhead per cycle. Default is inline (which is itself isolated per-tick via `/loop`).
|
|
52
|
-
|
|
53
|
-
## Design adjustment escalation
|
|
54
|
-
|
|
55
|
-
When the implementation cycle reports back that the review requires not just code change but a **design adjustment** beyond what the current requirements support (e.g. the build stage discovers the requested change conflicts with a load-bearing assumption), the cycle returns `failed: design-adjustment`. The loop treats this like an ambiguous escalation but with a different terminal message that points at the design conflict and asks the user to decide.
|
|
56
|
-
|
|
57
|
-
## Why a separate skill (and not e.g. inside the caller's own skill folder)
|
|
58
|
-
|
|
59
|
-
`/loop` dispatches via slash command; slash commands resolve to top-level skills under `plugin/skills/`. A per-tick loop driven by `/loop` therefore has to live as a top-level skill. Putting the loop's content directly inside a caller-specific folder would make `/loop`-dispatch impossible (or fragile via shell-only entry points). Keeping the loop generic and caller-agnostic is what lets `/loop` dispatch into it cleanly.
|
|
37
|
+
See [`CLAUDE.md`](CLAUDE.md) for the one-line index of every file in this folder.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Bootstrap Procedure
|
|
2
|
+
|
|
3
|
+
The procedure for the **bootstrap mode** of `muggle-pr-followup` — invoked when a user dispatches the skill with a GitHub PR URL. Routing into this mode is documented in [`SKILL.md`](SKILL.md#routing).
|
|
4
|
+
|
|
5
|
+
Bootstrap is **non-interactive**: it runs straight through, prompts the user for nothing, and ends with the first watcher dispatched. The first review the watcher sees triggers `/muggle-do`, where working-tree validation surfaces (via the existing E2E stage / muggle-test).
|
|
6
|
+
|
|
7
|
+
## Turn preamble
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
**muggle-pr-followup bootstrap** — seeding state for <owner>/<repo>#<n>.
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
`$ARGUMENTS = <pr-url> [--slug=<name>] [--resume]`
|
|
16
|
+
|
|
17
|
+
- `<pr-url>` matches `https?://github\.com/[^/]+/[^/]+/pull/\d+` — required.
|
|
18
|
+
- `--slug=<name>` overrides the default `<repo>-pr<n>` slug.
|
|
19
|
+
- `--resume` opts into refreshing an existing slot instead of refusing on conflict.
|
|
20
|
+
|
|
21
|
+
## Procedure
|
|
22
|
+
|
|
23
|
+
### Step 1 — Parse the URL
|
|
24
|
+
|
|
25
|
+
Extract `<owner>`, `<repo>`, `<pr-number>`. On malformed input, exit with the malformed-URL abort from [`output-templates/bootstrap.md`](output-templates/bootstrap.md).
|
|
26
|
+
|
|
27
|
+
### Step 2 — Fetch PR metadata
|
|
28
|
+
|
|
29
|
+
Per [`../_shared/github-cli-recipes/pr-metadata.md`](../_shared/github-cli-recipes/pr-metadata.md).
|
|
30
|
+
|
|
31
|
+
If `state` is `MERGED` or `CLOSED`, exit with the terminal-PR abort. If the `gh` call fails (not found, auth missing), surface the underlying error verbatim and exit.
|
|
32
|
+
|
|
33
|
+
### Step 3 — Verify the working tree
|
|
34
|
+
|
|
35
|
+
Per [`../_shared/github-cli-recipes/verify-working-tree.md`](../_shared/github-cli-recipes/verify-working-tree.md). On any check failure, exit with the wrong-working-tree abort.
|
|
36
|
+
|
|
37
|
+
### Step 4 — Resolve the slug
|
|
38
|
+
|
|
39
|
+
Default: `<repo>-pr<n>` (e.g. `muggle-ai-works-pr154`). Override: `--slug=<name>`. Session dir is `.muggle-do/sessions/<slug>/` relative to the caller's working tree.
|
|
40
|
+
|
|
41
|
+
### Step 5 — Idempotency check
|
|
42
|
+
|
|
43
|
+
If `.muggle-do/sessions/<slug>/` exists:
|
|
44
|
+
|
|
45
|
+
- Without `--resume` → exit with the slot-conflict abort. Both remedies (delete + re-run, or pass `--resume`) are spelled out in the message.
|
|
46
|
+
- With `--resume` → refresh `prs.json[0].head_sha` to the current `headRefOid` from Step 2. Leave `last_seen.json`, `state.md`, and everything else untouched. Skip to Step 8 (no need to re-seed; no need to refetch the cursor).
|
|
47
|
+
|
|
48
|
+
### Step 6 — Resolve the initial cursor
|
|
49
|
+
|
|
50
|
+
Fetch reviews per [`../_shared/github-cli-recipes/submitted-reviews.md`](../_shared/github-cli-recipes/submitted-reviews.md) with cursor 0, then take `max(id)`. If none, the cursor is 0. The watcher only acts on `id > cursor`, so this pins forward-only.
|
|
51
|
+
|
|
52
|
+
### Step 7 — Seed state files
|
|
53
|
+
|
|
54
|
+
Identify the loop user once per [`../_shared/github-cli-recipes/loop-user-identity.md`](../_shared/github-cli-recipes/loop-user-identity.md); cache in `state.md`.
|
|
55
|
+
|
|
56
|
+
Write under `.muggle-do/sessions/<slug>/`:
|
|
57
|
+
|
|
58
|
+
**`prs.json`** — see [`state-schemas.md`](state-schemas.md#prsjson). One entry, `state` = `"open"`, `head_sha` from Step 2's `headRefOid`.
|
|
59
|
+
|
|
60
|
+
**`last_seen.json`** — see [`state-schemas.md`](state-schemas.md#last_seenjson). One key (`"<owner>/<repo>#<n>"`), `reviewId` from Step 6, `last_pushed_sha: null`, `idle_tick_count: 0`, `cycles_completed: 0`, `escalated_review_ids: []`, `pushed_shas: []`.
|
|
61
|
+
|
|
62
|
+
**`state.md`** — see [`state-schemas.md`](state-schemas.md#statemd). `Bootstrapped from URL: yes`. Cache the loop-user login.
|
|
63
|
+
|
|
64
|
+
Do **not** write `cycle.json` or `requirements.md` — those files are no longer part of the session slot.
|
|
65
|
+
|
|
66
|
+
Create `iterations/` subdir (empty) for future caller use.
|
|
67
|
+
|
|
68
|
+
### Step 8 — Dispatch the first watcher
|
|
69
|
+
|
|
70
|
+
The last action of this turn:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
/loop 1m /muggle:muggle-pr-followup <slug> <n>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 9 — Print the success summary
|
|
77
|
+
|
|
78
|
+
Use the success-summary template from [`output-templates/bootstrap.md`](output-templates/bootstrap.md). Print it **before** the `/loop` dispatch so it's visible.
|
|
79
|
+
|
|
80
|
+
### Step 10 — Emit telemetry
|
|
81
|
+
|
|
82
|
+
Emit one event per [`../_shared/telemetry-events/pr-followup-bootstrap.md`](../_shared/telemetry-events/pr-followup-bootstrap.md). `caller = "user"` for direct invocation. Fire-and-forget per [`../_shared/telemetry-emit.md`](../_shared/telemetry-emit.md).
|
|
83
|
+
|
|
84
|
+
## Invariants
|
|
85
|
+
|
|
86
|
+
- All state writes happen in Step 7 — earlier aborts leave nothing on disk.
|
|
87
|
+
- If Step 7 fails mid-write, surface the OS error and tell the user to `rm -rf <slot>` and re-run; do not dispatch the watcher.
|
|
88
|
+
- Bootstrap never retries.
|
|
@@ -1,190 +1,73 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Watcher Per-Tick Contract
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The procedure for the **tick mode** of `muggle-pr-followup` — one polling iteration scoped to one PR. The watcher is a dumb pipe: it polls for new submitted reviews, dispatches `/muggle-do` if there are any, and exits. It does not classify, amend requirements, post replies, run cycles, or escalate.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
**PR follow-up** — polling <repo>#<pr-number>, tick #<K>.
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Resolve `<K>` from `idle_tick_count + cycles_completed` in this PR's state slot.
|
|
12
|
-
|
|
13
|
-
## When this contract may break the caller's "no questions" rule
|
|
14
|
-
|
|
15
|
-
Most callers' forward pipelines never ask the user mid-cycle. This loop, however, may emit a single escalation message when a submitted review is ambiguous (see [classify](#step-6-classify-the-review) below). By the time the loop is polling, the user has walked away from the forward pipeline; forcing a guess on an ambiguous review is worse than pausing.
|
|
16
|
-
|
|
17
|
-
Escalation is the **only** user-facing path. Otherwise the cycle runs silently end to end.
|
|
18
|
-
|
|
19
|
-
## Inputs
|
|
20
|
-
|
|
21
|
-
Read these from `.muggle-<caller>/sessions/<slug>/` (the caller's session dir):
|
|
5
|
+
Routing into this mode is documented in [`SKILL.md`](SKILL.md#routing). The architectural rationale lives in the brain doc `architecture/2026-05-08-muggle-do-pr-comment-loop-design.md`.
|
|
22
6
|
|
|
23
|
-
|
|
24
|
-
- `prs.json` — list of `{repo, number, url, head_sha, state, escalated?, cycling?}`. This loop touches only the entry whose `number` matches the dispatched PR number.
|
|
25
|
-
- `last_seen.json` — keyed by `"<owner>/<repo>#<n>"`. For this PR: `{reviewId, last_pushed_sha, idle_tick_count, cycles_completed, escalated_review_ids[]}`.
|
|
26
|
-
- `cycle.json` — caller's declared implementation cycle (see [SKILL.md](SKILL.md#caller-supplied-implementation-cycle)).
|
|
27
|
-
|
|
28
|
-
If any of these don't exist or the PR isn't in `prs.json`, the tick is a no-op — log an error to `followup.log` and exit.
|
|
29
|
-
|
|
30
|
-
## Per-tick contract
|
|
31
|
-
|
|
32
|
-
### Step 1: Refresh this PR's state
|
|
7
|
+
## Turn preamble
|
|
33
8
|
|
|
34
|
-
```bash
|
|
35
|
-
gh pr view <number> --repo <repo> --json state,mergedAt,closedAt,headRefOid
|
|
36
9
|
```
|
|
37
|
-
|
|
38
|
-
If `state` is `MERGED` or `CLOSED`, mark this entry terminal in `prs.json`. Update `head_sha` if it changed.
|
|
39
|
-
|
|
40
|
-
### Step 2: Termination check
|
|
41
|
-
|
|
42
|
-
If this PR is terminal: write a per-PR section into `result.md` (URL, final state, `cycles_completed`, count escalated, final SHA), emit final telemetry, **do not schedule another tick**. Other PRs in the session have their own loops; they terminate independently.
|
|
43
|
-
|
|
44
|
-
### Step 3: Resolve the reviewer allow-list (every tick)
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
gh pr view <number> --repo <repo> --json reviewRequests,author
|
|
10
|
+
**muggle-pr-followup tick** — polling <repo>#<pr-number>.
|
|
48
11
|
```
|
|
49
12
|
|
|
50
|
-
|
|
13
|
+
## Input
|
|
51
14
|
|
|
52
|
-
|
|
15
|
+
`$ARGUMENTS = <slug> <pr-number>` (or `<pr-number>` alone — slug inferred from on-disk state per [`SKILL.md`](SKILL.md#routing)).
|
|
53
16
|
|
|
54
|
-
|
|
55
|
-
gh api repos/<owner>/<repo>/pulls/<number>/reviews --paginate
|
|
56
|
-
```
|
|
17
|
+
## Inputs from disk
|
|
57
18
|
|
|
58
|
-
|
|
19
|
+
Read these from `.muggle-do/sessions/<slug>/`:
|
|
59
20
|
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
-
- `user.login` is in the allow-list.
|
|
63
|
-
- `id` is not in `escalated_review_ids`.
|
|
64
|
-
- `state` is `CHANGES_REQUESTED` or `COMMENTED`, OR `APPROVED` with at least one line comment or a non-empty body.
|
|
21
|
+
- `prs.json` — see [`state-schemas.md`](state-schemas.md#prsjson). The watcher touches the single entry whose `number` matches the dispatched PR number.
|
|
22
|
+
- `last_seen.json` — see [`state-schemas.md`](state-schemas.md#last_seenjson). Keyed by `"<owner>/<repo>#<n>"`.
|
|
65
23
|
|
|
66
|
-
|
|
24
|
+
If either file is missing or the PR is not in `prs.json`, the tick is a no-op. Log an error line in `followup.log` and exit. The watcher must not be invoked in this state — if it happens, the slot is corrupt.
|
|
67
25
|
|
|
68
|
-
|
|
26
|
+
## Procedure
|
|
69
27
|
|
|
70
|
-
|
|
28
|
+
### Step 1 — Refresh PR state
|
|
71
29
|
|
|
72
|
-
|
|
30
|
+
Per [`../_shared/github-cli-recipes/pr-metadata.md`](../_shared/github-cli-recipes/pr-metadata.md). Update `prs.json[0].head_sha` and `prs.json[0].state` from the response.
|
|
73
31
|
|
|
74
|
-
### Step
|
|
32
|
+
### Step 2 — Termination check
|
|
75
33
|
|
|
76
|
-
|
|
34
|
+
If `state` is `MERGED` or `CLOSED`:
|
|
77
35
|
|
|
78
|
-
|
|
79
|
-
|
|
36
|
+
1. Mark the entry terminal in `prs.json`.
|
|
37
|
+
2. Write `result.md` per [`state-schemas.md`](state-schemas.md#resultmd).
|
|
38
|
+
3. Append a terminal line to `followup.log` per [`output-templates/watcher-log.md`](output-templates/watcher-log.md).
|
|
39
|
+
4. Emit a `tick` event with `terminal: true` per [`../_shared/telemetry-events/pr-followup-tick.md`](../_shared/telemetry-events/pr-followup-tick.md).
|
|
40
|
+
5. Exit. **Do not schedule another tick.** The `/loop` framework stops invoking this skill once it sees no follow-up dispatch.
|
|
80
41
|
|
|
81
|
-
### Step
|
|
42
|
+
### Step 3 — Fetch new submitted reviews
|
|
82
43
|
|
|
83
|
-
|
|
44
|
+
Per [`../_shared/github-cli-recipes/submitted-reviews.md`](../_shared/github-cli-recipes/submitted-reviews.md). **Also exclude review ids that appear in `last_seen.escalated_review_ids`** — those have already been escalated and the watcher must not re-dispatch them.
|
|
84
45
|
|
|
85
|
-
|
|
86
|
-
2. **Amend `requirements.md`** in the session dir with a new `## Amendment — review <review_id> by <login> (<timestamp>)` section pasting the review body and each comment (with `<file>:<line>` context).
|
|
87
|
-
3. **Invoke the implementation cycle** declared in the caller's `cycle.json`. Iterate the `steps[]` in order. Each step is either a markdown file to follow, a skill to invoke, or a shell command (per the `cycle.json` schema in SKILL.md). When a step fails, the cycle returns `failed: <step-name>`; the loop escalates per Step 8 with the failure as the reason.
|
|
88
|
-
4. **Push** via `cycle.json`'s `pushHandler`. Set `last_seen.last_pushed_sha` to the new HEAD.
|
|
89
|
-
5. **Reply** per [helpers § Reply routing](../_shared/pr-followup-helpers.md#reply-routing) and [§ Classify](../_shared/pr-followup-helpers.md#classify) (reply shape). For each line comment in the review, derive `<attribution>` from `git diff <last_pushed_sha>..HEAD -- <comment.path>` near `comment.line` ±5 (fall back to `addressed indirectly — see walkthrough` if empty). `<status>` = `ran clean` or `had <N> failures, see walkthrough`. If the review is body-only (no line comments), post the top-level fallback shape; if both body and line comments, threaded replies cover it — no top-level.
|
|
90
|
-
6. **Resume polling**: clear `cycling: true`, increment `cycles_completed`, advance `last_seen.reviewId` past this review.
|
|
91
|
-
7. Emit per-cycle telemetry.
|
|
46
|
+
### Step 4 — If zero new reviews → idle
|
|
92
47
|
|
|
93
|
-
|
|
48
|
+
1. Increment `last_seen.idle_tick_count`.
|
|
49
|
+
2. Append an idle line to `followup.log` per [`output-templates/watcher-log.md`](output-templates/watcher-log.md).
|
|
50
|
+
3. Emit a `tick` event with `idle: true`, `reviews_seen: 0`, `dispatched_review_ids: []`.
|
|
51
|
+
4. Exit. The next tick fires in 1 min via `/loop`.
|
|
94
52
|
|
|
95
|
-
### Step
|
|
53
|
+
### Step 5 — If one or more new reviews → dispatch
|
|
96
54
|
|
|
97
|
-
|
|
55
|
+
The watcher does **not** classify. Classification, batching, replying, escalation, and cycle execution all live in `/muggle-do`. The watcher's job is to hand over the list of new review ids and exit.
|
|
98
56
|
|
|
99
|
-
1.
|
|
100
|
-
2.
|
|
101
|
-
|
|
102
|
-
|
|
57
|
+
1. Reset `last_seen.idle_tick_count` to 0.
|
|
58
|
+
2. Dispatch `/muggle-do` with an *address-reviews* directive carrying:
|
|
59
|
+
- PR URL (from `prs.json[0].url`)
|
|
60
|
+
- Session slug (from the invocation arguments)
|
|
61
|
+
- Every new review id from Step 3, as a space-separated list
|
|
103
62
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Comments:
|
|
112
|
-
- <file>:<line> — <quoted comment body>
|
|
113
|
-
|
|
114
|
-
[For ambiguous]
|
|
115
|
-
Best two interpretations:
|
|
116
|
-
1. <one-line interpretation A>
|
|
117
|
-
2. <one-line interpretation B>
|
|
118
|
-
|
|
119
|
-
[For cycle failure]
|
|
120
|
-
The implementation cycle failed at <step-name>: <reason>.
|
|
121
|
-
|
|
122
|
-
Reply on the review yourself, leave a follow-up comment, or tell me which way to go.
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
The user clears the escalation by replying on GitHub (next tick sees a new submitted review past the cursor) or by giving a directive in this terminal session.
|
|
126
|
-
|
|
127
|
-
### Step 9: Emit tick-summary telemetry and exit
|
|
128
|
-
|
|
129
|
-
Emit one tick event per `muggle-local-telemetry-skill-emit`. Exit the turn.
|
|
130
|
-
|
|
131
|
-
## Reply routing
|
|
132
|
-
|
|
133
|
-
- **Threaded reply per line comment** (default): `POST /repos/{owner}/{repo}/pulls/{n}/comments/{comment_id}/replies`. Use for every line comment in the review so each thread can be resolved in GitHub's UI.
|
|
134
|
-
- **Top-level summary on a body-only review** (fallback): `gh pr comment <number> --body "..."` referencing the review id and the new SHA. Used only when the review has body content and zero line comments — GitHub has no "reply to a review body" endpoint.
|
|
135
|
-
- **Never post the same reply twice** — `last_seen.reviewId` is the only re-entry guard.
|
|
136
|
-
- **Never post a top-level summary alongside threaded replies** — duplication pollutes the Conversation tab.
|
|
137
|
-
|
|
138
|
-
## Telemetry
|
|
139
|
-
|
|
140
|
-
**Per-cycle** (one event per actionable review handled):
|
|
141
|
-
|
|
142
|
-
```json
|
|
143
|
-
{
|
|
144
|
-
"skill": "muggle-pr-followup",
|
|
145
|
-
"event": "cycle",
|
|
146
|
-
"caller": "<caller>",
|
|
147
|
-
"session_slug": "<slug>",
|
|
148
|
-
"repo": "<repo>",
|
|
149
|
-
"pr_number": <n>,
|
|
150
|
-
"review_id": <id>,
|
|
151
|
-
"outcome": "pushed|escalated|failed:<step>",
|
|
152
|
-
"comment_count": <count>,
|
|
153
|
-
"head_sha_before": "<sha>",
|
|
154
|
-
"head_sha_after": "<sha-or-null>"
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
**Per-tick summary** (always one, even idle):
|
|
159
|
-
|
|
160
|
-
```json
|
|
161
|
-
{
|
|
162
|
-
"skill": "muggle-pr-followup",
|
|
163
|
-
"event": "tick",
|
|
164
|
-
"session_slug": "<slug>",
|
|
165
|
-
"repo": "<repo>",
|
|
166
|
-
"pr_number": <n>,
|
|
167
|
-
"reviews_seen": <count>,
|
|
168
|
-
"review_picked": true|false,
|
|
169
|
-
"cycle_dispatched": true|false,
|
|
170
|
-
"tick_duration_ms": <ms>
|
|
171
|
-
}
|
|
172
|
-
```
|
|
63
|
+
Exact phrasing belongs to `/muggle-do`'s intent-routing. A reasonable shape is:
|
|
64
|
+
```
|
|
65
|
+
/muggle-do address reviews <id1> <id2> ... on <pr-url> slug=<slug>
|
|
66
|
+
```
|
|
67
|
+
3. Append a dispatching line to `followup.log` per [`output-templates/watcher-log.md`](output-templates/watcher-log.md).
|
|
68
|
+
4. Emit a `tick` event with `reviews_seen: <count>`, `dispatched_review_ids: [<id>, ...]`.
|
|
69
|
+
5. Exit. **Do not schedule another tick.** `/muggle-do` will respawn the watcher at the end of its cycle.
|
|
173
70
|
|
|
174
71
|
## Output
|
|
175
72
|
|
|
176
|
-
|
|
177
|
-
- The turn preamble (always).
|
|
178
|
-
- An escalation terminal message (only when escalating).
|
|
179
|
-
- The final `result.md` summary section for this PR (only on the terminating tick — written to disk, not printed).
|
|
180
|
-
|
|
181
|
-
## Self-check before ending the turn
|
|
182
|
-
|
|
183
|
-
- [ ] `last_seen.json` advanced for any review handled.
|
|
184
|
-
- [ ] `prs.json` reflects current state (terminal marked; `escalated`/`cycling` flags consistent).
|
|
185
|
-
- [ ] `followup.log` has at minimum a heartbeat or per-review line for this tick.
|
|
186
|
-
- [ ] Telemetry events emitted (per-cycle when applicable + per-tick).
|
|
187
|
-
- [ ] If pushed, `last_pushed_sha` is set and `cycles_completed` incremented.
|
|
188
|
-
- [ ] If actionable, one threaded reply posted per line comment (or one top-level reply for body-only reviews) — never both, never zero.
|
|
189
|
-
- [ ] If escalated, `escalated_review_ids` contains the review id.
|
|
190
|
-
- [ ] If terminal, the loop is NOT continued.
|
|
73
|
+
No console output beyond the turn preamble and (if Step 5 fires) the `/muggle-do` dispatch. The watcher is invisible to the reviewer.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Bootstrap output templates
|
|
2
|
+
|
|
3
|
+
## Success summary (printed just before dispatch)
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Bootstrapped PR follow-up for <owner>/<repo>#<n>
|
|
7
|
+
Slug: <slug>
|
|
8
|
+
Cursor: review #<id> (forward-only) | empty (no prior reviews)
|
|
9
|
+
Working tree: <toplevel>
|
|
10
|
+
Dispatching: /loop 1m /muggle:muggle-pr-followup <slug> <n>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Aborts
|
|
14
|
+
|
|
15
|
+
**Terminal PR:**
|
|
16
|
+
```
|
|
17
|
+
PR <owner>/<repo>#<n> is <state>; nothing to poll. Bootstrap aborted.
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Wrong working tree / wrong branch:**
|
|
21
|
+
```
|
|
22
|
+
Bootstrap needs the PR's branch checked out locally.
|
|
23
|
+
Current cwd: <toplevel-or-"not in a git repo">
|
|
24
|
+
Current branch: <HEAD-or-"n/a">
|
|
25
|
+
Expected: a clone of <owner>/<repo> on branch <headRefName>.
|
|
26
|
+
From that clone, run: gh pr checkout <n>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Slot conflict (no `--resume`):**
|
|
30
|
+
```
|
|
31
|
+
Session <slug> already exists at <path>.
|
|
32
|
+
To reuse it, pass --resume on this invocation.
|
|
33
|
+
To start fresh, rm -rf the directory and re-run.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Malformed URL:**
|
|
37
|
+
```
|
|
38
|
+
Could not parse <input> as a GitHub PR URL.
|
|
39
|
+
Expected: https://github.com/<owner>/<repo>/pull/<number>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**GitHub API failure (PR not found, no auth, etc.):** repeat the underlying `gh` error verbatim. Do not paraphrase.
|