@skitterbyte/skitterspec-linear 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.
Files changed (45) hide show
  1. package/README.md +56 -0
  2. package/assets/claude-md-section.md +39 -0
  3. package/assets/core/env.config.json.example +28 -0
  4. package/assets/core/env.config.md +99 -0
  5. package/assets/core/linear.config.json.example +39 -0
  6. package/assets/core/linear.config.md +121 -0
  7. package/assets/rules/spec-planning.md +152 -0
  8. package/assets/skills/spec/SKILL.md +232 -0
  9. package/assets/skills/spec-bug/SKILL.md +110 -0
  10. package/assets/skills/spec-cancel/SKILL.md +61 -0
  11. package/assets/skills/spec-complete/SKILL.md +87 -0
  12. package/assets/skills/spec-env/SKILL.md +63 -0
  13. package/assets/skills/spec-env-down/SKILL.md +64 -0
  14. package/assets/skills/spec-go/SKILL.md +134 -0
  15. package/assets/skills/spec-init/SKILL.md +84 -0
  16. package/assets/skills/spec-pull/SKILL.md +46 -0
  17. package/assets/skills/spec-push/SKILL.md +53 -0
  18. package/assets/skills/spec-ready/SKILL.md +50 -0
  19. package/assets/skills/spec-review/SKILL.md +69 -0
  20. package/assets/skills/spec-status/SKILL.md +46 -0
  21. package/bin/skitterspec-linear.js +26 -0
  22. package/package.json +38 -0
  23. package/src/cli.js +495 -0
  24. package/src/deprecate.js +138 -0
  25. package/src/env/config.js +165 -0
  26. package/src/env/integrate.js +46 -0
  27. package/src/env/provision.js +76 -0
  28. package/src/env/registry.js +95 -0
  29. package/src/env/render.js +26 -0
  30. package/src/env/resolve.js +202 -0
  31. package/src/env/teardown.js +109 -0
  32. package/src/env/trust.js +87 -0
  33. package/src/init.js +311 -0
  34. package/src/prompts.js +56 -0
  35. package/src/vendor/linear/cli-sync.js +256 -0
  36. package/src/vendor/linear/config.js +198 -0
  37. package/src/vendor/linear/mcp.js +112 -0
  38. package/src/vendor/sync-core/index.js +35 -0
  39. package/src/vendor/sync-core/src/apply.js +66 -0
  40. package/src/vendor/sync-core/src/base.js +83 -0
  41. package/src/vendor/sync-core/src/compare.js +99 -0
  42. package/src/vendor/sync-core/src/normalize.js +249 -0
  43. package/src/vendor/sync-core/src/pull.js +84 -0
  44. package/src/vendor/sync-core/src/push.js +106 -0
  45. package/src/vendor/sync-core/src/write.js +86 -0
