@skyf0xx/hedgehog 3.0.6 → 3.0.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.
package/README.md CHANGED
@@ -88,7 +88,7 @@ Artifact
88
88
 
89
89
  ### Anything else
90
90
 
91
- A CLI, a library, a browser extension, a data pipeline, etc. fitting neither shape gets its own build order, designed at intake rather than chosen from a menu.
91
+ A CLI, a library, a browser extension, a data pipeline, etc. fitting neither shape gets its own build order, designed at intake rather than chosen from a menu — starting from a [battle-tested blueprint](src/skills/hedgehog-core-design/blueprints) for the system's shape where one exists.
92
92
 
93
93
  Run `init` with no core flag: planning intake names the system shape, picks
94
94
  the stack, derives the layers, and locks them to `.hedgehog/core.yaml`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyf0xx/hedgehog",
3
- "version": "3.0.6",
3
+ "version": "3.0.7",
4
4
  "description": "Install the Hedgehog build discipline (agents + skills) into a repo, for Claude Code, Cursor, or Gemini CLI.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -61,7 +61,12 @@ the design work onto the person who came here to avoid doing it.
61
61
  Pick one default per system shape, the same way the shipped cores commit
62
62
  to one choice per row rather than a menu (`hedgehog-bootstrap`'s stack
63
63
  table). Substitute off a default only for a concrete, named constraint
64
- read from `.hedgehog/BMAD/` — never a general preference for variety:
64
+ read from `.hedgehog/BMAD/` — never a general preference for variety.
65
+ Prefer an opinionated framework over a bare library wherever the shape
66
+ has one (a web/CLI/RPC framework that fixes where things live, the way
67
+ NestJS does for `full-stack-app`) — an opinionated default is a guardrail
68
+ this discipline doesn't have to write down, and is worth more than the
69
+ popular thin alternative:
65
70
 
66
71
  | System shape | Default stack | Substitute when |
67
72
  |---|---|---|
@@ -72,7 +77,7 @@ read from `.hedgehog/BMAD/` — never a general preference for variety:
72
77
  | Desktop app | TypeScript + Electron, Vitest + Playwright, pnpm | native platform integration is a stated hard requirement (macOS/Windows-only, deep OS API use) → Swift/AppKit or C#/WinUI, per platform, named explicitly |
73
78
  | Compiler / language tool | Rust, `cargo test`, Cargo | the brief is explicitly about fast iteration over raw performance, or targets a JS/TS-only toolchain (a Babel/ESLint plugin) → TypeScript, Vitest, pnpm |
74
79
  | Bot / agent | TypeScript, Vitest, pnpm | the brief calls for heavy ML/data-science library use → Python, pytest, uv |
75
- | Game | TypeScript + a canvas/WebGL engine already named in the brief (e.g. PixiJS, Three.js), Vitest, pnpm | a native/console target is explicit → the engine's native language (C#/Unity, C++), named per that engine |
80
+ | Game | TypeScript + PixiJS (2D) or Three.js (3D), Vitest, pnpm — read the dimensionality off the brief; an engine the brief names outright wins over both | a native/console target is explicit → the engine the brief names, per that engine's own language (see the caveat below) |
76
81
  | Infra / deploy tool | Go, `go test`, Go modules | the tool is a thin wrapper generating config/manifests with no systems-level need → TypeScript, Vitest, pnpm |
77
82
 
78
83
  A shape not on this table is rare enough that no default has been
@@ -82,20 +87,72 @@ target, the language the brief's own examples or comparables are
82
87
  written in) and name the result as a judgment call, not a table lookup,
83
88
  in `core-design.md`'s rationale.
84
89
 
