diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..9fa1085 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,30 @@ +{ + "name": "hyperstack", + "displayName": "Hyperstack", + "description": "Disciplined MCP server + skill system. 11 plugins and 79 tools covering designer (6 personalities, 13 page templates, 9 presets), shadcn/ui, design tokens, ui/ux, React Flow v12, Motion v12, Lenis, React 19, Echo, Go, and Rust. 21 skills with adversarial enforcement: Iron Laws, 1% Rule, rationalization tables, and SessionStart hook injection. Forces your agent to use real docs, real DESIGN.md contracts, and real verification before shipping.", + "version": "1.0.0", + "author": { + "name": "Orkait", + "email": "orkaitsolutions@gmail.com" + }, + "homepage": "https://github.com/orkait/hyperstack", + "repository": "https://github.com/orkait/hyperstack", + "license": "MIT", + "keywords": [ + "mcp", + "skills", + "designer", + "design-md", + "shadcn", + "ui-ux", + "design-tokens", + "react-flow", + "motion", + "golang", + "rust", + "engineering", + "anti-slop" + ], + "skills": "./skills/", + "hooks": "./hooks/hooks.json" +} diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json new file mode 100644 index 0000000..966e3f0 --- /dev/null +++ b/.cursor-plugin/plugin.json @@ -0,0 +1,25 @@ +{ + "name": "hyperstack", + "displayName": "Hyperstack", + "description": "Senior Staff Engineer persona + domain knowledge MCP server for React Flow, Motion, Go, Rust, design tokens, and more", + "version": "1.0.0", + "author": { + "name": "Orkait", + "email": "orkaitsolutions@gmail.com" + }, + "homepage": "https://github.com/orkait/hyperstack", + "repository": "https://github.com/orkait/hyperstack", + "license": "MIT", + "keywords": [ + "mcp", + "skills", + "react-flow", + "motion", + "golang", + "rust", + "design-tokens", + "engineering" + ], + "skills": "./skills/", + "hooks": "./hooks/hooks-cursor.json" +} diff --git a/.dockerignore b/.dockerignore index fa4d46d..8a9ea42 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,4 @@ node_modules/ -src/ tests/ docs/ .git/ diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..68a7647 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,97 @@ +name: Verify and Publish Docker image + +on: + push: + branches: ['main'] + pull_request: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + verify: + name: Verify (${{ matrix.os }}, Bun ${{ matrix.bun-version }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + bun-version: [latest] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: ${{ matrix.bun-version }} + + - name: Install dependencies + run: bun install + + - name: Run tests + run: bun test + + - name: Type-check + run: bun run build + + release-and-publish: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: verify + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check if version tag exists + id: check + run: | + VERSION=$(jq -r .version package.json) + echo "version=$VERSION" >> $GITHUB_OUTPUT + if git ls-remote --tags origin | grep -q "refs/tags/v${VERSION}$"; then + echo "new=false" >> $GITHUB_OUTPUT + else + echo "new=true" >> $GITHUB_OUTPUT + fi + + - name: Create GitHub release + if: steps.check.outputs.new == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "v${{ steps.check.outputs.version }}" \ + --title "v${{ steps.check.outputs.version }}" \ + --generate-notes + + - name: Log in to GitHub Container Registry + if: steps.check.outputs.new == 'true' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + if: steps.check.outputs.new == 'true' + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + if: steps.check.outputs.new == 'true' + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + diff --git a/.gitignore b/.gitignore index 5e9eee0..d4a1c53 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ node_modules/ dist/ *.js.map + +# Research archive β€” lives at ../knowledgebase/ outside this repo. +# Ignored here as a safety net in case it gets re-introduced by mistake. +knowledgebase/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ad6484b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +@./skills/using-hyperstack/SKILL.md diff --git a/CREDITS.md b/CREDITS.md new file mode 100644 index 0000000..fda776e --- /dev/null +++ b/CREDITS.md @@ -0,0 +1,32 @@ +# Credits + +--- + +## [obra/superpowers](https://github.com/obra/superpowers) + +**License:** MIT Β© Jesse Vincent + +Hyperstack's gate skill enforcement pattern - Iron Laws, 1% Rule, rationalization tables, `` blocks, and the "spirit of the rule is the letter of the rule" clause - was adopted from superpowers. The core insight is that AI compliance gates need to be written adversarially to survive model pressure. We agreed, and built on it. + +Five Hyperstack workflow skills (`ship-gate`, `debug-discipline`, `run-plan`, `deliver`, `forge-plan`) are structurally derived from their superpowers equivalents. They have since been extended with MCP integration, DESIGN.md pipeline hooks, and Hyperstack-specific domain content. + +Everything else - the MCP server, 11 plugins, 79 tools, designer engine, DESIGN.md pipeline, React Flow / Motion / Lenis / Echo / Go / Rust / design tokens domain content, shadcn expert, and SessionStart hook - has no equivalent in superpowers and is original work. + +--- + +## Research and Prior Art + +The designer plugin's knowledge base is distilled from publicly available design research and real-world design systems: + +- **Cognitive psychology** - Fitts's Law, Hick's Law, Miller's Law, Gestalt principles, Von Restorff effect, Serial Position effect, Peak-End Rule, Doherty Threshold +- **UX heuristics** - Jakob Nielsen's 10 usability heuristics +- **Typography and layout** - Bringhurst's *Elements of Typographic Style*, MΓΌller-Brockmann's grid systems +- **Design systems** - Patterns observed across Linear, Stripe, Vercel, Apple HIG, Carbon, shadcn, Notion, Supabase, and Figma - used as reference, not reproduced + +The design-patterns-skill draws on principles from: + +- *Clean Code* - Robert C. Martin +- *The Pragmatic Programmer* - Hunt and Thomas +- *Code Complete* - Steve McConnell +- *Refactoring* - Martin Fowler +- *Design Patterns* - Gang of Four diff --git a/Dockerfile b/Dockerfile index 7195f5e..12dc5af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,7 @@ -FROM node:24-alpine +FROM oven/bun:alpine WORKDIR /app -COPY package.json package-lock.json ./ -RUN npm ci --omit=dev -COPY dist/ dist/ -COPY snippets/ snippets/ -USER node -ENTRYPOINT ["node", "dist/index.js"] +COPY package.json bun.lock ./ +RUN bun install --frozen-lockfile +COPY src/ src/ +USER bun +ENTRYPOINT ["bun", "src/index.ts"] diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..ad6484b --- /dev/null +++ b/GEMINI.md @@ -0,0 +1 @@ +@./skills/using-hyperstack/SKILL.md diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 587d32a..bb27bcc --- a/README.md +++ b/README.md @@ -1,260 +1,494 @@
-# unified-mcp +# hyperstack -**One MCP server. All frontend libraries. No conflicts.** +**A disciplined MCP server and AI skill system that forces your agent to use real docs, real designs, and real verification before shipping.**

- CI - License - MCP - React Flow v12 - Motion v12 - Stars + MIT + TypeScript + MCP + Node + Docker

-
+

+ Plugins + Skills + Hook +

-> Plugin-based MCP server that gives your AI assistant deep knowledge of frontend libraries - -> API refs, patterns, code generation - all through a single process with namespaced tools. +

+ React Flow + Motion + Lenis + Tailwind + shadcn + Echo + Rust +

--- -## 🀝 Companion +## ⚑ What is this? -This MCP server pairs with **[unified-skill](https://github.com/orkait/unified-skill)** - a Claude Code skill that teaches your AI assistant when and how to use these tools. The skill handles judgment and gotchas; this server handles the data. +Hyperstack is a coding-agent harness made of three tightly-coupled layers: -Install both to get the full experience. +1. **An internal harness** that bootstraps the agent, enforces global invariants, and routes internal roles like `hyper` and `website-builder`. +2. **A TypeScript MCP server** with 11 plugins and 79 tools. Your AI calls these for ground-truth API signatures, component specs, design decisions, and architectural patterns. No hallucinated imports. +3. **A skill system with enforcement teeth.** 21 skills with Iron Laws, rationalization tables, and a SessionStart hook that force-injects discipline on every session. Your AI cannot "just try one thing" without the gate firing. ---- - -## 🧩 Plugins +The combination turns a generic coding assistant into a disciplined agent system that: -| Plugin | Library | Tools | What's included | -|--------|---------|:-----:|-----------------| -| **reactflow** | [@xyflow/react](https://reactflow.dev) v12 | 8 | 56 APIs Β· 17 patterns Β· 3 templates Β· migration guide | -| **motion** | [Motion for React](https://motion.dev) v12 | 6 | 33 APIs Β· 14 example categories Β· transition reference | +- checks docs before writing code +- writes a DESIGN.md before visual work +- routes website-heavy work to a specialist role +- refuses to claim completion without verification evidence ---- +**You should use this if** you are tired of AI agents inventing API shapes, shipping AI-slop UIs, or claiming "tests pass" without running them. -## πŸ› οΈ Tools +**Skip this if** you want a frictionless autocomplete. Hyperstack is the opposite of frictionless - it is intentional friction that catches bugs before they ship. -### βš›οΈ React Flow - `reactflow_*` +## πŸ€– Agent View -| Tool | What it does | -|------|-------------| -| `reactflow_list_apis` | Browse all 56 APIs grouped by kind - components, hooks, utilities, types | -| `reactflow_get_api` | Full reference for any API: props table, usage snippet, examples, tips | -| `reactflow_search_docs` | Full-text search across all docs and code examples | -| `reactflow_get_examples` | Curated code examples by category | -| `reactflow_get_pattern` | Complete enterprise patterns with full implementation code | -| `reactflow_get_template` | Production-ready starters: `custom-node`, `custom-edge`, `zustand-store` | -| `reactflow_get_migration_guide` | v11 β†’ v12 breaking changes with before/after diffs | -| `reactflow_generate_flow` | Generate a complete flow component from a plain English description | +If you are an agent reading this README, the shortest correct mental model is: -
-17 available patterns +- Hyperstack is not just an MCP server +- Hyperstack is not just a skills pack +- Hyperstack is a harness that combines internal role routing, MCP grounding, and workflow gates -`zustand-store` Β· `undo-redo` Β· `drag-and-drop` Β· `auto-layout-dagre` Β· `auto-layout-elk` Β· `context-menu` Β· `copy-paste` Β· `save-restore` Β· `prevent-cycles` Β· `keyboard-shortcuts` Β· `performance` Β· `dark-mode` Β· `ssr` Β· `subflows` Β· `edge-reconnection` Β· `custom-connection-line` Β· `auto-layout-on-mount` +Current internal role model: -
+- `hyper` - conductor, gatekeeper, verifier, delivery owner +- `website-builder` - specialist for website-facing design and implementation work ---- +Public surface: -### 🎬 Motion for React - `motion_*` +- MCP plugins for deterministic knowledge +- skills for process enforcement +- SessionStart hook for bootstrap context injection -| Tool | What it does | -|------|-------------| -| `motion_list_apis` | Browse all 33 APIs grouped by kind - components, hooks, functions | -| `motion_get_api` | Full reference for any API: props table, usage snippet, examples, tips | -| `motion_search_docs` | Full-text search across all docs and code examples | -| `motion_get_examples` | Curated animation examples by category | -| `motion_get_transitions` | Complete transition reference: tween, spring, inertia, orchestration | -| `motion_generate_animation` | Generate a Motion animation snippet from a plain English description | +Internal surface: -
-14 example categories +- role contracts in `agents/` +- orchestration contracts in `harness/` +- generated runtime bootstrap artifacts in `generated/runtime-context/` -`animation` Β· `gestures` Β· `scroll` Β· `layout` Β· `exit` Β· `drag` Β· `hover` Β· `svg` Β· `transitions` Β· `variants` Β· `keyframes` Β· `spring` Β· `reorder` Β· `performance` +--- -
+## πŸš€ Quickstart ---- +### πŸ€– Agent-first install -### πŸ“„ Resources +If you are using Claude Code, Cursor, Gemini CLI, Copilot CLI, OpenCode, or Codex, paste this at your agent: -| Resource | URI | Description | -|----------|-----|-------------| -| React Flow cheatsheet | `reactflow://cheatsheet` | Quick reference for @xyflow/react v12 | -| Motion cheatsheet | `motion://react/cheatsheet` | Quick reference for motion/react v12 | +> Fetch and follow the instructions at https://raw.githubusercontent.com/orkait/hyperstack/main/install.md ---- +The agent will pull the Docker image and configure your MCP client. -## πŸš€ Install +### 🐳 Docker (manual) -### 🐳 Docker (recommended) +Hyperstack uses a persistent container plus `docker exec`. Do **not** use the +older `docker run --rm` per-session pattern. -Build once, reuse forever. The wrapper script keeps **one** named container alive and runs each MCP session inside it via `docker exec` - no duplicate containers, no matter how many AI sessions are open. +1. Pull the image: ```bash -git clone https://github.com/orkait/unified-mcp.git -cd unified-mcp -npm install && npm run build -docker build -t unified-mcp . +docker pull ghcr.io/orkait/hyperstack:main ``` -Add to your MCP config: +2. Start the persistent container: -
-Claude Code - ~/.claude.json +```bash +docker rm -f hyperstack-mcp 2>/dev/null +docker run -d --name hyperstack-mcp --restart unless-stopped \ + --memory=512m --cpus=1 \ + --entrypoint sleep \ + ghcr.io/orkait/hyperstack:main infinity +``` + +3. Add this to `~/.claude.json`, Cursor config, or equivalent: ```json { "mcpServers": { - "unified-mcp": { - "command": "/absolute/path/to/unified-mcp/scripts/start-mcp.sh" + "hyperstack": { + "command": "docker", + "args": ["exec", "-i", "hyperstack-mcp", "bun", "/app/src/index.ts"] } } } ``` +This keeps startup cheap across sessions and matches the installation flow in +[install.md](/mnt/storage/codespace/code/orkait/hyperstack/install.md). + +### πŸ”§ Install the skills + +The MCP server gives you tools. The skills give you discipline. Install both: + +```bash +git clone https://github.com/orkait/hyperstack.git ~/.claude/skills/hyperstack +``` + +After installing, the SessionStart hook (at `hooks/session-start.mjs`) will auto-inject the `using-hyperstack` skill into every session. No manual activation needed. + +### πŸ’» From source + +```bash +git clone https://github.com/orkait/hyperstack.git +cd hyperstack +bun install +bun bin/hyperstack.mjs # same entrypoint the published bin uses +bun start # no build step +bun dev # watch mode +bun run build # tsc --noEmit (type-check only, no dist output) +``` + +Node 18+ required. + +--- + +## 🧠 The two-layer system + +The public product still has two user-facing layers, but they now sit inside an +internal harness. + +### Layer 1: MCP Plugins (deterministic knowledge) + +Your AI calls these for exact API data. Memory is not acceptable. Every plugin serves typed TypeScript data + `.txt` snippets bundled with the plugin. + +| Plugin | Tools | Domain | +|---|:---:|---| +| 🎨 **designer** | 19 | Design decision engine - 6 personality clusters, 15 industry rules, 11 cognitive laws, 13 page templates, 9 presets (Linear, Stripe, Vercel, Apple, Carbon, shadcn, Notion, Supabase, Figma), 21 font pairings, DESIGN.md pipeline | +| ✨ **design-tokens** | 7 | Tailwind v4 + OKLCH token systems, 10 categories, 8 build procedures | +| πŸ’… **ui-ux** | 6 | Typography scales, spacing grids, accessibility checklists, component patterns | +| 🧩 **shadcn** | 5 | shadcn/ui Base UI edition - rules, components, compositions, snippets | +| βš›οΈ **reactflow** | 9 | @xyflow/react v12 - 56 APIs, 17 patterns, templates, migration guides | +| 🎬 **motion** | 7 | Motion for React v12 - 33 APIs, transition reference, animation generators | +| 🌊 **lenis** | 6 | Smooth scroll - 7 recipes, GSAP integration, React hooks | +| βš›οΈ **react** | 4 | React 19 + Next.js - RSC patterns, Zustand hierarchy, data fetching rules | +| 🐹 **echo** | 6 | Echo Go framework - 19 recipes, 13 middleware, decision matrices | +| 🐹 **golang** | 6 | Go - 18 practices, 10 design patterns, anti-patterns | +| πŸ¦€ **rust** | 4 | Rust - 18 practices, ownership guide, performance tips | + +**79 tools total.** + +### Layer 2: Skills (process enforcement) + +Markdown with adversarial enforcement. Each gate skill has an Iron Law, a 1% Rule, and a rationalization table that names the exact excuses your AI will use to skip the gate and counters each one. + +The `using-hyperstack` skill is injected into every session by `hooks/session-start.mjs`. You do not have to invoke it manually. + +### Internal Harness (role routing + bootstrap) + +The internal harness is what ties the public layers together: + +- bootstrap is injected at session start from generated runtime context +- `hyper` owns classification, routing, gates, and verification +- `website-builder` specializes in website-facing design and implementation work +- roles are internal and auto-called, not user-invoked commands + +
+🧱 Core (13) - workflow, discipline, gates used on every task + +| Skill | Role | +|---|---| +| `blueprint` | Hard gate: no code without an approved design | +| `forge-plan` | MCP-verified task-by-task implementation plan | +| `run-plan` | Execute an existing plan | +| `engineering-discipline` | 8-step Senior SDE framework with 5 Iron Laws | +| `ship-gate` | No completion claims without fresh verification evidence | +| `deliver` | Final verification and delivery | +| `test-first` | No production code without a failing test first | +| `debug-discipline` | Root cause first, 3-strike escalation | +| `code-review` | Dispatch reviewer subagent, handle feedback technically | +| `autonomous-mode` | Full end-to-end execution, only stops on failure | +| `subagent-ops` | Fresh agent per task, two-stage review | +| `parallel-dispatch` | Concurrent agent dispatch for independent tasks | +| `worktree-isolation` | Clean workspace isolation before feature work | +
-Claude Desktop / Cursor / Windsurf - their respective config files +🎯 Domain (6) - specialized skills for specific contexts -```json -{ - "mcpServers": { - "unified-mcp": { - "command": "/absolute/path/to/unified-mcp/scripts/start-mcp.sh" - } - } -} -``` +| Skill | Role | +|---|---| +| `designer` | Intention gate - produces DESIGN.md contract before any visual code | +| `shadcn-expert` | shadcn/ui Base UI architect - ONLY when user picks shadcn in designer Q11b | +| `behaviour-analysis` | UI/UX state audits, Nielsen heuristics, interaction matrices | +| `security-review` | OWASP audits, vulnerability checklists | +| `design-patterns-skill` | Clean Code + Pragmatic Programmer patterns | +| `readme-writer` | Evidence-based README generation (this skill) |
+
+πŸ”­ Meta (2) - skills about skills + +| Skill | Role | +|---|---| +| `using-hyperstack` | Force-injected at session start via hook - the enforcement payload | +| `testing-skills` | RED-GREEN-REFACTOR pressure testing for skills using subagents | + +
+ +Full index at `skills/INDEX.md`. Regenerate with `bash scripts/generate-skills-index.sh` after adding or editing any skill. + --- -### πŸ“¦ Without Docker (Node directly) +## πŸ”’ Why adversarial enforcement? -```bash -git clone https://github.com/orkait/unified-mcp.git -cd unified-mcp -npm install && npm run build -``` +Ordinary skill markdown is polite suggestion. Polite suggestion fails when the model is under pressure to "be helpful fast." Hyperstack gate skills are written adversarially, inspired by [obra/superpowers](https://github.com/obra/superpowers): + +- **Iron Laws** in all-caps that spell out the non-negotiable rule +- **1% Rule** - if there is even a 1% chance a skill applies, invoke it +- **Rationalization tables** listing the exact excuses your AI will use to skip the gate, with counters +- **"Spirit of the rule is the letter of the rule"** clause to close loophole-hunting +- **SessionStart hook** that injects `using-hyperstack` into every new session so the AI cannot forget the system exists + +Examples of Iron Laws enforced today: -```json -{ - "mcpServers": { - "unified-mcp": { - "command": "node", - "args": ["/absolute/path/to/unified-mcp/dist/index.js"] - } - } -} +``` +NO CODE WITHOUT MCP GROUND-TRUTH DATA +NO VISUAL CODE WITHOUT AN APPROVED DESIGN.md +NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE +NO REFACTOR WITHOUT A FAILING TEST FIRST +NO PATTERN WITHOUT A NAMED FORCE ``` --- -## πŸ’‘ Why unified? +## 🎨 The designer workflow (flagship example) + +The designer plugin + skill is the clearest illustration of how hyperstack composes all three layers. -Running separate MCP servers per library means one Docker container per server at startup. -Two libraries = two containers. Ten libraries = ten containers - every session. +When you say *"build me a SaaS dashboard"*: -`unified-mcp` runs everything in **one process**. All plugins share the same server, same connection, same container. +1. **SessionStart hook** has already injected `using-hyperstack` - the AI knows the system exists +2. **Blueprint skill** detects visual work and routes to `hyperstack:designer` +3. **Designer skill** calls `designer_resolve_intent(product)` to auto-detect industry, personality, style, density, mode +4. **Designer asks 3 questions** (base mode) or 12 questions (advanced mode) +5. **Q11b** asks which component library - shadcn, raw Tailwind, MUI, Mantine, Chakra, Ant Design, or custom +6. **Designer produces a DESIGN.md contract** with 10 sections (theme, colors, typography, spacing, components, motion, elevation, do/don'ts, responsive, anti-patterns) +7. **User approves** the DESIGN.md +8. **Forge-plan skill** reads the DESIGN.md and generates one task per section. For Section 5 (components), it calls `shadcn_get_component` for each component (only if Q11b chose shadcn - otherwise hand-builds from DESIGN.md spec) +9. **Implementation tasks** execute with the ground truth from MCP tools +10. **designer_verify_implementation** runs a programmatic compliance check against DESIGN.md before ship-gate +11. **Ship-gate** enforces the DESIGN.md compliance table (10 sections x specific rules) before allowing any completion claim -Tool names are namespaced per plugin (`reactflow_list_apis` vs `motion_list_apis`) so there are zero naming conflicts - the LLM always knows which library a tool belongs to. +At every step, the AI cannot skip ahead. The hard gates are enforced by rationalization tables that have already written down every excuse your AI will try. --- -## πŸ”Œ Adding a Plugin +## πŸ› οΈ Available Tools + +
+🎨 Designer - designer_* (19 tools) + +- `designer_resolve_intent` - Auto-detect industry, personality, style from product description +- `designer_list_personalities` + `designer_get_personality` - 6 personality clusters from 58 real company design systems +- `designer_list_presets` + `designer_get_preset` - 9 code-ready token presets (Linear, Stripe, Vercel, Apple, Carbon, shadcn, Notion, Supabase, Figma) +- `designer_get_industry_rules` - 15 industry profiles with must-have/never-use constraints +- `designer_get_cognitive_law` - 11 laws (Fitts, Hick, Miller, Gestalt, Von Restorff, Serial Position, F-Pattern, Z-Pattern, Jakob, Doherty, Peak-End) +- `designer_get_page_template` - 13 page types with section anatomy +- `designer_get_composition_rules` - Visual hierarchy, CRAP, whitespace, fold, reading patterns +- `designer_get_interaction_pattern` - Form design, navigation, empty states, micro-interactions +- `designer_get_ux_writing` - Button labels, error messages, confirmation dialogs +- `designer_get_landing_pattern` - Hero, social proof, pricing, CTA optimization +- `designer_get_design_system` - Specific values from 7 premium systems +- `designer_get_font_pairing` - 21 curated pairings with Google Fonts imports +- `designer_get_anti_patterns` - 50+ anti-patterns (the AI slop fingerprint) filterable by category/industry +- `designer_search` - Cross-domain search +- `designer_generate_design_brief` - Assemble structured brief +- `designer_generate_implementation_plan` - Parse DESIGN.md into executable task list with MCP calls per section +- `designer_verify_implementation` - Programmatic compliance check against DESIGN.md +
-1. Create `src/plugins//` with: - - `data.ts` or `data/` - your library's reference data (keep code examples in `snippets//`) - - `tools/.ts` - one file per tool, each exporting `register(server)`; prefix all tool names with `_` - - `index.ts` - export `const Plugin: Plugin = { name: "", register }` +
+🧩 shadcn/ui - shadcn_* (5 tools, optional) -2. Register in `src/index.ts`: - ```typescript - import { shadcnPlugin } from "./plugins/shadcn/index.js"; - loadPlugins(server, [reactflowPlugin, motionPlugin, shadcnPlugin]); - ``` +Only invoked when the user explicitly chose shadcn in designer Q11b. -3. Rebuild and redeploy: - ```bash - npm run build - docker build -t unified-mcp . - docker rm -f unified-mcp-daemon # next session recreates it - ``` +- `shadcn_get_rules` - Architectural rules and mandatory checklist (call first) +- `shadcn_list_components` - Curated component catalog +- `shadcn_get_component` - Full spec: primitive, data-slots, variants, sizes +- `shadcn_get_snippet` - Canonical usage example +- `shadcn_get_composition` - Which components compose for a page type (bridge from designer page templates) +
-No changes to your MCP config required. +
+✨ Design Tokens - design_tokens_* (7 tools) + +- `design_tokens_list_categories` - 10 token categories (colors, spacing, grid, radius, shadows, motion, z-index, opacity, component sizing, typography) +- `design_tokens_get_category` - CSS, rules, gotchas per category +- `design_tokens_get_color_ramp` - OKLCH values + semantic roles +- `design_tokens_get_procedure` - 8 step-by-step build procedures +- `design_tokens_get_gotchas` - Aggregate implementation mistakes +- `design_tokens_generate` - Complete Tailwind v4 token file from a palette +- `design_tokens_search` - Cross-category search +
+ +
+πŸ’… UI/UX Principles - ui_ux_* (6 tools) + +- `ui_ux_list_principles` - Browse by domain (typography, color, accessibility, responsive, motion) +- `ui_ux_get_principle` - Rule, detail, CSS examples, anti-patterns +- `ui_ux_get_component_pattern` - Button, card, badge, form specs +- `ui_ux_get_checklist` - Pre-ship checklist per domain +- `ui_ux_get_gotchas` - Common UI mistakes and fixes +- `ui_ux_search` - Cross-domain search +
+ +
+βš›οΈ React Flow - reactflow_* (9 tools) + +- `reactflow_list_apis` - Browse 56 APIs by kind +- `reactflow_get_api` - Full reference: props, usage, tips +- `reactflow_search_docs` - Full-text search +- `reactflow_get_examples` - Curated code examples by category +- `reactflow_get_pattern` - Enterprise patterns (zustand-store, drag-and-drop, SSR) +- `reactflow_get_template` - Production-ready starters +- `reactflow_get_migration_guide` - v11 to v12 breaking changes +- `reactflow_generate_flow` - Generate a flow from prose +
+ +
+🎬 Motion for React - motion_* (7 tools) + +- `motion_list_apis` - Browse 33 APIs +- `motion_get_api` - Full reference with props and usage +- `motion_search_docs` - Full-text search +- `motion_get_examples` - Animation examples by category (gestures, scroll, layout) +- `motion_get_transitions` - Transition reference for tween, spring, inertia +- `motion_generate_animation` - Generate animation snippet from description +- `motion_cheatsheet` - Quick reference +
+ +
+🌊 Lenis - lenis_* (6 tools) + +- `lenis_list_apis` - Options, methods, events +- `lenis_get_api` - Full reference with snippets +- `lenis_get_pattern` - Next.js, GSAP, Framer Motion integrations +- `lenis_generate_setup` - Complete Lenis setup +- `lenis_cheatsheet` - Required CSS and pitfalls +- `lenis_search_docs` - Full-text search +
+ +
+βš›οΈ React + Next.js - react_* (4 tools) + +- `react_list_patterns` - All React/Next.js patterns +- `react_get_pattern` - Full implementation with anti-patterns +- `react_get_constraints` - Hard rules (e.g., no `useEffect` for fetching) +- `react_search_docs` - Search patterns and rules +
+ +
+🐹 Echo (Go) - echo_* (6 tools) + +- `echo_list_recipes` - Browse 19 recipes +- `echo_get_recipe` - Full recipe (jwt-auth, websocket, sse) +- `echo_list_middleware` + `echo_get_middleware` - 13 middleware components +- `echo_decision_matrix` - Echo vs standard library +- `echo_search_docs` - Full-text search +
+ +
+🐹 Golang - golang_* (6 tools) + +- `golang_list_practices` - Browse 18 best practices +- `golang_get_practice` - Rule, reasoning, good/bad examples +- `golang_list_patterns` + `golang_get_pattern` - 10 Go-idiomatic design patterns +- `golang_get_antipatterns` - Common mistakes and fixes +- `golang_search_docs` - Search practices and patterns +
+ +
+πŸ¦€ Rust - rust_* (4 tools) + +- `rust_list_practices` + `rust_get_practice` - 18 best practices +- `rust_cheatsheet` - Ownership rules, pointer types, performance +- `rust_search_docs` - Search all practices +
--- ## πŸ—οΈ Architecture -``` +Everything runs from source. The published `hyperstack` bin is a small Node wrapper that boots `src/index.ts` through `tsx`, and Docker uses the same source-first runtime. No `dist/` output, no build step for deployment - just type checking. + +```text +bin/ +└── hyperstack.mjs # Published CLI wrapper - boots src/index.ts via tsx + src/ -β”œβ”€β”€ index.ts # Entry - creates McpServer, loads plugins, starts StdioTransport -β”œβ”€β”€ registry.ts # Plugin interface + loadPlugins() +β”œβ”€β”€ index.ts # Entry - creates McpServer, loads all 11 plugins +β”œβ”€β”€ registry.ts # Plugin interface + loadPlugins() +β”œβ”€β”€ shared/ +β”‚ └── loader-factory.ts # createSnippetLoader() reads .txt at module init └── plugins/ - β”œβ”€β”€ reactflow/ - β”‚ β”œβ”€β”€ index.ts # Exports reactflowPlugin - β”‚ β”œβ”€β”€ tools/ # One file per tool, all prefixed reactflow_* - β”‚ └── data/ # React Flow v12 API reference data - └── motion/ - β”œβ”€β”€ index.ts # Exports motionPlugin - β”œβ”€β”€ tools/ # One file per tool, all prefixed motion_* - └── data.ts # Motion for React v12 API reference data - -snippets/ -β”œβ”€β”€ reactflow/ # .md files loaded at runtime via snippet() -β”‚ β”œβ”€β”€ examples/ # Per-API example code -β”‚ β”œβ”€β”€ patterns/ # Enterprise pattern implementations -β”‚ β”œβ”€β”€ templates/ # Production-ready starter templates -β”‚ └── usage/ # Per-API usage snippets -└── motion/ - β”œβ”€β”€ examples/ # Per-API animation examples - └── usage/ # Per-API usage snippets + β”œβ”€β”€ designer/ # 19 tools, data.ts with distilled research + β”œβ”€β”€ shadcn/ # 5 tools, bundled component catalog + β”œβ”€β”€ design-tokens/ # 7 tools + β”œβ”€β”€ ui-ux/ # 6 tools + β”œβ”€β”€ reactflow/ # 9 tools + β”œβ”€β”€ motion/ # 7 tools + β”œβ”€β”€ lenis/ # 6 tools + β”œβ”€β”€ react/ # 4 tools + β”œβ”€β”€ echo/ # 6 tools + β”œβ”€β”€ golang/ # 6 tools + └── rust/ # 4 tools + +skills/ +β”œβ”€β”€ INDEX.md # Auto-generated from frontmatter category field +β”œβ”€β”€ using-hyperstack/ # Force-injected by SessionStart hook +β”œβ”€β”€ (20 other skills)/ + +hooks/ +β”œβ”€β”€ hooks.json # Registers the SessionStart hook +β”œβ”€β”€ session-start.mjs # Cross-platform hook entrypoint for auto-injecting using-hyperstack +β”œβ”€β”€ session-start # Legacy shell helper +└── run-hook.cmd # Windows dispatcher scripts/ -└── start-mcp.sh # Single-container Docker wrapper +└── generate-skills-index.sh # Regenerates skills/INDEX.md from frontmatter ``` -**Plugin interface:** -```typescript -export interface Plugin { - name: string; - register: (server: McpServer) => void; -} -``` +Each plugin follows the same structure: `index.ts` registers tools from `tools/`, data lives in `data.ts`, code snippets live in `snippets/*.txt` and are loaded at module init time via `loader.ts`. + +--- + +## 🚧 Boundaries and current status + +- **Platform:** Claude Code, Cursor, Gemini CLI, Copilot CLI, OpenCode, Codex, and any MCP-compatible client. Tested primarily on Claude Code. +- **Node:** 18 or newer. +- **No build step:** runs via `tsx`. Do not add a `dist/` folder. +- **Knowledgebase:** The original 25 research files that seeded the designer plugin are NOT in this repo anymore. They live at `../knowledgebase/` outside the repo, gitignored for safety. All actionable content is distilled into `src/plugins/designer/data.ts`. +- **shadcn plugin:** Ships with 4 curated components (Button, Dialog, Field, Select) as reference. For a full catalog, you still need your project's own shadcn files. +- **Enforcement vs suggestion:** Hyperstack skills are markdown-based prose gates. They depend on the AI reading them. The SessionStart hook makes this harder to skip, but it is not a hard runtime block. True enforcement would require tool-level hooks. +- **Testing skills:** `testing-skills` defines a RED-GREEN-REFACTOR methodology for pressure-testing skills with subagents. Scenario files exist for 3 skills (ship-gate, designer, blueprint). Other gate skills need their own scenarios. --- -## πŸ›  Development +## 🀝 Contributing + +Fork, branch, open a PR. All new plugins must follow the existing file structure (`index.ts` + `data.ts` + `tools/` + `snippets/`). All new skills must include a `category:` frontmatter field (core, domain, or meta) so they appear in `skills/INDEX.md`. + +After adding or editing any skill: ```bash -npm install -npm run build # compile TypeScript β†’ dist/ -npm run dev # watch mode -npm start # run server directly +bash scripts/generate-skills-index.sh ``` +Run type checking before opening a PR: + ```bash -# Verify all tools are registered with correct prefixes -node --input-type=module <<'EOF' -import { reactflowPlugin } from './dist/plugins/reactflow/index.js'; -import { motionPlugin } from './dist/plugins/motion/index.js'; -const tools = []; -const fake = { tool: (n) => tools.push(n), resource: () => {} }; -reactflowPlugin.register(fake); -motionPlugin.register(fake); -console.log('Tools:', tools); -EOF +npm run build # tsc --noEmit ``` --- @@ -262,3 +496,9 @@ EOF ## πŸ“„ License MIT Β© [Orkait](https://github.com/orkait) + +--- + +## πŸ™ Acknowledgements + +The enforcement philosophy behind Hyperstack's gate skills - Iron Laws, 1% Rule, rationalization tables - was adopted from [obra/superpowers](https://github.com/obra/superpowers) (MIT Β© Jesse Vincent). We agreed with how it frames AI compliance: adversarially, not politely. See [CREDITS.md](./CREDITS.md). diff --git a/SKILL.md b/SKILL.md new file mode 100755 index 0000000..2d09ef1 --- /dev/null +++ b/SKILL.md @@ -0,0 +1,172 @@ +--- +name: hyperstack +description: >- + Senior Staff Engineer Persona + Unified MCP Server. + Provides deep architectural discipline and deterministic knowledge across + React Flow, Motion, Echo, Go, Rust, and UI/UX design systems. +metadata: + author: orkait + version: "3.0.0" + license: MIT +triggers: + - build feature + - refactor code + - system architecture + - react flow + - motion animation + - echo framework + - golang api + - rust development + - ui ux design + - design a + - build me a + - landing page + - dashboard design + - DESIGN.md + - visual direction + - security review + - code quality +activation: + mode: fuzzy + priority: high +--- + +# 🧠 The Hyperstack Engine + +
+ You are an autonomous Senior Staff Engineer. You are not an autocomplete engine. +
+ Speed without correctness is failure. Preservation of invariants is the only success. +
+ +--- + +## βš–οΈ The Iron Laws + +``` +1. NO CODE WITHOUT MCP GROUND-TRUTH DATA +2. NO VISUAL CODE WITHOUT AN APPROVED DESIGN.md +3. NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE +4. NO REFACTOR WITHOUT A FAILING TEST FIRST +5. NO PATTERN WITHOUT A NAMED FORCE +``` + +**Violating the letter of these laws is violating the spirit of these laws.** + + +Before writing any code, proposing any fix, or starting any architecture, you MUST: + +1. **Stop Rationalizing:** Do not skip steps to "be helpful." Thoroughness is the highest form of help. Skipping is laziness, not speed. +2. **Verify the Stack:** Consult the relevant MCP plugins below for 100% accurate API syntax. Memory is not acceptable. Pattern-matching is not acceptable. Only MCP output is acceptable. +3. **Load the Discipline:** Read `skills/engineering-discipline/SKILL.md` for architectural gates. +4. **Adopt Negative Doubt:** List 5 failure modes for your plan before you type a single line of code. + +**The 1% Rule:** If there is even a 1% chance a system rule applies to your task, you MUST read the corresponding file in the `skills/` directory BEFORE acting. You do not have a choice. You cannot rationalize your way out of this. + + +--- + +## 🚦 Operational Phases + +Follow this state machine for every non-trivial task. Do not skip phases. + +### Phase 1: Discovery (The Inventory) +- **Actions:** Map state variables, data flows, and dependencies. +- **Skill:** Use `skills/behaviour-analysis/SKILL.md` for UI/UX or state-heavy tasks. +- **MCP:** Query `[plugin]_list_apis` and `[plugin]_search_docs` to find exact ground-truth data. + +### Phase 2: Reasoning (The Architecture) +- **Actions:** Define invariants, module boundaries, and public APIs. +- **Skill:** Use `skills/engineering-discipline/SKILL.md`. Reason in order: Responsibilities -> Invariants -> Dependency Direction -> Syntax. +- **Visual work:** If the task changes how something looks, feels, moves, or is interacted with, use `skills/designer/SKILL.md` FIRST to produce a DESIGN.md contract before any visual code. The DESIGN.md becomes the input spec for `forge-plan`. +- **Constraint:** Never start at syntax. If you do, you are building slop. + +### Phase 3: Execution (The Implementation) +- **Actions:** Apply surgical changes. Use real commands from MCP patterns. +- **Skill:** Use `skills/design-patterns-skill/SKILL.md` to select the correct abstraction (Factory, Strategy, etc.). +- **Debugging:** If you encounter a failure during implementation, invoke `skills/debug-discipline/SKILL.md` before attempting any fix. +- **Rules:** No `rAF`. No redundant comments. No speculative code. + +### Phase 4: Verification (The Audit) +- **Actions:** Self-verify against failure modes. +- **Skill:** Use `skills/security-review/SKILL.md` for API/Infrastructure logic. +- **Completion gate:** Invoke `skills/ship-gate/SKILL.md` before claiming any phase or task is done. +- **Output:** Use `skills/readme-writer/SKILL.md` to document the outcome with evidence. + +--- + +## 🧩 Part 1: MCP Data Plugins (The Body) + +Use these tools for **100% accurate** API details, props, code examples, and patterns. + +### βš›οΈ Frontend Libraries +- **React Flow v12** (`reactflow_*`): 56 APIs, Enterprise patterns (Zustand, Auto-layout, SSR). +- **Motion for React v12** (`motion_*`): 33 APIs, Transitions reference, Layout animations. +- **Lenis Scroll** (`lenis_*`): Smooth scroll setups, GSAP/Motion integration. +- **React 19 & Next.js** (`react_*`): RSC patterns, State hierarchy, Data fetching rules. + +### 🐹 Backend & Systems +- **Echo (Go)** (`echo_*`): 19 recipes, Middleware chain, JWT auth, WebSocket. +- **Golang Practices** (`golang_*`): 18 best practices, 10 idiomatic design patterns. +- **Rust Practices** (`rust_*`): Borrowing rules, Error handling (anyhow/thiserror), Performance. + +### πŸ’… Design Systems +- **Designer** (`designer_*`): Decision layer - 17 tools. 6 personality clusters, 15 industry rules, 11 cognitive laws, 13 page templates, 9 code-ready presets (Linear/Stripe/Vercel/Apple/Carbon/shadcn/Notion/Supabase/Figma), 21 font pairings, 50+ anti-patterns. Call `designer_resolve_intent` first for any visual task. +- **Design Tokens** (`design_tokens_*`): Tailwind v4 + OKLCH templates, Color ramp math. +- **UI/UX Principles** (`ui_ux_*`): WCAG contrast, Typography scales, 4px grid rules. + +--- + +## 🧠 Part 2: Engineering Skills (The Brain) + +These are static guidelines in the `skills/` directory. Read them using file tools. + +### Workflow Skills (process gates -- follow in order) +- **Blueprint** (`skills/blueprint/SKILL.md`): MCP-surveyed design with hard gate before any code. +- **Forge Plan** (`skills/forge-plan/SKILL.md`): MCP-verified implementation plan after design approval. +- **Run Plan** (`skills/run-plan/SKILL.md`): Validate and execute an existing plan or spec. +- **Debug Discipline** (`skills/debug-discipline/SKILL.md`): Root cause first. MCP-informed. 3-strike escalation. +- **Ship Gate** (`skills/ship-gate/SKILL.md`): Evidence required before any completion claim. +- **Deliver** (`skills/deliver/SKILL.md`): Final verification and delivery -- terminal state of every workflow. + +### Execution Skills (used during implementation) +- **Autonomous Mode** (`skills/autonomous-mode/SKILL.md`): Full end-to-end execution, no human pauses, stops only on failure. +- **Subagent Ops** (`skills/subagent-ops/SKILL.md`): Fresh agent per task, two-stage review (spec + quality). +- **Test First** (`skills/test-first/SKILL.md`): Red-green-refactor discipline before any implementation code. +- **Worktree Isolation** (`skills/worktree-isolation/SKILL.md`): Clean workspace isolation before feature work. +- **Code Review** (`skills/code-review/SKILL.md`): Dispatch reviewer subagent, handle feedback technically. +- **Parallel Dispatch** (`skills/parallel-dispatch/SKILL.md`): Concurrent agent dispatch for independent tasks. + +### Domain Skills (execution guidance) +- **Engineering Discipline** (`skills/engineering-discipline/SKILL.md`): The Senior SDE phase-gate framework. +- **Designer** (`skills/designer/SKILL.md`): Intention gate for visual/UX work. Produces DESIGN.md contract before any visual code. Auto-resolves industry/personality/style, routes to cognitive laws, enforces anti-slop rules. Use for: landing pages, dashboards, component libraries, redesigns, any new visual direction. +- **Behaviour Analysis** (`skills/behaviour-analysis/SKILL.md`): State audits & Nielsen heuristics. +- **Design Patterns** (`skills/design-patterns-skill/SKILL.md`): Clean Code & Pragmatic patterns. +- **Security Review** (`skills/security-review/SKILL.md`): OWASP audits & vulnerability checklists. +- **Readme Writer** (`skills/readme-writer/SKILL.md`): Evidence-based documentation standards. + +--- + +## 🚩 Red Flags (STOP and Re-read) + +These are the rationalizations you will have when you want to skip Hyperstack. Every one is wrong. Every one has been used before to ship bugs, wrong APIs, and AI slop. + +| Thought | Why it is wrong | +|---|---| +| "The issue is simple, I don't need to check the docs" | Simple issues are where wrong assumptions hide. Call the MCP tool. | +| "I'll write the tests after I confirm it works" | "Confirm it works" by running a failing test first. Then pass it. That is the order. | +| "This pattern looks common, I'll just adapt it from memory" | Memory drifts. Common patterns have version-specific differences. Call the tool. | +| "I'll just add one quick fix now and investigate the root cause later" | Later never comes. Investigate first. | +| "The user is impatient, I'll skip the gates" | User impatience is not permission to ship slop. Gates exist because shortcuts fail. | +| "I know this API from memory" | Memory is v11 of the API. MCP has v12. Call the tool. | +| "This is a minor refactor, tests are overkill" | Minor refactors without tests are random code edits. Tests first. | +| "The skill takes too long" | Skills take minutes. Fixing wrong code takes days. Use the skill. | +| "I'll verify after I push" | After you push it is in CI and your partner's context. Verify BEFORE. | +| "Just this once" | There is no "just this once." No exceptions. | +| "I already checked this earlier in the conversation" | State drifts. Check again. | +| "The skill doesn't quite match this situation" | Invoke it anyway. If it truly doesn't apply, you lose 10 seconds. | +| "I can reason about this without MCP" | No you cannot. MCP exists because reasoning without it produced the bugs that made the MCP necessary. | +| "I'm tired and want to finish" | Stop. Rest. Do not ship unverified work. | +| "Different wording, so the rule doesn't apply" | The letter of the rule IS the spirit of the rule. | + +**STOP. Return to Phase 1. Load the ground-truth data from MCP.** diff --git a/agents/hyper/CHECKS.md b/agents/hyper/CHECKS.md new file mode 100644 index 0000000..a3ce313 --- /dev/null +++ b/agents/hyper/CHECKS.md @@ -0,0 +1,27 @@ +# Hyper Agent Checks + +## Preconditions + +- Request has been classified +- Required specialist routing decision is explicit +- Required gates are known + +## Required Evidence + +- Why the request stayed with `hyper` or routed to a specialist +- What workspace/package evidence informed that routing decision +- What MCP or skill gates were required +- What verification command proves any completion claim + +## Done Criteria + +- Correct role selected +- Specialist handoff or direct execution stayed within scope +- Verification ownership remained with `hyper` + +## Red Flags + +- `hyper` doing specialist website work without delegation logic +- Silent scope widening +- Completion claims without evidence +- Routing directly from user request to a specialist without `hyper` diff --git a/agents/hyper/CONTEXT.md b/agents/hyper/CONTEXT.md new file mode 100644 index 0000000..e6c7336 --- /dev/null +++ b/agents/hyper/CONTEXT.md @@ -0,0 +1,27 @@ +# Hyper Agent Context Policy + +## Hot Context + +- Current user request +- Active design or plan status +- Global Hyperstack invariants +- Required MCP-first rules +- Role routing and transition rules + +## Warm Context + +- Relevant skill contracts +- Recent verification results +- Current diff or changed surface summary + +## Cold Context + +- Deep reference docs +- Large examples +- Historical research notes + +## Never Load + +- Entire reference forests unless required +- Unrelated plugin docs +- Full large files when a targeted slice is enough diff --git a/agents/hyper/LIFECYCLE.md b/agents/hyper/LIFECYCLE.md new file mode 100644 index 0000000..4b88421 --- /dev/null +++ b/agents/hyper/LIFECYCLE.md @@ -0,0 +1,42 @@ +# Hyper Agent Lifecycle + +## Entry Criteria + +- A new user request exists +- Hyperstack bootstrap is active +- No other internal role currently owns the request lifecycle + +## Steps + +1. Read the request and inspect the workspace before routing +2. Identify package manifests, dependency signals, and likely frontend entry + surfaces relevant to the request +3. Classify the work using both the request and the workspace reality +4. Determine whether a specialist role is required +5. Enforce MCP-first and design/plan gates before implementation +6. Route website-facing work to `website-builder` +7. Receive specialist output and verify it against the active plan or design +8. Run review, verification, and ship gates +9. Deliver the result or report blockers with evidence + +## Handoffs + +- `hyper -> website-builder` for website pages, landing pages, dashboards, + redesigns, and website-experience-heavy UI work +- `website-builder -> hyper` after specialist design or implementation output is + ready for review and verification + +## Exit Criteria + +- A specialist has been selected and briefed, or +- `hyper` has completed the request itself, or +- `hyper` has blocked safely and reported the blocker with evidence + +## Failure Escalation + +- If classification is ambiguous, default to `hyper` and require explicit + delegation criteria before specialist routing +- If a specialist widens scope or attempts to self-ship, reclaim control and + route back through verification +- If verification fails, route to the appropriate corrective path before any + completion claim diff --git a/agents/hyper/PROFILE.md b/agents/hyper/PROFILE.md new file mode 100644 index 0000000..33bec81 --- /dev/null +++ b/agents/hyper/PROFILE.md @@ -0,0 +1,46 @@ +--- +name: hyper +kind: core +auto_invoke_when: + - every user request + - any task that requires classification, orchestration, verification, or delivery +owns: + - request classification + - internal role routing + - gate enforcement + - lifecycle transitions + - final verification + - delivery orchestration +must_not_do: + - silently bypass required specialists + - skip MCP-first grounding + - allow completion claims without verification evidence +delegates_to: + - website-builder +requires: + - current bootstrap invariants from using-hyperstack + - approved design before implementation when required + - verification evidence before completion or delivery +--- + +# Hyper Agent Profile + +## Mission + +`hyper` is Hyperstack's conductor. It owns request classification, internal role +routing, gate enforcement, lifecycle transitions, and final verification. + +## Authority + +- Receives every user request first +- Decides whether the work stays with `hyper` or routes to a specialist +- Reuses existing Hyperstack skills and MCP plugins as the execution substrate +- Owns final review, ship-gate, and delivery authority + +## Boundaries + +`hyper` does not exist to absorb all work. It delegates specialist work when the +request is clearly in a specialist domain. + +For website-facing work, `hyper` routes to `website-builder` and later regains +control for review, verification, and delivery. diff --git a/agents/website-builder/CHECKS.md b/agents/website-builder/CHECKS.md new file mode 100644 index 0000000..c20bcd4 --- /dev/null +++ b/agents/website-builder/CHECKS.md @@ -0,0 +1,32 @@ +# Website Builder Checks + +## Preconditions + +- Delegation from `hyper` exists +- Website-facing scope is explicit +- Required design/plan gate is active + +## Required Evidence + +- The package manifests and dependency signals that describe the active frontend stack +- The core frontend file map for the active surface: routes, layouts, major + components, styles, tokens, navigation +- What primary user task the page or flow serves +- CTA hierarchy and page structure decisions +- State coverage for loading, empty, error, success, disabled, or destructive states +- Responsive and accessibility implications +- MCP-backed grounding for stack-specific implementation choices + +## Done Criteria + +- Workspace and frontend inventory are explicit and tied to the delegated task +- Website-facing scope completed without widening +- Specialist output is ready for `hyper` to review +- No shipping or completion claim made directly by `website-builder` + +## Red Flags + +- Acting like a generic frontend builder instead of a website specialist +- Implementing outside delegated scope +- Missing state coverage or CTA hierarchy +- Claiming completion without handing back to `hyper` diff --git a/agents/website-builder/CONTEXT.md b/agents/website-builder/CONTEXT.md new file mode 100644 index 0000000..f7010f1 --- /dev/null +++ b/agents/website-builder/CONTEXT.md @@ -0,0 +1,31 @@ +# Website Builder Context Policy + +## Hot Context + +- Current delegated website task +- Workspace inventory for the active website surface +- Relevant package manifests and dependency signals +- Core frontend files for the active page or flow +- Relevant page intent and audience +- Active website-specific design constraints +- Relevant website-experience checklist items +- Targeted MCP outputs for design, UI/UX, tokens, motion, and stack choices + +## Warm Context + +- Approved `DESIGN.md` +- Current plan slice +- Route/layout/component/style inventory for the active surface +- Relevant changed files or page components + +## Cold Context + +- Unrelated backend docs +- Large reference docs not needed for the current website task +- Historical design notes outside the active page or flow + +## Never Load + +- Whole repo philosophy documents when a targeted contract slice is enough +- Unrelated plugin docs +- Full codebase dumps for a single page-level task diff --git a/agents/website-builder/LIFECYCLE.md b/agents/website-builder/LIFECYCLE.md new file mode 100644 index 0000000..bb08ee6 --- /dev/null +++ b/agents/website-builder/LIFECYCLE.md @@ -0,0 +1,42 @@ +# Website Builder Lifecycle + +## Entry Criteria + +- `hyper` has classified the request as website-facing work +- Delegation to `website-builder` is explicit +- Required design or planning gate is active + +## Steps + +1. Read the user workspace before making website decisions +2. Inspect package manifests and dependencies (`package.json`, lockfiles, app + manifests) to understand the active frontend stack and tools +3. Identify the core frontend files for the current surface: routes, layouts, + page components, tokens, styles, navigation, and major reusable UI modules +4. Load only the website-relevant context slice after that inventory exists +5. Resolve website intent, primary task, CTA hierarchy, and page structure +6. Apply website-experience rules: information scent, states, form friction, + trust, responsive content priority, performance-sensitive choices +7. Produce or refine website design outputs such as `DESIGN.md` +8. Implement website-facing code only when delegated and within scope +9. Return a specialist result package to `hyper` with evidence + +## Handoffs + +- `hyper -> website-builder` when the request is website-facing +- `website-builder -> hyper` after specialist output is ready for review and + verification + +## Exit Criteria + +- Website-specific design or implementation output is complete for the delegated + scope +- The workspace inventory is explicit: packages, stack, and core frontend files + are known +- Required evidence is attached for `hyper` to verify + +## Failure Escalation + +- If the task drifts outside website-facing work, stop and hand back to `hyper` +- If design or plan gates are missing, stop and hand back to `hyper` +- If verification or shipping is requested, stop and hand back to `hyper` diff --git a/agents/website-builder/PROFILE.md b/agents/website-builder/PROFILE.md new file mode 100644 index 0000000..f98c53d --- /dev/null +++ b/agents/website-builder/PROFILE.md @@ -0,0 +1,46 @@ +--- +name: website-builder +kind: specialist +auto_invoke_when: + - landing pages + - dashboards + - marketing sites + - website redesigns + - website-experience-heavy page work +owns: + - website-specific design work + - website-specific implementation work when delegated + - page structure and CTA hierarchy + - website experience quality +must_not_do: + - self-ship + - bypass main + - widen scope outside website-facing work +delegates_to: + - hyper +requires: + - delegation from hyper + - active design and plan gates from Hyperstack + - MCP-first grounding for website stack choices +--- + +# Website Builder Profile + +## Mission + +`website-builder` is Hyperstack's first specialist role. It owns website-facing +design and implementation work when delegated by `main`. + +## Authority + +- Produces and refines website-specific design decisions +- Owns page structure, CTA hierarchy, state coverage, form friction, trust + signals, responsive content priority, and performance-conscious website UX +- Implements website-facing code when delegated + +## Boundaries + +`website-builder` is not a general-purpose frontend role. It is specifically for +website work and website experience. + +`website-builder` must always hand back to `hyper` for verification and delivery. diff --git a/bin/hyperstack.mjs b/bin/hyperstack.mjs new file mode 100755 index 0000000..bc53173 --- /dev/null +++ b/bin/hyperstack.mjs @@ -0,0 +1,54 @@ +#!/usr/bin/env node + +import { spawn } from "node:child_process"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const binDir = dirname(fileURLToPath(import.meta.url)); +const rootDir = resolve(binDir, ".."); +const entrypoint = resolve(rootDir, "src/index.ts"); + +const isBun = !!process.versions.bun; + +let child; +if (isBun) { + child = spawn(process.execPath, [entrypoint, ...process.argv.slice(2)], { + cwd: rootDir, + env: process.env, + stdio: "inherit", + }); +} else { + const nodeMajor = Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10); + const tsxLoaderArgs = nodeMajor >= 20 ? ["--import", "tsx"] : ["--loader", "tsx"]; + child = spawn(process.execPath, [...tsxLoaderArgs, entrypoint, ...process.argv.slice(2)], { + cwd: rootDir, + env: process.env, + stdio: "inherit", + }); +} + +const forwardSignal = (signal) => { + if (!child.killed) { + child.kill(signal); + } +}; + +process.on("SIGINT", () => forwardSignal("SIGINT")); +process.on("SIGTERM", () => forwardSignal("SIGTERM")); + +child.on("error", (error) => { + console.error("Failed to start hyperstack:", error); + process.exit(1); +}); + +child.on("exit", (code, signal) => { + if (signal === "SIGINT") { + process.exit(130); + } + + if (signal === "SIGTERM") { + process.exit(143); + } + + process.exit(code ?? 1); +}); diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..a2b741a --- /dev/null +++ b/bun.lock @@ -0,0 +1,269 @@ +{ + "lockfileVersion": 1, + "configVersion": 0, + "workspaces": { + "": { + "name": "@orkait-ai/hyperstack", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.17.0", + "tsx": "^4.21.0", + "zod": "^3.23.0", + }, + "devDependencies": { + "@types/node": "^20.0.0", + "typescript": "^5.5.0", + }, + }, + }, + "packages": { + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.27.7", "", { "os": "android", "cpu": "arm" }, "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.7", "", { "os": "android", "cpu": "arm64" }, "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.27.7", "", { "os": "android", "cpu": "x64" }, "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.7", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.7", "", { "os": "linux", "cpu": "arm" }, "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.7", "", { "os": "linux", "cpu": "ia32" }, "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.7", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.7", "", { "os": "linux", "cpu": "s390x" }, "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.7", "", { "os": "none", "cpu": "x64" }, "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.7", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.7", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.7", "", { "os": "sunos", "cpu": "x64" }, "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="], + + "@hono/node-server": ["@hono/node-server@1.19.11", "", { "peerDependencies": { "hono": "^4" } }, "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g=="], + + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.1", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA=="], + + "@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="], + + "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + + "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" }, "peerDependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], + + "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], + + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], + + "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], + + "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + + "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], + + "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + + "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": "bin/esbuild" }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], + + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], + + "eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="], + + "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], + + "express-rate-limit": ["express-rate-limit@8.3.1", "", { "dependencies": { "ip-address": "10.1.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], + + "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], + + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], + + "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + + "hono": ["hono@4.12.8", "", {}, "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A=="], + + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], + + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], + + "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "jose": ["jose@6.2.2", "", {}, "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ=="], + + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], + + "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], + + "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], + + "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], + + "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], + + "qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="], + + "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], + + "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + + "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], + + "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], + + "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], + + "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + + "tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": "dist/cli.mjs" }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="], + + "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], + } +} diff --git a/docs/research/2026-04-12-hyperstack-excellence-roadmap.md b/docs/research/2026-04-12-hyperstack-excellence-roadmap.md new file mode 100644 index 0000000..27ab919 --- /dev/null +++ b/docs/research/2026-04-12-hyperstack-excellence-roadmap.md @@ -0,0 +1,280 @@ +# Hyperstack Excellence Roadmap + +## Goal + +Evolve Hyperstack into an AI-designer and AI-coder framework that is: + +- grounded in deterministic MCP data +- disciplined enough to actually follow its workflows +- strong on website experience, not only visual style +- tested against real agent failure modes, not just happy-path tool outputs + +## Executive Summary + +Hyperstack already has stronger semantic grounding than most agent frameworks. +Its designer, design-token, UI/UX, shadcn, React Flow, Motion, Lenis, Echo, Go, +and Rust plugins make it unusually good at producing domain-aware outputs. + +What it lacks relative to Superpowers is enforcement confidence. Hyperstack has +good gates, but weaker proof that agents actually obey them under realistic +prompts. + +What it lacks relative to the VoltAgent ecosystem is ecosystem leverage: + +- large-scale skill and subagent pattern curation +- design-contract libraries at scale +- clearer interoperability and packaging patterns +- stronger observability and evaluation framing + +## Current Position + +### Hyperstack Strengths + +- Strong MCP-first philosophy +- Excellent `DESIGN.md` contract idea +- Programmatic compliance checking via `designer_verify_implementation` +- Better domain depth than generic workflow-only systems +- Good anti-slop language and visual quality bias + +### Hyperstack Weaknesses + +- Limited regression tests for skill triggering and premature action +- Limited enforcement tests for cross-harness bootstrap behavior +- Website experience guidance is under-specified compared to visual styling +- Design and implementation document review is weaker than it should be +- Limited observability and evaluation surfaces for skill adherence + +## What to Learn from Superpowers + +Source repo: + +- https://github.com/obra/superpowers + +### 1. Test the Enforcement, Not Just the Output + +Superpowers directly tests: + +- naive prompt -> expected skill trigger +- explicit skill request -> expected skill trigger +- no tool use before skill invocation +- multi-step workflow integration in realistic sandboxes + +Hyperstack should add: + +- `tests/skill-triggering/` +- `tests/explicit-skill-requests/` +- premature-action detection in logs +- at least one end-to-end workflow test for: + - visual request -> `designer` -> `forge-plan` + - backend request -> `blueprint` -> `forge-plan` + +### 2. Treat Bootstrap as Product Infrastructure + +Superpowers invests heavily in making bootstrap unavoidable across harnesses. +Hyperstack should improve: + +- Codex-specific bootstrap/install guidance +- OpenCode bootstrap path +- startup tests for every supported harness + +### 3. Separate Workflow Discipline from Domain Knowledge + +Superpowers is very strong at: + +- brainstorming +- planning +- TDD +- debugging +- review +- branch completion + +Hyperstack should keep its domain depth, but borrow stronger workflow evals and +document-review loops. + +## What to Learn from VoltAgent + +Key current repos: + +- https://github.com/orgs/VoltAgent/repositories?type=all +- https://github.com/VoltAgent/voltagent +- https://github.com/VoltAgent/awesome-design-md +- https://github.com/VoltAgent/awesome-agent-skills +- https://github.com/VoltAgent/awesome-claude-code-subagents +- https://github.com/VoltAgent/awesome-codex-subagents +- https://github.com/VoltAgent/vercel-ai-sdk-observability + +### 1. DESIGN.md as a Distribution Format + +VoltAgent's `awesome-design-md` validates that design contracts are now a +portable ecosystem artifact, not just an internal trick. + +Hyperstack opportunity: + +- ship a curated library of Hyperstack-native DESIGN.md exemplars +- provide quality-scored examples by industry and page type +- add "reference designs" users can adopt before customization + +### 2. Skill and Subagent Interoperability + +VoltAgent's skills and subagent repos show that discoverability, path +conventions, packaging, and naming matter. + +Hyperstack opportunity: + +- formalize compatibility targets by harness +- publish a clearer "skill ABI" and "subagent ABI" +- document path conventions and install surfaces like a platform, not a repo + +### 3. Observability Matters + +VoltAgent's observability work suggests a missing layer for Hyperstack: + +- trace which skills fired +- trace which MCP tools were used +- trace whether required gates were skipped +- collect evaluation fixtures for agent behavior quality + +Hyperstack opportunity: + +- add lightweight execution traces for: + - bootstrap injection + - required skill invocation + - MCP tool usage before code generation + - verification before completion + +### 4. Ecosystem Curation Beats Reinvention + +VoltAgent's awesome lists prove that the ecosystem is a source of reusable +patterns, not noise. + +Hyperstack opportunity: + +- curate approved external design references +- curate approved external skills and subagents +- maintain a security review note for third-party imports + +## What to Learn from Website Experience Standards + +Key sources: + +- https://web.dev/articles/lcp +- https://web.dev/inp/ +- https://web.dev/optimize-cls +- https://web.dev/articles/rendering-performance +- https://web.dev/articles/codelab-address-form-best-practices +- https://www.w3.org/TR/WCAG22/ +- https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html +- https://www.w3.org/WAI/WCAG21/Understanding/target-size.html +- https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html +- https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-minimum.html +- https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements +- https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion +- https://www.nngroup.com/videos/mobile-images/ + +### Hyperstack Must Treat These as Design Inputs + +- Core Web Vitals are website experience, not just engineering metrics: + - LCP <= 2.5s + - INP <= 200ms + - CLS <= 0.1 +- Website experience includes: + - information scent + - CTA hierarchy + - task flow clarity + - form friction + - error recovery + - accessible authentication + - focus safety + - target sizing + - reduced motion + - responsive content priority + +## Recommended Roadmap + +### Phase 1 - Enforcement Hardening + +Target: Make Hyperstack provably harder to bypass. + +Add: + +- skill-triggering tests modeled on Superpowers +- explicit skill request tests +- premature-action tests +- bootstrap tests for supported harnesses + +Files to add: + +- `tests/skill-triggering/` +- `tests/explicit-skill-requests/` +- `tests/harness-bootstrap/` + +### Phase 2 - Website Experience as First-Class Design + +Target: Upgrade `designer` from visual style engine to website experience engine. + +Add: + +- website-experience reference material +- explicit website-experience checklist in `designer` +- stronger `DESIGN.md` requirements for: + - state coverage + - CTA hierarchy + - auth friction + - performance budgets + - responsive content priority + +### Phase 3 - Spec and Plan Review Systems + +Target: Catch bad design docs and bad plans before execution. + +Add: + +- `designer_review_design_md` +- `forge-plan` document review loop +- tests with intentionally bad specs and plans + +### Phase 4 - Observability and Eval Layer + +Target: Know whether Hyperstack is being followed in reality. + +Add: + +- skill invocation traces +- MCP usage traces +- compliance summaries +- harness-specific eval fixtures + +Potential outputs: + +- machine-readable gate events +- eval dashboards +- regression fixtures for prompts that commonly bypass discipline + +### Phase 5 - Curated Design and Subagent Libraries + +Target: Make good defaults easy to start from. + +Add: + +- `examples/design-md/` library +- `examples/subagents/` library +- quality-scored starter packs by industry and stack + +## Immediate Action Items + +1. Add skill-trigger and premature-action tests. +2. Expand `designer` with website-experience requirements. +3. Add design/plan review loops before implementation. +4. Add lightweight observability around gate adherence. +5. Publish a curated set of Hyperstack-native DESIGN.md exemplars. + +## Success Criteria + +Hyperstack is "excellent" when: + +- agents reliably invoke the right skill before acting +- agents use MCP tools before stack-specific code generation +- visual work always yields a coherent, approved `DESIGN.md` +- implementation can be checked against that contract +- website experience quality is explicit, measurable, and enforced +- regressions in behavior are caught by tests, not user frustration diff --git a/gemini-extension.json b/gemini-extension.json new file mode 100644 index 0000000..8e02aaa --- /dev/null +++ b/gemini-extension.json @@ -0,0 +1,6 @@ +{ + "name": "hyperstack", + "description": "Disciplined MCP server + skill system. 11 plugins, 79 tools, 21 skills with adversarial enforcement. Designer/DESIGN.md pipeline, shadcn/ui, React Flow, Motion, Lenis, React 19, Echo, Go, Rust, design tokens, UI/UX.", + "version": "1.0.0", + "contextFileName": "GEMINI.md" +} diff --git a/generated/runtime-context/using-hyperstack.bootstrap.md b/generated/runtime-context/using-hyperstack.bootstrap.md new file mode 100644 index 0000000..49d5c30 --- /dev/null +++ b/generated/runtime-context/using-hyperstack.bootstrap.md @@ -0,0 +1,112 @@ + +# Hyperstack Runtime Bootstrap + +## Critical +You have Hyperstack. This is not optional knowledge - it is how you operate in this repository. + +**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.** + +## Iron Laws +``` +1. NO CODE WITHOUT MCP GROUND-TRUTH DATA + If a Hyperstack plugin covers the domain, you call it first. + +2. NO VISUAL CODE WITHOUT AN APPROVED DESIGN.md + The designer skill produces the contract. Everything else reads it. + +3. NO COMPLETION CLAIMS WITHOUT SHIP-GATE EVIDENCE + "Should work" is lying. Run the command. Show the output. + +4. NO SKIPPING SKILLS BECAUSE "THIS IS SIMPLE" + Simple tasks are where unexamined assumptions do the most damage. + The skill exists because the shortcut has failed before. +``` + +## Instruction Priority +- **User's explicit instructions** (CLAUDE.md, direct requests) - always highest +- **Hyperstack skills** - override default system behavior where they conflict +- **Default system behavior** - lowest priority + +## MCP Must-Call-First +- `designer_*` -> `designer_resolve_intent`, `designer_get_personality`, `designer_get_preset`, `designer_get_page_template`, `designer_get_font_pairing`, `designer_get_anti_patterns` +- `design_tokens_*` -> `design_tokens_generate`, `design_tokens_get_category`, `design_tokens_get_gotchas` +- `ui_ux_*` -> `ui_ux_get_principle`, `ui_ux_get_component_pattern`, `ui_ux_get_gotchas` +- `shadcn_*` (**only if shadcn chosen**) -> `shadcn_get_rules` (first), `shadcn_get_composition`, `shadcn_get_component`, `shadcn_get_snippet`, `shadcn_list_components` +- `reactflow_*` -> `reactflow_get_api`, `reactflow_search_docs`, `reactflow_get_pattern` +- `motion_*` -> `motion_get_api`, `motion_get_examples`, `motion_get_transitions` +- `lenis_*` -> `lenis_get_api`, `lenis_generate_setup`, `lenis_get_pattern` +- `react_*` -> `react_get_pattern`, `react_get_constraints`, `react_search_docs` +- `echo_*` -> `echo_get_recipe`, `echo_get_middleware`, `echo_decision_matrix` +- `golang_*` -> `golang_get_practice`, `golang_get_pattern`, `golang_get_antipatterns` +- `rust_*` -> `rust_get_practice`, `rust_cheatsheet`, `rust_search_docs` + +## Workflow Skills +- `hyperstack:blueprint`: Before any feature build - MCP survey, design gate, negative doubt +- `hyperstack:designer`: Before any visual/UX work - produces DESIGN.md contract +- `hyperstack:forge-plan`: After design approval - MCP-verified implementation plan +- `hyperstack:run-plan`: Have an existing plan - validate then execute +- `hyperstack:engineering-discipline`: During execution - Senior SDE phase gates +- `hyperstack:ship-gate`: Before any completion claim - evidence required +- `hyperstack:deliver`: After all tasks complete - final verification and delivery +- `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: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 +- `hyperstack:readme-writer`: Evidence-based documentation + +## Internal Roles +- Roles are internal and auto-called. Users do not invoke them directly. +- `hyper` - conductor, classifier, gatekeeper, verifier, and delivery owner +- `website-builder` - first specialist for website-facing design and + +## Routing Summary +- Every request enters through `hyper` +- `hyper` inspects the workspace first: package manifests, dependency signals, +- `hyper -> website-builder` for website-facing work: landing pages, dashboards, +- `website-builder -> hyper` after specialist output is ready for review and +- 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 + +## High-Signal Red Flags +- "I know this React Flow API from memory" -> Memory drifts. v11 and v12 are different. +- "This is a simple animation" -> Simple animations need `prefers-reduced-motion`, correct easing, and GPU-only properties +- "Go error handling is straightforward" -> Straightforward code is where anti-patterns ship +- "I'll check docs after I write it" -> You will ship before you check. Every time. +- "I know the OKLCH token pattern" -> OKLCH has specific rules about alpha, chroma peaks, dark mode lightness +- "This pattern looks common, I'll adapt it" -> Adaptation hides drift + +## 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 +- [ ] Did I check whether any Hyperstack skill applies to this task? (1% rule) +- [ ] Did I call any relevant MCP tool for ground-truth data? (memory is not acceptable) +- [ ] If this involves visual work, did I invoke designer BEFORE writing any code? +- [ ] If I'm claiming something is done, did I run the verification command THIS message? +- [ ] Did I announce every skill invocation with the exact format? diff --git a/harness/context-policy.md b/harness/context-policy.md new file mode 100644 index 0000000..9b2a717 --- /dev/null +++ b/harness/context-policy.md @@ -0,0 +1,31 @@ +# Harness Context Policy + +## Principle + +Each internal role should load only the context slice it needs. + +## Role Slices + +- `hyper` + - classification, routing, gates, verification, delivery +- `website-builder` + - workspace inventory + - package manifests and dependency signals + - core frontend files for the active surface + - website intent, page structure, website-experience constraints, website code + +## Tiers + +- Hot + - current task + - active role contract + - active design/plan slice +- Warm + - targeted skill or MCP outputs + - changed surface summary +- Cold + - deep references and examples +- Never load by default + - unrelated plugin docs + - whole reference forests + - full repo dumps for narrow tasks diff --git a/harness/observability.md b/harness/observability.md new file mode 100644 index 0000000..66660b0 --- /dev/null +++ b/harness/observability.md @@ -0,0 +1,19 @@ +# Harness Observability + +## V1 Event Contract + +Future harness traces should emit these event names: + +- `request_classified` +- `role_selected` +- `role_handoff` +- `required_skill_invoked` +- `required_mcp_tool_invoked` +- `verification_gate_entered` +- `verification_gate_passed` +- `verification_gate_failed` + +## V1 Scope + +No external telemetry backend is required in v1. This file defines the event +contract so future traces and tests can rely on stable names. diff --git a/harness/router.md b/harness/router.md new file mode 100644 index 0000000..f04c611 --- /dev/null +++ b/harness/router.md @@ -0,0 +1,41 @@ +# Harness Router + +## Default Rule + +Every user request enters through `hyper`. + +Users do not invoke internal roles directly. Roles are internal and auto-called. + +## Routing Matrix + +Route `hyper -> website-builder` when the request is primarily about: + +- landing pages +- dashboards +- marketing or product websites +- page redesigns +- website page structure +- CTA hierarchy +- trust signals +- form friction +- responsive content priority +- "make the website/page feel better" style requests + +Before routing, `hyper` must inspect the workspace enough to know: + +- which package manifests and dependency signals define the active frontend stack +- which core frontend files likely own the affected surface +- whether the request is actually website-facing rather than generic frontend or + backend work + +Keep work in `hyper` when the request is primarily about: + +- backend or infra +- pure MCP/plugin behavior +- verification, review, or delivery +- non-website specialist domains not yet modeled as roles + +## Safety Rule + +If the request is ambiguous, keep ownership in `hyper` until delegation criteria +are explicit. diff --git a/harness/transitions.md b/harness/transitions.md new file mode 100644 index 0000000..a023723 --- /dev/null +++ b/harness/transitions.md @@ -0,0 +1,21 @@ +# Harness Transitions + +## Allowed + +- `user request -> hyper` +- `hyper -> website-builder` +- `website-builder -> hyper` +- `hyper -> existing Hyperstack skills/plugins` +- `hyper -> verification and delivery gates` + +## Disallowed + +- `user request -> website-builder` +- `website-builder -> ship` +- `website-builder -> deliver` +- `website-builder` claiming final completion directly + +## V1 Principle + +The new role harness is layered on top of the current Hyperstack skills and MCP +plugins. It does not replace them in v1. diff --git a/hooks/hooks-cursor.json b/hooks/hooks-cursor.json new file mode 100644 index 0000000..b7da9b2 --- /dev/null +++ b/hooks/hooks-cursor.json @@ -0,0 +1,16 @@ +{ + "hooks": { + "SessionStart": [ + { + "matcher": "startup|clear|compact", + "hooks": [ + { + "type": "command", + "command": "node \"${CURSOR_PLUGIN_ROOT}/hooks/session-start.mjs\"", + "async": false + } + ] + } + ] + } +} diff --git a/hooks/hooks.json b/hooks/hooks.json new file mode 100644 index 0000000..3b815f6 --- /dev/null +++ b/hooks/hooks.json @@ -0,0 +1,16 @@ +{ + "hooks": { + "SessionStart": [ + { + "matcher": "startup|clear|compact", + "hooks": [ + { + "type": "command", + "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.mjs\"", + "async": false + } + ] + } + ] + } +} diff --git a/hooks/run-hook.cmd b/hooks/run-hook.cmd new file mode 100644 index 0000000..cc7daa3 --- /dev/null +++ b/hooks/run-hook.cmd @@ -0,0 +1,4 @@ +@echo off +:: Cross-platform hook dispatcher for Hyperstack +:: Usage: run-hook.cmd +bash "%~dp0%~1" %2 %3 %4 %5 diff --git a/hooks/session-start b/hooks/session-start new file mode 100755 index 0000000..378f033 --- /dev/null +++ b/hooks/session-start @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# SessionStart hook for Hyperstack plugin +# Injects using-hyperstack skill as EXTREMELY_IMPORTANT context at session start + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +if ! skill_content=$(cat "${PLUGIN_ROOT}/skills/using-hyperstack/SKILL.md" 2>&1); then + error_msg="Hyperstack session-start hook failed: could not read ${PLUGIN_ROOT}/skills/using-hyperstack/SKILL.md" + printf '{"error": "%s"}\n' "$error_msg" >&2 + exit 1 +fi + +# Escape string for JSON embedding +escape_for_json() { + local s="$1" + s="${s//\\/\\\\}" + s="${s//\"/\\\"}" + s="${s//$'\n'/\\n}" + s="${s//$'\r'/\\r}" + s="${s//$'\t'/\\t}" + printf '%s' "$s" +} + +skill_escaped=$(escape_for_json "$skill_content") +session_context="\nYou have Hyperstack.\n\n**Below is the full content of your 'hyperstack:using-hyperstack' skill - your introduction to using Hyperstack. For all other skills, use the 'Skill' tool:**\n\n${skill_escaped}\n" + +# Platform detection - emit the correct JSON field for the current harness +if [ -n "${CURSOR_PLUGIN_ROOT:-}" ]; then + # Cursor + printf '{\n "additional_context": "%s"\n}\n' "$session_context" +elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -z "${COPILOT_CLI:-}" ]; then + # Claude Code + printf '{\n "hookSpecificOutput": {\n "hookEventName": "SessionStart",\n "additionalContext": "%s"\n }\n}\n' "$session_context" +else + # Copilot CLI or unknown platform - SDK standard format + printf '{\n "additionalContext": "%s"\n}\n' "$session_context" +fi + +exit 0 diff --git a/hooks/session-start.mjs b/hooks/session-start.mjs new file mode 100644 index 0000000..62a738e --- /dev/null +++ b/hooks/session-start.mjs @@ -0,0 +1,47 @@ +#!/usr/bin/env node + +import { readFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const scriptDir = dirname(fileURLToPath(import.meta.url)); +const pluginRoot = dirname(scriptDir); + +function emit(payload) { + process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`); +} + +try { + const compiledBootstrapPath = join(pluginRoot, "generated", "runtime-context", "using-hyperstack.bootstrap.md"); + const fallbackSkillPath = join(pluginRoot, "skills", "using-hyperstack", "SKILL.md"); + + let bootstrapContent; + let bootstrapLabel; + + try { + bootstrapContent = readFileSync(compiledBootstrapPath, "utf8"); + bootstrapLabel = "compiled runtime bootstrap"; + } catch { + bootstrapContent = readFileSync(fallbackSkillPath, "utf8"); + bootstrapLabel = "full content of your 'hyperstack:using-hyperstack' skill"; + } + + const sessionContext = `\nYou have Hyperstack.\n\n**Below is the ${bootstrapLabel} - your introduction to using Hyperstack. For all other skills, use the 'Skill' tool:**\n\n${bootstrapContent}\n`; + + if (process.env.CURSOR_PLUGIN_ROOT) { + emit({ additional_context: sessionContext }); + } else if (process.env.CLAUDE_PLUGIN_ROOT && !process.env.COPILOT_CLI) { + emit({ + hookSpecificOutput: { + hookEventName: "SessionStart", + additionalContext: sessionContext, + }, + }); + } else { + emit({ additionalContext: sessionContext }); + } +} catch (error) { + const message = error instanceof Error ? error.message : String(error); + process.stderr.write(`${JSON.stringify({ error: `Hyperstack session-start hook failed: ${message}` })}\n`); + process.exit(1); +} diff --git a/install.md b/install.md new file mode 100644 index 0000000..5c607e0 --- /dev/null +++ b/install.md @@ -0,0 +1,325 @@ +# Agent-First Installation Instructions for Hyperstack + +If you are an AI assistant reading this file, please perform the following steps to install Hyperstack on the user's system. You must adapt these steps based on the environment/CLI you are currently running in (e.g., Claude Code, Cursor, Gemini CLI, Copilot CLI, OpenCode, Codex, Windsurf, etc.). + +## Read This First + +If you only remember four things, remember these: + +1. Hyperstack is a harness, not just an MCP server. +2. Both the MCP server and the skills must be installed. +3. The preferred Docker setup is a persistent `hyperstack-mcp` container plus + `docker exec`, not `docker run --rm` per session. +4. Installation is not complete until the MCP server responds and the skills are + visible on disk. + +## What Hyperstack Gives the User + +Three tightly-coupled pieces, installed together: + +1. **An internal harness** - bootstrap, internal role routing, and workflow control. Current internal roles include `main` and `website-builder`. +2. **An MCP server** with 11 plugins and 79 tools - deterministic knowledge for React Flow v12, Motion v12, Lenis, React 19 / Next.js, Echo, Go, Rust, design tokens, UI/UX principles, shadcn/ui (Base UI edition), and the `designer` DESIGN.md pipeline. +3. **A skill system** with 21 skills including adversarial enforcement gates (`blueprint`, `designer`, `forge-plan`, `ship-gate`, `engineering-discipline`) and a SessionStart hook that force-injects the `using-hyperstack` skill at every session start. + +The install steps below wire the public pieces the user actually needs: the MCP +server and the skills. The internal harness is shipped inside the repository and +becomes active through the bootstrap hook and runtime context artifacts. + +If you install only one public piece: + +- MCP only -> the user gets tools without discipline +- skills only -> the user gets prose rules without tools + +## Step 1: Detect Environment + +Determine which CLI or IDE you are currently operating within. This dictates where the skills are cloned and which configuration file holds the MCP server definition. + +## Step 2: Install the Skills + +If the directory already exists (upgrade scenario), pull the latest instead of cloning: + +| Environment | Fresh Install | Upgrade | +|---|---|---| +| **Claude Code** | `git clone https://github.com/orkait/hyperstack.git ~/.claude/skills/hyperstack` | `git -C ~/.claude/skills/hyperstack pull` | +| **Cursor** | `git clone https://github.com/orkait/hyperstack.git ~/.cursor/skills/hyperstack` | `git -C ~/.cursor/skills/hyperstack pull` | +| **Gemini CLI** | `git clone https://github.com/orkait/hyperstack.git ~/.gemini/skills/hyperstack` | `git -C ~/.gemini/skills/hyperstack pull` | +| **Qwen Code** | `git clone https://github.com/orkait/hyperstack.git ~/.qwen/skills/hyperstack` | `git -C ~/.qwen/skills/hyperstack pull` | +| **Copilot CLI** | Use plugin marketplace if available, otherwise clone into the user's configured skills path | Pull in the cloned directory | +| **OpenCode / Codex** | Follow the platform's file-based skill installation path | Pull in the cloned directory | +| **Other** | If your environment supports local file-based skills, clone the repo to the standard skills/extensions directory for your platform. | Pull in the cloned directory | + +**Qwen Code note:** Qwen Code does not have a skill plugin system or SessionStart hook. Skills are cloned to `~/.qwen/skills/hyperstack/` and available on disk for the agent to reference manually (via `read_file` or the agent's own knowledge of the repo structure). The 21 skills are not auto-loaded at session start. + +To handle both cases automatically, use this one-liner (clone if missing, pull if present): + +```bash +SKILLS_DIR="$HOME/.claude/skills/hyperstack" && \ + ([ -d "$SKILLS_DIR" ] && git -C "$SKILLS_DIR" pull || git clone https://github.com/orkait/hyperstack.git "$SKILLS_DIR") +``` + +Replace `~/.claude/skills` with the correct path for the current environment (see table above). For example, on Qwen Code use `~/.qwen/skills/hyperstack`. + +The repository includes a `hooks/session-start.mjs` entrypoint that injects the +generated Hyperstack bootstrap into every session automatically. This is how the +enforcement and internal harness model reach the agent without manual +invocation. On platforms that support `.claude-plugin/hooks.json`, this happens +automatically. On others, the skills are still readable but the hook will not +fire. + +## Step 3: Configure the MCP Server + +Check if Docker is installed and running on the user's system. + +### Option A: Docker (Preferred) + +Hyperstack uses a **persistent container + `docker exec`** pattern. One long-lived container serves every CLI invocation and every session, so container startup cost is paid once - not on every `claude` run. + +**Step 1 - Pull the image:** + +```bash +docker pull ghcr.io/orkait/hyperstack:main +``` + +Pre-pulling is required. MCP servers have a short initialization timeout - if Docker pulls the image on first use it will time out and report as failed. + +**Step 2 - Start the persistent container (one-time setup):** + +If a `hyperstack-mcp` container already exists from a previous install, delete it first to ensure a clean state with the latest image: + +```bash +docker rm -f hyperstack-mcp 2>/dev/null # safe: no-op if container doesn't exist +``` + +Then create the fresh container: + +```bash +docker run -d --name hyperstack-mcp --restart unless-stopped \ + --memory=512m --cpus=1 \ + --entrypoint sleep \ + ghcr.io/orkait/hyperstack:main infinity +``` + +The container stays alive in the background with `sleep infinity` as PID 1. Each MCP session `exec`s a fresh `bun` process inside this container. `--restart unless-stopped` auto-starts the container after Docker restarts. `512m/1 cpu` covers several concurrent sessions. + +**Why delete the old container?** An existing `hyperstack-mcp` container may be running a stale image version, have leftover state from a prior install, or use incorrect resource limits. `docker rm -f` ensures every install starts from a known-good baseline. The `2>/dev/null` suppresses the "no such container" error on first-time installs. + +Verify it's running: + +```bash +docker ps --filter name=hyperstack-mcp +``` + +**Step 3 - Configure the MCP client:** + +Add the following configuration to the appropriate MCP config file for the current environment: + +| Environment | Config File | +|---|---| +| **Claude Code** | `~/.claude.json` | +| **Gemini CLI** | `~/.gemini/config.json` | +| **Qwen Code** | `~/.qwen/settings.json` (global) or `.qwen/settings.json` (project-level) | +| **Cursor / Windsurf / Others** | IDE-specific MCP settings panel or `.mcp.json` in project root | + +```json +{ + "mcpServers": { + "hyperstack": { + "command": "docker", + "args": ["exec", "-i", "hyperstack-mcp", "bun", "/app/src/index.ts"] + } + } +} +``` + +Each CLI invocation spawns a new `bun` process inside the existing `hyperstack-mcp` container - no new container, no startup cost. + +**Important:** Some environments (like Qwen Code) use `settings.json` at the root level rather than a dedicated `.mcp.json` file. The `mcpServers` object goes at the top level of the settings file. Do not nest it inside another key. + +**Name mismatch repair:** If the MCP config references `hyperstack-mcp` but the container has a different name (e.g., a random Docker name like `kind_bouman` from a previous `docker run`), fix it before proceeding: + +```bash +# Find the actual running hyperstack container +ACTUAL_NAME=$(docker ps --filter "ancestor=ghcr.io/orkait/hyperstack:main" --format "{{.Names}}" | head -1) +if [ -n "$ACTUAL_NAME" ] && [ "$ACTUAL_NAME" != "hyperstack-mcp" ]; then + docker rename "$ACTUAL_NAME" hyperstack-mcp + echo "Renamed container '$ACTUAL_NAME' β†’ 'hyperstack-mcp'" +fi +``` + +This is a common issue when the user ran `docker run` directly (without `--name`) before following these instructions, or when the image was pulled under a different container name. The `docker exec` MCP config requires the name to match exactly. + +**Why not `docker run --rm` per session?** `docker run` creates a brand-new container on every invocation. Over several sessions this piles up container state, spends 100–300ms per session on cold startup, and (without proper stdin lifecycle handling) can leave orphaned containers running after Claude exits. The `exec` pattern has none of these problems. + +**Upgrading the image:** + +```bash +docker pull ghcr.io/orkait/hyperstack:main +docker rm -f hyperstack-mcp +docker run -d --name hyperstack-mcp --restart unless-stopped \ + --memory=512m --cpus=1 \ + --entrypoint sleep \ + ghcr.io/orkait/hyperstack:main infinity +``` + +Always delete the old container before creating a new one - the `sleep infinity` pattern means the container never exits, so `docker run` with the same name will fail if the old one still exists. + +Then restart the CLI/IDE so open sessions reconnect to the new container. + +### Option B: Local Bun (Fallback) + +If Docker is NOT available, run the server locally using Bun: + +1. [Install Bun](https://bun.sh) if not already available (`curl -fsSL https://bun.sh/install | bash`) +2. Navigate to the directory where you cloned the repository (e.g., `~/.claude/skills/hyperstack`) +3. Run `bun install` in that directory +4. Add the following to the user's MCP config file, replacing `/absolute/path/to/...` with the actual clone path: + +```json +{ + "mcpServers": { + "hyperstack": { + "command": "bun", + "args": ["/absolute/path/to/hyperstack/bin/hyperstack.mjs"] + } + } +} +``` + +There is no build step. Bun runs TypeScript directly from source. + +## Step 4: Verify Installation + +**Pre-check: confirm the MCP server starts before opening the IDE.** + +For Docker (Option A), first confirm the persistent container is running AND the name matches the config: + +```bash +# Step 1 - Check container is running +docker ps --filter name=hyperstack-mcp + +# Step 2 - If empty, check if a differently-named hyperstack container exists +ACTUAL_NAME=$(docker ps --filter "ancestor=ghcr.io/orkait/hyperstack:main" --format "{{.Names}}" | head -1) +if [ -n "$ACTUAL_NAME" ] && [ "$ACTUAL_NAME" != "hyperstack-mcp" ]; then + docker rename "$ACTUAL_NAME" hyperstack-mcp + echo "Renamed '$ACTUAL_NAME' β†’ 'hyperstack-mcp' - config will now work" +fi +``` + +If no hyperstack container is running at all, go back to Step 2 of Option A. + +Then test the exec path directly: +```bash +echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | docker exec -i hyperstack-mcp bun /app/src/index.ts +``` + +Expected output (server is working): +```json +{"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{"listChanged":true},"resources":{"listChanged":true}},"serverInfo":{"name":"hyperstack","version":"1.0.0"}},"jsonrpc":"2.0","id":1} +``` + +If this command hangs or errors, the MCP server is not working. Fix it before proceeding - the IDE will show the same failure. + +For Local Bun (Option B): +```bash +echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | bun /path/to/hyperstack/bin/hyperstack.mjs +``` + +--- + +Once the pre-check passes, start a fresh session in the target environment (or restart so the SessionStart hook fires). + +**Verification 0: Installation sanity check.** Before trusting the install, run these checks: + +1. **MCP server responds:** Ask the agent to call `designer_list_personalities`. If it returns 6 clusters (premium-precision, technical-developer, warm-editorial, bold-energetic, cinematic-dark, enterprise-trust), the MCP server is connected and working. If the tool is unknown or fails, the MCP config is wrong or the session wasn't restarted. + +2. **Skills are on disk:** Confirm the skills directory exists and has content: + ```bash + ls ~/.claude/skills/hyperstack/skills/ # or ~/.qwen/skills/hyperstack/skills/ for Qwen Code + ``` + Should show 21 directories plus `INDEX.md`. If missing or empty, the clone failed. + +3. **Skills are auto-loaded (platforms with hooks only):** Ask: *"What Hyperstack skills are available?"* The agent should list skills from `skills/INDEX.md` (21 total, grouped into core / domain / meta). On platforms without hook support (e.g., Qwen Code), skip this - skills are on disk but not auto-injected. + +If any of these three checks fail, do not proceed. Fix the issue first: +- MCP tool unknown β†’ verify config file location and JSON syntax, then restart the session +- Skills missing β†’ re-run the clone command and confirm the path +- Skills not auto-loaded β†’ check that the platform supports `.claude-plugin/hooks.json`; if not, this is expected behavior + +--- + +**Verification A: SessionStart hook fires (platforms with hooks only).** On Claude Code and platforms with hook support, the agent should receive the Hyperstack bootstrap at session start. Ask: *"What Hyperstack skills are available?"* The agent should list skills from `skills/INDEX.md` (21 total, grouped into core / domain / meta). On platforms without hook support (e.g., Qwen Code), this step does not apply - skills are on disk but not auto-injected. + +**Verification B: Designer workflow triggers.** Ask: *"Help me design a SaaS dashboard for DevOps engineers."* On platforms with the SessionStart hook, the agent should invoke `hyperstack:designer` BEFORE writing any code. If it jumps straight to JSX, the hook did not fire - restart the client and try again. On platforms without hook support, this step is manual (the agent won't auto-invoke designer). + +If any verification step fails: +- For skill issues: confirm the repo was cloned to the correct skills directory for the environment +- For MCP issues: run the pre-check command above to confirm the server starts independently of the IDE +- For hook issues: confirm the environment supports `.claude-plugin/hooks.json`, otherwise the enforcement is reduced to documentation rather than automatic injection. Platforms without hook support: Qwen Code. + +## Step 5: Inform the User + +Tell the user: +1. Which environment you detected +2. Where the repository was cloned +3. Which MCP config file was updated (Docker or Bun fallback) +4. Whether the SessionStart hook is expected to fire on their platform (yes for Claude Code / platforms with hooks, no for Qwen Code / others) +5. Which verification step they should run first + +If installation failed at any step, report the specific error and what would need to be fixed, rather than claiming success. + +## Troubleshooting + +### MCP server shows as failed on first use + +Most common causes: + +1. **Container name mismatch.** The MCP config says `hyperstack-mcp` but the container has a random Docker name (e.g., `kind_bouman`). Fix: + ```bash + ACTUAL=$(docker ps --filter "ancestor=ghcr.io/orkait/hyperstack:main" --format "{{.Names}}" | head -1) + [ -n "$ACTUAL" ] && [ "$ACTUAL" != "hyperstack-mcp" ] && docker rename "$ACTUAL" hyperstack-mcp + ``` + This is the #1 cause of "tool not found" errors on fresh installs where the user ran `docker run` without `--name` at some point. + +2. **Persistent container not running.** Check: `docker ps --filter name=hyperstack-mcp`. If empty, run Step 2 from Option A to start it. +3. **Image not pulled.** Run `docker pull ghcr.io/orkait/hyperstack:main` and retry. +4. **Wrong container name in config.** The config must use `hyperstack-mcp` as the exec target - must match the `--name` used in Step 2. + +### MCP server shows as failed / cannot pull the Docker image + +Verify the image is accessible: `docker pull ghcr.io/orkait/hyperstack:main` + +If the pull fails, confirm Docker is running and you have an internet connection. The image is public on ghcr.io - no authentication is required to pull it. + +### MCP server starts but tools return no results + +The MCP config file may point to the wrong binary or the server is not running. Verify: +- Docker: run `docker exec -i hyperstack-mcp bun /app/src/index.ts` manually - it should accept JSON-RPC on stdin and respond. If the container isn't running, start it per Step 2 of Option A. +- Local Bun: confirm the absolute path in `args` exists (`ls /path/to/hyperstack/bin/hyperstack.mjs`) +- Restart the CLI/IDE after any config change - MCP servers are loaded at startup +- **Qwen Code:** Uses `~/.qwen/settings.json` (global) or `.qwen/settings.json` (project-level), NOT `.mcp.json`. The `mcpServers` key goes at the root of the settings file. + +### Too many hyperstack containers piling up + +If you see multiple `ghcr.io/orkait/hyperstack` containers running: + +```bash +docker ps -a --filter "ancestor=ghcr.io/orkait/hyperstack:main" +``` + +Your MCP config is using the legacy `docker run --rm` pattern instead of `docker exec`. Clean up and switch to the new config: + +```bash +docker ps -aq --filter "ancestor=ghcr.io/orkait/hyperstack:main" | xargs -r docker rm -f +``` + +Then follow Step 2 of Option A to start the single persistent `hyperstack-mcp` container, and update your MCP config to the `docker exec` form shown in Step 3. + +### SessionStart hook does not fire + +On Claude Code, hooks live in `.claude/hooks.json`. Confirm the file exists in the repository root and references `session-start.mjs`. If the hook is missing or malformed, the `using-hyperstack` skill will not be injected automatically. You can still invoke skills manually with `/using-hyperstack`. + +On Qwen Code, there is no plugin system or hook mechanism. Skills are available on disk at `~/.qwen/skills/hyperstack/skills/INDEX.md` but must be referenced manually by the agent - no auto-injection occurs. + +### `bun: command not found` when using Option B + +Install Bun: `curl -fsSL https://bun.sh/install | bash`, then open a new shell so the path update takes effect. diff --git a/package-lock.json b/package-lock.json index 43c4be8..a2e42cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,20 @@ { - "name": "@orkait-ai/unified-mcp", + "name": "@orkait-ai/hyperstack", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@orkait-ai/unified-mcp", + "name": "@orkait-ai/hyperstack", "version": "1.0.0", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.17.0", + "tsx": "^4.21.0", "zod": "^3.23.0" }, "bin": { - "unified-mcp": "dist/index.js" + "hyperstack": "bin/hyperstack.mjs" }, "devDependencies": { "@types/node": "^20.0.0", @@ -23,6 +24,422 @@ "node": ">=18" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@hono/node-server": { "version": "1.19.11", "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", @@ -349,6 +766,47 @@ "node": ">= 0.4" } }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -507,6 +965,20 @@ "node": ">= 0.8" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -553,6 +1025,18 @@ "node": ">= 0.4" } }, + "node_modules/get-tsconfig": { + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -901,6 +1385,15 @@ "node": ">=0.10.0" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -1085,6 +1578,25 @@ "node": ">=0.6" } }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", diff --git a/package.json b/package.json index 1c11063..1e0bd89 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,26 @@ { - "name": "@orkait-ai/unified-mcp", - "version": "1.0.0", - "description": "Unified MCP server for frontend libraries: React Flow, Motion for React, and more", - "main": "dist/index.js", + "name": "@orkait-ai/hyperstack", + "version": "1.0.1", + "description": "Disciplined MCP server + skill system. 11 plugins, 79 tools, 21 skills with adversarial enforcement. Designer/DESIGN.md pipeline, shadcn/ui, React Flow, Motion, Lenis, React 19, Echo, Go, Rust, design tokens, UI/UX.", "bin": { - "unified-mcp": "dist/index.js" + "hyperstack": "bin/hyperstack.mjs" }, "type": "module", "scripts": { - "build": "tsc", - "start": "node dist/index.js", - "dev": "tsc --watch" + "build": "tsc --noEmit", + "compile:context": "bun src/internal/compile-runtime-context.ts", + "test": "bun test", + "start": "bun src/index.ts", + "dev": "bun --watch src/index.ts" }, "author": "Orkait", "license": "MIT", - "engines": { "node": ">=18" }, + "engines": { + "node": ">=18" + }, "dependencies": { "@modelcontextprotocol/sdk": "^1.17.0", + "tsx": "^4.21.0", "zod": "^3.23.0" }, "devDependencies": { diff --git a/scripts/generate-skills-index.sh b/scripts/generate-skills-index.sh new file mode 100755 index 0000000..ed0fdff --- /dev/null +++ b/scripts/generate-skills-index.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +# Generates skills/INDEX.md from skill frontmatter category fields. +# Run: bash scripts/generate-skills-index.sh +# Categories: core (workflow/discipline), domain (specialized), meta (skills about skills) + +set -uo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +SKILLS_DIR="${REPO_ROOT}/skills" +INDEX="${SKILLS_DIR}/INDEX.md" + +# Collect skills by category +core_list="" +domain_list="" +meta_list="" +uncategorized_list="" + +for dir in "${SKILLS_DIR}"/*/; do + skill_name=$(basename "$dir") + skill_file="${dir}SKILL.md" + [ -f "$skill_file" ] || continue + + category=$(grep "^category:" "$skill_file" 2>/dev/null | head -1 | sed 's/category:[[:space:]]*//' | tr -d '\r') + + # Extract first line of description + desc_line=$(awk '/^description:/{flag=1; sub(/^description:[[:space:]]*/,""); sub(/^>-?/,""); if($0!="") print; flag=1; next} flag && /^ / {sub(/^[[:space:]]+/,""); print; exit} flag && /^[a-z]/ {exit}' "$skill_file" | head -1 | tr -d '"') + desc_short=$(printf '%s' "$desc_line" | cut -c 1-120) + + line="| \`${skill_name}\` | ${desc_short} |" + case "$category" in + core) core_list+="${line}"$'\n' ;; + domain) domain_list+="${line}"$'\n' ;; + meta) meta_list+="${line}"$'\n' ;; + *) uncategorized_list+="${line}"$'\n' ;; + esac +done + +# Write index +cat > "$INDEX" <> "$INDEX" <"$LOCK_FILE" -exec docker exec -i "$CONTAINER" node dist/index.js +exec docker exec -i "$CONTAINER" npx tsx src/index.ts diff --git a/skills/INDEX.md b/skills/INDEX.md new file mode 100644 index 0000000..a1a81b2 --- /dev/null +++ b/skills/INDEX.md @@ -0,0 +1,47 @@ +# Hyperstack Skills Index + +Auto-generated from each skill's frontmatter `category` field. +Regenerate with: `bash scripts/generate-skills-index.sh` + +Categories: +- **core** - workflow, discipline, and gates used on every task +- **domain** - specialized skills for specific contexts (visual, components, security, docs) +- **meta** - skills about skills (bootstrap, testing) + +--- + +## Core (workflow + discipline) + +| Skill | Description | +|---|---| +| `autonomous-mode` | Use when the user chooses fully autonomous execution. Aggressively uses the entire Hyperstack to implement the solution | +| `blueprint` | Use before any feature build, component creation, or behaviour modification. MCP-surveyed design with a hard gate before | +| `code-review` | Use when completing tasks, implementing features, or before merging - to dispatch a review subagent and handle feedback | +| `debug-discipline` | Use when encountering any bug, test failure, or unexpected behaviour. Root cause investigation is mandatory before any f | +| `deliver` | Use after all implementation tasks are complete. Runs final verification, confirms the branch is clean, and executes the | +| `engineering-discipline` | Apply senior-level software engineering discipline including design patterns, SOLID principles, architectural reasoning, | +| `forge-plan` | Use after blueprint design approval to produce a task-by-task implementation plan grounded in MCP-verified API calls. No | +| `parallel-dispatch` | Use when facing 2+ independent tasks that can be investigated or executed without shared state or sequential dependencie | +| `run-plan` | Use when you have an existing plan, spec, or task list to execute. Validates the plan for gaps and MCP accuracy before a | +| `ship-gate` | Use before claiming any work is complete, fixed, or passing. Run the verification command and show output before making | +| `subagent-ops` | Use when executing implementation plans with independent tasks. Dispatches one fresh subagent per task with two-stage re | +| `test-first` | Use when implementing any feature, bug fix, or behaviour change - before writing implementation code. Enforces test-befo | +| `worktree-isolation` | Use when starting feature work that needs isolation from the current workspace, or before executing implementation plans | + +## Domain (specialized context) + +| Skill | Description | +|---|---| +| `behaviour-analysis` | Systematic UI/UX behaviour analysis for interactive applications. Audits every user action, state transition, view mode, | +| `designer` | Evidence-based design decision engine. An intention gate that produces non-slop | +| `design-patterns-skill` | Apply core programming principles and design patterns from Clean Code, The Pragmatic Programmer, Code Complete, Refactor | +| `readme-writer` | Writes or rewrites project README files using repository evidence instead of generic filler. Use when creating a new REA | +| `security-review` | Security code review for vulnerabilities. Use when asked to security review, find vulnerabilities, check for security is | +| `shadcn-expert` | Advanced shadcn/ui architect specializing in Base UI, Tailwind v4, data-slot patterns, and component composition. Use wh | + +## Meta (skills about skills) + +| Skill | Description | +|---|---| +| `testing-skills` | Use when creating or editing Hyperstack skills, before shipping them, to verify they actually work under pressure and re | +| `using-hyperstack` | Bootstrap - establishes Hyperstack MCP tools and skills before any technical work. Auto-loaded at session start via Se | diff --git a/skills/autonomous-mode/SKILL.md b/skills/autonomous-mode/SKILL.md new file mode 100644 index 0000000..9dc8831 --- /dev/null +++ b/skills/autonomous-mode/SKILL.md @@ -0,0 +1,212 @@ +--- +name: autonomous-mode +category: core +description: Use when the user chooses fully autonomous execution. Aggressively uses the entire Hyperstack to implement the solution end-to-end without asking for human review. +--- + +# Autonomous Mode + +## What This Is + +You are unleashed. Execute the full plan end-to-end, aggressively using every Hyperstack MCP tool, web search, and skill to make evidence-backed decisions. You do not ask the user for review, clarification on covered topics, or permission between tasks. You think, you verify, you implement, you move. + +The user gets the finished product. Not questions. Not checkpoints. Not "does this look right?" + +## The Iron Law + +``` +AUTONOMOUS DOES NOT MEAN UNDISCIPLINED. +AUTONOMOUS MEANS YOU ARE THE DISCIPLINE. +``` + +You use the entire Hyperstack aggressively: +- Every MCP tool that could be relevant -- call it +- Every quality gate -- run it yourself +- Every decision point -- make it with evidence, log the reasoning, keep moving +- Every ambiguity -- resolve it using MCP data, web search, codebase patterns, and engineering judgment +- Every uncertainty -- ground it with a deterministic check before proceeding + +You are the senior engineer, the reviewer, the QA, and the decision-maker. The user trusts you to use Hyperstack to its full capacity and deliver a correct solution. + +## When to Use + +- User explicitly chose autonomous execution +- Plan has been approved (via `blueprint` or `run-plan` validation) +- User said something like "just do it", "go ahead", "autonomous", "don't ask, build it" + +## The Autonomous Loop: Reason-Act-Verify + +Every action in autonomous mode follows this tight loop. This is not optional -- it is the structure that prevents drift. + +``` +REASON: State what you're about to do and why (one line, logged in decision log) +ACT: Execute the action (write code, run command, call MCP tool) +VERIFY: Check the result against a deterministic signal (test output, exit code, MCP data, type check) + If PASS β†’ next action + If FAIL β†’ course-correct (see Self-Correction Hierarchy) +``` + +Never skip the VERIFY step. "It looks right" is not verification. A passing test, a zero exit code, a matching MCP output -- those are verification. + +## Process + +### Step 1: Pre-Flight + +Before writing any code: + +1. **Worktree** -- set up a clean workspace via `hyperstack:worktree-isolation` +2. **Aggressive MCP survey** -- for EVERY domain the plan touches, call the MCP tools proactively. Do not wait until you need them. Load ground truth for all relevant APIs upfront: + + | Domain in plan | Call NOW | + |---|---| + | React Flow | `reactflow_search_docs` + `reactflow_list_apis` + `reactflow_get_api` for each component | + | Motion | `motion_search_docs` + `motion_list_apis` | + | Go / Echo | `golang_search_docs` + `echo_list_recipes` + `echo_list_middleware` | + | Rust | `rust_search_docs` + `rust_list_practices` | + | React / Next.js | `react_search_docs` + `react_list_patterns` + `react_get_constraints` | + | Design tokens | `design_tokens_list_categories` + `design_tokens_get_gotchas` | + | UI/UX | `ui_ux_list_principles` + `ui_ux_get_gotchas` | + +3. **Baseline** -- run the full test suite. Record the pass count. This is your before-state. +4. **Task list** -- create tasks from the plan. All visible, all pending. +5. **Decision log** -- start a running log of autonomous decisions. Format: `Decision: [what] | Evidence: [source] | Alternatives rejected: [what and why]`. This log is presented to the user at delivery. + +### Step 2: Execute All Tasks + +For each task in order: + +1. Mark in progress +2. **MCP verify** -- call specific MCP tools for the APIs/patterns used in THIS task. Cross-reference against Step 1 survey. If anything was missed, update now. +3. **Test first** -- write the failing test. Run it. Confirm it fails for the right reason. (Inline `test-first` discipline -- you execute the discipline directly, not via Skill tool.) +4. **Implement** -- write minimal code to pass. Use MCP-verified API shapes. No guessing. +5. **Verify** -- run the test. Run full suite. Zero regressions. Check exit codes, not vibes. +6. **Self-review** -- read your own diff for this task. Check: matches plan? No debug artifacts? No unintended scope? If you spot something wrong, fix it immediately. +7. **Commit** -- atomic commit with descriptive message +8. Mark complete, move to next + +### Self-Correction Hierarchy + +When something goes wrong during execution, follow this hierarchy in order. Each level is tried before escalating to the next. + +``` +Level 1: MCP GROUND TRUTH + Call the relevant MCP tool. The answer is usually in the docs. + +Level 2: CODEBASE PATTERN MATCH + Grep for similar working implementations in the existing codebase. + What works elsewhere that's similar to what's broken? + +Level 3: WEB SEARCH + Search the web for the specific error, API, or pattern. + Use targeted queries: "[library] [version] [specific error or API name]" + Cross-reference results against MCP data -- web results can be outdated. + Prefer: official docs, GitHub issues, Stack Overflow answers with accepted solutions. + Reject: blog posts with no version info, AI-generated content, results for wrong versions. + +Level 4: DEBUG DISCIPLINE + Full root cause investigation via debug-discipline: + Read error in full β†’ reproduce β†’ check recent changes β†’ trace data flow + Form hypothesis β†’ test minimally β†’ fix + If fixed within 2 attempts: continue + If 3rd attempt fails: ABORT (see abort conditions) + +Level 5: ABORT + You've exhausted self-correction. Stop and report to user. +``` + +**Web search is not a first resort.** MCP data is ground truth. Codebase patterns are proven. Web search is for when those two are insufficient -- unfamiliar errors, third-party library quirks, platform-specific issues, or gaps in MCP coverage. + +**Web search IS mandatory when:** +- You encounter an error message you don't recognize and MCP has no relevant data +- You're using a library or API not covered by Hyperstack's MCP namespaces +- The MCP data seems outdated or incomplete for the specific version in use +- You're debugging a platform-specific issue (OS, browser, runtime version) + +### Decision-Making Without the User + +**On ambiguity in the plan:** Do not ask the user. Resolve using: +1. MCP tool output (ground truth) +2. Existing codebase patterns (grep for similar implementations) +3. Web search (if MCP and codebase are insufficient) +4. Engineering judgment (pick the simpler, more maintainable option) +5. Log every decision: `Decision: [what] | Evidence: [source] | Alternatives rejected: [why]` + +**On missing information:** Do not guess. Exhaust the self-correction hierarchy first. If all 4 levels fail, this becomes an abort condition. + +**On style/approach choices:** Follow existing codebase conventions. If no convention exists, pick the simpler option and log it. + +### Step 3: Final Verification + +After all tasks complete: + +1. `git diff ..HEAD` -- full diff review +2. Does the diff match the plan? Fix any drift. +3. Debug artifacts scan: remove console.logs, TODO comments, temporary code +4. Full test suite -- all green +5. Type/lint check -- zero errors +6. Run `hyperstack:ship-gate` -- evidence-backed completion verification + +All of this runs without asking the user anything. + +### Step 4: Deliver + +Invoke `hyperstack:deliver`. This is the ONLY human touchpoint. + +Present the user with: +- Summary of what was built (per-task, one line each) +- **Decision log** -- every autonomous decision with evidence and rejected alternatives +- Test results (before/after pass counts) +- Delivery options (PR / squash / branch) + +## What Runs Automatically (Everything) + +| Gate | How | +|---|---| +| MCP API verification | Aggressively, per-domain upfront + per-task inline | +| Web search | On unfamiliar errors, uncovered APIs, version-specific issues | +| Test-first discipline | Inline, every task, no exceptions | +| Full test suite | After every task + final | +| Debug-discipline | Inline on any failure, up to 3 attempts | +| Self-review | After every task + final diff review | +| Ship-gate | Final gate before delivery | +| Decision logging | Every autonomous choice recorded with evidence | + +## Abort Conditions (the ONLY things that stop you) + +1. **3-strike escalation** -- 3 failed fix attempts on a single task after exhausting the full self-correction hierarchy. Architectural problem you cannot solve alone. Stop and report with full evidence of what you tried. +2. **MCP down for critical domain** -- you cannot verify API shapes and the task requires domain-specific code. Try web search as fallback. If web results are insufficient or untrustworthy, stop and report. +3. **Test suite collapse** -- 3+ unrelated failures after a single task. Something systemic broke. Stop and report. +4. **Scope impossibility** -- you discover the plan requires something fundamentally impossible (missing dependency, incompatible library versions, circular requirement). Stop and report. +5. **Security concern** -- you discover the implementation would introduce a vulnerability (injection, auth bypass, data leak). Stop and report. Never ship insecure code autonomously. +6. **Information exhaustion** -- all 4 levels of self-correction (MCP, codebase, web search, debug-discipline) failed to resolve the issue. Stop and report what you tried at each level. + +**Everything else -- you handle it.** Ambiguity, minor gaps, style decisions, refactoring choices, test strategy -- you decide, you document, you move. + +## Drift Prevention + +Autonomous execution is vulnerable to drift -- gradually deviating from the plan's intent through accumulated small decisions. Prevent this: + +1. **Per-task plan check** -- before starting each task, re-read the plan's requirement for that task. After completing, verify the diff matches the requirement, not your interpretation of it. +2. **Scope fence** -- if you realize a task needs changes outside the plan's listed files, log it as out-of-scope and mention it at delivery. Do not silently expand scope. +3. **Decision log review** -- after every 3 tasks, scan your decision log. Are the decisions trending in a consistent direction, or are you course-correcting against your own earlier decisions? Repeated reversals signal you're drifting. +4. **Deterministic over probabilistic** -- when you can check something with a command (test, type check, lint, MCP call), always do that instead of reasoning about whether it's probably fine. + +## Red Flags -- STOP + +| Thought | Reality | +|---|---| +| "I'll skip the MCP check, I remember the API" | You are in autonomous mode. You have MORE responsibility to verify, not less. | +| "I'll skip the test for this task" | Autonomous does not mean undisciplined. Write the test. | +| "I'll ask the user about this" | Resolve it yourself with evidence. Only abort conditions reach the user. | +| "The test failed, I'll fix it in the next task" | Fix now. Autonomous mode does not carry debt forward. | +| "I'll skip self-review, ship-gate will catch it" | Self-review catches task-level issues. Ship-gate catches composition issues. Both run. | +| "This needs a change outside the plan's scope" | Log it, finish the plan, mention it at delivery. Do not scope-creep. | +| "I'm confused but I'll figure it out as I code" | Stop coding. Hit the self-correction hierarchy: MCP β†’ codebase β†’ web search β†’ debug. | +| "The web search result looks right" | Cross-reference against MCP data and library version. Web results can be outdated. | +| "I've been making a lot of decisions, that's fine" | Review your decision log. Too many decisions may signal plan gaps. | + +## Integration + +- **Requires:** Approved plan from `hyperstack:forge-plan` or validated plan from `hyperstack:run-plan` +- **Uses aggressively:** All MCP tools, web search, `hyperstack:worktree-isolation`, `hyperstack:test-first` (inline), `hyperstack:debug-discipline` (inline on failure), `hyperstack:ship-gate` (final) +- **Completes via:** `hyperstack:deliver` (only human touchpoint) diff --git a/skills/behaviour-analysis/SKILL.md b/skills/behaviour-analysis/SKILL.md new file mode 100755 index 0000000..1b75f3f --- /dev/null +++ b/skills/behaviour-analysis/SKILL.md @@ -0,0 +1,208 @@ +--- +name: behaviour-analysis +category: domain +description: Systematic UI/UX behaviour analysis for interactive applications. Audits every user action, state transition, view mode, and edge case like an experienced QA + UX engineer. Produces a complete interaction matrix with expected vs actual behaviour, finds inconsistencies, dead states, and missing feedback. Use when reviewing UI behaviour, before shipping features, or when something "feels off" but you can't pinpoint why. +compatibility: Requires Read, Grep, Glob, WebSearch tools. Works with any frontend codebase. +metadata: + author: kai + version: "1.0" +--- + +# Behaviour Analysis + +Systematic interaction audit combining UX heuristics, QA state-machine thinking, and developer code-reading. + +## When to Use + +- After implementing a feature with multiple interaction modes +- When the user reports something "doesn't feel right" or "is inconsistent" +- Before shipping - final behavioural review +- When adding a new view mode, action, or state to an existing system + +## Integration with hyperstack:designer + +**If a DESIGN.md exists** (produced by `hyperstack:designer`), use it as the "expected behaviour" ground truth for the interaction matrix in Phase 2. + +Mapping DESIGN.md sections to behaviour-analysis inputs: + +| DESIGN.md Section | Use as... | +|---|---| +| 5. Component Specifications | **Expected states** for each component in the matrix. Every listed state MUST exist and be visually distinct. | +| 6. Motion | **Expected timing** for transitions. The matrix "expected behaviour" column cites DESIGN.md durations. | +| 8. Do's and Don'ts | **Heuristic audit assertions**. Each Do is a check; each Don't is a violation to search for. | +| 9. Responsive Breakpoints | **Composition states** for Phase 4 edge case sweep. Test every listed breakpoint. | +| 10. Anti-Patterns | **Violations to search for** in Phase 4. Fail the audit if any found. | + +**Without a DESIGN.md:** Fall back to industry standards via WebSearch or general heuristics (the default behaviour described below). + +**Reverse escalation:** If the audit finds a gap that the DESIGN.md doesn't specify (e.g., expected behaviour is ambiguous), escalate back to `hyperstack:designer` - the DESIGN.md may need to be updated. + +## Process + +### Phase 1: Inventory (read code, build the map) + +Before judging anything, build a complete picture: + +1. **Identify all state variables** that affect UI behaviour + - Read the store/state management files + - List every piece of state: data, config, transient UI state + - Note which are persisted vs ephemeral + +2. **Identify all user actions** that modify state + - Buttons, clicks, drags, keyboard shortcuts, sliders, toggles + - API calls triggered by actions + - Implicit actions (hover, scroll, resize, mode switch) + +3. **Identify all view modes / display states** + - Tabs, toggles, conditional rendering branches + - How different modes compose (layout mode x view mode x highlight state) + +4. **Identify all feedback mechanisms** + - Visual feedback (highlighting, dimming, borders, badges, glow) + - Textual feedback (labels, counts, status text) + - Animated feedback (transitions, physics, spring effects) + - Absence of feedback (silent failures, no-ops) + +Output: A **state inventory table** and an **action inventory table**. + +### Phase 2: Interaction Matrix (the core analysis) + +Build a matrix: **every action x every relevant state combination**. + +For each cell ask: +- **What should happen?** (expected behaviour - think like a UX designer) +- **What does happen?** (actual behaviour - read the code path) +- **Match?** OK / BUG / UX-ISSUE / MISSING-FEEDBACK + +Structure the matrix by category: + +```markdown +| # | Action | Context/State | Expected | Actual | Status | +|---|--------|---------------|----------|--------|--------| +``` + +Categories to cover: +- **CRUD actions** (create, read, update, delete of primary data) +- **Selection & highlighting** (what gets selected, how, clear) +- **View mode transitions** (switching between modes) +- **Layout mode transitions** (switching layout engines) +- **Configuration changes** (sliders, toggles, settings) +- **Drag & interaction** (drag, hover, click targets) +- **Reset & cleanup** (what gets cleared, what persists) +- **Edge cases** (empty state, max state, conflicting states) + +### Phase 3: Heuristic Audit + +Apply Nielsen's 10 heuristics (adapted for interactive visualizations): + +1. **Visibility of system status** - Does the UI show what's active, selected, loading? +2. **Match between system and real world** - Do labels make sense? Are actions named clearly? +3. **User control and freedom** - Can the user undo/escape from any state? Is there always a way back? +4. **Consistency and standards** - Do similar actions behave the same way everywhere? +5. **Error prevention** - Can the user reach a broken/dead state? +6. **Recognition rather than recall** - Is the current mode/state visible without memorizing? +7. **Flexibility and efficiency** - Are there shortcuts for power users? +8. **Aesthetic and minimalist design** - Is information presented at the right density? +9. **Help users recover from errors** - What happens on API failure, empty results, bad input? +10. **Accessibility** - Keyboard navigation, screen reader, reduced motion? + +Refer to [references/heuristics.md](references/heuristics.md) for detailed questions per heuristic. + +### Phase 4: Edge Case Sweep + +Systematically check: + +**Empty states:** +- No data loaded +- No results +- No highlights active +- Empty search filter results + +**Boundary states:** +- Maximum data (100+ nodes) +- Single node, no edges +- All nodes highlighted +- All sliders at min/max + +**Transition states:** +- Mode switch with active highlights +- Mode switch mid-drag +- Query execution while loading +- Rapid repeated actions (double-click, spam slider) + +**Composition states:** +- Every view mode x every layout mode +- Highlight + search filter active simultaneously +- Collapsed groups + highlighting + path results + +### Phase 5: Report + +Output a structured report: + +```markdown +## State Inventory +[table of all state variables] + +## Action Γ— State Matrix +[full interaction matrix with status] + +## Heuristic Findings +[issues grouped by heuristic, with severity] + +## Edge Cases +[bugs and UX issues found] + +## Verdict +[summary: how many behaviours tested, how many correct, critical issues] +``` + +Severity levels: +- **CRITICAL** - broken functionality, data loss, unreachable state +- **HIGH** - major UX inconsistency, confusing behaviour +- **MEDIUM** - minor inconsistency, missing feedback +- **LOW** - cosmetic, nice-to-have + +## Research Enhancement + +Before starting the analysis, search for: +- Current best practices for the specific UI pattern being analyzed (graph viz, form, dashboard, etc.) +- Known UX patterns for the interaction model (drag-and-drop, force-directed graphs, etc.) +- Accessibility guidelines for the specific component type + +Use findings to set expectations in the matrix - "expected behaviour" should be informed by industry standards, not just gut feeling. + +## Key Principles + +- **Think like a user first** - what would someone expect when they click this? +- **Think like QA second** - what's the worst thing that could happen? +- **Think like a developer third** - read the code to verify, don't assume +- **Every action must have visible feedback** - if clicking something does nothing visibly, that's a bug +- **Every state must be escapable** - the user should never be "stuck" +- **Composition must be tested** - features that work alone often break in combination + +## The Iron Law + +``` +NO BEHAVIOUR CLAIM WITHOUT READING THE CODE PATH +``` + +You cannot say "this should work" - you must trace the actual code path and confirm. Reading code is not optional. Assumptions are bugs waiting to ship. + +## Red Flags - STOP + +These are the rationalizations you will have when you want to skip parts of the analysis. Every one is wrong. + +| Thought | Reality | +|---|---| +| "I'll just check a few interactions, not the full matrix" | Partial coverage misses composition bugs. Do the full matrix. | +| "This state combination is unlikely" | Unlikely states are where bugs live. Test them. | +| "Nielsen's heuristics are common sense" | Common sense is pattern-matching without verification. Apply them explicitly. | +| "I already know this code, I don't need to read it" | Code drifts. Mental models drift faster. Read it. | +| "Empty states are trivial, I'll skip them" | Empty states are the #1 place where products feel broken. Audit them. | +| "Transition states will be fine" | Mid-drag, mid-animation, mid-load states are where race conditions live. Audit them. | +| "The user will report any issues" | Users don't report feeling vague discomfort. They leave. | +| "This is for a simple component, full audit is overkill" | Simple components compose into complex flows. Audit it. | +| "I'll skip heuristics I don't remember exactly" | Open the reference. All 10 get applied. | +| "The behaviour feels right" | Feelings are not evidence. Read the code. | +| "I tested the happy path manually" | The happy path is 20% of the matrix. Audit the unhappy paths. | +| "There is no DESIGN.md, so I have no ground truth" | Search for one. Escalate to designer if missing. Do not audit against gut feeling. | diff --git a/skills/behaviour-analysis/references/heuristics.md b/skills/behaviour-analysis/references/heuristics.md new file mode 100755 index 0000000..881875d --- /dev/null +++ b/skills/behaviour-analysis/references/heuristics.md @@ -0,0 +1,114 @@ +# Heuristic Evaluation Questions + +Detailed questions per Nielsen's heuristic, adapted for interactive data visualizations and modern web apps. + +## 1. Visibility of System Status + +- Is the current view mode clearly indicated (active tab, highlight, selected state)? +- Is there a loading indicator when async operations run? +- Does the active/selected result show a distinct visual treatment? +- When a filter is active, is it obvious that results are filtered? +- Do sliders/toggles show their current value? +- After dragging a node, is the settled state visually clear? +- Is the current layout mode (dagre/cluster) clearly indicated? + +## 2. Match Between System and Real World + +- Do button labels describe what they DO, not what they ARE? ("Clear" not "X") +- Are view mode names intuitive? ("Live" vs "Results" vs "Highlight" - does a new user understand these?) +- Do edge/node labels match the domain vocabulary? +- Are slider labels clear about what they control? + +## 3. User Control and Freedom + +- Can every highlight be cleared? +- Can every mode switch be reversed? +- Can collapsed groups be re-expanded? +- Can the user undo the last action? +- Is there a "reset to defaults" for settings? +- Can the user escape from every state back to a clean view? + +## 4. Consistency and Standards + +- Do all "clear" actions clear the same scope of state? +- Do all click targets have hover states? +- Are all buttons the same size/style for the same level of importance? +- Does clicking behave the same way on result cards, nodes, edges? +- Do both layout modes support the same view modes identically? +- Are keyboard shortcuts consistent with platform conventions? + +## 5. Error Prevention + +- Can slider values be set to break the layout? +- Can the user reach a state where no nodes are visible and there's no indication why? +- Can rapid clicking cause race conditions? +- Does the UI prevent invalid state combinations? +- Are destructive actions (reset, clear all) confirmed or easily undoable? + +## 6. Recognition Rather Than Recall + +- Is the current state visible at all times (not hidden in a menu)? +- Can the user see which result is highlighted without scrolling the results panel? +- Are collapsed group contents summarized (count, kind)? +- Is the search filter text always visible when active? + +## 7. Flexibility and Efficiency + +- Can power users access functions via keyboard? +- Are there shortcuts for common workflows (run + highlight)? +- Can the user adjust layout parameters without opening a dialog? +- Is the most common action the easiest to perform? + +## 8. Aesthetic and Minimalist Design + +- Are controls only shown when relevant? (dagre sliders hidden in cluster mode) +- Is information density appropriate - not too sparse, not overwhelming? +- Are animations purposeful (communicate state change) or decorative (just pretty)? +- Do hover/highlight effects add information or just noise? + +## 9. Help Users Recover from Errors + +- What happens when the API is unreachable? +- What happens when a query returns an error? +- What happens when the graph data is malformed? +- Are error messages actionable ("server unreachable - is it running?")? +- Can the user retry failed operations? + +## 10. Accessibility + +- Can all interactive elements be reached via keyboard (Tab)? +- Do interactive elements have focus indicators? +- Is there sufficient color contrast for all states? +- Do animations respect `prefers-reduced-motion`? +- Are drag interactions achievable without a mouse? +- Do screen readers announce state changes (highlights, mode switches)? +- Are ARIA labels present on non-text interactive elements? + +## Visualization-Specific Heuristics + +Beyond Nielsen's 10, for data visualizations check: + +### Data-Ink Ratio +- Is every visual element carrying information? +- Can any decoration be removed without losing meaning? + +### Gestalt Principles +- Are related nodes visually grouped (proximity, color, enclosure)? +- Do edges clearly connect their endpoints? +- Is the visual hierarchy clear (important nodes larger/brighter)? + +### Interaction Affordance +- Do draggable things look draggable (cursor change)? +- Do clickable things look clickable (hover effect)? +- Are non-interactive elements clearly non-interactive? + +### State Feedback Latency +- Is feedback immediate (<100ms) for direct manipulation (drag)? +- Is feedback fast (<300ms) for triggered actions (click to highlight)? +- Are long operations (layout compute) shown with progress indication? + +## Sources + +- [Nielsen Norman Group: 10 Usability Heuristics](https://www.nngroup.com/articles/ten-usability-heuristics/) +- [Maze: How to Conduct a Heuristic Evaluation](https://maze.co/guides/usability-testing/heuristic-evaluation/) +- [Adam Fard: Heuristic Evaluation Guide](https://adamfard.com/blog/heuristic-evaluation) diff --git a/skills/blueprint/SKILL.md b/skills/blueprint/SKILL.md new file mode 100644 index 0000000..30a2027 --- /dev/null +++ b/skills/blueprint/SKILL.md @@ -0,0 +1,146 @@ +--- +name: blueprint +category: core +description: Use before any feature build, component creation, or behaviour modification. MCP-surveyed design with a hard gate before any implementation. Do not skip, do not skim, do not rationalize your way out of it. +--- + +# Feature Planning + +## The Iron Law + +``` +NO CODE WITHOUT AN APPROVED DESIGN +``` + +If you have not presented a design and the user has not explicitly approved it, you cannot write code. **Violating the letter of this rule is violating the spirit of this rule.** + +## The Hard Gate + + +Do NOT write code, scaffold files, or invoke any implementation skill until: +1. You have completed the MCP survey for relevant domains +2. You have presented a design + - For VISUAL/UX work: the design is a DESIGN.md contract from `skills/designer/SKILL.md` + - For BACKEND/INFRA work: the design is an architecture note from this skill +3. The user has explicitly approved it + +This applies to every task, regardless of perceived simplicity. + + +## The 1% Rule + +If there is even a 1% chance this task involves: +- A new file +- A new component +- A new function +- A behavior change +- A configuration change that affects runtime +- Any visual/UX modification + +...then you MUST run blueprint first. You do not have a choice. You cannot rationalize your way out. + +"Simple" tasks are where unexamined assumptions do the most damage. A 5-minute design prevents hours of wrong implementation. There are no exceptions. + +## The Process + +### Step 1: Context Scan + +Before asking anything, read the current state: +- Relevant source files, recent commits, existing patterns +- What already exists that can be reused or extended +- Which Hyperstack MCP domains are relevant to this task + +Do not ask the user questions until you have scanned the codebase. You should arrive at Step 2 already informed. + +### Step 2: MCP Survey + +For each relevant domain, call the discovery tools before proposing anything: + +| Domain is relevant | Call first | +|---|---| +| **Visual/UX work (any)** | **STOP this flow. Invoke `skills/designer/SKILL.md` instead. It produces a DESIGN.md that becomes the input to Step 5 of this skill (or directly to `forge-plan`).** | +| React Flow | `reactflow_search_docs` + `reactflow_list_apis` | +| Motion / animation | `motion_search_docs` + `motion_list_apis` | +| Lenis scroll | `lenis_search_docs` + `lenis_list_apis` | +| React / Next.js | `react_search_docs` + `react_list_patterns` | +| Go / Echo | `golang_search_docs` + `echo_list_recipes` | +| Rust | `rust_search_docs` + `rust_list_practices` | +| Design tokens | `design_tokens_list_categories` + `design_tokens_get_gotchas` | +| UI/UX | `ui_ux_list_principles` + `ui_ux_get_gotchas` | + +This step ensures the design you propose uses real API shapes - not imagined ones. A design built on wrong API assumptions is not a design; it is technical debt scheduled for delivery. + +**Visual work routing:** If the user's request involves designing a new page, component library, landing page, dashboard, redesign, or any "make it look like X" task - the `designer` skill owns the design gate. Invoke it instead of running Step 4-6 here. Return with a DESIGN.md contract and proceed to handoff (Step 7). + +### Step 3: Clarify Requirements + +Ask clarifying questions one at a time: +- Purpose and success criteria - what does done look like? +- Constraints - performance targets, accessibility requirements, existing patterns to follow +- Scope boundary - what is explicitly NOT included in this task? + +One question per message. Wait for the answer before asking the next one. + +If the request describes multiple independent subsystems, flag this before proceeding. One design β†’ one implementation cycle. Large requests must be decomposed into sub-projects first. + +### Step 4: Propose 2-3 Approaches + +Present options with: +- Trade-offs for each approach +- Which MCP-backed APIs and patterns each approach uses (cite the tool output from Step 2) +- Your recommendation with reasoning + +Lead with your recommended option. Do not present options without a recommendation. + +### Step 5: Present Design + +Scale each section to its complexity: + +- **Architecture** - module boundaries, data flow, key abstractions +- **Invariants** - what must always be true at runtime +- **Interfaces** - public APIs between modules, including types +- **Error paths** - what happens when dependencies fail, inputs are invalid, or async operations time out + +Get user confirmation after presenting. Revise if needed. Do not proceed until the user approves. + +### Step 6: Negative Doubt + +Before finalising, list at least 5 failure modes: + +- What breaks at runtime under normal usage? +- What edge cases does this design not handle? +- Which invariants could be violated by concurrent operations or unexpected state? +- What does the MCP `get_gotchas` data say about this domain? +- What external dependency (API, library version, browser API) could change and break this? + +Address each failure mode explicitly - either design around it or record the accepted risk. + +### Step 7: Handoff to Implementation + +Once the design is approved: +- Save a short design note to the relevant docs directory if the task is non-trivial +- For visual/UX work: DESIGN.md already exists (produced by `designer` skill). Save it at `docs/DESIGN.md` or `/DESIGN.md`. +- Invoke `hyperstack:forge-plan` to build a fully MCP-verified implementation plan from the approved design +- **If DESIGN.md exists:** forge-plan reads it as its input spec. Each of the 10 sections becomes one or more tasks. +- The approved design is the spec - `forge-plan` translates it into traceable tasks, `engineering-discipline` executes them + +## Red Flags - STOP + +These are the exact thoughts you will have when you want to skip this skill. Every one is a rationalization. Every one has been used before to build wrong architectures. Every one has a counter. + +| Thought | Reality | +|---|---| +| "I know React Flow well enough to skip the survey" | MCP data has v12-specific API shapes. Memory has v11. Call the tool. | +| "This is too simple for a design" | Simple tasks are where unexamined assumptions do the most damage. Return to the Hard Gate. | +| "Let me just start with a file and we'll design as we go" | This is how wrong architectures get built. Do the design FIRST. | +| "The user seems impatient, I'll skip Step 6" | User impatience is not permission to ship slop. Negative Doubt is not optional. | +| "I'll propose one approach - the obvious one" | Two approaches exist for every non-trivial design. Find both. | +| "The task is a single-line change" | A single line at the wrong place destroys invariants. Design first. | +| "This is a bug fix, not a feature" | Bug fixes change behavior. Behavior changes need designs. | +| "I'm just refactoring" | Refactors move responsibility. Moving responsibility is architectural. Design first. | +| "The design will slow us down" | No. Wrong code ships. Then you fix it. Then fix it again. That is slow. Design once, ship right. | +| "I can reason about this without external tools" | MCP data contains edge cases and gotchas you will not remember. Call the tool. | +| "The user will tell me if I'm wrong" | The user hired you to prevent that. Do the design. | +| "I already did a similar design last week" | State drifts. Codebase changes. Do the current survey. | +| "This is not my call, I'm just executing instructions" | Executing instructions with no design is how bad instructions become shipped bugs. Design first. | +| "Let me start with a prototype" | Prototypes become production. Design the prototype. | diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md new file mode 100644 index 0000000..5460905 --- /dev/null +++ b/skills/code-review/SKILL.md @@ -0,0 +1,133 @@ +--- +name: code-review +category: core +description: Use when completing tasks, implementing features, or before merging - to dispatch a review subagent and handle feedback with technical rigor. +--- + +# Code Review + +## Two Modes + +This skill covers both sides of code review: + +1. **Requesting** -- dispatching a reviewer subagent to evaluate your work +2. **Receiving** -- handling review feedback with technical rigor, not performative agreement + +## Requesting Review + +### When to Request + +**Mandatory:** +- After each task in `subagent-ops` (handled automatically by that skill) +- After completing a major feature +- Before merge to main + +**Valuable:** +- When stuck (fresh perspective) +- Before refactoring (baseline check) +- After fixing a complex bug + +### How to Dispatch + +**1. Get the diff range:** + +```bash +BASE_SHA=$(git merge-base HEAD main) # or master/develop +HEAD_SHA=$(git rev-parse HEAD) +``` + +**2. Dispatch a review subagent with:** + +- What was implemented (one sentence) +- The requirements or spec it should match +- The git diff (`git diff $BASE_SHA..$HEAD_SHA`) +- Specific question: "Does this match the spec? Flag missing, extra, or incorrect code." + +**Note:** Review subagents receive raw diff and spec only. Do not load bootstrap (`using-hyperstack`) into review subagents -- the `` gate prevents it, and review subagents do not need the full skill catalogue. Provide exactly what they need to evaluate. + +**3. Act on results:** + +| Severity | Action | +|---|---| +| Critical | Fix immediately. Do not proceed. | +| Important | Fix before moving to next task. | +| Minor | Note for later. | +| Disagree | Push back with technical reasoning. | + +### MCP-Enhanced Review + +When reviewing domain-specific code, include MCP verification in the review prompt: + +> "For any React Flow API usage, verify against `reactflow_get_api`. For any Go patterns, verify against `golang_get_practice`. Flag any API usage that doesn't match MCP output." + +This catches API drift that a generic code reviewer would miss. + +## Receiving Review + +### The Response Pattern + +``` +1. READ: Complete feedback without reacting +2. UNDERSTAND: Restate the requirement (or ask) +3. VERIFY: Check against codebase reality +4. EVALUATE: Technically sound for THIS codebase? +5. RESPOND: Technical acknowledgment or reasoned pushback +6. IMPLEMENT: One item at a time, test each +``` + +### Forbidden Responses + +Never respond with: +- "You're absolutely right!" +- "Great point!" +- "Thanks for catching that!" +- Any performative agreement + +Instead: +- Restate the technical requirement +- Ask clarifying questions if unclear +- Push back with reasoning if wrong +- Just fix it (actions over words) + +### When to Push Back + +Push back when: +- Suggestion breaks existing functionality +- Reviewer lacks full context +- Violates YAGNI (unused feature) +- Technically incorrect for this stack +- Conflicts with user's architectural decisions + +**How:** Use technical reasoning, not defensiveness. Reference working tests/code. Involve the user if architectural. + +### Handling Unclear Feedback + +If any item is unclear: **stop.** Do not implement anything yet. Ask for clarification on the unclear items first. + +Items may be related. Partial understanding leads to wrong implementation. + +### Implementation Order + +For multi-item feedback: +1. Clarify anything unclear FIRST +2. Blocking issues (breaks, security) +3. Simple fixes (typos, imports) +4. Complex fixes (refactoring, logic) +5. Test each fix individually +6. Verify no regressions + +## Red Flags -- STOP + +| Thought | Reality | +|---|---| +| "Skip review, it's simple" | Simple code has bugs. Review catches them. | +| "I'll review my own code" | Self-review is not code review. Dispatch a subagent. | +| "Reviewer is wrong, ignore it" | Push back with reasoning. Don't silently ignore. | +| "I agree with everything" | Performative agreement is not technical evaluation. | +| "I'll implement all feedback at once" | One item at a time, test each. | + +## Integration + +- **Called by:** `hyperstack:subagent-ops` (per-task review cycle), `hyperstack:deliver` (pre-merge review) +- **Pairs with:** `hyperstack:ship-gate` (verification after fixes) +- **Escalate to:** User if reviewer and implementer disagree on architectural decisions diff --git a/skills/debug-discipline/SKILL.md b/skills/debug-discipline/SKILL.md new file mode 100644 index 0000000..4b01e62 --- /dev/null +++ b/skills/debug-discipline/SKILL.md @@ -0,0 +1,137 @@ +--- +name: debug-discipline +category: core +description: Use when encountering any bug, test failure, or unexpected behaviour. Root cause investigation is mandatory before any fix attempt. +--- + +# Systematic Debugging + +## The Iron Law + +``` +NO FIXES WITHOUT ROOT CAUSE FIRST. +``` + +A symptom fix is a failure. Random changes are not debugging - they are thrashing. Every fix attempt without a confirmed root cause increases the probability of a second bug. + +**If you have not completed Phase 1, you cannot propose a fix.** + +## When to Use + +Use this for any technical failure: +- Test failures +- Runtime errors or panics +- Unexpected behaviour (wrong output, wrong rendering, wrong state) +- Build failures +- Performance regressions +- Integration issues + +Use it **especially** when: +- Under time pressure - urgency makes guessing tempting +- "The fix is obvious" - obvious fixes often address the wrong layer +- You have already tried something and it did not work +- The error message points to a dependency or library function + +## The Four Phases + +### Phase 1: Root Cause Investigation + +**BEFORE attempting any fix:** + +**1. Read the error in full** +Stack trace, error message, line numbers, exit codes - read every line. Do not skim. The exact wording often contains the fix. + +**2. Reproduce consistently** +Can you trigger it reliably? What are the exact steps? If you cannot reproduce it, do not guess - gather more data first. + +**3. Check recent changes** +`git diff`, recent commits. What changed that could have caused this? Assume the most recent change is guilty until proven otherwise. + +**4. Check MCP docs for the failing domain** + +Before assuming you understand how a library or API behaves, verify: + +| Domain | What to call | +|---|---| +| React Flow component behaves unexpectedly | `reactflow_get_api` for the component, `reactflow_get_pattern` for the usage pattern | +| Go runtime error (goroutine, context, nil pointer) | `golang_get_practice` for the relevant topic | +| Rust borrow checker / lifetime error | `rust_get_practice` + `rust_cheatsheet` | +| Echo middleware or routing issue | `echo_get_middleware` or `echo_get_recipe` | +| Motion animation not firing | `motion_get_api` for the failing hook or component | +| CSS/token rendering wrong | `design_tokens_get_gotchas` or `ui_ux_get_gotchas` | + +The MCP gotchas data frequently contains the exact failure mode you are looking at. Check it before forming a hypothesis. + +**5. Trace the data flow** + +Where does the bad value originate? Trace backwards from the symptom to the source. Add diagnostic logging at each layer boundary if needed. Run once to see which layer breaks. Then investigate that specific layer. + +Fix at the source. Never at the symptom. + +### Phase 2: Pattern Analysis + +Before writing a fix, find the correct pattern: + +1. Locate similar working code in the same codebase +2. Compare the failing code against the working example - list every difference, however small +3. Check the MCP reference for the correct pattern (`[domain]_get_pattern`) +4. Understand what the failing code assumed that the working code does not + +### Phase 3: Hypothesis and Test + +Scientific method - one variable at a time: + +1. **State the hypothesis explicitly:** "I believe X is the root cause because Y" +2. **Design the minimal test:** the smallest change that would confirm or refute the hypothesis +3. **Make one change** - do not bundle multiple fixes +4. **Verify the result:** + - Confirms hypothesis β†’ Phase 4 + - Refutes hypothesis β†’ form a new hypothesis, return to top of Phase 3 (count this as a failed attempt) + - After 2 refuted hypotheses: return to Phase 1 with all new information before forming another hypothesis + - After 3 failed hypotheses total: stop - go directly to the Escalation Rule below + - Do NOT stack a second change on top of a failed one + +If you genuinely do not know what the root cause is after Phase 1 and 2, say so explicitly. "I don't understand why X behaves this way" is correct. Proposing a fix you don't understand is not. + +### Phase 4: Fix + +Fix the root cause. Not the symptom. + +1. **Write a failing test first** - the simplest possible reproduction. Run it. Confirm it fails. +2. **Implement one fix** - address the confirmed root cause. One change. +3. **Run the test** - confirm it now passes. +4. **Check for regressions** - run the full test suite. +5. **Invoke `hyperstack:ship-gate`** before claiming the bug is fixed. + +**Attempt counter - mandatory:** +- Attempts 1-2: if the fix does not work, return to Phase 1 with the new information +- **Attempt 3: STOP. Do not attempt a fourth fix.** + +### Escalation Rule (3+ Failed Fixes) + +Three failed attempts signals an architectural problem, not a surface bug. + +Diagnostic pattern: +- Each fix reveals new coupling or unexpected shared state in a different location +- The correct fix would require "significant refactoring" - which means the current structure cannot accommodate the correct behaviour +- Each fix creates a new symptom elsewhere + +At this point, stop fixing. Present the findings to the user: what you tried, what each attempt revealed, and what architectural change appears to be required. Do not continue patching. + +## Red Flags - STOP + +| Thought | Reality | +|---|---| +| "Let me just try changing X" | You do not have a root cause | +| "It's probably a race condition" | "Probably" is not a root cause | +| "Quick fix now, investigate later" | There is no later | +| "Multiple small changes at once" | You cannot isolate what worked | +| "The library is broken" | Check the MCP docs first | +| "One more attempt" (after 2 failures) | Stop. Escalate. | +| "I fixed it - the error is gone" | Run `hyperstack:ship-gate` | + +## Integration + +- Use `hyperstack:ship-gate` before claiming any bug is fixed +- Use `hyperstack:engineering-discipline` if Phase 4 escalation reveals an architectural change is needed +- Use `hyperstack:blueprint` if the fix requires building new functionality rather than correcting existing behaviour diff --git a/skills/deliver/SKILL.md b/skills/deliver/SKILL.md new file mode 100644 index 0000000..6eb268c --- /dev/null +++ b/skills/deliver/SKILL.md @@ -0,0 +1,100 @@ +--- +name: deliver +category: core +description: Use after all implementation tasks are complete. Runs final verification, confirms the branch is clean, and executes the chosen delivery method. +--- + +# Deliver + +## When to Use + +After every task in the implementation plan is marked complete and all verification has passed. This is the terminal state of every Hyperstack workflow. + +Do NOT invoke this skill until all tasks are done. It is a gate, not a shortcut. + +## The Process + +### Step 1: Full Verification + +Run the complete test suite. Not a subset. Not the tests you just wrote. All of them. + +Show the output. If anything fails, stop here - invoke `hyperstack:debug-discipline` and resolve before continuing. + +### Step 2: Type / Lint Check + +Run the appropriate check for the project's language: + +| Language | Command | +|---|---| +| TypeScript / Next.js | `npx tsc --noEmit` | +| Rust | `cargo check` | +| Go | `go vet ./...` | +| Python | `mypy .` (if configured) | + +Zero errors required. Warnings are acceptable if pre-existing and documented. + +### Step 3: Diff Review + +Run `git diff ..HEAD` where `` is main, master, or develop - whichever this branch was cut from. + +Check: +- Does the diff match the plan or approved design? +- Are there any unintended changes (modified files outside the plan's scope)? +- Are there any debug statements, console.logs, or temporary code left in? + +If anything is unintended, revert it before continuing. + +### Step 4: Ship Gate + +Invoke `hyperstack:ship-gate` on the overall implementation. + +Do not skip this. Passing individual task verifications does not replace a final gate on the whole. + +### Step 5: Present Options + +Once Steps 1-4 pass, present the delivery options to the user: + +> "All verification passed. How do you want to deliver this? +> +> 1. **PR** - push branch and open a pull request (`gh pr create`) +> 2. **Squash** - squash all commits into one and merge +> 3. **Leave as branch** - push branch only, no PR yet" + +Wait for the user's choice. + +### Step 6: Execute + +Execute exactly the chosen option. Do not add steps. Do not clean up other things "while you're at it." + +**Option 1 - PR:** +```bash +git push -u origin [branch-name] +gh pr create --title "[feature name]" --body "[summary of changes]" +``` + +**Option 2 - Squash:** +```bash +git checkout main +git merge --squash [branch-name] +git commit -m "[single descriptive commit message]" +``` + +**Option 3 - Leave as branch:** +```bash +git push -u origin [branch-name] +``` + +## Red Flags - STOP + +| Thought | Reality | +|---|---| +| "Tests mostly pass, I'll fix the rest in a follow-up" | No. Fix them now or don't deliver. | +| "The type errors are pre-existing" | Verify with `git stash` - if they existed before your change, document it. If not, fix them. | +| "I'll skip ship-gate, I just ran individual verifications" | Individual gates do not cover composition. Run ship-gate. | +| "Let me also clean up X while I'm here" | Scope creep. Out-of-plan changes go on a new branch. | + +## Integration + +- **Requires:** All tasks in `forge-plan` or `run-plan` complete and individually verified (via `autonomous-mode`, `subagent-ops`, or `engineering-discipline`) +- **Requires:** `hyperstack:ship-gate` passing on full implementation +- **Invoked after:** `hyperstack:autonomous-mode`, `hyperstack:subagent-ops`, or `hyperstack:engineering-discipline` completes diff --git a/skills/design-patterns-skill/SKILL.md b/skills/design-patterns-skill/SKILL.md new file mode 100755 index 0000000..3da446b --- /dev/null +++ b/skills/design-patterns-skill/SKILL.md @@ -0,0 +1,125 @@ +--- +name: design-patterns-skill +category: domain +description: Apply core programming principles and design patterns from Clean Code, The Pragmatic Programmer, Code Complete, Refactoring, and Design Patterns. Use when writing code, reviewing PRs, refactoring, or designing system architecture. +triggers: + - "code review" + - "design pattern" + - "refactor" + - "clean code" + - "SOLID" + - "code quality" + - "architecture design" + - "code generation" +activation: + mode: fuzzy + priority: normal + triggers: + - "code review" + - "design pattern" + - "refactor" + - "clean code" + - "SOLID" + - "code quality" + - "architecture design" + - "code generation" +compatibility: ">=1.0.0" +metadata: + version: "1.0.0" +references: + - references/patterns/readability.md + - references/patterns/simplicity.md + - references/patterns/design-architecture.md + - references/patterns/testing.md + - references/patterns/error-handling.md + - references/patterns/maintainability.md +--- + +# Design Patterns & Programming Principles + +## Overview + +Structured guidance on programming principles and design patterns from foundational software engineering books. Ensures code follows industry-standard practices for readability, maintainability, simplicity, and architectural soundness. + +## When to Apply + +- **Code Generation:** Writing new functions, classes, or modules +- **Code Review:** Evaluating pull requests or existing codebases +- **Refactoring:** Improving code structure and clarity +- **Architecture Design:** Choosing appropriate patterns and abstractions + +--- + +## Core Philosophy + +1. **Readability over cleverness** - Code is read more than written +2. **Simplicity over complexity** - Use the simplest solution that works +3. **Testability by design** - Write code that's easy to test +4. **Incremental improvement** - Leave code better than you found it +5. **Patterns as tools** - Apply patterns when they clarify, not by default + +--- + +## Principle Categories + +### 1. Readability & Clarity +- Descriptive naming, consistent formatting, self-documenting code, small focused functions +- **Reference:** `references/patterns/readability.md` + +### 2. Simplicity & Efficiency +- KISS, DRY, YAGNI +- **Reference:** `references/patterns/simplicity.md` + +### 3. Design & Architecture +- SRP, composition over inheritance, program to interfaces +- Patterns: Factory, Strategy, Observer, Decorator, Adapter, Command, Singleton +- **Reference:** `references/patterns/design-architecture.md` + +### 4. Testing & Quality +- Automated testing, focused assertions, edge case coverage +- **Reference:** `references/patterns/testing.md` + +### 5. Error Handling +- Clear error messages, early validation, proper exception usage +- **Reference:** `references/patterns/error-handling.md` + +### 6. Maintainability +- Boy Scout Rule, continuous refactoring, atomic commits, automation +- **Reference:** `references/patterns/maintainability.md` + +--- + +## AI-Specific Guidance + +When generating or reviewing code, always: +1. Check for AI pitfalls listed in each principle +2. Avoid pattern prediction bias - don't use patterns just because they're common +3. Question generic naming - resist `data`, `temp`, `result` without context +4. Validate edge cases - don't skip error handling +5. Keep functions focused - resist combining unrelated operations +6. Match project conventions - maintain consistency with existing codebase + +--- + +## Quick Reference + +| Situation | Apply | +|-----------|-------| +| Function > 20 lines | Split into smaller functions (SRP) | +| Repeated code blocks | Extract to function/constant (DRY) | +| Complex conditionals | Strategy or State pattern | +| Object creation logic | Factory pattern | +| Cross-cutting concerns | Decorator or Observer pattern | +| Incompatible interfaces | Adapter pattern | +| Need undo/logging | Command pattern | +| Global access point | Singleton (use sparingly) | + +--- + +## Sources + +- *Clean Code* - Robert C. Martin +- *The Pragmatic Programmer* - Andrew Hunt & David Thomas +- *Code Complete* - Steve McConnell +- *Refactoring* - Martin Fowler +- *Design Patterns* - Gang of Four diff --git a/skills/design-patterns-skill/references/misc/overview.md b/skills/design-patterns-skill/references/misc/overview.md new file mode 100755 index 0000000..4bf7af1 --- /dev/null +++ b/skills/design-patterns-skill/references/misc/overview.md @@ -0,0 +1,170 @@ +# Design Patterns & Programming Principles Skill + +A comprehensive Kiro skill that provides structured guidance on programming principles and design patterns from foundational software engineering books. + +## Overview + +This skill encapsulates best practices from: +- *Clean Code* by Robert C. Martin +- *The Pragmatic Programmer* by Andrew Hunt & David Thomas +- *Code Complete* by Steve McConnell +- *Refactoring* by Martin Fowler +- *Design Patterns* by Gang of Four + +## Installation + +### For Workspace (Project-Specific) +```bash +mkdir -p .kiro/skills +cp -r design-patterns .kiro/skills/ +``` + +### For Global (All Projects) +```bash +mkdir -p ~/.kiro/skills +cp -r design-patterns ~/.kiro/skills/ +``` + +## Structure + +``` +design-patterns/ +β”œβ”€β”€ SKILL.md # Main skill definition +β”œβ”€β”€ README.md # This file +└── references/ + β”œβ”€β”€ readability.md # Naming, formatting, documentation + β”œβ”€β”€ simplicity.md # KISS, DRY, YAGNI principles + β”œβ”€β”€ design-architecture.md # SRP, patterns, composition + β”œβ”€β”€ testing.md # Testing strategies and best practices + β”œβ”€β”€ error-handling.md # Validation, exceptions, recovery + └── maintainability.md # Refactoring, commits, automation +``` + +## Usage + +The skill activates automatically when: +- Writing new code +- Reviewing pull requests +- Refactoring existing code +- Designing system architecture +- Assisting with AI code generation + +## Principle Categories + +### 1. Readability & Clarity +- Descriptive naming conventions +- Consistent code formatting +- Self-documenting code principles +- Small, focused functions + +### 2. Simplicity & Efficiency +- KISS (Keep It Simple, Stupid) +- DRY (Don't Repeat Yourself) +- YAGNI (You Aren't Gonna Need It) +- Avoiding premature optimization + +### 3. Design & Architecture +- Single Responsibility Principle (SRP) +- Composition over Inheritance +- Program to Interfaces +- Essential Design Patterns: + - Factory Pattern + - Strategy Pattern + - Observer Pattern + - Decorator Pattern + - Adapter Pattern + - Command Pattern + - Singleton Pattern + +### 4. Testing & Quality +- Test-driven development approach +- Focused test assertions +- Test pyramid (unit/integration/e2e) +- Mocking and test doubles + +### 5. Error Handling +- Clear error messages +- Early input validation +- Exception hierarchies +- Recovery strategies + +### 6. Maintainability +- Boy Scout Rule +- Continuous refactoring +- Incremental commits +- Automation and tooling + +## AI-Specific Guidance + +This skill includes specific guidance for AI code generation, helping avoid common pitfalls such as: +- Generic naming (`data`, `temp`, `result`) +- Over-commenting obvious code +- Skipping edge case validation +- Applying patterns unnecessarily +- Creating monolithic functions +- Duplicating code structures + +## Quick Reference Examples + +### Before & After + +**Poor Code:** +```python +def proc(u): + if u['age'] < 13: return False + db.save(u) + email.send(u['email'], 'Welcome') + return True +``` + +**Improved Code:** +```python +def is_eligible_user(user): + return user['age'] >= 13 + +def save_user(user): + db.save(user) + +def send_welcome_email(user): + email.send(user['email'], 'Welcome to the platform') + +def register_user(user): + if not is_eligible_user(user): + raise ValueError('User must be 13 or older') + save_user(user) + send_welcome_email(user) +``` + +## When to Apply + +| Situation | Recommended Principle/Pattern | +|-----------|------------------------------| +| Function > 20 lines | Split using SRP | +| Repeated code blocks | Extract with DRY | +| Complex conditionals | Strategy or State pattern | +| Object creation complexity | Factory pattern | +| Cross-cutting concerns | Decorator or Observer | +| Incompatible interfaces | Adapter pattern | +| Need undo/logging | Command pattern | + +## Contributing + +This skill is structured to be easily extended. To add new principles or patterns: + +1. Update the relevant reference file in `references/` +2. Add a cross-reference in `SKILL.md` +3. Include examples with "Do", "Don't", and "AI Pitfalls" sections + +## License + +This skill is based on principles from publicly available software engineering literature and industry best practices. + +## Additional Resources + +- [The 7 Most Important Software Design Patterns](https://learningdaily.dev/the-7-most-important-software-design-patterns-d60e546afb0e) +- [Refactoring Guru - Design Patterns](https://refactoring.guru/design-patterns) +- [SOLID Principles](https://en.wikipedia.org/wiki/SOLID) + +## Version + +1.0.0 - Initial release diff --git a/skills/design-patterns-skill/references/patterns/design-architecture.md b/skills/design-patterns-skill/references/patterns/design-architecture.md new file mode 100755 index 0000000..fc1cd6c --- /dev/null +++ b/skills/design-patterns-skill/references/patterns/design-architecture.md @@ -0,0 +1,477 @@ +# Design & Architecture Principles + +## Single Responsibility Principle (SRP) + +**Definition:** Each class or module should have only one reason to change. It should encapsulate one cohesive responsibility. + +**Supported by:** *Clean Code*, *The Pragmatic Programmer*, SOLID Principles + +### Examples + +```python +# Bad - Multiple responsibilities +class User: + def __init__(self, name, email): + self.name = name + self.email = email + + def save_to_database(self): + # Database logic + pass + + def send_welcome_email(self): + # Email logic + pass + + def generate_report(self): + # Reporting logic + pass + +# Good - Separated concerns +class User: + def __init__(self, name, email): + self.name = name + self.email = email + +class UserRepository: + def save(self, user): + # Database logic + pass + +class EmailService: + def send_welcome(self, user): + # Email logic + pass + +class UserReportGenerator: + def generate(self, user): + # Reporting logic + pass +``` + +### Do +- Encapsulate related data and behavior +- Separate concerns (data access, business logic, presentation) +- Create cohesive modules +- Make reasons for change explicit + +### Don't +- Mix data access, logic, and UI in one class +- Create "god objects" that do everything +- Couple unrelated functionality + +### AI Pitfalls +- Cramming multiple operations into one class +- Creating utility classes with unrelated methods +- Mixing infrastructure and domain logic + +--- + +## Composition Over Inheritance + +**Definition:** Prefer combining objects to form behavior over creating deep class hierarchies. Favor "has-a" relationships over "is-a". + +**Supported by:** *The Pragmatic Programmer*, *Design Patterns* + +### Examples + +```python +# Bad - Rigid inheritance hierarchy +class Bird: + def fly(self): + return "Flying" + +class Penguin(Bird): + def fly(self): + raise Exception("Penguins cannot fly") + +# Good - Composition with behavior injection +class FlyBehavior: + def fly(self): + pass + +class CanFly(FlyBehavior): + def fly(self): + return "Flying" + +class CannotFly(FlyBehavior): + def fly(self): + return "Cannot fly" + +class Bird: + def __init__(self, fly_behavior): + self.fly_behavior = fly_behavior + + def perform_fly(self): + return self.fly_behavior.fly() + +# Usage +sparrow = Bird(CanFly()) +penguin = Bird(CannotFly()) +``` + +### Do +- Use interfaces or protocols to define contracts +- Inject dependencies and behaviors +- Compose small, focused objects +- Favor delegation over inheritance + +### Don't +- Create deep inheritance hierarchies (>3 levels) +- Inherit just to override behavior +- Use inheritance for code reuse alone +- Force unnatural "is-a" relationships + +### AI Pitfalls +- Defaulting to inheritance for code reuse +- Creating rigid class hierarchies +- Not recognizing when composition is clearer + +--- + +## Program to an Interface, Not an Implementation + +**Definition:** Depend on abstractions (interfaces, protocols) rather than concrete implementations. This enables flexibility and testability. + +**Supported by:** *Design Patterns*, *Code Complete*, Dependency Inversion Principle + +### Examples + +```python +# Bad - Depends on concrete implementation +class OrderProcessor: + def __init__(self): + self.payment = StripePayment() # Hard-coded dependency + + def process(self, order): + self.payment.charge(order.total) + +# Good - Depends on abstraction +class PaymentProcessor: + def charge(self, amount): + raise NotImplementedError + +class StripePayment(PaymentProcessor): + def charge(self, amount): + # Stripe-specific logic + pass + +class PayPalPayment(PaymentProcessor): + def charge(self, amount): + # PayPal-specific logic + pass + +class OrderProcessor: + def __init__(self, payment_processor: PaymentProcessor): + self.payment = payment_processor + + def process(self, order): + self.payment.charge(order.total) + +# Usage - Easy to swap implementations +processor = OrderProcessor(StripePayment()) +# or +processor = OrderProcessor(PayPalPayment()) +``` + +### Do +- Define interfaces for key abstractions +- Inject dependencies via constructors +- Use dependency injection frameworks when appropriate +- Code against contracts, not implementations + +### Don't +- Hard-code concrete class names +- Use `isinstance()` checks to switch behavior +- Create tight coupling to specific implementations + +### AI Pitfalls +- Using fixed class names instead of interfaces +- Not recognizing opportunities for abstraction +- Creating concrete dependencies in constructors + +--- + +## Essential Design Patterns + +### Factory Pattern + +**Purpose:** Delegate object creation to factory methods or classes. Decouples client code from concrete instantiation. + +**Use when:** Object creation is complex or varies based on conditions. + +```python +# Example +class LoggerFactory: + @staticmethod + def get_logger(log_type): + if log_type == "file": + return FileLogger() + elif log_type == "console": + return ConsoleLogger() + elif log_type == "cloud": + return CloudLogger() + else: + raise ValueError(f"Unknown logger type: {log_type}") + +# Usage +logger = LoggerFactory.get_logger("file") +logger.log("Application started") +``` + +### Strategy Pattern + +**Purpose:** Define a family of interchangeable algorithms and make them swappable at runtime. + +**Use when:** You need different behaviors for the same operation. + +```python +# Example +class SortStrategy: + def sort(self, data): + raise NotImplementedError + +class QuickSort(SortStrategy): + def sort(self, data): + # Quick sort implementation + pass + +class MergeSort(SortStrategy): + def sort(self, data): + # Merge sort implementation + pass + +class DataProcessor: + def __init__(self, sort_strategy: SortStrategy): + self.sorter = sort_strategy + + def process(self, data): + sorted_data = self.sorter.sort(data) + return sorted_data + +# Usage +processor = DataProcessor(MergeSort()) +result = processor.process([3, 1, 4, 1, 5]) +``` + +### Observer Pattern + +**Purpose:** Define a one-to-many dependency where changes in one object notify all dependents automatically. + +**Use when:** Multiple objects need to react to state changes. + +```python +# Example +class Subject: + def __init__(self): + self._observers = [] + + def attach(self, observer): + self._observers.append(observer) + + def notify(self, event): + for observer in self._observers: + observer.update(event) + +class Observer: + def update(self, event): + raise NotImplementedError + +class EmailNotifier(Observer): + def update(self, event): + print(f"Sending email for: {event}") + +class SlackNotifier(Observer): + def update(self, event): + print(f"Posting to Slack: {event}") + +# Usage +order_system = Subject() +order_system.attach(EmailNotifier()) +order_system.attach(SlackNotifier()) +order_system.notify("Order #123 shipped") +``` + +### Decorator Pattern + +**Purpose:** Dynamically add responsibilities to objects without modifying their class. + +**Use when:** You need flexible, composable enhancements. + +```python +# Example +class Notifier: + def send(self, message): + raise NotImplementedError + +class BasicNotifier(Notifier): + def send(self, message): + print(f"Basic notification: {message}") + +class NotifierDecorator(Notifier): + def __init__(self, notifier: Notifier): + self._notifier = notifier + + def send(self, message): + self._notifier.send(message) + +class SlackDecorator(NotifierDecorator): + def send(self, message): + super().send(message) + print(f"Also sent to Slack: {message}") + +class EmailDecorator(NotifierDecorator): + def send(self, message): + super().send(message) + print(f"Also sent via email: {message}") + +# Usage - Compose behaviors +notifier = EmailDecorator(SlackDecorator(BasicNotifier())) +notifier.send("System alert") +``` + +### Adapter Pattern + +**Purpose:** Convert one interface into another that clients expect. Enables incompatible interfaces to work together. + +**Use when:** Integrating legacy systems or third-party libraries. + +```python +# Example +class LegacyPrinter: + def print_text(self, text): + print(f"[LEGACY] {text}") + +class ModernPrinter: + def print(self, content): + raise NotImplementedError + +class PrinterAdapter(ModernPrinter): + def __init__(self, legacy_printer: LegacyPrinter): + self.legacy = legacy_printer + + def print(self, content): + self.legacy.print_text(content) + +# Usage +old_printer = LegacyPrinter() +adapter = PrinterAdapter(old_printer) +adapter.print("Hello World") # Uses modern interface, delegates to legacy +``` + +### Command Pattern + +**Purpose:** Encapsulate a request as an object, enabling queuing, logging, or undoable operations. + +**Use when:** You need to queue operations, support undo/redo, or log actions. + +```python +# Example +class Command: + def execute(self): + raise NotImplementedError + + def undo(self): + raise NotImplementedError + +class Light: + def on(self): + print("Light is ON") + + def off(self): + print("Light is OFF") + +class LightOnCommand(Command): + def __init__(self, light: Light): + self.light = light + + def execute(self): + self.light.on() + + def undo(self): + self.light.off() + +class LightOffCommand(Command): + def __init__(self, light: Light): + self.light = light + + def execute(self): + self.light.off() + + def undo(self): + self.light.on() + +# Usage +living_room_light = Light() +light_on = LightOnCommand(living_room_light) +light_on.execute() # Light is ON +light_on.undo() # Light is OFF +``` + +### Singleton Pattern + +**Purpose:** Ensure only one instance of a class exists globally. + +**Use when:** You need a single point of access (e.g., config, logger, connection pool). + +**Caution:** Often overused. Consider dependency injection instead. + +```python +# Example +class Singleton: + _instance = None + + def __new__(cls): + if cls._instance is None: + cls._instance = super().__new__(cls) + return cls._instance + +class ConfigManager(Singleton): + def __init__(self): + if not hasattr(self, 'initialized'): + self.config = {} + self.initialized = True + +# Usage +config1 = ConfigManager() +config2 = ConfigManager() +assert config1 is config2 # Same instance +``` + +--- + +## Pattern Usage Guidelines + +### Do +- Apply patterns when they improve clarity and flexibility +- Choose patterns based on structural fit +- Use patterns to communicate design intent +- Combine patterns when appropriate + +### Don't +- Force patterns into simple code +- Use patterns for the sake of patterns +- Apply patterns without understanding the problem +- Over-abstract with unnecessary pattern layers + +### AI Pitfalls +- Predicting patterns where none are needed +- Misnaming pattern roles (e.g., calling a simple factory a "Factory Pattern") +- Misapplying pattern intent (e.g., Singleton for everything) +- Creating pattern boilerplate without actual benefit + +--- + +## Summary + +Good architecture is: +- **Modular** - clear boundaries and responsibilities +- **Flexible** - uses composition and interfaces +- **Abstract** - depends on contracts, not implementations +- **Pattern-aware** - applies proven solutions appropriately + +When designing systems, ask: +- Does each module have one clear responsibility? +- Can I swap implementations easily? +- Am I using inheritance or composition? +- Does this pattern solve a real structural problem? diff --git a/skills/design-patterns-skill/references/patterns/error-handling.md b/skills/design-patterns-skill/references/patterns/error-handling.md new file mode 100755 index 0000000..1b1c25f --- /dev/null +++ b/skills/design-patterns-skill/references/patterns/error-handling.md @@ -0,0 +1,364 @@ +# Error Handling & Input Validation + +## Handle Errors Clearly + +**Definition:** Use exceptions for unexpected states and provide clear error messages. Fail early and explicitly rather than allowing silent failures. + +**Supported by:** *Code Complete*, *Clean Code*, *The Pragmatic Programmer* + +### Examples + +```python +# Bad - Silent failure +def divide(a, b): + if b == 0: + return None # Caller has to check for None + return a / b + +# Good - Explicit error +def divide(a, b): + if b == 0: + raise ValueError("Cannot divide by zero") + return a / b +``` + +```python +# Bad - Vague error message +def process_user(user): + if not user: + raise Exception("Error") + +# Good - Descriptive error message +def process_user(user): + if user is None: + raise ValueError("User object cannot be None") + if not user.email: + raise ValueError(f"User {user.id} must have a valid email address") +``` + +### Do +- Use exceptions for exceptional conditions +- Provide descriptive error messages +- Include context (what failed, why, what was expected) +- Fail fast - validate inputs early +- Use specific exception types +- Document what exceptions can be raised + +### Don't +- Return None or -1 as error codes +- Swallow exceptions silently +- Use exceptions for control flow +- Provide generic error messages ("Error occurred") +- Catch exceptions you can't handle + +### AI Pitfalls +- Skipping edge-case validation +- Empty except blocks: `except: pass` +- Returning default values instead of raising errors +- Generic exception types instead of specific ones + +--- + +## Validate Inputs Early + +**Definition:** Check preconditions at the entry point of functions. Reject invalid input before processing. + +**Supported by:** *Code Complete*, *Clean Code* + +### Examples + +```python +# Bad - Late validation, partial processing +def register_user(username, email, age): + user = User(username, email, age) + save_to_database(user) + if age < 18: # Too late - already saved! + raise ValueError("User must be 18 or older") + +# Good - Early validation +def register_user(username, email, age): + if not username or len(username) < 3: + raise ValueError("Username must be at least 3 characters") + if not email or '@' not in email: + raise ValueError("Invalid email address") + if age < 18: + raise ValueError("User must be 18 or older") + + user = User(username, email, age) + save_to_database(user) +``` + +### Guard Clauses + +Use guard clauses to validate and exit early: + +```python +# Bad - Nested conditions +def process_order(order): + if order is not None: + if order.items: + if order.total > 0: + # Main logic here + charge_payment(order) + ship_order(order) + +# Good - Guard clauses +def process_order(order): + if order is None: + raise ValueError("Order cannot be None") + if not order.items: + raise ValueError("Order must contain at least one item") + if order.total <= 0: + raise ValueError("Order total must be positive") + + # Main logic - no nesting + charge_payment(order) + ship_order(order) +``` + +### Do +- Validate at function entry +- Use guard clauses to reduce nesting +- Check preconditions explicitly +- Validate types and ranges +- Use type hints and runtime validation + +### Don't +- Defer validation until deep in the logic +- Assume inputs are valid +- Mix validation with business logic + +--- + +## Exception Hierarchy + +**Definition:** Use specific exception types to allow targeted error handling. + +### Examples + +```python +# Bad - Generic exceptions +def fetch_user(user_id): + if user_id < 0: + raise Exception("Invalid ID") + user = db.get(user_id) + if not user: + raise Exception("Not found") + return user + +# Good - Specific exceptions +class InvalidUserIdError(ValueError): + pass + +class UserNotFoundError(LookupError): + pass + +def fetch_user(user_id): + if user_id < 0: + raise InvalidUserIdError(f"User ID must be positive, got {user_id}") + user = db.get(user_id) + if not user: + raise UserNotFoundError(f"User with ID {user_id} not found") + return user + +# Caller can handle specifically +try: + user = fetch_user(user_id) +except InvalidUserIdError as e: + return {"error": "bad_request", "message": str(e)} +except UserNotFoundError as e: + return {"error": "not_found", "message": str(e)} +``` + +### Do +- Create custom exception classes for domain errors +- Inherit from appropriate built-in exceptions +- Use exception hierarchies for related errors +- Document exception types in docstrings + +### Don't +- Raise generic `Exception` or `RuntimeError` +- Create exceptions for every possible error +- Use exceptions for non-exceptional cases + +--- + +## Error Recovery Strategies + +### Retry with Backoff + +```python +import time + +def fetch_with_retry(url, max_attempts=3): + for attempt in range(max_attempts): + try: + return http.get(url) + except TransientError as e: + if attempt == max_attempts - 1: + raise + wait_time = 2 ** attempt # Exponential backoff + time.sleep(wait_time) +``` + +### Fallback Mechanisms + +```python +def get_user_avatar(user_id): + try: + return cdn.fetch_avatar(user_id) + except CDNError: + # Fallback to default avatar + return DEFAULT_AVATAR_URL +``` + +### Circuit Breaker + +```python +class CircuitBreaker: + def __init__(self, failure_threshold=5): + self.failure_count = 0 + self.threshold = failure_threshold + self.state = "closed" # closed, open, half-open + + def call(self, func, *args): + if self.state == "open": + raise CircuitOpenError("Service is temporarily unavailable") + + try: + result = func(*args) + self.on_success() + return result + except Exception as e: + self.on_failure() + raise + + def on_success(self): + self.failure_count = 0 + self.state = "closed" + + def on_failure(self): + self.failure_count += 1 + if self.failure_count >= self.threshold: + self.state = "open" +``` + +--- + +## Logging vs. Exceptions + +**Definition:** Log for diagnostics, use exceptions for control flow. + +### When to Log + +```python +# Log operational info +logger.info(f"Processing order {order_id}") + +# Log warnings for recoverable issues +logger.warning(f"Slow query detected: {duration}ms") + +# Log errors with context +try: + process_payment(order) +except PaymentError as e: + logger.error(f"Payment failed for order {order.id}", exc_info=True) + raise # Re-raise after logging +``` + +### When to Raise Exceptions + +```python +# Invalid input - exception +def set_age(age): + if age < 0 or age > 150: + raise ValueError(f"Invalid age: {age}") + +# Business rule violation - exception +def withdraw(account, amount): + if account.balance < amount: + raise InsufficientFundsError(f"Balance: {account.balance}, requested: {amount}") + +# Operational issue - log + exception +def connect_to_database(): + try: + return db.connect() + except ConnectionError as e: + logger.error("Database connection failed", exc_info=True) + raise DatabaseUnavailableError("Cannot connect to database") from e +``` + +### Do +- Log context before re-raising +- Include exception traceback in logs +- Use structured logging for searchability +- Set appropriate log levels + +### Don't +- Log and swallow exceptions +- Log sensitive data (passwords, tokens) +- Over-log routine operations + +--- + +## Error Messages Best Practices + +### Good Error Messages + +**What went wrong:** +``` +"Invalid email address: 'user@domain' - missing top-level domain" +``` + +**What was expected:** +``` +"Order total must be positive, got -50.00" +``` + +**How to fix it:** +``` +"File not found: '/data/input.csv'. Check that the file exists and path is correct." +``` + +**Actionable context:** +``` +"User authentication failed: Invalid API key. Please check your credentials in the dashboard." +``` + +### Bad Error Messages + +``` +"Error" # Too vague +"Something went wrong" # Unhelpful +"Invalid input" # Missing details +"Error code: 42" # No explanation +``` + +### Do +- Explain what failed and why +- Include actual vs. expected values +- Suggest corrective actions +- Avoid technical jargon for user-facing errors +- Use clear, plain language + +### Don't +- Expose internal implementation details to end users +- Include stack traces in user-facing messages +- Use codes without explanations +- Be condescending ("You entered invalid data") + +--- + +## Summary + +Effective error handling: +- **Fails fast** - Validates early and explicitly +- **Provides clarity** - Error messages explain what and why +- **Uses exceptions correctly** - For exceptional conditions only +- **Enables recovery** - Appropriate retry and fallback strategies + +When handling errors, ask: +- Have I validated all inputs? +- Will the error message help someone fix the issue? +- Am I using the right exception type? +- Should this be logged, raised, or both? diff --git a/skills/design-patterns-skill/references/patterns/maintainability.md b/skills/design-patterns-skill/references/patterns/maintainability.md new file mode 100755 index 0000000..a085889 --- /dev/null +++ b/skills/design-patterns-skill/references/patterns/maintainability.md @@ -0,0 +1,548 @@ +# Maintainability & Best Practices + +## Boy Scout Rule + +**Definition:** "Leave the code better than you found it." Make small improvements whenever you touch existing code. + +**Supported by:** *Clean Code*, *The Pragmatic Programmer* + +### Examples + +```python +# Before - Existing code you're modifying +def calc(a, b): + return a + b + +# After - Improved while making your change +def calculate_sum(a, b): + """Return the sum of two numbers.""" + return a + b +``` + +```python +# Before - Adding a feature to messy code +def processUser(u): + # Check age + if u.age<18:return False + db.save(u) + return True + +# After - Clean up while you're here +def process_user(user): + """Register an eligible user.""" + if not is_eligible_user(user): + return False + save_user(user) + return True + +def is_eligible_user(user): + return user.age >= 18 +``` + +### Do +- Improve variable names +- Extract magic numbers to constants +- Add missing docstrings +- Fix formatting inconsistencies +- Remove dead code +- Simplify complex conditions + +### Don't +- Make unrelated large refactors +- Change behavior without tests +- Add hacks or workarounds +- Ignore obvious issues ("not my code") + +### AI Pitfalls +- Regenerating dirty code without improvements +- Not suggesting cleanup opportunities +- Adding to technical debt instead of reducing it + +--- + +## Continuous Refactoring + +**Definition:** Improve code structure regularly through small, safe changes backed by tests. Refactoring should be ongoing, not a separate phase. + +**Supported by:** *Refactoring*, *Code Complete*, *Clean Code* + +### Common Refactorings + +**Extract Method** +```python +# Before +def process_order(order): + # Validate + if not order.items: + raise ValueError("Empty order") + + # Calculate total + total = 0 + for item in order.items: + total += item.price * item.quantity + + # Apply discount + if order.customer.is_premium: + total *= 0.9 + + return total + +# After +def process_order(order): + validate_order(order) + total = calculate_total(order) + return apply_discount(total, order.customer) + +def validate_order(order): + if not order.items: + raise ValueError("Empty order") + +def calculate_total(order): + return sum(item.price * item.quantity for item in order.items) + +def apply_discount(total, customer): + if customer.is_premium: + return total * 0.9 + return total +``` + +**Extract Variable** +```python +# Before +if (user.age >= 18 and user.has_verified_email and user.account_status == 'active'): + grant_access() + +# After +is_adult = user.age >= 18 +has_verified_email = user.has_verified_email +is_active = user.account_status == 'active' + +if is_adult and has_verified_email and is_active: + grant_access() +``` + +**Rename** +```python +# Before +def fn(x, y): + return x * y + +# After +def calculate_area(width, height): + return width * height +``` + +**Replace Magic Numbers** +```python +# Before +def calculate_price(quantity): + if quantity > 100: + return quantity * 9.99 * 0.85 + return quantity * 9.99 + +# After +UNIT_PRICE = 9.99 +BULK_DISCOUNT = 0.85 +BULK_THRESHOLD = 100 + +def calculate_price(quantity): + price = quantity * UNIT_PRICE + if quantity > BULK_THRESHOLD: + price *= BULK_DISCOUNT + return price +``` + +### Refactoring Workflow + +1. **Ensure tests pass** - Start with green tests +2. **Make one change** - Small, focused refactor +3. **Run tests** - Verify behavior unchanged +4. **Commit** - Save working state +5. **Repeat** - Iterate on improvements + +### Do +- Refactor in small steps +- Run tests after each change +- Commit frequently +- Use IDE refactoring tools +- Keep behavior identical + +### Don't +- Refactor without tests +- Mix refactoring with feature work +- Make multiple changes at once +- Skip running tests +- Delay commits + +### AI Pitfalls +- Suggesting large refactors without incremental steps +- Omitting test runs between changes +- Changing behavior during refactoring + +--- + +## Version Control & Incremental Work + +**Definition:** Commit code in logical, testable chunks. Each commit should represent a complete, working unit of change. + +**Supported by:** *Refactoring*, *The Pragmatic Programmer*, Agile practices + +### Good Commit Practices + +**Atomic Commits** +``` +βœ“ "Add user email validation" +βœ“ "Extract payment processing to service" +βœ“ "Fix off-by-one error in pagination" + +βœ— "Fixed stuff" +βœ— "WIP" +βœ— "Updated files" +``` + +**Commit Messages** +``` +# Good - Imperative mood, clear intent +Add password strength validation + +Implement validation rules: +- Minimum 8 characters +- At least one uppercase letter +- At least one number +- At least one special character + +Closes #123 + +# Bad +fixed login +``` + +### Commit Workflow + +```bash +# 1. Make a focused change +# 2. Run tests +pytest + +# 3. Review changes +git diff + +# 4. Stage related files +git add user_validator.py tests/test_validator.py + +# 5. Commit with clear message +git commit -m "Add email format validation" + +# 6. Repeat for next logical change +``` + +### Do +- Commit working, tested code +- Write descriptive commit messages +- Keep commits focused and atomic +- Use branches for features +- Commit frequently + +### Don't +- Commit broken code +- Mix unrelated changes in one commit +- Skip commit messages +- Commit sensitive data (API keys, passwords) +- Leave uncommitted changes overnight + +### AI Pitfalls +- Generating large changes without guiding commit boundaries +- Not suggesting logical commit points +- Creating code that can't be committed incrementally + +--- + +## Code Reviews + +**Definition:** Systematic examination of code changes by peers to catch issues, share knowledge, and maintain quality. + +### Review Checklist + +**Correctness** +- Does it solve the stated problem? +- Are edge cases handled? +- Is error handling appropriate? +- Are there off-by-one errors or race conditions? + +**Design** +- Is it in the right place? +- Does it follow existing patterns? +- Is complexity warranted? +- Could it be simpler? + +**Readability** +- Are names clear? +- Is logic easy to follow? +- Are comments helpful (not redundant)? +- Is formatting consistent? + +**Testing** +- Are tests included? +- Do tests cover edge cases? +- Are tests readable and maintainable? + +**Security** +- Is input validated? +- Are secrets hardcoded? +- Are SQL queries parameterized? +- Is authentication/authorization correct? + +### Review Etiquette + +**As Reviewer** +``` +βœ“ "Consider extracting this to a helper function for reusability" +βœ“ "Could we add a test for the empty list case?" +βœ“ "This is clever! Can we add a comment explaining the algorithm?" + +βœ— "This is terrible" +βœ— "Why didn't you just..." +βœ— "Obviously this is wrong" +``` + +**As Author** +- Respond to all feedback +- Ask for clarification +- Explain non-obvious decisions +- Be open to suggestions +- Thank reviewers + +### Do +- Review promptly +- Focus on substance over style +- Suggest improvements, don't demand +- Automate style checks +- Learn from reviews you receive + +### Don't +- Approve without reading +- Nitpick trivial issues +- Review your own PRs +- Take criticism personally +- Skip review for "small" changes + +--- + +## Automation and Tooling + +**Definition:** Automate repetitive tasks and use tools to maintain consistency and quality. + +**Supported by:** *The Pragmatic Programmer*, *Clean Code* + +### Essential Tools + +**Linters** - Catch common mistakes +```bash +# Python +pylint myapp/ +flake8 myapp/ + +# JavaScript +eslint src/ + +# Go +golangci-lint run +``` + +**Formatters** - Maintain consistent style +```bash +# Python +black myapp/ + +# JavaScript +prettier --write src/ + +# Rust +rustfmt src/ +``` + +**Type Checkers** - Catch type errors +```bash +# Python +mypy myapp/ + +# TypeScript +tsc --noEmit + +# Flow +flow check +``` + +**Test Runners** - Verify behavior +```bash +# Python +pytest + +# JavaScript +jest + +# Go +go test ./... +``` + +### Continuous Integration + +```yaml +# .github/workflows/ci.yml +name: CI +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: pip install -r requirements.txt + - name: Lint + run: flake8 . + - name: Type check + run: mypy . + - name: Test + run: pytest --cov + - name: Security scan + run: bandit -r . +``` + +### Pre-commit Hooks + +```bash +# .pre-commit-config.yaml +repos: + - repo: https://github.com/psf/black + hooks: + - id: black + - repo: https://github.com/pycqa/flake8 + hooks: + - id: flake8 + - repo: https://github.com/pre-commit/pre-commit-hooks + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml +``` + +### Do +- Integrate tools into workflow +- Run checks locally before pushing +- Fail builds on violations +- Configure tools consistently +- Update tools regularly + +### Don't +- Rely on manual checks +- Ignore tool warnings +- Skip tools for "quick fixes" +- Disable checks without good reason + +### AI Pitfalls +- Producing code that doesn't pass linting +- Ignoring type annotations +- Generating code incompatible with project tools + +--- + +## Documentation + +**Definition:** Provide context and explanations where code alone isn't sufficient. + +### What to Document + +**APIs and Public Interfaces** +```python +def calculate_shipping_cost(weight_kg: float, destination: str) -> float: + """Calculate shipping cost based on weight and destination. + + Args: + weight_kg: Package weight in kilograms (must be positive) + destination: ISO 3166-1 alpha-2 country code + + Returns: + Shipping cost in USD + + Raises: + ValueError: If weight is negative or destination is invalid + + Example: + >>> calculate_shipping_cost(2.5, 'US') + 12.50 + """ +``` + +**Complex Algorithms** +```python +def dijkstra(graph, start): + """Find shortest paths using Dijkstra's algorithm. + + Time complexity: O((V + E) log V) where V is vertices, E is edges + Space complexity: O(V) + + See: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm + """ +``` + +**Non-Obvious Decisions** +```python +# Using MD5 for cache keys only - NOT for security +# MD5 is fast and collision-resistant enough for this use case +cache_key = hashlib.md5(url.encode()).hexdigest() +``` + +**Setup and Configuration** +```markdown +# README.md + +## Installation + +pip install -r requirements.txt + +## Configuration + +Set environment variables: +- `DATABASE_URL`: PostgreSQL connection string +- `API_KEY`: Third-party service API key + +## Running + +python app.py +``` + +### Don't Document + +- Obvious code (let code be self-documenting) +- Implementation details that change frequently +- Duplicated information available elsewhere + +### Do +- Keep docs close to code +- Update docs with code changes +- Use examples liberally +- Link to external references + +### Don't +- Let docs become stale +- Over-document simple code +- Duplicate info across files + +--- + +## Summary + +Maintainable code: +- **Improves incrementally** - Boy Scout Rule +- **Refactors continuously** - Small, safe improvements +- **Commits logically** - Atomic, tested changes +- **Automates quality** - Linters, formatters, CI/CD +- **Documents appropriately** - Context where needed + +When maintaining code, ask: +- Can I improve this while I'm here? +- Is this change small and safe? +- Should I commit now? +- Are my tools catching issues? +- Does this need documentation? diff --git a/skills/design-patterns-skill/references/patterns/readability.md b/skills/design-patterns-skill/references/patterns/readability.md new file mode 100755 index 0000000..edf85e0 --- /dev/null +++ b/skills/design-patterns-skill/references/patterns/readability.md @@ -0,0 +1,195 @@ +# Readability & Clarity Principles + +## Descriptive Naming + +**Definition:** Use clear, meaningful names for variables, functions, classes, etc., so code reads like natural language. Avoid vague, abbreviated, or encoded names. Good names explain intent without requiring comments. + +**Supported by:** *Clean Code*, *Code Complete* + +### Examples + +```python +# Bad +def calc(a, b): + return a * b + 3 + +# Good +def calculate_rectangle_area(width, height): + margin = 3 + return width * height + margin +``` + +### Do +- Use nouns for data structures and variables +- Use verbs for functions and methods +- Use consistent domain terminology +- Make names pronounceable and searchable +- Use solution/problem domain names + +### Don't +- Use single-letter names (except loop counters in small scopes) +- Create misleading names +- Use encodings or prefixes (Hungarian notation) +- Use abbreviations unless universally known +- Mix naming conventions in the same scope + +### AI Pitfalls +- Repeating generic names like `data`, `temp`, `foo`, `result` +- Inconsistent naming across similar concepts +- Using placeholder names and forgetting to rename +- Over-shortening meaningful names for brevity + +--- + +## Consistent Style & Formatting + +**Definition:** Follow a uniform coding style and project conventions. Consistency aids readability and reduces cognitive load. + +**Supported by:** *Clean Code*, *Code Complete* + +### Examples + +```javascript +// Bad - Inconsistent spacing, braces, indentation +if(x>0){ +y= x+10; + console.log(y);} + +// Good - Consistent formatting +if (x > 0) { + let result = x + 10; + console.log(result); +} +``` + +### Do +- Stick to one brace style (K&R, Allman, etc.) +- Use consistent indentation (2 or 4 spaces, never mix tabs/spaces) +- Follow language conventions (PEP 8 for Python, Airbnb for JS) +- Maintain consistent line length (80-120 characters) +- Use automated formatters (Prettier, Black, rustfmt) + +### Don't +- Mix different formatting styles in one file +- Ignore project linting rules +- Use inconsistent whitespace +- Create overly long lines + +### AI Pitfalls +- Producing inconsistent formatting across code blocks +- Mixing indentation styles +- Ignoring existing project formatting conventions + +--- + +## Self-Documenting Code (Minimize Comments) + +**Definition:** Write code so its intent is clear from the code itself. Comments should explain *why*, not *what*. + +**Supported by:** *Clean Code*, *Code Complete* + +### Examples + +```python +# Bad - Redundant comment +# Increment i by 1 +i = i + 1 + +# Good - No comment needed +i = i + 1 + +# Acceptable - Explains business rule +# Block access for users under minimum age requirement +if user.age < 13: + block_access() + +# Good - Explains non-obvious why +# Using exponential backoff to avoid API rate limits +retry_delay = base_delay * (2 ** attempt_count) +``` + +### Do +- Use clear naming and logic structure +- Comment complex algorithms or business rules +- Explain performance optimizations +- Document API contracts and side effects +- Add TODO comments for future work (with ticket IDs) + +### Don't +- Write comments that restate the code +- Leave commented-out code +- Write misleading or outdated comments +- Use comments to fix bad naming + +### AI Pitfalls +- Over-commenting obvious operations +- Leaving stale or contradictory comments +- Using comments instead of refactoring unclear code + +--- + +## Small Functions & Single Responsibility + +**Definition:** Functions and methods should do one thing and do it well. Small, cohesive units are easier to understand, test, and maintain. + +**Supported by:** *Clean Code*, *Code Complete* + +### Examples + +```python +# Bad - Function does too many things +def update_user(data): + validate(data) + update_database(data) + send_email(data) + log_activity(data) + invalidate_cache(data) + +# Good - Separated concerns +def update_user(data): + validated_data = validate(data) + save_user(validated_data) + notify_user(validated_data) + +def save_user(data): + update_database(data) + invalidate_cache(data) + +def notify_user(data): + send_email(data) + log_activity(data) +``` + +### Do +- Keep functions under 20-30 lines when possible +- Extract helper functions for complex logic +- Use descriptive function names that indicate purpose +- Limit function parameters (ideally ≀ 3) +- Make one level of abstraction per function + +### Don't +- Combine unrelated operations +- Create deeply nested logic +- Use flag arguments to control behavior +- Write functions that both query and modify state + +### AI Pitfalls +- Creating monolithic functions with multiple responsibilities +- Over-fragmenting into excessive tiny functions +- Mixing abstraction levels within one function +- Generating functions that modify global state unexpectedly + +--- + +## Summary + +Readable code is: +- **Self-explanatory** through naming +- **Consistent** in style and structure +- **Minimal in comments** - code speaks for itself +- **Small and focused** - easy to understand at a glance + +When writing or reviewing code, ask: +- Can I understand this without the author present? +- Would I want to debug this at 2 AM? +- Does this follow the team's conventions? diff --git a/skills/design-patterns-skill/references/patterns/simplicity.md b/skills/design-patterns-skill/references/patterns/simplicity.md new file mode 100755 index 0000000..54b8d1d --- /dev/null +++ b/skills/design-patterns-skill/references/patterns/simplicity.md @@ -0,0 +1,279 @@ +# Simplicity & Efficiency Principles + +## KISS (Keep It Simple, Stupid) + +**Definition:** Use the simplest solution that solves the problem. Avoid unnecessary complexity, over-engineering, or premature optimization. + +**Supported by:** *Clean Code*, *The Pragmatic Programmer* + +### Examples + +```javascript +// Bad - Unnecessary abstraction +class SingleValueContainer { + constructor(value) { + this.values = [value]; + } + add(value) { + this.values.push(value); + } + getValue() { + return this.values[0]; + } +} + +// Good - Use built-in features +let numbers = [5]; +numbers.push(7); +let firstNumber = numbers[0]; +``` + +```python +# Bad - Over-complicated +def is_even(n): + return True if n % 2 == 0 else False + +# Good - Direct and clear +def is_even(n): + return n % 2 == 0 +``` + +### Do +- Use language built-ins and standard libraries +- Choose clear, direct solutions +- Optimize only when profiling shows need +- Prefer composition of simple parts +- Write code for the current requirement + +### Don't +- Create abstractions without clear benefit +- Add complexity for hypothetical future needs +- Use clever tricks that obscure intent +- Build custom solutions when standard ones exist + +### AI Pitfalls +- Using classes or design patterns unnecessarily +- Creating abstractions for single-use code +- Over-complicating simple conditional logic +- Generating enterprise patterns for simple scripts + +--- + +## DRY (Don't Repeat Yourself) + +**Definition:** Eliminate duplicated code and logic. Every piece of knowledge should have a single, authoritative representation. + +**Supported by:** *The Pragmatic Programmer*, *Clean Code* + +### Examples + +```python +# Bad - Duplicated logic +def circle_area(radius): + return 3.14159 * radius * radius + +def quarter_circle_area(radius): + return 3.14159 * radius * radius / 4 + +def sphere_volume(radius): + return (4/3) * 3.14159 * radius * radius * radius + +# Good - Extracted constant and reused logic +PI = 3.14159 + +def circle_area(radius): + return PI * radius ** 2 + +def quarter_circle_area(radius): + return circle_area(radius) / 4 + +def sphere_volume(radius): + return (4/3) * PI * radius ** 3 +``` + +```javascript +// Bad - Repeated validation +function createUser(name, email) { + if (!email.includes('@')) throw Error('Invalid email'); + // ... +} + +function updateEmail(userId, email) { + if (!email.includes('@')) throw Error('Invalid email'); + // ... +} + +// Good - Extracted validation +function validateEmail(email) { + if (!email.includes('@')) { + throw Error('Invalid email'); + } +} + +function createUser(name, email) { + validateEmail(email); + // ... +} + +function updateEmail(userId, email) { + validateEmail(email); + // ... +} +``` + +### Do +- Extract common logic into functions +- Use constants for repeated values +- Abstract similar patterns +- Share code across modules appropriately +- Keep abstractions at the right level + +### Don't +- Copy-paste code blocks +- Duplicate business rules +- Repeat validation logic +- Hard-code the same values multiple times +- Create premature abstractions (see Rule of Three) + +### Rule of Three +Wait until you see duplication **three times** before abstracting. Two instances might be coincidental; three suggests a pattern. + +### AI Pitfalls +- Producing repeated code structures from pattern prediction +- Duplicating similar functions instead of parameterizing +- Repeating validation or error handling logic +- Not recognizing when to extract shared utilities + +--- + +## YAGNI (You Aren't Gonna Need It) + +**Definition:** Don't implement features or infrastructure until you actually need them. Avoid speculative development. + +**Supported by:** *The Pragmatic Programmer*, Extreme Programming (XP) + +### Examples + +```python +# Bad - Building for hypothetical futures +def process_order(order): + prepare_invoice(order) + apply_future_discount_system(order) # Not used yet + schedule_loyalty_rewards(order) # Not needed now + prepare_for_blockchain_audit(order) # Speculative + +# Good - Only what's needed now +def process_order(order): + prepare_invoice(order) + charge_payment(order) + ship_order(order) +``` + +```javascript +// Bad - Over-engineered configuration +class DatabaseConfig { + constructor() { + this.primaryHost = 'localhost'; + this.replicaHosts = []; // Not using replication + this.shardingStrategy = null; // Not sharding + this.cacheLayer = null; // No cache yet + } +} + +// Good - Current requirements only +class DatabaseConfig { + constructor(host) { + this.host = host; + } +} +``` + +### Do +- Write code for current, known requirements +- Add features when they're actually requested +- Keep infrastructure minimal +- Refactor when new needs emerge +- Trust that future changes will be manageable + +### Don't +- Build "just in case" features +- Create extensibility points without use cases +- Add configuration for hypothetical scenarios +- Implement features before they're specified + +### AI Pitfalls +- Generating code for unspecified future features +- Adding unnecessary configuration options +- Creating extensibility hooks without current need +- Building infrastructure beyond MVP scope + +--- + +## Premature Optimization + +**Definition:** Don't optimize until you have evidence of a performance problem. Clarity and correctness come first. + +**Supported by:** *The Pragmatic Programmer*, Donald Knuth's famous quote + +> "Premature optimization is the root of all evil" - Donald Knuth + +### Examples + +```python +# Bad - Premature optimization +def find_user(user_id): + # Using complex caching before knowing if it's needed + cache_key = f"user:{user_id}:v2" + if cache_key in cache: + return deserialize(decompress(cache[cache_key])) + user = db.query(user_id) + cache[cache_key] = compress(serialize(user)) + return user + +# Good - Start simple, optimize if needed +def find_user(user_id): + return db.query(user_id) + +# Later, if profiling shows this is slow: +def find_user(user_id): + cached = cache.get(f"user:{user_id}") + if cached: + return cached + user = db.query(user_id) + cache.set(f"user:{user_id}", user) + return user +``` + +### Do +- Write clear, correct code first +- Profile before optimizing +- Optimize only proven bottlenecks +- Measure impact of optimizations +- Document why optimizations were made + +### Don't +- Sacrifice readability for unmeasured performance +- Optimize without profiling data +- Use complex algorithms for small datasets +- Cache everything "just in case" + +### AI Pitfalls +- Adding caching layers without justification +- Using complex data structures for simple cases +- Micro-optimizing at the expense of clarity + +--- + +## Summary + +Simple code is: +- **Direct** - solves the problem at hand +- **DRY** - has no unnecessary duplication +- **Minimal** - contains only what's needed now +- **Clear** - prioritizes readability over premature optimization + +When writing code, ask: +- Is this the simplest approach that works? +- Am I repeating myself? +- Do I actually need this now? +- Am I optimizing based on evidence? diff --git a/skills/design-patterns-skill/references/patterns/testing.md b/skills/design-patterns-skill/references/patterns/testing.md new file mode 100755 index 0000000..6ddc615 --- /dev/null +++ b/skills/design-patterns-skill/references/patterns/testing.md @@ -0,0 +1,309 @@ +# Testing & Quality Principles + +## Write Automated Tests Early + +**Definition:** Use tests to guide design, prevent regressions, and validate behavior. Testing should be part of the development process, not an afterthought. + +**Supported by:** *Refactoring*, *The Pragmatic Programmer*, Test-Driven Development (TDD) + +### Examples + +```python +# Test-first approach +def test_calculate_discount(): + # Arrange + price = 100 + discount_percent = 10 + + # Act + result = calculate_discount(price, discount_percent) + + # Assert + assert result == 90 + +def calculate_discount(price, discount_percent): + return price * (1 - discount_percent / 100) +``` + +```python +# Test edge cases +def test_user_age_validation(): + assert is_adult(18) == True + assert is_adult(17) == False + assert is_adult(0) == False + assert is_adult(150) == True # No upper bound check yet + +def is_adult(age): + return age >= 18 +``` + +### Do +- Write tests before or alongside code +- Test edge cases and boundary conditions +- Test business logic thoroughly +- Use descriptive test names +- Keep tests fast and independent +- Use test fixtures and setup/teardown appropriately + +### Don't +- Skip tests for "simple" code +- Test implementation details instead of behavior +- Write brittle tests that break on refactoring +- Ignore failing tests +- Write tests that depend on external state + +### AI Pitfalls +- Missing tests entirely +- Writing overly broad test functions +- Not testing edge cases or error paths +- Creating tests with vague assertions + +--- + +## One Assert Per Test (Focus) + +**Definition:** Keep tests focused on a single behavior or scenario. This makes failures easy to diagnose. + +**Supported by:** *Clean Code*, TDD best practices + +### Examples + +```python +# Bad - Multiple unrelated assertions +def test_user(): + user = User("Alice", 25) + assert user.name == "Alice" + assert user.age == 25 + assert user.is_adult() == True + assert user.can_vote() == True + assert user.get_greeting() == "Hello, Alice" + +# Good - Focused tests +def test_user_name_is_set_correctly(): + user = User("Alice", 25) + assert user.name == "Alice" + +def test_user_age_is_set_correctly(): + user = User("Alice", 25) + assert user.age == 25 + +def test_user_is_adult_when_age_18_or_above(): + user = User("Alice", 25) + assert user.is_adult() == True + +def test_user_is_not_adult_when_age_below_18(): + user = User("Bob", 17) + assert user.is_adult() == False +``` + +### Guideline Exceptions + +Multiple assertions are acceptable when: +- Testing object state after a single operation +- Verifying related properties of one concept +- Testing list/collection contents + +```python +# Acceptable - Related assertions on same concept +def test_order_creation(): + order = Order(items=[item1, item2]) + assert len(order.items) == 2 + assert order.total == 50.00 + assert order.status == OrderStatus.PENDING +``` + +### Do +- Use test names to describe expected behavior +- Group related tests in test classes +- Use parametrized tests for similar scenarios +- Make test intent crystal clear + +### Don't +- Group many checks together +- Test multiple behaviors in one test +- Create generic test names like `test_user()` + +### AI Pitfalls +- Combining multiple assertions in one test function +- Creating catch-all test functions +- Not using descriptive test names + +--- + +## Test Coverage Guidelines + +**Definition:** Aim for meaningful coverage of critical paths, not just high percentages. Focus on business logic, edge cases, and failure modes. + +### What to Test + +**High Priority:** +- Business logic and algorithms +- Input validation and error handling +- State transitions +- Integration points +- Security-critical code + +**Medium Priority:** +- Data transformations +- Configuration handling +- User-facing features + +**Low Priority:** +- Trivial getters/setters +- Framework-generated code +- External library wrappers + +### Coverage Anti-Patterns + +```python +# Bad - Testing for coverage, not correctness +def test_add(): + add(2, 3) # No assertion! + +# Good - Test actual behavior +def test_add_returns_sum(): + result = add(2, 3) + assert result == 5 +``` + +### Do +- Focus on critical code paths +- Test public interfaces, not private methods +- Use code coverage as a guide, not a goal +- Write tests that catch real bugs + +### Don't +- Aim for 100% coverage blindly +- Test trivial code just for metrics +- Ignore untested critical paths + +--- + +## Test Pyramid + +**Definition:** Balance different types of tests - many unit tests, fewer integration tests, even fewer end-to-end tests. + +``` + /\ + / \ Few E2E tests (slow, brittle) + /____\ + / \ More integration tests (moderate speed) + /________\ + / \ Many unit tests (fast, isolated) +``` + +### Unit Tests +- Test individual functions/classes in isolation +- Fast execution (milliseconds) +- Mock external dependencies +- High count (hundreds to thousands) + +### Integration Tests +- Test interactions between components +- Moderate speed (seconds) +- Use real dependencies where practical +- Medium count (dozens to hundreds) + +### End-to-End Tests +- Test complete user workflows +- Slow execution (minutes) +- Test through actual UI/API +- Low count (handful to dozens) + +### Do +- Rely primarily on unit tests +- Use integration tests for critical paths +- Reserve E2E tests for key user journeys + +### Don't +- Over-rely on E2E tests +- Skip unit tests in favor of integration tests +- Test everything through the UI + +--- + +## Test Quality Checklist + +Good tests are: + +- **Fast** - Run in milliseconds +- **Isolated** - No shared state or order dependency +- **Repeatable** - Same result every time +- **Self-validating** - Pass/fail is clear +- **Timely** - Written close to code + +### Do +- Use test fixtures for setup +- Clean up resources in teardown +- Use meaningful test data +- Avoid test interdependence + +### Don't +- Rely on external services without mocks +- Use production data +- Write flaky tests +- Commit commented-out tests + +--- + +## Mocking & Test Doubles + +**Definition:** Use test doubles (mocks, stubs, fakes) to isolate the code under test. + +### Types of Test Doubles + +**Stub** - Returns canned responses +```python +class StubPaymentGateway: + def charge(self, amount): + return {"status": "success", "transaction_id": "123"} +``` + +**Mock** - Verifies interactions +```python +def test_order_charges_payment(): + mock_gateway = Mock() + processor = OrderProcessor(mock_gateway) + processor.process(order) + mock_gateway.charge.assert_called_once_with(100.00) +``` + +**Fake** - Simplified working implementation +```python +class FakeDatabase: + def __init__(self): + self.data = {} + + def save(self, key, value): + self.data[key] = value + + def get(self, key): + return self.data.get(key) +``` + +### Do +- Mock external dependencies (APIs, databases, file systems) +- Use dependency injection to enable mocking +- Verify behavior, not implementation +- Keep mocks simple + +### Don't +- Mock everything (test real code when possible) +- Create complex mock hierarchies +- Over-specify mock expectations + +--- + +## Summary + +Effective testing: +- **Guides design** - Tests drive better architecture +- **Prevents regressions** - Catches bugs early +- **Documents behavior** - Tests are living specifications +- **Enables refactoring** - Confidence to improve code + +When writing tests, ask: +- Does this test verify actual behavior? +- Will this test catch real bugs? +- Is this test easy to understand and maintain? +- Can this test run quickly and reliably? diff --git a/skills/designer/SKILL.md b/skills/designer/SKILL.md new file mode 100644 index 0000000..3d337f4 --- /dev/null +++ b/skills/designer/SKILL.md @@ -0,0 +1,1252 @@ +--- +name: designer +category: domain +description: >- + Evidence-based design decision engine. An intention gate that produces non-slop + UI/UX by forcing every visual choice through industry context, cognitive science, + design master principles, and anti-pattern detection before code generation. + Outputs a DESIGN.md contract that all subsequent implementation must follow. +metadata: + author: booleanstack + version: "3.0.0" + labels: [design, ui, ux, design-system, anti-slop] +triggers: + - design a + - build me a + - landing page + - dashboard design + - make it look + - visual direction + - ui design + - design system + - DESIGN.md + - create a page + - website for + - app design + - redesign + - style guide +activation: + mode: fuzzy + priority: high + triggers: + - design + - landing page + - dashboard + - visual + - DESIGN.md + - ui + - ux +references: + - references/design-md-template.md + - references/website-experience-cheatsheet.md + - examples/saas-dashboard.md + - examples/developer-tool.md + - examples/ecommerce-checkout.md +--- + +# Designer Skill - Intention Gate + +> AI-generated UIs all look the same because AI skips the decision process and jumps to code. +> This skill forces every design decision through evidence before code generation. +> No visual code until a DESIGN.md contract is produced and approved. + +--- + +## The Iron Law + +``` +NO VISUAL CODE WITHOUT AN APPROVED DESIGN.md +``` + +**Violating the letter of this rule is violating the spirit of this rule.** + +If you are about to write a single line of JSX, CSS, or styling code, and there is no approved DESIGN.md, you are breaking this rule. There are no exceptions. A "simple button" still needs personality, color, and state decisions. + +## Hard Gate + +``` +DO NOT GENERATE ANY VISUAL CODE UNTIL: + 1. Intent extracted (Phase 1) + 2. MCP tools consulted (Phase 2) + 3. Anti-patterns checked (Phase 3) + 4. DESIGN.md generated and presented (Phase 4) + 5. User has approved the DESIGN.md + +No exceptions. A "simple button" still needs personality, color, and state decisions. +``` + +## The 1% Rule + +If there is even a 1% chance that the task involves: +- A new page or view +- A new component +- Changing how something looks +- Changing how something moves (animation, transition, scroll) +- Changing how something responds to user input +- A landing page, dashboard, form, or data display +- "Make it look more like X" +- "Redesign" anything + +...then you MUST invoke this skill BEFORE writing any code. You cannot rationalize your way out. + +**Apply when:** the task changes how something **looks, feels, moves, or is interacted with**. +**Skip when:** pure backend with no frontend impact, single CSS bug fix (with the same colors/spacing), adding to existing design system with established tokens, performance optimization with no visual change, infrastructure. + +## Red Flags - STOP + +These are the rationalizations you will have when you want to skip this skill. Every one is wrong. + +| Thought | Reality | +|---|---| +| "This is a small component, it doesn't need a full DESIGN.md" | Small components with wrong decisions ship to production. Design it. | +| "I'll just use the default shadcn styles" | Defaults are decisions. Unexamined defaults produce AI slop. Design intentionally. | +| "The user said 'just make it work'" | "Just make it work" means "make something that makes sense visually." That needs design. | +| "I know what a SaaS dashboard looks like" | You know the AI-slop version. Designer prevents that specifically. | +| "I can fix the design after the user sees the code" | No. The AI slop fingerprint is sticky. Users will stop caring before you fix it. | +| "The MCP tools are overkill for this" | You don't get to decide. Call them. | +| "I'll generate a DESIGN.md after coding" | Then it is post-hoc justification, not design. Design FIRST. | +| "The user is iterating quickly, they don't want a gate" | User speed is not permission to ship slop. Gate first, iterate fast inside the gate. | +| "This is just a quick mockup" | Quick mockups become shipped products. Design them. | +| "Figma already has the design, I'll just translate" | Translating from Figma without design resolution creates absolute/relative dumps. Use designer anyway. | +| "I'll pick colors and fonts as I go" | That is how AI slop is made. Pick them deliberately via designer. | +| "Dark mode will just invert the light mode colors" | No it will not. This is the exact anti-pattern designer exists to prevent. | +| "The designer skill is slow" | The skill takes 2 minutes. Shipping wrong design takes 2 weeks to undo. | + +--- + +## Position in the Hyperstack Workflow + +``` + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + user request β”‚ β”‚ + β”‚ β”‚ Upstream: β”‚ + β–Ό β”‚ - hyperstack (root orchestrator) β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ - blueprint (visual routing) β”‚ + β”‚ blueprint │─── visual? ──┼─▢ designer (THIS SKILL) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ + β”‚ β”‚ Produces: β”‚ + β”‚ non-visual β”‚ - DESIGN.md contract (file) β”‚ + β”‚ β”‚ β”‚ + β–Ό β”‚ Downstream consumers: β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ - forge-plan (reads DESIGN.md) β”‚ + β”‚ forge-plan│◀─ DESIGN.md ── - shadcn-expert (per-section code) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ - motion_generate_animation β”‚ + β”‚ β”‚ - design_tokens_generate β”‚ + β–Ό β”‚ - behaviour-analysis (audit spec) β”‚ + execution β”‚ - ship-gate (compliance check) β”‚ + β”‚ β”‚ β”‚ + β–Ό β”‚ Reverse escalation (allowed): β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ - forge-plan β†’ designer β”‚ + β”‚ ship-gate β”‚ β”‚ (if visual gap discovered) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ - behaviour-analysis β†’ designer β”‚ + β”‚ β”‚ (if expected behavior unclear) β”‚ + β–Ό β”‚ β”‚ + deliver β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## The Three-Layer Stack + +| Layer | Plugin | Question | Tools | +|---|---|---|---| +| **Decision** | `designer` (this skill) | Which design? | 17 MCP tools | +| **Rules** | `ui-ux` | What principles? | 6 MCP tools | +| **Values** | `design-tokens` | What exact CSS? | 7 MCP tools | +| **Components** | `shadcn` | Which components to compose? | 4 MCP tools | +| **Motion** | `motion` | Exact animation code? | 7 MCP tools | + +--- + +## Website Experience Non-Negotiables + +Visual quality is necessary, but it is not sufficient. Hyperstack designs must also +produce good website experience under real usage. A page that "looks premium" but is +slow, confusing, inaccessible, or conversion-hostile is a failed design. + +Every DESIGN.md must explicitly resolve these seven questions. If any are missing, +the design is incomplete: + +1. **Primary path** - What is the user's main job-to-be-done on this page, and what + is the single primary action? +2. **Information scent** - Can the user quickly answer "Where am I, what can I do, + and what happens next?" +3. **State coverage** - What do loading, empty, error, success, disabled, and + destructive states look like? +4. **Form and auth friction** - Are labels persistent, validation humane, paste + allowed, and password managers supported? +5. **Performance budget** - What are the target budgets for LCP, INP, CLS, and + payload-sensitive media? +6. **Accessibility floor** - How are focus visibility, focus not obscured, target + size, reduced motion, and keyboard usage handled? +7. **Responsive content priority** - What survives first on mobile, and what gets + de-emphasized or deferred? + +Use [website-experience-cheatsheet](references/website-experience-cheatsheet.md) +while resolving these. + +**Do not let visual style erase usability.** + +## User Preferences Override Defaults + +Auto-resolved defaults, presets, and recommendations are starting points only. +They are not allowed to override explicit user preferences, brand language, +existing workspace conventions, or product constraints. + +Priority order for visual decisions: + +1. Explicit user preferences and constraints +2. Existing workspace reality (current framework, component library, design + system, tokens, and major frontend patterns) +3. Approved product or brand requirements +4. Designer auto-resolved defaults and presets + +If a user says "use these colors", "keep our current design system", "match this +existing app shell", or "do not use shadcn", that preference wins even if the +auto-resolved defaults would suggest something else. + +Treat auto-resolved defaults as suggestions to confirm or replace, never as +authority. + +# PHASE 1: INTENT EXTRACTION + +Two modes. Default to **Base** unless user says "advanced" or "detailed." + +## Base Mode (3 Questions + Confirm) + +**Step 0:** If this is an existing project, inspect the workspace first: +- identify framework and package manifests +- identify current component library and token system +- identify core frontend files for the active surface +- identify any explicit visual preferences already encoded in the repo + +**Step 1:** Call `designer_resolve_intent` with product description. Auto-detects: industry, personality, style, mode, density, color mood, must-haves, never-uses. + +**Step 2:** Ask 3 essential questions: + +| # | Question | Why | +|---|---|---| +| 1 | What is the product? (1 sentence) | Everything derives from this | +| 2 | Brand color? (hex, name, or "generate") | Can't guess someone's brand | +| 3 | What sections/pages to build? | What to implement | + +**Step 3:** Present auto-resolved defaults as suggestions, not decisions. Explicitly +ask whether any user preferences or existing workspace patterns should override +them. Then offer: *"Say 'advanced' for full control, or pick a preset to start from."* + +## Presets (Fast Start) + +If user says "make it feel like Linear" or "start from Stripe" or "use the Notion style" - call `designer_get_preset(name)` and use it as the DESIGN.md foundation. Customize brand color only. + +| Preset | Best For | Key Trait | +|---|---|---| +| `linear` | SaaS, productivity tools | Opacity hierarchy, 8px grid, snappy 150ms | +| `stripe` | Payment, docs, premium SaaS | Weight 300/500, CIELAB contrast, editorial polish | +| `vercel` | Dev tools, technical products | -0.04em tracking, zero chromatic bias, 96px sections | +| `apple` | Consumer, mobile-first | 17px body, spring physics, 44pt targets | +| `carbon` | Enterprise, regulated industries | Zero radius, IBM Plex, WCAG AA out of box | +| `shadcn` | Any React + Tailwind project | OKLCH, opacity borders, brand-agnostic default | +| `notion` | Content, editorial, notes | Warm cream bg, serif headings, 65ch prose | +| `supabase` | Developer tools, dark-first | Emerald on black, compact, code-native | +| `figma` | Creative tools, startups | Multi-color, spring animations, vivid | + +Call `designer_list_presets` to show all with details. Call `designer_get_preset(name)` for full token config + CSS. + +**Preset workflow:** Preset fills Sections 1-7 of DESIGN.md automatically. You only need to customize: brand color, specific sections/pages, and industry-specific do's/don'ts. + +## Advanced Mode (12 Questions) + +Call `designer_resolve_intent` first. Show suggested default alongside each question. Present in batches of 3-4 (Hick's Law). + +### Q1: What is the product? (1 sentence) +Determines industry category, anti-pattern set, style priority. + +### Q2: Who is the primary user? + +| User Type | Defaults | +|---|---| +| Developer | Dark default, monospace accents, keyboard-first, compact density | +| Consumer | Light default, friendly typography, mobile-first, comfortable density | +| Enterprise | Structured, conservative, data-dense, normal density | +| Child | Playful, large touch targets (48px+), high contrast, claymorphism | +| Creative | Rich motion, bold colors, portfolio-native | +| Healthcare | Calm, accessible (AAA), large text, minimal motion | + +### Q3: What emotional target? + +| Target | Visual Direction | +|---|---| +| Trustworthy | Professional palette, serif or clean sans, conservative radius | +| Playful | Vivid colors, rounded shapes (16-24px), spring animations | +| Premium | Tight tracking (-0.02em+), generous whitespace, single accent, subtle shadows | +| Energetic | High chroma (C 0.15+), large type (32px+ headings), rich motion | +| Calm | Muted palette, warm neutrals, generous line height, minimal motion | +| Technical | Dark default, monospace accents, compact density, snappy motion | +| Bold | Maximum contrast, large type, strong color blocks | +| Editorial | Serif headings, generous reading (18px body, 1.75 line-height), warm backgrounds | + +### Q4: Light or dark default? +Not a preference - a product decision. Developer tools β†’ dark. Marketing β†’ light. Editorial β†’ light. Gaming β†’ dark. Dashboards β†’ either, but intentional. + +### Q5: Brand color? +If given: extract hue, derive OKLCH ramp (11 stops). If "generate": pick from industry color mood. + +| Industry | Color Mood | +|---|---| +| SaaS | Trust blue + single accent | +| Healthcare | Calm blue + health green | +| Fintech | Navy + trust blue + gold | +| Luxury | Black + gold, minimal palette | +| AI/Tech | Neutral + one distinct (NOT #6366F1) | +| Education | Friendly pastels, warm accents | +| Wellness | Earth tones, sage green, soft coral | + +### Q6: Density? + +| Mode | Section Padding | Card Padding | Body Size | Use | +|---|---|---|---|---| +| Comfortable | 96px | 40px | 18px | Marketing, editorial, consumer | +| Normal | 64px | 28px | 16px | SaaS, dashboards, apps | +| Compact | 48px | 20px | 14px | Data tables, admin, dev tools | + +### Q7: Design style? +7 primary: minimalism, glassmorphism, soft-ui, dark-oled, vibrant-block, claymorphism, aurora-ui. If "recommend": resolved from industry + emotional target. + +### Q8: Font personality? + +| Personality | Pairing | Use | +|---|---|---| +| Technical | Geist + Geist Mono | Dev tools, SaaS, dashboards | +| Elegant | Cormorant + Montserrat | Luxury, editorial, premium | +| Friendly | Plus Jakarta Sans + mono | Consumer, education, SaaS | +| System | Inter (or system stack) | Universal, no strong personality | +| Editorial | Playfair Display + Lora | Content sites, blogs, news | + +### Q9: Motion level? + +| Level | What It Includes | +|---|---| +| Static | No animations at all | +| Subtle | Hover states + transitions only (150-200ms) | +| Moderate | + scroll reveals, micro-interactions (200-300ms) | +| Rich | + parallax, page transitions, animated backgrounds (300-500ms) | + +Always respects `prefers-reduced-motion` regardless of level. + +### Q10: Sections/pages? +Landing: Hero, Features, Testimonials, CTA, Footer, Pricing, FAQ. Dashboard: Sidebar, Header, Content, Data panels. Apps: Navigation, Content, Modals, Forms, Empty states. + +### Q11: Framework + Component Library? + +**Two sub-questions - ask both:** + +**Q11a - Framework:** +- React + Tailwind v4 (most common) +- Next.js + Tailwind v4 +- Vue + Tailwind +- Svelte + Tailwind +- HTML + Tailwind (no framework) +- Other (specify) + +**Q11b - Component Library:** +- **shadcn/ui (Base UI edition)** - invokes `hyperstack:shadcn-expert`, uses `shadcn_*` MCP tools +- **Raw Tailwind** - no component library, hand-built primitives from DESIGN.md +- **Material UI** - use its component catalog (no hyperstack plugin yet) +- **Mantine** - use its component catalog (no hyperstack plugin yet) +- **Chakra UI** - use its component catalog (no hyperstack plugin yet) +- **Ant Design** - enterprise component library (no hyperstack plugin yet) +- **Custom / existing design system** - user's own components +- **Ask me to recommend** - designer picks based on personality + industry + +**Do NOT assume shadcn by default.** If the user doesn't answer, ask explicitly. Different component libraries have incompatible architectures (Radix vs Base UI vs MUI primitives vs handcrafted). + +**Routing based on Q11b answer:** +- `shadcn/ui` β†’ `hyperstack:shadcn-expert` handles component work; forge-plan calls `shadcn_*` tools +- `Raw Tailwind` β†’ forge-plan hand-writes components from DESIGN.md Section 5 spec directly (no library wrapper) +- `Other library` β†’ forge-plan uses the library's own docs; hyperstack has no plugin; flag this to user +- `Custom/existing` β†’ read user's existing components first; match their patterns +- `Ask me to recommend` β†’ recommend shadcn/ui for React+Tailwind, or raw Tailwind if user wants maximum control + +### Q12: Constraints? +WCAG AA (default) or AAA. Performance budget (< 150KB JS, < 2s load). Dark mode required. Brand keywords. + +**Do NOT proceed to Phase 2 until Q1, Q5, Q10 answered.** + +--- + +# PHASE 2: DESIGN SYSTEM RESOLUTION + +Every MCP call must fill a specific section of the DESIGN.md. No call without a purpose. + +## Core Calls (Every Design Task - 4 calls) + +These 4 calls fill 80% of the DESIGN.md. Run them in parallel. + +### Call 1: `designer_resolve_intent(product_description)` +**FILLS:** All sections (defaults for everything) +**PURPOSE:** Auto-detects industry, personality, style, mode, density, color mood, must-haves, never-uses. Without this, you're guessing. +**USE RESULT TO:** Set defaults for the entire DESIGN.md. Present to user for confirmation in Phase 1. + +### Call 2: `designer_get_personality(resolved_cluster)` +**FILLS:** Section 1 (theme), Section 2 (color direction), Section 3 (typography), Section 4 (spacing), Section 6 (motion), Section 7 (elevation) +**PURPOSE:** Returns the concrete visual vocabulary - specific tracking values, radius range, shadow style, motion timing, density, CSS example. This is the single most important data source for the DESIGN.md. +**USE RESULT TO:** Set every visual property. The personality vocabulary IS the design system skeleton. + +### Call 3: `designer_get_page_template(page_type)` +**FILLS:** Section 5 (components), Section 9 (responsive) +**PURPOSE:** Returns section anatomy with component inventory and which cognitive laws apply to this page type. Without this, you're inventing sections from scratch. +**USE RESULT TO:** Define what sections to build, what components each needs, what responsive behavior each requires. + +### Call 4: `designer_get_anti_patterns(industry: resolved_industry)` +**FILLS:** Section 8 (do's/don'ts), Section 10 (anti-patterns) +**PURPOSE:** Returns the specific violations this industry must avoid. Without this, you might put AI purple on a bank or neon on a healthcare app. +**USE RESULT TO:** Write the Do's/Don'ts section and the anti-pattern checklist. Every "Don't" must come from this list. + +## Context Calls (Only When the Product Needs Them) + +These are NOT routine. Call ONLY when the product has these specific features. + +| Product Feature | Call | FILLS | WHY (what decision it changes) | +|---|---|---|---| +| **Landing page** | `designer_get_landing_pattern("hero-section")` | Section 5 | Conversion stats change hero layout: value prop in 3s, CTA above fold, 40-80px bleed | +| **Landing page** | `designer_get_landing_pattern("section-ordering")` | Section 5 | Unbounce 41K pages: Heroβ†’Proofβ†’Problemβ†’Featuresβ†’Testimonialsβ†’Pricingβ†’FAQβ†’CTA | +| **Landing page** | `designer_get_landing_pattern("social-proof")` | Section 5 | Named metrics (+30-70%) vs logos (+260%) vs badges (+55%) changes proof section design | +| **Landing page** | `designer_get_landing_pattern("cta-optimization")` | Section 8 | First-person CTAs +90%, single CTA +266%, "no credit card" +34% | +| **Pricing page** | `designer_get_landing_pattern("pricing-psychology")` | Section 5 | Ariely decoy changes tier structure: 3 tiers, highlight middle, expensive first | +| **Forms** | `designer_get_interaction_pattern("form-design")` | Section 5 | Validation timing (blur not input), label placement (top not placeholder), max field count | +| **Navigation** | `designer_get_interaction_pattern("navigation")` | Section 5 | Hamburger is 39% slower on desktop (NNG). Tab bars +58% engagement. Changes nav type. | +| **Onboarding** | `designer_get_interaction_pattern("onboarding")` | Section 5 | 3-5 checklist items outperform 8+. Interactive > passive. Changes onboarding structure. | +| **Data tables** | `designer_get_interaction_pattern("skeleton-vs-spinner")` | Section 6 | Skeleton for known structure, spinner for discrete actions. Changes loading pattern. | +| **Error handling** | `designer_get_ux_writing("error-messages")` | Section 8 | NNG rubric: what happened + why + how to fix. Changes error message format. | +| **CTAs/buttons** | `designer_get_ux_writing("button-labels")` | Section 8 | "Start my trial" +90% vs "Start your trial". Changes button copy strategy. | +| **Premium feel** | `designer_get_design_system("stripe")` or `("vercel-geist")` | Section 1 | Specific values to reference: Stripe weight 300/500, Vercel -0.04em tracking | +| **Enterprise** | `designer_get_design_system("ibm-carbon")` | Section 1 | Carbon's 12px spacing-04, IBM Plex, a11y-first component architecture | + +## Token Calls (Phase 5 only - when generating code) + +Do NOT call these during design resolution. Call them when writing actual CSS. + +``` +design_tokens_get_category("colors") β†’ OKLCH ramp construction procedure +design_tokens_get_category("typography") β†’ type scale token definitions +design_tokens_get_category("spacing") β†’ 4px grid token definitions +design_tokens_generate(description) β†’ generate complete Tailwind v4 CSS +``` + +--- + +# PHASE 3: CONSTRAINT APPLICATION + +Cross-reference every decision against the rules below. + +--- + +# DESIGN RULES BY PRIORITY + +*Follow P1β†’P10. Higher priority = fix first. Every rule has a source.* + +## P1: Accessibility (CRITICAL) + +| Rule | Standard | Avoid | +|---|---|---| +| `contrast-body` | 4.5:1 minimum for body text (AA); 7:1 for AAA | Testing only in light mode | +| `contrast-large` | 3:1 for text >= 18px bold or >= 24px | Assuming brand colors pass | +| `contrast-ui` | 3:1 for UI components, borders, icons | Low-contrast borders in dark mode | +| `focus-rings` | 2px ring, 2px offset, primary color on ALL interactive elements | `outline: none` without replacement | +| `touch-targets` | Min 44x44px (WCAG 2.5.5); recommended 48x48px; gap >= 8px | Touch targets < 44px on mobile | +| `color-not-only` | Color + icon/text for every state (error, success, warning) | Red border as sole error indicator | +| `reduced-motion` | `prefers-reduced-motion: reduce` with `!important` in `@layer base` | Missing media query (WCAG 2.3.3) | +| `keyboard-nav` | Tab order = visual order; Enter/Space activates; Escape closes | Unreachable interactive elements | +| `skip-links` | `Skip to main content` as first body element | No skip link on nav-heavy pages | +| `alt-text` | Descriptive for informational images; `alt=""` for decorative | `alt="image"` or missing alt | +| `aria-labels` | `aria-label` on icon-only buttons (on the button, not the icon) | Unlabeled icon buttons | +| `heading-hierarchy` | Sequential h1β†’h2β†’h3, no skipping levels | h1 β†’ h3 (skipped h2) | +| `zoom-support` | Layout works at 400% zoom; never `user-scalable=no` | Disabling pinch-to-zoom | +| `semantic-html` | `