@vpxa/aikit 0.1.308 → 0.1.309

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/package.json +1 -1
  2. package/packages/cli/dist/index.js +3 -3
  3. package/packages/cli/dist/{init-CyjUXjQw.js → init-VP9ig7OK.js} +1 -1
  4. package/packages/cli/dist/{templates-BQ1J4HzY.js → templates-WsJg6Pkc.js} +5 -5
  5. package/packages/server/dist/bin.js +1 -1
  6. package/packages/server/dist/index.js +1 -1
  7. package/packages/server/dist/repair-json-B6Q_HRoP.js +3 -0
  8. package/packages/server/dist/repair-json-D4mft_HA.js +4 -0
  9. package/packages/server/dist/{server-D6sJEw0I.js → server-DZKWh8ZG.js} +162 -164
  10. package/packages/server/dist/{server-BSvqfFcK.js → server-RV1UYywi.js} +162 -164
  11. package/packages/server/dist/{server-http-B1ixOw2x.js → server-http-DeWcQphZ.js} +1 -1
  12. package/packages/server/dist/{server-http-BurquBLf.js → server-http-Dk16rq4T.js} +1 -1
  13. package/packages/server/dist/server-stdio-Bx_Aa99F.js +1 -0
  14. package/packages/server/dist/server-stdio-CebgeeBc.js +2 -0
  15. package/scaffold/INSTRUCTIONS.md +273 -0
  16. package/scaffold/dist/adapters/copilot.mjs +2 -9
  17. package/scaffold/dist/adapters/hermes-agent.mjs +2 -2
  18. package/scaffold/dist/adapters/hermes.mjs +8 -4
  19. package/scaffold/dist/adapters/intellij.mjs +7 -3
  20. package/scaffold/dist/adapters/skills.mjs +3 -1
  21. package/scaffold/dist/adapters/zed.mjs +6 -2
  22. package/scaffold/dist/definitions/agents.mjs +2 -2
  23. package/scaffold/dist/definitions/bodies.mjs +95 -366
  24. package/scaffold/dist/definitions/protocols.mjs +117 -556
  25. package/scaffold/dist/definitions/skills/adr-skill.mjs +41 -197
  26. package/scaffold/dist/definitions/skills/aikit.mjs +52 -205
  27. package/scaffold/dist/definitions/skills/brainstorming.mjs +74 -112
  28. package/scaffold/dist/definitions/skills/browser-use.mjs +128 -184
  29. package/scaffold/dist/definitions/skills/c4-architecture.mjs +45 -106
  30. package/scaffold/dist/definitions/skills/docs.mjs +70 -214
  31. package/scaffold/dist/definitions/skills/frontend-design.mjs +96 -193
  32. package/scaffold/dist/definitions/skills/lesson-learned.mjs +57 -184
  33. package/scaffold/dist/definitions/skills/multi-agents-development.mjs +98 -408
  34. package/scaffold/dist/definitions/skills/present.mjs +193 -1
  35. package/scaffold/dist/definitions/skills/react.mjs +68 -111
  36. package/scaffold/dist/definitions/skills/repo-access.mjs +24 -169
  37. package/scaffold/dist/definitions/skills/requirements-clarity.mjs +45 -94
  38. package/scaffold/dist/definitions/skills/typescript.mjs +162 -230
  39. package/packages/server/dist/server-stdio-CBmXDMpq.js +0 -1
  40. package/packages/server/dist/server-stdio-z3_zG1HF.js +0 -2
