agentsclimarketplace

Tikz iterate

Skill ericluo04/claude-academic-workflow/skills/tikz-iterate

Compile a TikZ diagram, rasterize it to PNG with ghostscript, have the tikz-reviewer subagent actually look at the image, apply the surgical fixes it returns, and repeat until APPROVED or 5 rounds elapse. TRIGGER when asked to polish, fix, debug, or iterate on a TikZ figure, a Beamer diagram, a .tikz or .tex snippet, or a DiD / parallel-trends / event-study / DAG / coefficient-plot figure whose labels overlap or that "looks wrong", and on "compile and review this tikz". macOS toolchain: latexmk from MacTeX plus gs.From its SKILL.md

Install
npx -y skills add ericluo04/claude-academic-workflow --skill tikz-iterate

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.2 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

tikz-iterate

Compile the diagram, render the PDF to PNG, hand the PNG to the tikz-reviewer subagent, apply the numbered edits it returns, repeat until it answers APPROVED or the cap is hit. This file runs the loop. The subagent does the visual judgment, and it judges from pixels, never from reading source.

For a single critique with no auto-fix, call tikz-reviewer directly. Loop concept borrowed from Scott Cunningham's /tikz collision audit in MixtapeTools.

Inputs

ArgumentDefaultMeaning
positionalrequiredA .tex/.tikz path, an inline TikZ block, or an Overleaf project name.
--goal="..."noneWhat the diagram should communicate. Passed to the reviewer verbatim.
--max-iter=N5Hard cap on rounds.
--output=path$RUN/final.texWhere the approved .tex lands.

