@skitterbyte/skitterspec 18.0.0 → 20.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 +296 -10
- package/README.md +53 -4
- package/assets/claude-md-section.md +38 -2
- package/assets/commands/spec-connect.md +2 -2
- package/assets/commands/spec-live.md +2 -2
- package/assets/core/env.config.json.example +7 -3
- package/assets/core/env.config.md +90 -30
- package/assets/hooks/review-gate.js +141 -0
- package/assets/review/page.html +1787 -0
- package/assets/rules/spec-planning.md +250 -10
- package/assets/rules/spec-reports.md +321 -0
- package/assets/skills/spec/SKILL.md +32 -4
- package/assets/skills/spec-bug/SKILL.md +113 -8
- package/assets/skills/spec-cancel/SKILL.md +84 -19
- package/assets/skills/spec-complete/SKILL.md +80 -23
- package/assets/skills/spec-diff/SKILL.md +678 -0
- package/assets/skills/spec-hotfix/SKILL.md +113 -10
- package/assets/skills/spec-init/SKILL.md +56 -7
- package/assets/skills/spec-next/SKILL.md +408 -7
- package/assets/skills/spec-review/SKILL.md +26 -3
- package/assets/skills/spec-reviewed/SKILL.md +258 -0
- package/assets/skills/spec-start/SKILL.md +283 -106
- package/assets/skills/spec-to-main/SKILL.md +28 -6
- package/package.json +11 -7
- package/src/cli.js +1808 -89
- package/src/env/building.js +143 -0
- package/src/env/commitcmd.js +108 -0
- package/src/env/config.js +58 -9
- package/src/env/hooks.js +117 -0
- package/src/env/provision.js +54 -15
- package/src/env/proxy.js +34 -1
- package/src/env/render.js +3 -12
- package/src/env/resolve.js +295 -9
- package/src/env/review.js +1536 -0
- package/src/env/serve.js +573 -0
- package/src/env/teardown.js +13 -6
- package/src/init.js +150 -1
- package/LICENSE +0 -21
|
@@ -5,22 +5,30 @@ description: Put a spec in flight — provision its branch, move it to in-progre
|
|
|
5
5
|
|
|
6
6
|
# /spec-start — put a spec in flight
|
|
7
7
|
|
|
8
|
+
> Stay silent while this runs — speak only to ask something you cannot answer
|
|
9
|
+
> yourself, or to report a failure at the moment it happens. Read
|
|
10
|
+
> `.claude/rules/spec-reports.md` before reporting; it defines the block this
|
|
11
|
+
> skill ends with.
|
|
12
|
+
|
|
8
13
|
One checkout, one spec in flight. This skill is how a spec gets there:
|
|
9
14
|
provision, move it to `in-progress`, refresh the tracker, then hand straight on
|
|
10
15
|
to `/spec-next` for phase 1. Continuing a spec afterwards is `/spec-next`;
|
|
11
16
|
finishing it is `/spec-complete`.
|
|
12
17
|
|
|
13
|
-
## 1. The gate —
|
|
18
|
+
## 1. The gate — what each mode demands of the tree
|
|
14
19
|
|
|
15
20
|
**Check this first, before resolving anything or touching a file.** What the
|
|
16
21
|
gate demands depends on the mode, because the two modes hold work in different
|
|
17
22
|
places — read `mode` from `specs/.core/env.config.json` (default `worktree`).
|
|
18
23
|
|
|
19
|
-
**`worktree` mode —
|
|
20
|
-
|
|
21
|
-
parallelism the mode exists for.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
**`worktree` mode — there is no tree gate.** The spec is built in its own
|
|
25
|
+
worktree, so neither another spec being in flight nor its uncommitted files are a
|
|
26
|
+
conflict; both are the parallelism the mode exists for. `git worktree add`
|
|
27
|
+
carries nothing and forks from a commit, and the one thing this run writes into
|
|
28
|
+
the checkout — the spec's own commit, which `spec-env up` plans for you — names
|
|
29
|
+
its paths on both the `add` and the `commit`, so it cannot reach a file that is
|
|
30
|
+
not this spec's. Work belonging to someone else is **reported and left alone**,
|
|
31
|
+
never a refusal. Nothing is switched here and nothing is parked.
|
|
24
32
|
|
|
25
33
|
**`checkout` mode — the workbench must be free**: on the base branch (`main`, or
|
|
26
34
|
the configured `baseBranch`) and clean, since the branch is built right here and
|
|
@@ -37,21 +45,30 @@ and a half-built phase are each a decision someone must make deliberately — an
|
|
|
37
45
|
the cost of guessing is another spec's work moved without its author asking. A
|
|
38
46
|
refusal costs one command; the alternative can cost an afternoon.
|
|
39
47
|
|
|
40
|
-
**
|
|
41
|
-
|
|
42
|
-
what it says rather than deciding for yourself:
|
|
48
|
+
**What `spec-env up` does with the tree**, in both modes — relay what it says
|
|
49
|
+
rather than deciding for yourself:
|
|
43
50
|
|
|
44
|
-
| What it found |
|
|
45
|
-
|
|
46
|
-
| clean | provisions
|
|
47
|
-
| every path
|
|
48
|
-
|
|
|
51
|
+
| What it found | `worktree` | `checkout` |
|
|
52
|
+
|---------------|-------------|-------------|
|
|
53
|
+
| clean | provisions | provisions |
|
|
54
|
+
| every path is this spec's | commits those paths **first**, then forks | same, then switches |
|
|
55
|
+
| some path is not | commits this spec's, provisions, **reports the rest** | refuses, naming them |
|
|
49
56
|
|
|
50
57
|
That is membership in an exactly-known set — the spec's own folder plus the
|
|
51
58
|
project's `spec.companionPaths` — and **not** a judgement about whether the
|
|
52
|
-
changes look important.
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
changes look important. It never decides that.
|
|
60
|
+
|
|
61
|
+
**The last row is the only real difference, and it is mechanical.**
|
|
62
|
+
`git switch -c` carries the working tree onto the new branch, so in
|
|
63
|
+
`checkout` mode a colleague's files really would be moved without them asking.
|
|
64
|
+
`git worktree add` carries nothing, so in `worktree` mode the same files are
|
|
65
|
+
simply not this run's business — and refusing over them fired on the commonest
|
|
66
|
+
tree this workflow produces: a second spec authored while the first is still
|
|
67
|
+
uncommitted. When it reports them, say how many and whose in the `Untouched` row
|
|
68
|
+
and **keep the verdict `✅`** — nothing went wrong.
|
|
69
|
+
|
|
70
|
+
When it plans the commit, the paths are printed above the commands, so run them
|
|
71
|
+
as printed; when it refuses, relay the reason and stop.
|
|
55
72
|
|
|
56
73
|
It also refuses a **clean** tree whose spec is not in the commit the worktree
|
|
57
74
|
would fork from — otherwise you get a branch missing the very spec it is for.
|
|
@@ -71,69 +88,131 @@ would fork from — otherwise you get a branch missing the very spec it is for.
|
|
|
71
88
|
probably still exists, so this is a re-attach: say so rather than reporting a
|
|
72
89
|
fresh start, and skip the housekeeping that is already done.
|
|
73
90
|
|
|
91
|
+
## 2b. Bring the review server up — from here, before anything else
|
|
92
|
+
|
|
93
|
+
**Only when the project has per-spec isolation** (`specs/.core/env.config.json`
|
|
94
|
+
present). Without it there is no review server and this step does not exist —
|
|
95
|
+
skip it in silence rather than explaining an absence.
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
skitterspec spec-env review serve --host 0.0.0.0
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Here is the point.** Right now this session is standing in the
|
|
102
|
+
**primary checkout**, and in a moment step 3 `cd`s into a worktree and stays
|
|
103
|
+
there. A
|
|
104
|
+
daemon started after that `cd` is started *by the worktree's copy of the code* —
|
|
105
|
+
and when `/spec-complete` removes that worktree, the daemon keeps answering on
|
|
106
|
+
its port and fails on every page it is asked for, for every spec. The engine
|
|
107
|
+
defends against that now, but the cheapest fix is to never create the situation:
|
|
108
|
+
start it while you are still somewhere that outlives the spec.
|
|
109
|
+
|
|
110
|
+
It is also what lets **several specs be reviewed at once**. Reviews all render
|
|
111
|
+
into the primary checkout's `.spec-env/reviews/`, so one server serves every
|
|
112
|
+
provisioned spec — including specs another agent is building in another
|
|
113
|
+
worktree. Starting it here means that one server belongs to the checkout none of
|
|
114
|
+
them can delete.
|
|
115
|
+
|
|
116
|
+
**Say nothing when it is already up.** The usual outcome is adoption — a server
|
|
117
|
+
is running and this changes nothing — and a line per `/spec-start` about a
|
|
118
|
+
daemon nobody asked about is the narration `.claude/rules/spec-reports.md`
|
|
119
|
+
forbids. Speak only if it could not start.
|
|
120
|
+
|
|
121
|
+
**Never fatal, never a gate.** A busy port, no network address, a refused
|
|
122
|
+
spawn — say it in one line and **carry on**; provisioning is not conditional on
|
|
123
|
+
it, and the page falls back to its `file://` URL exactly as it does today.
|
|
124
|
+
|
|
125
|
+
**`--host 0.0.0.0` is the deliberate half.** It binds the server to this
|
|
126
|
+
machine's network addresses so the page opens on a phone, and the engine mints a
|
|
127
|
+
token with that bind as its only guard. On a machine you would rather not expose,
|
|
128
|
+
drop the flag — the server is then reachable from this machine alone and the
|
|
129
|
+
render says so. On **`--plan`** this step does not run at all.
|
|
130
|
+
|
|
74
131
|
## 3. Build its branch
|
|
75
132
|
|
|
76
133
|
### `worktree` mode
|
|
77
134
|
|
|
135
|
+
**One path. There is no branching here and none should be added back.**
|
|
136
|
+
|
|
78
137
|
1. **Provision.** Run `skitterspec spec-env up <name>` — a planner, so run the
|
|
79
|
-
`to provision, run:` commands it prints and confirm they succeeded
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
`
|
|
121
|
-
`
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
`to provision, run:` commands it prints and confirm they succeeded.
|
|
139
|
+
|
|
140
|
+
2. **Trust the worktree.** `spec-env up` wrote the printed `trusted:` root into
|
|
141
|
+
`.claude/settings.local.json`, but that file does not hot-reload in this
|
|
142
|
+
session — run **`/add-dir <trusted root>`** before editing into the worktree,
|
|
143
|
+
or the first write prompts. This is not tab machinery: worktrees live outside
|
|
144
|
+
the checkout, and the trust entry is what stops the prompt.
|
|
145
|
+
|
|
146
|
+
3. **Bootstrap it, and move into it.** The `cd` is in the command itself, and it
|
|
147
|
+
**moves this session** — that is what it is for, not a side effect of it. The
|
|
148
|
+
Bash working directory persists between calls, so from here on this session is
|
|
149
|
+
standing in the worktree, which is what lets a bare `/spec-next` resolve the
|
|
150
|
+
spec on its own:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
cd "<worktreePath>" && <the planner's "then, in the worktree, run:" steps>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Run the seeding steps before `setup`: a fresh worktree has no dependencies and
|
|
157
|
+
none of the repo's gitignored files, so hooks, typechecks and tests fail until
|
|
158
|
+
both have happened.
|
|
159
|
+
|
|
160
|
+
**Then confirm the move landed — never assume it.** Ask for a positive signal
|
|
161
|
+
rather than reading silence as success (`.claude/rules/negative-checks.md`
|
|
162
|
+
rule 1): run `skitterspec spec-env resolve` with **no argument** and read the
|
|
163
|
+
`spec:` line it prints.
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
skitterspec spec-env resolve # must name this spec
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Three states, not two. It names this spec → carry on. It names something else,
|
|
170
|
+
or resolves nothing → **the `cd` did not take**. Say so plainly and fall back
|
|
171
|
+
to the stop-here ending in step 6, printing the path so the operator can open
|
|
172
|
+
a session there themselves; do not build a phase from a session whose location
|
|
173
|
+
you could not confirm. A failed `cd` leaves you in the primary checkout on the
|
|
174
|
+
base branch, where a phase's worth of code looks entirely normal at the time.
|
|
175
|
+
|
|
176
|
+
4. **Housekeep with `git -C <worktreePath>`** — step 4 below, against the
|
|
177
|
+
worktree.
|
|
178
|
+
|
|
179
|
+
**Keep the `-C` prefix**, even though the session is inside the worktree now
|
|
180
|
+
and a bare `git` would usually do the same thing. It is immune to the one
|
|
181
|
+
failure this sequence can have — a `cd` that silently did not take — where a
|
|
182
|
+
bare `git` would instead write the spec's move into the primary checkout on
|
|
183
|
+
the base branch. It costs nothing and removes a whole failure mode, so do not
|
|
184
|
+
tidy it away.
|
|
185
|
+
|
|
186
|
+
5. **Print the worktree path.** What happens next is step 6 — it is offered
|
|
187
|
+
there, not decided here.
|
|
188
|
+
|
|
189
|
+
**The session moves into the worktree, and nothing opens a window.** Those are
|
|
190
|
+
two different claims and both are load-bearing. The move is real, and the `cd` in
|
|
191
|
+
step 3 is its whole mechanism — no tool call, because an approval prompt is
|
|
192
|
+
unusable on a phone and leaves the session stuck. Nothing is *spawned*: no new
|
|
193
|
+
terminal, no tab, no editor sent anywhere, because that machinery had nothing
|
|
194
|
+
left to do and was removed deliberately.
|
|
195
|
+
|
|
196
|
+
**Do not move the branch into this checkout**, and do not ask the operator to.
|
|
197
|
+
`/spec-live` is for testing a finished-enough spec on the already-running dev
|
|
198
|
+
server; it is not how work gets started.
|
|
199
|
+
|
|
200
|
+
**`/spec-next`'s refusal is unchanged by this.** Its rule 2 — "the worktree you
|
|
201
|
+
are standing in" — is what answers afterwards, and step 3 is what puts the session
|
|
202
|
+
there; nothing about rules 1 to 3 is loosened, and it must stay that way, because
|
|
203
|
+
the refusal exists so the wrong branch is never built. What changed is where the
|
|
204
|
+
session stands, not how weakly the rules read: a bare `/spec-next` typed from
|
|
205
|
+
somewhere that is neither a worktree nor a live checkout still refuses exactly as
|
|
206
|
+
it did. `--worktree <path>` survives untouched beside it — it answers before those
|
|
207
|
+
rules and cannot be reached by guessing.
|
|
208
|
+
|
|
209
|
+
**And the `cd` is a convenience, not the only thing holding this together.**
|
|
210
|
+
`/spec-next`'s **rule 4** asks the engine for the sole provisioned spec, so a
|
|
211
|
+
bare `/spec-next` resolves this spec from anywhere in the repo — after a
|
|
212
|
+
`/clear`, from a new tab, tomorrow morning. That is what makes step 6's
|
|
213
|
+
stop-here ending an honest offer rather than a promise only this session can
|
|
214
|
+
keep. Do not delete rule 4 as redundant with the `cd`: the `cd` is session state,
|
|
215
|
+
and rule 4 is what is left once it is gone.
|
|
137
216
|
|
|
138
217
|
### `checkout` mode
|
|
139
218
|
|
|
@@ -145,20 +224,46 @@ refusal and stop.
|
|
|
145
224
|
## 4. Move the spec into development
|
|
146
225
|
|
|
147
226
|
**Do this before you report anything**, so no path can end with a provisioned
|
|
148
|
-
worktree and a spec still reading `Ready` in `specs/backlog/`.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
in `checkout` mode the branch is already here.
|
|
227
|
+
worktree and a spec still reading `Ready` in `specs/backlog/`. In `worktree` mode
|
|
228
|
+
run it against the worktree with `git -C <worktreePath>`; in `checkout` mode the
|
|
229
|
+
branch is already here.
|
|
152
230
|
|
|
153
231
|
- `git mv "specs/backlog/<name>" "specs/in-progress/<name>"` if it isn't there
|
|
154
232
|
already (`mkdir -p specs/in-progress` first). Use `git mv` to keep history.
|
|
155
233
|
- Set the **Status** header: `> **Status:** In Progress — Phase 1 (started <YYYY-MM-DD>)`.
|
|
156
234
|
- Set **Developer** if it is still `—` (`git config user.name`).
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
157
238
|
- Append a **State log** row: `| <YYYY-MM-DD> | In Progress | in-progress | <git user.name> |`.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
- **Commit it.** One commit, the spec's own — it records the in-progress state on
|
|
243
|
+
the branch, and sweeps up everything above so the worktree is clean when you
|
|
244
|
+
hand it over.
|
|
245
|
+
|
|
246
|
+
**Publishing that branch is yours to do, and nothing here does it for you.**
|
|
247
|
+
Whenever you want the work somewhere other than this machine:
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
git -C <worktreePath> push -u origin <branch>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Print it if it is useful; never run it. This skill once pushed here, justified as
|
|
254
|
+
recording the state "for everyone" and firing the tracker's automation — and
|
|
255
|
+
neither half survives reading. The automation needs `{identifier}` in
|
|
256
|
+
`branch.pattern` (see `env.config.md`) to put an issue id in the branch name, and
|
|
257
|
+
the shipped default carries none, so the tracker has nothing to match. Nor was it
|
|
258
|
+
an invariant: `/spec-bug` provisions a worktree the same way and has never
|
|
259
|
+
pushed, and `/spec-hotfix` forbids it outright. This was the odd one out.
|
|
260
|
+
|
|
261
|
+
**It also kept a guard from ever firing.** `refuseTeardownIfUnpushed` blocks
|
|
262
|
+
teardown on commits that are unpushed and unlanded — which described no branch at
|
|
263
|
+
all while this skill published every one of them at provisioning. It can fire now,
|
|
264
|
+
and the place it does is `/spec-cancel`, where the work really is about to be
|
|
265
|
+
destroyed: that skill relays the refusal and offers both ways out. Nothing to do
|
|
266
|
+
here beyond knowing it is no longer dead code.
|
|
162
267
|
|
|
163
268
|
A spec ideally arrives `Ready` from `/spec`; a `Draft` works too — sanity-check
|
|
164
269
|
it is well-formed first.
|
|
@@ -193,18 +298,75 @@ marks phase 1 started, refreshes the mirror again, builds it with tests and
|
|
|
193
298
|
reports. Do not stop and ask the operator to run it: the branch is here and they
|
|
194
299
|
asked to start the spec.
|
|
195
300
|
|
|
196
|
-
**`worktree` mode —
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
301
|
+
**`worktree` mode — offer it, then do what they say.** Step 3 left this session
|
|
302
|
+
standing in the worktree, so both endings happen right here and neither needs a
|
|
303
|
+
second session opened anywhere. In prose: say the worktree is ready and name its
|
|
304
|
+
path, then ask **"build phase 1 now?"** — recommending that they do, and naming
|
|
305
|
+
both endings so the decline is a real answer rather than a formality.
|
|
306
|
+
|
|
307
|
+
**Never fence that question.** A grey box is read as an artefact to skim rather
|
|
308
|
+
than as something someone is being asked, which is the whole reason
|
|
309
|
+
`.claude/rules/spec-reports.md` bans fencing a message to the reader. This step
|
|
310
|
+
prescribed a fenced block for a long time and an operator read straight past it,
|
|
311
|
+
which is the evidence, not a preference.
|
|
312
|
+
|
|
313
|
+
- **Build it here** — carry on into a bare **`/spec-next`**. Bare is right: the
|
|
314
|
+
session is in the worktree, so its rule 2 resolves this spec with nothing
|
|
315
|
+
passed and nothing guessed.
|
|
316
|
+
- **Stop here** — the operator is left standing in the worktree on a provisioned
|
|
317
|
+
branch, which is a perfectly good place to leave things. Nothing has to be
|
|
318
|
+
reopened or handed anywhere, and `/spec-next` typed an hour later — from this
|
|
319
|
+
session or a fresh one — does exactly what it would have done now.
|
|
320
|
+
|
|
321
|
+
**Ask rather than deciding for them, and mean it.** Provisioning is cheap and
|
|
322
|
+
reversible; a phase build is neither, and one yes should not cover both. A large
|
|
323
|
+
phase is often better started in a session of its own with a whole context budget
|
|
324
|
+
to spend, and only the operator knows which this is. On **`--plan`** this step
|
|
325
|
+
does not run at all — nothing was provisioned to build in.
|
|
326
|
+
|
|
327
|
+
**`--worktree <path>` is still there, and is still not a way around the refusal.**
|
|
328
|
+
It builds a spec the session is *not* standing in, which after step 3 is the
|
|
329
|
+
exception rather than the normal path. Reach for it in exactly two cases: the
|
|
330
|
+
confirm in step 3 reported the `cd` did not take, or you deliberately mean to
|
|
331
|
+
build some other spec's phase from here. A path someone typed is not a path
|
|
332
|
+
anything guessed, which is why it was never a loosening of the refusal and still
|
|
333
|
+
is not.
|
|
334
|
+
|
|
335
|
+
## 7. Report
|
|
336
|
+
|
|
337
|
+
**When step 6 carried on into `/spec-next`, emit no block here.** That skill ends
|
|
338
|
+
with its own, and its `Branch` and `Spec` fields already carry everything this
|
|
339
|
+
one would say. Two blocks for one run is the noise the contract exists to
|
|
340
|
+
remove — this section is for the run that stops at step 6.
|
|
341
|
+
|
|
342
|
+
End with the block defined in `.claude/rules/spec-reports.md`. That file carries
|
|
343
|
+
the shape; this section carries only what is specific here.
|
|
344
|
+
|
|
345
|
+
**Verdicts**
|
|
346
|
+
|
|
347
|
+
- `✅` — the branch is provisioned, the spec is `in-progress`, the session is
|
|
348
|
+
standing in the worktree.
|
|
349
|
+
- `⚠️` — provisioned, with something worth knowing (dev servers that did not
|
|
350
|
+
come up, a mirror that did not refresh, a missing gating decision).
|
|
351
|
+
- `❌` — provisioning failed part-way and left something behind. Say what, and
|
|
352
|
+
where.
|
|
353
|
+
- `⏸` — the gate refused: in `checkout` mode a dirty tree or someone else's
|
|
354
|
+
unfinished work, in either mode a spec whose own files are not in the commit
|
|
355
|
+
the worktree would fork from. Nothing changed. Another spec's uncommitted work
|
|
356
|
+
is **not** on this list in `worktree` mode — it is an `Untouched` row on a
|
|
357
|
+
`✅`.
|
|
358
|
+
|
|
359
|
+
**Fields:** `Tracker` · `Branch` · `Spec` · `Worktree` · `Untouched` · `Follow-ups` · `Next`
|
|
360
|
+
|
|
361
|
+
`Worktree` carries the path, because the session is now standing in it and the
|
|
362
|
+
operator's next command depends on knowing that. `Next` is `/spec-next`.
|
|
363
|
+
|
|
364
|
+
`Untouched` appears only when `spec-env up` reported uncommitted work that was
|
|
365
|
+
not this spec's — say how much and whose, and **keep the verdict `✅`**. Nothing
|
|
366
|
+
went wrong: a worktree carries nothing, so that work was never in play.
|
|
367
|
+
|
|
368
|
+
On **`--plan`** nothing was provisioned, so the verdict is `⏸` and `Built`
|
|
369
|
+
carries the plan rather than a claim about the repo.
|
|
208
370
|
|
|
209
371
|
## Opt-outs
|
|
210
372
|
|
|
@@ -213,14 +375,29 @@ from here.
|
|
|
213
375
|
that the work lands wherever you are (usually the base branch); reserve it for
|
|
214
376
|
a trivial change or an explicit request.
|
|
215
377
|
|
|
216
|
-
There is no `--here
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
and
|
|
226
|
-
|
|
378
|
+
There is no `--here`. It existed to ask for the branch in the checkout you are
|
|
379
|
+
standing in — and in `checkout` mode that is already what happens, while in
|
|
380
|
+
`worktree` mode `--no-worktree` is the way to say it.
|
|
381
|
+
|
|
382
|
+
## Why this skill links nothing, but does mirror what it changes
|
|
383
|
+
|
|
384
|
+
This skill creates no spec and mints no issue, so it has **nothing to link** —
|
|
385
|
+
the intake and picker steps belong to `/spec`, `/spec-bug` and `/spec-hotfix`.
|
|
386
|
+
|
|
387
|
+
It does push, though, and that is step 4's seam. The state change it makes — the
|
|
388
|
+
spec moving to `in-progress` with a developer stamped on it — is mirrored by the
|
|
389
|
+
skill that makes it, exactly as `/spec-complete`, `/spec-cancel` and
|
|
390
|
+
`/spec-review` mirror theirs. It was once reasoned that the refresh `/spec-next`
|
|
391
|
+
runs would cover it, so a push here would send the same thing twice one commit
|
|
392
|
+
apart. That only ever held in `checkout` mode, where `/spec-next` follows
|
|
393
|
+
immediately; in `worktree` mode it can be hours away or never come, and the
|
|
394
|
+
issue sits in its old state with nobody assigned meanwhile.
|
|
395
|
+
|
|
396
|
+
The **assignment** seam just above it is still not a push, and does not need to
|
|
397
|
+
be. This is the one moment in the lifecycle where "who is building this" is
|
|
398
|
+
actually decided — the branch is being provisioned for someone, and that someone
|
|
399
|
+
is at the keyboard. It stamps the spec file and stops there, so it costs no
|
|
400
|
+
tracker call and rides out on the push below like every other field. Deferring
|
|
401
|
+
the stamp to `/spec-next` would be worse than untidy: in `worktree` mode the two
|
|
402
|
+
can be separated by hours, and a spec in flight with nobody named on it is
|
|
403
|
+
exactly the gap assignment exists to close.
|
|
@@ -6,6 +6,11 @@ disable-model-invocation: true
|
|
|
6
6
|
|
|
7
7
|
# /spec-to-main — land the branch on main, keep the spec open
|
|
8
8
|
|
|
9
|
+
> Stay silent while this runs — speak only to ask something you cannot answer
|
|
10
|
+
> yourself, or to report a failure at the moment it happens. Read
|
|
11
|
+
> `.claude/rules/spec-reports.md` before reporting; it defines the block this
|
|
12
|
+
> skill ends with.
|
|
13
|
+
|
|
9
14
|
The **intermediate** landing. `/spec-complete` also lands the branch, but then
|
|
10
15
|
verifies every phase, flips the status to Complete, `git mv`s the spec to
|
|
11
16
|
`complete/`, and tears the environment down.
|
|
@@ -93,10 +98,27 @@ and continue — the branch has no commits base doesn't already have.
|
|
|
93
98
|
- Do **NOT**: add a State-log row (status doesn't change), flip any phase/status
|
|
94
99
|
to Complete, `git mv` the spec, or tear down the worktree/stack.
|
|
95
100
|
**The spec stays `In Progress` and the worktree stays put.**
|
|
96
|
-
-
|
|
97
|
-
**never pushes** — mention the user can `git push` the base branch themselves to
|
|
101
|
+
- It **never pushes** — say the user can `git push` the base branch themselves to
|
|
98
102
|
trigger CI / the shared env.
|
|
99
|
-
-
|
|
100
|
-
committing on the same branch and can `/spec-to-main` again), and
|
|
101
|
-
when every phase is genuinely done — it will land the final
|
|
102
|
-
and tear down.
|
|
103
|
+
- `Next` points the way forward: `/spec-next` to continue the remaining phases
|
|
104
|
+
(you'll keep committing on the same branch and can `/spec-to-main` again), and
|
|
105
|
+
`/spec-complete` when every phase is genuinely done — it will land the final
|
|
106
|
+
commits, finalise, and tear down.
|
|
107
|
+
|
|
108
|
+
End with the block defined in `.claude/rules/spec-reports.md`. That file carries
|
|
109
|
+
the shape; this section carries only what is specific here.
|
|
110
|
+
|
|
111
|
+
**Verdicts**
|
|
112
|
+
|
|
113
|
+
- `✅` — the branch is on the base and the base is green.
|
|
114
|
+
- `⚠️` — landed, with something worth knowing.
|
|
115
|
+
- `❌` — the rebase conflicted, or the base went red after the fast-forward.
|
|
116
|
+
Quote it; the repo is mid-something and that is what the reader needs.
|
|
117
|
+
- `⏸` — a dirty worktree, red tests, or no spec to land. Nothing moved.
|
|
118
|
+
|
|
119
|
+
**Fields:** `Branch` · `Tests` · `Landed` · `Follow-ups` · `Next`
|
|
120
|
+
|
|
121
|
+
**No `Spec` field, deliberately.** This skill changes no status and moves no
|
|
122
|
+
folder, and a `Spec` line here would read as though it had. The spec stays
|
|
123
|
+
`In Progress` and the worktree stays standing — if that needs saying, the
|
|
124
|
+
verdict clause says it.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skitterbyte/skitterspec",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Spec-driven development for Claude Code
|
|
3
|
+
"version": "20.0.0",
|
|
4
|
+
"description": "Spec-driven development for Claude Code \u2014 a tracker-free filesystem workflow: lifecycle skills and per-spec isolation. For Linear sync, install @skitterbyte/skitterspec-linear instead.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
7
7
|
"claude-code",
|
|
@@ -23,14 +23,18 @@
|
|
|
23
23
|
"MIGRATION.md"
|
|
24
24
|
],
|
|
25
25
|
"engines": {
|
|
26
|
-
"node": ">=
|
|
26
|
+
"node": ">=22.13"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"prompts": "^2.4.2"
|
|
30
30
|
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"prepare": "node ../../scripts/build-dist.js skitterspec",
|
|
33
|
+
"prepack": "node ../../scripts/build-dist.js skitterspec"
|
|
34
|
+
},
|
|
31
35
|
"repository": {
|
|
32
36
|
"type": "git",
|
|
33
|
-
"url": "git+https://github.com/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
+
"url": "git+https://github.com/SkitterByte/skitterspec.git",
|
|
38
|
+
"directory": "packages/skitterspec"
|
|
39
|
+
}
|
|
40
|
+
}
|