From 65d5e5fb1f8cd95222d4b326ebba897dd2947a7e Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:53:05 +0900 Subject: [PATCH 01/25] Require inline PR review comments --- .opencode/commands/review-pr.md | 117 ++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 37 deletions(-) diff --git a/.opencode/commands/review-pr.md b/.opencode/commands/review-pr.md index 4cc8dc8..c6193b5 100644 --- a/.opencode/commands/review-pr.md +++ b/.opencode/commands/review-pr.md @@ -1,11 +1,13 @@ --- -description: Comprehensive GitHub PR review — gathers the PR via gh, runs specialized review subagents in parallel, normalizes and deduplicates findings, validates file:line references against the diff, and returns a single review response for the OpenCode GitHub integration to post. +description: Comprehensive GitHub PR review — gathers the PR via gh, runs specialized review subagents in parallel, normalizes and deduplicates findings, validates diff anchors, and submits GitHub inline review comments when findings can be anchored. agent: general --- # Comprehensive PR Review -Perform a comprehensive pull request review by orchestrating specialized review subagents in parallel. Each subagent returns only noteworthy findings in a normalized format. You then deduplicate and filter across agents, validate file:line references against the diff, and return a single review response. The surrounding `opencode github run` integration posts that response to the PR as `opencode-agent[bot]`; do not post to GitHub yourself. +Perform a comprehensive pull request review by orchestrating specialized review subagents in parallel. Each subagent returns only noteworthy findings in a normalized format. You then deduplicate and filter across agents, validate each finding against the PR diff, and submit a GitHub pull request review with inline comments for every finding that has a valid diff anchor. + +The surrounding `opencode github run` integration always posts your final text as a PR comment. Therefore, when you successfully submit GitHub review comments yourself, return only a short status message instead of a second full review body. **Requested review aspects (optional):** "$ARGUMENTS" @@ -31,8 +33,8 @@ if [[ -z "${PR_NUMBER}" && "${GITHUB_REF:-}" =~ ^refs/pull/([0-9]+)/merge$ ]]; t fi ``` -- If `PR_NUMBER` is set, run `gh pr view "$PR_NUMBER" --json number,title,body,baseRefName,headRefName,files,url` to confirm a PR is available. - - If it succeeds, you are in **PR mode**: return a review response (step 7). +- If `PR_NUMBER` is set, run `gh pr view "$PR_NUMBER" --json number,title,body,baseRefName,headRefName,headRefOid,files,url` to confirm a PR is available. + - If it succeeds, you are in **PR mode**: submit a GitHub PR review when findings exist (step 7). - If it fails (no PR or not in CI), fall back to **local mode**: review `git diff` and `git status`, and report findings directly to the user without posting anything to GitHub. - Do not rely on the current git branch to identify the PR. GitHub Actions pull request workflows usually check out a detached merge ref. @@ -41,7 +43,7 @@ fi - **PR mode:** run `gh pr diff "$PR_NUMBER"` for the full diff and use the `files` list from `gh pr view "$PR_NUMBER"` for the changed-file set. Prefer `gh pr diff "$PR_NUMBER"` over `git diff` because CI checkouts are shallow (`fetch-depth: 1`). - **Local mode:** run `git diff --name-only HEAD` plus untracked files from `git status --short` for the changed-file set, then `git diff` for content. -Capture the changed-file list, the full diff, and the PR metadata (title, body, base/head branch) to hand to the subagents. +Capture the changed-file list, the full diff, and the PR metadata (title, body, base/head branch, head SHA) to hand to the subagents and to build the final review payload. ## 3. Choose applicable reviewers based on $ARGUMENTS @@ -106,7 +108,7 @@ Instruct every subagent to: - If no noteworthy findings exist, return an empty list and a one-line "no issues" note. -Do **not** let subagents post comments themselves. The orchestrator returns the final response; the `opencode github run` integration posts it. +Do **not** let subagents post comments themselves. The orchestrator validates, deduplicates, and posts the final review. ## 5. Normalize, filter, and aggregate findings @@ -120,7 +122,7 @@ Collect all findings from all subagents. Each finding must have `file`, `line`, 2. **Drop nitpicks**: remove cosmetic preferences, style-only feedback, or issues with no real-world impact. 3. **Drop findings not supported by the diff**: if the file referenced is not in the changed-file set, drop the finding. Do **not** compare `line` against the changed-file set — it contains paths, not line numbers. Leave line validation to the diff-anchoring step (step 6). 4. **Deduplicate across agents**: if two or more agents report substantially the same issue at the same location, keep the most specific one (usually from the specialized agent) and discard the duplicate. -5. **Aggregate by root cause**: when several findings share the same underlying root cause (for example, the same inconsistency repeated across README, SKILL.md, and command files), keep **one representative finding** as a `file:line` reference and collapse the remaining occurrences into the summary body. Prefer root-cause aggregation over line-by-line repetition. Cross-document or cross-file consistency problems should usually be summarized once in the review body instead of repeated at each affected location. +5. **Aggregate by root cause only when it still preserves actionable anchors**: when several findings share the same underlying root cause, keep one representative inline comment at the best anchor and mention the other affected files briefly in that comment. Do not collapse anchored findings into a top-level-only summary when an inline anchor is available. 6. **Orchestrator second filter**: review every remaining finding yourself and remove any you do not also deem noteworthy. This filter keeps the signal high. ### Grouping @@ -133,64 +135,105 @@ Group surviving findings by severity: Prefer fewer, higher-signal comments over exhaustive lists. Optional guardrail suggestions (such as adding tests for agent frontmatter or reference validation) should be downgraded to `suggestion` severity at most. -## 6. Validate file:line references against the diff +## 6. Validate anchors and build inline review comments + +Before submitting a GitHub review, validate every finding against the PR diff and classify it as either `inline` or `summary_only`. -Before building the review response, validate every finding against the PR diff so the `file:line` references in the single OpenCode comment stay accurate. +### Inline-first contract -### Validation rules +- Every finding with a valid `file` and diff-anchorable `line` must become an inline review comment. +- Do not skip inline comments merely because the same finding is also listed in a summary. +- Do not convert all findings into a single top-level markdown response when one or more valid inline anchors exist. +- Summary-only findings are allowed only when the issue is real but cannot be safely anchored to the diff, such as a cross-file design issue or a stale/unavailable line. + +### Anchor validation rules - Obtain the diff hunk list from `gh pr diff "$PR_NUMBER"` (already gathered in step 2). -- For each finding, check whether its `line` appears in the diff or diff context for `file`. - - A line is valid if: it falls within a `+` hunk in the diff for the given file, or within the surrounding unchanged-context lines of that hunk. -- If a finding's line **cannot be safely matched** to the diff, keep it in the summary body but reference the nearest valid anchor line (or the file alone) instead of an unverified line number. Do **not** drop it — the file is a changed file, only the line is unverifiable. -- Never fail the entire review because one finding's line is unverifiable. Adjust the reference and continue. +- For each finding, check whether its `line` is present in a hunk for `file` on the head side of the PR. +- Prefer anchoring to an added or modified line that directly caused the issue. +- If the reported line is not anchorable but the same finding has a nearby valid head-side diff line in the same file, adjust the anchor to that nearest relevant line and keep it inline. +- If no safe anchor exists, mark the finding `summary_only` with a short reason. Do not silently drop it. + +### Inline comment body format -## 7. Return the results +Each inline comment body must be concise and self-contained: -### PR mode +```markdown +** · **: +``` -Return a **single concise markdown review response**. Do **not** call `gh api`, `gh pr review`, or `gh pr comment` — the surrounding `opencode github run` integration is responsible for posting the final response to the PR as `opencode-agent[bot]`. Calling GitHub write APIs directly would create a duplicate `github-actions[bot]` posting. +Avoid repeating the file path or line number inside the inline body because GitHub already displays the anchor. Keep each body one short paragraph unless a minimal code suggestion is genuinely useful. -Include all findings (whether or not their line matched the diff) in the summary body as `file:line` references so the single top-level OpenCode comment stays actionable. +## 7. Submit the review in PR mode -**Summary body format:** +### No findings -```markdown -## OpenCode PR Review +If there are no findings after filtering, return exactly: + +```text +No noteworthy issues found. +``` -Reviewed files across areas: . +Do not post a GitHub review with an empty comments array. -### Critical () +### Findings with at least one inline anchor -- `file:line` — issue +Submit a single GitHub pull request review using the REST API via `gh api`. Do not use `gh pr review` for inline findings because it cannot submit a structured `comments` array for per-line anchors in this workflow. -### Important () +Build a payload like this: -- `file:line` — issue +```json +{ + "commit_id": "", + "event": "COMMENT", + "body": "OpenCode PR Review: inline finding(s), summary-only finding(s).", + "comments": [ + { + "path": "path/to/file", + "line": 123, + "side": "RIGHT", + "body": "**important · security-code-reviewer**: Validate the user-controlled value before passing it to the shell." + } + ] +} +``` -### Suggestions () +Then submit it: -- `file:line` — issue +```bash +gh api \ + --method POST \ + "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/reviews" \ + --input /tmp/opencode-pr-review.json ``` -When a root cause affects multiple files, add a single summary entry naming all affected files (e.g. `Same inconsistency across README.md, SKILL.md, review-pr.md`). +Operational requirements: + +- `GH_TOKEN` or `GITHUB_TOKEN` must have `pull-requests: write` permission. +- Use the PR head SHA from `gh pr view --json headRefOid` as `commit_id`. +- Include `summary_only` findings in the review `body`, not as fake inline comments. +- If GitHub rejects the review because one inline anchor is invalid, remove only the rejected/unverifiable inline comment, move it to `summary_only` with the failure reason, and retry once. +- If the retry still fails, return a concise failure report that includes the attempted inline comment count, the failing anchor(s), and the summary-only fallback body. Do not claim inline comments were posted. -If there are **no findings at all**, return: +After a successful submission, return only a concise status for the surrounding OpenCode integration to post, for example: ```text -No noteworthy issues found. +Submitted OpenCode PR review with 3 inline comment(s) and 1 summary-only finding. ``` -Do not spam praise or padding. One concise confirmation is sufficient. +### Findings without inline anchors + +If all findings are valid but none can be safely anchored inline, return a concise markdown review body as a top-level fallback and explicitly state why inline comments were not used. -### Local mode +## 8. Local mode -Print the same summary to the user. Do not call `gh`. +Print the same normalized review summary to the user. Do not call `gh api`, `gh pr review`, or `gh pr comment`. -## 8. Notes +## 9. Notes - Keep feedback concise. A short review with real signal beats a long review with padding. -- Never include secrets, tokens, or full file contents in the review response. -- The `opencode github run` integration posts your final response to the PR as `opencode-agent[bot]`; do not call `gh api`, `gh pr review`, or `gh pr comment` yourself. The workflow may still grant `pull-requests: write` for the integration's posting, and `GH_TOKEN` or `GITHUB_TOKEN` is needed only for `gh pr diff` / `gh pr view` reads. Do not attempt to push commits or merge. +- Never include secrets, tokens, or full file contents in the review response or GitHub comments. +- Do not call `gh pr comment`; it creates top-level noise and bypasses inline review anchors. +- Use `gh api` only for the single final PR review submission after all findings are normalized, deduplicated, and anchor-validated. - If `$ARGUMENTS` lists specific aspects, respect them and skip the rest. - Re-run after fixes to verify issues are resolved. From 6f7ab138ee802faadf5df4e5308d2390858df0fb Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:53:32 +0900 Subject: [PATCH 02/25] Document inline PR review comments --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4843404..cf134cf 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ jobs: uses: dceoy/opencode-action@v0 env: OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ github.token }} with: model: opencode-go/glm-5.2 ``` @@ -82,9 +82,12 @@ When `use-github-token: true`, pass `GITHUB_TOKEN` in `env` and grant the workfl ## Pull Request Reviews -The bundled `/review-pr` command produces a single markdown review response that the OpenCode GitHub integration posts to the PR as `opencode-agent[bot]`. The command does not post to GitHub directly, so a review run yields one OpenCode PR comment rather than a separate `github-actions[bot]` review. Workflows that invoke it must provide: +The bundled `/review-pr` command submits a GitHub pull request review through `gh api`. It uses inline review comments for every finding that can be safely anchored to the PR diff, and includes only unanchorable findings in the review body as summary-only fallback items. The surrounding `opencode github run` integration still posts the command's final text to the PR, so the command returns only a short status message after a successful inline review submission. -- `GH_TOKEN: ${{ github.token }}` or `GITHUB_TOKEN: ${{ github.token }}` for `gh pr diff` / `gh pr view` reads +Workflows that invoke `/review-pr` must provide: + +- `pull-requests: write` permission +- `GH_TOKEN: ${{ github.token }}` or `GITHUB_TOKEN: ${{ github.token }}` for `gh pr diff`, `gh pr view`, and `gh api` review submission - A valid API key for the selected model provider with available credits or quota Example OpenCode step: @@ -134,7 +137,7 @@ The bundled toolkit combines Claude Code Action-style core reviewers with `pr-re - **`comment-analyzer`** — comment accuracy, completeness, and comment rot - **`type-design-analyzer`** — type invariants, encapsulation, and design quality -Findings are normalized, deduplicated across agents, and validated against the PR diff before being returned. All findings go into a single markdown response as `file:line` references; duplicated root causes produce one summary entry listing all affected files, and cross-document or cross-file consistency problems are summarized once instead of repeated at each location. The surrounding `opencode github run` integration posts that response to the PR as `opencode-agent[bot]`. +Findings are normalized, deduplicated across agents, and validated against the PR diff before being posted. Diff-anchorable findings are submitted as GitHub inline review comments. Findings that cannot be safely anchored remain in the PR review body with an explicit fallback reason instead of being silently skipped. ## Examples From 8221ce8a677053fcc7ece3df455f644c310f1826 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:57:24 +0900 Subject: [PATCH 03/25] Update review-pr skill for inline comments --- .opencode/skills/review-pr/SKILL.md | 98 ++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 28 deletions(-) diff --git a/.opencode/skills/review-pr/SKILL.md b/.opencode/skills/review-pr/SKILL.md index 021c460..d4e5c27 100644 --- a/.opencode/skills/review-pr/SKILL.md +++ b/.opencode/skills/review-pr/SKILL.md @@ -1,11 +1,13 @@ --- name: review-pr -description: Run a comprehensive pull request review across changed files using Claude Code Action-compatible core reviewers and pr-review-toolkit specialty agents. Gathers the PR via gh, runs agents in parallel, normalizes and deduplicates findings, validates file:line references against the diff, and returns a single review response for the OpenCode GitHub integration to post. Use when reviewing a PR before merge, before requesting review, after addressing feedback, or when the user asks to review a diff or recent changes. +description: Run a comprehensive pull request review across changed files using Claude Code Action-compatible core reviewers and pr-review-toolkit specialty agents. Gathers the PR via gh, runs agents in parallel, normalizes and deduplicates findings, validates diff anchors, and submits GitHub inline review comments when findings can be anchored. Use when reviewing a PR before merge, before requesting review, after addressing feedback, or when the user asks to review a diff or recent changes. --- # Comprehensive PR Review -Run a comprehensive pull request review by orchestrating specialized review agents, each focusing on one aspect of code quality. The orchestrator gathers the PR, spawns agents as subagents via the `task` tool, normalizes and deduplicates findings, validates file:line references against the diff, and returns a single review response. The surrounding `opencode github run` integration posts that response to the PR as `opencode-agent[bot]`; the skill must not post to GitHub directly. +Run a comprehensive pull request review by orchestrating specialized review agents, each focusing on one aspect of code quality. The orchestrator gathers the PR, spawns agents as subagents via the `task` tool, normalizes and deduplicates findings, validates every finding against the PR diff, and submits GitHub inline review comments for every diff-anchorable finding. + +The surrounding `opencode github run` integration always posts the final assistant text to the PR. After a successful inline review submission, return only a short status message so the integration does not duplicate the full review as a top-level comment. ## When to Use @@ -100,55 +102,95 @@ Every subagent returns findings in this normalized structure: message: ``` -### Filtering rules applied before returning the response +### Filtering rules applied before posting the review 1. Drop praise-only items (no actionable issue). 2. Drop nitpicks (cosmetic preferences, no real-world impact). 3. Drop findings not supported by the diff — check **file membership only**; the changed-file set contains paths, not line numbers. Leave line validation to the anchoring step. 4. Deduplicate across agents (keep the most specific finding when two agents report the same issue at the same location). -5. **Aggregate by root cause**: when several findings share the same underlying root cause (e.g. the same inconsistency repeated across README, SKILL.md, and command files), keep one representative finding as a `file:line` reference and collapse the rest into the summary body. Prefer root-cause aggregation over line-by-line repetition. Cross-document or cross-file consistency problems should usually be summarized once in the review body instead of repeated at each affected location. +5. Aggregate by root cause only when it still preserves an actionable inline anchor. If several findings share one root cause, keep one representative inline comment at the best anchor and mention the other affected files briefly in that comment. Do not collapse an anchorable finding into a top-level-only summary. 6. Orchestrator second filter: the orchestrator reviews every remaining finding and discards any it does not also deem noteworthy. Prefer fewer, higher-signal comments over exhaustive lists. Optional guardrail suggestions (such as adding tests for agent frontmatter or reference validation) should be downgraded to `suggestion` severity at most. -## File:line Reference Validation +## Diff Anchor Validation + +Before submitting a GitHub review, classify every surviving finding as either inline or summary-only. + +### Inline comment requirements -Before building the review response, every finding is validated against the PR diff so the `file:line` references in the single OpenCode comment stay accurate: +- Every finding with a valid `file` and diff-anchorable `line` must become an inline review comment. +- Do not skip inline comments merely because the same finding is also listed in a summary. +- Do not convert all findings into a single top-level markdown response when one or more valid inline anchors exist. +- Summary-only findings are allowed only when the issue is real but cannot be safely anchored to the diff, such as a cross-file design issue or a stale/unavailable line. -- A line is valid if it falls within a `+` hunk or surrounding unchanged-context lines of that hunk for the given file. -- Findings whose line cannot be safely matched are **kept in the summary body** with the nearest valid anchor line (or the file alone) instead of an unverified line number — not dropped, since the file is a changed file and only the line is unverifiable. +### Anchor validation rules + +- Use the hunk list from `gh pr diff` in PR mode or `git diff` in local mode. +- A line is valid when it can be anchored on the head side of a hunk for the given file. +- Prefer an added or modified line that directly caused the issue. +- If the reported line is not anchorable but the same finding has a nearby valid head-side diff line in the same file, adjust to the nearest relevant line and keep it inline. +- If no safe anchor exists, mark the finding summary-only with a short reason. Do not silently drop it. - One unverifiable reference never fails the entire review. -## Review Output Policy +## Review Submission Policy + +### PR mode with no findings + +Return exactly: + +```text +No noteworthy issues found. +``` + +Do not submit an empty GitHub review. -Return one final markdown review response. Do **not** call `gh api`, `gh pr review`, or `gh pr comment` — the surrounding `opencode github run` integration posts the response to the PR as `opencode-agent[bot]`. Posting directly would create a duplicate `github-actions[bot]` posting. +### PR mode with inline findings -All findings (whether or not their line matched the diff) go in the summary body as `file:line` references so the single top-level OpenCode comment stays actionable. +Submit one GitHub pull request review via `gh api` using a structured review payload with `comments` entries. Use `gh api` instead of `gh pr review` because this workflow needs explicit per-line anchors. -**Output policy:** +The review payload must include: + +- `commit_id`: PR head SHA from `gh pr view --json headRefOid` +- `event`: `COMMENT` +- `body`: concise review summary plus any summary-only findings and fallback reasons +- `comments`: one entry per inline finding, each with `path`, `line`, `side: RIGHT`, and concise `body` + +Inline comment body format: + +```markdown +** · **: +``` + +Operational requirements: + +- `GH_TOKEN` or `GITHUB_TOKEN` must have pull request write permission. +- If GitHub rejects the review because one inline anchor is invalid, remove only the rejected or unverifiable inline comment, move it to the summary-only section with the failure reason, and retry once. +- If the retry still fails, return a concise failure report that includes the attempted inline comment count, failing anchors, and the summary-only fallback body. Do not claim inline comments were posted. + +After a successful submission, return only a concise status, for example: + +```text +Submitted OpenCode PR review with 3 inline comment(s) and 1 summary-only finding. +``` -- **Duplicated root causes** → one summary entry listing all affected files. -- Reserve `file:line` references for issues tied to a specific line. Cross-document or cross-file consistency problems should usually be summarized once in the review body instead of repeated across every affected file. +### PR mode without inline findings -Use the review body for: +If all findings are valid but none can be safely anchored inline, return a concise markdown review body as a top-level fallback and explicitly state why inline comments were not used. -- Concise summary of areas reviewed -- All findings as `file:line` references -- Aggregated root-cause occurrences and their affected files -- General observations -- No-finding confirmation +### Local mode -If no findings: return `No noteworthy issues found.` — one line, no padding. +Print the same normalized review summary to the user. Do not call `gh api`, `gh pr review`, or `gh pr comment`. ## Workflow 1. **Detect context** — GitHub Actions (PR mode) or local (local mode). 2. **Gather diff** — `gh pr diff` in PR mode; `git diff` in local mode. -3. **Choose reviewers** — based on `$ARGUMENTS` and diff content. +3. **Choose reviewers** — based on requested aspects and diff content. 4. **Launch subagents in parallel** — pass diff, files, and PR metadata. 5. **Normalize, filter, and aggregate** — apply filtering rules, root-cause aggregation, and orchestrator second filter. -6. **Validate references** — check each finding against the diff; adjust unverifiable line references (do not drop them). -7. **Return** — single markdown review response in PR mode; print summary in local mode. The `opencode github run` integration posts the PR-mode response as `opencode-agent[bot]`. +6. **Validate anchors** — classify findings as inline or summary-only; adjust nearby anchors when safe. +7. **Submit or return** — submit an inline GitHub review in PR mode when anchors exist; otherwise use the documented fallback. In local mode, print the summary only. ## Workflow Integration @@ -170,7 +212,7 @@ If no findings: return `No noteworthy issues found.` — one line, no padding. **In GitHub Actions:** 1. The `opencode.yml` workflow runs `/review-pr` on PR open / ready for review. -2. The orchestrator gathers the PR via `gh`, runs the agents, and returns a single markdown review response. The `opencode github run` integration posts that response to the PR as `opencode-agent[bot]` — no separate `github-actions[bot]` review is produced. +2. The orchestrator gathers the PR via `gh`, runs the agents, validates anchors, and submits a GitHub review with inline comments for anchorable findings. The `opencode github run` integration then posts only a short status comment. 3. Re-run by commenting `/opencode` or `/oc` on the PR. **After PR feedback:** @@ -184,6 +226,6 @@ If no findings: return `No noteworthy issues found.` — one line, no padding. - Agents run autonomously and return structured findings. - Each agent focuses on its specialty for deep analysis. -- Results are actionable with specific `file:line` references. -- The skill returns one final markdown response; it never posts to GitHub directly. -- Never include secrets, tokens, or full file contents in the review response. +- Results are actionable with specific inline anchors whenever the diff supports them. +- The skill posts a GitHub review only in PR mode when inline anchors exist; otherwise it uses the documented fallback. +- Never include secrets, tokens, or full file contents in the review response or GitHub comments. From dacfe873787b5b8ad4260315fcd95f6ad57205a2 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:58:20 +0900 Subject: [PATCH 04/25] Format markdown files with prettier From 27ff248402747b2421f92ca10a74a9dafffce65b Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:58:57 +0900 Subject: [PATCH 05/25] Format README with prettier From b3641c1853a3a087da674925e172bb245c7351de Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 02:59:34 +0900 Subject: [PATCH 06/25] Format review-pr skill with prettier From 960f0e2e683389ec5905a27a5161a44e2ec2619b Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:00:08 +0900 Subject: [PATCH 07/25] Apply prettier formatting to review command From 7fb5ef465bf2ad0ffd37df9d0087dc241e7f1e1e Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:00:36 +0900 Subject: [PATCH 08/25] Apply prettier formatting to README From 67b1cb773af984caf40ed8c7d23c75aad6ca8a02 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:01:11 +0900 Subject: [PATCH 09/25] Apply prettier formatting to review skill From 73007f58f478c7db279a640e3b92abed07692d0a Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:01:39 +0900 Subject: [PATCH 10/25] Apply prettier formatting to markdown docs From cd313ea151d78fa7127e50214e98c63868e6d298 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:02:23 +0900 Subject: [PATCH 11/25] Format review skill markdown From f0217a9d0f029634452450045256f581132a71b3 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:03:02 +0900 Subject: [PATCH 12/25] Apply prettier formatting to review skill markdown From 7d4be6b5e6322da13f1ae733d3eb0699432b7738 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:03:30 +0900 Subject: [PATCH 13/25] Apply prettier formatting to command markdown From 555d22b81c446873a796aaebbfce0138ede2d58e Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:04:41 +0900 Subject: [PATCH 14/25] Finalize prettier formatting for review skill From 20f65c4771d057b2d11335a0881dae09b1b4746b Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:05:15 +0900 Subject: [PATCH 15/25] Finalize prettier formatting for markdown docs From 19bc25a8527a08a276092fff064c223bbc8e6dde Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:05:59 +0900 Subject: [PATCH 16/25] Ensure review skill markdown is formatted From ac9611b4220ab95396e5e28675002a1c6dc2234f Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:06:19 +0900 Subject: [PATCH 17/25] Ensure README markdown is formatted From af4537b5fafe84a95df98903d428ab33861997bd Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:06:56 +0900 Subject: [PATCH 18/25] Ensure review skill markdown is prettier formatted From ce8296d94985324f1c933933276d6e993e4edf88 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:16:59 +0900 Subject: [PATCH 19/25] Address PR review submission feedback --- .opencode/commands/review-pr.md | 45 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/.opencode/commands/review-pr.md b/.opencode/commands/review-pr.md index c6193b5..13dc602 100644 --- a/.opencode/commands/review-pr.md +++ b/.opencode/commands/review-pr.md @@ -180,31 +180,33 @@ Do not post a GitHub review with an empty comments array. Submit a single GitHub pull request review using the REST API via `gh api`. Do not use `gh pr review` for inline findings because it cannot submit a structured `comments` array for per-line anchors in this workflow. -Build a payload like this: - -```json -{ - "commit_id": "", - "event": "COMMENT", - "body": "OpenCode PR Review: inline finding(s), summary-only finding(s).", - "comments": [ - { - "path": "path/to/file", - "line": 123, - "side": "RIGHT", - "body": "**important · security-code-reviewer**: Validate the user-controlled value before passing it to the shell." - } - ] -} +Build the review body from trusted strings and normalized findings. It must enumerate every summary-only item, including its fallback reason: + +```markdown +OpenCode PR Review: inline finding(s), summary-only finding(s). + +Summary-only findings: +- `` — : ``` -Then submit it: +Build the JSON payload with `jq`, not string interpolation, so PR-authored content cannot break JSON structure or inject fields. Write it to a private temporary file and always remove it after submission: ```bash +review_payload="$(mktemp "${TMPDIR:-/tmp}/opencode-pr-review.XXXXXX.json")" +chmod 600 "$review_payload" +trap 'rm -f "$review_payload"' EXIT + +jq -n \ + --arg commit_id "$head_oid" \ + --arg body "$review_body" \ + --argjson comments "$comments_json" \ + '{commit_id: $commit_id, event: "COMMENT", body: $body, comments: $comments}' \ + > "$review_payload" + gh api \ --method POST \ "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/reviews" \ - --input /tmp/opencode-pr-review.json + --input "$review_payload" ``` Operational requirements: @@ -212,8 +214,11 @@ Operational requirements: - `GH_TOKEN` or `GITHUB_TOKEN` must have `pull-requests: write` permission. - Use the PR head SHA from `gh pr view --json headRefOid` as `commit_id`. - Include `summary_only` findings in the review `body`, not as fake inline comments. -- If GitHub rejects the review because one inline anchor is invalid, remove only the rejected/unverifiable inline comment, move it to `summary_only` with the failure reason, and retry once. -- If the retry still fails, return a concise failure report that includes the attempted inline comment count, the failing anchor(s), and the summary-only fallback body. Do not claim inline comments were posted. +- Handle only GitHub 422 anchor-validation failures with the inline-comment retry path. Inspect the response `errors[].field` values such as `comments[0].line` to map failures back to specific `comments[N]` entries. +- If GitHub rejects one or more inline anchors and the offending entries can be identified, move only those findings to `summary_only` with the rejection reason and retry once. +- If a 422 anchor error does not identify the offending `comments[N]` entry, move all inline findings from that failed attempt to `summary_only` before retrying or falling back so no finding is lost. +- If the error indicates the `commit_id` is stale or is no longer part of the pull request, refetch `headRefOid`, rebuild the payload with the new SHA, and retry once. If the refetched SHA still fails, use the fallback path. +- If the retry still fails, do not claim inline comments were posted. Return a concise failure report and convert every attempted inline finding into a summary-only fallback entry, including its file, line, severity, source, message, and failure reason. After a successful submission, return only a concise status for the surrounding OpenCode integration to post, for example: From 9f921150e7ce56eead1092e116bb68a0d1cf19df Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:17:30 +0900 Subject: [PATCH 20/25] Mirror hardened review submission guidance in skill --- .opencode/skills/review-pr/SKILL.md | 41 ++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/.opencode/skills/review-pr/SKILL.md b/.opencode/skills/review-pr/SKILL.md index d4e5c27..7666bec 100644 --- a/.opencode/skills/review-pr/SKILL.md +++ b/.opencode/skills/review-pr/SKILL.md @@ -149,24 +149,45 @@ Do not submit an empty GitHub review. Submit one GitHub pull request review via `gh api` using a structured review payload with `comments` entries. Use `gh api` instead of `gh pr review` because this workflow needs explicit per-line anchors. -The review payload must include: +The review body must enumerate every summary-only item, including its fallback reason: -- `commit_id`: PR head SHA from `gh pr view --json headRefOid` -- `event`: `COMMENT` -- `body`: concise review summary plus any summary-only findings and fallback reasons -- `comments`: one entry per inline finding, each with `path`, `line`, `side: RIGHT`, and concise `body` +```markdown +OpenCode PR Review: inline finding(s), summary-only finding(s). -Inline comment body format: +Summary-only findings: +- `` — : +``` -```markdown -** · **: +Build the review payload with `jq`, not string interpolation, and write it to a private temporary file: + +```bash +review_payload="$(mktemp "${TMPDIR:-/tmp}/opencode-pr-review.XXXXXX.json")" +chmod 600 "$review_payload" +trap 'rm -f "$review_payload"' EXIT + +jq -n \ + --arg commit_id "$head_oid" \ + --arg body "$review_body" \ + --argjson comments "$comments_json" \ + '{commit_id: $commit_id, event: "COMMENT", body: $body, comments: $comments}' \ + > "$review_payload" + +gh api \ + --method POST \ + "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/reviews" \ + --input "$review_payload" ``` Operational requirements: - `GH_TOKEN` or `GITHUB_TOKEN` must have pull request write permission. -- If GitHub rejects the review because one inline anchor is invalid, remove only the rejected or unverifiable inline comment, move it to the summary-only section with the failure reason, and retry once. -- If the retry still fails, return a concise failure report that includes the attempted inline comment count, failing anchors, and the summary-only fallback body. Do not claim inline comments were posted. +- Use the PR head SHA from `gh pr view --json headRefOid` as `commit_id`. +- Include `summary_only` findings in the review `body`, not as fake inline comments. +- Handle only GitHub 422 anchor-validation failures with the inline-comment retry path. Inspect `errors[].field` values such as `comments[0].line` to map failures back to specific `comments[N]` entries. +- If GitHub rejects one or more inline anchors and the offending entries can be identified, move only those findings to `summary_only` with the rejection reason and retry once. +- If a 422 anchor error does not identify the offending `comments[N]` entry, move all inline findings from that failed attempt to `summary_only` before retrying or falling back so no finding is lost. +- If the error indicates the `commit_id` is stale or is no longer part of the pull request, refetch `headRefOid`, rebuild the payload with the new SHA, and retry once. If the refetched SHA still fails, use the fallback path. +- If the retry still fails, do not claim inline comments were posted. Return a concise failure report and convert every attempted inline finding into a summary-only fallback entry, including its file, line, severity, source, message, and failure reason. After a successful submission, return only a concise status, for example: From 00c424848bd748c70eef96c7558a53c7d29b26f4 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:17:53 +0900 Subject: [PATCH 21/25] Clarify review body fallback behavior --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cf134cf..d496583 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ When `use-github-token: true`, pass `GITHUB_TOKEN` in `env` and grant the workfl ## Pull Request Reviews -The bundled `/review-pr` command submits a GitHub pull request review through `gh api`. It uses inline review comments for every finding that can be safely anchored to the PR diff, and includes only unanchorable findings in the review body as summary-only fallback items. The surrounding `opencode github run` integration still posts the command's final text to the PR, so the command returns only a short status message after a successful inline review submission. +The bundled `/review-pr` command submits a GitHub pull request review through `gh api`. It uses inline review comments for every finding that can be safely anchored to the PR diff, and includes only unanchorable findings in the review body as summary-only fallback items when at least one inline comment is submitted. If no finding can be anchored inline, `/review-pr` returns a top-level markdown fallback instead. The surrounding `opencode github run` integration still posts the command's final text to the PR, so the command returns only a short status message after a successful inline review submission. Workflows that invoke `/review-pr` must provide: @@ -137,7 +137,7 @@ The bundled toolkit combines Claude Code Action-style core reviewers with `pr-re - **`comment-analyzer`** — comment accuracy, completeness, and comment rot - **`type-design-analyzer`** — type invariants, encapsulation, and design quality -Findings are normalized, deduplicated across agents, and validated against the PR diff before being posted. Diff-anchorable findings are submitted as GitHub inline review comments. Findings that cannot be safely anchored remain in the PR review body with an explicit fallback reason instead of being silently skipped. +Findings are normalized, deduplicated across agents, and validated against the PR diff before being posted. Diff-anchorable findings are submitted as GitHub inline review comments. When inline comments are submitted, findings that cannot be safely anchored remain in the GitHub review body with an explicit fallback reason. When no inline anchors are available, the command returns a top-level fallback response instead. ## Examples From c297ca410bcd7469a4e06f2ea025acb6ba48e436 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:47:53 +0900 Subject: [PATCH 22/25] Prefer OpenCode App token for gh reviews --- .opencode/commands/review-pr.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/.opencode/commands/review-pr.md b/.opencode/commands/review-pr.md index 13dc602..db029d8 100644 --- a/.opencode/commands/review-pr.md +++ b/.opencode/commands/review-pr.md @@ -16,6 +16,29 @@ The surrounding `opencode github run` integration always posts your final text a Determine whether you are reviewing a real GitHub PR (running in GitHub Actions) or working locally. - In GitHub Actions the environment provides `GITHUB_EVENT_NAME`, `GITHUB_REPOSITORY`, `GITHUB_REF` (e.g. `refs/pull/42/merge`), and `GITHUB_EVENT_PATH`. The `gh` CLI also requires `GH_TOKEN` or `GITHUB_TOKEN` to be available in the environment. +- Before using `gh`, prefer the OpenCode GitHub App token that `opencode github run` installs into the Git extraheader when `use-github-token` is false. This makes direct `gh api` review submissions appear as `opencode-agent[bot]` instead of `github-actions[bot]`. + +```bash +prepare_opencode_gh_token() { + local extraheader encoded decoded token + extraheader="$(git config --local --get http.https://github.com/.extraheader 2>/dev/null || true)" + if [[ "${extraheader}" =~ ^AUTHORIZATION:\ basic\ (.+)$ ]]; then + encoded="${BASH_REMATCH[1]}" + decoded="$(printf '%s' "${encoded}" | base64 --decode 2>/dev/null || true)" + token="${decoded#x-access-token:}" + if [[ -n "${token}" && "${token}" != "${decoded}" ]]; then + export GH_TOKEN="${token}" + export GITHUB_TOKEN="${token}" + return 0 + fi + fi + return 0 +} + +prepare_opencode_gh_token +``` + +- If no OpenCode App token is available in Git config, keep the existing `GH_TOKEN` or `GITHUB_TOKEN` fallback. This happens when the workflow uses `use-github-token: true` or when running locally. - Derive the PR number from the event payload first: ```bash @@ -180,6 +203,8 @@ Do not post a GitHub review with an empty comments array. Submit a single GitHub pull request review using the REST API via `gh api`. Do not use `gh pr review` for inline findings because it cannot submit a structured `comments` array for per-line anchors in this workflow. +Before submission, call `prepare_opencode_gh_token` again. This ensures `gh api` uses the OpenCode GitHub App token when available, even if the workflow also provided a default `GITHUB_TOKEN`. + Build the review body from trusted strings and normalized findings. It must enumerate every summary-only item, including its fallback reason: ```markdown @@ -192,6 +217,8 @@ Summary-only findings: Build the JSON payload with `jq`, not string interpolation, so PR-authored content cannot break JSON structure or inject fields. Write it to a private temporary file and always remove it after submission: ```bash +prepare_opencode_gh_token + review_payload="$(mktemp "${TMPDIR:-/tmp}/opencode-pr-review.XXXXXX.json")" chmod 600 "$review_payload" trap 'rm -f "$review_payload"' EXIT @@ -211,7 +238,8 @@ gh api \ Operational requirements: -- `GH_TOKEN` or `GITHUB_TOKEN` must have `pull-requests: write` permission. +- Prefer the OpenCode GitHub App token from Git config for `gh` commands so inline review submissions are authored by `opencode-agent[bot]`. +- If no OpenCode App token is available, fall back to `GH_TOKEN` or `GITHUB_TOKEN`; this may make direct review submissions appear as `github-actions[bot]`. - Use the PR head SHA from `gh pr view --json headRefOid` as `commit_id`. - Include `summary_only` findings in the review `body`, not as fake inline comments. - Handle only GitHub 422 anchor-validation failures with the inline-comment retry path. Inspect the response `errors[].field` values such as `comments[0].line` to map failures back to specific `comments[N]` entries. @@ -238,6 +266,7 @@ Print the same normalized review summary to the user. Do not call `gh api`, `gh - Keep feedback concise. A short review with real signal beats a long review with padding. - Never include secrets, tokens, or full file contents in the review response or GitHub comments. +- Do not print tokens or decoded Git authentication headers in logs. - Do not call `gh pr comment`; it creates top-level noise and bypasses inline review anchors. - Use `gh api` only for the single final PR review submission after all findings are normalized, deduplicated, and anchor-validated. - If `$ARGUMENTS` lists specific aspects, respect them and skip the rest. From dabe43a8f8e14e45cd859b7e76232ef254e35216 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:48:35 +0900 Subject: [PATCH 23/25] Document OpenCode App token preference in skill --- .opencode/skills/review-pr/SKILL.md | 38 ++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/.opencode/skills/review-pr/SKILL.md b/.opencode/skills/review-pr/SKILL.md index 7666bec..be1ded9 100644 --- a/.opencode/skills/review-pr/SKILL.md +++ b/.opencode/skills/review-pr/SKILL.md @@ -24,6 +24,32 @@ Do not use this skill to triage existing review comments on a PR; use `pr-feedba If no aspects are specified, run all applicable reviews. +## GitHub Auth for Inline Reviews + +When `opencode github run` uses the default OpenCode GitHub App flow (`use-github-token: false`), OpenCode configures the Git remote extraheader with an `opencode-agent[bot]` App token before the agent runs. Before calling `gh`, prefer that App token over any workflow `GITHUB_TOKEN` so direct `gh api` review submissions are authored by `opencode-agent[bot]`. + +```bash +prepare_opencode_gh_token() { + local extraheader encoded decoded token + extraheader="$(git config --local --get http.https://github.com/.extraheader 2>/dev/null || true)" + if [[ "${extraheader}" =~ ^AUTHORIZATION:\ basic\ (.+)$ ]]; then + encoded="${BASH_REMATCH[1]}" + decoded="$(printf '%s' "${encoded}" | base64 --decode 2>/dev/null || true)" + token="${decoded#x-access-token:}" + if [[ -n "${token}" && "${token}" != "${decoded}" ]]; then + export GH_TOKEN="${token}" + export GITHUB_TOKEN="${token}" + return 0 + fi + fi + return 0 +} + +prepare_opencode_gh_token +``` + +If no OpenCode App token is available in Git config, keep the existing `GH_TOKEN` or `GITHUB_TOKEN` fallback. This happens when the workflow explicitly uses `use-github-token: true` or when running locally. Do not print tokens or decoded authentication headers. + ## Supported Aspects | Aspect | Agent(s) | Notes | @@ -149,6 +175,8 @@ Do not submit an empty GitHub review. Submit one GitHub pull request review via `gh api` using a structured review payload with `comments` entries. Use `gh api` instead of `gh pr review` because this workflow needs explicit per-line anchors. +Before submission, call `prepare_opencode_gh_token` again. This ensures `gh api` uses the OpenCode GitHub App token when available, even if the workflow also provided a default `GITHUB_TOKEN`. + The review body must enumerate every summary-only item, including its fallback reason: ```markdown @@ -161,6 +189,8 @@ Summary-only findings: Build the review payload with `jq`, not string interpolation, and write it to a private temporary file: ```bash +prepare_opencode_gh_token + review_payload="$(mktemp "${TMPDIR:-/tmp}/opencode-pr-review.XXXXXX.json")" chmod 600 "$review_payload" trap 'rm -f "$review_payload"' EXIT @@ -180,7 +210,8 @@ gh api \ Operational requirements: -- `GH_TOKEN` or `GITHUB_TOKEN` must have pull request write permission. +- Prefer the OpenCode GitHub App token from Git config for `gh` commands so inline review submissions are authored by `opencode-agent[bot]`. +- If no OpenCode App token is available, fall back to `GH_TOKEN` or `GITHUB_TOKEN`; this may make direct review submissions appear as `github-actions[bot]`. - Use the PR head SHA from `gh pr view --json headRefOid` as `commit_id`. - Include `summary_only` findings in the review `body`, not as fake inline comments. - Handle only GitHub 422 anchor-validation failures with the inline-comment retry path. Inspect `errors[].field` values such as `comments[0].line` to map failures back to specific `comments[N]` entries. @@ -205,7 +236,7 @@ Print the same normalized review summary to the user. Do not call `gh api`, `gh ## Workflow -1. **Detect context** — GitHub Actions (PR mode) or local (local mode). +1. **Detect context** — GitHub Actions (PR mode) or local (local mode). Prefer the OpenCode App token from Git config for `gh` when available. 2. **Gather diff** — `gh pr diff` in PR mode; `git diff` in local mode. 3. **Choose reviewers** — based on requested aspects and diff content. 4. **Launch subagents in parallel** — pass diff, files, and PR metadata. @@ -233,7 +264,7 @@ Print the same normalized review summary to the user. Do not call `gh api`, `gh **In GitHub Actions:** 1. The `opencode.yml` workflow runs `/review-pr` on PR open / ready for review. -2. The orchestrator gathers the PR via `gh`, runs the agents, validates anchors, and submits a GitHub review with inline comments for anchorable findings. The `opencode github run` integration then posts only a short status comment. +2. The orchestrator gathers the PR via `gh`, runs the agents, validates anchors, and submits a GitHub review with inline comments for anchorable findings. Direct review submissions prefer the OpenCode App token from Git config, so they are authored by `opencode-agent[bot]` when the default App-token flow is used. The `opencode github run` integration then posts only a short status comment. 3. Re-run by commenting `/opencode` or `/oc` on the PR. **After PR feedback:** @@ -250,3 +281,4 @@ Print the same normalized review summary to the user. Do not call `gh api`, `gh - Results are actionable with specific inline anchors whenever the diff supports them. - The skill posts a GitHub review only in PR mode when inline anchors exist; otherwise it uses the documented fallback. - Never include secrets, tokens, or full file contents in the review response or GitHub comments. +- Never print tokens or decoded authentication headers in logs. From ccd21c22c69cea79a831f19f5bae9e85420dbb7e Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:48:57 +0900 Subject: [PATCH 24/25] Document OpenCode App-authored inline reviews --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d496583..db007d7 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Then comment `/opencode` or `/oc` on an issue, pull request, or pull request rev | Output | Description | | ------------------ | ----------------------------------------------- | -| `opencode-version` | OpenCode version resolved for the workflow run. | +| `opencode-version` | OpenCode version resolved for this run. | | `cache-hit` | Whether the OpenCode binary cache was restored. | ## Secrets @@ -84,10 +84,12 @@ When `use-github-token: true`, pass `GITHUB_TOKEN` in `env` and grant the workfl The bundled `/review-pr` command submits a GitHub pull request review through `gh api`. It uses inline review comments for every finding that can be safely anchored to the PR diff, and includes only unanchorable findings in the review body as summary-only fallback items when at least one inline comment is submitted. If no finding can be anchored inline, `/review-pr` returns a top-level markdown fallback instead. The surrounding `opencode github run` integration still posts the command's final text to the PR, so the command returns only a short status message after a successful inline review submission. +When the default OpenCode GitHub App flow is used (`use-github-token: false`), `/review-pr` restores the App token that OpenCode configured in the local Git extraheader and exports it for `gh`. Direct inline review submissions are therefore authored by `opencode-agent[bot]`. If the workflow explicitly opts into `use-github-token: true`, `/review-pr` falls back to the workflow token and direct review submissions may appear as `github-actions[bot]`. + Workflows that invoke `/review-pr` must provide: - `pull-requests: write` permission -- `GH_TOKEN: ${{ github.token }}` or `GITHUB_TOKEN: ${{ github.token }}` for `gh pr diff`, `gh pr view`, and `gh api` review submission +- `GH_TOKEN: ${{ github.token }}` or `GITHUB_TOKEN: ${{ github.token }}` for `gh pr diff`, `gh pr view`, and `gh api` review submission when using `use-github-token: true`; with the default App-token flow, `/review-pr` prefers the OpenCode App token from Git config for `gh api` - A valid API key for the selected model provider with available credits or quota Example OpenCode step: @@ -97,7 +99,6 @@ Example OpenCode step: uses: dceoy/opencode-action@v0 env: OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} - GH_TOKEN: ${{ github.token }} with: model: openrouter/openrouter/free prompt: /review-pr From 72382d7ae62d42cf5b1d2f74e5477f175edd0187 Mon Sep 17 00:00:00 2001 From: Daichi Narushima <1938249+dceoy@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:58:54 +0900 Subject: [PATCH 25/25] Allow use-github-token in review docs validation --- .agents/skills/local-qa/scripts/validate-opencode.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.agents/skills/local-qa/scripts/validate-opencode.sh b/.agents/skills/local-qa/scripts/validate-opencode.sh index 8939622..b6e7f9c 100755 --- a/.agents/skills/local-qa/scripts/validate-opencode.sh +++ b/.agents/skills/local-qa/scripts/validate-opencode.sh @@ -6,8 +6,9 @@ cd "$(git rev-parse --show-toplevel)" agents_dir=".opencode/agents" docs=(.opencode/commands/review-pr.md .opencode/skills/review-pr/SKILL.md) required_keys=(name description mode permission) -# Backtick-quoted identifiers in the docs that are skills/toolkits, not agents. -non_agents=(pr-feedback-triage pr-review-toolkit) +# Backtick-quoted identifiers in the docs that are skills, toolkits, or config +# inputs rather than agents. +non_agents=(pr-feedback-triage pr-review-toolkit use-github-token) fail=0 warn() { echo "ERROR: $*" >&2; fail=1; }