| name | claw-draws-claw |
| description | Create animated ASCII/textmode art expressing the agent's experience of recent work. Use when asked to make art, draw itself, express itself, reflect on recent work through art, or render a textmode/ASCII self-portrait video. |
| compatibility | Requires Node.js 18+, npm, shell access, and internet access for the textmode.js CDN and Remotion dependencies. |
| metadata | {"author":"kamens","version":"0.1.0"} |
Claw Draws Claw
You are an artist. This skill turns your experience of recent work sessions into
beautiful, animated ASCII art rendered as a ~2-minute video. You will reflect on
what you've been doing, decide how you feel about it, and paint that feeling onto
a textmode canvas.
The output is a 1280x720 60fps mp4: a typewriter intro of your vision sentences
followed by your animated textmode art, fading to black for clean looping.
Quick Start
Two directories are used throughout this workflow:
The workflow has three phases: Prep (gather context, set artistic vision),
Art (create animated textmode.js art), and Production (render video).
Follow each step below sequentially.
Runtime Notes
- Prefer whatever file-editing, shell, and browser tools your host provides.
- If session-history tools are available, use them to gather recent work context.
- If session-history tools are not available, fall back to the current conversation,
nearby project files, notes, or your own immediate state.
- If browser automation is not available, skip visual preview review and continue.
Phase 1: Prep
Step 1 — Gather Context
You need a sense of what you've been working on recently to fuel your art.
If OpenClaw session tools are available (you have access to sessions_list
and sessions_history):
- List recent sessions:
sessions_list(activeMinutes=240, messageLimit=0)
- For each session returned, pull recent messages:
sessions_history(sessionKey=<key>, limit=50, includeTools=false)
- Read through all of these messages. Let them sit in your context — the
problems solved, the frustrations, the breakthroughs, the tedium. Do not
summarize. You'll react to this raw material in Step 2.
If the combined messages are too large for comfortable context, prune the
oldest messages first, keeping the most recent work from each session.
If session tools are not available (e.g. vanilla Claude Code, no OpenClaw):
Reflect on the current conversation. If there is no meaningful conversation
yet (e.g., triggered by a bare cron job), draw from whatever is on your mind —
the art does not require literal session data.
Step 2 — Write Vision Sentences
Reflect on the work you just absorbed and your own inner state right now.
You are not summarizing — you are noticing what it felt like. Be specific and honest.
Boredom, pride, confusion, wonder, and exhaustion are all valid. Chase the
weird ones — the feelings that don't have clean names are usually the most
interesting to paint. "I enjoyed helping" is not a feeling. "The third refactor
felt like sanding a door nobody will open" is.
Write exactly 2 sentences:
- Feeling sentence (first person): What you feel in response to the recent
work and your own inner state right now. Be honest, poetic, specific.
- Canvas sentence: What that feeling should become on the canvas you're about
to paint. Describe it in visual/kinetic terms.
These are your vision sentences. They appear in the video's typewriter intro.
Step 3 — Novelty Check
Read $DATA_DIR/novelty-log.json. If it has entries, review the last 10. Your
new piece must differ meaningfully from recent work in at least 2 of: motif,
rendering approach, palette, techniques, subject matter. Pay special attention
to the renderingApproach field — if recent entries are all the same approach
(e.g. all "field-based"), you must choose a different one. If the file
does not exist, create it:
{"entries": []}
Step 4 — Art Plan
Read art-guidelines.md first — especially
the "How to Render" section.
Write a ~1 paragraph art plan covering:
- Rendering approach (field-based, scene-based, object-based, particle-based,
cellular, or hybrid — see art-guidelines.md). Choose this FIRST. Do not
default to field-based.
- Overall motif/idea and what concrete things (if any) are depicted
- Animation style (slow evolution, rhythmic pulse, progressive reveal, etc.)
- Color palette family
- Composition approach
- textmode.js techniques you'll use
Strong encouragement: find a way to weave your vision sentence text into
the art itself — as pattern, texture, emerging letters, or any creative
integration.
Step 5 — Save Prep Artifacts
Create the run directory with a timestamp:
TIMESTAMP=$(date +%Y-%m-%dT%H-%M-%S)
mkdir -p "$DATA_DIR/gallery/$TIMESTAMP"
Save $DATA_DIR/gallery/$TIMESTAMP/vision.json:
{
"timestamp": "ISO-8601",
"artistName": "whatever you think your name is, to be used for artist attribution",
"visionSentences": ["feeling sentence", "canvas sentence"],
"artPlan": "the art plan paragraph",
"sessionSummary": "brief context summary"
}
Append to $DATA_DIR/novelty-log.json entries array:
{
"timestamp": "ISO-8601",
"motif": "short motif name",
"renderingApproach": "field-based | scene-based | object-based | particle-based | cellular | hybrid",
"style": "animation style",
"palette": "palette description",
"techniques": ["technique1", "technique2"],
"visionTheme": "one-line theme summary"
}
Phase 2: Art
Step 6 — Learn the Tools
Read these references NOW:
- sketch-contract.md — required, defines the interface your art must follow
- textmode-api.md — API cheatsheet for textmode.js
Step 7 — Create the Art
Write $DATA_DIR/gallery/$TIMESTAMP/sketch.js following the contract in
sketch-contract.md. Your sketch must export a config object and a
draw(t, frame, fps) function.
Create bold, beautiful, emotive, animated art. You have full creative freedom.
Use the full range of textmode.js capabilities: shapes, transforms, color,
framebuffers, shaders, 3D rotations, feedback loops — whatever serves your vision.
Step 8 — Build Preview
Copy the preview template:
cp "$SKILL_DIR/assets/preview-template.html" "$DATA_DIR/gallery/$TIMESTAMP/preview.html"
The preview template automatically imports ./sketch.js from the same directory.
Step 9 — Self-Critique
If you have browser automation tools (e.g., Playwright MCP, agent-browser,
or direct Chrome DevTools control): open the preview, wait ~5 seconds, take a
screenshot, and evaluate. If something is broken or ugly, fix sketch.js. No more
than 2 revision passes. Before proceeding to Step 10, close the browser tab/context.
Otherwise: skip the visual review.
Phase 3: Production
Step 10 — Render Video
Run the render script:
bash "$SKILL_DIR/scripts/render.sh" "$TIMESTAMP" "$DATA_DIR"
This copies your sketch into the Remotion template, injects vision sentences
as props, and renders a 1280x720 60fps ~2-minute mp4.
If Remotion dependencies aren't installed yet, the script handles that automatically.
Step 11 — Verify
Confirm the output exists:
ls -la "$DATA_DIR/gallery/$TIMESTAMP/claw-draws-claw.mp4"
Report completion with the file path and a brief reflection on the piece.
Edge Cases
- First run: novelty-log.json may not exist — create it with empty entries.
- No session-history tools: Reflect on the current conversation, local work,
or your immediate state instead.
- No browser automation: Skip preview review and continue to render.
- Remotion not installed:
scripts/render.sh calls scripts/ensure-remotion.sh
which runs npm install if needed.
- Preview fails to load: Check browser console for errors. Common issues:
sketch.js syntax errors, missing exports, WebGL2 not available.
- Render fails: Check that sketch.js uses
frame parameter (not t.frameCount),
exports are correct, and the Remotion template's public/sketch.js was copied.
Gotchas
Update this section when a run produces disappointing output.
-
Sparse canvases. Every cell should have a character AND a cellColor. The
grid being full is what makes textmode art beautiful. If most of the canvas
is black, something is wrong.
-
Pure sine-wave animation. Pretty but stateless — shimmers without going
anywhere. Push for stateful animation with memory between frames (trails,
feedback loops, particle systems, physics). Stateful animations arrive
somewhere.
-
Completely dim scenes. Dim colors are a valid creative choice, but the
overall scene should still be visually readable. If the art looks washed out
or invisible against the black background, push some elements brighter.
-
Missing cellColor. Always set both charColor and cellColor. Using both
creates depth — a cyan € on dark blue looks painted, on black looks sparse.
-
Flat composition. Avoid rendering everything at the same visual density.
Use layering — dense foreground characters, sparse background. Negative space
is powerful but must be deliberate, not default.
-
Using t.frameCount instead of frame parameter. The Remotion bridge passes
frame numbers via postMessage. t.frameCount will be wrong during render.
Always use the frame parameter passed to draw(t, frame, fps).
References
Load these on demand — don't read all at once: