@olegkoval/agent-skills 1.42.2 → 1.43.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/adapters/claude/olko-github-pr/skills/lekker-review/SKILL.md +314 -27
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/agents/implementation.md +29 -4
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/changed-files.sh +20 -7
- package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/setup-worktree.sh +57 -11
- package/package.json +1 -1
- package/plugins/olko-apple-kit/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-creative/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-garmin-kit/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-git-tools/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-github-pr/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-github-pr/skills/lekker-review/SKILL.md +314 -27
- package/plugins/olko-github-pr/skills/lekker-review/fix-workflow.js +10 -4
- package/plugins/olko-github-pr/skills/lekker-review/references/agents/implementation.md +29 -4
- package/plugins/olko-github-pr/skills/lekker-review/scripts/changed-files.sh +20 -7
- package/plugins/olko-github-pr/skills/lekker-review/scripts/setup-worktree.sh +57 -11
- package/plugins/olko-github-pr/skills/lekker-review/workflow.js +18 -9
- package/plugins/olko-obsidian/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-product/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-reflection/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-release/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-skill-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/olko-web-ops/.claude-plugin/plugin.json +1 -1
|
@@ -17,9 +17,16 @@ description: >
|
|
|
17
17
|
With --fix (or by accepting the post-review offer) it also APPLIES its own
|
|
18
18
|
Critical/Important findings as real code in the worktree, verifies each edit,
|
|
19
19
|
commits them, and pushes to the PR branch only after explicit confirmation.
|
|
20
|
+
Also reviews a LOCAL BRANCH BEFORE IT IS PUSHED (`/lekker-review branch
|
|
21
|
+
--fix`): same agents, same fixes, against the merge-base with the branch the
|
|
22
|
+
PR would target, with no PR and no network round trip. Running it pre-push is
|
|
23
|
+
how you stop paying bot reviewers like Greptile/CodeRabbit to find what this
|
|
24
|
+
skill finds for free, so branch mode defaults to --fix and offers to open the
|
|
25
|
+
PR when it is done.
|
|
20
26
|
Use when the user says "review this PR", "lekker review", "check this PR",
|
|
21
27
|
"do a code review on PR #N", "review and fix this PR", "apply the review
|
|
22
|
-
fixes",
|
|
28
|
+
fixes", "review my branch", "review before push", "check this before I open
|
|
29
|
+
the PR", provides a GitHub PR URL, or asks for a pull request review in any
|
|
23
30
|
form.
|
|
24
31
|
license: MIT
|
|
25
32
|
allowed-tools: Bash, Read, Write, Edit, Agent, Workflow, AskUserQuestion, Artifact
|
|
@@ -38,7 +45,7 @@ metadata:
|
|
|
38
45
|
- multi-agent
|
|
39
46
|
- workflow
|
|
40
47
|
- quality
|
|
41
|
-
argument-hint: "<github-pr-url | repo pr-number | repo pr-title> [scan|medium|deep] [--post] [--fix]"
|
|
48
|
+
argument-hint: "<github-pr-url | repo pr-number | repo pr-title | branch [ref]> [scan|medium|deep] [--post] [--fix] [--base <ref>]"
|
|
42
49
|
---
|
|
43
50
|
<!-- Generated by scripts/build-adapters.sh. Do not edit directly. -->
|
|
44
51
|
|
|
@@ -49,6 +56,19 @@ FAANG-grade code review. Isolated worktree checkout, full context gathering
|
|
|
49
56
|
you have MCP tools configured for), then 5 parallel specialized review
|
|
50
57
|
agents, a finding-verification pass, and one unified markdown output.
|
|
51
58
|
|
|
59
|
+
Two modes, same review engine:
|
|
60
|
+
|
|
61
|
+
| Mode | Target | Entry |
|
|
62
|
+
|------------|-------------------------------------|-----------------------------------------|
|
|
63
|
+
| **pr** | An open GitHub PR | a PR url / `repo N` / `repo "title"` |
|
|
64
|
+
| **branch** | A local branch, before it is pushed | `branch [ref]`, or `--branch` |
|
|
65
|
+
|
|
66
|
+
Branch mode exists to move the review left: everything a bot reviewer
|
|
67
|
+
(Greptile, CodeRabbit, or similar) would charge for on the PR is found and
|
|
68
|
+
FIXED locally first, so the PR opens clean and there is little left to bill
|
|
69
|
+
for. It reviews the same diff a PR would show - merge-base against the branch
|
|
70
|
+
the PR would target - and it defaults to `--fix`.
|
|
71
|
+
|
|
52
72
|
Each finding contains: **file + risk** · **bad code verbatim** · **why it's
|
|
53
73
|
wrong** · **fix with code example** - ready to paste directly into GitHub.
|
|
54
74
|
Reviews are saved to `~/code-reviews/` for future reference.
|
|
@@ -92,6 +112,24 @@ resolve every `references/...` and script path relative to it.
|
|
|
92
112
|
|
|
93
113
|
## Step 0 - Parse input
|
|
94
114
|
|
|
115
|
+
### Pick the mode first
|
|
116
|
+
|
|
117
|
+
`MODE=branch` when ANY of these hold:
|
|
118
|
+
- the argument is the literal word `branch` (optionally followed by a ref), or
|
|
119
|
+
the flag `--branch [ref]` is present
|
|
120
|
+
- the user asked for a review "before push", "before the PR", "of my branch",
|
|
121
|
+
"of these commits", or named a local branch that has no open PR
|
|
122
|
+
- no PR reference was given at all and `$PWD` is inside a git repo on a branch
|
|
123
|
+
that is not the base branch
|
|
124
|
+
|
|
125
|
+
Otherwise `MODE=pr`.
|
|
126
|
+
|
|
127
|
+
Never guess between the two. If a PR reference is present, it is `pr` mode
|
|
128
|
+
even in a git repo. If neither a PR reference nor a git repo is available,
|
|
129
|
+
stop and ask - do not review the wrong thing.
|
|
130
|
+
|
|
131
|
+
### MODE=pr
|
|
132
|
+
|
|
95
133
|
Accept any of:
|
|
96
134
|
- Full GitHub URL: `https://github.com/owner/repo/pull/123`
|
|
97
135
|
- Repo + number: `my-service 42`
|
|
@@ -106,10 +144,65 @@ Derive and carry these variables through every subsequent step:
|
|
|
106
144
|
- `PR_NUMBER`
|
|
107
145
|
- `PR_BRANCH` (from `gh pr view`)
|
|
108
146
|
- `PR_URL` = `https://github.com/<REPO_SLUG>/pull/<PR_NUMBER>`
|
|
147
|
+
- `TARGET_LABEL` = `PR #<PR_NUMBER>`
|
|
148
|
+
|
|
149
|
+
### MODE=branch
|
|
150
|
+
|
|
151
|
+
Resolve everything from the local repo - no `gh pr` call, no network:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
LOCAL_REPO=$(git -C "$PWD" rev-parse --show-toplevel)
|
|
155
|
+
# Use the ref the user named when present. Otherwise require an attached branch.
|
|
156
|
+
LOCAL_BRANCH="${USER_PROVIDED_REF:-}"
|
|
157
|
+
if [ -z "$LOCAL_BRANCH" ]; then
|
|
158
|
+
LOCAL_BRANCH=$(git -C "$LOCAL_REPO" symbolic-ref --short -q HEAD)
|
|
159
|
+
fi
|
|
160
|
+
if [ -z "$LOCAL_BRANCH" ]; then
|
|
161
|
+
echo "Detached HEAD: name the local ref to review." >&2
|
|
162
|
+
exit 1
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
ORIGIN_URL=$(git -C "$LOCAL_REPO" remote get-url origin 2>/dev/null || true)
|
|
166
|
+
if [ -n "$ORIGIN_URL" ]; then
|
|
167
|
+
REPO_SLUG=$(printf '%s\n' "$ORIGIN_URL" \
|
|
168
|
+
| sed -E 's#(git@github.com:|https://github.com/)##; s#\.git$##')
|
|
169
|
+
else
|
|
170
|
+
LOCAL_REPO_NAME=$(basename "$LOCAL_REPO" \
|
|
171
|
+
| sed -E 's#[^[:alnum:]_.-]+#-#g; s#^-+|-+$##g')
|
|
172
|
+
REPO_SLUG="local/${LOCAL_REPO_NAME:-repository}"
|
|
173
|
+
fi
|
|
174
|
+
```
|
|
109
175
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
176
|
+
An explicitly named ref may be reviewed from detached HEAD. Before landing
|
|
177
|
+
fixes, resolve it to a local branch name or stop; never build
|
|
178
|
+
`refs/heads/<LOCAL_BRANCH>` from a commit SHA or another non-branch ref. The
|
|
179
|
+
`local/<directory>` slug is reporting metadata for repositories without an
|
|
180
|
+
`origin`; preserve the origin-derived slug whenever that remote exists.
|
|
181
|
+
|
|
182
|
+
Then:
|
|
183
|
+
- `BASE_REF`: the branch the PR would target. Honour `--base <ref>` when given.
|
|
184
|
+
Otherwise let `scripts/changed-files.sh` detect it (origin's default branch,
|
|
185
|
+
then whatever your convention falls back to) and report which one it picked.
|
|
186
|
+
If detection lands on something that contradicts your team's actual
|
|
187
|
+
convention, say so in the review header rather than reviewing silently
|
|
188
|
+
against the wrong base.
|
|
189
|
+
- `PR_NUMBER` = null, `PR_URL` = null, `TARGET_LABEL` = `branch <LOCAL_BRANCH>`.
|
|
190
|
+
- The reviewed diff is `merge-base(HEAD, BASE_REF)..HEAD` - committed work only.
|
|
191
|
+
**Uncommitted and untracked changes are NOT reviewed.** If `git status
|
|
192
|
+
--porcelain` is non-empty, say so in one line before starting
|
|
193
|
+
(`⚠️ N uncommitted file(s) are not part of this review`) so nobody assumes
|
|
194
|
+
coverage that does not exist.
|
|
195
|
+
- If that diff is empty, stop: `nothing to review - <branch> matches <base>`.
|
|
196
|
+
|
|
197
|
+
**Guard:** never run branch mode on a long-lived integration branch. If
|
|
198
|
+
`LOCAL_BRANCH` is `main`, `master`, `develop`, `staging`, or `production`, stop
|
|
199
|
+
and say so.
|
|
200
|
+
|
|
201
|
+
**Depth:** explicit keyword `scan`, `medium`, or `deep` wins. If absent, get
|
|
202
|
+
the diff stat - in `pr` mode from
|
|
203
|
+
`gh pr view <PR_NUMBER> --repo <REPO_SLUG> --json additions,deletions,changedFiles`,
|
|
204
|
+
in `branch` mode from `git diff --shortstat <MERGE_BASE> HEAD` plus
|
|
205
|
+
`git diff --name-only <MERGE_BASE> HEAD | wc -l` - and apply AUTO-DEPTH:
|
|
113
206
|
- `scan` if additions+deletions < 150 AND changedFiles <= 5
|
|
114
207
|
- `deep` if additions+deletions > 800 OR changedFiles > 25 OR diff touches
|
|
115
208
|
`migrations/` or `*.sql`
|
|
@@ -124,11 +217,26 @@ checkout, so `--fix` forces Track A (worktree setup) to run even when
|
|
|
124
217
|
depth=scan. If the user did NOT pass `--fix`, leave `FIX_MODE=false` for now -
|
|
125
218
|
Step 4 offers it after the review is printed.
|
|
126
219
|
|
|
220
|
+
**Branch mode defaults to fix.** In `MODE=branch`, `FIX_MODE=true` and
|
|
221
|
+
`FIX_SCOPE=critical+important` unless the user passed `--no-fix`. That is the
|
|
222
|
+
whole point of reviewing pre-push: findings get applied before the PR exists,
|
|
223
|
+
so a bot reviewer never sees them. Landing those fixes on the local branch
|
|
224
|
+
still needs explicit confirmation (Step 4).
|
|
225
|
+
|
|
226
|
+
**`--base <ref>` flag (branch mode only):** overrides base-ref detection. Passed
|
|
227
|
+
through to the scripts as `LEKKER_BASE_REF`. Ignored in `pr` mode, where the
|
|
228
|
+
base comes from the PR.
|
|
229
|
+
|
|
230
|
+
**`--no-fix` flag:** parse and store as `FIX_MODE=false`, and do not offer fixes
|
|
231
|
+
in Step 4. Use it for a read-only pre-push look.
|
|
232
|
+
|
|
127
233
|
**`--no-artifact` flag:** parse and store as `ARTIFACT=false` (default true).
|
|
128
234
|
Skips Step 3.5 (living review artifact) silently.
|
|
129
235
|
|
|
130
236
|
**Re-review detection:** run
|
|
131
|
-
`ls ~/code-reviews
|
|
237
|
+
`ls ~/code-reviews/*-<TARGET_SLUG>-<repo-short-name>.md 2>/dev/null | sort | tail -1`
|
|
238
|
+
(`TARGET_SLUG` = `pr-<PR_NUMBER>` in pr mode, `branch-<LOCAL_BRANCH sanitized to
|
|
239
|
+
[a-z0-9-]>` in branch mode)
|
|
132
240
|
to find the newest prior review for this PR (repo-short-name = last segment of
|
|
133
241
|
REPO_SLUG; keeps PR numbers from colliding across repos). If found, grep it for
|
|
134
242
|
`\*\*Head:\*\*` and extract the short sha. Set `PREV_SHA=<sha>` and
|
|
@@ -159,6 +267,18 @@ For scan: note `⚡ scan - worktree unavailable, static checks skipped` in the
|
|
|
159
267
|
review header. When `--fix` forced the worktree at scan depth, drop that note
|
|
160
268
|
and say `⚡ scan - worktree created for --fix` instead.
|
|
161
269
|
|
|
270
|
+
**Branch mode always has a worktree** (fix mode is the default, and there is no
|
|
271
|
+
remote diff to fall back on), so the scan row's "skip worktree" never applies.
|
|
272
|
+
Everything else in the table is unchanged: branch mode is not a shallower
|
|
273
|
+
review, it is the same review earlier. Two rows differ because their inputs do
|
|
274
|
+
not exist yet:
|
|
275
|
+
|
|
276
|
+
| Step | branch mode |
|
|
277
|
+
|--------------------------|--------------------------------------------------------------|
|
|
278
|
+
| CI checks | `N/A - not pushed`; local compiler/linter/tests are the only signal |
|
|
279
|
+
| Existing bot reviews | none by definition - that is the saving |
|
|
280
|
+
| `--post` | unsupported until a PR exists (Step 4.6 can create one) |
|
|
281
|
+
|
|
162
282
|
---
|
|
163
283
|
|
|
164
284
|
## Step 1 - Context + worktree (concurrent)
|
|
@@ -170,14 +290,30 @@ Fire both tracks in the same turn.
|
|
|
170
290
|
Run via Bash with `run_in_background`:
|
|
171
291
|
|
|
172
292
|
```bash
|
|
293
|
+
# MODE=pr - checks out origin/<PR_BRANCH>, fetching if needed
|
|
173
294
|
${CLAUDE_PLUGIN_ROOT}/scripts/setup-worktree.sh \
|
|
174
295
|
<REPO_SLUG> <PR_BRANCH> <scratchpad>/worktree.json [PREV_SHA]
|
|
175
296
|
```
|
|
176
297
|
|
|
298
|
+
```bash
|
|
299
|
+
# MODE=branch - LOCAL ref only. LEKKER_LOCAL_REPO skips repo discovery, the
|
|
300
|
+
# fetch, and the origin/<branch> checkout entirely, and creates the worktree
|
|
301
|
+
# DETACHED so a branch already checked out in the user's own working copy can
|
|
302
|
+
# still be reviewed. LEKKER_BASE_REF is set only when --base was given.
|
|
303
|
+
LEKKER_LOCAL_REPO=<LOCAL_REPO> [LEKKER_BASE_REF=<BASE_REF>] \
|
|
304
|
+
${CLAUDE_PLUGIN_ROOT}/scripts/setup-worktree.sh \
|
|
305
|
+
<REPO_SLUG> <LOCAL_BRANCH> <scratchpad>/worktree.json [PREV_SHA]
|
|
306
|
+
```
|
|
307
|
+
|
|
177
308
|
On completion, read `worktree.json`. Keys emitted:
|
|
178
309
|
`worktreePath`, `repoRoot`, `headSha`, `headShaShort`, `tscTail`,
|
|
179
310
|
`tscChangedTail`, `tscErrorCount`, `eslintTail`, `eslintScope`, `changedFiles`,
|
|
180
|
-
`baseRef`, `projectRules`, `deltaFile`, `notes`.
|
|
311
|
+
`baseRef`, `mergeBase`, `projectRules`, `deltaFile`, `notes`.
|
|
312
|
+
|
|
313
|
+
`mergeBase` is the commit the file list was scoped against. Branch mode
|
|
314
|
+
generates its diff from that exact sha (below), so the diff the agents read and
|
|
315
|
+
the files the static checks were scoped to can never disagree. `notes` contains
|
|
316
|
+
`local-branch-mode;` when the local path ran.
|
|
181
317
|
|
|
182
318
|
Static checks are scoped so you can tell this PR's errors from the repo's
|
|
183
319
|
standing debt - do not try to infer that from the raw tail:
|
|
@@ -198,7 +334,11 @@ A failing CI build or test = Critical finding input.
|
|
|
198
334
|
|
|
199
335
|
When depth=scan: set `WORKTREE_PATH=null` without launching the script - unless
|
|
200
336
|
`FIX_MODE=true`, in which case run the script anyway (fix mode cannot edit code
|
|
201
|
-
from a diff).
|
|
337
|
+
from a diff). In `MODE=branch` the script always runs, at every depth.
|
|
338
|
+
|
|
339
|
+
A failing local compiler/linter/test run in branch mode is the direct
|
|
340
|
+
replacement for the failing-CI signal - treat it exactly the same way. Catching
|
|
341
|
+
it here is a CI run the PR never has to burn.
|
|
202
342
|
|
|
203
343
|
### Track B - metadata and signals (all calls fired in parallel)
|
|
204
344
|
|
|
@@ -206,6 +346,31 @@ Run ALL of the following in the same message. Full query details are in
|
|
|
206
346
|
`references/context-gathering.md` - follow it, do not paste it wholesale into
|
|
207
347
|
agent contexts.
|
|
208
348
|
|
|
349
|
+
**In `MODE=branch`, every `gh pr *` call below is skipped** - there is no PR.
|
|
350
|
+
Wait for Track A's `worktree.json` (you need `mergeBase`), then substitute:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# The diff, from the SAME merge-base the file list was scoped to.
|
|
354
|
+
git -C <worktreePath> diff <mergeBase> HEAD > <scratchpad>/pr.diff
|
|
355
|
+
|
|
356
|
+
# Commit log, for ticket ids and for the PR title the branch would need.
|
|
357
|
+
git -C <worktreePath> log --format='%s%n%b' <mergeBase>..HEAD
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
- The title/ticket-prefix check in branch mode is a PRE-check, not a
|
|
361
|
+
violation: scan the commit subjects for your team's ticket pattern, collect
|
|
362
|
+
the distinct ids, and set `RECOMMENDED_PREFIX`. There is no PR title to be
|
|
363
|
+
wrong yet, so `PR_TITLE_ISSUE=false` - report the prefix as the title to use,
|
|
364
|
+
in the Step 4.6 PR offer.
|
|
365
|
+
- Ticket ids come from the commit log and the branch name instead of the PR
|
|
366
|
+
title/body; the issue-tracker lookup below is otherwise identical.
|
|
367
|
+
- `ciStatus` = `N/A - not pushed`. `existingReviews` = null.
|
|
368
|
+
- Everything else in Track B (issue tracker, chat, docs, framework docs,
|
|
369
|
+
monitoring, prior-review memory) runs unchanged, keyed off the ticket ids
|
|
370
|
+
and the branch name.
|
|
371
|
+
|
|
372
|
+
`MODE=pr` calls:
|
|
373
|
+
|
|
209
374
|
- `gh pr view <PR_NUMBER> --repo <REPO_SLUG>` with fields: `number`, `title`,
|
|
210
375
|
`body`, `author`, `headRefName`, `baseRefName`, `labels`, `linkedBranches`,
|
|
211
376
|
`mergeStateStatus`, `additions`, `deletions`, `changedFiles`, `isDraft`,
|
|
@@ -241,10 +406,16 @@ Write `<scratchpad>/context.json` with keys:
|
|
|
241
406
|
"ciStatus": "<passing | failing: <names> | pending | N/A>",
|
|
242
407
|
"existingReviews": "<prior review summaries>",
|
|
243
408
|
"deltaFile": "<worktree.json deltaFile, or null>",
|
|
244
|
-
"houseRulesFile": "${CLAUDE_PLUGIN_ROOT}/references/house-rules.md"
|
|
409
|
+
"houseRulesFile": "${CLAUDE_PLUGIN_ROOT}/references/house-rules.md",
|
|
410
|
+
"reviewTarget": "<TARGET_LABEL, e.g. 'PR #412' or 'branch feat/offline-orders'>",
|
|
411
|
+
"prePush": "<true in MODE=branch, false in MODE=pr>"
|
|
245
412
|
}
|
|
246
413
|
```
|
|
247
414
|
|
|
415
|
+
`prePush: true` tells the agents there is no CI verdict and no bot review to
|
|
416
|
+
defer to, and that anything they flag is cheaper to fix now than after the PR
|
|
417
|
+
opens. It does NOT lower the bar: same severities, same no-nitpicking rule.
|
|
418
|
+
|
|
248
419
|
Agents read keys from this file. Nothing from CONTEXT_FILE is pasted into
|
|
249
420
|
their prompts wholesale - the workflow script delivers it by path.
|
|
250
421
|
|
|
@@ -258,8 +429,9 @@ Invoke the Workflow tool:
|
|
|
258
429
|
scriptPath: ${CLAUDE_PLUGIN_ROOT}/workflow.js
|
|
259
430
|
args: {
|
|
260
431
|
repoSlug,
|
|
261
|
-
prNumber,
|
|
262
|
-
prUrl,
|
|
432
|
+
prNumber, // null in MODE=branch
|
|
433
|
+
prUrl, // null in MODE=branch
|
|
434
|
+
targetLabel, // TARGET_LABEL - REQUIRED when prNumber is null
|
|
263
435
|
depth,
|
|
264
436
|
diffFile: "<scratchpad>/pr.diff",
|
|
265
437
|
contextFile: "<scratchpad>/context.json",
|
|
@@ -269,6 +441,10 @@ args: {
|
|
|
269
441
|
}
|
|
270
442
|
```
|
|
271
443
|
|
|
444
|
+
`targetLabel` is what every agent is told it is reviewing. The workflow falls
|
|
445
|
+
back to `PR #<prNumber>` when it is absent, so pr mode may omit it; branch mode
|
|
446
|
+
must pass it, or the workflow throws on its missing-args guard.
|
|
447
|
+
|
|
272
448
|
Two optional args tune concurrency; omit both unless a run needs it:
|
|
273
449
|
|
|
274
450
|
- `reviewBatchPlan` - batch sizes for the review dimensions, default `[5]`
|
|
@@ -399,12 +575,19 @@ dropped.
|
|
|
399
575
|
requirements:
|
|
400
576
|
|
|
401
577
|
- Header must include `**Head:** <headShaShort>` (enables future delta mode).
|
|
578
|
+
- **Branch mode header:** title the review `Pre-push review - <LOCAL_BRANCH>`,
|
|
579
|
+
and include `**Target:** branch <LOCAL_BRANCH> -> <BASE_REF> (not pushed)`,
|
|
580
|
+
`**Base:** <mergeBase short sha>`, and `**CI:** N/A - not pushed`. State the
|
|
581
|
+
uncommitted-file warning here if `git status --porcelain` was non-empty.
|
|
582
|
+
There is no PR link and no bot-review section; do not invent either.
|
|
402
583
|
- When `isDraft=true`: add `**DRAFT PR** - findings recorded for when this
|
|
403
584
|
is ready to merge.` after the header block.
|
|
404
585
|
- When `mergeStateStatus` is not CLEAN: note it (e.g. conflicts, failing
|
|
405
586
|
required checks).
|
|
406
587
|
- When `PR_TITLE_ISSUE=true`: insert the `⛔ CANNOT MERGE` block before the
|
|
407
|
-
Summary.
|
|
588
|
+
Summary. In branch mode there is no title yet, so instead print one line -
|
|
589
|
+
`**PR title to use:** <RECOMMENDED_PREFIX> <summary>` - and carry it into
|
|
590
|
+
the Step 4.6 offer.
|
|
408
591
|
- When `sentrySignals` is non-empty: include `## 🔥 Production Signals`.
|
|
409
592
|
- When `PREV_SHA` is set: include `## 🔁 Since last review` comparing
|
|
410
593
|
`PREV_REVIEW_FILE` findings against the new head - list each as fixed or
|
|
@@ -423,7 +606,9 @@ requirements:
|
|
|
423
606
|
|
|
424
607
|
```bash
|
|
425
608
|
mkdir -p ~/code-reviews
|
|
426
|
-
|
|
609
|
+
# TARGET_SLUG: "pr-<PR_NUMBER>" in pr mode,
|
|
610
|
+
# "branch-<LOCAL_BRANCH sanitized to [a-z0-9-]>" in branch mode
|
|
611
|
+
REVIEW_FILE=~/code-reviews/$(date +%Y-%m-%d)-<TARGET_SLUG>-<repo-short-name>.md
|
|
427
612
|
# write the review to $REVIEW_FILE
|
|
428
613
|
```
|
|
429
614
|
|
|
@@ -435,6 +620,18 @@ Also write the workflow's `findings` array verbatim to
|
|
|
435
620
|
`proof` objects ride along for the Step 5b proof flip), and it is the receipt
|
|
436
621
|
that what was reported equals what was found.
|
|
437
622
|
|
|
623
|
+
**Branch mode also drops a review marker**, so a pre-PR gate you build on top
|
|
624
|
+
of this skill can tell a reviewed branch from an unreviewed one:
|
|
625
|
+
|
|
626
|
+
```bash
|
|
627
|
+
mkdir -p ~/.cache/lekker-review/reviewed
|
|
628
|
+
printf '%s\n' "$REVIEW_FILE" > ~/.cache/lekker-review/reviewed/<headSha>
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
Write it against the sha that was actually reviewed. When fix mode later adds
|
|
632
|
+
commits, write a marker for the NEW head sha too - a gate keys on the tip
|
|
633
|
+
that is about to be pushed, and a marker for a superseded sha would be a lie.
|
|
634
|
+
|
|
438
635
|
Then print the full review as the response.
|
|
439
636
|
|
|
440
637
|
---
|
|
@@ -459,8 +656,8 @@ and print one line: `🔗 Living review: <url>`.
|
|
|
459
656
|
|
|
460
657
|
### Trigger
|
|
461
658
|
|
|
462
|
-
- `FIX_MODE=true` (the user passed `--fix`
|
|
463
|
-
`references/fix-mode.md`.
|
|
659
|
+
- `FIX_MODE=true` (the user passed `--fix`, or `MODE=branch` defaulted it on)
|
|
660
|
+
-> go straight to `references/fix-mode.md`.
|
|
464
661
|
- `FIX_MODE=false` and at least one Critical or Important finding has a `fix`
|
|
465
662
|
field -> ask once, via AskUserQuestion:
|
|
466
663
|
|
|
@@ -475,22 +672,29 @@ and print one line: `🔗 Living review: <url>`.
|
|
|
475
672
|
- No fixable findings, or the review found nothing -> do not ask. Say
|
|
476
673
|
`nothing to auto-fix` in one line and skip to Step 5.
|
|
477
674
|
- **Unattended run** (cron, `/loop`, background agent): never ask. Run fix mode
|
|
478
|
-
only when `--fix` was passed explicitly, and stop before pushing
|
|
675
|
+
only when `--fix` was passed explicitly, and stop before pushing (branch mode:
|
|
676
|
+
stop before landing).
|
|
479
677
|
|
|
480
678
|
### Procedure
|
|
481
679
|
|
|
482
680
|
Read `references/fix-mode.md` and follow it. Shape of the run:
|
|
483
681
|
|
|
484
|
-
1. Preconditions
|
|
485
|
-
`
|
|
682
|
+
1. Preconditions.
|
|
683
|
+
- `MODE=pr`: worktree exists + clean, `origin/<PR_BRANCH>` still at
|
|
684
|
+
`headSha`, PR open, head repo writable.
|
|
685
|
+
- `MODE=branch`: worktree exists + clean, and `refs/heads/<LOCAL_BRANCH>` in
|
|
686
|
+
`repoRoot` is still at `headSha`. If the branch moved while the review ran,
|
|
687
|
+
stop - do not land onto a tip you did not review.
|
|
486
688
|
2. Select eligible findings (Critical/Important with a `fix`, real file,
|
|
487
689
|
non-generated). Never auto-fix Observation, Idiomatic, or a title/process rule.
|
|
488
690
|
3. Invoke the fix workflow:
|
|
489
691
|
```
|
|
490
692
|
scriptPath: ${CLAUDE_PLUGIN_ROOT}/fix-workflow.js
|
|
491
|
-
args: { repoSlug, prNumber, worktreePath, diffFile, contextFile,
|
|
492
|
-
findings: [<selected findings verbatim>] }
|
|
693
|
+
args: { repoSlug, prNumber, targetLabel, worktreePath, diffFile, contextFile,
|
|
694
|
+
promptDir, findings: [<selected findings verbatim>] }
|
|
493
695
|
```
|
|
696
|
+
`targetLabel` is required whenever `prNumber` is null, same as the review
|
|
697
|
+
workflow.
|
|
494
698
|
One `sonnet` fix agent per file (never two on the same file), then a
|
|
495
699
|
read-only `sonnet` fix-verifier per file reading the actual `git diff`. One
|
|
496
700
|
retry max on a non-`good` verdict.
|
|
@@ -503,9 +707,37 @@ Read `references/fix-mode.md` and follow it. Shape of the run:
|
|
|
503
707
|
group even if the fix-verifier said `good`. An executed test outranks an
|
|
504
708
|
agent's opinion. Green -> record `proofFlip: green` in the status table.
|
|
505
709
|
6. Commit one commit per file with an explicit `git add -- <files>`.
|
|
506
|
-
7.
|
|
507
|
-
|
|
508
|
-
|
|
710
|
+
7. Land the commits, ONLY after the user confirms.
|
|
711
|
+
- `MODE=pr`: `git push origin "HEAD:refs/heads/$pr_branch"` with a re-fetch
|
|
712
|
+
sha guard. Never force, never rebase, never push to
|
|
713
|
+
main/master/staging/develop. Verify via `gh pr view --json headRefOid`.
|
|
714
|
+
- `MODE=branch`: nothing is pushed - the fixes move onto the LOCAL branch, so
|
|
715
|
+
the work is one branch again before it ever reaches the remote.
|
|
716
|
+
|
|
717
|
+
```bash
|
|
718
|
+
# Fast-forward the local branch onto the reviewed-and-fixed worktree tip.
|
|
719
|
+
# --ff-only and the old-value guard together mean this can only ever
|
|
720
|
+
# advance the exact commit the review started from.
|
|
721
|
+
git check-ref-format --branch "$local_branch"
|
|
722
|
+
git -C "$repo_root" update-ref "refs/heads/$local_branch" \
|
|
723
|
+
"$worktree_head_sha" "$head_sha"
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
Treat every repository path, ref, branch, title, and body as untrusted
|
|
727
|
+
data. Pass each value as a separately shell-quoted argument, never by
|
|
728
|
+
concatenating it into shell source. Put multiline PR bodies in a file and
|
|
729
|
+
pass the quoted path with `--body-file`.
|
|
730
|
+
|
|
731
|
+
If `$local_branch` is the branch checked out in `$repo_root`, `update-ref`
|
|
732
|
+
would leave the user's working tree looking like it had deleted the fixes.
|
|
733
|
+
In that case require a clean `git -C "$repo_root" status --porcelain` and use
|
|
734
|
+
`git -C "$repo_root" merge --ff-only "$worktree_head_sha"` instead. If the tree
|
|
735
|
+
is dirty, stop, keep the worktree, and print the exact command - never
|
|
736
|
+
stash or discard someone's uncommitted work.
|
|
737
|
+
|
|
738
|
+
Verify with `git -C "$repo_root" rev-parse "refs/heads/$local_branch"` and
|
|
739
|
+
confirm it equals `$worktree_head_sha`. Then refresh the review marker for
|
|
740
|
+
the new sha (Step 3).
|
|
509
741
|
8. Print the per-finding status table and append `## 🔧 Fixes applied` to the
|
|
510
742
|
saved review file.
|
|
511
743
|
|
|
@@ -514,10 +746,55 @@ Fix-agent tokens are additional spend: add a `Fix agents:` line to the
|
|
|
514
746
|
|
|
515
747
|
---
|
|
516
748
|
|
|
749
|
+
## Step 4.6 - Open the PR (MODE=branch only)
|
|
750
|
+
|
|
751
|
+
Skip entirely in `MODE=pr`.
|
|
752
|
+
|
|
753
|
+
The branch has now been reviewed and, where it had fixable findings, fixed. The
|
|
754
|
+
PR is the next step, but it is the USER'S call and it is the one irreversible
|
|
755
|
+
thing in this whole flow - once the PR exists a bot reviewer may start running
|
|
756
|
+
and start costing money. **Never create it silently.**
|
|
757
|
+
|
|
758
|
+
Ask once, via AskUserQuestion:
|
|
759
|
+
|
|
760
|
+
> Branch reviewed<, N fixes applied>. Open the PR now?
|
|
761
|
+
> - **Yes, create the PR** - `<RECOMMENDED_PREFIX>` title, base `<BASE_REF>`,
|
|
762
|
+
> pushes `<LOCAL_BRANCH>` first
|
|
763
|
+
> - **Push the branch only** - no PR yet
|
|
764
|
+
> - **No, stop here** - nothing leaves this machine
|
|
765
|
+
|
|
766
|
+
Rules for each answer:
|
|
767
|
+
|
|
768
|
+
- **Yes:** push with `git push -u origin "$local_branch"`, then create the PR
|
|
769
|
+
with `gh pr create --repo "$repo_slug" --base "$base_ref" --head
|
|
770
|
+
"$local_branch" --title "$pr_title" --body-file "$pr_body_file"`. Derive the title
|
|
771
|
+
from the commit log (the recommended prefix plus a summary of the change) and
|
|
772
|
+
the body from a short summary of what the branch does - do not leave either
|
|
773
|
+
as a placeholder. Report the PR url. The review is already saved locally;
|
|
774
|
+
offer `--post` on the new PR number only if the user asks - findings that fix
|
|
775
|
+
mode already applied must never be posted as review comments.
|
|
776
|
+
- **Push only:** `git push -u origin "$local_branch"` and stop. Say in one line
|
|
777
|
+
that no PR was created.
|
|
778
|
+
- **No:** stop. Print the branch name and the review file path.
|
|
779
|
+
|
|
780
|
+
**Unattended runs never ask and never create a PR** (see the operating contract
|
|
781
|
+
for your host: with no human present, "ask for confirmation" means stop and
|
|
782
|
+
report). Stage the branch, print what would have happened, and stop.
|
|
783
|
+
|
|
784
|
+
If the review verdict is `🚫 Needs work` with an unfixed Critical, say so in the
|
|
785
|
+
question - opening a PR on a known-broken branch just moves the finding to
|
|
786
|
+
whoever reviews it next.
|
|
787
|
+
|
|
788
|
+
---
|
|
789
|
+
|
|
517
790
|
## Step 5 - Post-review (after the review and any fixes)
|
|
518
791
|
|
|
519
792
|
### If POST_REVIEW=true
|
|
520
793
|
|
|
794
|
+
In `MODE=branch` there is no PR to post to. If `--post` was passed, say
|
|
795
|
+
`--post ignored - no PR yet` in one line and skip this section, unless Step 4.6
|
|
796
|
+
just created a PR, in which case use that PR number.
|
|
797
|
+
|
|
521
798
|
Follow `references/github-post.md`:
|
|
522
799
|
- Build a JSON payload with Critical + Important findings as inline comments
|
|
523
800
|
(only for lines present in the diff hunks).
|
|
@@ -544,10 +821,14 @@ repo-short-name + PR author login, instructed to follow
|
|
|
544
821
|
|
|
545
822
|
### Cleanup (when a worktree was created)
|
|
546
823
|
|
|
547
|
-
**Fix-mode override:** if fix mode produced commits that were NOT pushed
|
|
548
|
-
NOT
|
|
549
|
-
the
|
|
550
|
-
|
|
824
|
+
**Fix-mode override:** if fix mode produced commits that were NOT pushed (pr
|
|
825
|
+
mode) or NOT landed onto the local branch (branch mode), do NOT clean up. Keep
|
|
826
|
+
the worktree and the repo clone, print the worktree path and the exact
|
|
827
|
+
push/land command. Deleting it destroys the only copy of the work. Clean up
|
|
828
|
+
normally when the push or the land succeeded, or nothing was committed.
|
|
829
|
+
|
|
830
|
+
In branch mode `repoRoot` is the user's own working copy, never a
|
|
831
|
+
`/tmp/lekker-clone-*`. Remove the worktree; NEVER remove `repoRoot`.
|
|
551
832
|
|
|
552
833
|
```bash
|
|
553
834
|
git -C <repoRoot> worktree remove --force <worktreePath> \
|
|
@@ -583,3 +864,9 @@ Fix-mode specific:
|
|
|
583
864
|
- Never push without explicit confirmation, and never force-push or rebase a
|
|
584
865
|
PR branch. If the branch moved under you, stop and report - the commits stay
|
|
585
866
|
local.
|
|
867
|
+
- Branch mode never pushes on its own: landing means moving the reviewed
|
|
868
|
+
commits onto `refs/heads/<LOCAL_BRANCH>` in the user's own `repoRoot`, always
|
|
869
|
+
with a compare-and-swap (`update-ref <new> <old>` or `merge --ff-only`) that
|
|
870
|
+
can only succeed if the branch is still exactly where the review started. If
|
|
871
|
+
it moved, or the working tree is dirty, stop and print the exact command -
|
|
872
|
+
never stash or discard uncommitted work to force the landing through.
|
package/adapters/claude/olko-github-pr/skills/lekker-review/references/agents/implementation.md
CHANGED
|
@@ -9,6 +9,27 @@ Axes to cover:
|
|
|
9
9
|
✅ met / ⚠️ partial / ❌ missing. Scope creep is also worth flagging.
|
|
10
10
|
AC_LIST: read key "acList" from CONTEXT_FILE.
|
|
11
11
|
Return the complete status summary in the structured `acCoverage` field.
|
|
12
|
+
Decide each AC against the code that RUNS, not against the diff. When
|
|
13
|
+
WORKTREE_PATH is null, mark runtime verification as unavailable: do not inspect
|
|
14
|
+
worktree files or infer an AC status from runtime evidence you cannot verify.
|
|
15
|
+
Otherwise, use the worktree to follow the AC through its runtime path into
|
|
16
|
+
files the diff never touched, and specifically:
|
|
17
|
+
(a) Find what invokes the new code and on what trigger. New code that nothing
|
|
18
|
+
calls satisfies nothing, however correct its body is.
|
|
19
|
+
(b) For an AC with a timing, cadence or SLA component, name the trigger's
|
|
20
|
+
measurable frequency, such as its cron expression or poll interval, and
|
|
21
|
+
compare that number against the AC. For a webhook, compare a documented
|
|
22
|
+
delivery bound against the AC; without one, mark cadence verification as
|
|
23
|
+
unavailable rather than treating the webhook as a fixed-frequency trigger.
|
|
24
|
+
A reaper on a daily cron cannot meet a two-hour SLA.
|
|
25
|
+
(c) For an AC about a failure mode (crash, OOM, timeout, network loss), confirm
|
|
26
|
+
the handling is reachable under that failure. A process terminated by an
|
|
27
|
+
uncatchable signal such as SIGKILL cannot reach a `finally` block, shutdown
|
|
28
|
+
hook, or the tail of a long-running function; SIGTERM may allow graceful
|
|
29
|
+
handling. Verify the actual failure signal and its handling before concluding
|
|
30
|
+
that cleanup is unreachable.
|
|
31
|
+
An AC can fail with every added line correct, because the defect is what the
|
|
32
|
+
diff left alone. That is a finding, not an absence of one.
|
|
12
33
|
- Scalability: N+1 queries, missing pagination, unbounded in-memory
|
|
13
34
|
collections, missing rate-limit handling, cron jobs without overlap guard,
|
|
14
35
|
missing DB indexes for new query patterns.
|
|
@@ -37,7 +58,10 @@ Diff: read the full unified PR diff from the file DIFF_FILE (absolute path given
|
|
|
37
58
|
Worktree: WORKTREE_PATH is given in your task message (null in scan mode, diff only).
|
|
38
59
|
|
|
39
60
|
Rules:
|
|
40
|
-
- Every finding must trace to a + line in the diff
|
|
61
|
+
- Every finding must trace to a + line in the diff, with one exception: an unmet
|
|
62
|
+
AC whose defect lives in code the diff did not touch. Anchor that one to the
|
|
63
|
+
unchanged file:line that had to change, and say in the description why the
|
|
64
|
+
unchanged line is the defect.
|
|
41
65
|
- Report file:line: description. No positive observations.
|
|
42
66
|
- `badCode` is REQUIRED: the verbatim offending line(s) copied from the diff:
|
|
43
67
|
never paraphrased, never reconstructed from memory.
|
|
@@ -49,6 +73,7 @@ Rules:
|
|
|
49
73
|
on a `critical`/`important` finding: a finding you cannot quote and cannot
|
|
50
74
|
fix is a finding you have not proven, so drop it instead.
|
|
51
75
|
- Exception for a missing/partial AC: the defect is what is absent, so quote
|
|
52
|
-
the closest incomplete
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
the closest incomplete line(s) in `badCode` (the handler that stops short, the
|
|
77
|
+
branch never written, the caller on the wrong trigger) and put what must be
|
|
78
|
+
added in `fix`. That line may be an unchanged one. Do not drop an unmet AC for
|
|
79
|
+
lack of a quotable added line.
|
|
@@ -11,9 +11,15 @@
|
|
|
11
11
|
# tree + staged) changes -- what a fix agent just wrote, even if it wasn't
|
|
12
12
|
# part of the original PR diff.
|
|
13
13
|
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
14
|
+
# LEKKER_BASE_REF=<ref> overrides base-ref detection entirely (pre-push branch
|
|
15
|
+
# mode passes the branch the PR would target). Also prints the resolved
|
|
16
|
+
# "merge-base: <sha>" to stderr so a caller can produce a diff from the exact
|
|
17
|
+
# same point this file list was scoped to.
|
|
18
|
+
#
|
|
19
|
+
# If automatic base-ref detection finds nothing, prints NOTHING to stdout,
|
|
20
|
+
# "base-ref: unknown" to stderr, and exits 0 so callers can fall back to a
|
|
21
|
+
# repo-wide check. An invalid explicit base or a missing merge base is a caller
|
|
22
|
+
# error and exits nonzero without emitting base-ref/merge-base metadata.
|
|
17
23
|
|
|
18
24
|
set -uo pipefail
|
|
19
25
|
|
|
@@ -25,10 +31,16 @@ INCLUDE_UNCOMMITTED=false
|
|
|
25
31
|
# 1. Resolve a base ref: origin's default branch first, then a fixed
|
|
26
32
|
# fallback order.
|
|
27
33
|
# ---------------------------------------------------------------------------
|
|
28
|
-
BASE_REF=""
|
|
34
|
+
BASE_REF="${LEKKER_BASE_REF:-}"
|
|
35
|
+
if [[ -n "$BASE_REF" ]] && ! git -C "$WORKTREE_PATH" rev-parse --verify --quiet "$BASE_REF" >/dev/null 2>&1; then
|
|
36
|
+
# An override that does not resolve is a caller error, not a reason to
|
|
37
|
+
# silently review against the wrong base.
|
|
38
|
+
printf 'ERROR: LEKKER_BASE_REF does not resolve: %s\n' "$BASE_REF" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
29
41
|
|
|
30
42
|
SYM_REF="$(git -C "$WORKTREE_PATH" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null || true)"
|
|
31
|
-
if [[ -n "$SYM_REF" ]]; then
|
|
43
|
+
if [[ -z "$BASE_REF" ]] && [[ -n "$SYM_REF" ]]; then
|
|
32
44
|
candidate="origin/${SYM_REF#refs/remotes/origin/}"
|
|
33
45
|
if git -C "$WORKTREE_PATH" rev-parse --verify --quiet "$candidate" >/dev/null 2>&1; then
|
|
34
46
|
BASE_REF="$candidate"
|
|
@@ -54,11 +66,12 @@ fi
|
|
|
54
66
|
# ---------------------------------------------------------------------------
|
|
55
67
|
MERGE_BASE="$(git -C "$WORKTREE_PATH" merge-base HEAD "$BASE_REF" 2>/dev/null || true)"
|
|
56
68
|
if [[ -z "$MERGE_BASE" ]]; then
|
|
57
|
-
printf '
|
|
58
|
-
exit
|
|
69
|
+
printf 'ERROR: no merge base between HEAD and %s\n' "$BASE_REF" >&2
|
|
70
|
+
exit 1
|
|
59
71
|
fi
|
|
60
72
|
|
|
61
73
|
printf 'base-ref: %s\n' "$BASE_REF" >&2
|
|
74
|
+
printf 'merge-base: %s\n' "$MERGE_BASE" >&2
|
|
62
75
|
|
|
63
76
|
CHANGED_TMP="/tmp/lekker-changed-files-tmp-$$.txt"
|
|
64
77
|
git -C "$WORKTREE_PATH" diff --name-only "$MERGE_BASE" HEAD > "$CHANGED_TMP" 2>/dev/null || true
|