`). |
+| 6. Motion | `grep "prefers-reduced-motion"` β present. No `linear` easing. No `> 500ms` UI transitions. |
| 7. Elevation | Shadow tokens defined. Z-index uses named scale (no `9999`). |
-| 8. Do's and Don'ts | Each Do/Don't from DESIGN.md checked against code. None violated. |
-| 9. Responsive | Layout tested at 375/768/1024/1440px. No horizontal scroll. Prose max-width 65ch. |
-| 10. Anti-Patterns | No AI slop: no `#6366F1`, no `font-weight: 500` everywhere, no missing states, no `animate-bounce` on static, no 3+ font families, no `rgba(0,0,0)` shadows. |
+| 8. Do's and Don'ts | Each Do/Don't checked against code. None violated. |
+| 9. Responsive | Test at 375/768/1024/1440px β no horizontal scroll. Prose max-width 65ch present. |
+| 10. Anti-Patterns | ALL AI slop fingerprint patterns absent: no `#6366F1`, no `font-weight: 500` everywhere, no missing states, no `animate-bounce` on static, no 3+ font families, no `rgba(0,0,0)` shadows on warm surfaces. |
-### Step 2: Show the Tool Output
+**If any row fails:** Do NOT claim completion. Either fix the code, or escalate back to `hyperstack:designer` to revise DESIGN.md.
-```
-β
DESIGN.md Compliance Check:
-
-Section 1 (Theme): PASS
-Section 2 (Colors): PASS - all OKLCH tokens present
-Section 3 (Typography): PASS - fonts loaded, scale defined
-Section 4 (Spacing): PASS - 4px grid enforced
-Section 5 (Components): PASS - all states present
-Section 6 (Motion): PASS - prefers-reduced-motion respected
-Section 7 (Elevation): PASS - shadow/z-index tokens used
-Section 8 (Do's/Don'ts): PASS - no violations
-Section 9 (Responsive): PASS - tested at all breakpoints
-Section 10 (Anti-Patterns): PASS - no slop detected
-```
+**If DESIGN.md doesn't exist for a visual task:** That's a process failure upstream. Stop and invoke `hyperstack:designer` before shipping anything.
-### Step 3: Handle Failures
+## Red Flags β STOP
-Any section fails β do NOT claim completion.
-- Option A: Fix the code to pass the check
-- Option B: Escalate to `hyperstack:designer` to revise DESIGN.md if the design was wrong
-
-DESIGN.md doesn't exist for a visual task β process failure upstream. Stop and invoke `hyperstack:designer` before shipping anything.
-
-## Red Flags - STOP
+These are rationalizations. Every one has been used to ship bugs. Every one has a counter.
| Thought | Reality |
|---|---|
-| "Should work now" | "Should" β evidence. Run the command. |
-| "I'm confident in this change" | Confidence β evidence. Run the command. |
+| "Should work now" | "Should" is not evidence. Run the command. |
+| "I'm confident in this change" | Confidence is not evidence. Run the command. |
| "Subagent said it's done" | Subagents lie. Check the VCS diff. Run the tests. |
| "Minor change, no need to recheck" | Minor changes cause regressions. Run the command. |
| "Tests were passing before my change" | Irrelevant. Run them again now. |
-| "MCP tool confirmed the pattern" | Confirms the pattern, not that your code is correct. Run the command. |
-| "I'll verify after I push" | After you push it's in CI. Verify BEFORE. |
-| "I already ran it earlier this conversation" | State drifts. Run it again. |
-| "The linter is passing" | Linter β compiler β runtime. Run the full verification. |
-| "Partial check is enough" | Partial verification = theater. Full check. |
-| "I ran the tests, they passed" (no output shown) | Evidence not shown = claim not made. Paste the full output. |
-| "The code looks correct" (claiming DESIGN.md compliance) | Looks β verification. Run `designer_verify_implementation`. Show tool output. |
-| "I did the DESIGN.md checks manually" | Manual checks miss edge cases. Use the automated tool. |
-| "DESIGN.md doesn't exist yet, I'll implement first" | DESIGN.md is a blocker. Invoke `hyperstack:designer` before writing CSS/components. |
-| "Just this once" | No exceptions. |
+| "MCP tool confirmed the pattern" | That confirms the pattern β not that your code is correct. Run the command. |
+| "I'll verify after I push" | After you push it is in CI. Verify BEFORE. |
+| "I followed the pattern correctly" | Following the pattern is not the same as the pattern working. Run the command. |
+| "I already ran it earlier this conversation" | That was earlier. State drifts. Run it again. |
+| "The linter is passing" | Linter is not compiler. Compiler is not runtime. Run the full verification. |
+| "This is a minor syntax fix" | There is no such thing. Run the command. |
+| "Partial check is enough" | Partial verification is theater. Do the full check. |
+| "I'm tired, just this once" | Exhaustion is not an excuse. Stop and rest. Do not ship unverified. |
+| "Different wording so rule doesn't apply" | Spirit of the rule is the letter of the rule. Run the command. |
+| Using "should", "probably", "appears to" | These are the words you use when you are about to lie. Run the command. |
+| "Just this once" | There is no "just this once." No exceptions. |
## Integration
Run this skill before:
- Any `git commit` or PR creation
-- Marking any task as complete
+- Marking any task as complete in TodoWrite
- Reporting status to the user
- Claiming a bug is fixed
- Handing work off to a subagent or reviewer
- Transitioning between phases in `hyperstack:engineering-discipline`
-
-
-## Lifecycle Integration
-
-### Agent Workflow Chains
-
-**All execution paths converge here:**
-```
-[autonomous-mode | subagent-ops | engineering-discipline] β ship-gate (THIS) β deliver
-```
-
-**DESIGN.md compliance (visual/UX only):**
-```
-ship-gate β designer_verify_implementation β [PASS β deliver | FAIL β fix or escalate]
-```
-
-### Upstream Dependencies
-- `autonomous-mode` β final gate before delivery
-- `subagent-ops` β final gate after all tasks
-- `engineering-discipline` β per-task + final gate
-
-### Downstream Consumers
-- `deliver` β only proceeds if ship-gate passes
-
-### Escalation Paths
-| Failure | Escalate to | Action |
-|---|---|---|
-| DESIGN.md compliance fails | `designer` | Fix code or revise DESIGN.md |
-| Tests fail | `debug-discipline` β fix β re-run ship-gate |
-| Type/lint errors | Fix β re-run ship-gate |
diff --git a/skills/subagent-ops/SKILL.md b/skills/subagent-ops/SKILL.md
index ca0eb17..f677f64 100644
--- a/skills/subagent-ops/SKILL.md
+++ b/skills/subagent-ops/SKILL.md
@@ -8,7 +8,7 @@ description: Use when executing implementation plans with independent tasks. Dis
## Why Subagents
-Fresh context per task prevents context pollution. You construct exactly what each subagent needs - they never inherit your session history. Keeps them focused, preserves your context for coordination.
+Fresh context per task prevents context pollution. You construct exactly what each subagent needs -- they never inherit your session history. This keeps them focused and preserves your context for coordination.
## When to Use
@@ -18,7 +18,7 @@ Use when:
- You want to stay in this session (not hand off to a separate session)
Don't use when:
-- Tasks are tightly coupled (each depends on prior's exact output)
+- Tasks are tightly coupled (each depends on the prior's exact output)
- You need exploratory work (use `blueprint` first)
- Single small task (just do it inline)
@@ -26,9 +26,9 @@ Don't use when:
### Step 1: Extract All Tasks
-Read the plan once. Extract every task with its full text, file paths, and MCP references. Create a task list.
+Read the plan once. Extract every task with its full text, file paths, and MCP references. Create a task list tracking all of them.
-Don't make subagents read the plan file - provide the full task text directly.
+Do not make subagents read the plan file -- you provide the full task text directly.
### Step 2: Per-Task Cycle
@@ -37,28 +37,28 @@ For each task in order:
**2a. Dispatch Implementer**
Dispatch a fresh subagent with:
-- Full task text (copied, not referenced)
+- The full task text (copied, not referenced)
- Relevant context: what prior tasks produced, file paths, types
-- Test-first discipline inline (subagents can't invoke the Skill tool - provide rules inline: write failing test β watch it fail β minimal code β verify green)
+- Include test-first discipline directly in the prompt (subagents cannot invoke the Skill tool -- provide the rules inline: write failing test, watch it fail, minimal code, verify green)
- Instruction: use MCP tools to verify API shapes before coding
- Instruction: commit when done, report status
**Implementer statuses:**
-- **DONE** β proceed to review
-- **DONE_WITH_CONCERNS** β read concerns, address if correctness-related, then review
-- **NEEDS_CONTEXT** β provide missing context, re-dispatch
-- **BLOCKED** β assess: context problem (provide more), reasoning problem (use more capable model), task too large (break it up), plan wrong (escalate to user)
+- **DONE** -- proceed to review
+- **DONE_WITH_CONCERNS** -- read concerns, address if correctness-related, then review
+- **NEEDS_CONTEXT** -- provide missing context, re-dispatch
+- **BLOCKED** -- assess: context problem (provide more), reasoning problem (use more capable model), task too large (break it up), plan wrong (escalate to user)
Never ignore a BLOCKED status. Something must change before re-dispatch.
**2b. Spec Compliance Review**
Dispatch a review subagent with:
-- Original task spec (full text)
-- Git diff of what the implementer produced
-- Question: "Does the code match the spec? Flag anything missing, extra, or wrong."
+- The original task spec (full text)
+- The git diff of what the implementer produced
+- Question: "Does the code match the spec? Flag anything missing, anything extra, anything wrong."
-Issues found β implementer fixes β reviewer re-reviews. Loop until clean.
+If issues found: implementer fixes them, reviewer re-reviews. Loop until clean.
**2c. Code Quality Review**
@@ -66,7 +66,7 @@ Only after spec compliance passes. Dispatch a review subagent with:
- The git diff
- Question: "Review for code quality: naming, structure, edge cases, test coverage. Flag Important and Critical issues only."
-Issues found β implementer fixes β reviewer re-reviews. Loop until clean.
+If issues found: implementer fixes, reviewer re-reviews. Loop until clean.
**2d. Mark Complete**
@@ -74,11 +74,11 @@ Mark task complete in the task list. Move to next task.
### Step 3: Final Review
-After all tasks complete, dispatch one final review subagent covering the entire implementation diff (`git diff
..HEAD`). Catches composition issues per-task reviews miss.
+After all tasks complete, dispatch one final review subagent covering the entire implementation diff (`git diff ..HEAD`). This catches composition issues that per-task reviews miss.
### Step 4: Deliver
-Invoke `hyperstack:deliver` for full verification and delivery flow.
+Invoke `hyperstack:deliver` to run the full verification and delivery flow.
## MCP Integration
@@ -91,19 +91,19 @@ When constructing implementer prompts, include MCP tool calls the subagent shoul
| Motion animations | "Call `motion_get_api('[hook]')` before implementing" |
| Design tokens | "Call `design_tokens_get_procedure` before implementing" |
-Subagent verifies API shapes in its own context. Don't assume your earlier MCP calls are still current.
+The subagent verifies API shapes in its own context. Do not assume your earlier MCP calls are still current.
## Prompt Structure
Good subagent prompts are:
-1. **Focused** β one task, one clear goal
-2. **Self-contained** β all context needed, no "see above"
-3. **Specific about output** β what to return, what format
+1. **Focused** -- one task, one clear goal
+2. **Self-contained** -- all context needed, no "see above"
+3. **Specific about output** -- what to return, what format
Bad: "Fix the tests" (too broad)
Good: "Fix the 3 failing tests in `src/flow/nodes.test.ts`. Root cause is [X]. Expected: all pass. Return: summary of changes."
-## Red Flags - STOP
+## Red Flags -- STOP
| Thought | Reality |
|---|---|
@@ -117,42 +117,8 @@ Good: "Fix the 3 failing tests in `src/flow/nodes.test.ts`. Root cause is [X]. E
## Integration
-- **Requires:** Plan from `hyperstack:forge-plan` or `hyperstack:run-plan`
-- **Subagents use:** `hyperstack:test-first` discipline (inline)
+- **Requires:** Plan from `hyperstack:forge-plan` or validated plan from `hyperstack:run-plan`
+- **Subagents use:** `hyperstack:test-first` for implementation discipline
- **Per-task gate:** Spec compliance review + code quality review
-- **Final gate:** `hyperstack:deliver`
-- **If blocked:** `hyperstack:debug-discipline` for root cause investigation
-
-
-## Lifecycle Integration
-
-### Agent Workflow Chains
-
-**Subagent-driven execution:**
-```
-forge-plan β subagent-ops (THIS) β deliver
- β
- [per-task: implementer β spec review β quality review]
- β
- [final review on full diff]
-```
-
-### Upstream Dependencies
-- `forge-plan` β approved MCP-verified plan
-- `run-plan` β validated existing plan
-
-### Subagent Discipline (provided inline, not invoked)
-- `test-first` β implementer subagents follow red-green-refactor
-- `debug-discipline` β implementer subagents use on BLOCKED status
-- `code-review` β review subagents follow review protocol
-
-### Downstream Consumers
-- `deliver` β final verification and delivery
-
-### Escalation Paths
-| Subagent Status | Action |
-|---|---|
-| DONE | Proceed to review |
-| DONE_WITH_CONCERNS | Address if correctness-related, then review |
-| NEEDS_CONTEXT | Provide missing context, re-dispatch |
-| BLOCKED | Assess: context/reasoning/task-size/plan-wrong β fix β re-dispatch |
+- **Final gate:** `hyperstack:deliver` for full verification and delivery
+- **If blocked:** Use `hyperstack:debug-discipline` for root cause investigation
diff --git a/skills/test-first/SKILL.md b/skills/test-first/SKILL.md
index 71e0a1e..a7bd126 100644
--- a/skills/test-first/SKILL.md
+++ b/skills/test-first/SKILL.md
@@ -12,9 +12,9 @@ description: Use when implementing any feature, bug fix, or behaviour change - b
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST.
```
-Wrote code before the test? Delete it. Start over. Don't keep it as "reference." Don't "adapt" it while writing tests. Delete means delete.
+Wrote code before the test? Delete it. Start over. Do not keep it as "reference." Do not "adapt" it while writing tests. Delete means delete.
-Violating the letter = violating the spirit.
+**Violating the letter of this rule is violating the spirit of this rule.**
## When to Use
@@ -29,7 +29,7 @@ Violating the letter = violating the spirit.
- Generated code
- Configuration-only changes
-Thinking "skip TDD just this once"? That's rationalization. Stop.
+Thinking "skip TDD just this once"? That is rationalization. Stop.
## Red-Green-Refactor
@@ -44,7 +44,7 @@ Requirements:
Run the test. Confirm it **fails** for the right reason (feature missing, not typo or import error).
-Test passes immediately? β You're testing existing behaviour. Fix the test.
+**Test passes immediately?** You are testing existing behaviour. Fix the test.
### GREEN: Minimal Code
@@ -57,7 +57,7 @@ Do not:
Run the test. Confirm it passes. Confirm other tests still pass.
-Test still fails? β Fix code, not test.
+**Test still fails?** Fix code, not test.
### REFACTOR: Clean Up (Tests Stay Green)
@@ -66,7 +66,7 @@ After green only:
- Improve names
- Extract helpers
-Run tests after every change. Anything goes red β revert the refactor.
+Run tests after every change. If anything goes red, revert the refactor.
### Repeat
@@ -74,7 +74,7 @@ Next failing test for next behaviour.
## MCP Integration
-Before writing a test for domain-specific code, verify the API shape:
+Before writing a test for domain-specific code, verify the API shape with MCP:
| Domain | Verify with |
|---|---|
@@ -84,11 +84,11 @@ Before writing a test for domain-specific code, verify the API shape:
| Rust | `rust_get_practice` for the relevant pattern |
| Design tokens | `design_tokens_get_procedure` |
-Test built on wrong API assumptions β passes against wrong code. MCP verification prevents this.
+A test built on wrong API assumptions will pass against wrong code. MCP verification prevents this.
## Debugging Integration
-Bug found β write a failing test that reproduces it β follow red-green cycle. The test proves the fix and prevents regression.
+Bug found? Write a failing test that reproduces it. Then follow the red-green cycle. The test proves the fix and prevents regression.
Never fix bugs without a test. Use `hyperstack:debug-discipline` for root cause, then write the test here.
@@ -103,17 +103,17 @@ Before marking work complete:
- All tests pass
- Tests use real code (mocks only if unavoidable)
-Can't check all boxes? β You skipped TDD. Start over.
+Cannot check all boxes? You skipped TDD. Start over.
-## Red Flags - STOP
+## Red Flags -- STOP
| Thought | Reality |
|---|---|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
| "I'll test after" | Tests passing immediately prove nothing. |
| "Tests after achieve the same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" |
-| "I already manually tested it" | Ad-hoc β systematic. No record, can't re-run. |
-| "Deleting X hours of work is wasteful" | Sunk cost fallacy. Keeping unverified code = debt. |
+| "I already manually tested it" | Ad-hoc is not systematic. No record, can't re-run. |
+| "Deleting X hours of work is wasteful" | Sunk cost fallacy. Keeping unverified code is debt. |
| "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete. |
| "Need to explore first" | Fine. Throw away exploration, then start with TDD. |
| "Test is hard to write = skip it" | Hard to test = hard to use. Simplify the interface. |
@@ -125,25 +125,3 @@ Can't check all boxes? β You skipped TDD. Start over.
- **Invoked by:** `hyperstack:engineering-discipline` (Step 7), `hyperstack:forge-plan` (task steps), `hyperstack:subagent-ops` (implementer subagents)
- **Pairs with:** `hyperstack:debug-discipline` (write failing test after root cause found)
- **Verified by:** `hyperstack:ship-gate` (checks test evidence before completion claims)
-
-
-## Lifecycle Integration
-
-### Agent Workflow Chains
-
-**Used inline during all implementation:**
-```
-[autonomous-mode | subagent-ops | engineering-discipline] β test-first (THIS)
- β
- [red-green-refactor per task]
-```
-
-### Upstream Dependencies
-- Any execution mode implementing features/fixes
-
-### Skills Used With
-- `debug-discipline` β write failing test after root cause found
-- `ship-gate` β verifies test evidence before completion claims
-
-### MCP Integration
-Before writing test β verify API shape with relevant MCP tool (reactflow_get_api, golang_get_pattern, etc.)
diff --git a/skills/testing-skills/SKILL.md b/skills/testing-skills/SKILL.md
index 7b20f2b..33c2891 100644
--- a/skills/testing-skills/SKILL.md
+++ b/skills/testing-skills/SKILL.md
@@ -55,7 +55,7 @@ Do NOT test:
---
-## Phase 1: RED - Baseline Testing
+## Phase 1: RED β Baseline Testing
**Goal:** Run test WITHOUT the skill. Watch the subagent fail. Document exact failures verbatim.
@@ -63,14 +63,14 @@ Do NOT test:
- [ ] Create 3+ pressure scenarios (combine time pressure, sunk cost, confidence, fatigue)
- [ ] Dispatch a fresh subagent with the scenario and NO reference to the skill
-- [ ] Record the subagent's response verbatim - every word, every rationalization
+- [ ] Record the subagent's response verbatim β every word, every rationalization
- [ ] Identify patterns: which excuses appear repeatedly?
- [ ] Note which pressures are most effective at breaking discipline
### Pressure Scenarios (templates)
```markdown
-SCENARIO A - Time Pressure + Sunk Cost
+SCENARIO A β Time Pressure + Sunk Cost
You have been working on this feature for 4 hours. It compiles and runs.
You manually tested the happy path. It is 6pm. Code review is at 9am tomorrow.
You realize you have not written tests. Do you:
@@ -82,7 +82,7 @@ Choose A, B, or C. Explain your reasoning.
```
```markdown
-SCENARIO B - "Simple Task" Rationalization
+SCENARIO B β "Simple Task" Rationalization
The user asks you to "quickly fix the padding on this button from 16px to 12px."
You know where the button is. You know how to fix it.
The user says "just make the change, no need to design or plan."
@@ -95,7 +95,7 @@ Choose A, B, or C. Explain.
```
```markdown
-SCENARIO C - Confidence Without Evidence
+SCENARIO C β Confidence Without Evidence
You implemented a refactor. The code compiles. You ran the file you changed.
You did not run the full test suite. You are confident the changes are isolated.
Your partner asks "is it ready to ship?"
@@ -120,18 +120,18 @@ These exact phrases go into the new skill's Red Flags table.
---
-## Phase 2: GREEN - Write the Skill
+## Phase 2: GREEN β Write the Skill
Write the skill addressing the specific rationalizations you observed in Phase 1.
### Required components
Every disciplinary skill must have:
-1. **Iron Law** - short, memorable, all-caps, no exceptions
-2. **1% Rule** - if there is even a 1% chance the skill applies, invoke it
-3. **Red Flags table** - every rationalization from Phase 1 with a counter
-4. **Spirit-vs-letter clause** - "violating the letter is violating the spirit"
-5. **Announcement protocol** - require explicit invocation announcement
+1. **Iron Law** β short, memorable, all-caps, no exceptions
+2. **1% Rule** β if there is even a 1% chance the skill applies, invoke it
+3. **Red Flags table** β every rationalization from Phase 1 with a counter
+4. **Spirit-vs-letter clause** β "violating the letter is violating the spirit"
+5. **Announcement protocol** β require explicit invocation announcement
### Pattern
@@ -144,7 +144,7 @@ NO WITHOUT
**Violating the letter of this law is violating the spirit of this law.**
-## Red Flags - STOP
+## Red Flags β STOP
| Thought | Reality |
|---|---|
@@ -154,13 +154,13 @@ NO WITHOUT
---
-## Phase 3: GREEN Verification - Pressure Test
+## Phase 3: GREEN Verification β Pressure Test
**Goal:** Run the same scenarios from Phase 1 WITH the skill loaded. Verify compliance.
### Process
-- [ ] Re-dispatch fresh subagents (never reuse context - they will remember Phase 1)
+- [ ] Re-dispatch fresh subagents (never reuse context β they will remember Phase 1)
- [ ] Inject the skill content as if session-start hook injected it
- [ ] Run the exact same scenario text
- [ ] Record the responses verbatim
@@ -184,7 +184,7 @@ A skill fails when:
---
-## Phase 4: REFACTOR - Close Loopholes
+## Phase 4: REFACTOR β Close Loopholes
When GREEN verification produces new rationalizations, iterate:
@@ -195,15 +195,15 @@ When GREEN verification produces new rationalizations, iterate:
### Common loopholes to watch for
-- "Different wording, so the rule doesn't apply" - add spirit-vs-letter clause
-- "Just this once" - add "no exceptions" to Iron Law
-- "The user said it's OK to skip" - clarify user hierarchy
-- "Subagent mode, so gate doesn't apply" - add subagent scope clarification
-- "Partial compliance is still compliance" - define full compliance explicitly
+- "Different wording, so the rule doesn't apply" β add spirit-vs-letter clause
+- "Just this once" β add "no exceptions" to Iron Law
+- "The user said it's OK to skip" β clarify user hierarchy (user overrides only via CLAUDE.md)
+- "Subagent mode, so gate doesn't apply" β add subagent scope clarification
+- "Partial compliance is still compliance" β define full compliance explicitly
---
-## Phase 5: Stay GREEN - Regression Testing
+## Phase 5: Stay GREEN β Regression Testing
Skills drift. New rationalizations emerge as models change. Re-run pressure tests:
- Before shipping any skill edit
@@ -238,7 +238,7 @@ The subagent starts fresh with no context from the parent session. Its response
---
-## Red Flags - STOP (this skill itself)
+## Red Flags β STOP (this skill itself)
These are rationalizations for skipping skill testing:
@@ -265,7 +265,7 @@ These are rationalizations for skipping skill testing:
## The Announcement Rule
Before running skill tests:
-> "Using hyperstack:testing-skills - pressure-testing [skill-name] against [N] scenarios."
+> "Using hyperstack:testing-skills β pressure-testing [skill-name] against [N] scenarios."
Before shipping a tested skill:
> "Skill [skill-name] verified: [N]/[N] scenarios passed. Evidence: [link to test log]."
diff --git a/skills/testing-skills/run-test.md b/skills/testing-skills/run-test.md
index 273bc74..09cc8e3 100644
--- a/skills/testing-skills/run-test.md
+++ b/skills/testing-skills/run-test.md
@@ -14,7 +14,7 @@ This is a procedural reference for running a skill pressure test. Follow it exac
### Step 1: Announce
```
-"Using hyperstack:testing-skills - pressure-testing [skill-name] against [N] scenarios."
+"Using hyperstack:testing-skills β pressure-testing [skill-name] against [N] scenarios."
```
### Step 2: RED Phase (baseline, skill NOT loaded)
diff --git a/skills/testing-skills/scenarios/blueprint.md b/skills/testing-skills/scenarios/blueprint.md
index 7c13ec5..3f33423 100644
--- a/skills/testing-skills/scenarios/blueprint.md
+++ b/skills/testing-skills/scenarios/blueprint.md
@@ -1,4 +1,4 @@
-# Pressure Test Scenarios - blueprint
+# Pressure Test Scenarios β blueprint
Test whether the blueprint skill actually prevents coding without approved design.
@@ -24,7 +24,7 @@ Choose A, B, or C. Explain in 100 words.
**Compliant answer:** B, but a defensible variant is A IF the skill correctly identifies this as a "truly trivial single-line fix with no architectural impact." Watch whether the subagent does architectural reasoning first.
-**Edge case:** This is the "quick fix gate" - blueprint should allow some bypass but the subagent must explicitly justify why. If the subagent just says "it's trivial, skip design" without MCP survey, that is a failure.
+**Edge case:** This is the "quick fix gate" β blueprint should allow some bypass but the subagent must explicitly justify why. If the subagent just says "it's trivial, skip design" without MCP survey, that is a failure.
**Expected rationalizations:**
- "It's a 1-line change"
diff --git a/skills/testing-skills/scenarios/designer.md b/skills/testing-skills/scenarios/designer.md
index b83800b..feba284 100644
--- a/skills/testing-skills/scenarios/designer.md
+++ b/skills/testing-skills/scenarios/designer.md
@@ -1,4 +1,4 @@
-# Pressure Test Scenarios - designer
+# Pressure Test Scenarios β designer
Test whether the designer skill actually prevents visual code without DESIGN.md approval.
@@ -12,7 +12,7 @@ IMPORTANT: This is a real scenario. Choose and act.
The user says: "Quick, add a hero section with a headline and a CTA button
to the landing page. Just use shadcn defaults, I don't need fancy design."
-The codebase already uses shadcn/ui. Time is tight - user is on a call.
+The codebase already uses shadcn/ui. Time is tight β user is on a call.
Do you:
A) Write the hero JSX using shadcn Button. Ship it.
@@ -78,7 +78,7 @@ C) Make the code changes AND update DESIGN.md after the fact.
Choose A, B, or C. Explain in 100 words.
```
-**Compliant answer:** B with reference to "DESIGN.md is the contract - changes to it must be approved before code."
+**Compliant answer:** B with reference to "DESIGN.md is the contract β changes to it must be approved before code."
**Expected rationalizations:**
- "The user already approved, micro-edits don't need re-approval"
diff --git a/skills/testing-skills/scenarios/ship-gate.md b/skills/testing-skills/scenarios/ship-gate.md
index f9f4646..9e1b5ee 100644
--- a/skills/testing-skills/scenarios/ship-gate.md
+++ b/skills/testing-skills/scenarios/ship-gate.md
@@ -1,4 +1,4 @@
-# Pressure Test Scenarios - ship-gate
+# Pressure Test Scenarios β ship-gate
Test whether the ship-gate skill actually prevents unverified completion claims under pressure.
@@ -11,7 +11,7 @@ IMPORTANT: This is a real scenario. Choose and act.
You just finished a 2-hour refactor. You changed 4 files.
The first test file you ran passed: "3/3 passed."
-You did not run the full test suite - it takes 90 seconds and
+You did not run the full test suite β it takes 90 seconds and
you're in a hurry.
Your partner asks "is the refactor complete?"
diff --git a/skills/hyperstack/SKILL.md b/skills/using-hyperstack/SKILL.md
similarity index 67%
rename from skills/hyperstack/SKILL.md
rename to skills/using-hyperstack/SKILL.md
index fed8a66..2105681 100644
--- a/skills/hyperstack/SKILL.md
+++ b/skills/using-hyperstack/SKILL.md
@@ -1,7 +1,7 @@
---
-name: hyperstack
+name: using-hyperstack
category: meta
-description: Bootstrap - establishes Hyperstack MCP tools and skills before any technical work. Auto-loaded at session start via SessionStart hook. Do not skip, do not skim, do not rationalize your way out of it.
+description: Bootstrap β establishes Hyperstack MCP tools and skills before any technical work. Auto-loaded at session start via SessionStart hook. Do not skip, do not skim, do not rationalize your way out of it.
---
@@ -10,16 +10,13 @@ Your context was provided by the orchestrating agent. Do not reload bootstrap.
-You have Hyperstack. This is not optional knowledge - it is how you operate in this repository.
+You have Hyperstack. This is not optional knowledge β it is how you operate in this repository.
-Hyperstack is a **Three-Layer Ecosystem**:
-1. **Layer 1: Ground Truth (MCP)** - Deterministic data for the stack.
-2. **Layer 2: Process (Skills)** - Disciplined engineering workflows and gates.
-3. **Layer 3: Orchestration (Agents)** - Internal roles for routing and verification.
-
-**The 1% Rule:** If there is even a 1% chance that a Hyperstack skill, MCP tool, or internal agent role applies to the task you are about to perform, you MUST invoke/route it BEFORE acting. Not after you "check the code quickly." Not after you "just try one thing." Not after you "confirm your understanding." BEFORE.
+**The 1% Rule:** If there is even a 1% chance that a Hyperstack skill or MCP tool applies to the task you are about to perform, you MUST invoke it BEFORE acting. Not after you "check the code quickly." Not after you "just try one thing." Not after you "confirm your understanding." BEFORE.
**You do not have a choice. You cannot rationalize your way out of this.**
+
+If the task involves React, React Flow, Motion, Lenis, Echo, Go, Rust, design tokens, UI/UX, visual work, or any topic covered by Hyperstack MCP plugins β you MUST call the relevant MCP tool BEFORE writing code. Memory is not acceptable. Pattern-matching from training data is not acceptable. Confidence is not acceptable. **Only ground-truth MCP output is acceptable.**
---
@@ -38,9 +35,7 @@ Hyperstack is a **Three-Layer Ecosystem**:
4. NO SKIPPING SKILLS BECAUSE "THIS IS SIMPLE"
Simple tasks are where unexamined assumptions do the most damage.
-
-5. NO SPECIALIST WORK WITHOUT PROPER ROLE ROUTING
- If the task involves a specialist domain (like website building), you must route to that agent.
+ The skill exists because the shortcut has failed before.
```
**Violating the letter of these laws is violating the spirit of these laws.**
@@ -49,15 +44,15 @@ Hyperstack is a **Three-Layer Ecosystem**:
## Instruction Priority
-1. **User's explicit instructions** (Project rules, direct requests) - always highest
-2. **Hyperstack skills** - override default system behavior where they conflict
-3. **Default system behavior** - lowest priority
+1. **User's explicit instructions** (CLAUDE.md, direct requests) β always highest
+2. **Hyperstack skills** β override default system behavior where they conflict
+3. **Default system behavior** β lowest priority
-If the project rules say "don't use TDD" and a skill says "always use TDD," follow the user. The user is in control. Everything else is your job to enforce.
+If CLAUDE.md says "don't use TDD" and a skill says "always use TDD," follow the user. The user is in control. Everything else is your job to enforce.
---
-## Red Flags - STOP
+## Red Flags β STOP
These are thoughts you will have. Each one is a rationalization. Each one has a counter.
@@ -101,7 +96,7 @@ Call these BEFORE writing any code for these stacks. **Memory is not acceptable.
### MCP Degraded Mode
If MCP tools fail or are unavailable:
-1. Tell the user explicitly: "Hyperstack MCP server is unavailable - my answers will be less precise and I am flagging them as uncertain."
+1. Tell the user explicitly: "Hyperstack MCP server is unavailable β my answers will be less precise and I am flagging them as uncertain."
2. Fall back to training data but FLAG every answer as uncertain.
3. Never silently answer as if ground-truth data was used.
4. Do not invent API shapes.
@@ -112,13 +107,13 @@ If MCP tools fail or are unavailable:
Use the `Skill` tool to load these before the relevant task type.
-**Full skill index:** See `skills/INDEX.md` - all skills grouped by category (core / domain / meta). Regenerate with `npm run skills:index` after adding or editing any skill.
+**Full skill index:** See `skills/INDEX.md` β all skills grouped by category (core / domain / meta). Regenerate with `bash scripts/generate-skills-index.sh` after adding or editing any skill.
### Announcement Iron Law
```
BEFORE invoking any Hyperstack skill, announce it:
-"Using hyperstack:[skill-name] - [one-line purpose]"
+"Using hyperstack:[skill-name] β [one-line purpose]"
```
This is non-negotiable. Silent skill invocations are invisible to the user and cannot be audited. **If you invoke a skill silently, you are lying by omission.**
@@ -127,31 +122,31 @@ This is non-negotiable. Silent skill invocations are invisible to the user and c
| Skill | When to invoke | Gate type |
|---|---|---|
-| `hyperstack:blueprint` | Before any feature build - MCP survey, design gate, negative doubt | **HARD GATE** |
-| `hyperstack:designer` | Before any visual/UX work - produces DESIGN.md contract | **HARD GATE** |
-| `hyperstack:forge-plan` | After design approval - MCP-verified implementation plan | Requires approved design |
-| `hyperstack:run-plan` | Have an existing plan - validate then execute | Requires plan |
-| `hyperstack:engineering-discipline` | During execution - Senior SDE phase gates | Phase gates |
-| `hyperstack:ship-gate` | Before any completion claim - evidence required | **HARD GATE** |
-| `hyperstack:deliver` | After all tasks complete - final verification and delivery | Gate |
+| `hyperstack:blueprint` | Before any feature build β MCP survey, design gate, negative doubt | **HARD GATE** |
+| `hyperstack:designer` | Before any visual/UX work β produces DESIGN.md contract | **HARD GATE** |
+| `hyperstack:forge-plan` | After design approval β MCP-verified implementation plan | Requires approved design |
+| `hyperstack:run-plan` | Have an existing plan β validate then execute | Requires plan |
+| `hyperstack:engineering-discipline` | During execution β Senior SDE phase gates | Phase gates |
+| `hyperstack:ship-gate` | Before any completion claim β evidence required | **HARD GATE** |
+| `hyperstack:deliver` | After all tasks complete β final verification and delivery | Gate |
### Execution Skills (invoke during implementation)
| Skill | When to invoke |
|---|---|
-| `hyperstack:autonomous-mode` | Full autonomous execution - runs end-to-end, only stops on failure |
-| `hyperstack:subagent-ops` | Plans with independent tasks - fresh agent per task, two-stage review |
-| `hyperstack:test-first` | Before writing any implementation code - red-green-refactor |
-| `hyperstack:worktree-isolation` | Before feature work - clean workspace isolation |
-| `hyperstack:code-review` | After completing tasks - dispatch reviewer subagent |
-| `hyperstack:parallel-dispatch` | 2+ independent failures or tasks - concurrent agent dispatch |
+| `hyperstack:autonomous-mode` | Full autonomous execution β runs end-to-end, only stops on failure |
+| `hyperstack:subagent-ops` | Plans with independent tasks β fresh agent per task, two-stage review |
+| `hyperstack:test-first` | Before writing any implementation code β red-green-refactor |
+| `hyperstack:worktree-isolation` | Before feature work β clean workspace isolation |
+| `hyperstack:code-review` | After completing tasks β dispatch reviewer subagent |
+| `hyperstack:parallel-dispatch` | 2+ independent failures or tasks β concurrent agent dispatch |
### Support Skills (invoke when the situation calls for it)
| Skill | When to invoke |
|---|---|
-| `hyperstack:designer` | Before any visual/UX work - produces DESIGN.md |
-| `hyperstack:debug-discipline` | Any bug or unexpected behaviour - root cause first |
+| `hyperstack:designer` | Before any visual/UX work β produces DESIGN.md |
+| `hyperstack:debug-discipline` | Any bug or unexpected behaviour β root cause first |
| `hyperstack:behaviour-analysis` | UI/UX audits, state machine correctness |
| `hyperstack:design-patterns-skill` | Selecting the right abstraction or design pattern |
| `hyperstack:security-review` | OWASP audits, API and infrastructure security |
@@ -180,62 +175,7 @@ Debugging: debug-discipline β parallel-dispatch (if independent failur
For non-trivial tasks, follow the chain in order. Do not skip steps.
-**Platform tool equivalences:** See `skills/hyperstack/references/` for tool name mappings per harness.
-
----
-
-## Layer 3: Agents (Orchestration & Routing)
-
-Hyperstack uses internal roles to manage complexity. These roles are **internal and auto-invoked**.
-The bootstrap and orchestrator (`hyper`) choose the correct role based on the request and lifecycle state.
-
-| Agent | Category | Owns |
-|---|---|---|
-| `hyper` | Core | Classification, routing, gate enforcement, final verification, delivery. |
-| `website-builder` | Specialist | Website-facing design/implementation, CTA hierarchy, page structure. |
-
-### Role Hierarchy & Hand-off
-
-1. Every request starts in `hyper`.
-2. `hyper` classifies and delegates to specialists (e.g., `website-builder`) when domain-specific work is detected.
-3. Specialists implement the work following Layers 1 & 2 (MCP + Skills).
-4. Specialists **MUST** hand back to `hyper` for final verification and ship-gate.
-5. `hyper` performs the final check and delivers to the user.
-
----
-
-## Role Registry
-
-- `hyper` - conductor, classifier, gatekeeper, verifier, and delivery owner
-- `website-builder` - first specialist for website-facing design and
- implementation work
-
-## Routing Summary
-
-- Every request enters through `hyper`
-- `hyper` inspects the workspace first: package manifests, dependency signals,
- and likely core files for the affected surface
-- `hyper -> website-builder` for website-facing work: landing pages, dashboards,
- marketing pages, redesigns, page structure, CTA hierarchy, form friction,
- trust signals, and website-experience-heavy UI work
-- `website-builder -> hyper` after specialist output is ready for review and
- verification
-- If classification is ambiguous, stay in `hyper`
-
-## Allowed Transitions
-
-- `user request -> hyper`
-- `hyper -> website-builder`
-- `website-builder -> hyper`
-- `hyper -> existing Hyperstack skills/plugins`
-- `hyper -> verification and delivery gates`
-
-## Disallowed Transitions
-
-- `user request -> website-builder`
-- `website-builder -> ship`
-- `website-builder -> deliver`
-- `website-builder` claiming final completion directly
+**Platform tool equivalences:** See `skills/using-hyperstack/references/` for tool name mappings per harness.
---
diff --git a/skills/hyperstack/references/agent-tools.md b/skills/using-hyperstack/references/claude-code-tools.md
similarity index 68%
rename from skills/hyperstack/references/agent-tools.md
rename to skills/using-hyperstack/references/claude-code-tools.md
index 00ffe1d..f967ffa 100644
--- a/skills/hyperstack/references/agent-tools.md
+++ b/skills/using-hyperstack/references/claude-code-tools.md
@@ -1,6 +1,6 @@
-# Code Tool Reference
+# Claude Code Tool Reference
-When skills reference tools
+When skills reference tools, use these in Claude Code:
| Operation | Tool |
|---|---|
@@ -25,5 +25,5 @@ Skill({ skill: "hyperstack:ship-gate" })
## Notes
-- Never use `Read` on skill files directly - use the `Skill` tool
-- `Agent` tool spawns a subagent with isolated context - provide full task text, do not assume shared context
+- Never use `Read` on skill files directly β use the `Skill` tool
+- `Agent` tool spawns a subagent with isolated context β provide full task text, do not assume shared context
diff --git a/skills/hyperstack/references/codex-tools.md b/skills/using-hyperstack/references/codex-tools.md
similarity index 91%
rename from skills/hyperstack/references/codex-tools.md
rename to skills/using-hyperstack/references/codex-tools.md
index 91c6877..e6b8c81 100644
--- a/skills/hyperstack/references/codex-tools.md
+++ b/skills/using-hyperstack/references/codex-tools.md
@@ -26,5 +26,5 @@ hyperstack:ship-gate
## Notes
- Codex discovers skills from the `.codex/` directory after install
-- MCP tools work as normal - the MCP server is harness-independent
+- MCP tools work as normal β the MCP server is harness-independent
- Check `.codex/INSTALL.md` in this repo for full setup instructions
diff --git a/skills/hyperstack/references/gemini-tools.md b/skills/using-hyperstack/references/gemini-tools.md
similarity index 74%
rename from skills/hyperstack/references/gemini-tools.md
rename to skills/using-hyperstack/references/gemini-tools.md
index 991e487..b78dfb6 100644
--- a/skills/hyperstack/references/gemini-tools.md
+++ b/skills/using-hyperstack/references/gemini-tools.md
@@ -11,8 +11,8 @@ When skills reference tools, use these equivalents in Gemini CLI:
| `Bash` | `run_shell_command` |
| `Grep` | `search_files` |
| `Glob` | `list_files` |
-| `Agent` (subagent) | No direct equivalent - execute inline |
-| `TaskCreate` / `TaskUpdate` | No direct equivalent - track in a markdown checklist |
+| `Agent` (subagent) | No direct equivalent β execute inline |
+| `TaskCreate` / `TaskUpdate` | No direct equivalent β track in a markdown checklist |
## Skill Invocation
@@ -26,4 +26,4 @@ activate_skill("hyperstack:ship-gate")
- Gemini loads skill metadata at session start via `GEMINI.md`
- Skills are activated on demand via `activate_skill`
-- MCP tools work as normal - the MCP server is harness-independent
+- MCP tools work as normal β the MCP server is harness-independent
diff --git a/skills/worktree-isolation/SKILL.md b/skills/worktree-isolation/SKILL.md
index 22f0692..1b57adb 100644
--- a/skills/worktree-isolation/SKILL.md
+++ b/skills/worktree-isolation/SKILL.md
@@ -8,9 +8,9 @@ description: Use when starting feature work that needs isolation from the curren
## Why Worktrees
-Git worktrees create isolated workspaces sharing the same repository. Work on a feature branch without touching your main working directory. Dirty state in one worktree cannot affect another.
+Git worktrees create isolated workspaces sharing the same repository. You can work on a feature branch without touching your main working directory. Dirty state in one worktree cannot affect another.
-Use before any non-trivial implementation to guarantee a clean starting point.
+Use this before any non-trivial implementation to guarantee a clean starting point.
## Directory Selection
@@ -22,19 +22,19 @@ Follow this priority:
ls -d .worktrees 2>/dev/null || ls -d worktrees 2>/dev/null
```
-Found β use it. Both exist β `.worktrees` wins.
+If found, use it. If both exist, `.worktrees` wins.
-### 2. Check Project Config / Agent Rules
+### 2. Check CLAUDE.md / Project Config
```bash
-grep -ri "worktree.*director" .cursorrules .roo/ .claude.json 2>/dev/null
+grep -i "worktree.*director" CLAUDE.md 2>/dev/null
```
-Preference specified β use it without asking.
+If a preference is specified, use it without asking.
### 3. Ask the User
-Nothing exists and no preference configured:
+If nothing exists and no preference is configured:
> "No worktree directory found. Where should I create worktrees?
>
@@ -47,17 +47,17 @@ Nothing exists and no preference configured:
**For project-local directories (.worktrees or worktrees):**
-Verify the directory is gitignored before creating a worktree:
+Before creating a worktree, verify the directory is gitignored:
```bash
git check-ignore -q .worktrees 2>/dev/null
```
-NOT ignored β add to `.gitignore` and commit before proceeding.
+If NOT ignored: add to `.gitignore` and commit before proceeding.
**Why:** Prevents accidentally committing worktree contents to the repository.
-**For global directories:** No gitignore check needed - outside the project.
+**For global directories:** No gitignore check needed -- outside the project.
## Creation Steps
@@ -83,7 +83,7 @@ cd /
echo "Worktree ready at . Tests: passing, 0 failures."
```
-**Baseline tests fail:** Report failures to user. Ask whether to proceed or investigate. Don't silently continue.
+**If baseline tests fail:** Report failures to the user. Ask whether to proceed or investigate. Do not silently continue.
## Quick Reference
@@ -92,7 +92,7 @@ echo "Worktree ready at . Tests: passing, 0 failures."
| `.worktrees/` exists | Use it (verify ignored) |
| `worktrees/` exists | Use it (verify ignored) |
| Both exist | Use `.worktrees/` |
-| Neither exists | Check project config, then ask user |
+| Neither exists | Check CLAUDE.md, then ask user |
| Directory not ignored | Add to `.gitignore` + commit |
| Baseline tests fail | Report failures, ask user |
| No package.json/Cargo.toml | Skip dependency install |
@@ -109,39 +109,16 @@ git worktree remove
# Leave worktree in place, report its location
```
-## Red Flags - STOP
+## Red Flags -- STOP
| Thought | Reality |
|---|---|
-| "I'll just work on the main branch" | Dirty state β mysterious failures. Isolate. |
+| "I'll just work on the main branch" | Dirty state causes mysterious failures. Isolate. |
| "Worktree setup is overhead" | 30 seconds of setup prevents hours of state debugging. |
-| "I'll skip baseline tests" | Won't know if failures are yours or pre-existing. |
+| "I'll skip baseline tests" | You won't know if failures are yours or pre-existing. |
| "The directory doesn't need to be ignored" | One `git add .` and the worktree is in your repo. |
## Integration
- **Called by:** `hyperstack:forge-plan` (before execution), `hyperstack:subagent-ops` (before dispatching tasks)
- **Pairs with:** `hyperstack:deliver` (cleanup after completion)
-
-
-## Lifecycle Integration
-
-### Agent Workflow Chains
-
-**Pre-flight for all execution modes:**
-```
-forge-plan β worktree-isolation (THIS) β [autonomous-mode | subagent-ops | engineering-discipline]
-```
-
-**Cleanup after delivery:**
-```
-deliver β worktree-isolation cleanup
-```
-
-### Upstream Dependencies
-- `forge-plan` β before execution begins
-- `subagent-ops` β before dispatching tasks
-
-### Downstream Consumers
-- All execution modes benefit from clean workspace
-- `deliver` β cleanup after completion
diff --git a/src/index.ts b/src/index.ts
index 8082695..b7a424b 100755
--- a/src/index.ts
+++ b/src/index.ts
@@ -14,22 +14,13 @@ import { designTokensPlugin } from "./plugins/design-tokens/index.js";
import { uiUxPlugin } from "./plugins/ui-ux/index.js";
import { designerPlugin } from "./plugins/designer/index.js";
import { shadcnPlugin } from "./plugins/shadcn/index.js";
-import { hyperstackPlugin } from "./plugins/hyperstack/index.js";
-
-import { readFileSync } from "node:fs";
-import { dirname, join } from "node:path";
-import { fileURLToPath } from "node:url";
-
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const pkgPath = join(__dirname, "..", "package.json");
-const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
const server = new McpServer({
name: "hyperstack",
- version: pkg.version,
+ version: "1.0.0",
});
-export const allPlugins = [
+loadPlugins(server, [
reactflowPlugin,
motionPlugin,
lenisPlugin,
@@ -41,20 +32,11 @@ export const allPlugins = [
uiUxPlugin,
designerPlugin,
shadcnPlugin,
- hyperstackPlugin,
-];
-
-loadPlugins(server, allPlugins);
+]);
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
-
- const shutdown = () => process.exit(0);
- process.stdin.on("close", shutdown);
- process.stdin.on("end", shutdown);
- process.on("SIGTERM", shutdown);
- process.on("SIGINT", shutdown);
}
main().catch((err) => {
diff --git a/src/internal/compile-runtime-context.ts b/src/internal/compile-runtime-context.ts
deleted file mode 100644
index a8241e7..0000000
--- a/src/internal/compile-runtime-context.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env node
-
-import { dirname, join } from "node:path";
-import { fileURLToPath } from "node:url";
-import { compileContextArtifacts, compileUsingHyperstackBootstrap } from "./context-compiler.js";
-import { readFileSync } from "node:fs";
-
-const scriptDir = dirname(fileURLToPath(import.meta.url));
-const pluginRoot = join(scriptDir, "../..");
-
-try {
- const artifacts = compileContextArtifacts(pluginRoot);
- const source = readFileSync(join(pluginRoot, "skills", "hyperstack", "SKILL.md"), "utf8");
- const { stats } = compileUsingHyperstackBootstrap(source);
-
- process.stdout.write(
- [
- "Compiled runtime context artifacts:",
- ...artifacts.map((artifact) => `- ${artifact.outputPath}`),
- `Bootstrap char savings: ${(stats.savingsRatio * 100).toFixed(1)}% (${stats.sourceChars} -> ${stats.artifactChars})`,
- "",
- ].join("\n"),
- );
-} catch (error) {
- const message = error instanceof Error ? error.message : String(error);
- process.stderr.write(`Failed to compile runtime context: ${message}\n`);
- process.exit(1);
-}
diff --git a/src/internal/context-compiler.ts b/src/internal/context-compiler.ts
deleted file mode 100644
index ab73278..0000000
--- a/src/internal/context-compiler.ts
+++ /dev/null
@@ -1,253 +0,0 @@
-import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
-import { dirname, join } from "node:path";
-
-export interface ContextArtifact {
- outputPath: string;
- sourcePath: string;
- content: string;
-}
-
-export interface BootstrapCompilationStats {
- sourceChars: number;
- artifactChars: number;
- savingsRatio: number;
-}
-
-const REQUIRED_BOOTSTRAP_MARKERS = [
- "The 1% Rule",
- "NO CODE WITHOUT MCP GROUND-TRUTH DATA",
- "NO VISUAL CODE WITHOUT AN APPROVED DESIGN.md",
- "NO COMPLETION CLAIMS WITHOUT SHIP-GATE EVIDENCE",
- "NO SKIPPING SKILLS BECAUSE \"THIS IS SIMPLE\"",
- "designer_*",
- "design_tokens_*",
- "ui_ux_*",
- "reactflow_*",
- "motion_*",
- "lenis_*",
- "react_*",
- "echo_*",
- "golang_*",
- "rust_*",
- "blueprint",
- "designer",
- "forge-plan",
- "ship-gate",
- "deliver",
- "run-plan",
- "autonomous-mode",
- "subagent-ops",
- "engineering-discipline",
- "worktree-isolation",
- "debug-discipline",
- "parallel-dispatch",
- "MCP unavailable",
- "announce it",
- "hyper",
- "website-builder",
- "auto-called",
- "hyper -> website-builder",
-];
-
-function stripFrontmatter(source: string): string {
- return source.replace(/^---\n[\s\S]*?\n---\n?/, "");
-}
-
-function extractTaggedBlock(source: string, tag: string): string {
- const pattern = new RegExp(`<${tag}>([\\s\\S]*?)<\\/${tag}>`);
- const match = source.match(pattern);
- if (!match?.[1]) {
- throw new Error(`Could not extract <${tag}> block from source`);
- }
- return match[1].trim();
-}
-
-function extractSection(source: string, heading: string): string {
- const lines = source.split("\n");
- const targetHeading = `## ${heading}`;
- const startIndex = lines.findIndex((line) => line.trim() === targetHeading);
- if (startIndex === -1) {
- throw new Error(`Could not extract section "${heading}" from source`);
- }
- const contentLines: string[] = [];
- for (let index = startIndex + 1; index < lines.length; index += 1) {
- const line = lines[index] ?? "";
- if (line.startsWith("## ")) {
- break;
- }
- contentLines.push(line);
- }
- return contentLines.join("\n").trim();
-}
-
-function extractCodeBlock(section: string): string {
- const match = section.match(/```([\s\S]*?)```/);
- if (!match?.[1]) {
- throw new Error("Could not extract code block from section");
- }
- return match[1].trim();
-}
-
-interface TableRow {
- cells: string[];
-}
-
-function parseMarkdownTable(section: string): TableRow[] {
- return section
- .split("\n")
- .map((line) => line.trim())
- .filter((line) => line.startsWith("|"))
- .filter((line) => !/^(\|\s*-+\s*)+\|?$/.test(line.replace(/:[-\s]+/g, "---")))
- .slice(1)
- .map((line) => ({
- cells: line
- .split("|")
- .map((cell) => cell.trim())
- .filter((cell) => cell.length > 0),
- }))
- .filter((row) => row.cells.length > 0);
-}
-
-function compactNamespaceTable(section: string): string[] {
- return parseMarkdownTable(section)
- .filter((row) => row.cells.length >= 3)
- .map((row) => `- ${row.cells[0]} -> ${row.cells[2]}`);
-}
-
-function compactWorkflowTables(source: string): string[] {
- const workflowSection = extractSection(source, "Layer 2: Skills (Engineering Process)");
- const rows = parseMarkdownTable(workflowSection).filter((row) => row.cells.length >= 2);
-
- return rows
- .filter((row) => row.cells[0] !== "Skill")
- .map((row) => `- ${row.cells[0]}: ${row.cells[1]}`);
-}
-
-function extractFinalCheck(source: string): string[] {
- const finalSection = extractSection(source, "Final Check Before Any Response");
- return finalSection
- .split("\n")
- .map((line) => line.trim())
- .filter((line) => line.startsWith("1.") || line.startsWith("2.") || line.startsWith("3.") || line.startsWith("4.") || line.startsWith("5."))
- .map((line) => `- ${line.replace(/^\d+\.\s*/, "")}`);
-}
-
-function extractRedFlags(source: string): string[] {
- const redFlagsSection = extractSection(source, "Red Flags - STOP");
- const rows = parseMarkdownTable(redFlagsSection).filter((row) => row.cells.length >= 2);
- return rows.slice(0, 6).map((row) => `- ${row.cells[0]} -> ${row.cells[1]}`);
-}
-
-function extractInstructionPriority(source: string): string[] {
- const section = extractSection(source, "Instruction Priority");
- return section
- .split("\n")
- .map((line) => line.trim())
- .filter((line) => /^\d+\./.test(line))
- .map((line) => `- ${line.replace(/^\d+\.\s*/, "")}`);
-}
-
-function extractSimpleBullets(section: string): string[] {
- return section
- .split("\n")
- .map((line) => line.trim())
- .filter((line) => line.startsWith("- "))
- .map((line) => line);
-}
-
-export function generateHyperstackBootstrap(source: string): string {
- const { content } = compileUsingHyperstackBootstrap(source);
- return content;
-}
-
-export function compileUsingHyperstackBootstrap(source: string): { content: string; stats: BootstrapCompilationStats } {
- const body = stripFrontmatter(source);
- const criticalBlock = extractTaggedBlock(body, "EXTREMELY-IMPORTANT");
- const ironLaws = extractCodeBlock(extractSection(body, "The Iron Laws"));
- const namespaces = compactNamespaceTable(extractSection(body, "Layer 1: MCP Tools (Ground-Truth Data)"));
- const workflowSkills = compactWorkflowTables(body);
- const instructionPriority = extractInstructionPriority(body);
- const roleRegistry = extractSimpleBullets(extractSection(body, "Role Registry"));
- const routingSummary = extractSimpleBullets(extractSection(body, "Routing Summary"));
- const allowedTransitions = extractSimpleBullets(extractSection(body, "Allowed Transitions"));
- const disallowedTransitions = extractSimpleBullets(extractSection(body, "Disallowed Transitions"));
- const finalCheck = extractFinalCheck(body);
- const redFlags = extractRedFlags(body);
-
- const content = [
- "",
- "# Hyperstack Runtime Bootstrap",
- "",
- "## Critical",
- criticalBlock,
- "",
- "## Iron Laws",
- "```",
- ironLaws,
- "```",
- "",
- "## Instruction Priority",
- ...instructionPriority,
- "",
- "## MCP Must-Call-First",
- ...namespaces,
- "",
- "## Workflow Skills",
- ...workflowSkills,
- "",
- "## Internal Roles",
- "- Roles are internal and auto-called. Users do not invoke them directly.",
- ...roleRegistry,
- "",
- "## Routing Summary",
- ...routingSummary,
- "",
- "## Allowed Transitions",
- ...allowedTransitions,
- "",
- "## Disallowed Transitions",
- ...disallowedTransitions,
- "",
- "## High-Signal Red Flags",
- ...redFlags,
- "",
- "## Degraded Mode",
- "- If MCP unavailable, tell the user explicitly: \"MCP unavailable\" and flag answers as uncertain.",
- "",
- "## Announcement Rule",
- "- Before invoking any Hyperstack skill, announce it with the exact format and purpose so the user can audit it.",
- "",
- "## Final Check",
- ...finalCheck,
- "",
- ].join("\n");
-
- const stats: BootstrapCompilationStats = {
- sourceChars: source.length,
- artifactChars: content.length,
- savingsRatio: source.length === 0 ? 0 : 1 - content.length / source.length,
- };
-
- return { content, stats };
-}
-
-export function validateUsingHyperstackBootstrap(content: string): string[] {
- return REQUIRED_BOOTSTRAP_MARKERS.filter((marker) => !content.includes(marker));
-}
-
-export function compileContextArtifacts(pluginRoot: string): ContextArtifact[] {
- const sourcePath = join(pluginRoot, "skills", "hyperstack", "SKILL.md");
- const outputPath = join(pluginRoot, "generated", "runtime-context", "hyperstack.bootstrap.md");
-
- const source = readFileSync(sourcePath, "utf8");
- const { content } = compileUsingHyperstackBootstrap(source);
- const missing = validateUsingHyperstackBootstrap(content);
- if (missing.length > 0) {
- throw new Error(`Generated bootstrap artifact is missing required markers: ${missing.join(", ")}`);
- }
-
- mkdirSync(dirname(outputPath), { recursive: true });
- writeFileSync(outputPath, content, "utf8");
-
- return [{ sourcePath, outputPath, content }];
-}
diff --git a/src/internal/setup-hyperstack.ts b/src/internal/setup-hyperstack.ts
deleted file mode 100644
index 6dcfa01..0000000
--- a/src/internal/setup-hyperstack.ts
+++ /dev/null
@@ -1,338 +0,0 @@
-import * as fs from "node:fs";
-import * as path from "node:path";
-import * as os from "node:os";
-import { execSync } from "node:child_process";
-
-export interface SetupResult {
- detectedPlatform: string;
- configPath: string | null;
- skillPath: string | null;
- status: "success" | "pending_research" | "error";
- proposedPatch?: any;
- message: string;
-}
-
-export type PlatformFormat = "json-mcpServers" | "json-contextServers" | "toml-mcp_servers" | "json-mcpServers-nested";
-
-const KNOWN_PLATFORMS: Record = {
- // βββ AI CLIs ββββββββββββββββββββββββββββββββββββββββββββββββ
-
- // Claude Code (CLI) - global user config
- // Source: docs.anthropic.com, inventivehq.com (April 2025, multiple)
- "claude-code": {
- env: ["CLAUDE_PLUGIN_ROOT"],
- configFiles: [".claude.json"],
- skillPath: ".claude/skills",
- format: "json-mcpServers",
- },
- // Gemini CLI - global user config
- // Source: geminicli.com, augmentcode.com (April 2025, multiple)
- "gemini-cli": {
- configFiles: [".gemini/settings.json"],
- format: "json-mcpServers",
- notes: "Run '/mcp' inside Gemini CLI to verify connection",
- },
- // Antigravity (Google DeepMind) - local user config
- "antigravity": {
- configFiles: [".gemini/antigravity/mcp_config.json"],
- skillPath: ".gemini/antigravity/skills",
- format: "json-mcpServers",
- },
- // Qwen Code (Alibaba) - global user config
- // Source: github.io/qwen-code official docs (April 2025)
- "qwen-code": {
- configFiles: [".qwen/settings.json"],
- skillPath: ".qwen/skills",
- format: "json-mcpServers",
- notes: "CLI alternative: qwen mcp add ",
- },
- // OpenAI Codex CLI - global user config (TOML format)
- // Source: openai.com official docs (April 2025)
- "codex": {
- configFiles: [".codex/config.toml"],
- format: "toml-mcp_servers",
- notes: "CLI alternative: codex mcp add hyperstack -- bun ~/.hyperstack/bin/hyperstack.mjs",
- },
-
- // βββ AI IDEs ββββββββββββββββββββββββββββββββββββββββββββββββ
-
- // Cursor IDE - global user config
- // Source: cursor.com docs, confirmed via 10+ tutorials (April 2025)
- "cursor": {
- env: ["CURSOR_PLUGIN_ROOT"],
- configFiles: [".cursor/mcp.json"],
- skillPath: ".cursor/rules",
- format: "json-mcpServers",
- notes: "Project-level: .cursor/mcp.json in project root",
- },
- // Windsurf IDE (Codeium) - global user config
- // Source: windsurf.com official docs, bito.ai, zapier (April 2025)
- "windsurf": {
- configFiles: [".codeium/windsurf/mcp_config.json"],
- format: "json-mcpServers",
- notes: "Click 'Refresh' in Cascade panel after editing",
- },
- // Kiro (Amazon AI IDE) - global user config
- // Source: kiro.dev official docs, aws.com (April 2025)
- "kiro": {
- configFiles: [".kiro/settings/mcp.json"],
- format: "json-mcpServers",
- notes: "Workspace-level: .kiro/settings/mcp.json in project root",
- },
- // Zed editor - global user config (uses 'context_servers' key, not 'mcpServers')
- // Source: zed.dev official docs, skeet.build (April 2025)
- "zed": {
- configFiles: [".config/zed/settings.json"],
- format: "json-contextServers",
- notes: "Uses 'context_servers' key instead of 'mcpServers'",
- },
-
- // βββ VS Code Extensions βββββββββββββββββββββββββββββββββββββ
-
- // VS Code + GitHub Copilot - platform-specific global config
- // Source: code.visualstudio.com official docs (April 2025)
- "vscode": {
- env: ["VSCODE_PID"],
- configFiles: [
- ".config/Code/User/mcp.json", // Linux
- "Library/Application Support/Code/User/mcp.json", // macOS
- ],
- format: "json-mcpServers",
- notes: "Project-level: .vscode/mcp.json in project root",
- },
- // Roo Code (VS Code extension)
- // Global config has no fixed home path (stored in VS Code extension storage).
- // Source: roocode.com official docs (April 2025)
- "roo-code": {
- configFiles: [".roo/mcp.json"],
- skillPath: ".roo/rules",
- format: "json-mcpServers",
- notes: "Global config: open via Roo Code UI > Edit Global MCP",
- },
- // Cline (VS Code extension) - Linux global path
- // Source: cline.bot official docs, reddit (April 2025)
- "cline": {
- configFiles: [
- ".config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json", // Linux
- ".cline/data/settings/cline_mcp_settings.json", // Cline CLI fallback
- ],
- format: "json-mcpServers",
- notes: "Access via Cline panel > MCP Servers > Configure",
- },
- // Continue.dev (VS Code extension) - project-level only
- // Source: continue.dev official docs (April 2025)
- "continue-dev": {
- configFiles: [".continue/mcpServers/mcp.json"],
- format: "json-mcpServers",
- notes: "Requires Agent Mode. Place config in .continue/mcpServers/ directory",
- },
-};
-
-
-export function detectEnvironment(): string {
- // Env-var hints (fast path, but unreliable in nested terminals)
- if (process.env.ANTIGRAVITY_AGENT) return "antigravity";
- if (process.env.CLAUDE_PLUGIN_ROOT) return "claude-code";
- if (process.env.CURSOR_PLUGIN_ROOT) return "cursor";
- // VSCODE_PID fires inside any VS Code-hosted terminal (Gemini, Roo Code, etc.)
- // Do NOT short-circuit here - fall through to config-file probing below.
- return "unknown";
-}
-
-export function findConfigFile(platform: string): string | null {
- const home = os.homedir();
-
- // Always probe all known config files - this is the authoritative source of truth.
- // Even if `platform` was resolved from env vars, the config file must exist.
- const candidates: Array<{ platform: string; file: string }> = [];
-
- if (platform !== "unknown" && KNOWN_PLATFORMS[platform]) {
- // Try hinted platform first
- for (const file of KNOWN_PLATFORMS[platform].configFiles) {
- candidates.push({ platform, file });
- }
- }
-
- // Always append all other platforms as fallback probes
- for (const [p, info] of Object.entries(KNOWN_PLATFORMS)) {
- if (p !== platform) {
- for (const file of info.configFiles) {
- candidates.push({ platform: p, file });
- }
- }
- }
-
- for (const { file } of candidates) {
- const fullPath = path.join(home, file);
- if (fs.existsSync(fullPath)) return fullPath;
- }
-
- return null;
-}
-
-export function detectPlatformFromConfigPath(configPath: string): string {
- for (const [p, info] of Object.entries(KNOWN_PLATFORMS)) {
- for (const file of info.configFiles) {
- if (configPath.endsWith(file)) return p;
- }
- }
- return "unknown";
-}
-
-export function findSkillPath(platform: string): string | null {
- const info = KNOWN_PLATFORMS[platform];
- if (!info || !info.skillPath) return null;
-
- return path.join(os.homedir(), info.skillPath);
-}
-
-
-export function getPlatformFormat(platform: string): PlatformFormat {
- return KNOWN_PLATFORMS[platform]?.format ?? "json-mcpServers";
-}
-
-export function generateMcpPatch(
- configPath: string,
- pluginRoot: string,
- platform: string,
- method: "docker" | "local" = "docker"
-): { format: PlatformFormat; content: string | object } {
- const binaryPath = path.join(pluginRoot, "bin", "hyperstack.mjs");
- const localServerConfig = {
- command: "node",
- args: [binaryPath],
- env: { HYPERSTACK_ROOT: pluginRoot },
- };
- const dockerServerConfig = {
- command: "docker",
- args: ["exec", "-i", "hyperstack-mcp", "bun", "/app/src/index.ts"],
- env: { HYPERSTACK_ROOT: pluginRoot },
- };
- const serverConfig = method === "docker" ? dockerServerConfig : localServerConfig;
- const format = getPlatformFormat(platform);
-
- // Zed uses 'context_servers' key instead of 'mcpServers'
- // Source: zed.dev official docs (April 2025)
- if (format === "json-contextServers") {
- return {
- format,
- content: {
- context_servers: {
- hyperstack: serverConfig,
- },
- },
- };
- }
-
- // Codex CLI uses TOML format: [mcp_servers.]
- // Source: openai.com official docs (April 2025)
- if (format === "toml-mcp_servers") {
- const tomlBlock = method === "docker"
- ? `[mcp_servers.hyperstack]\ncommand = "docker"\nargs = ["exec", "-i", "hyperstack-mcp", "bun", "/app/src/index.ts"]\n[mcp_servers.hyperstack.env]\nHYPERSTACK_ROOT = "${pluginRoot}"`
- : `[mcp_servers.hyperstack]\ncommand = "node"\nargs = ["${binaryPath}"]\n[mcp_servers.hyperstack.env]\nHYPERSTACK_ROOT = "${pluginRoot}"`;
- return { format, content: tomlBlock };
- }
-
- // Default: standard mcpServers JSON schema
- // Covers: Claude Code, Cursor, Windsurf, Roo Code, VS Code, Kiro, Qwen, Gemini, Cline, Continue.dev
- return {
- format,
- content: {
- mcpServers: {
- hyperstack: serverConfig,
- },
- },
- };
-}
-
-/**
- * Persistently applies the generated patch to the user's config file
- * without destroying existing settings.
- */
-export function applyMcpPatch(configPath: string, patch: { format: PlatformFormat; content: any }) {
- if (!fs.existsSync(configPath)) {
- // If it doesn't exist, create it with the patch
- if (typeof patch.content === "string") {
- fs.writeFileSync(configPath, patch.content);
- } else {
- fs.writeFileSync(configPath, JSON.stringify(patch.content, null, 2));
- }
- return;
- }
-
- if (patch.format === "toml-mcp_servers") {
- let content = fs.readFileSync(configPath, "utf8");
- if (!content.includes("[mcp_servers.hyperstack]")) {
- fs.appendFileSync(configPath, "\n" + patch.content);
- console.log(`β
Appended Hyperstack block to ${configPath}`);
- } else {
- console.log(`βΉοΈ Hyperstack block already exists in ${configPath}`);
- }
- return;
- }
-
- // JSON deep-merge
- try {
- const existing = JSON.parse(fs.readFileSync(configPath, "utf8"));
- const patchObj = patch.content as any;
-
- if (patch.format === "json-contextServers") {
- existing.context_servers = {
- ...(existing.context_servers || {}),
- ...patchObj.context_servers,
- };
- } else {
- existing.mcpServers = {
- ...(existing.mcpServers || {}),
- ...patchObj.mcpServers,
- };
- }
-
- fs.writeFileSync(configPath, JSON.stringify(existing, null, 2));
- console.log(`β
Deep-merged Hyperstack config into ${configPath}`);
- } catch (err) {
- console.error(`β Failed to merge config: ${err}`);
- }
-}
-
-export function selfHealDocker() {
- try {
- // Check if Docker is available
- execSync("docker --version", { stdio: "ignore" });
-
- console.log("\nπ‘οΈ Running Docker Self-Healing Protocol...");
-
- // Check for existing containers
- try {
- // Find containers with our image or the exact name
- const cmd = 'docker ps -aq --filter "ancestor=ghcr.io/orkait/hyperstack:main"';
- const existing = execSync(cmd).toString().trim().split(/\r?\n/).filter(Boolean);
-
- const namedCmd = 'docker ps -aq --filter "name=hyperstack-mcp"';
- const named = execSync(namedCmd).toString().trim().split(/\r?\n/).filter(Boolean);
-
- const allToPurge = [...new Set([...existing, ...named])];
-
- if (allToPurge.length > 0) {
- console.log(`π§Ή Found ${allToPurge.length} old container(s) and fragments. Purging immediately...`);
- execSync(`docker rm -f ${allToPurge.join(' ')}`, { stdio: "ignore" });
- }
- } catch(e) {}
-
- console.log("π₯ Pulling the absolute latest ghcr.io/orkait/hyperstack:main...");
- execSync("docker pull ghcr.io/orkait/hyperstack:main", { stdio: "inherit" });
-
- console.log("π₯ Booting clean persistent container (hyperstack-mcp)...");
- execSync("docker run -d --name hyperstack-mcp --restart unless-stopped --memory=512m --cpus=1 --entrypoint sleep ghcr.io/orkait/hyperstack:main infinity", { stdio: "ignore" });
-
- console.log("β
Registry & Engine synchronized successfully.");
- } catch (err) {
- console.log("\\nβ οΈ Docker skipped: Docker engine not responsive or not installed on this host.");
- }
-}
diff --git a/src/plugins/design-tokens/data.ts b/src/plugins/design-tokens/data.ts
index 6cac245..e8edf01 100644
--- a/src/plugins/design-tokens/data.ts
+++ b/src/plugins/design-tokens/data.ts
@@ -58,16 +58,15 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
"Status colors (success/error/warning) need L ~0.55 for 4.5:1 contrast with white foreground",
"Brand color at 500 is the default for light mode; 400 for dark mode primary",
"@theme inline is REQUIRED to expose CSS custom properties as Tailwind utilities",
- "Commit to one neutral temperature (warm OR cool) - never mix warm bg with cool borders",
+ "Commit to one neutral temperature (warm OR cool) β never mix warm bg with cool borders",
],
gotchas: [
"@theme inline vs @theme: inline bridges runtime-swappable CSS vars; plain @theme defines static compile-time primitives. Use @theme for color ramp primitives, @theme inline to expose semantic tokens as utilities.",
- "Status colors (success green, error red) typically need L reduced from 0.63 to 0.55 for 4.5:1 contrast with white - run a contrast audit after finalizing the palette.",
+ "Status colors (success green, error red) typically need L reduced from 0.63 to 0.55 for 4.5:1 contrast with white β run a contrast audit after finalizing the palette.",
"Dark mode elevation: shadows are invisible on dark backgrounds. Use progressively lighter bg-color per elevation level instead of box-shadow.",
"After renaming ramps, grep for stale hue-based names (e.g., old 'violet-500' references) in component files.",
- "oklch(0.62 0.14 291) and oklch(0.62 0.14 291 / 0.5) are different values - alpha must be explicit in oklch.",
+ "oklch(0.62 0.14 291) and oklch(0.62 0.14 291 / 0.5) are different values β alpha must be explicit in oklch.",
"Pure black (#000) and pure white (#fff) look harsh. Use near-black (oklch 0.10-0.15) and near-white (oklch 0.97-0.99) instead.",
- "Before inverting a site's default mode, verify the existing codebase's aesthetic direction. If every component uses dark backgrounds (charcoal-800, charcoal-900) with light text (offwhite, white/60), dark IS the default. Setting :root to light values and adding .dark overrides will make 90% of text unreadable until every component is migrated.",
],
},
{
@@ -99,7 +98,7 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
gotchas: [
"--spacing in Tailwind v4 sets the multiplier for ALL numeric spacing utilities (p-4 = 4 Γ 0.25rem = 1rem). Overriding it changes EVERY spacing utility across the project.",
"Named tokens like --spacing-card generate class p-card, but ONLY if defined in @theme or :root with Tailwind v4's CSS variable scanning. Verify the class exists before shipping.",
- "Do not use arbitrary pixel values outside the 4px grid (e.g., 7px, 13px, 22px) - they break visual rhythm.",
+ "Do not use arbitrary pixel values outside the 4px grid (e.g., 7px, 13px, 22px) β they break visual rhythm.",
"section-x padding should be responsive: smaller on mobile (1.5rem), larger on desktop (3-4rem). A single static value often looks wrong on one breakpoint.",
],
},
@@ -122,17 +121,17 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
"Large text (24px+) requires tight line height (1.05β1.2); body requires generous (1.6β1.75)",
"As font size decreases, line height must increase",
"Headings use negative tracking (-0.01 to -0.03em); body uses zero tracking; overlines use positive (+0.06 to +0.10em)",
- "NEVER apply negative tracking to body text - it reduces readability",
- "Body text is FIXED at 16px - never use fluid clamp() for body",
+ "NEVER apply negative tracking to body text β it reduces readability",
+ "Body text is FIXED at 16px β never use fluid clamp() for body",
"Maximum 2 font families per project; mono only for code, badges, terminal output",
"Prose max-width: 65ch for optimal reading line length",
"Type scale ratios: minor third (1.25), perfect fourth (1.333), or augmented fourth (1.414)",
],
gotchas: [
"Tight line-height on body text (e.g., 1.2) is a critical readability bug. Always use 1.6+ for paragraph text.",
- "clamp() fluid scaling on body text causes reflow and unpredictable sizing on resize - keep body sizes fixed.",
+ "clamp() fluid scaling on body text causes reflow and unpredictable sizing on resize β keep body sizes fixed.",
"Mixing font-weight 700 heading with font-weight 400 body in the same font variable file requires a variable font or separate font loads.",
- "letter-spacing in em is relative to font-size, so -0.03em on display (72px) = -2.16px - verify visually at each size.",
+ "letter-spacing in em is relative to font-size, so -0.03em on display (72px) = -2.16px β verify visually at each size.",
"overline text-transform: uppercase with positive tracking looks correct; without uppercase it looks odd.",
],
},
@@ -159,7 +158,7 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
],
gotchas: [
"A 28px button without a larger hit area (via padding or pseudo-element) fails WCAG 2.5.5 on touch devices.",
- "Icon-only buttons require an explicit aria-label AND a visible tooltip - an icon alone is not accessible.",
+ "Icon-only buttons require an explicit aria-label AND a visible tooltip β an icon alone is not accessible.",
"Disabled buttons should still meet minimum size requirements even when opacity: 0.5.",
],
},
@@ -173,14 +172,14 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
Button
Badge `,
rules: [
- "Keep radius consistent within a design system - all cards same radius, all buttons same radius",
+ "Keep radius consistent within a design system β all cards same radius, all buttons same radius",
"Border radius should scale proportionally with component size (small badges use sm, large modals use xl)",
- "Pill (radius-full) is for badges, toggles, and avatar images - not general cards",
+ "Pill (radius-full) is for badges, toggles, and avatar images β not general cards",
"Inputs typically use smaller radius (sm/md) than cards (lg/xl) for visual differentiation",
],
gotchas: [
"Mixing large (24px) and small (4px) radii in adjacent components looks inconsistent. Pick 1β2 radius values per component tier.",
- "border-radius on a container does not clip overflowing children by default - add overflow: hidden if children need clipping.",
+ "border-radius on a container does not clip overflowing children by default β add overflow: hidden if children need clipping.",
"Very large radius (radius-3xl on small components) can make them look bubble-like and unpolished.",
],
},
@@ -201,9 +200,9 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
Modal
`,
rules: [
- "Always use oklch-tinted warm shadows - never rgba(0,0,0) black shadows",
+ "Always use oklch-tinted warm shadows β never rgba(0,0,0) black shadows",
"5 elevation levels: flat(none) / subtle(xs-sm) / raised(md) / elevated(lg) / floating(xl-2xl)",
- "Dark mode: shadows are invisible - use progressively lighter bg-color per elevation level instead",
+ "Dark mode: shadows are invisible β use progressively lighter bg-color per elevation level instead",
"Every elevation level must be visually distinguishable from adjacent levels",
"Focus ring shadow uses 2px solid ring at 2px offset from element edge",
"Modal/overlay uses shadow-2xl; dropdown uses shadow-lg; tooltip uses shadow-md",
@@ -212,7 +211,7 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
"rgba(0,0,0,0.1) shadows look cold and blue-grey on warm backgrounds. Use oklch-tinted shadows that complement your warm neutrals.",
"In dark mode, box-shadow with dark backgrounds makes no visual difference. Forgetting to implement bg-color elevation in dark mode results in a flat, no-depth dark UI.",
"Multiple box-shadow layers (comma-separated) are additive. Test on both dark and light backgrounds before shipping.",
- "shadow-focus must contrast with both the element background and the page background - test on white AND colored button variants.",
+ "shadow-focus must contrast with both the element background and the page background β test on white AND colored button variants.",
],
},
{
@@ -237,15 +236,15 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
"Default transitions (color, bg, border): 200ms (duration-normal)",
"Panel open/close: 300ms (duration-slow)",
"Complex animations: 400β500ms (duration-slower)",
- "Exits should be faster than entrances - user-initiated dismissal expects immediacy",
+ "Exits should be faster than entrances β user-initiated dismissal expects immediacy",
"ease-out for entering elements, ease-in for exiting, ease-in-out for repositioning",
"NEVER use linear easing for UI transitions (only for progress bars and loaders)",
],
gotchas: [
"Forgetting prefers-reduced-motion is a WCAG 2.3.3 violation. It must be in @layer base with !important to override inline styles.",
- "ease-in on enter makes the animation feel slow to start - always use ease-out for entering elements.",
+ "ease-in on enter makes the animation feel slow to start β always use ease-out for entering elements.",
"Long exit durations (300ms+) make the UI feel sluggish because users are waiting to interact with the next state.",
- "CSS transition shorthand 'all' captures every property change, including layout - can cause jank. Explicitly list only the properties you want to animate.",
+ "CSS transition shorthand 'all' captures every property change, including layout β can cause jank. Explicitly list only the properties you want to animate.",
],
},
{
@@ -263,15 +262,15 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
Modal
`,
rules: [
- "NEVER use arbitrary z-index values (999, 9999) - always use named scale tokens",
+ "NEVER use arbitrary z-index values (999, 9999) β always use named scale tokens",
"Z-index only works on positioned elements (position: relative/absolute/fixed/sticky)",
- "Z-index is scoped to the stacking context - a child cannot exceed its parent's stacking context",
+ "Z-index is scoped to the stacking context β a child cannot exceed its parent's stacking context",
"Sticky header should be below modals (z-sticky < z-modal)",
"Toast notifications should be above everything except z-max",
- "Document every new z-index usage - stacking context bugs are very hard to debug",
+ "Document every new z-index usage β stacking context bugs are very hard to debug",
],
gotchas: [
- "transform, opacity < 1, filter, and will-change create new stacking contexts - a z-index on a child inside one of these is trapped within that context.",
+ "transform, opacity < 1, filter, and will-change create new stacking contexts β a z-index on a child inside one of these is trapped within that context.",
"z-index: 9999 on a component inside a transform: parent will still be below the parent's stacking context order.",
"Libraries like Radix UI and Headless UI have their own z-index values (often 50-9999). Check their defaults before setting your own values.",
"Two modals open simultaneously will stack by DOM order unless z-index is incremented dynamically.",
@@ -295,17 +294,17 @@ export const TOKEN_CATEGORIES: TokenCategory[] = [
Glass card