@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,284 @@
1
+ ---
2
+ name: spec-reviewed
3
+ description: Pick up the review you approved on the page — run it bare to pick up the single waiting pass, paste the six-digit code off the page ("/spec-reviewed 608223") to name one exactly, or pass the verdict itself ("/spec-reviewed commit") when the page could not send and copied you a command instead. Use when the user says "/spec-reviewed", "I approved it", "I've reviewed it", "pick up my review", "I pressed approve", or otherwise says they have finished reviewing a rendered diff.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # /spec-reviewed — pick up the review you just approved
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
+ You read the diff somewhere else, pressed a verdict, and the engine is holding
15
+ the pass. This is how it gets picked up.
16
+
17
+ ## What this is for, now that the picker exists
18
+
19
+ `/spec-next` and `/spec-diff` both end in a picker carrying these same endings,
20
+ so the usual way to pick a review up is to choose one there. This command is
21
+ what covers the case that picker cannot.
22
+
23
+ **A picker is consumed when the turn ends.** Nobody scrolls back and answers one
24
+ an hour later. So a review read over lunch, a session cleared, a fresh terminal
25
+ tomorrow morning — in every one of those the control is gone and the pass is
26
+ still waiting, and this is the way in. That is a narrower job than it once had,
27
+ and not an absent one.
28
+
29
+ **It is also the only claim path the harness itself enforces** — see below.
30
+ Deleting this skill as redundant with the picker would leave no path that has
31
+ the mechanism at all, only paths that have the property.
32
+
33
+ ## Why this is user-only, and why that is the whole point
34
+
35
+ `disable-model-invocation: true` is not ergonomics here — it is the enforcement
36
+ of `/spec-diff` step 0's central rule:
37
+ **never claim a pass you were not asked to claim**.
38
+
39
+ That rule exists because a review pass can be POSTed by anything that reaches
40
+ the page. So a stranger's pass sits in the holding area — unless an agent goes
41
+ and fetches it, which is exactly what happened once: an agent found a waiting
42
+ approval, read its code off disk, claimed it, and reported the round-trip
43
+ working.
44
+
45
+ Prose alone did not prevent that. The harness does —
46
+ **the model cannot invoke this skill** — so a pass picked up *this way* is only
47
+ ever picked up because a person typed the command. Typing it *is* the human
48
+ signal. A later edit that makes this skill model-invocable does not make it more
49
+ convenient — it removes the only thing standing between a stray approval and
50
+ someone's repo.
51
+
52
+ **There is exactly one other way in, and it is bounded rather than trusting.**
53
+ A phase that ends waits on its page, and a pass arriving *during that wait* is
54
+ claimed by the engine (`--claim-since`, `/spec-diff` §4b): scoped to the window,
55
+ acting on nothing when no pass arrived, refusing when two did. A pass already
56
+ sitting there when the wait began is never swept up by it — which is the
57
+ stranger's pass this whole rule was written about. Everything outside that
58
+ window still comes through here.
59
+
60
+ ## 1. Resolve the spec
61
+
62
+ Bare, exactly as every other bare command in this workflow: the worktree you are
63
+ standing in, else the sole provisioned spec. Ask the engine rather than guessing:
64
+
65
+ ```
66
+ skitterspec spec-env resolve
67
+ ```
68
+
69
+ Several provisioned and none resolved is a refusal — relay its list and stop,
70
+ never pick from it. See `.claude/rules/spec-planning.md`; do not restate the
71
+ rule here.
72
+
73
+ **Four argument shapes, and they cannot collide.** A **six-digit code**
74
+ matches `^\d{6}$`; a **verdict** is one of a closed list of six words;
75
+ a **tracker id** carries a letter and a hyphen;
76
+ a **spec name** is none of them and always carries a lifecycle prefix
77
+ (`feat-`, `bug-`, `hotfix-`), which no verdict does. So the parse needs no flag,
78
+ and nothing has to be guessed at from context.
79
+
80
+ A **six-digit code** is a pass the operator read off their own page. It says
81
+ **which pass**, not which spec — so resolve the spec exactly as a bare
82
+ invocation does, above, and claim the code *there*. Then go to step 4 — a named
83
+ pass has nothing to disambiguate.
84
+
85
+ A **verdict word** — `commit`, `commit-continue`, `commit-start`,
86
+ `commit-land`, `continue`, `changes`, `discuss` — is the conclusion itself,
87
+ arriving without a pass behind it. It is
88
+ what a **`file://` page** hands over: that page has no server to POST to and no
89
+ store to write to, so it copies a command instead of sending anything, and this
90
+ is the command. Resolve the spec as a bare invocation does, then send the word
91
+ through the engine:
92
+
93
+ ```
94
+ skitterspec spec-env review <spec> --verdict <word>
95
+ ```
96
+
97
+ It joins the same merge a claimed pass goes through, so the routing in step 4
98
+ is unchanged: a commit over open notes is refused exactly as it would be, the
99
+ outcome log records it, and the gate a phase armed is cleared. Then go to step
100
+ 4 — there is nothing to disambiguate.
101
+
102
+ **A word carries a verdict and nothing else**, and that is a property of the
103
+ transport, not a shortcut. Accepts and comments do not fit on a command line,
104
+ so the page only ever offers the words while the reader has marked nothing —
105
+ the moment they tick an accept or write a note it goes back to handing over the
106
+ blob. If someone tells you they marked things up *and* gives you a word, ask
107
+ for the pass: the word would land a verdict with their notes silently dropped.
108
+
109
+ A **name** targets that spec instead. A **tracker id** does too, but only
110
+ through a **provider seam**: the base knows nothing about tracker ids, so
111
+ resolve one by asking whichever provider is installed for its listing —
112
+
113
+ ```
114
+ skitterspec spec-sync linked --json
115
+ ```
116
+
117
+ — which answers `[{ spec, bucket, identifier }]`, and match on `identifier`.
118
+ **With no provider installed an id resolves to nothing**, and that is the right
119
+ answer rather than a guess: a `SKS-227`-shaped string is not evidence that a
120
+ tracker exists. Say the id matched no spec and stop.
121
+
122
+ ## 1a. Targeting another spec? Get into its worktree first
123
+
124
+ **Only when the resolved spec's worktree is not where this session stands.**
125
+ Compare the `worktree:` line from `skitterspec spec-env resolve <spec>` against
126
+ cwd, resolving both paths first so a symlinked or trailing-slash spelling of one
127
+ tree does not read as two. **Same tree — say nothing and carry on.** That is the
128
+ ordinary case, and a line about it is narration.
129
+
130
+ **Different trees, and it matters for what comes after, not for the claim.**
131
+ Claiming is harmless from anywhere: the sidecar lives in the primary checkout.
132
+ But an honoured `commit` verdict **commits**, and `changes` **edits files**, and
133
+ both must land in *that spec's* worktree — done from here they would land in
134
+ this one, on the wrong branch, looking entirely normal at the time.
135
+
136
+ So **ask, then move**:
137
+
138
+ *"`feat-orders` lives in `../repo-wt/orders`, and picking its review up means
139
+ committing there — move this session over to carry on?"*
140
+
141
+ - **On a yes**, move with a plain `cd "<worktreePath>"`. That is the whole
142
+ mechanism, exactly as `/spec-start` does it — not a tool call, because an
143
+ approval prompt is unusable on a phone.
144
+ Then **confirm the move landed** rather than assuming it
145
+ (`.claude/rules/negative-checks.md` rule 1): run `skitterspec spec-env resolve`
146
+ with no argument and check its `spec:` line names the target. If it does not,
147
+ stop — do not claim a pass you are about to act on from a tree you could not
148
+ confirm.
149
+ - **On a no, stop without claiming.** A pass claimed here and acted on there is
150
+ exactly the split this guard exists to prevent, and claiming first would spend
151
+ the code for nothing.
152
+
153
+ **A target with no worktree is a refusal.** There is nowhere for a commit to
154
+ land. Name it, suggest `/spec-start <name>`, and stop.
155
+
156
+ **Why not simply refuse unless you are on the base branch?** Because that bans a
157
+ legitimate case — standing in one spec, picking up another's review — while
158
+ *still* leaving the work to be done in a tree you are not in. The relocation is
159
+ needed either way, so the relocation is the guard.
160
+
161
+ ## 2. Read what is waiting
162
+
163
+ ```
164
+ skitterspec spec-env review <spec>
165
+ ```
166
+
167
+ Its `pending:` block lists each waiting pass — code, verdict, age:
168
+
169
+ ```
170
+ pending: 1 waiting
171
+ 792969 · commit · 1 min ago
172
+ ```
173
+
174
+ **Never open `.spec-env/reviews/<spec>.pending.json`.** The render carries
175
+ everything a decision needs, so there is nothing to go looking for, and going
176
+ looking is the bypass step 0 forbids. The file is right there and readable; that
177
+ is precisely why the rule is written down rather than assumed.
178
+
179
+ **Check the store before concluding nothing is waiting.** Only when this spec
180
+ has a published page (`--json` reports a `url`): a reader off the LAN sent their
181
+ pass to the artifact's own `passes` collection rather than to the engine, so an
182
+ empty holding area is not an empty answer yet. Read it with the Artifact tool's
183
+ `read_db`, merge the `blob` through `--notes`, and **delete the document** —
184
+ `/spec-diff` §6 owns the whole sequence, including that a claim consumes.
185
+
186
+ **Nothing waiting in either is an ordinary answer.** Say so and stop. Do not hunt
187
+ through other specs, and do not treat an empty holding area as a problem — a
188
+ `file://` page copies to the clipboard instead of sending, so mention that the
189
+ pass may be on their clipboard waiting to be pasted, and finish.
190
+
191
+ ## 3. One pass waiting? Act on it
192
+
193
+ **Claim it and go to step 4.** Do not read the code out, and do not ask whether
194
+ it is theirs. The operator typed this command, which is the whole signal — and
195
+ this skill is the one place in the workflow where that signal cannot be
196
+ manufactured, because the model cannot invoke it.
197
+
198
+ **The code was never an authorisation.** A later edit must not restore it as
199
+ one. It earned its keep when the *page* pushed: the agent went looking, found
200
+ a pass, and had to prove which one it had. What stops a stranger's approval
201
+ reaching your repo is not those six digits — it is that this command cannot be
202
+ typed by anything but a person, and that the one automatic path (`--claim-since`)
203
+ is bounded by a window a stranger's pass falls outside of. The confirmation step
204
+ added nothing to either, and cost a round-trip on every review.
205
+
206
+ So the code has exactly one job left: **telling two passes apart**. That is
207
+ disambiguation, not a gate.
208
+
209
+ **Two or more waiting is a refusal to guess.** Name them all — code, verdict,
210
+ age — and ask which. Never take the newest, the oldest, or the only `commit`:
211
+ this is the one case where a stranger's pass really is sitting beside theirs,
212
+ and the six digits are the only thing that separates them.
213
+
214
+ *"Two are waiting — 792969 (commit, 1 min ago) and 324199 (commit-continue,
215
+ just now). Which is yours?"*
216
+
217
+ **A pasted code skips even that.** `/spec-reviewed 324199` names the pass
218
+ outright, so there is nothing to disambiguate and nothing to ask — claim it and
219
+ act.
220
+
221
+ **On "that isn't mine"**, leave it and offer to drop it:
222
+
223
+ ```
224
+ skitterspec spec-env review <spec> --drop <code>
225
+ ```
226
+
227
+ A pass that stays is reported on every render until the operator stops reading
228
+ the line — which is how the real one gets missed.
229
+
230
+ ## 4. Claim it and act
231
+
232
+ ```
233
+ skitterspec spec-env review <spec> --claim <code>
234
+ ```
235
+
236
+ Then **route on the verdict exactly as `/spec-diff` §2 does** — its steps 2, 2a
237
+ and 4 own that routing, including the commit hand-off through
238
+ `review.commitWith` and what `commit-continue` does after it. Follow it; do not
239
+ restate it here, because two copies of a routing rule is how the two come to
240
+ disagree.
241
+
242
+ That includes the one rule worth knowing before you invoke anything:
243
+ `commit-continue` runs `/spec-next` and **stops there**. It never completes,
244
+ lands or tears anything down.
245
+
246
+ **A code that matches nothing refuses, and names nothing.** The engine answers
247
+ that way and you relay it unchanged: do not list what *is* waiting, and never
248
+ fall back to "the only one". Both would hand a guesser the answer, and the
249
+ second is exactly the fallback that would let an unread pass through. A mistyped
250
+ digit is the ordinary cause — say the code matched nothing and let the operator
251
+ look again.
252
+
253
+ That holds whichever door the code came through, the paste included. A wrong
254
+ code is a wrong code.
255
+
256
+ A claim is a **delivery mechanism, not a second kind of review**: a pass that
257
+ arrived this way means exactly what the same pass pasted into the chat would
258
+ mean — or picked from `/spec-next`'s picker, which is the same conclusion
259
+ reached by a third route.
260
+
261
+ ## 5. Report
262
+
263
+ End with the block defined in `.claude/rules/spec-reports.md`. That file carries
264
+ the shape; this section carries only what is specific here.
265
+
266
+ **Verdicts**
267
+
268
+ - `✅` — a pass was claimed and its verdict acted on.
269
+ - `⚠️` — claimed and acted on, with something worth knowing.
270
+ - `❌` — it acted and stopped part-way; the commit failed, or the work did.
271
+ Quote it.
272
+ - `⏸` — nothing was waiting, the operator said the waiting pass was not theirs,
273
+ they declined the move to another spec's worktree, or the target has no
274
+ worktree at all. Nothing changed, and none of those is a failure.
275
+
276
+ **Fields:** `Tracker` · `Branch` · `Built` · `Tests` · `Worktree` ·
277
+ `Follow-ups` · `Next`
278
+
279
+ `Worktree` appears only when this run **moved the session** — the path it moved
280
+ to, because the operator's next command depends on knowing where they now are.
281
+ A run that stayed put omits it.
282
+
283
+ `Built` is what the verdict produced — the commit, or the commented files
284
+ worked. A run that claimed nothing built nothing and omits it.