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>
This commit is contained in:
aj.siegel
2026-09-21 23:05:57 -04:00
parent 339f9b1034
commit 20d8c1aedc
8 changed files with 229 additions and 59 deletions

View File

@@ -30,12 +30,11 @@ 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
This Notion MCP has no filter/query tool and `view://` URLs aren't fetchable, so use the search → fetch → filter pattern (see CLAUDE.md "HOW TO QUERY THESE DATABASES"). Do NOT try to fetch views and do NOT print any "falling back" message.
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. **Find candidate tasks** — `notion-search` the Tasks collection `collection://2c0abd6c-450a-8085-80a0-000ba136a154` with `page_size: 25`, `max_highlight_length: 0`, and a `query` seeded with the focus-project names plus "blocking due this week suggested today".
3. **Fetch candidate task pages in parallel** to read their real properties (`Status`, `Suggested for today`, `Due date`, `Blocking`, `Priority`, `Project`).
4. **Filter & rank locally**: drop `Status` = "Done" or "Blocked". Rank the rest by (1) `Blocking` populated, (2) `Suggested for today` ≤ tomorrow, (3) soonest `Due date`.
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.
@@ -46,8 +45,8 @@ Format the note with the following sections:
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. `notion-search` the Tasks collection (`collection://2c0abd6c-450a-8085-80a0-000ba136a154`) filtered/queried for `Top Task` = true (or check the pages already known from recent notes) to find any tasks still marked from a prior day.
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 (it can't be, since Step 3.4 already drops Done tasks). Don't wait for a replacement to unmark a completed task.
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.