@@ -0,0 +1,232 @@
1
+ ---
2
+ name: spec
3
+ description: Create a new spec-driven-development spec. Grills the user to a clear, shared understanding of the requirement AND the proposed solution FIRST, then writes one concise, phased, test-included, change-logged spec into specs/backlog/. Use when the user wants to plan a feature, write a spec, capture a requirement, or says "/spec" or "spec this out".
4
+ ---
5
+
6
+ # /spec — author a new spec
7
+
8
+ Produce ONE concise spec in `specs/backlog/`. Do not start coding — this skill
9
+ plans only. Implementation happens later via `/spec-go`.
10
+
11
+ Lifecycle (the governing skills) — status in parentheses:
12
+ `/spec` (Draft, backlog) → `/spec-ready` (Ready, still backlog) → `/spec-go`
13
+ (In Progress, in-progress; implement phase 1) → `/spec-complete` (Complete) /
14
+ `/spec-cancel` (Cancelled). See `.claude/rules/spec-planning.md`.
15
+
16
+ ## Phase A — reach a clear shared understanding (grill first)
17
+
18
+ Interview the user until requirement AND proposed solution are unambiguous. Do
19
+ not write the spec until this is resolved.
20
+
21
+ - Break the problem into **distinctive areas** and work them in logical order,
22
+ resolving dependencies between decisions one at a time.
23
+ - Ask **one question at a time**. For each, give your **recommended answer**.
24
+ - If a question can be answered by **reading the codebase, read it** instead of
25
+ asking. Verify endpoints/models/files actually exist before relying on them.
26
+ - Cover, at minimum, the areas that apply:
27
+ 1. **Problem & why** — what's broken/missing, who feels it, why now.
28
+ 2. **Scope & non-goals** — explicit out-of-scope items.
29
+ 3. **Affected areas** — concrete files/modules/packages this touches.
30
+ 4. **Proposed solution shape** — the chosen approach and the alternatives
31
+ rejected, with the reason (this becomes "Decisions").
32
+ 5. **Data / API impact** — schema/model changes, new endpoints, and
33
+ **backward compatibility** (additive = safe; breaking = needs explicit
34
+ permission and coordination).
35
+ 6. **Security & multi-tenancy** — authz, tenant scoping, untrusted input.
36
+ 7. **Edge cases & failure modes.**
37
+ 8. **Testing approach** — what proves each phase correct.
38
+ 9. **Isolation stack** *(only when `specs/.core/env.config.json` exists)* — does
39
+ this spec touch the DB / stateful services (so its worktree needs a Docker
40
+ stack), or is a plain worktree enough? Default `worktree`; escalate to
41
+ `worktree + docker` only when it must. This sets the `> **Stack:**` header
42
+ that `/spec-go` acts on (it can be escalated later). Skip when isolation
43
+ isn't enabled — leave the default `worktree`.
44
+ 10. **Open questions** — anything still undecided.
45
+
46
+ Stop grilling when there are no unresolved branches that would change the spec.
47
+ Briefly play back the agreed understanding before writing.
48
+
49
+ ## Phase B — write the spec
50
+
51
+ This skill is for **features**. For bugs, use `/spec-bug` (test-first, red→green).
52
+
53
+ - **Every spec is a folder** — never a bare file, even for a one-line change:
54
+ `specs/backlog/feat-<kebab-name>/`. Create it with `mkdir -p`.
55
+ - The entry point is **always `00-overview.md`** — the index/dashboard for the
56
+ spec. It holds the header block, Problem, Decisions, Solution overview, the
57
+ **phase index** (a table linking to each phase file), Open questions, State
58
+ log, and Changelog. It does **not** hold the per-phase task lists.
59
+ - **Each phase is its own file** — `01-<phase-slug>.md`, `02-<phase-slug>.md`, …
60
+ numbered in execution order; the slug is a short kebab description of the phase
61
+ goal (e.g. `01-data-model.md`, `02-api-endpoints.md`). The phase file holds
62
+ that phase's goal, its task checkboxes (tests included), and any phase-specific
63
+ notes. **Even a single-phase spec gets `01-….md`** — never lump phase tasks
64
+ into `00-overview.md`. This keeps each phase easy to dive into on its own.
65
+ - Choose a short kebab-case name and **prefix it `feat-`** (the bug counterpart
66
+ uses `bug-`).
67
+
68
+ Use this template (keep it **as concise as possible** — no filler, no restating
69
+ the codebase, link rather than duplicate):
70
+
71
+ ```markdown
72
+ # <Feature title>
73
+
74
+ > **Type:** Feature
75
+ > **Status:** Draft — not started
76
+ > **Author:** <git user.name — `git config user.name`>
77
+ > **Developer:** —
78
+ > **Raised:** <YYYY-MM-DD (today)>
79
+ > **Area:** <comma-separated files/modules this touches>
80
+ > **Stack:** <worktree — or "worktree + docker" if it touches the DB/stateful
81
+ > services; only acted on when isolation is enabled — see Phase A item 9>
82
+
83
+ ## Problem
84
+
85
+ <2–6 sentences: what's wrong/missing and why it matters. No fluff.>
86
+
87
+ ## Decisions
88
+
89
+ <Numbered, confirmed decisions from Phase A. Each: the choice + one-line why,
90
+ and the rejected alternative when it sharpens the choice. This is the heart of
91
+ the spec — be specific.>
92
+
93
+ ## Solution overview
94
+
95
+ <Short prose or bullets describing the chosen shape end-to-end. Optional small
96
+ schema/grammar/output snippets where they remove ambiguity.>
97
+
98
+ ## Phases
99
+
100
+ Each phase lives in its own file in this folder. Status: ⬜ not started ·
101
+ 🔄 in progress · ✅ done.
102
+
103
+ | # | Phase | Status | File |
104
+ |---|-------|--------|------|
105
+ | 1 | <goal> | ⬜ | [01-<phase-slug>.md](01-<phase-slug>.md) |
106
+ | 2 | <goal> | ⬜ | [02-<phase-slug>.md](02-<phase-slug>.md) |
107
+
108
+ ## Open questions
109
+
110
+ - [ ] <anything deferred — or "None">
111
+
112
+ ## State log
113
+
114
+ | Date | Status | Folder | By |
115
+ |------|--------|--------|----|
116
+ | <YYYY-MM-DD> | Draft | backlog | <author> |
117
+
118
+ ## Changelog
119
+
120
+ - <YYYY-MM-DD> — Spec created.
121
+ ```
122
+
123
+ Then create **one file per phase** (`01-<phase-slug>.md`, `02-…`, in execution
124
+ order). Each phase file uses this template:
125
+
126
+ ```markdown
127
+ # Phase 1 — <goal> ⬜
128
+
129
+ > Spec: [00-overview.md](00-overview.md) · **Status:** Not started
130
+
131
+ **Goal:** <one line — what this phase delivers and how it's proven>.
132
+
133
+ ## Tasks
134
+
135
+ - [ ] <clear, verb-first task>
136
+ - [ ] <clear, verb-first task>
137
+ - [ ] Add/extend tests covering this phase; run the project's typecheck and
138
+ test commands (see `.claude/rules/spec-planning.md`) — green before the
139
+ phase is done.
140
+
141
+ ## Notes
142
+
143
+ <Phase-specific decisions, gotchas, or context. Delete if empty.>
144
+ ```
145
+
146
+ Keep the `00-overview.md` phase index and the phase files in sync: the index row
147
+ is the one-line summary + status; the phase file is the detail.
148
+
149
+ The **State log** is the audit trail of folder/status transitions — every
150
+ lifecycle skill (`/spec-ready`, `/spec-go`, `/spec-complete`, `/spec-cancel`)
151
+ appends one row when it moves the spec. The **Changelog** is for decisions and
152
+ course-corrections only — keep the two separate.
153
+
154
+ Rules for the spec body:
155
+
156
+ - **Every phase is independently shippable and ends with tests.** A phase is
157
+ not "done" until its tests are written and the suite is green. Bake a test
158
+ task into each phase — never a separate "testing phase" at the end only.
159
+ - **Tasks are checkboxes** (`- [ ]`), clear, verb-first, and granular enough to
160
+ finish in one session. They live in the **phase files**, not the overview. Use
161
+ `⬜`/`🔄`/`✅` on each phase-file heading and mirror it in the `00-overview.md`
162
+ phase index.
163
+ - **Honour project conventions** when writing tasks — reference the relevant
164
+ `.claude/rules/*.md` rather than re-explaining them.
165
+ - **Changelog** is mandatory and lives in the spec. Every later decision or
166
+ course-correction gets a dated one-line entry. Convert relative dates to
167
+ absolute.
168
+ - Keep it tight. If a section adds no information, delete it.
169
+
170
+ ## Phase C — finish up
171
+
172
+ After writing, tell the user the path and that it's a `Draft` in `backlog`. Next
173
+ step is `/spec-ready` once it's groomed, then `/spec-go` to start building.
174
+
175
+ ## Phase D — record the isolation stack (only if configured)
176
+
177
+ **Only when `specs/.core/env.config.json` exists** (per-spec isolation is
178
+ enabled), make sure the `> **Stack:**` header reflects the Phase A item 9
179
+ decision — `worktree` (default) or `worktree + docker` when it touches the DB /
180
+ stateful services. Nothing to provision now: `/spec-go` gives every in-progress
181
+ spec its own worktree automatically, and brings up Docker only when the Stack
182
+ says so. Mention the operator can escalate the Stack later (edit the header, or
183
+ run `/spec-env <name>` to add Docker to an existing worktree). If
184
+ `env.config.json` is absent, isolation is off — leave the default `worktree` and
185
+ finish as above.
186
+
187
+ ## Phase E — link to a ticketing provider (only if one is installed)
188
+
189
+ **Only when a ticketing provider is installed and configured** (it ships the
190
+ `/spec-push` · `/spec-pull` · `/spec-status` skills and a provider config under
191
+ `specs/.core/`). If none is present, skip this phase entirely — the spec stays
192
+ local-only and `/spec` behaves exactly as above. When a provider is present, link
193
+ the spec to the tracker after writing it, so status and discussion live there
194
+ while the repo stays the co-authoring surface — follow the provider's link steps
195
+ below (nothing to do here without one).
196
+
197
+ **Only when `specs/.core/linear.config.json` exists** (Linear sync is opted in).
198
+ If it's absent, skip this phase entirely — the spec stays local-only and `/spec`
199
+ behaves exactly as above. When present, after writing the spec, link it to Linear
200
+ so status and discussion live there while the repo stays the co-authoring surface:
201
+
202
+ - **Discover the Linear MCP tools at runtime** (don't hardcode names). If Linear
203
+ isn't connected/authed, relay the fix and stop — leave the spec written and
204
+ local; the user can link it later with `/spec-push`. Do nothing destructive.
205
+ - **Create the Project** from the spec: name from the title, description from the
206
+ `00-overview.md` plan. Attach the `initiativeId` from `linear.config.json` when
207
+ one is set.
208
+ - **Create a Milestone per phase** (the `mapping.phases` target — milestones by
209
+ default), named from each phase file, in execution order.
210
+ - **Add the frontmatter block** to `00-overview.md` (above the `#` title) so the
211
+ spec is linkable:
212
+
213
+ ```yaml
214
+ ---
215
+ linear_project_id: "<uuid>"
216
+ linear_identifier: "<TEAM-123>"
217
+ linear_url: "https://linear.app/..."
218
+ spec_status: "backlog"
219
+ last_synced_at: "<ISO-8601 now>"
220
+ ---
221
+ ```
222
+
223
+ - **Write the initial base sidecar** so the spec starts clean and non-diverged —
224
+ run `skitterspec spec-sync normalize <spec>` to capture the local snapshot as the
225
+ committed base (`sync.baseDir`). `/spec-status` should report in-sync right after.
226
+ - **Echo the branch name** from `branch.pattern` so the user knows what `/spec-go`
227
+ will fork.
228
+
229
+ Leave committing to the existing convention (the user commits the spec as usual)
230
+ and **never auto-push git** — Linear's own automation reacts to real branch/PR
231
+ events later. Report the Linear project URL and the base as part of Phase C's
232
+ finish-up message.
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: spec-bug
3
+ description: Investigate a bug, capture it as a Bug-type spec, and drive it red→green. ALWAYS starts by reproducing the bug with a failing test, then writes the spec and works the test to green. Creates specs/in-progress/bug-<name>/00-overview.md. Use when the user reports a bug, says "/spec-bug", "investigate this bug", "this is broken — find and fix it", or pastes an error/stack trace.
4
+ ---
5
+
6
+ # /spec-bug — investigate a bug, prove it with a failing test, fix it
7
+
8
+ This is the **bug** counterpart to `/spec` (which is for **features**, plan-only).
9
+ Unlike `/spec`, this skill is hands-on and test-first: it reproduces the bug as a
10
+ **failing test (RED)**, captures a lean Bug spec, then works the test to **GREEN**.
11
+
12
+ Spec type convention (see `.claude/rules/spec-planning.md`):
13
+ - Bug specs are named `bug-<kebab-name>`; feature specs `feat-<kebab-name>`.
14
+ - Every spec header carries `> **Type:** Bug` (or `Feature`).
15
+
16
+ ## 1. Reproduce & isolate (light investigation)
17
+
18
+ Bugs are concrete — confirm, don't over-grill. Establish:
19
+
20
+ - **Repro:** exact steps / input that triggers it. Ask only if you can't derive it.
21
+ - **Expected vs actual:** what *should* happen vs what does.
22
+ - **Scope & blast radius:** which module(s)/endpoint(s)/package; one tenant or all.
23
+ - **Root cause:** read the code, trace it to `file:line`. Compare a working path
24
+ against the broken one (the bug usually lives in the differential). Do NOT
25
+ patch a symptom before you understand the cause.
26
+
27
+ ## 2. Write the failing test FIRST (RED) — mandatory
28
+
29
+ Encode the **correct** (expected) behaviour as a test, then run it and confirm it
30
+ **fails for the right reason**:
31
+
32
+ - Put it where the suite already covers that area. Reuse existing test helpers /
33
+ factories; follow the project's test rules (see `.claude/rules/`). Never
34
+ hardcode dates — compute them relative to now.
35
+ - Run it with the project's test command. Quote the red output. A test that
36
+ passes before the fix proves nothing — keep refining the assertion until it
37
+ genuinely captures the bug.
38
+
39
+ ## 3. Write the Bug spec
40
+
41
+ Create the spec **folder** `specs/in-progress/bug-<kebab-name>/` with its entry
42
+ point `00-overview.md` (every spec is a folder — never a bare file). A bug is
43
+ usually a single-pass fix, so the `## Fix` block can live directly in
44
+ `00-overview.md`. **If the fix needs phasing** (large/uncertain root cause),
45
+ split it into phase files (`01-<slug>.md`, `02-…`) with a phase index in
46
+ `00-overview.md`, exactly like a feature spec. It starts in `in-progress`
47
+ because work is already underway. Keep it lean:
48
+
49
+ ```markdown
50
+ # Bug: <short title>
51
+
52
+ > **Type:** Bug
53
+ > **Status:** In Progress — fixing (red test added)
54
+ > **Author:** <git user.name — who reported/captured it>
55
+ > **Developer:** <git user.name — you, since you're fixing it now>
56
+ > **Raised:** <YYYY-MM-DD (today)>
57
+ > **Area:** <files/modules>
58
+
59
+ ## Symptom
60
+
61
+ <observed wrong behaviour + repro steps; paste the error/stack if any>
62
+
63
+ ## Root cause
64
+
65
+ <the actual cause, at `file:line`. One paragraph — be specific.>
66
+
67
+ ## Failing test (red)
68
+
69
+ <test name + path; what it asserts. How to run it. Paste the red failure line.>
70
+
71
+ ## Fix
72
+
73
+ - [ ] <the minimal change that addresses the root cause, not the symptom>
74
+ - [ ] Failing test now passes (GREEN); run the project's typecheck and test
75
+ commands — confirm no regressions.
76
+ - [ ] <any follow-up hardening, or "None">
77
+
78
+ ## State log
79
+
80
+ | Date | Status | Folder | By |
81
+ |------|--------|--------|----|
82
+ | <YYYY-MM-DD> | In Progress | in-progress | <developer> |
83
+
84
+ ## Changelog
85
+
86
+ - <YYYY-MM-DD> — Bug reproduced; failing test added (red).
87
+ ```
88
+
89
+ The **State log** is the folder/status audit trail; later transitions
90
+ (`/spec-complete`, `/spec-cancel`) append a row. The **Changelog** is for the
91
+ fix narrative and decisions — keep them separate.
92
+
93
+ ## 4. Drive to GREEN
94
+
95
+ - Implement the **minimal, root-cause** fix. Match surrounding code; honour all
96
+ project rules (see `.claude/rules/`).
97
+ - Re-run the failing test → it must pass. Then run the project's typecheck and
98
+ test commands to confirm no regressions. Quote results.
99
+ - Tick the Fix tasks, add a Changelog line (`- <date> — Fixed: <one line>; test green`).
100
+
101
+ If the root cause is large/uncertain and can't be fixed in one pass: keep the red
102
+ test, split the fix into phase files (`01-<slug>.md` …) with a phase index in
103
+ `00-overview.md`, and leave the spec in `in-progress` for `/spec-go` to continue.
104
+ Say so explicitly — don't fake green.
105
+
106
+ ## 5. Report
107
+
108
+ Summarise: root cause, the failing→passing test, the fix, and the full test
109
+ result. The spec stays in `in-progress`; suggest `/spec-complete` to verify and
110
+ archive it. Do **not** `git commit` unless the user asks.
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: spec-cancel
3
+ description: Cancel a spec — capture the reason, record final progress, stamp the reason on the spec header, then move it into specs/cancelled/. Targets a spec by name (arg) or the spec currently in context. Use when the user says "/spec-cancel", "drop this spec", "we're not doing this spec", or "shelve <spec>".
4
+ ---
5
+
6
+ # /spec-cancel — record, stamp a reason, archive a spec
7
+
8
+ ## 1. Identify the target spec
9
+
10
+ - Use the name/path argument if given, else the spec **in context**. If unclear,
11
+ ask which spec.
12
+ - Locate it under `specs/` (any bucket — `backlog/`, `in-progress/`, …). Entry point
13
+ is its `00-overview.md`; phases are separate files (`01-<slug>.md`, `02-…`) listed
14
+ in its phase index (legacy specs may be a bare `<name>.md`).
15
+
16
+ ## 2. Ask for the cancellation reason — required
17
+
18
+ Ask the user **why** it's being cancelled (e.g. superseded by X, descoped, no
19
+ longer needed, blocked indefinitely). Do not proceed without a reason; capture
20
+ it verbatim/condensed for the header.
21
+
22
+ ## 3. Double-check and record progress
23
+
24
+ - Read the overview and every phase file and reconcile task state with reality:
25
+ tick anything that was actually completed before cancelling so the record is
26
+ honest about what landed.
27
+ - Note any partial/abandoned work so it isn't mistaken for unstarted.
28
+
29
+ ## 4. Stamp the spec
30
+
31
+ Update the **Status** header in the entry point so the reason is visible at the
32
+ top:
33
+
34
+ ```
35
+ > **Status:** Cancelled (<YYYY-MM-DD>) — <reason>
36
+ ```
37
+
38
+ Append a **State log** row:
39
+ `| <YYYY-MM-DD> | Cancelled | cancelled | <git user.name> |`.
40
+
41
+ Add a **Changelog** entry:
42
+ `- <YYYY-MM-DD> — Cancelled: <reason>.`
43
+
44
+ ## 5. Move to cancelled
45
+
46
+ `mkdir -p specs/cancelled` then **`git mv`** the file or folder:
47
+ `git mv "specs/<bucket>/<name>" "specs/cancelled/<name>"` (preserve history;
48
+ move the whole folder).
49
+
50
+ ## 6. Report
51
+
52
+ Confirm the cancellation, the reason recorded, and the new location. Do **not**
53
+ `git commit` unless the user asks.
54
+
55
+ ## 7. Offer teardown (opt-in, only if configured)
56
+
57
+ **Only when `specs/.core/env.config.json` exists**, offer — don't force — to
58
+ reclaim the cancelled spec's environment: "Want me to run `/spec-env-down
59
+ <name>` to remove its worktree, stack, volumes, and free its slot?" It respects
60
+ the teardown guards (won't destroy a dirty/unpushed worktree without `--force`).
61
+ If `env.config.json` is absent, skip this entirely — behave exactly as before.
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: spec-complete
3
+ description: Finish a spec — verify all phases are genuinely done, update progress, then move it into specs/complete/. Targets a spec by name (arg) or the spec currently in context. Use when the user says "/spec-complete", "mark this spec done", or "this spec is complete".
4
+ ---
5
+
6
+ # /spec-complete — verify, finalise, archive a spec
7
+
8
+ ## 1. Identify the target spec
9
+
10
+ - Use the name/path argument if given, else the spec **in context**. If unclear,
11
+ ask which spec.
12
+ - Locate the spec folder under `specs/` (usually `specs/in-progress/`). Entry
13
+ point is its `00-overview.md`; phases are separate files (`01-<slug>.md`, `02-…`)
14
+ listed in its phase index (legacy specs may be a bare `<name>.md`).
15
+
16
+ ## 2. Double-check progress — don't rubber-stamp
17
+
18
+ Before marking complete, confirm the work is actually finished:
19
+
20
+ - Read every phase file. For each **unchecked** task, check whether it is in fact
21
+ done in the code — tick it (`- [x]`) if so, or surface it if not.
22
+ - Run the project's typecheck and test commands. The suite must be **green** to
23
+ call a spec complete.
24
+ - For a **Bug** spec (`Type: Bug`), confirm the originally-failing test named in
25
+ the spec now passes — that test is the proof the bug is fixed.
26
+ - If genuinely incomplete work remains, **stop and tell the user** rather than
27
+ forcing completion. Offer to finish it (`/spec-go`) or to complete with the
28
+ remaining items explicitly listed as deferred.
29
+
30
+ ## 3. Update the spec
31
+
32
+ - Tick all completed tasks in the phase files; flip every finished phase-file
33
+ heading **and** every row in the `00-overview.md` phase index to `✅`.
34
+ - Set the **Status** header in the entry point:
35
+ `> **Status:** Complete (<YYYY-MM-DD>)`.
36
+ - Append a **State log** row:
37
+ `| <YYYY-MM-DD> | Complete | complete | <git user.name> |`.
38
+ - Add a **Changelog** entry:
39
+ `- <YYYY-MM-DD> — Completed; all phases done, tests green.`
40
+ (Note any consciously-deferred items here too.)
41
+
42
+ ## 4. Move to complete
43
+
44
+ `mkdir -p specs/complete` then **`git mv`** the file or folder:
45
+ `git mv "specs/in-progress/<name>" "specs/complete/<name>"` (preserve history;
46
+ move the whole folder). The `specs/complete/` folder is the record of finished
47
+ specs — `git log`/the per-spec State log give the completion order.
48
+
49
+ ## 5. Report
50
+
51
+ Confirm the move, the final test result, and list anything deferred. Do **not**
52
+ `git commit` unless the user asks.
53
+
54
+ ## 6. Integrate onto the base branch (opt-in, only if isolated)
55
+
56
+ **Only when `specs/.core/env.config.json` exists and the spec is on a worktree**
57
+ (it was provisioned by `/spec-go`). Otherwise skip this entirely — a non-isolated
58
+ spec has nothing to land, and `/spec-complete` behaves exactly as before. When it
59
+ applies, offer to land the finished branch on the base branch so the work reaches
60
+ `main` (or your configured `baseBranch`) in one flow:
61
+
62
+ 1. **Require a clean worktree.** The completion edits (status flip, the
63
+ `git mv` to `complete/`) must be committed first — integrate refuses a dirty
64
+ tree. If it's dirty, offer `/commit` and **stop**; don't auto-commit.
65
+ 2. **Plan + execute.** Run `skitterspec spec-env integrate <name>` and run the
66
+ printed commands **in order**:
67
+ - `git -C <worktree> rebase <base>` — replay the branch onto base.
68
+ - `git -C <mainRepoPath> merge --ff-only <branch>` — fast-forward base.
69
+ On a **rebase conflict** (non-zero exit), run
70
+ `git -C <worktree> rebase --abort`, relay the conflict, and **stop** — leave it
71
+ to the user; do not offer teardown.
72
+ On a **no-op** ("already landed"), just say so and continue.
73
+ 3. **Re-test on base.** Run the project's test command from the primary checkout;
74
+ it must be **green** before you call the landing done.
75
+ 4. **Report** the landing (base branch, fast-forward result). It **never pushes** —
76
+ mention the user can `git push` the base branch themselves.
77
+
78
+ ## 7. Offer teardown (opt-in, only if configured)
79
+
80
+ **Only when `specs/.core/env.config.json` exists**, offer — don't force — to
81
+ reclaim the finished spec's environment: "Want me to run `/spec-env-down <name>`
82
+ to remove its worktree, delete its branch, stack, volumes, and free its slot?"
83
+ Post-integrate the branch is merged into base, so teardown needs **no `--force`**
84
+ and deletes the branch (`git branch -d`) as part of the plan. It still respects
85
+ the guards (won't destroy a dirty or unpushed-and-unmerged worktree without
86
+ `--force`). If `env.config.json` is absent, skip this entirely — behave exactly as
87
+ before.
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: spec-env
3
+ description: Provision an isolated environment for a spec — a git worktree on its own branch + a namespaced Docker stack (isolated containers/networks/volumes + a reserved port block), plus an optional editor/terminal opener. Runs `skitterspec spec-env up` and executes the printed git/docker/open commands. Opt-in — needs specs/.core/env.config.json. Use when the user says "/spec-env", "spin up an environment for <spec>", "give this spec its own worktree/stack", or "isolate <spec>".
4
+ ---
5
+
6
+ # /spec-env — provision an isolated environment for a spec
7
+
8
+ Give an in-progress spec its own **git worktree** (a sibling directory on its own
9
+ branch, no stashing) + a **namespaced Docker stack** (`COMPOSE_PROJECT_NAME`
10
+ isolates containers/networks/volumes; `PORT_OFFSET` reserves a port block), so N
11
+ specs run side by side and `main` stays clean. An optional `open.command` then
12
+ opens the worktree however you like.
13
+
14
+ This skill is **opt-in**: it only works when `specs/.core/env.config.json` exists
15
+ (copy `env.config.json.example` to adopt it). If it's absent, tell the user how
16
+ to enable it and stop.
17
+
18
+ ## 1. Identify the target spec
19
+
20
+ - Use the spec named as an argument, else the spec **currently in context**. If
21
+ neither is clear, ask which spec.
22
+
23
+ ## 2. Plan the environment
24
+
25
+ Run the engine — it allocates the slot (idempotent), persists the registry, and
26
+ **prints** the plan (worktree path, branch, project name, port block, the exact
27
+ commands, the `.env` contents, and the opener):
28
+
29
+ ```
30
+ skitterspec spec-env up <spec>
31
+ ```
32
+
33
+ If it reports the feature isn't enabled, relay that and stop — do not hand-roll a
34
+ worktree/stack.
35
+
36
+ ## 3. Execute the printed side effects
37
+
38
+ Run the printed commands **in order**, exactly as printed:
39
+
40
+ 1. **`git worktree add …`** — creates the sibling worktree on its branch. It is a
41
+ **sibling** of this checkout, **never nested** inside it. If the worktree
42
+ already exists, the engine prints the *attach* form (no `-b`) — do not clobber
43
+ an existing worktree/branch.
44
+ 2. **Write the `.env`** — write the printed `.env` contents into the new
45
+ worktree's env file (default `.env`). Do this *after* the worktree exists.
46
+ 3. **`docker compose … up -d`** — only printed when Docker is enabled. Brings the
47
+ namespaced stack up in the spec's reserved port block.
48
+ 4. **Opener** — if an `open.command` line was printed, run it (e.g. opens the
49
+ worktree in your editor/terminal). Skipped silently when unset.
50
+ 5. **Trust the worktree root for this session** — the engine already wrote the
51
+ printed `trusted:` root into `.claude/settings.local.json` (gitignored, so it
52
+ persists for future sessions). That file likely won't hot-reload mid-session,
53
+ so also run `/add-dir <trusted root>` now to lift `Edit`/`Write` prompts for
54
+ the **current** session. (If the engine printed a `trusted: ! …` warning,
55
+ `settings.local.json` isn't valid JSON — fix it, then re-run.)
56
+
57
+ ## 4. Report
58
+
59
+ Echo the summary: worktree path, branch, project name, the allocated slot + port
60
+ block, and whether the stack was brought up. **Idempotent** — re-running attaches
61
+ to the existing slot/worktree and never reallocates.
62
+
63
+ Tear down later with `/spec-env-down <spec>`.
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: spec-env-down
3
+ description: Tear down a spec's isolated environment — stop and remove its namespaced Docker stack (optionally backing up + dropping volumes), remove its git worktree, and free its slot. Guards refuse teardown on a dirty or unpushed worktree unless --force. Runs `skitterspec spec-env down` and executes the printed commands. Opt-in — needs specs/.core/env.config.json. Use when the user says "/spec-env-down", "tear down <spec>'s environment", "clean up the worktree/stack for <spec>", or "reclaim <spec>'s slot".
4
+ ---
5
+
6
+ # /spec-env-down — tear down a spec's isolated environment
7
+
8
+ Reverse `/spec-env`: stop + remove the spec's Docker stack, remove its git
9
+ worktree, and free its slot so the ports/slot are reclaimed. **Volumes are the
10
+ only destructive part** — dropped by default (to reclaim disk) unless
11
+ `--keep-volumes`, and always backed up first when `docker.backupCommand` is set.
12
+
13
+ Opt-in: only works when `specs/.core/env.config.json` exists. If absent, say so
14
+ and stop.
15
+
16
+ ## 1. Identify the target spec
17
+
18
+ - Use the spec named as an argument, else the spec **currently in context**. If
19
+ neither is clear, ask which spec.
20
+
21
+ ## 2. Plan the teardown
22
+
23
+ Run the engine — it checks the guards, frees the slot, and **prints** the plan:
24
+
25
+ ```
26
+ skitterspec spec-env down <spec> [--keep-volumes] [--force]
27
+ ```
28
+
29
+ - **`--keep-volumes`** — keep the stack's data (plain `down`, no backup, no drop).
30
+ - **`--force`** — override the guards below.
31
+
32
+ ## 3. Handle a guard block
33
+
34
+ If the CLI reports **blocked** (the worktree has uncommitted changes, or unpushed
35
+ commits that aren't yet merged into the base branch), **relay the reason and
36
+ stop** — do not destroy unreviewed work. Offer the user `--force` (and suggest
37
+ committing/pushing first). Only re-run with `--force` when the user explicitly
38
+ asks. **A branch already merged into the base needs no `--force`** — the unpushed
39
+ guard treats "landed on base" as safe, so a completed spec (post-`/spec-complete`
40
+ integrate) tears down cleanly even with no remote.
41
+
42
+ ## 4. Execute the printed side effects
43
+
44
+ When not blocked, run the printed commands **in order**, exactly as printed:
45
+
46
+ 1. **Backup** (only when a `docker.backupCommand` is configured and volumes are
47
+ being dropped) — writes a dump under `.spec-env/backups/` before anything is
48
+ destroyed.
49
+ 2. **`docker compose … down`** — with `--volumes` unless `--keep-volumes`.
50
+ 3. **`git worktree remove …`** — removes the sibling worktree.
51
+ 4. **`git branch -d <branch>`** — deletes the spec's branch (freed by the worktree
52
+ removal above). It's `-d` (merged-only), never `-D`: if it reports the branch
53
+ isn't fully merged, **relay that and stop** — don't `-D` it. That only happens
54
+ on a `--force` teardown of unmerged work; the user can delete it by hand if
55
+ they're sure.
56
+
57
+ The slot is already freed by the CLI.
58
+
59
+ ## 5. Report
60
+
61
+ Confirm what happened: worktree removed, branch deleted, containers down, volumes
62
+ **dropped|kept**, slot freed, and the backup path (if any). If a `git branch -d`
63
+ was refused (unmerged), say so. If the spec wasn't provisioned / was already torn
64
+ down, the CLI reports a clean **no-op** — relay that; it's not an error.