@skitterbyte/skitterspec-jira 0.0.0-stage → 2.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 (113) hide show
  1. package/MIGRATION.md +1266 -0
  2. package/README.md +44 -2
  3. package/assets/claude-md-section.md +85 -0
  4. package/assets/commands/allow-main.md +33 -0
  5. package/assets/commands/spec-connect.md +13 -0
  6. package/assets/commands/spec-live.md +14 -0
  7. package/assets/commands/spec-remote-review.md +37 -0
  8. package/assets/commands/spec-skip.md +24 -0
  9. package/assets/core/SETUP.md +192 -0
  10. package/assets/core/env.config.json.example +56 -0
  11. package/assets/core/env.config.md +606 -0
  12. package/assets/core/gating.config.json.example +4 -0
  13. package/assets/core/gating.config.md +81 -0
  14. package/assets/core/jira.config.json.example +18 -0
  15. package/assets/core/jira.config.md +88 -0
  16. package/assets/hooks/main-guard.cjs +162 -0
  17. package/assets/hooks/review-gate.cjs +146 -0
  18. package/assets/review/page.html +3384 -0
  19. package/assets/rules/commit-trailers.md +96 -0
  20. package/assets/rules/negative-checks.md +69 -0
  21. package/assets/rules/offered-unblocks.md +100 -0
  22. package/assets/rules/spec-planning.md +702 -0
  23. package/assets/rules/spec-reports.md +572 -0
  24. package/assets/skills/no-spec/SKILL.md +249 -0
  25. package/assets/skills/spec/SKILL.md +714 -0
  26. package/assets/skills/spec-bug/SKILL.md +585 -0
  27. package/assets/skills/spec-cancel/SKILL.md +261 -0
  28. package/assets/skills/spec-complete/SKILL.md +451 -0
  29. package/assets/skills/spec-diff/SKILL.md +870 -0
  30. package/assets/skills/spec-hotfix/SKILL.md +607 -0
  31. package/assets/skills/spec-init/SKILL.md +178 -0
  32. package/assets/skills/spec-jira-setup/SKILL.md +221 -0
  33. package/assets/skills/spec-list/SKILL.md +173 -0
  34. package/assets/skills/spec-next/SKILL.md +678 -0
  35. package/assets/skills/spec-push/SKILL.md +306 -0
  36. package/assets/skills/spec-review/SKILL.md +256 -0
  37. package/assets/skills/spec-reviewed/SKILL.md +284 -0
  38. package/assets/skills/spec-start/SKILL.md +496 -0
  39. package/assets/skills/spec-status/SKILL.md +114 -0
  40. package/assets/skills/spec-sync/SKILL.md +220 -0
  41. package/assets/skills/spec-to-main/SKILL.md +141 -0
  42. package/bin/skitterspec-jira.js +68 -0
  43. package/package.json +40 -4
  44. package/src/cli.js +5967 -0
  45. package/src/deprecate.js +138 -0
  46. package/src/env/bootstrap.js +188 -0
  47. package/src/env/building.js +143 -0
  48. package/src/env/classify.js +176 -0
  49. package/src/env/commitcmd.js +108 -0
  50. package/src/env/config.js +850 -0
  51. package/src/env/dev.js +63 -0
  52. package/src/env/glob.js +34 -0
  53. package/src/env/hooks.js +226 -0
  54. package/src/env/hotfix.js +413 -0
  55. package/src/env/hotfixland.js +302 -0
  56. package/src/env/integrate.js +167 -0
  57. package/src/env/live.js +479 -0
  58. package/src/env/mainguard.js +299 -0
  59. package/src/env/provision.js +466 -0
  60. package/src/env/proxy.js +225 -0
  61. package/src/env/prune.js +119 -0
  62. package/src/env/registry.js +159 -0
  63. package/src/env/render.js +17 -0
  64. package/src/env/resolve.js +716 -0
  65. package/src/env/review.js +2622 -0
  66. package/src/env/reviewers/coderabbit.js +228 -0
  67. package/src/env/reviewers.js +517 -0
  68. package/src/env/serve.js +1044 -0
  69. package/src/env/supervise.js +157 -0
  70. package/src/env/teardown.js +248 -0
  71. package/src/env/trust.js +87 -0
  72. package/src/gating.js +155 -0
  73. package/src/init.js +1150 -0
  74. package/src/lines-diff.js +114 -0
  75. package/src/prompts.js +129 -0
  76. package/src/vendor/jira/adf.js +414 -0
  77. package/src/vendor/jira/api.js +295 -0
  78. package/src/vendor/jira/cli-sync.js +1252 -0
  79. package/src/vendor/jira/commands.js +44 -0
  80. package/src/vendor/jira/config.js +286 -0
  81. package/src/vendor/jira/credentials.js +108 -0
  82. package/src/vendor/jira/dialect.js +45 -0
  83. package/src/vendor/jira/mcp.js +129 -0
  84. package/src/vendor/provider-kit/index.js +41 -0
  85. package/src/vendor/provider-kit/src/adapter.js +23 -0
  86. package/src/vendor/provider-kit/src/apply.js +207 -0
  87. package/src/vendor/provider-kit/src/args.js +68 -0
  88. package/src/vendor/provider-kit/src/assignment.js +277 -0
  89. package/src/vendor/provider-kit/src/config.js +251 -0
  90. package/src/vendor/provider-kit/src/credentials.js +404 -0
  91. package/src/vendor/provider-kit/src/doctor.js +35 -0
  92. package/src/vendor/provider-kit/src/http.js +63 -0
  93. package/src/vendor/provider-kit/src/identity.js +93 -0
  94. package/src/vendor/provider-kit/src/list-assignee.js +71 -0
  95. package/src/vendor/provider-kit/src/list-rows.js +35 -0
  96. package/src/vendor/provider-kit/src/md-compare.js +39 -0
  97. package/src/vendor/provider-kit/src/md-tables.js +94 -0
  98. package/src/vendor/provider-kit/src/prompt.js +50 -0
  99. package/src/vendor/provider-kit/src/released.js +219 -0
  100. package/src/vendor/provider-kit/src/specs.js +248 -0
  101. package/src/vendor/provider-kit/src/transport.js +22 -0
  102. package/src/vendor/sync-core/index.js +92 -0
  103. package/src/vendor/sync-core/src/base.js +81 -0
  104. package/src/vendor/sync-core/src/compare.js +338 -0
  105. package/src/vendor/sync-core/src/dialect.js +51 -0
  106. package/src/vendor/sync-core/src/fields.js +36 -0
  107. package/src/vendor/sync-core/src/legacy.js +100 -0
  108. package/src/vendor/sync-core/src/normalize.js +971 -0
  109. package/src/vendor/sync-core/src/push.js +85 -0
  110. package/src/vendor/sync-core/src/retarget.js +278 -0
  111. package/src/vendor/sync-core/src/task-block.js +308 -0
  112. package/src/vendor/sync-core/src/verify.js +67 -0
  113. package/src/vendor/sync-core/src/write.js +191 -0
