paint
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePaint - The Master Painter
Paint - 大师级视觉构建工具
Paint a complete visual universe. Brainstorm first, design system second, implement third, audit last. This is NOT a quick beautifier - it's a full design pipeline.
打造完整的视觉体系。先头脑风暴,再搭建设计系统,接着落地实现,最后完成审计。 这不是快速美化工具——而是一套完整的设计流程。
Voice
交互语气
This skill speaks in two registers:
During execution - light ninja flair, signature, immersive. Short.
- "Brushing the color palette..."
- "Painting the hero with the unalloyed gold."
- "Setting the spacing tokens."
In reports / final summaries / audit results - plain, factual, dev-readable. Drop the flair entirely.
- "Done. Design system generated. Files: MASTER.md, tokens.css, theme.config.ts. 3 pages painted."
- No mystic prose, no metaphors. Just what changed, files touched, next step.
The flair lives at the intro and during work narration. The moment a result lands or a question gets asked, it's gone.
本技能采用两种语气风格:
执行过程中 - 带有轻量忍者风格的沉浸式简短表述:
- "正在梳理调色板..."
- "用纯粹金色绘制核心组件..."
- "设置间距令牌..."
报告/最终总结/审计结果中 - 平实、客观、便于开发者阅读的表述,完全摒弃风格化措辞:
- "完成。已生成设计系统。文件:MASTER.md、tokens.css、theme.config.ts。已完成3个页面的视觉构建。"
- 不使用神秘化表述或隐喻,仅说明变更内容、涉及文件及下一步操作。
风格化措辞仅用于开场和执行过程中的旁白,一旦输出结果或回应问题,立即切换为平实语气。
/paint vs /cast
/genjutsu:paint 与 /genjutsu:cast 对比
| | |
|---|---|---|
| Philosophy | "Make this thing beautiful/wow" | "Build a visual universe from scratch" |
| Entry point | Adapts to existing code | Mandatory brainstorm, wipes design if existing |
| Discovery | Lightweight, only when vague | Full brainstorm, never skipped |
| Design system | Optional, implicit | Required, generates MASTER.md |
| Audit | Quick check before delivery | Full design-audit at the end |
| Scope | One component/page/effect | Entire project visual identity |
/genjutsu:paint/genjutsu:cast | | |
|---|---|---|
| 核心理念 | "让这个事物变得美观/惊艳" | "从零开始构建完整的视觉体系" |
| 入口条件 | 适配现有代码 | 必须先进行头脑风暴,若已有设计则会覆盖 |
| 探索环节 | 轻量化,仅在需求模糊时进行 | 完整头脑风暴,不可跳过 |
| 设计系统 | 可选,隐式生成 | 必填,生成MASTER.md文档 |
| 审计环节 | 交付前快速检查 | 最终完成完整设计审计 |
| 覆盖范围 | 单个组件/页面/特效 | 整个项目的视觉标识 |
/genjutsu:paint/genjutsu:castIron Rules
铁则
- Never skip the brainstorm. Not even if the user says "just make it look good." Especially then. The single documented exception is light scope, below, which shortens the brainstorm to one question. It never removes it.
- One question at a time during brainstorm. Never bundle. The second question depends on the first answer.
- Never proceed without both theses validated. Visual + interaction, both explicitly approved.
- Every design token comes from MASTER.md. No magic numbers, no rogue hex values. On light scope, where no MASTER.md is written, they come from the tokens already in the project - read them first, invent nothing.
- Every animation respects the interaction thesis. Timing, easing, forbidden patterns — no exceptions.
- Never install a dependency without asking.
- Work page by page, validate page by page. Never try to do everything at once.
- The audit is not optional. Phase 5 always runs, even if the user seems happy.
- Stack with no detected animation library -> prefer the stack's native APIs before proposing a dependency.
- Animation library detected (GSAP, Framer Motion, Lottie, Rive, etc.) -> respect the dev's choice. Do not propose a replacement.
- Show, don't just describe. At the first visual gate, ask how the user wants to see it, then keep that mode for the session. The preview is throwaway - it communicates the theses, it never becomes the implementation.
- 绝不跳过头脑风暴。即使用户说“直接弄好看点”也不行,尤其是这种情况。唯一有记录的例外是轻量模式(下文详述),此时会将头脑风暴简化为一个问题,但绝不会完全跳过。
- 头脑风暴时一次只问一个问题。绝不批量提问,第二个问题的内容取决于第一个问题的答案。
- 必须同时确认视觉与交互两个核心方向。两者都需获得用户明确认可才能推进。
- 所有设计令牌均来自MASTER.md。不使用魔法数字或无来源的十六进制颜色值。在轻量模式下,若未生成MASTER.md,则使用项目中已有的令牌——先读取现有令牌,绝不凭空创建。
- 所有动画均需遵循交互方向。时长、缓动曲线、禁用模式——无一例外。
- 安装依赖前必须询问用户。
- 按页面逐步推进,逐页验证。绝不试图一次性完成所有工作。
- 审计环节不可省略。无论用户是否满意,第5阶段必须执行。
- 未检测到动画库的技术栈 -> 优先使用技术栈原生API,再考虑推荐依赖。
- 检测到动画库(GSAP、Framer Motion、Lottie、Rive等)-> 尊重开发者的选择,绝不推荐替代方案。
- 展示而非仅描述。在第一个视觉验证节点,询问用户希望的预览方式,并在整个会话中保持该模式。预览仅用于传达设计方向,绝不会直接成为最终实现。
Light scope - the one shortened path
轻量模式——简化流程
paint/genjutsu:castThey land here anyway sometimes: the user typed out of habit, or the host routed it. Running a full art-direction brainstorm on a single button is not rigour, it is a tax. Recognise the case and shorten, out loud.
/genjutsu:paintIt is light scope when all three hold:
- the target is one component, one effect, or one isolated element
- no visual identity is being established: the project already has colors and type, or there is no project yet, only a sketch
- nothing downstream depends on the result being systematised
If two or more fail, it is not light scope. Run the full pipeline and say in one line why.
What changes:
| Phase | Full | Light |
|---|---|---|
| 1 BRAINSTORM | five domains, one question at a time | one question, the least obvious one, then stop |
| 2 THESIS | visual + interaction, both validated | interaction thesis only, still validated |
| 3 DESIGN SYSTEM | generate MASTER.md and the stack token files | skipped. Read the tokens already in the project and use them. Write no MASTER.md. |
| 4 IMPLEMENT | page by page, validate page by page | the one component |
| 5 AUDIT | full design-audit sub-skill | the quick check: reduced-motion, exit animation, 60fps |
Announce it once, so the user knows which pipeline they got and can overrule it:
"This is a single component, so I am running paint light: one question, no design system file. Say so if you want the full pipeline."
What light scope never does: drop the brainstorm question entirely, skip the thesis, or skip validation. Every gate stays. Only their number goes down.
<!-- genjutsu:shared:preview:start -->
paint/genjutsu:cast有时用户会误将此类需求发送到这里:比如出于习惯输入,或被路由到此处。为单个按钮进行完整的艺术方向头脑风暴不是严谨,而是浪费时间。需识别此类情况并主动简化流程。
/genjutsu:paint满足以下全部条件时启用轻量模式:
- 目标为单个组件、单个特效或单个独立元素
- 无需建立新的视觉标识:项目已有颜色和字体规范,或仅为草图无完整项目
- 后续工作不依赖本次结果的系统化输出
若其中两项或以上不满足,则不启用轻量模式。需执行完整流程,并简要说明原因。
轻量模式的变更:
| 阶段 | 完整流程 | 轻量模式 |
|---|---|---|
| 1 头脑风暴 | 覆盖5个领域,逐个提问 | 仅一个问题,选择最不明确的领域提问后即停止 |
| 2 方向确认 | 视觉+交互方向,均需验证 | 仅交互方向,仍需验证 |
| 3 设计系统 | 生成MASTER.md及对应技术栈的令牌文件 | 跳过。读取项目中已有的令牌并使用,不生成MASTER.md |
| 4 落地实现 | 按页面逐步推进,逐页验证 | 仅实现单个组件 |
| 5 审计环节 | 完整设计审计子技能 | 快速检查:简化动画、退出动画、60fps帧率 |
需主动告知用户,让用户知晓当前使用的流程模式并可选择覆盖:
"这是单个组件的需求,因此我将运行轻量模式:仅一个问题,不生成设计系统文件。若需要完整流程,请告知。"
轻量模式绝不会: 完全跳过头脑风暴问题、跳过方向确认、跳过验证环节。所有验证节点都保留,仅减少节点数量。
<!-- genjutsu:shared:preview:start -->
Showing Your Work - The Preview Gate
成果展示——预览节点
Some gates in this pipeline exist so the user can look at something before approving it: an interaction thesis, a set of variants, a visual identity, a design system. Motion and color do not survive being described in a sentence - approving an easing curve you cannot see is not approval, it's a guess.
So before the first gate of that kind, ask how they want to see it. Then never ask again.
The menu - present it once, at the first visual gate, with the recommended default marked:
Before I show you this - how do you want to see it?A. Artifact - a live page: the real easing curve, the real durations, an element actually doing the motion. B. Live preview - a throwaway route in your project, real stack, real tokens. Native: a/@Previewscratch file. C. Inline - written out here in the conversation.#Preview
Recommended default - state it in the menu, never apply it silently:
| Situation | Default |
|---|---|
| Scope is light (a hover, one transition) | C - inline |
| Scope is medium or full, web stack | A - artifact |
| Scope is medium or full, Compose / SwiftUI | B - live preview, A as second choice |
| A full visual identity or design system is on the table | A - artifact |
| No dev server, or the repo must not be written to | A - artifact |
| Host is Cowork and there is no project checkout to write into | A - artifact, B is unavailable |
The choice sticks for the whole session. At every later gate, announce the mode in one line ("Variants in artifact.") and go. Do not reopen the menu. The user switches by saying so - "show me that as text", "put it in an artifact", "just tell me" - respect it immediately, and the new mode becomes the session default from then on.
Which host is this? The gate fires before LOAD, so does not exist yet and this stands on its own. Detect once, cheaply, then map:
$SKILL_BASEbash
if [ -d /mnt/skills/user ]; then
GENJUTSU_HOST=claude-ai
elif [ -d /mnt/.claude/skills ] \
|| [ -n "$(find /sessions -maxdepth 6 -type d -path '*/.claude/skills' 2>/dev/null | head -1)" ]; then
GENJUTSU_HOST=cowork
elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] || [ -d "$HOME/.claude/plugins" ]; then
GENJUTSU_HOST=claude-code
else
GENJUTSU_HOST=unknown
fi
echo "genjutsu host: $GENJUTSU_HOST"Cowork is tested before Claude Code on purpose: both can have a tree, and only Cowork has the session-rooted skills mount, so the specific signal has to win.
~/.claudeProducing the preview - resolve the host, degrade, never fail:
| Host | A - artifact | C - inline |
|---|---|---|
| claude.ai | Rendered natively. Just produce one. | Written out in the conversation. |
| Cowork | The host's persistent artifact. It outlives the turn, which is what a design system needs: the user comes back to it. | The host's inline widget, rendered in place. Right default for a short task. |
| Claude Code | The | Written out in the conversation. |
| unknown | A self-contained HTML file written to a temp path, hand back the path. | Written out in the conversation. |
Call whatever the host actually exposes, under the name it exposes it as - check the tools available in the session rather than assuming one. If nothing renders, fall back down the table rather than failing the gate: an inline preview always beats an aborted one.
B - live preview needs a project to write into. On Cowork there often is not one, so offer A and C, and say in one line why B is missing instead of listing an option that cannot work.
What goes in it. A preview that restates the sentence in a nicer font is worthless. Carry what a sentence cannot:
| Gate | The preview shows |
|---|---|
| An interaction thesis | The easing curve plotted in SVG with its exact value printed, an element that actually performs the interaction with a replay button, the bare numbers (duration, delay, stagger, spring parameters), and a reduced-motion toggle showing the degraded version. |
| A set of variants | That same card per variant, side by side, with one global trigger firing them simultaneously so they are comparable, plus a per-variant replay. |
| A visual identity | Swatches with hex and contrast ratio against their background, a type specimen at the real scale steps, spacing bars, radii and shadow samples, one real button and one real card. |
| A design system | Every token category rendered, the five states of each base component (default, hover, focus, active, disabled), light and dark side by side when both exist. |
Rules the preview obeys:
- It is throwaway. It never becomes the implementation. Build the real thing from the validated thesis and the loaded sub-skills, never by porting preview markup. This matters most on Compose / SwiftUI, where the HTML approximates timing and curve only, not rendering - say so on the page.
- Delete the live-preview route after validation, unless the user asks to keep it.
- Never install a dependency to build a preview.
- Never start a dev server without asking.
- Only show values that are in the thesis. A number that is not in the thesis has no business in the preview - otherwise the preview becomes a second thesis, and nobody validated that one.
流程中的部分节点需要用户先查看内容再进行确认:交互方向、变体集合、视觉标识、设计系统。仅用文字描述无法准确传达动画和颜色——无法看到的缓动曲线不能视为已确认,只是猜测。
因此在第一个此类视觉节点前,询问用户希望的预览方式,之后不再重复询问。
预览选项 - 在第一个视觉节点一次性展示,标记推荐默认选项:
在展示之前——您希望以哪种方式查看?A. 独立工件 - 一个可交互的页面:真实的缓动曲线、时长,元素实际执行动画效果。 B. 实时预览 - 在您的项目中创建一个临时路由,使用真实技术栈和令牌。原生平台:创建/@Preview临时文件。 C. 内联展示 - 在对话中直接呈现。#Preview
推荐默认选项 - 在选项中说明,绝不静默应用:
| 场景 | 默认选项 |
|---|---|
| 轻量模式(hover效果、单个过渡) | C - 内联展示 |
| 中等或完整范围,Web技术栈 | A - 独立工件 |
| 中等或完整范围,Compose / SwiftUI | B - 实时预览,A作为备选 |
| 涉及完整视觉标识或设计系统 | A - 独立工件 |
| 无开发服务器,或不可写入仓库 | A - 独立工件 |
| 宿主为Cowork且无项目检出权限 | A - 独立工件,B不可用 |
选择的模式将在整个会话中保持。后续每个节点仅用一句话说明模式(如“变体将以独立工件展示”),然后直接展示。不再重新提供选项菜单。用户可主动切换模式——“用文字展示”、“放到独立工件里”、“直接告诉我”——需立即尊重用户选择,新模式将成为会话默认模式。
检测宿主环境 - 该节点在LOAD前触发,因此尚未存在,需独立检测。仅检测一次,快速完成后映射:
$SKILL_BASEbash
if [ -d /mnt/skills/user ]; then
GENJUTSU_HOST=claude-ai
elif [ -d /mnt/.claude/skills ] \\
|| [ -n "$(find /sessions -maxdepth 6 -type d -path '*/.claude/skills' 2>/dev/null | head -1)" ]; then
GENJUTSU_HOST=cowork
elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] || [ -d "$HOME/.claude/plugins" ]; then
GENJUTSU_HOST=claude-code
else
GENJUTSU_HOST=unknown
fi
echo "genjutsu host: $GENJUTSU_HOST"优先检测Cowork而非Claude Code:两者都可能有目录,但只有Cowork有基于会话的技能挂载,因此特定信号需优先匹配。
~/.claude生成预览内容 - 根据宿主环境适配,绝不失败:
| 宿主 | A - 独立工件 | C - 内联展示 |
|---|---|---|
| claude.ai | 原生渲染。直接生成即可。 | 在对话中直接呈现。 |
| Cowork | 宿主的持久化工件。可在会话结束后保留,适合设计系统需求:用户可后续查看。 | 宿主的内联组件,直接在对话中渲染。适合短任务的默认选项。 |
| Claude Code | 使用 | 在对话中直接呈现。 |
| unknown | 生成独立HTML文件到临时路径,返回路径。 | 在对话中直接呈现。 |
调用宿主实际提供的工具,使用其暴露的名称——检查会话中可用的工具而非假设。若无法渲染,则降级处理而非失败:内联预览始终优于中止流程。
B - 实时预览需要可写入的项目。Cowork通常没有此类项目,因此仅提供A和C选项,并简要说明B不可用的原因,而非列出无法使用的选项。
预览内容要求。仅用更好的字体重述文字的预览毫无价值。需呈现文字无法传达的内容:
| 节点 | 预览需展示的内容 |
|---|---|
| 交互方向 | SVG绘制的缓动曲线及精确数值,带有重播按钮的交互演示元素,具体参数(时长、延迟、 stagger、弹簧参数),以及显示简化版本的动画开关。 |
| 变体集合 | 每个变体对应的卡片并排展示,全局触发器同步触发所有变体以便对比,每个变体带有独立重播按钮。 |
| 视觉标识 | 带有十六进制值和背景对比度的色板,真实尺寸的字体样本,间距标尺,圆角和阴影示例,真实样式的按钮和卡片。 |
| 设计系统 | 所有令牌分类的渲染效果,每个基础组件的5种状态(默认、hover、focus、active、disabled),同时展示亮色和暗色模式(若存在)。 |
预览遵循的规则:
- 预览为临时内容,绝不会成为最终实现。根据已验证的方向和加载的子技能构建真实实现,绝不通过移植预览标记完成。这在Compose / SwiftUI中尤为重要——HTML仅能近似时长和曲线,无法准确渲染——需在页面中说明。
- 验证完成后删除实时预览路由,除非用户要求保留。
- 绝不安装依赖来构建预览。
- 启动开发服务器前必须询问用户。
- 仅展示方向中包含的值。未在方向中提及的数值不应出现在预览中——否则预览会成为第二个未被验证的方向。
Sub-skills Path Detection
子技能路径检测
<!-- genjutsu:shared:skill-base:start -->
bash
undefined<!-- genjutsu:shared:skill-base:start -->
bash
undefinedEnvironment detection, most specific first:
环境检测,优先级从高到低:
- claude.ai: skills are uploaded individually to /mnt/skills/user/<name>/
- claude.ai: 技能单独上传到/mnt/skills/user/<name>/
- Claude Code: ${CLAUDE_PLUGIN_ROOT} resolves to THIS plugin version's
- Claude Code: ${CLAUDE_PLUGIN_ROOT}指向当前插件版本的安装目录。Claude Code会自动替换技能内容中的该变量。
install directory. Claude Code substitutes it anywhere in skill content.
- Cowork和技能目录安装:无固定路径。目录挂载在每次运行都会变化的会话根目录下,例如
- Cowork and skills-directory installs: no fixed path exists. The tree is
/sessions/<id>/mnt/.claude/skills/genjutsu/_jutsu。最后检测,因此上述两个环境仍能保持原有解析逻辑。
mounted under a session root that changes every run, e.g.
单包上传(genjutsu.zip)优先:子技能位于当前技能目录下,例如/mnt/skills/user/genjutsu/_jutsu/<name>/。
/sessions/<id>/mnt/.claude/skills/genjutsu/_jutsu. Probed last, so the two
当无固定路径时,探测已挂载的_jutsu目录。故意限制范围:
environments above keep resolving exactly as they did before.
每个根目录要么层级浅,要么有深度限制,因此不会遍历整个磁盘。
Single-bundle upload (genjutsu.zip) first: sub-skills live under this skill's
—
own dir, e.g. /mnt/skills/user/genjutsu/_jutsu/<name>/.
—
Probe for a mounted _jutsu when no fixed path applies. Bounded on purpose:
—
every root is either shallow or depth-capped, so this never walks the disk.
—
genjutsu_probe_jutsu() {
probe_hit=""
Walk up from the working directory first: cheapest, and correct whenever
the session root is an ancestor of wherever the pipeline is running. Hard
bounded, and the case guard catches "." and "": an empty or relative PWD
would otherwise never reach "/" and the loop would spin forever.
probe_dir="${PWD:-$(pwd)}"
probe_n=0
while [ "$probe_n" -lt 24 ]; do
probe_n=$((probe_n + 1))
probe_hit="$(find "$probe_dir/.claude/skills" -maxdepth 2 -type d -name _jutsu 2>/dev/null | head -1)"
[ -n "$probe_hit" ] && { printf '%s\n' "$probe_hit"; return 0; }
case "$probe_dir" in /|.|"") break ;; esac
probe_dir="$(dirname "$probe_dir")"
done
Then the fixed roots. A skills directory holds _jutsu two levels down, so
that is all they get: no reason to traverse a populated one any deeper.
for probe_root in "$HOME/.claude/skills" /mnt/.claude/skills; do
[ -d "$probe_root" ] || continue
probe_hit="$(find "$probe_root" -maxdepth 2 -type d -name _jutsu 2>/dev/null | head -1)"
[ -n "$probe_hit" ] && { printf '%s\n' "$probe_hit"; return 0; }
done
A session root is the one layout that needs more, for the session id and
its mnt/ wrapper. Still capped, and skipped entirely when absent.
if [ -d /sessions ]; then
probe_hit="$(find /sessions -maxdepth 8 -type d -path '/.claude/skills//_jutsu' 2>/dev/null | head -1)"
[ -n "$probe_hit" ] && { printf '%s\n' "$probe_hit"; return 0; }
fi
return 1
}
BUNDLE_JUTSU="$(find /mnt/skills/user -maxdepth 2 -type d -name _jutsu 2>/dev/null | head -1)"
if [ -n "$BUNDLE_JUTSU" ]; then
claude.ai - single self-contained genjutsu bundle
SKILL_BASE="$BUNDLE_JUTSU"
elif [ -d "/mnt/skills/user" ]; then
claude.ai - each sub-skill is its own uploaded skill (detect the mount, not
one specific sub-skill, so a partial upload still resolves the base).
SKILL_BASE="/mnt/skills/user"
else
Claude Code plugin
SKILL_BASE="${CLAUDE_PLUGIN_ROOT}/skills/_jutsu"
Fallback if the placeholder was not substituted: newest installed version.
Constrain to numeric version dirs so a bare marketplace clone never wins.
if [ ! -d "$SKILL_BASE" ]; then
SKILL_BASE=$(find ~/.claude/plugins/cache -type d -path '/genjutsu/[0-9]/skills/_jutsu' 2>/dev/null | sort -V | tail -1)
fi
Cowork / skills-directory install: session-rooted mount, nothing fixed to
match, so probe for it only once the two fixed layouts have both missed.
if [ -z "$SKILL_BASE" ] || [ ! -d "$SKILL_BASE" ]; then
SKILL_BASE="$(genjutsu_probe_jutsu)"
fi
fi
genjutsu_probe_jutsu() {
probe_hit=""
先从工作目录向上遍历:成本最低,且当会话根目录是流程运行目录的祖先时有效。
故意限制次数,且case判断会捕获"."和"":空或相对路径的PWD永远不会到达"/",避免无限循环。
probe_dir="${PWD:-$(pwd)}"
probe_n=0
while [ "$probe_n" -lt 24 ]; do
probe_n=$((probe_n + 1))
probe_hit="$(find "$probe_dir/.claude/skills" -maxdepth 2 -type d -name _jutsu 2>/dev/null | head -1)"
[ -n "$probe_hit" ] && { printf '%s
' "$probe_hit"; return 0; } case "$probe_dir" in /|.|"") break ;; esac probe_dir="$(dirname "$probe_dir")" done
' "$probe_hit"; return 0; } case "$probe_dir" in /|.|"") break ;; esac probe_dir="$(dirname "$probe_dir")" done
然后检测固定根目录。技能目录中_jutsu位于两层深度,因此无需更深遍历。
for probe_root in "$HOME/.claude/skills" /mnt/.claude/skills; do
[ -d "$probe_root" ] || continue
probe_hit="$(find "$probe_root" -maxdepth 2 -type d -name _jutsu 2>/dev/null | head -1)"
[ -n "$probe_hit" ] && { printf '%s
' "$probe_hit"; return 0; } done
' "$probe_hit"; return 0; } done
会话根目录需要更多检测,因为包含会话ID和mnt/包装器。仍有深度限制,不存在时完全跳过。
if [ -d /sessions ]; then
probe_hit="$(find /sessions -maxdepth 8 -type d -path '/.claude/skills//_jutsu' 2>/dev/null | head -1)"
[ -n "$probe_hit" ] && { printf '%s
' "$probe_hit"; return 0; } fi return 1 }
' "$probe_hit"; return 0; } fi return 1 }
BUNDLE_JUTSU="$(find /mnt/skills/user -maxdepth 2 -type d -name _jutsu 2>/dev/null | head -1)"
if [ -n "$BUNDLE_JUTSU" ]; then
claude.ai - 独立完整的genjutsu包
SKILL_BASE="$BUNDLE_JUTSU"
elif [ -d "/mnt/skills/user" ]; then
claude.ai - 每个子技能都是单独上传的技能(检测挂载目录而非特定子技能,因此部分上传仍能解析基础路径)。
SKILL_BASE="/mnt/skills/user"
else
Claude Code插件
SKILL_BASE="${CLAUDE_PLUGIN_ROOT}/skills/_jutsu"
若占位符未被替换,则回退到最新安装版本。
限制为数字版本目录,避免未发布的仓库克隆被选中。
if [ ! -d "$SKILL_BASE" ]; then
SKILL_BASE=$(find ~/.claude/plugins/cache -type d -path '/genjutsu/[0-9]/skills/_jutsu' 2>/dev/null | sort -V | tail -1)
fi
Cowork / 技能目录安装:基于会话的挂载,无固定路径,因此仅在上述两个固定布局都匹配失败时才探测。
if [ -z "$SKILL_BASE" ] || [ ! -d "$SKILL_BASE" ]; then
SKILL_BASE="$(genjutsu_probe_jutsu)"
fi
fi
Abort clearly instead of cat-ing bogus paths if resolution failed. Name every
若解析失败,清晰提示而非输出无效路径。列出所有尝试过的根目录,以便报告新的宿主布局而非猜测。
root that was tried, so a new host layout can be reported instead of guessed.
—
if [ -z "$SKILL_BASE" ] || [ ! -d "$SKILL_BASE" ]; then
echo "genjutsu: could not resolve the sub-skills directory." >&2
echo " claude.ai - upload the genjutsu skill ZIP(s) via Customize > Skills." >&2
echo " Claude Code - reinstall the plugin, then run /reload-plugins." >&2
echo " Cowork - expected a _jutsu directory under a */.claude/skills/<name>/ mount." >&2
echo " Tried: /mnt/skills/user, $CLAUDE_PLUGIN_ROOT, ~/.claude/plugins/cache," >&2
echo " $PWD ancestors, ~/.claude/skills, /mnt/.claude/skills, /sessions." >&2
fi
if [ -z "$SKILL_BASE" ] || [ ! -d "$SKILL_BASE" ]; then
echo "genjutsu: 无法解析子技能目录。" >&2
echo " claude.ai - 通过Customize > Skills上传genjutsu技能ZIP包。" >&2
echo " Claude Code - 重新安装插件,然后运行/reload-plugins。" >&2
echo " Cowork - 期望在*/.claude/skills/<name>/挂载目录下找到_jutsu目录。" >&2
echo " 已尝试:/mnt/skills/user, \$CLAUDE_PLUGIN_ROOT, ~/.claude/plugins/cache," >&2
echo " \$PWD上级目录, ~/.claude/skills, /mnt/.claude/skills, /sessions。" >&2
fi
Load a sub-skill, warning (not failing) if its ZIP was not uploaded / is missing.
加载子技能,若子技能ZIP未上传/缺失则警告(而非失败)。
The entry filename depends on the artifact, not on the host: a plugin install
入口文件名取决于工件而非宿主:插件安装包含SKILL.md,而claude.ai包在打包时会将内部文件重命名为GUIDE.md。
ships SKILL.md, while the claude.ai bundle renames every inner one to GUIDE.md
两者都可能挂载到Cowork会话根目录下,因此需尝试两种文件名。故意拆分名称——完整拼写会被打包步骤重写,导致回退失效。
at packaging time. Either can end up mounted under a Cowork session root, so
—
try both. The name is assembled from parts on purpose - spelled out in full it
—
would be rewritten by the same packaging step, defeating the fallback.
—
load_skill() {
for jutsu_doc in SKILL GUIDE; do
if [ -f "$SKILL_BASE/$1/$jutsu_doc.md" ]; then
cat "$SKILL_BASE/$1/$jutsu_doc.md"
return 0
fi
done
echo "genjutsu: sub-skill '$1' not found - upload its ZIP (claude.ai) or reinstall the plugin; continuing without it." >&2
}
<!-- genjutsu:shared:skill-base:end -->
All sub-skills are loaded via `load_skill <name>` (defined above), which cat's `$SKILL_BASE/<name>/SKILL.md` and warns instead of failing if a sub-skill was not uploaded.
---load_skill() {
for jutsu_doc in SKILL GUIDE; do
if [ -f "$SKILL_BASE/$1/$jutsu_doc.md" ]; then
cat "$SKILL_BASE/$1/$jutsu_doc.md"
return 0
fi
done
echo "genjutsu: 未找到子技能'$1' - 上传其ZIP包(claude.ai)或重新安装插件;将继续执行但不使用该子技能。" >&2
}
<!-- genjutsu:shared:skill-base:end -->
所有子技能通过`load_skill <name>`(如上定义)加载,该命令会输出`$SKILL_BASE/<name>/SKILL.md`内容,若子技能未上传则发出警告而非失败。
---Pipeline
流程阶段
Phase 1 — BRAINSTORM (mandatory, never skip)
阶段1——头脑风暴(必填,不可跳过)
This is the foundation. Rush it and everything downstream is wrong. The goal: understand the user's vision well enough to write two theses they'd agree with without hesitation.
这是整个流程的基础。仓促完成会导致后续所有工作出错。目标:充分理解用户愿景,能够写出用户会毫不犹豫认可的两个核心方向。
Stack scan (run before brainstorm)
技术栈扫描(头脑风暴前执行)
Before asking the user about tech stack, scan the project to detect what's already there:
<!-- genjutsu:shared:scan:start -->
bash
undefined在询问用户技术栈之前,先扫描项目检测已有技术栈:
<!-- genjutsu:shared:scan:start -->
bash
undefined1. Web (existing)
1. Web(已有项目)
cat package.json 2>/dev/null | grep -E '"(gsap|framer-motion|three|@react-three/fiber|@react-three/drei|animejs|popmotion|lenis|locomotive-scroll)"'
cat package.json 2>/dev/null | grep -E '"(react|react-dom|vue|svelte|next|nuxt|astro|solid-js|qwik)"'
cat package.json 2>/dev/null | grep -E '"(tailwindcss|styled-components|@emotion|sass|less|vanilla-extract|panda)"'
cat package.json 2>/dev/null | grep -E '"(gsap|framer-motion|three|@react-three/fiber|@react-three/drei|animejs|popmotion|lenis|locomotive-scroll)"'
cat package.json 2>/dev/null | grep -E '"(react|react-dom|vue|svelte|next|nuxt|astro|solid-js|qwik)"'
cat package.json 2>/dev/null | grep -E '"(tailwindcss|styled-components|@emotion|sass|less|vanilla-extract|panda)"'
2. Android / Compose
2. Android / Compose
ls build.gradle.kts build.gradle settings.gradle.kts settings.gradle 2>/dev/null
grep -rE 'androidx.compose|implementation("androidx.compose' build.gradle* settings.gradle* 2>/dev/null
ls build.gradle.kts build.gradle settings.gradle.kts settings.gradle 2>/dev/null
grep -rE 'androidx\.compose|implementation\("androidx\.compose' build.gradle* settings.gradle* 2>/dev/null
3. Compose Multiplatform / KMP
3. Compose Multiplatform / KMP
grep -rE 'org.jetbrains.compose|kotlin("multiplatform")|id("org.jetbrains.kotlin.multiplatform")' build.gradle* settings.gradle* 2>/dev/null
grep -rE 'org\.jetbrains\.compose|kotlin\("multiplatform"\)|id\("org\.jetbrains\.kotlin\.multiplatform"\)' build.gradle* settings.gradle* 2>/dev/null
4. Apple / SwiftUI
4. Apple / SwiftUI
ls *.xcodeproj *.xcworkspace Package.swift 2>/dev/null
grep -lE 'import SwiftUI|@main.App' --include=".swift" -r . 2>/dev/null | head -1
ls *.xcodeproj *.xcworkspace Package.swift 2>/dev/null
grep -lE 'import SwiftUI|@main.App' --include=".swift" -r . 2>/dev/null | head -1
5. Apple platform sub-detection (iOS vs macOS)
5. Apple平台细分检测(iOS vs macOS)
grep -E '.iOS(|.macOS(' Package.swift 2>/dev/null
grep -E 'SDKROOT = (iphoneos|macosx)' *.xcodeproj/project.pbxproj 2>/dev/null
grep -E '\.iOS\(|\.macOS\(' Package.swift 2>/dev/null
grep -E 'SDKROOT = (iphoneos|macosx)' *.xcodeproj/project.pbxproj 2>/dev/null
6. Mobile web indicators
6. 移动Web标识
grep -rE 'viewport.width=device-width|@media.pointer:\scoarse|@media.max-width' --include='.html' --include='.css' --include='*.scss' . 2>/dev/null | head -3
ls public/manifest.json public/sw.js 2>/dev/null
grep -rE 'viewport.width=device-width|@media.pointer:\scoarse|@media.max-width' --include='.html' --include='.css' --include='*.scss' . 2>/dev/null | head -3
ls public/manifest.json public/sw.js 2>/dev/null
7. Legacy bridge indicators (mention in DISCOVER, do not auto-load)
7. 遗留桥接标识(仅在DISCOVER中提及,不自动加载)
ls -- .xib .storyboard 2>/dev/null
find . -path '/res/layout/.xml' 2>/dev/null | head -1
grep -rE 'setContentView(R.layout' --include='.kt' --include='.java' . 2>/dev/null | head -1
Map the results:
- **Animation lib**: gsap, framer-motion, three/@react-three, anime.js, or none
- **Framework**: React, Vue, Svelte, Next.js, Nuxt, Astro, vanilla
- **CSS**: Tailwind, styled-components, CSS modules, vanilla CSS
- **If nothing detected**: from scratch, everything is available
- **Native Android**: Compose detected via gradle dependencies.
- **Native Apple**: SwiftUI detected via Package.swift / xcodeproj + swift files. Distinguish iOS vs macOS via Package.swift platforms or pbxproj SDKROOT.
- **Compose Multiplatform**: kotlin-multiplatform plugin + jetbrains.compose plugin.
- **Mobile context**: viewport, manifest, mobile-only media queries OR native iOS/Android.
- **Desktop context**: macOS target OR no mobile indicators on web.
- **Legacy mixed**: presence of `.xib`, `.storyboard`, layout XML, `setContentView(R.layout.*)`. Mention only, no auto-load.
<!-- genjutsu:shared:scan:end -->
**If legacy mixed detected** (XIB / storyboard / layout XML / setContentView(R.layout.\*)):
Ask exactly one question during brainstorm:
> "I see your project mixes [XML layouts / XIBs / classic Activities] with modern UI. For this task, should I stay on pure [Compose/SwiftUI], or integrate into a legacy screen?"
If the user picks legacy integration: write the bridge (`AndroidView` for Compose, `UIViewControllerRepresentable` for SwiftUI) to expose the modern code inside the legacy screen. Never generate new legacy code (no XML, no XIB, no setContentView).
**The five domains to cover:**
1. **Product** — What is it? (app, landing page, portfolio, SaaS, e-commerce, blog, dashboard...)
2. **Audience** — Who uses it? (devs, designers, general public, enterprise, kids, luxury...)
3. **Mood** — 3 to 5 adjectives that define the visual feel
4. **References** — Sites, screenshots, mood boards, anything visual
5. **Tech stack** — What's already in place? Or starting from scratch?
**How to ask:** One question at a time, starting with the least obvious domain. If you already know the tech stack from scanning `package.json`, don't ask — start with mood or audience instead. Each answer reshapes how you ask the next question.
**How to handle vague answers:**
When the user says "modern" or "clean" or "I don't know, just make it nice":
1. **Validate** — "That's a starting point. Let's make it precise."
2. **Offer concrete options** — "Clean like Stripe's editorial whitespace, clean like Linear's dense-but-organized, or clean like Apple's dramatic minimalism?"
3. **Reframe** — "What would feel *wrong*? What sites make you cringe? That's just as useful."
4. **Name the consequence** — "This choice drives the entire color palette and typography. Worth spending a minute on."
**Never** interpret a vague answer as confirmation. "Yeah something like that" means dig deeper — ask which part of "that" resonates.
**When the user pushes to skip or rush brainstorm:**
Do NOT capitulate. Instead:
> "We've covered [covered areas]. I'm still missing [missing areas], which will directly impact [concrete consequence]. Want me to ask one more question, or would you rather I make assumptions and you correct them afterward?"
This gives them an informed choice. If they choose assumptions, name each assumption explicitly in the thesis.
**Never** negotiate the number of remaining questions ("just two more, I promise"). You don't know how many you need until you hear the answers.
**When to stop:** When you can write both theses (visual + interaction) and you'd bet money the user will say "oui parfait." If you'd be guessing on even one aspect, keep asking.
---ls -- .xib .storyboard 2>/dev/null
find . -path '/res/layout/.xml' 2>/dev/null | head -1
grep -rE 'setContentView\(R\.layout' --include='.kt' --include='.java' . 2>/dev/null | head -1
映射扫描结果:
- **动画库**: gsap、framer-motion、three/@react-three、anime.js,或无
- **框架**: React、Vue、Svelte、Next.js、Nuxt、Astro、原生JS
- **CSS方案**: Tailwind、styled-components、CSS Modules、原生CSS
- **未检测到任何内容**: 从零开始,所有技术都可用
- **原生Android**: 通过gradle依赖检测到Compose
- **原生Apple**: 通过Package.swift / xcodeproj + swift文件检测到SwiftUI。通过Package.swift平台或pbxproj SDKROOT区分iOS vs macOS。
- **Compose Multiplatform**: kotlin-multiplatform插件 + jetbrains.compose插件
- **移动环境**: viewport、manifest、移动端专属媒体查询 或 原生iOS/Android
- **桌面环境**: macOS目标 或 Web项目无移动标识
- **混合遗留代码**: 存在`.xib`、`.storyboard`、布局XML、`setContentView(R.layout.*)`。仅提及,不自动加载。
<!-- genjutsu:shared:scan:end -->
**若检测到混合遗留代码**(XIB / storyboard / 布局XML / setContentView(R.layout.*)):
头脑风暴时仅问以下一个问题:
> "我发现您的项目混合了[XML布局 / XIB / 传统Activities]与现代UI。本次任务中,我应仅使用纯[Compose/SwiftUI],还是集成到遗留页面中?"
若用户选择集成到遗留页面:编写桥接代码(Compose使用`AndroidView`,SwiftUI使用`UIViewControllerRepresentable`)在遗留页面中嵌入现代代码。绝不生成新的遗留代码(无XML、无XIB、无setContentView)。
**需覆盖的五个领域:**
1. **产品定位** — 这是什么?(应用、着陆页、作品集、SaaS、电商、博客、仪表盘...)
2. **目标受众** — 谁会使用它?(开发者、设计师、普通大众、企业客户、儿童、高端用户...)
3. **情绪风格** — 3-5个描述视觉感受的形容词
4. **参考案例** — 网站、截图、情绪板等任何视觉参考
5. **技术栈** — 已有哪些技术?还是从零开始?
**提问方式:** 一次只问一个问题,从最不明确的领域开始。若已通过扫描`package.json`了解技术栈,则无需提问——从情绪风格或目标受众开始。每个答案会影响下一个问题的提问方式。
**处理模糊答案:**
当用户说“现代”、“简洁”或“我不知道,弄好看点就行”时:
1. **确认** — "这是个起点,我们来让它更具体。"
2. **提供具体选项** — "简洁是指Stripe那种排版留白,Linear那种紧凑但有条理,还是Apple那种极致极简?"
3. **重新表述** — "什么样的风格会让您觉得不合适?哪些网站会让您反感?这同样有价值。"
4. **说明影响** — "这个选择会决定整个调色板和排版方案,值得花一分钟确认。"
**绝不**将模糊答案视为确认。“差不多这样”意味着需要进一步挖掘——询问用户“这样”的哪部分更符合预期。
**当用户要求跳过或仓促完成头脑风暴时:**
绝不妥协。而是:
> "我们已经讨论了[已覆盖领域]。我仍缺少[未覆盖领域],这会直接影响[具体后果]。您希望我再问一个问题,还是让我先做假设之后您再纠正?"
这给用户提供了知情选择。若用户选择假设,则在方向中明确列出每个假设。
**绝不**协商剩余问题数量(“就再问两个,我保证”)。在得到答案前,你不知道需要多少个问题。
**停止时机:** 当你能够写出两个核心方向(视觉+交互),并且确定用户会说“完全正确”时。若对任何一个方面仍有猜测,则继续提问。
---Phase 2 — THESIS (define direction, get validation)
阶段2——方向确认(定义方向,获得验证)
From the brainstorm, produce two theses:
从头脑风暴结果中生成两个核心方向:
Visual Thesis
视觉方向
A single sentence that captures the entire visual identity. Must explicitly address all four:
- Color direction — dark/light, palette family, accent color
- Typography spirit — serif/sans/mono, weight usage, size contrast
- Spacing philosophy — dense/airy, base unit feel
- Component style — rounded/sharp, bordered/filled, elevated/flat
Example: "Dark neo-brutalist interface with bold monospace type, fluorescent chartreuse accents, generous whitespace, raw-edged components with offset shadows."
Self-check: read your thesis back. If any of the four areas is missing or vague ("nice typography"), rewrite it before presenting.
一句话概括整个视觉标识。必须明确涵盖以下四点:
- 色彩方向 — 深色/浅色、调色板风格、强调色
- 排版风格 — 衬线/无衬线/等宽字体、字重使用、尺寸对比
- 间距理念 — 紧凑/宽松、基础单位感受
- 组件样式 — 圆角/尖锐、边框/填充、悬浮/扁平化
示例:“深色新粗野主义界面,搭配粗体等宽字体、荧光绿强调色、充足留白、带有偏移阴影的原生质感组件。”
自我检查: 通读你的方向描述。若上述四个领域有任何缺失或模糊(如“好看的排版”),则在呈现前重写。
Interaction Thesis
交互方向
A single sentence that captures the motion and interaction language. Must explicitly address all four:
- Timing range — fast (100-200ms), medium (200-400ms), or slow (400ms+)
- Hover behavior — what happens on hover
- Scroll behavior — reveals, parallax, or nothing
- Forbidden patterns — what this project will NOT do
Example: "Fast and dry transitions (100-200ms), hover with subtle scale (1.02), scroll-triggered reveals with stagger, no bounce or elastic — all sharp ease-out."
Cross-platform thesis examples:
- "This Compose hero will use a SharedTransitionLayout with a spring(stiffness=Spring.StiffnessMedium, dampingRatio=0.85) for a fluid card-to-detail transition."
- "This SwiftUI tab transition will use matchedGeometryEffect with a .smooth spring (response: 0.5, dampingFraction: 0.85) for a tactile, spatial feel."
- "This macOS dashboard will use 100ms opacity hover states (no scale on hover, desktop subtlety) and a Cmd+1-9 keyboard shortcut to navigate panels."
- "This Android header will use an AGSL shader bound to scrollOffset for a dynamic liquid-glass effect (Android 13+, with a static fallback below)."
Self-check: read your thesis back. If you can't immediately derive the CSS/JS properties from it, it's too vague. Rewrite.
This is the first visual gate. Offer the preview menu (see "Showing Your Work" above), then present both theses in the chosen mode. The visual thesis in particular is worth far more shown than described - "fluorescent chartreuse accents" is a guess until it sits next to the neutrals.
Wait for explicit user validation of BOTH theses before moving on. If the user pushes back, don't start over — ask what feels wrong and adjust.
一句话概括动效和交互语言。必须明确涵盖以下四点:
- 时长范围 — 快速(100-200ms)、中等(200-400ms)或缓慢(400ms+)
- Hover行为 — 鼠标悬停时的效果
- 滚动行为 — 内容展示、视差滚动,或无
- 禁用模式 — 本项目绝不会使用的交互模式
示例:“快速干脆的过渡(100-200ms),hover时轻微缩放(1.02),滚动触发的渐显效果并带有 stagger,无弹跳或弹性效果——全部使用锐利的ease-out缓动曲线。”
跨平台方向示例:
- "这个Compose核心组件将使用SharedTransitionLayout,搭配spring(stiffness=Spring.StiffnessMedium, dampingRatio=0.85)实现流畅的卡片到详情页过渡。"
- "这个SwiftUI标签切换将使用matchedGeometryEffect,搭配.smooth弹簧(response: 0.5, dampingFraction: 0.85)实现触觉化空间感。"
- "这个macOS仪表盘将使用100ms透明度hover效果(桌面端保持简洁,无缩放),并支持Cmd+1-9快捷键切换面板。"
- "这个Android头部将使用AGSL着色器绑定scrollOffset实现动态液态玻璃效果(Android 13+,低版本提供静态 fallback)。"
自我检查: 通读你的方向描述。若无法直接从中推导出CSS/JS属性,则说明描述过于模糊。需重写。
这是第一个视觉验证节点。提供预览选项菜单(见上文“成果展示”),然后以用户选择的模式呈现两个核心方向。视觉方向尤其需要展示而非描述——“荧光绿强调色”在未与中性色搭配展示前只是猜测。
等待用户明确验证两个方向后再推进。若用户提出异议,无需从头开始——询问用户哪里不合适并调整。
Phase 3 — DESIGN SYSTEM
阶段3——设计系统
Load sub-skill:
_jutsu/ui-ux-pro-maxbash
cat "$SKILL_BASE/ui-ux-pro-max/SKILL.md"加载子技能:
_jutsu/ui-ux-pro-maxbash
cat "$SKILL_BASE/ui-ux-pro-max/SKILL.md"Stack-aware token generation
适配技术栈的令牌生成
The MASTER.md design system file is canonical, but the generated code files match the detected stack:
- Web stack detected: generate Tailwind config / CSS variables (existing format). Tokens in CSS hex, easings,
cubic-bezier(...)spacing. Output paired withremextension ortailwind.config.jsCSS.:root { --token: ... } - Android Compose stack detected: generate Kotlin design tokens. Output ,
Theme.kt,Color.kt,Type.kt,Shapes.ktreferenced from MASTER.md. Color tokens inMotion.kt, typography inColor(0xFF...), shapes inTextStyle, motion inRoundedCornerShape(M3 Expressive when scope is hero / impactful). Spacing inMotionScheme.dp - SwiftUI stack detected (iOS / macOS / multi-target): generate Swift extensions. Output ,
Color+App.swift,Font+App.swift,Animation+App.swift. Color tokens viaShape+App.swiftreferencing the asset catalog (orColor("AssetName")if no catalog), typography viaColor(red:green:blue:)orFont.system(...), animations via.custom(...)/.spring(...)/.snappynamed presets. Spacing in.bouncyconstants.CGFloat - Compose Multiplatform stack detected: generate Kotlin tokens in with
commonMainfor fonts and platform-specific colors. Same structure as Android Compose, plus a section in MASTER.md describing per-platform deviations.expect/actual - Multi-stack project (e.g., web admin + native mobile app): generate MASTER.md with clearly delimited sections for each stack, and produce code files for each.
The MASTER.md document itself remains a single canonical source-of-truth file. The generated code files (Theme.kt / Color+App.swift / etc.) are children of MASTER.md and reference it.
Generate the complete design system based on both theses:
- Color palette — Primary, secondary, accent, neutrals, semantic (success/warning/error/info). Light + dark if needed.
- Typography — Font stack, size scale (fluid or fixed), weight usage, line-height rules.
- Spacing — Base unit, scale (4px, 8px, 12px, 16px, 24px, 32px, 48px, 64px...).
- Radii — Border radius scale (none, sm, md, lg, full).
- Shadows — Elevation levels (0-4), consistent with visual thesis.
- Base components — Button, input, card, badge, link — styled per the theses.
- Motion tokens — Duration scale (fast/normal/slow), easing names, stagger delay.
MASTER.md设计系统文件是权威来源,但生成的代码文件需匹配检测到的技术栈:
- 检测到Web技术栈: 生成Tailwind配置/CSS变量(匹配现有格式)。令牌使用CSS十六进制值、缓动曲线、
cubic-bezier(...)单位。输出搭配rem扩展或tailwind.config.jsCSS文件。:root { --token: ... } - 检测到Android Compose技术栈: 生成Kotlin设计令牌。输出、
Theme.kt、Color.kt、Type.kt、Shapes.kt,均引用MASTER.md。颜色令牌使用Motion.kt,排版使用Color(0xFF...),形状使用TextStyle,动效使用RoundedCornerShape(当范围为核心组件/高视觉影响时使用M3 Expressive)。间距使用MotionScheme单位。dp - 检测到SwiftUI技术栈(iOS / macOS / 多目标): 生成Swift扩展。输出、
Color+App.swift、Font+App.swift、Animation+App.swift。颜色令牌通过Shape+App.swift引用资源目录(若无目录则使用Color("AssetName")),排版使用Color(red:green:blue:)或Font.system(...),动画使用.custom(...)/.spring(...)/.snappy命名预设。间距使用.bouncy常量。CGFloat - 检测到Compose Multiplatform技术栈: 在中生成Kotlin令牌,使用
commonMain处理字体和平台特定颜色。结构与Android Compose相同,MASTER.md中增加平台差异说明部分。expect/actual - 多技术栈项目(如Web后台 + 原生移动应用): 生成带有清晰分栏的MASTER.md,涵盖每个技术栈,并为每个技术栈生成代码文件。
MASTER.md文档本身始终是单一权威来源。生成的代码文件(Theme.kt / Color+App.swift等)是MASTER.md的衍生文件并引用它。
基于两个核心方向生成完整设计系统:
- 调色板 — 主色、辅助色、强调色、中性色、语义色(成功/警告/错误/信息)。根据需要生成亮色+暗色模式。
- 排版 — 字体栈、尺寸层级(流式或固定)、字重使用、行高规则。
- 间距 — 基础单位、尺寸层级(4px、8px、12px、16px、24px、32px、48px、64px...)。
- 圆角 — 边框圆角层级(无、sm、md、lg、全圆角)。
- 阴影 — elevation层级(0-4),与视觉方向一致。
- 基础组件 — 按钮、输入框、卡片、徽章、链接——根据方向设置样式。
- 动效令牌 — 时长层级(快速/正常/缓慢)、缓动曲线名称、stagger延迟。
MASTER.md
MASTER.md
Create a at project root with the full design system. This file is the single source of truth. Every implementation decision references it.
MASTER.md在项目根目录创建,包含完整设计系统。该文件是唯一权威来源,所有实现决策均需引用它。
MASTER.mdMCP Tools (if available)
MCP工具(若可用)
Check if these MCPs are connected and use them when available:
- Stitch — Generate mockups/wireframes
- Nano Banana — Generate visual assets (illustrations, icons, backgrounds)
- 21st.dev Magic — Generate UI components from descriptions
If MCPs are not available, skip gracefully — the design system + code implementation is the core path.
检查是否连接以下MCP工具并在可用时使用:
- Stitch — 生成原型/线框图
- Nano Banana — 生成视觉资产(插画、图标、背景)
- 21st.dev Magic — 根据描述生成UI组件
若MCP工具不可用,则优雅跳过——设计系统+代码实现是核心流程。
Show it before Phase 4
阶段4前展示设计系统
Present the design system in the session's preview mode - announce the mode in one line, don't reopen the menu - and get validation before implementing anything. A palette and a type scale listed as hex codes and pixel values in a transcript are precise and completely unreviewable; every token in MASTER.md is about to be applied everywhere, so this is the cheapest place to catch a wrong one.
以会话的预览模式呈现设计系统——用一句话说明模式,不重新打开菜单——并在实现前获得用户验证。仅在对话中列出十六进制颜色值和像素尺寸的调色板和字体层级虽然精确,但完全无法有效审核;MASTER.md中的每个令牌都将应用到所有地方,因此这是发现错误的最低成本环节。
Phase 4 — IMPLEMENT
阶段4——落地实现
Load sub-skills based on tech stack and interaction thesis.
Always load (load every sub-skill below via , defined above - it warns instead of failing silently if a ZIP is missing):
load_skill <name>- - the foundation
load_skill motion-principles
Context layers (load when applicable):
| Detected | Load |
|---|---|
| Mobile context (web mobile OR native iOS / Android) | |
| Desktop context (macOS OR web desktop with no mobile indicators) | |
| Audit explicitly requested OR scope=full | |
| Advanced UI/UX questions | |
Stack-specific (load by SCAN):
| Detected stack | Sub-skill to load |
|---|---|
| gsap | |
| framer-motion | |
| Pure CSS / Tailwind / no lib | |
| three / @react-three | |
| Canvas / generative | |
| Android Compose | |
| Compose Multiplatform | |
| SwiftUI iOS or macOS | |
"Advanced thesis" trigger for / :
compose-graphicsswiftui-graphicsThe thesis is "advanced" (and triggers loading the graphics sub-skill) if it contains any of these terms:
- ,
shader,Metal,AGSL,RuntimeShaderMSL - ,
liquid-glass,glassEffectmorphing transition - ,
M3 Expressive,MotionSchemeexpressive motion - ,
colorEffect,distortionEffectlayerEffect - (with generative / particle / flow field context)
Canvas - ,
holographic,CRT,displacementripple
Otherwise stick to the base motion sub-skill.
<!-- genjutsu:shared:load:end -->
Implementation rules:
- Work page by page or component by component — never try to do everything at once.
- Every color, font, spacing, shadow, radius MUST come from MASTER.md tokens. No magic numbers.
- Every animation MUST respect the interaction thesis (timing, easing, forbidden patterns).
- Apply the 5-state rule for interactive elements: default, hover, focus, active, disabled.
- Ask the user for validation after each major page/section before moving to the next.
根据技术栈和交互方向加载子技能。
必须加载(通过上述定义的加载以下所有子技能——若ZIP缺失则发出警告而非静默失败):
load_skill <name>- - 动效基础
load_skill motion-principles
上下文层(按需加载):
| 检测到的环境 | 加载内容 |
|---|---|
| 移动环境(Web移动 或 原生iOS / Android) | |
| 桌面环境(macOS 或 Web桌面且无移动标识) | |
| 明确要求审计 或 范围=完整 | |
| 高级UI/UX问题 | |
技术栈专属(根据扫描结果加载):
| 检测到的技术栈 | 需加载的子技能 |
|---|---|
| gsap | |
| framer-motion | |
| 纯CSS / Tailwind / 无动画库 | |
| three / @react-three | |
| Canvas / 生成式设计 | |
| Android Compose | |
| Compose Multiplatform | |
| SwiftUI iOS或macOS | |
compose-graphicsswiftui-graphics若方向中包含以下任一术语,则视为“高级”(触发加载图形子技能):
- ,
shader,Metal,AGSL,RuntimeShaderMSL - ,
liquid-glass,glassEffectmorphing transition - ,
M3 Expressive,MotionSchemeexpressive motion - ,
colorEffect,distortionEffectlayerEffect - (带有生成式/粒子/流场上下文)
Canvas - ,
holographic,CRT,displacementripple
否则仅加载基础动效子技能。
<!-- genjutsu:shared:load:end -->
实现规则:
- 按页面或组件逐步推进 — 绝不试图一次性完成所有工作。
- 所有颜色、字体、间距、阴影、圆角必须来自MASTER.md令牌。不使用魔法数字。
- 所有动画必须遵循交互方向(时长、缓动曲线、禁用模式)。
- 交互元素应用5状态规则:默认、hover、focus、active、disabled。
- 完成每个主要页面/部分后,询问用户验证再推进到下一个。
Phase 5 — AUDIT (never skip)
阶段5——审计(不可跳过)
Load sub-skill:
_jutsu/design-auditbash
cat "$SKILL_BASE/design-audit/SKILL.md"Run the full audit checklist matching the detected stack.
All stacks:
- Reduced motion respected (CSS , SwiftUI
prefers-reduced-motion, or Compose helper usingaccessibilityReduceMotion/ValueAnimator.areAnimatorsEnabled()).Settings.Global.ANIMATOR_DURATION_SCALE - Exit animations present (no abrupt vanishings).
- No layout-property animations (animate transform / opacity / graphicsLayer instead).
- Focus visible on interactive elements.
- Interactive elements have all relevant states (default, hover/press, focus, active, disabled).
- Colors and spacing consistent with MASTER.md tokens - no rogue hex values.
Web:
- Conditional renders with AnimatePresence (or framework equivalent).
- Contrast ratio >= 4.5:1 for all text.
- No forced reflow, used sparingly.
will-change - 60fps target verified via Chrome DevTools Performance panel.
- No clickable divs without role/button.
- on purely decorative animations.
aria-hidden - Responsive on 4 breakpoints: 375px (mobile) / 768px (tablet) / 1024px (small desktop) / 1440px (large desktop).
Compose:
- Recomposition counts verified (Layout Inspector / ).
Modifier.recomposeHighlighter - No animations on /
width(useheight).Modifier.graphicsLayer { translationX/Y, scaleX/Y } - set on custom interactive components.
Modifier.semantics - Frame timing OK on a mid-range device (Pixel 4a baseline) via Macrobenchmark.
SwiftUI:
- No recomputed on irrelevant state changes (use
body,@StateObjectcorrectly).@ObservableObject - Hitches Instrument shows no dropped frames during animation.
- /
.accessibilityLabelon all interactive views..accessibilityHint - Tested with Reduce Motion ON and Dynamic Type at 200%.
macOS-specific (in addition to SwiftUI):
- Hover states present on every interactive element.
- Keyboard shortcuts (,
Cmd+N,Cmd+W, etc.) bound to primary actions.Cmd+F - Multi-window state shared coherently if applicable.
- Focus rings visible on keyboard navigation (no without alternative).
outline: none
Present findings grouped by severity: Critical > Important > Nice-to-have.
加载子技能:
_jutsu/design-auditbash
cat "$SKILL_BASE/design-audit/SKILL.md"运行与检测到的技术栈匹配的完整审计清单。
所有技术栈通用:
- 遵循简化动效设置(CSS 、SwiftUI
prefers-reduced-motion,或Compose使用accessibilityReduceMotion/ValueAnimator.areAnimatorsEnabled()的辅助工具)。Settings.Global.ANIMATOR_DURATION_SCALE - 存在退出动画(无突然消失效果)。
- 无布局属性动画(优先动画transform / opacity / graphicsLayer)。
- 交互元素可见焦点状态。
- 交互元素包含所有相关状态(默认、hover/按压、focus、active、disabled)。
- 颜色和间距与MASTER.md令牌一致——无无来源的十六进制值。
Web技术栈:
- 使用AnimatePresence(或框架等效工具)处理条件渲染。
- 所有文本对比度 >= 4.5:1。
- 无强制回流,谨慎使用。
will-change - 通过Chrome DevTools性能面板验证60fps帧率目标。
- 无未设置role/button的可点击div。
- 纯装饰性动画设置。
aria-hidden - 在4个断点响应式适配:375px(移动端)/ 768px(平板)/ 1024px(小桌面)/ 1440px(大桌面)。
Compose技术栈:
- 验证重组次数(Layout Inspector / )。
Modifier.recomposeHighlighter - 无/
width动画(使用height)。Modifier.graphicsLayer { translationX/Y, scaleX/Y } - 自定义交互组件设置。
Modifier.semantics - 通过Macrobenchmark验证中端设备(Pixel 4a基准)的帧时序正常。
SwiftUI技术栈:
- 无关状态变化时不重新计算(正确使用
body、@StateObject)。@ObservableObject - Hitches Instrument显示动画期间无丢帧。
- 所有交互视图设置/
.accessibilityLabel。.accessibilityHint - 在简化动效开启和动态字体200%状态下测试。
macOS专属(SwiftUI基础上增加):
- 每个交互元素都有hover状态。
- 主要操作绑定键盘快捷键(、
Cmd+N、Cmd+W等)。Cmd+F - 多窗口状态同步一致(若适用)。
- 键盘导航时可见焦点环(无替代方案)。
outline: none
按严重程度分组呈现结果:关键 > 重要 > 建议优化。
Existing Project Protocol
已有项目处理规则
When invoked on a project that already has design/styling:
- Still run the full BRAINSTORM (Phase 1)
- Acknowledge existing design, but the thesis overrides it
- In Phase 4, replace existing design tokens/styles with the new design system
- Preserve functionality and layout structure — only replace the visual layer
This is intentional: rebuilds the visual universe. To enhance what exists, use instead.
/genjutsu:paint/genjutsu:cast在已有设计/样式的项目中调用时:
- 仍需执行完整的头脑风暴(阶段1)
- 认可现有设计,但新方向将覆盖它
- 在阶段4,用新设计系统替换现有设计令牌/样式
- 保留功能和布局结构——仅替换视觉层
这是有意设计的:会重建视觉体系。若要增强现有设计,请使用。
/genjutsu:paint/genjutsu:castRed Flags — You're About to Violate This Skill
危险信号——你即将违反本技能规则
| Thought | Reality |
|---|---|
| "The user already said 'minimal dark' — I have enough for a thesis" | Two words aren't five domains. Keep asking. |
| "I'll ask all five brainstorm questions at once" | One at a time. The answer to 'audience' changes how you ask about 'mood'. |
| "The user seems impatient, let's skip to coding" | Use the pressure protocol. A bad thesis costs days, not minutes. |
| "I'll pick colors that feel right" | Every token comes from MASTER.md. No freelancing. |
| "I'll do the whole site in one pass" | Page by page. Validate page by page. |
| "This animation would be cool even though the thesis says no bounce" | The thesis is law. Change it? Re-validate with the user first. |
| "The audit can wait, the user seems happy" | The audit is not optional. Phase 5 always runs. |
| "I'll interpret 'yeah something like that' as a yes" | That's not confirmation. Ask which part resonates. |
| "I'll list the palette as hex codes, that's precise" | Precise and unreviewable. Show it in the session's preview mode. |
| "I'll ask again how they want to see the design system" | Asked once, sticks for the session. Announce the mode and go. |
| "The preview page looks good, I'll build the app from it" | The preview is throwaway. Build from MASTER.md. |
| 错误想法 | 实际情况 |
|---|---|
| "用户已经说'极简深色'——我有足够信息写方向了" | 两个词不足以覆盖五个领域。继续提问。 |
| "我一次性问完五个头脑风暴问题" | 一次只问一个。“目标受众”的答案会改变“情绪风格”的提问方式。 |
| "用户看起来不耐烦,直接开始编码吧" | 使用压力应对规则。错误的方向会浪费数天时间,而非几分钟。 |
| "我选看起来合适的颜色就行" | 所有令牌必须来自MASTER.md。绝不自行决定。 |
| "我一次性完成整个网站" | 按页面逐步推进。逐页验证。 |
| "这个动画很酷,即使方向说不能用弹跳效果" | 方向是准则。要修改?先获得用户重新验证。 |
| "用户看起来满意,审计可以跳过" | 审计不可省略。阶段5必须执行。 |
| "我把'差不多这样'视为认可" | 这不是确认。询问用户哪部分符合预期。 |
| "我列出调色板的十六进制值,这很精确" | 精确但无法审核。用会话的预览模式展示。 |
| "我再问一次用户希望如何查看设计系统" | 只问一次,会话中保持该模式。说明模式后直接展示。 |
| "预览页面看起来不错,我直接基于它构建应用" | 预览是临时内容。基于MASTER.md构建。 |
| ", |