@@ -1 +1,193 @@
1
- function e(){return[{file:`SKILL.md`,content:'---\nname: present\ndescription: "Use the AI Kit `present` tool to display rich interactive dashboards, charts, timelines, status boards, and data visualizations in the browser or in-chat. Covers all 32 block types, chart types, actions, annotation system, and template contracts. Load this skill before calling the present tool to ensure professional output."\nmetadata:\n category: cross-cutting\n domain: general\n applicability: always\n inputs: [data, analysis]\n outputs: [dashboards, charts, reports]\n requires: [aikit]\nargument-hint: "Content to present — data, analysis results, status report, comparison, or interactive MCP App"\n---\n\n# Present Tool — Rich Interactive Dashboards\n\n> **Three-tier authoring model:** (1) Free-form `blocks[]`, (2) Named presets with structured data, (3) Viewer templates for custom HTML/iframes. Use `aikit://schemas/channel-surface` for block catalog, `aikit://present/presets` for preset contracts, `aikit://present/templates` for viewer schemas.\n\nThe tool normalizes all three input tiers into a validated `ChannelSurface` before rendering. Pipeline: **Input -> Normalizer -> ChannelSurface -> Transport Registry -> Render**. Validation errors return structured feedback with fix suggestions — not raw schema dumps.\n\n## 0. Auto-Activation & Feedback\n\n**When you include `actions` or set `response.required: true`, the present tool automatically activates browser transport.** You don\'t need to manually set `preferBrowser`.\n\n**A `💬 Feedback` action is automatically appended to every action array** so users can always provide input. It appears as a text-submit field at the end of the action list. This is added automatically — you do NOT need to include it in your `actions` array.\n\nFor surfaces without actions, the inline MCP App transport is used (renders inside the chat if supported).\n\n## 0b. Error Recovery\n\nWhen the present tool returns an error:\n- **`VALIDATION` errors**: Field-level fix suggestions are returned. Common issues:\n - `unknown block type`: Check the block type name — a list of closest matches is returned\n - `schemaVersion !== 1`: Always set `schemaVersion: 1`\n - `title missing`: Title is always required\n - `invalid field type`: The fix suggestion tells you the expected type\n- **`RENDER_FAILED` errors**: The block data is valid but rendering failed. Try simplifying the surface or switching to browser transport.\n- **Use `raw` field** for complex payloads (mermaid, code, many blocks) — the `raw` JSON string auto-repair handles common LLM JSON errors (unescaped newlines, trailing commas).\n\n## 1. Presets (Tier 2)\n\nPresets are named data contracts that expand `blocks[]` from structured input. 8 presets registered at runtime via `aikit://present/presets`:\n\n| Preset | Input shape | Expands to |\n|--------|------------|------------|\n| `summary` | `{ title, summary, passed?: number, failed?: number }` | heading, markdown, metrics |\n| `plan` | `{ title, steps: [{ label, checked }] }` | heading, checklist |\n| `understanding` | `{ title, explanation, details?: string }` | heading, markdown, kv |\n| `bug-analyze` | `{ title, severity, status, code?: string, analysis?: string }` | heading, kv, code, markdown |\n| `task-done` | `{ title, items: [{ label, checked }], completed?, total? }` | heading, checklist, metrics |\n| `review` | `{ title, criteria: [{ label, checked }] }` | heading, checklist + actions |\n| `explore` | `{ title, findings: [{ heading, code }] }` | heading, code (per finding) |\n| `decision` | `{ title, recommendation, options?: [{ title, items }] }` | heading, kv, comparison |\n\nEach preset supplies `inputSchema` (JSON Schema), `example` (JSON), and `expandsTo` (block description).\n\n## 2. All 32 Content Blocks\n\nPass content as a `blocks` array of `{ type, title?, value }` objects.\n\n| Category | Type | Value shape | Use for |\n|----------|------|-------------|---------|\n| **Content** | `prompt` | string | Prompt or callout text |\n| | `text` | string | Plain text without markdown parsing |\n| | `heading` | string | Standalone section headings |\n| | `paragraph` | string | Standalone paragraph copy |\n| | `markdown` | string | Prose, headings, code snippets |\n| | `code` | string | Code or diff excerpts |\n| | `list` | string[] | Bullet list items |\n| | `separator` | none | Visual divider |\n| | `diff` | `{ files: [{ path, hunks: [{ header, changes: [{ type, content }] }] }] }` | File diffs with +/- highlights |\n| | `finding` | `{ label: string; description?: string; severity?: string }` | Finding with severity pill (critical/high/medium/low) |\n| **Data** | `table` | `Record[]` or `{ headers, rows }` | Tabular data |\n| | `metrics` | `[{ label, value, trend?, status? }]` | KPI cards |\n| | `kv` | `Record<string, string>` | Key-value pairs |\n| | `tags` | string[] | Tag pills |\n| | `data-table-schema` | `{ fields: [{ name, type, required?, description?, constraints?, indexes? }] }` | Schema table with indexes |\n| | `chart` | `{ chartType, data, xKey?, yKeys? }` | `line | area | bar | horizontal-bar | pie | donut | sparkline | heatmap` |\n| **Visualization** | `cards` | `[{ title, body?, badge?, status? }]` | Summary cards |\n| | `tree` | `{ name, children? }` | Hierarchies |\n| | `timeline` | `[{ title, description?, timestamp?, status? }]` | Event sequences |\n| | `mermaid` | string | Diagrams |\n| | `graph` | `{ nodes: [{id, label?}], edges: [{from, to, label?}] }` | Network graphs |\n| | `comparison` | `[{title, items}]` or `{columns: [{title, items}]}` | Side-by-side comparisons |\n| | `lifecycle-flow` | `{ nodes: [{ id, label, type? }], edges: [{ source, target, label? }] }` | SVG flow diagram |\n| | `component-detail` | `{ name, type?, description?, responsibilities?, interfaces?, dependencies?, metrics?, codeLinks? }` | Component detail view |\n| **Interactive** | `checklist` | `[{ label, checked }]` | Task lists |\n| | `status-board` | `[{category, items}]` or `{items: [{category, items}]}` | Service health boards |\n| | `progress` | `{label, value, max?}` or `{items: [{label, value, max?, color?}]}` | Progress bars |\n| | `docs-browser` | `{ files: [{path, title?, content?, status?}], title? }` | Documentation indexes |\n| | `annotation` | `{ items: [{ label, description?, severity? }] }` | Annotation groups |\n| | `approval` | `{ options: [{ label, value }], comment?: string }` | Approval with options/textarea |\n| | `docs-hub` | `{ title, items: [{ title, description?, status? }] }` | Doc hub card grid |\n| **Layout** | `actions` | `[{ type, id, label, variant?, options? }]` | Inline action group |\n| | `separator` | none | Visual divider |\n\n> **Rules:**\n> - Prefer `table` blocks for tabular data (pipe tables in `markdown` are auto-normalized).\n> - Use `{ chartType, data, xKey, yKeys }`, not Chart.js `{ labels, datasets }`.\n> - Keep `markdown` for prose, headings, and code, not UI structure.\n> - **NEVER use `code` block for structured data** — use `table`, `checklist`, `kv`, or `markdown`.\n> - **NEVER JSON.stringify() data into a `code` or `markdown` block** — use the typed block.\n> - Block `title` is rendered as a section heading above the block (except for `heading` and `finding` types).\n\n### Data → Block Type Quick Reference\n\n| Your data looks like... | Use this block type | NOT this |\n|---|---|---|\n| Array of strings (decisions, findings, steps) | `list` or `markdown` (bullet list) | ~~`code` with JSON array~~ |\n| Key-value pairs (status, config, metadata) | `kv` or `table` (two columns) | ~~`code` with JSON object~~ |\n| Rows × columns (comparisons, components) | `table` | ~~`markdown` with pipe table~~ |\n| Items with done/not-done state | `checklist` | ~~`markdown` with checkmarks~~ |\n| Hierarchical items (file tree, org chart) | `tree` | ~~`code` with indentation~~ |\n| Numeric KPIs with labels | `metrics` | ~~`markdown`~~ |\n| Before/after or option A vs B | `comparison` | ~~two `code` blocks~~ |\n| Findings with severity | `finding` | ~~`markdown`~~ |\n| Approval or decision required | `approval` + `actions` | ~~`markdown` with options~~ |\n\n## 3. Actions & Annotation\n\nAction shape: `{ type, id, label, variant?, options? }`\n\nValid action types: `button | select | multi-select | form-submit | text-submit | confirm | custom`\n\n**Auto-activation:** Any `actions` array triggers browser transport automatically. The `response.required` flag also triggers browser transport.\n\n**Feedback action:** A "💬 Feedback" text-submit action is automatically appended to every action array. This lets users provide input without you having to add it manually.\n\n```json\n{ "actions": [{ "type": "button", "id": "ack", "label": "Acknowledge", "variant": "primary" }] }\n```\n\n## 4. MCP App Templates\n\n| Template | Purpose | Data shape | Returns |\n|----------|---------|------------|---------|\n| `list-sort` | Reorder a ranked list | `{ items: [{ id, label }] }` | Reordered items |\n| `data-table` | Inspect structured rows | `{ columns, rows, stats? }` | Selection/filter |\n| `picker` | Choose items from categories | `{ categories, items }` | Selected IDs |\n| `flame-graph` | Explore hierarchical totals | `{ profile }` | Clicked node |\n| `form` | Collect field values | `{ fields }` | Field map |\n| `checklist` | Interactive checklist | `{ items, title? }` | Checked state |\n| `document` | Structured long-form content | `{ sections, title? }` | Display only |\n| `report` | Synthesized report content | `{ title, sections, metrics?, tables? }` | Display only |\n| `error` | Structured error states | `{ code, message, details?, stack? }` | Display only |\n| `kanban` | Move cards across columns | `{ columns, cards }` | Card move |\n| `timeline` | Ordered milestones | `{ events }` | Display only |\n| `tree` | Browse nested nodes | `{ root }` | Display only |\n| `diff-view` | Show file diffs | `{ files, stats? }` | Display only |\n| `dashboard` | Show metric cards | `{ metrics }` | Display only |\n| `status-board` | Grouped status views | `{ categories }` | Display only |\n\n## 5. Viewer Templates\n\n| Template | Transport | Purpose |\n|----------|-----------|---------|\n| `c4-static@1` | mcp-app | Static architecture diagram |\n| `c4@1` | browser | Interactive architecture diagram |\n| `process-flow-static@1` | mcp-app | Static process flow |\n| `process-flow@1` | browser | Interactive process flow |\n| `tour@1` | browser | Guided walkthrough |\n| `task-plan-static@1` | mcp-app | Static task execution plan |\n| `task-plan@1` | browser | Interactive task plan with ReactFlow |\n\n## 6. Rules\n\n- **Auto-activation**: `actions` or `response.required` → browser transport. No `actions` → inline MCP App.\n- **Feedback**: A Feedback action is auto-appended. You do NOT need to add it.\n- **Error recovery**: Read the `fixSuggestion` field in validation errors — it tells you exactly what to change.\n- Use `raw` field for complex payloads to leverage auto-repair.\n- For custom HTML demos, write an HTML file, serve locally, open with `browser({ action: "open", url, mode: "ui" })`.\n- For surfaces with mixed content types (metrics + chart + table + markdown), combine them in one `blocks` array.\n- For structured data, prefer `table`, `kv`, `checklist`, `metrics` over reformatting in markdown.\n'}]}export{e as default};
1
+ function e(){return[{file:`SKILL.md`,content:`---
2
+ name: present
3
+ description: "Use the AI Kit present tool for rich dashboards, charts, timelines, status boards, data tables, reviews, approvals, and interactive MCP App surfaces. Load before calling present so output uses the right block/template/action contract and stays readable."
4
+ metadata:
5
+ category: cross-cutting
6
+ domain: general
7
+ applicability: always
8
+ inputs: [data, analysis]
9
+ outputs: [dashboards, charts, reports]
10
+ requires: [aikit]
11
+ argument-hint: "Content to present - data, analysis results, status report, comparison, or interactive MCP App"
12
+ ---
13
+
14
+ # Present Tool
15
+
16
+ Use present for complex user-facing output: reports, dashboards, evidence maps, plans, reviews, comparisons, approvals, charts, timelines, and interactive selections. Plain text is only for tiny status/questions.
17
+
18
+ ## Authoring Model
19
+
20
+ Choose one:
21
+ - blocks: direct markdown/heading/table/chart/cards/metrics/checklist/timeline/status-board/etc.
22
+ - template + data: report, task-plan, review, dashboard, diff, checklist, picker, form.
23
+ - raw JSON: complex surfaces where hand-authored object is clearer.
24
+
25
+ Always include schemaVersion: 1 and title. Use concise description when helpful.
26
+
27
+ ## Selection Guide
28
+
29
+ | Need | Shape |
30
+ |---|---|
31
+ | Summary/report | report template or heading + markdown/table |
32
+ | Plan/progress | task-plan/checklist/status-board |
33
+ | Metrics/trends | metrics + chart |
34
+ | Compare options | table + kv + recommendation |
35
+ | Review/approval | review template + approval action |
36
+ | Logs/errors | code/error block |
37
+ | Choice | actions select/confirm/button |
38
+
39
+ ## Actions
40
+
41
+ - Use actions for buttons, selects, multi-selects, confirmations, and text-submit.
42
+ - Browser transport activates automatically when actions or response.required exist.
43
+ - Free-form text input should use text-submit or elicitation when available.
44
+ - Keep action ids stable, labels short, variants meaningful.
45
+
46
+ ## Quality Bar
47
+
48
+ - One clear title, no giant unstructured markdown dumps.
49
+ - Tables have parallel columns and compact cells.
50
+ - Charts include labels/units and enough context.
51
+ - Approval surfaces state consequence and options clearly.
52
+ - Accessibility: readable order, text equivalents, no color-only meaning.
53
+ - Do not put secrets or huge raw tool output in surfaces.
54
+
55
+ ## Debugging
56
+
57
+ If validation fails, fix schema shape first. Use schema/preset/template resources only when block contract is unclear.
58
+
59
+ ## References
60
+
61
+ Load on demand:
62
+ - references/block-catalog.md — Complete 32-block type catalog with value shapes, best block for each data type, and rules.
63
+ - references/presets-templates.md — Preset contracts (8 presets), viewer templates (6), MCP App templates (14), and error recovery patterns.
64
+ `},{file:`references/block-catalog.md`,content:`# Block Catalog — 32 Content Blocks
65
+
66
+ Pass content as blocks array of { type, title?, value } objects.
67
+
68
+ ## Content Blocks
69
+
70
+ | Type | Value shape | Use for |
71
+ |------|-------------|---------|
72
+ | prompt | string | Prompt or callout text |
73
+ | text | string | Plain text without markdown parsing |
74
+ | heading | string | Standalone section headings |
75
+ | paragraph | string | Standalone paragraph copy |
76
+ | markdown | string | Prose, headings, code snippets |
77
+ | code | string | Code or diff excerpts |
78
+ | list | string[] | Bullet list items |
79
+ | separator | none | Visual divider |
80
+ | diff | { files: [{ path, hunks }] } | File diffs with +/- highlights |
81
+ | finding | { label, description?, severity? } | Finding with severity pill |
82
+
83
+ ## Data Blocks
84
+
85
+ | Type | Value shape | Use for |
86
+ |------|-------------|---------|
87
+ | table | Record[] or { headers, rows } | Tabular data |
88
+ | metrics | [{ label, value, trend?, status? }] | KPI cards |
89
+ | kv | Record<string, string> | Key-value pairs |
90
+ | tags | string[] | Tag pills |
91
+ | data-table-schema | { fields: [{ name, type, required? }] } | Schema table |
92
+ | chart | { chartType, data, xKey?, yKeys? } | line/area/bar/horizontal-bar/pie/donut/sparkline/heatmap |
93
+
94
+ ## Visualization Blocks
95
+
96
+ | Type | Value shape | Use for |
97
+ |------|-------------|---------|
98
+ | cards | [{ title, body?, badge?, status? }] | Summary cards |
99
+ | tree | { name, children? } | Hierarchies |
100
+ | timeline | [{ title, description?, timestamp?, status? }] | Event sequences |
101
+ | mermaid | string | Diagrams |
102
+ | graph | { nodes, edges } | Network graphs |
103
+ | comparison | [{title, items}] or {columns} | Side-by-side comparisons |
104
+ | lifecycle-flow | { nodes, edges } | SVG flow diagram |
105
+ | component-detail | { name, type?, description? } | Component detail view |
106
+
107
+ ## Interactive / Layout
108
+
109
+ | Type | Value shape | Use for |
110
+ |------|-------------|---------|
111
+ | checklist | [{ label, checked }] | Task lists |
112
+ | status-board | [{category, items}] | Service health |
113
+ | progress | {label, value, max?} | Progress bars |
114
+ | docs-browser | { files } | Documentation indexes |
115
+ | annotation | { items } | Annotation groups |
116
+ | approval | { options, comment? } | Approval with options/textarea |
117
+ | docs-hub | { title, items } | Doc hub card grid |
118
+ | actions | [{ type, id, label }] | Inline action group |
119
+
120
+ ## Data-to-Block Quick Reference
121
+
122
+ | Your data looks like... | Use this block type |
123
+ |---|---|
124
+ | Array of strings | list or markdown |
125
+ | Key-value pairs | kv or table (2 columns) |
126
+ | Rows x columns | table |
127
+ | Done/not-done state | checklist |
128
+ | Hierarchical items | tree |
129
+ | Numeric KPIs | metrics |
130
+ | Before/after or A vs B | comparison |
131
+ | Findings with severity | finding |
132
+ `},{file:`references/presets-templates.md`,content:`# Presets, Templates, and Error Recovery
133
+
134
+ ## 8 Named Presets
135
+
136
+ | Preset | Input shape | Expands to |
137
+ |--------|-------------|------------|
138
+ | summary | { title, summary, passed?, failed? } | heading, markdown, metrics |
139
+ | plan | { title, steps } | heading, checklist |
140
+ | understanding | { title, explanation, details? } | heading, markdown, kv |
141
+ | bug-analyze | { title, severity, status, code?, analysis? } | heading, kv, code, markdown |
142
+ | task-done | { title, items, completed?, total? } | heading, checklist, metrics |
143
+ | review | { title, criteria } | heading, checklist + actions |
144
+ | explore | { title, findings } | heading, code |
145
+ | decision | { title, recommendation, options? } | heading, kv, comparison |
146
+
147
+ Each preset supplies inputSchema (JSON Schema), example (JSON), and expandsTo (block description) via aikit://present/presets.
148
+
149
+ ## 6 Viewer Templates
150
+
151
+ | Template | Transport | Purpose |
152
+ |----------|-----------|---------|
153
+ | c4@1 | browser | Interactive C4 architecture diagram |
154
+ | c4-static@1 | mcp-app | Static architecture diagram |
155
+ | process-flow@1 | browser | Interactive process flow |
156
+ | process-flow-static@1 | mcp-app | Static process flow |
157
+ | tour@1 | browser | Guided walkthrough |
158
+ | task-plan@1 | browser | Interactive task plan with ReactFlow |
159
+
160
+ ## 14 MCP App Templates
161
+
162
+ | Template | Purpose | Returns |
163
+ |----------|---------|---------|
164
+ | list-sort | Reorder ranked list | Reordered items |
165
+ | data-table | Inspect structured rows | Selection/filter |
166
+ | picker | Choose items from categories | Selected IDs |
167
+ | flame-graph | Explore hierarchical totals | Clicked node |
168
+ | form | Collect field values | Field map |
169
+ | checklist | Interactive checklist | Checked state |
170
+ | document | Structured long-form content | Display only |
171
+ | report | Synthesized report | Display only |
172
+ | error | Structured error states | Display only |
173
+ | kanban | Move cards across columns | Card move |
174
+ | timeline | Ordered milestones | Display only |
175
+ | tree | Browse nested nodes | Display only |
176
+ | diff-view | Show file diffs | Display only |
177
+ | dashboard | Show metric cards | Display only |
178
+ | status-board | Grouped status views | Display only |
179
+
180
+ ## Error Recovery
181
+
182
+ When present returns VALIDATION errors:
183
+ - unknown block type: check closest matches in response
184
+ - schemaVersion !== 1: always set schemaVersion: 1
185
+ - title missing: title is always required
186
+ - invalid field type: fix suggestion tells expected type
187
+
188
+ For RENDER_FAILED errors: data is valid but rendering failed. Simplify surface or switch to browser transport.
189
+
190
+ Use raw JSON string field for complex payloads — auto-repair handles unescaped newlines and trailing commas.
191
+
192
+ A Feedback text-submit action is automatically appended to every actions array.
193
+ `}]}export{e as default};
@@ -12,98 +12,69 @@ metadata:
12
12
 
