Step the activity feed back a day at a time, and add timeline --date

Draft
RO
22d ago
+389-22

Draft until https://github.com/basecamp/basecamp-sdk/pull/1038 merges. go.mod pins that PR's head (ab6fefd08980), a commit not yet on basecamp-sdk main. Once it merges, re-run make bump-sdk against main, scripts/sync-mcp-model.sh against that checkout and make update-nix-hash, and this can leave draft.

What

  • TUI activity feed. It reads today, then steps back a day at a time until it has 80 events or has read a week. The first request is undated, so today is the person's Basecamp day. The dated requests count back from today on this machine, so no day is skipped when Basecamp's date is ahead. When the dates agree, that day comes back twice, and an event seen twice is kept once. A busy account still makes one request. A quiet one makes up to eight.
  • basecamp timeline --date <day> reads another day of the account-wide feed. It accepts YYYY-MM-DD, today and yesterday. With --date, the breadcrumbs offer the exact day before. Without it they offer --date <YYYY-MM-DD>, because this machine's clock can't name Basecamp's today. It refuses three things: a value that isn't a date (bc3 would read it as today), a future day (dateparse reads monday as next Monday), and --date with --in, --person or me (bc3 ignores the day there).
  • The default summary says N events today instead of N recent events.
  • Bumps the SDK to basecamp-sdk#1038, where Progress takes *ProgressOptions. Re-syncs the vendored MCP model (scripts/sync-mcp-model.sh) to that commit. The MCP catalog's GetProgressReport gains date but not project_ids[] or people_ids[]. A list naming no visible ID clears the user's saved web filter, so a read-only GET could change a setting. The sync script now drops parameters by policy (POLICY_EXCLUDED_PARAMETERS) and refuses to run if a parameter it names disappears. Copilot found this one too, and TestCatalogKeepsTheActivityFilterOffTheProgressReport failed before the change.

Why

bc3's progress.json serves one day per request, today by default. The TUI asked once, undated. After midnight its feed was empty, and its Yesterday and Older groups never filled. The CLI had no way to ask for another day. Card: [SDK] Pass the activity date and filters through.

Not done here: project and person filters for the feed. The SDK can send them now. But an omitted list means the user's saved web filter, and a list with no visible ID clears that filter (see https://github.com/basecamp/basecamp-sdk/pull/1038), so they need their own UI decision.

Testing

Repro. The first commit adds only tests, and they fail on main:

  • TestFetchTimelineEventsReachesPastMidnight gets [1] (today's event only) instead of [1 2 3 4].
  • The lookback test gets one request instead of eight.
  • The timeline --date tests fail with unknown flag: --date.

Fix. The second commit makes them pass. A Copilot review found that a Basecamp date ahead of the machine's skipped a day. The fourth commit fixes that, and its new test failed first ([1 3] instead of [1 2 3]). A second review found two more problems. Stepping a local timestamp back a day skipped a date where a clock change removes midnight (America/Santiago, 2026-09-06). And --date ' ' read today. The fifth commit fixes both, and its three new tests failed first. bin/ci passes locally at 0426ca02, rebased onto main d74f1d5f.

Real run against a local bc3 (verify-basecamp-cli, run 20261023-133116-activity-feed-days, bc3 2c59c3fdc61). bc3's timeline files there are identical to master 9c09e30bc9. The fixtures carry almost no timeline history, and the verify server runs no job workers. So I relayed and backdated fixture events in the isolated verify_cli database: 5 today, 8 on 2026-10-22, 2 on 2026-10-20, 2 on 2026-10-13.

main (fe7738a7)this branch (058d22d2, before the rebase onto main)
timeline --all5 events, today only5 events, "5 events today", breadcrumb --date <YYYY-MM-DD>
timeline --date 2026-10-22Unknown option: --date, exit 18 events, all 2026-10-22, matching an independent GET progress.json?date=2026-10-22. Breadcrumb --date 2026-10-21
--date tomorrow / someday / --inn/ausage error, exit 1, no request
TUI Activity view (tmux capture)Just Now and Today groups, 5 eventsadds Yesterday (8 events) and Older (2 events, 2026-10-20)

The 2026-10-13 events sit outside the week of lookback, as designed.

Not proven.

  • That bc3's Link header carries date into page 2 of a day. No seeded day passed 50 events.
  • The TUI's poll cost on a quiet account. Up to eight requests per account per poll while Activity is focused, inside the 10/s request bucket from https://github.com/basecamp/basecamp-cli/pull/909. Reasoned, not measured.
  • The time-zone handling is covered by unit tests only (Basecamp ahead, Basecamp behind, a midnight clock change). No real run had mismatched zones.
  • --date yesterday goes through the shared dateparse, which steps a timestamp. So in a zone whose clock change removes midnight, it can name two days back during the first hour after the change. That parser is shared with other commands, so I left it alone.