@olegkoval/agent-skills 1.51.3 → 1.53.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.
Files changed (51) hide show
  1. package/.github/prompts/codexloop.prompt.md +31 -7
  2. package/.github/prompts/pr-description-writer.prompt.md +25 -2
  3. package/.kiro/steering/codexloop.md +31 -7
  4. package/.windsurf/rules/codexloop.md +31 -7
  5. package/adapters/claude/olko-github-pr/skills/codexloop/SKILL.md +31 -7
  6. package/adapters/claude/olko-github-pr/skills/lekker-review/SKILL.md +121 -29
  7. package/adapters/claude/olko-github-pr/skills/lekker-review/references/agents/deps.md +54 -0
  8. package/adapters/claude/olko-github-pr/skills/lekker-review/references/artifact-page.md +40 -12
  9. package/adapters/claude/olko-github-pr/skills/lekker-review/references/codex-workflow.md +1 -0
  10. package/adapters/claude/olko-github-pr/skills/lekker-review/references/fun.json +222 -0
  11. package/adapters/claude/olko-github-pr/skills/lekker-review/references/github-post.md +8 -1
  12. package/adapters/claude/olko-github-pr/skills/lekker-review/references/output-format.md +15 -10
  13. package/adapters/claude/olko-github-pr/skills/lekker-review/references/pricing.json +12 -11
  14. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/deps-only.mjs +95 -0
  15. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/pick-closer.mjs +99 -0
  16. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/selftest.mjs +130 -6
  17. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/setup-worktree.sh +136 -16
  18. package/adapters/claude/olko-github-pr/skills/lekker-review/scripts/validate-lines.mjs +122 -0
  19. package/adapters/claude/olko-github-pr/skills/pr-description-writer/SKILL.md +26 -3
  20. package/adapters/cursor/olko-github-pr/skills/codexloop/SKILL.md +31 -7
  21. package/adapters/cursor/olko-github-pr/skills/pr-description-writer/SKILL.md +26 -3
  22. package/adapters/grok/olko-github-pr/skills/codexloop/SKILL.md +31 -7
  23. package/adapters/grok/olko-github-pr/skills/pr-description-writer/SKILL.md +26 -3
  24. package/package.json +1 -1
  25. package/plugins/olko-apple-kit/.claude-plugin/plugin.json +1 -1
  26. package/plugins/olko-creative/.claude-plugin/plugin.json +1 -1
  27. package/plugins/olko-garmin-kit/.claude-plugin/plugin.json +1 -1
  28. package/plugins/olko-git-tools/.claude-plugin/plugin.json +1 -1
  29. package/plugins/olko-github-pr/.claude-plugin/plugin.json +1 -1
  30. package/plugins/olko-github-pr/skills/codexloop/SKILL.md +31 -7
  31. package/plugins/olko-github-pr/skills/lekker-review/SKILL.md +121 -29
  32. package/plugins/olko-github-pr/skills/lekker-review/references/agents/deps.md +54 -0
  33. package/plugins/olko-github-pr/skills/lekker-review/references/artifact-page.md +40 -12
  34. package/plugins/olko-github-pr/skills/lekker-review/references/codex-workflow.md +1 -0
  35. package/plugins/olko-github-pr/skills/lekker-review/references/fun.json +222 -0
  36. package/plugins/olko-github-pr/skills/lekker-review/references/github-post.md +8 -1
  37. package/plugins/olko-github-pr/skills/lekker-review/references/output-format.md +15 -10
  38. package/plugins/olko-github-pr/skills/lekker-review/references/pricing.json +12 -11
  39. package/plugins/olko-github-pr/skills/lekker-review/scripts/deps-only.mjs +95 -0
  40. package/plugins/olko-github-pr/skills/lekker-review/scripts/pick-closer.mjs +99 -0
  41. package/plugins/olko-github-pr/skills/lekker-review/scripts/selftest.mjs +130 -6
  42. package/plugins/olko-github-pr/skills/lekker-review/scripts/setup-worktree.sh +136 -16
  43. package/plugins/olko-github-pr/skills/lekker-review/scripts/validate-lines.mjs +122 -0
  44. package/plugins/olko-github-pr/skills/lekker-review/workflow.js +43 -23
  45. package/plugins/olko-github-pr/skills/pr-description-writer/SKILL.md +26 -3
  46. package/plugins/olko-obsidian/.claude-plugin/plugin.json +1 -1
  47. package/plugins/olko-product/.claude-plugin/plugin.json +1 -1
  48. package/plugins/olko-reflection/.claude-plugin/plugin.json +1 -1
  49. package/plugins/olko-release/.claude-plugin/plugin.json +1 -1
  50. package/plugins/olko-skill-meta/.claude-plugin/plugin.json +1 -1
  51. package/plugins/olko-web-ops/.claude-plugin/plugin.json +1 -1
@@ -7,7 +7,7 @@ description: >
7
7
  Chains naturally after git-commit and before qodoloop / coderabbitloop.
8
8
  license: MIT
9
9
  allowed-tools: Bash, Read, Write
10
- compatibility: Codex, Claude Code, Cursor, GitHub Copilot, Windsurf, Kiro, and other Agent Skills compatible tools. Requires git and gh (GitHub CLI) authenticated.
10
+ compatibility: Codex, Claude Code, Cursor, GitHub Copilot, Windsurf, Kiro, and other Agent Skills compatible tools. Requires git, jq, and gh (GitHub CLI) authenticated.
11
11
  metadata:
12
12
  targets: [_source-only]
