@skitterbyte/skitterspec-linear 7.0.2 → 8.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.
@@ -1,9 +1,11 @@
1
- # Setting up Linear hybrid-sync
1
+ # Setting up Linear sync (one-way)
2
2
 
3
- A start-to-finish guide to getting `/spec-status`, `/spec-pull`, and `/spec-push`
4
- working against a real Linear workspace. Covers the **Linear side** (connecting
5
- the MCP server, finding your team) that the config reference
6
- (`linear.config.md`) assumes you already have.
3
+ A start-to-finish guide to getting `/spec-status` and `/spec-push` working against
4
+ a real Linear workspace. Sync is **one-way**: the repo is the source of truth and
5
+ the linked Linear project is a **generated mirror** content is pushed up, never
6
+ read back or merged. Covers the **Linear side** (connecting the MCP server,
7
+ finding your team) that the config reference (`linear.config.md`) assumes you
8
+ already have.
7
9
 
8
10
  > The whole feature is **opt-in**: until `specs/.core/linear.config.json` exists,
9
11
  > everything below is inert and the package behaves exactly like the base
@@ -47,7 +49,7 @@ claude mcp list
47
49
  ```
48
50
 
49
51
  > Read-only trial: use `https://mcp.linear.app/mcp/readonly` to exercise
50
- > `/spec-status` and `/spec-pull` without granting write access. `/spec-push`
52
+ > `/spec-status` (drift report) without granting write access. `/spec-push`
51
53
  > needs the full (writable) endpoint.
52
54
 
53
55
  ## 3. Find your team id
@@ -108,33 +110,30 @@ Two ways to get there:
108
110
 
109
111
  | Command | Direction | What it does |
110
112
  |---------|-----------|--------------|
