@skitterbyte/skitterspec-linear 11.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 (60) hide show
  1. package/MIGRATION.md +260 -10
  2. package/README.md +32 -2
  3. package/assets/claude-md-section.md +48 -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 +9 -3
  8. package/assets/core/env.config.md +102 -30
  9. package/assets/core/gating.config.json.example +4 -0
  10. package/assets/core/gating.config.md +81 -0
  11. package/assets/core/linear.config.md +67 -8
  12. package/assets/review/page.html +1501 -0
  13. package/assets/rules/spec-planning.md +224 -15
  14. package/assets/rules/spec-reports.md +269 -0
  15. package/assets/skills/spec/SKILL.md +64 -13
  16. package/assets/skills/spec-bug/SKILL.md +193 -27
  17. package/assets/skills/spec-cancel/SKILL.md +99 -8
  18. package/assets/skills/spec-claim/SKILL.md +114 -0
  19. package/assets/skills/spec-complete/SKILL.md +123 -22
  20. package/assets/skills/spec-diff/SKILL.md +564 -0
  21. package/assets/skills/spec-hotfix/SKILL.md +202 -22
  22. package/assets/skills/spec-init/SKILL.md +49 -9
  23. package/assets/skills/spec-linear-setup/SKILL.md +86 -7
  24. package/assets/skills/spec-list/SKILL.md +218 -0
  25. package/assets/skills/spec-next/SKILL.md +300 -7
  26. package/assets/skills/spec-push/SKILL.md +45 -22
  27. package/assets/skills/spec-review/SKILL.md +59 -11
  28. package/assets/skills/spec-reviewed/SKILL.md +241 -0
  29. package/assets/skills/spec-start/SKILL.md +426 -66
  30. package/assets/skills/spec-status/SKILL.md +24 -2
  31. package/assets/skills/spec-sync/SKILL.md +47 -11
  32. package/assets/skills/spec-to-main/SKILL.md +42 -20
  33. package/package.json +11 -7
  34. package/src/cli.js +1710 -80
  35. package/src/env/building.js +143 -0
  36. package/src/env/classify.js +91 -0
  37. package/src/env/config.js +57 -9
  38. package/src/env/provision.js +192 -19
  39. package/src/env/proxy.js +34 -1
  40. package/src/env/render.js +3 -12
  41. package/src/env/resolve.js +296 -9
  42. package/src/env/review.js +1329 -0
  43. package/src/env/serve.js +549 -0
  44. package/src/env/teardown.js +13 -6
  45. package/src/gating.js +155 -0
  46. package/src/init.js +124 -2
  47. package/src/prompts.js +10 -1
  48. package/src/vendor/linear/api.js +104 -1
  49. package/src/vendor/linear/cli-sync.js +874 -17
  50. package/src/vendor/linear/config.js +8 -0
  51. package/src/vendor/linear/credentials.js +94 -0
  52. package/src/vendor/linear/doctor.js +35 -0
  53. package/src/vendor/linear/identity.js +105 -0
  54. package/src/vendor/linear/mcp.js +26 -0
  55. package/src/vendor/sync-core/index.js +6 -2
  56. package/src/vendor/sync-core/src/compare.js +74 -5
  57. package/src/vendor/sync-core/src/normalize.js +30 -0
  58. package/src/vendor/sync-core/src/push.js +11 -1
  59. package/src/vendor/sync-core/src/write.js +38 -0
  60. package/LICENSE +0 -21
@@ -6,6 +6,11 @@ disable-model-invocation: true
6
6
 
7
7
  # /spec-sync — the repo-wide Linear sync operations
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
  `/spec-push` and `/spec-status` cover **one spec**. This skill covers everything
10
15
  **repo-wide**, and is the answer to a bare "run spec-sync" — which is not itself
11
16
  a command.
@@ -34,12 +39,18 @@ In a project that installs the Linear superset the binary is
34
39
  |---------------|-----|
35
40
  | bare `/spec-sync`, "what's linked?", "how much is mirrored?" | `linked` |
