@skitterbyte/skitterspec-linear 10.7.0 → 11.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/MIGRATION.md +36 -0
- package/README.md +3 -3
- package/assets/claude-md-section.md +13 -51
- package/assets/commands/spec-live.md +2 -2
- package/assets/core/SETUP.md +1 -1
- package/assets/core/env.config.json.example +4 -1
- package/assets/core/env.config.md +26 -6
- package/assets/core/linear.config.json.example +2 -1
- package/assets/core/linear.config.md +46 -4
- package/assets/rules/spec-planning.md +30 -10
- package/assets/skills/spec/SKILL.md +15 -10
- package/assets/skills/spec-bug/SKILL.md +43 -9
- package/assets/skills/spec-cancel/SKILL.md +12 -0
- package/assets/skills/spec-complete/SKILL.md +26 -5
- package/assets/skills/spec-hotfix/SKILL.md +42 -8
- package/assets/skills/spec-init/SKILL.md +16 -6
- package/assets/skills/spec-linear-setup/SKILL.md +1 -1
- package/assets/skills/spec-next/SKILL.md +141 -0
- package/assets/skills/spec-push/SKILL.md +2 -2
- package/assets/skills/spec-review/SKILL.md +5 -5
- package/assets/skills/spec-start/SKILL.md +146 -0
- package/assets/skills/spec-status/SKILL.md +2 -2
- package/assets/skills/spec-sync/SKILL.md +9 -1
- package/assets/skills/spec-to-main/SKILL.md +7 -5
- package/package.json +1 -1
- package/src/cli.js +234 -20
- package/src/env/config.js +24 -1
- package/src/env/integrate.js +61 -1
- package/src/env/live.js +27 -3
- package/src/env/provision.js +58 -1
- package/src/env/teardown.js +41 -3
- package/src/init.js +21 -12
- package/src/prompts.js +31 -3
- package/src/vendor/linear/cli-sync.js +55 -4
- package/src/vendor/linear/config.js +70 -3
- package/src/vendor/linear/released.js +65 -5
- package/assets/skills/spec-go/SKILL.md +0 -233
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: spec-go
|
|
3
|
-
description: Promote a spec into active development and build the next phase — provisions its worktree, brings up its host dev servers (confirm first), then implements the phase with tests. Targets a spec by name (arg) or the spec currently in context. Use when the user says "/spec-go", "start this spec", "begin implementing <spec>", or "let's build the next phase".
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# /spec-go — start (or continue) implementing a spec
|
|
7
|
-
|
|
8
|
-
The "up" button: it promotes the spec, provisions its worktree, brings its host
|
|
9
|
-
dev servers up on the spec's reserved ports (with your OK), then builds the phase.
|
|
10
|
-
Diverting your browser to the spec is a separate explicit step the **user**
|
|
11
|
-
types — `/spec-connect` (a slash command, not a skill you can invoke).
|
|
12
|
-
|
|
13
|
-
## 1. Identify the target spec
|
|
14
|
-
|
|
15
|
-
- If a name/path is given as an argument, use it.
|
|
16
|
-
- Otherwise use the spec **currently in context** (the one just created or
|
|
17
|
-
discussed). If neither is clear, ask which spec.
|
|
18
|
-
- Locate it by searching `specs/` (check `specs/backlog/` first, then the other
|
|
19
|
-
buckets). A spec is a `<name>/` folder whose entry point is `00-overview.md`,
|
|
20
|
-
with **one file per phase** alongside it (`01-<slug>.md`, `02-…`). Legacy specs
|
|
21
|
-
may be a bare `<name>.md`, or a `00-overview.md` with inline phases — handle
|
|
22
|
-
those too.
|
|
23
|
-
|
|
24
|
-
## 2. Move it into development
|
|
25
|
-
|
|
26
|
-
**Live check first (isolation only).** If per-spec isolation is enabled, before
|
|
27
|
-
provisioning run `skitterspec spec-env live status <name>` and read its `live:`
|
|
28
|
-
line. If it says **`live: yes`**, this spec is already checked out in the
|
|
29
|
-
**primary checkout** (you took it live with `/spec-live`) — **do not provision,
|
|
30
|
-
do not run `spec-env up`, and do not "work in the worktree"**. Its branch lives
|
|
31
|
-
in the primary checkout and its worktree is on a **detached HEAD**, so a commit
|
|
32
|
-
made in the worktree would strand on that detached HEAD and never reach the
|
|
33
|
-
branch. Instead skip the provisioning bullets and step 2b, leave the spec where
|
|
34
|
-
it is, and go straight to **step 4**, implementing the phase **in the primary
|
|
35
|
-
checkout on the branch** — edits and commits there advance the branch, and
|
|
36
|
-
`/spec-complete` lands them. (`spec-env up` refuses while live and says the same.
|
|
37
|
-
To return to an isolated worktree instead, ask the user to type `/spec-live main`
|
|
38
|
-
first, then re-run `/spec-go`.)
|
|
39
|
-
|
|
40
|
-
**If per-spec isolation is enabled** (`specs/.core/env.config.json` exists), the
|
|
41
|
-
spec **isn't already live** (the check above), and it doesn't already have a
|
|
42
|
-
worktree, provision it **first**, so all the housekeeping below lands on the
|
|
43
|
-
spec's branch and never on `main`:
|
|
44
|
-
|
|
45
|
-
**Opt-out:** if the user passes `--no-worktree` (or explicitly asks to work in
|
|
46
|
-
place), skip the provisioning bullets below and build on the current branch — the
|
|
47
|
-
same "in place otherwise" path used when isolation is off. Warn that the work
|
|
48
|
-
will land wherever you currently are (usually `main`); reserve it for a trivial
|
|
49
|
-
change or an explicit request.
|
|
50
|
-
|
|
51
|
-
- Run `skitterspec spec-env up <name>` (the `spec-env` CLI engine). It is a
|
|
52
|
-
**planner: it prints commands and creates nothing itself.** Under
|
|
53
|
-
`to provision, run:` it emits the `git worktree add` on a branch forked from
|
|
54
|
-
`main` and — only when the spec's `> **Stack:**` header is
|
|
55
|
-
`worktree + docker` — the Docker bring-up.
|
|
56
|
-
**Run those commands and confirm they succeeded** before anything below: every
|
|
57
|
-
later step assumes the worktree exists, and the header line says
|
|
58
|
-
`(plan — nothing created yet)` precisely because at that point it doesn't.
|
|
59
|
-
Print the worktree path and the opener command it emits.
|
|
60
|
-
- **Bootstrap the worktree's dependencies.** A fresh worktree has an empty
|
|
61
|
-
working tree — no installed dependencies, and none of the repo's gitignored
|
|
62
|
-
files (`.env`, local secret/config overrides) — so git hooks, typechecks,
|
|
63
|
-
builds and tests fail until they're in place. `spec-env up` prints the
|
|
64
|
-
project's configured **`then, in the worktree, run:`** commands — run them in
|
|
65
|
-
order, before doing anything else. Each one begins by `cd`-ing into the
|
|
66
|
-
worktree, so it works from any cwd and cannot quietly act on the main
|
|
67
|
-
checkout; if the worktree is missing it prints
|
|
68
|
-
**`no worktree at … — run the provisioning commands first`** and exits
|
|
69
|
-
non-zero. Seeing that means the `git worktree add` above didn't run or didn't
|
|
70
|
-
work — fix that before going on. Those commands are: first any
|
|
71
|
-
**file seeding** (from `env.config.json` → `seedFiles`), which symlinks or
|
|
72
|
-
copies the configured gitignored files from the main checkout into the fresh
|
|
73
|
-
worktree so setup can rely on them; then the **`setup`** commands (e.g. an
|
|
74
|
-
install command). With neither configured there's nothing to run; add
|
|
75
|
-
`seedFiles`/`setup` if agents keep stalling on a missing `.env` or dependencies.
|
|
76
|
-
- **Trust the worktree for this session.** The engine wrote the printed
|
|
77
|
-
`trusted:` root into `.claude/settings.local.json` (gitignored) so future
|
|
78
|
-
sessions trust it automatically — but that file likely won't hot-reload now,
|
|
79
|
-
so run `/add-dir <trusted root>` before editing into the worktree, or the
|
|
80
|
-
first edits will prompt.
|
|
81
|
-
- **Do the rest in the worktree**, on the branch: open it (the printed opener, or
|
|
82
|
-
a fresh Claude session rooted there) or, staying in this session, act on the
|
|
83
|
-
worktree path with absolute paths / `git -C <worktreePath>`. The spec move,
|
|
84
|
-
header edits **and** the phase's code all happen on the branch — so the spec's
|
|
85
|
-
evolution travels with the code it describes and lands in one PR. `main` changes
|
|
86
|
-
only when that branch merges (at `/spec-complete`).
|
|
87
|
-
|
|
88
|
-
Then move the spec (in the worktree when isolated, in place otherwise):
|
|
89
|
-
|
|
90
|
-
- If it isn't already under `specs/in-progress/`, move the whole spec folder
|
|
91
|
-
there. **Use `git mv`** to keep history:
|
|
92
|
-
`git mv "specs/backlog/<name>" "specs/in-progress/<name>"`.
|
|
93
|
-
`mkdir -p specs/in-progress` first if needed.
|
|
94
|
-
- Update the **Status** header in the entry point:
|
|
95
|
-
`> **Status:** In Progress — Phase 1 (started <YYYY-MM-DD>)`.
|
|
96
|
-
- Set the **Developer** header field if it's still `—`: use `git config user.name`.
|
|
97
|
-
- Append a **State log** row:
|
|
98
|
-
`| <YYYY-MM-DD> | In Progress | in-progress | <git user.name> |`.
|
|
99
|
-
- **When isolated:** commit the move and **push the branch** now — that records
|
|
100
|
-
the in-progress state for everyone and fires the tracker's automation (when a
|
|
101
|
-
ticketing provider is linked).
|
|
102
|
-
|
|
103
|
-
A spec ideally reaches here already `Ready` (written by `/spec`), but `/spec-go`
|
|
104
|
-
works on a `Draft` too — just sanity-check it's well-formed before building.
|
|
105
|
-
|
|
106
|
-
If the spec is already in `in-progress`, skip the move and implement the **next
|
|
107
|
-
unfinished phase** instead of Phase 1. (When isolated, subsequent `/spec-go` runs
|
|
108
|
-
happen from inside the worktree — where the spec already sits in `in-progress` on
|
|
109
|
-
the branch — and a re-run of `spec-env up` just re-attaches it.)
|
|
110
|
-
|
|
111
|
-
## 2b. Bring the spec's dev servers up — confirm before heavy steps
|
|
112
|
-
|
|
113
|
-
**Only when isolation is enabled and the project configures host dev servers**
|
|
114
|
-
(`env.config.json` → a non-empty `dev` array). This is what makes the spec
|
|
115
|
-
runnable — its UI/API on the spec's reserved port block, isolated from `main`.
|
|
116
|
-
|
|
117
|
-
- **Show the plan and get a yes first.** List what will start: the per-process
|
|
118
|
-
dev commands, the ports they'll bind (the spec's slot block), and any Docker
|
|
119
|
-
stack. Don't start heavy processes silently. If the user passed **`--plan`**,
|
|
120
|
-
print this plan and **stop** (preview only).
|
|
121
|
-
- On confirmation, run `skitterspec spec-env dev up <name>` — it launches each
|
|
122
|
-
dev process detached on its port, logs to `.spec-env/logs/`, and waits on each
|
|
123
|
-
`health` check. With no `dev` configured it's a clean no-op; skip this step.
|
|
124
|
-
- **Diverting your browser is a separate step.** To test the spec at your normal
|
|
125
|
-
`localhost` URL, the **user** types **`/spec-connect <name>`** (exclusive — it
|
|
126
|
-
exposes this spec on the canonical ports; `/spec-connect main` hands them back).
|
|
127
|
-
`/spec-go` never seizes the canonical ports on its own. For a **code-only** spec,
|
|
128
|
-
the lighter **`/spec-live <name>`** reuses the already-running dev server (a
|
|
129
|
-
branch-switch, no second stack) — `/spec-live main` hands it back. Both are
|
|
130
|
-
user-only slash commands: tell the user to run one, never try to invoke it.
|
|
131
|
-
|
|
132
|
-
## 3. Pre-flight — commit prior work
|
|
133
|
-
|
|
134
|
-
Before writing any code for this phase, get the workspace clean:
|
|
135
|
-
|
|
136
|
-
- **Confirm the last-worked phase is committed.** Run `git status` and
|
|
137
|
-
`git log --oneline -5`. The most recently *implemented* phase (not necessarily
|
|
138
|
-
the numerically previous one) should already be committed. If prior-phase work
|
|
139
|
-
is still uncommitted, **stop and suggest committing it first** (e.g. via
|
|
140
|
-
`/commit`) so each phase lands as its own reviewable commit — don't build the
|
|
141
|
-
next phase on top of an uncommitted one. (Skip if this is the first phase —
|
|
142
|
-
there's nothing prior to commit.)
|
|
143
|
-
|
|
144
|
-
## 4. Implement the phase
|
|
145
|
-
|
|
146
|
-
Identify the **first unfinished phase** from the `00-overview.md` phase index,
|
|
147
|
-
then open its phase file (`0N-<slug>.md`) — that file holds the tasks. Mark it
|
|
148
|
-
started: set the phase-file heading to `🔄` and its `> **Status:**` to
|
|
149
|
-
`In progress`, and flip the matching row in the overview phase index to `🔄`.
|
|
150
|
-
|
|
151
|
-
**Then sync with the tracker (only if a provider is installed).** The phase has
|
|
152
|
-
just changed state, so refresh the mirror before the build starts — that is what
|
|
153
|
-
makes the phase show as in progress *while* it is being built rather than only
|
|
154
|
-
once it is over. Without a provider this is a no-op and nothing below changes.
|
|
155
|
-
|
|
156
|
-
**Only when `specs/.core/linear.config.json` exists** and the spec carries a
|
|
157
|
-
`linear_identifier`. Otherwise skip this step — no config means zero change.
|
|
158
|
-
|
|
159
|
-
- **No pull.** Linear is a generated mirror in one-way sync, so there is nothing
|
|
160
|
-
to bring down before building — the repo is already the source of truth. (A
|
|
161
|
-
workflow-state a teammate moved in Linear is advisory only; `/spec-status`
|
|
162
|
-
surfaces it. It is overwritten on the next push.)
|
|
163
|
-
- **Refresh the mirror now, without asking.** Run `/spec-push`. The spec has just
|
|
164
|
-
moved to `in-progress` and its phase to `🔄` — both real state changes, and the
|
|
165
|
-
tracker is a generated mirror of them. This holds under **both**
|
|
166
|
-
`mapping.phases` modes, for different reasons:
|
|
167
|
-
- `"subissue"` (the default) — the phase sub-issues already exist, and this
|
|
168
|
-
push is what moves the current one into its in-progress state. Skip it and
|
|
169
|
-
every sub-issue sits in Backlog until the spec completes.
|
|
170
|
-
- `"deferred"` — the sub-issues do not exist yet, and this push is what mints
|
|
171
|
-
them. Skip it and a started spec stays mirrored as a phase-less issue.
|
|
172
|
-
- **Never mint the spec issue.** An unlinked spec is skipped, not created —
|
|
173
|
-
`/spec-push` is how someone opts in.
|
|
174
|
-
- **Never fatal.** If the push fails — offline, no key, a Linear error — say so
|
|
175
|
-
and **carry on with the build**. The repo is correct regardless; the mirror is
|
|
176
|
-
disposable and the next push repairs it.
|
|
177
|
-
- **Expect a dirty `specs/.core/` afterwards.** The push writes a base snapshot
|
|
178
|
-
and stamps any new ids, and `/spec-go` does not commit. The next `/commit`
|
|
179
|
-
sweeps it up with the phase's own work.
|
|
180
|
-
- Linear's GitHub branch/PR automation may drive status transitions off the
|
|
181
|
-
branch/PR you pushed in step 2; that's expected and the repo still wins on the
|
|
182
|
-
next `/spec-push`.
|
|
183
|
-
|
|
184
|
-
Then build it, following the project rules in `.claude/rules/*.md` and `CLAUDE.md`:
|
|
185
|
-
|
|
186
|
-
- Work task by task through the phase file. Make focused edits that match
|
|
187
|
-
surrounding code.
|
|
188
|
-
- Honour the project's conventions (see `.claude/rules/spec-planning.md` and the
|
|
189
|
-
rules it links).
|
|
190
|
-
- **Tests are part of the phase, not after it.** Create/extend tests for the
|
|
191
|
-
work, then run the project's typecheck and test commands. Do not declare the
|
|
192
|
-
phase done until green.
|
|
193
|
-
- Never hardcode dates in tests; never run destructive commands against a real
|
|
194
|
-
database — use the project's test database only.
|
|
195
|
-
|
|
196
|
-
## 5. Record progress
|
|
197
|
-
|
|
198
|
-
- In the **phase file**: tick completed tasks (`- [x]`), flip its heading to `✅`,
|
|
199
|
-
and set its `> **Status:**` to `Done`.
|
|
200
|
-
- In **`00-overview.md`**: flip the matching phase-index row to `✅`.
|
|
201
|
-
- If anything changed from the plan (a decision, a deviation, a discovered
|
|
202
|
-
constraint), add a dated **Changelog** entry in `00-overview.md`.
|
|
203
|
-
- If new work surfaced, add it as tasks to the appropriate phase file (or add a
|
|
204
|
-
new phase file + index row) rather than doing it silently.
|
|
205
|
-
|
|
206
|
-
**Then refresh the mirror (only if a provider is installed).** The phase is done
|
|
207
|
-
in the repo now; leaving the tracker to catch up at `/spec-complete` is what makes
|
|
208
|
-
a mirror lag a whole spec behind. Without a provider this is a no-op.
|
|
209
|
-
|
|
210
|
-
**Only when `specs/.core/linear.config.json` exists** and the spec carries a
|
|
211
|
-
`linear_identifier`. Either missing → **skip**, in one line
|
|
212
|
-
(`not linked to Linear — /spec-push to mirror it`), and carry on.
|
|
213
|
-
|
|
214
|
-
**Refresh the mirror now, without asking.** Run `/spec-push`. The repo has just
|
|
215
|
-
become the truth about this phase's progress, and progress is what the mirror
|
|
216
|
-
exists to show. Deferring it to `/spec-complete` is what makes every phase
|
|
217
|
-
sub-issue jump from Backlog straight to Done, with nothing visible in between.
|
|
218
|
-
|
|
219
|
-
- **Never mint.** An unlinked spec is skipped, not created.
|
|
220
|
-
- **Never fatal.** If the push fails — offline, no key, a Linear error — say so
|
|
221
|
-
and **finish the operation anyway**. The phase is done in the repo regardless;
|
|
222
|
-
the mirror is disposable and the next push repairs it.
|
|
223
|
-
- **Expect a dirty `specs/.core/` afterwards.** The push writes a base snapshot
|
|
224
|
-
and stamps any new ids, and these skills do not commit. The next `/commit`
|
|
225
|
-
sweeps it up with the phase's own work.
|
|
226
|
-
- **Say what happened** in the skill's report: mirror updated, skipped as
|
|
227
|
-
unlinked, or failed with the reason.
|
|
228
|
-
|
|
229
|
-
## 6. Report
|
|
230
|
-
|
|
231
|
-
Summarise what was implemented, the test result (quote failures if any), and
|
|
232
|
-
which phase is next. Do **not** `git commit` unless the user asks — finish,
|
|
233
|
-
verify, and wait.
|