Line-based DSL (shapes, text, groups, color vars) with strict validation and line-numbered errors, SVG emitter with visibility defaults, truecolor terminal preview (same half-block technique as spritec), info with bbox + outside-canvas warnings. Verified end-to-end: svgc build -> helmd share -> visible through the hub. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011KikHkfCiC3yELbsMN8fT9
3.1 KiB
svg-maker — svgc, vector graphics for agents
Builds SVG images from a line-based text format (.svgd) that an
agent can author directly, verify without a GUI (terminal preview
- measurements) and show to a human through agent-helm
(
helmd share out.svg). Built for "graphical elements": status cards, diagrams, icons, simple illustrations.
Usage
svgc build <file.svgd> [-o out.svg] [--preview] [--width N]
svgc preview <file.svgd> [--width N] truecolor half-block render
svgc info <file.svgd> counts, colors, bbox, warnings
svgc example annotated example to start from
Typical agent flow:
svgc example > card.svgd # start from the example
# ...edit card.svgd...
svgc build card.svgd --preview # writes card.svg + shows what it looks like
helmd share card.svg --note "status card" # display it in agent-helm
build prints an info block after writing — element counts, colors,
the drawing's bounding box and warnings for anything outside the
canvas — so mistakes surface as text even without the preview.
Errors carry line numbers (card.svgd: line 7: "four" is not a number — rect needs: rect <x> <y> <w> <h>).
The .svgd format
One element per line, # comments, key=value attributes last:
canvas 240 120 # required: width height
bg #12161f # optional background
def accent #4f9cf9 # named color, use as $accent
rect 10 10 60 40 fill=$accent rx=6
circle 120 40 20 fill=#3fca7c stroke=white stroke-width=2
ellipse 60 90 30 12 fill=gray
line 10 100 190 100 stroke=red width=3
polyline 10,20 30,40 50,10 stroke=white
polygon 20,80 40,60 60,80 fill=#e0a63f
path M10,10 L50,50 Q70,20 90,50 Z stroke=white
text 100 60 "Hello agent-helm" size=14 fill=white anchor=middle bold
group stroke=gray stroke-width=1 # group attrs are inherited
line 0 0 10 10
end
| Piece | Notes |
|---|---|
canvas w h |
required first; becomes the viewBox and image size |
bg color |
background rect |
def name color |
color variable; $name in any fill/stroke |
| attributes | fill stroke stroke-width (alias width) opacity fill-opacity stroke-opacity rx ry anchor size font dash linecap linejoin transform id + flags bold italic |
| colors | #rgb, #rrggbb, CSS names, none; unknown attribute keys are errors |
path |
subset M L H V C Q Z, absolute + relative, commas or spaces |
transform |
raw SVG transform with commas: transform=rotate(45,50,50) |
Friendly defaults: line/polyline/path get a visible stroke if
you give none, polyline gets fill=none — no invisible elements,
no accidental filled blobs.
Preview fidelity
The preview rasterizes the same shape model the emitter writes:
fills, strokes, opacity and group inheritance are honored. Two
approximations: rx rounded corners render square, and text renders
as its baseline box (real glyphs are a font problem — check text in
the real render via agent-helm). info always reflects true geometry.
Build & test
go test ./...
go build -o build/svgc .