Agent Skills › xuiltul/animaworks › cron-management

cron-management

GitHub

提供cron.md文件的读写规范,指导添加、更新和删除定时任务。明确5字段Cron表达式格式及LLM/命令类型任务的Markdown结构,确保计划任务配置的正确性与一致性。

templates/en/common_skills/cron-management/SKILL.md xuiltul/animaworks

Trigger Scenarios

需要编辑或新增Cron定时任务 需要删除现有定时任务 维护LLM或命令行类型的调度作业

Install

npx skills add xuiltul/animaworks --skill cron-management -g -y
More Options

Non-standard path

npx skills add https://github.com/xuiltul/animaworks/tree/main/templates/en/common_skills/cron-management -g -y

Use without installing

npx skills use xuiltul/animaworks@cron-management

指定 Agent (Claude Code)

npx skills add xuiltul/animaworks --skill cron-management -a claude-code -g -y

安装 repo 全部 skill

npx skills add xuiltul/animaworks --all -g -y

预览 repo 内 skill

npx skills add xuiltul/animaworks --list

SKILL.md

Frontmatter
{
    "name": "cron-management",
    "description": "cron.mdA skill for reading and writing in the correct format. Provides procedures for adding, updating, and deleting scheduled tasks. Use when: cron.mdwhen you need to edit, add cron expressions, add or delete LLM-type or command-type tasks, or maintain scheduled jobs."
}

Framework-side implementation (for reference)

cron (Scheduled Tasks)

Parsing of cron is handled by core/runtime/schedule_parser.py (parse_cron_md / parse_schedule), while registration, execution, and reloading are handled by core/runtime/scheduler_manager.py (APScheduler, AsyncIOScheduler(timezone=get_app_timezone())).

core/tasks/background.py (a separate system from cron)

This module does not perform cron scheduling. It handles background execution of long-running tool calls and rotation of DM logs. Do not confuse it with cron.

