@vintasoftware/pr-review-canvas 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -31
- package/docs/reference.md +396 -101
- package/package.json +9 -4
- package/pr-review.config.example.yml +44 -4
- package/prompts/chat-seed.md +3 -0
- package/prompts/generation-format.md +123 -26
- package/prompts/generation-strict-incremental.md +53 -0
- package/prompts/generation-strict.md +1 -27
- package/prompts/generation-surfacing-incremental.md +56 -0
- package/prompts/generation-surfacing.md +1 -58
- package/prompts/judging-strict.md +27 -0
- package/prompts/judging-surfacing.md +58 -0
- package/skills/pr-review-canvas/SKILL.md +81 -42
- package/src/acpx/acpx.ts +98 -5
- package/src/acpx/models.ts +43 -0
- package/src/canvas/comment.ts +24 -0
- package/src/canvas/import.ts +30 -9
- package/src/canvas/name.ts +1 -0
- package/src/canvas/zip.ts +21 -1
- package/src/chat/chat-manager.ts +67 -40
- package/src/chat/threads.ts +27 -26
- package/src/cli.ts +70 -8
- package/src/commands.ts +50 -17
- package/src/config.ts +14 -26
- package/src/contract/api.ts +58 -2
- package/src/contract/canvas-manifest.ts +7 -0
- package/src/contract/comments.ts +5 -0
- package/src/contract/discovery.ts +5 -2
- package/src/contract/generation-context.ts +76 -2
- package/src/contract/keys.ts +1 -0
- package/src/contract/pending.ts +49 -0
- package/src/contract/review-artifact.ts +50 -7
- package/src/contract/review-key.ts +51 -0
- package/src/contract/reviews.ts +26 -0
- package/src/contract/settings.ts +7 -0
- package/src/contract/state.ts +53 -22
- package/src/contract/validation.ts +1 -0
- package/src/git/environment.mjs +27 -0
- package/src/git/git.ts +109 -9
- package/src/git/local-target.ts +138 -0
- package/src/git/patch-lines.ts +34 -2
- package/src/git/pr-refs.ts +36 -0
- package/src/github/attachments.ts +9 -257
- package/src/github/canvas-comment.ts +22 -0
- package/src/github/capabilities.ts +3 -41
- package/src/github/comments.ts +3 -24
- package/src/github/post-comment.ts +3 -36
- package/src/github/post-review.ts +64 -23
- package/src/github/pr.ts +6 -87
- package/src/github/threads.ts +2 -2
- package/src/gitlab/attachments.ts +40 -0
- package/src/gitlab/canvas-comment.ts +26 -0
- package/src/gitlab/capabilities.ts +64 -0
- package/src/gitlab/comments.ts +164 -0
- package/src/gitlab/mr.ts +115 -0
- package/src/gitlab/post-comment.ts +111 -0
- package/src/gitlab/post-review.ts +93 -0
- package/src/gitlab/project.ts +13 -0
- package/src/gitlab/publish-drafts.ts +69 -0
- package/src/host/attachments.ts +293 -0
- package/src/host/capabilities.ts +38 -0
- package/src/host/client.ts +246 -0
- package/src/host/host.ts +154 -0
- package/src/host/pr.ts +51 -0
- package/src/host/remote.ts +42 -0
- package/src/project-config.ts +26 -0
- package/src/review/carry-marks.ts +131 -0
- package/src/review/carry-over.ts +79 -0
- package/src/review/doctor.ts +82 -38
- package/src/review/incremental.ts +107 -0
- package/src/review/normalize.ts +14 -4
- package/src/review/prepare.ts +111 -10
- package/src/review/prompt.ts +112 -5
- package/src/review/publish.ts +62 -10
- package/src/{github → review}/review-body.ts +17 -5
- package/src/review/skill-command.ts +5 -3
- package/src/review/test-paths.ts +44 -4
- package/src/review/validate-folds.ts +349 -24
- package/src/review/validate.ts +14 -5
- package/src/server/bundle.ts +324 -111
- package/src/server/context.ts +10 -8
- package/src/server/errors.ts +30 -8
- package/src/server/html.ts +35 -11
- package/src/server/routes/api.ts +63 -26
- package/src/server/routes/chat-routes.ts +91 -44
- package/src/server/routes/pages.ts +26 -9
- package/src/server/routes/review-routes.ts +278 -67
- package/src/store/canvas-store.ts +93 -55
- package/src/store/data-dir.ts +2 -1
- package/src/store/derived-store.ts +41 -27
- package/src/store/pr-store.ts +23 -14
- package/src/store/settings-store.ts +9 -1
- package/src/store/state-store.ts +105 -36
- package/src/upgrade.ts +338 -0
- package/static/js/api.js +87 -25
- package/static/js/app.js +50 -15
- package/static/js/chat-panel.js +32 -9
- package/static/js/chat.js +30 -6
- package/static/js/code-folds.js +171 -44
- package/static/js/composer.js +132 -17
- package/static/js/contract-types.d.ts +7 -0
- package/static/js/diff-decorations.js +67 -1
- package/static/js/diff-renderer.js +1 -1
- package/static/js/download.js +1 -1
- package/static/js/empty-state.js +102 -18
- package/static/js/errors.js +22 -6
- package/static/js/fold-levels.js +176 -0
- package/static/js/header.js +65 -15
- package/static/js/host.js +40 -0
- package/static/js/import-zone.js +1 -1
- package/static/js/interactions.js +274 -46
- package/static/js/keyboard.js +4 -1
- package/static/js/keys.js +12 -0
- package/static/js/layers.js +295 -32
- package/static/js/links.js +3 -3
- package/static/js/markdown.js +28 -1
- package/static/js/nav.js +22 -4
- package/static/js/pending.js +161 -0
- package/static/js/points.js +70 -9
- package/static/js/progress.js +4 -5
- package/static/js/quick-questions.js +15 -2
- package/static/js/reading-level.js +97 -0
- package/static/js/review-session.js +113 -29
- package/static/js/settings.js +55 -24
- package/static/js/signoff.js +79 -10
- package/static/js/skin.js +2 -2
- package/static/styles/chat-panel.css +22 -24
- package/static/styles/chat.css +4 -0
- package/static/styles/commands.css +6 -0
- package/static/styles/header.css +21 -0
- package/static/styles/panels.css +4 -0
- package/static/styles/pending.css +102 -0
- package/static/styles/review-actions.css +1 -0
- package/static/styles/review.css +4 -0
- package/static/styles/skin-github.css +7 -1
- package/static/styles.css +1 -0
- package/src/github/gh.ts +0 -211
package/docs/reference.md
CHANGED
|
@@ -15,17 +15,20 @@ For setup and the basic review workflow, see the [README](../README.md).
|
|
|
15
15
|
|
|
16
16
|
### Repository and runtime options
|
|
17
17
|
|
|
18
|
-
| Option | Applies to
|
|
19
|
-
| -------------------------------- |
|
|
20
|
-
| `--repo <dir>` | All commands
|
|
21
|
-
| `--data-dir <dir>` | All except `install-skill` | Overrides `PR_REVIEW_DATA_DIR`, then the default `<main checkout>/.pr-review` |
|
|
22
|
-
| `--port <n>` | `serve`
|
|
23
|
-
| `--agent claude\|codex` | `serve`
|
|
24
|
-
| `--model <id>` | `serve`
|
|
25
|
-
| `--fixture-canvas <review.json>` | `serve`
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
| Option | Applies to | Default and behavior |
|
|
19
|
+
| -------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
20
|
+
| `--repo <dir>` | All commands | Uses the current directory when omitted; resolves the repository root from there |
|
|
21
|
+
| `--data-dir <dir>` | All except `install-skill` and `upgrade` | Overrides `PR_REVIEW_DATA_DIR`, then the default `<main checkout>/.pr-review` |
|
|
22
|
+
| `--port <n>` | `serve` | Overrides `PR_REVIEW_PORT`, then `3010`; accepts 1–65535 |
|
|
23
|
+
| `--agent claude\|codex` | `serve` | Overrides the saved chat agent for this run |
|
|
24
|
+
| `--model <id>` | `serve` | Overrides the saved chat model for this run |
|
|
25
|
+
| `--fixture-canvas <review.json>` | `serve` | Development preview: uses the supplied canvas for every requested PR, with its head replaced by the live PR head |
|
|
26
|
+
| `PR_REVIEW_HOST=gitlab` | Environment | Treats a non-github.com origin as GitLab (self-hosted hosts whose name does not contain `gitlab`) |
|
|
27
|
+
|
|
28
|
+
Repository operations require an `origin` remote on **github.com** or **GitLab** (gitlab.com, a
|
|
29
|
+
hostname that contains `gitlab`, or any host with `PR_REVIEW_HOST=gitlab`). GitHub Enterprise Server
|
|
30
|
+
hosts are not supported. Fetching a PR or merge request does not check out its branch. Use `--pr`
|
|
31
|
+
for both GitHub pull request numbers and GitLab merge request IIDs.
|
|
29
32
|
|
|
30
33
|
### Prepare, validate, and publish
|
|
31
34
|
|
|
@@ -33,7 +36,7 @@ These commands support custom generation workflows. The bundled
|
|
|
33
36
|
[generation skill](../skills/pr-review-canvas/SKILL.md) describes the complete sequence and model rules.
|
|
34
37
|
|
|
35
38
|
```text
|
|
36
|
-
pr-review prepare (--pr <n> | --base <ref> --head <ref>) [--force]
|
|
39
|
+
pr-review prepare (--pr <n> | --branch | --uncommitted | --base <ref> --head <ref>) [--base <ref>] [--force]
|
|
37
40
|
pr-review validate <model.json|review.json> --canvas <dir> [--human] [--fix]
|
|
38
41
|
pr-review publish <canvasDir> --agent <id> [--model <id>] --harness claude-code|codex|other [--allow-stale]
|
|
39
42
|
```
|
|
@@ -43,18 +46,59 @@ A status of `exists` means that head already has a canvas. With `--force`, prepa
|
|
|
43
46
|
previous generation's working files while keeping the published canvas available until a new
|
|
44
47
|
publish succeeds.
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
### Reviewing before the pull request exists
|
|
50
|
+
|
|
51
|
+
There are two reviews of the work in a clone, and they are separate targets:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pr-review prepare --branch # served at /review/branch
|
|
55
|
+
pr-review prepare --uncommitted # served at /review/uncommitted
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`--branch` describes the tip of the current branch. `--uncommitted` describes the working tree as
|
|
59
|
+
it stands, with the edits and the untracked files on top of that tip; with a clean tree the two
|
|
60
|
+
build the same canvas. Each keeps its own canvas, review progress and chat threads, so preparing
|
|
61
|
+
one never disturbs the other.
|
|
62
|
+
|
|
63
|
+
- **Base.** Both compare against the repository's default branch, resolved from `origin/HEAD` and
|
|
64
|
+
falling back to `origin/main`, `origin/master`, `main`, then `master`. `--base <ref>` overrides
|
|
65
|
+
it. Preparation fails with a hint when none of them resolve.
|
|
66
|
+
- **Uncommitted work.** `--uncommitted` stages the working tree into an index of its own and
|
|
67
|
+
writes a commit from it, so the diff covers files that are not committed yet. Nothing the user
|
|
68
|
+
staged is touched, ignored files stay out, and the commit is anchored at
|
|
69
|
+
`refs/worktree/pr-review-snapshot` so `git gc` cannot collect it before `publish`. Publishing
|
|
70
|
+
gives that canvas an anchor of its own under `refs/worktree/pr-review-canvas/`, so a later
|
|
71
|
+
snapshot cannot leave it collectable. The same working tree always hashes to the same commit.
|
|
72
|
+
- **Staleness.** Committing after `--branch`, or editing a file after `--uncommitted`, moves the
|
|
73
|
+
head, so `publish` answers `CANVAS_STALE`, exactly as a push does for a pull request. The page
|
|
74
|
+
reads the head again when it is opened and when `refresh` is pressed, and offers to regenerate.
|
|
75
|
+
Its background polls answer about that same head, so they never contradict what the page shows;
|
|
76
|
+
they read the work again only once a new canvas has been prepared.
|
|
77
|
+
- **Worktrees.** The snapshot index and its anchor are per worktree, so two worktrees of one clone
|
|
78
|
+
never overwrite each other's snapshot. The review targets are not: `branch` and `uncommitted`
|
|
79
|
+
name one review per clone, so worktrees share their canvas, review progress and chat threads.
|
|
80
|
+
Review local work from one worktree at a time.
|
|
81
|
+
- **No forge side.** A local canvas posts nothing: comments, sign-off, canvas import, and
|
|
82
|
+
attachment discovery are refused for it. The page draws no import drop zone and no shared-canvas
|
|
83
|
+
callout, and the comment and sign-off commands stay disabled with the reason. A canvas of a working-tree
|
|
84
|
+
snapshot is never offered as a pull request's canvas, or as the branch review's, because its
|
|
85
|
+
commit is on no branch.
|
|
86
|
+
|
|
87
|
+
For a comparison between two commits that both exist, name them instead:
|
|
47
88
|
|
|
48
89
|
```bash
|
|
49
90
|
pr-review prepare --base origin/main --head HEAD
|
|
50
91
|
```
|
|
51
92
|
|
|
52
93
|
`validate` checks the supplied file against the context in `--canvas`. By default it returns
|
|
53
|
-
`{ ok, errors }`; `--human` prints readable diagnostics.
|
|
94
|
+
`{ ok, errors }`; `--human` prints readable diagnostics. A `review.json` is checked for
|
|
95
|
+
correctness only. The folding rules (`FOLD_MISSING`, a test file collapsed at `light`) apply only
|
|
96
|
+
to a `model.json`, because older canvases predate them. `--fix` edits overlong titles by removing
|
|
54
97
|
the explanation after the first `:` or `—` and reports the changes. Titles that still exceed the
|
|
55
98
|
limit and overlong prose require rewriting.
|
|
56
99
|
|
|
57
|
-
`publish` returns `status`, `headSha`, `reviewJsonPath`, `attempts`, and a `reviewUrl`
|
|
100
|
+
`publish` returns `status`, `headSha`, `reviewJsonPath`, `attempts`, `sharing`, and a `reviewUrl`
|
|
101
|
+
for PR and local runs.
|
|
58
102
|
Its `--agent`, `--model`, and `--harness` describe who generated the canvas; they do not launch or
|
|
59
103
|
select an agent. `--allow-stale` permits publishing for the prepared commit after the PR head has
|
|
60
104
|
moved. Use it only when that older commit is the intended review target.
|
|
@@ -63,6 +107,35 @@ For more than 400 changed files or 50,000 added/deleted lines, preparation leave
|
|
|
63
107
|
prompt and directs the generator to read patch files individually. Smaller diffs are inlined up
|
|
64
108
|
to `generation.inlineDiffMaxLines`.
|
|
65
109
|
|
|
110
|
+
### Automatic sharing and ZIP fallback
|
|
111
|
+
|
|
112
|
+
For PR/MR targets, `publish` saves the validated canvas locally, then posts its compressed ZIP
|
|
113
|
+
as base64 inside a hidden HTML comment on GitHub or GitLab. The visible comment identifies the
|
|
114
|
+
commit and explains how to open the canvas. Publishing again updates the existing canvas comment
|
|
115
|
+
owned by the current CLI account; another author's comment is left alone. The payload contains
|
|
116
|
+
the same `manifest.json` and `review.json` as an export, including the PR/MR description and review
|
|
117
|
+
notes. Hidden markup is not private: anyone who can read the comment can retrieve the payload.
|
|
118
|
+
No generated files enter Git history and no storage service or CI workflow is required.
|
|
119
|
+
|
|
120
|
+
Check the `sharing` result even when the process exits successfully:
|
|
121
|
+
|
|
122
|
+
- `{ "status": "shared", "url": "..." }`: the host accepted the comment.
|
|
123
|
+
- `{ "status": "failed", "warning": "...", "zipPath": "..." }`: the canvas is saved locally,
|
|
124
|
+
but automatic sharing failed. The CLI also prints a warning to stderr and exports a fallback ZIP.
|
|
125
|
+
Upload that ZIP into the PR/MR description in the browser and save; replace an older attachment
|
|
126
|
+
link if present. A host failure can have an uncertain outcome, so check the comment before retrying.
|
|
127
|
+
- `{ "status": "local" }`: a refs-only target has no PR/MR to publish to.
|
|
128
|
+
|
|
129
|
+
The entire comment must fit the host limit: 65,536 characters on GitHub and 1,000,000 on GitLab.
|
|
130
|
+
Base64 uses roughly four characters per three compressed bytes, leaving slightly under 48 KiB
|
|
131
|
+
for a GitHub ZIP after the envelope and visible text. Oversize canvases are never split or truncated.
|
|
132
|
+
Permission, login, network, and host-policy errors use the same ZIP fallback. A sharing failure
|
|
133
|
+
keeps exit code 0 because local publication succeeded; validation errors still exit 5.
|
|
134
|
+
The generation skill must report the warning and manual-upload instructions on sharing failure.
|
|
135
|
+
|
|
136
|
+
`export` remains a local-only command for backups and manual sharing. For refs-only canvases,
|
|
137
|
+
export with `--head <sha> --pr <n>` once the PR exists, or regenerate for the PR to share automatically.
|
|
138
|
+
|
|
66
139
|
### Export and import options
|
|
67
140
|
|
|
68
141
|
```text
|
|
@@ -79,16 +152,21 @@ pr-review import <zip> [--pr <n>] [--force]
|
|
|
79
152
|
canvas generation time in UTC, to seconds, so exports sort chronologically within each PR.
|
|
80
153
|
Before a PR exists, `ref-` replaces `pr-<number>-`. Re-exporting the same canvas keeps its name.
|
|
81
154
|
- Export returns `status`, `path`, `name`, `headSha`, and `prNumber` when supplied or stored.
|
|
82
|
-
- `import --pr` compares the imported canvas with that PR's current head
|
|
83
|
-
|
|
155
|
+
- `import --pr` compares the imported canvas with that PR's current head, and refuses a canvas
|
|
156
|
+
exported for a different pull request with `CANVAS_PR_MISMATCH`. `--force` does not lift that
|
|
157
|
+
refusal: a canvas is stored under the pull request it names, so importing the same ZIP without
|
|
158
|
+
`--pr` stores it under its own PR instead. Without `--pr`, import does not check against a live
|
|
159
|
+
PR. A canvas generated before the PR existed names none and joins the pull request it is
|
|
160
|
+
imported for.
|
|
84
161
|
- Import returns `ready`, `stale`, or `exists`, plus commit information and warnings. `exists`
|
|
85
162
|
keeps a stored canvas generated at the same time or later. `derivable: false` means the canvas
|
|
86
163
|
was accepted but its source diffs could not be rebuilt from Git.
|
|
87
164
|
- `import --force` allows a canvas from another repository. It does not force an older canvas to
|
|
88
|
-
replace a newer one.
|
|
165
|
+
replace a newer one, and does not allow a canvas of another pull request.
|
|
89
166
|
|
|
90
167
|
Imports accept archives up to **20 MiB**. The required `manifest.json` and `review.json` entries
|
|
91
|
-
must be at the archive root
|
|
168
|
+
must be at the archive root, pass format validation, and agree on the commit and the pull request
|
|
169
|
+
they describe. If the necessary commits are missing,
|
|
92
170
|
the tool attempts to fetch them; a failed fetch can leave the notes available without diffs.
|
|
93
171
|
|
|
94
172
|
### Skill installation options
|
|
@@ -112,14 +190,45 @@ Each installed `SKILL.md` records `metadata.body-sha256` in its YAML frontmatter
|
|
|
112
190
|
covers the body after the closing frontmatter delimiter, with CRLF normalized to LF. `doctor`
|
|
113
191
|
compares the recorded hash and actual body against the skill bundled with the running CLI. Any
|
|
114
192
|
outdated or modified copy in `.claude/skills` or `.agents/skills` fails the skill check, even if the
|
|
115
|
-
other copy is current. Refresh copies with `pr-review install-skill` (repeat
|
|
116
|
-
flags used during installation). Automatic discovery checks the two default directories.
|
|
193
|
+
other copy is current. Refresh copies with `pr-review upgrade` or `pr-review install-skill` (repeat
|
|
194
|
+
any custom directory flags used during installation). Automatic discovery checks the two default directories.
|
|
117
195
|
|
|
118
196
|
`serve` runs this skill check automatically and prints failures with a repair hint to stderr.
|
|
119
197
|
Warnings do not prevent the server from starting. Use `doctor --all-checks` for full diagnostics.
|
|
120
198
|
The `.gitignore` update always applies to the selected repository root, even with custom skill
|
|
121
199
|
directories.
|
|
122
200
|
|
|
201
|
+
### Upgrade options
|
|
202
|
+
|
|
203
|
+
```text
|
|
204
|
+
pr-review upgrade [--yes] [--only package,acpx,skill] [--repo <dir>]
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`upgrade` checks three things, prints a plan to stderr, and asks `Proceed? [y/N]`:
|
|
208
|
+
|
|
209
|
+
| What | When it changes | How |
|
|
210
|
+
| ----------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
211
|
+
| pr-review | npm has a newer version, and this copy is the global npm install | `npm install -g @vintasoftware/pr-review-canvas@<version>` |
|
|
212
|
+
| acpx | npm has a newer version, and the acpx on PATH is the global npm install | `npm install -g acpx@<version>` |
|
|
213
|
+
| The project skill | A copy in `.claude/skills` or `.agents/skills` differs from the bundled one | The same copy `install-skill` makes |
|
|
214
|
+
|
|
215
|
+
When pr-review itself upgrades, the skill step covers every copy, since the new version may ship
|
|
216
|
+
a new skill. After installing, it runs the new version as `pr-review upgrade --yes --only <kinds>`
|
|
217
|
+
with the confirmed steps, so the new version copies its own skill and takes only the steps the plan
|
|
218
|
+
showed. If the install fails, the current version runs the remaining steps itself.
|
|
219
|
+
|
|
220
|
+
- `--only` limits the run to the named kinds. Skipped kinds are listed in `notes`.
|
|
221
|
+
- `upgrade` does not install a missing acpx or add a missing skill copy. It prints the command
|
|
222
|
+
that does.
|
|
223
|
+
- An unmanaged skill directory is left alone; replace it with `install-skill --force`.
|
|
224
|
+
- A pr-review run from a clone or through `npx` is left alone, with a note to update it the way it
|
|
225
|
+
was installed.
|
|
226
|
+
|
|
227
|
+
Without a terminal, `upgrade` prints the plan and changes nothing. `--yes` applies it without
|
|
228
|
+
asking. stdout is one JSON line with `applied` and, after applying, `ok` and each step's `status`
|
|
229
|
+
(`done` or `failed`, with a `detail`). The exit code is `1` when a step fails. When a skill copy
|
|
230
|
+
changes, stderr says to commit and push it.
|
|
231
|
+
|
|
123
232
|
### Output and exit codes
|
|
124
233
|
|
|
125
234
|
One-shot commands normally print a JSON result on stdout. Preparation progress goes to stderr.
|
|
@@ -134,7 +243,7 @@ Validation failures from `validate` use its report format instead.
|
|
|
134
243
|
| `0` | Success |
|
|
135
244
|
| `1` | Error, including a failed `doctor` check |
|
|
136
245
|
| `2` | Command usage error, such as an unknown command or missing required flag |
|
|
137
|
-
| `4` | GitHub CLI missing or unauthenticated
|
|
246
|
+
| `4` | GitHub CLI (`gh`) or GitLab CLI (`glab`) missing or unauthenticated |
|
|
138
247
|
| `5` | Validation failed in `validate` or `publish` |
|
|
139
248
|
|
|
140
249
|
`doctor` reports failed checks with exit `1`, including authentication failures.
|
|
@@ -148,20 +257,22 @@ Lists you supply replace their defaults.
|
|
|
148
257
|
Path patterns match repository-relative paths. `**` crosses directories; `*` and `?` match
|
|
149
258
|
within one path segment.
|
|
150
259
|
|
|
151
|
-
| Key | Default
|
|
152
|
-
| ------------------------------- |
|
|
153
|
-
| `version` | `1`
|
|
154
|
-
| `rulebook` | Unset
|
|
155
|
-
| `layers` | `[]`
|
|
156
|
-
| `highRisk` | `[]`
|
|
157
|
-
| `generation.mode` | `strict`
|
|
158
|
-
| `generation.maxRepairRounds` | `3`
|
|
159
|
-
| `generation.inlineDiffMaxLines` | `1500`
|
|
160
|
-
| `generation.smallPrHunks` | `10`
|
|
161
|
-
| `generation.caps` | See below
|
|
162
|
-
| `tests.patterns` |
|
|
163
|
-
| `chat.enabled` | `true`
|
|
164
|
-
| `
|
|
260
|
+
| Key | Default | Details |
|
|
261
|
+
| ------------------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
262
|
+
| `version` | `1` | The only supported configuration version |
|
|
263
|
+
| `rulebook` | Unset | Path to a Markdown file of project code standards, resolved from the repository root; these standards take precedence over bundled standards |
|
|
264
|
+
| `layers` | `[]` | Optional review guidance; each entry has `id`, `title`, `description`, and optional `paths` patterns. The agent may combine, split, or reorder groups. When omitted or empty, it chooses semantic sections from the change |
|
|
265
|
+
| `highRisk` | `[]` | Entries with a `pattern` glob and `label`; matching changes receive risk labels and cannot go in the Other layer |
|
|
266
|
+
| `generation.mode` | `strict` | See [generation modes](#generation-modes) |
|
|
267
|
+
| `generation.maxRepairRounds` | `3` | Failed validation rounds allowed by the generation skill |
|
|
268
|
+
| `generation.inlineDiffMaxLines` | `1500` | Maximum diff length to include directly in the generation prompt |
|
|
269
|
+
| `generation.smallPrHunks` | `10` | At or below this hunk count, the prompt asks for one layer unless concerns differ |
|
|
270
|
+
| `generation.caps` | See below | Overrides individual text limits |
|
|
271
|
+
| `tests.patterns` | Test directories and file-name shapes across stacks; see the example config | Paths treated as tests for review ordering, labels, and the light reading level |
|
|
272
|
+
| `chat.enabled` | `true` | Set to `false` to disable AI Chat |
|
|
273
|
+
| `canvas.keepForIdenticalDiff` | `true` | Keep the canvas current for a later head whose diff is identical to the canvas's; see [outdated canvases](#outdated-canvases). Set to `false` to mark it outdated on every commit |
|
|
274
|
+
| `canvas.incremental` | `true` | Regenerate a canvas for a new head by updating the newest canvas of a commit the head was built on; see [incremental canvases](#incremental-canvases). Set to `false` to generate every canvas from a blank page |
|
|
275
|
+
| `prompts` | Bundled templates | See [prompt templates](#prompt-templates) for supported keys and behavior |
|
|
165
276
|
|
|
166
277
|
Generation's numeric options and text caps must be positive integers. An empty `layers` list
|
|
167
278
|
provides no suggested groups; an empty `tests.patterns` list recognizes no files as tests.
|
|
@@ -182,14 +293,18 @@ affects canvas generation; chat answers the reviewer's selected question.
|
|
|
182
293
|
|
|
183
294
|
The `prompts` map in `pr-review.config.yml` accepts these keys:
|
|
184
295
|
|
|
185
|
-
| Key
|
|
186
|
-
|
|
|
187
|
-
| `generation-format.md`
|
|
188
|
-
| `generation-strict.md`
|
|
189
|
-
| `generation-surfacing.md`
|
|
190
|
-
| `
|
|
191
|
-
| `
|
|
192
|
-
| `
|
|
296
|
+
| Key | Purpose |
|
|
297
|
+
| ------------------------------------- | ----------------------------------------------------------- |
|
|
298
|
+
| `generation-format.md` | Schema and output rules |
|
|
299
|
+
| `generation-strict.md` | Instructions for strict mode |
|
|
300
|
+
| `generation-surfacing.md` | Instructions for surfacing mode |
|
|
301
|
+
| `generation-strict-incremental.md` | Strict mode, updating an existing canvas |
|
|
302
|
+
| `generation-surfacing-incremental.md` | Surfacing mode, updating an existing canvas |
|
|
303
|
+
| `judging-strict.md` | Strict mode's judging rules, shared by both of its tasks |
|
|
304
|
+
| `judging-surfacing.md` | Surfacing mode's judging rules, shared by both of its tasks |
|
|
305
|
+
| `quality-standards.md` | Bundled code standards |
|
|
306
|
+
| `layering-guidance.md` | Guidance for grouping related changes |
|
|
307
|
+
| `chat-seed.md` | Opening AI Chat instructions |
|
|
193
308
|
|
|
194
309
|
Each configured file replaces a whole template. Paths resolve from the project root,
|
|
195
310
|
including when running from a subdirectory or using `--repo`. Absolute paths work for
|
|
@@ -247,25 +362,60 @@ placed in Other while its source is in a regular layer.
|
|
|
247
362
|
|
|
248
363
|
The data directory's `settings.yml` accepts these keys and values:
|
|
249
364
|
|
|
250
|
-
| Key | Default
|
|
251
|
-
| ---------------- |
|
|
252
|
-
| `version` | `1`
|
|
253
|
-
| `skin` | `
|
|
254
|
-
| `theme` | `auto`
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
258
|
-
| `
|
|
365
|
+
| Key | Default | Accepted values |
|
|
366
|
+
| ---------------- | -------- | ------------------------------------------------- |
|
|
367
|
+
| `version` | `1` | `1` |
|
|
368
|
+
| `skin` | `github` | `terminal`, `github` |
|
|
369
|
+
| `theme` | `auto` | `auto`, `light`, `dark` |
|
|
370
|
+
| `foldLevel` | `light` | `light`, `moderate`, `aggressive` |
|
|
371
|
+
| `agent` | `claude` | `claude`, `codex` |
|
|
372
|
+
| `model` | `null` | A model ID, or `null` for the agent's default (1) |
|
|
373
|
+
| `chatTimeoutSec` | `600` | Integer seconds, 30–3600 |
|
|
374
|
+
| `maxTurns` | `null` | Integer 1–100, or `null` for the agent's default |
|
|
375
|
+
|
|
376
|
+
(1) A model ID names a family; see [Model families](#model-families).
|
|
259
377
|
|
|
260
378
|
Invalid settings fall back to defaults. URL parameters `?skin=github&theme=light` can override
|
|
261
379
|
appearance for one page load without saving it.
|
|
262
380
|
|
|
381
|
+
#### Model families
|
|
382
|
+
|
|
383
|
+
Each chat turn runs the newest model of the saved model's family. A trailing `[...]`, such as
|
|
384
|
+
`[1m]` or `[high]`, is kept.
|
|
385
|
+
|
|
386
|
+
- **Claude:** an Anthropic model ID becomes its family alias, which the `claude` CLI resolves to
|
|
387
|
+
its newest model. `claude-opus-4-8[1m]` runs as `opus[1m]`, and `claude-haiku-4-5-20251001` runs
|
|
388
|
+
as `haiku`.
|
|
389
|
+
- **Codex:** a GPT model follows the `upgrade` links in the Codex model catalog
|
|
390
|
+
(`codex debug models`) to the model that replaced it, even under a new name: `gpt-5.6-terra` runs
|
|
391
|
+
as `gpt-6-sol`. A model with no `upgrade` link runs as saved.
|
|
392
|
+
- **Blank model:** the agent's default applies. A thread still on a replaced model moves to its
|
|
393
|
+
replacement.
|
|
394
|
+
|
|
395
|
+
To pin an exact version, prefix the ID with `pin:`. The ID is then sent as written, for either
|
|
396
|
+
agent:
|
|
397
|
+
|
|
398
|
+
| Agent | Example | Runs |
|
|
399
|
+
| ------ | ------------------------- | -------------------------- |
|
|
400
|
+
| Claude | `pin:claude-opus-4-8` | Opus 4.8 |
|
|
401
|
+
| Codex | `pin:gpt-5.6-terra[high]` | GPT-5.6 Terra, high effort |
|
|
402
|
+
|
|
403
|
+
The agent must still offer the model. Claude Code refuses some combinations, for example
|
|
404
|
+
`claude-opus-4-8[1m]`, and the turn fails with the agent's error.
|
|
405
|
+
|
|
406
|
+
Bedrock and Vertex Claude IDs, such as `us.anthropic.claude-opus-4-8-v1:0` or
|
|
407
|
+
`claude-opus-4-8@20260801`, run as written without `pin:`. They work only when Claude Code is set
|
|
408
|
+
up for that provider, for example with `CLAUDE_CODE_USE_BEDROCK=1` or `CLAUDE_CODE_USE_VERTEX=1`.
|
|
409
|
+
|
|
410
|
+
Claude chat runs the `claude` CLI on PATH, or the Claude Code bundled with acpx when there is none.
|
|
411
|
+
To use another binary, set `CLAUDE_CODE_EXECUTABLE` before `pr-review serve`.
|
|
412
|
+
|
|
263
413
|
By default, Git worktrees of the same clone share the main checkout's data directory. Separate
|
|
264
414
|
clones have separate data. An explicit data-directory override also relocates `settings.yml`,
|
|
265
415
|
canvases, review progress, and chat history.
|
|
266
416
|
|
|
267
|
-
The data directory contains exported archives, saved canvases, generation inputs, cached GitHub
|
|
268
|
-
data, source diffs, and personal review progress. Its own `.gitignore` excludes its contents.
|
|
417
|
+
The data directory contains exported archives, saved canvases, generation inputs, cached GitHub or
|
|
418
|
+
GitLab data, source diffs, and personal review progress. Its own `.gitignore` excludes its contents.
|
|
269
419
|
Deleting the directory loses saved preferences, canvases, progress, and chat history.
|
|
270
420
|
|
|
271
421
|
## Review controls
|
|
@@ -293,29 +443,169 @@ start collapsed. Click the summary to expand them. Moves are detected within a f
|
|
|
293
443
|
between files appear as deletions and additions. Edited moves keep their changed text visible.
|
|
294
444
|
Collapsing content does not mark it reviewed.
|
|
295
445
|
|
|
446
|
+
### Reading levels
|
|
447
|
+
|
|
448
|
+
The **Hide code** control, beside the review progress, sets how much of the canvas is hidden. The
|
|
449
|
+
levels nest: whatever `light` hides, `moderate` and `aggressive` hide too. The generator gives each
|
|
450
|
+
fold and each collapsed file the lowest level at which it hides.
|
|
451
|
+
|
|
452
|
+
| Level | What it hides |
|
|
453
|
+
| ------------ | ---------------------------------------------------------------------------------------- |
|
|
454
|
+
| `light` | Imports, whitespace, moves, and wholly generated files (the default) |
|
|
455
|
+
| `moderate` | Also test bodies under their titles, helpers, adapters, boilerplate, mappings and wiring |
|
|
456
|
+
| `aggressive` | Also any block its title explains, so the change reads as pseudo-code |
|
|
457
|
+
|
|
458
|
+
The control shows what the chosen level hides and how many lines that is. Each layer shows its count
|
|
459
|
+
in its Files heading, and the sign-off dialog records the total.
|
|
460
|
+
|
|
461
|
+
The page opens at `foldLevel` from `settings.yml` (`light` by default), which the **Hide code by
|
|
462
|
+
default** field in the settings dialog sets. The control and the `f` key change the level for the
|
|
463
|
+
current page only. Changing the level redraws the visible diffs and re-applies file collapse,
|
|
464
|
+
including cards opened by hand.
|
|
465
|
+
|
|
466
|
+
These always stay visible:
|
|
467
|
+
|
|
468
|
+
- Attention points, comment threads, and pending review drafts. A file with a thread or a draft
|
|
469
|
+
folds nothing.
|
|
470
|
+
- Files with an annotation or an attention point. They never collapse whole.
|
|
471
|
+
- Annotations, except under an `aggressive` fold that covers the whole annotation and no other. That
|
|
472
|
+
fold shows the annotation's text instead of its title.
|
|
473
|
+
- Test files at `light`, except snapshots and fixtures. From `moderate`, each test body folds under
|
|
474
|
+
its own title, or the file collapses whole.
|
|
475
|
+
|
|
476
|
+
Validation fails with `FOLD_MISSING` when the generator hides too little:
|
|
477
|
+
|
|
478
|
+
- A file with more than 20 changed lines outside its annotations and no attention point hides
|
|
479
|
+
nothing at any level.
|
|
480
|
+
- An open file over 60 lines folds less than half of its lines outside attention points by
|
|
481
|
+
`aggressive`. Annotated lines count, since an aggressive fold may hide them.
|
|
482
|
+
- A layer over 100 changed lines leaves more than 20 lines open at `moderate` (outside attention
|
|
483
|
+
points) and hides nothing more at `aggressive`. Smaller layers only need to pass the file rules.
|
|
484
|
+
|
|
485
|
+
A `light` fold may cover at most 40 lines of generated content.
|
|
486
|
+
|
|
296
487
|
Files with patches longer than 2,000 lines wait behind **show diff**. A link into the file opens
|
|
297
488
|
it automatically.
|
|
298
489
|
|
|
299
490
|
### Finding shared canvases
|
|
300
491
|
|
|
301
|
-
Discovery checks the PR description and comments for
|
|
492
|
+
Discovery reads compressed canvas comments and checks the PR description and comments for legacy
|
|
493
|
+
canvas ZIP links. Both use the same ZIP validation and import path. It prefers a filename
|
|
302
494
|
matching the current head, then the PR number, then the most recently edited source text.
|
|
303
|
-
If a
|
|
304
|
-
canvas can be recognized.
|
|
495
|
+
If a candidate fails, it tries other matching canvases. Keep the exported filename so the
|
|
496
|
+
canvas can be recognized. **Refresh** also checks for regenerated canvases at the same head commit.
|
|
497
|
+
|
|
498
|
+
An attachment exported for a different pull request is reported rather than imported, and is not
|
|
499
|
+
downloaded at all when its filename already names the other PR. The page says so and offers the
|
|
500
|
+
drop zone, which applies the same check: a ZIP whose name or manifest belongs to another PR is
|
|
501
|
+
refused.
|
|
305
502
|
|
|
306
|
-
When automatic download fails, download the archive in GitHub
|
|
307
|
-
or `pr-review import <zip> --pr <n>`.
|
|
503
|
+
When automatic download fails, download the archive in GitHub or GitLab and use the page's drop
|
|
504
|
+
zone or `pr-review import <zip> --pr <n>`.
|
|
308
505
|
|
|
309
506
|
### Comments and sign-off
|
|
310
507
|
|
|
311
508
|
You can post inline comments, replies, PR-level comments, and attention points. Inline comments
|
|
312
|
-
must target lines in the diff. Posting uses your
|
|
509
|
+
must target lines in the diff. Posting uses your `gh` or `glab` account and remains subject to its
|
|
313
510
|
repository permissions.
|
|
314
511
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
512
|
+
Click a line number to comment on one line. Shift-click a second line number, or drag across a
|
|
513
|
+
range, to select several lines: the comment then covers the whole range, and posts as a multi-line
|
|
514
|
+
comment (`start_line` on GitHub, a `line_range` position on GitLab). A range must stay inside one
|
|
515
|
+
chunk of the diff.
|
|
516
|
+
|
|
517
|
+
### Pending reviews
|
|
518
|
+
|
|
519
|
+
A pending review holds comments on your machine until you submit them together.
|
|
520
|
+
|
|
521
|
+
- **post to github** on a diff-line comment posts it at once. **start a review** adds it to a new
|
|
522
|
+
pending review instead.
|
|
523
|
+
- While a review is open, a diff-line comment can only **add review comment**, so no comment
|
|
524
|
+
publishes ahead of the review. Replies and pull-request comments are not part of a forge review,
|
|
525
|
+
so they still post at once.
|
|
526
|
+
- An attention point keeps both **post to github** and **add to review**, since its text is written
|
|
527
|
+
in advance. A point in the review shows **in your review**; edit or remove it as the draft on its
|
|
528
|
+
line. After submission, the point shows the comment it became.
|
|
529
|
+
- A bar under the progress line shows how many drafts are waiting. Each draft appears on its line
|
|
530
|
+
with a **pending** badge and edit and delete commands. Drafts are saved in the local review state
|
|
531
|
+
and survive a reload. **discard** drops the whole review; nothing was sent to the forge.
|
|
532
|
+
- Drafts from an earlier commit are listed separately in the bar with their original location and
|
|
533
|
+
commit. They are submitted only when the stored diff is identical to the current one and
|
|
534
|
+
`canvas.keepForIdenticalDiff` is on. Otherwise, copy the text, delete the draft, and comment on
|
|
535
|
+
the current code.
|
|
536
|
+
- A draft added or edited during submission stays pending.
|
|
537
|
+
|
|
538
|
+
**finish your review** opens the sign-off dialog, which shows how many drafts go out with the
|
|
539
|
+
review:
|
|
540
|
+
|
|
541
|
+
- **GitHub:** the drafts are the comments of the single call that creates the review.
|
|
542
|
+
- **GitLab:** the inline comments and summary are staged as draft notes and published in one batch.
|
|
543
|
+
Finish or discard any review already pending in GitLab first. Approval is a separate call; if it
|
|
544
|
+
fails after publication, the comments stay published and the page asks you to approve in GitLab.
|
|
545
|
+
|
|
546
|
+
A refused submission keeps the local drafts and removes the remote drafts that attempt staged.
|
|
547
|
+
|
|
548
|
+
### Sign-off
|
|
549
|
+
|
|
550
|
+
Sign-off offers three verdicts: **approve**, **request changes**, and **comment**, which posts a
|
|
551
|
+
review with no verdict. Each opens a
|
|
552
|
+
dialog previewing an editable review body summarizing reviewed layers, dismissed attention points,
|
|
553
|
+
and comments posted from the canvas, so an approval or a rejection always carries a comment.
|
|
554
|
+
|
|
555
|
+
Approval requires every layer except **Other changes** to be reviewed for the current head.
|
|
556
|
+
Requesting changes and a comment-only review do not require that completion. On GitLab,
|
|
557
|
+
**approve** calls GitLab's approve API; **request changes** and **comment** post the review body
|
|
558
|
+
as a merge request note. If the head moves before submission, reload and review the current
|
|
559
|
+
commit.
|
|
560
|
+
|
|
561
|
+
### Outdated canvases
|
|
562
|
+
|
|
563
|
+
A canvas describes one head commit. When the pull request moves to another commit, the page
|
|
564
|
+
shows **Canvas is outdated**, offers the older canvas read-only, and disables posting from it.
|
|
565
|
+
|
|
566
|
+
An identical diff is the exception. When the head's diff against its merge base is the same as
|
|
567
|
+
the canvas commit's diff against its own, file by file and byte for byte, the canvas is carried
|
|
568
|
+
over: the page shows it under a **Canvas still applies** note, review progress carries over, and
|
|
569
|
+
sign-off, comments, and AI Chat keep working. The note says how many commits later the head is,
|
|
570
|
+
when the head was built on the canvas's commit. Merging the base branch in (**Update branch**) keeps
|
|
571
|
+
the diff identical as long as the base did not touch the changed files. The rule does not care how
|
|
572
|
+
the head reached that diff, only that it did; a diff that differs anywhere, even a hunk moved down
|
|
573
|
+
by a base change, marks the canvas outdated as before, because the canvas's layers, hunk ids, and
|
|
574
|
+
attention points describe the diff it was generated from. It needs `canvas.keepForIdenticalDiff`
|
|
575
|
+
(the default) and both commits in the local clone: the canvas's own commit has to be there for its
|
|
576
|
+
diff to be rebuilt, and without that diff there is nothing to compare, so the canvas reads outdated.
|
|
577
|
+
Two empty change sets are not compared either. `pr-review publish` and `pr-review import` apply the
|
|
578
|
+
same rule, so the CLI never calls a canvas stale that the page shows as current.
|
|
579
|
+
|
|
580
|
+
AI Chat also answers on an outdated canvas: it quotes the diff of the canvas's own commit, the
|
|
581
|
+
one on screen.
|
|
582
|
+
|
|
583
|
+
## Incremental canvases
|
|
584
|
+
|
|
585
|
+
When a canvas is regenerated for a new head, `pr-review prepare` starts from the **basis canvas**:
|
|
586
|
+
the newest canvas of a commit the head was built on. A canvas of a commit the head no longer
|
|
587
|
+
contains is never a basis. `--force` starts from a blank page, and `canvas.incremental: false`
|
|
588
|
+
turns this off for the project.
|
|
589
|
+
|
|
590
|
+
`prepare` compares the basis diff with the head diff file by file. A file whose patch is
|
|
591
|
+
byte-identical is untouched. The prompt tells the generator to copy, word for word:
|
|
592
|
+
|
|
593
|
+
- whole layers whose files are all untouched;
|
|
594
|
+
- in other layers, the notes, folds, annotations, and attention points of untouched files.
|
|
595
|
+
|
|
596
|
+
Everything else is decided again. The summary and risk tags are always rewritten. A carried
|
|
597
|
+
attention point keeps its kind, path, and title, so it keeps its fingerprint and any dismissal.
|
|
598
|
+
|
|
599
|
+
The canvas records only which basis it came from. Your server decides which review marks follow,
|
|
600
|
+
using the two canvases and your clone:
|
|
601
|
+
|
|
602
|
+
- A file's mark follows when the file is in both canvases, under the same layer key, with a
|
|
603
|
+
byte-identical patch.
|
|
604
|
+
- A layer's mark follows only when the layer has exactly the same files and none changed.
|
|
605
|
+
|
|
606
|
+
The canvas you marked is compared directly with the one on screen, so marks survive any number of
|
|
607
|
+
regenerations in between. When a mark follows, the page names the canvas you made it on. If your
|
|
608
|
+
machine lacks that canvas or cannot rebuild either diff, no marks follow.
|
|
319
609
|
|
|
320
610
|
## AI Chat
|
|
321
611
|
|
|
@@ -323,7 +613,7 @@ completion. If the head moves before submission, reload and review the current c
|
|
|
323
613
|
Choosing another target replaces it; **clear** returns to the whole PR. The `a` key asks about
|
|
324
614
|
the focused target, and `/` focuses the message box.
|
|
325
615
|
|
|
326
|
-
Chat can propose an inline
|
|
616
|
+
Chat can propose an inline comment. A valid proposal appears with controls to post, edit,
|
|
327
617
|
or copy it. A proposal outside the current diff remains text with an explanation.
|
|
328
618
|
|
|
329
619
|
Use **stop** to interrupt a reply. Only one chat turn can run per PR at a time. A timeout or
|
|
@@ -332,9 +622,10 @@ incomplete answer can be retried; increase `chatTimeoutSec` if replies need more
|
|
|
332
622
|
## Network access and permissions
|
|
333
623
|
|
|
334
624
|
The server binds to `127.0.0.1` and rejects browser writes from other origins. It is intended for
|
|
335
|
-
local use with your GitHub login.
|
|
625
|
+
local use with your GitHub or GitLab login.
|
|
336
626
|
|
|
337
|
-
|
|
627
|
+
Publishing sends the canvas as a PR/MR comment. Host requests also fetch PR or MR data and
|
|
628
|
+
attachments and submit the comments or reviews you choose to
|
|
338
629
|
post. Rendered Markdown can load images from HTTPS hosts. Generation and chat send review
|
|
339
630
|
context to the selected coding agent and its configured provider.
|
|
340
631
|
|
|
@@ -344,41 +635,45 @@ sandbox for the agent. Its access also depends on the agent's own permissions. D
|
|
|
344
635
|
|
|
345
636
|
## Troubleshooting
|
|
346
637
|
|
|
347
|
-
| Symptom or code
|
|
348
|
-
|
|
|
349
|
-
| `NOT_A_REPO`
|
|
350
|
-
| `NO_ORIGIN`
|
|
351
|
-
| `GH_MISSING` / `GH_UNAUTHENTICATED`
|
|
352
|
-
| `GITHUB_API_ERROR`
|
|
353
|
-
| `
|
|
354
|
-
| `
|
|
355
|
-
| `
|
|
356
|
-
| `
|
|
357
|
-
| `
|
|
358
|
-
| `
|
|
359
|
-
| `
|
|
360
|
-
| `
|
|
361
|
-
| `
|
|
362
|
-
| `
|
|
363
|
-
| `
|
|
364
|
-
| `
|
|
365
|
-
| `
|
|
366
|
-
| `
|
|
367
|
-
| `
|
|
368
|
-
| `
|
|
638
|
+
| Symptom or code | Next step |
|
|
639
|
+
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
640
|
+
| `NOT_A_REPO` | Run inside a Git clone or pass `--repo <dir>` |
|
|
641
|
+
| `NO_ORIGIN` | Check that `origin` points to github.com or GitLab; for self-hosted GitLab set `PR_REVIEW_HOST=gitlab` |
|
|
642
|
+
| `GH_MISSING` / `GH_UNAUTHENTICATED` | Install [GitHub CLI](https://cli.github.com), run `gh auth login`, and check authentication in the same environment that runs the server |
|
|
643
|
+
| `GITHUB_API_ERROR` | Read the underlying error for permissions, rate limits, connectivity, or GitHub service problems |
|
|
644
|
+
| `GLAB_MISSING` / `GLAB_UNAUTHENTICATED` | Install [GitLab CLI](https://gitlab.com/gitlab-org/cli), run `glab auth login`, and check authentication in the same environment that runs the server |
|
|
645
|
+
| `GITLAB_API_ERROR` | Read the underlying error for permissions, rate limits, connectivity, or GitLab service problems |
|
|
646
|
+
| `PR_NOT_FOUND` | Check the PR number, repository, and your access |
|
|
647
|
+
| `CANVAS_NOT_FOUND` | Generate or import a canvas for the requested commit |
|
|
648
|
+
| `CANVAS_INVALID` | Read the format errors; re-export or regenerate the canvas |
|
|
649
|
+
| `CANVAS_REPO_MISMATCH` | Check which clone is open; use `import --force` only when importing from the other repository is intentional |
|
|
650
|
+
| `CANVAS_PR_MISMATCH` | The ZIP was exported for another pull request; import the canvas of this PR, or import that ZIP without `--pr` to store it under its own |
|
|
651
|
+
| `CANVAS_TOO_LARGE` | The archive exceeds the 20 MiB import limit |
|
|
652
|
+
| `CANVAS_STALE` | The PR head moved; prepare again for the current commit |
|
|
653
|
+
| `MODEL_INVALID` | Fix the reported problems in `model.json`, validate, then publish again |
|
|
654
|
+
| `SKILL_DIR_EXISTS` | The destination contains a customized directory; preserve it elsewhere before replacing it with `--force` |
|
|
655
|
+
| `CHAT_BUSY` | Wait for the running reply or press **stop** |
|
|
656
|
+
| `AGENT_AUTH_REQUIRED` | Sign in through the selected agent's CLI, then retry |
|
|
657
|
+
| `AGENT_MISSING` or missing chat pane | Check `chat.enabled` and confirm the server can find `acpx` and the selected agent; run `pr-review doctor --all-checks` |
|
|
658
|
+
| `AGENT_INCOMPLETE` | Retry the message or increase the chat timeout |
|
|
659
|
+
| `COMMENT_FORBIDDEN` | Check the GitHub or GitLab account's repository access and token permissions |
|
|
660
|
+
| `COMMENT_LINE_NOT_IN_DIFF` | Choose a line shown in the current diff |
|
|
661
|
+
| `SIGNOFF_INCOMPLETE` | Mark every layer except Other reviewed for this head |
|
|
662
|
+
| `FORBIDDEN_HOST` / `CROSS_ORIGIN` | Open the local server using `localhost` or `127.0.0.1` and submit actions from that page |
|
|
369
663
|
|
|
370
664
|
### Validation diagnostics
|
|
371
665
|
|
|
372
666
|
Validation reports name the field, file, hunk, or line to fix. Common groups are:
|
|
373
667
|
|
|
374
|
-
| Codes | What to check
|
|
375
|
-
| --------------------------------------------------------------- |
|
|
376
|
-
| `SCHEMA`, `TEXT_TOO_LONG` | Required fields, types, and text limits
|
|
377
|
-
| `HUNK_UNASSIGNED`, `HUNK_DUPLICATE`, `HUNK_UNKNOWN` | Each known hunk belongs to exactly one layer
|
|
378
|
-
| `PATH_UNKNOWN`, `TEST_PATH_UNKNOWN` | Referenced files exist in the relevant diff or PR head
|
|
379
|
-
| `LAYER_EMPTY`, `LAYER_KEY_DUPLICATE` | Layers contain hunks and have unique keys
|
|
380
|
-
| `OTHER_DUPLICATE`, `OTHER_NOT_LAST`, `RISK_IN_OTHER` | At most one Other layer, last, without risk-tagged changes
|
|
381
|
-
| `TEST_NOT_LAST`, `TEST_IN_OTHER` | Tests follow the code they cover and use the appropriate layer
|
|
382
|
-
| `ANNOTATION_OUTSIDE_HUNK`, `POINT_OUTSIDE_DIFF`, `FOLD_INVALID` | Locations and fold ranges fit the assigned diff
|
|
383
|
-
| `
|
|
384
|
-
| `
|
|
668
|
+
| Codes | What to check |
|
|
669
|
+
| --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
670
|
+
| `SCHEMA`, `TEXT_TOO_LONG` | Required fields, types, and text limits |
|
|
671
|
+
| `HUNK_UNASSIGNED`, `HUNK_DUPLICATE`, `HUNK_UNKNOWN` | Each known hunk belongs to exactly one layer |
|
|
672
|
+
| `PATH_UNKNOWN`, `TEST_PATH_UNKNOWN` | Referenced files exist in the relevant diff or PR head |
|
|
673
|
+
| `LAYER_EMPTY`, `LAYER_KEY_DUPLICATE` | Layers contain hunks and have unique keys |
|
|
674
|
+
| `OTHER_DUPLICATE`, `OTHER_NOT_LAST`, `RISK_IN_OTHER` | At most one Other layer, last, without risk-tagged changes |
|
|
675
|
+
| `TEST_NOT_LAST`, `TEST_IN_OTHER` | Tests follow the code they cover and use the appropriate layer |
|
|
676
|
+
| `ANNOTATION_OUTSIDE_HUNK`, `POINT_OUTSIDE_DIFF`, `FOLD_INVALID` | Locations and fold ranges fit the assigned diff |
|
|
677
|
+
| `FOLD_MISSING` | A file over 20 unannotated lines hides something; an open file over 60 folds half; a layer over 100 hides more at aggressive |
|
|
678
|
+
| `TOO_MANY_POINTS` | Count explicit points and missing-test entries together |
|
|
679
|
+
| `LINK_UNRESOLVED`, `DIAGRAM_NODE_UNKNOWN`, `DIAGRAM_LIMIT` | Link targets, diagram node IDs, and diagram counts |
|