13
13
  # React
14
14
 
15
- > Comprehensive React development patterns — component architecture, React 19 APIs, Server Components, TypeScript integration, and performance optimization. Synthesized from react-dev patterns, react-patterns (React 19), and Vercel React best practices.
15
+ Use for React components, hooks, pages, Server Components, Server Actions, data fetching, performance, and React code review. Pair with typescript and frontend-design when relevant.
16
16
 
17
- ## When to Use
17
+ ## Mental Model
18
18
 
19
- **MANDATORY** for the Frontend agent on every React task. Also use when:
20
- - Building React components, hooks, or pages
21
- - Working with Server Components or Server Actions
22
- - Optimizing React performance (re-renders, bundle size, data fetching)
23
- - Reviewing React code for correctness and best practices
19
+ React renders UI from state. Keep render pure, state minimal, effects rare, data flow explicit, and component boundaries aligned with user-facing behavior.
24
20
 
25
- ## Thinking Model
21
+ ## Component Design
26
22
 
27
- React is a **description language for UI**, not an imperative framework. Think in snapshots, not steps:
28
- - "Given this state, what should the screen look like?" (declarative)
29
- - NOT "When this happens, do these 5 things in order" (imperative)
23
+ - Prefer small components with clear props and ownership.
24
+ - Keep derived values out of state; compute or memoize only when needed.
25
+ - Split container/data logic from presentational pieces when it reduces complexity.
26
+ - Preserve accessibility semantics; use buttons/forms/labels before custom roles.
27
+ - Use existing component library and styling conventions.
30
28
 