36
41
  | "what states / projects does the workspace have?" | `states`, `projects` |
42
+ | "what specs are there?", "what's in the backlog?", "what is Jane on?" | `list` — or hand to `/spec-list` |
37
43
  | "did the mirror survive the push?" | `verify <spec> --stored <file>` |
38
44
  | "link this spec to KEY-1 by hand" | `stamp <spec> --issue KEY-1` |
39
45
  | "mirror the whole backlog / every complete spec" | `apply --all <bucket>` — **confirm first** |
40
46
  | "is the team key stale?", "did Linear get renamed?" | `retarget` |
41
47
  | "what ticket am I on?", writing a commit | `ref` |
42
48
  | "what shipped in this release?" | `released` |
49
+ | "move the shipped tickets on", "what's on test?" | `stage` — dry run unless `--apply` |
50
+ | "is any of this wired up?", "why isn't sync working?" | `doctor` — scaffold, isolation, tracker and key in one |
51
+ | "set my Linear key", "am I authenticated?" | `credentials <status\|set\|unset>` |
52
+ | "who am I in Linear?", "why is it assigning the wrong person?" | `whoami` — `--set` for a shared or bot key |
53
+ | "who's on this team?", "find Jane's user id" | `users <name-or-email>` |
43
54
  | push one spec, or "what would push?" | **defer** — see below |
44
55
 
45
56
  **With no argument, run `linked`.** It is the repo-wide overview, it is
@@ -74,6 +85,14 @@ pnpm exec skitterspec-linear spec-sync projects [--via api|mcp] [--json]
74
85
  - **`states` / `projects`** reach the workspace. `states` also reports the
75
86
  **transport** (`api` when a key is set, else `mcp`), which is the honest way to
76
87
  answer "how is this talking to Linear?".
