@olegkoval/agent-skills 1.49.2 โ 1.51.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/.github/copilot-instructions.md +1 -0
- package/.github/prompts/coderabbitloop.prompt.md +90 -15
- package/.github/prompts/codexloop.prompt.md +33 -6
- package/.github/prompts/copilotloop.prompt.md +302 -0
- package/.github/prompts/geminiloop.prompt.md +34 -6
- package/.github/prompts/qodoloop.prompt.md +18 -0
- package/.kiro/steering/coderabbitloop.md +90 -15
- package/.kiro/steering/codexloop.md +33 -6
- package/.kiro/steering/copilotloop.md +301 -0
- package/.kiro/steering/geminiloop.md +34 -6
- package/.kiro/steering/qodoloop.md +18 -0
- package/.windsurf/rules/coderabbitloop.md +90 -15
- package/.windsurf/rules/codexloop.md +33 -6
- package/.windsurf/rules/copilotloop.md +300 -0
- package/.windsurf/rules/geminiloop.md +34 -6
- package/.windsurf/rules/qodoloop.md +18 -0
- package/README.md +1 -0
- package/adapters/claude/olko-github-pr/skills/coderabbitloop/SKILL.md +91 -16
- package/adapters/claude/olko-github-pr/skills/coderabbitloop/references/graphql-queries.md +41 -9
- package/adapters/claude/olko-github-pr/skills/codexloop/SKILL.md +35 -8
- package/adapters/claude/olko-github-pr/skills/copilotloop/SKILL.md +309 -0
- package/adapters/claude/olko-github-pr/skills/geminiloop/SKILL.md +36 -8
- package/adapters/claude/olko-github-pr/skills/lekker-review/SKILL.md +26 -1
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/agents/completeness-critic.md +12 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/agents/implementation.md +26 -1
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/agents/prover.md +8 -1
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/agents/test-quality.md +20 -2
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/agents/verifier.md +25 -0
- package/adapters/claude/olko-github-pr/skills/lekker-review/references/fix-mode.md +23 -0
- package/adapters/claude/olko-github-pr/skills/qodoloop/SKILL.md +19 -1
- package/adapters/claude/olko-github-pr/skills/qodoloop/references/graphql-queries.md +19 -2
- package/adapters/codex/olko-github-pr/README.md +1 -0
- package/adapters/cursor/olko-github-pr/skills/coderabbitloop/SKILL.md +91 -16
- package/adapters/cursor/olko-github-pr/skills/coderabbitloop/references/graphql-queries.md +41 -9
- package/adapters/cursor/olko-github-pr/skills/codexloop/SKILL.md +35 -8
- package/adapters/cursor/olko-github-pr/skills/copilotloop/SKILL.md +309 -0
- package/adapters/cursor/olko-github-pr/skills/geminiloop/SKILL.md +36 -8
- package/adapters/cursor/olko-github-pr/skills/qodoloop/SKILL.md +19 -1
- package/adapters/cursor/olko-github-pr/skills/qodoloop/references/graphql-queries.md +19 -2
- package/adapters/grok/olko-github-pr/skills/coderabbitloop/SKILL.md +91 -16
- package/adapters/grok/olko-github-pr/skills/coderabbitloop/references/graphql-queries.md +41 -9
- package/adapters/grok/olko-github-pr/skills/codexloop/SKILL.md +35 -8
- package/adapters/grok/olko-github-pr/skills/copilotloop/SKILL.md +309 -0
- package/adapters/grok/olko-github-pr/skills/geminiloop/SKILL.md +36 -8
- package/adapters/grok/olko-github-pr/skills/qodoloop/SKILL.md +19 -1
- package/adapters/grok/olko-github-pr/skills/qodoloop/references/graphql-queries.md +19 -2
- package/catalog/skills.json +23 -0
- 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/coderabbitloop/SKILL.md +91 -16
- package/plugins/olko-github-pr/skills/coderabbitloop/references/graphql-queries.md +41 -9
- package/plugins/olko-github-pr/skills/codexloop/SKILL.md +35 -8
- package/plugins/olko-github-pr/skills/copilotloop/SKILL.md +308 -0
- package/plugins/olko-github-pr/skills/geminiloop/SKILL.md +36 -8
- package/plugins/olko-github-pr/skills/lekker-review/SKILL.md +26 -1
- package/plugins/olko-github-pr/skills/lekker-review/references/agents/completeness-critic.md +12 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/agents/implementation.md +26 -1
- package/plugins/olko-github-pr/skills/lekker-review/references/agents/prover.md +8 -1
- package/plugins/olko-github-pr/skills/lekker-review/references/agents/test-quality.md +20 -2
- package/plugins/olko-github-pr/skills/lekker-review/references/agents/verifier.md +25 -0
- package/plugins/olko-github-pr/skills/lekker-review/references/fix-mode.md +23 -0
- package/plugins/olko-github-pr/skills/lekker-review/workflow.js +87 -5
- package/plugins/olko-github-pr/skills/qodoloop/SKILL.md +19 -1
- package/plugins/olko-github-pr/skills/qodoloop/references/graphql-queries.md +19 -2
- 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
- package/scripts/lib/catalog.mjs +1 -1
|
@@ -8,11 +8,30 @@ export const meta = {
|
|
|
8
8
|
// Schemas
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
10
10
|
|
|
11
|
+
const BOUNDARY_SCHEMA = {
|
|
12
|
+
type: 'object',
|
|
13
|
+
required: ['entryPoint', 'consumer'],
|
|
14
|
+
properties: {
|
|
15
|
+
entryPoint: { type: 'string', minLength: 1, pattern: '\\S' },
|
|
16
|
+
decisionPoint: { type: 'string' },
|
|
17
|
+
realizationPoint: { type: 'string' },
|
|
18
|
+
consumer: { type: 'string', minLength: 1, pattern: '\\S' },
|
|
19
|
+
stateOwner: { type: 'string' },
|
|
20
|
+
evidenceClass: { type: 'string' },
|
|
21
|
+
identityDimensions: { type: 'array', items: { type: 'string' } },
|
|
22
|
+
transitions: { type: 'array', items: { type: 'string' } },
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
|
|
11
26
|
const FINDINGS_ARRAY_SCHEMA = {
|
|
12
27
|
type: 'array',
|
|
13
28
|
items: {
|
|
14
29
|
type: 'object',
|
|
15
30
|
required: ['file', 'line', 'severity', 'title', 'description', 'badCode', 'fix'],
|
|
31
|
+
anyOf: [
|
|
32
|
+
{ properties: { severity: { enum: ['observation', 'idiomatic'] } } },
|
|
33
|
+
{ required: ['boundary'] },
|
|
34
|
+
],
|
|
16
35
|
properties: {
|
|
17
36
|
file: { type: 'string' },
|
|
18
37
|
line: { type: 'integer' },
|
|
@@ -23,6 +42,7 @@ const FINDINGS_ARRAY_SCHEMA = {
|
|
|
23
42
|
fix: { type: 'string' },
|
|
24
43
|
precedent: { type: 'string' },
|
|
25
44
|
rule: { type: 'string', minLength: 1, pattern: '\\S' },
|
|
45
|
+
boundary: BOUNDARY_SCHEMA,
|
|
26
46
|
},
|
|
27
47
|
},
|
|
28
48
|
}
|
|
@@ -267,6 +287,41 @@ function shouldVerify(finding) {
|
|
|
267
287
|
return finding.severity === 'critical' || finding.severity === 'important'
|
|
268
288
|
}
|
|
269
289
|
|
|
290
|
+
/**
|
|
291
|
+
* Does the finding carry enough of a composed boundary map to attempt a
|
|
292
|
+
* proof? Requires an entry point and a consumer, plus at least one of a
|
|
293
|
+
* realization point, state owner, or recorded transition.
|
|
294
|
+
*/
|
|
295
|
+
function hasBoundaryProofSurface(finding) {
|
|
296
|
+
const boundary = finding && finding.boundary
|
|
297
|
+
if (!boundary || typeof boundary !== 'object') {
|
|
298
|
+
return false
|
|
299
|
+
}
|
|
300
|
+
const hasText = function(value) {
|
|
301
|
+
return typeof value === 'string' && value.trim().length > 0
|
|
302
|
+
}
|
|
303
|
+
const hasList = function(value) {
|
|
304
|
+
return Array.isArray(value) && value.length > 0
|
|
305
|
+
}
|
|
306
|
+
return hasText(boundary.entryPoint)
|
|
307
|
+
&& hasText(boundary.consumer)
|
|
308
|
+
&& (
|
|
309
|
+
hasText(boundary.realizationPoint)
|
|
310
|
+
|| hasText(boundary.stateOwner)
|
|
311
|
+
|| hasList(boundary.transitions)
|
|
312
|
+
)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Does this finding qualify for the Prove stage? Every Critical finding
|
|
317
|
+
* qualifies; an Important finding only qualifies when it has a composed
|
|
318
|
+
* boundary map to prove against.
|
|
319
|
+
*/
|
|
320
|
+
function shouldProve(finding) {
|
|
321
|
+
return finding.severity === 'critical'
|
|
322
|
+
|| (finding.severity === 'important' && hasBoundaryProofSurface(finding))
|
|
323
|
+
}
|
|
324
|
+
|
|
270
325
|
function normalizeProof(result) {
|
|
271
326
|
const hasText = function(value) {
|
|
272
327
|
return typeof value === 'string' && value.trim().length > 0
|
|
@@ -520,7 +575,29 @@ const budgetAtStart = budget.spent()
|
|
|
520
575
|
// rule-specific checks and skip only its runtime-oriented challenges.
|
|
521
576
|
// -------------------------------------------------------------------------
|
|
522
577
|
|
|
578
|
+
// A model verdict cannot replace the required production boundary map.
|
|
579
|
+
function enforceBoundary(finding) {
|
|
580
|
+
if (!shouldVerify(finding)) return finding
|
|
581
|
+
const boundary = finding.boundary
|
|
582
|
+
const hasText = function(value) {
|
|
583
|
+
return typeof value === 'string' && value.trim().length > 0
|
|
584
|
+
}
|
|
585
|
+
if (boundary && typeof boundary === 'object' && !Array.isArray(boundary)
|
|
586
|
+
&& hasText(boundary.entryPoint) && hasText(boundary.consumer)) {
|
|
587
|
+
return finding
|
|
588
|
+
}
|
|
589
|
+
downgradedCount++
|
|
590
|
+
const unverified = Object.assign({}, finding, {
|
|
591
|
+
severity: 'observation',
|
|
592
|
+
verificationStatus: 'unverified',
|
|
593
|
+
verifierReasoning: 'Missing boundary object or identified production entry point/downstream consumer; downgraded to non-blocking',
|
|
594
|
+
})
|
|
595
|
+
delete unverified.proof
|
|
596
|
+
return unverified
|
|
597
|
+
}
|
|
598
|
+
|
|
523
599
|
async function verifyAll(findings) {
|
|
600
|
+
findings = findings.map(enforceBoundary)
|
|
524
601
|
const inScope = findings.filter(function(f) {
|
|
525
602
|
return shouldVerify(f)
|
|
526
603
|
})
|
|
@@ -704,7 +781,8 @@ const budgetAtStart = budget.spent()
|
|
|
704
781
|
}
|
|
705
782
|
|
|
706
783
|
// Verify the new finding through the same verifier path
|
|
707
|
-
const newFinding = Object.assign({}, reResult.findings[0])
|
|
784
|
+
const newFinding = enforceBoundary(Object.assign({}, reResult.findings[0]))
|
|
785
|
+
if (newFinding.verificationStatus === 'unverified') return [newFinding]
|
|
708
786
|
newFinding._dimension = `critic:${angle.axis}`
|
|
709
787
|
|
|
710
788
|
agentCount++
|
|
@@ -749,9 +827,13 @@ const budgetAtStart = budget.spent()
|
|
|
749
827
|
|
|
750
828
|
} // end ENGINE === 'workflow' branch
|
|
751
829
|
|
|
830
|
+
// Recheck after critic dedup and imported results, before proof promotion.
|
|
831
|
+
finalFindings = finalFindings.map(enforceBoundary)
|
|
832
|
+
|
|
752
833
|
// -------------------------------------------------------------------------
|
|
753
|
-
// Prove: for each Critical finding
|
|
754
|
-
//
|
|
834
|
+
// Prove: for each Critical finding and each Important finding with a
|
|
835
|
+
// composed boundary map (excluding hard rules, which are policy violations
|
|
836
|
+
// with no runtime failure to demonstrate), attempt to produce an
|
|
755
837
|
// executable failing test in the worktree. Only runs with a worktree and
|
|
756
838
|
// outside scan depth, and is capped so a pathological finding count can't
|
|
757
839
|
// blow the budget.
|
|
@@ -770,7 +852,7 @@ const budgetAtStart = budget.spent()
|
|
|
770
852
|
|
|
771
853
|
if (worktreePath && depth !== 'scan') {
|
|
772
854
|
const proveCandidates = finalFindings.filter(function(f) {
|
|
773
|
-
return f
|
|
855
|
+
return shouldProve(f) && !isHardRule(f)
|
|
774
856
|
})
|
|
775
857
|
|
|
776
858
|
if (proveCandidates.length > 0) {
|
|
@@ -779,7 +861,7 @@ const budgetAtStart = budget.spent()
|
|
|
779
861
|
const capped = proveCandidates.slice(0, 5)
|
|
780
862
|
const skipped = proveCandidates.length - capped.length
|
|
781
863
|
if (skipped > 0) {
|
|
782
|
-
log(`Prove: capping at 5 provers, skipping ${skipped} additional
|
|
864
|
+
log(`Prove: capping at 5 provers, skipping ${skipped} additional finding(s)`)
|
|
783
865
|
}
|
|
784
866
|
|
|
785
867
|
await batched(capped.map(function(finding) {
|
|
@@ -8,7 +8,7 @@ description: >
|
|
|
8
8
|
addressed against Qodo's review, or says "run qodoloop" / "satisfy Qodo" / "resolve Qodo comments".
|
|
9
9
|
compatibility: Requires git and gh (GitHub CLI) authenticated, with Qodo Merge installed on the repo.
|
|
10
10
|
metadata:
|
|
11
|
-
version: "1.
|
|
11
|
+
version: "1.1"
|
|
12
12
|
allowed-tools: Bash(gh:*) Bash(git:*)
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -85,6 +85,14 @@ Run the paginated GraphQL query in `references/graphql-queries.md` (`unresolvedQ
|
|
|
85
85
|
|
|
86
86
|
Build the working set: all `recommended` threads, plus `optional` ones too if `--include-optional`.
|
|
87
87
|
|
|
88
|
+
Mark each thread as seen with an ๐ reaction on its first comment (`databaseId` from the query), so
|
|
89
|
+
the bot and a watching human can tell it is being worked. GitHub's reaction set is fixed; `eyes` is
|
|
90
|
+
the only "looking at it" value:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
gh api --method POST repos/{owner}/{repo}/pulls/comments/<DATABASE_ID>/reactions -f content=eyes
|
|
94
|
+
```
|
|
95
|
+
|
|
88
96
|
#### C. Check exit conditions
|
|
89
97
|
|
|
90
98
|
Stop if the working set is empty, or max iterations reached.
|
|
@@ -121,6 +129,16 @@ This is the "answer to the comments" half of the job, not optional cleanup, and
|
|
|
121
129
|
Pass the thread id and reply text as GraphQL **variables** (`-f threadId=... -f body=...`), never interpolated into the query string itself: a reply containing a quote, backtick, or newline breaks (or worse, injects into) a hand-built query. Then resolve with `resolveReviewThread` (see references file).
|
|
122
130
|
- **Blocked** findings: reply explaining exactly why (false positive / needs a human call), but **do not resolve**: leave the thread open. A blocked finding that gets silently resolved is a false "done".
|
|
123
131
|
|
|
132
|
+
Then record each disposition as a reaction on the thread's first comment: the learning signal, and
|
|
133
|
+
a visible marker for a human scanning the PR. ๐ (`+1`) for a fixed finding, ๐ (`-1`) for a
|
|
134
|
+
blocked/rebutted one. Reply first, react, then resolve: a reaction never replaces the reply.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
gh api --method POST repos/{owner}/{repo}/pulls/comments/<DATABASE_ID>/reactions -f content=+1
|
|
138
|
+
# blocked/rebutted finding:
|
|
139
|
+
gh api --method POST repos/{owner}/{repo}/pulls/comments/<DATABASE_ID>/reactions -f content=-1
|
|
140
|
+
```
|
|
141
|
+
|
|
124
142
|
Go back to step A.
|
|
125
143
|
|
|
126
144
|
### 3. Report
|
|
@@ -26,7 +26,7 @@ query($cursor: String) {
|
|
|
26
26
|
id
|
|
27
27
|
isResolved
|
|
28
28
|
comments(first: 1) {
|
|
29
|
-
nodes { body path line author { login } }
|
|
29
|
+
nodes { databaseId body path line author { login } }
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -60,7 +60,7 @@ while :; do
|
|
|
60
60
|
nodes {
|
|
61
61
|
id
|
|
62
62
|
isResolved
|
|
63
|
-
comments(first: 1) { nodes { body path line author { login } } }
|
|
63
|
+
comments(first: 1) { nodes { databaseId body path line author { login } } }
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -126,6 +126,23 @@ the branch (SKILL.md ยง2E-F): resolving first and pushing second means a
|
|
|
126
126
|
failed push leaves GitHub showing the finding as handled when it isn't. Never
|
|
127
127
|
resolve a blocked/skipped finding at all; reply to it and leave it open.
|
|
128
128
|
|
|
129
|
+
## React to a comment (the bot's learning signal)
|
|
130
|
+
|
|
131
|
+
Reacting needs the comment's REST id, which is why `databaseId` is selected in
|
|
132
|
+
the thread query above. The reaction set is fixed; only eight values exist:
|
|
133
|
+
`+1`, `-1`, `laugh`, `confused`, `heart`, `hooray`, `rocket`, `eyes`.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# ๐ as soon as you start working a finding
|
|
137
|
+
gh api --method POST repos/{owner}/{repo}/pulls/comments/<DATABASE_ID>/reactions -f content=eyes
|
|
138
|
+
# ๐ when it was accepted and fixed, ๐ when it was rebutted (the correction signal)
|
|
139
|
+
gh api --method POST repos/{owner}/{repo}/pulls/comments/<DATABASE_ID>/reactions -f content=+1
|
|
140
|
+
gh api --method POST repos/{owner}/{repo}/pulls/comments/<DATABASE_ID>/reactions -f content=-1
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
React after the reply and before the resolve, so GitHub records the reason and
|
|
144
|
+
the disposition together. A reaction never replaces the reply.
|
|
145
|
+
|
|
129
146
|
## Fetch the rollup issue comment (context only, not the source of truth)
|
|
130
147
|
|
|
131
148
|
Useful for the human-readable summary counts (bugs/rule-violations) in your
|
package/scripts/lib/catalog.mjs
CHANGED
|
@@ -6,7 +6,7 @@ export const PLUGIN_ASSIGNMENT = {
|
|
|
6
6
|
'olko-github-pr': {
|
|
7
7
|
description: 'Drive GitHub pull requests to merge-ready: review-bot loops, CI fixes, descriptions, dependency triage.',
|
|
8
8
|
skills: ['pr-finalize', 'pr-finalize-complete', 'pr-to-green', 'pr-description-writer',
|
|
9
|
-
'qodoloop', 'coderabbitloop', 'codexloop', 'geminiloop', 'ci-fix-loop',
|
|
9
|
+
'qodoloop', 'coderabbitloop', 'codexloop', 'copilotloop', 'geminiloop', 'ci-fix-loop',
|
|
10
10
|
'dependabot-triage', 'lekker-review'],
|
|
11
11
|
},
|
|
12
12
|
'olko-git-tools': {
|