@acme-skunkworks/agent-skills 1.0.0 → 1.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.
Files changed (43) hide show
  1. package/README.md +5 -4
  2. package/package.json +2 -6
  3. package/skills/changelog/README.md +59 -0
  4. package/skills/changelog/SKILL.md +187 -0
  5. package/skills/changelog/config.example.json +5 -0
  6. package/skills/changelog/config.json +5 -0
  7. package/skills/changelog/package.json +31 -0
  8. package/skills/changelog/references/changelog-contract.md +121 -0
  9. package/skills/changelog/scripts/add-links.mjs +97 -0
  10. package/skills/changelog/scripts/lib/changelog.mjs +46 -0
  11. package/skills/changelog/scripts/lib/config.mjs +53 -0
  12. package/skills/changelog/scripts/lib/derive-packages.mjs +39 -0
  13. package/skills/changelog/scripts/lib/frontmatter.mjs +369 -0
  14. package/skills/changelog/scripts/preflight-changelog-ci.mjs +152 -0
  15. package/skills/changelog/scripts/set-affected-packages.mjs +99 -0
  16. package/skills/changelog/scripts/validate-changelog.mjs +264 -0
  17. package/skills/linear-sync/README.md +47 -0
  18. package/skills/linear-sync/SKILL.md +115 -0
  19. package/skills/linear-sync/config.example.json +4 -0
  20. package/skills/linear-sync/config.json +4 -0
  21. package/skills/linear-sync/package.json +31 -0
  22. package/skills/preflight/README.md +70 -0
  23. package/skills/preflight/SKILL.md +148 -0
  24. package/skills/preflight/config.example.json +6 -0
  25. package/skills/preflight/package.json +33 -0
  26. package/skills/preflight/scripts/classify-lint.mjs +176 -0
  27. package/skills/preflight/scripts/lib/diff-lines.mjs +83 -0
  28. package/skills/preflight/scripts/lib/paths.mjs +26 -0
  29. package/skills/preflight/scripts/lib/scope.mjs +530 -0
  30. package/skills/preflight/scripts/lint-fix.mjs +78 -0
  31. package/skills/preflight/scripts/preflight.mjs +416 -0
  32. package/skills/send-it/README.md +75 -0
  33. package/skills/send-it/SKILL.md +391 -0
  34. package/skills/send-it/config.example.json +5 -0
  35. package/skills/send-it/config.json +5 -0
  36. package/skills/send-it/package.json +33 -0
  37. package/skills/send-it/scripts/derive-bump.mjs +139 -0
  38. package/skills/triage-pr/README.md +56 -0
  39. package/skills/triage-pr/SKILL.md +291 -0
  40. package/skills/triage-pr/config.json +4 -0
  41. package/skills/triage-pr/package.json +32 -0
  42. package/skills/triage-pr/references/review-discipline.md +73 -0
  43. package/skills/triage-pr/scripts/review-threads.mjs +549 -0
