jobs
Create and manage scheduled background jobs. Use when the user asks to set up recurring tasks, cron jobs, or anything that should run automatically on a schedule.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create and manage scheduled background jobs. Use when the user asks to set up recurring tasks, cron jobs, or anything that should run automatically on a schedule.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Create, inspect, query, and maintain durable user data tables in ~/.enso/enso.db. Use when the user wants to track structured facts, measurements, metrics, history, or any persistent data that should be filtered, joined, or aggregated later.
Consult and write operator reference docs under ~/.enso/docs/. Use when a task depends on how this machine, network, services, or accounts are wired, or when a durable fact about the setup should be recorded instead of just answered.
Look up Slack users and channels by name, open DMs, read channel history, and search messages. Use when you need to resolve a name to an ID (e.g. someone asks you to "mention Gavin" and you need `<@U…>`), find a channel, or retrieve context from other Slack conversations.
| name | jobs |
| description | Create and manage scheduled background jobs. Use when the user asks to set up recurring tasks, cron jobs, or anything that should run automatically on a schedule. |
Background jobs are scheduled tasks that run autonomously via the
Enso service. Each job spawns a CLI agent on a cron schedule.
Jobs that fail notify the user automatically. Successful jobs are
silent by default — use enso message send in the prompt to
send alerts to the user.
enso job create --name "Name" --provider claude --model sonnet --schedule "0 9 * * *"
— creates the directory and a JOB.md with enabled: falseenabled: true in the frontmatterenso job run <name> to verify it worksenso job list # show all jobs with status
enso job run <name> # manual run (output to stdout)
enso job create --name "Name" --provider claude --model sonnet --schedule "0 9 * * *"
enso job create --name "Name" --provider codex --model terra --schedule "0 9 * * *"
enso job create --name "Name" --provider agy --model gemini-3.6-flash-high --schedule "0 9 * * *"
~/.enso/jobs/
└── <job-name>/
├── JOB.md # Job definition (frontmatter + prompt)
└── prerun.sh # Optional gate/data-gathering script
---
name: Human-readable name
schedule: "0 9 * * *"
provider: claude
model: sonnet
enabled: true
prerun: prerun.sh
---
The prompt goes here. Use {{prerun_output}} to inject prerun results.
| Field | Required | Description |
|---|---|---|
name | yes | Display name (shown in notifications) |
schedule | yes | Cron: minute hour dom month dow |
provider | yes | claude, codex, or agy |
model | yes | Model name (e.g. sonnet; Codex: sol, terra, or luna; Agy: gemini-3.6-flash-high) |
enabled | yes | true or false — disabled jobs are skipped |
prerun | no | Script filename in the job directory |
prerun_timeout | no | Max seconds for the prerun (default 120) |
notify | no | Telegram user ID or Slack channel/DM for failure alerts |
timeout | no | Max seconds for the run (default 900) |
catch_up | no | true to run a missed schedule late (default false) |
misfire_grace_seconds | no | How late a missed run may still fire (default 300) |
provider and model are validated against the configured providers and
their model lists — a job naming an unknown provider or model is rejected at
creation and fails with a clear error instead of running. The cron schedule
is validated at creation too; if a hand-edited schedule later becomes
invalid, the scheduler skips that job (with a log warning) rather than run it.
By default a job that misses its scheduled time by more than
misfire_grace_seconds (e.g. the machine was asleep) is skipped rather than
run late; set catch_up: true when a late run is better than no run.
┌───────────── minute (0-59)
│ ┌─────────── hour (0-23)
│ │ ┌───────── day of month (1-31)
│ │ │ ┌─────── month (1-12)
│ │ │ │ ┌───── day of week (0-6, 0=Sun)
│ │ │ │ │
* * * * *
Examples:
0 9 * * * — daily at 9:00 AM30 6 * * 1-5 — weekdays at 6:30 AM*/15 * * * * — every 15 minutes0 9 * * 1 — Mondays at 9:00 AMMost jobs should have a prerun script. It runs before the LLM is invoked, avoiding wasted tokens when there is nothing to do while keeping real failures visible.
{{prerun_output}} appearsOnly use exit 1 deliberately. Shell wrappers must map command failures to exit
2, and Python entrypoints must catch unexpected exceptions rather than allowing
Python's default exit 1 to collide with the no-work sentinel.
For a useful alert without leaking source data, write one safe summary line to
stderr as ENSO_ERROR: <summary>. Enso never copies prerun stdout or arbitrary
stderr into notifications. Repeated identical failures are suppressed for 24 hours;
a changed failure alerts immediately, and the next healthy prerun sends one recovery.
#!/usr/bin/env bash
# prerun.sh — gate the job and gather data
set -uo pipefail
# 1. Check if there's work to do
if ! RESULT=$(some-command-here); then
echo "ENSO_ERROR: data check failed" >&2
exit 2
fi
# 2. Exit exactly 1 when the command succeeded but found no work
if [[ -z "$RESULT" ]]; then
exit 1
fi
# 3. Output data for the prompt (injected as {{prerun_output}})
echo "$RESULT"
Enso invokes the file through bash, so it does not require an executable bit.
---
name: Daily Overview
schedule: "30 6 * * *"
provider: claude
model: sonnet
enabled: true
---
Generate today's daily overview note. Check the calendar for events
and yesterday's incomplete tasks.
---
name: YouTube Summaries
schedule: "*/15 * * * *"
provider: claude
model: haiku
enabled: true
prerun: prerun.sh
---
Summarise this video and create a note:
{{prerun_output}}
prerun.sh:
#!/usr/bin/env bash
set -uo pipefail
if ! VIDEO=$(python3 check_playlist.py); then
echo "ENSO_ERROR: playlist check failed" >&2
exit 2
fi
if [[ -z "$VIDEO" ]]; then
exit 1
fi
echo "$VIDEO"
---
name: Meeting Prep
schedule: "0 7 * * 1-5"
provider: claude
model: sonnet
enabled: true
prerun: prerun.sh
---
Research these meeting attendees and create notes:
{{prerun_output}}
prerun.sh:
#!/usr/bin/env bash
set -uo pipefail
if ! NEW_PEOPLE=$(osascript get-new-attendees.js); then
echo "ENSO_ERROR: attendee lookup failed" >&2
exit 2
fi
if [[ -z "$NEW_PEOPLE" ]]; then
exit 1
fi
echo "$NEW_PEOPLE"
haiku or sonnet for frequent/simple jobs to save costopus for jobs that need deep reasoning or complex outputsol for frontier work, terra for balanced everyday work, or luna for fast, affordable runsagy), use a gemini-3.6-flash-* model for fast, inexpensive runs or gemini-3.1-pro-* for deeper reasoningenso job run <name> before relying on the scheduleenso service logs if a job isn't firingenabled: false to pause a job without deleting it