@skitterbyte/skitterspec-linear 12.0.0 → 13.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 (55) hide show
  1. package/MIGRATION.md +208 -10
  2. package/README.md +32 -2
  3. package/assets/claude-md-section.md +38 -2
  4. package/assets/commands/spec-connect.md +2 -2
  5. package/assets/commands/spec-live.md +2 -2
  6. package/assets/core/SETUP.md +21 -3
  7. package/assets/core/env.config.json.example +6 -3
  8. package/assets/core/env.config.md +77 -30
  9. package/assets/core/linear.config.md +58 -0
  10. package/assets/review/page.html +1501 -0
  11. package/assets/rules/spec-planning.md +198 -10
  12. package/assets/rules/spec-reports.md +269 -0
  13. package/assets/skills/spec/SKILL.md +33 -5
  14. package/assets/skills/spec-bug/SKILL.md +172 -9
  15. package/assets/skills/spec-cancel/SKILL.md +98 -21
  16. package/assets/skills/spec-claim/SKILL.md +114 -0
  17. package/assets/skills/spec-complete/SKILL.md +94 -25
  18. package/assets/skills/spec-diff/SKILL.md +564 -0
  19. package/assets/skills/spec-hotfix/SKILL.md +172 -11
  20. package/assets/skills/spec-init/SKILL.md +34 -7
  21. package/assets/skills/spec-linear-setup/SKILL.md +55 -1
  22. package/assets/skills/spec-list/SKILL.md +218 -0
  23. package/assets/skills/spec-next/SKILL.md +299 -6
  24. package/assets/skills/spec-push/SKILL.md +32 -8
  25. package/assets/skills/spec-review/SKILL.md +40 -5
  26. package/assets/skills/spec-reviewed/SKILL.md +241 -0
  27. package/assets/skills/spec-start/SKILL.md +386 -106
  28. package/assets/skills/spec-status/SKILL.md +24 -2
  29. package/assets/skills/spec-sync/SKILL.md +40 -4
  30. package/assets/skills/spec-to-main/SKILL.md +28 -6
  31. package/package.json +11 -7
  32. package/src/cli.js +1513 -89
  33. package/src/env/building.js +143 -0
  34. package/src/env/config.js +42 -9
  35. package/src/env/provision.js +54 -15
  36. package/src/env/proxy.js +34 -1
  37. package/src/env/render.js +3 -12
  38. package/src/env/resolve.js +295 -9
  39. package/src/env/review.js +1329 -0
  40. package/src/env/serve.js +549 -0
  41. package/src/env/teardown.js +13 -6
  42. package/src/init.js +96 -1
  43. package/src/vendor/linear/api.js +104 -1
  44. package/src/vendor/linear/cli-sync.js +854 -17
  45. package/src/vendor/linear/config.js +8 -0
  46. package/src/vendor/linear/credentials.js +94 -0
  47. package/src/vendor/linear/doctor.js +35 -0
  48. package/src/vendor/linear/identity.js +105 -0
  49. package/src/vendor/linear/mcp.js +26 -0
  50. package/src/vendor/sync-core/index.js +6 -2
  51. package/src/vendor/sync-core/src/compare.js +49 -3
  52. package/src/vendor/sync-core/src/normalize.js +30 -0
  53. package/src/vendor/sync-core/src/push.js +11 -1
  54. package/src/vendor/sync-core/src/write.js +38 -0
  55. 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/`. The `git add specs/` that follows sweeps both up
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
- git add specs/ && git commit -m "chore(spec): complete <name>"
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
- Step 2 established the tree was otherwise clean, so this commits exactly the
115
- status flip and the move nothing of yours rides along.
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
- Confirm the move, the commit, the final test result, and list anything deferred.
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
- session's cwd is inside the spec's own worktree, get out **first**, then run the
226
- teardown commands. How you leave depends on how you got in:
227
-
228
- - **`/spec-start` moved this session in** — the normal path in `worktree` mode.
229
- Call **`ExitWorktree`** with `action: "keep"`. It restores the session to the
230
- directory it started from *and* clears the caches still pointing at the
231
- worktree, which a bare `cd` does not: after a `cd` the session stays registered
232
- against the tree and asks you about it again when it ends.
233
- - **You opened the terminal yourself** `cd` to the primary checkout, as always.
234
- `ExitWorktree` is a no-op outside a session it moved, so trying it costs
235
- nothing, but the `cd` is what relocates you.
236
-
237
- **Always `keep`, never `remove`.** `ExitWorktree` refuses to remove a worktree
238
- entered by path in any case, and the `spec-env down` plan below has to stay the
239
- single thing that deletes a second deleter is how the teardown guards get
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
- `/spec-start` pushed this branch when it provisioned, so the remote copy
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