90
+ Where a substitution lands on a stack whose primary artifacts are binary
91
+ (engine scenes and prefabs, visual-editor projects, compiled design
92
+ files), say so at Confirm & Lock. Scope globs and `verify` commands still
93
+ hold on that stack's text sources, but a layer whose real output is a
94
+ binary file can't be diffed or meaningfully gated, so the enforcement is
95
+ partial in a way the text-source defaults aren't. That's a reason to
96
+ prefer a text-source stack where the brief leaves it open, and a fact the
97
+ user should have before confirming where it doesn't.
98
+
85
99
  Record the choice as one line — language, package manager, the named
86
- framework(s), test runner — before moving to Step 3; every layer's
87
- `scope` and `verify` in Step 3 draws from it.
100
+ framework(s), test runner — before moving to Step 3. Alongside it, record
101
+ a one-line decision for each of these concerns, whichever apply to the
102
+ shape (a browser extension has no DI story; a data pipeline has no
103
+ routing layer) — each is a place an authored core silently forks into
104
+ per-project convention if left unstated, the way `full-stack-app` never
105
+ has to think about because NestJS already decided:
106
+
107
+ - **Composition** — how one part of the system gets a dependency it
108
+ doesn't construct itself (a DI container, explicit constructor passing,
109
+ a module registry).
110
+ - **Error model** — how a failure crosses a layer boundary (typed
111
+ exceptions, a `Result`/`Either` return, error codes).
112
+ - **Config and secrets** — where runtime configuration is read from and
113
+ validated (env vars through a typed schema, a config file, flags).
114
+ - **Entrypoint layout** — what file the runtime starts from and how it
115
+ wires the layers together.
116
+
117
+ Every layer's `scope` and `verify` in Step 3 draws from this record.
88
118
 
89
119
  ## Step 3 — derive the layers
90
120
 
91
121
  Read `.hedgehog/BMAD/` for what the system actually does, then decide the
92
122
  layers it builds in. A layer earns its place by owning a distinct
93
123
  artifact that can be verified on its own. Order by dependency first (a
94
- layer that another layer imports comes first) and by risk second (where
95
- two layers are independent, build the one that would invalidate the other
96
- if it went wrong first).
97
-
98
- Three rules with teeth:
124
+ layer that another layer imports comes first), by contract second (a
125
+ layer that pins an external interface a schema, a wire format, a public
126
+ API surface — comes before the layers that build against it, the way
127
+ `full-stack-app` puts `schema` before `contract` before everything else),
128
+ and by risk third (where two layers are still tied, build the one that
129
+ would invalidate the other if it went wrong first).
130
+
131
+ Start from the blueprint for the chosen system shape — a starting
132
+ sequence, not a fixed one. Each blueprint names where it's safe to add,
133
+ merge, or drop a layer for the project at hand, and the one boundary that
134
+ has to hold whatever else changes; treat those adaptation points as
135
+ expected, not as exceptions. Record which blueprint was used and what
136
+ changed from it in `core-design.md`'s rationale (Step 6).
137
+
138
+ | System shape | Blueprint |
139
+ |---|---|
140
+ | CLI | [blueprints/cli.md](blueprints/cli.md) |
141
+ | Library / SDK | [blueprints/library-sdk.md](blueprints/library-sdk.md) |
142
+ | Data pipeline | [blueprints/data-pipeline.md](blueprints/data-pipeline.md) |
143
+ | Browser extension | [blueprints/browser-extension.md](blueprints/browser-extension.md) |
144
+ | Desktop app | [blueprints/desktop-app.md](blueprints/desktop-app.md) |
145
+ | Compiler / language tool | [blueprints/compiler-language-tool.md](blueprints/compiler-language-tool.md) |
146
+ | Bot / agent | [blueprints/bot-agent.md](blueprints/bot-agent.md) |
147
+ | Game | [blueprints/game.md](blueprints/game.md) |
148
+ | Infra / deploy tool | [blueprints/infra-deploy-tool.md](blueprints/infra-deploy-tool.md) |
149
+
150
+ A shape off this table gets no starting sequence — derive layers directly
151
+ from this step's rules and the BMAD brief, and name that in
152
+ `core-design.md` as a judgment call, the same as an off-table stack.
153
+
154
+ Three rules with teeth, on every blueprint and every derived sequence
155
+ alike:
99
156
 
