Adds schedule_create, schedule_list and schedule_cancel tools in the
opencode namespace so the agent can schedule prompts back into its own
session. schedule_create accepts `every` (30s/15m/2h/1d), `at` (ISO 8601
with offset) for a single run, or both (`at` sets the first run).
SessionSchedule now stores multiple schedules per session, keyed by a
new `sch_` ID, and persists the absolute next fire time instead of only
the interval. This replaces the one-schedule-per-session model and fixes
restarts resetting the countdown: one-shots fire at their original time
after a restart, and overdue recurring schedules fire once then resume
their cadence rather than bursting. `/schedule off` now cancels every
schedule in the session. Past `at` times, missing timing and invalid
intervals return tool errors.
Verified with an isolated managed-mode server and a scripted
OpenAI-compatible mock model driving `execute`: create every 5s fired
every 5s; `at` fired at 15:55:42.013 for a 15:55:42 target; a one-shot
created before a restart fired on time after it (15:56:23.013); list
returned both schedules with server time; cancel stopped firing; invalid
inputs returned the three expected errors. core and server typecheck.
Moves schedule timers out of the per-Location plugin into a new global
SessionSchedule service. Previously timers lived in the Location's plugin
scope, so they stopped on server restart until something reloaded the
Location, and stopped whenever the Location was evicted after 60 minutes
of inactivity. Timers now live in the global service and call
Session.prompt, which loads the Location on demand, so schedules fire
even when the session is not open.
- SessionSchedule persists entries in KV (session.schedule/<id>) and
exposes set/remove/resume. A deleted session ends its schedule.
- The managed server calls resume at boot next to restart continuity;
unmanaged servers sharing the database do not restore schedules.
- The opencode.schedule plugin now only registers /schedule and
delegates to the service; the per-Location restore logic is removed.
Verified: core and server typecheck; against an isolated managed-mode
server, a 5s schedule fired every 5s, resumed after a restart with no
client touching the session, and `/schedule off` stopped the
boot-restored timer. Server tests: 3 OpenAI OAuth port tests fail
identically without this change.
Adds a minimal built-in plugin (opencode.schedule) that registers
`/schedule <30s|15m|2h> <prompt>` and `/schedule off`. Each schedule is
saved in plugin storage keyed by session ID and re-queues the prompt with
delivery "queue" on a fixed interval, modeled on the warming plugin loop.
When a location loads, the plugin restarts only schedules whose session
belongs to that location, so a session is never double-scheduled.
Known gaps (prototype): schedules resume after a server restart only once
something loads the session's location, and intervals longer than the
60-minute location inactivity TTL stop when the location is evicted.
Verified: core typecheck passes; against an isolated `serve` instance, a
5s schedule admitted prompts every 5s, stopped across a restart, and
resumed after the session's location was reloaded by a manual prompt.