From 4e691f79b175f7cfafc2f8c26a902ac4f086517f Mon Sep 17 00:00:00 2001 From: Fahmi Harun <34875577+kuker24@users.noreply.github.com> Date: Wed, 23 Sep 2026 19:54:09 +0700 Subject: [PATCH 1/2] feat(wave): modernize CBM 0.11.0, shadcn 4.21.0, impeccable email reference, and Emil motion doctrines - Upgrade codebase-memory-mcp to 0.11.0 with SHA-256 archive and inner binary verification, plus automatic --format json argument passing in lib/cbm.py. - Bump shadcn CLI MCP pin to 4.21.0 across policies, installer, routing, and doctor tests. - Refresh impeccable craft floor mechanics in craft-floor.md from upstream tag skill-v4.3.1 / main (e0881d2de397). - Create skills/impeccable/reference/email.md synthesizing anti-slop email design with client rendering resilience (table layout for raw HTML,
allowed for preheaders/enhancement, framework exemption for React Email/MJML) and wire email routing. - Consolidate Emil Kowalski motion doctrines into skills/emil-design-eng/references/ (motion.md, apple-principles.md, native-motion.md, interface-feel.md) preserving exact 62-catalog freeze. - Align docs/source-wave.md, CHANGELOG.md, THIRD_PARTY_NOTICES.md, and vendor/sources.json with explicit dispositions (PIN_ONLY vs body refreshed) and full upstream attributions. - Add unit test coverage for CBM archive/binary checksum verification and shadcn@4.21.0 mcp subcommand probing. --- CHANGELOG.md | 9 + README.md | 4 +- THIRD_PARTY_NOTICES.md | 2 + docs/mcp.md | 4 +- docs/source-wave.md | 14 +- lib/cbm.py | 5 +- lib/install.py | 11 +- rules/00-routing.md | 2 +- skills/emil-design-eng/SKILL.md | 14 +- .../references/apple-principles.md | 100 +++++++++ skills/emil-design-eng/references/motion.md | 205 ++++++++++++++++++ .../references/native-motion.md | 170 +++++++++++++++ skills/impeccable/SKILL.md | 1 + skills/impeccable/reference/craft-floor.md | 5 + skills/impeccable/reference/email.md | 182 ++++++++++++++++ skills/impeccable/reference/routing.md | 16 +- skills/impeccable/reference/ui-hub.md | 1 + tests/fixtures/codebase-memory-mcp | 2 +- tests/test_doctor.py | 7 +- tests/test_install.py | 41 ++++ tests/test_v2_schema.py | 13 ++ vendor/mcp-policy.json | 2 +- vendor/mcp-wanted.json | 2 +- vendor/sources.json | 74 ++++++- 24 files changed, 852 insertions(+), 34 deletions(-) create mode 100644 skills/emil-design-eng/references/apple-principles.md create mode 100644 skills/emil-design-eng/references/motion.md create mode 100644 skills/emil-design-eng/references/native-motion.md create mode 100644 skills/impeccable/reference/email.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 09b6694..88eca2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +- Upgraded `codebase-memory-mcp` pin to v0.11.0 with SHA-256 verified portable tarball download, and added automatic `--format json` argument propagation in `lib/cbm.py` for reliable JSON extraction across project listing and status commands. +- Bumped `shadcn` CLI MCP pin to `4.21.0` across `vendor/mcp-wanted.json`, `vendor/mcp-policy.json`, `lib/install.py`, `rules/00-routing.md`, and doctor tests. +- Refreshed `impeccable` craft floor mechanics in `skills/impeccable/reference/craft-floor.md` from upstream `skill-v4.3.1` / main (tracking caps at -0.04em, single elevation declarations via border or shadow, banning amateur sketch imitation in SVG while preserving geometric linework, subject-world textures, and truth-grounded claims). +- Created `skills/impeccable/reference/email.md` synthesizing email design intelligence and bulletproof rendering (CosmoBlk, email-pro-max, email-skills, agent-skills): 6 committed archetypes (Editorial, Bold-mono, Minimal-lux, Founder letter, Punk/Character, Lookbook), strict presentation tables (or React Email/MJML framework components), inline CSS, 6-digit hex colors, bulletproof table-cell CTA buttons, preheader anti-spill ZWNJ padding, dark mode resilience, and <100KB deliverability constraints. +- Wired email design routing into `skills/impeccable/SKILL.md`, `skills/impeccable/reference/routing.md`, and `skills/impeccable/reference/ui-hub.md` to guarantee web component libraries are never mistakenly installed into email templates. +- Consolidated Emil Kowalski motion doctrines into `skills/emil-design-eng/references/`: created `motion.md` (decision framework, compositor-only properties, production recipes, exit choreography), `apple-principles.md` (WWDC 2018 fluid interfaces, physics-based springs, velocity handoff, momentum projection, materials, SF Pro optical sizing), and `native-motion.md` (eliminating mobile web browser tells, 100dvh, safe area insets, touch-action, overscroll containment, and Expo / React Native Reanimated 3 worklets). Maintained zero new skill names, preserving catalog freeze at 62. +- Refreshed upstream pins in `vendor/sources.json` for `pbakaus/impeccable` (tag `skill-v4.3.1` `cd12f8660e2d` / verified main `e0881d2de397`), `emilkowalski/skills` (`85e8e2363b71`), `microsoft/markitdown` (v0.1.8 `b8f79c57`, PIN_ONLY), and `kunchenguid/axi` (`85a8723276ca`, PIN_ONLY). +- Updated `docs/source-wave.md`, `docs/mcp.md`, `README.md`, and `THIRD_PARTY_NOTICES.md` with complete attribution and license notices for merged doctrines. + ## 0.1.3 — 2026-09-23 - Codified the 20-member closed intent classification set in `rules/00-routing.md`, `docs/routing.md`, and `templates/AGENTS.md` (`repo_understand | bug | security | perf | ui_direction | ui_implement | motion | scroll_2d | scroll_3d | img3d | docs | ingest_md | prose | academic | browser_qa | architecture | warehouse | ops_data | video_html | demo_id`). diff --git a/README.md b/README.md index cf6df02..36ddf6e 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ Native OpenCode 2 shape (`mcp.servers`, every entry has `type`, `disabled` not V }, "shadcn": { "type": "local", - "command": ["npx", "-y", "shadcn@4.18.0", "mcp"], + "command": ["npx", "-y", "shadcn@4.21.0", "mcp"], "disabled": false } } @@ -166,7 +166,7 @@ Core (installed): - `codebase-memory-mcp` — downloaded, SHA-256 verified, Linux x86_64. If the binary will not run, doctor reports `DEGRADED`, never fake `CONNECTED`. - `context7` — `https://mcp.context7.com/mcp` (no secret stored) -- `shadcn` — `npx -y shadcn@4.18.0 mcp` +- `shadcn` — `npx -y shadcn@4.21.0 mcp` Optional: diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 3fef3be..a5d7680 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -27,6 +27,8 @@ Machine-readable copy: `vendor/license-audit.json`. | `academic` | Original first-party text. Conceptual pipeline (research→write→review→revise) independently implemented. No source copied from Imbad0202/academic-research-skills (CC-BY-NC-4.0). | MIT © 2026 OpenCodeHighEnd contributors | follow MIT | | `hyperframes` | [heygen-com/hyperframes](https://github.com/heygen-com/hyperframes); skill `NOTICE.md` | Apache-2.0 | follow Apache-2.0 | | `diagram-design` | [cathrynlavery/diagram-design](https://github.com/cathrynlavery/diagram-design); skill `NOTICE.md` | MIT © 2024-2026 Cathryn Lavery contributors | follow MIT | +| Email design doctrine | Merged from [CosmoBlk/email-design](https://github.com/CosmoBlk/email-design) (MIT © 2026 CosmoBlk), [jayesh-bansal/email-pro-max](https://github.com/jayesh-bansal/email-pro-max) (MIT © 2026 Jayesh Bansal), [chunkydotdev/email-skills](https://github.com/chunkydotdev/email-skills) (MIT © 2026 chunkydotdev), and [Olshansk/agent-skills](https://github.com/Olshansk/agent-skills) (MIT © 2026 Olshansk) into `skills/impeccable/reference/email.md` | MIT | follow MIT | +| Emil Kowalski motion doctrines | Merged from [emilkowalski/skills](https://github.com/emilkowalski/skills) (`85e8e2363b71`) into `skills/emil-design-eng/references/` (`motion.md`, `apple-principles.md`, `native-motion.md`, `interface-feel.md`) | MIT © 2024-2026 Emil Kowalski | follow MIT | | Warehouse Batch 2a (`agent-architecture-audit`, `cost-aware-llm-pipeline`, `eval-harness`, `prompt-optimizer`, `skill-stocktake`) | Adapted from [affaan-m/ECC](https://github.com/affaan-m/ECC); respective skill `NOTICE.md` files | MIT © 2024-2026 affaan-m and ECC contributors | follow MIT | | Warehouse Batch 3a (`api-design`, `automation-audit-ops`, `click-path-audit`, `code-tour`, `contract-first`) | Adapted from [affaan-m/ECC](https://github.com/affaan-m/ECC); respective skill `NOTICE.md` files | MIT © 2024-2026 affaan-m and ECC contributors | follow MIT | | Design bank media | User-provided public bootstrap artifact or existing local bank | **not cleared** | not in git; normal install does not download it | diff --git a/docs/mcp.md b/docs/mcp.md index 5476822..4bcd9e9 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -6,9 +6,9 @@ Owned: | Name | Type | Pin | | --- | --- | --- | -| codebase-memory-mcp | local stdio | 0.9.0 SHA-256 verified | +| codebase-memory-mcp | local stdio | 0.11.0 SHA-256 verified | | context7 | remote HTTP | https://mcp.context7.com/mcp | -| shadcn | local stdio | `npx -y shadcn@4.18.0 mcp` | +| shadcn | local stdio | `npx -y shadcn@4.21.0 mcp` | Optional: diff --git a/docs/source-wave.md b/docs/source-wave.md index 860eb4c..4c47d98 100644 --- a/docs/source-wave.md +++ b/docs/source-wave.md @@ -7,13 +7,13 @@ Recorded per Phase 0 contract. |---|---|---|:---:|---|---| | [miqdadbadjuber/anti-slop](https://github.com/miqdadbadjuber/anti-slop) | `743735248fbaefd76bb56619615687dfa8b3bc1e` (v3.2.9) | UI/copy filter (38 rules R-01–R-38), 3 tiers (Hard Gate, Purpose-Gate, Quality Locks), Delivery Gate checklist, Liveliness dials, during/after usage modes. MIT. | **MERGE** | `skills/impeccable` (taste-guard + direction), `skills/humanizer`, `rules/03-prose-discipline.md` | Filter, not a style guide. Do not vendor as 65th skill (`antislop` or `antislop-ui`). Distinct from Oxlint. | | [dmmulroy/anti-slop](https://github.com/dmmulroy/anti-slop) | `e8c4880471b23ab7f216fba7b27d173a6ef07d4c` (v0.1.2) | TypeScript/JavaScript Oxlint static linter ruleset. MIT. | **DONE** | `skills/install-anti-slop` | Already vendored and pinned. Strictly for static code linting on opt-in TS/JS projects. | -| [microsoft/markitdown](https://github.com/microsoft/markitdown) | `945314a45ddbe02935f2fd287b797dc0ba4a01e4` (v0.1.7 tag `63714e4`) | File to Markdown converter (Office/PDF/HTML/CSV/XLSX/PPTX/EPUB/ZIP). MIT. | **UPDATE** | `skills/markitdown` | Update pin and CLI invocation surface. Output is data-only. SmartDoc keeps contract/QA/render. MCP remains FOREIGN_ON_DEMAND. | +| [microsoft/markitdown](https://github.com/microsoft/markitdown) | `b8f79c57ebc0044be41323d89b2a45d3fda8460e` (v0.1.8) | File to Markdown converter (Office/PDF/HTML/CSV/XLSX/PPTX/EPUB/ZIP). MIT. | **PIN_ONLY** | `skills/markitdown` | Pinned to v0.1.8 (commit `b8f79c57`). CLI invocation unchanged; output remains data-only. SmartDoc keeps contract/QA/render. MCP remains FOREIGN_ON_DEMAND. | | [affaan-m/ECC](https://github.com/affaan-m/ECC) | `dd6ee538aee0f548d4a6b520118f875431fd749e` | External agent control plane (68 agents, 292 skills, hooks, learning runtime). | **REJECT** | None (`FOREIGN_ON_DEMAND`) | Do not vendor harness control plane or 292 skills. No installer mutator. Doctor does not fail when absent. Individual warehouse ports remain first-party MIT. | | [Leonxlnx/taste-skill](https://github.com/Leonxlnx/taste-skill) | `e79ca9ec7e071eb3a3b623c4fb752e853fc3ed58` (`ccbc156` base) | Design taste dials (VARIANCE, MOTION, DENSITY), quality rules, GSAP/Tailwind references. MIT. | **MERGE** | `skills/impeccable/reference/taste/direction.md`, `taste-guard.md` | Dials already integrated into Impeccable surface brief. Fenced after Design Bank or DESIGN.md direction exists. Never a frontend-design twin. | | [ashemag/human-atlas](https://github.com/ashemag/human-atlas) | `1c38bf35c254a891200d3cedecfd57abebe83d8d` | 3D human anatomy application (Three.js/R3F + BodyParts3D dataset). CC BY-SA 4.0 / CC BY 4.0 data. | **REJECT** | None (catalog reject) | Standalone 3D application, not an agent writing or coding skill. Do not vendor heavy anatomy meshes or CC BY-4.0 data into OCBF overlay. | | [oso95/scroll-world](https://github.com/oso95/scroll-world) | `71cc36d3bb150248ae36a2c552f9cbf88802a79c` | Continuous camera fly-through landing, vanilla-JS scrub engine, seam QA. MIT. | **UPDATE** | `skills/scroll-world` | Update camera style choices and composition seam QA. Retain boundary: scroll-craft = 2D timeline; scroll-world = 3D camera flight. Do not vendor paid video backends (degrade to NOT_CONFIGURED). | | [VoltAgent/awesome-design-md](https://github.com/VoltAgent/awesome-design-md) | `8147538b4226ae41e2487a9179e3bcc1f68e8554` | Curated repository of brand DESIGN.md files and design token guidelines. | **REJECT** (vendor) / **FOREIGN** (reference) | Mention in `skills/found-this-design` | Human-chosen reference corpus only. Do not clone brand files into overlay. Direction stays Design Bank + project DESIGN.md. | -| [kunchenguid/axi](https://github.com/kunchenguid/axi) | `fb752160dea2eb421b082dee77fc1d5bc152639c` | Agent eXperience Interface (AXI) — 10 CLI principles; official `gh-axi`, `chrome-devtools-axi`. MIT. | **UPDATE** | `skills/gh-axi`, `skills/chrome-devtools-axi` | Refresh command surfaces and principles from upstream. Do not introduce a generic "axi" skill. Maintain 4-door browser hierarchy. | +| [kunchenguid/axi](https://github.com/kunchenguid/axi) | `85a8723276ca` | Agent eXperience Interface (AXI) — 10 CLI principles; official `gh-axi`, `chrome-devtools-axi`. MIT. | **PIN_ONLY** | `skills/gh-axi`, `skills/chrome-devtools-axi` | Pinned commit `85a8723276ca`. Command surfaces and 4-door browser hierarchy unchanged. Do not introduce a generic "axi" skill. | | [browser-act/skills](https://github.com/browser-act/skills) | `11c057b03f92101642cadc9f840564574120d184` | BrowserAct CLI agent skills (2.0.2 stub, multi-account, stealth, session isolation). MIT. | **UPDATE** | `skills/browser-act` | Document three modes: `chrome` (profile reuse), `stealth-fresh`, `stealth-fixed`. Ban `chrome-direct`. Playwright-qa remains primary default QA adapter. | | [cursor/plugins](https://github.com/cursor/plugins) | `e31650eea443aaea1e84cc15d88c13f40080b275` (`60c641e` base) | Cursor ecosystem: pstack, SaaS connectors (Gmail, HubSpot, Salesforce), continual-learning, ralph-loop, orchestrate. | **DONE** (pstack) / **REJECT** (SaaS & autopilot) | Existing specialists | pstack principles already absorbed in routing and engineering principles. Reject foreign SaaS connectors and autopilot loops (`ralph-loop`, `orchestrate`, `continual-learning`). | | [jakubkrehel/make-interfaces-feel-better](https://ui-skills.com) | ui-skills upstream | Interface tactile feel: typography stability, hit targets, concentric border radii, layered shadows. MIT. | **MERGE** | `skills/emil-design-eng/references/interface-feel.md` | Concrete checklists for tactile feel merged directly into `emil-design-eng`. Zero catalog bloat; no new skill folder. | @@ -31,6 +31,14 @@ Recorded per Phase 0 contract. | [emilkowalski/emil-design-eng](https://github.com/emilkowalski) | animations.dev | Design engineering, interaction feel, and spring physics. | **UPDATE** | `skills/emil-design-eng/` | Update references and interaction doctrines. | | [emilkowalski/apple-design](https://github.com/emilkowalski) + [wshobson/interaction-design](https://github.com/wshobson/interaction-design) | upstream refs | Apple-grade tactile motion, velocity inheritance, interruptible springs. | **MERGE** | `skills/emil-design-eng/references/interface-feel.md` | Merge interruptible springs, velocity inheritance, and tactile press feedback. Never an Apple-clone skill. | | [mengto/beautiful-shadows](https://github.com/mengto) + [pbakaus/adapt](https://github.com/pbakaus) + [superfuture/design-review](https://github.com/superfuture) | upstream refs | Multi-layer ambient shadows, adaptive container queries, and design review checklists. | **MERGE** | `skills/emil-design-eng/references/interface-feel.md`, `skills/impeccable/reference/audit.md` | Merged bounded checklist items (≤15 bullets total). No new skill. | -| [shadcn-ui/shadcn](https://github.com/shadcn-ui/ui) | upstream ref | Shadcn component registry and CLI MCP. | **SKIP** | `mcp.servers.shadcn` | Core MCP already owned and pinned (`shadcn@4.18.0`). Skip raw skill text to prevent duplicate routing. | +| [shadcn-ui/shadcn](https://github.com/shadcn-ui/ui) | upstream ref | Shadcn component registry and CLI MCP. | **SKIP** | `mcp.servers.shadcn` | Core MCP already owned and pinned (`shadcn@4.21.0`). Skip raw skill text to prevent duplicate routing. | | [anthropics/frontend-design](https://github.com/anthropics) | upstream ref | Frontend design principles and anti-generic aesthetic filters. | **MERGE** | `skills/impeccable/reference/taste-guard.md` | Merged anti-generic rules (≤25 bullets: no cream #F4F1EA kit, no terracotta cards, token system before markup). NEVER add as skill; NEVER implement product UI from it when Design Bank misses. | | [ui-skills.com](https://www.ui-skills.com) | remote MCP | Curated design-skill reference server. | **FOREIGN_ON_DEMAND** | `docs/mcp.md` | Lookup-only remote MCP (`list_skills`, `get_skill`). Product UI remains Design Bank + Impeccable + Design V2 atoms + shadcn; BANK_MISS never generates from ui-skills document. | +| [pbakaus/impeccable](https://github.com/pbakaus/impeccable) | tag `skill-v4.3.1` (`cd12f8660e2d`), main `e0881d2de397` | Impeccable design skill suite. Apache-2.0. | **UPDATE** | `skills/impeccable` | Refreshed craft floor mechanics (`reference/craft-floor.md`) from upstream tag/main; merged anti-slop email reference (`reference/email.md`). Preserved Design Bank overlay gates. | +| [CosmoBlk/email-design](https://github.com/CosmoBlk/email-design) + [jayesh-bansal/email-pro-max](https://github.com/jayesh-bansal/email-pro-max) + [chunkydotdev/email-skills](https://github.com/chunkydotdev/email-skills) + [Olshansk/agent-skills](https://github.com/Olshansk/agent-skills) | upstream refs (`c56bfe0`, `6a28b31`, `dca18fc`, `d43745c`) | Anti-slop email design, 6 archetypes, and bulletproof multi-client HTML email rendering. MIT. | **MERGE** | `skills/impeccable/reference/email.md` | Merged into single reference under Impeccable; strict tables, inline CSS, 6-digit hex, bulletproof CTA, preheader anti-spill padding, framework exemption for React Email/MJML. No new skill. | +| [emilkowalski/skills](https://github.com/emilkowalski/skills) | `85e8e2363b71` | Animation recipes, WWDC fluid interface design, mobile web polish, and Expo motion. MIT. | **MERGE** | `skills/emil-design-eng/references/` | Merged `motion.md`, `apple-principles.md`, and `native-motion.md` into references. Zero new skill names, exact catalog freeze maintained. | +| [codebase-memory-mcp](https://github.com/codebase-memory/codebase-memory-mcp) | `v0.11.0` | Codebase indexing and symbol memory MCP server. | **UPDATE** | `vendor/sources.json`, `lib/install.py`, `lib/cbm.py` | Bumped binary pin to 0.11.0 with SHA-256 verified portable tarball and added native `--format json` argument passing for CLI commands. | +| [heygen-com/hyperframes](https://github.com/heygen-com/hyperframes) | `ed75203cb6aa` (v0.8.64) | Deterministic HTML/CSS video composition. Apache-2.0. | **PIN_ONLY** | `skills/hyperframes` | Pinned commit `ed75203cb6aa` in `vendor/sources.json`. Skill body unchanged. | +| [cathrynlavery/diagram-design](https://github.com/cathrynlavery/diagram-design) | `dc1ace47b99a` (v2.6.33) | Editorial HTML/SVG diagram design. MIT. | **PIN_ONLY** | `skills/diagram-design` | Pinned commit `dc1ace47b99a` in `vendor/sources.json`. Skill body unchanged. | +| [blader/humanizer](https://github.com/blader/humanizer) | `3.0.0` | AI prose humanizing and slop removal. MIT. | **PIN_ONLY** | `skills/humanizer` | Pinned v3.0.0 in `vendor/sources.json`. Skill body unchanged. | +| [semgrep / gitleaks / osv-scanner](https://github.com) | `semgrep` 1.177.0, `gitleaks` 8.30.1, `osv-scanner` 2.6.0 | Host security scanners. | **PIN_ONLY** | `skills/full-audit-keamanan` | Host scanner version pins recorded in `vendor/sources.json`. | diff --git a/lib/cbm.py b/lib/cbm.py index 7ec017c..88a9e03 100644 --- a/lib/cbm.py +++ b/lib/cbm.py @@ -54,7 +54,10 @@ def cbm_cli(args: list[str]) -> tuple[int, object | None, str]: bin_path = cbm_bin() if not bin_path: return 2, None, "missing" - r = run([str(bin_path), "cli", *args]) + cli_args = list(args) + if cli_args and cli_args[0] in {"list_projects", "index_status"} and "--format" not in cli_args: + cli_args.extend(["--format", "json"]) + r = run([str(bin_path), "cli", *cli_args]) text = (r.stdout or "") + (r.stderr or "") if r.returncode != 0: try: diff --git a/lib/install.py b/lib/install.py index b8a4917..44bef43 100644 --- a/lib/install.py +++ b/lib/install.py @@ -243,6 +243,7 @@ def download_codebase_memory(offline: bool = False) -> Path: sources = load_json(repo_root() / "vendor" / "sources.json")["sources"]["codebase-memory"] url = sources["artifactUrl"] expected = sources["artifactSha256"] + expected_bin = sources.get("innerBinarySha256") version = sources["version"] target_dir = share_dir() / "components" / "codebase-memory" / "bin" target = target_dir / "codebase-memory-mcp" @@ -287,6 +288,10 @@ def download_codebase_memory(offline: bool = False) -> Path: if not found: die("codebase-memory binary missing from archive") bin_path = found[0] + if expected_bin: + got_bin = sha256_file(bin_path) + if got_bin != expected_bin: + die(f"CODEBASE_MEMORY_BINARY_CHECKSUM_FAILED expected={expected_bin} got={got_bin}") bin_path.chmod(bin_path.stat().st_mode | stat.S_IXUSR) ver = run([str(bin_path), "--version"]) if ver.returncode != 0 or version not in (ver.stdout + ver.stderr): @@ -313,7 +318,7 @@ def owned_mcp_spec(cbm_bin: Path) -> dict: }, "shadcn": { "type": "local", - "command": ["npx", "-y", "shadcn@4.18.0", "mcp"], + "command": ["npx", "-y", "shadcn@4.21.0", "mcp"], "disabled": False, }, } @@ -1085,7 +1090,9 @@ def cmd_install( bank = (None, "not-requested", "DEGRADED_DESIGN_BANK") cbm = Path(os.environ.get("OPENCODE_HE_TEST_CBM") or "/nonexistent/codebase-memory-mcp") mcp_plan = merge_opencode_config(cbm, dry_run=True) - print(plan_text(meta, mcp_plan, bank, "download-or-reuse 0.9.0")) + sources = load_json(repo_root() / "vendor" / "sources.json") + cbm_ver = sources.get("sources", {}).get("codebase-memory", {}).get("version", "0.11.0") + print(plan_text(meta, mcp_plan, bank, f"download-or-reuse {cbm_ver}")) if with_design_bank: print("DESIGN_BOOTSTRAP would run after core install") print("DRY_RUN_NO_MUTATION") diff --git a/rules/00-routing.md b/rules/00-routing.md index 48b97c1..083cde2 100644 --- a/rules/00-routing.md +++ b/rules/00-routing.md @@ -86,7 +86,7 @@ Never list unused tools or uncalled MCP methods as used. - Repository structure and impact: MCP `codebase-memory-mcp` first. If Codebase Memory has no project for cwd, skip it and use repo files. Do not retry. - Exact cross-file symbol work: MCP `serena` only if already registered and only after Codebase Memory and simpler repo evidence are not enough. Do not run Serena and Codebase Memory as the main brain at the same time. If Serena is absent, say so; do not `opencode mcp add serena` from a session unless the user asked. Helper: `opencode-he serena enable`. - Current library or framework docs: MCP `context7` only when repo evidence is insufficient. -- Installable React/shadcn registry items: MCP `shadcn` (pinned CLI `shadcn@4.18.0`). Search, inspect, then install. Context7 stays documentation. +- Installable React/shadcn registry items: MCP `shadcn` (pinned CLI `shadcn@4.21.0`). Search, inspect, then install. Context7 stays documentation. - Broader web research: built-in `WebSearch` and `WebFetch`. MCP `exa` is foreign/pre-existing and ON_DEMAND. Use it only if already connected and research needs it. Never add or remove `exa`. - Hard, high-impact, divergent decisions, fuzzy debugging, API or schema alternatives, trap detection: `/adhd` on demand only. Skip ADHD for typos, ordinary CRUD, or bugs with a known cause. - Official library, spec, or first-party API facts: `/research` (Context7 when repo evidence is not enough). Why *this repo* chose an approach: suggest `/why` (manual). Do not mix the two. diff --git a/skills/emil-design-eng/SKILL.md b/skills/emil-design-eng/SKILL.md index ab1a534..bcf741a 100644 --- a/skills/emil-design-eng/SKILL.md +++ b/skills/emil-design-eng/SKILL.md @@ -675,12 +675,10 @@ When reviewing UI code, check for: | Same enter/exit transition speed | Make exit faster than enter (e.g., enter 2s, exit 200ms) | | Elements all appear at once | Add stagger delay (30-80ms between items) | -## Interface Feel & Tactile Polish +## Reference Modules -Beyond animation curves, great interfaces feel responsive and stable through tactile details: -- **Typography**: Apply `tabular-nums` to numbers/metrics to eliminate layout jitter. Use `text-wrap: balance` on headlines and `text-wrap: pretty` on copy. -- **Hit targets**: Maintain >=44×44px hit targets (using negative pseudo-element insets if visual element is smaller). Set `user-select: none` on clickable badges/controls. -- **Surfaces**: Enforce concentric nested radius (`inner = max(0, outer - padding)`). Use layered diffuse shadows and 1px semi-transparent borders. -- **Optical alignment**: Nudge icons in text containers up 0.5–1px for baseline harmony. - -See detailed checklist in [references/interface-feel.md](references/interface-feel.md). +For deeper doctrine and production code recipes, consult the specialized references: +- **[references/motion.md](references/motion.md)**: Web animation construction, decision gates, compositor-only rules, and ready-to-use component recipes. +- **[references/apple-principles.md](references/apple-principles.md)**: WWDC 2018 fluid interface principles, spring physics, velocity handoff, and momentum projection. +- **[references/native-motion.md](references/native-motion.md)**: Eradicating mobile browser tells (100dvh, safe-area-inset, tap-highlight, overscroll) and React Native / Expo Reanimated 3 motion. +- **[references/interface-feel.md](references/interface-feel.md)**: Tactile polish checklist (tabular-nums, concentric radius, multi-layer shadows, hit target ergonomics). diff --git a/skills/emil-design-eng/references/apple-principles.md b/skills/emil-design-eng/references/apple-principles.md new file mode 100644 index 0000000..8b0a594 --- /dev/null +++ b/skills/emil-design-eng/references/apple-principles.md @@ -0,0 +1,100 @@ +# Fluid Interfaces & Apple Design Principles + +Synthesized from Apple's design engineering foundations and WWDC *Designing Fluid Interfaces* (WWDC 2018), translated for modern web and native application engineering. + +--- + +## 1. The Core Law of Fluidity + +> An interface feels alive when motion begins from the current on-screen position, inherits the user's velocity, projects momentum forward, and remains interruptible at any sub-millisecond instant. + +When software treats animations as fire-and-forget fixed-duration movies, it feels stiff and mechanical. When software treats motion as physical objects governed by mass, stiffness, and damping, it feels like an extension of the user's body. + +--- + +## 2. The Nine Fluid Interaction Principles + +### Principle 1: Zero Latency Response +Immediate visual confirmation on pointerdown. When a user touches or clicks a surface, visual acknowledgment must occur within 16ms (the very first frame). +- Never wait for a click or pointerup event before providing visual feedback. +- Buttons scale to `0.97` or illuminate immediately on pointerdown. + +### Principle 2: 1:1 Direct Manipulation +While a pointer or finger is moving across the screen, the dragged element must track 1:1 with pointer coordinates. +- No lagging behind or rubber-banding while within active bounds. +- The anchor point under the user's cursor remains locked. + +### Principle 3: Absolute Interruptibility +**This is the single most critical principle in modern interaction design.** +- If an element is animating in and the user taps close, it must immediately reverse from its current position and velocity. +- Never block gestures with boolean flags like `isAnimating = true`. +- Never queue transitions sequentially when the user rapidly toggles state; blend them dynamically. + +### Principle 4: Springs Over Bezier Timers +Fixed-duration bezier curves (`transition: transform 300ms ease`) cannot handle interruptibility smoothly because resetting time `t = 0` causes velocity jumps or hitching. +Springs do not have fixed durations—they calculate instantaneous acceleration based on distance and velocity: + +$$\text{Force} = -k \cdot x - c \cdot v$$ + +Recommended spring configurations: +- **Snappy UI (Buttons, toggles, menus)**: Stiffness: 400, Damping: 30, Mass: 1 (rapid settle, zero overshoot). +- **Smooth Sheets / Drawers**: Stiffness: 300, Damping: 32, Mass: 1 (clean glide, gentle settle). +- **Bouncy Accents (Badges, likes, celebrations)**: Stiffness: 350, Damping: 18, Mass: 1 (controlled 1-2 oscillation overshoot). + +### Principle 5: Velocity Handoff +When the user releases a drag or swipe gesture, the physics simulation must inherit the pointer's release velocity vector ($v_x, v_y$): +- If the user flicks a sheet downward fast, the closing spring must start with that downward speed. +- If the user slowly drags and lets go, initial velocity is ~0. +- A fast flick must never abruptly decelerate to a preset slow transition speed. + +### Principle 6: Momentum Projection +Project the user's trajectory to decide target state: +$$\text{Projected Position} = \text{Current Position} + \frac{\text{Velocity}}{\text{Deceleration Rate}}$$ +If the projected position crosses 50% of the threshold or velocity exceeds flick threshold (e.g. 500px/s), commit to the open/close state even if the release point was only 20% along the path. + +### Principle 7: Spatial Symmetry & Anchor Points +- Elements must exit along the path they entered. A drawer that slides in from the bottom must slide out to the bottom. +- Popovers, context menus, and tooltips must anchor their `transform-origin` to the exact bounding box of the trigger control, not screen center. + +### Principle 8: Rubber-Banding at Soft Boundaries +When dragging beyond valid scroll or drag limits, apply logarithmic resistance rather than a hard stop: +$$dx_{\text{clamped}} = dx_{\text{boundary}} + (dx - dx_{\text{boundary}}) \times \left(1 - \frac{1}{\frac{|dx - dx_{\text{boundary}}|}{\text{dimension}} \times c + 1}\right)$$ +This communicates boundary elasticity and hints that the action has reached its extent. + +### Principle 9: Reduced Motion & Accessibility +When `prefers-reduced-motion: reduce` is active: +- Disable spatial translations (`translateX`, `translateY`, `scale`). +- Preserve instantaneous or subtle cross-fade opacity transitions (`150ms ease-out`). +- Never strip functional state changes; ensure focus outlines and selection badges remain visible. + +--- + +## 3. Materials, Depth & Translucency + +In Apple design, depth is functional hierarchy, not decoration: +1. **Translucent Frosted Materials**: + - Navigation bars, toolbars, and sheets use backdrop blur with semi-transparent backgrounds to maintain environmental context: + ```css + backdrop-filter: blur(20px) saturate(180%); + background-color: rgba(255, 255, 255, 0.75); /* Light */ + /* Dark mode */ + background-color: rgba(18, 18, 18, 0.75); + ``` +2. **Specular Hairlines & Bevels**: + - Glass surfaces feature an inner 1px white highlight at top (`inset 0 1px 0 rgba(255, 255, 255, 0.15)`) to ground illumination. +3. **Concentric Radii**: + - Outer and inner rounded rectangles must share a center: + $$\text{Radius}_{\text{inner}} = \max(0, \text{Radius}_{\text{outer}} - \text{Padding})$$ + +--- + +## 4. Typography Discipline (Optical Sizing & SF Pro Harmony) + +- **Tracking (Letter Spacing)**: + - Large display type (≥32px): tight negative tracking (`-0.02em` to `-0.03em`). + - Standard body text (14–17px): default tracking (`0em`). + - Small captions / badges (10–12px): slightly positive tracking (`+0.01em` to `+0.03em`). +- **Tabular Figures**: + - Always enforce `tabular-nums` on timers, counters, stock tickers, and tabular data to avoid vibrating characters. +- **Dynamic Type Balance**: + - Use `text-wrap: balance` for titles up to 3 lines. diff --git a/skills/emil-design-eng/references/motion.md b/skills/emil-design-eng/references/motion.md new file mode 100644 index 0000000..b59e9bc --- /dev/null +++ b/skills/emil-design-eng/references/motion.md @@ -0,0 +1,205 @@ +# Motion Engineering & Animation Recipes + +Knowledge synthesized from Emil Kowalski's animation engineering doctrines. Use this reference when building, refining, or reviewing interface animations. + +--- + +## 1. The Animation Decision Framework + +Before writing animation code, run these three gates in order: + +### Gate 1: Should this animate at all? +Base the decision on usage frequency: + +| Frequency | Action | Example | +| --- | --- | --- | +| **100+ times/day** | **Zero animation. Ever.** | Command palettes, keyboard shortcuts, tabs, editor hotkeys | +| **Tens of times/day** | **Minimal or instantaneous** | Hover states, list item selection, dropdown menus | +| **Occasional (a few times/session)** | **Standard polished motion** | Modals, drawers, toasts, accordions | +| **Rare / First-run** | **Can add expressive delight** | Onboarding milestones, celebrations, success states | + +**Never animate keyboard-initiated actions.** Users type at 60–100 WPM; animation introduces perceived lag and breaks muscle memory. + +### Gate 2: What is the purpose? +Valid purposes: +- **Spatial consistency**: Dialog originates from the button that triggered it; drawer slides back to the edge it came from. +- **State confirmation**: Button depresses on click to prove input was acknowledged. +- **Preventing jarring cuts**: Smoothly transitioning layout when items are added or removed. +- **Orientation**: Directing attention to what just changed (e.g. toast notification). + +If the answer is merely "it looks fancy" on a high-frequency control, cut the animation. + +### Gate 3: What easing curve? +- **Entering the screen**: Strong `ease-out` (starts instantly, decelerates smoothly). +- **Moving across screen**: Strong `ease-in-out` (smooth acceleration and deceleration). +- **Leaving the screen**: Fast `ease-in` or accelerated `ease-out` (exits must never linger). +- **Standard CSS curves (`ease`, `linear`) are too weak.** Use custom high-tension curves: + +```css +:root { + /* Strong ease-out for entering UI elements and popovers */ + --ease-out: cubic-bezier(0.23, 1, 0.32, 1); + + /* Strong ease-in-out for morphing or cross-screen repositioning */ + --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); + + /* Deep iOS-style drawer curve */ + --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); + + /* Fast exit curve */ + --ease-exit: cubic-bezier(0.4, 0, 1, 1); +} +``` + +--- + +## 2. Properties to Animate + +Stick to compositor-only properties to guarantee steady 60/120fps without layout thrash: +- **Fast / GPU-accelerated**: `transform` (`translate`, `scale`, `rotate`), `opacity`, `filter` (`blur`), `clip-path`. +- **Forbidden in high-frequency animations**: `width`, `height`, `top`, `left`, `margin`, `padding`, `border-width`. These trigger costly layout reflows on the main thread. + +For expanding accordion height, use CSS Grid 0fr → 1fr rather than animating max-height: +```css +.accordion-content { + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows 250ms var(--ease-out); +} +.accordion-content[data-expanded="true"] { + grid-template-rows: 1fr; +} +.accordion-inner { + overflow: hidden; +} +``` + +--- + +## 3. Production Animation Recipes + +### Recipe A: Button Press +Immediate feedback that the interface received the user's action: + +```css +.button { + transition: transform 140ms var(--ease-out); +} + +.button:active { + transform: scale(0.97); +} +``` + +### Recipe B: Popover, Dropdown, Menu, Select +Originates from its trigger element using dynamic `transform-origin`: + +```css +.popover { + transform-origin: var(--transform-origin, center top); + transition: + opacity 180ms var(--ease-out), + transform 180ms var(--ease-out); +} + +.popover[data-state="closed"] { + opacity: 0; + transform: scale(0.95); + pointer-events: none; +} + +.popover[data-state="open"] { + opacity: 1; + transform: scale(1); +} +``` + +### Recipe C: Tooltip with Group Instant Warmup +Tooltips delay on first hover to prevent nuisance flashing, but open instantly once a toolbar session is active: + +```css +.tooltip { + transform-origin: var(--transform-origin, center bottom); + transition: + transform 120ms var(--ease-out), + opacity 120ms var(--ease-out); +} + +.tooltip[data-state="closed"] { + opacity: 0; + transform: scale(0.96); +} + +/* When another tooltip in the group was recently open, skip delay & duration */ +.tooltip-group[data-instant] .tooltip { + transition-duration: 0ms !important; +} +``` + +### Recipe D: Centered Modal Dialog +Modals stay centered. Scale subtly from 0.95 → 1.0 (never 0 → 1.0; elements in reality do not emerge from a microscopic dot): + +```css +.modal-overlay { + transition: opacity 220ms var(--ease-out); +} +.modal-overlay[data-state="closed"] { + opacity: 0; +} + +.modal-content { + transform-origin: center center; + transition: + opacity 220ms var(--ease-out), + transform 220ms var(--ease-out); +} +.modal-content[data-state="closed"] { + opacity: 0; + transform: scale(0.95); +} +.modal-content[data-state="open"] { + opacity: 1; + transform: scale(1); +} +``` + +### Recipe E: Bottom Sheet / Drawer +Slides cleanly from viewport edge with iOS-like deceleration: + +```css +.drawer { + transition: transform 320ms var(--ease-drawer); + transform: translateY(0); +} + +.drawer[data-state="closed"] { + transform: translateY(100%); +} +``` + +### Recipe F: List Item Exit / Deletion Choreography +Collapsing deleted items smoothly without jarring jumps: +1. Fade and slide out item horizontally (`opacity: 0; transform: translateX(20px);`). +2. Collapse item height and margin to 0 over 200ms using CSS grid or height animation on wrapper. +3. Cleanly remove node from DOM. + +--- + +## 4. Exit Choreography Rules + +1. **Exits must be faster than entries.** If entering takes 250ms, exiting should take 160–180ms. The user has already finished interacting and wants the obstacle out of the way. +2. **Never stagger exits.** Entering items can stagger by 20–30ms to reveal structure. Exiting items should vanish simultaneously or near-instantly. +3. **No exit spring oscillations.** Springs that overshoot on exit look sloppy; use clean critical damping or straight ease-out. + +--- + +## 5. Review Format Checklist + +When reviewing animation code, format output in a Markdown comparison table: + +| Before | After | Why | +| --- | --- | --- | +| `transition: all 300ms ease;` | `transition: transform 180ms var(--ease-out);` | Never animate `all`; specify properties and use high-tension ease-out. | +| `transform: scale(0);` | `transform: scale(0.95); opacity: 0;` | Elements should scale from ~95%, not thin air. | +| `ease-in` on dropdown menu | `ease-out` | `ease-in` starts slowly and feels sluggish to human touch. | +| Missing active state | `transform: scale(0.97)` on `:active` | Touch/click lacks tactile confirmation without active scale. | diff --git a/skills/emil-design-eng/references/native-motion.md b/skills/emil-design-eng/references/native-motion.md new file mode 100644 index 0000000..c1aae18 --- /dev/null +++ b/skills/emil-design-eng/references/native-motion.md @@ -0,0 +1,170 @@ +# Mobile Native & Touch Interaction Engineering + +Engineering guidelines for mobile web polish and native mobile motion (React Native / Expo / iOS / Android). Synthesized from Emil Kowalski's mobile-native and animate-expo doctrines. + +--- + +## 1. Web on Mobile: Eradicating Browser Tells + +When running a web app on a mobile device, eliminating "website tells" transforms the perceived quality from an ordinary web page to an installed application: + +### A. Viewport & 100dvh +- Standard `100vh` on mobile browsers includes the dynamic address bar, causing layout jumping when scrolling begins. +- Use `100dvh` (dynamic viewport height) or `100svh` (small viewport height) for full-screen application shells: + ```css + .app-shell { + height: 100dvh; + min-height: 100dvh; + } + ``` +- Viewport meta tag configuration: + ```html + + ``` + +### B. Safe Area Insets (The Notch & Home Indicator) +Ensure fixed navigation bars, headers, and floating action buttons respect device safe zones: +```css +.header { + padding-top: max(16px, env(safe-area-inset-top)); +} +.bottom-bar { + padding-bottom: max(16px, env(safe-area-inset-bottom)); +} +``` + +### C. Eliminating the Gray Tap Highlight +Mobile Safari and Android Chrome flash an ugly gray rectangular highlight on tapped elements by default: +```css +* { + -webkit-tap-highlight-color: transparent; +} +``` + +### D. Eliminating 300ms Tap Delay & Unwanted Pinch Zoom +Add `touch-action: manipulation` to interactive controls. This signals to the browser that double-tap-to-zoom is not needed, removing the 300ms gesture disambiguation delay: +```css +button, a, input, [role="button"] { + touch-action: manipulation; +} +``` + +### E. Preventing iOS Auto-Zoom on Input Focus +iOS Safari automatically zooms the page when an ``, `