feat: forgejo PR lifecycle — create, API squash merge, close, review threads (#17)

Merged
FO
1mo ago
+1014-21

Closes #17

  • forgejo_pr_create: head = current branch, base = repo default branch
  • forgejo_pr_merge: POST /pulls/{n}/merge (default squash + delete branch, head_commit_id pinned). Refuses merged/closed/unmergeable PRs, missing head sha, unreadable reviews, open human threads and requested changes. Bots never block. 405/409 → one line
  • forgejo_pr_close: close without merging, optional comment
  • forgejo_pr_comments: conversation + verdicts + inline comments, open human threads marked
  • forgejo_pr_status: mergeability + threads line for open PRs
  • Threads = conversations (file+line), resolved when resolved in the Forgejo UI — a reply alone never clears one (matches the rule "reply until they resolve"; the issue's "later author reply" heuristic is deliberately not used)
  • README: workflow walkthrough, token scopes per tool (PR tools need issue too); 25 → 29 tools, 0.4.0

Step 0 not done: the live squash-merge check against a real Forgejo instance needs a token, which this machine doesn't have. Run once before relying on forgejo_pr_merge: open a throwaway PR, forgejo_pr_merge pr=<n>, confirm the PR shows merged and the referenced issue closed.

Gates: tsc clean · 304 tests pass · build ok · local review: re-score pending


Summary by cubic

Implements the full Forgejo PR lifecycle — create, API squash merge, close, and review-thread reading — and extends forgejo_pr_status with mergeability and thread state. Package @four-bytes/four-opencode-git bumps to 0.4.0 (25 → 29 tools). Closes #17.

One live check is still missing: a real Forgejo squash merge wasn't verified because this machine has no token. Merge a throwaway PR once to confirm it shows merged and a referenced Closes #N issue closes.

Merge and review rules

  • forgejo_pr_merge refuses closed, conflicted, or review-blocked PRs and never merges blind when reviews can't be read; 405/409 failures map to one readable line.
  • Only unresolved human threads or a human REQUEST_CHANGES verdict block merges — bot findings never do.
  • Inline comments are grouped into conversations by file + line (same-line threads count as one); dismissed-review comments are ignored.
  • A thread counts as open until resolved in the Forgejo UI; a reply alone never clears it.
  • forgejo_pr_comments lists conversations, verdicts, and inline comments in time order, marking OPEN threads.
  • forgejo_pr_status shows mergeability for open PRs, flagging "unknown" when Forgejo hasn't computed it yet.
  • README documents a workflow walkthrough and per-tool token scopes; PR tools need the issue scope too.