opencode-scheduled-tasks 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +287 -0
- package/dist/cli.js +1225 -0
- package/dist/cli.js.map +1 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.js +882 -0
- package/dist/plugin.js.map +1 -0
- package/examples/daily-cleanup.md +16 -0
- package/examples/weekly-report.md +20 -0
- package/package.json +69 -0
- package/skill/SKILL.md +119 -0
package/README.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# opencode-scheduled-tasks
|
|
2
|
+
|
|
3
|
+
Scheduled task runner plugin for [OpenCode](https://opencode.ai). Define recurring tasks as markdown files with cron schedules, or let agents schedule one-off tasks via tool calls. A background daemon executes tasks on schedule via `opencode run`.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### 1. Add the plugin to your OpenCode config
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"plugin": ["opencode-scheduled-tasks"]
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Install the scheduler daemon
|
|
16
|
+
|
|
17
|
+
The daemon runs every 60 seconds and executes any tasks that are due. It auto-detects your platform (macOS launchd or Linux systemd).
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx opencode-scheduler --install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 3. Install the agent skill (optional)
|
|
24
|
+
|
|
25
|
+
This gives the agent context on how to use the scheduling tools, especially around permissions.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx opencode-scheduler --install-skill
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
Create a task file at `~/.config/opencode/tasks/daily-standup.md`:
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
---
|
|
37
|
+
schedule: "0 9 * * 1-5"
|
|
38
|
+
cwd: ~/projects/my-app
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
Summarize all git commits from yesterday. Include the files changed and a brief
|
|
42
|
+
description of each change. Format as a bulleted list.
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
That's it. The scheduler will run this task every weekday at 9 AM.
|
|
46
|
+
|
|
47
|
+
## Recurring tasks
|
|
48
|
+
|
|
49
|
+
Recurring tasks are markdown files in `~/.config/opencode/tasks/`. The filename (without `.md`) is used as the task name.
|
|
50
|
+
|
|
51
|
+
The file has YAML frontmatter followed by the prompt that gets sent to the agent.
|
|
52
|
+
|
|
53
|
+
### Frontmatter reference
|
|
54
|
+
|
|
55
|
+
| Field | Type | Required | Default | Description |
|
|
56
|
+
|-------|------|----------|---------|-------------|
|
|
57
|
+
| `description` | string | no | — | Human-readable description. |
|
|
58
|
+
| `schedule` | string | yes | — | 5-field cron expression. Uses system local timezone. |
|
|
59
|
+
| `cwd` | string | yes | — | Working directory. Supports `~` expansion. |
|
|
60
|
+
| `session_name` | string | no | — | If set, reuses the same session across runs. If omitted, creates a fresh session each run. |
|
|
61
|
+
| `model` | string | no | user default | Model in `provider/model` format (e.g., `anthropic/claude-sonnet-4-6`). |
|
|
62
|
+
| `agent` | string | no | user default | Agent to use. |
|
|
63
|
+
| `permission` | object | no | opencode defaults | Permission config. Same schema as the `permission` key in `opencode.json`. See [Permissions](#permissions). |
|
|
64
|
+
| `enabled` | boolean | no | `true` | Set to `false` to temporarily disable without deleting. |
|
|
65
|
+
|
|
66
|
+
### Cron expression reference
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
┌───────── minute (0-59)
|
|
70
|
+
│ ┌───────── hour (0-23)
|
|
71
|
+
│ │ ┌───────── day of month (1-31)
|
|
72
|
+
│ │ │ ┌───────── month (1-12)
|
|
73
|
+
│ │ │ │ ┌───────── day of week (0-7, 0 and 7 are Sunday)
|
|
74
|
+
│ │ │ │ │
|
|
75
|
+
* * * * *
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| Expression | Meaning |
|
|
79
|
+
|------------|---------|
|
|
80
|
+
| `0 9 * * *` | Every day at 9:00 AM |
|
|
81
|
+
| `0 9 * * 1-5` | Every weekday at 9:00 AM |
|
|
82
|
+
| `*/30 * * * *` | Every 30 minutes |
|
|
83
|
+
| `0 0 * * 0` | Every Sunday at midnight |
|
|
84
|
+
| `0 9 1 * *` | First day of every month at 9:00 AM |
|
|
85
|
+
|
|
86
|
+
### Examples
|
|
87
|
+
|
|
88
|
+
**Daily branch cleanup** (reuses the same session):
|
|
89
|
+
|
|
90
|
+
```yaml
|
|
91
|
+
---
|
|
92
|
+
description: Clean up merged git branches
|
|
93
|
+
schedule: "0 9 * * *"
|
|
94
|
+
cwd: ~/projects/my-app
|
|
95
|
+
session_name: daily-cleanup
|
|
96
|
+
permission:
|
|
97
|
+
bash:
|
|
98
|
+
"*": "allow"
|
|
99
|
+
"git push *": "deny"
|
|
100
|
+
edit: "deny"
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
Check for local branches that have been merged into main and delete them.
|
|
104
|
+
List any branches that look stale but haven't been merged yet.
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Weekly project report** (fresh session each time):
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
---
|
|
111
|
+
description: Generate a weekly summary of project activity
|
|
112
|
+
schedule: "0 8 * * 1"
|
|
113
|
+
cwd: ~/projects/my-app
|
|
114
|
+
model: anthropic/claude-sonnet-4-6
|
|
115
|
+
permission:
|
|
116
|
+
bash:
|
|
117
|
+
"*": "allow"
|
|
118
|
+
edit: "deny"
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
Generate a weekly summary of project activity for the past 7 days.
|
|
122
|
+
Include commits, files changed, open PRs, and a brief velocity analysis.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## One-off tasks
|
|
126
|
+
|
|
127
|
+
Agents can schedule one-off tasks using the `schedule_task` tool. These are stored in a SQLite database and executed once at the scheduled time.
|
|
128
|
+
|
|
129
|
+
The agent has access to these tools:
|
|
130
|
+
|
|
131
|
+
| Tool | Description |
|
|
132
|
+
|------|-------------|
|
|
133
|
+
| `schedule_task` | Schedule a one-off task for a specific time |
|
|
134
|
+
| `list_tasks` | List all recurring and one-off tasks |
|
|
135
|
+
| `cancel_task` | Cancel a pending one-off task or disable a recurring task |
|
|
136
|
+
| `task_history` | View execution history for a task |
|
|
137
|
+
| `get_task_instructions` | Get the full frontmatter format for recurring tasks |
|
|
138
|
+
|
|
139
|
+
Example agent interaction:
|
|
140
|
+
|
|
141
|
+
> "Schedule a task to run the test suite tomorrow at 8 AM"
|
|
142
|
+
|
|
143
|
+
The agent will call `schedule_task` with the appropriate prompt, time, working directory, and permissions.
|
|
144
|
+
|
|
145
|
+
## Permissions
|
|
146
|
+
|
|
147
|
+
Scheduled tasks run in the background with no user present. Any permission set to `"ask"` will effectively be **denied** since there's nobody to approve the prompt.
|
|
148
|
+
|
|
149
|
+
Most permissions (`bash`, `edit`, `read`) default to `"allow"` and work fine without explicit configuration.
|
|
150
|
+
|
|
151
|
+
### `external_directory` — the common gotcha
|
|
152
|
+
|
|
153
|
+
The `external_directory` permission defaults to `"ask"`, which means **any file access outside the task's `cwd` will silently fail** in background execution.
|
|
154
|
+
|
|
155
|
+
If your task reads or writes files outside its working directory, you must explicitly allow those paths:
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
permission:
|
|
159
|
+
external_directory:
|
|
160
|
+
"/tmp/*": "allow"
|
|
161
|
+
"~/other-project/*": "allow"
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Rule of thumb
|
|
165
|
+
|
|
166
|
+
Ask: "Will this task touch any files outside its `cwd`?" If yes, add `external_directory` rules.
|
|
167
|
+
|
|
168
|
+
## CLI reference
|
|
169
|
+
|
|
170
|
+
The `opencode-scheduler` CLI manages the scheduler daemon and provides task visibility. All commands are available via `npx`.
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
npx opencode-scheduler --install Install the system scheduler (launchd/systemd)
|
|
174
|
+
npx opencode-scheduler --uninstall Remove the system scheduler
|
|
175
|
+
npx opencode-scheduler --install-skill Install the scheduled-tasks agent skill
|
|
176
|
+
npx opencode-scheduler --status Show scheduler and task status
|
|
177
|
+
npx opencode-scheduler --list List all tasks with next run times
|
|
178
|
+
npx opencode-scheduler --help Show help
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The following commands are used internally by the scheduler daemon and generally don't need to be run manually:
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
opencode-scheduler --run-once Run one scheduler tick
|
|
185
|
+
opencode-scheduler --exec-task <id> Execute a specific task (used by worker processes)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Example output
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
$ npx opencode-scheduler --status
|
|
192
|
+
|
|
193
|
+
Scheduler: installed (macos-launchd)
|
|
194
|
+
Plist: ~/Library/LaunchAgents/ai.opencode.scheduled-tasks.plist
|
|
195
|
+
|
|
196
|
+
Recurring tasks: 2 (1 enabled, 1 disabled)
|
|
197
|
+
daily-cleanup next: 2026-03-31T13:00:00.000Z last: completed 2026-03-30T13:00:12.000Z
|
|
198
|
+
weekly-report disabled
|
|
199
|
+
|
|
200
|
+
One-off tasks: 1 pending
|
|
201
|
+
abc123def4... "Run migration check" scheduled: 2026-03-30T19:00:00.000Z
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Session behavior
|
|
205
|
+
|
|
206
|
+
By default, each task run creates a fresh OpenCode session. This is good for independent, stateless tasks.
|
|
207
|
+
|
|
208
|
+
If you set `session_name`, the task reuses the same session across runs. The agent can see previous messages and build on prior context. This is useful for tasks like:
|
|
209
|
+
|
|
210
|
+
- A daily standup that references yesterday's summary
|
|
211
|
+
- An ongoing code review that accumulates findings
|
|
212
|
+
- A monitoring task that tracks changes over time
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
session_name: daily-standup
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The session is created on the first run and reused on subsequent runs. Session ID mappings are stored in the SQLite database.
|
|
219
|
+
|
|
220
|
+
## Architecture
|
|
221
|
+
|
|
222
|
+
The plugin has three components:
|
|
223
|
+
|
|
224
|
+
1. **Plugin** (`dist/plugin.js`) — Loaded by OpenCode's Bun-based plugin runtime. Exposes tools to the agent and reads/writes the SQLite database. Uses `bun:sqlite`.
|
|
225
|
+
|
|
226
|
+
2. **CLI** (`dist/cli.js`, bin: `opencode-scheduler`) — Standalone Node.js script. Manages the scheduler daemon, runs scheduler ticks, and executes task workers. Uses `better-sqlite3`.
|
|
227
|
+
|
|
228
|
+
3. **Task files** (`~/.config/opencode/tasks/*.md`) — User-editable recurring task definitions with YAML frontmatter.
|
|
229
|
+
|
|
230
|
+
Both the plugin and CLI read/write the same SQLite database at `~/.config/opencode/.tasks.db`.
|
|
231
|
+
|
|
232
|
+
### How tasks execute
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
launchd/systemd (every 60s)
|
|
236
|
+
└─ opencode-scheduler --run-once # scheduler tick
|
|
237
|
+
├─ checks which tasks are due
|
|
238
|
+
├─ spawns worker for each due task # returns immediately
|
|
239
|
+
│ └─ opencode-scheduler --exec-task <id>
|
|
240
|
+
│ └─ opencode run ... # full LLM session
|
|
241
|
+
│ └─ updates DB on completion
|
|
242
|
+
└─ reaps any crashed workers
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The scheduler tick is non-blocking — it spawns detached worker processes and exits immediately. Each worker runs `opencode run` synchronously, captures the session ID from the JSON output, and updates the database when done.
|
|
246
|
+
|
|
247
|
+
Concurrency is managed via PID tracking. If a task is already running (its worker PID is still alive), the scheduler skips it.
|
|
248
|
+
|
|
249
|
+
## Development
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Install dependencies
|
|
253
|
+
npm install
|
|
254
|
+
|
|
255
|
+
# Build
|
|
256
|
+
npm run build
|
|
257
|
+
|
|
258
|
+
# Run tests
|
|
259
|
+
npm test
|
|
260
|
+
|
|
261
|
+
# Watch mode
|
|
262
|
+
npm run dev
|
|
263
|
+
npm run test:watch
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Project structure
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
src/
|
|
270
|
+
cli.ts # CLI entry point (opencode-scheduler)
|
|
271
|
+
plugin.ts # OpenCode plugin entry point
|
|
272
|
+
lib/
|
|
273
|
+
types.ts # Shared TypeScript types
|
|
274
|
+
db.ts # SQLite database (schema, migrations, CRUD)
|
|
275
|
+
sqlite.ts # Runtime-agnostic SQLite abstraction (bun:sqlite / better-sqlite3)
|
|
276
|
+
tasks.ts # Task file parser (frontmatter validation)
|
|
277
|
+
cron.ts # Cron evaluation (isDue, nextRunTime)
|
|
278
|
+
runner.ts # Task execution (spawn workers, run opencode)
|
|
279
|
+
installer.ts # Platform detection + launchd/systemd installation
|
|
280
|
+
__tests__/ # Unit tests
|
|
281
|
+
examples/ # Example task files
|
|
282
|
+
skill/ # Agent skill (SKILL.md)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## License
|
|
286
|
+
|
|
287
|
+
MIT
|