<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rulesets/.ai/scripts/upcoming_birthdays.py, branch main</title>
<subtitle>Claude Code skills, rules, and language bundles
</subtitle>
<id>https://git.cjennings.net/rulesets/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/rulesets/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/'/>
<updated>2026-07-18T23:22:32+00:00</updated>
<entry>
<title>feat(daily-prep): add upcoming-birthdays block from contacts.org</title>
<updated>2026-07-18T23:22:32+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-18T23:22:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=80ebb74e4f3f35c2204ba5fee8c48bf5d18f0559'/>
<id>urn:sha1:80ebb74e4f3f35c2204ba5fee8c48bf5d18f0559</id>
<content type='text'>
New stdlib-only upcoming_birthdays.py reads ~/sync/org/contacts.org for :BIRTHDAY: properties and prints a daily-prep block: name, date, days-away, and the age turned when the birth year is known (1900 is the org-contacts unknown-year placeholder, rendered date-only). Birthdays inside 7 days come back flagged so a gift or plan gets prompted. 19 pytest cases cover the window boundaries, leap-day fallback to Feb 28, the placeholder year, and the CLI.

daily-prep gains a Phase A source that runs the script and a Heads-Up line that folds in the block, so contact birthdays the calendar doesn't carry still surface.

Built and tested in the home project. Promoted here because the daily-prep hook lives in this synced workflow and the contacts file is present on every machine.
</content>
</entry>
</feed>
