Files
full-focus/.claude/commands/evening-prep.md
aj.siegel 20d8c1aedc Add fetch_evening_tasks.py script and shared notion_helpers module
Refactors weekly-template's Notion client setup into a shared helper
(with .env/dotenv support and full pagination), and adds a dedicated
evening-prep script so both commands can fall back to script-based
fetching instead of the MCP search/fetch pattern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 23:05:57 -04:00

6.3 KiB
Raw Blame History

Evening Prep

You are given the following context for my day: $ARGUMENTS

Please create a new note in the "Daily Notes" folder.

  • The title should be "Daily Note - YYYY-MM-DD" using today's date.
  • Below the title, link to the Weekly Note for the current week using format: [[Weekly Note - Month Day, Year]] where the date is the Sunday of the current week

Step 1: read tomorrow's calendar events

Use the Microsoft 365 connector's outlook_calendar_search tool to fetch tomorrow's events:

  • afterDateTime: tomorrow at 00:00, beforeDateTime: tomorrow at 23:59
  • query: "*", order: "oldest", limit: 25

🚨 TIMEZONE: The connector returns times in UTC (ISO strings ending in Z). Convert each to Eastern Time before displaying — EDT = UTC−4 (mid-Mar to early-Nov), EST = UTC−5 otherwise. Flag any isAllDay events (PTO/OOO) as out-of-office rather than meetings.

Step 1b: Check tomorrow's Runna workout

Fetch the Runna ical feed (see CLAUDE.md "Data Sources") with curl -sL <url> and find the VEVENT whose DTSTART is tomorrow's date.

  • If one exists: the workout block is 9:00 AM + X-WORKOUT-ESTIMATED-DURATION (fall back to the high end of the duration range in SUMMARY/DESCRIPTION if that field is missing) + a 20-minute shower buffer after.
  • Check that block against tomorrow's calendar events from Step 1. If clear, note AJ is free for the workout and what time he's clear by. If a meeting falls inside the block, flag it by name and time so AJ can decide whether to move, shorten, or skip the workout.
  • If no workout is scheduled tomorrow, skip this silently — do not add a Workout section.

Step 2: Under the Agenda heading

Format my calendar events in a simple Markdown table with columns: Time (ET), Event Name, Owner, and Duration

  • Time should be the FIRST column
  • Put a star next to any events that overlap with other events
  • Put two !! next to any events starting before 9 AM ET or after 5 PM ET
  • Do not include personal appointments that don't affect my work day
  • My work day goes from 9 AM ET to 5:30 PM ET. Use this to determine my availability. Let me know how much unscheduled time I have.
  • Directly beneath the Agenda table, if Step 1b found a workout scheduled tomorrow, add a one-line Workout note stating whether the 9 AM block is clear or naming the conflicting meeting.

Step 3: Get task data

  1. Get this week's focus projects — read the current Weekly Note (Weekly Notes/Weekly Note - <Sunday's date>.md) and use its listed focus projects + weekly goals. (Only if that note is missing: notion-search the Projects collection collection://2c0abd6c-450a-807a-a3d7-000b8d8aaecc with page_size: 25, fetch the results in parallel, and keep those with Focus this week = __YES__ and Status = "Active".)
  2. Get candidate tasks — run python3 scripts/fetch_evening_tasks.py. This already excludes Status = "Done" or "Blocked" and paginates through the full Tasks database, so no candidate is missed as the tracker grows.
  3. Rank locally: by (1) has_blocking true, (2) suggested_for_today ≤ tomorrow, (3) soonest due_date.

If the script errors or is unavailable (e.g. missing .env/NOTION_TOKEN on this machine), fall back instead of failing the command: notion-search the Tasks collection collection://2c0abd6c-450a-8085-80a0-000ba136a154 with page_size: 25, max_highlight_length: 0, seeded with the focus-project names plus "blocking due this week suggested today" (this Notion MCP has no filter/query tool and view:// URLs aren't fetchable — see CLAUDE.md "HOW TO QUERY THESE DATABASES"). Fetch candidate pages in parallel to read Status, Suggested for today, Due date, Blocking, Priority, Project, then filter/rank as in step 3 above. Do NOT print any "falling back" message for view:// fetches, but DO tell me the script failed and you're using the fallback.

Format the note with the following sections:

  1. Under Suggested Tasks list up to 3 tasks from the ranked set above (Blocking-others tasks always come first). For each, show the task name, related project, and a Notion link.
  2. Under Key Projects list this week's focus projects with their weekly goal.
  • If a search legitimately returns no qualifying open tasks, say so plainly — never invent tasks to fill the list.

Step 4: Mark Top Tasks in Notion

The Tasks Tracker has a Top Task checkbox property and a Top Tasks view (filtered to Top Task = true AND Status != Done) for surfacing the current day's Big 3 at a glance. At most 3 tasks may be checked at any time.

  1. Present the Suggested Tasks from Step 3 to AJ and let him confirm or swap any of them before finalizing.
  2. Use marked_top_tasks from the Step 3 script output (already every task with Top Task = true, any status — no extra search needed). If the Step 3 fallback was used instead, notion-search the Tasks collection (collection://2c0abd6c-450a-8085-80a0-000ba136a154) filtered/queried for Top Task = true.
  3. Any currently-marked task whose status = "Done" gets Top Task set to false immediately — regardless of whether it's in today's agreed set. Don't wait for a replacement to unmark a completed task.
  4. For each other currently-marked task that is NOT in today's agreed set, notion-update-page to set Top Task = false.
  5. For each of the (up to 3) agreed tasks, notion-update-page to set Top Task = true.
  6. Never have more than 3 tasks checked at once — unmark old ones before marking new ones.

Note: this only unchecks stale Done tasks when an evening-prep run touches them. It isn't real-time — if AJ marks a task Done in Notion outside of this flow, the checkbox stays checked until the next evening-prep pass (though the Top Tasks view already filters out Status = Done, so it won't show there regardless). True real-time un-checking would need a native Notion automation (Settings → Automations → when Status is set to Done → uncheck Top Task), which isn't something these tools can create.

Formatting Rules

  • Always provide a tl;dr summary at the top of the note
  • Add a "## Table of Contents" section after the frontmatter using Obsidian internal link syntax [[#Heading Name]] for all H2 sections
  • Include all major sections: tl;dr, Agenda, Suggested Tasks, Key Projects, Suggested Reading, etc.
  • Format all date displays as Month, Day Year