design-notebook

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Design Notebook

设计笔记本

Scaffold and run a design iteration notebook — a focused canvas that shows one iteration at a time, with prev/next navigation, side-by-side comparisons for divergent exploration, and a collapsible filmstrip drawer for visual overview of every step.
搭建并运行设计迭代笔记本——这是一个聚焦画布,每次展示一个迭代版本,支持上一个/下一个导航,可并排对比用于发散探索,还有可折叠的幻灯片抽屉用于直观概览所有步骤。

Step 1: Choose Scaffold Path

步骤1:选择搭建路径

Path A: Standalone project (no existing React framework)

路径A:独立项目(无现有React框架)

Use this when the working directory is empty or has no React framework.
The template directory is at
template/
relative to this SKILL.md file. Use
cp
commands to copy files — do NOT read and rewrite them.
bash
undefined
当工作目录为空或没有React框架时使用此路径。
模板目录位于此SKILL.md文件的相对路径
template/
下。使用
cp
命令复制文件——请勿读取并重写文件。
bash
undefined

Copy project config files

Copy project config files

cp template/package.json template/tsconfig.json template/vite.config.ts template/index.html .
cp template/package.json template/tsconfig.json template/vite.config.ts template/index.html .

Copy all source files

Copy all source files

cp -r template/src .
cp -r template/src .

Copy AGENTS.md and symlink CLAUDE.md

Copy AGENTS.md and symlink CLAUDE.md

cp template/AGENTS.md . ln -s AGENTS.md CLAUDE.md
cp template/AGENTS.md . ln -s AGENTS.md CLAUDE.md

Install dependencies and start dev server

Install dependencies and start dev server

npm install && npm run dev
undefined
npm install && npm run dev
undefined

Path B: Inject into existing React project

路径B:注入到现有React项目

Each notebook gets a slug — a lowercase-kebab-case name derived from the user's topic (e.g. "nav redesign" →
nav-redesign
). If the user doesn't provide one, ask.
The harness (NotebookApp, chrome, state-explorer, etc.) is shared across all notebooks. It lives in
src/design-notebooks/_harness/
and is copied once. Each notebook only contains its own
iterations/
,
main.tsx
, and
index.css
.
src/design-notebooks/
  _harness/          ← shared, copied once from template/src
    NotebookApp.tsx
    chrome.tsx
    state-explorer.tsx
    types.ts
    notebook.css
  CLAUDE.md          ← copied once
  <slug>/            ← per notebook
    main.tsx
    index.css
    types.ts         ← re-exports from _harness/types
    iterations/
      index.ts
      baseline/
The template directory is at
template/
relative to this SKILL.md file. Use
cp
commands to copy files — do NOT read and rewrite them.
First notebook (sets up harness + first notebook):
bash
undefined
每个笔记本都有一个slug——从用户的主题派生的小写短横线分隔命名(例如“导航重设计” →
nav-redesign
)。如果用户没有提供,请主动询问。
工具套件(NotebookApp、chrome、state-explorer等)在所有笔记本之间共享,存放于
src/design-notebooks/_harness/
,只需复制一次。每个笔记本仅包含自己的
iterations/
main.tsx
index.css
src/design-notebooks/
  _harness/          ← 共享资源,仅从template/src复制一次
    NotebookApp.tsx
    chrome.tsx
    state-explorer.tsx
    types.ts
    notebook.css
  CLAUDE.md          ← 仅复制一次
  <slug>/            ← 每个笔记本专属目录
    main.tsx
    index.css
    types.ts         ← 从_harness/types重新导出
    iterations/
      index.ts
      baseline/
模板目录位于此SKILL.md文件的相对路径
template/
下。使用
cp
命令复制文件——请勿读取并重写文件。
首个笔记本(搭建工具套件 + 第一个笔记本):
bash
undefined

Copy shared harness files

Copy shared harness files

mkdir -p src/design-notebooks/_harness cp template/src/NotebookApp.tsx template/src/chrome.tsx template/src/state-explorer.tsx template/src/types.ts template/src/notebook.css src/design-notebooks/_harness/
mkdir -p src/design-notebooks/_harness cp template/src/NotebookApp.tsx template/src/chrome.tsx template/src/state-explorer.tsx template/src/types.ts template/src/notebook.css src/design-notebooks/_harness/

