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 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.