Scheduled tasks
A scheduled task is a prompt and a cadence: “every weekday at 02:30, triage today’s new issues”. spwn runs it without you, headlessly and read-only, in a session of its own, and flags that session when it’s done so the result is waiting for you.
From the panel
Section titled “From the panel”Open a project’s ◷ Scheduled Tasks row in the sidebar and click + New Task:
- Name and Prompt: what the agent should do. It can read the project; it can’t edit files.
- Time: local time of day.
- Days: pick weekdays, or none for every day.
- Use project context: prepend the project’s Merge tray (on by default).
Each task has Run now, Disable / Enable, Edit and Delete, and shows when it last ran.
From a file
Section titled “From a file”A task can live in the repository instead, as .spwn/schedules/<name>.toml:
name = "Nightly triage" # optional; the file stem otherwisetime = "02:30" # local time, 24h HH:MMweekdays = [1, 2, 3, 4, 5] # 0 = Sun … 6 = Sat; omit for every dayenabled = true # optional, default trueuse_context = true # optional, default trueprompt = """Triage today's new issues and comment on anything that looks like a duplicate."""prompt and time are required. Unknown keys are an error, so a typo like uses_context
is reported rather than silently ignored. A file that doesn’t parse still appears in the
panel, disabled, with its error.
spwn watches .spwn/schedules, so adding, editing or pulling a file takes effect straight
away. Commit it to share the task with your team, or leave it untracked to keep it to this
machine. spwn never writes into the file; when it last ran is kept in spwn’s own store. The
panel shows file tasks read-only, with Run now, and you change them in the file.
What a run does
Section titled “What a run does”When a task fires, spwn:
- adds a session to the project titled
◷ <task name>, - gives it its own worktree and branch off the project’s current branch (through the
session-createdhooks, with any hook prompt declined), or runs in the project folder if it isn’t a git repo, - starts the default agent headlessly with a first turn made of the Merge tray’s blocks (if
use_contextis on and the tray isn’t empty) followed by the prompt, - flags the session for your attention when the run ends, successfully or not.
For Claude the headless command is claude -p … --permission-mode plan, which is what keeps
the run read-only. The run is an ordinary rmux pane, so you can open the session and watch it
work, and it survives a restart of spwn. The finished session stays until you delete it.
A task never runs twice at once.
Missed runs
Section titled “Missed runs”Tasks fire only while spwn is running; it checks every 30 seconds. If spwn was down when a task was due, it runs once when spwn comes back, however many occurrences it missed. It catches up the most recent occurrence within the last week.
A file task spwn has never seen is the exception. Pulling a branch with five schedule files shouldn’t fire five runs for times before the files existed, so a new file task waits for its next occurrence. Use Run now if you don’t want to wait.
use_context
Section titled “use_context”The Merge tray is the project’s reusable context space: notes, files and turns you’ve
collected from sessions. With use_context on, each run starts with those blocks,
assembled into Markdown, then ---, then your prompt. That’s how a nightly task knows the
conventions you’ve written down without repeating them in every prompt. Turn it off for a
task that should see only its prompt.