skills/automation/SKILL.md
Create and manage scheduled automations. Use when the user wants something to happen automatically on a schedule (e.g. 'send me a daily report at 16:00', 'check the weather every morning', 'warn me about thunderstorms every hour', 'tell me when my train is delayed').
npx skillsauth add cutec-chris/PawLia automationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Creates scheduled automations the scheduler runs at the given times.
Default to a script. An automation is a deterministic script the scheduler executes. The script decides for itself whether there is anything worth saying: when nothing is up, it prints nothing and the user hears nothing; when something is up, it prints the message (that text becomes the notification). This is the key behaviour for monitoring jobs (thunderstorm alert, train-delay watch) — they must stay silent on a quiet day instead of pinging "all ok" every hour.
The LLM is a step inside the script (via the harness llm_call()), used only
when there is genuinely something to phrase or curate — never the thing that runs
every tick and decides whether to notify.
A bare natural-language --instruction (LLM every tick, always replies) still
exists for trivial one-off jobs, but is the exception, not the default.
notify modes (set via the CLI flags below):
output_only (default for --script) — deliver only when the script prints
something. Empty output → nothing sent. This is what makes monitors silent.True (default for --instruction) — always deliver (empty becomes "erledigt").error — deliver only when the job fails.False — never deliver on success.Failures (script exits non-zero / raises) are always surfaced, in every mode — a broken monitor must not fail silently.
A script reports by printing to stdout. To stay silent it simply prints nothing
(or the marker PAWLIA_SILENT).
Job scripts import pawlia.automation_harness (always importable inside a job;
the scheduler puts it on PYTHONPATH):
from pawlia.automation_harness import get_params, emit, silent, llm_call, log
get_params() -> dict # the job's --params, e.g. {"city": "Magdeburg"}
emit(text) # report text → becomes the notification (empty = silent)
silent() # say nothing (documents intent; a no-op)
log(msg) # diagnostics to stderr (never sent to the user)
llm_call(prompt, system=None, model=None) -> str # one robust LLM call, retries
Rules: do the deterministic check first; call emit() only when there is
something to report; use llm_call() sparingly; let exceptions propagate so
failures are loud.
#!/usr/bin/env python
from pawlia.automation_harness import get_params, emit, silent, log
import urllib.request, json
p = get_params()
city = p.get("city", "Magdeburg")
# ... fetch forecast from a weather API ...
data = json.loads(urllib.request.urlopen(f"https://api.example/forecast?q={city}").read())
if not data.get("thunderstorm"):
silent() # quiet day → nothing sent
else:
emit(f"⛈ Gewitterwarnung {city}: {data['summary']} ab {data['start']}")
#!/usr/bin/env python
import sys
from pawlia.automation_harness import get_params, emit, llm_call
messages = collect_all_messages() # deterministic data gathering
if not messages:
sys.exit(0) # nothing to report → silent
report = llm_call(
system="Du bist ein knapper Nachrichten-Kurator. Fasse zusammen, gruppiere, priorisiere.",
prompt="Erstelle einen aufgeräumten Morgenbericht aus:\n\n" + "\n".join(messages),
)
emit(report)
Pick the kind that matches the silence rule — before you build the script:
| Job kind | Stays silent when there is nothing to say? | Use |
|----------|--------------------------------------------|-----|
| Monitor (cyclic check: thunderstorm, train delay, inbox watch) | Yes — the script decides; empty stdout = no notification | script in workspace/skills/scripts/<name>.py, register with add-job --script |
| One-shot (must produce output every tick: morning digest, daily summary) | No — the LLM is invoked every run, the response is always delivered | add-job --instruction (or a script that always emits) |
Rule of thumb: "tell me only when something is up" → script. "give me an update every morning" → instruction.
A trivial gate you can write inline → write it to
workspace/skills/scripts/<name>.py. Anything with API calls, parsing, or
LLM curation → ask skill-creator to build it (it knows the harness skeleton
and will test the script before you register it):
Call skill-creator with: "Baue ein Automations-Skript das [task]. Nutze das
pawlia.automation_harness (get_params/emit/silent/llm_call) und bleib still wenn
nichts zu melden ist."
The script must live under workspace/skills/scripts/ (the primary path the
scheduler resolves job scripts from; workspace/.scripts/ and automations/
still resolve as legacy fallbacks for older jobs).
For a monitor (script that may stay silent):
python <scripts_dir>/../organizer/scripts/organizer.py add-job \
--name "<descriptive name>" \
--schedule "<schedule>" \
--script "<name>.py" \
--params '{"city":"Magdeburg"}'
For a one-shot that always delivers output:
python <scripts_dir>/../organizer/scripts/organizer.py add-job \
--name "<name>" --schedule "<schedule>" --instruction "<instruction>"
Notify flags (override the per-kind default):
--notify-on-output — deliver only when there is output (silent on empty). Default for --script.--notify-on-error — deliver only on failure.--no-notify — never deliver on success (failures still surface).Schedule formats:
"16:00" — daily at 16:00"interval:5m" — every 5 minutes (m/h/d)"interval:1h" — every hour"weekly:0:09:00" — weekly Monday 09:00 (0=Mon..6=Sun)"monthly:1:10:00" — monthly on the 1st at 10:00"30 8 * * 1,3" — cron syntax (5 space-separated fields)python <scripts_dir>/../organizer/scripts/organizer.py list-jobs
python <scripts_dir>/../organizer/scripts/organizer.py delete-job --job-id "<id>"
python <scripts_dir>/../organizer/scripts/organizer.py toggle-job --job-id "<id>"
python <scripts_dir>/../organizer/scripts/organizer.py run-job --job-id "<id>"
Flags the job for immediate execution on the next scheduler tick (within 60s). Use this after building/modifying the script to verify the job behaves: confirm the silent case sends nothing and the alert case sends exactly one message.
run-job and confirm no notification is sent when the script prints nothing.After registering, confirm to the user:
tools
Sets up SSH-based git push for the Pawlia workspace, manages the workspace git remote, and creates automation jobs for regular pushes. Use when the user wants to: sync the workspace to an external git repo, set up git push, configure a git remote for the workspace, fix git push errors (SSH key, host key, authentication), check push status. Triggers on phrases like "workspace git", "git push einrichten", "ssh key für git", "workspace remote", "git sync", "push workspace".
development
Create new PawLia skills from scratch, improve or audit existing ones. Also manages credentials for skills — store, check, list and delete API keys and tokens that other skills need at runtime (skills themselves only see the runtime `CRED_*` env vars, never the store). When a skill has bugs or needs changes, delegate the full task here — describe the problem and let the skill-creator autonomously diagnose and fix it. Do not pre-read the skill files yourself. Use when the user wants to: create a new skill, scaffold a skill directory, manage skill credentials, improve or review an existing skill, validate a SKILL.md against the spec, package a skill for distribution. Triggers on phrases like "create a skill", "new skill", "store api key", "add credentials", "improve this skill", "validate skill", "audit skill", "scaffold a skill".
development
Perform web searches using a SearXNG instance. Use when the user asks for web search results, current information, news, or wants to find online resources.
development
Collect web sources into named research projects and answer questions from them. Scrapes URLs (recursive crawl, PDFs, YouTube transcripts) into a project, then answers questions grounded in the gathered sources via semantic/keyword search. Use for "research X", building a sourced dossier on a topic, or querying previously gathered material — as opposed to a one-shot web search (perplexica/searxng). Commands: create, list, add, query, delete, rename (syntax in the skill instructions).