heyspex 0.2.5 → 0.2.7

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 (110) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/bin/hs.mjs +349 -38
  3. package/bin/spexcode.mjs +31 -0
  4. package/dev-factory/lib/dispatch-guard.mjs +75 -0
  5. package/dev-factory/lib/local-firecrawl.mjs +294 -0
  6. package/dev-factory/lib/runner-path.mjs +51 -0
  7. package/dev-factory/lib/seat-context.mjs +20 -4
  8. package/dev-factory/model-catalog.json +222 -222
  9. package/dev-factory/spexcrawl/firecrawl-cli.mjs +755 -0
  10. package/dev-factory/spexcrawl/spexcrawl-cli.mjs +734 -0
  11. package/dist/cli/hs-connect.mjs +40 -3
  12. package/dist/cli/hs-defer.mjs +3817 -3741
  13. package/dist/cli/hs-events.mjs +1296 -0
  14. package/dist/cli/hs-export-events.mjs +1252 -0
  15. package/dist/cli/hs-handoff.mjs +2576 -0
  16. package/dist/cli/hs-index-rebuild.mjs +228 -37
  17. package/dist/cli/hs-index-reconcile.mjs +231 -40
  18. package/dist/cli/hs-init.mjs +22 -3
  19. package/dist/cli/hs-install.mjs +22 -3
  20. package/dist/cli/hs-join.mjs +40 -3
  21. package/dist/cli/hs-next-launch.mjs +2777 -0
  22. package/dist/cli/hs-pin.mjs +1336 -0
  23. package/dist/cli/hs-prereq.mjs +1380 -0
  24. package/dist/cli/hs-revalidate.mjs +3257 -0
  25. package/dist/cli/hs-spawn.mjs +12403 -0
  26. package/dist/cli/hs-test.mjs +1046 -0
  27. package/dist/cli/hs-trash.mjs +362 -0
  28. package/dist/cli/hs-trust.mjs +197 -0
  29. package/dist/cli/hs-vault-pull.mjs +233 -42
  30. package/dist/cli/hs-vault-push.mjs +231 -40
  31. package/dist/cli/hs-vault.mjs +21 -7
  32. package/dist/cli/hs-workspace.mjs +19 -1
  33. package/dist/cli-templates/customer-vault/specs/entity-model.md +1728 -1728
  34. package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +464 -464
  35. package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -122
  36. package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +46 -46
  37. package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +530 -530
  38. package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -83
  39. package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -28
  40. package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -62
  41. package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -29
  42. package/dist/cli-templates/harness-commands/claude/hs-ground.md +30 -30
  43. package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -29
  44. package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -70
  45. package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -35
  46. package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -27
  47. package/dist/cli-templates/harness-commands/claude/hs-res.md +83 -63
  48. package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -23
  49. package/dist/cli-templates/harness-commands/claude/hs-view.md +28 -28
  50. package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -32
  51. package/dist/cli-templates/harness-commands/claude/prototype.md +91 -91
  52. package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +22 -22
  53. package/dist/cli-templates/harness-commands/cursor/hs-capture.md +56 -56
  54. package/dist/cli-templates/harness-commands/cursor/hs-defer.md +23 -23
  55. package/dist/cli-templates/harness-commands/cursor/hs-ground.md +24 -24
  56. package/dist/cli-templates/harness-commands/cursor/hs-next.md +23 -23
  57. package/dist/cli-templates/harness-commands/cursor/hs-promote.md +64 -64
  58. package/dist/cli-templates/harness-commands/cursor/hs-push.md +29 -29
  59. package/dist/cli-templates/harness-commands/cursor/hs-qc.md +21 -21
  60. package/dist/cli-templates/harness-commands/cursor/hs-res.md +78 -58
  61. package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +17 -17
  62. package/dist/cli-templates/harness-commands/cursor/hs-view.md +23 -23
  63. package/dist/cli-templates/harness-commands/cursor/kill-ports.md +26 -26
  64. package/dist/cli-templates/harness-commands/cursor/prototype.md +86 -86
  65. package/docs/copilot-plugin-install.md +9 -2
  66. package/docs/mcp-client-config.md +6 -0
  67. package/package.json +266 -257
  68. package/plugins/heyspex/.claude-plugin/plugin.json +1 -1
  69. package/plugins/heyspex/.cursor-plugin/plugin.json +1 -1
  70. package/plugins/heyspex/README.md +6 -0
  71. package/plugins/heyspex/bin/launch-mcp.mjs +17 -0
  72. package/plugins/heyspex/hooks/hooks.json +418 -418
  73. package/scripts/claude-hooks/_intent-classifier-semantic.mjs +2 -2
  74. package/scripts/claude-hooks/wip-checkpoint.mjs +17 -2
  75. package/scripts/claude-statusline/statusline-command.mjs +287 -27
  76. package/scripts/hs-companion.mjs +41 -3
  77. package/scripts/install-claude-code-hooks.mjs +104 -3
  78. package/scripts/install-copilot-hooks.mjs +21 -1
  79. package/scripts/install-cursor-hooks.mjs +4 -3
  80. package/scripts/lib/capture-execution-guard.mjs +221 -0
  81. package/scripts/lib/companion-install.mjs +768 -0
  82. package/scripts/lib/customer-kit.mjs +53 -3
  83. package/scripts/lib/hs-companion-settings.mjs +26 -0
  84. package/scripts/lib/hs-source-push.mjs +386 -386
  85. package/scripts/record-grounding.mjs +38 -0
  86. package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -29
  87. package/spexharness/src/adapters/copilot-models.mjs +179 -0
  88. package/spexharness/src/adapters/harness-detect.mjs +148 -0
  89. package/spexharness/src/gates/directive-obligation-gate.decide.mjs +132 -132
  90. package/spexharness/src/gates/vault-write-tier-guard.decide.mjs +153 -125
  91. package/spexharness/src/seat-context.mjs +10 -5
  92. package/spexharness/src/session-bootstrap.mjs +6 -3
  93. package/vendor/heyspex-mcp/cli.mjs +6 -1
  94. package/vendor/heyspex-mcp/config-seed.yaml +15 -15
  95. package/vendor/heyspex-mcp/dev-factory-overlay.mjs +142 -0
  96. package/vendor/heyspex-mcp/http-transport.mjs +1 -1
  97. package/vendor/heyspex-mcp/memory-tools.mjs +523 -523
  98. package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -1708
  99. package/vendor/heyspex-mcp/procedure-handlers.mjs +327 -327
  100. package/vendor/heyspex-mcp/procedure-tools.mjs +1209 -1181
  101. package/vendor/heyspex-mcp/research-tools.mjs +22 -2
  102. package/vendor/heyspex-mcp/seat-assign-cli.mjs +242 -0
  103. package/vendor/heyspex-mcp/seat-assignment-rules.mjs +96 -0
  104. package/vendor/heyspex-mcp/seat-assignments-client.mjs +265 -0
  105. package/vendor/heyspex-mcp/seat-defaults-cli.mjs +45 -0
  106. package/vendor/heyspex-mcp/seat-defaults.mjs +232 -0
  107. package/vendor/heyspex-mcp/seat-identity.mjs +171 -0
  108. package/vendor/heyspex-mcp/test-helpers.mjs +37 -23
  109. package/vendor/heyspex-mcp/vault-io.mjs +720 -720
  110. package/bin/postinstall.mjs +0 -88
