@skitterbyte/skitterspec 22.3.0 → 22.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/core/env.config.md +1 -0
- package/package.json +1 -1
- package/src/cli.js +49 -9
|
@@ -188,6 +188,7 @@ through to a documented conservative default; see the field notes below.
|
|
|
188
188
|
// deliberate: the file it names then belongs to some other spec, and the safe
|
|
189
189
|
// failure is a refusal you clear with /commit, not a stranger's file swept
|
|
190
190
|
// into your commit. Default: none — a spec owns only its own folder.
|
|
191
|
+
|
|
191
192
|
"spec": {
|
|
192
193
|
"companionPaths": []
|
|
193
194
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skitterbyte/skitterspec",
|
|
3
|
-
"version": "22.3.
|
|
3
|
+
"version": "22.3.1",
|
|
4
4
|
"description": "Spec-driven development for Claude Code \u2014 a tracker-free filesystem workflow: lifecycle skills and per-spec isolation. For Linear sync, install @skitterbyte/skitterspec-linear instead.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
package/src/cli.js
CHANGED
|
@@ -2576,18 +2576,58 @@ function specEnvReviewAllow(dir, config, tier, flags) {
|
|
|
2576
2576
|
}
|
|
2577
2577
|
|
|
2578
2578
|
// `review skip` — move on without a verdict, on the record.
|
|
2579
|
-
|
|
2579
|
+
/**
|
|
2580
|
+
* Split `skip`'s positionals into a spec and a reason.
|
|
2581
|
+
*
|
|
2582
|
+
* WHY IT IS NOT SIMPLY `positional[1]`. It was, and it made the gate's own
|
|
2583
|
+
* documented exit unreachable: a spec whose worktree is gone resolves neither
|
|
2584
|
+
* from the cwd nor from a sole provisioned spec, so the refusal told the
|
|
2585
|
+
* operator to "name the one you mean" — a thing the command could not accept —
|
|
2586
|
+
* while its worktree, the other half of that advice, no longer existed. The
|
|
2587
|
+
* gate was then permanent, and clearing it meant hand-editing a gitignored
|
|
2588
|
+
* sidecar. `review gate <spec>` and `review <spec> --claim-since` both take a
|
|
2589
|
+
* name; this was the one that did not.
|
|
2590
|
+
*
|
|
2591
|
+
* TWO POSITIONALS are unambiguous: spec, then reason.
|
|
2592
|
+
*
|
|
2593
|
+
* ONE IS DECIDED BY A POSITIVE SIGNAL (`.claude/rules/negative-checks.md`
|
|
2594
|
+
* rule 1) — it is a spec only where it RESOLVES to one. `findSpecFolder`
|
|
2595
|
+
* matches a bucket folder by exact basename, so nothing fuzzy gets in: a reason
|
|
2596
|
+
* has to be spelled exactly like a spec folder to be read as one, and a reason
|
|
2597
|
+
* that is spelled exactly like a spec folder is a person naming a spec. Every
|
|
2598
|
+
* cannot-tell — an unknown name, an unresolvable repo, a thrown resolver —
|
|
2599
|
+
* falls to the reason, which is the behaviour this command has always had and
|
|
2600
|
+
* the harmless branch.
|
|
2601
|
+
*
|
|
2602
|
+
* THE PROBE NEVER DECIDES THE OUTCOME, only which slot the word fills. What
|
|
2603
|
+
* happens next is the ordinary resolution, refusal text and all.
|
|
2604
|
+
*/
|
|
2605
|
+
function splitSkipArgs(dir, config, rest) {
|
|
2606
|
+
const args = (rest || []).filter((a) => a !== undefined && a !== null)
|
|
2607
|
+
if (args.length >= 2) return { specArg: args[0], reason: args[1] }
|
|
2608
|
+
if (args.length === 1) {
|
|
2609
|
+
return gateTarget(dir, config, args[0]).spec
|
|
2610
|
+
? { specArg: args[0], reason: null }
|
|
2611
|
+
: { specArg: null, reason: args[0] }
|
|
2612
|
+
}
|
|
2613
|
+
return { specArg: null, reason: null }
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
function specEnvReviewSkip(dir, config, rest, flags) {
|
|
2617
|
+
const { specArg, reason } = splitSkipArgs(dir, config, rest)
|
|
2580
2618
|
const said = String(reason || '').trim()
|
|
2581
2619
|
if (!said) {
|
|
2582
2620
|
// The reason IS the feature. A skip with no reason is the silence this
|
|
2583
|
-
// whole gate exists to replace, so it is refused rather than defaulted
|
|
2621
|
+
// whole gate exists to replace, so it is refused rather than defaulted —
|
|
2622
|
+
// and naming the spec is not giving one, which is why the probe above puts
|
|
2623
|
+
// a lone spec name in the spec slot and leaves this empty.
|
|
2584
2624
|
process.stdout.write(
|
|
2585
|
-
'spec-env review skip: needs a reason — skitterspec spec-env review skip "<why>"\n',
|
|
2625
|
+
'spec-env review skip: needs a reason — skitterspec spec-env review skip [<spec>] "<why>"\n',
|
|
2586
2626
|
)
|
|
2587
2627
|
process.exitCode = 1
|
|
2588
2628
|
return
|
|
2589
2629
|
}
|
|
2590
|
-
const target = gateTarget(dir, config,
|
|
2630
|
+
const target = gateTarget(dir, config, specArg)
|
|
2591
2631
|
if (!target.spec) {
|
|
2592
2632
|
process.stdout.write(`spec-env review skip: cannot tell which spec — ${target.reason}\n`)
|
|
2593
2633
|
process.exitCode = 1
|
|
@@ -5114,10 +5154,10 @@ async function specEnv(rest) {
|
|
|
5114
5154
|
break
|
|
5115
5155
|
}
|
|
5116
5156
|
if (positional[0] === 'skip') {
|
|
5117
|
-
//
|
|
5118
|
-
//
|
|
5119
|
-
//
|
|
5120
|
-
specEnvReviewSkip(dir, config, positional
|
|
5157
|
+
// `skip [<spec>] "<why>"`. The spec is usually resolvable from where you
|
|
5158
|
+
// are standing, which is why it stays optional — but not always, and
|
|
5159
|
+
// `splitSkipArgs` carries why that mattered enough to change.
|
|
5160
|
+
specEnvReviewSkip(dir, config, positional.slice(1), flags)
|
|
5121
5161
|
break
|
|
5122
5162
|
}
|
|
5123
5163
|
await specEnvReview(dir, config, positional[0], flags, invokedFrom)
|
|
@@ -5134,7 +5174,7 @@ async function specEnv(rest) {
|
|
|
5134
5174
|
' review arm [spec] [--phase <n>] a phase ended — its diff now owes a verdict\n' +
|
|
5135
5175
|
' review gate [spec] [--check] [--json] is one owed? --check exits non-zero if so\n' +
|
|
5136
5176
|
' [--for-command <cmdline>] ...but only when that command is a git commit\n' +
|
|
5137
|
-
' review skip "<reason>"
|
|
5177
|
+
' review skip [spec] "<reason>" move on without one, on the record\n' +
|
|
5138
5178
|
' review gate [spec] --offered record that the bypass was offered (spends it)\n' +
|
|
5139
5179
|
' review wait [spec] --heartbeat <secs> proof-of-life cadence on stderr; 0 disables\n' +
|
|
5140
5180
|
' review wait [spec] --since <iso> block until a verdict arrives ([--timeout <s>])\n' +
|