← Back to Skills Marketplace
23
Downloads
0
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install laosi-scheduler
Description
任务调度 - 定时任务/周期性任务/一次性提醒,cron语法支持,持久化存储,下次执行时间自动计算
README (SKILL.md)
Scheduler - 任务调度器
激活词: 调度 / 定时任务 / 提醒 / schedule
功能
- 创建定时任务(cron表达式)
- 一次性提醒(指定时间)
- 周期性任务(每天/每周/每月)
- 任务列表和状态管理
- 下次执行时间自动计算
- 持久化存储
Python 实现
import os, json, re
from datetime import datetime, timedelta
from typing import List, Optional, Dict
from dataclasses import dataclass, field, asdict
SCHEDULE_FILE = os.path.join(os.path.dirname(__file__), "scheduled_tasks.json")
@dataclass
class ScheduledTask:
name: str
schedule: str # cron表达式: "minute hour day month weekday"
description: str = ""
enabled: bool = True
last_run: Optional[str] = None
next_run: Optional[str] = None
created: str = ""
run_count: int = 0
tags: List[str] = field(default_factory=list)
class Scheduler:
def __init__(self):
os.makedirs(os.path.dirname(SCHEDULE_FILE), exist_ok=True)
self.tasks: List[ScheduledTask] = []
self._load()
def _load(self):
if os.path.exists(SCHEDULE_FILE):
with open(SCHEDULE_FILE, encoding="utf-8") as f:
data = json.load(f)
self.tasks = [ScheduledTask(**t) for t in data]
def _save(self):
with open(SCHEDULE_FILE, "w", encoding="utf-8") as f:
json.dump([asdict(t) for t in self.tasks], f,
ensure_ascii=False, indent=2)
def add_task(self, name: str, schedule: str,
description: str = "", tags: list = None) -> ScheduledTask:
"""添加定时任务"""
task = ScheduledTask(
name=name,
schedule=schedule,
description=description,
enabled=True,
created=datetime.now().isoformat(),
next_run=self._calc_next_run(schedule),
tags=tags or []
)
self.tasks.append(task)
self._save()
return task
def _calc_next_run(self, cron_expr: str) -> str:
"""计算下次执行时间(简化实现)"""
parts = cron_expr.strip().split()
if len(parts) != 5:
return datetime.now().isoformat()
minute, hour, day, month, weekday = parts
now = datetime.now()
# 简单解析:如果只有小时和分钟指定
if minute == "*" and hour == "*":
# 每分钟:下一分钟
next_time = now + timedelta(minutes=1)
elif minute != "*" and hour == "*":
# 每小时的指定分钟
m = int(minute)
next_time = now.replace(minute=m, second=0, microsecond=0)
if next_time \x3C= now:
next_time += timedelta(hours=1)
elif minute != "*" and hour != "*":
# 每天的指定时间
h, m = int(hour), int(minute)
next_time = now.replace(hour=h, minute=m, second=0, microsecond=0)
if next_time \x3C= now:
next_time += timedelta(days=1)
else:
# 默认:1小时后
next_time = now + timedelta(hours=1)
return next_time.isoformat()
def remove_task(self, task_id: int) -> bool:
"""删除任务"""
if 0 \x3C= task_id \x3C len(self.tasks):
self.tasks.pop(task_id)
self._save()
return True
return False
def toggle(self, task_id: int) -> Optional[bool]:
"""启用/禁用任务"""
if 0 \x3C= task_id \x3C len(self.tasks):
self.tasks[task_id].enabled = not self.tasks[task_id].enabled
self._save()
return self.tasks[task_id].enabled
return None
def mark_run(self, task_id: int):
"""标记任务已执行"""
if 0 \x3C= task_id \x3C len(self.tasks):
task = self.tasks[task_id]
task.last_run = datetime.now().isoformat()
task.run_count += 1
task.next_run = self._calc_next_run(task.schedule)
self._save()
def due_tasks(self) -> List[ScheduledTask]:
"""获取到期的任务"""
now = datetime.now()
return [
t for t in self.tasks
if t.enabled and t.next_run and datetime.fromisoformat(t.next_run) \x3C= now
]
def list_tasks(self, enabled_only: bool = False) -> List[Dict]:
"""列出所有任务"""
tasks = [t for t in self.tasks if not enabled_only or t.enabled]
return [
{
"id": i,
"name": t.name,
"schedule": t.schedule,
"enabled": t.enabled,
"next_run": t.next_run,
"last_run": t.last_run or "never",
"run_count": t.run_count,
"tags": t.tags,
}
for i, t in enumerate(tasks)
]
def summary(self) -> Dict:
"""调度器概览"""
total = len(self.tasks)
enabled = sum(1 for t in self.tasks if t.enabled)
due_now = len(self.due_tasks())
return {
"total": total,
"enabled": enabled,
"disabled": total - enabled,
"due_now": due_now,
"file": SCHEDULE_FILE
}
# 使用示例
sched = Scheduler()
# 添加定时任务
sched.add_task(
name="daily backup",
schedule="0 2 * * *", # 每天凌晨2点
description="Run daily database backup",
tags=["system", "backup"]
)
sched.add_task(
name="health check",
schedule="*/5 * * * *", # 每5分钟
description="Ping all services",
tags=["monitoring"]
)
sched.add_task(
name="weekly report",
schedule="0 9 * * 1", # 每周一9点
description="Generate and email weekly report",
tags=["report", "email"]
)
sched.add_task(
name="standup reminder",
schedule="0 10 * * 1-5", # 工作日10点
description="Remind team for daily standup",
tags=["team", "meeting"]
)
# 查看所有任务
print("任务列表:")
for t in sched.list_tasks():
status = "🟢" if t["enabled"] else "🔴"
print(f" {status} [{t['id']}] {t['name']} ({t['schedule']})")
print(f" Next: {t['next_run']}")
# 调度器概览
stats = sched.summary()
print(f"\
调度器: {stats['enabled']}/{stats['total']} 启用, {stats['due_now']} 个待执行")
# 检查到期任务
due = sched.due_tasks()
if due:
print(f"\
到期任务 ({len(due)}):")
for t in due:
print(f" ⏰ {t.name} - 应在 {t.next_run} 执行")
# 执行并标记
sched.mark_run(self.tasks.index(t))
Cron语法速查
* * * * *
│ │ │ │ │
│ │ │ │ └── 星期 (0-7, 0和7=周日)
│ │ │ └──── 月份 (1-12)
│ │ └────── 日期 (1-31)
│ └──────── 小时 (0-23)
└────────── 分钟 (0-59)
| 示例 | 含义 |
|---|---|
0 2 * * * |
每天凌晨2点 |
*/5 * * * * |
每5分钟 |
0 9 * * 1 |
每周一9点 |
0 9-17 * * 1-5 |
工作日9点到17点每小时 |
0 0 1 * * |
每月1日0点 |
30 8 * * * |
每天8:30 |
使用场景
- 系统维护: 定时备份、日志清理、缓存刷新
- 监控告警: 定期健康检查,异常自动告警
- 报告生成: 自动生成日报/周报并发送
- 个人提醒: 喝水/站立/休息的定时提醒
- 工作流: 定时触发数据同步/ETL任务
依赖
- Python 3.8+
- 无第三方依赖
Usage Guidance
Install only if you want a local reminder/task metadata helper. Ask the agent to confirm before creating, deleting, or disabling tasks, and be aware that broad words like "reminder" or "schedule" may activate it depending on the host's matching behavior.
Capability Assessment
Purpose & Capability
The artifact purpose is task scheduling, reminders, cron-style next-run calculation, listing, toggling, and removal; the included Python code matches that purpose and only manages task metadata.
Instruction Scope
The activation words include generic terms such as scheduling and reminders, which are relevant to the purpose but could invoke the skill in ordinary conversation if the host uses loose matching.
Install Mechanism
The package contains a single markdown skill file with no executable installer, external dependency declaration, network fetch, or post-install script.
Credentials
The implementation uses local Python standard-library file I/O only, writing a scheduled_tasks.json file next to the skill; this is proportionate for persistent reminders and does not read broad local data or credentials.
Persistence & Privilege
Persistence is disclosed and limited to saved scheduled task records; task creation, deletion, toggling, and run marking mutate that local store, so users should expect local state changes.
How to Use
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install laosi-scheduler - After installation, invoke the skill by name or use
/laosi-scheduler - Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial release of laosi-scheduler.
- Supports creating scheduled, recurring, and one-time tasks using cron syntax.
- Persists tasks with automatic calculation of the next execution time.
- Enables viewing, enabling/disabling, and removing tasks.
- Allows tracking run history and task summaries.
- No external dependencies; implemented in pure Python 3.8+.
Metadata
Frequently Asked Questions
What is 任务调度器?
任务调度 - 定时任务/周期性任务/一次性提醒,cron语法支持,持久化存储,下次执行时间自动计算. It is an AI Agent Skill for Claude Code / OpenClaw, with 23 downloads so far.
How do I install 任务调度器?
Run "/install laosi-scheduler" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is 任务调度器 free?
Yes, 任务调度器 is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does 任务调度器 support?
任务调度器 is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created 任务调度器?
It is built and maintained by 534422530 (@534422530); the current version is v1.0.0.
More Skills