Copy CLAUDE.md

Copy CLAUDE.md

cp template/AGENTS.md src/design-notebooks/CLAUDE.md
cp template/AGENTS.md src/design-notebooks/CLAUDE.md

Create the notebook

Create the notebook

mkdir -p src/design-notebooks/<slug>/iterations cp -r template/src/iterations/* src/design-notebooks/<slug>/iterations/ cp template/inject/main.tsx template/inject/index.css template/inject/types.ts src/design-notebooks/<slug>/

**Additional notebooks** (harness already exists):

```bash
mkdir -p src/design-notebooks/<slug>/iterations
cp -r template/src/iterations/* src/design-notebooks/<slug>/iterations/
cp template/inject/main.tsx template/inject/index.css template/inject/types.ts src/design-notebooks/<slug>/
Then wire a framework-specific entry point using the slug (see table below).
Framework-specific entry point wiring:
FrameworkWhat to createHow to wire
Vite
design-notebooks/<slug>.html
at project root
Copy
template/inject/entry.html
, replace
__SLUG__
with the notebook slug. Add to
build.rollupOptions.input
in
vite.config.*
Next.js App Router
app/design-notebooks/<slug>/page.tsx
that imports and renders NotebookApp from
_harness/
No config changes needed — file-based routing
Next.js Pages Router
pages/design-notebooks/<slug>.tsx
that imports and renders NotebookApp from
_harness/
No config changes needed — file-based routing
Remix
app/routes/design-notebooks.<slug>.tsx
that imports and renders NotebookApp from
_harness/
No config changes needed — file-based routing
Astro
src/pages/design-notebooks/<slug>.astro
with
<NotebookApp client:only="react" />
No config changes needed
For inject entry points (Next.js, Remix, Astro), create a page component that imports
notebook.css
from
_harness/
and renders
NotebookApp
from
_harness/
, passing
iterations={ITERATIONS}
and
project={PROJECT}
from the notebook's own
iterations/index.ts
. For Next.js, add
'use client'
directive.
Import paths: Check
tsconfig.json
/
jsconfig.json
for path aliases (e.g.
@/*
,
~/
). If the project has one configured, use it (e.g.
@/design-notebooks/_harness/NotebookApp
). Otherwise use relative paths from the entry point file.
mkdir -p src/design-notebooks/<slug>/iterations cp -r template/src/iterations/* src/design-notebooks/<slug>/iterations/ cp template/inject/main.tsx template/inject/index.css template/inject/types.ts src/design-notebooks/<slug>/

**额外笔记本**(工具套件已存在):

```bash
mkdir -p src/design-notebooks/<slug>/iterations
cp -r template/src/iterations/* src/design-notebooks/<slug>/iterations/
cp template/inject/main.tsx template/inject/index.css template/inject/types.ts src/design-notebooks/<slug>/
然后使用slug配置对应框架的入口点(见下表)。
框架专属入口点配置:
框架需要创建的内容配置方式
Vite项目根目录下的
design-notebooks/<slug>.html
复制
template/inject/entry.html
,将
__SLUG__
替换为笔记本slug。添加到
vite.config.*
build.rollupOptions.input
配置中
Next.js App Router导入并渲染
_harness/
中NotebookApp的
app/design-notebooks/<slug>/page.tsx
无需修改配置,基于文件路由自动生效
Next.js Pages Router导入并渲染
_harness/
中NotebookApp的
pages/design-notebooks/<slug>.tsx
无需修改配置,基于文件路由自动生效
Remix导入并渲染
_harness/
中NotebookApp的
app/routes/design-notebooks.<slug>.tsx
无需修改配置,基于文件路由自动生效
Astro包含
<NotebookApp client:only="react" />
src/pages/design-notebooks/<slug>.astro
无需修改配置
对于注入式入口点(Next.js、Remix、Astro),创建一个页面组件,从
_harness/
导入
notebook.css
并渲染
NotebookApp
,传入笔记本自有
iterations/index.ts
中的
iterations={ITERATIONS}
project={PROJECT}
参数。对于Next.js,添加
'use client'
指令。
导入路径: 检查
tsconfig.json
/
jsconfig.json
中的路径别名(例如
@/*
~/
)。如果项目配置了别名,请使用别名(例如
@/design-notebooks/_harness/NotebookApp
),否则使用相对于入口点文件的相对路径。

Step 2: Set the Project Context

步骤2:设置项目上下文

After scaffolding, ask the user what they're iterating on. Use their answer to set the
PROJECT
metadata in
iterations/index.ts
.
搭建完成后,询问用户要迭代的内容。使用用户的回答设置
iterations/index.ts
中的
PROJECT
元数据。

Populate the baseline (Path B only)

填充基线版本(仅路径B)

When injecting into an existing project, the baseline iteration MUST render the project's actual components — do not rebuild or mock them.
  1. Import the real components into
    baseline/Content.tsx
    . The project already has working UI; wrap it with any missing context providers (e.g. theme, auth) so it renders correctly in isolation.
  2. Define 4-6 presets in
    baseline/definition.ts
    that represent the component's meaningful states (loading, error, empty, edge cases, highlight modes). Look at the component's props and internal state to identify what varies.
  3. Build fine-tuning controls in
    baseline/controls.tsx
    for any continuous values (speeds, opacities, counts) or toggles.
The baseline must look identical to the live site. If it doesn't, something is wrong.
Then begin the iteration workflow as described in AGENTS.md.
注入到现有项目时,基线迭代必须渲染项目的真实组件——请勿重建或模拟组件。
  1. 导入真实组件
    baseline/Content.tsx
    。项目已有可运行的UI;为其添加所有缺失的上下文提供者(例如主题、认证),使其可以在独立环境下正确渲染。
  2. 定义4-6个预设
    baseline/definition.ts
    中,代表组件的核心状态(加载、错误、空状态、边缘case、高亮模式)。查看组件的props和内部状态识别可变维度。
  3. 构建微调控件
    baseline/controls.tsx
    中,用于调整所有连续值(速度、不透明度、数量)或开关项。
基线版本必须和线上站点外观完全一致,如果不一致则说明存在问题。
然后按照AGENTS.md中描述的流程开始迭代工作流。

The Iteration Workflow

迭代工作流

Once the notebook is scaffolded, follow the workflow documented in AGENTS.md (which was placed in the project root during scaffolding). The core loop:
笔记本搭建完成后,遵循AGENTS.md中记录的工作流(搭建时已放到项目根目录)。核心循环:

Refine or Diverge?

优化还是发散?

When the user requests a change, ask whether to refine the current iteration in-place or diverge into a new one. Small fixes (copy, spacing, colours) usually refine; new concepts or structural changes usually diverge.
用户请求变更时,询问是要就地优化当前迭代,还是发散生成新迭代。小修复(文案、间距、颜色)通常选择优化;新概念或结构变更通常选择发散。

Sharpen

明确需求

Ask 2-3 clarifying questions before generating. Target: scope, tone, constraints, reference points.
生成前询问2-3个澄清问题,聚焦范围、风格、约束、参考点。

Diverge

发散

Generate 3-4 variations as a
{ group: [...] }
entry in ITERATIONS. Each gets its own folder under
iterations/
with
definition.ts
,
Content.tsx
, and
controls.tsx
.
在ITERATIONS中生成3-4个变体作为
{ group: [...] }
条目。每个变体在
iterations/
下有独立文件夹,包含
definition.ts
Content.tsx
controls.tsx

Converge

收敛

User picks a direction. Mark with
tag: 'picked'
, then generate next iteration as a single entry building on the pick.
用户选择一个方向,标记为
tag: 'picked'
,然后基于选中的版本生成下一个迭代作为单个条目。

Repeat

重复

Append to ITERATIONS, never delete. The notebook tracks all iterations via filmstrip navigation.
追加到ITERATIONS,永远不要删除。笔记本通过幻灯片导航追踪所有迭代。

Iteration Convention

迭代规范

Each iteration is a 3-file folder under
iterations/
:
iterations/
  baseline/
    definition.ts   # config, state shape, presets, resolvePreset
    Content.tsx      # the full mockup
    controls.tsx     # fine-tuning controls (FineTuning component)
  v2/
    definition.ts
    Content.tsx
    controls.tsx
When creating a new iteration, copy the previous iteration's folder (
cp -r iterations/baseline/ iterations/v2/
) and edit the copy. Do not rewrite files from scratch — start from the last iteration and modify what changed.
Each folder is a complete copy — duplicate components freely, no shared primitives between iterations. However, iterations CAN and SHOULD import components from the host project (Path B) — the "no shared primitives" rule applies between iteration folders, not between iterations and the project.
Register each iteration in
iterations/index.ts
:
ts
import { baseline } from './baseline/definition'
import { v2 } from './v2/definition'

export const ITERATIONS: IterationDefinitionEntry[] = [baseline, v2]
每个迭代是
iterations/
下的一个包含3个文件的文件夹:
iterations/
  baseline/
    definition.ts   # 配置、状态结构、预设、resolvePreset
    Content.tsx      # 完整原型
    controls.tsx     # 微调控件(FineTuning组件)
  v2/
    definition.ts
    Content.tsx
    controls.tsx
创建新迭代时,复制上一个迭代的文件夹
cp -r iterations/baseline/ iterations/v2/
)并编辑副本。不要从零开始重写文件——从上一个迭代开始,修改变更的部分。
每个文件夹都是完整副本——可以自由复制组件,迭代之间不要共享基础组件。不过,迭代可以且应该从宿主项目导入组件(路径B)——“不共享基础组件”规则仅适用于迭代文件夹之间,不适用于迭代和项目之间。
iterations/index.ts
中注册每个迭代:
ts
import { baseline } from './baseline/definition'
import { v2 } from './v2/definition'

export const ITERATIONS: IterationDefinitionEntry[] = [baseline, v2]

Semantic Diffs

语义化差异

The
changes
array describes design shifts, not code changes. Prefix with
+
(additions) and
(removals) for green/red coloring.
ts
changes: ['+ source citations', '+ favicon pills']
changes: ['+ guided questions from v4b', '− separate approaches']
Keep chips to 2-5 words. Name concepts, not implementation details.
changes
数组描述设计变更,而非代码变更。使用
+
(新增)和
(移除)前缀来区分绿色/红色高亮:
ts
changes: ['+ source citations', '+ favicon pills']
changes: ['+ guided questions from v4b', '− separate approaches']
每个变更标签保持2-5个词,命名概念而非实现细节。

Presets & State Explorer

预设与状态探索器

Each iteration MUST define 4-6 presets as combo snapshots. This includes the baseline — never ship an iteration with empty presets:
  • Default / happy path
  • Loading / in-progress
  • Edge case (overflow, multi-turn)
  • Error / degraded
  • Empty / new
Build fine-tuning controls in
controls.tsx
with a
FineTuning
component that takes
{ state, onChange }
props.
每个迭代必须定义4-6个预设作为组合快照,包括基线版本——永远不要发布预设为空的迭代:
  • 默认/正常流程
  • 加载/进行中
  • 边缘case(溢出、多轮交互)
  • 错误/降级
  • 空状态/新用户
controls.tsx
中构建微调控件,使用接收
{ state, onChange }
参数的
FineTuning
组件。

Working State

工作状态

Before editing any
Content.tsx
, add
className="nb-working"
to its root
<div>
. Save immediately — HMR shows a shimmer overlay so the user knows which iteration is being worked on. Remove when done.
编辑任何
Content.tsx
之前,在根
<div>
上添加
className="nb-working"
。立即保存——HMR会显示一个闪烁遮罩,让用户知道正在处理哪个迭代。完成后移除该类名。

Filmstrip & History

幻灯片与历史记录

The filmstrip is a collapsible drawer toggled via the "History" button in the header bar. It shows scaled thumbnails of all iterations with change summaries on each card. Write summaries as past-tense outcomes:
  • Single:
    'Switched to dark palette, warm neutrals'
  • Group:
    'Tried 3 nav patterns: tabs, sidebar, floating'
  • Converge:
    'Picked sidebar nav, dropped tabs'
幻灯片是可折叠抽屉,通过头部栏的“History”按钮切换。它展示所有迭代的缩放缩略图,每个卡片上有变更摘要。摘要使用过去式的结果描述:
  • 单个迭代:
    'Switched to dark palette, warm neutrals'
  • 组迭代:
    'Tried 3 nav patterns: tabs, sidebar, floating'
  • 收敛:
    'Picked sidebar nav, dropped tabs'