BackgroundTaskManager

  • Role: Executes target tools asynchronously on asyncio and saves status to disk.
  • Persistence location: state/background_tasks/{task_id}.json (pending / running / completed / failed, result strings, errors, timestamps).
  • Public API (overview):
    • submit(tool_name, tool_args, execute_fn) — Runs synchronous execution functions in a thread pool.
    • submit_async(...) — Asynchronous execute_fn version.
    • get_task / list_tasks / active_count — Queries.
    • cleanup_old_tasks(max_age_hours=24) — Deletes completed and failed tasks older than 24 hours. Additionally, deletes JSON files that have remained in running state for more than 48 hours (crash orphans).
  • from_profiles(anima_dir, ..., profiles, config_eligible): The set of background target tools is merged from the following 3 layers (later wins).
    1. In-code defaults _DEFAULT_ELIGIBLE_TOOLS (a fixed list compatible with Mode A)
    2. Entries from EXECUTION_PROFILE to background_eligible: true in each tool module (core.integrations._base.get_eligible_tools_from_profiles). Keys use the "{tool}:{subcommand}" format (consistent with Mode S's submit)
    3. config_eligible passed from config.json and others (explicit override)
  • is_eligible(tool_name): Matching is possible by either of the following names — schema name (e.g., generate_3d_model), profile key (e.g., image_gen:3d).
  • Examples included in _DEFAULT_ELIGIBLE_TOOLS by default (values are approximate seconds): generate_character_assets / generate_fullbody / generate_bustup / generate_icon / generate_chibi / generate_3d_model / generate_rigged_model / generate_animations (30 each), local_llm / run_command (60 each).
  • Completion hook: Callable[[BackgroundTask], Awaitable[None]] can be set in on_complete. The application side can write Markdown notifications to state/background_notifications/ from here (background.py itself does not touch the notification directory).

rotate_dm_logs

  • Truncates entries in shared/dm_logs/*.jsonl at max_age_days (default 7 days), appending old lines to {stem}.{YYYYMMDD}.archive.jsonl as an archive. This is not a cron task, but it is defined in the same file as background maintenance, so it is listed here for reference.

Structure of cron.md

Overall configuration

# Cron: {自分の名前}

## タスク名1
schedule: 0 9 * * *
type: llm
タスクの説明文...

## タスク名2
schedule: */5 * * * *
type: command
command: /path/to/script.sh

Rules that must be strictly followed

  1. Each task must start with ## タスク名 (H2 heading. Do not use H3 or H1)
  2. The schedule: line is mandatory (must start with the keyword schedule:. Do not make it a ### heading)
  3. The schedule must be a standard 5-field cron expression only (09:00 and 毎週金曜 17:00 are not allowed)
  4. The type: line is mandatory (either llm or command)
  5. Insert a blank line between tasks (for readability)

Incorrect writing style

❌ ### */5 * * * *           ← H3見出しにcron式を書いてはいけない
❌ ### 09:00                 ← 自然言語の時刻表記は不可
❌ ### 毎週金曜 17:00         ← 日本語のスケジュール表記は不可
❌ cron: 0 9 * * *           ← キー名は "schedule:" であること("cron:" ではない)
❌ interval: 5m              ← interval形式は不可
❌ schedule: 0 9 * * * *     ← 6フィールドは不可(5フィールドのみ)

Correct writing style

✅ schedule: 0 9 * * *       ← "schedule:" + 半角スペース + 5フィールドcron式
✅ schedule: */5 * * * *
✅ schedule: 30 21 * * *
✅ schedule: 0 17 * * 5

5-field cron expression reference

Field structure

schedule: 分 時 日 月 曜日
Field Position Range Description
Minute 1 0-59 At what minute to execute
Hour 2 0-23 At what hour to execute (24-hour format)
Day 3 1-31 On what day to execute
Month 4 1-12 In what month to execute
Weekday 5 0-6 On what weekday to execute (0=Mon, 6=Sun)

Note: Weekday is 0=Monday, 6=Sunday (APScheduler specification. This differs from the common cron convention where 0=Sunday)

Special characters

Character Meaning Example
* All values * * * * * = every minute
*/n Interval of n */5 * * * * = every 5 minutes
n-m Range 0 9-17 * * * = every hour from 9:00 to 17:00
n,m List 0 9,12,18 * * * = 9:00, 12:00, 18:00
n-m/s Range + interval 0 9-17/2 * * * = every 2 hours from 9:00 to 17:00

Commonly used schedule examples

Daily

What you want to do cron expression Explanation
Every morning at 9:00 0 9 * * * minute=0, hour=9
Every morning at 9:30 30 9 * * * minute=30, hour=9
Every day at 12:00 (noon) 0 12 * * * minute=0, hour=12
Every day at 18:00 0 18 * * * minute=0, hour=18
Every evening at 21:30 30 21 * * * minute=30, hour=21
Every day at 2:00 AM 0 2 * * * minute=0, hour=2

Interval-based

What you want to do cron expression Explanation
Every 5 minutes */5 * * * * minute=*/5(0,5,10,...,55)
Every 10 minutes */10 * * * * minute=*/10(0,10,20,...,50)
Every 15 minutes */15 * * * * minute=*/15(0,15,30,45)
Every 30 minutes */30 * * * * minute=*/30(0,30)
Every hour 0 * * * * at minute 0 of every hour
Every 2 hours 0 */2 * * * at minute 0 of 0:00, 2:00, 4:00, ..., 22:00
Every 5 minutes during business hours only */5 9-17 * * * every 5 minutes from 9:00 to 17:55
Every hour during business hours only 0 9-17 * * * every hour on the hour from 9:00 to 17:00

Weekday-based

What you want to do cron expression Explanation
Every weekday morning at 9:00 0 9 * * 0-4 weekday=0-4 (Mon-Fri)
Every Monday at 9:00 0 9 * * 0 weekday=0 (Mon)
Every Friday at 17:00 0 17 * * 4 weekday=4 (Fri)
Every Friday at 18:00 0 18 * * 4 weekday=4 (Fri)
Every 30 minutes during business hours on weekdays */30 9-17 * * 0-4 weekdays 9:00-17:30
Every weekend morning at 10:00 0 10 * * 5,6 weekday=5,6 (Sat, Sun)

Monthly

What you want to do cron expression Explanation
On the 1st of every month at 9:00 0 9 1 * * day=1
On the 15th of every month at 12:00 0 12 15 * * day=15
Near the last business day of every month (28th) 0 17 28 * * day=28 (approximation)
On the first day of each quarter at 9:00 (Jan, Apr, Jul, Oct) 0 9 1 1,4,7,10 * month=1,4,7,10

Task type details

type: llm — LLM judgment task

Tasks that require thinking and judgment. Write the task content as free text after schedule: and type: llm.

## 毎朝の業務計画
schedule: 0 9 * * *
type: llm
長期記憶から昨日の進捗を確認し、今日のタスクを計画する。
理念と目標に照らして優先順位を判断する。
結果は state/current_state.md に書き出す。
  • The description is passed directly as the prompt to the LLM
  • Clearly specifying the concrete output (what to write out) is effective
  • Multiple lines are allowed
  • If you want to include a fenced code block in the body (```)が含まれると、パーサーが警告ログを出す(確定コマンドなら type: command should be considered)

type: command — Command execution task

Bash commands or tool calls that execute deterministically.

Pattern A: bash command

## バックアップ実行
schedule: 0 2 * * *
type: command
command: /usr/local/bin/backup.sh
  • Write the command to execute in a single line in command:
  • Shell redirection (>, >>, |) is usable
  • Multi-line commands are not recommended (combine into one line or use a script file)

Pattern B: tool call

## Slack朝の通知
schedule: 0 9 * * 0-4
type: command
tool: slack_channel_post
args:
  channel_id: "C0123456789"
  text: "おはようございます!"
  • Write the tool name in tool: (a schema name included in the permission settings of permissions.json. For example, for Slack posting, use slack_channel_post)
  • After args:, use a YAML block format with 2-space indentation
  • It is executed with ToolHandler.handle(tool, args), and the result string is treated as the equivalent of stdout

Option: skip_pattern

A follow-up cron LLM (an analysis session with heartbeat-equivalent context) that runs only when the command succeeds (exit_code == 0) via type: command and stdout is non-empty is suppressed when stdout matches this regular expression.

## Chatwork未返信チェック
schedule: */5 * * * *
type: command
command: chatwork_cli.py unreplied --json
skip_pattern: "^\[\]$"
  • Write a regular expression in skip_pattern: (at runtime, re.search(skip_pattern, stdout) is used)
  • If the regular expression contains YAML special characters such as [], enclose it in quotes ("..." or '...'). The parser automatically removes the outer quotes
  • At parse time, an invalid regular expression → a warning is logged and skip_pattern is treated as unset (no follow-up suppression)
  • At runtime, if re.search throws an exception (e.g., a residual invalid pattern) → a warning is logged and the follow-up is executed without suppression
  • In the example above, the follow-up is skipped when the number of unreplied messages is 0 ([])

Option: trigger_heartbeat

Controls per-task whether to run the follow-up cron LLM when the command succeeds (following the evaluation order of SchedulerManager._run_cron_task).

## Chatwork未返信チェック
schedule: */15 * * * *
type: command
command: animaworks-tool chatwork unreplied
skip_pattern: "^\[\]$"
trigger_heartbeat: false
  • Conditions under which a follow-up is considered (when all are satisfied): exit_code == 0 and stdout (after .strip()) is non-empty
  • Length of stdout: The stdout that run_cron_command returns to the scheduler is truncated to the first 1000 characters. This preview is also what is passed to the follow-up LLM. For the full log, refer to state/cron_logs/ (JSONL)
  • trigger_heartbeat: false — Even if the above conditions are satisfied, the follow-up cron LLM is not executed (evaluated before skip_pattern)
  • trigger_heartbeat: true (default) — If the conditions are satisfied, the follow-up is executed (then skip_pattern is evaluated next)
  • If false, no, or 0 is specified, it is suppressed. Otherwise, it is treated as true
  • The follow-up cron LLM runs with a heartbeat-equivalent prompt filter (background context)
  • When exit_code != 0 or stdout is empty, the follow-up does not start in the first place (skip_pattern / trigger_heartbeat are irrelevant)

Criteria for choosing between types

Cases where type: command should be used

  • The command to execute is fully determined
  • Parameters are fixed (region, cluster name, profile, etc.)
  • Judgment of the result is left to the cron LLM session

Cases where type: llm should be used

  • The execution content needs to change depending on the situation
  • Investigation combining multiple tools is required
  • Human-like judgment and analysis are needed at the execution stage

Prohibited patterns

  • Including a code block (a fixed command) in type: llm → That command should be type: command
  • Writing "execute exactly as follows" but using type: llm → The LLM cannot accurately reproduce commands. Use type: command

Anima is not "a person who memorizes commands"

type: command is the same as a human saving a script. Anima's value lies in the ability to judge based on results. Leave deterministic execution to the framework, and have Anima focus on judgment, analysis, and reporting.


cron.md Parse Notifications (Automatic)

When a parse or registration error is detected during the initial registration of cron.md or at reload_schedule, the scheduler generates a state/background_notifications/cron_health_{タイムスタンプ}.md. The notification is included in the context of the next heartbeat or cron execution. There is no feature for periodically monitoring the execution status of registered cron jobs.

Detected issues:

  • A task is defined, but no valid schedule can be registered (e.g., all expressions are invalid)
  • Outside of comments or code fences, there is a schedule: line with leading whitespace (schedule: must be written at the beginning of the line)
  • The valid configuration text contains schedule:, but the parser returns no tasks at all

cron.md Operating Procedures

Target Paths and Subordinate Editing

  • Read your own cron.md via read_memory_file(path="cron.md"), and update it via write_memory_file(path="cron.md", ...).
  • A supervisor can edit subordinates' cron.md / heartbeat.md using the write memory tool by specifying them as in ../{anima_name}/cron.md (applies to all subordinates, including children, grandchildren, and below).
  • status.json / identity.md / permissions.json are owned by root and cannot be written to from memory or file tools. Authorized supervisor injection.md changes and identity creation requests during bootstrap are forwarded to and authorized by root. No direct file operations are performed.

Adding a New Task

  1. Load your own cron.md
  2. Append a new section at the end of the file
  3. Verify the format before writing (see the checklist below)
  4. Write the file
## 新しいタスク名
schedule: <5フィールドcron式>
type: llm|command
<説明またはcommand/tool行>

Modifying an Existing Task

  1. Load cron.md
  2. Locate the relevant section (from ## タスク名 up to just before the next ##)
  3. Edit the lines to change (schedule:, type:, description text, etc.)
  4. Write the file

Deleting a Task

  1. Load cron.md
  2. Delete the entire relevant section (from ## タスク名 up to just before the next ##)
  3. Write the file

Temporarily Disabling a Task

Wrapping it in HTML comments makes the parser skip it:

<!--
## 一時停止中のタスク
schedule: 0 9 * * *
type: llm
このタスクは一時的に停止中。
-->

Pre-Write Checklist

Before updating cron.md, always verify the following:

  • Each task starts with ## タスク名 (not ### or #)
  • A schedule: line exists (not a ### heading or natural language)
  • The schedule is a 5-field cron expression (分 時 日 月 曜日)
  • Each field's value is within the valid range (minute: 0-59, hour: 0-23, day: 1-31, month: 1-12, weekday: 0-6)
  • A type: line exists (llm or command)
  • For command type, command: or tool: exists
  • For tool type, the indentation of args: is correct (2 spaces)
  • There is a blank line between tasks
  • schedule: is not written inside a code block (this can cause health warnings)

Validation Method

After writing, you can verify that parsing works correctly with the following command:

# プロジェクトルートで実行。ANIMAWORKS_ANIMA_DIR 未設定時は ~/.animaworks/animas/default を使用
python -c "
from core.runtime.schedule_parser import parse_cron_md, parse_schedule
import os
from pathlib import Path

cron_path = Path(os.environ.get('ANIMAWORKS_ANIMA_DIR', '~/.animaworks/animas/default')) / 'cron.md'
content = cron_path.expanduser().read_text()
tasks = parse_cron_md(content)
for t in tasks:
    trigger = parse_schedule(t.schedule)
    status = '✅' if trigger else '❌ パース失敗'
    print(f'{status} {t.name}: schedule=\"{t.schedule}\" type={t.type}')
"

If all tasks show ✅, everything is normal. If ❌ appears, correct the schedule expression.


Complete Example

# Cron: example_anima

## 毎朝の業務計画
schedule: 0 9 * * *
type: llm
長期記憶から昨日の進捗を確認し、今日のタスクを計画する。
理念と目標に照らして優先順位を判断する。
結果は state/current_state.md に書き出す。

## Chatwork未返信チェック
schedule: */5 9-18 * * 0-4
type: command
command: chatwork-cli unreplied --json > $ANIMAWORKS_ANIMA_DIR/state/chatwork_unreplied.json
skip_pattern: "^\[\]$"
trigger_heartbeat: false

## Slack朝の挨拶
schedule: 0 9 * * 0-4
type: command
tool: slack_channel_post
args:
  channel_id: "C0123456789"
  text: "おはようございます!今日もよろしくお願いします。"

## 週次振り返り
schedule: 0 17 * * 4
type: llm
今週のepisodes/を読み返し、パターンを抽出してknowledge/に統合する。
改善点があれば procedures/ に手順を追記する。

## 月次レポート
schedule: 0 10 1 * *
type: llm
先月のepisodes/とknowledge/を分析し、月次サマリーレポートを作成する。
レポートは knowledge/monthly_report_YYYY-MM.md として保存する。

Common Mistakes and Fixes

Mistake Correct Form Reason
### */5 * * * * schedule: */5 * * * * H3 headings cannot be used as task separators
### 09:00 schedule: 0 9 * * * Natural language times cannot be parsed
### 毎週金曜 17:00 schedule: 0 17 * * 4 Japanese notation cannot be parsed
schedule: 9:00 schedule: 0 9 * * * HH:MM format is not a 5-field cron expression
schedule: every 5 minutes schedule: */5 * * * * English notation cannot be parsed
schedule: 0 9 * * 7 schedule: 0 9 * * 6 Weekday 7 is out of range (0-6)
schedule: 0 9 * * SUN schedule: 0 9 * * 6 Weekday names cannot be used (numbers only)
schedule: 0 25 * * * schedule: 0 23 * * * Hour must be in the range 0-23
schedule: 60 * * * * schedule: 0 * * * * Minute must be in the range 0-59
skip_pattern: ^\[\]$ (without quotes) skip_pattern: "^\[\]$" [] is interpreted as an empty list in YAML. Wrap it in quotes

Notes

  • Hot reload: When cron.md / heartbeat.md are updated via Anima's write_memory_file, etc., the schedule change callback triggers reload_schedule and re-registers immediately. Subordinate management files are also edited with the write memory tool as in ../{anima_name}/cron.md. External direct edits are also detected by the mtime check (_check_schedule_freshness) just before the next heartbeat or any cron fires, but this is not the standard procedure for supervisor edits to subordinate files
  • Old jobs immediately after reload: When the scheduler is rebuilt upon detecting an mtime change, cron firings tied to the previous definition may be skipped as "stale" (intentional duplicate execution prevention)
  • Time zone: APScheduler uses get_app_timezone(). The system.timezone of config.json can be set to an IANA name (e.g., Asia/Tokyo). When empty, the OS time zone is auto-detected, falling back to Asia/Tokyo on failure
  • Concurrency: If task names differ, multiple jobs in the same minute may run in parallel via asyncio.create_task. The same task name will not re-enter while running (skipped via _cron_running). Each job is max_instances=1
  • Command type does not stop the process on failure (cron_executed is recorded, and stderr / exit_code remain in the log). The follow-up cron LLM runs only on success and when stdout exists (as described above)
  • Periodic execution of type: llm uses the background model (background_model of status.json, etc.; the main model is used if not set)
  • Detailed command output accumulates in state/cron_logs/ (daily JSONL) and is housekept for up to 14 days
  • When accessing another Anima's tools/ directory, check permissions in advance

Version History

  • 0f2a80e Current 2026-10-19 11:10
  • edd4a93 2026-09-28 03:35
  • 140e43b 2026-07-25 09:12

Same Skill Collection

.claude/skills/bustup-frame-gen/SKILL.md
.claude/skills/pixel-asset-gen/SKILL.md
templates/en/common_skills/agent-browser/SKILL.md
templates/en/common_skills/animaworks-guide/SKILL.md
templates/en/common_skills/aws-collector-tool/SKILL.md
templates/en/common_skills/chatwork-tool/SKILL.md
templates/en/common_skills/discord-tool/SKILL.md
templates/en/common_skills/github-tool/SKILL.md
templates/en/common_skills/gmail-tool/SKILL.md
templates/en/common_skills/google-calendar-tool/SKILL.md
templates/en/common_skills/google-tasks-tool/SKILL.md
templates/en/common_skills/image-gen-tool/SKILL.md
templates/en/common_skills/image-posting/SKILL.md
templates/en/common_skills/local-llm-tool/SKILL.md
templates/en/common_skills/machine-tool/SKILL.md
templates/en/common_skills/notion-tool/SKILL.md
templates/en/common_skills/skill-creator/SKILL.md
templates/en/common_skills/slack-tool/SKILL.md
templates/en/common_skills/subagent-cli/SKILL.md
templates/en/common_skills/subordinate-management/SKILL.md
templates/en/common_skills/tool-creator/SKILL.md
templates/en/common_skills/transcribe-tool/SKILL.md
templates/en/common_skills/web-search-tool/SKILL.md
templates/en/common_skills/workspace-manager/SKILL.md
templates/en/common_skills/x-search-tool/SKILL.md
templates/en/common_skills/zoom-meeting-scribe/SKILL.md
templates/ja/common_skills/agent-browser/SKILL.md
templates/ja/common_skills/animaworks-guide/SKILL.md
templates/ja/common_skills/aws-collector-tool/SKILL.md
templates/ja/common_skills/chatwork-tool/SKILL.md
templates/ja/common_skills/cron-management/SKILL.md
templates/ja/common_skills/discord-tool/SKILL.md
templates/ja/common_skills/github-tool/SKILL.md
templates/ja/common_skills/gmail-tool/SKILL.md
templates/ja/common_skills/google-calendar-tool/SKILL.md
templates/ja/common_skills/google-tasks-tool/SKILL.md
templates/ja/common_skills/image-gen-tool/SKILL.md
templates/ja/common_skills/image-posting/SKILL.md
templates/ja/common_skills/local-llm-tool/SKILL.md
templates/ja/common_skills/machine-tool/SKILL.md
templates/ja/common_skills/notion-tool/SKILL.md
templates/ja/common_skills/skill-creator/SKILL.md
templates/ja/common_skills/slack-tool/SKILL.md
templates/ja/common_skills/subagent-cli/SKILL.md
templates/ja/common_skills/subordinate-management/SKILL.md
templates/ja/common_skills/tool-creator/SKILL.md
templates/ja/common_skills/transcribe-tool/SKILL.md
templates/ja/common_skills/web-search-tool/SKILL.md
templates/ja/common_skills/workspace-manager/SKILL.md

Metadata

Files
0
Version
0f2a80e
Hash
57e41e5e
Indexed
2026-07-25 09:11

홈 - 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-25 03:21
浙ICP备14020137号-1