add create-scheduled-task skill, update plugin registries

New skill for creating/managing headless Claude scheduled tasks
on systemd timers. Plugin blocklist and marketplace files updated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2026-03-01 00:33:30 -06:00
parent e76527a0a0
commit 0617a0a499
3 changed files with 258 additions and 2 deletions

View File

@ -1,5 +1,5 @@
{
"fetchedAt": "2026-02-28T18:10:38.336Z",
"fetchedAt": "2026-03-01T05:51:34.878Z",
"plugins": [
{
"plugin": "code-review@claude-plugins-official",

View File

@ -13,6 +13,6 @@
"repo": "anthropics/claude-code"
},
"installLocation": "/home/cal/.claude/plugins/marketplaces/claude-code-plugins",
"lastUpdated": "2026-02-28T18:11:46.614Z"
"lastUpdated": "2026-03-01T06:14:11.879Z"
}
}

View File

@ -0,0 +1,256 @@
---
name: create-scheduled-task
description: Create, manage, or debug headless Claude scheduled tasks that run on systemd timers. USE WHEN user says "create a scheduled task", "add a cron job for Claude", "schedule a task", "new scheduled task", "manage scheduled tasks", or wants Claude to do something automatically on a timer.
---
# Create Scheduled Task
## When to Activate This Skill
- "Create a scheduled task for X"
- "Schedule Claude to do X every day"
- "Add a new automated task"
- "Debug a scheduled task"
- "List scheduled tasks"
- "Manage scheduled tasks"
## System Overview
Headless Claude Code sessions triggered by systemd timers. Each task has its own prompt, MCP config, settings, and timer.
```
~/.config/claude-scheduled/
├── runner.sh # Universal task runner (DO NOT MODIFY)
├── disabled # Touch this file to globally disable all tasks
├── logs -> ~/.local/share/... # Symlink to log directory
└── tasks/
└── <task-name>/
├── prompt.md # What Claude should do
├── settings.json # Model, budget, tools, working dir
└── mcp.json # MCP servers this task needs (optional)
~/.config/systemd/user/
├── claude-scheduled@.service # Template unit (DO NOT MODIFY)
└── claude-scheduled@<task-name>.timer # One per task
```
## Creating a New Task
### Step 1: Create the task directory
```bash
mkdir -p ~/.config/claude-scheduled/tasks/<task-name>
mkdir -p ~/.local/share/claude-scheduled/logs/<task-name>
```
### Step 2: Write the prompt (`prompt.md`)
Write a clear, structured prompt that tells Claude exactly what to do. Include:
- Specific instructions (repos to check, files to read, etc.)
- Desired output format (structured text or JSON)
- Any cognitive-memory operations (recall context, store results)
**Guidelines:**
- Be explicit — headless Claude has no user to ask for clarification
- Specify output format so results are parseable in logs
- Keep prompts focused on a single concern
### Step 3: Write settings (`settings.json`)
```json
{
"model": "sonnet",
"effort": "medium",
"max_budget_usd": 0.75,
"allowed_tools": "<space-separated tool list>",
"graph": "default",
"working_dir": "/mnt/NV2/Development/claude-home",
"timeout_seconds": 300
}
```
**Settings reference:**
| Field | Default | Description |
|-------|---------|-------------|
| `model` | `sonnet` | Model alias or full ID. Use `sonnet` for cost efficiency. |
| `effort` | `medium` | `low`, `medium`, or `high`. Controls reasoning depth. |
| `max_budget_usd` | `0.25` | Per-session cost ceiling. Typical triage run: ~$0.20. |
| `allowed_tools` | `Read(*) Glob(*) Grep(*)` | Space-separated tool allowlist. Principle of least privilege. |
| `graph` | `default` | Cognitive-memory graph for storing results. |
| `working_dir` | `/mnt/NV2/Development/claude-home` | `cd` here before running. Loads that project's CLAUDE.md. |
| `timeout_seconds` | `300` | Hard timeout. 300s (5 min) is usually sufficient. |
**Common tool allowlists by task type:**
Read-only triage (Gitea + memory):
```
mcp__gitea-mcp__list_repo_issues mcp__gitea-mcp__get_issue_by_index mcp__gitea-mcp__list_repo_labels mcp__gitea-mcp__list_repo_pull_requests mcp__cognitive-memory__memory_recall mcp__cognitive-memory__memory_search mcp__cognitive-memory__memory_store mcp__cognitive-memory__memory_episode
```
Code analysis (read-only):
```
Read(*) Glob(*) Grep(*)
```
Memory maintenance:
```
mcp__cognitive-memory__memory_recall mcp__cognitive-memory__memory_search mcp__cognitive-memory__memory_store mcp__cognitive-memory__memory_relate mcp__cognitive-memory__memory_reflect mcp__cognitive-memory__memory_episode
```
### Step 4: Write MCP config (`mcp.json`) — if needed
Only include MCP servers the task actually needs. Use `--strict-mcp-config` (runner does this automatically when mcp.json exists).
**Available MCP server configs to copy from:**
Gitea:
```json
{
"gitea-mcp": {
"type": "stdio",
"command": "/home/cal/.local/bin/gitea-mcp",
"args": ["-t", "stdio", "-host", "https://git.manticorum.com"],
"env": {
"GITEA_ACCESS_TOKEN": "<token from ~/.claude.json>"
}
}
}
```
Cognitive Memory:
```json
{
"cognitive-memory": {
"command": "python3",
"type": "stdio",
"args": ["/mnt/NV2/Development/cognitive-memory/mcp_server.py"],
"env": {}
}
}
```
n8n:
```json
{
"n8n-mcp": {
"command": "npx",
"type": "stdio",
"args": ["n8n-mcp"],
"env": {
"MCP_MODE": "stdio",
"N8N_API_URL": "http://10.10.0.210:5678",
"N8N_API_KEY": "<token from ~/.claude/.mcp-full.json>"
}
}
}
```
Wrap in `{"mcpServers": { ... }}` structure.
### Step 5: Create the systemd timer
Create `~/.config/systemd/user/claude-scheduled@<task-name>.timer`:
```ini
[Unit]
Description=Claude Scheduled Task Timer: <task-name>
[Timer]
OnCalendar=<schedule>
Persistent=true
[Install]
WantedBy=timers.target
```
**Common OnCalendar expressions:**
| Schedule | Expression |
|----------|------------|
| Daily at 9am | `*-*-* 09:00:00` |
| Every 6 hours | `*-*-* 00/6:00:00` |
| Weekdays at 8am | `Mon..Fri *-*-* 08:00:00` |
| Weekly Sunday 3am | `Sun *-*-* 03:00:00` |
| Monthly 1st at midnight | `*-*-01 00:00:00` |
`Persistent=true` means if the machine was off during a scheduled run, it catches up on next boot.
### Step 6: Enable the timer
```bash
systemctl --user daemon-reload
systemctl --user enable --now claude-scheduled@<task-name>.timer
```
## Managing Tasks
### List all scheduled tasks
```bash
systemctl --user list-timers 'claude-scheduled*'
```
### Manual test run
```bash
~/.config/claude-scheduled/runner.sh <task-name>
```
### Check logs
```bash
# Latest log
ls -t ~/.local/share/claude-scheduled/logs/<task-name>/ | head -1 | xargs -I{} cat ~/.local/share/claude-scheduled/logs/<task-name>/{}
# Via journalctl (if triggered by systemd)
journalctl --user -u claude-scheduled@<task-name>.service --since today
```
### Disable a single task
```bash
systemctl --user disable --now claude-scheduled@<task-name>.timer
```
### Disable ALL tasks (kill switch)
```bash
touch ~/.config/claude-scheduled/disabled
# To re-enable:
rm ~/.config/claude-scheduled/disabled
```
### Check task run history
```bash
ls -lt ~/.local/share/claude-scheduled/logs/<task-name>/
```
## Existing Tasks
| Task | Schedule | Budget | Description |
|------|----------|--------|-------------|
| `backlog-triage` | Daily 09:00 | $0.75 | Scan Gitea issues across repos, prioritize, suggest focus |
## How the Runner Works
`runner.sh` is the universal executor. For each task it:
1. Reads `settings.json` for model, budget, tools, working dir
2. Reads `prompt.md` as the Claude prompt
3. Invokes `claude -p` with `--strict-mcp-config`, `--allowedTools`, `--no-session-persistence`, `--output-format json`
4. Unsets `CLAUDECODE` env var to allow nested sessions
5. Logs full output to `~/.local/share/claude-scheduled/logs/<task>/`
6. Stores a summary to cognitive-memory as a workflow + episode
7. Rotates logs (keeps last 30 per task)
**The runner does NOT need modification to add new tasks** — just add files under `tasks/` and a timer.
## Key Constraints
- **Read-only by default**: Tasks should use `--allowedTools` to restrict to only what they need. No Bash, no Edit unless explicitly required.
- **Cost ceiling**: `max_budget_usd` is a hard limit per session. Typical Sonnet run with MCP tools: $0.150.30.
- **OAuth auth**: Uses Cal's Claude Max subscription via OAuth. No API key needed.
- **Nested sessions**: The runner unsets `CLAUDECODE` so it works from within a Claude session or from systemd.
- **Log retention**: 30 logs per task, oldest auto-deleted.
## Reference Files
- Runner: `~/.config/claude-scheduled/runner.sh`
- Template service: `~/.config/systemd/user/claude-scheduled@.service`
- Example task: `~/.config/claude-scheduled/tasks/backlog-triage/`
- Gitea issue: [claude-home#2](https://git.manticorum.com/cal/claude-home/issues/2)