@skitterbyte/skitterspec-linear 1.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 (45) hide show
  1. package/README.md +56 -0
  2. package/assets/claude-md-section.md +39 -0
  3. package/assets/core/env.config.json.example +28 -0
  4. package/assets/core/env.config.md +99 -0
  5. package/assets/core/linear.config.json.example +39 -0
  6. package/assets/core/linear.config.md +121 -0
  7. package/assets/rules/spec-planning.md +152 -0
  8. package/assets/skills/spec/SKILL.md +232 -0
  9. package/assets/skills/spec-bug/SKILL.md +110 -0
  10. package/assets/skills/spec-cancel/SKILL.md +61 -0
  11. package/assets/skills/spec-complete/SKILL.md +87 -0
  12. package/assets/skills/spec-env/SKILL.md +63 -0
  13. package/assets/skills/spec-env-down/SKILL.md +64 -0
  14. package/assets/skills/spec-go/SKILL.md +134 -0
  15. package/assets/skills/spec-init/SKILL.md +84 -0
  16. package/assets/skills/spec-pull/SKILL.md +46 -0
  17. package/assets/skills/spec-push/SKILL.md +53 -0
  18. package/assets/skills/spec-ready/SKILL.md +50 -0
  19. package/assets/skills/spec-review/SKILL.md +69 -0
  20. package/assets/skills/spec-status/SKILL.md +46 -0
  21. package/bin/skitterspec-linear.js +26 -0
  22. package/package.json +38 -0
  23. package/src/cli.js +495 -0
  24. package/src/deprecate.js +138 -0
  25. package/src/env/config.js +165 -0
  26. package/src/env/integrate.js +46 -0
  27. package/src/env/provision.js +76 -0
  28. package/src/env/registry.js +95 -0
  29. package/src/env/render.js +26 -0
  30. package/src/env/resolve.js +202 -0
  31. package/src/env/teardown.js +109 -0
  32. package/src/env/trust.js +87 -0
  33. package/src/init.js +311 -0
  34. package/src/prompts.js +56 -0
  35. package/src/vendor/linear/cli-sync.js +256 -0
  36. package/src/vendor/linear/config.js +198 -0
  37. package/src/vendor/linear/mcp.js +112 -0
  38. package/src/vendor/sync-core/index.js +35 -0
  39. package/src/vendor/sync-core/src/apply.js +66 -0
  40. package/src/vendor/sync-core/src/base.js +83 -0
  41. package/src/vendor/sync-core/src/compare.js +99 -0
  42. package/src/vendor/sync-core/src/normalize.js +249 -0
  43. package/src/vendor/sync-core/src/pull.js +84 -0
  44. package/src/vendor/sync-core/src/push.js +106 -0
  45. package/src/vendor/sync-core/src/write.js +86 -0
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: spec-go
3
+ description: Promote a spec into active development and implement its first phase. Moves the spec from backlog into specs/in-progress/, then builds phase 1 with tests. Targets a spec by name (arg) or the spec currently in context. Use when the user says "/spec-go", "start this spec", "begin implementing <spec>", or "let's build the next phase".
4
+ ---
5
+
6
+ # /spec-go — start (or continue) implementing a spec
7
+
8
+ ## 1. Identify the target spec
9
+
10
+ - If a name/path is given as an argument, use it.
11
+ - Otherwise use the spec **currently in context** (the one just created or
12
+ discussed). If neither is clear, ask which spec.
13
+ - Locate it by searching `specs/` (check `specs/backlog/` first, then the other
14
+ buckets). A spec is a `<name>/` folder whose entry point is `00-overview.md`,
15
+ with **one file per phase** alongside it (`01-<slug>.md`, `02-…`). Legacy specs
16
+ may be a bare `<name>.md`, or a `00-overview.md` with inline phases — handle
17
+ those too.
18
+
19
+ ## 2. Move it into development
20
+
21
+ **If per-spec isolation is enabled** (`specs/.core/env.config.json` exists) and
22
+ the spec doesn't already have a worktree, provision it **first**, so all the
23
+ housekeeping below lands on the spec's branch and never on `main`:
24
+
25
+ - Run `skitterspec spec-env up <name>` (the `/spec-env` engine). It adds a git
26
+ worktree on a branch forked from `main`, and — only when the spec's
27
+ `> **Stack:**` header is `worktree + docker` — also brings up its Docker stack.
28
+ Print the worktree path and the opener command it emits.
29
+ - **Trust the worktree for this session.** The engine wrote the printed
30
+ `trusted:` root into `.claude/settings.local.json` (gitignored) so future
31
+ sessions trust it automatically — but that file likely won't hot-reload now,
32
+ so run `/add-dir <trusted root>` before editing into the worktree, or the
33
+ first edits will prompt.
34
+ - **Do the rest in the worktree**, on the branch: open it (the printed opener, or
35
+ a fresh Claude session rooted there) or, staying in this session, act on the
36
+ worktree path with absolute paths / `git -C <worktreePath>`. The spec move,
37
+ header edits **and** the phase's code all happen on the branch — so the spec's
38
+ evolution travels with the code it describes and lands in one PR. `main` changes
39
+ only when that branch merges (at `/spec-complete`).
40
+
41
+ Then move the spec (in the worktree when isolated, in place otherwise):
42
+
43
+ - If it isn't already under `specs/in-progress/`, move the whole spec folder
44
+ there. **Use `git mv`** to keep history:
45
+ `git mv "specs/backlog/<name>" "specs/in-progress/<name>"`.
46
+ `mkdir -p specs/in-progress` first if needed.
47
+ - Update the **Status** header in the entry point:
48
+ `> **Status:** In Progress — Phase 1 (started <YYYY-MM-DD>)`.
49
+ - Set the **Developer** header field if it's still `—`: use `git config user.name`.
50
+ - Append a **State log** row:
51
+ `| <YYYY-MM-DD> | In Progress | in-progress | <git user.name> |`.
52
+ - **When isolated:** commit the move and **push the branch** now — that records
53
+ the in-progress state for everyone and fires the tracker's automation (when a
54
+ ticketing provider is linked).
55
+
56
+ A spec ideally reaches here as `Ready` (via `/spec-ready`), but `/spec-go` works
57
+ on a `Draft` too — just sanity-check it's well-formed before building.
58
+
59
+ If the spec is already in `in-progress`, skip the move and implement the **next
60
+ unfinished phase** instead of Phase 1. (When isolated, subsequent `/spec-go` runs
61
+ happen from inside the worktree — where the spec already sits in `in-progress` on
62
+ the branch — and a re-run of `spec-env up` just re-attaches it.)
63
+
64
+ ## 3. Pre-flight — commit prior work, then compact
65
+
66
+ Before writing any code for this phase, get the workspace and context clean:
67
+
68
+ - **Confirm the last-worked phase is committed.** Run `git status` and
69
+ `git log --oneline -5`. The most recently *implemented* phase (not necessarily
70
+ the numerically previous one) should already be committed. If prior-phase work
71
+ is still uncommitted, **stop and suggest committing it first** (e.g. via
72
+ `/commit`) so each phase lands as its own reviewable commit — don't build the
73
+ next phase on top of an uncommitted one. (Skip if this is the first phase —
74
+ there's nothing prior to commit.)
75
+ - **Compact, then continue.** Recommend the user run `/compact` now. A fresh,
76
+ minimal context keeps the phase focused and avoids drift from earlier turns;
77
+ the spec file on disk is the source of truth, so nothing is lost. Pause for the
78
+ `/compact`, then implement the phase.
79
+
80
+ ## 3b. Pull from the tracker first (only if a provider is installed)
81
+
82
+ **Only when a ticketing provider with a `/spec-pull` skill is installed** and the
83
+ spec is linked to the tracker. Otherwise skip this step — no provider means zero
84
+ change to the flow below. Follow the provider's pull steps below (nothing to do
85
+ here without one).
86
+
87
+ **Only when `specs/.core/linear.config.json` exists** and the spec carries a
88
+ `linear_project_id` in its `00-overview.md` frontmatter. Otherwise skip this
89
+ step — no config means zero change to the flow below.
90
+
91
+ - **Run `/spec-pull` first.** Bring down anything Linear changed since the last
92
+ sync (status, priority, discussion-driven fields) so you build against the
93
+ current shared state, not a stale snapshot. On a conflict it refuses — relay
94
+ that and let the user resolve before continuing; do not `--force` for them.
95
+ - **Commit the refreshed snapshot** into the feature branch (a small
96
+ `chore(spec): pull latest from Linear`-style commit) so the frozen spec rides
97
+ in the PR alongside the code it describes.
98
+ - Linear's GitHub branch/PR automation may now drive status transitions off the
99
+ branch and PR you pushed in step 2 — expect state to move on the Linear side;
100
+ keep any manual status edits minimal to avoid fighting it.
101
+
102
+ ## 4. Implement the phase
103
+
104
+ Identify the **first unfinished phase** from the `00-overview.md` phase index,
105
+ then open its phase file (`0N-<slug>.md`) — that file holds the tasks. Mark it
106
+ started: set the phase-file heading to `🔄` and its `> **Status:**` to
107
+ `In progress`, and flip the matching row in the overview phase index to `🔄`.
108
+ Then build it, following the project rules in `.claude/rules/*.md` and `CLAUDE.md`:
109
+
110
+ - Work task by task through the phase file. Make focused edits that match
111
+ surrounding code.
112
+ - Honour the project's conventions (see `.claude/rules/spec-planning.md` and the
113
+ rules it links).
114
+ - **Tests are part of the phase, not after it.** Create/extend tests for the
115
+ work, then run the project's typecheck and test commands. Do not declare the
116
+ phase done until green.
117
+ - Never hardcode dates in tests; never run destructive commands against a real
118
+ database — use the project's test database only.
119
+
120
+ ## 5. Record progress
121
+
122
+ - In the **phase file**: tick completed tasks (`- [x]`), flip its heading to `✅`,
123
+ and set its `> **Status:**` to `Done`.
124
+ - In **`00-overview.md`**: flip the matching phase-index row to `✅`.
125
+ - If anything changed from the plan (a decision, a deviation, a discovered
126
+ constraint), add a dated **Changelog** entry in `00-overview.md`.
127
+ - If new work surfaced, add it as tasks to the appropriate phase file (or add a
128
+ new phase file + index row) rather than doing it silently.
129
+
130
+ ## 6. Report
131
+
132
+ Summarise what was implemented, the test result (quote failures if any), and
133
+ which phase is next. Do **not** `git commit` unless the user asks — finish,
134
+ verify, and wait.
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: spec-init
3
+ description: Bootstrap the spec-driven-development workflow in the current project — create the specs/ lifecycle folders and .core, wire version-control so specs are tracked, verify the spec skills are installed, and add the spec workflow to CLAUDE.md and .claude/rules. Idempotent and safe to re-run. Use when setting up a new project for specs or repairing the setup, or when the user says "/spec-init", "set up specs here", "initialise the spec process".
4
+ ---
5
+
6
+ # /spec-init — set up the spec-driven-development workflow
7
+
8
+ Bootstrap (or repair) everything this project needs to run the spec lifecycle.
9
+ **Idempotent:** detect what already exists, create only what's missing, and never
10
+ clobber customised content. Finish with a summary of created vs already-present.
11
+
12
+ > If `@skitterbyte/skitterspec` is installed, `npx @skitterbyte/skitterspec init` does
13
+ > all of the below mechanically. This skill is the manual/repair path and is
14
+ > useful when the package isn't available or you only need to fix part of the
15
+ > setup.
16
+
17
+ The system is **eight skills**: `spec` (feature), `spec-bug` (bug), `spec-ready`,
18
+ `spec-review`, `spec-go`, `spec-complete`, `spec-cancel`, and this `spec-init`. The lifecycle is
19
+ `backlog → in-progress → complete / cancelled`, with `.core` holding always-apply
20
+ project rules.
21
+
22
+ ## 1. Folders
23
+
24
+ Create any that are missing; drop a `.gitkeep` into ones that would otherwise be
25
+ empty so git keeps them:
26
+
27
+ - `specs/.core/` — project rules (always apply; never moved)
28
+ - `specs/backlog/` `specs/in-progress/` `specs/complete/` `specs/cancelled/`
29
+
30
+ ## 2. Version control — keep specs tracked
31
+
32
+ The whole lifecycle lives in git — **everything under `specs/` is tracked**, so
33
+ the default is simply *no ignore rule excluding it*. Ensure `.gitignore` has no
34
+ `/specs/*` (or similar) entry that would hide spec folders; if one exists and the
35
+ project wants everything tracked, remove it. Confirm with
36
+ `git check-ignore -v specs/.core/<any-file>` — it should print nothing (tracked).
37
+
38
+ - **`.core` dotfile caveat:** only relevant if a `/specs/*` ignore is
39
+ (re)introduced — `*` matches dotfiles, so `.core` would need an explicit
40
+ `!/specs/.core/` negation. With no ignore rule, it's tracked automatically.
41
+ - If the project uses a formatter/linter ignore glob that excludes `specs/**`,
42
+ decide whether spec markdown should be formatted/linted and adjust accordingly.
43
+ - If a project later wants to **stop** versioning work-in-progress specs, that's
44
+ a deliberate opt-out (e.g. `/specs/*` + `!/specs/.core/`) — ask first; the
45
+ default is track-everything.
46
+
47
+ ## 3. Verify the skills are installed
48
+
49
+ Check each of the eight skills resolves — `.claude/skills/<name>/SKILL.md`
50
+ (project) or `~/.claude/skills/<name>/` (global). List any missing. This skill
51
+ scaffolds the project; it does **not** regenerate skill bodies — missing skills
52
+ must be copied in (e.g. `npx @skitterbyte/skitterspec init`) from a global install
53
+ or a sibling project. If most/all are global, just confirm availability.
54
+
55
+ ## 4. Governing rule (`.claude/rules/spec-planning.md`)
56
+
57
+ Ensure it exists. If missing, create it documenting:
58
+
59
+ - the lifecycle skills with their **status** and **folder** (table);
60
+ - the **type** convention — header `> **Type:** Feature|Bug` + filename prefix
61
+ `feat-`/`bug-` (never `[BUG]` brackets — glob hazard);
62
+ - the **Author** / **Developer** header fields;
63
+ - the **State log** audit table (folder/status transitions), kept separate from
64
+ the **Changelog** (decisions);
65
+ - the project's concrete typecheck/test commands, and the rule that **every
66
+ phase ends with creating + running tests**.
67
+
68
+ Read a sibling spec skill (e.g. `spec`, `spec-go`) for the canonical shapes
69
+ rather than inventing them. If the rule already exists, leave it unless stale.
70
+
71
+ ## 5. CLAUDE.md
72
+
73
+ Ensure a `## Spec workflow` section exists. If absent, add one with the
74
+ skill table (`Skill | Action | Status | Folder`), the Feature/Bug type note,
75
+ and a pointer to `.claude/rules/spec-planning.md`. Also update the `specs/` entry
76
+ in any project-structure tree to show `.core/` + the four lifecycle folders. If
77
+ the section exists, refresh only stale folder/skill names — don't rewrite it.
78
+
79
+ ## 6. Report
80
+
81
+ Summarise per area — folders, `.gitignore` lines, tooling-ignore negations,
82
+ skills (present/missing), rule file, CLAUDE.md section — as created / updated /
83
+ already-present, plus the `git check-ignore` result for `.core`. Do **not**
84
+ `git commit` unless the user asks.
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: spec-pull
3
+ description: Pull a spec's linked Linear project into the local spec (Linear → repo), three-way aware. Applies remote-only fields; refuses to clobber local edits on a conflict unless --force (which backs up the local side first). Fetches Linear over MCP and runs `skitterspec spec-sync pull`. Opt-in — needs specs/.core/linear.config.json. Use when the user says "/spec-pull", "pull from Linear", "sync Linear changes down", or "update this spec from Linear".
4
+ ---
5
+
6
+ # /spec-pull — bring Linear changes into the spec
7
+
8
+ Linear → repo. Applies fields Linear changed since the last sync (status,
9
+ priority, labels, and co-authored fields), rewrites the committed base, and
10
+ stamps `last_synced_at`. It **refuses** to overwrite a local edit that conflicts
11
+ with a Linear edit unless you pass `--force`.
12
+
13
+ **Opt-in**: only runs when `specs/.core/linear.config.json` exists. If absent,
14
+ tell the user how to enable Linear sync and stop.
15
+
16
+ ## 1. Identify the target spec
17
+
18
+ Use the argument, else the spec in context; ask if unclear.
19
+
20
+ ## 2. Fetch the Linear project
21
+
22
+ - Read `linear_project_id` from `00-overview.md` frontmatter; if missing, the
23
+ spec isn't linked — stop and point at `/spec`.
24
+ - Discover the Linear MCP project-read tool at runtime. If Linear isn't
25
+ connected, relay the fix and stop — **do nothing destructive**.
26
+ - Call it and write the project JSON to a temp file.
27
+
28
+ ## 3. Run the engine
29
+
30
+ ```
31
+ skitterspec spec-sync pull <spec> --remote <tempfile> [--force]
32
+ ```
33
+
34
+ - **No conflict** — the engine applies remote-only fields to the local snapshot,
35
+ rewrites the base, and stamps the sync. Body fields with no local home yet are
36
+ reported as `deferred` (apply them by hand from Linear if needed).
37
+ - **Conflict** (a co-authored field changed on both sides) — the engine
38
+ **refuses** and lists the fields. Relay that; do not force on the user's behalf.
39
+ - **`--force`** — only when the user explicitly asks. Remote wins after the engine
40
+ backs up the local side under `sync.backupDir` (the reflog). Relay the backup
41
+ path.
42
+
43
+ ## 4. Report
44
+
45
+ Relay the git-like summary (applied / deferred / conflicts / backup / base). If
46
+ fields were applied, remind the user to review and commit the refreshed snapshot.
@@ -0,0 +1,53 @@
1
+ ---
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".
4
+ ---
5
+
6
+ # /spec-push — send spec content up to Linear
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`.
12
+
13
+ **Opt-in**: only runs when `specs/.core/linear.config.json` exists. If absent,
14
+ tell the user how to enable Linear sync and stop.
15
+
16
+ ## 1. Identify the target spec
17
+
18
+ Use the argument, else the spec in context; ask if unclear.
19
+
20
+ ## 2. Fetch the Linear project
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.
28
+
29
+ ## 3. Run the engine (the guard)
30
+
31
+ ```
32
+ skitterspec spec-sync push <spec> --remote <tempfile> --out <mergedfile> [--force]
33
+ ```
34
+
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.
42
+
43
+ ## 4. Apply the blessed writes to Linear
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.
49
+
50
+ ## 5. Report
51
+
52
+ Relay the git-like summary (written / skipped / backup / base) plus which Linear
53
+ fields you updated.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: spec-ready
3
+ description: Mark a Draft spec as Ready — confirm it's groomed (no unresolved open questions, phases and per-phase tests defined, decisions captured) and flip its status to Ready so it's a candidate for /spec-go. Stays in specs/backlog/. Targets a spec by name (arg) or the spec in context. Use when the user says "/spec-ready", "this spec is ready", or "mark <spec> ready to start".
4
+ ---
5
+
6
+ # /spec-ready — promote a Draft spec to Ready
7
+
8
+ A grooming gate between authoring (`/spec`, status `Draft`) and implementation
9
+ (`/spec-go`, status `In Progress`). It does **not** move the spec — it stays in
10
+ `specs/backlog/`; it only confirms quality and flips the status to `Ready` so
11
+ you can see at a glance which backlog specs are good to start.
12
+
13
+ ## 1. Identify the target spec
14
+
15
+ - Use the name/path argument if given, else the spec **in context**. If unclear,
16
+ ask which spec.
17
+ - Locate the spec folder under `specs/backlog/`. Entry point is its
18
+ `00-overview.md`; phases are separate files (`01-<slug>.md`, `02-…`) listed in
19
+ its phase index (legacy specs may be a bare `<name>.md`).
20
+
21
+ ## 2. Check it's actually ready — don't rubber-stamp
22
+
23
+ Review the spec against the readiness bar. If any of these fail, **stop and tell
24
+ the user what's missing** rather than marking it Ready:
25
+
26
+ - **Open questions resolved** — the `## Open questions` section is empty or
27
+ reads "None". Unresolved branches mean it isn't ready.
28
+ - **Decisions captured** — the chosen solution and key trade-offs are recorded.
29
+ - **Phased with clear tasks** — work is broken into phases, and **every phase in
30
+ the `00-overview.md` index has a matching phase file** (`0N-<slug>.md`) with
31
+ verb-first `- [ ]` tasks granular enough for one session. No index row without
32
+ a file, no orphan file without an index row.
33
+ - **Tests baked into every phase** — each phase file ends with a
34
+ create-and-run-tests task (a phase isn't done until green).
35
+ - **Concise and current** — no stale/contradictory sections.
36
+
37
+ Offer to fix small gaps inline if the user wants; otherwise leave it `Draft`.
38
+
39
+ ## 3. Mark Ready
40
+
41
+ - Set the **Status** header in the entry point:
42
+ `> **Status:** Ready (<YYYY-MM-DD>)`.
43
+ - Append a **State log** row: `| <YYYY-MM-DD> | Ready | backlog | <git user.name> |`
44
+ (no folder change — Ready stays in `backlog`).
45
+ - Optionally add a **Changelog** note if grooming changed anything substantive.
46
+
47
+ ## 4. Report
48
+
49
+ Confirm it's Ready and note it stays in `backlog` until `/spec-go` picks it up.
50
+ If you blocked it, list exactly what needs resolving first.
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: spec-review
3
+ description: Re-validate an existing spec against the current codebase — detect drift (renamed/removed files, changed APIs, tasks already done in code, stale decisions), grill where a decision is needed, and update the spec so it's relevant again. Targets a spec by name (arg) or the spec in context. Use when the user says "/spec-review", "is this spec still accurate", "this spec has gone stale", or before picking up an old backlog spec.
4
+ ---
5
+
6
+ # /spec-review — bring a spec back in sync with the codebase
7
+
8
+ Specs rot: the code moves on while a spec sits in the backlog or pauses
9
+ mid-build. This skill re-validates a spec against the **current** code and
10
+ rewrites the stale parts so it's safe to act on. It plans only — it does not
11
+ implement anything (that's `/spec-go`).
12
+
13
+ ## 1. Identify the target spec
14
+
15
+ - Use the name/path argument if given, else the spec **in context**. If unclear,
16
+ ask which spec.
17
+ - Locate the spec folder under `specs/` (any bucket). Entry point is its
18
+ `00-overview.md`; read it **and every phase file** (`01-<slug>.md`, `02-…`)
19
+ listed in its phase index (legacy specs may be a bare `<name>.md`).
20
+
21
+ ## 2. Validate against the codebase — evidence first
22
+
23
+ Read the spec, then check every claim it makes against the real code. Don't
24
+ trust the spec's own wording — verify:
25
+
26
+ - **Referenced things still exist.** Grep/read for each `file:line`, module,
27
+ function, route, model, type, or symbol the spec names. Flag anything renamed,
28
+ moved, or deleted.
29
+ - **Tasks already done.** For each `- [ ]`, check whether the code already
30
+ implements it (it may have landed via other work). Tick `- [x]` what's done.
31
+ - **Decisions still valid.** Re-check each `## Decisions` entry against the
32
+ current architecture and `.claude/rules/*.md`. Flag any that now conflict with
33
+ how the codebase actually works (a changed convention, a superseded approach).
34
+ - **New constraints.** Note rules/patterns introduced since the spec was written
35
+ that it must now honour (e.g. a new required field, a new error type, a new
36
+ pattern the rest of the code now follows).
37
+ - **Backward compatibility.** Re-confirm the planned API/schema changes are still
38
+ additive/safe given the current code (see the project's compatibility rules).
39
+
40
+ ## 3. Grill only where a decision is needed
41
+
42
+ Where the drift forces a choice (the old approach no longer fits, a referenced
43
+ thing is gone, scope is now ambiguous), grill the user like `/spec` Phase A —
44
+ **one question at a time, with a recommended answer** — but scoped tightly to
45
+ the drift. Don't re-litigate decisions that still hold. If you can resolve it by
46
+ reading the code, do that instead of asking.
47
+
48
+ ## 4. Update the spec
49
+
50
+ - Rewrite stale **Decisions** / **Solution overview** in `00-overview.md` and
51
+ stale **tasks** in the phase files so they match the current code and the
52
+ resolved questions. Add/remove tasks within a phase file; add a new phase by
53
+ creating a `0N-<slug>.md` file **and** a matching overview index row, or drop a
54
+ dead phase by removing both. Keep the index and files in sync; **preserve
55
+ completed `[x]` history**.
56
+ - Tick tasks already satisfied by the code; re-open `## Open questions` for
57
+ anything still undecided.
58
+ - Add a dated **Changelog** entry summarising the review (e.g. `- <date> —
59
+ Reviewed vs codebase: retargeted Phase 2 onto X, dropped Y (removed), ticked Z
60
+ (already done)`).
61
+ - **Status:** if drift is minor, leave status as-is. If a `Ready` spec needs real
62
+ re-grooming, knock it back to `Draft` (set `> **Status:** Draft` and append a
63
+ **State log** row).
64
+
65
+ ## 5. Report
66
+
67
+ Summarise the drift found, what you changed, any questions still open, and
68
+ whether the spec is now safe to `/spec-go` (or needs `/spec-ready` again). Do
69
+ **not** `git commit` unless the user asks.
@@ -0,0 +1,46 @@
1
+ ---
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".
4
+ ---
5
+
6
+ # /spec-status — show a spec's divergence from Linear
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.
11
+
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.
15
+
16
+ ## 1. Identify the target spec
17
+
18
+ Use the spec named as an argument, else the spec **currently in context**. If
19
+ neither is clear, ask which spec.
20
+
21
+ ## 2. Fetch the Linear project (read-only)
22
+
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).
30
+
31
+ ## 3. Run the engine
32
+
33
+ ```
34
+ skitterspec spec-sync status <spec> --remote <tempfile>
35
+ ```
36
+
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).
40
+
41
+ ## 4. Report
42
+
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.
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ 'use strict'
3
+
4
+ /**
5
+ * The Linear-provider distribution's bin — a superset of the base CLI.
6
+ *
7
+ * `spec-sync …` is handled here (the provider engine seam); every other command
8
+ * (`init`, `update`, `spec-env`, `--help`, …) delegates to the base CLI unchanged.
9
+ */
10
+
11
+ const { run } = require('../src/cli.js')
12
+ const { specSync } = require('../src/vendor/linear/cli-sync.js')
13
+
14
+ async function main(argv) {
15
+ const [cmd, ...rest] = argv
16
+ if (cmd === 'spec-sync') {
17
+ await specSync(rest)
18
+ return
19
+ }
20
+ await run(argv)
21
+ }
22
+
23
+ main(process.argv.slice(2)).catch((err) => {
24
+ console.error(`skitterspec-linear: ${err.message}`)
25
+ process.exit(1)
26
+ })
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@skitterbyte/skitterspec-linear",
3
+ "version": "1.0.0",
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
+ "keywords": [
6
+ "claude",
7
+ "claude-code",
8
+ "spec-driven-development",
9
+ "sdd",
10
+ "skills",
11
+ "scaffold",
12
+ "linear"
13
+ ],
14
+ "license": "MIT",
15
+ "author": "Reuben Greaves",
16
+ "type": "commonjs",
17
+ "bin": {
18
+ "skitterspec-linear": "bin/skitterspec-linear.js"
19
+ },
20
+ "files": [
21
+ "bin",
22
+ "src",
23
+ "assets"
24
+ ],
25
+ "engines": {
26
+ "node": ">=18"
27
+ },
28
+ "dependencies": {
29
+ "prompts": "^2.4.2"
30
+ },
31
+ "scripts": {
32
+ "prepack": "node ../../scripts/build-dist.js skitterspec-linear"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/skitterbyte/skitterspec.git"
37
+ }
38
+ }