Skip to content

feat: support daily and weekly zoned schedules - #2656

Merged
nicobailon merged 6 commits into
nicobailon:mainfrom
quifox:feat/calendar-schedules
Oct 3, 2026
Merged

nicobailon merged 6 commits into
nicobailon:mainfrom
quifox:feat/calendar-schedules

Conversation

@quifox

@quifox quifox commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Fixed duration schedules cannot preserve a local clock time across daylight-saving changes or express selected weekdays. Add daily and weekly schedules with an explicit IANA timezone, HH:mm and weekday selection. Missing local times are skipped; repeated times use their first instant. Pending local dates survive restoration, and existing catch-up, manual, quiet and mission controls apply.

Validation: typecheck, package build, focused calendar/scheduler/schema tests, native Pi tool-activation smoke, clean packed-package DST smoke and independent review passed on Linux Node 24. Checks were repeated after rebasing onto 0.75.0, including the unchanged schema size budget. Existing Linux/Windows CI runs these tests; a focused macOS calendar job is added. Required exact-head CI remains pending. Local fresh-process import median increased by approximately 25 ms in a seven-sample comparison.

Cross-session schedule-store concurrency and lock recovery remain separate work; this feature does not establish cross-session scheduling reliability.

Related: #815.

CI update: all checks on 85c06a51 passed, including the full Linux/Windows suites, the focused macOS calendar/scheduler job, native tool activation, and clean-install/standalone jobs.

Review follow-up: if a natural calendar fire advances the cursor while a manual attachment is pending and that attachment fails, restore both nextLocalDate and nextRunAt on the latest schedule record. A pause issued during attachment remains effective, and successful manual overlap still consumes exactly one date.

Validation: typecheck, package build and 74 focused calendar/scheduler tests pass on Linux. New regressions cover failed manual overlap, retry of the pending natural fire and pause preservation; existing successful-overlap and interval/one-shot tests remain green. The calendar macOS job and full Linux/Windows suites will validate the appended commit.

Follow-up head: 75105ee8.

CI update for 75105ee8: all 16 configured checks passed, including full Linux/Windows suites, macOS calendar/scheduler coverage, native tool activation and standalone/clean-install jobs. The complete Linux unit suite also passed (3,686 passed, 15 existing skips).

Maintainer review follow-up (0eebf73f): load the Temporal polyfill synchronously through createRequire only at the first calendar calculation and cache the result. Type annotations use a type-only import; bind and restore stay synchronous. Remove docs/design/calendar-schedules.md; the shipped interface remains documented in the missions and tool reference pages. Keep the macOS calendar-timezones job.

Validation: typecheck, package build, 86 calendar/scheduler/mission/store tests and both tool-activation smoke tests passed. A fresh-process regression rejects an eager ESM polyfill import and verifies no runtime load during rule normalization, then synchronous loading and reuse at calendar evaluation. The compiled extension also imports without loading the polyfill and evaluates the first calendar occurrence successfully.

No-calendar import measurement on Linux Node 24.19.0, alternating before/after in fresh processes with seven samples each: extension import median 1140.7 ms before and 1096.6 ms after; calendar module import 53.9 ms before and 34.7 ms after. Wall-clock differences include host noise; the unloaded-module checks verify the eliminated eager load directly. Checks on the appended head are pending.

Integration follow-up (526d1619): merge current main (8fb89814) with an additional merge commit and preserve both changelog contributions. Typecheck, package build and all 86 focused calendar/scheduler/mission/store tests passed again after integration. The new exact-head CI run is 37130623222; cross-platform results are pending.

CI update for 526d1619: all 16 configured checks passed, including full Linux/Windows suites, the macOS calendar-timezone job, native loader and nested-wait checks, and standalone/clean-install jobs (run). The latest code review reports no outstanding findings; the branch has no merge conflicts.

@greptile-apps

greptile-apps Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[High risk] Adds calendar-based scheduling with timezone support.

No outstanding code finding blocks this PR, but merge readiness requires verification of CI on the current head.

Summary

Adds daily and weekly schedules at a specified local time and timezone, with persisted local-date cursors and daylight-saving-time handling.

  • Extends schedule creation, restoration, catch-up, manual-run behavior, schemas, documentation, and focused tests.
  • Adds a macOS calendar regression job and contributor credit.
  • The supplied CI results cover the previous head; required CI on 42e2208f remains a merge gate until verified.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Rule[Daily or weekly local-time rule] --> Occurrence[Resolve next local date in timezone]
  Occurrence --> Store[Persist date and UTC fire time]
  Store --> Timer[Timer or restoration]
  Timer --> Run{Due and eligible?}
  Run -->|Yes| Launch[Launch workflow and advance cursor]
  Run -->|Missed or overlapping| Advance[Record outcome and advance cursor]
Loading

Reviews (5) · Last reviewed commit: "Merge main into calendar schedules"

Comment thread src/runs/background/scheduled-runs.ts Resolved
@nicobailon

Copy link
Copy Markdown
Owner

Reviewed at 75105ee8. Calendar recurrence is part of the #815 plan, and the scheduler logic held up: DST gaps and folds, Lord Howe, Apia's skipped date, catch-up, the manual-overlap restore, and pause during attachment all check out, and the 92 focused tests pass. Two changes before merge:

  1. Load the polyfill only when a calendar schedule is evaluated. src/extension/index.ts → scheduled-runs.ts → calendar-schedule.ts imports @js-temporal/polyfill statically, so every extension load pays for it, even with no calendar schedules. Measured on Node 24.21 with seven fresh imports each: median 623.6 ms on main, 642.6 ms on this head (+19 ms; the polyfill alone is about 14.7 ms). A synchronous lazy load (for example createRequire(import.meta.url) of the package's CommonJS build, cached on first use) keeps bind/restore synchronous; use type-only imports for annotations. Please re-measure the no-calendar import after the change.
  2. Drop docs/design/calendar-schedules.md. It reads as a working brief (implementation touchpoints, prototype results, delivery notes, and the separate stale-state fix plan) rather than user documentation, and docs/design/ doesn't exist on main. docs/missions.md and docs/tool-reference.md already cover the shipped behavior.

The macOS calendar-timezones job is worth keeping. If I don't see an update by 2026-10-03 22:00 UTC, I'll push these two changes to your branch myself and keep your authorship and credit.

@nicobailon
nicobailon merged commit a4b1fb9 into nicobailon:main Oct 3, 2026
17 checks passed
@nicobailon

Copy link
Copy Markdown
Owner

Merged, thanks @quifox. The lazy load holds up: no measurable import cost on main, and it works under all five loaders the review tried. While merging main I kept both new macOS CI jobs, and I folded the lazy-load changelog line into the feature entry, since calendar schedules have not been released yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants