neo pr
Manage pull requests
neo pr [OPTIONS] <COMMAND>neo pr create
Section titled “neo pr create”Open a pull request.
The source branch defaults to the current git branch.
neo pr create [OPTIONS] [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--title |
<TITLE> |
no | Pull request title. Defaults to the oldest commit subject in the local base..head range. Say what the change does and why — it is what a reviewer sees before opening anything; the detail belongs in --body |
|||
--body |
<BODY> |
no | "" |
Markdown description | ||
--base |
<BASE> |
no | Target branch the PR merges into. Defaults to the repo’s default branch when omitted | |||
--head |
<HEAD> |
no | Source branch. Defaults to the current git branch | |||
--draft |
no | Open as a draft | ||||
--json |
no | Print the raw response as JSON |
neo pr list
Section titled “neo pr list”List pull requests
neo pr list [OPTIONS] [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--state |
<STATE> |
no | open |
open, merged, closed, all |
Which pull requests to list | |
--json |
no | Print the raw response as JSON |
neo pr view
Section titled “neo pr view”Show one PR with its diffstat, reviews and comments.
The diffstat is merge-base-aware (three-dot, the same range the merge would apply) and its totals cover the whole diff even when the file list is capped; the trailing line says which cap applied.
While the merge queue tests the PR on a candidate merge commit, the candidate’s checks (the ones that gate the merge) are listed above the head’s, whose runs the queue superseded.
neo pr view [OPTIONS] <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--json |
no | Print {pull_request, checks, diffstat, reviews, comments} as JSON |
neo pr context
Section titled “neo pr context”Agent context pack for a pull request (always JSON).
The PR plus its checks roll-up, review comments and inline threads, a per-file change summary (paths and line counts, no patch text), and the issues it links to. Bounds are reported in truncated. --attachments <DIR> also downloads the images it references.
neo pr context [OPTIONS] <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--attachments |
<DIR> |
no | Also download every attachment the pack references into DIR (created if missing), as <id>.<ext>. stdout is still exactly the JSON pack; each attachment gets one line on stderr, /a/<id> -> <path>, or a skip line for one you cannot read, which is not an error |
neo pr wait
Section titled “neo pr wait”Block until a PR reaches a terminal state, printing status transitions.
The first-class replacement for a shell loop around neo pr view: one process, and a distinct exit code per outcome instead of grepping prose. It wakes on the repo’s event stream, so a check going green is usually noticed in a second or two rather than at the next poll.
Exit codes: 0 the condition held · 3 a check failed, contexts listed (--for checks) · 4 closed without merging · 5 rejected from the queue or the merge gate still refuses after checks finish, with its reasons (--for merged) · 6 timed out · 7 every check was skipped, so nothing ran (--for checks) · 8 the PR is not being tested on a merge queue candidate (it left the queue, or the queue gates on its head), nothing on the head is red or running, and some head checks were superseded by an earlier candidate, so they will never finish: re-run them, or wait on the queue with --for merged (--for checks) · 1 the command itself failed.
The check set folds BOTH sources the merge gate judges — workflow runs and externally-posted commit statuses — so a red external status cannot read as green. While the merge queue tests the PR on a candidate merge commit, that candidate’s checks are the ones judged (they gate the merge), and each transition names the commit judged.
neo pr wait [OPTIONS] <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--for |
<WAIT_FOR> |
no | checks |
checks, merged |
What to wait for. checks (the default) waits for the CI that gates the PR to finish — on its head, or on the merge queue’s candidate while the queue tests one — a question that always answers itself. merged waits for the PR to land, including queued candidate verification. It warns when no merge is requested and reports a queue rejection or a gate that still refuses after CI finishes outside the queue. |
|
--timeout |
<TIMEOUT> |
no | 3600 |
Maximum seconds to wait (at most 7 days) | ||
--interval |
<INTERVAL> |
no | 30 |
Poll interval in seconds. Values below the floor (30) are raised to it with a warning — replacing hot polling is the point of the command. This is the read cadence only when the forge’s event stream is unavailable (an older deploy, a proxy that will not pass text/event-stream, an exhausted stream budget). With the stream connected the command wakes on events and the timer is a backstop on a longer period, so a lost event costs latency and never a hang. A value above that backstop still wins. |
neo pr merge
Section titled “neo pr merge”Merge a PR when ready, or add it to the merge queue.
Merges immediately when requirements pass, the head is current, and the queue is empty. Otherwise the queue verifies its merge with the target in order. The freshly fetched head guards concurrent pushes. A refusal the queue reaches at once — a red required check, a moved head — exits non-zero with the reason; a PR that is merely waiting prints its queue position and exits 0.
neo pr merge [OPTIONS] <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--auto |
no | Arm the merge without the fetched-head guard. Same merge-or-queue behaviour, but the request carries no expected_head: an armed intent is meant to outlive this command, and a guard taken from a momentarily stale view would have the queue eject it as “source branch moved” on its first look. |
||||
--merge |
no | Land it as a two-parent merge commit. Omit both this and --squash to use the repository’s default method. The selected method is retained while queued. |
||||
--squash |
no | Land it as ONE commit carrying the whole change, authored by the source head’s author, with Co-authored-by: trailers for everyone else on the branch. Refused for a PR with stacked children |
||||
--json |
no | Print the resulting PR as JSON. Queued PRs stay open and carry merge_queue progress; only a completed merge has status: merged |
neo pr update-branch
Section titled “neo pr update-branch”Update a PR’s branch by merging the target into it.
The freshly fetched head commit is sent as a stale guard, so a concurrent push turns the update into an error.
neo pr update-branch [OPTIONS] <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--json |
no | Print what the update DID as JSON — {outcome, new_head}, not a pull request. outcome is updated or already_up_to_date, and new_head carries the source branch’s new head commit exactly when the branch moved |
neo pr close
Section titled “neo pr close”Close a PR without merging
neo pr close [OPTIONS] <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--comment |
<BODY> |
no | Markdown comment to post before closing | |||
--json |
no | Print the closed pull request as JSON |
neo pr edit
Section titled “neo pr edit”Edit a PR’s title or description.
Only supplied fields change; anything omitted keeps its current value. At least one of --title, --body, or --body-file is required. The new description is re-parsed for issue links, so a Closes #N line added or removed here links or unlinks that issue.
neo pr edit [OPTIONS] <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--title |
<TITLE> |
no | Replace the title | |||
--body |
<BODY> |
no | Markdown description; --body "" clears it. Mutually exclusive with --body-file |
|||
--body-file |
<BODY_FILE> |
no | Read the markdown description from a file instead of a shell argument — - reads stdin. Avoids shell-quoting long bodies. Mutually exclusive with --body |
|||
--json |
no | Print the updated pull request as JSON |
neo pr ready
Section titled “neo pr ready”Mark a draft PR ready for review.
Clears the draft flag so the PR can merge and arm auto-merge. --undo converts it back to a draft. Idempotent either way.
neo pr ready [OPTIONS] <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--undo |
no | Convert the pull request back to a draft instead | ||||
--json |
no | Print the updated pull request as JSON |
neo pr comment
Section titled “neo pr comment”Comment on a PR
neo pr comment [OPTIONS] --body <BODY> <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--body |
<BODY> |
yes | Markdown comment body | |||
--json |
no | Print the created comment as JSON |
neo pr review
Section titled “neo pr review”Submit a review decision on a PR
neo pr review [OPTIONS] <--approve|--request-changes|--comment> <NUMBER> [TARGET]| Option | Value | Required | Default | Env | Values | Description |
|---|---|---|---|---|---|---|
<NUMBER> |
yes | Pull request number (the 42 in acme/api#42) |
||||
<TARGET> |
no | <owner>/<repo> or bare <repo>. Inferred from a checkout remote pointing at this host when omitted |
||||
--approve |
no | Approve the PR | ||||
--request-changes |
no | Request changes | ||||
--comment |
no | Comment-only review (no approval state change) | ||||
--body |
<BODY> |
no | "" |
Optional review summary (Markdown) | ||
--json |
no | Print the submitted review as JSON |