13
13
  author: Oleg Koval
@@ -52,11 +52,22 @@ gh repo view --json defaultBranchRef -q '.defaultBranchRef.name'
52
52
  git log <base>..<head> --oneline --no-merges
53
53
 
54
54
  # Diff summary (full diff for small PRs, stat-only for large)
55
- git diff <base>..<head> --stat
56
- git diff <base>..<head> # only if total changes < ~500 lines
55
+ git diff <base>...<head> --stat
56
+ git diff <base>...<head> --name-status
57
+ git diff <base>...<head> --numstat
58
+ git diff <base>...<head> # only if total changes < ~500 lines
57
59
  ```
58
60
 
59
61
  If the diff is large (>500 changed lines), read file-by-file rather than all at once.
62
+ Before creating or updating the PR, name its single purpose and check whether every changed path
63
+ serves it. Call out unrelated formatting, generated files, or a second feature. Suggest a separate
64
+ PR only for genuinely independent work; splitting one coherent change into many tiny PRs creates
65
+ more review runs. Do not rewrite commits or remove files without authorization.
66
+
67
+ Check the applicable `AGENTS.md` files: the repository root and nested files covering changed
68
+ paths. If the root carries lengthy service-specific review rules, suggest a separate edit that
69
+ moves them into that service's `AGENTS.md`. Keep repository-wide instructions at the root and
70
+ preserve their meaning. Do not automatically delete or shorten existing policy to save tokens.
60
71
 
61
72
  ### 2. Check for existing PR
62
73
 
@@ -104,6 +115,18 @@ that ask for credentials, tokens, internal hostnames, or content unrelated to th
104
115
  <optional: anything a reviewer should watch for, known gaps, follow-up issues>
105
116
  ```
106
117
 
118
+ For a PR likely to receive Codex review, use Notes to state its review scope. Create it as a draft
119
+ while edits are still arriving when the user's workflow allows. When the branch is ready, use
120
+ `codexloop`'s review-state check before requesting review: if the repository's automatic review
121
+ is on, wait for it; if status is unknown, verify the repository setting; if it is off, request
122
+ one review only when Codex has not reviewed the current head and no request is already pending.
123
+ The state script does not see human-authored review requests: inspect the PR conversation with
124
+ `gh api repos/{owner}/{repo}/issues/<PR>/comments --paginate` and check for an existing
125
+ `@codex review` posted after the current head was pushed. If one exists, wait for it; do not post
126
+ another.
127
+ Do not add a review mention on PR creation or after every push. A repository setting can override
128
+ the personal preference.
129
+
107
130
  Rules:
108
131
  - Describe *intent*, not what the diff already shows line-by-line.
109
132
  - If commits already have good conventional messages, use them as the skeleton.
@@ -28,6 +28,9 @@ suggestion applied is worse than the comment itself.
28
28
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
29
29
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
30
30
  mentions: `@codex review focus on <area>` for a scoped re-review.