31
- The render function is a PURE function of (props, state) → JSX. Side effects live in clearly-marked boundaries (effects, event handlers, server actions).
29
+ ## State + Effects
32
30
 
33
- **Server vs Client boundary** the most common architectural mistake in modern React:
34
- - Default to Server Components (zero JS shipped, direct data access)
35
- - Add 'use client' only when you need: event handlers, useState/useEffect, browser APIs
36
- - The boundary is a CONTRACT — server can render client, client CANNOT import server
31
+ Use local state for local UI, URL state for navigable filters/tabs, server/cache state for remote data, context for stable cross-tree values.
37
32
 
38
- Before coding, decide in this order:
39
- 1. **What is pure UI derivation?** Keep it in render.
40
- 2. **What is interaction state?** Keep it in the smallest client boundary.
41
- 3. **What is data loading or mutation?** Prefer server.
42
- 4. **What is side effect vs event response?** Effects synchronize with outside systems; event handlers respond to user intent.
33
+ Effects are for synchronization with external systems. Avoid effects for derivations, event handling, or copying props into state.
43
34
 
44
- ## Decision Flow
35
+ ## Hooks
45
36
 
46
- When implementing a React feature, follow this order:
37
+ - Follow exhaustive deps; fix design instead of suppressing rule.
38
+ - Custom hooks own reusable behavior, not arbitrary grouping.
39
+ - useMemo/useCallback only for measured/reasonable identity or expensive computation needs.
40
+ - useRef for mutable instance values that should not trigger render.
47
41
 
