feat(dev-kit): add plugin with ci-fix, pr-shepherd, dep-upgrade-check and pr-open skills - #15
Conversation
There was a problem hiding this comment.
Important
Two of the four skills have steps that cannot execute as written: pr-shepherd ends its loop with a ScheduleWakeup parameter that does not exist, and dep-upgrade-check's allowed-tools omits most of the tools its own steps invoke. The debut version baseline also needs to be 0.0.0 for release.sh to cut v0.1.0.
Reviewed changes — full read of all 5 commits (0aef892..58e78ad) adding plugins/dev-kit/, a prompt-only plugin with no scripts, evals, or CI hook.
- Plugin scaffold —
plugin.json,CHANGELOG.md([Unreleased]only, correct for a debut),README.md, and amarketplace.jsonentry. Author name/email and description are byte-identical across both manifests. ci-fix— resolves a failed Actions run from a URL/ID/PR or the current branch, traces a root cause, fixes and verifies locally, one commit per cause. Apush-authorizedtoken switches it to unattended mode where every "ask the user" becomes statusblocked. Emits a fixed-key result block.pr-shepherd— one iteration of a self-paced/loopover the current branch's PR. Delegates red CI toci-fix … push-authorizedand reads its result block; classifies GraphQLreviewThreadsas open/awaiting and replies or resolves accordingly.dep-upgrade-check— read-only upgrade impact analysis intersecting a change ledger with a usage surface, plusbot-prs.md(Renovate/Dependabot parsing) andecosystems.md(npm/yarn/Python/Go/PHP/Rust lookups).pr-open— pushes the branch and opens a PR filled from the repository's template, falling back to a built-in Smart Brevity skeleton.
I verified four things that looked wrong and are in fact correct, so they are deliberately not raised below: disallowed-tools is a documented SKILL.md field whose own doc example is AskUserQuestion for a background loop; mcp__context7__query-docs is the current Context7 tool name (get-library-docs was removed in @upstash/context7-mcp@2.0.0); the space form Bash(gh pr view *) is the canonical permission syntax, not a malformed :*; and find -ipath './.github/pull_request_template*' does match PULL_REQUEST_TEMPLATE/bug.md, since -ipath wildcards cross /.
ℹ️ Four skills that commit, push, rerun CI and post review replies ship with no automated verification
Nothing in CI touches plugins/dev-kit/**: fd3-evals.yml is scoped to plugins/fd3/**, and lint.yml is shellcheck over *.sh only. The PR body states no skill has been run end to end. That is a reasonable call for a prompt-only debut, but these four skills push commits, rerun workflows and post review replies under push-authorized — the blast radius of a prose defect is higher here than for a read-only skill, and the three findings above are all the kind a single dry run would have surfaced.
Technical details
# No verification surface for plugins/dev-kit
## Affected sites
- `.github/workflows/fd3-evals.yml` — the only eval CI, scoped to `plugins/fd3/**`
- `.github/workflows/lint.yml` — shellcheck over `*.sh`; dev-kit ships no shell scripts
## Open questions for the human
- Is an `evals/` suite intended for dev-kit later, or are these skills deliberately
manual-verification-only?
- `pr-shepherd` and `ci-fix` both act unattended with push rights. Is a dry run against a
throwaway PR worth doing before the debut release tag, given no eval gates them?ℹ️ Nitpicks
plugins/dev-kit/skills/ci-fix/SKILL.md:48— "whenattemptis already above 1 with the same failure, it is not transient" removes the job from the Transient bucket but does not route it to any of the other four, leaving the classification undefined for exactly the case that matters most (a repeat failure). Naming the fallback bucket would close it.plugins/dev-kit/skills/pr-open/SKILL.md:19— "push (step 5)" points at a step whose four substeps includegh pr create, which would fail when a PR already exists. Referring togit push -u origin HEADdirectly avoids the literal reading.
Claude Opus | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the 2 commits since the previous review at 58e78ad, a 3-line delta across 3 files, both of them fixes for that review.
- Set the debut version baseline to
0.0.0—plugins/dev-kit/.claude-plugin/plugin.json:4and.claude-plugin/marketplace.json:195moved off0.1.0and stay in parity.bump_versioninscripts/release.sh:60-69turns0.0.0into0.1.0on aminor, so the first./scripts/release.sh dev-kit minornow cutsdev-kit/v0.1.0instead of skipping it. - Gave
pr-shepherd's loop an exit for threads it has decided not to handle —skills/pr-shepherd/SKILL.md:97widened the CI-green stop to cover handed over threads (two rebuttals already posted, orviewerCanReply/viewerCanResolvefalse) alongside the 24-hour quiet-reviewer case.
I re-traced both leak paths the previous review described against the new wording. A permission-blocked thread parked by :89 and a twice-rebutted thread parked by :72 are each still classified open by :49, so :93's Done condition still does not fire for them — but both now match the handed over clause at :97, so a loop holding only those threads stops on the iteration it reaches them rather than spinning to the iteration-48 cap. The two remaining stops (:98, :99) are unchanged and the awaiting-thread wake cadence at :101-104 is untouched.
The ScheduleWakeup and allowed-tools threads were declined with reasoned, sourced rebuttals and resolved by the author; both rest on lines these commits did not touch, so they are not reopened here. The no-automated-verification observation from the previous review still stands as written and is not restated.
Claude Opus | 𝕏
There was a problem hiding this comment.
ℹ️ No blocking issues — one suggestion inline, plus one scope question about how long the new grant lasts.
Reviewed changes — the 2 commits since the previous review at 45404e2, a 3-line delta across 3 files that gives the two unattended skills an allowed-tools grant.
- Pre-approved
ci-fix's git and gh commands —skills/ci-fix/SKILL.md:5now grantsgh run view|list|rerun,gh pr checks|checkout,gh api repos/*, and gitstatus|fetch|switch|log|diff|show|add|commit|push. Everygit/ghinvocation in the skill body is covered. - Pre-approved
pr-shepherd's git, gh and delegation calls —skills/pr-shepherd/SKILL.md:5adds the same core plusgit rev-list,git pull --ff-only,gh pr view|checks|comment,gh api graphql *, andSkill(dev-kit:ci-fix *)for the hand-off toci-fix. Also fully covered. - Documented the limit of the pre-approval —
README.md:30states that the reproduce/verify commands (tests, lint, build) are repository-specific, cannot be shipped in the plugin, and must go in the project's own.claude/settings.jsonor the loop pauses at the first such prompt.
Three things I checked that are correct and are deliberately not raised below. Skill(dev-kit:ci-fix *) is the documented rule shape — the skills doc gives "Skill(name) for exact match, Skill(name *) for prefix match with any arguments", and plugin skills are namespaced plugin-name:skill-name. The absence of ScheduleWakeup and CronDelete from the list is harmless: the tool reference marks both as requiring no approval, so pr-shepherd:19 and :102 never prompt. And Bash(gh api graphql *) genuinely needs write scope, since :78 and :82 are the addPullRequestReviewThreadReply and resolveReviewThread mutations.
ℹ️ The grant is scoped to one turn, but pr-shepherd is designed to span many
The skills documentation is explicit that allowed-tools "grants permission for the listed tools during the turn that invokes the skill" and that "the grant clears when you send your next message, even though the skill content stays in context; invoking the skill again re-applies it for that turn." pr-shepherd is a self-paced /loop: every iteration after the first arrives as a separate turn woken by ScheduleWakeup. Whether the pre-approval survives therefore depends on each wake-up re-entering through the Skill tool rather than running the body from context — and ## Entry (:15) explicitly sanctions the second shape with "or this turn is already a /loop fire, run the iteration". If that branch ever runs without a fresh invocation, iteration 2 onward executes with the grant already cleared and stalls on the first git push, which is the exact failure these commits set out to remove.
Technical details
# `allowed-tools` is a per-turn grant; `pr-shepherd` iterates across turns
## Affected sites
- `plugins/dev-kit/skills/pr-shepherd/SKILL.md:5` — the grant that the loop depends on
- `plugins/dev-kit/skills/pr-shepherd/SKILL.md:15` — `## Entry` admits two ways an
iteration can begin: the arguments carry `iteration`, or "this turn is already a
`/loop` fire". Only a path that re-invokes the skill re-applies the grant.
- `plugins/dev-kit/skills/pr-shepherd/SKILL.md:102` — `ScheduleWakeup` for the next
iteration; each fire is a new turn
- `plugins/dev-kit/README.md:30` — names the repo-specific test/lint commands as the one
limit of the pre-approval, and does not mention turn scoping
## Required outcome
- An iteration woken by `ScheduleWakeup` must run with the same pre-approval as the first
one, or the README should say that it does not.
## Open questions for the human
- Does the `/loop` skill re-fire `/dev-kit:pr-shepherd iteration` as a skill invocation on
every wake-up (re-applying the grant), or does the iteration continue from the skill
content already in context?
- If it is the latter, should `## Entry` require re-invoking the skill on every fire rather
than offering the "already a `/loop` fire" shortcut?ℹ️ Nitpicks
plugins/dev-kit/skills/ci-fix/SKILL.md:5andplugins/dev-kit/skills/pr-shepherd/SKILL.md:5—Bash(git fetch)andBash(git push)are redundant next to their*twins. The permissions doc: "A*at the end, with a space before it, also matches the bare command.Bash(ls *)matchesls, andBash(git log *)matchesgit log." SoBash(git fetch *)andBash(git push *)already cover the argument-less invocations, and the four paired rules can collapse to two.
Claude Opus | 𝕏
There was a problem hiding this comment.
ℹ️ No blocking issues — one suggestion inline on the new
--assigneeflag.
Reviewed changes — the single commit since the previous review at d000668, a 2-line delta across 2 files that self-assigns the pull requests pr-open opens.
- Self-assigned newly created pull requests —
skills/pr-open/SKILL.md:79appends--assignee @meto step 5.3'sgh pr create. It affects the creation path only; the existing-PR branch at:19still just refreshes the body withgh pr edit --body-fileand does not assign. - Documented it in the skill list —
README.md:43gains "Assigns the PR to you." to thepr-openparagraph.
Two things I checked that are correct and are deliberately not raised below. --assignee @me is valid gh pr create syntax, and pr-open is the one skill declaring no allowed-tools, so the new flag needs no permission-rule change. The [Unreleased] changelog correctly gains nothing: its pr-open bullet is the plugin's debut entry and describes the skill at a level that enumerates neither assignment nor the existing-PR refresh.
The Bash(gh api repos/*) thread from the previous review sits on a line this commit did not touch, so it stays open and is not restated here.
Claude Opus | 𝕏
|
@pullfrog On the per-turn |
There was a problem hiding this comment.
ℹ️ No new issues — both open threads are properly fixed; one README line went stale with the
gh apigrant removal.
Reviewed changes — the 2 commits since the previous review at b449db9, a 3-line delta across 2 files, both of them fixes for the open inline threads.
- Dropped
ci-fix'sgh apipre-approval —skills/ci-fix/SKILL.md:5no longer grantsBash(gh api repos/*). The two check-run reads at:27are untouched and now go through the normal prompt, and no replacement grant was introduced anywhere in the skill, soci-fixnow matches the deliberate "gh apican write, keep it behind consent" stance already taken fordep-upgrade-check. - Split PR assignment out of
gh pr create—skills/pr-open/SKILL.md:79reverts to a plaingh pr create, and a new step 5.5 at:81assigns withgh pr edit <url> --add-assignee @me, stating why it runs apart from the create and that on failure the PR stays opened and is reported unassigned.
I re-traced the assignment failure path against the new ordering. gh pr create is now the only mutation whose failure means no pull request, :80's temp-file cleanup sits ahead of the assignment rather than behind it, and :83's Done condition ("the PR exists and its URL is printed") is no longer satisfiable by a non-zero exit — which was the exact shape of the previous finding. The syntax holds too: gh pr edit accepts a URL selector and @me is a documented special value of --add-assignee.
pr-shepherd:5 deliberately keeps Bash(gh api graphql *), which is load-bearing there rather than incidental — :78 and :82 are the addPullRequestReviewThreadReply and resolveReviewThread mutations — so it is not raised as a parallel to the ci-fix removal. The turn-scoping question on that grant and the absence of any CI covering plugins/dev-kit/** both rest on lines these commits did not touch and are not restated.
ℹ️ Nitpicks
plugins/dev-kit/README.md:30— "pr-shepherdandci-fixpre-approve thegitandghcommands they run" stopped being true in07254c6:ci-fix:27's twogh api repos/.../check-runsreads are now outside the grant on purpose. The paragraph then names the repository-specific test/lint/build commands as the one exception, so someone setting up an unattended loop would not expect the third-party-check branch to prompt. A clause naminggh apias the second, deliberate exception would close it.
Claude Opus | 𝕏
|
No change to For the record, the grant-scope question is in review 5315803467 — the linked 5317717122 only covers The rationale holds on the re-entry path, traced as far as this environment allows:
One limit on the verification worth stating plainly: the No files changed; the working tree is clean.
|

Adds
dev-kit, a plugin with four everyday skills for CI, pull requests and dependency upgrades.Why it matters: fixing red CI, answering review comments, checking a dependency bump and opening a PR are routine work that now runs as one skill each, invocable by the user or picked up by Claude.
What changed:
ci-fix: takes a failed run, job, PR or commit URL (or the current branch), finds the root cause, fixes and verifies it locally, commits once per cause. Pushes on consent, or unattended withpush-authorized. Transient and flaky failures get one rerun; environment problems are reported.pr-shepherd: self-paced/loopover the current branch's PR. Red CI goes toci-fix; justified review comments are fixed, pushed and resolved; unjustified ones get an in-thread reply mentioning the author. Stops when checks are green and no thread is open, or hands over when a human is needed.dep-upgrade-check: read-only check of an upgrade (package + version, or a Renovate/Dependabot PR). Builds a ledger of every change in the range and maps it to real usage. Verdict: safe / safe with changes / breaking, with a file:line table.pr-open: pushes the branch and opens a PR that keeps the repository's template structure and fills it in Smart Brevity style..claude-plugin/marketplace.jsonat0.1.0; README and[Unreleased]changelog entries added.How tested:
claude plugin validate plugins/dev-kitandclaude plugin validate .pass.pr-open+pr-shepherdrun.