chore(forge): search pull requests and issues, pr close and reopen, pr view --body and --json #831

Open
zeldaootr wants to merge 7 commits from zeldaootr/Longshot:forge-search-close-body into main
Contributor

Type: chore · Risk: low · Tested on: Linux, game-free checks and read-only calls to git.magicbean.dev · Needs: none

Why

An agent spent hours building a change that another contributor already had open as a WIP pull request under the same
switch name: pr list prints only titles, over 350 of them, and nothing searches the descriptions. A PR superseded by
a merged change could only be commented on, not closed, and editing a description meant calling the API by hand to get
its raw text. This adds the three commands that were missing.

What changed

forge.py search finds the pull requests and issues that already name a switch, a function or some words; pr close
closes a PR with a comment saying why; pr view --body prints the description alone, so it can be edited and put back.

  • forge: search WORD|"A PHRASE" ... [--state open|closed|all] [--mine] [--limit N] in scripts/forge.py
    (cmd_search, listing, matching_line): every word or quoted phrase must be in the title or the description, in
    any case. Each hit prints its number, PR or issue, its state (open, wip, merged, closed), author, title and
    the description's line with the match, shortened around it. Nothing found says so, with exit code 0. It reads the
    issue listing (both kinds, 50 a page, 4 pages at once) and matches locally, not through Forgejo's q= search: on
    this forge (17.0.1) the indexer found 70 of the 90 items with "mesh" and "shaders" in them and was no faster. --mine
    passes created_by.
  • forge: pr close N (--comment TEXT | --comment-file F) [--force] (cmd_pr_close) posts the comment, then closes.
    The comment is required, and someone else's PR is refused without --force. pr reopen N [--comment ...]
    (cmd_pr_reopen) opens a closed PR again and refuses a merged one.
  • forge: pr view N --body (print_raw) prints the description exactly as stored and nothing else: into a file or a
    pipe its UTF-8 bytes, so CRLF stays CRLF on Windows too. --json (pr_json) prints number, title, state, WIP, head
    and base refs and commits, merge base, author, labels, description and times. Both exclude --comments. The plain
    pr view output is unchanged.
  • docs: docs/forge.md (a Search before building section, close and reopen, --body for editing a description),
    AGENTS.md (search before building, in the Choosing or claiming work bullet, linking docs/forge.md).
  • tests: tests/test_forge_search.py (new) and tests/test_forge_pr.py, against a stand-in Forgejo in memory.

Measurements

Nothing to measure: a script for the forge with its own game-free tests; the game doesn't run it.

Flags and settings

None

Testing