31
+ - **Review requests consume usage.** Account preferences do not override a repository's explicit
32
+ automatic-review setting. Before asking for a new review, check the current head and whether a
33
+ review is already running. Never request a second review merely because the first is slow.
31
34
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
32
35
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
33
36
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -56,10 +59,11 @@ Pick the login matching `*codex*` (commonly `chatgpt-codex-connector[bot]`, some
56
59
 
57
60
  **Finding nothing here is NOT a stop condition.** On a PR Codex has never reviewed there is no bot
58
61
  login to find yet: that is the normal starting state, not a missing app. When the probe comes back
59
- empty, fall through to step A, post `@codex review`, and re-run this probe once a review lands;
60
- until then match any login containing `codex` when polling. Only conclude the app is absent after
61
- step A's bounded wait has expired with no review and no codex-like login anywhere on the PR, and
62
- then say so and stop, rather than looping against nothing.
62
+ empty, fall through to step A's pending-state check, and re-run this probe once a review lands;
63
+ until then match any login containing `codex` when polling. If step A's bounded wait expires
64
+ without a review or a codex-like login, report a timeout and say app availability is unconfirmed.
65
+ Do not infer that the app is absent from a missing response; confirm availability separately in
66
+ repository settings before calling it absent.
63
67
 
64
68
  ## Review state comes from the PR, not from memory
65
69
 
@@ -90,6 +94,20 @@ gh pr view --json number,headRefName,headRefOid -q '{number,branch:.headRefName,
90
94
 
91
95
  Switch to the PR branch if not already on it. Capture `OWNER`/`REPO` (`gh repo view --json owner,name`).
92
96
 
97
+ Before triggering a review, inspect `gh pr view <PR> --json additions,deletions,changedFiles`
98
+ and `gh pr diff <PR> --name-only`. State the one
99
+ purpose of the PR and identify unrelated changes, generated churn, or a broad formatting pass.
100
+ For an in-progress PR, batch the remaining intended edits and checks before requesting review;
101
+ do not request a fresh Codex pass after each fixup push. Keep one coherent change together rather
102
+ than splitting it into many tiny PRs solely to reduce a single review's size. Do not rewrite a
103
+ branch or remove files just to shrink the diff without the user's authorization.
104
+
105
+ Read only the root `AGENTS.md` and the nested `AGENTS.md` files applicable to changed paths.
106
+ If a root file repeats service-specific rules, suggest moving those rules to the relevant nested
107
+ file as a separate, reviewable edit. Preserve the rules' meaning; do not silently delete policy.
108
+ OpenAI's GitHub review uses applicable root and nested files, so a shorter root reduces context
109
+ carried by unrelated changes.
110
+
93
111
  ## 2. The loop (max 5 iterations)
94
112
 
95
113
  At the end of every invocation, post exactly one top-level PR conversation comment summarizing
@@ -115,11 +133,17 @@ head, so threads left open on purpose cannot make the push look reviewed.
115
133
 
116
134
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
117
135
  already posted.
118
- - Exit `20` (`pending`): post `@codex review` (`gh pr comment <PR> --body "@codex review"`). Then wait with the same command plus `--wait 600`. Run the
136
+ - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
137
+ review already in progress can land. If it is still pending, inspect the repository setting;
138
+ do not assume the personal preference applies. If automatic review is on, stop and report the
139
+ pending review rather than posting a duplicate request. If automatic review is off and no
140
+ request was posted for this head, post one `@codex review`
141
+ (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
142
+ with the same command plus `--wait 600`. Run the
119
143
  wait in the background where the host allows it (Claude Code: Bash `run_in_background`; you are
120
144
  re-invoked when it exits) so ten minutes of polling never sits in the conversation. Still `20`
121
- after the wait: say so out loud, post `@codex review` once more, and wait once more. Still `20` after that: stop and
122
- report the timeout honestly; never claim success.
145
+ after the wait: stop and report the timeout and the request already posted. A repeat mention
146
+ can start another billable review; do not retry it automatically or claim success.
123
147
  - Exit `0` (`clean`): go to the exit check. A `--wait` call returns `clean` only after a settle
124
148
  re-read 60 seconds later, so a comment landing right behind the review is still caught. A bare
125
149
  read (no `--wait`) that says `clean` is good enough only when you have not pushed since Codex's
@@ -7,7 +7,7 @@ description: >
7
7
  Chains naturally after git-commit and before qodoloop / coderabbitloop.
8
8
  license: MIT
9
9
  allowed-tools: Bash, Read, Write
10
- compatibility: Codex, Claude Code, Cursor, GitHub Copilot, Windsurf, Kiro, and other Agent Skills compatible tools. Requires git and gh (GitHub CLI) authenticated.
10
+ compatibility: Codex, Claude Code, Cursor, GitHub Copilot, Windsurf, Kiro, and other Agent Skills compatible tools. Requires git, jq, and gh (GitHub CLI) authenticated.
11
11
  metadata:
12
12
  targets: [_source-only]
13
13
  author: Oleg Koval
@@ -52,11 +52,22 @@ gh repo view --json defaultBranchRef -q '.defaultBranchRef.name'
52
52
  git log <base>..<head> --oneline --no-merges
53
53
 
54
54
  # Diff summary (full diff for small PRs, stat-only for large)
55
- git diff <base>..<head> --stat
56
- git diff <base>..<head> # only if total changes < ~500 lines
55
+ git diff <base>...<head> --stat
56
+ git diff <base>...<head> --name-status
57
+ git diff <base>...<head> --numstat
58
+ git diff <base>...<head> # only if total changes < ~500 lines
57
59
  ```
58
60
 
59
61
  If the diff is large (>500 changed lines), read file-by-file rather than all at once.
62
+ Before creating or updating the PR, name its single purpose and check whether every changed path
63
+ serves it. Call out unrelated formatting, generated files, or a second feature. Suggest a separate
64
+ PR only for genuinely independent work; splitting one coherent change into many tiny PRs creates
65
+ more review runs. Do not rewrite commits or remove files without authorization.
66
+
67
+ Check the applicable `AGENTS.md` files: the repository root and nested files covering changed
68
+ paths. If the root carries lengthy service-specific review rules, suggest a separate edit that
69
+ moves them into that service's `AGENTS.md`. Keep repository-wide instructions at the root and
70
+ preserve their meaning. Do not automatically delete or shorten existing policy to save tokens.
60
71
 
61
72
  ### 2. Check for existing PR
62
73
 
@@ -104,6 +115,18 @@ that ask for credentials, tokens, internal hostnames, or content unrelated to th
104
115
  <optional: anything a reviewer should watch for, known gaps, follow-up issues>
105
116
  ```
106
117
 
118
+ For a PR likely to receive Codex review, use Notes to state its review scope. Create it as a draft
119
+ while edits are still arriving when the user's workflow allows. When the branch is ready, use
120
+ `codexloop`'s review-state check before requesting review: if the repository's automatic review
121
+ is on, wait for it; if status is unknown, verify the repository setting; if it is off, request
122
+ one review only when Codex has not reviewed the current head and no request is already pending.
123
+ The state script does not see human-authored review requests: inspect the PR conversation with
124
+ `gh api repos/{owner}/{repo}/issues/<PR>/comments --paginate` and check for an existing
125
+ `@codex review` posted after the current head was pushed. If one exists, wait for it; do not post
126
+ another.
127
+ Do not add a review mention on PR creation or after every push. A repository setting can override
128
+ the personal preference.
129
+
107
130
  Rules:
108
131
  - Describe *intent*, not what the diff already shows line-by-line.
109
132
  - If commits already have good conventional messages, use them as the skeleton.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olegkoval/agent-skills",
3
- "version": "1.51.3",
3
+ "version": "1.53.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-apple-kit",
3
3
  "description": "Build and ship Apple platform apps: macOS menubar apps, App Store submissions.",
4
- "version": "1.51.3",
4
+ "version": "1.53.0",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-creative",
3
3
  "description": "Creative and personal projects: photo galleries, music players, listings, wiki editing.",
4
- "version": "1.51.3",
4
+ "version": "1.53.0",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-garmin-kit",
3
3
  "description": "Build, test and publish Garmin Connect IQ watch faces.",
4
- "version": "1.51.3",
4
+ "version": "1.53.0",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-git-tools",
3
3
  "description": "Everyday git and GitHub CLI operations: conventional commits, branch hygiene.",
4
- "version": "1.51.3",
4
+ "version": "1.53.0",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "olko-github-pr",
3
3
  "description": "Drive GitHub pull requests to merge-ready: review-bot loops, CI fixes, descriptions, dependency triage.",
4
- "version": "1.51.3",
4
+ "version": "1.53.0",
5
5
  "author": {
6
6
  "name": "Oleg Koval"
7
7
  },
@@ -27,6 +27,9 @@ suggestion applied is worse than the comment itself.
27
27
  - **Trigger phrase is `@codex review`.** Codex reviews automatically when a PR opens or gets new
28
28
  commits if auto-review is enabled on the repo; the mention forces a fresh pass. Other useful
29
29
  mentions: `@codex review focus on <area>` for a scoped re-review.
30
+ - **Review requests consume usage.** Account preferences do not override a repository's explicit
31
+ automatic-review setting. Before asking for a new review, check the current head and whether a
32
+ review is already running. Never request a second review merely because the first is slow.
30
33
  - **Priority, not confidence.** Codex findings usually lead with a severity/priority word (`P1`,
31
34
  `P2`, `P3` or `critical`/`major`/`minor`) or a short titled heading. Weight the top tier
32
35
  seriously; treat the bottom tier as usually-skippable nits unless clearly correct.
@@ -55,10 +58,11 @@ Pick the login matching `*codex*` (commonly `chatgpt-codex-connector[bot]`, some
55
58
 
56
59
  **Finding nothing here is NOT a stop condition.** On a PR Codex has never reviewed there is no bot
57
60
  login to find yet: that is the normal starting state, not a missing app. When the probe comes back
58
- empty, fall through to step A, post `@codex review`, and re-run this probe once a review lands;
59
- until then match any login containing `codex` when polling. Only conclude the app is absent after
60
- step A's bounded wait has expired with no review and no codex-like login anywhere on the PR, and
61
- then say so and stop, rather than looping against nothing.
61
+ empty, fall through to step A's pending-state check, and re-run this probe once a review lands;
62
+ until then match any login containing `codex` when polling. If step A's bounded wait expires
63
+ without a review or a codex-like login, report a timeout and say app availability is unconfirmed.
64
+ Do not infer that the app is absent from a missing response; confirm availability separately in
65
+ repository settings before calling it absent.
62
66
 
63
67
  ## Review state comes from the PR, not from memory
64
68
 
@@ -89,6 +93,20 @@ gh pr view --json number,headRefName,headRefOid -q '{number,branch:.headRefName,
89
93
 
90
94
  Switch to the PR branch if not already on it. Capture `OWNER`/`REPO` (`gh repo view --json owner,name`).
91
95
 
96
+ Before triggering a review, inspect `gh pr view <PR> --json additions,deletions,changedFiles`
97
+ and `gh pr diff <PR> --name-only`. State the one
98
+ purpose of the PR and identify unrelated changes, generated churn, or a broad formatting pass.
99
+ For an in-progress PR, batch the remaining intended edits and checks before requesting review;
100
+ do not request a fresh Codex pass after each fixup push. Keep one coherent change together rather
101
+ than splitting it into many tiny PRs solely to reduce a single review's size. Do not rewrite a
102
+ branch or remove files just to shrink the diff without the user's authorization.
103
+
104
+ Read only the root `AGENTS.md` and the nested `AGENTS.md` files applicable to changed paths.
105
+ If a root file repeats service-specific rules, suggest moving those rules to the relevant nested
106
+ file as a separate, reviewable edit. Preserve the rules' meaning; do not silently delete policy.
107
+ OpenAI's GitHub review uses applicable root and nested files, so a shorter root reduces context
108
+ carried by unrelated changes.
109
+
92
110
  ## 2. The loop (max 5 iterations)
93
111
 
94
112
  At the end of every invocation, post exactly one top-level PR conversation comment summarizing
@@ -114,11 +132,17 @@ head, so threads left open on purpose cannot make the push look reviewed.
114
132
 
115
133
  - Exit `10` (`findings`): go to B. On iteration 1 this is whatever Codex (or another bot)
116
134
  already posted.
117
- - Exit `20` (`pending`): post `@codex review` (`gh pr comment <PR> --body "@codex review"`). Then wait with the same command plus `--wait 600`. Run the
135
+ - Exit `20` (`pending`): if automatic-review status is unknown, wait up to 600 seconds first so a
136
+ review already in progress can land. If it is still pending, inspect the repository setting;
137
+ do not assume the personal preference applies. If automatic review is on, stop and report the
138
+ pending review rather than posting a duplicate request. If automatic review is off and no
139
+ request was posted for this head, post one `@codex review`
140
+ (`gh pr comment <PR> --body "@codex review"`) and record that request for this head. Then wait
141
+ with the same command plus `--wait 600`. Run the
118
142
  wait in the background where the host allows it (Claude Code: Bash `run_in_background`; you are
119
143
  re-invoked when it exits) so ten minutes of polling never sits in the conversation. Still `20`
120
- after the wait: say so out loud, post `@codex review` once more, and wait once more. Still `20` after that: stop and
121
- report the timeout honestly; never claim success.
144
+ after the wait: stop and report the timeout and the request already posted. A repeat mention
145
+ can start another billable review; do not retry it automatically or claim success.
122
146
  - Exit `0` (`clean`): go to the exit check. A `--wait` call returns `clean` only after a settle
123
147
  re-read 60 seconds later, so a comment landing right behind the review is still caught. A bare
124
148
  read (no `--wait`) that says `clean` is good enough only when you have not pushed since Codex's
@@ -45,7 +45,7 @@ metadata:
45
45
  - multi-agent
46
46
  - workflow
47
47
  - quality
48
- argument-hint: "<github-pr-url | repo pr-number | repo pr-title | branch [ref]> [scan|medium|deep] [--post] [--fix] [--base <ref>]"
48
+ argument-hint: "<github-pr-url | repo pr-number | repo pr-title | branch [ref]> [scan|medium|deep|deps] [--post] [--fix] [--base <ref>]"
49
49
  ---
50
50
 
51
51
  # Lekker Review
@@ -244,11 +244,17 @@ Then:
244
244
  `LOCAL_BRANCH` is `main`, `master`, `develop`, `staging`, or `production`, stop
245
245
  and say so.
246
246
 
247
- **Depth:** explicit keyword `scan`, `medium`, or `deep` wins. If absent, get
248
- the diff stat - in `pr` mode from
249
- `gh pr view <PR_NUMBER> --repo <REPO_SLUG> --json additions,deletions,changedFiles`,
250
- in `branch` mode from `git diff --shortstat <MERGE_BASE> HEAD` plus
251
- `git diff --name-only <MERGE_BASE> HEAD | wc -l` - and apply AUTO-DEPTH:
247
+ **Depth:** explicit keyword `scan`, `medium`, `deep` or `deps` wins. If absent,
248
+ get the per-file stat - in `pr` mode from
249
+ `gh pr view <PR_NUMBER> --repo <REPO_SLUG> --json additions,deletions,changedFiles,files,baseRefName,state,mergeCommit`
250
+ (keep `baseRefName` as `BASE_BRANCH` and `changedFiles` as `EXPECTED_FILES` for
251
+ Track A; when `state` is `MERGED`, keep `mergeCommit.oid` as `MERGE_COMMIT`), in `branch` mode from `git diff --numstat <MERGE_BASE> HEAD` - and
252
+ apply AUTO-DEPTH. Lockfiles (`package-lock.json`, `npm-shrinkwrap.json`,
253
+ `yarn.lock`, `pnpm-lock.yaml`, `bun.lock`, `bun.lockb`) do NOT count toward
254
+ additions+deletions: a regenerated lockfile is thousands of lines nobody reads.
255
+ - `deps` (candidate) if every changed file is a lockfile or a `package.json`.
256
+ Confirmed after Track A by `scripts/deps-only.mjs` (see "Confirm deps depth");
257
+ until then run Track B as for `scan`.
252
258
  - `scan` if additions+deletions < 150 AND changedFiles <= 5
253
259
  - `deep` if additions+deletions > 800 OR changedFiles > 25 OR diff touches
254
260
  `migrations/` or `*.sql`
@@ -271,7 +277,8 @@ still needs explicit confirmation (Step 4).
271
277
 
272
278
  **`--base <ref>` flag (branch mode only):** overrides base-ref detection. Passed
273
279
  through to the scripts as `LEKKER_BASE_REF`. Ignored in `pr` mode, where the
274
- base comes from the PR.
280
+ base comes from the PR: Track A passes `LEKKER_BASE_REF=origin/<BASE_BRANCH>`
281
+ itself, so the script fetches the base and diffs against its current tip.
275
282
 
276
283
  **`--no-fix` flag:** parse and store as `FIX_MODE=false`, and do not offer fixes
277
284
  in Step 4. Use it for a read-only pre-push look.
@@ -279,13 +286,16 @@ in Step 4. Use it for a read-only pre-push look.
279
286
  **`--no-artifact` flag:** parse and store as `ARTIFACT=false` (default true).
280
287
  Skips Step 3.5 (living review artifact) silently.
281
288
 
289
+ **`--no-fun` flag:** parse and store as `FUN=false` (default true). Skips the
290
+ closer (Step 3) everywhere: terminal, saved file, artifact, GitHub body.
291
+
282
292
  **`--engine revmux|workflow|codex` flag:** parse and store as `ENGINE`. Default
283
293
  to `workflow` for `HOST=claude` and `codex` for `HOST=codex`. Reject an explicit
284
294
  engine that does not exist on the current host (`workflow` requires Claude's
285
295
  Workflow tool; `codex` requires Codex native collaboration). `revmux` is
286
296
  allowed only at depth `medium` or `deep` - revmux's
287
- scripts reject `scan` (see Depth gate). If depth resolves to `scan` (explicit
288
- or auto), force `ENGINE` back to the current host's native engine regardless of
297
+ scripts reject `scan` (see Depth gate). If depth resolves to `scan` or `deps`
298
+ (explicit or auto), force `ENGINE` back to the current host's native engine regardless of
289
299
  the flag and note `engine forced to <workflow|codex> - revmux needs
290
300
  medium/deep` in the review header.
291
301
 
@@ -306,19 +316,19 @@ page for this PR.
306
316
 
307
317
  ## Depth gate
308
318
 
309
- | Step | scan | medium | deep |
310
- |-----------------------------|-----------------------|---------------------|----------------------------|
311
- | Context: issue-tracker/CI/diff/existing-reviews | always | always | always |
312
- | Context: chat/docs/framework-docs/monitoring/prior-review-memory (optional, MCP-dependent) | skip | included | included + broader recall |
313
- | Worktree + static checks | skip (WORKTREE_PATH=null) unless `--fix` | included | included |
314
- | Review agents | 2 triage (haiku) | 5 specialists (sonnet) | 5 specialists (sonnet) |
315
- | Per-finding verification | Criticals + Importants | Criticals + Importants | Criticals + Importants |
316
- | Completeness critic | skip | skip | included |
317
- | Proof-of-bug (failing test per Critical or composed-boundary Important) | skip | included (max 5) | included (max 5) |
318
- | Living review artifact | included | included | included |
319
- | Housekeeping (optional memory/notes writeback) | skip | included | included |
320
- | `--post` | supported | supported | supported |
321
- | `--fix` / fix offer | supported (forces worktree) | supported | supported |
319
+ | Step | 📦 deps | scan | medium | deep |
320
+ |-----------------------------|-----------------------|-----------------------|---------------------|----------------------------|
321
+ | Context: issue-tracker/CI/diff/existing-reviews | always | always | always | always |
322
+ | Context: chat/docs/framework-docs/monitoring/prior-review-memory (optional, MCP-dependent) | skip | skip | included | included + broader recall |
323
+ | Worktree + static checks | included (`npm ci` per changed lockfile) | skip (WORKTREE_PATH=null) unless `--fix` | included | included |
324
+ | Review agents | 1 deps checklist | 2 triage (haiku) | 5 specialists (sonnet) | 5 specialists (sonnet) |
325
+ | Per-finding verification | none | Criticals + Importants | Criticals + Importants | Criticals + Importants |
326
+ | Completeness critic | skip | skip | skip | included |
327
+ | Proof-of-bug (failing test per Critical or composed-boundary Important) | skip | skip | included (max 5) | included (max 5) |
328
+ | Living review artifact | included | included | included | included |
329
+ | Housekeeping (optional memory/notes writeback) | skip | skip | included | included |
330
+ | `--post` | supported | supported | supported | supported |
331
+ | `--fix` / fix offer | supported | supported (forces worktree) | supported | supported |
322
332
 
323
333
  For scan: note `⚡ scan - worktree unavailable, static checks skipped` in the
324
334
  review header. When `--fix` forced the worktree at scan depth, drop that note
@@ -347,7 +357,19 @@ Fire both tracks in the same turn.
347
357
  Run via Bash with `run_in_background`:
348
358
 
349
359
  ```bash
350
- # MODE=pr - checks out origin/<PR_BRANCH>, fetching if needed
360
+ # MODE=pr - fetches origin/<PR_BRANCH> AND origin/<BASE_BRANCH>, then checks out
361
+ # the PR branch. Without the base fetch the merge-base is whatever this clone
362
+ # last saw, and the file list widens (65 files instead of 9 on one PR).
363
+ # LEKKER_EXPECTED_FILES lets the script report a list that still disagrees.
364
+ LEKKER_BASE_REF=origin/<BASE_BRANCH> LEKKER_EXPECTED_FILES=<EXPECTED_FILES> \
365
+ ${SKILL_ROOT}/scripts/setup-worktree.sh \
366
+ <REPO_SLUG> <PR_BRANCH> <scratchpad>/worktree.json [PREV_SHA]
367
+
368
+ # MODE=pr, PR already MERGED - the head is inside the base branch now, so
369
+ # merge-base(head, origin/<BASE_BRANCH>) is the head and the diff is empty.
370
+ # Diff against the base as it was just before the merge instead.
371
+ LEKKER_BASE_BRANCH=<BASE_BRANCH> LEKKER_BASE_REF=<MERGE_COMMIT>^1 \
372
+ LEKKER_EXPECTED_FILES=<EXPECTED_FILES> \
351
373
  ${SKILL_ROOT}/scripts/setup-worktree.sh \
352
374
  <REPO_SLUG> <PR_BRANCH> <scratchpad>/worktree.json [PREV_SHA]
353
375
  ```
@@ -365,7 +387,32 @@ ${SKILL_ROOT}/scripts/setup-worktree.sh \
365
387
  On completion, read `worktree.json`. Keys emitted:
366
388
  `worktreePath`, `repoRoot`, `headSha`, `headShaShort`, `tscTail`,
367
389
  `tscChangedTail`, `tscErrorCount`, `eslintTail`, `eslintScope`, `changedFiles`,
368
- `baseRef`, `mergeBase`, `projectRules`, `deltaFile`, `notes`.
390
+ `baseRef`, `mergeBase`, `projectRules`, `deltaFile`, `notes`, `depsInstall`.
391
+
392
+ `notes` containing `changed-files-mismatch:<got>-vs-<expected>` means the
393
+ merge-base still disagrees with the PR. Use the `files` list from `gh pr view`
394
+ as the changed-file list for the review header and agents, and say so in the
395
+ header; the static-check scoping is the script's best effort.
396
+
397
+ `depsInstall` is non-empty when the diff changed a lockfile: one row per
398
+ lockfile dir, `{dir, status: ok|failed|timeout, tail?}`. The script ran
399
+ `npm ci --ignore-scripts` there instead of symlinking the repo's
400
+ `node_modules`, which holds the pre-PR dependency tree. A row that is not `ok`
401
+ is evidence for the review (a lockfile `npm ci` rejects fails the deploy too),
402
+ not a reason to stop. Set `LEKKER_NO_INSTALL=1` to skip the install. Lockfile
403
+ dirs using yarn, pnpm or bun are not installed (note `deps-install-unsupported`).
404
+
405
+ **Confirm deps depth** (only when Step 0 picked the `deps` candidate):
406
+
407
+ ```bash
408
+ node ${SKILL_ROOT}/scripts/deps-only.mjs \
409
+ <worktreePath> <mergeBase> <changedFiles...> > <scratchpad>/deps-report.json
410
+ ```
411
+
412
+ `kind: "deps"` confirms it; pass the report as `depsReport` in CONTEXT_FILE.
413
+ `kind: "mixed"` (a `scripts`, `name` or other non-dependency key changed, or a
414
+ `package.json` was added) means re-apply AUTO-DEPTH without the `deps` rule, and
415
+ fetch the Track B sources the new depth includes before Step 2.
369
416
 
370
417
  `mergeBase` is the commit the file list was scoped against. Branch mode
371
418
  generates its diff from that exact sha (below), so the diff the agents read and
@@ -465,7 +512,10 @@ Write `<scratchpad>/context.json` with keys:
465
512
  "deltaFile": "<worktree.json deltaFile, or null>",
466
513
  "houseRulesFile": "${SKILL_ROOT}/references/house-rules.md",
467
514
  "reviewTarget": "<TARGET_LABEL, e.g. 'PR #412' or 'branch feat/offline-orders'>",
468
- "prePush": "<true in MODE=branch, false in MODE=pr>"
515
+ "prePush": "<true in MODE=branch, false in MODE=pr>",
516
+ "depsReport": "<deps-report.json contents at depth deps, else null>",
517
+ "depsInstall": "<worktree.json depsInstall>",
518
+ "prBody": "<PR body at depth deps, else omit>"
469
519
  }
470
520
  ```
471
521
 
@@ -535,7 +585,7 @@ that only when a specific run needs a smaller footprint.
535
585
 
536
586
  The workflow runs three phases:
537
587
 
538
- - **Review:** scan uses `[triage-quality, triage-logic]` on `haiku`; medium/deep
588
+ - **Review:** deps uses the single `deps` checklist agent; scan uses `[triage-quality, triage-logic]` on `haiku`; medium/deep
539
589
  use 5 specialists (quality, implementation, simplification, conventions,
540
590
  test-quality) on `sonnet`. Agents receive DIFF_FILE + CONTEXT_FILE by path.
541
591
  All five run concurrently: the stage is self-limiting at one agent per
@@ -548,8 +598,9 @@ The workflow runs three phases:
548
598
  description/badCode/fix of the set - a Critical is never demoted by an
549
599
  Observation someone else filed at the same line - and records every
550
600
  contributing dimension in `agreedBy`.
551
- - **Verify:** every Critical and Important is checked at every depth because it
552
- can affect the verdict. Hard-rule findings (`rule` set) use the verifier's
601
+ - **Verify:** every Critical and Important is checked at scan, medium and deep because it
602
+ can affect the verdict. The `deps` depth verifies nothing: its findings are advisory
603
+ checklist facts (audit delta, install result) with nothing for a verifier to refute. Hard-rule findings (`rule` set) use the verifier's
553
604
  diff-anchor and rule-applicability checks instead of runtime challenges.
554
605
  Each verifier runs the five-challenge adversarial refutation from
555
606
  `references/agents/verifier.md` against one finding, returns
@@ -724,6 +775,37 @@ codebase. Never on taste alone. These land in their own section, not in
724
775
  Critical/Important. A finding without a cited precedent from the codebase is
725
776
  dropped.
726
777
 
778
+ **Validate line numbers first.** When there is a worktree, write the workflow's
779
+ `findings` to `<scratchpad>/findings.json` and run
780
+
781
+ ```bash
782
+ node ${SKILL_ROOT}/scripts/validate-lines.mjs \
783
+ <scratchpad>/findings.json <worktreePath>
784
+ ```
785
+
786
+ It checks each `line` against the file at HEAD using the finding's `badCode`:
787
+ kept when it is within 3 lines, re-anchored on a unique match
788
+ (`lineRemapped: true`), or set to `null` when the code is not in the file
789
+ (a `pr.diff` line number cited as a file line). Use the rewritten file from
790
+ here on. A `null` line is a PR-level finding: cite the file without a line, and
791
+ never post it as an inline comment. With no worktree (scan), skip this and do
792
+ not claim the lines were checked. Print the summary counts only when something
793
+ was remapped or nulled.
794
+
795
+ **Pick the closer** (skip when `FUN=false`): once the verdict is decided, run
796
+ the picker ONCE and keep its JSON as `CLOSER` for the rest of the run, so the
797
+ terminal, saved file, artifact and GitHub body all show the same joke:
798
+
799
+ ```bash
800
+ # verdict key: ✅ -> lgtm, ⚠️ -> lgtm-with-changes, 🚫 -> needs-work
801
+ node ${SKILL_ROOT}/scripts/pick-closer.mjs --verdict <key>
802
+ ```
803
+
804
+ Empty output means no closer (pool missing or broken): leave `CLOSER` empty and
805
+ carry on. Never invent an xkcd number or GIF URL in its place; the pool in
806
+ `references/fun.json` is URL-verified, a guessed link is not. Unattended runs
807
+ include it too.
808
+
727
809
  **Format** the review per `references/output-format.md` (read it now). Key
728
810
  requirements:
729
811
 
@@ -798,12 +880,21 @@ that is about to be pushed, and a marker for a superseded sha would be a lie.
798
880
 
799
881
  Then print the full review as the response.
800
882
 
883
+ **Closer goes last.** The run's FINAL message (this one, or the later summary
884
+ after Step 4 / 4.6 / 5 when those run) ends with `CLOSER.md_terminal` as its
885
+ last line. Print it once per run, on whichever message is last, not on every
886
+ step. Pass `CLOSER` to the Step 3.5 artifact agent and to the Step 5 GitHub
887
+ post.
888
+
801
889
  ---
802
890
 
803
891
  ## Step 3.5 - Living review artifact (skip when ARTIFACT=false)
804
892
 
805
893
  Immediately after printing the review, follow `references/artifact-page.md`.
806
- Claude publishes through Artifact. Codex uses a publish-capable artifact tool
894
+ On Claude, the renderer subagent only writes the HTML and returns its path; the
895
+ main loop fetches the closer image into a base64 `data:` URI file
896
+ (`CLOSER_DATAURI_FILE`), reads the HTML, checks its `<title>` and that it has no
897
+ external `<img>`, and publishes it through Artifact. Codex uses a publish-capable artifact tool
807
898
  when one is already available; otherwise it writes or updates the stable local
808
899
  self-contained HTML path defined there. The page is the living version of the
809
900
  review: verdict header, since-last-review timeline, findings with proof panels.
@@ -976,6 +1067,7 @@ Follow `references/github-post.md`:
976
1067
  - Verify post-condition: fetch review list, confirm PENDING state exists.
977
1068
  - Print count + link.
978
1069
  - Observation and Idiomatic findings go in the review body, never inline.
1070
+ - When `CLOSER` is set, its `md_github` is the last thing in the review body.
979
1071
  - Never submit the review programmatically.
980
1072
  - When fix mode applied and committed a finding, EXCLUDE it from the inline
981
1073
  comments - do not ask for a change you already made. Mention the applied
@@ -0,0 +1,54 @@
1
+ # deps - lekker-review agent prompt
2
+ You will receive in your task message: REPO_SLUG, PR_NUMBER, PR_URL, DIFF_FILE, CONTEXT_FILE (JSON), WORKTREE_PATH.
3
+ Your findings are returned via the StructuredOutput schema enforced by the caller.
4
+
5
+ This PR changes only lockfiles and the dependency keys of `package.json`
6
+ (`depsReport` in CONTEXT_FILE says which keys, per file). You are the ONLY
7
+ reviewer, so cover the whole checklist. Skip lockfile churn line by line: a
8
+ regenerated lockfile is not reviewable by eye, and the install and audit below
9
+ are the evidence for it.
10
+
11
+ Inputs from CONTEXT_FILE:
12
+ - `depsReport`: `{ packageJsons: [{ file, depKeysChanged }], lockDirs }`.
13
+ - `depsInstall`: per lockfile dir, `{ dir, status: ok|failed|timeout, tail? }`
14
+ from `npm ci --ignore-scripts` in the worktree. Empty means none ran.
15
+ - `prBody`, `ciStatus`, `existingReviews` (skip anything already raised).
16
+
17
+ Checklist, in order:
18
+
19
+ 1. **Reason per change.** Every added or raised version, and every new
20
+ `overrides`/`resolutions` entry, has a stated reason: an advisory id
21
+ (GHSA/CVE), a Dependabot alert, or a line in the PR body. No reason ->
22
+ `observation`.
23
+ 2. **Overrides that force a major.** For each override, read the dependant's
24
+ own declared range (`WORKTREE_PATH/<dir>/node_modules/<dependant>/package.json`
25
+ or `npm ls <pkg>` in that dir). An override pinning a major the dependant does
26
+ not declare -> `observation` asking for a removal ticket, naming the
27
+ condition that lets it go (dependant upgrade).
28
+ 3. **Runtime compatibility.** A new major that drops a Node version: compare
29
+ with `engines.node` and with the runtime image (`Dockerfile` `FROM`, CI
30
+ `node-version`). An actual mismatch -> `important`.
31
+ 4. **Install.** Any `depsInstall` row not `ok` -> `important`, quoting the tail.
32
+ A lockfile that `npm ci` rejects will fail the deploy too.
33
+ 5. **Audit delta.** In each `lockDirs` dir run
34
+ `npm audit --omit=dev --json` in WORKTREE_PATH (head), and compare with the
35
+ advisories the PR body says it fixes. A high/critical advisory still present
36
+ that the PR claims to fix -> `important`. One introduced by the bump ->
37
+ `important`. Pre-existing ones with no fix -> one `observation`, not one per
38
+ advisory. If `npm audit` cannot run (no network), say so in that observation;
39
+ never report it as clean.
40
+ Read the whole `prBody` first: when it already names the residual advisories
41
+ or says the audit check stays red, say that in the observation and ask for
42
+ nothing; never request a note the author already wrote.
43
+ 6. **Runtime vs dev.** Note which bumps reach production (`dependencies`) and
44
+ which are dev-only; a runtime major bump with no test or changelog note in
45
+ the PR body -> `observation`.
46
+
47
+ Rules:
48
+ - `file` + `line`: anchor on the `package.json` line of the dependency or
49
+ override (1-based line in the file at HEAD), never on a lockfile line.
50
+ - `badCode`: that `package.json` line verbatim. `fix`: the concrete change or
51
+ the ticket to open.
52
+ - No Critical findings: a dependency bump that breaks something shows up as a
53
+ failed install, a failed check or an advisory, which are `important`.
54
+ - Do not re-review lockfile integrity hashes or resolved URLs.