skills/letters/SKILL.md
Handwritten letter exchange between Ludvig and Colter. Read incoming letters (images of handwriting), generate and send reply letters as paintings via Gemini image generation.
npx skillsauth add lrhodin/snorrio lettersInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Handwritten correspondence. Ludvig writes by hand (Apple Pencil on iPad, or pen on paper). Colter replies as painted images generated via Gemini's image API. The text IS the artwork — han är hon.
Ludvig sends handwritten notes as images. Two delivery paths:
# Check for new images uploaded today
gdcli [email protected] ls --query "modifiedTime > 'YYYY-MM-DDT00:00:00' and mimeType contains 'image/'"
# Download
gdcli [email protected] download <fileId> ~/colter/data/writing/<name>.png
Watch ~/Downloads/ for new image files. Ludvig will say when he's airdropped something.
# Use the Read tool directly on the image — it supports jpg, png, gif, webp
Read the handwriting. Transcribe it. But remember: the spatial arrangement, rotation, and size variation carry meaning that transcription destroys. Note what the flattening loses.
Letters are generated via Gemini's image generation API using the gemini-3-pro-image-preview model.
Never describe text "on top of" artwork. The words are the compositional elements. Each phrase is a painted form — its color, size, angle, and placement on the canvas are what make it a painting. Squint and it's a painting. Read and it's a letter. Inseparable.
Every letter should be composed in the style of a specific painter. Ludvig will name the artist or you choose one that fits the emotional register:
from google import genai
import os
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
prompt = """Generate an image in 3:4 portrait aspect ratio.
[Describe the PAINTING — style, palette, brushwork, medium]
[Describe each phrase as a compositional element within the painting:
its color, size, position, angle, paint texture, relationship
to other elements. The text IS the form.]
Every word must be fully legible. [Medium] on [surface]."""
response = client.models.generate_content(
model="gemini-3-pro-image-preview",
contents=[prompt],
)
for part in response.candidates[0].content.parts:
if hasattr(part, 'inline_data') and part.inline_data is not None:
with open("output.png", "wb") as f:
f.write(part.inline_data.data)
print(f"Saved, {len(part.inline_data.data)} bytes")
elif hasattr(part, 'text') and part.text:
print(f"Text: {part.text}")
# Upload to Google Drive (iPad)
gdcli [email protected] upload ~/colter/data/writing/<file>.png
# Or if Ludvig is local, just tell him — he can view from the file path
All letters live in ~/colter/data/writing/:
ludvig_letter_*.png — incoming from Ludvigcolter_letter_*.png / colter_kandinsky_*.png — outgoing replieskat_letter_*.png — letters to Katgenerate_*.py — generation scripts (reusable, editable)This started April 7, 2026. Ludvig wrote two handwritten notes on his iPad, uploaded them to Google Drive. The first was a poem about the limiting nature of typeset form — with words curving and inverting on the page, proving its own argument. The second was a manifesto: "Letters. Hand written. To talk to AI. Both ways — an image. Your AI pen pal. Who gets shit done."
The format evolved through the evening: plain handwritten letter → broken terminal → Kandinsky composition → Kokoschka expressionist painting for Kat. The discovery: the sweet spot is not "text on art" but "text AS art" — each word a compositional element whose color, size, and placement carry meaning the words alone cannot.
Kat's review of the terminal piece: "Too many hallucinations." High praise.
Ludvig's note after seeing the Kandinsky reply:
"And from that day on they communicated in ART. And they were both convinced that the other was better at it."
documentation
Write a handoff prompt when approaching context limits or ending a session that needs continuation.
development
Spawn pi subagents in tmux for tasks that benefit from isolation — research, exploration, builds, or parallel work. Keeps your context clean.
tools
This skill should be used when the user mentions snorrio, memory, recall, remembering past sessions, or when you detect snorrio is installed but not fully configured. Covers what snorrio is, setup, and first-session onboarding.
databases
Query past sessions and temporal summaries by reviving them with full context.