@rtorcato/repo-tooling 3.16.1 ā 3.16.3
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.
|
@@ -108,7 +108,7 @@ export async function setupProject(options) {
|
|
|
108
108
|
const interactive = !options.config && !options.preset;
|
|
109
109
|
const dryRun = options.dryRun === true;
|
|
110
110
|
if (interactive && !dryRun) {
|
|
111
|
-
console.log(chalk.cyan('\nš ļø Welcome to
|
|
111
|
+
console.log(chalk.cyan('\nš ļø Welcome to repo-tooling setup!\n'));
|
|
112
112
|
console.log(chalk.gray(`Setting up tooling in: ${targetDir}\n`));
|
|
113
113
|
}
|
|
114
114
|
try {
|
package/package.json
CHANGED
|
@@ -43,14 +43,12 @@ real approvals.
|
|
|
43
43
|
|
|
44
44
|
The same constraint makes everything an agent posts *look* hand-written by the
|
|
45
45
|
owner. So **every comment any agent leaves ā review, blocked, gave-up, declined ā
|
|
46
|
-
opens with a `š¤ *Automated ā¦*` italic header line
|
|
47
|
-
|
|
48
|
-
human's avatar misrepresents who reviewed the code
|
|
46
|
+
opens with a `š¤ *Automated ā¦*` italic header line naming which agent wrote it**,
|
|
47
|
+
then a blank line. Name the agent and stop there: a detailed security review
|
|
48
|
+
under a human's avatar misrepresents who reviewed the code, but *why* it wears
|
|
49
|
+
that avatar is read once and then reread on every comment forever.
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
header names the agent *and* says why it is wearing a human's face:
|
|
52
|
-
|
|
53
|
-
`š¤ *Automated ā <which agent> via ai-issue-loop. Posted under the owner's account by an agent; not a human message. There is no separate GitHub account for AI agents, so this appears under @<owner>'s avatar.*`
|
|
51
|
+
`š¤ *Automated ā <which agent> via ai-issue-loop.*`
|
|
54
52
|
|
|
55
53
|
**Comment budget: ā¤10 lines, and a clean outcome gets no comment at all.** A
|
|
56
54
|
40-line comment on every PR trains the reader to skip all of them, including the
|
|
@@ -63,16 +61,16 @@ drift with a second copy to maintain.
|
|
|
63
61
|
| Clean and ready | **None.** `ai-ok-code, ai-ok-sec` + assigned + no `ai-review` already says it. |
|
|
64
62
|
| `ai-notes` | ā¤10 lines; link the reviewer's `### Before merging`. |
|
|
65
63
|
| `ai-changes`, CI red, `ai-blocked` | ā¤10 lines, action first, then the specific cause. |
|
|
66
|
-
| Reviewer verdict | `### Before merging` plus
|
|
64
|
+
| Reviewer verdict | `### Before merging` plus ā¤600 characters above it. |
|
|
67
65
|
| Declining an issue | The one exception ā a hard handoff needs its reasoning; see Pass 4. |
|
|
68
66
|
|
|
69
67
|
## Labels
|
|
70
68
|
|
|
71
69
|
| Label | On | Meaning |
|
|
72
70
|
|---|---|---|
|
|
73
|
-
| `ai-ready` | issue | Eligible for an agent. The hard gate
|
|
74
|
-
| `ai-wip` | issue | Claimed; a worktree exists. |
|
|
75
|
-
| `ai-blocked` | issue | Agent gave up; needs a human. |
|
|
71
|
+
| `ai-ready` | issue | Eligible for an agent. The hard gate; **cleared on pickup**. |
|
|
72
|
+
| `ai-wip` | issue | Claimed; a worktree exists. Never rides alongside `ai-ready`. |
|
|
73
|
+
| `ai-blocked` | issue | Agent gave up; needs a human. Only a human re-adds `ai-ready`. |
|
|
76
74
|
| `ai-review` | PR | Awaiting agent review. |
|
|
77
75
|
| `ai-reviewing-code` | PR | `code-reviewer` claimed and running. Cleared with its verdict. |
|
|
78
76
|
| `ai-reviewing-sec` | PR | `security-expert` claimed and running. Cleared with its verdict. |
|
|
@@ -400,13 +398,21 @@ Only then:
|
|
|
400
398
|
git -C "$ROOT" worktree remove --force "$WT_DIR" # the path found above, not a rebuilt one
|
|
401
399
|
git -C "$ROOT" branch -D "$BRANCH" 2>/dev/null
|
|
402
400
|
gh issue edit <N> --remove-label ai-wip 2>/dev/null
|
|
401
|
+
# Still OPEN means the PR said only `Refs #N`; a `Closes #N` issue is already closed.
|
|
402
|
+
if [ "$(gh issue view <N> --json state -q .state)" = OPEN ]; then
|
|
403
|
+
gh issue edit <N> --add-assignee @me
|
|
404
|
+
fi
|
|
403
405
|
```
|
|
404
406
|
|
|
405
407
|
A closed-unmerged PR is the exception: there is no squash to find, so skip the
|
|
406
408
|
confirmation and remove ā the work was abandoned deliberately.
|
|
407
409
|
|
|
408
|
-
The issue itself closes from the PR body's `Closes #N
|
|
409
|
-
|
|
410
|
+
The issue itself closes from the PR body's `Closes #N`, so both edits are normally
|
|
411
|
+
no-ops on a closed issue. A PR that said only `Refs #N` leaves it **open**, which is
|
|
412
|
+
what the state check catches. The work has landed, so it must not go back in
|
|
413
|
+
the queue; pickup already dropped `ai-ready`, and assigning it is what stops a
|
|
414
|
+
merged issue sitting unowned instead (#429 had to be moved to `holding` by hand).
|
|
415
|
+
This pass is what frees concurrency slots, so it must run before Pass 4.
|
|
410
416
|
|
|
411
417
|
**Then reap the stalled.** Nothing can time out an agent: the Agent tool takes no
|
|
412
418
|
timeout, and an agent whose session died leaves its labels behind with no process
|
|
@@ -432,13 +438,15 @@ work must never be reaped out from under itself.
|
|
|
432
438
|
The **no PR exists** condition on the first row is what makes reaping safe. An
|
|
433
439
|
agent that got as far as opening a PR has handed off to the label state machine
|
|
434
440
|
and is no longer the thing being waited on; only a run that produced nothing is
|
|
435
|
-
presumed dead.
|
|
436
|
-
|
|
441
|
+
presumed dead. Reaping deliberately does **not** restore `ai-ready` ā `ai-blocked`
|
|
442
|
+
means a human decides when the issue re-enters the queue, and the removed worktree
|
|
443
|
+
means their re-label starts clean. The other two `ai-blocked` exits, Pass 3's
|
|
444
|
+
ping-pong stop and an implementer handing back, leave it off for the same reason.
|
|
437
445
|
|
|
438
446
|
**Every `ai-blocked` must say why, and land in front of a human.** So reaping always
|
|
439
447
|
does three things together ā label, assign, comment ā and the comment opens with
|
|
440
448
|
|
|
441
|
-
`š¤ *Automated ā \`ai-issue-loop\` Pass 2 (stall reaping)
|
|
449
|
+
`š¤ *Automated ā \`ai-issue-loop\` Pass 2 (stall reaping).*`
|
|
442
450
|
|
|
443
451
|
then a blank line. State which stall rule fired, how long the label sat, and whether a
|
|
444
452
|
worktree was removed. A bare `ai-blocked` with no explanation is worse than no label:
|
|
@@ -448,9 +456,12 @@ puts it in the statusline and fires a notification with a sound.
|
|
|
448
456
|
**Reaping is not always the right call ā say so when it isn't.** The rule assumes a
|
|
449
457
|
dead agent, but a stale `ai-wip` can also come from a run that was cancelled
|
|
450
458
|
deliberately, in which case the work is fine and only the claim is stale. If you know
|
|
451
|
-
the cause and it is benign,
|
|
452
|
-
|
|
453
|
-
|
|
459
|
+
the cause and it is benign, **return it to the queue** ā `gh issue edit <N> --add-label
|
|
460
|
+
ai-ready --remove-label ai-wip`, no `ai-blocked` ā so Pass 4 picks it straight back up,
|
|
461
|
+
and say in the comment that you re-queued it, that you deviated, and why. Re-adding
|
|
462
|
+
`ai-ready` is not optional: pickup cleared it, so clearing `ai-wip` alone drops the
|
|
463
|
+
issue out of the queue silently, which is the worse failure. `ai-blocked` means *a
|
|
464
|
+
human must look*; do not spend it on a claim you already understand.
|
|
454
465
|
|
|
455
466
|
### Pass 3 ā review
|
|
456
467
|
|
|
@@ -493,20 +504,19 @@ Reviewer prompt template:
|
|
|
493
504
|
> purpose. Also read the repo's `CLAUDE.md` if the diff plausibly touches a rule
|
|
494
505
|
> it states.
|
|
495
506
|
>
|
|
496
|
-
> `<code-reviewer: Judge correctness, obvious bugs, and adherence to the repo's
|
|
497
|
-
>
|
|
498
|
-
>
|
|
499
|
-
>
|
|
507
|
+
> `<code-reviewer: Judge correctness, obvious bugs, and adherence to the repo's stated
|
|
508
|
+
> conventions.>` / `<security-expert: Judge injection risk, leaked secrets, unsafe
|
|
509
|
+
> shell/SQL construction, and dependency or supply-chain changes.>` That is the
|
|
510
|
+
> checklist to run, not an outline to write up.
|
|
500
511
|
>
|
|
501
512
|
> Post your verdict as a comment ā **never** `--approve`, it errors on your own
|
|
502
513
|
> PR:
|
|
503
514
|
> `gh pr review <N> --comment --body "..."`
|
|
504
515
|
>
|
|
505
|
-
> The body **must** begin with this exact header line, then a blank line
|
|
506
|
-
>
|
|
507
|
-
> a human wrote the review:
|
|
516
|
+
> The body **must** begin with this exact header line, then a blank line ā you
|
|
517
|
+
> authenticate as the repo owner, so without it the review reads as a human's:
|
|
508
518
|
>
|
|
509
|
-
> `š¤ *Automated review ā \`<your agent type>\` via ai-issue-loop
|
|
519
|
+
> `š¤ *Automated review ā \`<your agent type>\` via ai-issue-loop.*`
|
|
510
520
|
>
|
|
511
521
|
> The body **must end** with this section, as its last thing:
|
|
512
522
|
>
|
|
@@ -525,13 +535,14 @@ Reviewer prompt template:
|
|
|
525
535
|
> That section is what a human reads at merge time, so put anything you would
|
|
526
536
|
> want them to know there rather than leaving it in the prose above ā a finding
|
|
527
537
|
> buried mid-paragraph does not survive the handoff. For the same reason, **cap
|
|
528
|
-
> the body at that section plus
|
|
529
|
-
>
|
|
530
|
-
>
|
|
531
|
-
>
|
|
532
|
-
>
|
|
533
|
-
>
|
|
534
|
-
>
|
|
538
|
+
> the body at that section plus ā¤600 characters above it**. Verify everything;
|
|
539
|
+
> narrate only where the PR is **wrong** or **silent**. Never list what you
|
|
540
|
+
> checked and found clean, and never confirm a claim the PR body already makes ā
|
|
541
|
+
> agreement is what the pass label is for, so a review that agrees is nearly
|
|
542
|
+
> empty. The bar is a finding that **changes what a human would do**: a semver
|
|
543
|
+
> implication, a deliberate omission, a follow-up that must be filed. Writing
|
|
544
|
+
> `Nothing.` is a real verdict and the common one ā say it plainly rather than
|
|
545
|
+
> padding to look thorough.
|
|
535
546
|
>
|
|
536
547
|
> Then apply exactly one verdict label, **clearing your claim label in the same
|
|
537
548
|
> command**:
|
|
@@ -633,8 +644,8 @@ package/from/to table survives because it sits at the top; classify from that.
|
|
|
633
644
|
> State in your comment which rule fired, name the packages that tripped it, and say
|
|
634
645
|
> whether the body was truncated so the reader knows what you could and couldn't see.
|
|
635
646
|
> Same `š¤ *Automated review ā ā¦*` header line, same closing `### Before merging`
|
|
636
|
-
> section, same
|
|
637
|
-
> above ā **including clearing your
|
|
647
|
+
> section, same ā¤600-character cap and no-negative-findings rule on the body, and same
|
|
648
|
+
> one-verdict-label rule as above ā **including clearing your
|
|
638
649
|
> `<ai-reviewing-code|ai-reviewing-sec>` claim label in the same `gh pr edit`**.
|
|
639
650
|
> Pass 3 claimed you with it before spawning you, and a claim left behind wedges
|
|
640
651
|
> your half of the review until Pass 2 reaps it.
|
|
@@ -669,7 +680,7 @@ gh api "repos/$OWNER_REPO/issues/<N>/timeline" \
|
|
|
669
680
|
```
|
|
670
681
|
|
|
671
682
|
If that count is **ā„ 3**, stop looping. Comment the reason on the PR ā opening with
|
|
672
|
-
`š¤ *Automated ā \`ai-issue-loop\` Pass 3
|
|
683
|
+
`š¤ *Automated ā \`ai-issue-loop\` Pass 3.*`
|
|
673
684
|
and a blank line ā naming what each round changed and why the reviewer kept objecting,
|
|
674
685
|
then:
|
|
675
686
|
|
|
@@ -738,10 +749,9 @@ same issue gets re-triaged from scratch every time, and the reasoning that took
|
|
|
738
749
|
real work to reach is lost.
|
|
739
750
|
|
|
740
751
|
The comment opens with the standard `š¤ *Automated ā¦*` header ā see the top of this
|
|
741
|
-
file
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
whole value is the reasoning; do not reach for this shape on a PR handoff:
|
|
752
|
+
file. Then, in the body ā **this is the one comment exempt from the ā¤10-line
|
|
753
|
+
budget, and only this one.** Declining is a hard handoff whose whole value is the
|
|
754
|
+
reasoning; do not reach for this shape on a PR handoff:
|
|
745
755
|
|
|
746
756
|
- **Why an agent cannot finish it**, concretely. "Not suitable" is useless. Name
|
|
747
757
|
the blocker: binary assets it cannot author, a force-push past branch
|
|
@@ -769,9 +779,17 @@ Take the first `slots` issues. For each, **claim it first** so a concurrent tick
|
|
|
769
779
|
can't double-pick:
|
|
770
780
|
|
|
771
781
|
```bash
|
|
772
|
-
gh issue edit <N> --add-label ai-wip
|
|
782
|
+
gh issue edit <N> --add-label ai-wip --remove-label ai-ready
|
|
773
783
|
```
|
|
774
784
|
|
|
785
|
+
Dropping `ai-ready` is half the claim, not tidiness ā the diagram above is a
|
|
786
|
+
transition, not an accumulation. An issue left carrying both re-enters the queue
|
|
787
|
+
the instant `ai-wip` clears for any reason other than the PR closing it, and the
|
|
788
|
+
next tick spawns an agent to re-implement work already sitting in an open PR
|
|
789
|
+
(#458, #467, #461, #452, all in one session). Every path that legitimately returns
|
|
790
|
+
an issue to the queue therefore re-adds `ai-ready` explicitly; Pass 2's benign-stall
|
|
791
|
+
path is the only one, and a human does the rest.
|
|
792
|
+
|
|
775
793
|
**Then create the worktree yourself**, before spawning anything. `<slug>` is 3ā4
|
|
776
794
|
kebab-case words from the title:
|
|
777
795
|
|
|
@@ -858,7 +876,7 @@ Then spawn a background implementer agent:
|
|
|
858
876
|
> **must** open with this exact line, then a blank line ā you authenticate as the
|
|
859
877
|
> owner, so without it the issue reads as if they wrote it themselves:
|
|
860
878
|
>
|
|
861
|
-
> `š¤ *Automated ā implementer via ai-issue-loop
|
|
879
|
+
> `š¤ *Automated ā implementer via ai-issue-loop.*`
|
|
862
880
|
>
|
|
863
881
|
> Say what you tried, the exact error, and what a human would need to decide. "Could
|
|
864
882
|
> not finish" with no detail wastes the handoff ā the whole point of the label is that
|