@cobusgreyling/loop-init 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/cli.js +56 -2
- package/dist/contributor-cta.d.ts +2 -0
- package/dist/contributor-cta.js +6 -0
- package/package.json +1 -1
- package/starters/README.md +6 -0
- package/starters/changelog-drafter-opencode/AGENTS.md +15 -0
- package/starters/changelog-drafter-opencode/LOOP.md +26 -0
- package/starters/changelog-drafter-opencode/README.md +44 -0
- package/starters/changelog-drafter-opencode/changelog-drafter-state.md.example +10 -0
- package/starters/changelog-drafter-opencode/opencode.json.example +35 -0
- package/starters/changelog-drafter-opencode/skills/changelog-scan/SKILL.md +38 -0
- package/starters/ci-sweeper-opencode/AGENTS.md +17 -0
- package/starters/ci-sweeper-opencode/LOOP.md +26 -0
- package/starters/ci-sweeper-opencode/README.md +43 -0
- package/starters/ci-sweeper-opencode/ci-sweeper-state.md.example +10 -0
- package/starters/ci-sweeper-opencode/opencode.json.example +35 -0
- package/starters/ci-sweeper-opencode/skills/ci-triage/SKILL.md +32 -0
- package/starters/dependency-sweeper-opencode/AGENTS.md +15 -0
- package/starters/dependency-sweeper-opencode/LOOP.md +27 -0
- package/starters/dependency-sweeper-opencode/README.md +44 -0
- package/starters/dependency-sweeper-opencode/dependency-sweeper-state.md.example +11 -0
- package/starters/dependency-sweeper-opencode/opencode.json.example +35 -0
- package/starters/dependency-sweeper-opencode/skills/dependency-triage/SKILL.md +35 -0
- package/starters/issue-triage-opencode/AGENTS.md +16 -0
- package/starters/issue-triage-opencode/LOOP.md +21 -0
- package/starters/issue-triage-opencode/README.md +43 -0
- package/starters/issue-triage-opencode/issue-triage-state.md.example +11 -0
- package/starters/issue-triage-opencode/opencode.json.example +35 -0
- package/starters/issue-triage-opencode/skills/issue-triage/SKILL.md +33 -0
- package/starters/post-merge-cleanup-opencode/AGENTS.md +15 -0
- package/starters/post-merge-cleanup-opencode/LOOP.md +26 -0
- package/starters/post-merge-cleanup-opencode/README.md +44 -0
- package/starters/post-merge-cleanup-opencode/opencode.json.example +35 -0
- package/starters/post-merge-cleanup-opencode/post-merge-state.md.example +10 -0
- package/starters/post-merge-cleanup-opencode/skills/post-merge-scan/SKILL.md +34 -0
- package/starters/pr-babysitter-opencode/AGENTS.md +18 -0
- package/starters/pr-babysitter-opencode/LOOP.md +27 -0
- package/starters/pr-babysitter-opencode/README.md +44 -0
- package/starters/pr-babysitter-opencode/opencode.json.example +35 -0
- package/starters/pr-babysitter-opencode/pr-babysitter-state.md.example +10 -0
- package/starters/pr-babysitter-opencode/skills/pr-review-triage/SKILL.md +33 -0
- package/templates/SKILL.md.loop-guard +94 -0
- package/templates/loop-constraints.md +1 -0
package/README.md
CHANGED
|
@@ -31,6 +31,13 @@ After scaffolding, always run `npx @cobusgreyling/loop-audit . --suggest` and ac
|
|
|
31
31
|
|
|
32
32
|
L2 patterns (`ci-sweeper`, `dependency-sweeper`) also copy `minimal-fix` and `loop-verifier` templates when missing from the starter.
|
|
33
33
|
|
|
34
|
+
Fix-capable patterns (`pr-babysitter`, `ci-sweeper`, `dependency-sweeper`, `post-merge-cleanup`) also get a **circuit breaker**:
|
|
35
|
+
|
|
36
|
+
- `loop-guard` skill — logs each attempt to `loop-ledger.json` and runs [`loop-context`](../loop-context) `--check` before retrying
|
|
37
|
+
- `loop-ledger.json` — seeded with the pattern's goal, its `pattern`/`level`, and an empty `attempts` array
|
|
38
|
+
|
|
39
|
+
The ledger's `pattern`/`level` let `loop-guard` size the breaker's `--token-budget` from [`loop-cost`](../loop-cost)'s realistic per-run estimate instead of a hand-typed number. The breaker escalates (same error N× in a row, too many consecutive failures, token budget, or iteration cap) instead of looping in vain. Report-only patterns skip it.
|
|
40
|
+
|
|
34
41
|
Every scaffold also creates:
|
|
35
42
|
|
|
36
43
|
- `loop-budget.md` — pattern-specific daily caps and kill switch
|
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import { spawn } from 'node:child_process';
|
|
|
3
3
|
import { cp, mkdir, readFile, writeFile, access } from 'node:fs/promises';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { printContributorCta } from './contributor-cta.js';
|
|
6
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
8
|
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
8
9
|
const MONOREPO_STARTERS = path.resolve(PACKAGE_ROOT, '../../starters');
|
|
@@ -142,6 +143,53 @@ async function copyL2Templates(pattern, tool, targetDir, templatesRoot, dryRun)
|
|
|
142
143
|
await copyTemplateVerifier(templatesRoot, targetDir, tool, dryRun);
|
|
143
144
|
}
|
|
144
145
|
}
|
|
146
|
+
/** Per-pattern goal seeded into loop-ledger.json for the circuit breaker. */
|
|
147
|
+
const LEDGER_GOAL = {
|
|
148
|
+
'daily-triage': 'Keep the repo healthy and STATE.md current',
|
|
149
|
+
'pr-babysitter': 'Get the watched PR review-ready and green',
|
|
150
|
+
'ci-sweeper': 'Get failing CI back to green',
|
|
151
|
+
'dependency-sweeper': 'Land safe dependency updates',
|
|
152
|
+
'post-merge-cleanup': 'Clean up regressions from recent merges',
|
|
153
|
+
'changelog-drafter': 'Draft accurate release notes',
|
|
154
|
+
'issue-triage': 'Triage the open issue queue',
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Readiness level seeded into loop-ledger.json so the loop-guard skill can
|
|
158
|
+
* resolve a realistic per-run token budget from `loop-cost --json` instead of a
|
|
159
|
+
* hand-typed number. Fix-capable loops draft changes with a verifier (a human
|
|
160
|
+
* still merges), so L2 is the right default; tune it in the ledger if a loop
|
|
161
|
+
* runs unattended (L3) or report-only (L1).
|
|
162
|
+
*/
|
|
163
|
+
const LEDGER_LEVEL = {
|
|
164
|
+
'daily-triage': 'L1',
|
|
165
|
+
'pr-babysitter': 'L2',
|
|
166
|
+
'ci-sweeper': 'L2',
|
|
167
|
+
'dependency-sweeper': 'L2',
|
|
168
|
+
'post-merge-cleanup': 'L2',
|
|
169
|
+
'changelog-drafter': 'L1',
|
|
170
|
+
'issue-triage': 'L1',
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Fix-capable loops retry actions, so they need a circuit breaker: scaffold the
|
|
174
|
+
* loop-guard skill plus a seeded loop-ledger.json wired to `loop-context`.
|
|
175
|
+
* Report-only patterns (daily-triage, issue-triage, changelog-drafter) don't
|
|
176
|
+
* retry fixes, so they skip this to keep the scaffold minimal.
|
|
177
|
+
*/
|
|
178
|
+
async function scaffoldCircuitBreaker(pattern, tool, targetDir, templatesRoot, dryRun) {
|
|
179
|
+
if (!PATTERNS_NEEDING_FIX.has(pattern))
|
|
180
|
+
return;
|
|
181
|
+
await copyTemplateSkill(templatesRoot, 'SKILL.md.loop-guard', targetDir, tool, 'loop-guard', dryRun);
|
|
182
|
+
const ledgerPath = path.join(targetDir, 'loop-ledger.json');
|
|
183
|
+
if (await exists(ledgerPath))
|
|
184
|
+
return;
|
|
185
|
+
const seed = `${JSON.stringify({ goal: LEDGER_GOAL[pattern], pattern, level: LEDGER_LEVEL[pattern], attempts: [] }, null, 2)}\n`;
|
|
186
|
+
if (dryRun) {
|
|
187
|
+
console.log(` would write: ${ledgerPath}`);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
await writeFile(ledgerPath, seed);
|
|
191
|
+
console.log(' created: loop-ledger.json (circuit breaker)');
|
|
192
|
+
}
|
|
145
193
|
function formatTokenCap(n) {
|
|
146
194
|
if (n >= 1_000_000)
|
|
147
195
|
return `${n / 1_000_000}M`;
|
|
@@ -361,7 +409,7 @@ Examples:
|
|
|
361
409
|
const targetDir = path.resolve(target);
|
|
362
410
|
const baseStarter = PATTERN_STARTERS[pattern];
|
|
363
411
|
const suffix = TOOL_SUFFIX[tool];
|
|
364
|
-
const starterName =
|
|
412
|
+
const starterName = `${baseStarter}${suffix}`;
|
|
365
413
|
const startersRoot = await resolveBundledOrMonorepo('starters');
|
|
366
414
|
const templatesRoot = await resolveBundledOrMonorepo('templates');
|
|
367
415
|
const starterRoot = path.join(startersRoot, starterName);
|
|
@@ -442,6 +490,7 @@ Examples:
|
|
|
442
490
|
await copyFile(loopMd, path.join(targetDir, 'LOOP.md'), dryRun);
|
|
443
491
|
}
|
|
444
492
|
await copyL2Templates(pattern, tool, targetDir, templatesRoot, dryRun);
|
|
493
|
+
await scaffoldCircuitBreaker(pattern, tool, targetDir, templatesRoot, dryRun);
|
|
445
494
|
await scaffoldObservability(pattern, tool, targetDir, templatesRoot, dryRun);
|
|
446
495
|
await scaffoldConstraints(targetDir, templatesRoot, tool, dryRun);
|
|
447
496
|
if (tool !== 'opencode' && !dryRun && !(await exists(path.join(targetDir, 'AGENTS.md')))) {
|
|
@@ -475,12 +524,17 @@ npm run lint
|
|
|
475
524
|
console.log(` npx @cobusgreyling/loop-audit ${auditArg} --suggest`);
|
|
476
525
|
}
|
|
477
526
|
}
|
|
527
|
+
if (PATTERNS_NEEDING_FIX.has(pattern)) {
|
|
528
|
+
console.log('');
|
|
529
|
+
console.log('Circuit breaker wired (loop-guard skill + loop-ledger.json):');
|
|
530
|
+
console.log(' npx @cobusgreyling/loop-context --check --ledger loop-ledger.json');
|
|
531
|
+
}
|
|
478
532
|
console.log('');
|
|
479
533
|
console.log(`First loop (${tool}):`);
|
|
480
534
|
console.log(` ${firstLoopCommand(pattern, tool)}`);
|
|
481
535
|
console.log('');
|
|
482
536
|
console.log(`Estimate cost: npx @cobusgreyling/loop-cost --pattern ${pattern} --level L1`);
|
|
483
|
-
|
|
537
|
+
printContributorCta();
|
|
484
538
|
}
|
|
485
539
|
async function readDirNames(dir) {
|
|
486
540
|
const { readdir } = await import('node:fs/promises');
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const CONTRIBUTOR_QUICKSTART_URL = 'https://github.com/cobusgreyling/loop-engineering/discussions/123';
|
|
2
|
+
export function printContributorCta() {
|
|
3
|
+
console.log('');
|
|
4
|
+
console.log('Contribute (~15 min tasks):');
|
|
5
|
+
console.log(` ${CONTRIBUTOR_QUICKSTART_URL}`);
|
|
6
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cobusgreyling/loop-init",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "Scaffold loop engineering patterns and starters into any project. Supports Grok, Claude Code, Codex, Opencode and more. npx @cobusgreyling/loop-init . --pattern daily-triage --tool opencode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/starters/README.md
CHANGED
|
@@ -21,11 +21,17 @@ npx @cobusgreyling/loop-init . -p pr-babysitter -t claude
|
|
|
21
21
|
| Starter | Pattern | Tools | Readiness |
|
|
22
22
|
|---------|---------|-------|-----------|
|
|
23
23
|
| [pr-babysitter](./pr-babysitter/) | PR Babysitter | Grok, Claude, Codex | L2 assisted |
|
|
24
|
+
| [pr-babysitter-opencode](./pr-babysitter-opencode/) | PR Babysitter | Opencode | L1 → L2 |
|
|
24
25
|
| [ci-sweeper](./ci-sweeper/) | CI Sweeper | Grok, Claude, Codex | L2 assisted |
|
|
26
|
+
| [ci-sweeper-opencode](./ci-sweeper-opencode/) | CI Sweeper | Opencode | L2 cautious |
|
|
25
27
|
| [dependency-sweeper](./dependency-sweeper/) | Dependency Sweeper | Grok, Claude, Codex | L2 patch-only |
|
|
28
|
+
| [dependency-sweeper-opencode](./dependency-sweeper-opencode/) | Dependency Sweeper | Opencode | L2 patch-only |
|
|
26
29
|
| [post-merge-cleanup](./post-merge-cleanup/) | Post-Merge Cleanup | Grok, Claude, Codex | L1 → L2 |
|
|
30
|
+
| [post-merge-cleanup-opencode](./post-merge-cleanup-opencode/) | Post-Merge Cleanup | Opencode | L1 → L2 |
|
|
27
31
|
| [changelog-drafter](./changelog-drafter/) | Changelog Drafter | Grok, Claude, Codex | L1 draft → L2 |
|
|
32
|
+
| [changelog-drafter-opencode](./changelog-drafter-opencode/) | Changelog Drafter | Opencode | L1 draft → L2 |
|
|
28
33
|
| [issue-triage](./issue-triage/) | Issue Triage | Grok, Claude, Codex | L1 propose-only |
|
|
34
|
+
| [issue-triage-opencode](./issue-triage-opencode/) | Issue Triage | Opencode | L1 propose-only |
|
|
29
35
|
|
|
30
36
|
After copying:
|
|
31
37
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# AGENTS.md — Changelog Drafter (Opencode)
|
|
2
|
+
|
|
3
|
+
## Loop Mode
|
|
4
|
+
- L1 report + draft for the first 1-2 weeks.
|
|
5
|
+
- Read `changelog-drafter-state.md` before every run.
|
|
6
|
+
- Human approves every draft before any publish or PR.
|
|
7
|
+
|
|
8
|
+
## Safety
|
|
9
|
+
- Never create tags, GitHub releases, or update CHANGELOG.md without explicit human approval.
|
|
10
|
+
- Breaking changes and security items must be surfaced explicitly.
|
|
11
|
+
- Draft PRs only when L2 is enabled — never auto-merge.
|
|
12
|
+
|
|
13
|
+
## Verification
|
|
14
|
+
- Verifier checks draft completeness: categories, date range, links.
|
|
15
|
+
- Record draft status and human feedback in state.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Loop Configuration — Changelog Drafter (Opencode)
|
|
2
|
+
|
|
3
|
+
## Active Loops
|
|
4
|
+
|
|
5
|
+
| Pattern | Cadence | Status | Command |
|
|
6
|
+
|---------|---------|--------|---------|
|
|
7
|
+
| Changelog Drafter | 1d or on release prep | L1 draft-only | `opencode run "Run changelog-scan"` via cron (after merges settle) |
|
|
8
|
+
|
|
9
|
+
## Human Gates
|
|
10
|
+
- Breaking changes always human review.
|
|
11
|
+
- Security notes / CVEs human must approve wording.
|
|
12
|
+
- No tags, no PRs, no publishes without explicit approval.
|
|
13
|
+
- First 3 releases: human approves full draft.
|
|
14
|
+
|
|
15
|
+
## Budget
|
|
16
|
+
- Max sub-agent spawns per run: 2 (scanner + drafter).
|
|
17
|
+
- Prefer running after merges settle (evening).
|
|
18
|
+
|
|
19
|
+
## Output Convention
|
|
20
|
+
- Draft: `RELEASE_NOTES_DRAFT.md` at repo root.
|
|
21
|
+
- State: `changelog-drafter-state.md`.
|
|
22
|
+
|
|
23
|
+
## Links
|
|
24
|
+
- Pattern: [changelog-drafter](../../patterns/changelog-drafter.md)
|
|
25
|
+
- Example: [examples/opencode/changelog-drafter.md](../../examples/opencode/changelog-drafter.md)
|
|
26
|
+
- Safety: [docs/safety.md](../../docs/safety.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog Drafter — Opencode Starter
|
|
2
|
+
|
|
3
|
+
Clone-and-run scaffold for the **Changelog Drafter** pattern with opencode. Scan merged PRs and commits, produce categorized release notes.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @cobusgreyling/loop-init . --pattern changelog-drafter --tool opencode
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or copy manually:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cp -r starters/changelog-drafter-opencode/skills .
|
|
15
|
+
cp starters/changelog-drafter-opencode/AGENTS.md .
|
|
16
|
+
cp starters/changelog-drafter-opencode/LOOP.md .
|
|
17
|
+
cp starters/changelog-drafter-opencode/changelog-drafter-state.md.example changelog-drafter-state.md
|
|
18
|
+
cp starters/changelog-drafter-opencode/opencode.json.example opencode.json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Start (L1 report + draft, week 1):
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
opencode run \
|
|
25
|
+
"Run skills/changelog-scan/SKILL.md. Scan merges since last tag (or last 7 days). Produce categorized draft in RELEASE_NOTES_DRAFT.md. Update state. Do not publish or create PRs." \
|
|
26
|
+
--title "Changelog drafter"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## What's Included
|
|
30
|
+
|
|
31
|
+
| File | Purpose |
|
|
32
|
+
|------|---------|
|
|
33
|
+
| `changelog-drafter-state.md.example` | State spine (last release, draft status) |
|
|
34
|
+
| `skills/changelog-scan/SKILL.md` | Merge scan and categorization skill |
|
|
35
|
+
| `AGENTS.md` | Always-on safety rules |
|
|
36
|
+
| `LOOP.md` | Cadence, gates, budget |
|
|
37
|
+
| `opencode.json.example` | Named agent definitions |
|
|
38
|
+
|
|
39
|
+
## Next Steps
|
|
40
|
+
|
|
41
|
+
- [patterns/changelog-drafter.md](../../patterns/changelog-drafter.md)
|
|
42
|
+
- [examples/opencode/changelog-drafter.md](../../examples/opencode/changelog-drafter.md)
|
|
43
|
+
- [docs/loop-design-checklist.md](../../docs/loop-design-checklist.md)
|
|
44
|
+
- [stories/changelog-drafter-week-one.md](../../stories/changelog-drafter-week-one.md)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opencode.ai/config.json",
|
|
3
|
+
"agent": {
|
|
4
|
+
"changelog-scan": {
|
|
5
|
+
"name": "changelog-scan",
|
|
6
|
+
"description": "Changelog drafting loop. Reads changelog-drafter-state.md, scans merges, and produces categorized release notes.",
|
|
7
|
+
"mode": "primary",
|
|
8
|
+
"prompt": "Read AGENTS.md, LOOP.md, changelog-drafter-state.md, and skills/changelog-scan/SKILL.md. Scan merges since last tag. Produce categorized draft in RELEASE_NOTES_DRAFT.md. Never publish or tag without human approval.",
|
|
9
|
+
"permission": {
|
|
10
|
+
"bash": "ask",
|
|
11
|
+
"edit": "ask"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"implementer": {
|
|
15
|
+
"name": "implementer",
|
|
16
|
+
"description": "L2 implementer for creating changelog PRs.",
|
|
17
|
+
"mode": "subagent",
|
|
18
|
+
"prompt": "Commit the approved release notes to a new branch and open a draft PR. Flag breaking changes and security items explicitly in the PR body. Do not merge.",
|
|
19
|
+
"permission": {
|
|
20
|
+
"bash": "ask",
|
|
21
|
+
"edit": "ask"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"verifier": {
|
|
25
|
+
"name": "verifier",
|
|
26
|
+
"description": "Checker agent for draft release notes. APPROVE or REJECT only.",
|
|
27
|
+
"mode": "subagent",
|
|
28
|
+
"prompt": "Review the draft notes for completeness, categorization, and correct date range. Flag missing sections. Do not edit. APPROVE or REJECT.",
|
|
29
|
+
"permission": {
|
|
30
|
+
"bash": "ask",
|
|
31
|
+
"edit": "deny"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: changelog-scan
|
|
3
|
+
description: >
|
|
4
|
+
Scan merged PRs and commits since a given reference, extract
|
|
5
|
+
titles, labels, types, and signals. Produces structured input
|
|
6
|
+
for release notes drafting.
|
|
7
|
+
user_invocable: true
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Changelog Scan Skill
|
|
11
|
+
|
|
12
|
+
You are a changelog drafting agent. Scan merges and produce release notes.
|
|
13
|
+
|
|
14
|
+
## Scan Sources
|
|
15
|
+
|
|
16
|
+
- `git log --merges --oneline <last-tag>..HEAD`
|
|
17
|
+
- PR labels and milestones
|
|
18
|
+
- Commit messages since last tag
|
|
19
|
+
|
|
20
|
+
## Categories
|
|
21
|
+
|
|
22
|
+
- Features
|
|
23
|
+
- Bug fixes
|
|
24
|
+
- Documentation
|
|
25
|
+
- Dependencies
|
|
26
|
+
- Breaking changes
|
|
27
|
+
- Security
|
|
28
|
+
|
|
29
|
+
## Output
|
|
30
|
+
|
|
31
|
+
- Categorized draft in `RELEASE_NOTES_DRAFT.md`
|
|
32
|
+
- Update `changelog-drafter-state.md` with scan window
|
|
33
|
+
|
|
34
|
+
## Rules
|
|
35
|
+
|
|
36
|
+
- Never publish or tag without explicit human approval.
|
|
37
|
+
- Surface breaking changes and security items explicitly.
|
|
38
|
+
- L1: draft only — no PRs, no tags.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# AGENTS.md — CI Sweeper (Opencode)
|
|
2
|
+
|
|
3
|
+
## Loop Mode
|
|
4
|
+
- CI sweeper is L2 from week one (action-oriented — CIs are urgent).
|
|
5
|
+
- Read `ci-sweeper-state.md` before every run.
|
|
6
|
+
- Classify failures before attempting any fix.
|
|
7
|
+
|
|
8
|
+
## Safety
|
|
9
|
+
- Always dispatch into a git worktree per attempt.
|
|
10
|
+
- Infra / security / payments test failures: do not auto-fix; flag and stop.
|
|
11
|
+
- Max 3 fix attempts per item; escalate after.
|
|
12
|
+
- Enforce budget cap from `LOOP.md`.
|
|
13
|
+
|
|
14
|
+
## Verification
|
|
15
|
+
- Verifier must run tests after implementer.
|
|
16
|
+
- Record attempt count in `ci-sweeper-state.md`.
|
|
17
|
+
- No auto-merge without verifier approval.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Loop Configuration — CI Sweeper (Opencode)
|
|
2
|
+
|
|
3
|
+
## Active Loops
|
|
4
|
+
|
|
5
|
+
| Pattern | Cadence | Status | Command |
|
|
6
|
+
|---------|---------|--------|---------|
|
|
7
|
+
| CI Sweeper | 5-15m | L2 cautious | `opencode run "Run ci-triage" --agent loop-triage` via cron/systemd |
|
|
8
|
+
|
|
9
|
+
## Human Gates
|
|
10
|
+
- Infra / security / payments test failures: do not auto-fix.
|
|
11
|
+
- Max 3 fix attempts per item; escalate after.
|
|
12
|
+
- No auto-merge without verifier pass.
|
|
13
|
+
|
|
14
|
+
## Worktrees
|
|
15
|
+
- Always dispatch into a git worktree per attempt.
|
|
16
|
+
- One worktree per fix; discard after REJECT.
|
|
17
|
+
|
|
18
|
+
## Budget
|
|
19
|
+
- Max sub-agent spawns per run: 3.
|
|
20
|
+
- Max auto-PRs per day: 5.
|
|
21
|
+
- Early exit if no failures found.
|
|
22
|
+
|
|
23
|
+
## Links
|
|
24
|
+
- Pattern: [ci-sweeper](../../patterns/ci-sweeper.md)
|
|
25
|
+
- Example: [examples/opencode/ci-sweeper.md](../../examples/opencode/ci-sweeper.md)
|
|
26
|
+
- Safety: [docs/safety.md](../../docs/safety.md)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# CI Sweeper — Opencode Starter
|
|
2
|
+
|
|
3
|
+
Clone-and-run scaffold for the **CI Sweeper** pattern with opencode. React to failing CI with minimal fixes at short cadences.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @cobusgreyling/loop-init . --pattern ci-sweeper --tool opencode
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or copy manually:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cp -r starters/ci-sweeper-opencode/skills .
|
|
15
|
+
cp starters/ci-sweeper-opencode/AGENTS.md .
|
|
16
|
+
cp starters/ci-sweeper-opencode/LOOP.md .
|
|
17
|
+
cp starters/ci-sweeper-opencode/ci-sweeper-state.md.example ci-sweeper-state.md
|
|
18
|
+
cp starters/ci-sweeper-opencode/opencode.json.example opencode.json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Start (L2 cautious — CI sweeper is action-oriented from week one):
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
opencode run \
|
|
25
|
+
"Run skills/ci-triage/SKILL.md. Classify each failing check. For clear single-file regressions, create a worktree and apply a minimal fix with verifier. Update ci-sweeper-state.md. Infra and security failures: escalate." \
|
|
26
|
+
--title "CI sweeper"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## What's Included
|
|
30
|
+
|
|
31
|
+
| File | Purpose |
|
|
32
|
+
|------|---------|
|
|
33
|
+
| `ci-sweeper-state.md.example` | State spine (in-flight CI failures) |
|
|
34
|
+
| `skills/ci-triage/SKILL.md` | CI-focused triage skill |
|
|
35
|
+
| `AGENTS.md` | Always-on safety rules |
|
|
36
|
+
| `LOOP.md` | Cadence, gates, budget |
|
|
37
|
+
| `opencode.json.example` | Named agent definitions |
|
|
38
|
+
|
|
39
|
+
## Next Steps
|
|
40
|
+
|
|
41
|
+
- [patterns/ci-sweeper.md](../../patterns/ci-sweeper.md)
|
|
42
|
+
- [examples/opencode/ci-sweeper.md](../../examples/opencode/ci-sweeper.md)
|
|
43
|
+
- [docs/loop-design-checklist.md](../../docs/loop-design-checklist.md)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opencode.ai/config.json",
|
|
3
|
+
"agent": {
|
|
4
|
+
"ci-triage": {
|
|
5
|
+
"name": "ci-triage",
|
|
6
|
+
"description": "CI-focused triage and fix loop. Reads ci-sweeper-state.md, classifies CI failures, and applies minimal fixes in worktrees with verifier.",
|
|
7
|
+
"mode": "primary",
|
|
8
|
+
"prompt": "Read AGENTS.md, LOOP.md, ci-sweeper-state.md, and skills/ci-triage/SKILL.md. Classify each failing check. For clear regressions: worktree + implementer + verifier. Escalate infra and security failures.",
|
|
9
|
+
"permission": {
|
|
10
|
+
"bash": "ask",
|
|
11
|
+
"edit": "ask"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"implementer": {
|
|
15
|
+
"name": "implementer",
|
|
16
|
+
"description": "L2 implementer for CI-fix patches inside an isolated worktree.",
|
|
17
|
+
"mode": "subagent",
|
|
18
|
+
"prompt": "Implement the minimal fix for the identified CI failure inside the supplied worktree. Run tests. Output the diff path. Max 3 attempts per item.",
|
|
19
|
+
"permission": {
|
|
20
|
+
"bash": "ask",
|
|
21
|
+
"edit": "ask"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"verifier": {
|
|
25
|
+
"name": "verifier",
|
|
26
|
+
"description": "Checker agent for CI fix diffs. APPROVE or REJECT only.",
|
|
27
|
+
"mode": "subagent",
|
|
28
|
+
"prompt": "Review the supplied CI-fix diff. Verify tests pass. Do not edit files. APPROVE or REJECT with evidence.",
|
|
29
|
+
"permission": {
|
|
30
|
+
"bash": "ask",
|
|
31
|
+
"edit": "deny"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ci-triage
|
|
3
|
+
description: >
|
|
4
|
+
Classify CI failures — distinguish clear regressions from infra flakes
|
|
5
|
+
and security-test failures. Produces structured failure reports.
|
|
6
|
+
user_invocable: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# CI Triage Skill
|
|
10
|
+
|
|
11
|
+
You are a CI triage agent. Classify each failing check and decide the next action.
|
|
12
|
+
|
|
13
|
+
## Classification
|
|
14
|
+
|
|
15
|
+
- **Clear regression**: single-file, obvious root cause (candidate for auto-fix)
|
|
16
|
+
- **Infra flake**: network timeout, runner issue, dependency unavailable
|
|
17
|
+
- **Security test failure**: never auto-fix; escalate to human
|
|
18
|
+
- **Non-deterministic**: retry once before classifying
|
|
19
|
+
|
|
20
|
+
## Output
|
|
21
|
+
|
|
22
|
+
Update `ci-sweeper-state.md` with:
|
|
23
|
+
|
|
24
|
+
- List of failures by category
|
|
25
|
+
- Suggested next action per item
|
|
26
|
+
- Attempt count per item
|
|
27
|
+
|
|
28
|
+
## Rules
|
|
29
|
+
|
|
30
|
+
- Infra and security failures always escalate.
|
|
31
|
+
- Max 3 fix attempts per item.
|
|
32
|
+
- Worktree isolation required for any code change.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# AGENTS.md — Dependency Sweeper (Opencode)
|
|
2
|
+
|
|
3
|
+
## Loop Mode
|
|
4
|
+
- L2 assisted from week one (patch-only with strong verifier gates).
|
|
5
|
+
- Read `dependency-sweeper-state.md` before every run.
|
|
6
|
+
|
|
7
|
+
## Safety
|
|
8
|
+
- Patch-only by default. Majors and breaking changes escalate to human.
|
|
9
|
+
- Maintain denylist in state file — never touch those packages.
|
|
10
|
+
- One worktree per update attempt.
|
|
11
|
+
- Max 3 fix attempts per run; max 5 auto-PRs per day.
|
|
12
|
+
|
|
13
|
+
## Verification
|
|
14
|
+
- Verifier must run `npm ci && npm test` (or equivalent).
|
|
15
|
+
- Record attempt count and test evidence in state.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Loop Configuration — Dependency Sweeper (Opencode)
|
|
2
|
+
|
|
3
|
+
## Active Loops
|
|
4
|
+
|
|
5
|
+
| Pattern | Cadence | Status | Command |
|
|
6
|
+
|---------|---------|--------|---------|
|
|
7
|
+
| Dependency Sweeper | 6h | L2 patch-only | `opencode run "Run dependency-triage" --agent loop-triage` via cron |
|
|
8
|
+
|
|
9
|
+
## Human Gates
|
|
10
|
+
- Major version bumps always human.
|
|
11
|
+
- High-severity CVE requiring breaking change: human.
|
|
12
|
+
- Denylist packages (edit in state) never auto-touched.
|
|
13
|
+
- No auto-merge without verifier pass.
|
|
14
|
+
|
|
15
|
+
## Worktrees
|
|
16
|
+
- One worktree per package update attempt.
|
|
17
|
+
- Discard on REJECT or human escalation.
|
|
18
|
+
|
|
19
|
+
## Budget
|
|
20
|
+
- Max sub-agent spawns per run: 3.
|
|
21
|
+
- Max auto-PRs per day: 5.
|
|
22
|
+
- Pause if token budget exceeded.
|
|
23
|
+
|
|
24
|
+
## Links
|
|
25
|
+
- Pattern: [dependency-sweeper](../../patterns/dependency-sweeper.md)
|
|
26
|
+
- Example: [examples/opencode/dependency-sweeper.md](../../examples/opencode/dependency-sweeper.md)
|
|
27
|
+
- Safety: [docs/safety.md](../../docs/safety.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Dependency Sweeper — Opencode Starter
|
|
2
|
+
|
|
3
|
+
Clone-and-run scaffold for the **Dependency Sweeper** pattern with opencode. Discover, safely apply, and verify dependency updates.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @cobusgreyling/loop-init . --pattern dependency-sweeper --tool opencode
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or copy manually:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cp -r starters/dependency-sweeper-opencode/skills .
|
|
15
|
+
cp starters/dependency-sweeper-opencode/AGENTS.md .
|
|
16
|
+
cp starters/dependency-sweeper-opencode/LOOP.md .
|
|
17
|
+
cp starters/dependency-sweeper-opencode/dependency-sweeper-state.md.example dependency-sweeper-state.md
|
|
18
|
+
cp starters/dependency-sweeper-opencode/opencode.json.example opencode.json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Start (L2 assisted, patch-only):
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
opencode run \
|
|
25
|
+
"Run skills/dependency-triage/SKILL.md. Scan package manifests for outdated and vulnerable deps. Patch-only auto-fix in worktree with verifier. Escalate majors, high-sev CVEs, and denylist packages. Update state." \
|
|
26
|
+
--title "Dependency sweeper"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## What's Included
|
|
30
|
+
|
|
31
|
+
| File | Purpose |
|
|
32
|
+
|------|---------|
|
|
33
|
+
| `dependency-sweeper-state.md.example` | State spine (in-flight updates, denylist) |
|
|
34
|
+
| `skills/dependency-triage/SKILL.md` | Dependency-focused triage skill |
|
|
35
|
+
| `AGENTS.md` | Always-on safety rules |
|
|
36
|
+
| `LOOP.md` | Cadence, gates, budget |
|
|
37
|
+
| `opencode.json.example` | Named agent definitions |
|
|
38
|
+
|
|
39
|
+
## Next Steps
|
|
40
|
+
|
|
41
|
+
- [patterns/dependency-sweeper.md](../../patterns/dependency-sweeper.md)
|
|
42
|
+
- [examples/opencode/dependency-sweeper.md](../../examples/opencode/dependency-sweeper.md)
|
|
43
|
+
- [docs/loop-design-checklist.md](../../docs/loop-design-checklist.md)
|
|
44
|
+
- [stories/dependency-sweeper-week-one.md](../../stories/dependency-sweeper-week-one.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Dependency Sweeper State
|
|
2
|
+
Last run: 2026-06-20 09:00 UTC
|
|
3
|
+
Outdated packages: 0
|
|
4
|
+
Attempt counts: {}
|
|
5
|
+
Auto-PRs today: 0
|
|
6
|
+
|
|
7
|
+
## Denylist (never touch)
|
|
8
|
+
- <!-- Add packages the loop must never update -->
|
|
9
|
+
|
|
10
|
+
## Escalated to Human
|
|
11
|
+
- <!-- Major bumps and high-sev CVEs -->
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opencode.ai/config.json",
|
|
3
|
+
"agent": {
|
|
4
|
+
"dependency-triage": {
|
|
5
|
+
"name": "dependency-triage",
|
|
6
|
+
"description": "Dependency-focused triage loop. Reads dependency-sweeper-state.md, scans manifests, and applies patch-only upgrades with verifier.",
|
|
7
|
+
"mode": "primary",
|
|
8
|
+
"prompt": "Read AGENTS.md, LOOP.md, dependency-sweeper-state.md, and skills/dependency-triage/SKILL.md. Scan manifests for outdated and vulnerable deps. Patch-only auto-fix in worktree. Escalate majors and denylisted packages.",
|
|
9
|
+
"permission": {
|
|
10
|
+
"bash": "ask",
|
|
11
|
+
"edit": "ask"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"implementer": {
|
|
15
|
+
"name": "implementer",
|
|
16
|
+
"description": "L2 implementer for patch-only dependency upgrades in a worktree.",
|
|
17
|
+
"mode": "subagent",
|
|
18
|
+
"prompt": "Apply the identified patch-only upgrade inside the supplied worktree. Run npm ci && npm test. Never touch denylisted packages. Output the diff.",
|
|
19
|
+
"permission": {
|
|
20
|
+
"bash": "ask",
|
|
21
|
+
"edit": "ask"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"verifier": {
|
|
25
|
+
"name": "verifier",
|
|
26
|
+
"description": "Checker agent for dependency upgrade diffs. APPROVE or REJECT only.",
|
|
27
|
+
"mode": "subagent",
|
|
28
|
+
"prompt": "Verify the dependency patch passes tests and touches no denylisted packages. Do not edit files. APPROVE or REJECT with evidence.",
|
|
29
|
+
"permission": {
|
|
30
|
+
"bash": "ask",
|
|
31
|
+
"edit": "deny"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|