111
- | `/spec-status` | — | Read-only. Per-field divergence: `local-only` / `remote-only` / `conflict` / `in sync`. |
112
- | `/spec-pull` | Linearrepo | Applies remote-owned fields (status/priority/labels). Refuses a real conflict unless `--force`. |
113
- | `/spec-push` | repo → Linear | Sends the co-authored `description` up. Refuses if a co-authored field moved on Linear since your last sync (pull first) unless `--force`. |
114
-
115
- Typical loop: `/spec-status` `/spec-pull` (take Linear's status) edit the spec
116
- in-repo → `/spec-push` (send content up).
117
-
118
- ### What actually syncs
119
-
120
- | Field | Owner | Direction |
121
- |-------|-------|-----------|
122
- | `description` (the whole spec body: problem, solution, **phases**, acceptance criteria) | co-authored | push **and** pull |
123
- | `workflowState` `spec_status` | Linear | pull only |
124
- | `priority` | Linear | pull only |
125
- | `labels` | Linear | pull only |
126
-
127
- By default the **entire spec body travels as the project `description`** phases
128
- and acceptance criteria included.
129
-
130
- **Optional: body round-trip.** Opt in — add `milestones`/`tasks` to
131
- `sync.keyedFields` (and `sync.fieldOwnership`) and phases sync as **Milestones**
132
- and tasks as **Issues**, compared per item: edit an individual phase or task in
133
- Linear and pull just that back into the right phase file / task line, or push
134
- local changes up. The link ids live in the phase file frontmatter
135
- (`linear_milestone_id`) and inline on task lines (`- [ ] do it (SKI-123)`).
136
- Deletions are report-only (surfaced by `/spec-status`, never auto-applied). Full
137
- details in the "Body round-trip" section of `linear.config.md`.
113
+ | `/spec-status` | — | Read-only drift report: what would push (create/update), and whether Linear's workflow-state drifted from the spec. Writes nothing. |
114
+ | `/spec-push` | repoLinear | Computes a create/update plan vs the last-pushed snapshot and applies it (project description/status, milestones, issues), stamping new ids back into the spec. |
115
+
116
+ Typical loop: edit the spec in-repo → `/spec-status` (what's pending) →
117
+ `/spec-push` (send it up). There is no pull Linear is a generated mirror.
118
+
119
+ ### What gets pushed
120
+
121
+ | Field | What |
122
+ |-------|------|
123
+ | `description` | the spec body (problem, solution, acceptance criteria) as the project description |
124
+ | `milestones` | one per phase (name + goal) |
125
+ | `issues` | one per task first-sentence **title**, full task text as the **description** |
126
+ | `workflowState` project status | the spec's lifecycle bucket, mapped via `states` |
127
+
128
+ Priority, labels, cycles and comments are **Linear-native triage** — the PM's to
129
+ set in Linear. One-way sync neither pushes nor reads them, so they're never
130
+ clobbered. A workflow-state a teammate moves in Linear is surfaced by
131
+ `/spec-status` as drift and overwritten on the next push.
132
+
133
+ Phases push as **Milestones** and tasks as **Issues** by default. The link ids
134
+ live in the phase-file frontmatter (`linear_milestone_id`) and inline on task
135
+ lines (`- [ ] do it (SKI-123)`); `/spec-push` stamps them the first time it
136
+ creates each object, so later pushes update instead of recreate.
138
137
 
139
138
  Sections listed in `sync.localOnlySections` (default: **State log**, **Changelog**,
140
139
  **Open questions**) are stripped from the pushed description — they never leave
@@ -142,24 +141,20 @@ the repo.
142
141
 
143
142
  ## 7. What to commit
144
143
 
145
- - **Commit** `specs/.core/linear-base/` — the three-way merge's base sidecars
146
- (last-synced snapshot per spec). Each worktree carries its own, so it must
147
- travel with the branch.
148
- - **Gitignore** `specs/.core/linear-backups/` — `--force` recovery copies, local
149
- and per-machine. Add `specs/.core/linear-backups/` to `.gitignore`.
144
+ - **Commit** `specs/.core/linear-base/` — the last-pushed snapshots (content
145
+ hashes per spec, so `/spec-push` knows what changed without reading Linear
146
+ back). Each worktree carries its own, so it must travel with the branch.
150
147
 
151
148
  ## 8. Smoke test (verify your setup)
152
149
 
153
- With a linked spec, confirm the round-trip end-to-end:
150
+ With a linked spec, confirm push end-to-end:
154
151
 
155
- 1. `/spec-status` → note the current divergence.
156
- 2. `/spec-pull` → Linear's status/priority/labels land in the spec's frontmatter
157
- (`spec_status`, `priority`, `labels`).
158
- 3. `/spec-status` again → **in sync**. (This also proves description idempotency:
159
- Linear rewrites markdown bullets on save, and the sync canonicalizes both
160
- sides so that never shows as a spurious change.)
161
- 4. Edit the spec body locally, `/spec-push` → the change lands on the Linear
162
- project's description; `/spec-status` returns to **in sync**.
152
+ 1. `/spec-status` → shows what would push (`pending — N to create, M to update`).
153
+ 2. `/spec-push` → creates the project's milestones/issues and sets the
154
+ description/status; ids are stamped back into the spec.
155
+ 3. `/spec-status` again → **up to date** (nothing changed since the last push).
156
+ 4. Edit a task locally, `/spec-push` the matching issue updates;
157
+ `/spec-status` returns to **up to date**.
163
158
 
164
159
  ## Troubleshooting
165
160
 
@@ -167,9 +162,9 @@ With a linked spec, confirm the round-trip end-to-end:
167
162
  this session. Re-run step 2; remember a fresh add needs a Claude Code restart.
168
163
  - **"missing required tools: projectUpdate"** — you're on the read-only endpoint
169
164
  (or a restricted API key). Use `https://mcp.linear.app/mcp` for push.
170
- - **A field won't stop showing as diverged** — that field genuinely differs on
171
- the two sides. `pull`-owned fields (status/priority/labels) resolve to Linear;
172
- `/spec-pull` reconciles them. For a co-authored `conflict`, resolve locally or
173
- `--force` (which backs up the losing side under `sync.backupDir` first).
165
+ - **A configured status name silently does nothing** — Linear ignores an unknown
166
+ project status. Run `/spec-status` (it validates the `states` names against the
167
+ workspace) and fix `linear.config.json` to the real project-status names
168
+ (`Backlog / Planned / In Progress / Completed / Canceled`).
174
169
  - **Reconnecting doesn't switch workspace** — Linear ties the OAuth session to one
175
170
  workspace. Remove and re-add the server to authenticate against another.
@@ -12,8 +12,8 @@
12
12
  "states": {
13
13
  "backlog": "Backlog",
14
14
  "in-progress": "In Progress",
15
- "complete": "Done",
16
- "cancelled": "Cancelled"
15
+ "complete": "Completed",
16
+ "cancelled": "Canceled"
17
17
  },
18
18
  "snapshot": {
19
19
  "overviewFile": "00-overview.md"
@@ -1,10 +1,12 @@
1
- # `linear.config.json` — Linear hybrid-sync config
2
-
3
- Opt-in config for the git-like Linear sync (`/spec-status`, `/spec-pull`,
4
- `/spec-push`, and the Linear-aware paths of `/spec` and `/spec-go`). Linear owns
5
- **status and discussion**; the repo stays the **co-authoring surface for spec
6
- content**. Sync is bidirectional but git-like: explicit commands, a committed
7
- **base sidecar** for three-way merge, and no blind overwrites.
1
+ # `linear.config.json` — Linear one-way sync config
2
+
3
+ Opt-in config for the Linear sync (`/spec-status`, `/spec-push`, and the
4
+ Linear-aware paths of `/spec` and `/spec-go`). Sync is **one-way**: the repo is
5
+ the source of truth and the Linear project is a **generated mirror**. Content is
6
+ pushed up and never read back or merged — `/spec-push` diffs the spec against a
7
+ committed **last-pushed snapshot** and applies only what changed; `/spec-status`
8
+ is a read-only drift report. The `sync.fieldOwnership` map now just selects the
9
+ projection field set (every field is repo-owned and pushed).
8
10
 
9
11
  **Every Linear step is gated on this file.** While `specs/.core/linear.config.json`
10
12
  is absent the feature is simply unused — `/spec`, `/spec-go`, and the CLI's
@@ -68,13 +68,15 @@ Beneath it, `skitterspec spec-env live <take|release|abort|status>` is the engin
68
68
  tracker-free: it knows nothing about any specific ticketing system. A
69
69
  ticketing provider is installed as its own distribution that plugs into two named
70
70
  **seams** in the shared skills (`/spec` Phase E, `/spec-go` step 3b) and fulfils a
71
- skill-name + CLI contract it ships `/spec-status` (read-only per-field
72
- divergence), `/spec-pull` (tracker→repo), and `/spec-push` (repo→tracker), backed
73
- by a `spec-sync` CLI, three-way merged against a committed base sidecar. When a
74
- provider is present, `/spec` also links the spec to the tracker and `/spec-go`
75
- pulls first. With no provider installed the seams are empty and every skill
76
- behaves as a plain filesystem workflow. See the provider package's own docs for
77
- its config and field reference.
71
+ skill-name + CLI contract. Sync is **one-way**: the repo is the source of truth
72
+ and the tracker is a **generated mirror**. It ships `/spec-push` (repo→tracker;
73
+ computes a create/update plan against a committed last-pushed snapshot and applies
74
+ it) and `/spec-status` (read-only drift report what would push, and whether the
75
+ tracker's workflow-state drifted), backed by a `spec-sync` CLI. There is no
76
+ content pull the tracker is never read back or merged. When a provider is
77
+ present, `/spec` also links the spec to the tracker. With no provider installed
78
+ the seams are empty and every skill behaves as a plain filesystem workflow. See
79
+ the provider package's own docs for its config and field reference.
78
80
 
79
81
  ## Project conventions (fill this in)
80
82
 
@@ -137,19 +137,18 @@ change to the flow below. Follow the provider's pull steps below (nothing to do
137
137
  here without one).
138
138
 
139
139
  **Only when `specs/.core/linear.config.json` exists** and the spec carries a
140
- `linear_project_id` in its `00-overview.md` frontmatter. Otherwise skip this
141
- step — no config means zero change to the flow below.
142
-
143
- - **Run `/spec-pull` first.** Bring down anything Linear changed since the last
144
- sync (status, priority, discussion-driven fields) so you build against the
145
- current shared state, not a stale snapshot. On a conflict it refuses relay
146
- that and let the user resolve before continuing; do not `--force` for them.
147
- - **Commit the refreshed snapshot** into the feature branch (a small
148
- `chore(spec): pull latest from Linear`-style commit) so the frozen spec rides
149
- in the PR alongside the code it describes.
150
- - Linear's GitHub branch/PR automation may now drive status transitions off the
151
- branch and PR you pushed in step 2 — expect state to move on the Linear side;
152
- keep any manual status edits minimal to avoid fighting it.
140
+ `linear_project_id`. Otherwise skip this step no config means zero change.
141
+
142
+ - **No pull.** Linear is a generated mirror in one-way sync, so there is nothing
143
+ to bring down before building the repo is already the source of truth. (A
144
+ workflow-state a teammate moved in Linear is advisory only; `/spec-status`
145
+ surfaces it. It is overwritten on the next push.)
146
+ - **Optional: refresh the mirror.** If you want Linear to reflect the now
147
+ in-progress spec, run `/spec-push` to send it up. This is optional at
148
+ `/spec-go` time the mirror can equally be refreshed later.
149
+ - Linear's GitHub branch/PR automation may drive status transitions off the
150
+ branch/PR you pushed in step 2; that's expected and the repo still wins on the
151
+ next `/spec-push`.
153
152
 
154
153
  ## 4. Implement the phase
155
154
 
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  name: spec-push
3
- description: Push a spec's local content up to its linked Linear project (repo → Linear), three-way aware and ownership-respecting. Never pushes pull-owned fields or local-only sections; aborts if Linear moved since the last sync unless --force (which backs up the remote side first). Runs `skitterspec spec-sync push` then applies the blessed writes over MCP. Opt-in — needs specs/.core/linear.config.json. Use when the user says "/spec-push", "push to Linear", "sync my spec up to Linear", or "update the Linear project from this spec".
3
+ description: Push a spec up to its linked Linear project (repo → Linear, one-way). The repo is the source of truth; Linear is a generated mirror. Runs `skitterspec spec-sync push` to get a create/update plan, applies it over MCP (project description/status, milestones, issues), stamps the returned ids back into the spec, then records the snapshot. Never reads Linear content back. Opt-in — needs specs/.core/linear.config.json. Use when the user says "/spec-push", "push to Linear", "update the Linear project from this spec".
4
4
  ---
5
5
 
6
- # /spec-push — send spec content up to Linear
6
+ # /spec-push — send a spec up to Linear (one-way)
7
7
 
8
- Repo → Linear. Sends the fields the repo owns/co-authors (description, phases,
9
- tasks per config) up to the linked project. It **never** writes `pull`-owned
10
- fields (status/priority/labels) or `localOnlySections`, and it **aborts** if
11
- Linear moved since the last sync (pull first) unless you `--force`.
8
+ Repo → Linear. The repo is the **source of truth**; Linear is a **generated
9
+ mirror**. This skill computes what changed since the last push and applies it
10
+ it never reads Linear content back or merges. A person editing the mirror in
11
+ Linear will see it overwritten on the next push.
12
12
 
13
13
  **Opt-in**: only runs when `specs/.core/linear.config.json` exists. If absent,
14
14
  tell the user how to enable Linear sync and stop.
@@ -17,58 +17,64 @@ tell the user how to enable Linear sync and stop.
17
17
 
18
18
  Use the argument, else the spec in context; ask if unclear.
19
19
 
20
- ## 2. Fetch the Linear project
20
+ ## 2. Get the plan from the engine
21
21
 
22
- - Read `linear_project_id` from `00-overview.md` frontmatter; if missing, stop
23
- (link via `/spec` first).
24
- - Discover the Linear MCP tools at runtime (project read **and** update). If
25
- Linear isn't connected — or the update tool is missing — relay the fix and stop,
26
- **writing nothing**.
27
- - Call the read tool and write the project JSON to a temp file.
22
+ ```
23
+ skitterspec spec-sync push <spec> --json
24
+ ```
28
25
 
29
- ## 3. Run the engine (the guard)
26
+ The engine prints a JSON **plan** (no network, no remote read):
30
27
 
28
+ ```json
29
+ {
30
+ "project": { "description": "…", "status": "in-progress", "priority": 2, "labels": ["…"] },
31
+ "milestones": { "create": [{ "ref": "01-outbox", "name": "…", "goal": "…" }], "update": [{ "id": "…", "name": "…", "goal": "…" }] },
32
+ "issues": { "create": [{ "ref": "<task text>", "title": "…", "description": "…", "done": false, "milestoneRef": "01-outbox" }], "update": [{ "id": "SKI-1", "title": "…", "description": "…", "done": true }] }
33
+ }
31
34
  ```
32
- skitterspec spec-sync push <spec> --remote <tempfile> --out <mergedfile> [--force]
33
- ```
34
35
 
35
- - **Refused** (`remote-moved` / `concurrent-write` / conflict) relay the message
36
- and **stop**. Do not write to Linear. Suggest `/spec-pull` first.
37
- - **OK** — the engine has confirmed it's safe, rewritten the base, and stamped
38
- `last_synced_at`. Its summary lists the `written` fields (and any `skipped`
39
- because they're not pushable).
40
- - **`--force`** — only when the user explicitly asks. Local wins after the engine
41
- backs up the remote side under `sync.backupDir`. Relay the backup path.
36
+ An empty plan (no project, no create/update) means the mirror is up to date —
37
+ say so and stop.
38
+
39
+ ## 3. Discover the Linear MCP tools
42
40
 
43
- ## 4. Apply the blessed writes to Linear
41
+ Discover project + milestone + issue **create/update** tools at runtime. If
42
+ Linear isn't connected or a needed tool is missing, relay the fix and stop,
43
+ **writing nothing**.
44
44
 
45
- Only when step 3 returned OK: for each `written` field, call the Linear update
46
- tool with that field's local value (e.g. `description` the project description).
47
- The engine has already vetted the change and moved the base so if a Linear
48
- write fails, re-run `/spec-pull` to reconcile rather than retrying blindly.
45
+ **Validate the project states first.** Fetch the workspace's project-status
46
+ names and run `skitterspec spec-sync status <spec> --workspace-states <file>`; if
47
+ it errors (a configured `states` name isn't in the workspace), stop and fix the
48
+ config Linear silently ignores an unknown project status.
49
49
 
50
- **Milestones (`milestonesPush` in the result).** When milestones are keyed, the
51
- engine can't write them itself — apply the plan over MCP:
50
+ ## 4. Apply the plan (order matters)
52
51
 
53
- - `update`: for each `{ id, name, goal }`, call the milestone-save tool with that
54
- `id` (name milestone name, goal its description).
55
- - `create`: for each `{ name, goal }`, call the milestone-save tool with no id to
56
- create it under the project, then **stamp the returned milestone id** into the
57
- matching phase file's frontmatter (`linear_milestone_id`) so it links on the
58
- next sync. Match the phase file by its title.
52
+ 1. **Milestones create** → create each in Linear; for each, stamp the returned id
53
+ into its phase file: the `ref` is the phase-file basename.
54
+ 2. **Issues create** create each (link to its milestone by `milestoneRef`,
55
+ resolving a `create` ref to the id just minted); stamp the returned identifier
56
+ back onto the matching task line (`ref` is the task's text).
57
+ 3. **Milestones/issues update** save by `id`.
58
+ 4. **Project** → set description + status (map `status` — the local bucket — to
59
+ the Linear project-status name via `config.states`). Priority, labels, cycles
60
+ and comments are Linear-native triage — do **not** push them; they're the PM's.
59
61
 
60
- Progress is Linear-derived never push it.
62
+ Map the local status bucket to Linear's project status through `config.states`
63
+ (e.g. `complete → Completed`).
61
64
 
62
- **Issues (`issuesPush` in the result).** When tasks are keyed:
65
+ ## 5. Record the snapshot
66
+
67
+ After everything applied and the ids are stamped into the files:
68
+
69
+ ```
70
+ skitterspec spec-sync record <spec>
71
+ ```
63
72
 
64
- - `update`: for each `{ id, text, done }`, call the issue-save tool with that `id`
65
- (text title; `done` a completed state, else a non-completed state — leave an
66
- already-non-completed issue's exact state untouched).
67
- - `create`: for each `{ text, done }`, create an issue under the project (attach it
68
- to the milestone of the phase the task lives in when known), then **stamp the new
69
- issue identifier inline** on that task line (`… (SKI-123)`), matching by text.
73
+ This writes the last-pushed snapshot from the now-stamped files, so the next
74
+ `/spec-push` produces an empty plan. Commit the stamped spec + snapshot into the
75
+ branch so the mirror-link rides in the PR.
70
76
 
71
- ## 5. Report
77
+ ## 6. Report
72
78
 
73
- Relay the git-like summary (written / skipped / backup / base) plus which Linear
74
- fields you updated.
79
+ Summarise what was created/updated in Linear and confirm the snapshot was
80
+ recorded. There is no pull — Linear is a generated mirror.
@@ -1,46 +1,51 @@
1
1
  ---
2
2
  name: spec-status
3
- description: Show a spec's sync status against its linked Linear project — a read-only, git-status-style per-field divergence (local-only / remote-only / conflict / in-sync). Fetches the Linear project 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's diverged from Linear", or "show spec sync status".
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 workflow-state differs from the spec's. Fetches the Linear project 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
4
  ---
5
5
 
6
- # /spec-status — show a spec's divergence from Linear
6
+ # /spec-status — one-way sync drift report
7
7
 
8
- Read-only. Prints, per field, whether the spec and its linked Linear project have
9
- diverged since the last sync — the `git status` of the hybrid sync. Writes
10
- nothing to either side.
8
+ Read-only. Reports two things and writes nothing:
11
9
 
12
- This skill is **opt-in**: it only runs when `specs/.core/linear.config.json`
13
- exists. If it's absent, tell the user to copy `linear.config.json.example`
14
- `linear.config.json` to enable Linear sync, and stop.
10
+ 1. **Pending push** has the spec changed since the last push (are there
11
+ milestones/issues/description to create or update)?
12
+ 2. **State drift** — does Linear's project workflow-state differ from the spec's
13
+ status? (The repo wins on the next push; this is just a heads-up, e.g. a card
14
+ moved in Linear.)
15
+
16
+ The repo is the source of truth; Linear is a generated mirror, so there is no
17
+ per-field "conflict" — only "what would the next push send" and "did the mirror
18
+ drift".
19
+
20
+ **Opt-in**: only runs when `specs/.core/linear.config.json` exists. If absent,
21
+ tell the user how to enable Linear sync and stop.
15
22
 
16
23
  ## 1. Identify the target spec
17
24
 
18
- Use the spec named as an argument, else the spec **currently in context**. If
19
- neither is clear, ask which spec.
25
+ Use the argument, else the spec in context; ask if unclear.
26
+
27
+ ## 2. Fetch the Linear project (optional, for drift)
20
28
 
21
- ## 2. Fetch the Linear project (read-only)
29
+ If the spec has a `linear_project_id`, discover the Linear MCP read tool and write
30
+ the project JSON to a temp file — this lets the report compare workflow-state. If
31
+ Linear isn't connected, skip the drift line (still report pending-push).
22
32
 
23
- - Read the spec's `linear_project_id` from `00-overview.md` frontmatter. If it's
24
- missing, the spec isn't linked yet — say so and stop (link it via `/spec`).
25
- - Discover the connected Linear MCP tools at runtime (the project-read tool). If
26
- Linear isn't connected, relay "connect the `linear` MCP server" and stop — do
27
- nothing else.
28
- - Call the project-read tool for that id and write the returned JSON to a temp
29
- file (e.g. under the OS temp dir).
33
+ Optionally fetch the workspace project-status names to a file to validate the
34
+ configured `states` at the same time.
30
35
 
31
36
  ## 3. Run the engine
32
37
 
33
38
  ```
34
- skitterspec spec-sync status <spec> --remote <tempfile>
39
+ skitterspec spec-sync status <spec> [--remote <projectfile>] [--workspace-states <statesfile>]
35
40
  ```
36
41
 
37
- The engine does the three-way compare (local vs Linear vs the committed base) and
38
- prints each diverged field with its classification and sync direction. Without
39
- `--remote` it falls back to a local-vs-base comparison (still read-only).
42
+ - Reports `push: pending N to create, M to update` or `up to date`.
43
+ - With `--remote`, adds a `drift:` line comparing Linear's workflow-state to the
44
+ spec's status.
45
+ - With `--workspace-states`, fails loudly if a configured state name isn't in the
46
+ workspace (Linear would silently no-op it).
40
47
 
41
48
  ## 4. Report
42
49
 
43
- Relay the engine's summary verbatim, then offer the natural next step:
44
- `/spec-pull` for remote-only changes, `/spec-push` for local-only, and — for a
45
- `conflict` — resolve locally or use `--force` (which backs up the losing side).
46
- Never write anything from this skill.
50
+ Relay the engine's output verbatim. Suggest `/spec-push` if a push is pending.
51
+ Never write to either side.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skitterbyte/skitterspec-linear",
3
- "version": "7.0.2",
3
+ "version": "8.0.0",
4
4
  "description": "Spec-driven development for Claude Code, with Linear hybrid-sync — a superset of @skitterbyte/skitterspec: the base filesystem workflow plus git-like /spec-status · /spec-pull · /spec-push and the spec-sync CLI. Install this OR the base, not both.",
5
5
  "keywords": [
6
6
  "claude",
Binary file