@skitterbyte/skitterspec 20.0.0 → 22.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.
- package/MIGRATION.md +304 -4
- package/README.md +113 -6
- package/assets/claude-md-section.md +29 -18
- package/assets/commands/spec-remote-review.md +22 -0
- package/assets/core/env.config.json.example +4 -2
- package/assets/core/env.config.md +103 -25
- package/assets/review/page.html +1101 -108
- package/assets/rules/spec-planning.md +39 -7
- package/assets/rules/spec-reports.md +210 -31
- package/assets/skills/spec/SKILL.md +129 -1
- package/assets/skills/spec-bug/SKILL.md +63 -43
- package/assets/skills/spec-diff/SKILL.md +183 -39
- package/assets/skills/spec-hotfix/SKILL.md +57 -43
- package/assets/skills/spec-init/SKILL.md +18 -6
- package/assets/skills/spec-next/SKILL.md +145 -60
- package/assets/skills/spec-review/SKILL.md +87 -0
- package/assets/skills/spec-reviewed/SKILL.md +31 -5
- package/assets/skills/spec-start/SKILL.md +19 -0
- package/package.json +1 -1
- package/src/cli.js +940 -116
- package/src/env/classify.js +87 -2
- package/src/env/config.js +214 -17
- package/src/env/hooks.js +49 -9
- package/src/env/live.js +94 -0
- package/src/env/resolve.js +36 -2
- package/src/env/review.js +581 -21
- package/src/env/serve.js +298 -19
- package/src/env/supervise.js +8 -1
- package/src/init.js +88 -13
- /package/assets/hooks/{review-gate.js → review-gate.cjs} +0 -0
|
@@ -21,8 +21,27 @@ port block, and no `.env`.
|
|
|
21
21
|
exactly as it does today.
|
|
22
22
|
|
|
23
23
|
The loader (`src/env/config.js` → `loadEnvConfig`) merges your file over the
|
|
24
|
-
frozen defaults below and returns `{ config, present }`;
|
|
25
|
-
no live `env.config.json` was found.
|
|
24
|
+
frozen defaults below and returns `{ config, present, unknown }`;
|
|
25
|
+
`present:false` means no live `env.config.json` was found.
|
|
26
|
+
|
|
27
|
+
**A key not listed below is ignored — and says so.** Every `spec-env` command
|
|
28
|
+
prints one advisory line per unrecognised key, top-level or nested:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
spec-env: env.config.json — unknown key "docker.portbase" is ignored.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
It is advisory in the strongest sense: the key is dropped exactly as it always
|
|
35
|
+
was, nothing refuses, and the exit status is unchanged. It exists because the
|
|
36
|
+
two things an unknown key can be — a deliberate forward-compat entry and a typo
|
|
37
|
+
— are indistinguishable from here, and only one of them is a mistake you would
|
|
38
|
+
want to hear about. A mis-typed `review.required` leaves the commit gate on and
|
|
39
|
+
a mis-typed `teardown.deleteRemoteBranch` reverts to `prompt`; before this, the
|
|
40
|
+
only signal either gave was that nothing happened.
|
|
41
|
+
|
|
42
|
+
A **known** key whose value is rejected — `mode: "Checkout"`,
|
|
43
|
+
`teardown.deleteRemoteBranch: "yes"` — is not reported here. Each of those falls
|
|
44
|
+
through to a documented conservative default; see the field notes below.
|
|
26
45
|
|
|
27
46
|
## Fields
|
|
28
47
|
|
|
@@ -74,8 +93,9 @@ no live `env.config.json` was found.
|
|
|
74
93
|
// `spec-env up`, right after `git worktree add` and BEFORE `setup` runs — so a
|
|
75
94
|
// fresh linked worktree (which starts with none of the repo's gitignored files)
|
|
76
95
|
// has the .env / local secret overrides / local config that setup steps and
|
|
77
|
-
// git hooks depend on. Without this
|
|
78
|
-
//
|
|
96
|
+
// git hooks depend on. Without this any setup step that reads .env — a schema
|
|
97
|
+
// or client generator, a codegen pass — hard-fails in the new worktree
|
|
98
|
+
// because the file it expects isn't there.
|
|
79
99
|
// mode "symlink" (default) points the worktree file at the main file, so it
|
|
80
100
|
// stays in sync; "copy" makes an independent copy.
|
|
81
101
|
// files repo-relative paths to seed. A source absent in main is a printed
|
|
@@ -221,13 +241,15 @@ no live `env.config.json` was found.
|
|
|
221
241
|
|
|
222
242
|
// Reading a spec's diff (`spec-env review`, `/spec-diff`).
|
|
223
243
|
//
|
|
224
|
-
// `reader` decides how the page's LOCATION IS WORDED
|
|
225
|
-
//
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
// "
|
|
244
|
+
// `reader` decides how the page's LOCATION IS WORDED. It no longer decides
|
|
245
|
+
// the bind — `allowNetwork` does, see below — and it no longer decides which
|
|
246
|
+
// tiers are offered, because every tier is now listed whatever it says.
|
|
247
|
+
// WHAT THE SERVER
|
|
248
|
+
// BINDS TO — and nothing else. It never decides whether to serve (`serve`
|
|
249
|
+
// does) and never decides to PUBLISH. Three values:
|
|
250
|
+
// "local" — you are at the machine holding the page; it binds 127.0.0.1.
|
|
251
|
+
// "remote" — you are not; it binds every interface so the page opens.
|
|
252
|
+
// "detect" — work it out (the default); cannot-tell binds 127.0.0.1.
|
|
231
253
|
// An explicit "local"/"remote" is BELIEVED WITHOUT SNIFFING: you know where
|
|
232
254
|
// you are reading, and no signal outranks being told. Detection is only the
|
|
233
255
|
// default, and it has three outcomes rather than two — local, remote, and
|
|
@@ -237,25 +259,81 @@ no live `env.config.json` was found.
|
|
|
237
259
|
// unrecognised value falls through to "detect", so a typo cannot become a
|
|
238
260
|
// confident answer. Default: detect.
|
|
239
261
|
//
|
|
240
|
-
// `servePort` is the
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
//
|
|
245
|
-
//
|
|
262
|
+
// `servePort` is the port for `spec-env review serve`, which renders every
|
|
263
|
+
// spec's diff per request on one local server. Two forms:
|
|
264
|
+
//
|
|
265
|
+
// "auto" (the default) — derive it from this repo's path, as
|
|
266
|
+
// 7700 + hash(realpath(repoRoot)) % 100. Two repos on one machine stop
|
|
267
|
+
// competing for one shared port without anyone configuring anything, and
|
|
268
|
+
// — the part that matters — THE SAME REPO GETS THE SAME PORT EVERY TIME.
|
|
269
|
+
// The derivation reads nothing on disk, so the port survives a restart, a
|
|
270
|
+
// reboot and a `--stop`, which is what lets a link handed out yesterday
|
|
271
|
+
// still resolve. A symlinked spelling of the tree resolves first, so one
|
|
272
|
+
// repo never lands on two ports.
|
|
273
|
+
// <a number> — pin it. An explicit number always wins, and pinning is what
|
|
274
|
+
// you do when you want a port you can memorise, or when two repos derive
|
|
275
|
+
// the same one.
|
|
246
276
|
//
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
//
|
|
277
|
+
// A derived port CAN still collide — a hundred slots is a small chance, not
|
|
278
|
+
// no chance — and the server refuses rather than moving itself aside. The fix
|
|
279
|
+
// it names is `servePort`, because that is what the next link is built from;
|
|
280
|
+
// `--port` moves one run and leaves every link already handed out pointing at
|
|
281
|
+
// the busy port. `spec-env review serve --status` prints the port and which
|
|
282
|
+
// of the three chose it.
|
|
283
|
+
//
|
|
284
|
+
// An unrecognised value falls through to "auto", like every other typed key
|
|
285
|
+
// here. Default: "auto".
|
|
286
|
+
//
|
|
287
|
+
// The server binds 127.0.0.1 unless `--host 0.0.0.0` is passed, which mints
|
|
288
|
+
// an unguessable path token and prints the LAN URL including it — anyone
|
|
289
|
+
// holding that URL can read every spec's diff while it runs.
|
|
290
|
+
//
|
|
291
|
+
// `serve` is whether a render stands the local server up at all:
|
|
292
|
+
// "always" — every render does (the default), so `local:` and `network:`
|
|
293
|
+
// are both http URLs the page can POST a verdict back to. The
|
|
294
|
+
// LAN address comes first with the rest listed under it, because
|
|
295
|
+
// the guess reads interface names and a VPN or an unusual
|
|
296
|
+
// adapter will fool it.
|
|
297
|
+
// "never" — `local:` is a file:// URL instead. Note what that costs: a
|
|
298
|
+
// file:// page has no server to POST to, so its verdict buttons
|
|
299
|
+
// copy a command for you to paste rather than sending anything.
|
|
300
|
+
// It replaced `serveOnRemote`, which gated serving on the reader — and so
|
|
301
|
+
// handed a local machine a page it could read and not answer. A legacy
|
|
302
|
+
// `serveOnRemote: false` is still read as `serve: "never"`.
|
|
253
303
|
// Either way NOTHING IS PUBLISHED on a detection: a server is one process
|
|
254
304
|
// ended by one flag, while a published page is one this tooling cannot
|
|
255
305
|
// remove, so that half stays an explicit ask. Teardown names a server that
|
|
256
306
|
// served the last spec, and `spec-env prune` reaps a pidfile whose process is
|
|
257
307
|
// gone. Default: true.
|
|
258
308
|
//
|
|
309
|
+
// `allowNetwork` and `allowRemote` decide WHICH TIERS a render offers, and
|
|
310
|
+
// they replaced the engine guessing where the reader was sitting. It guessed
|
|
311
|
+
// for a while and got it wrong three separate ways in one day: a file:// page
|
|
312
|
+
// on a session detected `unknown`, a LAN URL for a phone that had left the
|
|
313
|
+
// network, and an address that changed underneath a reader mid-session. So
|
|
314
|
+
// every tier is listed, labelled, and either a URL or the one command that
|
|
315
|
+
// turns it on — and you pick the one that reaches you.
|
|
316
|
+
//
|
|
317
|
+
// `allowNetwork` — whether the review server binds EVERY INTERFACE, so the
|
|
318
|
+
// page opens on your phone, or loopback only. THIS IS WHAT
|
|
319
|
+
// CHOOSES THE BIND; `reader` no longer does. Default: true,
|
|
320
|
+
// which matches what the engine already did.
|
|
321
|
+
// `allowRemote` — whether PUBLISHING is permitted at all. It permits it; it
|
|
322
|
+
// publishes nothing. Default: FALSE, because a published
|
|
323
|
+
// page is one skitterspec cannot delete, so it must never
|
|
324
|
+
// happen unasked.
|
|
325
|
+
//
|
|
326
|
+
// `local` and `network` are two doors into ONE ROOM — the page POSTs to
|
|
327
|
+
// `location.pathname`, so both reach the same server and the same waiting
|
|
328
|
+
// verdict, and one wait covers both. `remote` is a second store: a verdict
|
|
329
|
+
// pressed on a published page needs `/spec-reviewed`, because nothing pushes
|
|
330
|
+
// from an artifact's store into a conversation.
|
|
331
|
+
//
|
|
332
|
+
// Both are toggled by `spec-env review allow <tier> --set [on|off]`, where an
|
|
333
|
+
// empty value toggles — which is what `/spec-remote-review` runs. It writes
|
|
334
|
+
// THIS FILE in the primary checkout, so it changes for everyone who pulls and
|
|
335
|
+
// leaves that tree dirty; the engine says so when it does.
|
|
336
|
+
//
|
|
259
337
|
// `commitWith` names the skill a COMMITTING verdict hands off to. A review
|
|
260
338
|
// page ends in a verdict — commit, commit & continue, request changes,
|
|
261
339
|
// discuss — and the point of the first two is that the commit follows from
|
|
@@ -288,8 +366,8 @@ no live `env.config.json` was found.
|
|
|
288
366
|
// place rather than quietly disabling it. Default: true.
|
|
289
367
|
"review": {
|
|
290
368
|
"reader": "detect",
|
|
291
|
-
"servePort":
|
|
292
|
-
"
|
|
369
|
+
"servePort": "auto",
|
|
370
|
+
"serve": "always",
|
|
293
371
|
"commitWith": "/commit",
|
|
294
372
|
"required": true
|
|
295
373
|
}
|