Skip to content

Releases: p5ych0/watch-pr-skill

watch-pr-skill 2.13.0

Choose a tag to compare

@p5ych0 p5ych0 released this 13 Oct 22:34
239cd7f

The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought, and a hooks module
that sets the model and effort of the loop's subagents from the size of the work. No daemon,
and one install serves every project.

In 2.13.0

  • A round's edits run in a subagent, at a tier the session names. 2.12.0 sized a fix
    pass only where the session chose to delegate one, and sized it by a count of findings. A
    count is a weak measure of the work: one finding can need a redesign, and a pass of five
    wordings is an afternoon's nothing. And a session that made every edit itself got no
    tiering at all. SKILL.md now has the session decide the answer to each finding and then
    hand the edits to a subagent by default, where the harness has subagents and the operator
    has not said otherwise. It marks the call review-fix: and names the tier, small,
    medium or large, by the hardest finding in the pass, as in
    review-fix: large, 2 findings. The hooks module reads the tier where it comes first
    after the marker and takes the rung for it; where no tier is named, the stated count
    decides as before, so the 2.12.0 form keeps working. The commit, the self-check, the
    thread replies, the round summary and every judgment call stay with the session, and the
    subagent is told to commit, push, post and resolve nothing and to report, for each
    finding, the mutation it ran and what failed. What an operator gains is the delegation
    itself, a word to the session that keeps the edits there, and a tier the module reads.

    No model call sits in the hook to judge the size: the session has already read the
    findings, and a second judgment would add cost and delay to every pass. Twenty cases
    under tests/ hold the module, the two new ones proved against a module that ignores a
    named tier, one that reads a tier anywhere in the description, and one that takes a word
    that only starts like a tier, a hyphenated one included. test-hooks.sh holds that the
    marker and the three tiers SKILL.md tells the session to write are the ones the module
    reads. Closes #370.

Also since 2.11.4: 2.12.0

2.12.0 was not released on its own; this release carries it.

  • The loop's subagents are sized to the work. A cold read of a ten-line fix and one of a
    five-hundred-line change ran at whatever model and effort the session happened to pass,
    and so did a fix pass handed to a subagent, whether it answered one finding or eight. The
    plugin now ships the hooks module
    docs/decisions/2026-10-13-plugin-ships-one-hooks-module.md admits, hooks/tiering.ts,
    which sets effort on two kinds of Agent call before the subagent starts and logs one
    line saying what it picked and from what. A cold-reviewer run, the plugin's or a
    project's, is sized by the lines added and deleted against the merge base with the
    remote-tracking origin/… ref the prompt names first, else with origin/HEAD; which
    names are refs is git's answer, the longest listed one written at that place, so no
    pattern decides where a name ends; a base the checkout has not fetched is not listed,
    and a fetched ref whose name begins it is taken in its place. A fix pass is sized by the number
    of findings the session states, by starting the call's description with review-fix: and
    that number, as in review-fix: 3 findings. Each kind has three rungs and two bounds
    between them, ten options in plugin.json that /plugin configure watch-pr-skill sets.
    The small bound is read first, so where an operator's two bounds overlap a size both
    cover is small. A rung is <model>/<effort>,
    and the shipped default names default for the model on every rung, which leaves the
    call's model as it was: out of the box only effort moves, medium, high, then xhigh, and no
    install is sent to a model its account may lack. A rung that names a model replaces the
    call's. The last twelve merged changes here ran from 18 to 258 changed lines, and the
    bounds of 60 and 200 split them six small, four medium and two large.

    The module gates nothing. A call it cannot size goes through as the session made it: a
    merge base git fails to compute, a checkout holding untracked files, which the reviewer
    reads and the measure does not count, a git that fails or outlives its ten-second
    bound, a fix pass that states no number. So does every other subagent and every fork. A Claude Code
    build without function hooks reads the empty command-hook record beside the module and
    runs nothing. SKILL.md says how a fix pass is
    marked and that model and effort are left unset on both kinds of call. Eighteen cases
    under tests/ hold the behaviour under claude plugin test, each proved against its
    mutant, and test-hooks.sh holds what the suite can: the module and its cases are
    present, every rung's default names no model, and the options the module reads are
    exactly the ones plugin.json declares. Closes #366.

The hooks module needs a Claude Code build with function hooks, measured on 2.1.296. An
older build does not run it, and the loop runs as before. Its ten options are set with
/plugin configure watch-pr-skill: see Subagent model and effort in the README.

Install

/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools

To update an existing install:

/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins

Coming from 1.x

2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.

The full history is in CHANGELOG.md.

watch-pr-skill 2.11.4

