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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/dist/chunk-35FFLWP3.js +79 -0
  4. package/dist/chunk-35FFLWP3.js.map +1 -0
  5. package/dist/chunk-FMGZ3SSS.js +57 -0
  6. package/dist/chunk-FMGZ3SSS.js.map +1 -0
  7. package/dist/chunk-LPAFZNXK.js +214 -0
  8. package/dist/chunk-LPAFZNXK.js.map +1 -0
  9. package/dist/chunk-YMAT5MON.js +22 -0
  10. package/dist/chunk-YMAT5MON.js.map +1 -0
  11. package/dist/cli/index.cjs +879 -0
  12. package/dist/cli/index.cjs.map +1 -0
  13. package/dist/cli/index.d.cts +2 -0
  14. package/dist/cli/index.d.ts +2 -0
  15. package/dist/cli/index.js +554 -0
  16. package/dist/cli/index.js.map +1 -0
  17. package/dist/daemon/index.cjs +1655 -0
  18. package/dist/daemon/index.cjs.map +1 -0
  19. package/dist/daemon/index.d.cts +2 -0
  20. package/dist/daemon/index.d.ts +2 -0
  21. package/dist/daemon/index.js +1306 -0
  22. package/dist/daemon/index.js.map +1 -0
  23. package/dist/dashboard/.gitkeep +0 -0
  24. package/dist/dashboard/dashboard.css +192 -0
  25. package/dist/dashboard/dashboard.js +316 -0
  26. package/dist/dashboard/index.html +108 -0
  27. package/dist/index.cjs +180 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +121 -0
  30. package/dist/index.d.ts +121 -0
  31. package/dist/index.js +32 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/job-JQGLDEJV.js +26 -0
  34. package/dist/job-JQGLDEJV.js.map +1 -0
  35. package/dist/mcp/index.cjs +1000 -0
  36. package/dist/mcp/index.cjs.map +1 -0
  37. package/dist/mcp/index.d.cts +13 -0
  38. package/dist/mcp/index.d.ts +13 -0
  39. package/dist/mcp/index.js +876 -0
  40. package/dist/mcp/index.js.map +1 -0
  41. package/package.json +81 -0
  42. package/plugin/.gitkeep +0 -0
  43. package/plugin/README.md +50 -0
  44. package/plugin/install.mjs +155 -0
  45. package/plugin/plugin.json +11 -0
  46. package/plugin/uninstall.mjs +68 -0
  47. 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`