| name | annotate |
| description | Apply annotations to an image — arrows, text callouts, boxes, highlights, numbered markers — driven by a JSON spec. Originals are never modified; output goes to <input_dir>/annotated/<stem>_annotated<ext> by default. |
Annotate
Apply visual annotations to an existing image file via the bundled Pillow-based annotator.
Originals-clean rule (non-negotiable)
This skill never modifies the original image unless the user explicitly says so. Default output behaviour:
- If
--output is given, write there.
- Else, write to
<input_dir>/annotated/<stem>_annotated<ext> (directory created if missing).
--in-place overwrites the input. Only pass this when the user has explicitly confirmed they want the original replaced.
This rule is enforced by scripts/annotate.py. Do not bypass it by calling ImageMagick directly to write back over the input.
Just run the script
- Build a JSON spec describing the operations and write it to a temp file (e.g.
/tmp/annot-spec-<random>.json).
- Invoke the annotator:
python3 "$CLAUDE_PLUGIN_ROOT/scripts/annotate.py" \
--input "$INPUT" \
--spec "$SPEC_JSON" \
[--output "$OUTPUT"]
[--in-place]
- The script prints the output path on success. Delete the temp spec file.
Spec format
{
"operations": [
{"type": "arrow", "from": [100, 200], "to": [300, 200], "color": "red", "width": 4},
{"type": "box", "xy": [50, 50, 200, 100], "color": "red", "width": 3},
{
Coordinates are pixels from the top-left of the image.
Defaults to assume when the user is loose
color: red for arrows/boxes/markers; yellow for highlights.
- Text on busy backgrounds: keep
"background": true (translucent white pad with red outline) unless the user says otherwise.
- Font: bundled DejaVu Sans Bold (always present after
install-deps).
When the user wants something simple
For a one-shot "draw an arrow at X→Y", still go through this script with a one-op spec. Don't reach for a separate ImageMagick invocation — keeping a single code path keeps the originals-clean rule airtight.