From 33e35bce3c1e419c973926660acc5099cb74e8d4 Mon Sep 17 00:00:00 2001 From: Eduardo Marquez <55303379+DocksDocks@users.noreply.github.com> Date: Tue, 25 Aug 2026 00:13:52 -0300 Subject: [PATCH] feat(skills): fix 24-skill audit findings, add routing, remove okf-bundle Implements reviewed plan #35: - remove okf-bundle (zero inbound references) - security/refactor: GitHub-issue-only lifecycle, full phase label set - fix-workflow: A05:2025, finding-field input mapping, lifecycle routing - tdd/test-coverage/commit-discipline: routing + rewrite confirmation gates - type-safety/solid/code-clarity: Kotlin 1.7+ claim, exhaustive strategy map, three-way boundary routes - accessibility/design-tokenization/react-component-patterns: dialog claim qualified, reciprocal routing - make-interfaces-feel-better: re-vendored at pinned upstream 5a4076a with injection review; divergences enumerated in metadata.patches - productivity wording fixes; content hashes re-synced --- README.md | 2 +- .../skills/engineering/accessibility/SKILL.md | 6 +- .../skills/engineering/code-clarity/SKILL.md | 6 +- .../engineering/commit-discipline/SKILL.md | 37 ++-- .../engineering/dep-vuln-workflow/SKILL.md | 4 +- .../references/npm-pnpm-playbook.md | 2 +- .../engineering/design-tokenization/SKILL.md | 8 +- .../skills/engineering/fix-workflow/SKILL.md | 7 +- .../references/security-fix-templates.md | 4 +- .../make-interfaces-feel-better/SKILL.md | 172 +++++++++------- .../references/animations.md | 66 ++++--- .../references/icons.md | 63 ++++++ .../references/performance.md | 6 +- .../references/surfaces.md | 56 ++---- .../references/typography.md | 33 +++- .../react-component-patterns/SKILL.md | 6 +- .../skills/engineering/refactor/SKILL.md | 12 +- .../skills/engineering/security/SKILL.md | 12 +- .../docks/skills/engineering/solid/SKILL.md | 13 +- .../skills/engineering/tdd-workflow/SKILL.md | 10 +- .../skills/engineering/test-coverage/SKILL.md | 5 +- .../type-safety-discipline/SKILL.md | 8 +- .../references/kotlin-value-class.md | 14 +- .../productivity/multi-tool-bridge/SKILL.md | 5 +- .../skills/productivity/okf-bundle/SKILL.md | 184 ------------------ .../skills/productivity/scaffold/SKILL.md | 6 +- .../productivity/skill-maintenance/SKILL.md | 12 +- .../skills/productivity/zoom-out/SKILL.md | 6 +- 28 files changed, 348 insertions(+), 417 deletions(-) create mode 100644 plugins/docks/skills/engineering/make-interfaces-feel-better/references/icons.md delete mode 100644 plugins/docks/skills/productivity/okf-bundle/SKILL.md diff --git a/README.md b/README.md index fc29343e..4d302e39 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Auto-trigger on matching tasks (all `user-invocable: false`): | `solid` | Generic SOLID for TS/Python/Go modules — strategy maps, discriminated unions, fat-interface splits, dependency injection | | `type-safety-discipline` | Branded/newtype IDs, discriminated unions, parse-don't-validate — TS primary; references for Rust/Kotlin/Python | -Plus `write-skill`, `multi-tool-bridge` (CLAUDE.md ↔ AGENTS.md ↔ skills bridging), `zoom-out`, and `caveman` under `productivity/`. +The `productivity/` category contains `context-tree`, `multi-tool-bridge`, `scaffold`, `skill-agent-pipeline`, `skill-maintenance`, `write-skill`, and `zoom-out`. ### Plan lifecycle (the `plan-lifecycle` plugin) diff --git a/plugins/docks/skills/engineering/accessibility/SKILL.md b/plugins/docks/skills/engineering/accessibility/SKILL.md index 4459bf35..04fe34ec 100644 --- a/plugins/docks/skills/engineering/accessibility/SKILL.md +++ b/plugins/docks/skills/engineering/accessibility/SKILL.md @@ -4,8 +4,8 @@ description: "Use when making UI accessible: focus trap + restore-on-close in mo user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-07-05" - content_hash: "985675bbaf37ed2650caa40c4ea85e4f54a8cad1e973195471f250679408c579" + updated: "2026-08-25" + content_hash: "0f7879efd0b3f50143ee7b916576d681603f376e416cfb36c0babefcaaeb1e59" --- # Accessibility @@ -47,7 +47,7 @@ Native-element decision line: navigates → ``; performs an action → ` ## Focus management -**Modals: prefer native `` + `showModal()`.** It delivers the full APG dialog contract for free: `::backdrop`, everything outside made `inert`, Escape closes, implicit `aria-modal="true"`, initial focus moves inside, focus returns to the invoker on close (Baseline since 2022; verify: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dialog). +**Modals: prefer native `` + `showModal()`.** It supplies `::backdrop`, makes everything outside `inert`, closes on Escape, exposes modal semantics, and moves initial focus inside (Baseline since 2022; verify: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dialog). Focus restoration to the invoker is not guaranteed: capture the invoking element reference and restore focus explicitly on close. ```html diff --git a/plugins/docks/skills/engineering/code-clarity/SKILL.md b/plugins/docks/skills/engineering/code-clarity/SKILL.md index 562b4fbe..fad048bd 100644 --- a/plugins/docks/skills/engineering/code-clarity/SKILL.md +++ b/plugins/docks/skills/engineering/code-clarity/SKILL.md @@ -1,11 +1,11 @@ --- name: code-clarity -description: "Use when code is hard to understand without narration; improving names, types, function boundaries, comments, docstrings, error messages, or test names; deciding what belongs in code versus documentation; or removing prose that merely restates mechanics. Not for structural dead-code/duplication/SOLID audits (use refactor), correctness/security review (use code-review), or type design alone (use type-safety-discipline)." +description: "Use when code is hard to understand without narration; improving names, types, function boundaries, comments, docstrings, error messages, or test names; deciding what belongs in code versus documentation; or removing prose that merely restates mechanics. Not for dead-code/duplication sweeps (use refactor), demonstrated SOLID design patterns (use solid), correctness/security review (use code-review), or type design alone (use type-safety-discipline)." user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-07-14" - content_hash: "d926bb858cddf15a5cad1bc03f293458212bcf042bcd895b1e02b1f71aaefa83" + updated: "2026-08-25" + content_hash: "84451e4b342b8bb8ff2fd3160c13d6298b0738ff0f5c03dcbb7bf7963c9a42f4" --- # Code Clarity diff --git a/plugins/docks/skills/engineering/commit-discipline/SKILL.md b/plugins/docks/skills/engineering/commit-discipline/SKILL.md index 0bc0c41a..b98891ef 100644 --- a/plugins/docks/skills/engineering/commit-discipline/SKILL.md +++ b/plugins/docks/skills/engineering/commit-discipline/SKILL.md @@ -4,8 +4,8 @@ description: "Use when splitting work into small reviewable/atomic commits, deci user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-07-05" - content_hash: "10cb9a6d895fa037bdfe8c12d29d0abb7ac5e5df16314b6255c6c95abf726937" + updated: "2026-08-25" + content_hash: "976d6d6824383ff2213244f57e58004fc0453c3eb487e5e4c2516aff46ca3f9b" --- # Commit & PR Discipline @@ -33,10 +33,11 @@ into independently green commits, they are one commit, not two. -Never rewrite history others may have built on. Fixup, autosquash, amend, and -rebase are for your own not-yet-merged branch. Push rewritten history only with -`git push --force-with-lease` (never bare `--force` — it silently discards a -collaborator's or CI bot's newer commits), and only to your own PR branch. +Never rewrite history others may have built on. Never force-push or rewrite any +history without explicit user confirmation, even on your own PR branch. Once +confirmed, amend, autosquash, and rebase are limited to your own not-yet-merged +branch. Push rewritten history only with `git push --force-with-lease` (never +bare `--force` — it silently discards a collaborator's or CI bot's newer commits). ## When to use / when NOT @@ -128,14 +129,15 @@ type or missed `!` mis-versions the next release. ## Fixup / autosquash — clean up before review, not after Address review feedback and self-caught mistakes as fixups while the PR is open, -then fold them before merge (or let squash-merge do it — see the merge table): +then, after explicit user confirmation, fold them before merge (or let +squash-merge do it — see the merge table): ```bash git commit --fixup= # fix goes into on autosquash git commit --fixup=amend: # also reword 's message (editor opens) git commit --fixup=reword: # reword ONLY — no content change -git rebase -i --autosquash # reorders fixup! commits onto their targets -git push --force-with-lease # your own PR branch only (constraint above) +git rebase -i --autosquash # explicit user confirmation required first +git push --force-with-lease # own PR branch; explicit confirmation required ``` - `--autosquash` matches on the `fixup!`/`squash!` subject prefix against earlier @@ -144,13 +146,18 @@ git push --force-with-lease # your own PR branch only (constraint above) - `rebase.autoSquash=true` makes interactive rebases autosquash by default; whether your Git also applies it to non-interactive rebases varies by version (verify: `git rebase -h | grep -i autosquash`, or your installed `git-rebase(1)`). -- Stacked branches: `git rebase --update-refs` force-updates the other branches - pointing at rebased commits (checked-out worktrees excluded). +- After explicit user confirmation, stacked branches may use + `git rebase --update-refs` to force-update the other branches pointing at + rebased commits (checked-out worktrees excluded). - During review, PREFER pushing fixup commits over force-pushing rewrites: reviewers see what changed since their last pass; rewriting mid-review destroys their per-commit anchor points. ## PR hygiene +Plan-lifecycle branches are excluded from the generic landing guidance below. +Defer landing them to `plan-manager`, which must obtain fresh explicit user +approval to "Merge now"; do not apply generic merge, squash, or rebase advice to +those branches. GitHub's guidance (verified 2026-07-05; re-verify: ): @@ -210,11 +217,11 @@ craft into the PR title/description, which become the squashed message. | Gotcha | Consequence | Right move | |---|---|---| | `git commit -am` as reflex | stages everything tracked — unrelated edits ride along | `git add -p`, review `git diff --cached`, then commit | -| Amending or rebasing after pushing to a shared branch | collaborators' pulls diverge; their work needs manual rescue | rewrite only unpushed/own-PR-branch history; `--force-with-lease` | +| Amending or rebasing after pushing to a shared branch | collaborators' pulls diverge; their work needs manual rescue | never rewrite shared history; on your own PR branch, rewrite only after explicit user confirmation and use `--force-with-lease` | | Conventional-commit type chosen by vibe (`chore` for a bug fix) | release tooling mis-versions or drops the change from the changelog | `fix`/`feat` per actual effect; check what the repo's tooling parses | | PR description = pasted commit list | reviewer gets no narrative, reads the diff cold | write the briefing (what/why, review order, verification) | -| Force-pushing a rewrite mid-review | reviewer's inline comments detach; they re-review from scratch | push fixup commits during review; fold them at merge time | -| Merging with "fixup!" commits still unfolded | noise commits land on the base branch permanently | `rebase -i --autosquash` before merge, or use squash-merge | +| Force-pushing a rewrite mid-review | reviewer's inline comments detach; they re-review from scratch | push fixup commits during review; after explicit confirmation, fold them at merge time | +| Merging with "fixup!" commits still unfolded | noise commits land on the base branch permanently | after explicit confirmation, `rebase -i --autosquash` before merge, or use squash-merge | | Splitting so far that a commit is not independently green | bisect lands on red commits; revert takes multiple steps | the green-tree constraint bounds the split | ## Verification @@ -224,7 +231,7 @@ required (use the project's CI/validators too, if present): ```bash git log --oneline @{upstream}.. # each subject: imperative, one idea, no "and" -git rebase -i --exec 'npm test' @{upstream} # green at EVERY commit, not just HEAD +git rebase -i --exec 'npm test' @{upstream} # after confirmation; green at every commit git diff @{upstream}.. --stat # size sanity: is this one reviewable unit? ``` diff --git a/plugins/docks/skills/engineering/dep-vuln-workflow/SKILL.md b/plugins/docks/skills/engineering/dep-vuln-workflow/SKILL.md index 183437ad..fb536eba 100644 --- a/plugins/docks/skills/engineering/dep-vuln-workflow/SKILL.md +++ b/plugins/docks/skills/engineering/dep-vuln-workflow/SKILL.md @@ -4,8 +4,8 @@ description: Use when running bun/pnpm/npm/yarn audit, pip-audit, cargo audit, o user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-08-20" - content_hash: "5c5d8cc137ca9ab04ced232c915cab1dd1597c2d03222e331661694f56760e26" + updated: "2026-08-25" + content_hash: "0e50c0d72dd4c8fae297e5a3875c6bed9411dda8303d3d13a146c2320d7445e7" --- # Dependency Vulnerability & Upgrade Workflow diff --git a/plugins/docks/skills/engineering/dep-vuln-workflow/references/npm-pnpm-playbook.md b/plugins/docks/skills/engineering/dep-vuln-workflow/references/npm-pnpm-playbook.md index fd8d86d5..3f453bee 100644 --- a/plugins/docks/skills/engineering/dep-vuln-workflow/references/npm-pnpm-playbook.md +++ b/plugins/docks/skills/engineering/dep-vuln-workflow/references/npm-pnpm-playbook.md @@ -59,7 +59,7 @@ bun run lint && bun run typecheck && bun run build && bun audit pnpm lint && pnpm typecheck && pnpm build && pnpm audit ``` -Commit once: `chore(deps): bump X/Y/Z + patch CVE-XXXX-YYYY` with the advisory link in the body. +Commit in at least two independently revertible units: the security bump stands alone with the advisory link in its body, and hygiene upgrades go in a separate commit. ## JS Major Upgrade Surprises diff --git a/plugins/docks/skills/engineering/design-tokenization/SKILL.md b/plugins/docks/skills/engineering/design-tokenization/SKILL.md index 16c309ab..4f2b392c 100644 --- a/plugins/docks/skills/engineering/design-tokenization/SKILL.md +++ b/plugins/docks/skills/engineering/design-tokenization/SKILL.md @@ -1,11 +1,11 @@ --- name: design-tokenization -description: "Use when working with colors, Tailwind classes, CSS variables, dark mode, semantic/brand tokens, or theming shadcn/ui, Base UI, or Radix components. Also audits hex literals, soft tints, paired foreground tokens, and Tailwind v4 @source. Preserve the project's bg-X/text-on-X or bg-X/text-X-foreground convention. Not for React composition/effects/RSC (use react-component-patterns) or spacing/motion/radius polish (use make-interfaces-feel-better)." +description: "Use when working with colors, Tailwind classes, CSS variables, dark mode, semantic/brand tokens, or theming shadcn/ui, Base UI, or Radix components. Also audits hex literals, soft tints, paired foreground tokens, and Tailwind v4 @source. Preserve the project's bg-X/text-on-X or bg-X/text-X-foreground convention. Not for accessibility semantics/keyboard/ARIA (use accessibility), React composition/effects/RSC (use react-component-patterns), or spacing/motion/radius polish (use make-interfaces-feel-better)." user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-07-24" - content_hash: "a1ee372206679472e3790b3af150bee2030a16e638f8659a006e5da38887c461" + updated: "2026-08-25" + content_hash: "dd48a1e744a7ce5044e4c42ac32e5cd6d1b3c8f658f8bee90b4abb385dcd57a2" --- # Design Tokenization @@ -176,4 +176,4 @@ Four-step procedure. Don't skip the audit — proposing token names without seei - Tailwind v4 `@source` (automatic source detection + explicit registration): https://tailwindcss.com/docs/detecting-classes-in-source-files - shadcn/ui design tokens: https://ui.shadcn.com/docs/theming (uses the `*-foreground` convention) - Brandfetch / logo.dev — verify official hex before adding a brand token -- Companion skills: `make-interfaces-feel-better` (visual polish), `lint-no-suppressions` (when CI greps feel "annoying" — fix the violation, don't disable) +- Companion skills: `accessibility` (semantics, keyboard behavior, and ARIA), `make-interfaces-feel-better` (visual polish), `lint-no-suppressions` (when CI greps feel "annoying" — fix the violation, don't disable) diff --git a/plugins/docks/skills/engineering/fix-workflow/SKILL.md b/plugins/docks/skills/engineering/fix-workflow/SKILL.md index 3abf414f..1cbac325 100644 --- a/plugins/docks/skills/engineering/fix-workflow/SKILL.md +++ b/plugins/docks/skills/engineering/fix-workflow/SKILL.md @@ -4,8 +4,8 @@ description: Use when fixing a specific bug, security finding, performance regre user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-08-20" - content_hash: "4f92bd65d07cf1fe79dc6f103f6f78bfd03b2101b4c4d86786abdeb113216de7" + updated: "2026-08-25" + content_hash: "3c08cc3be5b2c17de11bc9ef12ef7f6be0b9810adcccbe41f57c73e801674766" --- # Fix Workflow @@ -117,6 +117,9 @@ For each finding, fill in this template before writing any code: | Revert trigger | Specific test/lint that, if it flips, triggers `git restore` | | Blast radius | What else touches this code path | +Normalize upstream findings into these fields before planning. For a `security` finding, map `location` plus `evidence` to **Files/Before**, `remediation` to **After**, `CWE` plus `exploitation` to **Why/Blast radius**, and derive **Test strategy/Revert trigger** from the exploitation path and its narrowest deterministic signal. For a `code-review` line (`SEVERITY / category / locator / defect / fix`), map `locator` plus `defect` to **Files/Before**, `fix` to **After**, `SEVERITY` plus `category` and `defect` to **Why/Blast radius**, and derive **Test strategy/Revert trigger** from the defect's observable behavior. + +Route any fix with non-local effects through the `plan-lifecycle` skill's `plan-manager`; do not treat the local fix table as approval to bypass that lifecycle. Show the user the table grouped by tier. If the plan contains any Tier 2/3 fix, print it as your final message and end the turn — do not call Edit/Write until the user approves (a Tier-1-only plan may proceed directly). **For finding-type-specific test strategies and revert triggers**, load the matching reference file from the routing table above. diff --git a/plugins/docks/skills/engineering/fix-workflow/references/security-fix-templates.md b/plugins/docks/skills/engineering/fix-workflow/references/security-fix-templates.md index 9a2e9f79..94dbbf9a 100644 --- a/plugins/docks/skills/engineering/fix-workflow/references/security-fix-templates.md +++ b/plugins/docks/skills/engineering/fix-workflow/references/security-fix-templates.md @@ -12,7 +12,7 @@ Before writing the Step 4 row for a security finding, run this checklist: | Advisory URL pinned | The "Why" field cites the advisory; no link = no traceable rationale | | Reachability confirmed | Build-time-only deps don't ship; if vuln isn't in runtime bundle, it's a hygiene fix not a security fix | | Fixed-version available | If upstream has no fix yet, plan a `replace` / `pnpm.overrides` / `[patch.crates-io]` workaround instead | -| OWASP category tagged | Helps the commit message + future grep (`OWASP A03:2021` for injection, etc.) | +| OWASP category tagged | Helps the commit message + future grep (`OWASP A05:2025` for injection, etc.) | ## Test-Strategy Template @@ -54,5 +54,5 @@ The universal "if test X fails, revert" rule isn't enough for security. Add thes - `../SKILL.md` — universal 6-step procedure - `dep-vuln-workflow` skill — severity triage and ecosystem-readiness - `lint-no-suppressions` skill — never silence security linter output -- OWASP Top 10 (2021): https://owasp.org/Top10/ +- OWASP Top 10 (2025): https://owasp.org/Top10/2025/ - GitHub Advisory Database: https://github.com/advisories diff --git a/plugins/docks/skills/engineering/make-interfaces-feel-better/SKILL.md b/plugins/docks/skills/engineering/make-interfaces-feel-better/SKILL.md index 89fcaf07..0ece5fdc 100644 --- a/plugins/docks/skills/engineering/make-interfaces-feel-better/SKILL.md +++ b/plugins/docks/skills/engineering/make-interfaces-feel-better/SKILL.md @@ -1,34 +1,28 @@ --- name: make-interfaces-feel-better -description: "Use when building or reviewing UI components; fixing positioning that 'feels off' or 'feels detached'; placing popovers/dropdowns/tooltips relative to their trigger; implementing animations, hover/press states, shadows, borders, typography, micro-interactions, or enter/exit transitions. Triggers on 'make it feel better', 'feels off', 'looks weird', or any visual-detail polish work. Not for color/token systems (use design-tokenization) or composition APIs (use react-component-patterns)." +description: "Use when building or reviewing UI components; fixing positioning that feels off; placing popovers/dropdowns/tooltips; or polishing animations, hover/press states, shadows, borders, typography, icons, and enter/exit transitions. Triggers on 'make it feel better', 'feels off', 'looks weird', or visual-detail polish. Not for color/token systems (use design-tokenization) or composition APIs (use react-component-patterns). Not for accessibility semantics/keyboard/ARIA (use accessibility)." user-invocable: true metadata: pattern: upstream-adapted - updated: "2026-07-05" + updated: "2026-08-25" upstream: source: https://github.com/jakubkrehel/make-interfaces-feel-better license: MIT - vendored_at: "2026-04-20" + vendored_at: "2026-08-25" + commit: "5a4076ac611d6610b9cb4d67f5275cb4f869411b" patches: - - "2026-07-05: animations.md easing string → ease-[cubic-bezier(...)] — upstream snippet emits a non-class" - content_hash: "9f30aa3921141efc3b63c51a1b07374776687141ab549845a3cbc45b0bd9d161" + - "2026-08-25: SKILL.md keeps docks frontmatter and relocates reference links under references/; upstream agents/openai.yaml is omitted because docks carries distribution metadata in SKILL.md" + - "2026-08-25: SKILL.md description and icons.md route accessibility semantics, keyboard, and ARIA work to accessibility" + - "2026-08-25: SKILL.md and surfaces.md distinguish WCAG 2.2 Target Size (Minimum) AA 24×24px from 44×44px touch and 40×40px dense-desktop usability heuristics" + - "2026-08-25: animations.md, surfaces.md, and typography.md add Contents tables required by docks reference hygiene" + content_hash: "7d94c2ea34fa0ed414aabda7aea4ee9484f364a37e93b5e6912a5c8030d0bcbe" --- # Details that make interfaces feel better -Great interfaces rarely come from a single thing. It's usually a collection of small details that compound into a great experience. Apply these principles when building or reviewing UI code. +Great interfaces rarely come from a single thing. It's usually a collection of small details that compound into a great experience. Apply these principles when building or reviewing UI code. Before suggesting or writing a fix, identify the project's existing styling system and express the change in that system: Tailwind in a Tailwind project, plain CSS in a CSS project, or the established CSS-in-JS approach. Never introduce a second styling system just to apply a polish fix. - -The numeric values here are tuned, not illustrative — `scale(0.96)` on press (never below `0.95`), `bounce: 0` on every spring, icon cross-fade `scale 0.25→1` / `opacity 0→1` / `blur 4px→0`, image outline at exactly `rgba(0,0,0,0.1)` (light) / `rgba(255,255,255,0.1)` (dark). A plausible-looking substitute (a `0.9` press, a `bounce: 0.2`, a slate-tinted outline) is the difference between "polished" and "off." If you change one, change it because the design calls for it, not because you guessed. - - - -Never animate `transition: all` or scope `will-change` broadly. `all` animates properties you didn't mean to (layout, color), which janks on the first interaction and defeats GPU compositing; `will-change: all` forces every property onto its own layer and exhausts GPU memory. Always name the exact properties (`transition-property: scale, opacity`), and only ever `will-change` the compositable trio `transform` / `opacity` / `filter`. - - - -Nested rounded elements must use concentric radii: `outerRadius = innerRadius + padding`. A card and the button inside it sharing one radius value is the single most common reason an interface "feels off" — the corners visibly diverge as they curve. Compute the outer radius from the inner one and the gap, every time something rounded sits inside something else rounded. - +When reviewing, slow the interface down: replay motion at 10% speed in the browser's Animations panel and walk every state: hover, focus, active, loading, empty. What feels off at 10% speed is what's subtly wrong at full speed. ## Quick Reference @@ -36,7 +30,8 @@ Nested rounded elements must use concentric radii: `outerRadius = innerRadius + | --- | --- | | [Typography](references/typography.md) | Text wrapping, font smoothing, tabular numbers | | [Surfaces](references/surfaces.md) | Border radius, optical alignment, shadows, image outlines, hit areas | -| [Animations](references/animations.md) | Interruptible animations, enter/exit transitions, icon animations, scale on press | +| [Animations](references/animations.md) | Interruptible animations, enter/exit transitions, icon animations, scale on press, motion restraint | +| [Icons](references/icons.md) | Icon stroke weight, states via `currentColor`, outline vs fill, sizing, RTL flipping | | [Performance](references/performance.md) | Transition specificity, `will-change` usage | ## Core Principles @@ -49,9 +44,9 @@ Outer radius = inner radius + padding. Mismatched radii on nested elements is th When geometric centering looks off, align optically. Buttons with icons, play triangles, and asymmetric icons all need manual adjustment. -### 3. Shadows Over Borders +### 3. Shadows for Elevation, Borders for Structure -Layer multiple transparent `box-shadow` values for natural depth. Shadows adapt to any background; solid borders don't. +For buttons, cards, and containers whose border exists only to create depth, prefer layered transparent `box-shadow` values. Keep borders that communicate structure or state: dividers, layout separators, and selected or focus states. ### 4. Interruptible Animations @@ -59,15 +54,15 @@ Use CSS transitions for interactive state changes — they can be interrupted mi ### 5. Split and Stagger Enter Animations -Don't animate a single container. Break content into semantic chunks and stagger each with ~100ms delay. +For an infrequent staged entrance where sequence helps communicate hierarchy, break content into semantic chunks and stagger them by ~100ms instead of animating one container. Do not stagger routine, high-frequency interactions. ### 6. Subtle Exit Animations -Use a small fixed `translateY` instead of full height. Exits should be softer than enters. +Use a small fixed `translateY` instead of full height. Exits should be softer than enters. Use `ease-out` for both enter and exit transitions. ### 7. Contextual Icon Animations -Animate icons with `opacity`, `scale`, and `blur` instead of toggling visibility. Use exactly these values: scale from `0.25` to `1`, opacity from `0` to `1`, blur from `4px` to `0px`. If the project has `motion` or `framer-motion` in `package.json`, use `transition: { type: "spring", duration: 0.3, bounce: 0 }` — bounce must always be `0`. If no motion library is installed, keep both icons in the DOM (one absolute-positioned) and cross-fade with CSS transitions using `cubic-bezier(0.2, 0, 0, 1)` — this gives both enter and exit animations without any dependency. +Animate icons with `opacity`, `scale`, and `blur` instead of toggling visibility. Use exactly these values: scale from `0.25` to `1`, opacity from `0` to `1`, blur from `4px` to `0px`. If the project has `motion` or `framer-motion` in `package.json`, match that package's import path (or the established nearby imports when both exist) and use `transition: { type: "spring", duration: 0.3, bounce: 0 }` — bounce must always be `0`. If no motion library is installed, keep both icons in the DOM (one absolute-positioned) and cross-fade with CSS transitions using `cubic-bezier(0.2, 0, 0, 1)` — this gives both enter and exit animations without any dependency. ### 8. Font Smoothing @@ -83,7 +78,7 @@ Use `text-wrap: balance` on headings. Use `text-wrap: pretty` for body text to a ### 11. Image Outlines -Add a subtle `1px` outline with low opacity to images for consistent depth. The color must be pure black in light mode (`rgba(0, 0, 0, 0.1)`) and pure white in dark mode (`rgba(255, 255, 255, 0.1)`) — never a near-black like slate, zinc, or any tinted neutral. A tinted outline picks up the surface color underneath it and reads as dirt on the image edge. +Add a subtle `1px` outline with low opacity to images for consistent depth. The color must be pure black in light mode (`oklch(0 0 0 / 0.1)`) and pure white in dark mode (`oklch(1 0 0 / 0.1)`), never a near-black like slate, zinc, or any tinted neutral. A tinted outline picks up the surface color underneath it and reads as dirt on the image edge. ### 12. Scale on Press @@ -97,21 +92,25 @@ Use `initial={false}` on `AnimatePresence` to prevent enter animations on first Always specify exact properties: `transition-property: scale, opacity`. Tailwind's `transition-transform` covers `transform, translate, scale, rotate`. -```css -/* BAD — animates layout + color too; the hover jank you can't pin down */ -.card { transition: all 0.2s; } - -/* GOOD — only the compositable properties you actually change */ -.card { transition-property: scale, opacity; transition-duration: 0.2s; } -``` - ### 15. Use `will-change` Sparingly Only for `transform`, `opacity`, `filter` — properties the GPU can composite. Never use `will-change: all`. Only add when you notice first-frame stutter. ### 16. Minimum Hit Area -Interactive elements need at least 40×40px hit area. Extend with a pseudo-element if the visible element is smaller. Never let hit areas of two elements overlap. +WCAG 2.2 Target Size (Minimum) (2.5.8, Level AA) requires targets to be at least 24×24 CSS px or meet its spacing or exception conditions. That conformance floor is distinct from larger usability heuristics: prefer 44×44px for touch or mobile contexts, and use 40×40px in dense desktop interfaces. Extend with a pseudo-element if the visible element is smaller. Never let hit areas of two elements overlap. + +### 17. Match Icon Stroke to Text Weight + +An icon next to text carries the text's optical weight: `1.5px` stroke beside regular (400) text, `2px` beside semibold (600). One stroke weight per icon set; never mix libraries on one surface. + +### 18. One SVG, Recolored per State + +Icons use `currentColor` and get their states (hover, selected, disabled) from CSS color and opacity, never from separate assets. Outline variant is the default; fill variant marks the active state. + +### 19. Motion Restraint + +No custom animation on high-frequency interactions: the attention cost repeats on every trigger. Motion is never the only feedback channel; every animated state change also needs a static cue such as color, icon, or label. ## Common Mistakes @@ -119,61 +118,84 @@ Interactive elements need at least 40×40px hit area. Extend with a pseudo-eleme | --- | --- | | Same border radius on parent and child | Calculate `outerRadius = innerRadius + padding` | | Icons look off-center | Adjust optically with padding or fix SVG directly | -| Hard borders between sections | Use layered `box-shadow` with transparency | -| Jarring enter/exit animations | Split, stagger, and keep exits subtle | +| Border used only to fake elevation | Use layered `box-shadow` with transparency; keep structural and state borders | +| Jarring staged entrance or contextual exit | Stagger infrequent entrances and keep context-preserving exits subtle | | Numbers cause layout shift | Apply `tabular-nums` | | Heavy text on macOS | Apply `antialiased` to root | | Animation plays on page load | Add `initial={false}` to `AnimatePresence` | | `transition: all` on elements | Specify exact properties | | First-frame animation stutter | Add `will-change: transform` (sparingly) | -| Tiny hit areas on small controls | Extend with pseudo-element to 40×40px | +| Tiny hit areas on small controls | Meet WCAG 2.2 AA: at least 24×24 CSS px or its spacing/exception conditions; prefer 44×44px for touch/mobile and 40×40px for dense desktop as usability heuristics | +| Hairline icon beside bold text | Match the stroke width to the text weight | +| Separate icon assets per state | One `currentColor` SVG, states via CSS | +| Filled icons everywhere | Outline as default, fill only for the active state | +| Entrance animation on every hover or keystroke | Instant feedback or ≤150ms opacity/color transition | ## Review Output Format -Always present changes as a markdown table with **Before** and **After** columns. Include every change you made — not just a subset. Never list findings as separate "Before:" / "After:" lines outside of a table. Group changes by principle using a heading above each table, and keep each row focused on a single diff so the reader can scan the whole list quickly. +Use `full` when no review mode is supplied. + +| Mode | Coverage | Finding cap | +| --- | --- | --- | +| `quick` | Primary user path and highest-traffic states; report only `HIGH` and `MEDIUM` issues | 5 | +| `full` | Entire requested scope across typography, surfaces, animations, icons, and performance | 15 | + +### Scope and Coverage + +State the mode, exact scope, framework, styling conventions, and any review boundary. Show what was actually inspected: + +| Category | Evidence inspected | Result | +| --- | --- | --- | +| Typography | Files, components, states, or checks | Findings count, `Clear`, or `Not reviewed` with a reason | + +Include all five Quick Reference categories. Never imply an uninspected surface was reviewed. + +### Findings + +Group findings by principle. Use a markdown table with **Severity**, **Location**, **Before**, **After**, and **Why** columns. Include every change made or proposed, not a subset. Never use separate "Before:" / "After:" lines. + +- **Severity**: `HIGH` makes an interaction inaccessible, misleading, unreadable, or repeatedly disruptive; `MEDIUM` creates a noticeable usability or consistency problem; `LOW` is isolated polish and appears only in `full` mode. +- **Location**: cite `path/to/file:line`. If the artifact has no source files, cite the exact screen and component instead. +- **Before / After**: show the current implementation and an actionable replacement. +- **Why**: name the violated principle and explain its user impact. + +Consolidate a repeated systemic issue into one row and list every affected location. Omit principles with no findings and never pad the report to reach the cap. ### Example #### Concentric border radius -| Before | After | -| --- | --- | -| `rounded-xl` on card + `rounded-xl` on inner button (`p-2`) | `rounded-2xl` on card (`12 + 8`), `rounded-lg` on inner button | -| `border-radius: 16px` on both nested surfaces | Outer `24px`, inner `16px` with `8px` padding | +| Severity | Location | Before | After | Why | +| --- | --- | --- | --- | --- | +| LOW | `src/Card.tsx:28` | `rounded-xl` on card + `rounded-xl` on inner button (`p-2`) | `rounded-2xl` on card (`8 + 8 = 16`), `rounded-lg` on inner button | Nested corners should be concentric | +| LOW | `src/card.css:11` | `border-radius: 16px` on both nested surfaces | Outer `24px`, inner `16px` with `8px` padding | Equal nested radii make the inner surface look pinched | #### Tabular numbers -| Before | After | -| --- | --- | -| `{count}` on animated counter | `{count}` | -| Default numerals on timer | Added `font-variant-numeric: tabular-nums` to root | +| Severity | Location | Before | After | Why | +| --- | --- | --- | --- | --- | +| MEDIUM | `src/Counter.tsx:17` | `{count}` | `{count}` | Proportional digits cause changing values to shift | +| LOW | `src/timer.css:8` | Default numerals on a timer | Add `font-variant-numeric: tabular-nums` to the timer | Equal-width digits keep the timer stable | #### Scale on press -| Before | After | -| --- | --- | -| ` ``` ### Collision Rule -If the extended hit area overlaps another interactive element, shrink the pseudo-element — but make it as large as possible without colliding. Two interactive elements should never have overlapping hit areas. +If the extended hit area overlaps another interactive element, shrink the pseudo-element — but make it as large as possible without colliding. Two interactive elements should never have overlapping hit areas. If a target is smaller than 24×24 CSS px, verify that it satisfies WCAG 2.5.8 spacing or another exception; the 40×40px and 44×44px values are usability heuristics, not WCAG thresholds. diff --git a/plugins/docks/skills/engineering/make-interfaces-feel-better/references/typography.md b/plugins/docks/skills/engineering/make-interfaces-feel-better/references/typography.md index 77ae2ee4..9eb0c108 100644 --- a/plugins/docks/skills/engineering/make-interfaces-feel-better/references/typography.md +++ b/plugins/docks/skills/engineering/make-interfaces-feel-better/references/typography.md @@ -1,18 +1,13 @@ # Typography +Typography rendering details that make interfaces feel better. + ## Contents - [Text Wrapping](#text-wrapping) - - [text-wrap: balance](#text-wrap-balance) - - [text-wrap: pretty](#text-wrap-pretty) - - [When to Use Which](#when-to-use-which) - [Font Smoothing (macOS)](#font-smoothing-macos) - - [Good vs. Bad](#good-vs-bad) +- [Font Family Scope](#font-family-scope) - [Tabular Numbers](#tabular-numbers) - - [When to Use](#when-to-use) - - [Caveat](#caveat) - -Typography rendering details that make interfaces feel better. ## Text Wrapping @@ -110,6 +105,28 @@ html { **Note:** This only affects macOS rendering. Other platforms ignore these properties, so it's safe to apply universally. +## Font Family Scope + +This skill does not require a specific font family. Do not introduce a paid or proprietary typeface just to satisfy the polish checklist. + +Use the product's existing type system unless the task explicitly asks for a type change. If the design calls for a system-native macOS feel, use the system font stack. If the design calls for a commercial face such as Helvetica Now, treat it as an optional brand decision and keep a practical fallback stack. + +```css +/* System-native macOS/iOS feel */ +html { + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} +``` + +```css +/* Commercial brand face with safe fallbacks */ +html { + font-family: "Helvetica Now", "Helvetica Neue", Arial, sans-serif; +} +``` + +**Rule:** font smoothing, text wrapping, and tabular numbers are rendering details. They do not override the project's chosen font family. + ## Tabular Numbers When numbers update dynamically (counters, prices, timers, table columns), use tabular-nums to make all digits equal width. This prevents layout shift as values change. diff --git a/plugins/docks/skills/engineering/react-component-patterns/SKILL.md b/plugins/docks/skills/engineering/react-component-patterns/SKILL.md index 257a1966..b04194db 100644 --- a/plugins/docks/skills/engineering/react-component-patterns/SKILL.md +++ b/plugins/docks/skills/engineering/react-component-patterns/SKILL.md @@ -1,6 +1,6 @@ --- name: react-component-patterns -description: "Use when designing or reviewing React components — `useEffect`/`react-hooks` errors, composition APIs, Next.js RSC boundaries, or reusable shadcn/ui, Base UI, and Radix primitives. Inventory and reuse existing components first; React 19 uses ref-as-prop. Not for Tailwind/color/theme token work (use design-tokenization), visual polish (use make-interfaces-feel-better), or speculative one-caller abstractions." +description: "Use when designing or reviewing React components — `useEffect`/`react-hooks` errors, composition APIs, Next.js RSC boundaries, or reusable shadcn/ui, Base UI, and Radix primitives. Inventory and reuse existing components first; React 19 uses ref-as-prop. Not for accessibility semantics/keyboard/ARIA (use accessibility), Tailwind/color/theme token work (use design-tokenization), visual polish (use make-interfaces-feel-better), or speculative one-caller abstractions." user-invocable: false paths: - "**/*.tsx" @@ -9,8 +9,8 @@ paths: - "**/*.js" metadata: pattern: tool-wrapper - updated: "2026-07-24" - content_hash: "1dc27aeba859b5bf214e718094a51ac72ea3c8ed0ac775abe2604794f1bc5010" + updated: "2026-08-25" + content_hash: "cce28baced98fd4e6497765f24d432543231613c3187eaddeb48dd2f91cd9a08" --- # React Component Patterns diff --git a/plugins/docks/skills/engineering/refactor/SKILL.md b/plugins/docks/skills/engineering/refactor/SKILL.md index 9278d1cf..f001e266 100644 --- a/plugins/docks/skills/engineering/refactor/SKILL.md +++ b/plugins/docks/skills/engineering/refactor/SKILL.md @@ -4,8 +4,8 @@ description: "Use when auditing a codebase for structural issues — dead code, user-invocable: true metadata: pattern: pipeline - updated: "2026-08-21" - content_hash: "3c2e953bdcd16540ffb49f86bc4b157b3072e1a0793c755f5d4c9b1d20620f43" + updated: "2026-08-25" + content_hash: "082d42dc672fe8b5374559ca3f13585651d9c603288a9705bf4f759f8d897eac" --- # Refactor (cross-tool pipeline) @@ -17,7 +17,7 @@ Single-agent sequential **by default**. Execute the phases IN ORDER, in THIS con -Phases 1–5 are READ-ONLY analysis. If the user asked only for an assessment or plan, the reviewed plan is the deliverable and the run stops after reporting it. If the user asked to refactor or implement, the unified `plan-manager` owns canonical-plan creation, the single pre-implementation plan review, implementation and delegation, verification, the post-implementation code review, and archive; continue into Phases 7–8 without requiring another user-issued lifecycle command. Do not call `ExitPlanMode` (Claude-only). Stop only for a real unresolved user decision or persisted blocker. +Phases 1–5 are READ-ONLY analysis. If the user asked only for an assessment or plan, the reviewed plan is the deliverable and the run stops after reporting it. If the user asked to refactor or implement, hand the plan to `plan-manager` for the six manager lifecycle phases — decide, draft, research, plan review, implement, and code review — which are separate from this skill's internal phases. The manager owns the canonical GitHub issue, lifecycle transitions, delegation, verification, and archive; continue into Phases 7–8 without requiring another user-issued lifecycle command. Do not call `ExitPlanMode` (Claude-only). Stop only for a real unresolved user decision or persisted blocker. Prerequisite: `plan-lifecycle` must be installed. If `plan-workspace` or `plan-manager` is unavailable, STOP, name the missing `plan-lifecycle` plugin, and do not create or mutate a plan. @@ -67,15 +67,15 @@ Phase 3 uses Phase 2a's SAFE tier to skip files about to be deleted. Phase 4 mer ## How to run each phase 1. Anchor the date once (`date "+%Y-%m-%d"`), record scope (a path, or the whole project). -2. Ask `plan-manager` to create the canonical plan issue with `plan.mjs new --title --goal ` and own every lifecycle write. In a repository without a GitHub remote, use the untracked fallback below. Write an `## Environment` block (date, branch, short git status). +2. Ask `plan-manager` to create the canonical plan issue with `plan.mjs new --title --goal ` and own every lifecycle write. If no GitHub-backed plan lifecycle is available, stop and report; never write a tracked or untracked plan file. Write an `## Environment` block (date, branch, short git status). 3. For each read-only row (1 → 5), in order: read `references/.md`, perform it, write under the row's heading, confirm the heading landed before the next phase. If a phase finds nothing, write "no findings" — never silently skip. 4. At the HANDOFF, follow the request intent below. Resume at Phase 7 after the manager sets the plan `ongoing`; no user lifecycle command is required. ## The plan record (IPC + deliverable) ```text -GitHub issue # labeled plan, plan:drafting (created and managed by plan-manager) -docs/refactor-plan-.md (untracked fallback only when the repository has no GitHub remote) +GitHub issue # labeled plan plus exactly one lifecycle label: +plan:drafting | plan:planned | plan:ongoing | plan:blocked ``` Hand phase output to `plan-manager` as you go — do not hold all of it in context and dump it at the end. Downstream phases and a resumed run read the issue with `plan.mjs show --body` and locate prior output by grepping the headings. diff --git a/plugins/docks/skills/engineering/security/SKILL.md b/plugins/docks/skills/engineering/security/SKILL.md index 2c88a247..0855f55f 100644 --- a/plugins/docks/skills/engineering/security/SKILL.md +++ b/plugins/docks/skills/engineering/security/SKILL.md @@ -4,8 +4,8 @@ description: "Use when running a security audit on a codebase — OWASP Top 10, user-invocable: true metadata: pattern: pipeline - updated: "2026-08-20" - content_hash: "ad67d35bcd6555712c0186c0a5001b9474131e3e34627841eee6b2836224d8ee" + updated: "2026-08-25" + content_hash: "f108c4f561c1c05d73670783cdc425333b867e6cc64057289d7c85a8d7e290a7" --- # Security Audit (cross-tool pipeline) @@ -21,7 +21,7 @@ Read-only. This pipeline never modifies source. Its only deliverable is the audi -Intent controls the handoff, not Plan Mode. Hand the full report to `plan-manager`, which files it as a plan issue with `plan.mjs new --title --goal `, and do NOT call `ExitPlanMode` (Claude-only). `plan-workspace` owns label and workspace setup; the unified `plan-manager` owns canonical-plan creation, fresh review, lifecycle, and any requested implementation. An audit-only request ends after the report. If the current request explicitly includes remediation, keep this pipeline read-only, then hand confirmed findings to `fix-workflow` and continue through `plan-manager` without requiring another user-issued lifecycle command. Use `docs/security-audit-.md` only as an untracked fallback when the repository has no GitHub remote. +Intent controls the handoff, not Plan Mode. Hand the full report to `plan-manager`, which owns the GitHub plan issue through the six manager lifecycle phases — decide, draft, research, plan review, implement, and code review; these are separate from the audit's five internal analysis phases below. Do NOT call `ExitPlanMode` (Claude-only). `plan-workspace` owns label and workspace setup. An audit-only request ends after the report. If the current request explicitly includes remediation, keep this pipeline read-only, then hand confirmed findings to `fix-workflow` and continue through `plan-manager` without requiring another user-issued lifecycle command. If no GitHub-backed plan lifecycle is available, STOP and report that prerequisite; never write a tracked or untracked plan file. Prerequisite: `plan-lifecycle` must be installed. If `plan-workspace` or `plan-manager` is unavailable, STOP, name the missing `plan-lifecycle` plugin, and do not create or mutate a plan. @@ -62,7 +62,7 @@ Phases 2a–2c are independent lenses over the same Phase 1 map; run them sequen ## How to run each phase 1. Anchor the date once (`date "+%Y-%m-%d"`) and record scope (a path argument, or the whole project). -2. Ask `plan-manager` to create the canonical audit issue with `plan.mjs new --title --goal ` and own every later lifecycle write. In a repository without a GitHub remote, use the untracked fallback below. Write an `## Environment` block: date, branch, short git status. +2. Ask `plan-manager` to create the canonical audit issue with `plan.mjs new --title --goal ` and own every later lifecycle write. If no GitHub-backed plan lifecycle is available, stop and report; never write a plan file. Write an `## Environment` block: date, branch, short git status. 3. For each pipeline row, in order: - Read `references/.md`. - Perform that analysis against the scope, using Phase 1's map as the starting point for phases 2–3. @@ -75,8 +75,8 @@ Phases 2a–2c are independent lenses over the same Phase 1 map; run them sequen The plan issue holds the whole run. It doubles as inter-phase memory and the final artifact. ```text -GitHub issue # labeled plan, plan:drafting (created and managed by plan-manager) -docs/security-audit-.md (untracked fallback only when the repository has no GitHub remote) +GitHub issue # labeled plan plus exactly one lifecycle label: +plan:drafting | plan:planned | plan:ongoing | plan:blocked ``` Hand phase output to `plan-manager` as you go — do not hold all of it in context and dump it at the end. The headings above are the contract; downstream phases and a resumed run read the issue with `plan.mjs show --body` and locate prior output by grepping for them. diff --git a/plugins/docks/skills/engineering/solid/SKILL.md b/plugins/docks/skills/engineering/solid/SKILL.md index b863e0df..f58a2545 100644 --- a/plugins/docks/skills/engineering/solid/SKILL.md +++ b/plugins/docks/skills/engineering/solid/SKILL.md @@ -1,11 +1,11 @@ --- name: solid -description: Use when designing a module / service / class with multiple concerns, refactoring a 300+ LOC file with mixed change axes, replacing a growing switch/if-else with a strategy map, converting runtime instanceof checks into discriminated unions, splitting a fat interface, or breaking a hard-coded dependency on a concrete SDK. Generic SOLID across TS / Rust / Python / Go — React-component composition lives in react-component-patterns; type-level union/`class` design in type-safety-discipline. +description: Use when designing a module / service / class with multiple concerns, refactoring a 300+ LOC file with mixed change axes, replacing a growing switch/if-else with a strategy map, converting runtime instanceof checks into discriminated unions, splitting a fat interface, or breaking a hard-coded dependency on a concrete SDK. Generic SOLID across TS / Rust / Python / Go — React-component composition lives in react-component-patterns; type-level union/`class` design in type-safety-discipline. Not for readability-only naming or prose (use code-clarity). user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-07-05" - content_hash: "778c905fca15e0a10499f5a8ca7b007e7f5603b3156db382a3826a892334e1dc" + updated: "2026-08-25" + content_hash: "8d1db580f817b4866a2d3b44505169749da88af65a42b7636fbddda47d0a7cfc" --- # SOLID — Single Responsibility, Open/Closed, Liskov, Interface Segregation, Dependency Inversion @@ -79,16 +79,17 @@ function formatEvent(type: string, e: Event): string { ```ts // GOOD — Strategy Map; new variants drop in without editing the dispatcher +type EventKind = "user_invited" | "role_changed" | "permission_granted"; type Formatter = (e: Event) => string; -const FORMATTERS: Record = { +const FORMATTERS: Record = { user_invited: (e) => `${e.actor} invited ${e.target}`, role_changed: (e) => `${e.actor} changed role`, permission_granted: (e) => `${e.actor} granted ${e.resource}`, }; -function formatEvent(type: string, e: Event): string { - return (FORMATTERS[type] ?? ((evt) => `unknown: ${type}`))(e); +function formatEvent(type: EventKind, e: Event): string { + return FORMATTERS[type](e); } ``` diff --git a/plugins/docks/skills/engineering/tdd-workflow/SKILL.md b/plugins/docks/skills/engineering/tdd-workflow/SKILL.md index 5745aae2..d784e56b 100644 --- a/plugins/docks/skills/engineering/tdd-workflow/SKILL.md +++ b/plugins/docks/skills/engineering/tdd-workflow/SKILL.md @@ -1,11 +1,11 @@ --- name: tdd-workflow -description: Use when the user asks for TDD, test-first, "write the test first then implement", "spec it out with tests", red-green-refactor, or describes a feature as input/output pairs and wants tests to drive the implementation. Also for NEW behavior with no test coverage where tests act as the spec. Not for adding tests to existing code (use test-coverage). Not for migrations/ports ("failing test per route before porting") — characterization, not spec; use the porting skill or test-coverage. +description: Use when the user asks for TDD, test-first, "write the test first then implement", "spec it out with tests", red-green-refactor, or describes a feature as input/output pairs and wants tests to drive the implementation. Also for NEW behavior with no test coverage where tests act as the spec. Not for adding tests to existing code (use test-coverage). Not for migrations/ports ("failing test per route before porting") — characterization of existing behavior belongs in test-coverage, not TDD. user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-07-05" - content_hash: "fde4faf4646f87a3dfa58d34169f4f212da9012e9fa95faf433f5eb6076e1464" + updated: "2026-08-25" + content_hash: "d5b3326c92bf72d4023f5ff2726f459875158b33a77b566c4749169d825f1fd9" --- # Test-Driven Development Workflow @@ -21,8 +21,8 @@ TDD is an ORDERING contract, not a label. Production code MUST NOT be written be - Bug fix where the user wants a regression test written first that reproduces the bug, then the fix NOT for: -- Adding tests to code that already works (use coverage-driven test generation — different skill) -- Refactoring with a safety net — pinning current behavior with tests before changing the implementation is characterization of EXISTING code, which is coverage-driven (use the test-coverage skill) +- Adding tests to code that already works (use the `test-coverage` skill) +- Structural refactoring itself (use the `refactor` skill); use `test-coverage` first only when existing behavior needs characterization - Exploratory spikes / one-shot scripts where the spec genuinely doesn't exist yet - Pure debugging where you already have a failing test from CI diff --git a/plugins/docks/skills/engineering/test-coverage/SKILL.md b/plugins/docks/skills/engineering/test-coverage/SKILL.md index b508b7d4..decca2e3 100644 --- a/plugins/docks/skills/engineering/test-coverage/SKILL.md +++ b/plugins/docks/skills/engineering/test-coverage/SKILL.md @@ -4,8 +4,8 @@ description: Use when writing tests for code that ALREADY EXISTS — adding cove user-invocable: false metadata: pattern: tool-wrapper - updated: "2026-08-20" - content_hash: "99057f59ad0d400835f2160d10f48f5106e0d2677552f6ba5f94b9337d5eb579" + updated: "2026-08-25" + content_hash: "0bdc8f81f2d1858f2fdf008f288ec927da14996dd7bc2f3e9499501afca0c683" --- # Test Coverage Generation @@ -35,6 +35,7 @@ Don't generate tests for code with no behavior worth verifying — re-export bar NOT for: - Test-first development where the test is the spec (use **tdd-workflow** — different skill, different ordering) +- Structural refactoring itself (use **refactor**; use this skill first only when existing behavior needs characterization) - Pure smoke tests that only check "does it import" (those tests are noise; write meaningful assertions or skip) ## The Six-Step Procedure diff --git a/plugins/docks/skills/engineering/type-safety-discipline/SKILL.md b/plugins/docks/skills/engineering/type-safety-discipline/SKILL.md index ab1ee3f1..7c9830d0 100644 --- a/plugins/docks/skills/engineering/type-safety-discipline/SKILL.md +++ b/plugins/docks/skills/engineering/type-safety-discipline/SKILL.md @@ -1,6 +1,6 @@ --- name: type-safety-discipline -description: "Use when designing identifier types that could be mixed up across entities (UserId vs OrderId), validating external input (form/API/env), switching over tagged unions for exhaustiveness, choosing between `any`/`unknown`/generics or `interface`/`type` alias, OR deciding whether a TypeScript `class` is justified (Error subtype, long-lived stateful object with invariants, framework-mandated shape). Primary examples in TS; equivalencies for Rust (newtype), Kotlin (value class), Python (NewType)." +description: "Use when designing identifier types that could be mixed up across entities (UserId vs OrderId), validating external input (form/API/env), switching over tagged unions for exhaustiveness, choosing between `any`/`unknown`/generics or `interface`/`type` alias, OR deciding whether a TypeScript `class` is justified (Error subtype, long-lived stateful object with invariants, framework-mandated shape). Primary examples in TS; equivalencies for Rust (newtype), Kotlin (value class), Python (NewType). Not for readability-only naming or prose (use code-clarity) or demonstrated structural SOLID patterns (use solid)." user-invocable: false paths: - "**/*.ts" @@ -11,8 +11,8 @@ paths: - "**/*.py" metadata: pattern: tool-wrapper - updated: "2026-07-05" - content_hash: "74c4701d627121b99f58d1e71065e2c45fbd318db0692cc263f4bc4d95807181" + updated: "2026-08-25" + content_hash: "836e27d3196f88f3b6ea039fc3b992856d4594042d44c040faaca41e3ebed5d0" --- # Type-Safety Discipline @@ -235,7 +235,7 @@ The runtime `throw` covers the off-chance the compiler is bypassed (data crossin **Equivalency:** - **Rust:** `match` is exhaustive by default — the compiler errors on missing arms. No special idiom needed. -- **Kotlin:** `when` over a `sealed` class/interface is exhaustive when used as an expression: `val r = when (e) { is Click -> ...; is Key -> ...; is Scroll -> ... }`. Statement form (`when (e) { ... }`) is not checked — always assign or return. +- **Kotlin:** Kotlin 1.7+ checks `when` exhaustiveness for sealed, enum, and Boolean subjects in both expression and statement form. Open-ended subjects such as `String` are not exhaustiveness-checked as statements; use expression form with `else` when every path must produce a value. - **Python:** `match` + `typing.assert_never(x)` in a wildcard arm (3.11+) forces `mypy --strict` to error on unhandled variants. ## 8. Parse, don't assert, at I/O boundaries diff --git a/plugins/docks/skills/engineering/type-safety-discipline/references/kotlin-value-class.md b/plugins/docks/skills/engineering/type-safety-discipline/references/kotlin-value-class.md index c3ceb095..73c65242 100644 --- a/plugins/docks/skills/engineering/type-safety-discipline/references/kotlin-value-class.md +++ b/plugins/docks/skills/engineering/type-safety-discipline/references/kotlin-value-class.md @@ -61,25 +61,31 @@ fun send(invite: Invite) = when (invite) { } ``` -`sealed` constrains subclasses to the same compilation unit (Kotlin 1.5+). Combined with `when` as an expression, the compiler checks exhaustiveness. +`sealed` constrains subclasses to the same compilation unit (Kotlin 1.5+). Kotlin 1.7+ checks exhaustiveness for `when` over sealed, enum, and Boolean subjects in both expression and statement form. ### Exhaustive `when` ```kotlin -// EXHAUSTIVE — `when` is used as an expression (assigned) +// EXHAUSTIVE — Kotlin 1.7+ checks this sealed-subject expression val message = when (invite) { is Invite.User -> "Sent to user ${invite.id.value}" is Invite.Guest -> "Sent to ${invite.email}" } -// NOT exhaustive — statement form, no compile-time check +// ALSO EXHAUSTIVE — sealed-subject statements are compile-checked in Kotlin 1.7+ when (invite) { is Invite.User -> sendToUser(invite.id) is Invite.Guest -> sendToGuest(invite.email, invite.name) } + +// NOT EXHAUSTIVENESS-CHECKED — String is an open-ended subject +val status: String = readStatus() +when (status) { + "ready" -> start() +} ``` -Always assign or return from `when` to get the check. +On Kotlin 1.7+, statement form is safe for sealed, enum, and Boolean subjects. For open-ended subjects such as `String`, use expression form with `else` when every path must produce a value. ## Parse-don't-validate with kotlinx.serialization diff --git a/plugins/docks/skills/productivity/multi-tool-bridge/SKILL.md b/plugins/docks/skills/productivity/multi-tool-bridge/SKILL.md index b3dbbb20..680be708 100644 --- a/plugins/docks/skills/productivity/multi-tool-bridge/SKILL.md +++ b/plugins/docks/skills/productivity/multi-tool-bridge/SKILL.md @@ -4,8 +4,8 @@ description: Use when setting up multi-tool agent compatibility in a project (Co user-invocable: true metadata: pattern: tool-wrapper - updated: "2026-08-20" - content_hash: "eb846d12a14539882857bbc651f5894efae6c258482dfea886ec004de43afcbd" + updated: "2026-08-25" + content_hash: "c34569700d395d37eff6238c5508353ffa5f7731f9ec9cf9b75639a7eb80b6ce" --- # Multi-Tool Agent Bridge @@ -126,6 +126,7 @@ For each row classified `CREATE` / `MIGRATE+SYMLINK` / `REWRITE+@IMPORT`: git mv .claude/skills/ .agents/skills/ ln -s ../../.agents/skills/ .claude/skills/ ``` + After creating each entry, run `readlink .claude/skills/`; expect `../../.agents/skills/`. Skip when destination already exists. If `.claude/skills/` is already a symlink pointing at the right target → SKIP. If it's a symlink pointing somewhere else → STOP and ask the user (do not silently fix). 4. **CLAUDE.md rewrite** — first pick the TARGET file: diff --git a/plugins/docks/skills/productivity/okf-bundle/SKILL.md b/plugins/docks/skills/productivity/okf-bundle/SKILL.md deleted file mode 100644 index fedfd493..00000000 --- a/plugins/docks/skills/productivity/okf-bundle/SKILL.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -name: okf-bundle -description: "Use when project facts — datasets, tables, API endpoints, services, metrics, runbooks — need an agent-readable home as an LLM-wiki: seeds and maintains a knowledge/ bundle in Google's Open Knowledge Format (OKF v0.1, typed markdown concepts with YAML frontmatter). Ops: seed / add concept / audit conformance. Not for per-area conventions (use context-tree), plugin skeletons (use scaffold), or adding OKF frontmatter to skills or AGENTS.md files." -user-invocable: true -metadata: - pattern: meta-skill - updated: "2026-07-03" - content_hash: "8c0e0a7edeb339e568d64e3cb8829d4890fcb6fd56ac62f5e82da42198cc3f1b" ---- - -# OKF knowledge bundle — project facts as an LLM-wiki - -The context tree organizes **conventions** (how to work here); an OKF bundle organizes **knowledge** (what is true here — the facts an agent would otherwise re-derive from raw documents every session). Google's Open Knowledge Format v0.1 formalizes Karpathy's LLM-wiki pattern into a portable spec: a directory of markdown files with YAML frontmatter, no schema registry, no required tooling. This skill seeds and maintains a `knowledge/` bundle that any OKF consumer (and any agent) can read. - - -The whole conformance surface is three rules (spec §9) — hold all three on every write: (1) every non-reserved `.md` file inside the bundle tree carries a parseable YAML frontmatter block, (2) every frontmatter block has a non-empty `type` field, (3) the reserved filenames `index.md` and `log.md` follow their defined structures. Consequence: never place an `AGENTS.md`, `CLAUDE.md`, or `SKILL.md` inside the bundle tree — they are not reserved names, so they become frontmatter-less "concept documents" and break rules 1–2. Document the bundle from the PARENT context node instead. - - - -Use RELATIVE markdown links between concepts (`[blocks](../tables/blocks.md)`), not the spec-recommended bundle-absolute form (`/tables/blocks.md`) — absolute links render broken on GitHub and in repo-rooted tooling (upstream issue #157), and Google's own sample bundles use relative links. Pin the spec version with `okf_version: "0.1"` in the bundle-root `index.md` frontmatter — the spec is a Draft with rename proposals open against its required field and reserved filenames, and the pin is the only forward-compat signal it defines. - - - -Concepts record VERIFIED facts, not aspirations: every claim sourced from outside the repo gets a `# Citations` entry, and a fact you cannot verify is omitted or explicitly marked unverified — an LLM-wiki that mints plausible-but-wrong facts is worse than no wiki, because agents downstream trust it over raw sources. Conventions, workflows, and style rules stay OUT of the bundle (they belong in AGENTS.md nodes and skills); a bundle entry answers "what is X?", never "how should I work?". - - -## Ops - -| Op | Trigger | What it does | -|---|---|---| -| **seed** | "set up a knowledge bundle", "create an OKF wiki" | Create the bundle (default root `knowledge/` at the project root; honor a user-chosen location), mine first concepts from real sources (READMEs, configs, schemas — confirm with the user; constraint 3 applies to seeds too), wire the parent context node | -| **add concept** | "document the payments API in the knowledge base" | New `/.md` with frontmatter, linked per the reachability rule below; append a `log.md` entry when the file exists | -| **audit** | "check the bundle", after any bulk edit | Run the conformance loop below; fix findings | - -## Bundle shape - -```text -knowledge/ -├── index.md # root listing; frontmatter = okf_version: "0.1" ONLY -├── log.md # optional history; ISO YYYY-MM-DD date headings -├── services/ -│ ├── index.md # per-directory listing (NO frontmatter here) -│ └── billing-api.md # a concept document -└── datasets/ - └── events.md -``` - -Concept frontmatter (spec §4.1) — `type` is the only required field: - -| Field | Status | Content | -|---|---|---| -| `type` | **required** | Short kind string (`API Endpoint`, `Dataset`, `Service`, `Metric`, `Playbook`, `Reference`) — free vocabulary, pick descriptive values | -| `title` | recommended | Display name (falls back to filename) | -| `description` | recommended | One sentence; index generators and previews use it | -| `resource` | recommended | URI of the underlying asset; omit for abstract concepts | -| `tags` | optional | YAML list of short strings | -| `timestamp` | optional | ISO 8601 datetime of last meaningful change | - -Extra keys are allowed (consumers must tolerate them); don't import vocabularies from other systems — no `name:`/`user-invocable:` here, no OKF `type:` on skill files. - -## Seeding - -Root `index.md` — the one place frontmatter is permitted in an index, and only for the version pin: - -```markdown ---- -okf_version: "0.1" ---- - -# Project knowledge - -* [Services](./services/index.md) - Service and API endpoint concepts. -* [Events dataset](./datasets/events.md) - Append-only product analytics events table. -``` - -**Reachability rule (indexes):** every concept is listed in the NEAREST `index.md` above it, and every non-root `index.md` is itself listed in its parent's index — so the root reaches everything transitively. Per-directory indexes are optional (consumers may synthesize one); create one when a directory holds 2+ concepts, and when you do, move that directory's per-concept entries out of the root into it, leaving one directory entry at the root. Adding a concept never leaves it invisible from the root chain. - -**Reserved-file structures (what rule 3 means concretely):** - -- `index.md` (any level): NO frontmatter (sole exception: the root pin above). Body = optional `#`/`##` headings + bullet entries `* [Title](./relative-link.md) - one-line description` (mirror the target's frontmatter `description`). -- `log.md`: no frontmatter; newest-first entries grouped under ISO `YYYY-MM-DD` date headings (the ISO form is the MUST; heading level is free). Entry shape by convention: - -```markdown -## 2026-07-03 - -- **Update**: documented rate limits on services/billing-api. -- **Creation**: added datasets/events. -``` - -A concept document: - -```markdown ---- -type: API Endpoint -title: Billing API -description: Internal REST API for invoicing and payment state. -resource: https://billing.internal.example.com/v2 -tags: - - payments - - internal -timestamp: "2026-07-03T14:30:00+00:00" ---- - -Owned by the payments team. Auth is service-to-service JWT; tokens mint via -the identity sidecar, never per-user. Rate limit 50 rps per caller. - -# Examples - -`GET /v2/invoices/{id}` returns the invoice envelope; 404 means never-issued, -410 means voided. - -# Citations - -[1] [payments team runbook](https://wiki.example.com/payments-runbook) -``` - -(In-bundle citation targets are fine too — but any `references/*.md` file inside the bundle is a concept document like any other and needs `type` frontmatter.) - -Body sections are free-form; `# Schema`, `# Examples`, `# Citations` are the spec's conventional headings — use them when they apply. Concept identity is the path minus `.md` (`services/billing-api`), so renames are link-breaking: update inbound links when moving a file (broken links are *conformant* — the spec treats them as not-yet-written knowledge — but they're still rot). - -**Volatile facts carry their re-derivation source.** A concept outlives the state it records, so any fact that can silently change (a rate limit, a version, a count, an endpoint) names where it re-derives — the `resource` URI, a command, or a `# Citations` entry — and the concept's `timestamp` bumps when the fact does. A fact with no re-derivation source is either stable (state it plainly) or should be omitted. Seed the bundle-root `index.md` listing with one standing line for readers: facts here were true at each concept's `timestamp` — re-verify volatile values against their stated source before acting on them. - -## Wiring into the context tree - -The bundle is documented from OUTSIDE itself. Add one row to the root `AGENTS.md` (or the nearest parent node): - -```markdown -| `knowledge/` | OKF v0.1 knowledge bundle — project facts as linked, typed markdown concepts; start at `knowledge/index.md` | -``` - -### BAD - -```text -knowledge/AGENTS.md # non-reserved .md without type → bundle no longer conformant -knowledge/CLAUDE.md # same violation; also drags conventions into the facts tree -``` - -### GOOD - -```text -AGENTS.md # parent node: one table row pointing at knowledge/ -knowledge/index.md # bundle-root listing, okf_version pinned -``` - -## Conformance audit (self-contained — no tooling required) - -Run from the bundle's PARENT directory; set `B` to the bundle root: - -```bash -B=knowledge # adjust if the bundle lives elsewhere (e.g. docs/knowledge) -find "$B" -name '*.md' ! -name index.md ! -name log.md | while read -r f; do - head -n1 "$f" | grep -qx -- '---' || { echo "9.1 no frontmatter: $f"; continue; } - awk '/^---$/{c++; next} c==1 && /^type:[[:space:]]*[^[:space:]]/{ok=1} END{exit !ok}' "$f" \ - || echo "9.2 missing/empty type: $f" -done -find "$B" \( -name index.md ! -path "$B/index.md" -o -name log.md \) \ - -exec sh -c 'head -n1 "$1" | grep -qx -- "---" && echo "9.3 frontmatter in reserved file: $1"' _ {} \; -grep -qx 'okf_version: "0.1"' "$B/index.md" 2>/dev/null || echo "pin: okf_version missing in $B/index.md" -``` - -Silent output = no rule-1/2 violations, no frontmatter in reserved files, version pin present. Two rule-3 aspects stay a manual read: `log.md` date headings are ISO-dated, and index entries follow the bullet-link shape. Then fix → re-run → repeat until silent. If the project has its own CI or validators, wire the loop there; the check needs only `find`, `grep`, and `awk`. - -## Gotchas - -| Gotcha | Rule | -|---|---| -| `index.md`/`log.md` are reserved at EVERY level | Never write a concept into those names; non-root `index.md` gets no frontmatter at all | -| A pre-existing `index.md`/`log.md` under the chosen root | It's claimed by the reserved-file rules — audit before declaring conformance | -| `log.md` date headings | MUST be ISO `YYYY-MM-DD`; the leading `**Update**`/`**Creation**` bold word is convention only | -| Non-`.md` files in the bundle | Out of conformance scope entirely — assets and data files are fine | -| Spec churn (v0.1 Draft) | Open upstream proposals rename `type`→`kind` (#154) and the reserved files (#146/#164); the `okf_version` pin is the hedge — don't chase unmerged proposals | -| OKF `timestamp` vs skill `metadata.updated` | Parallel staleness fields in different vocabularies — never unify them | - -## When NOT to use - -- Per-area conventions, lazy-loading rules → **context-tree** -- New plugin/project skeleton → **scaffold** -- Authoring or restructuring skills → **write-skill** (and never put OKF frontmatter on a SKILL.md) - -## Sources - -- Spec: (`SPEC.md`, v0.1 Draft, Apache-2.0) -- Announcement: (Google Cloud, 2026-06-12) -- Pattern: Karpathy's LLM-wiki gist diff --git a/plugins/docks/skills/productivity/scaffold/SKILL.md b/plugins/docks/skills/productivity/scaffold/SKILL.md index e670bf45..63f5d813 100644 --- a/plugins/docks/skills/productivity/scaffold/SKILL.md +++ b/plugins/docks/skills/productivity/scaffold/SKILL.md @@ -4,8 +4,8 @@ description: "Use when spinning up a new docks-style plugin project, or capturin user-invocable: true metadata: pattern: generative-skill - updated: "2026-08-21" - content_hash: "96b4c6b604aa0fc811fa3f1c7a1db4bf259616792c42c8aacb65d301be9ac8d9" + updated: "2026-08-25" + content_hash: "5c7e2316f3c6e7dc45c831806d2bee85853995696725a6933232c1aa6adc023b" --- # Scaffold — capture a repo's shape, seed new projects from it @@ -81,7 +81,7 @@ plugins/acme-tools/.claude-plugin/plugin.json ← plugin_name = "acme 3. **Choose templates.** For each file a new project needs parameterized (manifests, root AGENTS.md, node AGENTS.md), create `templates/.template` with `{{ var }}` placeholders where repo-specific values appear. 4. **Propose.** Show the spec (variables, tree_nodes, bundled_skills, scripts) + the template file list. **STOP for confirmation** (constraint 2). 5. **Write.** Create `docs/scaffold/spec.yaml`, `docs/scaffold/templates/`, and the `docs/scaffold/` context-tree node pair (AGENTS.md + CLAUDE.md). -6. **Verify.** Parse the spec as YAML; reject anchors, aliases, unknown schema versions, missing sources, and missing templates. Render every template with fixed test values into a temporary directory, require zero unresolved `{{` tokens, then run the generated project's validators. +6. **Verify.** Parse the spec as YAML; reject anchors, aliases, unknown schema versions, missing sources, and missing templates. Render every template with fixed test values into a temporary directory, require zero unresolved `{{` tokens, and validate the temporary render. Defer generated-project validator execution to seed mode, after writing a complete project. ## Workflow — seed mode (`scaffold `) diff --git a/plugins/docks/skills/productivity/skill-maintenance/SKILL.md b/plugins/docks/skills/productivity/skill-maintenance/SKILL.md index 7da173a6..a48ef48f 100644 --- a/plugins/docks/skills/productivity/skill-maintenance/SKILL.md +++ b/plugins/docks/skills/productivity/skill-maintenance/SKILL.md @@ -4,8 +4,8 @@ description: "Use when project-local SKILL.md files need validation or refresh a user-invocable: false metadata: pattern: reviewer - updated: "2026-07-05" - content_hash: "f93e5a4d42153056c333f3381d04bbb85242309be850b16a268f82f930ec56e2" + updated: "2026-08-25" + content_hash: "4e80cc6d2403b2923e3bb5b1e6eac684a7e4c25a5b149e45cbb9739b6b88b86c" --- # Skill Maintenance @@ -53,9 +53,11 @@ local behavior, and wait for explicit user approval before deleting files. typo), show the before/after as a diff and get explicit confirmation before writing — silently auto-rewriting prose can drop authored intent. Relocate verbatim; reword only on approval. -6. **Bump metadata only on meaning change.** Change `metadata.updated` when the - normalized body or any reference content changed. Do not bump it for a pure - formatting no-op. +6. **Refresh metadata only on meaning change.** When the project provides + content-hash tooling, use it to re-sync `metadata.content_hash` and + `metadata.updated` after normalized body or reference content changes. + Otherwise, bump `metadata.updated` manually. Do not update metadata for a + pure formatting no-op. 7. **Verify loading.** Re-run the narrow validator or startup command available in the project, then list any residual risk. diff --git a/plugins/docks/skills/productivity/zoom-out/SKILL.md b/plugins/docks/skills/productivity/zoom-out/SKILL.md index 13c316cd..12cd1b03 100644 --- a/plugins/docks/skills/productivity/zoom-out/SKILL.md +++ b/plugins/docks/skills/productivity/zoom-out/SKILL.md @@ -1,11 +1,11 @@ --- name: zoom-out -description: "Use when tunneling in code-level detail and you need a system-level map — modules, callers, data flow, seams — using the project's domain vocabulary. Triggers: user says \"zoom out\", \"give me a map\", \"I'm lost in this code\", \"how does this fit\"; OR you've been reading the same file for 10+ minutes without a model of the surrounding system; OR an architectural question landed and the next action isn't obvious. Output is a labelled diagram or tight bullet list, not prose." +description: "Use when tunneling in code-level detail and you need a system-level map — modules, callers, data flow, seams — using the project's domain vocabulary. Triggers: user says \"zoom out\", \"give me a map\", \"I'm lost in this code\", \"how does this fit\"; OR you've been reading the same file for 10+ minutes without a model of the surrounding system; OR an architectural question landed and the next action isn't obvious. Output is a labelled diagram or tight bullet list, not prose. Not for finding one symbol or fixing a single function (stay in direct work), or structural refactoring (use solid or refactor)." user-invocable: true metadata: pattern: micro-skill - updated: "2026-07-05" - content_hash: "178ae11f7be487c7c59cbe64ba01e8769f1fb0b003b334a0453ca4c4fe694c8e" + updated: "2026-08-25" + content_hash: "d0f032b8cf888879525a072f59d0e10e65cc546796d451465e8948115fef7d2a" --- # Zoom Out