100
157
  - **A layer with no executable verification is not a layer.** Fold it
101
158
  into its neighbour or drop it. `verify: manually inspect` is not a
@@ -178,6 +235,12 @@ if missed:
178
235
  belongs in `.hedgehog/core-design.md`.
179
236
  - **`depends_on` names one layer**, and the chain must be acyclic. The
180
237
  compiler walks it directly into `dependencies` rows.
238
+ - **`verify` must prove the layer's own claim, not just exit clean.** A
239
+ command that runs but asserts nothing (`tsc --noEmit` alone on a layer
240
+ whose job is behavior, a `test -s` on a file nothing checks the content
241
+ of) passes on an empty implementation. Pair typecheck/build commands
242
+ with a test command that exercises the layer's actual output whenever
243
+ the layer produces behavior, not just types.
181
244
 
182
245
  Verify the file loads before showing it back, by calling the loader
183
246
  directly:
@@ -196,12 +259,14 @@ forward.
196
259
 
197
260
  The rationale the engine doesn't read but the project needs: the system
198
261
  shape and why, the stack and why (the default it came from, or the named
199
- constraint that justified a substitution), the layers with a line each on
200
- what they own and why they sit where they do, the module-axis decision,
201
- and anything left unresolved. Written once, archival, never edited after
202
- the same stance `.hedgehog/BMAD/` takes. Later changes to the
203
- architecture are Correction Protocol entries in the commit log, not edits
204
- here.
262
+ constraint that justified a substitution), the composition/error/config/
263
+ entrypoint decisions from Step 2, the layer blueprint used and what
264
+ changed from it (or, off-table, that layers were derived directly and
265
+ why), the layers with a line each on what they own and why they sit where
266
+ they do, the module-axis decision, and anything left unresolved. Written
267
+ once, archival, never edited after — the same stance `.hedgehog/BMAD/`
268
+ takes. Later changes to the architecture are Correction Protocol entries
269
+ in the commit log, not edits here.
205
270
 
206
271
  ## Confirm & Lock
207
272
 