Choose a tag to compare

@p5ych0 p5ych0 released this 25 Sep 07:47
fa2a3fd

The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought. No daemon, and one
install serves every project.

In 2.11.4

  • No session could start on a stock Mac. pr-origin.sh refused any component on the way
    to setup's directory whose ls -ld mode field ended in + or @, reading the mark and
    never what it stood for, and stock macOS marks both parents setup can use: the system
    TMPDIR under /var/folders carries an extended attribute and no ACL entry, and every home
    directory carries one ACL entry, group:everyone deny delete. Measured on a GitHub macOS 26
    runner, the first attempt was refused under the system TMPDIR, the attempt under
    ~/.watch-pr with TMPDIR unset was refused at the home directory, and so was the retry,
    each with terminal status 1. A marked component now has its entries listed with ls -led
    and passes only when every entry is a deny, inherited or not, since a deny can only take
    access away; an allow entry, a line that does not parse, a + with no entry listed and a
    listing that fails all refuse as before. GNU ls has no -e, so on Linux every mark still
    refuses. The same runner, on this change, reached status=ready in all three cases.
    test-pr-origin.sh stages each shape through a stubbed ls: the home's single deny and the
    TMPDIR's bare xattr accepted, a deny list with an inherited deny accepted, and an allow, an
    inherited allow, a deny then an allow behind @, an unparseable line, a + with no entry
    and a failed listing under either mark refused; the existing @ case now lists the allow it
    guards against. Each was proved against its mutant. Closes #361.

Also since 2.11.2: 2.11.3

2.11.3 was not released on its own; this release carries it.

  • Every session left a directory in the operator's home. Where TMPDIR was unset or
    relative — most Linux desktops, and a Claude Code session there — setup reserved
    ~/watch-pr-setup.<pid>.<random>, and its retry was ~/watch-pr-setup-2.… whatever
    TMPDIR was. Nothing under a setup directory is removed, so they piled up in ~ itself,
    seventeen in two weeks on one workstation. Setup now works under ~/.watch-pr in both
    places, created mode 700 where missing but never with a missing home directory above it,
    which is refused as before; a TMPDIR the system sets to an absolute path is
    still used first. The no-removal rule is unchanged, and directories earlier releases left
    in ~ stay where they are (#360).

    The parent sits directly under HOME so the ancestry pr-origin.sh walks gains one
    component, the one the fence creates: a parent under ~/.cache would have refused every
    session on a machine whose ~/.cache some other tool had created group-writable. A parent
    that cannot be created stops setup with an ABORT: naming it, on the first attempt before
    any helper runs and on the retry before a second one does. test-pr-skill-contract.sh runs
    the setup fence with TMPDIR unset under umask 002 and asserts the session lands in
    ~/.watch-pr with nothing else in HOME, and with HOME read-only asserts the abort on
    each path; the retry and relative-TMPDIR cases now expect ~/.watch-pr, and an absolute
    TMPDIR is asserted to leave HOME untouched, a missing HOME to stop setup with nothing
    created, and a ~/.watch-pr left by an earlier session to be reused by either attempt.
    Closes #359.

The setup directories earlier releases left directly in your home can be moved under
~/.watch-pr with one command: see Setup directories from before 2.11.3 in the README.

Install

/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools

To update an existing install:

/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins

Coming from 1.x

2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.

The full history is in CHANGELOG.md.

watch-pr-skill 2.11.2

Choose a tag to compare

@p5ych0 p5ych0 released this 22 Sep 21:37
b77924a

The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought. No daemon, and one
install serves every project.

In 2.11.2

  • The request comment carried the mention twice. On the manual path the opening request
    and a Codex round's summary are posted under a @codex review line this loop writes, and a
    body that already quoted the mention — out of a finding, a PR description or a previous
    round — was posted underneath it unchanged. One comment is one trigger, so the pass was
    never doubled; what doubled was what the operator reads, a request that says itself twice,
    reported twice from one repository before anyone traced it. Quoting stays allowed, because
    quoting a finding is most of what a round summary does: the mention is written only when
    the body carries none, so the loop never writes a second one above it. The drop rests on
    the same measurement the refusals do — the trigger matches case-insensitively anywhere in
    the body, so a quoted mention, indented or fenced, requests the pass by itself. test-pr-request-review.sh
    and test-pr-close-round.sh count the mentions in what was posted, for a body that quotes
    one and for a body that does not; both cases fail against the unfixed helpers.
    rb_review_trigger answers from a case pattern rather than folding the text with tr, so the
    question runs no command and cannot come back indeterminate. gate asks it before the threads
    are resolved and post asks it again afterwards, where a refusal would have left the round
    half-closed with nothing posted; test-recordlib.sh runs both answers with an empty PATH,
    which the folding version could not survive.

Install

/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools

To update an existing install:

/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins

Coming from 1.x

2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.

The full history is in CHANGELOG.md.

watch-pr-skill 2.11.1

Choose a tag to compare

@p5ych0 p5ych0 released this 12 Sep 23:16
f8655c4

The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought. No daemon, and one
install serves every project.

In 2.11.1

  • A link one level up is a link. The cold reviewer probed a changed path with
    test -L <root>/<path>, which answers for the component it names. Where a tracked
    directory had been replaced by a symlink to a directory outside the checkout holding the
    same child path, the child printed not-a-link, test -e printed present, and the Read
    tool followed the symlinked parent out — while the brief says a link is read through
    readlink and never opened, which is why the probe exists at all. The pattern is ordinary:
    a framework that links a public directory at its own storage outside the tree. The probe is
    asked of every prefix from the root down now, and a path under one that prints link is
    reported as reached through it and nothing under it is opened. test-hooks.sh builds a
    directory that is a link to one outside the probe root and asserts what made the gap: the
    child answers not-a-link and present, while the prefix answers link. The old
    single-component sentence is refused beside it.

Install

/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools

To update an existing install:

/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins

Coming from 1.x

2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.

The full history is in CHANGELOG.md.

watch-pr-skill 2.11.0

Choose a tag to compare

@p5ych0 p5ych0 released this 12 Sep 21:22
eda8424

The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought. No daemon, and one
install serves every project.

In 2.11.0

  • A project can add its own checks and paths to the cold reviewer. The brief the plugin
    ships is the same everywhere: it reads the root's policy files, applies one secrets rule,
    and judges the change against the PR body. Everything a project knew beyond that — checks
    distilled from rounds it had already paid for, rules kept below the root, credential names
    the rule does not cover — lived in whatever the caller remembered to type, which is the
    failure 2.10.3 fixed for the step itself. A .cold-review.md at the root, read from the
    base like every other policy input so a pull request cannot widen its own review, now
    carries two headings and nothing else: ## Checks, points to raise, which say what to
    look for and change nothing about what may be read or run; and ## Paths, lines
    policy:, secret: and open:. A policy: path is listed and read from the base under
    the same mode rule as every other policy file, taken as a policy file and only as one, and
    only where the listing prints exactly one entry for it; one the secrets rule still marks —
    the file's own secret: and open: lines counted — is reported as named and left unread,
    so the project's own file cannot route a credential into the read. That line is how a rule
    below the root reaches the read after 2.10.0 stopped guessing at subtree scope. A secret: name joins the secrets rule. An open: name unmarks the name
    half of that rule alone, so a marked directory still marks everything under it and a path
    the policy forbids stays unopened. A path that is absolute or climbs with .. is reported
    and ignored. A project without the file is reviewed exactly as before. test-hooks.sh
    pins each bound against the brief flattened.

Also since 2.10.3

2.10.4

  • A committed .example template is not a secret. The cold reviewer's secrets rule marks a
    path named .env or .env.*, which takes a tracked .env.example or
    <dir>/.env.example with it: the pre-read reported such a file as changed and left it
    unread, though its contents are committed and both reviewers read them once the PR is
    pushed. A project keeping three of those templates had every change to one reviewed cold
    without it. A name ending .example is exempt now, and is marked only where a directory
    above it is. The exemption is by name, so a *.pem.example or *.key.example template is
    read on the same argument, and a marking directory still marks every template under it.
    Another spelling — .env.sample, .env.template — stays unread, which is for a project
    to exempt itself once it can (#351). test-hooks.sh pins the exemption beside the rest of
    the rule.

Install

/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools

To update an existing install:

/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins

Coming from 1.x

2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.

The full history is in CHANGELOG.md.

watch-pr-skill 2.10.3

Choose a tag to compare

@p5ych0 p5ych0 released this 11 Sep 18:01
aa7621b

The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. From 2.10 it also ships a cold reviewer, a
subagent that reads each change the way the reviewers will before a round is bought. No
daemon, and one install serves every project.

In 2.10.3

  • SKILL.md runs the cold reviewer. 2.10.0 shipped the cold-reviewer agent to installing
    projects, but the driver never named it, so a session in such a project had the agent and
    no step that ran it, and bought review rounds a minute's cold read would have saved. Step 1
    now has it read the change before the first request, and before the PR is opened where
    automatic review is on, with its fixes committed, self-checked and pushed before the
    request. Step 5's procedure has it read each round's fixes after the self-check and before
    the round boundary and the push, given the base ref, the PR body, the newest round summary
    and the earlier findings with their replies; its fixes carry the phase trailer and are
    written into the round summary. The session fixes what it names as a defect the change
    introduced and files the rest. It stays a pre-read, not a gate, and not a reviewer. The
    contract test pins both placements, the name the plugin loads it under and the commit
    instructions; README's session description says the same.

Also since 2.9.3

2.10.2

  • The cold reviewer's path probes print their answers. Its brief decided what a changed
    path is with test -L and then test -e, which answer only through their exit status,
    and a subagent's tool output may not show one. A downstream cold read reported that
    test -L "printed nothing even on a file I know is regular" and fell back to readlink
    and the modes git records, though the brief says the probes decide. Each probe is now
    test -L <path> && echo link || echo not-a-link and
    test -e <path> && echo present || echo absent, echo is allowed for that purpose
    only, and a probe's exit status no longer reads as a failed command. test-hooks.sh
    takes both probes from the brief and runs them on a dangling link, a file and a missing
    path.

2.10.1

  • The cold reviewer sees both ends of a move. Its brief listed what changed with
    git diff --name-only, and rename detection is on by default, so a commit that moves a
    file listed only the destination: the per-path diff then showed a new file and never the
    deletion at the source, and what a move left behind went unread, which is what a
    "location only" claim needs checked. Measured on a downstream commit with a rename, the
    default listing gave only the destination. The listing is
    git diff --no-renames --name-only now, which names the source as deleted and the
    destination as added. test-hooks.sh pins the flag and runs it on a commit that moves a
    file.

2.10.0

  • The cold reviewer ships with the plugin. The subagent that reads a branch against its
    base the way Codex and Copilot will, before a round is bought, lived in this checkout's
    .claude/agents/, which Claude Code does not load from a plugin. A project that installed
    watch-pr-skill got the review loop without the pre-read that makes a round cheaper, and
    one measured downstream session spent rounds on four findings a cold read of the diff would
    have made first. It is agents/cold-reviewer.md at the plugin root now, loaded as
    watch-pr-skill:cold-reviewer. Its brief read AGENTS.md and CLAUDE.md off the base and
    stopped where either was missing. It now asks the base which of
    .github/copilot-instructions.md and the root's AGENTS.override.md (read, unless empty,
    in place of AGENTS.md), AGENTS.md and CLAUDE.md it has, reads those first and says which it
    found, and leaves unopened a path that policy says not to open; the same files below the
    root are not read. Its secrets rule now also covers anything under a .env or .env.*
    directory, and a .ssh directory at any depth; its other safety rules are unchanged. This checkout keeps a link to the brief in .claude/agents/, so that a
    session here uses the branch's brief, not the installed release's. test-hooks.sh pins the
    shipped file, its name, its read-only tool list, its secrets rule and its policy read in
    every copy, and the link in this checkout.

Install

/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools

To update an existing install:

/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins

Coming from 1.x

2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.

The full history is in CHANGELOG.md.

watch-pr-skill 2.9.3

Choose a tag to compare

@p5ych0 p5ych0 released this 07 Sep 23:18
688d4bd

The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. No daemon, and one install serves every
project.

In 2.9.3

  • The manifests name the generation. Both descriptions carried one sentence, which said
    what the plugin does and nothing about which of the two incompatible generations it is, so
    a reader who knew the 1.x file bus could not tell from a marketplace listing that the
    daemons and the codex exec reviewer are gone. They say 2.x and no daemon now.

Install

/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools

To update an existing install:

/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins

Coming from 1.x

2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.

The full history is in CHANGELOG.md.

watch-pr-skill 2.9.2

Choose a tag to compare

@p5ych0 p5ych0 released this 07 Sep 22:49
30afd31

The first tagged 2.x release. The plugin drives a pull request through GitHub's own
reviewers, Codex and Copilot, works the fix → reply → resolve → re-request loop to a clean
signoff, and stops for you before the second reviewer's phase and before the merge. No
daemon, and one install serves every project.

In 2.9.2

  • A hex class is spelled out, not ranged. On bash 3.2 under a non-C locale a bracket
    range collates by locale, so [0-9a-f] takes A through E and a value git never emits
    read as a full sha in recordlib.sh's case, and in the driver's read-back of the Codex
    signoff. Both spell the sixteen characters out. The mac-shaped CI job runs under C.UTF-8
    and did not see it; a Mac in a user's locale would.

The tag also carries README.md's Upgrading from 1.x section, which landed after the
release commit and changed no installed file.

Install

/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools

Coming from 1.x

2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.

The full history is in CHANGELOG.md.