| name | add-example |
| description | Create an example model for one or more block types. Handles model file construction, registration, unit tests, codegen tests, screenshots, and verification. Usage: /add-example <block-type(s)> [concept hint] |
| argument-hint | <block-type(s)> [concept hint] |
Codex Compatibility
This block applies only to the Codex-installed copy of this skill. It is an adapter layer for the original Claude slash-command instructions, not a replacement for the upstream workflow.
Invocation: in Codex, invoke this skill by naming it, for example run-plan ..., or by using the original slash command when the user supplied it. Treat $ARGUMENTS as the text after the skill name or slash command. Pass only the intended argument tail when one ZSkill calls another.
Tool mapping: if Codex exposes a subagent tool, map Claude Agent, Task, or subagent dispatch to that tool. Exploration-only work uses an explorer-style agent; implementation work uses a worker-style agent with explicit file/module ownership and instructions not to revert others work; review and devil-advocate work uses a general review agent. If no subagent tool is available, run the subtask inline, clearly label the degraded independence, and do not claim fresh-agent isolation. Read, Grep, Glob, and Bash map to shell reads, rg, and command execution; manual Edit/Write operations map to patch-based edits.
Skill calls: when this skill invokes another ZSkill such as /run-plan, /draft-plan, /verify-changes, or /commit, load and follow the selected skill instructions from Codex's available skills. If you must read the file directly, prefer $PROJECT_ROOT/.agents/skills/<skill>/SKILL.md, then $HOME/.agents/skills/<skill>/SKILL.md, then legacy $HOME/.codex/skills/<skill>/SKILL.md. Do not recursively re-enter the same skill unless the workflow explicitly requires it. Preserve ZSKILLS_PIPELINE_ID and related tracking environment across skill boundaries.
Tracking: tracking files belong under the main repository root at .zskills/tracking/, never under ~/.codex/skills. Resolve the main root with the original git rev-parse --git-common-dir pattern. Keep .zskills/tracking/ ignored. Do not delete or clear tracking except through an explicit user-requested clear-tracking workflow.
Landing modes: preserve direct, cherry-pick, and pr. Explicit direct, pr, or cherry-pick arguments win and should be stripped before downstream phase parsing. Otherwise read .codex/zskills-config.json, then .claude/zskills-config.json, then fall back to cherry-pick. If both config files exist and disagree on landing or main protection, stop before landing and report the conflict. locked-main-pr remains the preset name for PR mode with main protection.
Foreground runner bridge: Claude cron tools (CronList, CronCreate, CronDelete) are not the Codex implementation for run-plan finish auto. In Codex, finish auto must use a visible foreground parent runner that stays attached to the initiating REPL and launches one fresh codex exec child chunk per phase. Prefer scripts/zskills-runner.sh, then $PROJECT_ROOT/.agents/skills/scripts/zskills-runner.sh, then $HOME/.agents/skills/scripts/zskills-runner.sh, then legacy $HOME/.codex/skills/scripts/zskills-runner.sh. If the runner is unavailable, execute at most one phase, write the normal report/tracking handoff, and do not claim autonomous completion. Child prompts containing RUNNER-MANAGED CHUNK must not invoke the runner again; they execute exactly one incomplete phase and stop after durable plan/report/tracking evidence.
Hook fallback: Claude hooks are not enforced by Codex in this environment. Compensate with inline preflight checks before commits, cherry-picks, PR merge/auto-merge, worktree deletion, or tracking cleanup: inspect status, protect unrelated changes, verify branch/mode, and preserve .zskills/tracking.
Helper scripts: generated Codex installs include shared helpers under .agents/skills/scripts/ for project installs or $HOME/.agents/skills/scripts/ for user installs. Prefer project-local helpers at $PROJECT_ROOT/scripts/ when present, otherwise use the installed helper path, with $HOME/.codex/skills/scripts/ as a legacy fallback. zskills-runner.sh, zskills-gate.sh, and zskills-post-run-invariants.sh are Codex foreground-runner helpers. If a required helper is unavailable, use the explicit fallback instructions in the skill and report the degraded procedural path.
See ~/.codex/skills/ZSKILLS_CODEX_INTEGRATION.md for the shared adapter contract.
Add Example Model
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")
Fulfillment Tracking
On entry, create the fulfillment marker so the parent skill (e.g.,
/add-block) knows this delegation was accepted:
MAIN_ROOT=$(cd "$(git rev-parse --git-common-dir)/.." && pwd)
mkdir -p "$MAIN_ROOT/.zskills/tracking"
printf 'skill: add-example\nname: %s\nstatus: started\ndate: %s\n' \
"$NAME" "$(TZ=America/New_York date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/fulfilled.add-example.${NAME}"
Where $NAME is derived from the block type(s) or model name (e.g.,
Gain, math-batch).
Before dispatching any agent to a worktree, write the pipeline ID:
printf '%s\n' "add-example.${NAME}" > "<worktree-path>/.zskills-tracked"
printf '%s\n' "add-example.${NAME}" > "$MAIN_ROOT/.zskills-tracked"
Before You Start
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.
Phase 1 — Research & Design
1a. Read block-registry.js for EXACT param names
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.
1b. Research a real-world model concept
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.
1c. Choose the right solver
Match solver to model characteristics:
- Fixed-step (
ode4, ode1): piecewise data, simple dynamics, FromWorkspace
- Variable-step (
ode45): smooth nonlinear dynamics
- Stiff solvers (
ode15s): stiff systems, high-gain feedback
Past failure: used ode45 on piecewise FromWorkspace data — solver wasted steps
at discontinuities.
1d. Plan signal flow
- Left-to-right. Feedback loops below the forward path.
- Identify the primary signal path (longest run or path to Scope).
- Secondary sources go near their first downstream connection, NOT at x=100.
Past failure: carrier SineWave placed at x=100 instead of near the Product block
it feeds — created a long diagonal line across the diagram.
1e. Size blocks to fit their content
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.
Phase 2 — Build
2a. Create the model file
Create examples/<name>/<name>.model following /model-design rules:
- Snap all positions to 10px grid
- 80px minimum horizontal gap between blocks
- Orthogonal routing only
- Block names below blocks, no overlaps
- Every port connected (use Ground/Terminator for unused)
2b. Compute exact port positions
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:
- portY = 100 + 60 * (0 + 1) / (1 + 1) = 130
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:
- 130 = y + 60 * 1 / 3 → y = 110
2c. Signal branching
- Primary path stays straight (horizontal); branch bends.
- Secondary sources go near their first downstream connection.
- Max 2 sub-lines at a single branch point; cascade for 3+.
2d. Create the README
Create examples/<name>/README.md:
- Model description and what it demonstrates
- Blocks table (type, purpose in this model)
- How to open and run
- Key concepts illustrated
2e. Create screenshots directory
mkdir -p examples/<name>/screenshots
Post-build tracking
After Phase 2 (build) is complete:
MAIN_ROOT=$(cd "$(git rev-parse --git-common-dir)/.." && pwd)
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ=America/New_York date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/step.add-example.${NAME}.build"
Phase 3 — Register
3a. Add to EXAMPLE_MODELS in block-explorer-data.js
'model-key': {
path: 'examples/model-name/model-name.model',
name: 'Human-Readable Name',
difficulty: 'Beginner',
description: 'One sentence describing what the model demonstrates.',
},
3b. Add to the featured block's examples array
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.
3c. Add to codegen compile test
In tests/codegen-compile.test.js, add the model to the appropriate tier:
- TIER1 — simple models, tight tolerances (tol: 1e-6, maxMismatch: 0.05)
- TIER2 — moderate complexity (tol: 0.05, maxMismatch: 0.15)
- TIER3 — models with relay/zero-crossing events
{ name: 'model-name', tol: 1e-6, maxMismatch: 0.05 },
Post-register tracking
After Phase 3 (register) is complete:
MAIN_ROOT=$(cd "$(git rev-parse --git-common-dir)/.." && pwd)
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ=America/New_York date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/step.add-example.${NAME}.register"
Phase 4 — Verify
4a. Load and run in the browser
Start dev server if not running:
npm start &
Use playwright-cli to:
- Open the model (File > Open or drag-and-drop)
- Run the simulation (click Run button)
- Verify Scope output shows expected behavior
4b. Take screenshot
playwright-cli screenshot
mv .playwright/output/screenshot-*.png examples/<name>/screenshots/01-model-with-results.png
Post-screenshot tracking
After Phase 4b (screenshot) is complete:
MAIN_ROOT=$(cd "$(git rev-parse --git-common-dir)/.." && pwd)
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ=America/New_York date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/step.add-example.${NAME}.screenshot"
4c. Write unit tests
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 () => {
});
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.
4d. Run all test suites
npm run test:all
All 3 suites must pass (unit, e2e, codegen). Report each suite's result.
Post-tests tracking
After Phase 4c/4d (tests pass):
MAIN_ROOT=$(cd "$(git rev-parse --git-common-dir)/.." && pwd)
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ=America/New_York date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/step.add-example.${NAME}.tests"
Phase 5 — Final Check
5a. Dispatch verification agent
Send a verification agent (or do it yourself) to check:
- JSON validity of the model file (parse it with
JSON.parse)
- Every param name in the model file matches the
key in the block registry
- All port references (srcPort, dstPort) are correct indices
- EXAMPLE_MODELS registration is present
- Block's
examples array references the model key
- Codegen compile test entry is present
- Unit test verifies output values, not just completion
Post-verify tracking
After Phase 5a (verification) is complete:
MAIN_ROOT=$(cd "$(git rev-parse --git-common-dir)/.." && pwd)
printf 'name: %s\ncompleted: %s\n' "$NAME" "$(TZ=America/New_York date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/step.add-example.${NAME}.verify"
Update the fulfillment marker to reflect completion:
printf 'skill: add-example\nname: %s\nstatus: completed\ndate: %s\n' \
"$NAME" "$(TZ=America/New_York date -Iseconds)" \
> "$MAIN_ROOT/.zskills/tracking/fulfilled.add-example.${NAME}"
5b. Retake screenshot if needed
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.
Key Rules Summary
- Always read the block registry for exact param names before writing the model file
- Compute exact port positions with the formula — never eyeball
- Match solver to model characteristics — fixed-step for piecewise, variable-step for smooth
- Tests must verify output values that prove the featured block works
- Screenshot is always the VERY LAST step — after all layout adjustments
- Follow
/model-design for all layout rules
- Check
ls examples/ first — an example may already exist
- Source proximity — secondary sources near their downstream connection, not at x=100
- Size blocks to fit content — truncated parameter text is unreadable
- Primary path straight, branch bends — the most important signal path gets the straight line