@@ -0,0 +1,291 @@
1
+ ---
2
+ name: triage-pr
3
+ description: >-
4
+ Drive a pull request from draft with failing CI to merge-ready. While the PR
5
+ is a draft, inspect and fix in-scope CI failures (lint, changeset status,
6
+ manifest-lint, build, tests) using the gh CLI and GitHub Actions logs — never
7
+ weakening CI config to greenwash. After the PR is marked ready-for-review,
8
+ fetch the unresolved AI review threads (Claude Code Review, Bugbot), validate
9
+ each finding against the codebase before changing anything, fix the valid
10
+ ones, decline the invalid ones with technical reasoning, then re-watch CI
11
+ until green. Use when asked to triage a PR, fix failing CI or red checks on a
12
+ PR, address or respond to PR review comments, action Bugbot or Claude review
13
+ feedback, get a PR green, or take a draft PR to merge-ready. Handles
14
+ base-branch drift and in-scope merge conflicts; escalates ambiguous ones.
15
+ license: MIT
16
+ compatibility: >-
17
+ Requires the `gh` CLI (authenticated — `gh auth status` must pass) and `git`.
18
+ The bundled review-thread fetcher needs Node.js >=22 (ES modules).
19
+ Designed for repositories whose AI review runs only on
20
+ ready-for-review PRs (draft-gated), so Phase A and Phase B do not overlap.
21
+ metadata:
22
+ version: 0.1.0
23
+ allowed-tools: Read, Edit, Write, Glob, Grep, Bash(gh:*), Bash(git:*), Bash(node:*), Bash(pnpm:*), Bash(npx:*)
24
+ ---
25
+
26
+ # triage-pr
27
+
28
+ Take a pull request from **draft + failing CI** to **merge-ready**, in two
29
+ phases, choosing the phase from the PR's draft state:
30
+
31
+ - **Phase A — while the PR is a draft:** inspect failing checks, pull GitHub
32
+ Actions logs, and fix failures **in PR scope only**. Loop until CI is green or
33
+ report blockers.
34
+ - **Phase B — after the PR is ready-for-review:** AI review is gated on
35
+ `draft == false`, so once a human flips the PR, reviewers (Claude Code Review,
36
+ Bugbot) post feedback. Fetch the **unresolved** findings, validate each
37
+ against the codebase before changing anything, fix the valid ones, decline the
38
+ invalid ones with technical reasoning, then loop back through Phase A.
39
+
40
+ This skill complements `/send-it` (which **opens** the draft PR). It **never
41
+ flips the PR from draft to ready** — that is the human's call (and the gate that
42
+ turns AI review on). See [`references/review-discipline.md`](references/review-discipline.md)
43
+ for the full review-reception and verification rules folded into Phase B.
44
+
45
+ ## Configuration
46
+
47
+ Two knobs live in [`config.json`](config.json) beside this file. Read it at the
48
+ start of a run and use its values throughout. Edit your copied `config.json` to
49
+ match the consuming repo's review bots.
50
+
51
+ | Key | Meaning | Default |
52
+ | --- | --- | --- |
53
+ | `reviewBots` | GitHub login names whose comments and threads are treated as first-class AI review feedback. Matched against `author.login`; the `[bot]` suffix is normalised, so `claude` and `claude[bot]` both match (the GraphQL API returns the bare form). Edit to match your install — review-bot logins vary per repo. `github-actions` is deliberately excluded by default: it posts CI status and release-PR comments, not code review, so Phase B would otherwise action them as findings; add it only if your install genuinely posts review-type comments via the Actions bot. | `["claude", "cursor", "coderabbitai"]` |
54
+ | `maxCiRounds` | Maximum Phase-A re-watch iterations before stopping and reporting blockers. Bounds the fix-and-watch loop so it can't spin forever. | `5` |
55
+
56
+ Only the configured `reviewBots` are actioned in Phase B. Human review comments
57
+ are surfaced in the final report but never auto-actioned, replied to, or
58
+ resolved — leave those for the human.
59
+
60
+ ## Usage modes
61
+
62
+ **Auto** — detect the current branch's PR and its phase, then run:
63
+
64
+ ```bash
65
+ triage-pr
66
+ ```
67
+
68
+ **Explicit PR** — operate on a specific PR by number or URL:
69
+
70
+ ```bash
71
+ triage-pr 123
72
+ ```
73
+
74
+ **CI only** — run Phase A and stop, even if the PR is ready:
75
+
76
+ ```bash
77
+ triage-pr --ci-only
78
+ ```
79
+
80
+ **Dry run** — report failing checks and unresolved findings and propose fixes,
81
+ but change nothing (no commits, no pushes, no thread replies):
82
+
83
+ ```bash
84
+ triage-pr --dry-run
85
+ ```
86
+
87
+ ## Process
88
+
89
+ ### Step 1 — Locate the PR and detect the phase
90
+
91
+ ```bash
92
+ gh pr view <pr> --json number,isDraft,state,headRefName,baseRefName,mergeable,mergeStateStatus,statusCheckRollup
93
+ ```
94
+
95
+ - Resolve the PR from the argument, or from the current branch when none is
96
+ given. If `gh pr view` finds no PR, stop and tell the user to open one with
97
+ `/send-it` first.
98
+ - `isDraft == true` → **Phase A only**. When CI is green, report and stop (do not
99
+ attempt Phase B; AI review has not run yet, and this skill never flips the PR
100
+ to ready).
101
+ - `isDraft == false` → **Phase A** (confirm/clear CI), then **Phase B**.
102
+ - Record `baseRefName` for the drift checks and `mergeStateStatus` for conflict
103
+ detection.
104
+
105
+ ### Step 2 — Phase A: inspect failing checks
106
+
107
+ ```bash
108
+ gh pr checks <pr>
109
+ ```
110
+
111
+ For each failed Actions check, resolve its run ID from the check's `detailsUrl`
112
+ (in `statusCheckRollup`) and read the failing step's logs:
113
+
114
+ ```bash
115
+ gh run view <run-id> --log-failed
116
+ ```
117
+
118
+ Capture the **actual failing command and error lines**, not just the check name.
119
+ You are diagnosing a root cause, not pattern-matching a label.
120
+
121
+ ### Step 3 — Phase A: classify each failure (in-scope vs upstream)
122
+
123
+ ```bash
124
+ git fetch origin <base>
125
+ git diff --name-only origin/<base>...HEAD # files this PR actually touches
126
+ ```
127
+
128
+ - **In-scope** — the failure names files in this PR's diff, or is a lint / test /
129
+ build failure reproducible on the branch head. Fix it (Step 4).
130
+ - **Upstream / base drift** — the job also fails on `origin/<base>` independent of
131
+ this diff, **or** `mergeStateStatus == BEHIND`, **or** the error names files the
132
+ PR never touched. Remedy is to rebase/merge the base (Step 5), **not** to edit
133
+ the failing code.
134
+ - A failure that can only be "fixed" by weakening a gate is never in-scope — see
135
+ **Important rules**.
136
+
137
+ ### Step 4 — Phase A: fix in-scope failures, one at a time
138
+
139
+ - Apply the smallest fix that addresses the **root cause** within the PR's scope.
140
+ - Re-run the **specific** failing command locally and read its exit code before
141
+ claiming it fixed (e.g. `pnpm lint`, `pnpm changeset status`,
142
+ `npx skills-ref validate ./skills/<name>`, the failing test). Evidence before
143
+ claims — never assert a fix on "should" or "probably".
144
+ - Commit with a Conventional Commit subject, then push. One fix → one
145
+ verification → next fix.
146
+
147
+ ### Step 5 — Phase A: handle base-branch drift
148
+
149
+ Only when Step 3 classified the failure as upstream/behind:
150
+
151
+ ```bash
152
+ git fetch origin <base>
153
+ git merge origin/<base> # or rebase, per the repo's convention
154
+ ```
155
+
156
+ - Clean merge → push and re-watch (Step 6).
157
+ - Conflict → go to **Merge conflicts** below.
158
+
159
+ ### Step 6 — Phase A: re-watch CI until green or budget exhausted
160
+
161
+ ```bash
162
+ gh pr checks <pr> --watch
163
+ ```
164
+
165
+ - After each push, watch the rollup to completion. Still red → loop back to
166
+ Step 2.
167
+ - **Bound the loop** by `maxCiRounds`. When exhausted, stop and report the
168
+ remaining failures as blockers rather than looping forever.
169
+ - Green **and draft** → report green and **stop**.
170
+ - Green **and ready** → continue to Phase B.
171
+
172
+ ### Step 7 — Phase B: fetch unresolved review feedback
173
+
174
+ Run the bundled fetcher. Its path is **relative to this skill's own directory**
175
+ (the one holding this `SKILL.md` and `config.json`) — resolve it from there, not
176
+ from the consuming repo's root, or the run fails with `ENOENT`. The `--bots`
177
+ value is `config.reviewBots` joined by commas:
178
+
179
+ ```bash
180
+ node scripts/review-threads.mjs <pr> --bots "claude,cursor,coderabbitai"
181
+ ```
182
+
183
+ It prints minimal JSON with three groups:
184
+
185
+ - `unresolvedThreads` — inline review threads (`isResolved == false`) raised by a
186
+ configured `reviewBot`, trimmed to `{threadId, path, line, isOutdated, author,
187
+ comments}`. This is the actionable set.
188
+ - `humanThreads` — the same shape, for unresolved threads **not** raised by a
189
+ review bot. Surface these in the report for the human; do not auto-action them.
190
+ - `aiSummaryComments` — the sticky issue-level summary the review action posts via
191
+ `track_progress` / `use_sticky_comment`. Surface it **separately**: it is an
192
+ issue comment, **not** a review thread, so it has no `isResolved` and never
193
+ appears in `unresolvedThreads`. Missing it would mean missing the headline
194
+ review.
195
+
196
+ Resolved threads are filtered out so the context stays small. Empty
197
+ `unresolvedThreads` **and** no AI summary → report "no actionable AI review
198
+ feedback" and skip to Step 10.
199
+
200
+ ### Step 8 — Phase B: validate each finding before touching code
201
+
202
+ Apply the six-step reception (full rules in
203
+ [`references/review-discipline.md`](references/review-discipline.md)):
204
+
205
+ 1. **READ** the finding in full — body plus the cited file and line.
206
+ 2. **UNDERSTAND** what it claims and why; restate it for yourself.
207
+ 3. **VERIFY** it against the actual codebase. Open the cited lines and confirm
208
+ the issue is real and not already handled. Never trust the bot's framing.
209
+ 4. **EVALUATE** — is it correct, in-scope, and not a YAGNI or architecture
210
+ violation?
211
+ 5. **RESPOND** — for a decline, reply on the thread with concise **technical
212
+ reasoning** and resolve it; for an accepted finding, note the planned fix. No
213
+ sycophancy ("You're absolutely right!", "Great point!") — state facts.
214
+ 6. **IMPLEMENT** accepted findings one at a time (Step 9).
215
+
216
+ Reply and resolve:
217
+
218
+ ```bash
219
+ gh api graphql -f query='mutation($id:ID!){ resolveReviewThread(input:{threadId:$id}){ thread { isResolved } } }' -f id='<threadId>'
220
+ ```
221
+
222
+ ### Step 9 — Phase B: apply accepted fixes, then re-run Phase A
223
+
224
+ - Implement each accepted finding on its own; after each, freshly run the proving
225
+ command and read its output and exit code before claiming it works.
226
+ - Commit and push, then **return to Step 2** — a new push re-fires CI, and AI
227
+ review re-fires too (the PR is ready), producing fresh threads and an updated
228
+ sticky comment.
229
+ - Loop Phase B ↔ Phase A until CI is green **and** no unresolved AI threads
230
+ remain (or every remaining one has been declined with reasoning and resolved).
231
+
232
+ ### Step 10 — Report
233
+
234
+ Summarise:
235
+
236
+ - Checks fixed, each with the failing command it addressed.
237
+ - Findings accepted and fixed.
238
+ - Findings declined, each with the technical reasoning given.
239
+ - Base merges/rebases performed.
240
+ - Remaining blockers (if `maxCiRounds` was exhausted).
241
+ - Final CI state, with the proving command's output.
242
+ - Any **human** review comments, surfaced for the human to handle.
243
+ - A reminder that the PR's draft/ready state is unchanged — the human flips it.
244
+
245
+ ## Merge conflicts
246
+
247
+ - Resolve **only** when the resolution is unambiguous and within the PR's scope
248
+ (e.g. both sides touched disjoint hunks, or this branch's intent clearly
249
+ supersedes).
250
+ - **Abort and ask the human** when intent is ambiguous: both sides changed the
251
+ same logical thing, the conflict reaches files outside the PR's scope, or
252
+ resolving needs a product decision. Run `git merge --abort` and report the
253
+ conflicting files.
254
+ - Never resolve a conflict by deleting the other side's work just to make it
255
+ compile.
256
+
257
+ ## Important rules
258
+
259
+ - **Never greenwash.** Never edit `.github/workflows/*`, disable or loosen a lint
260
+ rule, delete or skip a test, or relax a CI threshold to make a check pass. Fix
261
+ the code, or report the failure as a blocker.
262
+ - **In-scope only.** Fix what this PR's diff is responsible for; don't fix
263
+ unrelated repo problems.
264
+ - **Validate before implementing.** Never apply a review suggestion without first
265
+ verifying it against the codebase.
266
+ - **AI bots only.** Action only the configured `reviewBots`; surface human
267
+ comments but leave them for the human.
268
+ - **No sycophancy.** Decline with technical reasoning, not flattery.
269
+ - **Evidence before claims.** Never say CI is green or a fix works without freshly
270
+ running the proving command and reading its exit code.
271
+ - **Never flip draft → ready.** This skill only reads the draft state to choose a
272
+ phase; promoting the PR is the human's call.
273
+ - **Bounded loops.** Stop after `maxCiRounds` and escalate.
274
+
275
+ ## Error handling
276
+
277
+ - `gh auth status` fails → stop and tell the user to run `gh auth login`.
278
+ - No PR for the branch → stop with "open one with `/send-it` first".
279
+ - `gh run view --log-failed` unavailable (logs expired or run purged) → report
280
+ the failing check by name without guessing its cause; do not fabricate a fix.
281
+ - The review-thread fetcher exits non-zero (rate limit, permissions, GraphQL
282
+ error) → report it and fall back to `gh pr view <pr> --json reviews,comments`.
283
+ Never treat "couldn't fetch" as "no findings".
284
+ - A finding cites a file or line that no longer exists (outdated thread) → note it
285
+ as outdated and resolve it without a code change.
286
+ - `resolveReviewThread` fails on permissions → fall back to a plain reply with the
287
+ reasoning rather than aborting.
288
+
289
+ ## Arguments
290
+
291
+ $ARGUMENTS
@@ -0,0 +1,4 @@
1
+ {
2
+ "reviewBots": ["claude", "cursor", "coderabbitai"],
3
+ "maxCiRounds": 5
4
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@acme-skunkworks/skill-triage-pr",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "Agent skill: take a pull request from draft with failing CI to merge-ready — fix in-scope CI failures, then validate and action AI review feedback.",
6
+ "keywords": [
7
+ "agent-skill",
8
+ "claude-code",
9
+ "cursor",
10
+ "github",
11
+ "pull-request",
12
+ "ci",
13
+ "code-review"
14
+ ],
15
+ "homepage": "https://github.com/acme-skunkworks/agent-skills/tree/main/skills/triage-pr#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/acme-skunkworks/agent-skills/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/acme-skunkworks/agent-skills.git",
22
+ "directory": "skills/triage-pr"
23
+ },
24
+ "license": "MIT",
25
+ "author": {
26
+ "name": "Rob Easthope",
27
+ "url": "https://github.com/RobEasthope"
28
+ },
29
+ "engines": {
30
+ "node": ">=22"
31
+ }
32
+ }
@@ -0,0 +1,73 @@
1
+ # triage-pr — review discipline
2
+
3
+ The Phase B triage in [`../SKILL.md`](../SKILL.md) compresses two well-worn
4
+ review-handling disciplines into a short step list. The full rules live here, so
5
+ the body stays lean and an agent can load this on demand. They are adapted from
6
+ the community `receiving-code-review` and `verification-before-completion` skills
7
+ (obra/superpowers).
8
+
9
+ ## Receiving review feedback — the six steps
10
+
11
+ Run every AI finding through these in order. The point is **technical rigour, not
12
+ performative agreement**: a review bot is frequently wrong, partially right, or
13
+ missing context, and applying its suggestion blind is how a green PR ships a
14
+ regression.
15
+
16
+ 1. **READ.** Absorb the whole finding — the comment body *and* the cited file and
17
+ line — before reacting. Don't start editing on the strength of the summary.
18
+ 2. **UNDERSTAND.** Restate the claim in your own words. If you can't, the finding
19
+ is unclear; treat that as a signal to verify harder, not to guess.
20
+ 3. **VERIFY.** Check the suggestion against the **actual codebase**. Open the
21
+ cited lines. Confirm the problem is real, reproduces, and isn't already handled
22
+ elsewhere. Never trust the bot's framing of the code — read the code.
23
+ 4. **EVALUATE.** Decide whether the change is correct *for this project*: in
24
+ scope, compatible with the stack, and not a YAGNI or architecture violation.
25
+ 5. **RESPOND.** State a technical acknowledgement or a justified technical
26
+ objection. For an accepted finding, note the planned fix. For a decline, reply
27
+ on the thread with the reasoning and resolve it.
28
+ 6. **IMPLEMENT.** Apply accepted findings **one at a time**, verifying each before
29
+ the next. Batching changes hides which one broke something.
30
+
31
+ ## No sycophancy
32
+
33
+ Do **not** open a reply with praise — "You're absolutely right!", "Great point!",
34
+ "Excellent feedback!". Actions speak: the code change itself shows the finding was
35
+ heard. Acknowledge by describing what changed ("Fixed — `line` now falls back to
36
+ `originalLine` for outdated threads") or simply implement without commentary.
37
+
38
+ ## When to decline
39
+
40
+ Push back — with technical reasoning, not defensiveness — when the suggestion:
41
+
42
+ - breaks existing functionality;
43
+ - is made without the full context (the bot couldn't see a constraint you can);
44
+ - violates YAGNI (adds an unused capability "just in case");
45
+ - conflicts with the codebase's technical stack or conventions; or
46
+ - contradicts a deliberate architectural decision.
47
+
48
+ A declined finding still gets a reply explaining *why*, then the thread is
49
+ resolved so it doesn't re-surface.
50
+
51
+ ## Evidence before claims
52
+
53
+ Before asserting that CI is green, a check passes, or a fix works:
54
+
55
+ 1. Identify the command that **proves** the claim.
56
+ 2. Run it freshly and completely — not from memory of a previous run.
57
+ 3. Read the full output **and** the exit code.
58
+ 4. Only then state the result, citing the evidence.
59
+
60
+ Banned until you have run the proving command: "should", "probably", "seems to",
61
+ and premature satisfaction ("Done!", "Perfect!", "All green!"). Any wording that
62
+ implies success without fresh verification breaks this rule.
63
+
64
+ Proving commands by claim:
65
+
66
+ | Claim | Proof |
67
+ | --- | --- |
68
+ | Lint clean | the lint command's output showing zero errors |
69
+ | Tests pass | the test command's output showing zero failures |
70
+ | Build succeeds | the build command exiting `0` |
71
+ | Manifest valid | `npx skills-ref validate ./skills/<name>` exiting `0` |
72
+ | CI green | `gh pr checks <pr>` showing every required check passed |
73
+ | Bug fixed | the original failing symptom now passing |