@@ -0,0 +1,220 @@
1
+ ---
2
+ name: spec-sync
3
+ description: Run the repo-wide spec-sync operations against Jira — what is linked, the project's statuses, read-back verification, manual stamping, and bulk apply. Run it bare for the repo-wide overview. Defers to /spec-push and /spec-status for per-spec work. Opt-in — needs specs/.core/jira.config.json. Use when the user says "/spec-sync", "run spec-sync", "what's linked to Jira", "which statuses does the project have", or "mirror the whole backlog".
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # /spec-sync — the repo-wide Jira sync operations
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
+
14
+ `/spec-push` and `/spec-status` cover **one spec**. This skill covers everything
15
+ **repo-wide**, and is the answer to a bare "run spec-sync" — which is not itself
16
+ a command.
17
+
18
+ **Opt-in**: only runs when `specs/.core/jira.config.json` exists. If absent,
19
+ tell the user how to enable Jira sync and stop.
20
+
21
+ ## The invocation — always state it
22
+
23
+ `spec-sync` is a subcommand of a binary that is a **local devDependency**, so it
24
+ is never on `PATH`. Typing `spec-sync` gives `command not found`, which reads as
25
+ a broken install rather than a wrong invocation. Always run it — and always show
26
+ the user you ran it — in full:
27
+
28
+ ```
29
+ pnpm exec skitterspec-jira spec-sync <subcommand> [args]
30
+ ```
31
+
32
+ In a project that installs the Jira superset the binary is
33
+ `skitterspec-jira` (it also answers to `skitterspec`). Never print a bare
34
+ `spec-sync …` as if the user could type it.
35
+
36
+ ## 1. Route the ask
37
+
38
+ | The user asks | Run |
39
+ |---------------|-----|
40
+ | bare `/spec-sync`, "what's linked?", "how much is mirrored?" | `linked` |
41
+ | "what statuses does the project have?" | `states` |
42
+ | "what specs are there?", "what's in the backlog?" | `list` — or hand to `/spec-list` |
43
+ | "did the mirror survive the push?" | `verify <spec> --stored <file>` |
44
+ | "link this spec to PROJ-1 by hand" | `stamp <spec> --issue PROJ-1` |
45
+ | "mirror the whole backlog / every complete spec" | `apply --all <bucket>` — **confirm first** |
46
+ | "what ticket am I on?", writing a commit | `ref` |
47
+ | "what shipped in this release?", "which tickets does CI mark deployed?" | `released` — `--json` for a script; recording deploys is the project's own |
48
+ | "is any of this wired up?", "why isn't sync working?" | `doctor` — scaffold, isolation, tracker and credentials in one |
49
+ | "set my Jira credentials", "am I authenticated?" | `credentials <status\|set\|unset>` |
50
+ | push one spec, or "what would push?" | **defer** — see below |
51
+
52
+ The Linear provider's `retarget`, `reattach`, `stage`, `whoami`, `users`,
53
+ `assign` and `sanitise` are **not yet shipped for the Jira provider** — say so
54
+ when one is asked for, rather than improvising an equivalent.
55
+
56
+ **With no argument, run `linked`.** It is the repo-wide overview, it is
57
+ read-only, and it is what a bare "run spec-sync" means.
58
+
59
+ **When the ask is genuinely ambiguous between a read and a write — ask.**
60
+ "Sync the backlog" could mean `linked` (show me) or `apply --all backlog`
61
+ (write dozens of issues). Never resolve that guess in favour of the write.
62
+
63
+ ## 2. Defer, don't duplicate
64
+
65
+ Two front doors to one write path is worse than none:
66
+
67
+ - **Push one spec** → `/spec-push`. It owns the transport choice, the
68
+ status-name gate, the plan, the apply, the stamping and the snapshot.
69
+ - **Per-spec status** ("is this spec in sync?", "what would push?") →
70
+ `/spec-status`.
71
+
72
+ Say which skill you're handing to and stop; don't reimplement either.
73
+
74
+ ## 3. The read-only subcommands
75
+
76
+ ```
77
+ pnpm exec skitterspec-jira spec-sync linked [--json]
78
+ pnpm exec skitterspec-jira spec-sync states [--via api|mcp] [--json]
79
+ ```
80
+
81
+ - **`linked`** is offline: which specs carry a `jira_identifier`, their bucket,
82
+ and an `N/M linked` total. Relay it, and when specs in `in-progress` have no
83
+ issue, say so — those are the ones a push would mint.
84
+ - **`states`** reaches the project. It also reports the **transport** (`api`
85
+ when credentials resolve, else `mcp`), which is the honest way to answer "how
86
+ is this talking to Jira?". Its non-JSON output ends with the **bucket map** —
87
+ every lifecycle bucket against the project's real statuses, a verdict per
88
+ row — which is the answer to relay when the user asks whether the mapping is
89
+ right.
90
+ - **`list`** is the read side of the mirror: every spec issue Jira holds,
91
+ joined to the local spec folder that owns it. Unlike `linked`, it asks JIRA
92
+ what exists rather than the repo — which is the only way to see a spec started
93
+ on a branch this checkout has not got. Scope is the live statuses by default
94
+ (`--all`, or `--state <name>`). **`/spec-list` is the front door** — hand over
95
+ to it for anything beyond a bare listing; it carries the MCP path and the
96
+ offline degradation.
97
+
98
+ ## 4. `verify` — check what the tracker actually stored
99
+
100
+ ```
101
+ pnpm exec skitterspec-jira spec-sync verify <spec> --stored <file>
102
+ ```
103
+
104
+ `--stored` is **what Jira currently holds**, read back over MCP:
105
+
106
+ ```json
107
+ { "issue": "…", "subIssues": { "01-engine": "…" } }
108
+ ```
109
+
110
+ **It is not a `jira-base/*.base.json` snapshot.** That file holds content
111
+ *hashes* keyed by identifier; comparing one against a description reports
112
+ enormous losses on a perfectly intact mirror. The engine refuses a snapshot
113
+ outright — if you see that refusal, you passed the wrong file, not found a bug.
114
+
115
+ Warns, never fails. The repo is the source of truth; a mangled mirror is fixed
116
+ by pushing again. Jira stores descriptions as ADF and the adapter converts
117
+ markdown at the boundary, so the comparison is words, not bytes.
118
+
119
+ ## 5. `stamp` — the manual escape hatch
120
+
121
+ ```
122
+ pnpm exec skitterspec-jira spec-sync stamp <spec> --issue PROJ-1 [--url URL] [--sub <ref>=PROJ-2 …]
123
+ ```
124
+
125
+ Writes the keys into the spec's frontmatter without touching Jira. For adopting
126
+ an issue created by hand, or repairing a stamp — not the normal path, which is
127
+ `/spec-push`. A wrong key here makes the next push see an **unlinked** spec and
128
+ mint a duplicate, so read the values back to the user before writing.
129
+
130
+ ## 6. `apply --all <bucket>` — bulk, and the one with real blast radius
131
+
132
+ ```
133
+ pnpm exec skitterspec-jira spec-sync apply --all <bucket> [--via api|mcp] [--json]
134
+ ```
135
+
136
+ **Confirm before running, and state creates and updates separately.** They are
137
+ not the same risk:
138
+
139
+ - an **update** refreshes a mirror that already exists;
140
+ - a **create** mints new issues and subtasks in someone's shared tracker.
141
+
142
+ A repo adopting Jira reports "N to create" for every unlinked spec, so an
143
+ unconsidered `--all` can mint dozens of subtasks. Get the counts first — run
144
+ `linked` to see what is unlinked, or `spec-sync plan <spec>` per spec for exact
145
+ numbers — then show the user something like:
146
+
147
+ ```
148
+ apply --all backlog would:
149
+ create 12 issue(s) + 34 subtask(s) ← new objects in Jira
150
+ update 3 issue(s) + 5 subtask(s) ← refresh existing mirrors
151
+ ```
152
+
153
+ Only run it on an explicit yes. It is resumable: every key is stamped the moment
154
+ its object exists, so an interrupted run continues rather than duplicating.
155
+
156
+ `--all` refuses over MCP by design — bulk goes through the API path.
157
+
158
+ ## 7. `ref` and `released` — tickets in commits
159
+
160
+ ```
161
+ pnpm exec skitterspec-jira spec-sync ref [--json]
162
+ pnpm exec skitterspec-jira spec-sync released [<range>] [--json]
163
+ ```
164
+
165
+ `ref` prints the ticket for the branch you are on, so a commit can carry
166
+ `Refs: <PROJ-N>` — see `.claude/rules/commit-trailers.md`.
167
+ **Off a spec branch, or on a spec that is not linked, it prints nothing and exits non-zero.**
168
+ That is the correct answer, not an error to work around: do not invent a ref,
169
+ and never write `Refs: none`.
170
+
171
+ `released` reports the tickets in a commit range — by default since the most
172
+ recent tag, and it always prints the range it chose so a wrong default is
173
+ visible. It is **read-only**: it does not move anything in Jira. Each ticket
174
+ row names the `spec` and `url` behind it (`null` when no spec linked the ref),
175
+ so `--json` is what a project's CI pipes into its own tooling to record a
176
+ release or a deploy. Recording those is the project's job, not skitterspec's.
177
+
178
+ Relay the **unreferenced count** even when it is zero. A chore commit
179
+ legitimately carries no ticket and a *missed* trailer looks identical, so
180
+ omitting the number reads as "everything is accounted for" when it may not be.
181
+
182
+ **Bookkeeping commits are excluded.** A spec's `chore(spec): complete <name>`
183
+ commit carries the same ref as the code it describes but lands *after* the tag
184
+ that shipped it, so counting it would put the ticket in two consecutive releases.
185
+ A commit whose changed paths are **all** under `release.ignorePaths` (default
186
+ `specs/`) contributes nothing; one that touches an ignored path *and* a source
187
+ file still counts. Relay the **ignored count** whenever it is non-zero — that is
188
+ the report saying which commits it set aside.
189
+
190
+ ## 8. Report
191
+
192
+ Relay the engine's output **above the block**, and name the subcommand you ran
193
+ **in full**, so the user can re-run it themselves.
194
+
195
+ End with the block defined in `.claude/rules/spec-reports.md`. That file carries
196
+ the shape; this section carries only what is specific here.
197
+
198
+ **Verdicts**
199
+
200
+ - `✅` — the subcommand did what it says.
201
+ - `⚠️` — it ran, with something worth knowing — a partial result, a warning it
202
+ printed, a degradation it fell back to.
203
+ - `❌` — it wrote some objects and failed on another. Say what exists now.
204
+ - `⏸` — it refused: no config, an unvalidated status list, a bad argument.
205
+ Nothing was written.
206
+
207
+ **A branch-local bucket is the normal case, never the caveat.** `linked`
208
+ reads the checkout it runs in, and an in-flight spec's move to
209
+ `in-progress` lives on its own unlanded branch — so from the primary
210
+ checkout the spec still reads `backlog` while the tracker (pushed from
211
+ the worktree) is ahead. That is worktree mode working as designed:
212
+ report it `✅` with the fact in `Notes`. Spending `⚠️` on the normal
213
+ case is how the verdict stops meaning anything — the same argument
214
+ `spec-reports.md` makes for `Untouched`.
215
+
216
+ **Fields:** `Tracker` · `Notes` · `Follow-ups` · `Next`
217
+
218
+ `Tracker` says what changed in Jira **and that the repo is unchanged** — it is
219
+ the source of truth either way, and a report that omits the second half reads as
220
+ though a sync had edited the repo.
@@ -0,0 +1,141 @@
1
+ ---
2
+ name: spec-to-main
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
5
+ ---
6
+
7
+ # /spec-to-main — land the branch on main, keep the spec open
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
+
14
+ The **intermediate** landing. `/spec-complete` also lands the branch, but then
15
+ verifies every phase, flips the status to Complete, `git mv`s the spec to
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.
19
+
20
+ Use it when a later phase can only be done *after* the current work is on `main` —
21
+ e.g. it needs to run in CI, a deploy pipeline, or a shared test environment that
22
+ builds from `main`. Land what you have, run that step, then come back and finish
23
+ the remaining phases with `/spec-next` and eventually `/spec-complete`.
24
+
25
+ It reuses the **same engine** as `/spec-complete`'s landing (`spec-env integrate`
26
+ — rebase + fast-forward), so it produces identical linear history. Because a
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.
30
+
31
+ ## 0. Preconditions — when this applies
32
+
33
+ - **Isolation must be on** (`specs/.core/env.config.json` exists **and** the spec
34
+ was provisioned by `/spec-start` — a worktree, or its branch in the checkout under
35
+ `mode: checkout`). If isolation is absent, there is nothing to land — the spec
36
+ is authored directly on `main` already. Say so and stop. `spec-env integrate`
37
+ reads `mode` and emits the matching plan; in checkout mode it rebases in place,
38
+ switches to base and fast-forwards, all in the one repo.
39
+ - **Feature / Bug specs only.** A **Hotfix** (`Type: Hotfix`) is built on a
40
+ release *tag* and cannot fast-forward onto `main` — refuse it and point the user
41
+ at `/spec-complete` (it lands a hotfix via tag + cherry-pick). Check the header
42
+ `> **Type:**` before proceeding.
43
+
44
+ ## 1. Identify the target spec
45
+
46
+ - Use the name/path argument if given, else the spec **in context**. If unclear,
47
+ ask which spec.
48
+ - Locate its folder under `specs/in-progress/`. Entry point is `00-overview.md`;
49
+ confirm `> **Status:**` is `In Progress` and `> **Type:**` is `Feature` or
50
+ `Bug`.
51
+
52
+ ## 2. Require a clean worktree
53
+
54
+ The land rebases the branch — it refuses a dirty tree. If the worktree has
55
+ uncommitted changes, offer `/commit` and **stop**; don't auto-commit.
56
+
57
+ **If the spec is live** (you took the running instance with `/spec-live`):
58
+ `integrate` is live-aware — it ends the live session first (releases the branch
59
+ back to base, re-isolates it into its worktree, clears the receipt), then prints
60
+ the landing plan. Commit any live fixes to the branch first; it refuses if the
61
+ primary checkout is dirty, or if a *different* spec holds it (release that one with
62
+ `/spec-live main`, which the user types).
63
+
64
+ ## 3. Tests must be green before landing
65
+
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.
70
+
71
+ (Note this is the *worktree* suite. The whole point of this skill is often to run
72
+ a *further* check that only exists on `main` / in CI — that one runs **after** the
73
+ land, in step 5.)
74
+
75
+ ## 4. Land — rebase + fast-forward
76
+
77
+ Run `skitterspec spec-env integrate <name>` and run the printed commands
78
+ **in order**:
79
+
80
+ - `git -C <worktree> rebase <base>` — replay the branch onto base.
81
+ - `git -C <mainRepoPath> merge --ff-only <branch>` — fast-forward base.
82
+
83
+ On a **rebase conflict** (non-zero exit), run `git -C <worktree> rebase --abort`,
84
+ relay the conflict, and **stop** — leave the resolution to the user; change
85
+ nothing else.
86
+
87
+ On a **no-op** ("already landed on `<base>` — nothing to integrate"), just say so
88
+ and continue — the branch has no commits base doesn't already have.
89
+
90
+ **Then run the after-land commands.** Where the plan ends with a
91
+ `then, in the primary checkout (<path>), run:` section — the project's
92
+ `afterLand`, such as a data migration — run those commands in that directory,
93
+ in order, after the fast-forward and **before** the re-test below, which may
94
+ need them. Run only the lines under that heading; a
95
+ `skipped (nothing in the land matched):` block lists conditional entries this
96
+ land did not need, and is information, never commands. Run them on the no-op too: the engine prints them there because a
97
+ land made elsewhere leaves them pending here.
98
+ **Stop at the first non-zero exit**, and carry on with §5: a failure makes the run `⚠️`, naming the command
99
+ that failed and the ones that did not run, and it **never undoes the land**.
100
+ No section, nothing to run, and nothing to say about it.
101
+
102
+ ## 5. Re-test on base, then report
103
+
104
+ - Run the project's test command **from the primary checkout** — base must be
105
+ **green** after the fast-forward.
106
+ - Add a **Changelog** entry to `00-overview.md` recording the intermediate land
107
+ and *why*, e.g.
108
+ `- <YYYY-MM-DD> — Landed intermediate work onto <base> to <run CI / deploy to
109
+ test env / …>; spec stays In Progress.`
110
+ - Do **NOT**: add a State-log row (status doesn't change), flip any phase/status
111
+ to Complete, `git mv` the spec, or tear down the worktree/stack.
112
+ **The spec stays `In Progress` and the worktree stays put.**
113
+ - It **never pushes** — say the user can `git push` the base branch themselves to
114
+ trigger CI / the shared env.
115
+ - `Next` points the way forward: `/spec-next` to continue the remaining phases
116
+ (you'll keep committing on the same branch and can `/spec-to-main` again), and
117
+ `/spec-complete` when every phase is genuinely done — it will land the final
118
+ commits, finalise, and tear down.
119
+
120
+ End with the block defined in `.claude/rules/spec-reports.md`. That file carries
121
+ the shape; this section carries only what is specific here.
122
+
123
+ **Verdicts**
124
+
125
+ - `✅` — the branch is on the base and the base is green.
126
+ - `⚠️` — landed, with something worth knowing — an after-land command that
127
+ failed, for one.
128
+ - `❌` — the rebase conflicted, or the base went red after the fast-forward.
129
+ Quote it; the repo is mid-something and that is what the reader needs.
130
+ - `⏸` — a dirty worktree, red tests, or no spec to land. Nothing moved.
131
+
132
+ **Fields:** `Branch` · `Tests` · `Notes` · `Landed` · `Follow-ups` · `Next`
133
+
134
+ `Notes` carries the after-land commands §4 ran, and where, and any it
135
+ skipped because the land matched no `when` — or the one that failed and the ones that did not run. Nothing about it when none are
136
+ configured.
137
+
138
+ **No `Spec` field, deliberately.** This skill changes no status and moves no
139
+ folder, and a `Spec` line here would read as though it had. The spec stays
140
+ `In Progress` and the worktree stays standing — if that needs saying, the
141
+ verdict clause says it.
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ 'use strict'
3
+
4
+ // The Jira superset's entry point: the base CLI plus this provider's commands.
5
+ //
6
+ // In the PUBLISHED distribution, bin/src/assets are composed at build time and
7
+ // never committed — so a missing src/ means someone is running from a raw
8
+ // checkout of the dist package, which has nothing to run. Inline rather than
9
+ // shared: a helper would have to live in src/, which is exactly what may be
10
+ // missing. In the workspace source package src/ always exists, so this is
11
+ // inert there.
12
+ const { existsSync } = require('node:fs')
13
+ const { join } = require('node:path')
14
+ if (!existsSync(join(__dirname, '..', 'src'))) {
15
+ console.error(
16
+ 'skitterspec-jira: no build output — this package\'s bin/src/assets are composed, not committed.\n' +
17
+ ' run "npm run build" in the skitterspec repo, then try again.',
18
+ )
19
+ process.exit(1)
20
+ }
21
+
22
+ const { run, HELP } = require('../src/cli.js')
23
+
24
+ // The provider's isolation defaults, registered beneath the project's own
25
+ // env.config.json so `spec-env stage` claims this provider's snapshot sidecar
26
+ // without a hand edit (see common src/env/config.js, setProviderEnvDefaults).
27
+ require('../src/env/config.js').setProviderEnvDefaults(
28
+ require('../src/vendor/jira/config.js').ENV_CONFIG_DEFAULTS,
29
+ )
30
+ const {
31
+ PROVIDER_COMMANDS,
32
+ providerHelpSection,
33
+ } = require('../src/vendor/jira/commands.js')
34
+
35
+ async function main(argv) {
36
+ const [cmd, ...rest] = argv
37
+
38
+ // A source package HAS a runnable bin and src, but its assets/ is
39
+ // PRE-composition (seam markers still literal). Installing from it would
40
+ // write those markers into the user's skills — refuse before any install
41
+ // command runs.
42
+ if (cmd === 'init' || cmd === 'update') {
43
+ require('../src/init.js').assertComposedAssets()
44
+ }
45
+
46
+ // Base help + what this distribution adds. Matched on the COMMAND SLOT only,
47
+ // never the whole argv: `spec-sync --help` must reach that command's own
48
+ // help, not be swallowed by the top-level one.
49
+ if (!cmd || cmd === '--help' || cmd === '-h') {
50
+ process.stdout.write(`${HELP}\n${providerHelpSection()}`)
51
+ return
52
+ }
53
+
54
+ const provider = PROVIDER_COMMANDS[cmd]
55
+ if (provider) {
56
+ // Propagate the exit code: a refused stamp or a failed state check must
57
+ // not look successful to a caller checking $?.
58
+ process.exitCode = await provider.run(rest)
59
+ return
60
+ }
61
+
62
+ await run(argv)
63
+ }
64
+
65
+ main(process.argv.slice(2)).catch((err) => {
66
+ console.error(`skitterspec-jira: ${err.message}`)
67
+ process.exit(1)
68
+ })
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@skitterbyte/skitterspec-jira",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "2.0.0",
4
+ "description": "Spec-driven development for Claude Code, with one-way Jira Cloud sync — a superset of @skitterbyte/skitterspec: the base filesystem workflow plus /spec-status · /spec-push and the spec-sync CLI. The repo is canonical; Jira is a generated mirror. Install this OR the base OR the Linear superset — exactly one.",
5
+ "keywords": [
6
+ "claude",
7
+ "claude-code",
8
+ "spec-driven-development",
9
+ "sdd",
10
+ "skills",
11
+ "scaffold",
12
+ "jira"
13
+ ],
14
+ "license": "MIT",
15
+ "author": "Reuben Greaves",
16
+ "type": "commonjs",
17
+ "bin": {
18
+ "skitterspec-jira": "bin/skitterspec-jira.js",
19
+ "skitterspec": "bin/skitterspec-jira.js"
20
+ },
21
+ "files": [
22
+ "bin",
23
+ "src",
24
+ "assets",
25
+ "MIGRATION.md"
26
+ ],
27
+ "engines": {
28
+ "node": ">=22.13"
29
+ },
30
+ "dependencies": {
31
+ "prompts": "^2.4.2"
32
+ },
33
+ "scripts": {
34
+ "prepare": "node ../../scripts/build-dist.js skitterspec-jira",
35
+ "prepack": "node ../../scripts/build-dist.js skitterspec-jira"
36
+ },
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/SkitterByte/skitterspec.git",
40
+ "directory": "packages/skitterspec-jira"
41
+ }
42
+ }