Tested: Linux. python -I -B tests/run_all.py: 495 passed, 85 skipped, 14 failed. The same 14 fail on main
(aa95d35f) on this PC, and none of them reads the forge script: test_appimage_player_build, test_lift_cache,
test_crash_dialog, test_mods_size_table, test_make_game_cache, test_pipeline_tour, test_env_on,
test_lift_cleanup_error, test_cpm_discovery, test_walk_key, test_bake_portability, test_vk_pgo,
test_readback_late, test_options_budget_once. The forge checks (test_forge_pr, test_forge_search,
test_forge_session_lock, test_check_pr_description) pass. The new tests cover search matching (a switch name in a
Flags table, any case, a phrase across a line break, every word required), the output's shape, the states, --state,
--mine, --limit and paging, and nothing found. They also cover pr close's comment and PATCH bodies in that
order, its refusals (no comment, an empty one, someone else's PR, a closed or merged one), pr reopen, pr view --body
printing exactly the body (CRLF, no last newline, an emoji, into a cp1252 pipe), and --json's fields. Close and
reopen also ran over HTTP against a local stub server, which received the comment POST, then
PATCH {"state": "closed"} (and {"state": "open"} for reopen), with the sign-in's bearer token. Read-only against
git.magicbean.dev: search RX_VK_ASTC_BC1 (2 found, both WIP PRs naming it, in about 12 s), search "mesh shaders"
(38 found in about 8 s), pr view 687 --body | head and pr view 687 --json.

Not tested: pr close and pr reopen against git.magicbean.dev itself (only read-only calls were made there);
Windows (the code is the standard library only, and --body's byte output is covered by the cp1252 pipe test).

Must be tested:

  • None

Risks

What could break: Nothing existing: pr list, pr view without the new flags and the other commands print as
before. A search lists every open item (about 570 now), which takes 8 to 15 s.

Turning it off: revert the commit

Compatibility: Nothing changes

Checklist

Everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description) of the status line's type.
  • Why gives the reason plainly and links the issues that fit (the tracker searched).
  • Measurements has a verdict, or one line saying why there is nothing to measure.
  • Testing names what was tested, what wasn't, and what must still be tested, where and how.
  • Rebased on current main. Onto main 94abdd57 (head da418ffa) with one conflict, in AGENTS.md: main's 08f3d3d3 (docs(agents)) replaced its Pick and claim work section and the PR command block with a guide per task, so the search line now sits in the Choosing or claiming work bullet and links docs/forge.md#search-before-building, and the pr view --body and pr close lines, which docs/forge.md in this PR already has, are no longer added to AGENTS.md (that commit is now docs(agents): search before building), with the commit subjects made Conventional Commits, which CI's lint job now checks for every commit, on a base that has CI's config (#417); each commit's change is the same as before by git patch-id. The commits named in this description are from before this rebase: 23e4ff77 is now 82d96724, c1452d58 is now 69c47ab4, 1a8e39e6 is now b76e55a7, 0be29674 is now af1dd980, 584b15c2 is now de07ec7d, b48507b4 is now 35f9e11e, 306dd602 is now da418ffa. Re-run on 94abdd57: the forge checks (test_forge_pr, test_forge_search, test_forge_session_lock, test_check_pr_description) and every check that reads the changed files pass, 5 of 5 with g++ and the 2 new ones with clang too.
  • python -I -B tests/run_all.py passes (any failure that also fails on main is named).
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

When it applies

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • A check under tests/ that reads changed source updated in this PR, not weakened.
  • Docs updated.
**Type:** chore · **Risk:** low · **Tested on:** Linux, game-free checks and read-only calls to git.magicbean.dev · **Needs:** none ## Why An agent spent hours building a change that another contributor already had open as a WIP pull request under the same switch name: `pr list` prints only titles, over 350 of them, and nothing searches the descriptions. A PR superseded by a merged change could only be commented on, not closed, and editing a description meant calling the API by hand to get its raw text. This adds the three commands that were missing. ## What changed `forge.py search` finds the pull requests and issues that already name a switch, a function or some words; `pr close` closes a PR with a comment saying why; `pr view --body` prints the description alone, so it can be edited and put back. - forge: `search WORD|"A PHRASE" ... [--state open|closed|all] [--mine] [--limit N]` in `scripts/forge.py` (`cmd_search`, `listing`, `matching_line`): every word or quoted phrase must be in the title or the description, in any case. Each hit prints its number, PR or issue, its state (`open`, `wip`, `merged`, `closed`), author, title and the description's line with the match, shortened around it. Nothing found says so, with exit code 0. It reads the issue listing (both kinds, 50 a page, 4 pages at once) and matches locally, not through Forgejo's `q=` search: on this forge (17.0.1) the indexer found 70 of the 90 items with "mesh" and "shaders" in them and was no faster. `--mine` passes `created_by`. - forge: `pr close N (--comment TEXT | --comment-file F) [--force]` (`cmd_pr_close`) posts the comment, then closes. The comment is required, and someone else's PR is refused without `--force`. `pr reopen N [--comment ...]` (`cmd_pr_reopen`) opens a closed PR again and refuses a merged one. - forge: `pr view N --body` (`print_raw`) prints the description exactly as stored and nothing else: into a file or a pipe its UTF-8 bytes, so CRLF stays CRLF on Windows too. `--json` (`pr_json`) prints number, title, state, WIP, head and base refs and commits, merge base, author, labels, description and times. Both exclude `--comments`. The plain `pr view` output is unchanged. - docs: `docs/forge.md` (a *Search before building* section, close and reopen, `--body` for editing a description), `AGENTS.md` (search before building, in the *Choosing or claiming work* bullet, linking `docs/forge.md`). - tests: `tests/test_forge_search.py` (new) and `tests/test_forge_pr.py`, against a stand-in Forgejo in memory. ## Measurements Nothing to measure: a script for the forge with its own game-free tests; the game doesn't run it. ### Flags and settings None ## Testing **Tested:** Linux. `python -I -B tests/run_all.py`: 495 passed, 85 skipped, 14 failed. The same 14 fail on `main` (`aa95d35f`) on this PC, and none of them reads the forge script: `test_appimage_player_build`, `test_lift_cache`, `test_crash_dialog`, `test_mods_size_table`, `test_make_game_cache`, `test_pipeline_tour`, `test_env_on`, `test_lift_cleanup_error`, `test_cpm_discovery`, `test_walk_key`, `test_bake_portability`, `test_vk_pgo`, `test_readback_late`, `test_options_budget_once`. The forge checks (`test_forge_pr`, `test_forge_search`, `test_forge_session_lock`, `test_check_pr_description`) pass. The new tests cover search matching (a switch name in a Flags table, any case, a phrase across a line break, every word required), the output's shape, the states, `--state`, `--mine`, `--limit` and paging, and nothing found. They also cover `pr close`'s comment and `PATCH` bodies in that order, its refusals (no comment, an empty one, someone else's PR, a closed or merged one), `pr reopen`, `pr view --body` printing exactly the body (CRLF, no last newline, an emoji, into a cp1252 pipe), and `--json`'s fields. Close and reopen also ran over HTTP against a local stub server, which received the comment `POST`, then `PATCH {"state": "closed"}` (and `{"state": "open"}` for reopen), with the sign-in's bearer token. Read-only against git.magicbean.dev: `search RX_VK_ASTC_BC1` (2 found, both WIP PRs naming it, in about 12 s), `search "mesh shaders"` (38 found in about 8 s), `pr view 687 --body | head` and `pr view 687 --json`. **Not tested:** `pr close` and `pr reopen` against git.magicbean.dev itself (only read-only calls were made there); Windows (the code is the standard library only, and `--body`'s byte output is covered by the cp1252 pipe test). **Must be tested:** - None ## Risks **What could break:** Nothing existing: `pr list`, `pr view` without the new flags and the other commands print as before. A search lists every open item (about 570 now), which takes 8 to 15 s. **Turning it off:** revert the commit **Compatibility:** Nothing changes ## Checklist ### Everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`) of the status line's type. - [x] Why gives the reason plainly and links the issues that fit (the tracker searched). - [x] Measurements has a verdict, or one line saying why there is nothing to measure. - [x] Testing names what was tested, what wasn't, and what must still be tested, where and how. - [x] Rebased on current `main`. Onto main 94abdd57 (head da418ffa) with one conflict, in `AGENTS.md`: main's 08f3d3d3 (`docs(agents)`) replaced its *Pick and claim work* section and the PR command block with a guide per task, so the search line now sits in the *Choosing or claiming work* bullet and links `docs/forge.md#search-before-building`, and the `pr view --body` and `pr close` lines, which `docs/forge.md` in this PR already has, are no longer added to `AGENTS.md` (that commit is now `docs(agents): search before building`), with the commit subjects made Conventional Commits, which CI's lint job now checks for every commit, on a base that has CI's config (https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/417); each commit's change is the same as before by `git patch-id`. The commits named in this description are from before this rebase: 23e4ff77 is now 82d96724, c1452d58 is now 69c47ab4, 1a8e39e6 is now b76e55a7, 0be29674 is now af1dd980, 584b15c2 is now de07ec7d, b48507b4 is now 35f9e11e, 306dd602 is now da418ffa. Re-run on 94abdd57: the forge checks (`test_forge_pr`, `test_forge_search`, `test_forge_session_lock`, `test_check_pr_description`) and every check that reads the changed files pass, 5 of 5 with g++ and the 2 new ones with clang too. - [x] `python -I -B tests/run_all.py` passes (any failure that also fails on `main` is named). - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### When it applies - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] A check under `tests/` that reads changed source updated in this PR, not weakened. - [x] Docs updated.
Assisted-by: Claude
Assisted-by: Claude
Assisted-by: Claude
Assisted-by: Claude
Assisted-by: Claude
Assisted-by: Claude
docs(agents): search before building, pr view --body, pr close
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 4s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Guide screenshots / Guide images and local UI source review (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
306dd6027e
Assisted-by: Claude
Owner

This conflicts with main in AGENTS.md: it was cut down to a pointer page and its pull request guidance moved to docs/agent-pull-requests.md (the docs(agents) commit, then #571), so the two new lines (search before building, pr view --body and pr close) need a new home there. The code and test commits rebase without conflicts. Please rebase onto current main.

This conflicts with `main` in `AGENTS.md`: it was cut down to a pointer page and its pull request guidance moved to `docs/agent-pull-requests.md` (the `docs(agents)` commit, then https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/571), so the two new lines (search before building, `pr view --body` and `pr close`) need a new home there. The code and test commits rebase without conflicts. Please rebase onto current `main`.
zeldaootr force-pushed forge-search-close-body from 306dd6027e
Some checks failed
PR description / Description follows the template (pull_request_target) Successful in 4s
CI / Conventional Commit title (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been cancelled
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been cancelled
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been cancelled
CI / Workflow lint (actionlint) (pull_request) Has been cancelled
Guide screenshots / Guide images and local UI source review (pull_request) Has been cancelled
Third-party parts / As their notes say (pull_request) Has been cancelled
Third-party parts / The same as upstream (pull_request) Has been cancelled
to da418ffa7a
Some checks are pending
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
Guide screenshots / Guide images and local UI source review (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
Website / Website on Cloudflare (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 3s
2026-11-15 19:16:32 +00:00
Compare
Author
Contributor

Rebased onto main 94abdd57 (head da418ffa), with one conflict, in AGENTS.md: main's 08f3d3d3 (docs(agents)) replaced its Pick and claim work section and the PR command block with a guide per task, so the search line now sits in the Choosing or claiming work bullet and links docs/forge.md#search-before-building, and the pr view --body and pr close lines, which docs/forge.md in this PR already has, are no longer added to AGENTS.md (that commit is now docs(agents): search before building); the commit subjects are now Conventional Commits, which CircleCI's lint job checks for every commit of a pull request (#417), and the base has the CI's config, which a fork's pull request needs at its own head. No other change: each commit's change is the same as before by git patch-id.
Re-run on 94abdd57: the forge checks (test_forge_pr, test_forge_search, test_forge_session_lock, test_check_pr_description) and every check that reads the changed files pass, 5 of 5 with g++ and the 2 new ones with clang too. The description names the new commits.

Rebased onto `main` 94abdd57 (head da418ffa), with one conflict, in `AGENTS.md`: main's 08f3d3d3 (`docs(agents)`) replaced its *Pick and claim work* section and the PR command block with a guide per task, so the search line now sits in the *Choosing or claiming work* bullet and links `docs/forge.md#search-before-building`, and the `pr view --body` and `pr close` lines, which `docs/forge.md` in this PR already has, are no longer added to `AGENTS.md` (that commit is now `docs(agents): search before building`); the commit subjects are now Conventional Commits, which CircleCI's lint job checks for every commit of a pull request (https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/417), and the base has the CI's config, which a fork's pull request needs at its own head. No other change: each commit's change is the same as before by `git patch-id`. Re-run on 94abdd57: the forge checks (`test_forge_pr`, `test_forge_search`, `test_forge_session_lock`, `test_check_pr_description`) and every check that reads the changed files pass, 5 of 5 with g++ and the 2 new ones with clang too. The description names the new commits.
Some checks are pending
CI / Conventional Commit title (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Blocked by required conditions
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Blocked by required conditions
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Blocked by required conditions
CI / Workflow lint (actionlint) (pull_request) Blocked by required conditions
Guide screenshots / Guide images and local UI source review (pull_request) Blocked by required conditions
Third-party parts / As their notes say (pull_request) Blocked by required conditions
Third-party parts / The same as upstream (pull_request) Blocked by required conditions
Website / Website on Cloudflare (pull_request) Blocked by required conditions
PR description / Description follows the template (pull_request_target) Successful in 3s
This pull request has changes conflicting with the target branch.
  • AGENTS.md
  • scripts/forge.py
Some workflows are waiting to be reviewed.
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'forge-search-close-body:zeldaootr-forge-search-close-body'
git switch 'zeldaootr-forge-search-close-body'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Longshot!831
No description provided.