@skitterbyte/skitterspec-linear 12.0.0 → 14.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 +32 -2
- 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/SETUP.md +21 -3
- package/assets/core/env.config.json.example +7 -3
- package/assets/core/env.config.md +90 -30
- package/assets/core/linear.config.md +58 -0
- 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 +33 -5
- package/assets/skills/spec-bug/SKILL.md +172 -9
- package/assets/skills/spec-cancel/SKILL.md +98 -21
- package/assets/skills/spec-claim/SKILL.md +114 -0
- package/assets/skills/spec-complete/SKILL.md +94 -25
- package/assets/skills/spec-diff/SKILL.md +678 -0
- package/assets/skills/spec-hotfix/SKILL.md +172 -11
- package/assets/skills/spec-init/SKILL.md +56 -7
- package/assets/skills/spec-linear-setup/SKILL.md +55 -1
- package/assets/skills/spec-list/SKILL.md +218 -0
- package/assets/skills/spec-next/SKILL.md +419 -7
- package/assets/skills/spec-push/SKILL.md +32 -8
- package/assets/skills/spec-review/SKILL.md +40 -5
- package/assets/skills/spec-reviewed/SKILL.md +258 -0
- package/assets/skills/spec-start/SKILL.md +386 -106
- package/assets/skills/spec-status/SKILL.md +24 -2
- package/assets/skills/spec-sync/SKILL.md +40 -4
- 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/src/vendor/linear/api.js +104 -1
- package/src/vendor/linear/cli-sync.js +854 -17
- package/src/vendor/linear/config.js +8 -0
- package/src/vendor/linear/credentials.js +94 -0
- package/src/vendor/linear/doctor.js +35 -0
- package/src/vendor/linear/identity.js +105 -0
- package/src/vendor/linear/mcp.js +26 -0
- package/src/vendor/sync-core/index.js +6 -2
- package/src/vendor/sync-core/src/compare.js +49 -3
- package/src/vendor/sync-core/src/normalize.js +30 -0
- package/src/vendor/sync-core/src/push.js +11 -1
- package/src/vendor/sync-core/src/write.js +38 -0
- package/LICENSE +0 -21
|
@@ -5,6 +5,11 @@ description: Finish a spec — verify all phases are genuinely done, update prog
|
|
|
5
5
|
|
|
6
6
|
# /spec-complete — verify, finalise, archive a spec
|
|
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
|
## 1. Identify the target spec
|
|
9
14
|
|
|
10
15
|
- Use the name/path argument if given, else the spec **in context**. If unclear,
|
|
@@ -90,6 +95,12 @@ Linear API key is set (see `apply.transport` in `linear.config.md`).
|
|
|
90
95
|
Do not roll anything back, and do not stop to ask.
|
|
91
96
|
- **Say what happened** in the skill's report: mirror updated, skipped as
|
|
92
97
|
unlinked, or failed with the reason.
|
|
98
|
+
- **There is no unassign step, and that is not an omission.** With `assignee` in
|
|
99
|
+
`sync.fieldOwnership`, the projection derives it from the spec's lifecycle
|
|
100
|
+
bucket — so moving the folder to `complete`/`cancelled` is *itself* what
|
|
101
|
+
releases the issue, and the push above carries it like any other field. The
|
|
102
|
+
`linear_assignee_id` stamp and the `> **Developer:**` header both stay put:
|
|
103
|
+
they record who actioned the work, which outlives who is holding it.
|
|
93
104
|
|
|
94
105
|
### Why it sits here
|
|
95
106
|
|
|
@@ -100,26 +111,74 @@ In `/spec-complete` and `/spec-cancel` this step is deliberately pinned
|
|
|
100
111
|
its folder bucket. Push while the folder is still in `in-progress/` and the
|
|
101
112
|
issue is set to the state the spec is *leaving*.
|
|
102
113
|
- **Before the commit**, because the push stamps ids into the spec and writes a
|
|
103
|
-
snapshot under `specs/.core/`.
|
|
104
|
-
with the status change; push after it instead and those files are left
|
|
114
|
+
snapshot under `specs/.core/`. Push after the commit instead and both are left
|
|
105
115
|
uncommitted, which makes `spec-env integrate` refuse to land the branch.
|
|
106
116
|
|
|
117
|
+
The snapshot is reached **by name**, not by breadth. It is a declared
|
|
118
|
+
`spec.companionPaths` entry (`specs/.core/linear-base/{identifier}.base.json`),
|
|
119
|
+
so `spec-env stage` returns it among this spec's owned paths and the commit below
|
|
120
|
+
names it. This is why the commit no longer stages `specs/` wholesale: the one
|
|
121
|
+
file outside the spec's folder that had to be swept up is addressable, so the
|
|
122
|
+
breadth bought nothing and cost another session's work.
|
|
123
|
+
|
|
107
124
|
Then **commit the completion edits** — steps 3–4 are this skill's own output, so
|
|
108
|
-
it finishes its own work rather than handing you a dirty tree
|
|
125
|
+
it finishes its own work rather than handing you a dirty tree. Ask the engine
|
|
126
|
+
which paths are this spec's, then stage and commit **exactly those**:
|
|
109
127
|
|
|
110
128
|
```
|
|
111
|
-
|
|
129
|
+
skitterspec spec-env stage <name> # lists them; --json to consume
|
|
130
|
+
git add -- <the owned paths>
|
|
131
|
+
git commit -m "chore(spec): complete <name>" -- <the owned paths>
|
|
112
132
|
```
|
|
113
133
|
|
|
114
|
-
|
|
115
|
-
|
|
134
|
+
**Never `git add specs/`.** That stages a *directory*, so a spec another
|
|
135
|
+
session is part-way through writing lands in this commit under this spec's
|
|
136
|
+
ticket. The `--` on the **commit** is the other half: a checkout has one
|
|
137
|
+
`.git/index`, shared by every session standing in it, so a bare `git commit`
|
|
138
|
+
takes whatever else is staged there however carefully you staged your own.
|
|
139
|
+
`.claude/rules/spec-planning.md` carries the full account.
|
|
140
|
+
|
|
141
|
+
So this commits exactly the status flip and the move, and nothing of yours — or
|
|
142
|
+
of anyone else's — rides along.
|
|
116
143
|
**This is what lets step 6 land:** `integrate` refuses a dirty worktree, so
|
|
117
144
|
without committing here the skill would block on the very edits it just made.
|
|
118
145
|
Do not `git push`.
|
|
119
146
|
|
|
120
147
|
## 5. Report
|
|
121
148
|
|
|
122
|
-
|
|
149
|
+
**The block is emitted when the run ends, not where this section sits.** The
|
|
150
|
+
sections below run after it, so their outcome belongs in the block — write it
|
|
151
|
+
once, at the end, with what actually happened.
|
|
152
|
+
|
|
153
|
+
End with the block defined in `.claude/rules/spec-reports.md`. That file carries
|
|
154
|
+
the shape; this section carries only what is specific here.
|
|
155
|
+
|
|
156
|
+
**Verdicts**
|
|
157
|
+
|
|
158
|
+
- `✅` — every phase done, tests green, landed, torn down.
|
|
159
|
+
- `⚠️` — finished, with something worth knowing: teardown declined, a tracker
|
|
160
|
+
refresh that failed, a hotfix tag still waiting to be pushed.
|
|
161
|
+
- `❌` — it acted and stopped part-way — a conflicted rebase, a failed
|
|
162
|
+
cherry-pick, a red base after landing. Say what state the repo is in and quote
|
|
163
|
+
the failure; there is a mess to clear and the reader needs to know where.
|
|
164
|
+
- `⏸` — phases are unfinished, tests are red, or the tree is dirty. Nothing
|
|
165
|
+
moved.
|
|
166
|
+
|
|
167
|
+
**Fields:** `Tracker` · `Spec` · `Tests` · `Landed` · `Worktree` ·
|
|
168
|
+
`Follow-ups` · `Next`
|
|
169
|
+
|
|
170
|
+
**Report this spec and no other.** A completion is the moment it is most
|
|
171
|
+
tempting to survey what is left — what else is in flight, what is in the
|
|
172
|
+
backlog, which worktrees are still standing — and it is the moment it helps
|
|
173
|
+
least: the reader has just finished something and cannot tell whether a line
|
|
174
|
+
about another spec followed from it. `Next` is one action for this spec, and
|
|
175
|
+
`/spec-list` is where the wider picture lives if they want it.
|
|
176
|
+
|
|
177
|
+
`Landed` says how, because the two ways differ: a fast-forward names the base
|
|
178
|
+
and the commit, a hotfix names the deploy tag and the `main` cherry-pick — and
|
|
179
|
+
a deploy tag that has not been pushed is a `⚠️`, not a `✅`. `Worktree` says
|
|
180
|
+
what was reclaimed, including any orphaned volumes swept, or that teardown was
|
|
181
|
+
declined and the worktree still stands.
|
|
123
182
|
|
|
124
183
|
## 6. Land the branch (opt-in, only if isolated)
|
|
125
184
|
|
|
@@ -221,22 +280,22 @@ worktree and branch are being kept, and go straight to sub-step 4. Mention
|
|
|
221
280
|
canonical ports go back to the primary checkout.
|
|
222
281
|
2. **Stop its host dev servers:** `skitterspec spec-env dev down <name>` (a
|
|
223
282
|
no-op when none are running / configured).
|
|
224
|
-
**Standing in the worktree? Leave it before you tear it down.** If this
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
283
|
+
**Standing in the worktree? Leave it before you tear it down.** If this session's
|
|
284
|
+
cwd is inside the spec's own worktree — the normal case in `worktree` mode, since
|
|
285
|
+
`/spec-start` moves you there — get out **first**, then run the teardown commands.
|
|
286
|
+
One instruction covers it:
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
cd <primary checkout>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
That is the whole mechanism, and it does not matter how you got in: the session
|
|
293
|
+
was moved by a `cd` and it leaves by one. There is no tool to call here, and none
|
|
294
|
+
should be reached for — the move in is a plain `cd` precisely because a tool that
|
|
295
|
+
asks for approval is unusable on a phone.
|
|
296
|
+
|
|
297
|
+
**`spec-env down` stays the single thing that deletes a worktree.** The plan
|
|
298
|
+
below is the only deleter, because a second one is how the teardown guards get
|
|
240
299
|
bypassed.
|
|
241
300
|
|
|
242
301
|
Not because git refuses — it does not. `git worktree remove` **succeeds** on the
|
|
@@ -256,9 +315,19 @@ only ordering that survives.
|
|
|
256
315
|
worktree without `--force`), so if it *does* refuse, relay that and stop
|
|
257
316
|
rather than reaching for `--force`.
|
|
258
317
|
|
|
318
|
+
**The unpushed half of that guard cannot fire here, by construction.**
|
|
319
|
+
Step 6 landed the branch, so `merged` is true and `planDown` skips the check
|
|
320
|
+
entirely (`env/teardown.js`) — completing a spec never meets it, however the
|
|
321
|
+
branch was or was not published. `/spec-cancel` is where it does fire, because
|
|
322
|
+
a cancelled spec is unlanded and its worktree really is the only copy; the
|
|
323
|
+
publish-or-`--force` path therefore lives in that skill and this one needs no
|
|
324
|
+
equivalent. A refusal reaching this step is about a **dirty tree** instead,
|
|
325
|
+
which means something wrote into the worktree after the landing — read it,
|
|
326
|
+
don't force it.
|
|
327
|
+
|
|
259
328
|
**If the plan prints a `remote branch — confirm with the user first:` section, ask before running it.**
|
|
260
|
-
|
|
261
|
-
outlives teardown unless someone deletes it. The planner only ever offers
|
|
329
|
+
Nothing published this branch for you, so a remote copy exists only because
|
|
330
|
+
you pushed it by hand — and it outlives teardown unless someone deletes it. The planner only ever offers
|
|
262
331
|
this for a branch that has **landed**, so say so plainly when you ask — the
|
|
263
332
|
commits are on the base branch (or captured by the deploy tag), so deleting
|
|
264
333
|
the remote branch loses nothing. On a yes, run the printed
|