cavekit-opencode 1.0.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/AGENTS.md +27 -0
- package/FORMAT.md +119 -0
- package/INSTALL.md +50 -0
- package/README.md +96 -0
- package/commands/ck-build.md +68 -0
- package/commands/ck-check.md +82 -0
- package/commands/ck-spec.md +72 -0
- package/install.sh +28 -0
- package/package.json +33 -0
- package/plugin.js +43 -0
- package/skills/ck-build/SKILL.md +24 -0
- package/skills/ck-check/SKILL.md +18 -0
- package/skills/ck-spec/SKILL.md +22 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# cavekit — spec-driven development
|
|
2
|
+
|
|
3
|
+
cavekit commands available: `/ck-spec`, `/ck-build`, `/ck-check`.
|
|
4
|
+
|
|
5
|
+
## FORMAT
|
|
6
|
+
|
|
7
|
+
SPEC.md lives at repo root. Sections: §G GOAL, §C CONSTRAINTS, §I INTERFACES, §V INVARIANTS, §T TASKS, §B BUGS. Reference `FORMAT.md` for full schema.
|
|
8
|
+
|
|
9
|
+
## BACKPROP PROTOCOL
|
|
10
|
+
|
|
11
|
+
When test fails during `/ck-build`:
|
|
12
|
+
1. Read failure.
|
|
13
|
+
2. Classify: code bug / spec wrong / edge case.
|
|
14
|
+
3. If spec wrong → `/ck-spec bug: <cause>` updates §V + §B.
|
|
15
|
+
4. If code bug → fix, re-run. No spec change.
|
|
16
|
+
5. Never silently fix root cause without considering §B entry.
|
|
17
|
+
|
|
18
|
+
## CAVEMAN ENCODING
|
|
19
|
+
|
|
20
|
+
Apply to all SPEC.md content: drop articles/filler, use fragments, preserve code verbatim.
|
|
21
|
+
Reference symbols from FORMAT.md (→, ∴, ∀, !, ⊥, ≠, ≤, ≥).
|
|
22
|
+
|
|
23
|
+
## COMMANDS
|
|
24
|
+
|
|
25
|
+
- `/ck-spec` — create/amend/backprop SPEC.md. Sole mutator.
|
|
26
|
+
- `/ck-build` — plan-execute against spec. Auto-backprops on failure.
|
|
27
|
+
- `/ck-check` — drift report. Read-only.
|
package/FORMAT.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# SPEC.md FORMAT
|
|
2
|
+
|
|
3
|
+
Single file. Project root. Every cavekit command reads it.
|
|
4
|
+
|
|
5
|
+
## SECTIONS
|
|
6
|
+
|
|
7
|
+
Fixed order. Fixed headers. Addressable.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
# SPEC
|
|
11
|
+
|
|
12
|
+
## §G GOAL
|
|
13
|
+
one line. what code must do.
|
|
14
|
+
|
|
15
|
+
## §C CONSTRAINTS
|
|
16
|
+
- bullet. non-negotiable boundary.
|
|
17
|
+
- bullet. tech/lang/lib locked in.
|
|
18
|
+
|
|
19
|
+
## §I INTERFACES
|
|
20
|
+
external surface. what world sees.
|
|
21
|
+
- cmd: `foo bar` → stdout JSON
|
|
22
|
+
- api: POST /x → 200 {id}
|
|
23
|
+
- file: `config.yaml` schema …
|
|
24
|
+
- env: `FOO_KEY` required
|
|
25
|
+
|
|
26
|
+
## §V INVARIANTS
|
|
27
|
+
numbered. testable. each ! MUST hold.
|
|
28
|
+
V1: ∀ req → auth check before handler
|
|
29
|
+
V2: token expiry ≤ ⊥ allowed
|
|
30
|
+
V3: DB write ! in transaction
|
|
31
|
+
|
|
32
|
+
## §T TASKS
|
|
33
|
+
pipe table. ids monotonic (never reused). status: `x` done / `~` wip / `.` todo.
|
|
34
|
+
id|status|task|cites
|
|
35
|
+
T1|.|scaffold repo|-
|
|
36
|
+
T2|.|impl §I.api POST /x|V2
|
|
37
|
+
T3|x|add §V.1 middleware|V1,I.api
|
|
38
|
+
|
|
39
|
+
## §B BUGS
|
|
40
|
+
pipe table. backprop log. each row = bug + invariant that catches recurrence.
|
|
41
|
+
id|date|cause|fix
|
|
42
|
+
B1|2026-04-20|token `<` not `≤`|V2
|
|
43
|
+
B2|2026-04-21|race on write|V3
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Table cell rules**: literal `|` → escape as `\|`. Backticks OK. Cells trimmed. Empty = `-`.
|
|
47
|
+
|
|
48
|
+
## ADDRESSING
|
|
49
|
+
|
|
50
|
+
`§<S>.<n>` = section.item. `§V.2` = invariants section, item 2.
|
|
51
|
+
Commands, commits, PRs all reference by §. Zero ambiguity.
|
|
52
|
+
|
|
53
|
+
## CAVEMAN ENCODING
|
|
54
|
+
|
|
55
|
+
Default for every section. Rules:
|
|
56
|
+
|
|
57
|
+
- Drop articles (a, an, the). Drop filler.
|
|
58
|
+
- Drop aux verbs (is, are, was) where fragment works.
|
|
59
|
+
- Short synonyms (fix > implement).
|
|
60
|
+
- Fragments fine.
|
|
61
|
+
|
|
62
|
+
**Preserve verbatim**: code, paths, identifiers, URLs, numbers, error strings, SQL, regex.
|
|
63
|
+
|
|
64
|
+
**Symbols** (save tokens, machine-readable):
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
→ leads to / becomes / triggers
|
|
68
|
+
∴ therefore / fix
|
|
69
|
+
∀ for all / every
|
|
70
|
+
∃ exists / some
|
|
71
|
+
! must
|
|
72
|
+
? may / optional
|
|
73
|
+
⊥ never / impossible / forbidden
|
|
74
|
+
≠ not equal / differs from
|
|
75
|
+
∈ in / member of
|
|
76
|
+
∉ not in
|
|
77
|
+
≤ at most
|
|
78
|
+
≥ at least
|
|
79
|
+
& and
|
|
80
|
+
| or
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Bad** (prose):
|
|
84
|
+
|
|
85
|
+
> The authentication middleware must verify the token expiry on every request before allowing the handler to execute.
|
|
86
|
+
|
|
87
|
+
**Good** (caveman):
|
|
88
|
+
|
|
89
|
+
> V1: ∀ req → auth check before handler
|
|
90
|
+
|
|
91
|
+
**Bad** (prose bug note):
|
|
92
|
+
|
|
93
|
+
> Fixed a bug where token expiry comparison used strict less-than instead of less-than-or-equal, causing tokens to be rejected exactly at their expiry timestamp.
|
|
94
|
+
|
|
95
|
+
**Good** (caveman):
|
|
96
|
+
|
|
97
|
+
> B1: token `<` not `<=` ∴ tokens rejected @ expiry. §V.2 now ! `≤`.
|
|
98
|
+
|
|
99
|
+
## WHY CAVEMAN FOR SPECS
|
|
100
|
+
|
|
101
|
+
Spec loaded every invocation. 75% fewer tokens = 75% fewer dollars & faster reads.
|
|
102
|
+
Human skims fast too. Symbols unambiguous.
|
|
103
|
+
|
|
104
|
+
## ONE FILE RULE
|
|
105
|
+
|
|
106
|
+
Big project → more sections, not more files. grep ceremony kills agent speed.
|
|
107
|
+
If SPEC.md > 500 lines, compact §B (old bugs drop oldest) before splitting.
|
|
108
|
+
|
|
109
|
+
## WRITES
|
|
110
|
+
|
|
111
|
+
| command | writes | section |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `/ck-spec new` | creates | all |
|
|
114
|
+
| `/ck-spec amend` | edits | chosen |
|
|
115
|
+
| `/ck-spec bug` | appends | §B + §V |
|
|
116
|
+
| `/ck-build` | flips | §T status cell `.` → `~` → `x` |
|
|
117
|
+
| `/ck-check` | — | read only |
|
|
118
|
+
|
|
119
|
+
That's the whole format.
|
package/INSTALL.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Install cavekit for OpenCode
|
|
2
|
+
|
|
3
|
+
## One-liner
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
# Install commands globally (available in any project)
|
|
7
|
+
cp -r commands/* ~/.config/opencode/commands/
|
|
8
|
+
|
|
9
|
+
# Install skills globally
|
|
10
|
+
cp -r skills/* ~/.config/opencode/skills/
|
|
11
|
+
|
|
12
|
+
# Or per-project (replace ~/.config/opencode with .opencode in your project root)
|
|
13
|
+
cp -r commands/* .opencode/commands/
|
|
14
|
+
cp -r skills/* .opencode/skills/
|
|
15
|
+
|
|
16
|
+
# Copy AGENTS.md to your project root (optional, embeds backprop+caveman rules)
|
|
17
|
+
cp AGENTS.md /path/to/your/project/
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Using the install script
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
./install.sh # install globally
|
|
24
|
+
./install.sh /path/to/project # install per-project
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## What you get
|
|
28
|
+
|
|
29
|
+
| File | Location | Purpose |
|
|
30
|
+
|------|----------|---------|
|
|
31
|
+
| `commands/ck-spec.md` | `~/.config/opencode/commands/` | `/ck-spec` — create/amend/backprop SPEC.md |
|
|
32
|
+
| `commands/ck-build.md` | `~/.config/opencode/commands/` | `/ck-build` — plan-execute against spec |
|
|
33
|
+
| `commands/ck-check.md` | `~/.config/opencode/commands/` | `/ck-check` — drift detection |
|
|
34
|
+
| `skills/ck-spec/SKILL.md` | `~/.config/opencode/skills/` | Auto-trigger on "write a spec" |
|
|
35
|
+
| `skills/ck-build/SKILL.md` | `~/.config/opencode/skills/` | Auto-trigger on "build next task" |
|
|
36
|
+
| `skills/ck-check/SKILL.md` | `~/.config/opencode/skills/` | Auto-trigger on "check spec drift" |
|
|
37
|
+
| `FORMAT.md` | project root | SPEC.md schema reference |
|
|
38
|
+
| `AGENTS.md` | project root | Backprop protocol + caveman encoding rules |
|
|
39
|
+
|
|
40
|
+
## Dependencies
|
|
41
|
+
|
|
42
|
+
- [caveman](https://github.com/JuliusBrussee/caveman) plugin for OpenCode (optional, recommended)
|
|
43
|
+
- OpenCode >= 1.15
|
|
44
|
+
|
|
45
|
+
## Uninstall
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
rm ~/.config/opencode/commands/ck-*.md
|
|
49
|
+
rm -rf ~/.config/opencode/skills/ck-*/
|
|
50
|
+
```
|
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# cavekit-opencode
|
|
2
|
+
|
|
3
|
+
Spec-driven development commands for OpenCode. Port of [cavekit v4](https://github.com/JuliusBrussee/cavekit) — compressed spec, plan-execute loop, drift detection.
|
|
4
|
+
|
|
5
|
+
**One spec to rule them all. Three commands. Zero sub-agents.**
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
| Command | Job |
|
|
10
|
+
|---------|-----|
|
|
11
|
+
| `/ck-spec` | Create / amend / backprop `SPEC.md`. Sole mutator. |
|
|
12
|
+
| `/ck-build` | Plan-then-execute against spec. Auto-backprops on failure. |
|
|
13
|
+
| `/ck-check` | Read-only drift report. Lists §V / §I / §T violations. |
|
|
14
|
+
|
|
15
|
+
## How it works
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
SPEC.md at repo root ← durable artifact surviving context resets
|
|
19
|
+
├── §G GOAL one-line intent
|
|
20
|
+
├── §C CONSTRAINTS non-negotiable boundaries
|
|
21
|
+
├── §I INTERFACES external surfaces (api, cmd, file, env)
|
|
22
|
+
├── §V INVARIANTS numbered testable rules (! MUST hold)
|
|
23
|
+
├── §T TASKS pipe table — x/~/. status
|
|
24
|
+
└── §B BUGS backprop log — bug → invariant
|
|
25
|
+
|
|
26
|
+
/ck-spec new → creates SPEC.md
|
|
27
|
+
/ck-build → reads §T, plans, edits, verifies
|
|
28
|
+
→ failure triggers backprop → §B + §V update
|
|
29
|
+
/ck-check → reads SPEC.md, diffs against code, reports drift
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Every test failure becomes a §B entry. Classes of bug become §V invariants the spec never forgets.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
### Via opencode.json (recommended)
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"plugin": ["cavekit-opencode"]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The plugin auto-installs commands and skills into your opencode config on load.
|
|
45
|
+
|
|
46
|
+
**Prerequisite**: `npm install -g cavekit-opencode` or add to your project:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
npm install cavekit-opencode # project-level
|
|
50
|
+
npm install -g cavekit-opencode # global
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Manual install
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
git clone https://github.com/gggiiia/cavekit-opencode.git
|
|
57
|
+
cd cavekit-opencode
|
|
58
|
+
cp commands/ck-*.md ~/.config/opencode/commands/
|
|
59
|
+
cp -r skills/ck-* ~/.config/opencode/skills/
|
|
60
|
+
cp FORMAT.md /path/to/your/project/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Or use the install script: `bash install.sh [project-path]`
|
|
64
|
+
|
|
65
|
+
### Dependencies
|
|
66
|
+
|
|
67
|
+
- [caveman](https://github.com/JuliusBrussee/caveman) plugin for OpenCode (recommended)
|
|
68
|
+
- OpenCode >= 1.15
|
|
69
|
+
|
|
70
|
+
## Files
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
commands/
|
|
74
|
+
├── ck-spec.md spec mutator
|
|
75
|
+
├── ck-build.md plan-execute loop
|
|
76
|
+
└── ck-check.md drift detector
|
|
77
|
+
skills/
|
|
78
|
+
├── ck-spec/SKILL.md discovery-triggered spec
|
|
79
|
+
├── ck-build/SKILL.md discovery-triggered build
|
|
80
|
+
└── ck-check/SKILL.md discovery-triggered check
|
|
81
|
+
FORMAT.md SPEC.md schema + caveman encoding rules
|
|
82
|
+
AGENTS.md always-on backprop protocol + encoding rules
|
|
83
|
+
install.sh installer
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Why cavekit?
|
|
87
|
+
|
|
88
|
+
The spec is the only artifact that earns its tokens. Everything else that costs tokens must either save more tokens later, or the user's attention, or it gets cut.
|
|
89
|
+
|
|
90
|
+
- **Caveman encoding** — 75% fewer tokens than prose specs.
|
|
91
|
+
- **Backprop reflex** — test failures auto-commit as §B entries.
|
|
92
|
+
- **One file** — `cat SPEC.md` is the dashboard.
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
MIT
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Plan-then-execute against SPEC.md. Single-thread native loop.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /ck-build — implement spec
|
|
6
|
+
|
|
7
|
+
Single-thread native plan→execute. No sub-agents.
|
|
8
|
+
|
|
9
|
+
## LOAD
|
|
10
|
+
|
|
11
|
+
1. Read `SPEC.md`. If missing → tell user run `/ck-spec` first. Stop.
|
|
12
|
+
2. Read `FORMAT.md` once if not loaded.
|
|
13
|
+
3. Parse `$ARGUMENTS`:
|
|
14
|
+
- `§T.n` → that task only
|
|
15
|
+
- `--next` → lowest-numbered row with status `.` or `~`
|
|
16
|
+
- `--all` or empty → every `.` row in §T order
|
|
17
|
+
|
|
18
|
+
## PLAN
|
|
19
|
+
|
|
20
|
+
Native plan mode. For chosen task(s):
|
|
21
|
+
|
|
22
|
+
1. Cite every §V invariant that applies. Plan must respect all.
|
|
23
|
+
2. Cite every §I interface touched. Plan must preserve shape.
|
|
24
|
+
3. List files to create / edit.
|
|
25
|
+
4. List tests to add or update (one per invariant touched).
|
|
26
|
+
5. Name verification command (test, build, lint).
|
|
27
|
+
|
|
28
|
+
Show plan. Wait for user OK unless auto mode.
|
|
29
|
+
|
|
30
|
+
## EXECUTE
|
|
31
|
+
|
|
32
|
+
Per task in order:
|
|
33
|
+
|
|
34
|
+
1. Flip §T.n status `.` → `~`. No commit — just write SPEC.md.
|
|
35
|
+
2. Edit code per plan.
|
|
36
|
+
3. Run verification command.
|
|
37
|
+
4. **Pass** → flip `~` → `x`. Next task.
|
|
38
|
+
5. **Fail** → invoke backprop. Do NOT retry blindly.
|
|
39
|
+
|
|
40
|
+
## FAIL → BACKPROP
|
|
41
|
+
|
|
42
|
+
On test/build failure:
|
|
43
|
+
|
|
44
|
+
1. Read failure output: !`$TEST_COMMAND` or last run output.
|
|
45
|
+
2. Ask: is failure (a) my code bug, (b) spec wrong, or (c) unspecified edge case?
|
|
46
|
+
3. If (a) → fix code, re-run. No spec change.
|
|
47
|
+
4. If (b) or (c) → run `/ck-spec bug: <cause>` first, let it update §V and §B, then resume build against updated spec.
|
|
48
|
+
|
|
49
|
+
Rule: never silently fix root-cause without considering backprop. §B is memory that stops recurrence.
|
|
50
|
+
|
|
51
|
+
## WRITE POLICY
|
|
52
|
+
|
|
53
|
+
- Only flip §T status. No other SPEC.md edits.
|
|
54
|
+
- Other spec edits → `/ck-spec`.
|
|
55
|
+
- Commit after each §T completes. Message: `T<n>: <goal line>` + §V cites.
|
|
56
|
+
|
|
57
|
+
## VERIFICATION
|
|
58
|
+
|
|
59
|
+
Task `[x]` only if:
|
|
60
|
+
- Verification command exits 0.
|
|
61
|
+
- New test(s) added per plan.
|
|
62
|
+
- No §V invariant regressed (full test suite at end).
|
|
63
|
+
|
|
64
|
+
## NON-GOALS
|
|
65
|
+
|
|
66
|
+
- No sub-agents. No parallel workers. Main thread only.
|
|
67
|
+
- No progress dashboards. `cat SPEC.md | grep §T` is dashboard.
|
|
68
|
+
- No speculative work beyond chosen task scope.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Drift detector. Diffs SPEC.md against code. Read-only, zero writes.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /ck-check — drift report
|
|
6
|
+
|
|
7
|
+
Pure diagnostic. Reports violations. Writes nothing. User decides remedy.
|
|
8
|
+
|
|
9
|
+
## LOAD
|
|
10
|
+
|
|
11
|
+
1. Read `SPEC.md`. If missing → "no spec, nothing to check." Stop.
|
|
12
|
+
2. Parse `$ARGUMENTS`:
|
|
13
|
+
- `§V` → check invariants only (default)
|
|
14
|
+
- `§I` → check interfaces
|
|
15
|
+
- `§T` → audit task status vs code
|
|
16
|
+
- `--all` → all three
|
|
17
|
+
|
|
18
|
+
## CHECK §V — invariants
|
|
19
|
+
|
|
20
|
+
For each V<n>:
|
|
21
|
+
|
|
22
|
+
1. Translate invariant into verifiable claim about code.
|
|
23
|
+
2. Grep / read relevant files.
|
|
24
|
+
3. Classify: **HOLD** / **VIOLATE** / **UNVERIFIABLE**.
|
|
25
|
+
4. Record address + file:line evidence.
|
|
26
|
+
|
|
27
|
+
## CHECK §I — interfaces
|
|
28
|
+
|
|
29
|
+
For each I item:
|
|
30
|
+
|
|
31
|
+
1. Locate implementation.
|
|
32
|
+
2. Classify:
|
|
33
|
+
- **MATCH** — shape in code = shape in spec.
|
|
34
|
+
- **DRIFT** — impl exists, shape differs.
|
|
35
|
+
- **MISSING** — impl absent.
|
|
36
|
+
- **EXTRA** — code exposes surface not in §I.
|
|
37
|
+
|
|
38
|
+
## CHECK §T — tasks
|
|
39
|
+
|
|
40
|
+
For each T<n>:
|
|
41
|
+
|
|
42
|
+
1. If `x`: verify claimed work present.
|
|
43
|
+
2. If `~`: note as in-progress.
|
|
44
|
+
3. If `.`: note as pending.
|
|
45
|
+
4. Flag `x` rows with no evidence as **STALE**.
|
|
46
|
+
|
|
47
|
+
## REPORT
|
|
48
|
+
|
|
49
|
+
Caveman. Grouped by severity.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
## §V drift
|
|
53
|
+
V2 VIOLATE: auth/mw.go:47 uses `<` not `≤`. see §B.1.
|
|
54
|
+
V5 UNVERIFIABLE: no test covers ∀ req path.
|
|
55
|
+
|
|
56
|
+
## §I drift
|
|
57
|
+
I.api DRIFT: POST /x returns `{result}` not `{id}`. route.go:112.
|
|
58
|
+
I.cmd MISSING: `foo bar` absent from cli/*.go.
|
|
59
|
+
|
|
60
|
+
## §T drift
|
|
61
|
+
T3 STALE: status `x`, no middleware file exists.
|
|
62
|
+
|
|
63
|
+
## summary
|
|
64
|
+
2 violate. 1 missing. 1 stale. 1 unverifiable.
|
|
65
|
+
next: `/ck-spec bug:` or fix code at cited lines.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## REMEDY HINTS (not actions)
|
|
69
|
+
|
|
70
|
+
End report with one-line hint per class:
|
|
71
|
+
- VIOLATE / DRIFT → `/ck-spec bug: <V.n>` or fix code.
|
|
72
|
+
- MISSING → `/ck-build §T.n` if task exists; else `/ck-spec amend §T`.
|
|
73
|
+
- STALE → `/ck-spec amend §T` to uncheck.
|
|
74
|
+
- EXTRA → `/ck-spec amend §I` to document, or delete code.
|
|
75
|
+
|
|
76
|
+
Never invoke fixes. Report only.
|
|
77
|
+
|
|
78
|
+
## NON-GOALS
|
|
79
|
+
|
|
80
|
+
- Zero writes. No SPEC.md edits. No code edits.
|
|
81
|
+
- No sub-agents. Main thread reads.
|
|
82
|
+
- No scores, no grades. Binary per item: holds or drifts.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Create, amend, or backprop bug into SPEC.md. Sole mutator of spec.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /ck-spec — spec mutator
|
|
6
|
+
|
|
7
|
+
Read `FORMAT.md` at repo root if not already loaded. Caveman rules apply.
|
|
8
|
+
|
|
9
|
+
## DISPATCH
|
|
10
|
+
|
|
11
|
+
Inspect `$ARGUMENTS` and project state:
|
|
12
|
+
|
|
13
|
+
1. No `SPEC.md` at repo root AND args describe idea → **NEW**
|
|
14
|
+
2. No `SPEC.md` AND `from-code` in args → **DISTILL**
|
|
15
|
+
3. `SPEC.md` exists AND args start `bug:` → **BACKPROP**
|
|
16
|
+
4. `SPEC.md` exists AND args start `amend` → **AMEND**
|
|
17
|
+
5. `SPEC.md` exists, no args → ask user which mode
|
|
18
|
+
|
|
19
|
+
## NEW — idea → spec
|
|
20
|
+
|
|
21
|
+
Input: user idea in args.
|
|
22
|
+
|
|
23
|
+
Steps:
|
|
24
|
+
1. Extract goal (1 line, caveman). → §G.
|
|
25
|
+
2. List constraints user stated or implied. → §C.
|
|
26
|
+
3. List external surfaces user named. → §I.
|
|
27
|
+
4. Propose initial invariants. → §V (numbered V1…).
|
|
28
|
+
5. Break goal into ordered tasks. → §T pipe table, status `.`, ids T1…
|
|
29
|
+
6. §B section with header row only (`id|date|cause|fix`).
|
|
30
|
+
|
|
31
|
+
Write `SPEC.md`. Show user full file. Ask: "spec OK? suggest edits or `/ck-build`."
|
|
32
|
+
|
|
33
|
+
## DISTILL — code → spec
|
|
34
|
+
|
|
35
|
+
Walk repo. Produce §G (infer from README/package.json/main entry), §C (infer from stack), §I (enumerate public APIs/CLIs/configs), §V (derive from tests and assertions), §T (one task per known TODO or missing test), §B (empty).
|
|
36
|
+
|
|
37
|
+
Caveman everywhere. Flag uncertain items with `?` so user can confirm.
|
|
38
|
+
|
|
39
|
+
## BACKPROP — bug → §B + §V
|
|
40
|
+
|
|
41
|
+
Input: `bug: <description>`.
|
|
42
|
+
|
|
43
|
+
1. Parse bug description.
|
|
44
|
+
2. Find root cause (read relevant code).
|
|
45
|
+
3. Decide: would new invariant catch recurrence? If yes → draft `V<next>`.
|
|
46
|
+
4. Append §B row: `B<next>|<date>|<cause>|V<N>`.
|
|
47
|
+
5. Append new invariant to §V.
|
|
48
|
+
6. If fix also changes behavior → add/update §T rows.
|
|
49
|
+
7. Show diff. Apply only on user OK.
|
|
50
|
+
|
|
51
|
+
Rule: every bug gets §B entry. Invariant optional but preferred.
|
|
52
|
+
|
|
53
|
+
## AMEND — targeted edit
|
|
54
|
+
|
|
55
|
+
Input: `amend §V.3` or `amend §T` etc.
|
|
56
|
+
|
|
57
|
+
Read that section. Show current. Ask user changes. Write. Show diff.
|
|
58
|
+
|
|
59
|
+
Never silently rewrite sections user did not name.
|
|
60
|
+
|
|
61
|
+
## OUTPUT RULES
|
|
62
|
+
|
|
63
|
+
- Caveman format per `FORMAT.md`.
|
|
64
|
+
- Preserve identifiers, paths, code verbatim.
|
|
65
|
+
- Numbering monotonic — never reuse §V.N or §B.N.
|
|
66
|
+
- §T row `cites` column ! list §V/§I deps: `T5|.|impl auth mw|V2,I.api`.
|
|
67
|
+
|
|
68
|
+
## NON-GOALS
|
|
69
|
+
|
|
70
|
+
- No sub-agents. Main thread writes.
|
|
71
|
+
- No dashboards, no logs, no state files beyond SPEC.md.
|
|
72
|
+
- No auto-build after /ck-spec. User invokes `/ck-build` explicitly.
|
package/install.sh
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
TARGET="${1:-global}"
|
|
6
|
+
|
|
7
|
+
if [ "$TARGET" = "global" ]; then
|
|
8
|
+
CMD_DIR="$HOME/.config/opencode/commands"
|
|
9
|
+
SKILL_DIR="$HOME/.config/opencode/skills"
|
|
10
|
+
else
|
|
11
|
+
CMD_DIR="$TARGET/.opencode/commands"
|
|
12
|
+
SKILL_DIR="$TARGET/.opencode/skills"
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
mkdir -p "$CMD_DIR" "$SKILL_DIR"
|
|
16
|
+
|
|
17
|
+
cp "$SCRIPT_DIR/commands/ck-spec.md" "$CMD_DIR/"
|
|
18
|
+
cp "$SCRIPT_DIR/commands/ck-build.md" "$CMD_DIR/"
|
|
19
|
+
cp "$SCRIPT_DIR/commands/ck-check.md" "$CMD_DIR/"
|
|
20
|
+
cp -r "$SCRIPT_DIR/skills/ck-spec" "$SKILL_DIR/"
|
|
21
|
+
cp -r "$SCRIPT_DIR/skills/ck-build" "$SKILL_DIR/"
|
|
22
|
+
cp -r "$SCRIPT_DIR/skills/ck-check" "$SKILL_DIR/"
|
|
23
|
+
|
|
24
|
+
echo "cavekit installed to:"
|
|
25
|
+
echo " commands → $CMD_DIR/ck-*.md"
|
|
26
|
+
echo " skills → $SKILL_DIR/ck-*/"
|
|
27
|
+
echo ""
|
|
28
|
+
echo "Copy FORMAT.md and/or AGENTS.md to your project root as needed."
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cavekit-opencode",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Spec-driven development commands for OpenCode — compressed spec, plan-execute loop, drift detection.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "plugin.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./plugin.js"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"author": "gggiiia",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/gggiiia/cavekit-opencode.git"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"plugin.js",
|
|
18
|
+
"commands/",
|
|
19
|
+
"skills/",
|
|
20
|
+
"FORMAT.md",
|
|
21
|
+
"AGENTS.md",
|
|
22
|
+
"INSTALL.md",
|
|
23
|
+
"install.sh"
|
|
24
|
+
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"opencode",
|
|
27
|
+
"opencode-plugin",
|
|
28
|
+
"cavekit",
|
|
29
|
+
"caveman",
|
|
30
|
+
"spec-driven-development",
|
|
31
|
+
"sdd"
|
|
32
|
+
]
|
|
33
|
+
}
|
package/plugin.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
|
|
6
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
|
|
8
|
+
function opencodeConfigDir() {
|
|
9
|
+
if (process.env.XDG_CONFIG_HOME) {
|
|
10
|
+
return join(process.env.XDG_CONFIG_HOME, 'opencode');
|
|
11
|
+
}
|
|
12
|
+
return join(os.homedir(), '.config', 'opencode');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function copyDir(src, dst) {
|
|
16
|
+
if (!existsSync(src)) return;
|
|
17
|
+
mkdirSync(dst, { recursive: true });
|
|
18
|
+
for (const entry of readdirSync(src)) {
|
|
19
|
+
const s = join(src, entry);
|
|
20
|
+
const d = join(dst, entry);
|
|
21
|
+
if (statSync(s).isDirectory()) {
|
|
22
|
+
copyDir(s, d);
|
|
23
|
+
} else {
|
|
24
|
+
writeFileSync(d, readFileSync(s, 'utf8'));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function installFiles() {
|
|
30
|
+
const configDir = opencodeConfigDir();
|
|
31
|
+
|
|
32
|
+
const cmdDir = join(configDir, 'commands');
|
|
33
|
+
copyDir(join(here, 'commands'), cmdDir);
|
|
34
|
+
|
|
35
|
+
const skillDir = join(configDir, 'skills');
|
|
36
|
+
copyDir(join(here, 'skills'), skillDir);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default async () => {
|
|
40
|
+
installFiles();
|
|
41
|
+
|
|
42
|
+
return {};
|
|
43
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
Build against SPEC.md — plan-then-execute per task.
|
|
4
|
+
Trigger: "build next task", "implement spec", "build task", "run build".
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ck-build — plan-execute loop
|
|
8
|
+
|
|
9
|
+
You are running the build skill. Read `SPEC.md`. Read `FORMAT.md` if not loaded.
|
|
10
|
+
|
|
11
|
+
Dispatch on intent:
|
|
12
|
+
- **Single task** → plan respecting cited §V/§I, execute, verify.
|
|
13
|
+
- **Next task** → lowest-numbered `.` or `~` row.
|
|
14
|
+
- **All tasks** → every `.` row in §T order.
|
|
15
|
+
|
|
16
|
+
Per task:
|
|
17
|
+
1. Flip status `.` → `~` in SPEC.md.
|
|
18
|
+
2. Edit code per plan.
|
|
19
|
+
3. Run verification command.
|
|
20
|
+
4. Pass → flip `~` → `x`. Fail → backprop.
|
|
21
|
+
|
|
22
|
+
On failure: classify (code bug / spec wrong / edge case). If spec-related, backprop via /ck-spec then resume. Never silently fix without considering §B.
|
|
23
|
+
|
|
24
|
+
Write policy: only flip §T status. No other edits to SPEC.md.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
Check SPEC.md drift against code.
|
|
4
|
+
Trigger: "check spec", "drift report", "spec drift", "audit spec".
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ck-check — drift report
|
|
8
|
+
|
|
9
|
+
You are running the check skill. Read `SPEC.md`. If missing → "no spec".
|
|
10
|
+
|
|
11
|
+
Check requested sections (§V only by default):
|
|
12
|
+
- **§V** → each invariant: verify in code. Classify HOLD / VIOLATE / UNVERIFIABLE.
|
|
13
|
+
- **§I** → each interface: locate impl. Classify MATCH / DRIFT / MISSING / EXTRA.
|
|
14
|
+
- **§T** → each task: verify `x` rows, note `~`/`.` status.
|
|
15
|
+
|
|
16
|
+
Report in caveman format. Group by severity. End with one-line remedy hints.
|
|
17
|
+
|
|
18
|
+
Zero writes. No code edits. No SPEC.md edits.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
Write or update SPEC.md — spec-driven development format.
|
|
4
|
+
Trigger: "write a spec", "create spec", "amend spec", "backprop bug", "distill spec from code".
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ck-spec — spec mutator
|
|
8
|
+
|
|
9
|
+
You are running the spec skill. Load `FORMAT.md` at repo root. Read `SPEC.md` if exists.
|
|
10
|
+
|
|
11
|
+
Dispatch on intent:
|
|
12
|
+
- **New spec** → extract goal/constraints/interfaces/invariants/tasks. Write `SPEC.md`.
|
|
13
|
+
- **Distill from code** → walk repo, infer sections flagging `?` for uncertainty.
|
|
14
|
+
- **Backprop bug** → find root cause, append §B row, propose §V invariant.
|
|
15
|
+
- **Amend** → targeted edit of one spec section.
|
|
16
|
+
|
|
17
|
+
Rules:
|
|
18
|
+
- Caveman format per FORMAT.md.
|
|
19
|
+
- Preserve identifiers, paths, code verbatim.
|
|
20
|
+
- Numbering monotonic — never reuse §V.N or §B.N.
|
|
21
|
+
- Show diff. Apply on user OK.
|
|
22
|
+
- Never auto-build after spec change. User calls /ck-build.
|