@@ -0,0 +1,35 @@
1
+ # Bot / agent blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ bot/agent system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ contract — the typed input/output shape of every capability, and the intent type policy decides over
10
+ tools — each capability's implementation, independently callable and testable with no model in the loop
11
+ policy — the decision logic: which tool a given input calls, knowing nothing about the delivery surface
12
+ transport — the platform integration (webhook, socket, polling loop) carrying input in and results back out
13
+ ```
14
+
15
+ ## Adaptation points
16
+
17
+ - Merge `transport` into `policy` when the agent runs as a single-process
18
+ script with no external trigger surface (a CLI-invoked agent, a batch
19
+ job) — there's no separate integration to isolate.
20
+ - Split `tools` per capability (`tools/{module}`) when the agent's
21
+ capabilities hit independent external systems with their own auth and
22
+ failure modes; keep one layer when they share a backend.
23
+ - Add a `memory` layer between `tools` and `policy`, depending on
24
+ `contract`, when the agent persists state across runs (conversation
25
+ history, a vector store) — keep it out of `policy` so the decision logic
26
+ stays testable against a fake memory.
27
+
28
+ ## Boundary that must hold
29
+
30
+ `policy` calls tools only through the types `contract` defines — never by
31
+ constructing a provider-specific call inline — and never imports
32
+ `transport`. This is what makes the decision logic testable without
33
+ standing up the real delivery surface or a live model: a policy layer
34
+ that reaches into a specific SDK can only be tested against that SDK, and
35
+ that is the layer whose behavior most needs cheap tests.
@@ -0,0 +1,26 @@
1
+ # Browser extension blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ browser extension system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ messaging — the typed message contract between background/content-script/popup
10
+ background — the service-worker-side logic (state, alarms, cross-tab coordination)
11
+ content — page-context logic (DOM reads/writes, page-side event listeners)
12
+ popup — the extension UI, consumes background/content only through messaging
13
+ ```
14
+
15
+ ## Adaptation points
16
+
17
+ - Drop `popup` entirely for an extension with no browser action UI.
18
+ - Merge `content` into `background` when the extension never injects into
19
+ page context (a pure background-worker extension).
20
+
21
+ ## Boundary that must hold
22
+
23
+ `popup` never imports from `background` or `content` directly — every
24
+ cross-context call goes through `messaging`, because a WebExtension's
25
+ contexts are separate JS runtimes and a direct import silently fails at
26
+ runtime rather than at build time.
@@ -0,0 +1,26 @@
1
+ # CLI blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the CLI
4
+ system shape. Adapt it for the project at hand — the adaptation points
5
+ below are expected, not exceptions — and record what changed in
6
+ `core-design.md`'s rationale.
7
+
8
+ ```
9
+ command — argument/flag parsing and dispatch only, one file per subcommand
10
+ domain — the logic the command triggers, no knowledge of argv or stdout
11
+ io-adapter — anything crossing a real boundary: filesystem, network, a wrapped subprocess
12
+ ```
13
+
14
+ ## Adaptation points
15
+
16
+ - Merge `io-adapter` into `domain` when the tool touches only the local
17
+ filesystem through the language's standard library — no separate
18
+ adapter earns its place.
19
+ - Add a `config` layer before `command` when the tool reads a
20
+ project-level config file in addition to flags.
21
+
22
+ ## Boundary that must hold
23
+
24
+ Never let `command` reach past `domain` into `io-adapter` directly — that
25
+ collapses the one boundary that makes `domain` testable without a real
26
+ filesystem or network.
@@ -0,0 +1,36 @@
1
+ # Compiler / language tool blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ compiler/language tool system shape. Adapt it for the project at hand —
5
+ the adaptation points below are expected, not exceptions — and record
6
+ what changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ ast — the node types, spans, and the diagnostic type every later layer reports through
10
+ lexer — source text to tokens
11
+ parser — tokens to ast, recovering from errors rather than aborting on the first one
12
+ analysis — name resolution, type checking, lints: ast in, diagnostics out
13
+ emit — the output artifact: generated code, a formatted document, a transformed ast
14
+ ```
15
+
16
+ ## Adaptation points
17
+
18
+ - Merge `lexer` into `parser` when the grammar is simple enough that the
19
+ tokenizer is a handful of functions (a config language, a template
20
+ syntax) — a separate layer buys nothing.
21
+ - Drop `emit` for a pure analysis tool (a linter, a type checker) whose
22
+ output is diagnostics rather than an artifact.
23
+ - Drop `analysis` for a pure syntactic tool (a formatter, a
24
+ syntax-highlighter grammar) that never resolves names or types.
25
+ - Add a `driver` layer after `emit` when the tool has a real CLI or
26
+ watch-mode surface — it owns argv, file discovery, and diagnostic
27
+ rendering, keeping the pipeline layers free of both.
28
+
29
+ ## Boundary that must hold
30
+
31
+ `ast` comes first and everything depends on it, because the node types
32
+ and the span/diagnostic representation are the contract every other layer
33
+ speaks. Layers report errors as diagnostics carrying spans — never by
34
+ printing, and never by aborting on the first failure. A tool that stops
35
+ at the first error can't be used in an editor, and retrofitting error
36
+ recovery after `parser` is written is a rewrite of `parser`.
@@ -0,0 +1,36 @@
1
+ # Data pipeline blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the data
4
+ pipeline system shape. Adapt it for the project at hand — the adaptation
5
+ points below are expected, not exceptions — and record what changed in
6
+ `core-design.md`'s rationale.
7
+
8
+ ```
9
+ schema — the typed shape of every record crossing a stage boundary, and the validation that enforces it
10
+ extract — pulling raw records from each source, with no reshaping beyond what the source forces
11
+ transform — the business logic: cleaning, joining, deriving, aggregating, all pure and source-agnostic
12
+ load — writing results to the destination, plus whatever idempotency/upsert key the destination needs
13
+ schedule — the orchestration wiring: what runs when, retries, backfill entry points
14
+ ```
15
+
16
+ ## Adaptation points
17
+
18
+ - Merge `schedule` into `load` when the pipeline is invoked externally
19
+ (cron calling a script, an orchestrator defined outside this repo) —
20
+ there's no orchestration surface here to build.
21
+ - Split `extract` per source (`extract/{module}`) when the pipeline pulls
22
+ from several genuinely different systems with independent failure modes
23
+ and auth; keep one `extract` layer for a single source.
24
+ - Merge `schema` into `extract` when there is one source and one
25
+ destination and the record shape is small enough to declare in a single
26
+ file — the types still exist and are still validated, they just don't
27
+ need a layer of their own.
28
+
29
+ ## Boundary that must hold
30
+
31
+ `transform` never reads from a source or writes to a destination — it
32
+ takes validated records in and returns records out. This is what lets the
33
+ business logic be tested on fixtures without network, credentials, or a
34
+ warehouse, and it's the boundary that decays first under deadline
35
+ pressure. A transform that "just needs one lookup" from the source is the
36
+ signal to widen `extract`'s output, not to reach across.
@@ -0,0 +1,34 @@
1
+ # Desktop app blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ desktop app system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ ipc — the typed contract between the privileged process and the UI process
10
+ main — privileged-process logic: filesystem, OS integration, windows, auto-update, native menus
11
+ domain — the app's own logic, running in whichever process owns it, with no window or IPC knowledge
12
+ renderer — the UI, reaching the privileged process only through ipc
13
+ ```
14
+
15
+ ## Adaptation points
16
+
17
+ - Merge `domain` into `main` for an app whose logic is mostly OS
18
+ orchestration (a launcher, a sync daemon with a thin window) — there's
19
+ no separable domain to isolate.
20
+ - Add a `persistence` layer between `domain` and `main`, depending on
21
+ `domain`, when the app owns a real local store (SQLite, a document
22
+ format) rather than plain preference files.
23
+ - On a native stack (Swift/AppKit, C#/WinUI) the `ipc` layer disappears —
24
+ there's one process. Keep `domain` separate from `renderer` regardless;
25
+ that boundary is what survives a platform's UI framework changing.
26
+
27
+ ## Boundary that must hold
28
+
29
+ `renderer` never touches the filesystem, spawns processes, or reads
30
+ secrets directly — every privileged operation crosses `ipc` to `main`.
31
+ This is a security boundary before it's an architectural one: a renderer
32
+ running remote or user-supplied content with direct privileged access is
33
+ the standard desktop-app vulnerability, and the layer split is what keeps
34
+ the privileged surface small enough to audit.
@@ -0,0 +1,35 @@
1
+ # Game blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the game
4
+ system shape. Adapt it for the project at hand — the adaptation points
5
+ below are expected, not exceptions — and record what changed in
6
+ `core-design.md`'s rationale.
7
+
8
+ ```
9
+ state — the world model and the rules that mutate it: pure, deterministic, no rendering or input
10
+ systems — the per-tick logic (movement, collision, ai, scoring) operating on state
11
+ input — device events to intents, so state never reads a keyboard or gamepad directly
12
+ render — drawing current state to the canvas/scene graph, reading state and never writing it
13
+ loop — the tick/frame driver wiring input, systems, and render together
14
+ ```
15
+
16
+ ## Adaptation points
17
+
18
+ - Merge `systems` into `state` for a game whose rules are small enough to
19
+ live with the model (a puzzle game, a turn-based prototype).
20
+ - Add an `assets` layer before `render`, depending on nothing, when the
21
+ game has a real content pipeline (sprite atlases, audio banks, level
22
+ data) rather than a handful of inline files.
23
+ - On an engine that owns the frame loop, `loop` disappears into the
24
+ engine — keep the other four, mapped onto the engine's own lifecycle
25
+ hooks, and scope them to the engine's text sources (scripts), since
26
+ scenes and prefabs are binary and can't be gated.
27
+
28
+ ## Boundary that must hold
29
+
30
+ `render` reads `state` and never writes it, and `state` never reads input
31
+ devices or draws. A deterministic state layer is what makes a game
32
+ testable at all — you can tick it through a scripted sequence of intents
33
+ and assert the outcome with no window open. It's also what makes replays,
34
+ save files, and any future networking possible; a game whose rules mutate
35
+ during rendering can never get those without a rewrite.
@@ -0,0 +1,34 @@
1
+ # Infra / deploy tool blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ infra/deploy tool system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ model — the typed desired-state the tool works against, parsed and validated from config
10
+ provider — the typed operations against each target system (cloud api, kubernetes, ssh), one per target
11
+ plan — diffing desired state against observed state into an ordered list of changes, pure and printable
12
+ apply — executing a plan through providers, with the failure/rollback behavior the tool promises
13
+ cli — argv, output rendering, and the confirmation gate in front of apply
14
+ ```
15
+
16
+ ## Adaptation points
17
+
18
+ - Merge `plan` into `apply` only for a tool that is genuinely fire-and-forget
19
+ (a one-shot bootstrap script) — and note that this gives up the dry-run
20
+ surface, which is the main reason to reach for this shape.
21
+ - Split `provider` per target (`provider/{module}`) when the tool spans
22
+ several systems with independent auth and failure modes; keep one layer
23
+ for a single target.
24
+ - Drop `model` as its own layer when desired state comes entirely from
25
+ flags rather than a config file.
26
+
27
+ ## Boundary that must hold
28
+
29
+ `plan` computes changes without performing any, and `apply` performs only
30
+ what a plan named. A tool that mutates during planning can't offer a
31
+ trustworthy dry run, and dry run is the safety property this shape exists
32
+ to provide — an infra tool without it is a script that edits production
33
+ with no preview. `plan` must be printable and diffable on its own, with
34
+ no credentials required beyond reading observed state.
@@ -0,0 +1,31 @@
1
+ # Library / SDK blueprint
2
+
3
+ A starting layer sequence for `hedgehog-core-design` Step 3 on the
4
+ library/SDK system shape. Adapt it for the project at hand — the
5
+ adaptation points below are expected, not exceptions — and record what
6
+ changed in `core-design.md`'s rationale.
7
+
8
+ ```
9
+ core — the implementation, importable and testable with no knowledge of how it's packaged
10
+ public — the exported surface: what `index.ts` re-exports, typed and versioned independently of internals
11
+ examples — runnable usage samples that exercise the public surface only, doubling as integration tests
12
+ ```
13
+
14
+ ## Adaptation points
15
+
16
+ - Drop `examples` as its own layer when the consuming ecosystem's
17
+ convention folds them into the test suite (pytest doctests, Rust
18
+ `examples/` compiled by `cargo test`) — fold its verify command into
19
+ `public`'s instead.
20
+ - Split `core` into per-domain sub-layers (`core/{module}`) only when the
21
+ library has genuinely independent domains a consumer might import
22
+ separately (a multi-package SDK) — a single-purpose library keeps one
23
+ `core` layer.
24
+
25
+ ## Boundary that must hold
26
+
27
+ `public` re-exports from `core`; nothing outside `public` is a supported
28
+ import path. A consumer reaching into `core` directly is the signal this
29
+ boundary was drawn in the wrong place, not a usage error to document
30
+ around — the layer sequence exists so `core` can change shape without
31
+ breaking every consumer, and an internal import defeats that.