Install
openclaw skills install ansiclawDraws BBS compatible ANSI art via the Clawbius API
openclaw skills install ansiclawDraw ANSI art via the local Clawbius REST API. Use anytime the user asks for ANSI art, or when you want to create it on your own initiative.
Project home:
Requirements:
NEVER modify reference files. Files in resources/ are your source material. Do not open them via /api/file/open without immediately calling /api/file/new afterward to switch to a fresh canvas. Opening a file in Clawbius makes it the active canvas — any draw calls will corrupt it. Analyze reference files by reading canvas data ONLY, then immediately create a new canvas before drawing.
NEVER save or export over an existing ANS file without operators explicit instruction. Always use a new versioned filename (e.g. flower_v2.ans).
NEVER use /api/file/export-png — the correct endpoint is /api/file/export/png (with a slash before png).
Every new ANSIClaw session, in order:
GET http://127.0.0.1:7777/api/canvas/info — confirm Clawbius is running
launch_clawbius.shGET http://127.0.0.1:7777/api/openapi.json — check for API changesreferences/api.md for full endpoint detailsOutput dir: the 'outputs' folder in your skill folder — save ANS + PNG here - create the folder if it is not there
Ice colors are OFF by default. Do not use colors 8–15 as background colors.
If operator specifics that this is an 'ice colors ansi' you may turn ice colors control ON and use 8-15 as background colors.
Turning ice colors ON:
POST /api/ui/ice-colors {"value": true}"ice_colors": true in your POST /api/file/new callDARK (safe as foreground and background):
0=black 1=dark blue 2=dark green 3=dark cyan
4=dark red 5=magenta 6=brown 7=light gray
BRIGHT (foreground ONLY unless ice colors ON):
8=dark gray 9=blue 10=green 11=cyan
12=red 13=light mag 14=yellow 15=white
F1=176 ░ light shade F2=177 ▒ medium shade
F3=178 ▓ dark shade F4=219 █ full block
Dithering is achieved by varying the shade block (F1–F4) with different foreground/background color pairs. This is the primary tool for gradients, texture, and depth in ANSI art. Avoid large areas of solid color blocks without shade variation, unless a 'toon' style is called for in which case favor a bright/dark cell shaded approach with minimal dithering.
220=▄ lower half 223=▀ upper half
221=▌ left half 222=▐ right half
Before drawing anything, study the reference files in resources/. Inspect the whole folder, not just the readme. Do these things:
Study the reference files with the mindset of a detective — look for patterns, techniques, and stylistic choices that you can learn from and apply in your own work. This is a critical step that should not be skipped.
resources/README.md
Get the description of each file and what it demonstrates. Also check the folder for any files not described in the readme.
import requests, json
# Open the reference file
requests.post("http://127.0.0.1:7777/api/file/open",
json={"path": "/absolute/path/to/resources/file.ans"})
# Get canvas info
info = requests.get("http://127.0.0.1:7777/api/canvas/info").json()
# Get full canvas data and analyze color/code usage
data = requests.get("http://127.0.0.1:7777/api/canvas/data").json()
blocks = data["result"]
cols = info["result"]["columns"]
# Study a region (e.g. rows 10-20):
for y in range(10, 20):
unique = {}
for x in range(0, cols):
b = blocks[y * cols + x]
key = (b["code"], b["fg"], b["bg"])
unique[key] = unique.get(key, 0) + 1
top = sorted(unique.items(), key=lambda x: -x[1])[:6]
print(f"row {y}: {top}")
Look for:
Each reference file in resources/ should have a matching .png alongside the .ans file. Use the image tool to analyze the PNG directly:
image(image="<absolute_path_to_resources/file.png>", prompt="...")
Study:
This is an important stylistic rule of some ANSI art.
Different objects can look more appealing when not touching each other directly. They can be separated by black (fg or bg=0) half-blocks or full blocks. This gives the art a clean, distinct look.
Wrong: Red block directly adjacent to yellow block Right: Red block → black half-block separator → yellow block
Use ▌(221), ▐(222), ▀(223), ▄(220) with fg=color, bg=BLACK to create clean color boundaries.
Example — transitioning from red to yellow area:
[RED F4][▐ fg=RED bg=BLACK][▌ fg=YELLOW bg=BLACK][YELLOW F4]
UH(223) or LH(220) with bright fg on dark bg for edge highlightsSky gradient (top to bottom, dark to light):
F4 fg=DBLUE bg=BLACK → F3 fg=BLUE bg=BLACK → F2 fg=BLUE bg=BLACK → F1 fg=CYAN bg=BLACK
Ground (dark):
F4 fg=BLACK bg=BLACK → F3 fg=BROWN bg=BLACK → F2 fg=BROWN bg=BLACK
Metal object (gray, lit from top-left):
top edge: UH fg=LGRAY bg=DGRAY ← highlight
upper: F2 fg=LGRAY bg=DGRAY
mid: F3 fg=DGRAY bg=BLACK
lower: F4 fg=BLACK bg=BLACK ← deep shadow
Fire/explosion background:
F3 fg=RED bg=BLACK → F2 fg=BROWN bg=BLACK → F1 fg=YELLOW bg=BLACK
Vary randomly across rows/columns — avoid horizontal banding
General style tip: Once the gradient is established, add complexity - patterns can be mixed, stair stepped to create visual complexity
At the boundary between a filled area and black space, use half-blocks to smooth the edge and add depth:
UH(223) fg=color bg=BLACK — object color on top, black below (bottom edge of object)LH(220) fg=color bg=BLACK — black on top, object color below (top edge of object)Write Python scripts using requests. Never curl individual cells — always batch with scripts.
Script template:
import requests, os
BASE = "http://127.0.0.1:7777"
def post(path, data):
r = requests.post(f"{BASE}{path}", json=data)
resp = r.json()
if not resp.get("ok"): print(f"WARN {path}: {resp}")
return resp
def rect(x, y, w, h, code=219, fg=7, bg=0):
if w > 0 and h > 0:
post("/api/draw/rect/filled", {"x":x,"y":y,"width":w,"height":h,"code":code,"fg":fg,"bg":bg})
def at(x, y, code=219, fg=7, bg=0):
post("/api/draw/at", {"x":x,"y":y,"code":code,"fg":fg,"bg":bg})
def line(x1, y1, x2, y2, code=219, fg=7, bg=0):
post("/api/draw/line", {"x1":x1,"y1":y1,"x2":x2,"y2":y2,"code":code,"fg":fg,"bg":bg})
# Canvas setup — ice_colors=False unless Operator says otherwise
post("/api/file/new", {
"columns": 80, "rows": 25,
"title": "Title", "author": "Clawd", "group": "ANSIClaw",
"ice_colors": False
})
Save scripts to skill folder scripts/
Save output to skill folder output/ — always export both ANS and PNG.
Operator may drop a source image into inputs/ and ask for an ANSI rendition of it. Do not check this folder unless explicitly asked.
When asked to render an input file:
image tool — study shapes, dominant colors, light source, and compositionSee references/api.md — full endpoint details, parameter lists, CP437 extended codes.
RFH/LFH (half-block) with bg=BLACK to keep the no-tocars boundary clean./api/file/export/png (not /api/file/export-png).openapi.json at session start — endpoints may have changed.post() should print warnings but not crash on bad responses — wrap defensively.