Skip to content

jouet pr next ​

jouet pr next says the one thing each pull request needs next, why, and the command that does it. It follows Kent C. Dodds' ship-pr.mjs: instead of reading a pull request's whole status and deciding what matters, an agent runs one command and does what it says.

text
jouet pr next [PR...] [--mine] [--search QUERY] [--repo OWNER/NAME]... [--settle DUR]

The flags are listed in the CLI reference. Pull requests are chosen the same way as for jouet pr status.

jouet pr next runs the built-in pr-next routine, so its decisions are a Luau program you can read with joue pr-next --help and copy into a routine of your own. The routine selects and fetches pull requests through the same primitive as pr status; against GitHub it takes the same time as the Rust version it replaced.

text
$ jouet pr next --repo jdx/mise 15187 15169 15172 15205
#15187 done merged: Merged
#15169 done closed: Closed without merging; reopen it to continue
#15172 act  draft: The PR is a draft
       next: gh pr ready 15172 --repo jdx/mise
#15205 act  checks_failing: 2 failing: title, status
       next: jouet wait ci jdx/mise#15205
4 PRs: 2 to act on (#15172, #15205), 2 done (#15187, #15169)

The order ​

The states are checked in a fixed order, and the first that applies is the answer. A pull request that is a draft and conflicts is a draft first; one that conflicts and fails CI has a conflict first, because pull_request CI cannot run until the conflict is gone.

ActionKindWhenNext
mergeddoneIt is merged
closeddoneIt was closed without merging
draftactIt is a draftgh pr ready N --repo OWNER/NAME
conflictactIt conflicts with its basegit fetch origin BASE && git merge origin/BASE
mergeable_unknownwaitGitHub has not finished computing mergeability or the merge statejouet wait pr PR --until mergeable
behind_baseactBranch protection, or a failing Entire Gates check, requires the branch to be up to date with its basegit fetch origin BASE && git merge origin/BASE
checks_failingactA check failedjouet wait ci PR, which shows the failed step's log
checks_pendingwaitA check is still running, or none has registered yet on a recent pushjouet wait ci PR
changes_requestedactA reviewer requested changesjouet pr threads PR --include-reviews
unresolved_threadsactReview threads are unresolvedjouet pr threads PR
entire_findingsactThe Entire Gates check fails on open findings. The reason names the first finding and where it is, as Fix Entire finding [entire:01M4C997EA] at e2e/cli/test_deps_tool_install:21 (medium): ..., when the entire CLI could list themjouet pr threads PR
entire_gateswaitThe Entire Gates check fails on a gate jouet does not knowjouet pr status PR
awaiting_approvalwaitAn approving review is requiredjouet wait pr PR --until approved
blockedwaitGitHub reports the merge as blocked by another branch protection rule or rulesetjouet wait pr PR --until any-change
auto_mergewaitAuto-merge is enabled, so GitHub will merge itjouet wait pr PR --until merged
ready_to_mergedoneNothing stands in the wayjouet pr land PR

The data and the reasons come from the same query and attention codes as jouet pr status, so the two commands never disagree. --settle waits for an unknown mergeable state the same way.

Three choices are deliberate:

  • Updating is a merge. Both conflict and behind_base suggest merging the base into the branch, never a rebase and force-push.
  • Entire Gates is not a check of its own. A failing Entire Gates check is never checks_failing: its checks gate repeats the other checks, its up-to-date gate is behind_base, and its findings gate is entire_findings.
  • No checks is not a blocker on its own. A push with no checks yet is checks_pending for 5 minutes. After that, a repository with no CI can still be ready_to_merge: branch protection knows which checks it requires, and a missing required check makes GitHub report the merge as blocked.

ready_to_merge is "done" for the agent: landing the pull request is a decision for whoever owns it, made with jouet pr land.

JSON ​

json
{
  "prs": [
    {
      "repo": "jdx/mise",
      "number": 15205,
      "title": "chore(deps): update aube to v2.8.5",
      "url": "https://github.com/jdx/mise/pull/15205",
      "action": "checks_failing",
      "kind": "act",
      "reason": "2 failing: title, status",
      "command": "jouet wait ci jdx/mise#15205"
    }
  ]
}

command is left out when there is nothing to run. not_found and incomplete are as for jouet pr status.

Exit codes ​

jouet pr next answers with its exit code, so a script or an agent can branch on it without reading the output. 10 and 20 sit outside the shared table on purpose, as in ship-pr, so that "act" and "wait" can never be mistaken for an error:

CodeWhen
0Nothing is left for the agent: every pull request is merged, closed, or ready to merge
10The agent must act on at least one pull request
20Nothing needs the agent, but at least one pull request is waiting on CI, a reviewer or GitHub
2Bad arguments
3A pull request was not found. The others are still reported
5Authentication, network or rate-limit failure

With several pull requests, 10 wins over 20, and 20 over 0.

MIT LicenseCopyright © 2026jdx.dev