一键导入
add-example
Create an example model for one or more block types. Handles model file construction, registration, unit + codegen tests, screenshots, and verification.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create an example model for one or more block types. Handles model file construction, registration, unit + codegen tests, screenshots, and verification.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Step-by-step guide for adding new block types. Use when the user asks to "add a block", "create a new block", or "implement a block".
Design guidelines for creating well-laid-out block diagrams and state charts. Use when building or reviewing model files.
Generate a project briefing: worktree status, open checkboxes, recent commits. Modes: summary (default), report, verify, current, worktrees. Period: 1h, 6h, 24h, 2d, 7d.
Post-PR-merge local normalization: fetch-and-prune origin, switch off merged feature branches, pull main, and delete local branches whose upstream is gone, whose PR has merged, or whose tip is fully contained in main (0 commits ahead). Preview by default — run `/cleanup-merged apply` to execute. `local` (default) / `remote` / `all` pick the scope; pass explicit branch names to narrow the candidate set. `--force` overrides the merged-check + unpushed guard for branches you explicitly name. Protected branches from config are NEVER deleted (even with `--force`) — they are always skipped.
Safe commit workflow with optional scope hint. Inventories all changes, classifies related vs. unrelated files, traces dependencies, protects other agents' work, and optionally pushes, lands worktree commits, or opens a PR via /land-pr. Positional auto enables auto-merge (PR mode only).
Create a git worktree for agent work. Thin wrapper around create-worktree.sh — owns prefix-derived path, optional --branch-name override, optional pre-flight prune+fetch+ff-merge, safe worktree-add, and sanitised .zskills-tracked / .worktreepurpose writes. Prints the worktree path on stdout.
| name | add-example |
| description | Create an example model for one or more block types. Handles model file construction, registration, unit + codegen tests, screenshots, and verification. |
| argument-hint | <block-type(s)> [concept hint] |
| metadata | {"version":"2026.06.03+820c28"} |
Create a complete example model that showcases one or more block types in a real-world context. This skill covers the full workflow from research through verification, distilled from real mistakes.
Arguments:
<block-type> — which block(s) the example must feature (comma-separated for batch)[concept hint] — optional real-world model concept (e.g., "PID temperature control")All implementation happens in a pre-created worktree. Before any
fulfillment-marker writes or model construction, front-run the shared
ensure-worktree.sh gate. When /add-example is dispatched FROM
/add-block, the helper's in-worktree gate returns empty + exits 0, so this
preamble is a no-op in that case; the parent's ZSKILLS_PATHS_ROOT is
preserved.
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
MAIN_ROOT=$(cd "$(git rev-parse --git-common-dir)/.." && pwd)
TOPLEVEL=$(git rev-parse --show-toplevel)
HELPER="$ZSKILLS_SKILLS_ROOT/create-worktree/scripts/ensure-worktree.sh"
if [ ! -x "$HELPER" ]; then
echo "add-example: ensure-worktree.sh missing at $HELPER — run /update-zskills to repair" >&2
exit 11
fi
WT_PATH=$(bash "$HELPER" \
--prefix add-example \
--pipeline-id "add-example.${NAME}" \
--purpose "add-example; name=${NAME}" \
"${NAME}")
RC=$?
if [ "$RC" -ne 0 ]; then
echo "ensure-worktree failed (rc=$RC) for /add-example" >&2
exit "$RC"
fi
if [ -n "$WT_PATH" ]; then
cd "$WT_PATH" || { echo "add-example: cd $WT_PATH failed" >&2; exit 1; }
export ZSKILLS_PATHS_ROOT="$WT_PATH" # R3-1 — re-anchor downstream path resolution
fi
On entry, resolve PIPELINE_ID and NAME_SLUG, then create the
fulfillment marker so the parent skill (e.g., /add-block) knows this
delegation was accepted. add-example may run as a sub-skill (delegated
from /add-block) OR standalone (/add-example is registered as a
top-level slash command — see frontmatter and block-diagram/README.md).
Resolution is therefore 3-tier with a synthesized fallback so direct
invocation works. In delegated mode, tier-2 .zskills-tracked always
fires (the parent's worktree wrote it), so the synthesized fallback never
triggers and markers correctly land in the parent's subdir.
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
MAIN_ROOT=$(cd "$(git rev-parse --git-common-dir)/.." && pwd)
# 3-tier PIPELINE_ID resolution: env → worktree .zskills-tracked
# (parent's PIPELINE_ID, written by add-block's ensure-worktree.sh
# --pipeline-id call) → synthesized fallback for standalone use.
# In delegated mode tier 2 always fires; tier 3 fires only when
# /add-example is invoked directly with no parent worktree.
PIPELINE_ID="${ZSKILLS_PIPELINE_ID:-}"
if [ -z "$PIPELINE_ID" ] && [ -f ".zskills-tracked" ]; then
PIPELINE_ID=$(tr -d '[:space:]' < ".zskills-tracked")
fi
: "${PIPELINE_ID:=add-example.${NAME}}"
PIPELINE_ID=$(bash "$ZSKILLS_SKILLS_ROOT/create-worktree/scripts/sanitize-pipeline-id.sh" "$PIPELINE_ID")
# Sanitised per-marker suffix slug — pairs with add-block's BLOCK_SLUG
# when invoked under delegation (orchestrator passes NAME == BLOCK_NAME).
NAME_SLUG=$(bash "$ZSKILLS_SKILLS_ROOT/create-worktree/scripts/sanitize-pipeline-id.sh" "$NAME")
[ -n "$PIPELINE_ID" ] || { echo "tracking: empty PIPELINE_ID — refusing flat write" >&2; exit 1; }
mkdir -p "$MAIN_ROOT/.zskills/tracking/$PIPELINE_ID"
printf 'skill: add-example\nname: %s\nstatus: started\ndate: %s\n' \
"$NAME" "$(TZ="${TIMEZONE:-UTC}" date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/$PIPELINE_ID/fulfilled.add-example.${NAME_SLUG}"
Where $NAME is derived from the block type(s) or model name (e.g.,
Gain, math-batch).
/add-example runs as a sub-skill inside its parent's worktree (Claude
Code subagents cannot dispatch their own subagents). Do not write
.zskills-tracked here — the worktree's existing file (written by the
parent's ensure-worktree.sh --pipeline-id call) defines the active
pipeline ID, and overwriting it would corrupt the parent's tracking
scope.
ls examples/
Check if an example already exists that features the target block(s). If so,
just add the example key to the block's examples array in
block-explorer-data.js and stop.
# Find the block definition — get param keys, port counts, defaults
grep -A 30 "type: 'YourBlockType'" src/library/block-registry.js
Use the exact key values from param() calls in your model file.
Past failure: used expression instead of expr because param name was not
checked against block-registry.js. The model loaded but produced wrong output.
Find a model from textbooks, reference examples, control theory papers, or engineering tutorials that naturally uses the target block(s). Do NOT invent a toy model from scratch — real-world models produce better examples.
Match solver to model characteristics:
ode4, ode1): piecewise data, simple dynamics, FromWorkspaceode45): smooth nonlinear dynamicsode15s): stiff systems, high-gain feedbackPast failure: used ode45 on piecewise FromWorkspace data — solver wasted steps
at discontinuities.
Past failure: carrier SineWave placed at x=100 instead of near the Product block it feeds — created a long diagonal line across the diagram.
If a block shows parameter text (Fcn expression, Transfer Function coefficients), size it wide enough to display the full text.
Past failure: 80px-wide Fcn block with a 35-character expression — text was truncated and unreadable.
Create examples/<name>/<name>.model following /model-design rules:
Use the formula — never eyeball:
portY = block.y + block.height * (portIndex + 1) / (portCount + 1)
Match source output portY to destination input portY exactly. Even 2px misalignment creates visible kinks and doubled-stroke rendering artifacts at branch points.
Example: A block at y=100, height=60, with 1 output port:
The downstream block's input port must also be at y=130. If the downstream block is at y=?, height=60, with 2 input ports and you need port index 0:
Create examples/<name>/README.md:
mkdir -p examples/<name>/screenshots
After Phase 2 (build) is complete:
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
[ -n "$PIPELINE_ID" ] || { echo "tracking: empty PIPELINE_ID — refusing flat write" >&2; exit 1; }
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ="${TIMEZONE:-UTC}" date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/$PIPELINE_ID/step.add-example.${NAME_SLUG}.build"
'model-key': {
path: 'examples/model-name/model-name.model',
name: 'Human-Readable Name',
difficulty: 'Beginner', // or 'Intermediate', 'Advanced'
description: 'One sentence describing what the model demonstrates.',
},
In BLOCK_EXPLORER_DATA in the same file, add 'model-key' to the examples
array of every block type the example is designed to showcase.
In tests/codegen-compile.test.js, add the model to the appropriate tier:
{ name: 'model-name', tol: 1e-6, maxMismatch: 0.05 },
After Phase 3 (register) is complete:
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
[ -n "$PIPELINE_ID" ] || { echo "tracking: empty PIPELINE_ID — refusing flat write" >&2; exit 1; }
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ="${TIMEZONE:-UTC}" date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/$PIPELINE_ID/step.add-example.${NAME_SLUG}.register"
Start dev server if not running:
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
if [ -z "$DEV_SERVER_CMD" ]; then
echo "ERROR: dev_server.cmd not configured. Run /update-zskills." >&2
exit 1
fi
$DEV_SERVER_CMD &
Use playwright-cli to:
playwright-cli screenshot
# Then rename to something descriptive:
mv .playwright/output/screenshot-*.png examples/<name>/screenshots/01-model-with-results.png
After Phase 4b (screenshot) is complete:
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
[ -n "$PIPELINE_ID" ] || { echo "tracking: empty PIPELINE_ID — refusing flat write" >&2; exit 1; }
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ="${TIMEZONE:-UTC}" date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/$PIPELINE_ID/step.add-example.${NAME_SLUG}.screenshot"
Add tests in tests/example-models.test.js. Tests must verify key output
values that prove the featured block works — not just "runs without errors."
it('model-name produces correct output', async () => {
// Build model, compile, simulate
// Assert specific output values at specific times
// e.g., assert that Gain output = input * gainValue
});
Past failure: tests only checked engine.status === 'completed', missed that a
wrong param name produced wrong output. The test passed but the model was broken.
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
if [ -z "$FULL_TEST_CMD" ]; then
echo "ERROR: testing.full_cmd not configured. Run /update-zskills." >&2
exit 1
fi
$FULL_TEST_CMD
All 3 suites must pass (unit, e2e, codegen). Report each suite's result.
After Phase 4c/4d (tests pass):
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
[ -n "$PIPELINE_ID" ] || { echo "tracking: empty PIPELINE_ID — refusing flat write" >&2; exit 1; }
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ="${TIMEZONE:-UTC}" date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/$PIPELINE_ID/step.add-example.${NAME_SLUG}.tests"
Send a verification agent (or do it yourself) to check:
JSON.parse)key in the block registryexamples array references the model keyAfter Phase 5a (verification) is complete:
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
[ -n "$PIPELINE_ID" ] || { echo "tracking: empty PIPELINE_ID — refusing flat write" >&2; exit 1; }
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ="${TIMEZONE:-UTC}" date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/$PIPELINE_ID/step.add-example.${NAME_SLUG}.verify"
Update the fulfillment marker to reflect completion:
if [ -f "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh" ]; then
export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
. "${CLAUDE_PLUGIN_ROOT}/skills/update-zskills/scripts/zskills-resolve-config.sh"
else
. "$CLAUDE_PROJECT_DIR/.claude/skills/update-zskills/scripts/zskills-resolve-config.sh"
fi
[ -n "$PIPELINE_ID" ] || { echo "tracking: empty PIPELINE_ID — refusing flat write" >&2; exit 1; }
printf 'skill: add-example\nname: %s\nstatus: completed\ndate: %s\n' \
"$NAME" "$(TZ="${TIMEZONE:-UTC}" date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/$PIPELINE_ID/fulfilled.add-example.${NAME_SLUG}"
If any layout adjustments were made during verification, retake the screenshot. The screenshot must always reflect the final layout.
Past failure: screenshot showed the old layout before a branch-point fix. The README referenced a screenshot that did not match the actual model.
/model-design for all layout rulesls examples/ first — an example may already exist