@skitterbyte/skitterspec-linear 10.5.2 → 10.7.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/assets/claude-md-section.md +19 -9
- package/assets/commands/spec-connect.md +13 -0
- package/assets/commands/spec-live.md +14 -0
- package/assets/core/ci-stages.md +110 -0
- package/assets/core/env.config.md +18 -0
- package/assets/core/linear.config.json.example +3 -0
- package/assets/core/linear.config.md +46 -0
- package/assets/rules/commit-trailers.md +84 -0
- package/assets/rules/spec-planning.md +17 -3
- package/assets/skills/spec/SKILL.md +20 -0
- package/assets/skills/spec-bug/SKILL.md +40 -2
- package/assets/skills/spec-cancel/SKILL.md +9 -0
- package/assets/skills/spec-complete/SKILL.md +12 -1
- package/assets/skills/spec-go/SKILL.md +60 -28
- package/assets/skills/spec-hotfix/SKILL.md +41 -3
- package/assets/skills/spec-linear-setup/SKILL.md +38 -2
- package/assets/skills/spec-status/SKILL.md +1 -0
- package/assets/skills/spec-sync/SKILL.md +27 -2
- package/assets/skills/spec-to-main/SKILL.md +2 -1
- package/bin/skitterspec-linear.js +10 -0
- package/package.json +1 -1
- package/src/cli.js +176 -39
- package/src/env/config.js +19 -0
- package/src/env/teardown.js +62 -4
- package/src/init.js +120 -2
- package/src/vendor/linear/cli-sync.js +560 -12
- package/src/vendor/linear/config.js +91 -1
- package/src/vendor/linear/doctor.js +67 -1
- package/src/vendor/linear/released.js +164 -0
- package/src/vendor/sync-core/index.js +4 -1
- package/src/vendor/sync-core/src/compare.js +59 -3
- package/src/vendor/sync-core/src/normalize.js +65 -2
- package/assets/skills/spec-connect/SKILL.md +0 -59
- package/assets/skills/spec-live/SKILL.md +0 -73
|
@@ -7,7 +7,8 @@ description: Promote a spec into active development and build the next phase —
|
|
|
7
7
|
|
|
8
8
|
The "up" button: it promotes the spec, provisions its worktree, brings its host
|
|
9
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
|
|
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).
|
|
11
12
|
|
|
12
13
|
## 1. Identify the target spec
|
|
13
14
|
|
|
@@ -33,8 +34,8 @@ branch. Instead skip the provisioning bullets and step 2b, leave the spec where
|
|
|
33
34
|
it is, and go straight to **step 4**, implementing the phase **in the primary
|
|
34
35
|
checkout on the branch** — edits and commits there advance the branch, and
|
|
35
36
|
`/spec-complete` lands them. (`spec-env up` refuses while live and says the same.
|
|
36
|
-
To return to an isolated worktree instead,
|
|
37
|
-
re-run `/spec-go`.)
|
|
37
|
+
To return to an isolated worktree instead, ask the user to type `/spec-live main`
|
|
38
|
+
first, then re-run `/spec-go`.)
|
|
38
39
|
|
|
39
40
|
**If per-spec isolation is enabled** (`specs/.core/env.config.json` exists), the
|
|
40
41
|
spec **isn't already live** (the check above), and it doesn't already have a
|
|
@@ -121,11 +122,12 @@ runnable — its UI/API on the spec's reserved port block, isolated from `main`.
|
|
|
121
122
|
dev process detached on its port, logs to `.spec-env/logs/`, and waits on each
|
|
122
123
|
`health` check. With no `dev` configured it's a clean no-op; skip this step.
|
|
123
124
|
- **Diverting your browser is a separate step.** To test the spec at your normal
|
|
124
|
-
`localhost` URL,
|
|
125
|
-
spec on the canonical ports; `/spec-connect main` hands them back).
|
|
126
|
-
never seizes the canonical ports on its own. For a **code-only** spec,
|
|
127
|
-
lighter **`/spec-live <name>`** reuses
|
|
128
|
-
branch-switch, no second stack) — `/spec-live main` hands it back.
|
|
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.
|
|
129
131
|
|
|
130
132
|
## 3. Pre-flight — commit prior work
|
|
131
133
|
|
|
@@ -139,11 +141,17 @@ Before writing any code for this phase, get the workspace clean:
|
|
|
139
141
|
next phase on top of an uncommitted one. (Skip if this is the first phase —
|
|
140
142
|
there's nothing prior to commit.)
|
|
141
143
|
|
|
142
|
-
##
|
|
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 `🔄`.
|
|
143
150
|
|
|
144
|
-
**
|
|
145
|
-
|
|
146
|
-
|
|
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.
|
|
147
155
|
|
|
148
156
|
**Only when `specs/.core/linear.config.json` exists** and the spec carries a
|
|
149
157
|
`linear_identifier`. Otherwise skip this step — no config means zero change.
|
|
@@ -152,26 +160,27 @@ below. Follow the provider's steps below (nothing to do here without one).
|
|
|
152
160
|
to bring down before building — the repo is already the source of truth. (A
|
|
153
161
|
workflow-state a teammate moved in Linear is advisory only; `/spec-status`
|
|
154
162
|
surfaces it. It is overwritten on the next push.)
|
|
155
|
-
- **Refresh the mirror.** Run `/spec-push
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
- `"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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.
|
|
165
180
|
- Linear's GitHub branch/PR automation may drive status transitions off the
|
|
166
181
|
branch/PR you pushed in step 2; that's expected and the repo still wins on the
|
|
167
182
|
next `/spec-push`.
|
|
168
183
|
|
|
169
|
-
## 4. Implement the phase
|
|
170
|
-
|
|
171
|
-
Identify the **first unfinished phase** from the `00-overview.md` phase index,
|
|
172
|
-
then open its phase file (`0N-<slug>.md`) — that file holds the tasks. Mark it
|
|
173
|
-
started: set the phase-file heading to `🔄` and its `> **Status:**` to
|
|
174
|
-
`In progress`, and flip the matching row in the overview phase index to `🔄`.
|
|
175
184
|
Then build it, following the project rules in `.claude/rules/*.md` and `CLAUDE.md`:
|
|
176
185
|
|
|
177
186
|
- Work task by task through the phase file. Make focused edits that match
|
|
@@ -194,6 +203,29 @@ Then build it, following the project rules in `.claude/rules/*.md` and `CLAUDE.m
|
|
|
194
203
|
- If new work surfaced, add it as tasks to the appropriate phase file (or add a
|
|
195
204
|
new phase file + index row) rather than doing it silently.
|
|
196
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
|
+
|
|
197
229
|
## 6. Report
|
|
198
230
|
|
|
199
231
|
Summarise what was implemented, the test result (quote failures if any), and
|
|
@@ -155,8 +155,22 @@ that header — must exist **before** `spec-env up`:
|
|
|
155
155
|
bootstrap steps.
|
|
156
156
|
- Run the printed `git worktree add`. **The worktree is checked out at the tag,
|
|
157
157
|
so your uncommitted stub doesn't travel with it** — move it across so `main`
|
|
158
|
-
stays pristine
|
|
159
|
-
|
|
158
|
+
stays pristine. **Create the destination bucket first:**
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
mkdir -p <worktreePath>/specs/in-progress
|
|
162
|
+
mv specs/in-progress/hotfix-<name> <worktreePath>/specs/in-progress/
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The `mkdir -p` is not belt-and-braces. Git does not store empty directories, so
|
|
166
|
+
`specs/in-progress/` is **absent** from the worktree whenever nothing was in
|
|
167
|
+
progress at that point in history — and here that point is an **old release
|
|
168
|
+
tag**, where it is absent more often than not. `mv` into a missing destination
|
|
169
|
+
renames your spec folder **to** `specs/in-progress`, silently: the spec's files
|
|
170
|
+
end up one level too high, `00-overview.md` sits where the bucket should be, and
|
|
171
|
+
every later step still appears to work until something cannot find the spec.
|
|
172
|
+
Confirm the result before carrying on — you want
|
|
173
|
+
`<worktreePath>/specs/in-progress/hotfix-<name>/00-overview.md`.
|
|
160
174
|
- **Bootstrap the worktree.** A fresh worktree has no installed dependencies and
|
|
161
175
|
none of the repo's gitignored files (`.env`, local overrides). Run the printed
|
|
162
176
|
`in the worktree, run:` steps (file seeding, then setup) in order, before
|
|
@@ -318,6 +332,30 @@ message.
|
|
|
318
332
|
- Commit the fix to the `hotfix/<slug>` branch (this commit is what gets tagged
|
|
319
333
|
and cherry-picked). Tick the Fix tasks; add a Changelog line.
|
|
320
334
|
|
|
335
|
+
**Then refresh the mirror (only if a provider is installed).** The Fix tasks are
|
|
336
|
+
ticked, so the repo is now the truth about this fix — and this skill can take a
|
|
337
|
+
bug all the way to green without `/spec-go` ever running. Without a provider this
|
|
338
|
+
is a no-op.
|
|
339
|
+
|
|
340
|
+
**Only when `specs/.core/linear.config.json` exists** and the spec carries a
|
|
341
|
+
`linear_identifier`. Either missing → **skip**, in one line
|
|
342
|
+
(`not linked to Linear — /spec-push to mirror it`), and carry on.
|
|
343
|
+
|
|
344
|
+
**Refresh the mirror now, without asking.** Run `/spec-push`. The repo has just
|
|
345
|
+
become the truth about this phase's progress, and progress is what the mirror
|
|
346
|
+
exists to show. Deferring it to `/spec-complete` is what makes every phase
|
|
347
|
+
sub-issue jump from Backlog straight to Done, with nothing visible in between.
|
|
348
|
+
|
|
349
|
+
- **Never mint.** An unlinked spec is skipped, not created.
|
|
350
|
+
- **Never fatal.** If the push fails — offline, no key, a Linear error — say so
|
|
351
|
+
and **finish the operation anyway**. The phase is done in the repo regardless;
|
|
352
|
+
the mirror is disposable and the next push repairs it.
|
|
353
|
+
- **Expect a dirty `specs/.core/` afterwards.** The push writes a base snapshot
|
|
354
|
+
and stamps any new ids, and these skills do not commit. The next `/commit`
|
|
355
|
+
sweeps it up with the phase's own work.
|
|
356
|
+
- **Say what happened** in the skill's report: mirror updated, skipped as
|
|
357
|
+
unlinked, or failed with the reason.
|
|
358
|
+
|
|
321
359
|
## 7. Report
|
|
322
360
|
|
|
323
361
|
Summarise: the base tag, root cause, the failing→passing test, the fix, and the
|
|
@@ -325,7 +363,7 @@ full test result. The spec stays in `in-progress`.
|
|
|
325
363
|
|
|
326
364
|
- **`/spec-live` is refused for a hotfix** — its branch is built on an old tag, so
|
|
327
365
|
hot-reloading it onto the running dev server could break the shared instance.
|
|
328
|
-
To test it,
|
|
366
|
+
To test it, the user runs `/spec-connect` (its own isolated stack).
|
|
329
367
|
- Suggest **`/spec-complete`** to land it: it patch-bumps the base tag, tags the
|
|
330
368
|
hotfix branch **locally** (you push it to deploy), and cherry-picks the fix onto
|
|
331
369
|
`main`. Add `--also <tag>` at completion to also patch other release lines
|
|
@@ -142,7 +142,38 @@ never apply one they didn't agree to), and re-run with the `--state` flags. If i
|
|
|
142
142
|
made no suggestion for a bucket, **ask** which state means "finished" here rather
|
|
143
143
|
than guessing.
|
|
144
144
|
|
|
145
|
-
## 7.
|
|
145
|
+
## 7. Does this repo deploy through stages? (optional)
|
|
146
|
+
|
|
147
|
+
A spec's lifecycle ends at `complete`. Where a ticket goes **after** that —
|
|
148
|
+
deployed to test, approved for demo, live in production — is a fact about an
|
|
149
|
+
environment, and nothing in the repo can derive it. If the team runs a deploy
|
|
150
|
+
pipeline, it can declare that ladder here and CI moves tickets along it with
|
|
151
|
+
`spec-sync stage`.
|
|
152
|
+
|
|
153
|
+
**Ask, do not assume.** Most projects have no ladder, and an invented one is
|
|
154
|
+
worse than none: `spec-sync stage` refuses cleanly when none is declared, whereas
|
|
155
|
+
a wrong ladder is a pipeline quietly moving tickets to the wrong column. If the
|
|
156
|
+
user does not raise deployment, offer it once in a line and take "no" for an
|
|
157
|
+
answer.
|
|
158
|
+
|
|
159
|
+
If they do want one, ask for the stages **in deployment order**, and map each to
|
|
160
|
+
a state from the `list_issue_statuses` names you already have:
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
--stage test="On Test" --stage demo="Ready for Demo" --stage prod="Done"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
- The **key** (`test`) is what a pipeline names; the **state** is the Linear
|
|
167
|
+
column. Pipelines reference the key, so renaming the column later is one edit
|
|
168
|
+
here.
|
|
169
|
+
- Order is recorded, not enforced — a rollback and a hotfix straight to prod are
|
|
170
|
+
both legitimate and are never refused.
|
|
171
|
+
- **Ask what closes an issue.** If the last rung is not a completed-type state,
|
|
172
|
+
tickets that finish the ladder never reach Done. That is fine when Linear
|
|
173
|
+
automation closes them and a problem otherwise — `spec-sync doctor` warns about
|
|
174
|
+
it either way, so say which it is.
|
|
175
|
+
|
|
176
|
+
## 8. Write it
|
|
146
177
|
|
|
147
178
|
```
|
|
148
179
|
skitterspec spec-sync init-config \
|
|
@@ -157,12 +188,17 @@ shows this repo's choices and keeps inheriting everything else. `--force` is
|
|
|
157
188
|
required to replace an existing config — never pass it without the user having
|
|
158
189
|
asked for a rewrite in step 1.
|
|
159
190
|
|
|
191
|
+
Every `--stage` state is checked against the workspace exactly like a bucket
|
|
192
|
+
state, and a bad one is refused the same way — as `release.stages[test]` rather
|
|
193
|
+
than `states.complete`. There is no suggestion for a rung: the vocabulary is the
|
|
194
|
+
project's own, so ask rather than guess.
|
|
195
|
+
|
|
160
196
|
**Relay the engine's report as printed.** It names the team, the project (or
|
|
161
197
|
"team only"), the intake labels, and how many state names were checked against
|
|
162
198
|
the workspace — that report is the evidence the setup is right, so don't
|
|
163
199
|
paraphrase it into "done".
|
|
164
200
|
|
|
165
|
-
##
|
|
201
|
+
## 9. Report and hand off
|
|
166
202
|
|
|
167
203
|
**Finish by checking, not by describing.** First write down what the MCP server
|
|
168
204
|
says, from the reads you already made in step 2 — no extra round trip unless a
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spec-status
|
|
3
3
|
description: Show a spec's one-way sync status against Linear — a read-only drift report. Reports whether the spec changed since the last push (there's something to push) and, optionally, whether Linear's issue workflow-state differs from the spec's. Fetches the Linear issue over MCP and runs `skitterspec spec-sync status`. Changes nothing. Opt-in — needs specs/.core/linear.config.json. Use when the user says "/spec-status", "is this spec in sync with Linear", "what would push", or "show spec sync status".
|
|
4
|
+
disable-model-invocation: true
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# /spec-status — one-way sync drift report
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spec-sync
|
|
3
3
|
description: Run the repo-wide spec-sync operations against Linear — what's linked, the workspace's states and projects, read-back verification, manual stamping, and bulk `apply --all <bucket>`. Run it bare for the repo-wide overview. Wraps the `spec-sync` CLI, which is a local devDependency and never on PATH, so this skill always states the full invocation. Defers to /spec-push and /spec-status for per-spec work. Opt-in — needs specs/.core/linear.config.json. Use when the user says "/spec-sync", "run spec-sync", "what's linked to Linear", "which states does the workspace have", or "mirror the whole backlog".
|
|
4
|
+
disable-model-invocation: true
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# /spec-sync — the repo-wide Linear sync operations
|
|
@@ -37,6 +38,8 @@ In a project that installs the Linear superset the binary is
|
|
|
37
38
|
| "link this spec to KEY-1 by hand" | `stamp <spec> --issue KEY-1` |
|
|
38
39
|
| "mirror the whole backlog / every complete spec" | `apply --all <bucket>` — **confirm first** |
|
|
39
40
|
| "is the team key stale?", "did Linear get renamed?" | `retarget` |
|
|
41
|
+
| "what ticket am I on?", writing a commit | `ref` |
|
|
42
|
+
| "what shipped in this release?" | `released` |
|
|
40
43
|
| push one spec, or "what would push?" | **defer** — see below |
|
|
41
44
|
|
|
42
45
|
**With no argument, run `linked`.** It is the repo-wide overview, it is
|
|
@@ -131,7 +134,29 @@ its object exists, so an interrupted run continues rather than duplicating.
|
|
|
131
134
|
|
|
132
135
|
`--all` refuses over MCP by design — bulk goes through the API path.
|
|
133
136
|
|
|
134
|
-
## 7. `
|
|
137
|
+
## 7. `ref` and `released` — tickets in commits
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
pnpm exec skitterspec-linear spec-sync ref [--json]
|
|
141
|
+
pnpm exec skitterspec-linear spec-sync released [<range>] [--json]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`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`.
|
|
149
|
+
|
|
150
|
+
`released` reports the tickets in a commit range — by default since the most
|
|
151
|
+
recent tag, and it always prints the range it chose so a wrong default is
|
|
152
|
+
visible. It is **read-only**: it does not move anything in Linear. A release can
|
|
153
|
+
be cut and never deployed, so transitioning tickets stays a deliberate act.
|
|
154
|
+
|
|
155
|
+
Relay the **unreferenced count** even when it is zero. A chore commit
|
|
156
|
+
legitimately carries no ticket and a *missed* trailer looks identical, so
|
|
157
|
+
omitting the number reads as "everything is accounted for" when it may not be.
|
|
158
|
+
|
|
159
|
+
## 8. `retarget` — after a Linear team is renamed
|
|
135
160
|
|
|
136
161
|
```
|
|
137
162
|
pnpm exec skitterspec-linear spec-sync retarget [--yes]
|
|
@@ -160,7 +185,7 @@ rewrites those fields. Read-only until `--yes`.
|
|
|
160
185
|
Over MCP the team key is unreadable (`get_team` does not return it), so it says
|
|
161
186
|
so and asks you to confirm the key rather than guessing.
|
|
162
187
|
|
|
163
|
-
##
|
|
188
|
+
## 9. Report
|
|
164
189
|
|
|
165
190
|
Relay the engine's output. Name the subcommand you ran, in full, so the user can
|
|
166
191
|
re-run it themselves. For anything that wrote, say what changed in Linear and
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spec-to-main
|
|
3
3
|
description: Land an in-progress spec's branch onto main WITHOUT finishing it — rebase + fast-forward so the work reaches main (to run it in CI / a shared test env), while the worktree stays and the spec stays In Progress. Repeatable — land again as you commit more. Targets a spec by name (arg) or the spec in context. Use when the user says "/spec-to-main", "land this on main but keep going", "I need this on main to run tests before finishing", or "merge to main without completing the spec".
|
|
4
|
+
disable-model-invocation: true
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# /spec-to-main — land the branch on main, keep the spec open
|
|
@@ -51,7 +52,7 @@ uncommitted changes, offer `/commit` and **stop**; don't auto-commit.
|
|
|
51
52
|
back to base, re-isolates it into its worktree, clears the receipt), then prints
|
|
52
53
|
the landing plan. Commit any live fixes to the branch first; it refuses if the
|
|
53
54
|
primary checkout is dirty, or if a *different* spec holds it (release that one with
|
|
54
|
-
`/spec-live main
|
|
55
|
+
`/spec-live main`, which the user types).
|
|
55
56
|
|
|
56
57
|
## 3. Tests must be green before landing
|
|
57
58
|
|
|
@@ -41,6 +41,16 @@ const {
|
|
|
41
41
|
async function main(argv) {
|
|
42
42
|
const [cmd, ...rest] = argv
|
|
43
43
|
|
|
44
|
+
// The check above asks whether src/ exists, which is inert in a workspace source
|
|
45
|
+
// package — src/ is committed there. That is exactly where the other half of the
|
|
46
|
+
// problem lives: a source package HAS a runnable bin and src, but its assets/ is
|
|
47
|
+
// PRE-composition (seam markers still literal). Installing from it writes those
|
|
48
|
+
// markers into the user's skills. So ask a second, positive question before any
|
|
49
|
+
// install command runs.
|
|
50
|
+
if (cmd === 'init' || cmd === 'update') {
|
|
51
|
+
require('../src/init.js').assertComposedAssets()
|
|
52
|
+
}
|
|
53
|
+
|
|
44
54
|
// Base help + what this distribution adds. Matched on the COMMAND SLOT only,
|
|
45
55
|
// never the whole argv: `spec-sanitise --help` must reach that command's own
|
|
46
56
|
// help, not be swallowed by the top-level one.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skitterbyte/skitterspec-linear",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.7.0",
|
|
4
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.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|