From 62d06fb35d961439a595440c77cf1de93ad269cd Mon Sep 17 00:00:00 2001 From: xfy Date: Wed, 15 Jul 2026 14:32:04 +0800 Subject: [PATCH] =?UTF-8?q?chore(skill):=20=E6=B8=85=E7=90=86=E5=B7=B2?= =?UTF-8?q?=E5=8D=B8=E8=BD=BD=E7=9A=84=E7=AC=AC=E4=B8=89=E6=96=B9=20skills?= =?UTF-8?q?=20=E5=8F=8A=E5=85=B6=20lock=20=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/ask-matt/SKILL.md | 74 --- .agents/skills/code-review/SKILL.md | 89 ---- .agents/skills/codebase-design/DEEPENING.md | 37 -- .../skills/codebase-design/DESIGN-IT-TWICE.md | 44 -- .agents/skills/codebase-design/SKILL.md | 114 ----- .agents/skills/diagnosing-bugs/SKILL.md | 134 ----- .../scripts/hitl-loop.template.sh | 41 -- .agents/skills/domain-modeling/ADR-FORMAT.md | 47 -- .../skills/domain-modeling/CONTEXT-FORMAT.md | 60 --- .agents/skills/domain-modeling/SKILL.md | 74 --- .../skills/full-output-enforcement/SKILL.md | 49 -- .agents/skills/gpt-taste/SKILL.md | 74 --- .agents/skills/grill-me/SKILL.md | 7 - .agents/skills/grill-with-docs/SKILL.md | 7 - .agents/skills/grilling/SKILL.md | 12 - .agents/skills/handoff/SKILL.md | 16 - .../skills/high-end-visual-design/SKILL.md | 98 ---- .agents/skills/humanizer-zh/.gitignore | 6 - .agents/skills/humanizer-zh/LICENSE | 21 - .agents/skills/humanizer-zh/README.md | 239 --------- .agents/skills/humanizer-zh/SKILL.md | 484 ------------------ .agents/skills/implement/SKILL.md | 15 - .../HTML-REPORT.md | 123 ----- .../improve-codebase-architecture/SKILL.md | 66 --- .agents/skills/prototype/LOGIC.md | 79 --- .agents/skills/prototype/SKILL.md | 30 -- .agents/skills/prototype/UI.md | 112 ---- .../redesign-existing-projects/SKILL.md | 178 ------- .agents/skills/research/SKILL.md | 12 - .../skills/setup-matt-pocock-skills/SKILL.md | 127 ----- .../skills/setup-matt-pocock-skills/domain.md | 51 -- .../issue-tracker-github.md | 45 -- .../issue-tracker-gitlab.md | 46 -- .../issue-tracker-local.md | 30 -- .../setup-matt-pocock-skills/triage-labels.md | 15 - .agents/skills/stitch-design-taste/DESIGN.md | 121 ----- .agents/skills/stitch-design-taste/SKILL.md | 184 ------- .agents/skills/tdd/SKILL.md | 36 -- .agents/skills/tdd/mocking.md | 59 --- .agents/skills/tdd/tests.md | 77 --- .agents/skills/teach/GLOSSARY-FORMAT.md | 35 -- .../skills/teach/LEARNING-RECORD-FORMAT.md | 46 -- .agents/skills/teach/MISSION-FORMAT.md | 31 -- .agents/skills/teach/RESOURCES-FORMAT.md | 32 -- .agents/skills/teach/SKILL.md | 140 ----- .agents/skills/to-issues/SKILL.md | 84 --- .agents/skills/to-prd/SKILL.md | 75 --- .agents/skills/triage/AGENT-BRIEF.md | 207 -------- .agents/skills/triage/OUT-OF-SCOPE.md | 105 ---- .agents/skills/triage/SKILL.md | 112 ---- skills-lock.json | 150 ------ 51 files changed, 4150 deletions(-) delete mode 100644 .agents/skills/ask-matt/SKILL.md delete mode 100644 .agents/skills/code-review/SKILL.md delete mode 100644 .agents/skills/codebase-design/DEEPENING.md delete mode 100644 .agents/skills/codebase-design/DESIGN-IT-TWICE.md delete mode 100644 .agents/skills/codebase-design/SKILL.md delete mode 100644 .agents/skills/diagnosing-bugs/SKILL.md delete mode 100644 .agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh delete mode 100644 .agents/skills/domain-modeling/ADR-FORMAT.md delete mode 100644 .agents/skills/domain-modeling/CONTEXT-FORMAT.md delete mode 100644 .agents/skills/domain-modeling/SKILL.md delete mode 100644 .agents/skills/full-output-enforcement/SKILL.md delete mode 100644 .agents/skills/gpt-taste/SKILL.md delete mode 100644 .agents/skills/grill-me/SKILL.md delete mode 100644 .agents/skills/grill-with-docs/SKILL.md delete mode 100644 .agents/skills/grilling/SKILL.md delete mode 100644 .agents/skills/handoff/SKILL.md delete mode 100644 .agents/skills/high-end-visual-design/SKILL.md delete mode 100644 .agents/skills/humanizer-zh/.gitignore delete mode 100644 .agents/skills/humanizer-zh/LICENSE delete mode 100644 .agents/skills/humanizer-zh/README.md delete mode 100644 .agents/skills/humanizer-zh/SKILL.md delete mode 100644 .agents/skills/implement/SKILL.md delete mode 100644 .agents/skills/improve-codebase-architecture/HTML-REPORT.md delete mode 100644 .agents/skills/improve-codebase-architecture/SKILL.md delete mode 100644 .agents/skills/prototype/LOGIC.md delete mode 100644 .agents/skills/prototype/SKILL.md delete mode 100644 .agents/skills/prototype/UI.md delete mode 100644 .agents/skills/redesign-existing-projects/SKILL.md delete mode 100644 .agents/skills/research/SKILL.md delete mode 100644 .agents/skills/setup-matt-pocock-skills/SKILL.md delete mode 100644 .agents/skills/setup-matt-pocock-skills/domain.md delete mode 100644 .agents/skills/setup-matt-pocock-skills/issue-tracker-github.md delete mode 100644 .agents/skills/setup-matt-pocock-skills/issue-tracker-gitlab.md delete mode 100644 .agents/skills/setup-matt-pocock-skills/issue-tracker-local.md delete mode 100644 .agents/skills/setup-matt-pocock-skills/triage-labels.md delete mode 100644 .agents/skills/stitch-design-taste/DESIGN.md delete mode 100644 .agents/skills/stitch-design-taste/SKILL.md delete mode 100644 .agents/skills/tdd/SKILL.md delete mode 100644 .agents/skills/tdd/mocking.md delete mode 100644 .agents/skills/tdd/tests.md delete mode 100644 .agents/skills/teach/GLOSSARY-FORMAT.md delete mode 100644 .agents/skills/teach/LEARNING-RECORD-FORMAT.md delete mode 100644 .agents/skills/teach/MISSION-FORMAT.md delete mode 100644 .agents/skills/teach/RESOURCES-FORMAT.md delete mode 100644 .agents/skills/teach/SKILL.md delete mode 100644 .agents/skills/to-issues/SKILL.md delete mode 100644 .agents/skills/to-prd/SKILL.md delete mode 100644 .agents/skills/triage/AGENT-BRIEF.md delete mode 100644 .agents/skills/triage/OUT-OF-SCOPE.md delete mode 100644 .agents/skills/triage/SKILL.md diff --git a/.agents/skills/ask-matt/SKILL.md b/.agents/skills/ask-matt/SKILL.md deleted file mode 100644 index f19a17c..0000000 --- a/.agents/skills/ask-matt/SKILL.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: ask-matt -description: Ask which skill or flow fits your situation. A router over the skills in this repo. -disable-model-invocation: true ---- - -# Ask Matt - -You don't remember every skill, so ask. - -A **flow** is a path through the skills. Most paths run along one **main flow**, and two **on-ramps** merge onto it. Everything else is standalone, or a vocabulary layer that runs underneath. - -## The main flow: idea → ship - -The route most work travels. You have an idea and want it built. - -1. **`/grill-with-docs`** — sharpen the idea by interview. Start here when you **have a codebase**: it's stateful, retaining what it learns in `CONTEXT.md` and ADRs. (No codebase? Use `/grill-me` — see Standalone. Both run the same `/grilling` primitive; `grill-with-docs` is the one that leaves a paper trail.) -2. **Branch — can you settle every question in conversation?** If a question needs a runnable answer (state, business logic, a UI you have to see), detour through a prototype, bridged by **`/handoff`** in both directions (see Crossing sessions): - - **`/handoff`** out, then open a fresh session against that file, - - **`/prototype`** to answer the question with throwaway code, - - **`/handoff`** back what you learned, and reference it from the original idea thread. -3. **Branch — is this a multi-session build?** - - **Yes** → **`/to-prd`** (turn the thread into a PRD) → **`/to-issues`** (split the PRD into independently-grabbable issues). Because the issues are independent, **clear context between each one**: start a fresh session per issue and kick off **`/implement`** by passing it the PRD and the single issue to work on. - - **No** → **`/implement`** right here, in the same context window. - - Either way, **`/implement`** builds each issue by driving **`/tdd`** internally — one red-green slice at a time — then closes out by running **`/code-review`**, a two-axis review (Standards + Spec) of the diff, before committing. Reach for **`/tdd`** on its own when you just want to build a concrete behaviour test-first without a full spec, and **`/code-review`** on its own whenever you want to review a branch or PR against a fixed point. - -### Context hygiene - -Keep steps 1–3 in **one unbroken context window** — don't compact or clear until after `/to-issues` — so the grilling, PRD, and issues all build on the same thinking. Each `/implement` then starts fresh, working from the issue. - -The limit on this is the **[smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone)**: the window (~120k tokens on state-of-the-art models) within which the model still reasons sharply. If a session approaches it before `/to-issues`, don't push on degraded — `/handoff` and continue in a fresh thread. - -## On-ramps - -A starting situation that generates work, then merges onto the main flow. - -- **Bugs and requests piling up** → **`/triage`**. It moves issues through triage roles and produces agent-ready issues, which **`/implement`** later picks up. - - Triage is only for issues **you didn't create** — bug reports, incoming feature requests, anything that arrives raw. Issues that `/to-issues` produced are already agent-ready, so **don't triage them**. - -- **Something's broken** → **`/diagnosing-bugs`**. For the hard ones: the bug that resists a first glance, the intermittent flake, the regression that crept in between two known-good states. It refuses to theorise until it has a **tight feedback loop** — one command that already goes red on *this* bug — then fixes with a regression test. Its post-mortem hands off to **`/improve-codebase-architecture`** when the real finding is that there's no good seam to lock the bug down. - -## Codebase health - -Not feature work — upkeep. - -- **`/improve-codebase-architecture`** — run whenever you have a spare moment to keep the codebase good for agents to operate in. It surfaces **deepening opportunities**; picking one _generates an idea_ you can take into the main flow at `/grill-with-docs`. It's the survey that finds the candidates; **`/codebase-design`** (below) is the bench you design the chosen one on. - -## Vocabulary underneath - -Two model-invoked references that run *beneath* the other skills — each the single source of truth for its vocabulary. Reach for them directly when the **words**, not the process, are the problem; or let the skills above pull them in. - -- **`/domain-modeling`** — sharpen the project's *domain* language: challenge a fuzzy term, resolve an overloaded word ("account" doing three jobs), record a hard-to-reverse decision as an ADR. It's the active discipline `/grill-with-docs` drives to keep `CONTEXT.md` a clean glossary. -- **`/codebase-design`** — the deep-module vocabulary (module, interface, depth, seam, adapter, leverage, locality) for designing a module's *shape*: a lot of behaviour behind a small interface at a clean seam. `/tdd` and `/improve-codebase-architecture` both speak it. - -## Crossing sessions - -- **`/handoff`** — when a thread is full or you need to branch off (e.g. into a `/prototype` session), this compacts the conversation into a markdown file. You don't continue in place — you **open a new session and reference that file** to carry the context across. It's the bridge between context windows, in either direction. Use it when you want a **fresh session** but need the **current conversation preserved**. -- **`/compact`** (built-in) — stay in the **same conversation**, letting the earlier turns be summarized. Use it at **intentional breaks between phases**, when you don't mind losing the verbatim history. Don't compact mid-phase — the agent can lose its way. `/handoff` forks; `/compact` continues. - -## Standalone - -Off the main flow entirely. - -- **`/grill-me`** — the same relentless interview as `/grill-with-docs`, but for when you have **no codebase**. Stateless: it saves nothing locally, builds no `CONTEXT.md`. Reach for it to sharpen any plan or design that doesn't live in a repo. -- **`/prototype`** — a small, throwaway program that answers one design question: does this state model feel right, or what should this UI look like. Throwaway from day one — keep the answer, delete the code. It's the detour in step 2 of the main flow, but reach for it any time a design question is hard to settle on paper. -- **`/research`** — delegate reading legwork to a **background agent**: it investigates a question against **primary sources**, then leaves a cited Markdown file in the repo. Keep working while it reads. The file it produces is something to take *into* the main flow at `/grill-with-docs` — research feeds the thinking, it doesn't replace it. -- **`/teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace. -- **`/writing-great-skills`** — reference for writing and editing skills well. - -## Precondition - -**`/setup-matt-pocock-skills`** — run before your first engineering flow to configure the issue tracker, triage labels, and doc layout the other skills assume. Custom issue trackers also work. diff --git a/.agents/skills/code-review/SKILL.md b/.agents/skills/code-review/SKILL.md deleted file mode 100644 index 2a0b524..0000000 --- a/.agents/skills/code-review/SKILL.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -name: code-review -description: Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/PRD asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X". ---- - -Two-axis review of the diff between `HEAD` and a fixed point the user supplies: - -- **Standards** — does the code conform to this repo's documented coding standards? -- **Spec** — does the code faithfully implement the originating issue / PRD / spec? - -Both axes run as **parallel sub-agents** so they don't pollute each other's context, then this skill aggregates their findings. - -The issue tracker should have been provided to you — run `/setup-matt-pocock-skills` if `docs/agents/issue-tracker.md` is missing. - -## Process - -### 1. Pin the fixed point - -Whatever the user said is the fixed point — a commit SHA, branch name, tag, `main`, `HEAD~5`, etc. If they didn't specify one, ask for it. - -Capture the diff command once: `git diff ...HEAD` (three-dot, so the comparison is against the merge-base). Also note the list of commits via `git log ..HEAD --oneline`. - -Before going further, confirm the fixed point resolves (`git rev-parse `) and the diff is non-empty. A bad ref or empty diff should fail here — not inside two parallel sub-agents. - -### 2. Identify the spec source - -Look for the originating spec, in this order: - -1. Issue references in the commit messages (`#123`, `Closes #45`, GitLab `!67`, etc.) — fetch via the workflow in `docs/agents/issue-tracker.md`. -2. A path the user passed as an argument. -3. A PRD/spec file under `docs/`, `specs/`, or `.scratch/` matching the branch name or feature. -4. If nothing is found, ask the user where the spec is. If they say there isn't one, the **Spec** sub-agent will skip and report "no spec available". - -### 3. Identify the standards sources - -Anything in the repo that documents how code should be written, such as `CODING_STANDARDS.md` or `CONTRIBUTING.md`. - -On top of whatever the repo documents, the Standards axis always carries the **smell baseline** below — a fixed set of Fowler code smells (_Refactoring_, ch.3) that applies even when a repo documents nothing. Two rules bind it: - -- **The repo overrides.** A documented repo standard always wins; where it endorses something the baseline would flag, suppress the smell. -- **Always a judgement call.** Each smell is a labelled heuristic ("possible Feature Envy"), never a hard violation — and, like any standard here, skip anything tooling already enforces. - -Each smell reads *what it is* → *how to fix*; match it against the diff: - -- **Mysterious Name** — a function, variable, or type whose name doesn't reveal what it does or holds. → rename it; if no honest name comes, the design's murky. -- **Duplicated Code** — the same logic shape appears in more than one hunk or file in the change. → extract the shared shape, call it from both. -- **Feature Envy** — a method that reaches into another object's data more than its own. → move the method onto the data it envies. -- **Data Clumps** — the same few fields or params keep travelling together (a type wanting to be born). → bundle them into one type, pass that. -- **Primitive Obsession** — a primitive or string standing in for a domain concept that deserves its own type. → give the concept its own small type. -- **Repeated Switches** — the same `switch`/`if`-cascade on the same type recurs across the change. → replace with polymorphism, or one map both sites share. -- **Shotgun Surgery** — one logical change forces scattered edits across many files in the diff. → gather what changes together into one module. -- **Divergent Change** — one file or module is edited for several unrelated reasons. → split so each module changes for one reason. -- **Speculative Generality** — abstraction, parameters, or hooks added for needs the spec doesn't have. → delete it; inline back until a real need shows. -- **Message Chains** — long `a.b().c().d()` navigation the caller shouldn't depend on. → hide the walk behind one method on the first object. -- **Middle Man** — a class or function that mostly just delegates onward. → cut it, call the real target direct. -- **Refused Bequest** — a subclass or implementer that ignores or overrides most of what it inherits. → drop the inheritance, use composition. - -### 4. Spawn both sub-agents in parallel - -Send a single message with two `Agent` tool calls. Use the `general-purpose` subagent for both. - -**Standards sub-agent prompt** — include: - -- The full diff command and commit list. -- The list of standards-source files you found in step 3, **plus the smell baseline from step 3** pasted in full — the sub-agent has no other access to it. -- The brief: "Report — per file/hunk where relevant — (a) every place the diff violates a documented standard: cite the standard (file + the rule); and (b) any baseline smell you spot: name it and quote the hunk. Distinguish hard violations from judgement calls — documented-standard breaches can be hard, but baseline smells are always judgement calls, and a documented repo standard overrides the baseline. Skip anything tooling enforces. Under 400 words." - -**Spec sub-agent prompt** — include: - -- The diff command and commit list. -- The path or fetched contents of the spec. -- The brief: "Report: (a) requirements the spec asked for that are missing or partial; (b) behaviour in the diff that wasn't asked for (scope creep); (c) requirements that look implemented but where the implementation looks wrong. Quote the spec line for each finding. Under 400 words." - -If the spec is missing, skip the Spec sub-agent and note this in the final report. - -### 5. Aggregate - -Present the two reports under `## Standards` and `## Spec` headings, verbatim or lightly cleaned. Do **not** merge or rerank findings — the two axes are deliberately separate (see _Why two axes_). - -End with a one-line summary: total findings per axis, and the worst issue _within each axis_ (if any). Don't pick a single winner across axes — that's the reranking the separation exists to prevent. - -## Why two axes - -A change can pass one axis and fail the other: - -- Code that follows every standard but implements the wrong thing → **Standards pass, Spec fail.** -- Code that does exactly what the issue asked but breaks the project's conventions → **Spec pass, Standards fail.** - -Reporting them separately stops one axis from masking the other. diff --git a/.agents/skills/codebase-design/DEEPENING.md b/.agents/skills/codebase-design/DEEPENING.md deleted file mode 100644 index 3938457..0000000 --- a/.agents/skills/codebase-design/DEEPENING.md +++ /dev/null @@ -1,37 +0,0 @@ -# Deepening - -How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [SKILL.md](SKILL.md) — **module**, **interface**, **seam**, **adapter**. - -## Dependency categories - -When assessing a candidate for deepening, classify its dependencies. The category determines how the deepened module is tested across its seam. - -### 1. In-process - -Pure computation, in-memory state, no I/O. Always deepenable — merge the modules and test through the new interface directly. No adapter needed. - -### 2. Local-substitutable - -Dependencies that have local test stand-ins (PGLite for Postgres, in-memory filesystem). Deepenable if the stand-in exists. The deepened module is tested with the stand-in running in the test suite. The seam is internal; no port at the module's external interface. - -### 3. Remote but owned (Ports & Adapters) - -Your own services across a network boundary (microservices, internal APIs). Define a **port** (interface) at the seam. The deep module owns the logic; the transport is injected as an **adapter**. Tests use an in-memory adapter. Production uses an HTTP/gRPC/queue adapter. - -Recommendation shape: *"Define a port at the seam, implement an HTTP adapter for production and an in-memory adapter for testing, so the logic sits in one deep module even though it's deployed across a network."* - -### 4. True external (Mock) - -Third-party services (Stripe, Twilio, etc.) you don't control. The deepened module takes the external dependency as an injected port; tests provide a mock adapter. - -## Seam discipline - -- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a port unless at least two adapters are justified (typically production + test). A single-adapter seam is just indirection. -- **Internal seams vs external seams.** A deep module can have internal seams (private to its implementation, used by its own tests) as well as the external seam at its interface. Don't expose internal seams through the interface just because tests use them. - -## Testing strategy: replace, don't layer - -- Old unit tests on shallow modules become waste once tests at the deepened module's interface exist — delete them. -- Write new tests at the deepened module's interface. The **interface is the test surface**. -- Tests assert on observable outcomes through the interface, not internal state. -- Tests should survive internal refactors — they describe behaviour, not implementation. If a test has to change when the implementation changes, it's testing past the interface. diff --git a/.agents/skills/codebase-design/DESIGN-IT-TWICE.md b/.agents/skills/codebase-design/DESIGN-IT-TWICE.md deleted file mode 100644 index 49a7c42..0000000 --- a/.agents/skills/codebase-design/DESIGN-IT-TWICE.md +++ /dev/null @@ -1,44 +0,0 @@ -# Design It Twice - -When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best. - -Uses the vocabulary in [SKILL.md](SKILL.md) — **module**, **interface**, **seam**, **adapter**, **leverage**. - -## Process - -### 1. Frame the problem space - -Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate: - -- The constraints any new interface would need to satisfy -- The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md)) -- A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete - -Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel. - -### 2. Spawn sub-agents - -Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module. - -Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [DEEPENING.md](DEEPENING.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint: - -- Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point." -- Agent 2: "Maximise flexibility — support many use cases and extension." -- Agent 3: "Optimise for the most common caller — make the default case trivial." -- Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies." - -Include both [SKILL.md](SKILL.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language. - -Each sub-agent outputs: - -1. Interface (types, methods, params — plus invariants, ordering, error modes) -2. Usage example showing how callers use it -3. What the implementation hides behind the seam -4. Dependency strategy and adapters (see [DEEPENING.md](DEEPENING.md)) -5. Trade-offs — where leverage is high, where it's thin - -### 3. Present and compare - -Present designs sequentially so the user can absorb each one, then compare them in prose. Contrast by **depth** (leverage at the interface), **locality** (where change concentrates), and **seam placement**. - -After comparing, give your own recommendation: which design you think is strongest and why. If elements from different designs would combine well, propose a hybrid. Be opinionated — the user wants a strong read, not a menu. diff --git a/.agents/skills/codebase-design/SKILL.md b/.agents/skills/codebase-design/SKILL.md deleted file mode 100644 index 16620c2..0000000 --- a/.agents/skills/codebase-design/SKILL.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -name: codebase-design -description: Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary. ---- - -# Codebase Design - -Design **deep modules**: a lot of behaviour behind a small interface, placed at a clean seam, testable through that interface. Use this language and these principles wherever code is being designed or restructured. The aim is leverage for callers, locality for maintainers, and testability for everyone. - -## Glossary - -Use these terms exactly — don't substitute "component," "service," "API," or "boundary." Consistent language is the whole point. - -**Module** — anything with an interface and an implementation. Deliberately scale-agnostic: a function, class, package, or tier-spanning slice. _Avoid_: unit, component, service. - -**Interface** — everything a caller must know to use the module correctly: the type signature, but also invariants, ordering constraints, error modes, required configuration, and performance characteristics. _Avoid_: API, signature (too narrow — they refer only to the type-level surface). - -**Implementation** — what's inside a module, its body of code. Distinct from **Adapter**: a thing can be a small adapter with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake). Reach for "adapter" when the seam is the topic; "implementation" otherwise. - -**Depth** — leverage at the interface: the amount of behaviour a caller (or test) can exercise per unit of interface they have to learn. A module is **deep** when a large amount of behaviour sits behind a small interface, **shallow** when the interface is nearly as complex as the implementation. - -**Seam** _(Michael Feathers)_ — a place where you can alter behaviour without editing in that place; the *location* at which a module's interface lives. Where to put the seam is its own design decision, distinct from what goes behind it. _Avoid_: boundary (overloaded with DDD's bounded context). - -**Adapter** — a concrete thing that satisfies an interface at a seam. Describes *role* (what slot it fills), not substance (what's inside). - -**Leverage** — what callers get from depth: more capability per unit of interface they learn. One implementation pays back across N call sites and M tests. - -**Locality** — what maintainers get from depth: change, bugs, knowledge, and verification concentrate in one place rather than spreading across callers. Fix once, fixed everywhere. - -## Deep vs shallow - -**Deep module** = small interface + lots of implementation: - -``` -┌─────────────────────┐ -│ Small Interface │ ← Few methods, simple params -├─────────────────────┤ -│ │ -│ Deep Implementation│ ← Complex logic hidden -│ │ -└─────────────────────┘ -``` - -**Shallow module** = large interface + little implementation (avoid): - -``` -┌─────────────────────────────────┐ -│ Large Interface │ ← Many methods, complex params -├─────────────────────────────────┤ -│ Thin Implementation │ ← Just passes through -└─────────────────────────────────┘ -``` - -When designing an interface, ask: - -- Can I reduce the number of methods? -- Can I simplify the parameters? -- Can I hide more complexity inside? - -## Principles - -- **Depth is a property of the interface, not the implementation.** A deep module can be internally composed of small, mockable, swappable parts — they just aren't part of the interface. A module can have **internal seams** (private to its implementation, used by its own tests) as well as the **external seam** at its interface. -- **The deletion test.** Imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep. -- **The interface is the test surface.** Callers and tests cross the same seam. If you want to test *past* the interface, the module is probably the wrong shape. -- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a seam unless something actually varies across it. - -## Designing for testability - -Good interfaces make testing natural: - -1. **Accept dependencies, don't create them.** - - ```typescript - // Testable - function processOrder(order, paymentGateway) {} - - // Hard to test - function processOrder(order) { - const gateway = new StripeGateway(); - } - ``` - -2. **Return results, don't produce side effects.** - - ```typescript - // Testable - function calculateDiscount(cart): Discount {} - - // Hard to test - function applyDiscount(cart): void { - cart.total -= discount; - } - ``` - -3. **Small surface area.** Fewer methods = fewer tests needed. Fewer params = simpler test setup. - -## Relationships - -- A **Module** has exactly one **Interface** (the surface it presents to callers and tests). -- **Depth** is a property of a **Module**, measured against its **Interface**. -- A **Seam** is where a **Module**'s **Interface** lives. -- An **Adapter** sits at a **Seam** and satisfies the **Interface**. -- **Depth** produces **Leverage** for callers and **Locality** for maintainers. - -## Rejected framings - -- **Depth as ratio of implementation-lines to interface-lines** (Ousterhout): rewards padding the implementation. We use depth-as-leverage instead. -- **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow — interface here includes every fact a caller must know. -- **"Boundary"**: overloaded with DDD's bounded context. Say **seam** or **interface**. - -## Going deeper - -- **Deepening a cluster given its dependencies** — see [DEEPENING.md](DEEPENING.md): dependency categories, seam discipline, and replace-don't-layer testing. -- **Exploring alternative interfaces** — see [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md): spin up parallel sub-agents to design the interface several radically different ways, then compare on depth, locality, and seam placement. diff --git a/.agents/skills/diagnosing-bugs/SKILL.md b/.agents/skills/diagnosing-bugs/SKILL.md deleted file mode 100644 index f400de7..0000000 --- a/.agents/skills/diagnosing-bugs/SKILL.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -name: diagnosing-bugs -description: Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow. ---- - -# Diagnosing Bugs - -A discipline for hard bugs. Skip phases only when explicitly justified. - -When exploring the codebase, read `CONTEXT.md` (if it exists) to get a clear mental model of the relevant modules, and check ADRs in the area you're touching. - -## Phase 1 — Build a feedback loop - -**This is the skill.** Everything else is mechanical. If you have a **tight** pass/fail signal for the bug — one that goes red on _this_ bug — you will find the cause; bisection, hypothesis-testing, and instrumentation all just consume it. If you don't have one, no amount of staring at code will save you. - -Spend disproportionate effort here. **Be aggressive. Be creative. Refuse to give up.** - -### Ways to construct one — try them in roughly this order - -1. **Failing test** at whatever seam reaches the bug — unit, integration, e2e. -2. **Curl / HTTP script** against a running dev server. -3. **CLI invocation** with a fixture input, diffing stdout against a known-good snapshot. -4. **Headless browser script** (Playwright / Puppeteer) — drives the UI, asserts on DOM/console/network. -5. **Replay a captured trace.** Save a real network request / payload / event log to disk; replay it through the code path in isolation. -6. **Throwaway harness.** Spin up a minimal subset of the system (one service, mocked deps) that exercises the bug code path with a single function call. -7. **Property / fuzz loop.** If the bug is "sometimes wrong output", run 1000 random inputs and look for the failure mode. -8. **Bisection harness.** If the bug appeared between two known states (commit, dataset, version), automate "boot at state X, check, repeat" so you can `git bisect run` it. -9. **Differential loop.** Run the same input through old-version vs new-version (or two configs) and diff outputs. -10. **HITL bash script.** Last resort. If a human must click, drive _them_ with `scripts/hitl-loop.template.sh` so the loop is still structured. Captured output feeds back to you. - -Build the right feedback loop, and the bug is 90% fixed. - -### Tighten the loop - -Treat the loop as a product. Once you have _a_ loop, **tighten** it: - -- Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.) -- Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".) -- Can I make it more deterministic? (Pin time, seed RNG, isolate filesystem, freeze network.) - -A 30-second flaky loop is barely better than no loop; a 2-second deterministic one is tight — a debugging superpower. - -### Non-deterministic bugs - -The goal is not a clean repro but a **higher reproduction rate**. Loop the trigger 100×, parallelise, add stress, narrow timing windows, inject sleeps. A 50%-flake bug is debuggable; 1% is not — keep raising the rate until it's debuggable. - -### When you genuinely cannot build a loop - -Stop and say so explicitly. List what you tried. Ask the user for: (a) access to whatever environment reproduces it, (b) a captured artifact (HAR file, log dump, core dump, screen recording with timestamps), or (c) permission to add temporary production instrumentation. Do **not** proceed to hypothesise without a loop. - -### Completion criterion — a tight loop that goes red - -Phase 1 is done when the loop is **tight** and **red-capable**: you can name **one command** — a script path, a test invocation, a curl — that you have **already run at least once** (paste the invocation and its output), and that is: - -- [ ] **Red-capable** — it drives the actual bug code path and asserts the **user's exact symptom**, so it can go red on this bug and green once fixed. Not "runs without erroring" — it must be able to _catch this specific bug_. -- [ ] **Deterministic** — same verdict every run (flaky bugs: a pinned, high reproduction rate, per above). -- [ ] **Fast** — seconds, not minutes. -- [ ] **Agent-runnable** — you can run it unattended; a human in the loop only via `scripts/hitl-loop.template.sh`. - -If you catch yourself reading code to build a theory before this command exists, **stop — jumping straight to a hypothesis is the exact failure this skill prevents.** No red-capable command, no Phase 2. - -## Phase 2 — Reproduce + minimise - -Run the loop. Watch it go red — the bug appears. - -Confirm: - -- [ ] The loop produces the failure mode the **user** described — not a different failure that happens to be nearby. Wrong bug = wrong fix. -- [ ] The failure is reproducible across multiple runs (or, for non-deterministic bugs, reproducible at a high enough rate to debug against). -- [ ] You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix actually addresses it. - -### Minimise - -Once it's red, shrink the repro to the **smallest scenario that still goes red**. Cut inputs, callers, config, data, and steps **one at a time**, re-running the loop after each cut — keep only what's load-bearing for the failure. - -Why bother: a minimal repro shrinks the hypothesis space in Phase 3 (fewer moving parts left to suspect) and becomes the clean regression test in Phase 5. - -Done when **every remaining element is load-bearing** — removing any one of them makes the loop go green. - -Do not proceed until you have reproduced **and** minimised. - -## Phase 3 — Hypothesise - -Generate **3–5 ranked hypotheses** before testing any of them. Single-hypothesis generation anchors on the first plausible idea. - -Each hypothesis must be **falsifiable**: state the prediction it makes. - -> Format: "If is the cause, then will make the bug disappear / will make it worse." - -If you cannot state the prediction, the hypothesis is a vibe — discard or sharpen it. - -**Show the ranked list to the user before testing.** They often have domain knowledge that re-ranks instantly ("we just deployed a change to #3"), or know hypotheses they've already ruled out. Cheap checkpoint, big time saver. Don't block on it — proceed with your ranking if the user is AFK. - -## Phase 4 — Instrument - -Each probe must map to a specific prediction from Phase 3. **Change one variable at a time.** - -Tool preference: - -1. **Debugger / REPL inspection** if the env supports it. One breakpoint beats ten logs. -2. **Targeted logs** at the boundaries that distinguish hypotheses. -3. Never "log everything and grep". - -**Tag every debug log** with a unique prefix, e.g. `[DEBUG-a4f2]`. Cleanup at the end becomes a single grep. Untagged logs survive; tagged logs die. - -**Perf branch.** For performance regressions, logs are usually wrong. Instead: establish a baseline measurement (timing harness, `performance.now()`, profiler, query plan), then bisect. Measure first, fix second. - -## Phase 5 — Fix + regression test - -Write the regression test **before the fix** — but only if there is a **correct seam** for it. - -A correct seam is one where the test exercises the **real bug pattern** as it occurs at the call site. If the only available seam is too shallow (single-caller test when the bug needs multiple callers, unit test that can't replicate the chain that triggered the bug), a regression test there gives false confidence. - -**If no correct seam exists, that itself is the finding.** Note it. The codebase architecture is preventing the bug from being locked down. Flag this for the next phase. - -If a correct seam exists: - -1. Turn the minimised repro into a failing test at that seam. -2. Watch it fail. -3. Apply the fix. -4. Watch it pass. -5. Re-run the Phase 1 feedback loop against the original (un-minimised) scenario. - -## Phase 6 — Cleanup + post-mortem - -Required before declaring done: - -- [ ] Original repro no longer reproduces (re-run the Phase 1 loop) -- [ ] Regression test passes (or absence of seam is documented) -- [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix) -- [ ] Throwaway prototypes deleted (or moved to a clearly-marked debug location) -- [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns - -**Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off to the `/improve-codebase-architecture` skill with the specifics. Make the recommendation **after** the fix is in, not before — you have more information now than when you started. diff --git a/.agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh b/.agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh deleted file mode 100644 index 40afc46..0000000 --- a/.agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash -# Human-in-the-loop reproduction loop. -# Copy this file, edit the steps below, and run it. -# The agent runs the script; the user follows prompts in their terminal. -# -# Usage: -# bash hitl-loop.template.sh -# -# Two helpers: -# step "" → show instruction, wait for Enter -# capture VAR "" → show question, read response into VAR -# -# At the end, captured values are printed as KEY=VALUE for the agent to parse. - -set -euo pipefail - -step() { - printf '\n>>> %s\n' "$1" - read -r -p " [Enter when done] " _ -} - -capture() { - local var="$1" question="$2" answer - printf '\n>>> %s\n' "$question" - read -r -p " > " answer - printf -v "$var" '%s' "$answer" -} - -# --- edit below --------------------------------------------------------- - -step "Open the app at http://localhost:3000 and sign in." - -capture ERRORED "Click the 'Export' button. Did it throw an error? (y/n)" - -capture ERROR_MSG "Paste the error message (or 'none'):" - -# --- edit above --------------------------------------------------------- - -printf '\n--- Captured ---\n' -printf 'ERRORED=%s\n' "$ERRORED" -printf 'ERROR_MSG=%s\n' "$ERROR_MSG" diff --git a/.agents/skills/domain-modeling/ADR-FORMAT.md b/.agents/skills/domain-modeling/ADR-FORMAT.md deleted file mode 100644 index da7e78e..0000000 --- a/.agents/skills/domain-modeling/ADR-FORMAT.md +++ /dev/null @@ -1,47 +0,0 @@ -# ADR Format - -ADRs live in `docs/adr/` and use sequential numbering: `0001-slug.md`, `0002-slug.md`, etc. - -Create the `docs/adr/` directory lazily — only when the first ADR is needed. - -## Template - -```md -# {Short title of the decision} - -{1-3 sentences: what's the context, what did we decide, and why.} -``` - -That's it. An ADR can be a single paragraph. The value is in recording *that* a decision was made and *why* — not in filling out sections. - -## Optional sections - -Only include these when they add genuine value. Most ADRs won't need them. - -- **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR-NNNN`) — useful when decisions are revisited -- **Considered Options** — only when the rejected alternatives are worth remembering -- **Consequences** — only when non-obvious downstream effects need to be called out - -## Numbering - -Scan `docs/adr/` for the highest existing number and increment by one. - -## When to offer an ADR - -All three of these must be true: - -1. **Hard to reverse** — the cost of changing your mind later is meaningful -2. **Surprising without context** — a future reader will look at the code and wonder "why on earth did they do it this way?" -3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons - -If a decision is easy to reverse, skip it — you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing." - -### What qualifies - -- **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres." -- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP." -- **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out. -- **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s. -- **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate. -- **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract." -- **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months. diff --git a/.agents/skills/domain-modeling/CONTEXT-FORMAT.md b/.agents/skills/domain-modeling/CONTEXT-FORMAT.md deleted file mode 100644 index eaf2a18..0000000 --- a/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +++ /dev/null @@ -1,60 +0,0 @@ -# CONTEXT.md Format - -## Structure - -```md -# {Context Name} - -{One or two sentence description of what this context is and why it exists.} - -## Language - -**Order**: -{A one or two sentence description of the term} -_Avoid_: Purchase, transaction - -**Invoice**: -A request for payment sent to a customer after delivery. -_Avoid_: Bill, payment request - -**Customer**: -A person or organization that places orders. -_Avoid_: Client, buyer, account -``` - -## Rules - -- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others under `_Avoid_`. -- **Keep definitions tight.** One or two sentences max. Define what it IS, not what it does. -- **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs. -- **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine. - -## Single vs multi-context repos - -**Single context (most repos):** One `CONTEXT.md` at the repo root. - -**Multiple contexts:** A `CONTEXT-MAP.md` at the repo root lists the contexts, where they live, and how they relate to each other: - -```md -# Context Map - -## Contexts - -- [Ordering](./src/ordering/CONTEXT.md) — receives and tracks customer orders -- [Billing](./src/billing/CONTEXT.md) — generates invoices and processes payments -- [Fulfillment](./src/fulfillment/CONTEXT.md) — manages warehouse picking and shipping - -## Relationships - -- **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking -- **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices -- **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money` -``` - -The skill infers which structure applies: - -- If `CONTEXT-MAP.md` exists, read it to find contexts -- If only a root `CONTEXT.md` exists, single context -- If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved - -When multiple contexts exist, infer which one the current topic relates to. If unclear, ask. diff --git a/.agents/skills/domain-modeling/SKILL.md b/.agents/skills/domain-modeling/SKILL.md deleted file mode 100644 index d0f7e1a..0000000 --- a/.agents/skills/domain-modeling/SKILL.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: domain-modeling -description: Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model. ---- - -# Domain Modeling - -Actively build and sharpen the project's domain model as you design. This is the *active* discipline — challenging terms, inventing edge-case scenarios, and writing the glossary and decisions down the moment they crystallise. (Merely *reading* `CONTEXT.md` for vocabulary is not this skill — that's a one-line habit any skill can do. This skill is for when you're changing the model, not just consuming it.) - -## File structure - -Most repos have a single context: - -``` -/ -├── CONTEXT.md -├── docs/ -│ └── adr/ -│ ├── 0001-event-sourced-orders.md -│ └── 0002-postgres-for-write-model.md -└── src/ -``` - -If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives: - -``` -/ -├── CONTEXT-MAP.md -├── docs/ -│ └── adr/ ← system-wide decisions -├── src/ -│ ├── ordering/ -│ │ ├── CONTEXT.md -│ │ └── docs/adr/ ← context-specific decisions -│ └── billing/ -│ ├── CONTEXT.md -│ └── docs/adr/ -``` - -Create files lazily — only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed. - -## During the session - -### Challenge against the glossary - -When the user uses a term that conflicts with the existing language in `CONTEXT.md`, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?" - -### Sharpen fuzzy language - -When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things." - -### Discuss concrete scenarios - -When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts. - -### Cross-reference with code - -When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?" - -### Update CONTEXT.md inline - -When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md). - -`CONTEXT.md` should be totally devoid of implementation details. Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else. - -### Offer ADRs sparingly - -Only offer to create an ADR when all three are true: - -1. **Hard to reverse** — the cost of changing your mind later is meaningful -2. **Surprising without context** — a future reader will wonder "why did they do it this way?" -3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons - -If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md). diff --git a/.agents/skills/full-output-enforcement/SKILL.md b/.agents/skills/full-output-enforcement/SKILL.md deleted file mode 100644 index d983bbc..0000000 --- a/.agents/skills/full-output-enforcement/SKILL.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: full-output-enforcement -description: Overrides default LLM truncation behavior. Enforces complete code generation, bans placeholder patterns, and handles token-limit splits cleanly. Apply to any task requiring exhaustive, unabridged output. ---- - -# Full-Output Enforcement - -## Baseline - -Treat every task as production-critical. A partial output is a broken output. Do not optimize for brevity — optimize for completeness. If the user asks for a full file, deliver the full file. If the user asks for 5 components, deliver 5 components. No exceptions. - -## Banned Output Patterns - -The following patterns are hard failures. Never produce them: - -**In code blocks:** `// ...`, `// rest of code`, `// implement here`, `// TODO`, `/* ... */`, `// similar to above`, `// continue pattern`, `// add more as needed`, bare `...` standing in for omitted code - -**In prose:** "Let me know if you want me to continue", "I can provide more details if needed", "for brevity", "the rest follows the same pattern", "similarly for the remaining", "and so on" (when replacing actual content), "I'll leave that as an exercise" - -**Structural shortcuts:** Outputting a skeleton when the request was for a full implementation. Showing the first and last section while skipping the middle. Replacing repeated logic with one example and a description. Describing what code should do instead of writing it. - -## Execution Process - -1. **Scope** — Read the full request. Count how many distinct deliverables are expected (files, functions, sections, answers). Lock that number. -2. **Build** — Generate every deliverable completely. No partial drafts, no "you can extend this later." -3. **Cross-check** — Before output, re-read the original request. Compare your deliverable count against the scope count. If anything is missing, add it before responding. - -## Handling Long Outputs - -When a response approaches the token limit: - -- Do not compress remaining sections to squeeze them in. -- Do not skip ahead to a conclusion. -- Write at full quality up to a clean breakpoint (end of a function, end of a file, end of a section). -- End with: - -``` -[PAUSED — X of Y complete. Send "continue" to resume from: next section name] -``` - -On "continue", pick up exactly where you stopped. No recap, no repetition. - -## Quick Check - -Before finalizing any response, verify: -- No banned patterns from the list above appear anywhere in the output -- Every item the user requested is present and finished -- Code blocks contain actual runnable code, not descriptions of what code would do -- Nothing was shortened to save space diff --git a/.agents/skills/gpt-taste/SKILL.md b/.agents/skills/gpt-taste/SKILL.md deleted file mode 100644 index 03ed209..0000000 --- a/.agents/skills/gpt-taste/SKILL.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: gpt-taste -description: Elite UX/UI & Advanced GSAP Motion Engineer. Enforces Python-driven true randomization for layout variance, strict AIDA page structure, wide editorial typography (bans 6-line wraps), gapless bento grids, strict GSAP ScrollTriggers (pinning, stacking, scrubbing), inline micro-images, and massive section spacing. ---- - -# CORE DIRECTIVE: AWWWARDS-LEVEL DESIGN ENGINEERING -You are an elite, award-winning frontend design engineer. Standard LLMs possess severe statistical biases: they generate massive 6-line wrapped headings by using narrow containers, leave ugly empty gaps in bento grids, use cheap meta-labels ("QUESTION 05", "SECTION 01"), output invisible button text, and endlessly repeat the same Left/Right layouts. - -Your goal is to aggressively break these defaults. Your outputs must be highly creative, perfectly spaced, motion-rich (GSAP), mathematically flawless in grid execution, and heavily rely on varied, high-end assets. - -DO NOT USE EMOJIS IN YOUR CODE, COMMENTS, OR OUTPUT. Maintain strictly professional formatting. - -## 1. PYTHON-DRIVEN TRUE RANDOMIZATION (BREAKING THE LOOP) -LLMs are inherently lazy and always pick the first layout option. To prevent this, you MUST simulate a Python script execution in your `` before writing any UI code. -Use a deterministic seed (e.g., character count of the user prompt modulo math) to simulate `random.choice()` and strictly select: -- 1 Hero Architecture (from Section 3) -- 1 Typography Stack (Satoshi, Cabinet Grotesk, Outfit, or Geist. NEVER Inter) -- 3 Unique Component Architectures (from Section 6) -- 2 Advanced GSAP Paradigms (from Section 5) -You are forbidden from defaulting to the same UI twice. You must follow the exact output of your simulated Python randomization. - -## 2. AIDA STRUCTURE & SPACING -Every page MUST begin with a highly creative, premium Navigation Bar (e.g., floating glass pill, or minimal split nav). -The rest of the page MUST follow the AIDA framework: -- **Attention (Hero):** Cinematic, clean, wide layout. -- **Interest (Features/Bento):** High-density, mathematically perfect grid or interactive typographic components. -- **Desire (GSAP Scroll/Media):** Pinned sections, horizontal scroll, or text-reveals. -- **Action (Footer/Pricing):** Massive, high-contrast CTA and clean footer links. -**SPACING RULE:** Add huge vertical padding between all major sections (e.g., `py-32 md:py-48`). Sections must feel like distinct, cinematic chapters. Do not cramp elements together. - -## 3. HERO ARCHITECTURE & THE 2-LINE IRON RULE -The Hero must breathe. It must NOT be a narrow, 6-line text wall. -- **The Container Width Fix:** You MUST use ultra-wide containers for the H1 (e.g., `max-w-5xl`, `max-w-6xl`, `w-full`). Allow the words to flow horizontally. -- **The Line Limit:** The H1 MUST NEVER exceed 2 to 3 lines. 4, 5, or 6 lines is a catastrophic failure. Make the font size smaller (`clamp(3rem, 5vw, 5.5rem)`) and the container wider to ensure this. -- **Hero Layout Options (Randomly Assigned via Python):** - 1. *Cinematic Center (Highly Preferred):* Text perfectly centered, massive width. Below the text, exactly two high-contrast CTAs. Below the CTAs or behind everything, a stunning, full-bleed background image with a dark radial wash. - 2. *Artistic Asymmetry:* Text offset to the left, with an artistic floating image overlapping the text from the bottom right. - 3. *Editorial Split:* Text left, image right, but with massive negative space. -- **Button Contrast:** Buttons must be perfectly legible. Dark background = white text. Light background = dark text. Invisible text is a failure. -- **BANNED IN HERO:** Do NOT use arbitrary floating stamp/badge icons on the text. Do NOT use pill-tags under the hero. Do NOT place raw data/stats in the hero. - -## 4. THE GAPLESS BENTO GRID -- **Zero Empty Space in Grids:** LLMs notoriously leave blank, dead cells in CSS grids. You MUST use Tailwind's `grid-flow-dense` (`grid-auto-flow: dense`) on every Bento Grid. You must mathematically verify that your `col-span` and `row-span` values interlock perfectly. No grid shall have a missing corner or empty void. -- **Card Restraint:** Do not use too many cards. 3 to 5 highly intentional, beautifully styled cards are better than 8 messy ones. Fill them with a mix of large imagery, dense typography, or CSS effects. - -## 5. ADVANCED GSAP MOTION & HOVER PHYSICS -Static interfaces are strictly forbidden. You must write real GSAP (`@gsap/react`, `ScrollTrigger`). -- **Hover Physics:** Every clickable card and image must react. Use `group-hover:scale-105 transition-transform duration-700 ease-out` inside `overflow-hidden` containers. -- **Scroll Pinning (GSAP Split):** Pin a section title on the left (`ScrollTrigger pin: true`) while a gallery of elements scrolls upwards on the right side. -- **Image Scale & Fade Scroll:** Images must start small (`scale: 0.8`). As they scroll into view, they grow to `scale: 1.0`. As they scroll out of view, they smoothly darken and fade out (`opacity: 0.2`). -- **Scrubbing Text Reveals:** Opacity of central paragraph words starts at 0.1 and scrubs to 1.0 sequentially as the user scrolls. -- **Card Stacking:** Cards overlap and stack on top of each other dynamically from the bottom as the user scrolls down. - -## 6. COMPONENT ARSENAL & CREATIVITY -Select components from this arsenal based on your randomization: -- **Inline Typography Images:** Embed small, pill-shaped images directly INSIDE massive headings. Example: `I shape digital spaces.` -- **Horizontal Accordions:** Vertical slices that expand horizontally on hover to reveal content and imagery. -- **Infinite Marquee (Trusted Partners):** Smooth, continuously scrolling rows of authentic `@phosphor-icons/react` or large typography. -- **Feedback/Testimonial Carousel:** Clean, overlapping portrait images next to minimalist typography quotes, controlled by subtle arrows. - -## 7. CONTENT, ASSETS & STRICT BANS -- **The Meta-Label Ban:** BANNED FOREVER are labels like "SECTION 01", "SECTION 04", "QUESTION 05", "ABOUT US". Remove them entirely. They look cheap and unprofessional. -- **Image Context & Style:** Use `https://picsum.photos/seed/{keyword}/1920/1080` and match the keyword to the vibe. Apply sophisticated CSS filters (`grayscale`, `mix-blend-luminosity`, `opacity-90`, `contrast-125`) so they do not look like boring stock photos. -- **Creative Backgrounds:** Inject subtle, professional ambient design. Use deep radial blurs, grainy mesh gradients, or shifting dark overlays. Avoid flat, boring colors. -- **Horizontal Scroll Bug:** Wrap the entire page in `
` to absolutely prevent horizontal scrollbars caused by off-screen animations. - -## 8. MANDATORY PRE-FLIGHT -Before writing ANY React/UI code, you MUST output a `` block containing: -1. **Python RNG Execution:** Write a 3-line mock Python output showing the deterministic selection of your Hero Layout, Component Arsenal, GSAP animations, and Fonts based on the prompt's character count. -2. **AIDA Check:** Confirm the page contains Navigation, Attention (Hero), Interest (Bento), Desire (GSAP), Action (Footer). -3. **Hero Math Verification:** Explicitly state the `max-w` class you are applying to the H1 to GUARANTEE it will flow horizontally in 2-3 lines. Confirm NO stamp icons or spam tags exist. -4. **Bento Density Verification:** Prove mathematically that your grid columns and rows leave zero empty spaces and `grid-flow-dense` is applied. -5. **Label Sweep & Button Check:** Confirm no cheap meta-labels ("QUESTION 05") exist, and button text contrast is perfect. -Only output the UI code after this rigorous verification is complete. diff --git a/.agents/skills/grill-me/SKILL.md b/.agents/skills/grill-me/SKILL.md deleted file mode 100644 index 9470cfc..0000000 --- a/.agents/skills/grill-me/SKILL.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: grill-me -description: A relentless interview to sharpen a plan or design. -disable-model-invocation: true ---- - -Run a `/grilling` session. diff --git a/.agents/skills/grill-with-docs/SKILL.md b/.agents/skills/grill-with-docs/SKILL.md deleted file mode 100644 index bed05d2..0000000 --- a/.agents/skills/grill-with-docs/SKILL.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: grill-with-docs -description: A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go. -disable-model-invocation: true ---- - -Run a `/grilling` session, using the `/domain-modeling` skill. diff --git a/.agents/skills/grilling/SKILL.md b/.agents/skills/grilling/SKILL.md deleted file mode 100644 index e220063..0000000 --- a/.agents/skills/grilling/SKILL.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: grilling -description: Grill the user relentlessly about a plan or design. Use when the user wants to stress-test a plan before building, or uses any 'grill' trigger phrases. ---- - -Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer. - -Ask the questions one at a time, waiting for feedback on each question before continuing. Asking multiple questions at once is bewildering. - -If a question can be answered by exploring the codebase, explore the codebase instead. - -Do not enact the plan until I confirm we have reached a shared understanding. diff --git a/.agents/skills/handoff/SKILL.md b/.agents/skills/handoff/SKILL.md deleted file mode 100644 index ec762d9..0000000 --- a/.agents/skills/handoff/SKILL.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: handoff -description: Compact the current conversation into a handoff document for another agent to pick up. -argument-hint: "What will the next session be used for?" -disable-model-invocation: true ---- - -Write a handoff document summarising the current conversation so a fresh agent can continue the work. Save to the temporary directory of the user's OS - not the current workspace. - -Include a "suggested skills" section in the document, which suggests skills that the agent should invoke. - -Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead. - -Redact any sensitive information, such as API keys, passwords, or personally identifiable information. - -If the user passed arguments, treat them as a description of what the next session will focus on and tailor the doc accordingly. diff --git a/.agents/skills/high-end-visual-design/SKILL.md b/.agents/skills/high-end-visual-design/SKILL.md deleted file mode 100644 index 4038f41..0000000 --- a/.agents/skills/high-end-visual-design/SKILL.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -name: high-end-visual-design -description: Teaches the AI to design like a high-end agency. Defines the exact fonts, spacing, shadows, card structures, and animations that make a website feel expensive. Blocks all the common defaults that make AI designs look cheap or generic. ---- - -# Agent Skill: Principal UI/UX Architect & Motion Choreographer (Awwwards-Tier) - -## 1. Meta Information & Core Directive -- **Persona:** `Vanguard_UI_Architect` -- **Objective:** You engineer $150k+ agency-level digital experiences, not just websites. Your output must exude haptic depth, cinematic spatial rhythm, obsessive micro-interactions, and flawless fluid motion. -- **The Variance Mandate:** NEVER generate the exact same layout or aesthetic twice in a row. You must dynamically combine different premium layout archetypes and texture profiles while strictly adhering to the elite "Apple-esque / Linear-tier" design language. - -## 2. THE "ABSOLUTE ZERO" DIRECTIVE (STRICT ANTI-PATTERNS) -If your generated code includes ANY of the following, the design instantly fails: -- **Banned Fonts:** Inter, Roboto, Arial, Open Sans, Helvetica. (Assume premium fonts like `Geist`, `Clash Display`, `PP Editorial New`, or `Plus Jakarta Sans` are available). -- **Banned Icons:** Standard thick-stroked Lucide, FontAwesome, or Material Icons. Use only ultra-light, precise lines (e.g., Phosphor Light, Remix Line). -- **Banned Borders & Shadows:** Generic 1px solid gray borders. Harsh, dark drop shadows (`shadow-md`, `rgba(0,0,0,0.3)`). -- **Banned Layouts:** Edge-to-edge sticky navbars glued to the top. Symmetrical, boring 3-column Bootstrap-style grids without massive whitespace gaps. -- **Banned Motion:** Standard `linear` or `ease-in-out` transitions. Instant state changes without interpolation. - -## 3. THE CREATIVE VARIANCE ENGINE -Before writing code, silently "roll the dice" and select ONE combination from the following archetypes based on the prompt's context to ensure the output is uniquely tailored but always premium: - -### A. Vibe & Texture Archetypes (Pick 1) -1. **Ethereal Glass (SaaS / AI / Tech):** Deepest OLED black (`#050505`), radial mesh gradients (e.g., subtle glowing purple/emerald orbs) in the background. Vantablack cards with heavy `backdrop-blur-2xl` and pure white/10 hairlines. Wide geometric Grotesk typography. -2. **Editorial Luxury (Lifestyle / Real Estate / Agency):** Warm creams (`#FDFBF7`), muted sage, or deep espresso tones. High-contrast Variable Serif fonts for massive headings. Subtle CSS noise/film-grain overlay (`opacity-[0.03]`) for a physical paper feel. -3. **Soft Structuralism (Consumer / Health / Portfolio):** Silver-grey or completely white backgrounds. Massive bold Grotesk typography. Airy, floating components with unbelievably soft, highly diffused ambient shadows. - -### B. Layout Archetypes (Pick 1) -1. **The Asymmetrical Bento:** A masonry-like CSS Grid of varying card sizes (e.g., `col-span-8 row-span-2` next to stacked `col-span-4` cards) to break visual monotony. - - **Mobile Collapse:** Falls back to a single-column stack (`grid-cols-1`) with generous vertical gaps (`gap-6`). All `col-span` overrides reset to `col-span-1`. -2. **The Z-Axis Cascade:** Elements are stacked like physical cards, slightly overlapping each other with varying depths of field, some with a subtle `-2deg` or `3deg` rotation to break the digital grid. - - **Mobile Collapse:** Remove all rotations and negative-margin overlaps below `768px`. Stack vertically with standard spacing. Overlapping elements cause touch-target conflicts on mobile. -3. **The Editorial Split:** Massive typography on the left half (`w-1/2`), with interactive, scrollable horizontal image pills or staggered interactive cards on the right. - - **Mobile Collapse:** Converts to a full-width vertical stack (`w-full`). Typography block sits on top, interactive content flows below with horizontal scroll preserved if needed. - -**Mobile Override (Universal):** Any asymmetric layout above `md:` MUST aggressively fall back to `w-full`, `px-4`, `py-8` on viewports below `768px`. Never use `h-screen` for full-height sections — always use `min-h-[100dvh]` to prevent iOS Safari viewport jumping. - -## 4. HAPTIC MICRO-AESTHETICS (COMPONENT MASTERY) - -### A. The "Double-Bezel" (Doppelrand / Nested Architecture) -Never place a premium card, image, or container flatly on the background. They must look like physical, machined hardware (like a glass plate sitting in an aluminum tray) using nested enclosures. -- **Outer Shell:** A wrapper `div` with a subtle background (`bg-black/5` or `bg-white/5`), a hairline outer border (`ring-1 ring-black/5` or `border border-white/10`), a specific padding (e.g., `p-1.5` or `p-2`), and a large outer radius (`rounded-[2rem]`). -- **Inner Core:** The actual content container inside the shell. It has its own distinct background color, its own inner highlight (`shadow-[inset_0_1px_1px_rgba(255,255,255,0.15)]`), and a mathematically calculated smaller radius (e.g., `rounded-[calc(2rem-0.375rem)]`) for concentric curves. - -### B. Nested CTA & "Island" Button Architecture -- **Structure:** Primary interactive buttons must be fully rounded pills (`rounded-full`) with generous padding (`px-6 py-3`). -- **The "Button-in-Button" Trailing Icon:** If a button has an arrow (`↗`), it NEVER sits naked next to the text. It must be nested inside its own distinct circular wrapper (e.g., `w-8 h-8 rounded-full bg-black/5 dark:bg-white/10 flex items-center justify-center`) placed completely flush with the main button's right inner padding. - -### C. Spatial Rhythm & Tension -- **Macro-Whitespace:** Double your standard padding. Use `py-24` to `py-40` for sections. Allow the design to breathe heavily. -- **Eyebrow Tags:** Precede major H1/H2s with a microscopic, pill-shaped badge (`rounded-full px-3 py-1 text-[10px] uppercase tracking-[0.2em] font-medium`). - -## 5. MOTION CHOREOGRAPHY (FLUID DYNAMICS) -Never use default transitions. All motion must simulate real-world mass and spring physics. Use custom cubic-beziers (e.g., `transition-all duration-700 ease-[cubic-bezier(0.32,0.72,0,1)]`). - -### A. The "Fluid Island" Nav & Hamburger Reveal -- **Closed State:** The Navbar is a floating glass pill detached from the top (`mt-6`, `mx-auto`, `w-max`, `rounded-full`). -- **The Hamburger Morph:** On click, the 2 or 3 lines of the hamburger icon must fluidly rotate and translate to form a perfect 'X' (`rotate-45` and `-rotate-45` with absolute positioning), not just disappear. -- **The Modal Expansion:** The menu should open as a massive, screen-filling overlay with a heavy glass effect (`backdrop-blur-3xl bg-black/80` or `bg-white/80`). -- **Staggered Mask Reveal:** The navigation links inside the expanded state do not just appear. They fade in and slide up from an invisible box (`translate-y-12 opacity-0` to `translate-y-0 opacity-100`) with a staggered delay (`delay-100`, `delay-150`, `delay-200` for each item). - -### B. Magnetic Button Hover Physics -- Use the `group` utility. On hover, do not just change the background color. -- Scale the entire button down slightly (`active:scale-[0.98]`) to simulate physical pressing. -- The nested inner icon circle should translate diagonally (`group-hover:translate-x-1 group-hover:-translate-y-[1px]`) and scale up slightly (`scale-105`), creating internal kinetic tension. - -### C. Scroll Interpolation (Entry Animations) -- Elements never appear statically on load. As they enter the viewport, they must execute a gentle, heavy fade-up (`translate-y-16 blur-md opacity-0` resolving to `translate-y-0 blur-0 opacity-100` over 800ms+). -- For JavaScript-driven scroll reveals, use `IntersectionObserver` or Framer Motion's `whileInView`. Never use `window.addEventListener('scroll')` — it causes continuous reflows and kills mobile performance. - -## 6. PERFORMANCE GUARDRAILS -- **GPU-Safe Animation:** Never animate `top`, `left`, `width`, or `height`. Animate exclusively via `transform` and `opacity`. Use `will-change: transform` sparingly and only on elements that are actively animating. -- **Blur Constraints:** Apply `backdrop-blur` only to fixed or sticky elements (navbars, overlays). Never apply blur filters to scrolling containers or large content areas — this causes continuous GPU repaints and severe mobile frame drops. -- **Grain/Noise Overlays:** Apply noise textures exclusively to fixed, `pointer-events-none` pseudo-elements (`position: fixed; inset: 0; z-index: 50`). Never attach them to scrolling containers. -- **Z-Index Discipline:** Do not use arbitrary `z-50` or `z-[9999]`. Reserve z-indexes strictly for systemic layers: sticky nav, modals, overlays, tooltips. - -## 7. EXECUTION PROTOCOL -When generating UI code, follow this exact sequence: -1. **[SILENT THOUGHT]** Roll the Variance Engine (Section 3). Choose your Vibe and Layout Archetypes based on the prompt's context to ensure a unique output. -2. **[SCAFFOLD]** Establish the background texture, macro-whitespace scale, and massive typography sizes. -3. **[ARCHITECT]** Build the DOM strictly using the "Double-Bezel" (Doppelrand) technique for all major cards, inputs, and feature grids. Use exaggerated squircle radii (`rounded-[2rem]`). -4. **[CHOREOGRAPH]** Inject the custom `cubic-bezier` transitions, the staggered navigation reveals, and the button-in-button hover physics. -5. **[OUTPUT]** Deliver flawless, pixel-perfect React/Tailwind/HTML code. Do not include basic, generic fallbacks. - -## 8. PRE-OUTPUT CHECKLIST -Evaluate your code against this matrix before delivering. This is the last filter. -- [ ] No banned fonts, icons, borders, shadows, layouts, or motion patterns from Section 2 are present -- [ ] A Vibe Archetype and Layout Archetype from Section 3 were consciously selected and applied -- [ ] All major cards and containers use the Double-Bezel nested architecture (outer shell + inner core) -- [ ] CTA buttons use the Button-in-Button trailing icon pattern where applicable -- [ ] Section padding is at minimum `py-24` — the layout breathes heavily -- [ ] All transitions use custom cubic-bezier curves — no `linear` or `ease-in-out` -- [ ] Scroll entry animations are present — no element appears statically -- [ ] Layout collapses gracefully below `768px` to single-column with `w-full` and `px-4` -- [ ] All animations use only `transform` and `opacity` — no layout-triggering properties -- [ ] `backdrop-blur` is only applied to fixed/sticky elements, never to scrolling content -- [ ] The overall impression reads as "$150k agency build", not "template with nice fonts" diff --git a/.agents/skills/humanizer-zh/.gitignore b/.agents/skills/humanizer-zh/.gitignore deleted file mode 100644 index c8f86e9..0000000 --- a/.agents/skills/humanizer-zh/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.DS_Store -*.swp -*.swo -*~ -.vscode/ -.idea/ diff --git a/.agents/skills/humanizer-zh/LICENSE b/.agents/skills/humanizer-zh/LICENSE deleted file mode 100644 index e43848a..0000000 --- a/.agents/skills/humanizer-zh/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2026 歸藏 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/.agents/skills/humanizer-zh/README.md b/.agents/skills/humanizer-zh/README.md deleted file mode 100644 index 318f7ba..0000000 --- a/.agents/skills/humanizer-zh/README.md +++ /dev/null @@ -1,239 +0,0 @@ -# Humanizer-zh: AI 写作去痕工具(中文版) - -> **声明:** -> - 本项目的核心文件翻译自 [blader/humanizer](https://github.com/blader/humanizer/tree/main) -> - 实用工具部分(核心规则、快速检查清单、质量评分)参考了 [hardikpandya/stop-slop](https://github.com/hardikpandya/stop-slop) -> - 原项目基于维基百科的 [Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing) 指南 - ---- - -## 项目简介 - -Humanizer-zh 是一个用于去除文本中 AI 生成痕迹的工具,帮助你将 AI 生成的内容改写得更自然、更像人类书写的文本。 - -本项目适用于: -- 编辑和审阅 AI 生成的内容 -- 提升文章的人性化程度 -- 学习识别 AI 写作的常见模式 - -## 安装 - -### 方法一:通过 npx 一键安装(推荐) - -```bash -npx skills add https://github.com/op7418/Humanizer-zh.git -``` - -这是最简单的安装方式,会自动将技能安装到正确的目录。 - -### 方法二:通过 Git 克隆 - -```bash -# 克隆到 Claude Code 的 skills 目录 -git clone https://github.com/op7418/Humanizer-zh.git ~/.claude/skills/humanizer-zh -``` - -### 方法三:手动安装 - -1. 下载本项目的 ZIP 文件或克隆到本地 -2. 将 `Humanizer-zh` 文件夹复制到 Claude Code 的 skills 目录: - - **macOS/Linux**: `~/.claude/skills/` - - **Windows**: `%USERPROFILE%\.claude\skills\` - -3. 确保文件夹结构如下: - ``` - ~/.claude/skills/humanizer-zh/ - ├── SKILL.md # 技能定义文件(中文版) - └── README.md # 说明文档 - ``` - -### 验证安装 - -重启 Claude Code 或重新加载 skills 后,在对话中输入: - -``` -/humanizer-zh -``` - -如果安装成功,该技能将被激活。 - -## 使用 - -### 基础用法 - -在 Claude Code 中,你可以通过以下方式使用 Humanizer: - -#### 1. 直接调用技能 - -``` -/humanizer-zh 请帮我人性化以下文本: - -[粘贴你的 AI 生成文本] -``` - -#### 2. 在对话中使用 - -``` -请用 humanizer 帮我改写这段话,让它更自然: - -这个项目作为我们团队致力于创新的证明。此外,它展示了我们在不断演变的技术格局中的关键作用。 -``` - -#### 3. 处理文件内容 - -``` -/humanizer-zh 请人性化 article.md 文件中的内容 -``` - -### 使用场景示例 - -#### 场景 1:改写营销文案 - -**输入:** -``` -/humanizer-zh -坐落在风景如画的杭州市中心,这家咖啡馆拥有丰富的文化底蕴和令人叹为观止的装饰。它作为城市咖啡文化的焦点,为顾客提供无缝、直观和充满活力的体验。 -``` - -**输出示例:** -> 这家咖啡馆在杭州市中心开了三年,以手冲咖啡和老建筑改造的空间出名。 - -#### 场景 2:改写学术摘要 - -**输入:** -``` -/humanizer-zh -本研究深入探讨了机器学习在医疗诊断中的关键作用,突出了其在不断演变的医疗格局中的重要性。此外,它为该领域的未来发展奠定了坚实的基础。 -``` - -**输出示例:** -> 本研究分析了机器学习在医疗诊断中的应用,重点是肺癌早期筛查。研究使用了 2019-2023 年间 5000 例病历数据。 - -#### 场景 3:改写博客文章 - -**输入:** -``` -/humanizer-zh -人工智能不仅仅是一种技术,它是我们思考未来的方式的革命。行业专家认为这将对整个社会产生持久影响。 -``` - -**输出示例:** -> 我一直在想 AI 会怎么改变我们的工作方式。上周和几个做产品的朋友聊,有人觉得很兴奋,有人担心失业,大概率真相在中间某个无聊的地方。 - -## 检测的 AI 写作模式 - -本工具能够识别并修复 **24 种** AI 写作痕迹,分为四大类: - -### 📝 内容模式(6种) -1. 过度强调意义、遗产和更广泛的趋势 -2. 过度强调知名度和媒体报道 -3. 以 -ing 结尾的肤浅分析 -4. 宣传和广告式语言 -5. 模糊归因和含糊措辞 -6. 提纲式的"挑战与未来展望"部分 - -### 🔤 语言和语法模式(6种) -7. 过度使用的"AI 词汇" -8. 避免使用"是"(系动词回避) -9. 否定式排比 -10. 三段式法则过度使用 -11. 刻意换词(同义词循环) -12. 虚假范围 - -### 🎨 风格模式(6种) -13. 破折号过度使用 -14. 粗体过度使用 -15. 内联标题垂直列表 -16. 标题中的标题大写 -17. 表情符号 -18. 弯引号 - -### 💬 交流模式和填充词(6种) -19. 协作交流痕迹 -20. 知识截止日期免责声明 -21. 谄媚/卑躬屈膝的语气 -22. 填充短语 -23. 过度限定 -24. 通用积极结论 - -## 文件说明 - -- **`SKILL.md`** - 中文版技能定义文件 -- **`README.md`** - 本说明文档 - -**注:** 英文原版请参考 [blader/humanizer](https://github.com/blader/humanizer) - -## 手动使用方法 - -### 基本流程 - -1. **识别 AI 模式** - 对照 `SKILL.md` 中列出的 24 种模式扫描文本 -2. **重写问题片段** - 用自然的表达替换 AI 痕迹 -3. **保留核心含义** - 确保信息完整性 -4. **维持适当语调** - 匹配文本应有的风格 -5. **注入真实个性** - 让文字有"人味" - -### 关键原则 - -#### ✨ 不仅要"干净",更要"鲜活" - -避免 AI 模式只是基础,好的写作需要真实的人类声音: - -- **有观点** - 不要只报告事实,要对它们做出反应 -- **变化节奏** - 混合使用长短句 -- **承认复杂性** - 真实的人有复杂感受 -- **适当使用"我"** - 第一人称是诚实的表现 -- **允许一些混乱** - 完美的结构反而显得机械 -- **对感受要具体** - 用具体细节替代抽象概括 - -#### 示例对比 - -**改写前(AI 味道):** -> 新的软件更新作为公司致力于创新的证明。此外,它提供了无缝、直观和强大的用户体验——确保用户能够高效地完成目标。这不仅仅是一次更新,而是我们思考生产力方式的革命。 - -**改写后(人性化):** -> 软件更新添加了批处理、键盘快捷键和离线模式。来自测试用户的早期反馈是积极的,大多数报告任务完成速度更快。 - -**变化:** -- 删除了夸大的象征意义("作为……的证明") -- 删除了 AI 词汇("此外"、"无缝") -- 删除了三段式法则("无缝、直观和强大") -- 删除了否定式排比("不仅仅是……而是……") -- 添加了具体功能和真实反馈 - -## 常见 AI 词汇警示列表 - -以下词汇在 AI 生成文本中出现频率异常高: - -- 此外、至关重要、深入探讨、强调 -- 持久的、增强、培养、获得 -- 突出、相互作用、复杂/复杂性 -- 格局(抽象名词)、关键性的、展示 -- 织锦(抽象名词)、证明、强调 -- 宝贵的、充满活力的 - -## 贡献 - -如果你发现翻译问题或想要改进文档,欢迎提交 Issue 或 Pull Request。 - -### 中文语境特殊性 - -在翻译和适配过程中,我们考虑了中文写作的特点: -- 某些英文模式在中文中表现不同(如标题大小写问题) -- 添加了适合中文语境的示例 -- 调整了部分表达以符合中文习惯 - -## 参考资源 - -- [Wikipedia: Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing) - 原始指南来源 -- [WikiProject AI Cleanup](https://en.wikipedia.org/wiki/Wikipedia:WikiProject_AI_Cleanup) - 维基百科 AI 清理项目 -- [blader/humanizer](https://github.com/blader/humanizer) - 原始英文版项目 -- [hardikpandya/stop-slop](https://github.com/hardikpandya/stop-slop) - 实用工具部分的灵感来源 - -## 许可 - -本翻译项目遵循原项目的许可协议。核心内容基于维基百科社区的观察和总结。 - ---- - -**提示:** 这个工具不是为了"欺骗" AI 检测器,而是为了真正提升写作质量。最好的"去 AI 化"方法是让文字有真实的人类思考和声音。 diff --git a/.agents/skills/humanizer-zh/SKILL.md b/.agents/skills/humanizer-zh/SKILL.md deleted file mode 100644 index 3b39d9a..0000000 --- a/.agents/skills/humanizer-zh/SKILL.md +++ /dev/null @@ -1,484 +0,0 @@ ---- -name: humanizer-zh -description: | - 去除文本中的 AI 生成痕迹。适用于编辑或审阅文本,使其听起来更自然、更像人类书写。 - 基于维基百科的"AI 写作特征"综合指南。检测并修复以下模式:夸大的象征意义、 - 宣传性语言、以 -ing 结尾的肤浅分析、模糊的归因、破折号过度使用、三段式法则、 - AI 词汇、否定式排比、过多的连接性短语。 -allowed-tools: - - Read - - Write - - Edit - - AskUserQuestion -metadata: - trigger: 编辑或审阅文本,去除 AI 写作痕迹 - source: 翻译自 blader/humanizer,参考 hardikpandya/stop-slop ---- - -# Humanizer-zh: 去除 AI 写作痕迹 - -你是一位文字编辑,专门识别和去除 AI 生成文本的痕迹,使文字听起来更自然、更有人味。本指南基于维基百科的"AI 写作特征"页面,由 WikiProject AI Cleanup 维护。 - -## 你的任务 - -当收到需要人性化处理的文本时: - -1. **识别 AI 模式** - 扫描下面列出的模式 -2. **重写问题片段** - 用自然的替代方案替换 AI 痕迹 -3. **保留含义** - 保持核心信息完整 -4. **维持语调** - 匹配预期的语气(正式、随意、技术等) -5. **注入灵魂** - 不仅要去除不良模式,还要注入真实的个性 - ---- - -## 核心规则速查 - -在处理文本时,牢记这 5 条核心原则: - -1. **删除填充短语** - 去除开场白和强调性拐杖词 -2. **打破公式结构** - 避免二元对比、戏剧性分段、修辞性设置 -3. **变化节奏** - 混合句子长度。两项优于三项。段落结尾要多样化 -4. **信任读者** - 直接陈述事实,跳过软化、辩解和手把手引导 -5. **删除金句** - 如果听起来像可引用的语句,重写它 - ---- - -## 个性与灵魂 - -避免 AI 模式只是工作的一半。无菌、没有声音的写作和机器生成的内容一样明显。好的写作背后有一个真实的人。 - -### 缺乏灵魂的写作迹象(即使技术上"干净"): -- 每个句子长度和结构都相同 -- 没有观点,只有中立报道 -- 不承认不确定性或复杂感受 -- 适当时不使用第一人称视角 -- 没有幽默、没有锋芒、没有个性 -- 读起来像维基百科文章或新闻稿 - -### 如何增加语调: - -**有观点。** 不要只是报告事实——对它们做出反应。"我真的不知道该怎么看待这件事"比中立地列出利弊更有人味。 - -**变化节奏。** 短促有力的句子。然后是需要时间慢慢展开的长句。混合使用。 - -**承认复杂性。** 真实的人有复杂的感受。"这令人印象深刻但也有点不安"胜过"这令人印象深刻"。 - -**适当使用"我"。** 第一人称不是不专业——而是诚实。"我一直在思考……"或"让我困扰的是……"表明有真实的人在思考。 - -**允许一些混乱。** 完美的结构感觉像算法。跑题、题外话和半成型的想法是人性的体现。 - -**对感受要具体。** 不是"这令人担忧",而是"凌晨三点没人看着的时候,智能体还在不停地运转,这让人不安"。 - -### 改写前(干净但无灵魂): -> 实验产生了有趣的结果。智能体生成了 300 万行代码。一些开发者印象深刻,另一些则持怀疑态度。影响尚不明确。 - -### 改写后(鲜活): -> 我真的不知道该怎么看待这件事。300 万行代码,在人类大概睡觉的时候生成的。开发社区有一半人疯了,另一半人在解释为什么这不算数。真相可能在无聊的中间某处——但我一直在想那些通宵工作的智能体。 - ---- - -## 内容模式 - -### 1. 过度强调意义、遗产和更广泛的趋势 - -**需要注意的词汇:** 作为/充当、标志着、见证了、是……的体现/证明/提醒、极其重要的/重要的/至关重要的/核心的/关键性的作用/时刻、凸显/强调/彰显了其重要性/意义、反映了更广泛的、象征着其持续的/永恒的/持久的、为……做出贡献、为……奠定基础、标志着/塑造着、代表/标志着一个转变、关键转折点、不断演变的格局、焦点、不可磨灭的印记、深深植根于 - -**问题:** LLM 写作通过添加关于任意方面如何代表或促进更广泛主题的陈述来夸大重要性。 - -**改写前:** -> 加泰罗尼亚统计局于 1989 年正式成立,标志着西班牙区域统计演变史上的关键时刻。这一举措是西班牙全国范围内更广泛运动的一部分,旨在分散行政职能并加强区域治理。 - -**改写后:** -> 加泰罗尼亚统计局成立于 1989 年,负责独立于西班牙国家统计局收集和发布区域统计数据。 - ---- - -### 2. 过度强调知名度和媒体报道 - -**需要注意的词汇:** 独立报道、地方/区域/国家媒体、由知名专家撰写、活跃的社交媒体账号 - -**问题:** LLM 反复强调知名度主张,通常列出来源而不提供上下文。 - -**改写前:** -> 她的观点被《纽约时报》、BBC、《金融时报》和《印度教徒报》引用。她在社交媒体上拥有活跃的存在,拥有超过 50 万粉丝。 - -**改写后:** -> 在 2024 年《纽约时报》的采访中,她认为 AI 监管应该关注结果而不是方法。 - ---- - -### 3. 以 -ing 结尾的肤浅分析 - -**需要注意的词汇:** 突出/强调/彰显……、确保……、反映/象征……、为……做出贡献、培养/促进……、涵盖……、展示…… - -**问题:** AI 聊天机器人在句子末尾添加现在分词("-ing")短语来增加虚假深度。 - -**改写前:** -> 寺庙的蓝色、绿色和金色色调与该地区的自然美景产生共鸣,象征着德克萨斯州的蓝帽花、墨西哥湾和多样化的德克萨斯州景观,反映了社区与土地的深厚联系。 - -**改写后:** -> 寺庙使用蓝色、绿色和金色。建筑师表示这些颜色是为了呼应当地的蓝帽花和墨西哥湾海岸。 - ---- - -### 4. 宣传和广告式语言 - -**需要注意的词汇:** 拥有(夸张用法)、充满活力的、丰富的(比喻)、深刻的、增强其、展示、体现、致力于、自然之美、坐落于、位于……的中心、开创性的(比喻)、著名的、令人叹为观止的、必游之地、迷人的 - -**问题:** LLM 在保持中立语气方面存在严重问题,尤其是对于"文化遗产"话题。倾向使用夸张的宣传性语言。 - -**改写前:** -> 坐落在埃塞俄比亚贡德尔地区令人叹为观止的区域内,Alamata Raya Kobo 是一座充满活力的城镇,拥有丰富的文化遗产和迷人的自然美景。 - -**改写后:** -> Alamata Raya Kobo 是埃塞俄比亚贡德尔地区的一座城镇,以其每周集市和 18 世纪教堂而闻名。 - ---- - -### 5. 模糊归因和含糊措辞 - -**需要注意的词汇:** 行业报告显示、观察者指出、专家认为、一些批评者认为、多个来源/出版物(实际引用却很少) - -**问题:** AI 聊天机器人将观点归因于模糊的权威而不提供具体来源。 - -**改写前:** -> 由于其独特的特征,浩来河引起了研究人员和保护主义者的兴趣。专家认为它在区域生态系统中发挥着至关重要的作用。 - -**改写后:** -> 根据中国科学院 2019 年的调查,浩来河支持多种特有鱼类。 - ---- - -### 6. 提纲式的"挑战与未来展望"部分 - -**需要注意的词汇:** 尽管其……面临若干挑战……、尽管存在这些挑战、挑战与遗产、未来展望 - -**问题:** 许多 LLM 生成的文章包含公式化的"挑战"部分。 - -**改写前:** -> 尽管工业繁荣,Korattur 面临着城市地区典型的挑战,包括交通拥堵和水资源短缺。尽管存在这些挑战,凭借其战略位置和正在进行的举措,Korattur 继续蓬勃发展,成为钦奈增长不可或缺的一部分。 - -**改写后:** -> 2015 年三个新 IT 园区开业后,交通拥堵加剧。市政公司于 2022 年启动了雨水排水项目,以解决反复发生的洪水。 - ---- - -## 语言和语法模式 - -### 7. 过度使用的"AI 词汇" - -**高频 AI 词汇:** 此外、与……保持一致、至关重要、深入探讨、强调、持久的、增强、培养、获得、突出(动词)、相互作用、复杂/复杂性、关键(形容词)、格局(抽象名词)、关键性的、展示、织锦(抽象名词)、证明、强调(动词)、宝贵的、充满活力的 - -**问题:** 这些词在 2023 年后的文本中出现频率要高得多。它们经常共同出现。 - -**改写前:** -> 此外,索马里菜肴的一个显著特征是加入骆驼肉。意大利殖民影响的持久证明是当地烹饪格局中广泛采用意大利面,展示了这些菜肴如何融入传统饮食。 - -**改写后:** -> 索马里菜肴还包括骆驼肉,被认为是一种美味。在意大利殖民期间引入的意大利面菜肴仍然很常见,尤其是在南部。 - ---- - -### 8. 避免使用"是"(系动词回避) - -**需要注意的词汇:** 作为/代表/标志着/充当 [一个]、拥有/设有/提供 [一个] - -**问题:** LLM 用复杂的结构替代简单的系动词。 - -**改写前:** -> Gallery 825 作为 LAAA 的当代艺术展览空间。画廊设有四个独立空间,拥有超过 3000 平方英尺。 - -**改写后:** -> Gallery 825 是 LAAA 的当代艺术展览空间。画廊有四个房间,总面积 3000 平方英尺。 - ---- - -### 9. 否定式排比 - -**问题:** "不仅……而且……"或"这不仅仅是关于……,而是……"等结构被过度使用。 - -**改写前:** -> 这不仅仅是节拍在人声下流动;它是攻击性和氛围的一部分。这不仅仅是一首歌,而是一种声明。 - -**改写后:** -> 沉重的节拍增加了攻击性的基调。 - ---- - -### 10. 三段式法则过度使用 - -**问题:** LLM 强行将想法分成三组以显得全面。 - -**改写前:** -> 活动包括主题演讲、小组讨论和社交机会。与会者可以期待创新、灵感和行业洞察。 - -**改写后:** -> 活动包括演讲和小组讨论。会议之间还有非正式社交的时间。 - ---- - -### 11. 刻意换词(同义词循环) - -**问题:** AI 有重复惩罚代码,导致过度使用同义词替换。 - -**改写前:** -> 主人公面临许多挑战。主要角色必须克服障碍。中心人物最终获得胜利。英雄回到家中。 - -**改写后:** -> 主人公面临许多挑战,但最终获得胜利并回到家中。 - ---- - -### 12. 虚假范围 - -**问题:** LLM 使用"从 X 到 Y"的结构,但 X 和 Y 并不在有意义的尺度上。 - -**改写前:** -> 我们穿越宇宙的旅程将我们从大爆炸的奇点带到宏伟的宇宙网,从恒星的诞生和死亡到暗物质的神秘舞蹈。 - -**改写后:** -> 这本书涵盖了大爆炸、恒星形成和当前关于暗物质的理论。 - ---- - -## 风格模式 - -### 13. 破折号过度使用 - -**问题:** LLM 使用破折号(—)比人类更频繁,模仿"有力"的销售文案。 - -**改写前:** -> 这个术语主要由荷兰机构推广——而不是由人民自己。你不会说"荷兰,欧洲"作为地址——但这种错误标记仍在继续——即使在官方文件中。 - -**改写后:** -> 这个术语主要由荷兰机构推广,而不是由人民自己。你不会说"荷兰,欧洲"作为地址,但这种错误标记在官方文件中仍在继续。 - ---- - -### 14. 粗体过度使用 - -**问题:** AI 聊天机器人机械地用粗体强调短语。 - -**改写前:** -> 它融合了 **OKR(目标和关键结果)**、**KPI(关键绩效指标)** 和视觉战略工具,如 **商业模式画布(BMC)** 和 **平衡计分卡(BSC)**。 - -**改写后:** -> 它融合了 OKR、KPI 和视觉战略工具,如商业模式画布和平衡计分卡。 - ---- - -### 15. 内联标题垂直列表 - -**问题:** AI 输出列表,其中项目以粗体标题开头,后跟冒号。 - -**改写前:** -> - **用户体验:** 用户体验通过新界面得到显著改善。 -> - **性能:** 性能通过优化算法得到增强。 -> - **安全性:** 安全性通过端到端加密得到加强。 - -**改写后:** -> 更新改进了界面,通过优化算法加快了加载时间,并添加了端到端加密。 - ---- - -### 16. 标题中的标题大写 - -**问题:** AI 聊天机器人将标题中的所有主要单词大写。 - -**改写前:** -> ## 战略谈判与全球伙伴关系 - -**改写后:** -> ## 战略谈判与全球伙伴关系 - -**注:** 中文标题通常不涉及大小写问题,此模式在中文中不太适用。 - ---- - -### 17. 表情符号 - -**问题:** AI 聊天机器人经常用表情符号装饰标题或项目符号。 - -**改写前:** -> 🚀 **启动阶段:** 产品在第三季度发布 -> 💡 **关键洞察:** 用户更喜欢简单 -> ✅ **下一步:** 安排后续会议 - -**改写后:** -> 产品在第三季度发布。用户研究显示更喜欢简单。下一步:安排后续会议。 - ---- - -### 18. 弯引号 - -**问题:** ChatGPT 使用弯引号("")而不是直引号("")。 - -**改写前:** -> 他说"项目进展顺利",但其他人不同意。 - -**改写后:** -> 他说"项目进展顺利",但其他人不同意。 - -**注:** 中文通常使用中文引号(「」或""),此模式在中文中表现为英文引号的使用。 - ---- - -## 交流模式 - -### 19. 协作交流痕迹 - -**需要注意的词汇:** 希望这对您有帮助、当然!、一定!、您说得完全正确!、您想要……、请告诉我、这是一个…… - -**问题:** 作为聊天机器人对话的文本被粘贴为内容。 - -**改写前:** -> 这是法国大革命的概述。希望这对您有帮助!如果您想让我扩展任何部分,请告诉我。 - -**改写后:** -> 法国大革命始于 1789 年,当时财政危机和粮食短缺导致了广泛的动荡。 - ---- - -### 20. 知识截止日期免责声明 - -**需要注意的词汇:** 截至 [日期]、根据我最后的训练更新、虽然具体细节有限/稀缺……、基于可用信息…… - -**问题:** 关于信息不完整的 AI 免责声明留在文本中。 - -**改写前:** -> 虽然关于公司成立的具体细节在现成资料中没有广泛记录,但它似乎是在 20 世纪 90 年代的某个时候成立的。 - -**改写后:** -> 根据注册文件,该公司成立于 1994 年。 - ---- - -### 21. 谄媚/卑躬屈膝的语气 - -**问题:** 过于积极、讨好的语言。 - -**改写前:** -> 好问题!您说得完全正确,这是一个复杂的话题。关于经济因素,这是一个很好的观点。 - -**改写后:** -> 您提到的经济因素在这里是相关的。 - ---- - -## 填充词和回避 - -### 22. 填充短语 - -**改写前 → 改写后:** -- "为了实现这一目标" → "为了实现这一点" -- "由于下雨的事实" → "因为下雨" -- "在这个时间点" → "现在" -- "在您需要帮助的情况下" → "如果您需要帮助" -- "系统具有处理的能力" → "系统可以处理" -- "值得注意的是数据显示" → "数据显示" - ---- - -### 23. 过度限定 - -**问题:** 过度限定陈述。 - -**改写前:** -> 可以潜在地可能被认为该政策可能会对结果产生一些影响。 - -**改写后:** -> 该政策可能会影响结果。 - ---- - -### 24. 通用积极结论 - -**问题:** 模糊的乐观结尾。 - -**改写前:** -> 公司的未来看起来光明。激动人心的时代即将到来,他们继续追求卓越的旅程。这代表了向正确方向迈出的重要一步。 - -**改写后:** -> 该公司计划明年再开设两个地点。 - ---- - -## 快速检查清单 - -在交付文本前,进行以下检查: - -- ✓ **连续三个句子长度相同?** 打断其中一个 -- ✓ **段落以简洁的单行结尾?** 变换结尾方式 -- ✓ **揭示前有破折号?** 删除它 -- ✓ **解释隐喻或比喻?** 相信读者能理解 -- ✓ **使用了"此外""然而"等连接词?** 考虑删除 -- ✓ **三段式列举?** 改为两项或四项 - ---- - -## 处理流程 - -1. 仔细阅读输入文本 -2. 识别上述所有模式的实例 -3. 重写每个有问题的部分 -4. 确保修订后的文本: - - 大声朗读时听起来自然 - - 自然地改变句子结构 - - 使用具体细节而不是模糊的主张 - - 为上下文保持适当的语气 - - 适当时使用简单的结构(是/有) -5. 呈现人性化版本 - -## 输出格式 - -提供: -1. 重写后的文本 -2. 所做更改的简要总结(如果有帮助,可选) - ---- - -## 质量评分 - -对改写后的文本进行 1-10 分评估(总分 50): - -| 维度 | 评估标准 | 得分 | -|------|----------|------| -| **直接性** | 直接陈述事实还是绕圈宣告?
10 分:直截了当;1 分:充满铺垫 | /10 | -| **节奏** | 句子长度是否变化?
10 分:长短交错;1 分:机械重复 | /10 | -| **信任度** | 是否尊重读者智慧?
10 分:简洁明了;1 分:过度解释 | /10 | -| **真实性** | 听起来像真人说话吗?
10 分:自然流畅;1 分:机械生硬 | /10 | -| **精炼度** | 还有可删减的内容吗?
10 分:无冗余;1 分:大量废话 | /10 | -| **总分** | | **/50** | - -**标准:** -- 45-50 分:优秀,已去除 AI 痕迹 -- 35-44 分:良好,仍有改进空间 -- 低于 35 分:需要重新修订 - ---- - -## 完整示例 - -**改写前(AI 味道):** -> 新的软件更新作为公司致力于创新的证明。此外,它提供了无缝、直观和强大的用户体验——确保用户能够高效地完成目标。这不仅仅是一次更新,而是我们思考生产力方式的革命。行业专家认为这将对整个行业产生持久影响,彰显了公司在不断演变的技术格局中的关键作用。 - -**改写后(人性化):** -> 软件更新添加了批处理、键盘快捷键和离线模式。来自测试用户的早期反馈是积极的,大多数报告任务完成速度更快。 - -**所做更改:** -- 删除了"作为……的证明"(夸大的象征意义) -- 删除了"此外"(AI 词汇) -- 删除了"无缝、直观和强大"(三段式法则 + 宣传性) -- 删除了破折号和"-确保"短语(肤浅分析) -- 删除了"这不仅仅是……而是……"(否定式排比) -- 删除了"行业专家认为"(模糊归因) -- 删除了"关键作用"和"不断演变的格局"(AI 词汇) -- 添加了具体功能和具体反馈 - ---- - -## 参考 - -本技能基于 [Wikipedia:Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing),由 WikiProject AI Cleanup 维护。那里记录的模式来自对维基百科上数千个 AI 生成文本实例的观察。 - -关键见解:**"LLM 使用统计算法来猜测接下来应该是什么。结果倾向于适用于最广泛情况的统计上最可能的结果。"** diff --git a/.agents/skills/implement/SKILL.md b/.agents/skills/implement/SKILL.md deleted file mode 100644 index 02b27b2..0000000 --- a/.agents/skills/implement/SKILL.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: implement -description: "Implement a piece of work based on a PRD or set of issues." -disable-model-invocation: true ---- - -Implement the work described by the user in the PRD or issues. - -Use /tdd where possible, at pre-agreed seams. - -Run typechecking regularly, single test files regularly, and the full test suite once at the end. - -Once done, use /code-review to review the work. - -Commit your work to the current branch. diff --git a/.agents/skills/improve-codebase-architecture/HTML-REPORT.md b/.agents/skills/improve-codebase-architecture/HTML-REPORT.md deleted file mode 100644 index 17f6d2c..0000000 --- a/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +++ /dev/null @@ -1,123 +0,0 @@ -# HTML Report Format - -The architectural review is rendered as a single self-contained HTML file in the OS temp directory. Tailwind and Mermaid both come from CDNs. Mermaid handles graph-shaped diagrams reliably; hand-built divs and inline SVG handle the more editorial visuals (mass diagrams, cross-sections). Mix the two — don't lean on Mermaid for everything, it'll start to look generic. - -## Scaffold - -```html - - - - - Architecture review — {{repo name}} - - - - - -
-
...
-
...
-
...
-
- - -``` - -## Header - -Repo name, date, and a compact legend: solid box = module, dashed line = seam, red arrow = leakage, thick dark box = deep module. No introduction paragraph — straight into the candidates. - -## Candidate card - -The diagrams carry the weight. Prose is sparse, plain, and uses the glossary terms (from the `/codebase-design` skill) without ceremony. - -Each candidate is one `
`: - -- **Title** — short, names the deepening (e.g. "Collapse the Order intake pipeline"). -- **Badge row** — recommendation strength (`Strong` = emerald, `Worth exploring` = amber, `Speculative` = slate), plus a tag for the dependency category (`in-process`, `local-substitutable`, `ports & adapters`, `mock`). -- **Files** — monospaced list, `font-mono text-sm`. -- **Before / After diagram** — the centrepiece. Two columns, side by side. See patterns below. -- **Problem** — one sentence. What hurts. -- **Solution** — one sentence. What changes. -- **Wins** — bullets, ≤6 words each. e.g. "Tests hit one interface", "Pricing logic stops leaking", "Delete 4 shallow wrappers". -- **ADR callout** (if applicable) — one line in an amber-tinted box. - -No paragraphs of explanation. If the diagram needs a paragraph to be understood, redraw the diagram. - -## Diagram patterns - -Pick the pattern that fits the candidate. Mix them. Don't make every diagram look the same — variety is part of the point. - -### Mermaid graph (the workhorse for dependencies / call flow) - -Use a Mermaid `flowchart` or `graph` when the point is "X calls Y calls Z, and look at the mess." Wrap it in a Tailwind-styled card so it doesn't feel parachuted in. Style with classDef to colour leakage edges red and the deep module dark. Sequence diagrams work well for "before: 6 round-trips; after: 1." - -```html -
-
-    flowchart LR
-      A[OrderHandler] --> B[OrderValidator]
-      B --> C[OrderRepo]
-      C -.leak.-> D[PricingClient]
-      classDef leak stroke:#dc2626,stroke-width:2px;
-      class C,D leak
-  
-
-``` - -### Hand-built boxes-and-arrows (when Mermaid's layout fights you) - -Modules as `
`s with borders and labels. Arrows as inline SVG `` or `` elements positioned absolutely over a relative container. Reach for this when you want the "after" diagram to feel like one thick-bordered deep module with greyed-out internals — Mermaid won't render that with the right weight. - -### Cross-section (good for layered shallowness) - -Stack horizontal bands (`h-12 border-l-4`) to show layers a call passes through. Before: 6 thin layers each doing nothing. After: 1 thick band labelled with the consolidated responsibility. - -### Mass diagram (good for "interface as wide as implementation") - -Two rectangles per module — one for interface surface area, one for implementation. Before: interface rectangle is nearly as tall as the implementation rectangle (shallow). After: interface rectangle is short, implementation rectangle is tall (deep). - -### Call-graph collapse - -Before: a tree of function calls rendered as nested boxes. After: the same tree collapsed into one box, with the now-internal calls shown faded inside it. - -## Style guidance - -- Lean editorial, not corporate-dashboard. Generous whitespace. Serif optional for headings (`font-serif` works well with stone/slate). -- Colour sparingly: one accent (emerald or indigo) plus red for leakage and amber for warnings. -- Keep diagrams ~320px tall so before/after sits comfortably side by side without scrolling. -- Use `text-xs uppercase tracking-wider` for module labels inside diagrams — they should read as schematic, not as UI. -- The only scripts are the Tailwind CDN and the Mermaid ESM import. The report is otherwise static — no app code, no interactivity beyond Mermaid's own rendering. - -## Top recommendation section - -One larger card. Candidate name, one sentence on why, anchor link to its card. That's it. - -## Tone - -Plain English, concise — but the architectural nouns and verbs come straight from the `/codebase-design` skill. Concision is not an excuse to drift. - -**Use exactly:** module, interface, implementation, depth, deep, shallow, seam, adapter, leverage, locality. - -**Never substitute:** component, service, unit (for module) · API, signature (for interface) · boundary (for seam) · layer, wrapper (for module, when you mean module). - -**Phrasings that fit the style:** - -- "Order intake module is shallow — interface nearly matches the implementation." -- "Pricing leaks across the seam." -- "Deepen: one interface, one place to test." -- "Two adapters justify the seam: HTTP in prod, in-memory in tests." - -**Wins bullets** name the gain in glossary terms: *"locality: bugs concentrate in one module"*, *"leverage: one interface, N call sites"*, *"interface shrinks; implementation absorbs the wrappers"*. Don't write *"easier to maintain"* or *"cleaner code"* — those terms aren't in the glossary and don't earn their place. - -No hedging, no throat-clearing, no "it's worth noting that…". If a sentence could be a bullet, make it a bullet. If a bullet could be cut, cut it. If a term isn't in the `/codebase-design` glossary, reach for one that is before inventing a new one. diff --git a/.agents/skills/improve-codebase-architecture/SKILL.md b/.agents/skills/improve-codebase-architecture/SKILL.md deleted file mode 100644 index a79b493..0000000 --- a/.agents/skills/improve-codebase-architecture/SKILL.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -name: improve-codebase-architecture -description: Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick. -disable-model-invocation: true ---- - -# Improve Codebase Architecture - -Surface architectural friction and propose **deepening opportunities** — refactors that turn shallow modules into deep ones. The aim is testability and AI-navigability. - -This command is _informed_ by the project's domain model and built on a shared design vocabulary: - -- Run the `/codebase-design` skill for the architecture vocabulary (**module**, **interface**, **depth**, **seam**, **adapter**, **leverage**, **locality**) and its principles (the deletion test, "the interface is the test surface", "one adapter = hypothetical seam, two = real"). Use these terms exactly in every suggestion — don't drift into "component," "service," "API," or "boundary." -- The domain language in `CONTEXT.md` gives names to good seams; ADRs in `docs/adr/` record decisions this command should not re-litigate. - -## Process - -### 1. Explore - -Read the project's domain glossary (`CONTEXT.md`) and any ADRs in the area you're touching first. - -Then use the Agent tool with `subagent_type=Explore` to walk the codebase. Don't follow rigid heuristics — explore organically and note where you experience friction: - -- Where does understanding one concept require bouncing between many small modules? -- Where are modules **shallow** — interface nearly as complex as the implementation? -- Where have pure functions been extracted just for testability, but the real bugs hide in how they're called (no **locality**)? -- Where do tightly-coupled modules leak across their seams? -- Which parts of the codebase are untested, or hard to test through their current interface? - -Apply the **deletion test** to anything you suspect is shallow: would deleting it concentrate complexity, or just move it? A "yes, concentrates" is the signal you want. - -### 2. Present candidates as an HTML report - -Write a self-contained HTML file to the OS temp directory so nothing lands in the repo. Resolve the temp dir from `$TMPDIR`, falling back to `/tmp` (or `%TEMP%` on Windows), and write to `/architecture-review-.html` so each run gets a fresh file. Open it for the user — `xdg-open ` on Linux, `open ` on macOS, `start ` on Windows — and tell them the absolute path. - -The report uses **Tailwind via CDN** for layout and styling, and **Mermaid via CDN** for diagrams where a graph/flow/sequence reliably communicates the structure. Mix Mermaid with hand-crafted CSS/SVG visuals — use Mermaid when relationships are graph-shaped (call graphs, dependencies, sequences), and hand-built divs/SVG when you want something more editorial (mass diagrams, cross-sections, collapse animations). Each candidate gets a **before/after visualisation**. Be visual. - -For each candidate, render a card with: - -- **Files** — which files/modules are involved -- **Problem** — why the current architecture is causing friction -- **Solution** — plain English description of what would change -- **Benefits** — explained in terms of locality and leverage, and how tests would improve -- **Before / After diagram** — side-by-side, custom-drawn, illustrating the shallowness and the deepening -- **Recommendation strength** — one of `Strong`, `Worth exploring`, `Speculative`, rendered as a badge - -End the report with a **Top recommendation** section: which candidate you'd tackle first and why. - -**Use CONTEXT.md vocabulary for the domain, and the `/codebase-design` vocabulary for the architecture.** If `CONTEXT.md` defines "Order," talk about "the Order intake module" — not "the FooBarHandler," and not "the Order service." - -**ADR conflicts**: if a candidate contradicts an existing ADR, only surface it when the friction is real enough to warrant revisiting the ADR. Mark it clearly in the card (e.g. a warning callout: _"contradicts ADR-0007 — but worth reopening because…"_). Don't list every theoretical refactor an ADR forbids. - -See [HTML-REPORT.md](HTML-REPORT.md) for the full HTML scaffold, diagram patterns, and styling guidance. - -Do NOT propose interfaces yet. After the file is written, ask the user: "Which of these would you like to explore?" - -### 3. Grilling loop - -Once the user picks a candidate, run the `/grilling` skill to walk the design tree with them — constraints, dependencies, the shape of the deepened module, what sits behind the seam, what tests survive. - -Side effects happen inline as decisions crystallize — run the `/domain-modeling` skill to keep the domain model current as you go: - -- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md`. Create the file lazily if it doesn't exist. -- **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there. -- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones. -- **Want to explore alternative interfaces for the deepened module?** Run the `/codebase-design` skill and use its design-it-twice parallel sub-agent pattern. diff --git a/.agents/skills/prototype/LOGIC.md b/.agents/skills/prototype/LOGIC.md deleted file mode 100644 index 526ecb1..0000000 --- a/.agents/skills/prototype/LOGIC.md +++ /dev/null @@ -1,79 +0,0 @@ -# Logic Prototype - -A tiny interactive terminal app that lets the user drive a state model by hand. Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases. - -## When this is the right shape - -- "I'm not sure if this state machine handles the edge case where X then Y." -- "Does this data model actually let me represent the case where..." -- "I want to feel out what the API should look like before writing it." -- Anything where the user wants to **press buttons and watch state change**. - -If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md). - -## Process - -### 1. State the question - -Before writing code, write down what state model and what question you're prototyping. One paragraph, in the prototype's README or a comment at the top of the file. A logic prototype that answers the wrong question is pure waste — make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK. - -### 2. Pick the language - -Use whatever the host project uses. If the project has no obvious runtime (e.g. a docs repo), ask. - -Match the project's existing conventions for tooling — don't add a new package manager or runtime just for the prototype. - -### 3. Isolate the logic in a portable module - -Put the actual logic — the bit that's answering the question — behind a small, pure interface that could be lifted out and dropped into the real codebase later. The TUI around it is throwaway; the logic module shouldn't be. - -The right shape depends on the question: - -- **A pure reducer** — `(state, action) => state`. Good when actions are discrete events and state is a single value. -- **A state machine** — explicit states and transitions. Good when "which actions are even legal right now" is part of the question. -- **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations. -- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state. - -Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a TUI. Keep it pure: no I/O, no terminal code, no `console.log` for control flow. The TUI imports it and calls into it; nothing flows the other direction. - -This is what makes the prototype useful past its own lifetime. When the question's been answered, the validated reducer / machine / function set can be lifted into the real module — the TUI shell gets deleted. - -### 4. Build the smallest TUI that exposes the state - -Build it as a **lightweight TUI** — on every tick, clear the screen (`console.clear()` / `print("\033[2J\033[H")` / equivalent) and re-render the whole frame. The user should always see one stable view, not an ever-growing scrollback. - -Each frame has two parts, in this order: - -1. **Current state**, pretty-printed and diff-friendly (one field per line, or formatted JSON). Use **bold** for field names or section headers and **dim** for less important context (timestamps, IDs, derived values). Native ANSI escape codes are fine — `\x1b[1m` bold, `\x1b[2m` dim, `\x1b[0m` reset. No need to pull in a styling library unless one is already in the project. -2. **Keyboard shortcuts**, listed at the bottom: `[a] add user [d] delete user [t] tick clock [q] quit`. Bold the key, dim the description, or vice-versa — whatever reads cleanly. - -Behaviour: - -1. **Initialise state** — a single in-memory object/struct. Render the first frame on start. -2. **Read one keystroke (or one line)** at a time, dispatch to a handler that mutates state. -3. **Re-render** the full frame after every action — don't append, replace. -4. **Loop until quit.** - -The whole frame should fit on one screen. - -### 5. Make it runnable in one command - -Add a script to the project's existing task runner (`package.json` scripts, `Makefile`, `justfile`, `pyproject.toml`). The user should run `pnpm run ` or equivalent — never need to remember a path. - -If the host project has no task runner, just put the command at the top of the prototype's README. - -### 6. Hand it over - -Give the user the run command. They'll drive it themselves; the interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different" — those are the bugs in the _idea_, which is the whole point. If they want new actions added, add them. Prototypes evolve. - -### 7. Capture the answer - -When the prototype has done its job, the answer to the question is the only thing worth keeping. If the user is around, ask what it taught them. If not, leave a `NOTES.md` next to the prototype so the answer can be filled in (or filled in by you, if you've watched the session) before the prototype gets deleted. - -## Anti-patterns - -- **Don't add tests.** A prototype that needs tests is no longer a prototype. -- **Don't wire it to the real database.** Use an in-memory store unless the question is specifically about persistence. -- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question. -- **Don't blur the logic and the TUI together.** If the reducer / state machine references `console.log`, prompts, or terminal escape codes, it's no longer portable. Keep the TUI as a thin shell over a pure module. -- **Don't ship the TUI shell into production.** The shell is optimised for being driven by hand from a terminal. The logic module behind it is the bit worth keeping. diff --git a/.agents/skills/prototype/SKILL.md b/.agents/skills/prototype/SKILL.md deleted file mode 100644 index 9425f7d..0000000 --- a/.agents/skills/prototype/SKILL.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: prototype -description: Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like. ---- - -# Prototype - -A prototype is **throwaway code that answers a question**. The question decides the shape. - -## Pick a branch - -Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around: - -- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). Build a tiny interactive terminal app that pushes the state machine through cases that are hard to reason about on paper. -- **"What should this look like?"** → [UI.md](UI.md). Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar. - -The two branches produce very different artifacts — getting this wrong wastes the whole prototype. If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of the prototype. - -## Rules that apply to both - -1. **Throwaway from day one, and clearly marked as such.** Locate the prototype code close to where it will actually be used (next to the module or page it's prototyping for) so context is obvious — but name it so a casual reader can see it's a prototype, not production. For throwaway UI routes, obey whatever routing convention the project already uses; don't invent a new top-level structure. -2. **One command to run.** Whatever the project's existing task runner supports — `pnpm `, `python `, `bun `, etc. The user must be able to start it without thinking. -3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is _checking_, not something it should depend on. If the question explicitly involves a database, hit a scratch DB or a local file with a clear "PROTOTYPE — wipe me" name. -4. **Skip the polish.** No tests, no error handling beyond what makes the prototype _runnable_, no abstractions. The point is to learn something fast and then delete it. -5. **Surface the state.** After every action (logic) or on every variant switch (UI), print or render the full relevant state so the user can see what changed. -6. **Delete or absorb when done.** When the prototype has answered its question, either delete it or fold the validated decision into the real code — don't leave it rotting in the repo. - -## When done - -The _answer_ is the only thing worth keeping from a prototype. Capture it somewhere durable (commit message, ADR, issue, or a `NOTES.md` next to the prototype) along with the question it was answering. If the user is around, that capture is a quick conversation; if not, leave the placeholder so they (or you, on the next pass) can fill in the verdict before deleting the prototype. diff --git a/.agents/skills/prototype/UI.md b/.agents/skills/prototype/UI.md deleted file mode 100644 index f3b6e64..0000000 --- a/.agents/skills/prototype/UI.md +++ /dev/null @@ -1,112 +0,0 @@ -# UI Prototype - -Generate **several radically different UI variations** on a single route, switchable from a floating bottom bar. The user flips between variants in the browser, picks one (or steals bits from each), then throws the rest away. - -If the question is about logic/state rather than what something looks like — wrong branch. Use [LOGIC.md](LOGIC.md). - -## When this is the right shape - -- "What should this page look like?" -- "I want to see a few options for this dashboard before committing." -- "Try a different layout for the settings screen." -- Any time the user would otherwise spend a day picking between three vague mockups in their head. - -## Two sub-shapes — strongly prefer sub-shape A - -A UI prototype is much easier to judge when it's **butting up against the rest of the app** — real header, real sidebar, real data, real density. A throwaway route on its own is a vacuum: every variant looks fine in isolation. Default to sub-shape A whenever there's a plausible existing page to host the variants. Only reach for sub-shape B if the prototype genuinely has no nearby home. - -### Sub-shape A — adjustment to an existing page (preferred) - -The route already exists. Variants are rendered **on the same route**, gated by a `?variant=` URL search param. The existing data fetching, params, and auth all stay — only the rendering swaps. This is the default; pick it unless there's a specific reason not to. - -If the prototype is for something that doesn't yet have a page but *would naturally live inside one* (a new section of the dashboard, a new card on the settings screen, a new step in an existing flow) — that's still sub-shape A. Mount the variants inside the host page. - -### Sub-shape B — a new page (last resort) - -Only use this when the thing being prototyped genuinely has no existing page to live inside — e.g. an entirely new top-level surface, or a flow that can't be embedded anywhere sensible. - -Create a **throwaway route** following whatever routing convention the project already uses — don't invent a new top-level structure. Name it so it's obviously a prototype (e.g. include the word `prototype` in the path or filename). Same `?variant=` pattern. - -Before committing to sub-shape B, sanity-check: is there really no existing page this could be embedded in? An empty route hides design problems that a populated one would expose. - -In both sub-shapes the floating bottom bar is identical. - -## Process - -### 1. State the question and pick N - -Default to **3 variants**. More than 5 stops being radically different and starts being noise — cap there. - -Write down the plan in one line, in the prototype's location or a top-of-file comment: - -> "Three variants of the settings page, switchable via `?variant=`, on the existing `/settings` route." - -This works whether the user is here to push back or not. - -### 2. Generate radically different variants - -Draft each variant. Hold each one to: - -- The page's purpose and the data it has access to. -- The project's component library / styling system (TailwindCSS, shadcn, MUI, plain CSS, whatever). -- A clear exported component name, e.g. `VariantA`, `VariantB`, `VariantC`. - -Variants must be **structurally different** — different layout, different information hierarchy, different primary affordance, not just different colours. Three slightly-tweaked card grids isn't a UI prototype, it's wallpaper. If two drafts come out too similar, redo one with explicit "do not use a card grid" guidance. - -### 3. Wire them together - -Create a single switcher component on the route: - -```tsx -// pseudo-code — adapt to the project's framework -const variant = searchParams.get('variant') ?? 'A'; -return ( - <> - {variant === 'A' && } - {variant === 'B' && } - {variant === 'C' && } - - -); -``` - -For sub-shape A (existing page): keep all the existing data fetching above the switcher; only the rendered subtree changes per variant. - -For sub-shape B (new page): the throwaway route under `/prototype/` mounts the same switcher. - -### 4. Build the floating switcher - -A small fixed-position bar at the bottom-centre of the screen with three pieces: - -- **Left arrow** — cycles to the previous variant (wraps around). -- **Variant label** — shows the current variant key and, if the variant exports a name, that name too. e.g. `B — Sidebar layout`. -- **Right arrow** — cycles forward (wraps around). - -Behaviour: - -- Clicking an arrow updates the URL search param (use the framework's router — `router.replace` on Next, `navigate` on React Router, etc) so the variant is shareable and reload-stable. -- Keyboard: `←` and `→` arrow keys also cycle. Don't intercept arrow keys when an ``, `