Sync iMessage contacts into wiki person pages following STYLE.md. Use when Kevin says "sync iMessage", "update people pages", "add people from messages", "who am I texting most", or wants to bring person pages up to date with recent contacts. Reads ~/Library/Messages/chat.db, ranks 1:1 contacts, resolves names via AddressBook, drafts pages preserving Kevin's voice.
Sync Kevin's iMessage contacts into the wiki at ~/Documents/GitHub/kevin-wiki/wiki/people/. Follows the voice/style rules in wiki/people/STYLE.md.
state.json → syncs.imessage)chat.db — macOS Full Disk Access required. Always run extraction from a real terminal (Terminal.app or iTerm) with FDA enabled. Tell Kevin to run the script himself the first time.raw/imessage/ is gitignored. Extractions stay local. Person pages in wiki/people/ ARE committed.cd ~/Documents/GitHub/kevin-wiki && ./scripts/sync-imessage.shOutputs to raw/imessage/<YYYY-MM-DD>/:
top-contacts.json — ranked 1:1 contacts (last 365d, ≥10 msgs)contacts/<handle>.md — per-contact metadata + recent message samplescontacts.json — Address Book records for name resolutionTunables via env vars: LOOKBACK_DAYS_STATS, LOOKBACK_DAYS_SAMPLES, MIN_MSG_COUNT, TOP_N, SAMPLES_PER_CONTACT.
Use scripts/resolve-imessage.py (or recreate it) to:
top-contacts-annotated.jsonUse scripts/build-people-plan.py (or recreate it) to assign tiers:
| Tier | Threshold | Page depth |
|---|---|---|
| 1 | ≥400 msgs OR family/partner | Full STYLE pages, 50–80 lines, rich personal sections, multiple Kevin quotes woven in |
| 2 | 100–400 msgs with identifiable context | Medium pages, 30–45 lines, focused thread + 1–2 quotes |
| 3 | <100 msgs OR thin context | Stub pages, 15–25 lines, factual sketch only |
Promotion overrides:
For Tier 1 / Tier 2, ALWAYS read the contact's contacts/<handle>.md file in full before drafting. The voice texture is in the messages.
For Tier 3, can use the stub generator: scripts/gen-t3-stubs.py (or recreate it). Stubs auto-write factual metadata + 1-paragraph relationship sketch using the first 3 sample messages.
Read wiki/people/STYLE.md BEFORE writing. Two registers:
The personal section should sound like Kevin talking about the person, converted to third person — not the agent describing from outside.
---
title: Full Name
type: person
created: YYYY-MM-DD
updated: YYYY-MM-DD
source: raw/imessage/<date>/contacts/<handle>.md
tags: [person, ...context]
aliases: ["Nickname", "+phone", "email@example.com"]
tier: 1 | 2 | 3
related: ["[[USER]]", "[[other-page]]"]
---
# Full Name
> One-line summary in Kevin's framing.
## Background
{Factual register}
## How Kevin Knows Them
{Personal register, paragraphs, Kevin's voice}
## Relationship
{Personal register, paragraphs with direct quotes from Kevin and them}
## Notable
{Bullets OK here — quirks, opinions, catchphrases}
---
## Timeline
- **YYYY-MM-DD** | What happened. [Source: iMessage, YYYY-MM-DD]first-last.md kebab-casedavid-liu-princeton.md vs david-li.md vs Kevin's brother matthew-liu.mdyu-liu.md, haiying-tang.md)tal-princeton.md (disambiguate from any future Tals)After writing pages:
wiki/_index.md (use gen-people-index.py)wiki/log.md with ## [YYYY-MM-DD] ingest | iMessage syncstate.json syncs.imessage to today's datewiki/people/STYLE.md if new Kevin phrasings surfacedSome threads contain heavy emotional content (breakups, friend-group conflicts, vulnerable disclosures). Default rules:
Per AGENTS.md "Notability Gate":
m.text and stores message in m.attributedBody binary plist. Add Python plist decoder to recover those.raw/calendar/, raw/email/, raw/meetings/ to thicken person pages.This skill expects (or creates) the following at the wiki repo:
scripts/sync-imessage.sh — extraction (committed)scripts/resolve-imessage.py — name resolver (recreate as needed)scripts/build-people-plan.py — tier assignment (recreate as needed)scripts/gen-t3-stubs.py — stub generator (recreate as needed)scripts/gen-people-index.py — index regenerator (recreate as needed)Recreate the helper scripts inline if missing — they're idempotent and short. The shell extraction script is the only one that must persist.