crontick 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/LICENSE +21 -0
- package/README.md +56 -0
- package/dist/chunk-35FFLWP3.js +79 -0
- package/dist/chunk-35FFLWP3.js.map +1 -0
- package/dist/chunk-FMGZ3SSS.js +57 -0
- package/dist/chunk-FMGZ3SSS.js.map +1 -0
- package/dist/chunk-LPAFZNXK.js +214 -0
- package/dist/chunk-LPAFZNXK.js.map +1 -0
- package/dist/chunk-YMAT5MON.js +22 -0
- package/dist/chunk-YMAT5MON.js.map +1 -0
- package/dist/cli/index.cjs +879 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +2 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +554 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/daemon/index.cjs +1655 -0
- package/dist/daemon/index.cjs.map +1 -0
- package/dist/daemon/index.d.cts +2 -0
- package/dist/daemon/index.d.ts +2 -0
- package/dist/daemon/index.js +1306 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/dashboard/.gitkeep +0 -0
- package/dist/dashboard/dashboard.css +192 -0
- package/dist/dashboard/dashboard.js +316 -0
- package/dist/dashboard/index.html +108 -0
- package/dist/index.cjs +180 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +121 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/job-JQGLDEJV.js +26 -0
- package/dist/job-JQGLDEJV.js.map +1 -0
- package/dist/mcp/index.cjs +1000 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +13 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +876 -0
- package/dist/mcp/index.js.map +1 -0
- package/package.json +81 -0
- package/plugin/.gitkeep +0 -0
- package/plugin/README.md +50 -0
- package/plugin/install.mjs +155 -0
- package/plugin/plugin.json +11 -0
- package/plugin/uninstall.mjs +68 -0
- package/src/skill/SKILL.md +227 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# crontick — Scheduling Skill for MCP-Capable LLMs
|
|
2
|
+
|
|
3
|
+
> **Version**: 1.0 (M4)
|
|
4
|
+
> **Purpose**: Teach any MCP-capable LLM to schedule recurring or one-shot scripts on a local machine using the `crontick` daemon.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## When to Use This Skill
|
|
9
|
+
|
|
10
|
+
Use `crontick` tools when the user asks to:
|
|
11
|
+
|
|
12
|
+
- Run a script, command, or task on a schedule ("every day at 9am", "every 5 minutes", "every Monday")
|
|
13
|
+
- Back up files, clean up directories, or run maintenance automatically
|
|
14
|
+
- Trigger a CLI tool (e.g. `git push`, `copilot -p "..."`, `claude`) on a timer
|
|
15
|
+
- Monitor a condition and take action periodically
|
|
16
|
+
- Set up a one-shot delayed task ("in 30 minutes", "at midnight tonight")
|
|
17
|
+
|
|
18
|
+
**Do NOT use** for: interactive tasks requiring human input, long-running LLM reasoning sessions that need a session ID, or tasks that require browser or GUI automation.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
Follow these steps in order. Do not skip validation.
|
|
25
|
+
|
|
26
|
+
### Step 1 — Understand the Intent
|
|
27
|
+
|
|
28
|
+
Ask (or infer from context):
|
|
29
|
+
- What should the script _do_? (write a 1-sentence summary)
|
|
30
|
+
- When should it run? (schedule cadence, timezone)
|
|
31
|
+
- Any side effects? (writes files, network calls, sends alerts)
|
|
32
|
+
- On which OS? (Windows → PowerShell; Unix/macOS → bash; **assume Windows if unspecified**)
|
|
33
|
+
- Required environment (working directory, secrets, binaries that must be on PATH)
|
|
34
|
+
|
|
35
|
+
### Step 2 — Draft a Self-Contained Script
|
|
36
|
+
|
|
37
|
+
Write a script that accomplishes the task:
|
|
38
|
+
|
|
39
|
+
**Windows (PowerShell):**
|
|
40
|
+
```powershell
|
|
41
|
+
$ErrorActionPreference = 'Stop'
|
|
42
|
+
# Your task here
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Unix/macOS (bash):**
|
|
46
|
+
```bash
|
|
47
|
+
#!/usr/bin/env bash
|
|
48
|
+
set -euo pipefail
|
|
49
|
+
# Your task here
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Rules for the script:
|
|
53
|
+
- **Idempotent**: running it twice must not corrupt state
|
|
54
|
+
- **Self-contained**: do not rely on external session state or env vars (except those explicitly declared in `action.env`)
|
|
55
|
+
- **Explicit working directory**: always set `action.cwd` — never rely on the daemon's working directory
|
|
56
|
+
- **Secrets via env**: do not hardcode tokens or passwords; put them in `action.env` or reference a secrets file
|
|
57
|
+
- **Timeout**: set `action.timeoutSec` to a reasonable upper bound (default: 3600 for long jobs, 60 for short ones)
|
|
58
|
+
- **Concise description**: fill `description` with a one-line plain-English explanation
|
|
59
|
+
- The script may shell out to other CLIs: `copilot -p "..."`, `claude`, `git`, `npm run`, etc. — those invocations happen inside the script, not in `crontick` itself
|
|
60
|
+
|
|
61
|
+
### Step 3 — Validate the Schedule
|
|
62
|
+
|
|
63
|
+
Call `crontick_schedule_validate` with the proposed schedule:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{ "schedule": { "kind": "cron", "cron": "0 9 * * *", "tz": "America/Los_Angeles" } }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Supported schedule kinds:
|
|
70
|
+
- `cron` — cron expression + optional timezone (`tz`)
|
|
71
|
+
- `interval` — `{ "kind": "interval", "everySec": 300 }` for "every N seconds"
|
|
72
|
+
- `one-shot` — `{ "kind": "one-shot", "runAt": "2026-08-01T09:00:00Z" }` for a single future run
|
|
73
|
+
|
|
74
|
+
Then call `crontick_schedule_preview` to show the next 5 fire times. Always show these to the user for confirmation before creating the job.
|
|
75
|
+
|
|
76
|
+
### Step 4 — Create the Job
|
|
77
|
+
|
|
78
|
+
Once the user confirms the schedule, call `crontick_job_create`:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"id": "daily-backup",
|
|
83
|
+
"description": "Back up ~/projects to ~/backups every day at 9am PT",
|
|
84
|
+
"schedule": { "kind": "cron", "cron": "0 9 * * *", "tz": "America/Los_Angeles" },
|
|
85
|
+
"action": {
|
|
86
|
+
"kind": "script",
|
|
87
|
+
"script": "$ErrorActionPreference = 'Stop'\nCopy-Item -Recurse ~/projects ~/backups/$(Get-Date -f yyyyMMdd) -Force",
|
|
88
|
+
"shell": "pwsh",
|
|
89
|
+
"cwd": "~",
|
|
90
|
+
"timeoutSec": 300
|
|
91
|
+
},
|
|
92
|
+
"overlap": "skip",
|
|
93
|
+
"retry": { "max": 1, "backoffSec": 60 }
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
For a simple command (no shell), use `action.kind: "exec"`:
|
|
98
|
+
```json
|
|
99
|
+
{ "action": { "kind": "exec", "command": "git", "args": ["-C", "/path/to/repo", "push"] } }
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Step 5 — Confirm and Report
|
|
103
|
+
|
|
104
|
+
After `crontick_job_create` returns:
|
|
105
|
+
1. Report the returned `id` and `nextRunAt` to the user
|
|
106
|
+
2. Offer to run immediately with `crontick_job_run_now` if they want to test it
|
|
107
|
+
3. Show `crontick://schemas/job` if the user wants to see the full schema
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Tool Reference
|
|
112
|
+
|
|
113
|
+
| Tool | Description |
|
|
114
|
+
|------|-------------|
|
|
115
|
+
| `crontick_job_create` | Create and schedule a new job |
|
|
116
|
+
| `crontick_job_list` | List all jobs with status and next run |
|
|
117
|
+
| `crontick_job_get` | Get full definition of a specific job |
|
|
118
|
+
| `crontick_job_update` | Update fields on an existing job (partial) |
|
|
119
|
+
| `crontick_job_delete` | Permanently delete a job (confirm first!) |
|
|
120
|
+
| `crontick_job_enable` | Re-enable a disabled job |
|
|
121
|
+
| `crontick_job_disable` | Disable without deleting |
|
|
122
|
+
| `crontick_job_run_now` | Trigger an immediate run |
|
|
123
|
+
| `crontick_job_cancel_run` | Cancel an in-progress run |
|
|
124
|
+
| `crontick_run_list` | List recent runs (filterable by job ID) |
|
|
125
|
+
| `crontick_run_get` | Get status and details of a specific run |
|
|
126
|
+
| `crontick_run_logs_tail` | Get last N lines of a run's output |
|
|
127
|
+
| `crontick_schedule_validate` | Validate a schedule before using it |
|
|
128
|
+
| `crontick_schedule_preview` | Preview next N fire times |
|
|
129
|
+
| `crontick_stats_summary` | Aggregate stats for all jobs |
|
|
130
|
+
| `crontick_stats_job` | Per-job run statistics |
|
|
131
|
+
| `crontick_daemon_status` | Daemon PID, version, uptime |
|
|
132
|
+
| `crontick_daemon_reload` | Reload job definitions from disk |
|
|
133
|
+
| `crontick_daemon_restart` | Restart the daemon (interrupts running jobs) |
|
|
134
|
+
| `crontick_autostart_status` | Check if daemon is registered for autostart |
|
|
135
|
+
| `crontick_autostart_install` | Register daemon for login autostart |
|
|
136
|
+
| `crontick_autostart_remove` | Unregister daemon from login autostart |
|
|
137
|
+
| `crontick_export` | Export all jobs as JSON |
|
|
138
|
+
| `crontick_import` | Import jobs from a JSON array (upsert) |
|
|
139
|
+
| `crontick_dashboard_open` | Get the URL for the local web dashboard |
|
|
140
|
+
| `crontick_doctor` | Health check: Node.js, SQLite, data dir, daemon |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Rules
|
|
145
|
+
|
|
146
|
+
1. **Always validate the schedule first** (`crontick_schedule_validate` → `crontick_schedule_preview` → user confirms → create)
|
|
147
|
+
2. **Always confirm before delete or disable** — `crontick_job_delete` and `crontick_job_disable` are irreversible or disruptive; ask the user explicitly
|
|
148
|
+
3. **Scripts must be self-contained** — `action.script` must not rely on env vars or files set up by other scripts
|
|
149
|
+
4. **Use error-first shell settings** — `set -euo pipefail` in bash; `$ErrorActionPreference = 'Stop'` in pwsh
|
|
150
|
+
5. **Set explicit `cwd`** — never rely on the daemon's working directory
|
|
151
|
+
6. **Secrets via `action.env`** — `{ "GITHUB_TOKEN": "ghp_..." }` or reference a dotenv file; never hardcode secrets in the script body
|
|
152
|
+
7. **Set `timeoutSec`** — prevents runaway jobs from consuming resources
|
|
153
|
+
8. **Never invent an LLM sub-runtime** — do NOT create jobs with `action.kind: "llm-prompt"` or similar; that kind does not exist. If the user wants the script to invoke an LLM CLI, put `copilot -p "..."` or `claude -p "..."` inside the script body
|
|
154
|
+
9. **Job IDs must be kebab-case** — e.g. `daily-backup`, `weekly-cleanup-2026`
|
|
155
|
+
10. **Assume Windows if OS is unspecified** — use `shell: "pwsh"` and PowerShell syntax
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Ban List
|
|
160
|
+
|
|
161
|
+
- ❌ Do NOT use `action.kind: "llm-prompt"` — this kind does not exist
|
|
162
|
+
- ❌ Do NOT set `action.provider` — there is no provider field
|
|
163
|
+
- ❌ Do NOT use `action.resumeSessionId` — sessions are not supported
|
|
164
|
+
- ❌ Do NOT call `crontick_daemon_restart` without user confirmation — it interrupts running jobs
|
|
165
|
+
- ❌ Do NOT call `crontick_job_delete` without explicit user confirmation ("yes, delete it")
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Worked Examples
|
|
170
|
+
|
|
171
|
+
### Example 1 — Daily Backup (Windows)
|
|
172
|
+
|
|
173
|
+
**User**: "Back up my code repos to an external drive every day at 10pm"
|
|
174
|
+
|
|
175
|
+
1. Clarify: repos at `C:\Users\alice\code`, backup drive `E:\Backups`
|
|
176
|
+
2. Draft script (pwsh):
|
|
177
|
+
```powershell
|
|
178
|
+
$ErrorActionPreference = 'Stop'
|
|
179
|
+
$src = 'C:\Users\alice\code'
|
|
180
|
+
$dst = "E:\Backups\code-$(Get-Date -f yyyyMMdd)"
|
|
181
|
+
if (-not (Test-Path E:\Backups)) { throw 'Backup drive E: not mounted' }
|
|
182
|
+
Copy-Item -Recurse $src $dst -Force
|
|
183
|
+
Write-Output "Backup complete: $dst"
|
|
184
|
+
```
|
|
185
|
+
3. Validate: `crontick_schedule_validate { kind: "cron", cron: "0 22 * * *", tz: "America/New_York" }`
|
|
186
|
+
4. Preview next 5 fires → show user → user confirms
|
|
187
|
+
5. Create:
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"id": "daily-code-backup",
|
|
191
|
+
"description": "Back up C:\\Users\\alice\\code to E:\\Backups daily at 10pm ET",
|
|
192
|
+
"schedule": { "kind": "cron", "cron": "0 22 * * *", "tz": "America/New_York" },
|
|
193
|
+
"action": {
|
|
194
|
+
"kind": "script", "shell": "pwsh",
|
|
195
|
+
"cwd": "C:\\Users\\alice",
|
|
196
|
+
"script": "$ErrorActionPreference = 'Stop'\n...",
|
|
197
|
+
"timeoutSec": 600
|
|
198
|
+
},
|
|
199
|
+
"overlap": "skip"
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
6. Report: job `daily-code-backup` created, next run 2026-07-19T02:00:00Z
|
|
203
|
+
|
|
204
|
+
### Example 2 — Weekly Dependency Cleanup (macOS/Linux)
|
|
205
|
+
|
|
206
|
+
**User**: "Clean up old node_modules in my projects folder every Sunday"
|
|
207
|
+
|
|
208
|
+
1. Clarify: projects at `~/projects`, remove `node_modules` older than 30 days
|
|
209
|
+
2. Draft script (bash):
|
|
210
|
+
```bash
|
|
211
|
+
#!/usr/bin/env bash
|
|
212
|
+
set -euo pipefail
|
|
213
|
+
find ~/projects -name node_modules -type d -maxdepth 3 -mtime +30 -print -exec rm -rf {} +
|
|
214
|
+
echo "Cleanup done."
|
|
215
|
+
```
|
|
216
|
+
3. Validate + preview for `"0 3 * * 0"` (Sunday 3am)
|
|
217
|
+
4. Create with `shell: "bash"`, `cwd: "~"`, `timeoutSec: 3600`
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Resources
|
|
222
|
+
|
|
223
|
+
- Job schema: `crontick://schemas/job`
|
|
224
|
+
- Jobs list: `crontick://jobs`
|
|
225
|
+
- Individual job: `crontick://jobs/{id}`
|
|
226
|
+
- Run record: `crontick://runs/{id}`
|
|
227
|
+
- Run logs: `crontick://runs/{id}/log`
|