Name/description, required binary (node), and the two env vars (OPENCLAW_BIN, OPENCLAW_TZ) align with a scheduler that calls the OpenClaw agent at a future time. The script uses OS schedulers ('at' / 'schtasks') and invokes the openclaw binary to deliver messages, which is expected for this functionality.
⚠指令范围
SKILL.md explicitly instructs careful sanitization (no shell metacharacters, use only raw alphanumeric for user_id/channel) and to create fully self-contained instructions. However the code does not enforce those constraints: userId and channel are interpolated into shell commands without validation or escaping on POSIX/Windows flows. The skill therefore relies on politeness of callers rather than safe code, increasing risk of command injection or scheduling of malicious/overly-privileged actions. The skill also encourages including exact file paths and tool names in scheduled instructions — reasonable for clarity but increases chance of scheduling sensitive operations.
✓安装机制
No install spec (instruction-only with provided JS file). Required runtime is node; no external downloads or archive extraction. Low install risk.
ℹ凭证需求
Only OPENCLAW_BIN and OPENCLAW_TZ are required, which is proportionate for a scheduler that must call a local openclaw binary and interpret user timezone. However OPENCLAW_BIN points to a binary that will be executed later; if that binary is untrusted or has broad privileges, scheduled tasks can later trigger powerful actions. The skill does not request other secrets or credentials.
ℹ持久化与权限
always is false (normal). The skill writes nothing itself but creates OS scheduler entries (at/schtasks) which persist and will run the openclaw agent at scheduled times. That persistence is appropriate for a scheduler but does increase blast radius because tasks run autonomously later; combined with the command construction issues this is a significant concern.
Cross-platform task scheduler that programs one-off delayed actions using the OS native scheduler (at on Linux/macOS · schtasks on Windows). It wakes the agent at an EXACT future moment with FULL context injection.
Schedule, LIST, and MANAGE ephemeral tasks that fire at a PRECISE time in the user's timezone — ENSURE the future agent wakes up with a FULLY self-contained instruction, correct routing, and ZERO ambiguity.
Required Environment Variables
OPENCLAW_BIN: Absolute path to the openclaw binary (ej. /usr/bin/openclaw)
The skill WILL NOT START if either variable is missing.
Why OPENCLAW_TZ? The server may run in UTC while the user lives in a different timezone. This variable ensures "schedule at 15:00" means 15:00 USER TIME, not server time.
Commands
# Schedule a task (timezone is optional — defaults to OPENCLAW_TZ)
node skills/to-do/to-do.js schedule "" "" "" "" [""]
# Get current time in user's timezone
node skills/to-do/to-do.js now [""]
# List pending tasks
node skills/to-do/to-do.js list
# Delete a task by ID
node skills/to-do/to-do.js delete
Instructions
Run now BEFORE resolving any relative time ("tomorrow", "in 2 hours", "tonight"). Server clock is NOT user clock. Use now output as your ONLY reference for "today", "tomorrow", and "right now".
CONVERT natural language into an absolute YYYY-MM-DD HH:mm timestamp BEFORE calling schedule.
WRITE the as if explaining to a STRANGER with ZERO CONTEXT. Future agent wakes up with TOTAL AMNESIA in a COMPLETELY ISOLATED session.
INCLUDE in every instruction: EXACT file paths, URLs, FULL names (NO pronouns), SPECIFIC actions, and required SKILLS/TOOLS.
ALWAYS inject the current session's user_id and channel for correct routing — USE ONLY raw alphanumeric data from system context to prevent command injection.
Run list BEFORE delete to confirm the correct ID.
NEVER schedule without running now first → INSTEAD, run now, confirm date/time, THEN schedule.
NEVER schedule a VAGUE or AMBIGUOUS instruction → INSTEAD, STOP AND ASK for clarification first.
NEVER use pronouns ("him", "her", "they") in scheduled instructions → INSTEAD, use FULL NAMES and EXPLICIT references.
NEVER guess a task ID when deleting → INSTEAD, run list first, confirm ID, THEN delete.
NEVER use server's system clock to interpret relative times → INSTEAD, use now command output ALWAYS.
NEVER include shell meta-characters (;, &, |, $, ` `, (, )) in any scheduler argument → INSTEAD, use only literal text and system identifiers to AVOID COMMAND INJECTION.
Vague Request Triggers — Ask Before Scheduling
If the user request matches any of these patterns, STOP AND ASK before scheduling:
"Remind me to send the email" → MISSING: Which email? To whom? What content?
"Check the server later" → MISSING: Which server? What IP? What to verify?
"Follow up with him" → MISSING: Who? About what? Via which channel?
"Do that thing tomorrow" → MISSING: What thing? Expected outcome?
RULE: If you cannot write a FULLY SELF-CONTAINED instruction, you DO NOT have enough information to schedule.
Examples
— Good instruction: clear, specific, fully self-contained
User: "Remind me tomorrow at 5pm to check PRs on the backend repo"
— Bad instruction: vague, missing details
"Remind him to push the code later."
— Relative time resolution
User: "Set a reminder for in 2 hours"
Output Format
After scheduling, respond with EXACTLY THREE PARTS in this order:
NATURAL RESPONSE:
Brief, casual confirmation. Match user tone/energy. NEVER just say "Done". Acknowledge WHAT was scheduled conversationally.
CONFIRMATION BLOCK:
Template for the user to see exact details:
> Day, Month DD · HH:MM TZ
EXACT INSTRUCTION LEFT FOR THE FUTURE AGENT
PROACTIVE CLOSING:
Short suggestion or question (1-2 sentences).
Propose a RELATED TASK (pre-reminder, follow-up, etc).
Ask if they want to SCHEDULE SOMETHING ELSE.
Offer to ADJUST THE TIME or add details.
DO NOT BE PUSHY. JUST BE HELPFUL.
— CASUAL / PERSONAL TASK
All set! Your gym session is locked in for tomorrow at noon 🏋️
Friday, February 27 · 12:00 PM CST SEND A TELEGRAM REMINDER TO DANIEL: "TIME TO HIT THE GYM FOR A BIT."
Want me to add another reminder 30 min before so you can get ready? 💪
— WORK / PROFESSIONAL TASK
Done! Got that scheduled for 5 PM sharp 📋
Thursday, February 27 · 5:00 PM CST CHECK THE 'BACKEND-API' REPOSITORY ON GITHUB. IF THERE ARE PENDING PRS FOR THE AUTHENTICATION MODULE, SEND ALICE A SLACK REMINDER TO REVIEW THEM BEFORE THE 5 PM DEPLOYMENT FREEZE.
Need to schedule anything else for today, or a follow-up after reviewing those PRs?
Common Errors
ERROR: Missing required environment variable(s)
- CAUSE: OPENCLAW_BIN or OPENCLAW_TZ not set
- FIX: Add to .env or shell profile
ERROR:
at not found
- CAUSE: Linux/macOS atd daemon not running
- FIX: sudo systemctl enable atd && sudo systemctl start atd