88
+ - **`list`** is the read side of the mirror: every spec issue Linear holds,
89
+ joined to the local spec folder that owns it. Unlike `linked`, it asks LINEAR
90
+ what exists rather than the repo — which is the only way to see a spec started
91
+ on a branch this checkout has not got. Scope is the live states by default
92
+ (`--all`, `--state <name>`, `--in-progress`, or `--next N` for the top of the
93
+ backlog in Linear's own order), and `--mine` / `--by <user>` filter by
94
+ assignee. **`/spec-list` is the front door** — hand over to it for anything
95
+ beyond a bare listing; it carries the MCP path and the offline degradation.
77
96
 
78
97
  ## 4. `verify` — check what the tracker actually stored
79
98
 
@@ -120,7 +139,7 @@ not the same risk:
120
139
 
121
140
  A repo adopting Linear reports "N to create" for every unlinked spec, so an
122
141
  unconsidered `--all` can mint dozens of sub-issues. Get the counts first — run
123
- `linked` to see what is unlinked, or `spec-sync push <spec>` per spec for exact
142
+ `linked` to see what is unlinked, or `spec-sync plan <spec>` per spec for exact
124
143
  numbers — then show the user something like:
125
144
 
126
145
  ```
@@ -142,10 +161,10 @@ pnpm exec skitterspec-linear spec-sync released [<range>] [--json]
142
161
  ```
143
162
 
144
163
  `ref` prints the ticket for the branch you are on, so a commit can carry
145
- `Refs: <KEY-N>` — see `.claude/rules/commit-trailers.md`. **Off a spec branch, or
146
- on a spec that is not linked, it prints nothing and exits non-zero.** That is the
147
- correct answer, not an error to work around: do not invent a ref, and never write
148
- `Refs: none`.
164
+ `Refs: <KEY-N>` — see `.claude/rules/commit-trailers.md`.
165
+ **Off a spec branch, or on a spec that is not linked, it prints nothing and exits non-zero.**
166
+ That is the correct answer, not an error to work around: do not invent a ref,
167
+ and never write `Refs: none`.
149
168
 
150
169
  `released` reports the tickets in a commit range — by default since the most
151
170
  recent tag, and it always prints the range it chose so a wrong default is
@@ -170,9 +189,9 @@ the report saying which commits it set aside.
170
189
  pnpm exec skitterspec-linear spec-sync retarget [--yes]
171
190
  ```
172
191
 
173
- Renaming a Linear team rewrites the key in every issue identifier, and **nothing
174
- in the repo moves**: the frontmatter stamps, the config `teamKey`, and the
175
- snapshot filenames and their sub-issue keys all keep the old prefix, so
192
+ Renaming a Linear team rewrites the key in every issue identifier, and
193
+ **nothing in the repo moves**: the frontmatter stamps, the config `teamKey`,
194
+ and the snapshot filenames and their sub-issue keys all keep the old prefix, so
176
195
  `/spec-push` starts failing with `no Linear issue found for SKI-7`.
177
196
 
178
197
  `retarget` detects the rename (the team id survives it; the key does not) and
@@ -195,6 +214,23 @@ so and asks you to confirm the key rather than guessing.
195
214
 
196
215
  ## 9. Report
197
216
 
198
- Relay the engine's output. Name the subcommand you ran, in full, so the user can
199
- re-run it themselves. For anything that wrote, say what changed in Linear and
200
- that the repo is unchanged — it is the source of truth either way.
217
+ Relay the engine's output **above the block**, and name the subcommand you ran
218
+ **in full**, so the user can re-run it themselves.
219
+
220
+ End with the block defined in `.claude/rules/spec-reports.md`. That file carries
221
+ the shape; this section carries only what is specific here.
222
+
223
+ **Verdicts**
224
+
225
+ - `✅` — the subcommand did what it says.
226
+ - `⚠️` — it ran, with something worth knowing — a partial result, a warning it
227
+ printed, a degradation it fell back to.
228
+ - `❌` — it wrote some objects and failed on another. Say what exists now.
229
+ - `⏸` — it refused: no config, an unvalidated state list, a bad argument.
230
+ Nothing was written.
231
+
232
+ **Fields:** `Tracker` · `Follow-ups` · `Next`
233
+
234
+ `Tracker` says what changed in Linear **and that the repo is unchanged** — it is
235
+ the source of truth either way, and a report that omits the second half reads as
236
+ though a sync had edited the repo.
@@ -6,11 +6,16 @@ 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
- `complete/`, and tears the environment down. **`/spec-to-main` stops after the
12
- land**: the worktree stays, the spec stays `In Progress`, and you can land again
13
- as you add commits.
16
+ `complete/`, and tears the environment down.
17
+ **`/spec-to-main` stops after the land**: the worktree stays, the spec stays
18
+ `In Progress`, and you can land again as you add commits.
14
19
 
15
20
  Use it when a later phase can only be done *after* the current work is on `main` —
16
21
  e.g. it needs to run in CI, a deploy pipeline, or a shared test environment that
@@ -19,9 +24,9 @@ the remaining phases with `/spec-next` and eventually `/spec-complete`.
19
24
 
20
25
  It reuses the **same engine** as `/spec-complete`'s landing (`spec-env integrate`
21
26
  — rebase + fast-forward), so it produces identical linear history. Because a
22
- fast-forward leaves `base == branch`, the operation is **idempotent and
23
- repeatable**: new commits put the branch ahead of base again, and you can run
24
- `/spec-to-main` as many times as you like.
27
+ fast-forward leaves `base == branch`, the operation is
28
+ **idempotent and repeatable**: new commits put the branch ahead of base again,
29
+ and you can run `/spec-to-main` as many times as you like.
25
30
 
26
31
  ## 0. Preconditions — when this applies
27
32
 
@@ -58,10 +63,10 @@ primary checkout is dirty, or if a *different* spec holds it (release that one w
58
63
 
59
64
  ## 3. Tests must be green before landing
60
65
 
61
- Don't push red to `main`. Run the project's typecheck and test commands **in the
62
- worktree**; the suite must be **green**. For a **Bug** spec, confirm the
63
- originally-failing test now passes. If anything is red, stop and report — landing
64
- broken code onto `main` defeats the purpose.
66
+ Don't push red to `main`. Run the project's typecheck and test commands
67
+ **in the worktree**; the suite must be **green**. For a **Bug** spec, confirm
68
+ the originally-failing test now passes. If anything is red, stop and report —
69
+ landing broken code onto `main` defeats the purpose.
65
70
 
66
71
  (Note this is the *worktree* suite. The whole point of this skill is often to run
67
72
  a *further* check that only exists on `main` / in CI — that one runs **after** the
@@ -69,8 +74,8 @@ land, in step 5.)
69
74
 
70
75
  ## 4. Land — rebase + fast-forward
71
76
 
72
- Run `skitterspec spec-env integrate <name>` and run the printed commands **in
73
- order**:
77
+ Run `skitterspec spec-env integrate <name>` and run the printed commands
78
+ **in order**:
74
79
 
75
80
  - `git -C <worktree> rebase <base>` — replay the branch onto base.
76
81
  - `git -C <mainRepoPath> merge --ff-only <branch>` — fast-forward base.
@@ -91,12 +96,29 @@ and continue — the branch has no commits base doesn't already have.
91
96
  `- <YYYY-MM-DD> — Landed intermediate work onto <base> to <run CI / deploy to
92
97
  test env / …>; spec stays In Progress.`
93
98
  - Do **NOT**: add a State-log row (status doesn't change), flip any phase/status
94
- to Complete, `git mv` the spec, or tear down the worktree/stack. **The spec
95
- stays `In Progress` and the worktree stays put.**
96
- - Report: the base branch, the fast-forward result, and the green base test. It
97
- **never pushes** — mention the user can `git push` the base branch themselves to
99
+ to Complete, `git mv` the spec, or tear down the worktree/stack.
100
+ **The spec stays `In Progress` and the worktree stays put.**
101
+ - It **never pushes** say the user can `git push` the base branch themselves to
98
102
  trigger CI / the shared env.
99
- - Point the way forward: `/spec-next` to continue the remaining phases (you'll keep
100
- committing on the same branch and can `/spec-to-main` again), and `/spec-complete`
101
- when every phase is genuinely done — it will land the final commits, finalise,
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-linear",
3
- "version": "11.0.0",
4
- "description": "Spec-driven development for Claude Code, with one-way Linear sync a superset of @skitterbyte/skitterspec: the base filesystem workflow plus /spec-status · /spec-push and the spec-sync CLI. The repo is canonical; Linear is a generated mirror. Install this OR the base, not both.",
3
+ "version": "13.0.0",
4
+ "description": "Spec-driven development for Claude Code, with one-way Linear sync \u2014 a superset of @skitterbyte/skitterspec: the base filesystem workflow plus /spec-status \u00b7 /spec-push and the spec-sync CLI. The repo is canonical; Linear is a generated mirror. Install this OR the base, not both.",
5
5
  "keywords": [
6
6
  "claude",
7
7
  "claude-code",
@@ -25,14 +25,18 @@
25
25
  "MIGRATION.md"
26
26
  ],
27
27
  "engines": {
28
- "node": ">=18"
28
+ "node": ">=22.13"
29
29
  },
30
30
  "dependencies": {
31
31
  "prompts": "^2.4.2"
32
32
  },
33
+ "scripts": {
34
+ "prepare": "node ../../scripts/build-dist.js skitterspec-linear",
35
+ "prepack": "node ../../scripts/build-dist.js skitterspec-linear"
36
+ },
33
37
  "repository": {
34
38
  "type": "git",
35
- "url": "git+https://github.com/skitterbyte/skitterspec.git"
36
- },
37
- "scripts": {}
38
- }
39
+ "url": "git+https://github.com/SkitterByte/skitterspec.git",
40
+ "directory": "packages/skitterspec-linear"
41
+ }
42
+ }