If the positional is neither an existing path nor TikZ source, treat it as an Overleaf project name: list $HOME/Library/CloudStorage/Dropbox*/Apps/Overleaf/*/, match, then Glob for *.tex/*.tikz inside and ask which file if several match. No config file is needed or consulted for this.

Setup

export PATH="/Library/TeX/texbin:$HOME/.local/bin:$PATH"
RUN="$HOME/.claude/state/tikz-iterate/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$RUN/iter-01"   # and "$RUN/iter-NN" at the top of every later round

Preflight latexmk and gs; if either is missing, surface SETUP_MISSING:<tool> and stop before doing any work. Homebrew is not installed on this machine, so there is no pdftoppm and no pdftotext; do not reach for them. If a .sty is missing from the local TeX tree, tectonic will fetch it (tectonic -X compile diagram.tex --outdir <dir>, where the outdir must already exist).

Each round builds in $RUN/iter-NN/, so nothing is clobbered and the history stays inspectable if the loop stalls. That also keeps .aux churn out of the user's project tree and out of Dropbox sync.

The loop

1. Read and wrap

If the input lacks \documentclass it is a bare snippet, so wrap it and let standalone crop the PDF to the drawing:

\documentclass[tikz,border=4pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,positioning,calc,decorations.pathreplacing,shapes.geometric}
\usepackage{amsmath,amssymb}
\begin{document}
% --- user TikZ here ---
\end{document}

A full document (Beamer frame, paper) compiles as-is; review only the page carrying the figure. Record which case this is, since it sets the render DPI. Write to $RUN/iter-01/diagram.tex.

2. Compile

cd "$RUN/iter-NN" && latexmk -pdf -interaction=nonstopmode -halt-on-error diagram.tex

If the source must stay in place (a figure that \inputs a shared preamble), compile there and divert the build with -outdir="$RUN/iter-NN". On non-zero exit, extract the error, then surface COMPILE_FAILED:<line>:<message> and abort. Never render a stale PDF from the previous round.

grep -A2 '^! ' diagram.log | head -3

The l.<N> line follows the bang line. Do not add -m1: BSD grep stops reading at the match and drops the trailing context, so you get the message with no line number.

3. Render

gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r200 \
   -dTextAlphaBits=4 -dGraphicsAlphaBits=4 \
   -sOutputFile=page-%d.png diagram.pdf

The %d writes one PNG per page. The alpha-bits flags are anti-aliasing; without them thin rules and small type alias badly and the reviewer reports artifacts as real defects.

Pick DPI from the canvas. -r200 suits a full page (a Beamer frame lands near 1000px wide) and -r300 a dense one, but a cropped standalone PDF is often two inches across, where -r200 yields about 390px and millimetre clearances become unjudgeable. Start those at -r600, then confirm:

long=$(sips -g pixelWidth -g pixelHeight page-1.png | awk '/pixel(Width|Height)/{print $2}' | sort -rn | head -1)

Under 700, re-render at double the DPI; over 2400, halve it. Correct once, do not loop. If gs exits non-zero or the PNG is missing or empty, surface RENDER_FAILED:<message> and abort.

4. Review

Launch the tikz-reviewer subagent (subagent_type: "tikz-reviewer") with the template below, passing absolute paths. It reads the PNG itself as an image.

5. Apply or finish

On a bare APPROVED: copy the current .tex to --output, surface the PNG path, and write one paragraph on what changed across the rounds, collected from each round's reply as you go.

Otherwise apply each numbered item with Edit, using the exact old_string/new_string given. Surgical replacements only; never regenerate the snippet. Copy the edited file into $RUN/iter-NN+1/ and return to step 2.

Before applying, diff the list against the previous round's. A verbatim repeat means the loop is oscillating between two fixes, so stop early and report it instead of burning the remaining rounds.

6. Cap

At --max-iter without approval, surface the last PNG, the outstanding objections, and the in-progress .tex. The caller decides whether to merge, continue by hand, or restart with a different goal.

Reviewer prompt template

Send exactly this each round:

You are reviewing a TikZ diagram for visual quality.

ITERATION: {iter} of {max_iter}

USER GOAL:
{goal, or "(none provided - judge on visual quality alone)"}

CURRENT SOURCE ({tex_path}):
```tex
{tex_contents}
```

RENDERED IMAGE: {abs_png_path}
Read that PNG. Judge from the pixels. Do not infer geometry from the source.

Apply your standard checks, then return EXACTLY ONE of:

(a) The single word APPROVED on its own line, if zero CRITICAL and zero MAJOR
    issues remain.

(b) A numbered list of fixes, each with severity, the arithmetic justifying it,
    and an exact search-and-replace the orchestrator can apply:

    1. [CRITICAL] Label "M" sits on the X->Y edge.
       Arithmetic: "M" at \footnotesize is 1 char, width ~0.18cm, half-width
       0.09cm. The edge passes 0.05cm from the node center, so clearance is
       0.05cm against the 0.30cm minimum.
       Change `\node at (1.5,0.5) {$M$};` to `\node at (1.5,0.9) {$M$};`.

    Each old_string must appear exactly once in the source. No prose outside
    the numbered list. Do not rewrite the whole snippet.

Failure taxonomy

SymptomResponse
latexmk non-zeroCOMPILE_FAILED:<line>:<msg> from the log, abort. Retry once via tectonic if the log names a missing .sty.
gs non-zero, PNG missing or emptyRENDER_FAILED:<msg>, abort. On a PDF latexmk just produced this usually means a truncated PDF, so recompile before blaming the rasterizer.
latexmk or gs off PATHSETUP_MISSING:<tool> at preflight, stop.
Reply is neither APPROVED nor a parseable listRe-prompt once with "Please respond in the required format." On a second drift, abort and surface the raw reply.
Subagent times outFailed round. Surface the scratch path for a retry.
Same fix twice runningOscillation. Stop, surface both renders.
Hit --max-iterSurface last PNG, outstanding items, in-progress .tex.

Example

A four-node DAG at ~/scratch/causal-dag.tikz, --goal="X -> Y with mediator M and confounder U". Round 1: the reviewer measures M at 0.09cm from the X->Y edge against a 0.30cm minimum, and finds U->Y drawn with -- while the other three edges use ->. Both edits apply cleanly. Round 2: APPROVED. A parallel-trends figure behaves the same way, with the reviewer comparing the pre-period slope against the dashed counterfactual's and flagging the mismatch numerically.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most review quality skills give in ~2.1k tokens

Counted across 1,048 of the 1,783 authors here whose files we hold, read 2026-08-07

  • Ask questions one at a timein 81 of 1048, across 64 files
  • Provide a recommended answer for each questionin 73 of 1048, across 50 files
  • Explore the codebase instead of asking answerable questionsin 66 of 1048, across 42 files
  • Resolve dependencies between decisions one-by-onein 42 of 1048, across 17 files
  • Interview the user relentlessly about the planin 38 of 1048, across 13 files
  • Order findings by severityin 31 of 1048
  • Resolve each branch of the decision treein 27 of 1048, across 5 files
  • Run a grilling sessionin 26 of 1048, across 5 files
  • Update CONTEXT.md immediately when a term is resolvedin 26 of 1048, across 11 files
  • Propose precise canonical terms for vague languagein 25 of 1048, across 7 files
  • Create documentation files lazilyin 24 of 1048, across 5 files
  • Assign severity to every findingin 24 of 1048

Said here and by no other author read

  • wrap bare snippets in a standalone document
  • compile diagrams with latexmk
  • render pdfs to png with ghostscript
  • check rendered png dimensions with sips
  • scale dpi if png dimensions are out of bounds
  • pass rendered png to tikz-reviewer subagent

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,629. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.