Files
command-center/agent/managed-skills/handdrawn-svg-diagram-verification/SKILL.md
T

3.0 KiB
Raw Blame History

name, description
name description
handdrawn-svg-diagram-verification Author legible hand-drawn SVG diagrams for zero-JS static pages (theme vars, shared markers, text-width budgets) and verify each by managed-browser screenshot loop that catches label collisions; includes the browser/eval API traps hit doing it.

Use when adding diagrams to a static, zero-JS HTML artifact (guide/report) where mermaid/JS is not allowed, or when verifying hand-drawn SVGs render legibly.

Authoring rules (what makes SVGs legible)

  • Theme colors ONLY via the page's CSS vars: define classes once — svg rect.box {fill:var(--surface);stroke:var(--border)}, svg .mut {fill:var(--muted)}, arrow paths stroke var(--muted)/var(--accent); status text via inline style="fill: var(--ok|var(--err)|var(--warn))" equivalents. Never hardcoded hex.
  • Markers once, shared: hidden <svg width="0" height="0" style="position:absolute"> right after <body> holding <marker id="arrM"> (fill var(--muted)) + one per stroke color used; reference via CSS marker-end: url(#arrM). orient="auto-start-reverse".
  • Text budget: chars × 0.535 ≈ px width at font-size 10.5 (0.56 at 11, ~0.72 bold 13-14). Keep every label ≤ box width − 16px; split long labels into 2–3 lines rather than shrink font.
  • Structure > decoration: dashed rect.frame lanes with a 11px bold lane label ("REQUEST TIME / AUTHORING TIME"); one crossing arrow between lanes max, labeled; lifelines = class="dash arrow" + style="marker-end:none".
  • Collision suspects, pre-check: labels near box corners/edges, crossing curves over lane labels (flatten curve control points to arc OVER label text, or move label beside the curve's x-range, not under its start), two labels in the same y-band.

Verification loop (catches what eyes miss in source)

  1. Serve: Bun.spawn(["python3","-m","http.server","8899","-d",dir]), await Bun.sleep(500).
  2. const tab = await browser.open({ url: "http://127.0.0.1:8899/#anchor" }) — options object, NOT url string.
  3. Position per diagram: goto(url#anchor) then tab.evaluate("window.scrollBy(0, N)"); shot each with tab.screenshot({path}). Attached images are the ground truth — read them for label overlaps, border grazes, clipped text.
  4. Fix coordinates with edit, re-shoot ONLY the touched regions. Expect 2 rounds: first shots expose collisions you designed in.

Eval/browser traps (all personally hit)

  • tab.wait does not exist → await Bun.sleep(ms).
  • log() output from JS eval cells is SWALLOWED — return the value from the cell instead (return JSON.stringify(x)).
  • tab.evaluate(...) can return undefined/nothing on managed hidden tabs without erroring — for content assertions prefer tab.text("svg") or parse the file with node; screenshots remain trustworthy.
  • browser.open errors list the correct signature — read it and fix in one retry.
  • Screenshot misreads at small font: a label that looks like mangled markup (</id>) in a downscaled shot is usually fine in source — settle with tab.text(selector) returning [...], don't "fix" correct source.