@@ -7,29 +7,29 @@ description: Kill every process listening on a TCP port in the range 3000–5999
7
7
 
8
8
  **Usage:** `/kill-ports (no arguments)`
9
9
 
10
- **Always use the PowerShell tool for this command — never the Bash tool.** Bash routes to a POSIX shell in this environment and the PowerShell syntax below will fail there.
11
-
12
- Kill all processes that are **listening** on TCP ports in the range **3000–5999** inclusive. This clears orphaned dev servers (Next.js, console, companion bridges, etc.) that are holding ports.
13
-
14
- Run this single command via the **PowerShell** tool. It discovers the listening connections in range, reports each `port → pid (process name)` it is about to kill, then force-kills the unique owning PIDs and confirms:
15
-
16
- ```powershell
17
- $conns = Get-NetTCPConnection -State Listen -ErrorAction SilentlyContinue |
18
- Where-Object { $_.LocalPort -ge 3000 -and $_.LocalPort -le 5999 }
19
- if (-not $conns) { Write-Output 'No listeners on ports 3000-5999. Nothing to kill.'; return }
20
- $pids = $conns | Select-Object -ExpandProperty OwningProcess -Unique
21
- foreach ($c in $conns) {
22
- $p = Get-Process -Id $c.OwningProcess -ErrorAction SilentlyContinue
23
- $name = if ($p) { $p.ProcessName } else { '?' }
24
- Write-Output ("port {0,-5} -> pid {1} ({2})" -f $c.LocalPort, $c.OwningProcess, $name)
25
- }
26
- foreach ($procId in $pids) {
27
- try { Stop-Process -Id $procId -Force -ErrorAction Stop; Write-Output ("killed pid {0}" -f $procId) }
28
- catch { Write-Output ("could not kill pid {0}: {1}" -f $procId, $_.Exception.Message) }
29
- }
30
- ```
31
-
32
- Notes:
33
- - Only TCP **listeners** are targeted, so client/outbound connections in that range are left alone.
34
- - If `Stop-Process` fails on a PID (e.g. a Windows system process like `svchost`, which needs admin and shouldn't be killed anyway, or a process that already exited), report the `Access is denied` / error and continue with the rest — do not abort the whole run.
35
- - After running, briefly summarize how many ports were freed.
10
+ **Always use the PowerShell tool for this command — never the Bash tool.** Bash routes to a POSIX shell in this environment and the PowerShell syntax below will fail there.
11
+
12
+ Kill all processes that are **listening** on TCP ports in the range **3000–5999** inclusive. This clears orphaned dev servers (Next.js, console, companion bridges, etc.) that are holding ports.
13
+
14
+ Run this single command via the **PowerShell** tool. It discovers the listening connections in range, reports each `port → pid (process name)` it is about to kill, then force-kills the unique owning PIDs and confirms:
15
+
16
+ ```powershell
17
+ $conns = Get-NetTCPConnection -State Listen -ErrorAction SilentlyContinue |
18
+ Where-Object { $_.LocalPort -ge 3000 -and $_.LocalPort -le 5999 }
19
+ if (-not $conns) { Write-Output 'No listeners on ports 3000-5999. Nothing to kill.'; return }
20
+ $pids = $conns | Select-Object -ExpandProperty OwningProcess -Unique
21
+ foreach ($c in $conns) {
22
+ $p = Get-Process -Id $c.OwningProcess -ErrorAction SilentlyContinue
23
+ $name = if ($p) { $p.ProcessName } else { '?' }
24
+ Write-Output ("port {0,-5} -> pid {1} ({2})" -f $c.LocalPort, $c.OwningProcess, $name)
25
+ }
26
+ foreach ($procId in $pids) {
27
+ try { Stop-Process -Id $procId -Force -ErrorAction Stop; Write-Output ("killed pid {0}" -f $procId) }
28
+ catch { Write-Output ("could not kill pid {0}: {1}" -f $procId, $_.Exception.Message) }
29
+ }
30
+ ```
31
+
32
+ Notes:
33
+ - Only TCP **listeners** are targeted, so client/outbound connections in that range are left alone.
34
+ - If `Stop-Process` fails on a PID (e.g. a Windows system process like `svchost`, which needs admin and shouldn't be killed anyway, or a process that already exited), report the `Access is denied` / error and continue with the rest — do not abort the whole run.
35
+ - After running, briefly summarize how many ports were freed.
@@ -7,89 +7,89 @@ description: Build an HTML/frontend prototype for the HeySpex Console. Files MUS
7
7
 
8
8
  **Usage:** `/prototype <slug> [--from-spec HS-XXXX] [--bump] [--variant <name>]`
9
9
 
10
- This skill is the **implementation** of `specs/protocols/prototype-lifecycle-protocol.md`. The protocol is the SSOT — when they conflict, the protocol wins and this skill is the bug. Fetch it with `heyspex_get_procedure({ name: "prototype-lifecycle-protocol" })` when you need the full rules.
11
-
12
- It applies to:
13
-
14
- - explicit `/prototype` invocation
15
- - any natural-language "build me an HTML prototype / mock / preview / canvas" ask
16
- - `/frontend-design` invocations in this repo (the plugin builds the artifact; this skill governs placement)
17
-
18
- ## The contract — no exceptions
19
-
20
- **Required output paths** (both files, same commit):
21
-
22
- 1. `spex-console/public/design-previews/<slug>-v<N>[-<variant>].html` — the self-contained prototype.
23
- 2. `spex-console/public/design-previews/<slug>-v<N>[-<variant>].meta.json` — the sidecar.
24
-
25
- Anything outside this folder — including a stray top-level `prototypes/` directory — is **invisible** to the console. The route at `spex-console/src/app/api/ui-design/prototypes/route.ts` reads this folder flat (no recursion, no nested folders). A prototype that doesn't show up in the Prototypes surface does not exist for the user.
26
-
27
- ## Naming
28
-
29
- - **`<slug>`** (lineage slug) — kebab-case, describes the surface (`capture-canvas`, `shipped-surface`, `review-inbox`). May contain hyphens. **Match an existing lineage if you're iterating on a known surface** — grep `spex-console/public/design-previews/` before inventing a new slug.
30
- - **`-v<N>`** — version, starts at `-v1`. **Bump rather than overwrite.** The console groups versions into a lineage with full history. If `--bump`, increment from the highest existing `-v<N>` for that slug.
31
- - **`-<variant>`** (optional) — sibling variant within a version (e.g. `-v2-alt`, `-v2-minimal`, `-v2-terminal`). May contain hyphens. The console nests variants under their parent version and shows a `+N variants at vK` chip on the lineage card. Variants are for "A/B explorations of the same version", not new lineages.
32
- - **No `index.html`, no nested folders, no dated filenames.** Just `<slug>-v<N>[-<variant>].html`.
33
-
34
- ## meta.json schema
35
-
36
- Validate against `specs/schemas/prototype-meta.schema.json`. Required: `title` + `status`. Always set `surface_area` and 1–4 `tags` on new sidecars (the console's filter rail depends on them — leaving them empty makes the prototype harder to find).
37
-
38
- ```json
39
- {
40
- "title": "Human-readable name (e.g. 'Capture canvas v2')",
41
- "description": "One-paragraph summary: what it demonstrates, key interactions, aesthetic direction, technical notes. The console hides this on the card and shows it in the drawer Notes tab — write for that context.",
42
- "status": "draft",
43
- "surface_area": "capture | on-deck | preloader | shell | review | roadmap | other",
44
- "tags": ["kebab-case", "1-to-4"],
45
- "updated_at": "2026-06-03T18:17:00.000Z",
46
- "design_doc": "specs/ui/<slug>-design.md (optional but required for promotion to accepted)",
47
- "linked_specs": [
48
- "HS-XXXX-CAP-...",
49
- "HS-XXXX-EPIC-..."
50
- ],
51
- "parent": "<slug>-v<N-1>.html (optional, when this iterates on a prior version)",
52
- "embeds": ["other-prototype-slug (optional)"]
53
- }
54
- ```
55
-
56
- - **`status` MUST be `"draft"` at create time.** Promotion to `"accepted"` runs through the console's `/api/ui-design/prototypes/<slug>/promote` route and requires both a linked `design_doc` AND a review entry under `specs/reviews/`. The skill does not write `accepted` — refuse if the user asks. (`"archived"` is for superseded versions; usually set later, not at create time.)
57
- - **Compute `updated_at` as `new Date().toISOString()`** at write time.
58
- - **`linked_specs`** accepts vault basenames (no `.md` extension) and `HS-*` IDs. Always include the capture/epic/task the prototype embodies. Pull from `--from-spec` if provided. Never invent IDs.
59
- - Reference siblings in this folder for examples — `shipped-surface-v1.meta.json` (thorough) or `on-deck-v2.meta.json` (minimal).
60
-
61
- ## Workflow
62
-
63
- When this skill is invoked or matched:
64
-
65
- 1. **Resolve lineage slug.** Match an existing slug if iterating on a known surface; otherwise pick a new kebab-case slug.
66
- 2. **Resolve version.** Default `-v1`. If a file with the same slug already exists, default to bumping to the next integer; honour explicit `--bump`. **Never silently overwrite** — if the target file exists and `--bump` was not passed, surface the conflict and ask.
67
- 3. **Resolve variant.** `--variant <name>` produces `<slug>-v<N>-<name>.html`. Without it, you produce the base variant.
68
- 4. **Pull source spec context.** If `--from-spec HS-XXXX` is passed or the user references a spec, Read it first so the prototype reflects real content, not invented filler.
69
- 5. **Aesthetic.** Defer to the user's brief (e.g. "Claude-in-PowerShell terminal aesthetic" overrides defaults). Otherwise honour console design-system tokens — fetch via `heyspex_design_*` MCP tools, do not grep `spex-console/DESIGN.md`. Recall UI memories first: `heyspex_recall_memories({ tags: ["ui", "console", "design-system"] })`.
70
- 6. **Decide `surface_area` and `tags`.** Pick `surface_area` from the enum based on what the prototype shows. Pick 1–4 lowercase kebab-case `tags` covering the dominant patterns (e.g. `empty-state`, `dark-mode`, `keyboard-nav`).
71
- 7. **Write both files in the same commit.** HTML at `spex-console/public/design-previews/<slug>-v<N>[-<variant>].html`, sidecar at the matching `.meta.json` path. Single self-contained HTML file (inline CSS/JS).
72
- 8. **Validate the sidecar shape** against the schema before saving. Required: `title` + `status`. `status` MUST be `"draft"`. `tags` MUST match `^[a-z0-9-]+$`. `surface_area` MUST be in the enum. `linked_specs[]` items MUST match `^HS-[A-Z0-9]+-` (family keys contain digits, e.g. `HS-9HVY-CAP`). Fix and re-write if any fail.
73
- 9. **Confirm.** After writing, report the gallery URL (`/design-previews/<slug>-v<N>[-<variant>].html`). The console's UI-Design → Prototypes surface picks it up via `/api/ui-design/prototypes` and groups it into the matching lineage automatically.
74
-
75
- ## Anti-patterns — do not do these
76
-
77
- - Do **not** create a new `prototypes/` folder at the repo root.
78
- - Do **not** nest as `<slug>/index.html`.
79
- - Do **not** overwrite an existing `<slug>-v<N>[-<variant>].html` — bump or use a new variant.
80
- - Do **not** ship without a sibling sidecar.
81
- - Do **not** write `status: "accepted"` from this skill — promotion runs through the console's `/promote` route only.
82
- - Do **not** invent linked specs. Only reference `HS-*` IDs that exist in the vault.
83
- - Do **not** leave `surface_area` and `tags` empty on new sidecars — the console's filter rail depends on them.
84
- - Do **not** Read `spex-console/DESIGN.md` for token lookups; use `heyspex_design_get_token` / `heyspex_design_get_pattern` MCP tools.
85
-
86
- ## Reference
87
-
88
- - **Protocol (SSOT):** `specs/protocols/prototype-lifecycle-protocol.md` — fetch with `heyspex_get_procedure({ name: "prototype-lifecycle-protocol" })`
89
- - **Schema (SSOT):** `specs/schemas/prototype-meta.schema.json`
90
- - **Discovery route:** `spex-console/src/app/api/ui-design/prototypes/route.ts`
91
- - **Surface component:** `spex-console/src/components/surfaces/ui-design-surface.tsx`
92
- - **Lineage parser:** `spex-console/src/lib/prototype-lineage.ts`
93
- - **Folder:** `spex-console/public/design-previews/`
94
- - **Thorough sidecar example:** `shipped-surface-v1.meta.json`
95
- - **Minimal sidecar example:** `on-deck-v2.meta.json`
10
+ This skill is the **implementation** of `specs/protocols/prototype-lifecycle-protocol.md`. The protocol is the SSOT — when they conflict, the protocol wins and this skill is the bug. Fetch it with `heyspex_get_procedure({ name: "prototype-lifecycle-protocol" })` when you need the full rules.
11
+
12
+ It applies to:
13
+
14
+ - explicit `/prototype` invocation
15
+ - any natural-language "build me an HTML prototype / mock / preview / canvas" ask
16
+ - `/frontend-design` invocations in this repo (the plugin builds the artifact; this skill governs placement)
17
+
18
+ ## The contract — no exceptions
19
+
20
+ **Required output paths** (both files, same commit):
21
+
22
+ 1. `spex-console/public/design-previews/<slug>-v<N>[-<variant>].html` — the self-contained prototype.
23
+ 2. `spex-console/public/design-previews/<slug>-v<N>[-<variant>].meta.json` — the sidecar.
24
+
25
+ Anything outside this folder — including a stray top-level `prototypes/` directory — is **invisible** to the console. The route at `spex-console/src/app/api/ui-design/prototypes/route.ts` reads this folder flat (no recursion, no nested folders). A prototype that doesn't show up in the Prototypes surface does not exist for the user.
26
+
27
+ ## Naming
28
+
29
+ - **`<slug>`** (lineage slug) — kebab-case, describes the surface (`capture-canvas`, `shipped-surface`, `review-inbox`). May contain hyphens. **Match an existing lineage if you're iterating on a known surface** — grep `spex-console/public/design-previews/` before inventing a new slug.
30
+ - **`-v<N>`** — version, starts at `-v1`. **Bump rather than overwrite.** The console groups versions into a lineage with full history. If `--bump`, increment from the highest existing `-v<N>` for that slug.
31
+ - **`-<variant>`** (optional) — sibling variant within a version (e.g. `-v2-alt`, `-v2-minimal`, `-v2-terminal`). May contain hyphens. The console nests variants under their parent version and shows a `+N variants at vK` chip on the lineage card. Variants are for "A/B explorations of the same version", not new lineages.
32
+ - **No `index.html`, no nested folders, no dated filenames.** Just `<slug>-v<N>[-<variant>].html`.
33
+
34
+ ## meta.json schema
35
+
36
+ Validate against `specs/schemas/prototype-meta.schema.json`. Required: `title` + `status`. Always set `surface_area` and 1–4 `tags` on new sidecars (the console's filter rail depends on them — leaving them empty makes the prototype harder to find).
37
+
38
+ ```json
39
+ {
40
+ "title": "Human-readable name (e.g. 'Capture canvas v2')",
41
+ "description": "One-paragraph summary: what it demonstrates, key interactions, aesthetic direction, technical notes. The console hides this on the card and shows it in the drawer Notes tab — write for that context.",
42
+ "status": "draft",
43
+ "surface_area": "capture | on-deck | preloader | shell | review | roadmap | other",
44
+ "tags": ["kebab-case", "1-to-4"],
45
+ "updated_at": "2026-06-03T18:17:00.000Z",
46
+ "design_doc": "specs/ui/<slug>-design.md (optional but required for promotion to accepted)",
47
+ "linked_specs": [
48
+ "HS-XXXX-CAP-...",
49
+ "HS-XXXX-EPIC-..."
50
+ ],
51
+ "parent": "<slug>-v<N-1>.html (optional, when this iterates on a prior version)",
52
+ "embeds": ["other-prototype-slug (optional)"]
53
+ }
54
+ ```
55
+
56
+ - **`status` MUST be `"draft"` at create time.** Promotion to `"accepted"` runs through the console's `/api/ui-design/prototypes/<slug>/promote` route and requires both a linked `design_doc` AND a review entry under `specs/reviews/`. The skill does not write `accepted` — refuse if the user asks. (`"archived"` is for superseded versions; usually set later, not at create time.)
57
+ - **Compute `updated_at` as `new Date().toISOString()`** at write time.
58
+ - **`linked_specs`** accepts vault basenames (no `.md` extension) and `HS-*` IDs. Always include the capture/epic/task the prototype embodies. Pull from `--from-spec` if provided. Never invent IDs.
59
+ - Reference siblings in this folder for examples — `shipped-surface-v1.meta.json` (thorough) or `on-deck-v2.meta.json` (minimal).
60
+
61
+ ## Workflow
62
+
63
+ When this skill is invoked or matched:
64
+
65
+ 1. **Resolve lineage slug.** Match an existing slug if iterating on a known surface; otherwise pick a new kebab-case slug.
66
+ 2. **Resolve version.** Default `-v1`. If a file with the same slug already exists, default to bumping to the next integer; honour explicit `--bump`. **Never silently overwrite** — if the target file exists and `--bump` was not passed, surface the conflict and ask.
67
+ 3. **Resolve variant.** `--variant <name>` produces `<slug>-v<N>-<name>.html`. Without it, you produce the base variant.
68
+ 4. **Pull source spec context.** If `--from-spec HS-XXXX` is passed or the user references a spec, Read it first so the prototype reflects real content, not invented filler.
69
+ 5. **Aesthetic.** Defer to the user's brief (e.g. "Claude-in-PowerShell terminal aesthetic" overrides defaults). Otherwise honour console design-system tokens — fetch via `heyspex_design_*` MCP tools, do not grep `spex-console/DESIGN.md`. Recall UI memories first: `heyspex_recall_memories({ tags: ["ui", "console", "design-system"] })`.
70
+ 6. **Decide `surface_area` and `tags`.** Pick `surface_area` from the enum based on what the prototype shows. Pick 1–4 lowercase kebab-case `tags` covering the dominant patterns (e.g. `empty-state`, `dark-mode`, `keyboard-nav`).
71
+ 7. **Write both files in the same commit.** HTML at `spex-console/public/design-previews/<slug>-v<N>[-<variant>].html`, sidecar at the matching `.meta.json` path. Single self-contained HTML file (inline CSS/JS).
72
+ 8. **Validate the sidecar shape** against the schema before saving. Required: `title` + `status`. `status` MUST be `"draft"`. `tags` MUST match `^[a-z0-9-]+$`. `surface_area` MUST be in the enum. `linked_specs[]` items MUST match `^HS-[A-Z0-9]+-` (family keys contain digits, e.g. `HS-9HVY-CAP`). Fix and re-write if any fail.
73
+ 9. **Confirm.** After writing, report the gallery URL (`/design-previews/<slug>-v<N>[-<variant>].html`). The console's UI-Design → Prototypes surface picks it up via `/api/ui-design/prototypes` and groups it into the matching lineage automatically.
74
+
75
+ ## Anti-patterns — do not do these
76
+
77
+ - Do **not** create a new `prototypes/` folder at the repo root.
78
+ - Do **not** nest as `<slug>/index.html`.
79
+ - Do **not** overwrite an existing `<slug>-v<N>[-<variant>].html` — bump or use a new variant.
80
+ - Do **not** ship without a sibling sidecar.
81
+ - Do **not** write `status: "accepted"` from this skill — promotion runs through the console's `/promote` route only.
82
+ - Do **not** invent linked specs. Only reference `HS-*` IDs that exist in the vault.
83
+ - Do **not** leave `surface_area` and `tags` empty on new sidecars — the console's filter rail depends on them.
84
+ - Do **not** Read `spex-console/DESIGN.md` for token lookups; use `heyspex_design_get_token` / `heyspex_design_get_pattern` MCP tools.
85
+
86
+ ## Reference
87
+
88
+ - **Protocol (SSOT):** `specs/protocols/prototype-lifecycle-protocol.md` — fetch with `heyspex_get_procedure({ name: "prototype-lifecycle-protocol" })`
89
+ - **Schema (SSOT):** `specs/schemas/prototype-meta.schema.json`
90
+ - **Discovery route:** `spex-console/src/app/api/ui-design/prototypes/route.ts`
91
+ - **Surface component:** `spex-console/src/components/surfaces/ui-design-surface.tsx`
92
+ - **Lineage parser:** `spex-console/src/lib/prototype-lineage.ts`
93
+ - **Folder:** `spex-console/public/design-previews/`
94
+ - **Thorough sidecar example:** `shipped-surface-v1.meta.json`
95
+ - **Minimal sidecar example:** `on-deck-v2.meta.json`
@@ -32,7 +32,7 @@ The heyspex-app repository is not required and is not available to customers. Ev
32
32
  works from the published npm package `heyspex` (or a tarball your HeySpex contact hands you), which
33
33
  carries the plugin, the marketplace manifest, the hooks and the MCP server.
34
34
 
35
- - Node.js 20 or newer on PATH (`node --version`).
35
+ - Node.js 20–24 on PATH (`node --version`; the package requires `>=20 <25`).
36
36
  - GitHub Copilot CLI installed and signed in. Any one of: the GitHub Copilot app (its bundled
37
37
  `%LOCALAPPDATA%\github-copilot-sdk\cli\<version>\copilot.exe` is auto-detected, newest version
38
38
  wins, no PATH entry needed), `npm install -g @github/copilot`, or `winget install GitHub.Copilot`.
@@ -43,7 +43,7 @@ carries the plugin, the marketplace manifest, the hooks and the MCP server.
43
43
  ```bash
44
44
  npm install heyspex
45
45
  # or, from a tarball you were given:
46
- npm install ./heyspex-0.2.0.tgz
46
+ npm install ./heyspex-<version>.tgz
47
47
  ```
48
48
 
49
49
  - Sign the machine in to the HeySpex console so hooks and MCP tools can reach the vault:
@@ -52,6 +52,13 @@ npm install ./heyspex-0.2.0.tgz
52
52
  npx hs login
53
53
  ```
54
54
 
55
+ - For research (`/hs-res`) only: Docker Desktop running a self-hosted Firecrawl stack on this
56
+ machine (official steps: `SELF_HOST.md` in github.com/firecrawl/firecrawl: clone it, add a
57
+ `.env` with `PORT=3002` and `USE_DB_AUTHENTICATION=false`, then
58
+ `docker compose build && docker compose up -d`). No env var or API key: the packaged Firecrawl
59
+ CLI finds it through `docker ps` / localhost:3002. Check it with
60
+ `node node_modules/heyspex/dev-factory/spexcrawl/firecrawl-cli.mjs search "test" --json`.
61
+
55
62
  ## 2. Pick ONE: the plugin or the repo hooks (never both)
56
63
 
57
64
  Copilot reads hooks from an installed plugin and from `.github/hooks/` in the repo. With both,
@@ -42,6 +42,12 @@ name, which is unambiguous:
42
42
  npx --yes --package heyspex heyspex-mcp
43
43
  ```
44
44
 
45
+ **Research prerequisite (`/hs-res` only).** Docker Desktop running a self-hosted Firecrawl stack
46
+ on this machine (official steps: `SELF_HOST.md` in github.com/firecrawl/firecrawl: clone it, add a
47
+ `.env` with `PORT=3002` and `USE_DB_AUTHENTICATION=false`, then
48
+ `docker compose build && docker compose up -d`). No env var or API key: the packaged Firecrawl CLI
49
+ finds it through `docker ps` / localhost:3002.
50
+
45
51
  **What the agent kit injects at session start.** With the kit hooks installed (`hs install` /
46
52
  `hs connect`, or the plugin), the `inject-doctrine` SessionStart hook adds the **baseline
47
53
  edition of SpexCode Doctrine** to each session: a short list of general working principles