aae4d42229
Adds the agent-facing workspace and a 20-task plan for migrating the site to Astro. Nothing here implements the refactor; these are briefs, rules and templates that the task agents read. - .agents/ holds context, rules, checklists, skills, specialist agents, component/page/config templates and gate scripts. It is vendor-neutral so MiniMax, Gemini and Codex can all read it; CLAUDE.md just points at AGENTS.md. - .husky/ plus .lintstagedrc.json wire the three gate tiers. gate.sh locks on the shared git-common-dir so parallel worktrees serialise, and guards the assertion count in scripts/verify.mjs against a coverage drop. - plans/astro-refactor/ carries the phase graph, per-task briefs and the model-routing recommendation. These files must be tracked before fanning out: a worktree only checks out tracked files, so an untracked plan is invisible to every agent working in one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
54 lines
1.9 KiB
Markdown
54 lines
1.9 KiB
Markdown
# Rule: componentization
|
|
|
|
## When to make a component
|
|
|
|
Extract when the same markup appears **three times**, or when a block has a name
|
|
a person would use out loud ("the eyebrow", "the route card", "the phase panel").
|
|
|
|
Do not extract on the second occurrence. Two similar blocks often diverge; the
|
|
premature abstraction costs more than the duplication.
|
|
|
|
## Sizes
|
|
|
|
- A component that exceeds ~120 lines of markup is doing two jobs. Split it.
|
|
- A page that is a bare list of components with no markup of its own has been
|
|
over-split. Pages are allowed to contain layout.
|
|
|
|
## Boundaries
|
|
|
|
```
|
|
src/components/
|
|
primitives/ Eyebrow, Rule, Callout, CodeBlock — no domain knowledge
|
|
blocks/ RouteCard, PhasePanel, HandoffTable, SkillPackage — composed, page-agnostic
|
|
islands/ interactive only; each one justified per rules/astro.md
|
|
```
|
|
|
|
- Primitives never import blocks.
|
|
- Blocks never import page-specific data; they take props.
|
|
- Islands are leaves. An island must not wrap static children that could have
|
|
been server-rendered.
|
|
|
|
## Props
|
|
|
|
- Typed `interface Props`, every field. No `any`, no untyped rest spread.
|
|
- Required by default. Optional props need a default and a reason.
|
|
- Pass data, not markup. If you find yourself passing an HTML string, you want a
|
|
`<slot>`.
|
|
|
|
## Named exports, no barrels
|
|
|
|
Import the file you need. Barrel `index.ts` files break tree-shaking and create
|
|
import cycles; bulletproof-react advises against them and so do we.
|
|
|
|
## The catalog is data, not components
|
|
|
|
The 24 review-desk entries are content, not 24 components. One
|
|
`SkillReviewCard.astro` iterating a typed collection. If you are writing the
|
|
25th near-identical component, stop and model the data.
|
|
|
|
## Do not componentize
|
|
|
|
`hands-on/starter/` and `hands-on/rules/` are lab fixtures. Their whole value is
|
|
being flat, dependency-free files an attendee hands to an agent. They ship from
|
|
`public/` unchanged.
|