48
- 1. **Server or Client?**
49
- - If it needs browser APIs, event handlers, or local interaction state → Client Component.
50
- - Everything else starts as a Server Component.
51
- - Keep the client boundary as small as possible: interactive leaf, server parent.
42
+ ## React 19 / Server
52
43
 
53
- 2. **Derived state or stored state?**
54
- - If a value can be computed from props/state during render, do NOT store it.
55
- - Store only user input, async status, or state you cannot recompute cheaply or correctly.
44
+ - Server Components fetch/read server data and avoid client JS where possible.
45
+ - Client Components handle interactivity, browser APIs, local state, and effects.
46
+ - Keep server/client boundary explicit; do not pass non-serializable values across.
47
+ - Server Actions need validation, auth, and error handling like any endpoint.
56
48
 
57
- 3. **Data loading location?**
58
- - Initial fetch on server.
59
- - Client refetch/cache only when data must stay live after hydration or respond to client events.
49
+ ## Performance
60
50
 
61
- 4. **Mutation path?**
62
- - Forms and mutations: Server Action + validation.
63
- - Use \`useActionState\` for submission state/errors.
64
- - Add \`useOptimistic\` only when instant feedback materially improves UX.
51
+ Check actual render cause before optimizing. Common fixes:
52
+ - Move state down or split components.
53
+ - Stabilize expensive props only where identity matters.
54
+ - Virtualize long lists.
55
+ - Code split route-heavy UI.
56
+ - Use Suspense/loading boundaries sized to avoid layout shift.
65
57
 
66
- 5. **Effect or not?**
67
- - If synchronizing with DOM, network subscription, timer, or external API → effect.
68
- - If reacting to user input → event handler.
69
- - If deriving view state → render logic, not effect.
58
+ ## Forms + Errors
70
59
 
71
- 6. **Error and loading boundaries?**
72
- - Rendering latency \`<Suspense>\` with a real skeleton.
73
- - Render failures Error Boundary.
74
- - Mutation failures return structured errors from the Server Action.
60
+ - Controlled inputs for dynamic validation; uncontrolled/form actions when simpler.
61
+ - Preserve user input on failure.
62
+ - Show inline field errors and summary for multi-field failures.
63
+ - Error boundaries for render failures; user-safe messages only.
75
64
 
76
- 7. **Performance pass?**
77
- - Start with correct boundaries and minimal client JS.
78
- - Then rely on React Compiler if enabled.
79
- - Only then add manual memoization, virtualization, or code splitting where profiling justifies it.
65
+ ## Validation Before Done
80
66
 
81
- 8. **Extraction pass?**
82
- - Business rules → hooks, utilities, or server functions.
83
- - Components stay focused on describing UI.
67
+ Run relevant tests/checks. For UI changes, verify browser screenshot/interaction paths when possible: desktop, mobile, keyboard, loading, error, empty states.
84
68
 
85
- ## NEVER
69
+ ## References
86
70
 
87
- - **NEVER use \`useEffect\` for derived state** — if you can compute it from props/state, compute it inline or with \`useMemo\`. Effects for derivation cause extra renders and race conditions.
88
- - **NEVER put business logic in components** components are UI description, not business rules. Extract logic to hooks, utilities, or server functions.
89
- - **NEVER use \`any\` to silence TypeScript in component props** use \`unknown\` and narrow, or fix the actual type. \`any\` in props infects the entire component tree.
90
- - **NEVER create a context for state that only one component reads** — prop drilling 2-3 levels is fine. Context adds re-render cost to EVERY consumer.
91
- - **NEVER \`await\` inside \`useEffect\` directly** — use an inner async function or a data-fetching library. Direct await creates unhandled promise rejections and races.
92
- - **NEVER conditionally call hooks** — hooks must be called in the same order every render. If you need conditional logic, move it INSIDE the hook.
93
- - **NEVER spread props onto DOM elements without filtering** — \`{...props}\` passes unknown attributes to the DOM, causing console warnings and potential XSS vectors.
94
- - **NEVER render a list without a stable key** — index-as-key causes state corruption on reorder. Use a domain ID or generate a stable key from content.
71
+ Load on demand:
72
+ - references/component-patterns.mdCode examples: extend native, discriminated union, generic, children typing, ref as prop.
73
+ - references/server-actions.mdFull Server Component, Server Action, and optimistic update code examples.
74
+ `},{file:`references/component-patterns.md`,content:`# Component Patterns
95
75
 
96
- ## React 19 Quick Reference
76
+ ## Extend Native Elements
97
77
 
98
- - \`ref\` as prop — no \`forwardRef\` wrapper for common cases
99
- - \`use()\` — read promises/context during render
100
- - \`useActionState\` + \`<form action>\` — form mutations with server actions
101
- - \`useOptimistic\` + \`useTransition\` — optimistic and non-urgent updates
102
- - Server Components / Server Actions — default to server, opt into client only when needed
103
-
104
- ## Component Patterns
105
-
106
- ### Extend Native Elements
107
78
  \`\`\`tsx
108
79
  type ButtonProps = React.ComponentProps<"button"> & {
109
80
  variant?: "primary" | "secondary" | "ghost";
@@ -115,7 +86,8 @@ function Button({ variant = "primary", size = "md", className, ...props }: Butto
115
86
  }
116
87
  \`\`\`
117
88
 
118
- ### Discriminated Union Props
89
+ ## Discriminated Union Props
90
+
119
91
  \`\`\`tsx
120
92
  type ModalProps =
121
93
  | { variant: "alert"; message: string; onConfirm: () => void }
@@ -129,7 +101,8 @@ function Modal(props: ModalProps) {
129
101
  }
130
102
  \`\`\`
131
103
 
132
- ### Generic Components
104
+ ## Generic Components
105
+
133
106
  \`\`\`tsx
134
107
  type TableProps<T> = {
135
108
  data: T[];
@@ -142,7 +115,8 @@ function Table<T extends Record<string, unknown>>({ data, columns, onRowClick }:
142
115
  }
143
116
  \`\`\`
144
117
 
145
- ### Children Typing
118
+ ## Children Typing
119
+
146
120
  - Specific children: \`React.ReactElement<TabProps>[]\`
147
121
  - Render prop: \`(data: T) => React.ReactNode\`
148
122
  - Text-only API: \`string\`
@@ -157,9 +131,21 @@ function Input({ ref, ...props }: React.ComponentProps<"input">) {
157
131
 
158
132
  Callback refs can return cleanup functions in React 19. Use that for measurement/subscription teardown instead of scattering cleanup elsewhere.
159
133
 
160
- ## Server Components & Actions
134
+ ## Event Handler Types
135
+
136
+ Prefer exact DOM event types at the boundary: \`MouseEvent<HTMLButtonElement>\`, \`ChangeEvent<HTMLInputElement>\`, \`FormEvent<HTMLFormElement>\`. Broad \`SyntheticEvent\` is usually typing too late.
137
+
138
+ ## Hooks Typing
139
+
140
+ - \`useState\` — model UI state with explicit unions, not booleans that drift out of sync.
141
+ - \`useRef<HTMLInputElement>(null)\` for DOM refs; mutable refs only for non-render state.
142
+ - \`useReducer\` — discriminated union actions when state transitions are non-trivial.
143
+ - Custom hooks returning tuples should use \`as const\`.
144
+ - Context consumers should null-guard and fail fast outside their provider.
145
+ `},{file:`references/server-actions.md`,content:`# Server Components & Actions
146
+
147
+ ## Server Component (default — no directive needed)
161
148
 
162
- ### Server Component (default — no directive needed)
163
149
  \`\`\`tsx
164
150
  import { db } from "@/lib/db";
165
151
 
@@ -169,7 +155,8 @@ export default async function UsersPage() {
169
155
  }
170
156
  \`\`\`
171
157
 
172
- ### Client Component (explicit opt-in)
158
+ ## Client Component (explicit opt-in)
159
+
173
160
  \`\`\`tsx
174
161
  "use client";
175
162
  import { useState } from "react";
@@ -180,7 +167,8 @@ export function Counter({ initialCount }: { initialCount: number }) {
180
167
  }
181
168
  \`\`\`
182
169
 
183
- ### Server Action with Form
170
+ ## Server Action with Form
171
+
184
172
  \`\`\`tsx
185
173
  "use server";
186
174
  import { z } from "zod";
@@ -212,7 +200,8 @@ export function CreateUserForm() {
212
200
  }
213
201
  \`\`\`
214
202
 
215
- ### Optimistic Updates
203
+ ## Optimistic Updates
204
+
216
205
  \`\`\`tsx
217
206
  "use client";
218
207
  import { useOptimistic } from "react";
@@ -242,36 +231,4 @@ function TodoList({ todos, addTodo }: { todos: Todo[]; addTodo: (text: string) =
242
231
  );
243
232
  }
244
233
  \`\`\`
245
-
246
- ## Event Handler Types
247
-
248
- Prefer exact DOM event types at the boundary: \`MouseEvent<HTMLButtonElement>\`, \`ChangeEvent<HTMLInputElement>\`, \`FormEvent<HTMLFormElement>\`. If you start with a broad \`SyntheticEvent\`, you are probably typing too late.
249
-
250
- ## Hooks Typing
251
-
252
- - \`useState\` — model UI state with explicit unions, not booleans that drift out of sync
253
- - \`useRef<HTMLInputElement>(null)\` for DOM refs; mutable refs only for non-render state
254
- - \`useReducer\` — discriminated union actions when state transitions are non-trivial
255
- - Custom hooks returning tuples should use \`as const\`
256
- - Context consumers should null-guard and fail fast outside their provider
257
-
258
- ## Performance Rules
259
-
260
- ### Prevent Async Waterfalls
261
- \`\`\`tsx
262
- const user = await getUser(id);
263
- const posts = await getPosts(user.id);
264
-
265
- const [user, posts] = await Promise.all([getUser(id), getPosts(id)]);
266
- \`\`\`
267
-
268
- ### Performance Checklist
269
- - Server Components first; ship less JS before optimizing JS
270
- - \`<Suspense>\` + streaming for slow server work
271
- - SWR/React Query when client data must stay fresh after hydration
272
- - React Compiler first, then manual \`useMemo\`/\`useCallback\` only when profiling proves need
273
- - Virtualize lists >100 items; defer heavy client work with \`useDeferredValue\`
274
- - Lazy load below-fold components; prefer named imports for tree-shaking
275
- - Avoid passing large objects across the server/client boundary
276
-
277
234
  `}];export{e as default};