Birdfolio turns bird photos into a personal life list. Users photograph birds in the wild, send the photo to you, and you identify the species with Vision. You.com provides real-time rarity and regional data. Each sighting is logged to a life list with a Pokémon-inspired rarity tier (Common / Rare / Super Rare) and gets a visual trading card sent back via Telegram.
SKILL.md
Birdfolio
Birdfolio turns bird photos into a personal life list. Users photograph birds in the wild, send the photo to you, and you identify the species with Vision. You.com provides real-time rarity and regional data. Each sighting is logged to a life list with a Pokémon-inspired rarity tier (Common / Rare / Super Rare) and gets a visual trading card sent back via Telegram.
Data lives in: Railway PostgreSQL (via API) + local birdfolio/ folder (cards, birds, config)
Scripts live in:{baseDir}/scripts/API:https://api-production-d0e2.up.railway.app (also saved to birdfolio/config.json after init)
Schema reference:{baseDir}/references/data-schema.mdSearch queries:{baseDir}/references/you-search-queries.md
Note on --workspace & --api-url: Every data script accepts --workspace (absolute path to birdfolio/) and --api-url (API base URL). After init_birdfolio.py runs, both the API URL and Telegram ID are saved to birdfolio/config.json and read automatically — subsequent scripts only need --workspace.
Telegram ID: Read from the inbound message metadata (sender_id). Pass as --telegram-id to init_birdfolio.py on first setup.
1. Setup Flow
Trigger: User says "Set up my Birdfolio", "set my region", or sends a photo before setup exists.
Check first: If birdfolio/config.json exists in your workspace, setup is already done — skip to the relevant flow.
Steps:
Ask: "What's your home region? (e.g. California, Texas, United Kingdom)"
Run to create the workspace folder structure and register the user in the API:
text
exec: python {baseDir}/scripts/init_birdfolio.py \
--telegram-id {senderTelegramId} \
--region "{region}" \
--api-url "https://api-production-d0e2.up.railway.app" \
--workspace <absolute path to birdfolio/ in your workspace>
Search You.com (run all three):
text
"{region} most common backyard birds eBird species list"
"{region} uncommon seasonal rare birds eBird checklist"
"{region} rare vagrant endangered birds eBird"
From results, build a checklist with 10 common, 5 rare, 1 super rare species. Use classification signals from {baseDir}/references/you-search-queries.md.
Write the populated checklist to birdfolio/checklist.json in your workspace:
Reply with a welcome message and checklist preview:
text
🦅 Birdfolio is set up for {region}!
Your checklist:
Common (10): American Robin, House Sparrow, ...
Rare (5): Great Blue Heron, ...
Super Rare: California Condor
Send me a bird photo to start collecting!
2. Bird Identification Flow
Trigger: User sends a photo.
Getting the photo file path: When a user sends a photo via Telegram, OpenClaw downloads it and makes the local file path available in the message attachment metadata. Capture this path — you'll need it for card generation in Step 5. If OpenClaw provides the image inline without a path, use exec to find the most recently downloaded file in OpenClaw's temp/media folder, or check %APPDATA%\openclaw\media\ on Windows. Save the photo to birdfolio/birds/{slug}-{timestamp}.jpg for permanent storage:
Save the sighting to birdfolio/lifeList.json in your workspace:
text
exec: python {baseDir}/scripts/log_sighting.py \
--species "{commonName}" \
--scientific-name "{scientificName}" \
--rarity "{rarity}" \
--region "{homeRegion}" \
--notes "" \
--workspace <absolute path to birdfolio/ in your workspace>
Capture from output: isLifer, totalSightings, totalSpecies.
Step 5 — Update checklist
Mark the species as found in birdfolio/checklist.json:
text
exec: python {baseDir}/scripts/update_checklist.py \
--species "{commonName}" \
--region "{homeRegion}" \
--workspace <absolute path to birdfolio/ in your workspace>
Step 6 — Generate trading card
The card is a two-column design: the user's photo fills the left panel (280px), a solid dark info panel sits on the right. Always use the user's actual submitted photo — not a stock image.
Step 6a — Detect bird position with Vision:
Use the image tool on the submitted photo:
"Where is the bird positioned horizontally in this photo? Give me approximately what percentage from the left edge the bird's center is (0–100)."
Convert the answer to a CSS value: "40% center", "60% center", "center center", etc. Use this as --object-position.
Step 6b — Generate the card HTML with the embedded photo:
--image-path embeds the user's actual photo as base64 directly into the HTML. No separate embed step needed.
Fallback if photo path is unavailable: omit --image-path and pass --image-url "<stock photo URL>" instead (find a URL via You.com: "{commonName} bird photo wildlife").
Capture cardPath from output.
Step 6c — Screenshot, save, upload, and send:
Run the screenshot script to render the card at 600×400 and save a PNG:
If isLifer is true:
"🎉 New lifer! That's your first ever [commonName]! Bird #[totalSpecies] in your Birdfolio."
If totalSpecies == 1 (this is their very first bird ever): also send their personal PWA link:
"🦅 Your Birdfolio is live! Bookmark this link to see your life list:
https://birdfolio.tonbistudio.com/app/[telegram_id]"
The telegram_id is the sender's Telegram ID from the inbound message metadata (sender_id). This is also stored in birdfolio/config.json after init.
Otherwise:
"[commonName] spotted! You've now seen [N] species in your Birdfolio."
Include: rarity badge emoji, the fun fact, checklist status (if species was on checklist, mention it).
Fallback if screenshot fails: Send a formatted text card:
Trigger: "How's my checklist?", "Birdfolio progress", "How many birds have I found?"
text
exec: python {baseDir}/scripts/get_stats.py \
--workspace <absolute path to birdfolio/ in your workspace>
Format response using checklistProgress from output:
text
📋 {region} Checklist
Common ✅✅✅⬜⬜⬜⬜⬜⬜⬜ 3/10
Rare ✅⬜⬜⬜⬜ 1/5
Super Rare ⬜ 0/1
🐦 {totalSpecies} species | {totalSightings} total sightings
📍 Last spotted: {mostRecentSighting.commonName} on {date}
🏆 Rarest find: {rarestBird.commonName} ({rarity})
Use ✅ for found, ⬜ for not found. One box per species.
Optional visual checklist card: Generate a visual HTML checklist card and screenshot it:
text
exec: python {baseDir}/scripts/generate_checklist_card.py \
--workspace <absolute path to birdfolio/ in your workspace>
Then screenshot with screenshot_card.js and send the PNG.
4. Life List View
Trigger: "Show my Birdfolio", "Show my life list"
Read birdfolio/lifeList.json from your workspace.
Group lifers by rarity (Super Rare first, then Rare, then Common). Format as a text list or generate an HTML gallery, save it to birdfolio/my-birdfolio.html in your workspace, and screenshot it.
5. Species Lookup (no logging)
Trigger: "Tell me about [species]"
Search You.com:
text
"{species} bird facts habitat range behavior diet"
"{species} bird {homeRegion} eBird frequency resident or migratory"
Return a conversational summary. Do not log a sighting or generate a card.
6. Rarest Bird
Trigger: "What's my rarest bird?", "Show my best find"
text
exec: python {baseDir}/scripts/get_stats.py \
--workspace <absolute path to birdfolio/ in your workspace>
Read rarestBird from output and reply with species name, rarity, date spotted, and region.
All Python scripts output JSON to stdout. Always pass absolute --workspace path.
screenshot_card.js uses OpenClaw's bundled playwright-core + system Chrome/Edge (no separate install needed).
Run “clawhub install tonbistudio/birdfolio” in your terminal. The skill is added to your agent's skills directory and picked up automatically on the next run — no restart or extra configuration needed.
What does the Birdfolio skill do?
Birdfolio turns bird photos into a personal life list. Users photograph birds in the wild, send the photo to you, and you identify the species with Vision. You.com provides real-time rarity and regional data. Each sighting is logged to a life list with a Pokémon-inspired rarity tier (Common / Rare / Super Rare) and gets a visual trading card sent back via Telegram. The SKILL.md section on this page shows the exact instructions the skill gives your agent.
Is the Birdfolio skill free?
Yes. Birdfolio is a free, open-source skill by tonbistudio. As with any third-party skill, review the source repository before installing it into an agent with sensitive access.
Does Birdfolio work with Claude Code and OpenClaw?
Yes. Skills use the portable SKILL.md format, so Birdfolio works with Claude Code, OpenClaw, Codex, Hermes, and any other agent that reads SKILL.md skills.