opencode-plugin-zooplankton
Advanced tools
@@ -140,2 +140,28 @@ /** | ||
| /** | ||
| * Build endpoint-neutral inline comment anchors for line-anchored findings. | ||
| * | ||
| * Returns objects with shape `{ path, position: null, _line, body }` where: | ||
| * - `path` — file path relative to repo root (passed through to GitHub as-is) | ||
| * - `position` — set to `null`; the orchestrator MUST resolve this to a diff | ||
| * position integer before POSTing to `POST /pulls/{n}/reviews`. | ||
| * See review-protocol.md §4b.5 for how to compute `position` | ||
| * from the PR unified diff. | ||
| * - `_line` — the original file line number from the finding; kept as a hint | ||
| * for the position-resolution step. The underscore prefix signals | ||
| * this field must NOT be forwarded to the GitHub API. | ||
| * - `body` — sanitized comment body string ready for GitHub. | ||
| * | ||
| * The `line`/`side` fields accepted by the per-comment endpoint | ||
| * (`POST /pulls/{n}/comments`) are intentionally absent; the consolidated | ||
| * reviews endpoint (`POST /pulls/{n}/reviews`) uses `position` instead. | ||
| * | ||
| * ⚠ IMPORTANT: The `_line` field MUST be stripped from each anchor object | ||
| * before forwarding to the GitHub API. It is an internal hint for diff- | ||
| * position resolution only; GitHub will reject or ignore unknown fields and | ||
| * leaking it risks future API-breakage. Callers should pick exactly | ||
| * `{ path, position, body }` (and optionally `side`/`start_line` post- | ||
| * resolution) before serializing the request payload. See | ||
| * review-protocol.md §4b.5 for the canonical resolution + stripping flow. | ||
| */ | ||
| export const buildInlineCommentAnchors = (findings) => | ||
@@ -146,11 +172,35 @@ (Array.isArray(findings) ? findings : []) | ||
| path: finding.path, | ||
| line: finding.line, | ||
| side: "RIGHT", | ||
| position: null, | ||
| _line: finding.line, | ||
| body: `[${sanitizeInlineMarkdown(finding.cluster_id)}] [${sanitizeInlineMarkdown(finding.severity)}] ${sanitizeInlineMarkdown(finding.summary)}${finding.detail ? `\n\n${sanitizeBlockMarkdown(finding.detail)}` : ""}`, | ||
| })); | ||
| /** | ||
| * Plan a deterministic retry tier for posting inline review comments. | ||
| * | ||
| * Accepts comment objects in **either** shape (back-compat): | ||
| * - **Legacy shape** — `{ path, line, body }` where `line` is the file line | ||
| * number directly. Produced by older callers / test fixtures. | ||
| * - **Anchor shape** — `{ path, position, _line, body }` as produced by | ||
| * `buildInlineCommentAnchors`. Here `position` is the GitHub diff position | ||
| * (initially `null` until resolved) and `_line` is the original file line | ||
| * number kept as a sort/anchor hint. | ||
| * | ||
| * Sort key precedence: `_line ?? line ?? -1`. `_line` takes precedence over | ||
| * `line` when both are present so anchor-shape callers get stable ordering | ||
| * keyed off the original file line even after `position` is filled in. | ||
| * | ||
| * Tiers: | ||
| * - 1 — keep all as inline comments | ||
| * - 2 — keep first half inline, downgrade second half to body-only | ||
| * - 3 — downgrade all to body-only | ||
| * | ||
| * Throws on any other tier value. | ||
| */ | ||
| export const planReviewPostRetry = (comments, tier) => { | ||
| const sorted = [...(Array.isArray(comments) ? comments : [])].sort((a, b) => { | ||
| if (a.path !== b.path) return a.path < b.path ? -1 : 1; | ||
| if (a.line !== b.line) return (a.line ?? -1) - (b.line ?? -1); | ||
| const aLine = a._line ?? a.line ?? -1; | ||
| const bLine = b._line ?? b.line ?? -1; | ||
| if (aLine !== bLine) return aLine - bLine; | ||
| return (a.body ?? "") < (b.body ?? "") ? -1 : (a.body ?? "") > (b.body ?? "") ? 1 : 0; | ||
@@ -157,0 +207,0 @@ }); |
@@ -22,3 +22,3 @@ # Security Reviewer Guide | ||
| - **Timing:** Pre-merge only (runs after code-review rounds converge, immediately before merge decision). | ||
| - **GitHub mode — allowed bash (read-only):** `gh pr view *`, `gh pr diff *`, `gh pr checks *`. `gh api *`, `gh api .../reviews --method POST`, and `gh pr review` are **not** allowed. | ||
| - **GitHub mode — allowed bash (read-only):** `gh pr view *`, `gh pr diff *`. `gh pr checks *`, `gh api *`, `gh api .../reviews --method POST`, and `gh pr review` are **not** allowed. | ||
| - **Local mode — allowed bash:** `git diff *`, `git log *`, `git fetch *`. Use the `read` tool for direct file access. Do not use `gh` commands. | ||
@@ -25,0 +25,0 @@ |
+1
-1
| { | ||
| "name": "opencode-plugin-zooplankton", | ||
| "version": "0.6.1", | ||
| "version": "0.6.2", | ||
| "description": "Unified global OpenCode plugin for ZooplanktonAI — coding standards, multi-agent skills (brainstorm / plan / orchestrate), commands, guides, and the autonomous-mode permission hook.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -154,4 +154,4 @@ # Review Protocol Reference | ||
| 1. Build the body with `renderConsolidatedReviewBody(...)`. | ||
| 2. Build endpoint-neutral line anchors with `buildInlineCommentAnchors(findings)`. | ||
| 3. Before calling GitHub, resolve anchors to the exact endpoint payload. `POST /pulls/{pull_number}/reviews` review comments require `path` + `position` (with `commit_id` at the top level) — `position` is the diff-position integer described above, not the file line number. The legacy `POST /pulls/{pull_number}/comments` per-comment endpoint (which does accept `path` + `line` + `side`) is **not** used by the consolidated post. | ||
| 2. Build endpoint-neutral line anchors with `buildInlineCommentAnchors(findings)`. Each anchor has shape `{ path, position: null, _line, body }` — `position` is `null` as a placeholder; `_line` is the file line number retained as a resolution hint. Do NOT forward `_line` to GitHub. | ||
| 3. Before calling GitHub, resolve each anchor's `position`. `POST /pulls/{pull_number}/reviews` review comments require `path` + `position` (with `commit_id` at the top level) — `position` is the diff-position integer described above, not the file line number. Use `_line` to find the target line in the unified diff, then count positions from the hunk header. The legacy `POST /pulls/{pull_number}/comments` per-comment endpoint (which does accept `path` + `line` + `side`) is **not** used by the consolidated post. | ||
| 4. Tier 1: re-validate anchors against current `headRefOid`, then retry with `planReviewPostRetry(comments, 1)`. | ||
@@ -158,0 +158,0 @@ 5. Tier 2: deterministically halve inline comments and move the rest into the body with `planReviewPostRetry(comments, 2)`. |
Sorry, the diff of this file is too big to display
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
355686
1.23%3437
2.35%