אין שגיאה, אין התראה, אין שורה ביומן. פשוט בוקר אחד אין קובץ, ואז עוד בוקר. העמוד הזה מסביר למה זה קורה, נותן לכם פרומפט אחד שמאבחן את המצב אצלכם, ובונה את השגרה מחדש על מתזמן שרץ גם כשהאפליקציה סגורה. No error, no alert, nothing in a log. One morning the file just isn't there, and then another morning. This page explains why that happens, hands you one prompt that diagnoses your own machine, and rebuilds the routine on a scheduler that runs while the app is closed.
השגרות שמגדירים בתוך אפליקציית קלוד רצות רק כשהאפליקציה פתוחה ואתם מחוברים. אם סגרתם אותה בערב, או שהמחשב עשה ריסטארט בלילה, השעה עוברת ואף אחד לא מפעיל כלום.
The scheduled tasks you create inside the Claude desktop app run only while the app is open and you are logged in. Close it in the evening, or let the machine restart overnight, and the scheduled minute passes with nobody home to act on it.
והנה החלק שמבלבל: אין שום מקום שרושם את ההחלטה לא להפעיל. אתם רואים מסך שנראה בדיוק כמו אתמול, ולכן זה מרגיש כמו תקלה, בזמן שזו התנהגות מתוכננת של הכלי.
Here is what makes it confusing. Nothing records the decision not to fire. You see a screen that looks exactly like yesterday, so it feels like a bug when it is simply how the tool is built.
מתזמן א: משימות מתוזמנות באפליקציה
אלה שהגדרתם דרך הממשק, והן יושבות בתיקיית scheduled-tasks. נוחות להגדרה, ותלויות לחלוטין באפליקציה פתוחה ובמשתמש מחובר. מצוינות להדגמה, חלשות בתור שגרה שאמורה לתפוס אתכם ישנים.
Scheduler A: desktop app scheduled tasks
The ones you set up through the interface, sitting in the scheduled-tasks folder. Easy to create, and completely dependent on an open app with a logged in user. Great for a demo, weak as a routine that is supposed to run while you sleep.
מתזמן ב: קרונים שנוצרים בתוך שיחה
אלה נוצרים בתוך שיחה, למשל דרך /loop, ומתים יחד עם השיחה. אם השגרה שלכם קיימת רק שם, היא מעולם לא הותקנה. אין מה לתקן בשעה, צריך להתקין אותה במקום אחר.
Scheduler B: crons created inside a chat
These are created inside a chat, with /loop for example, and they die when the chat closes. If your routine lives only there, it was never installed in the first place. Changing the hour will not help, it needs a real home.
מתזמן ג: המתזמן של מערכת ההפעלה
launchd ב-Mac, Task Scheduler ב-Windows. הוא חלק מהמחשב עצמו, הוא ער כל עוד המחשב ער, ולא מעניין אותו אם אפליקציה כלשהי פתוחה. הוא פשוט מריץ את מה שאמרתם לו להריץ, בשעה שאמרתם.
Scheduler C: your operating system's own scheduler
launchd on a Mac, Task Scheduler on Windows. It is part of the machine, it is awake as long as the machine is awake, and it does not care whether any app is open. It runs what you told it to run, at the hour you told it.
התשובה הכנה היא להעביר את השגרה למתזמן ג'. פשוט להעביר אותה למקום שלא תלוי בכם, ולא באפליקציה פתוחה.
The honest answer is to move the routine onto scheduler C. Put it somewhere that depends on the machine, not on you or on an open app.
זה קרה גם לנו. לצוות שלנו יש שלושה מיילים שבועיים: יומן ביום שישי, סיכום בשבת, והקלטה קולית קצרה אחרי הסיכום. הם רצו כמו שעון, עד שהם הפסיקו.
It happened to us. Our team runs three weekly emails: a journal on Friday, a summary on Saturday, and a short voice note after the summary. They ran like clockwork, until they stopped.
שבועיים שלמים, מה-22 באוגוסט ועד ה-5 בספטמבר, לא יצא אף אחד מהם. הם היו מוגדרים כמשימות מתוזמנות באפליקציה. במחשב הנייד הן היו מכובות, ומחשב אחר שדולק תמיד החזיק אותן, עד שהוא עשה ריסטארט ומנגנון המשימות שלו פשוט נשאר שקט.
For two full weeks, from 22 August to 5 September, not one of them went out. They lived as scheduled tasks inside the desktop app. On the laptop they were disabled, and an always on machine carried them, until it rebooted and its task runner quietly stayed idle.
שום דבר לא התריע. לא קיבלנו שגיאה, לא ראינו לוג, ואף אחד לא שם לב שבועיים, כי מייל שלא נשלח לא מרעיש. שקט נראה בדיוק כמו הצלחה.
Nothing alerted us. No error arrived, no log showed anything, and nobody noticed for two weeks, because an email that was never sent makes no noise. Silence looks exactly like success.
העברנו את שלושתם ל-launchd, עם בדיקה שרצה אחרי כל הרצה ומוודאת שהקובץ באמת נוצר. שלושתם רצו תוך 20 דקות. הלקח שנשאר לנו: שגרה חייבת להוכיח שהיא רצה, על ידי תוצר שאתם יכולים לבדוק.
We moved all three onto launchd, with a check that runs after every run and confirms the artifact was actually written. All three fired within 20 minutes. The lesson we kept: a routine has to prove it ran, by producing something you can go and look at.
לפני שמתקנים משהו, כדאי לדעת מה בכלל שבור. שלוש בדיקות קצרות, ואתם יודעים.
Before fixing anything, it helps to know what is broken. Three short checks and you know.
זה מספיק בשביל לדעת לאן פניכם. את העבודה המדויקת, עם הראיות, נשאיר לפרומפט שבשלב הבא.
That is enough to know where you stand. The precise work, with evidence, belongs to the prompt in the next step.
הפרומפט עושה שלושה דברים לפי הסדר: קודם הוא עורך אינוונטר של כל השגרות שלכם ומסמן לכל אחת על איזה מתזמן היא יושבת, אחר כך הוא אוסף ראיות ומראה מתי כל שגרה רצה בפעם האחרונה ובאיזו שכבה היא נשברת, ורק אחרי שהוא מציג לכם טבלה ומקבל אישור, הוא בונה מחדש.
The prompt does three things in order. First it inventories every routine you have and marks which scheduler each one sits on. Then it gathers evidence and shows you when each routine last really ran and which layer breaks. Only after it shows you a table and gets your yes does it rebuild anything.
מה לצפות: קובץ דוח שנכתב תוך כדי עבודה, כדי שתוכלו לקרוא אותו גם אם הסשן נופל באמצע, ולכל היותר שתי שאלות אליכם. כל טענה בדוח מגיעה עם נתיב או פלט פקודה שהוא באמת ראה.
What to expect: a report file written as it goes, so you can read it even if the session dies, and at most two questions for you. Every claim in the report comes with a path or a command output it actually saw.
שימו לב: תקראו את הטבלה של חלק 2 לפני שאתם אומרים כן לחלק 3. שם רואים אם הבעיה היא בהפעלה או בהרצה, ואישור מהיר מדי בונה מחדש את הדבר הלא נכון.
One caution: read the Part 2 table before you say yes to Part 3. That table tells you whether the trigger or the run itself is broken, and a quick yes rebuilds the wrong thing.
You are auditing my scheduled routines in Claude Code. They do not fire on time, and in past sessions you told me to run them manually or to contact Anthropic. Both answers are forbidden in this session. Your job is to find the exact layer that fails, prove it with evidence, and rebuild the routines on a scheduler that works without me.
Rules for this session:
1. Every claim you make must cite a file path you read or a command output you saw. No guessing. If you cannot verify something, write "unverified" and move on.
2. Diagnose first. Do not change anything until Part 1 and Part 2 are complete and written to the report.
3. Write everything into one file: `ops/routines-audit-<YYYY-MM-DD>.md` inside my project folder. Create the folder if it is missing. Update the file as you go so I can read it even if the session dies.
4. Ask me at most 2 questions, and only if the answer changes what you do.
## Part 0: Which machine am I on?
Detect the operating system first (`uname -s` on Mac or Linux, `$env:OS` or `ver` on Windows). Write it at the top of the report. Every command below has a Mac branch and a Windows branch. Use the one that matches. On Linux use the Mac branch with `cron` or `systemd --user` timers in place of launchd.
## Part 1: Inventory. Which scheduler am I actually using?
There are three different schedulers and they behave differently. Find which one each routine of mine lives on:
A. Desktop app scheduled tasks. Look in the Claude scheduled-tasks folder (Mac: `~/.claude/scheduled-tasks/`, Windows: `%USERPROFILE%\.claude\scheduled-tasks\`), one folder per task with a SKILL.md, plus the `scheduled-tasks-archive` folder next to it. List every task: name, description line, the schedule if written anywhere, and the last modified date of the folder. Also check `settings.json` and `settings.local.json` in the same `.claude` folder for anything about scheduled tasks.
B. Session crons. These are created with CronCreate or /loop inside a chat and die when that chat closes. Check whether any routine I described exists only as a cron in a session (run CronList if the tool exists). If yes, that is the bug for that routine: it was never persistent.
C. Operating system schedulers.
- Mac: `launchctl list | grep -v com.apple` and `crontab -l`. For each launchd job `cat` its plist from `~/Library/LaunchAgents/` and note ProgramArguments, StartCalendarInterval or StartInterval, StandardOutPath, StandardErrorPath, EnvironmentVariables.
- Windows: `schtasks /query /fo LIST /v` (or in PowerShell `Get-ScheduledTask | Where-Object {$_.TaskPath -notlike '\Microsoft\*'} | Get-ScheduledTaskInfo`). For each task of mine note the action (program and arguments), the trigger, "Last Run Time", "Last Result" (0 means success, anything else is an error code), and "Run only when user is logged on" versus "Run whether user is logged on or not".
List any job that runs `claude`, a script of mine, or anything in my project folder.
Also list what I told you my routines are supposed to be (tasks, content, search), and map each one to A, B, or C, or to "not registered anywhere". A routine that exists in no scheduler is not a bug in the trigger layer. It was never installed.
## Part 2: Evidence. Why does the trigger not fire?
For each routine, answer these with evidence, not opinion:
1. When did it last actually run? Look for artifacts: output files with timestamps, git commits, log files, session folders under `.claude/projects/` sorted by modification time, the launchd StandardOutPath log on Mac, or "Last Run Time" and "Last Result" from Task Scheduler on Windows. Write the last real run time, or "no evidence it ever ran".
2. For desktop app tasks (type A): confirm with me whether the Claude desktop app was open and I was logged in at the scheduled minute. State plainly that these tasks only fire while the app runs, that there is no user-visible log of the trigger decision, and that this is the limitation, not something I can fix from inside the prompt.
3. Does the routine depend on secrets or environment variables (API keys, tokens, the path to node or python)? Grep the SKILL.md or script for `$` variables, `%VAR%`, `.env`, `api_key`, `token`. Scheduled runs are fresh sessions: they do not load my `.env` and they do not inherit my shell PATH. On Windows, Task Scheduler runs with a minimal environment and may not see user-level PATH additions at all. If a routine needs any of these and they are not set inside the task, plist, or script, it fails silently at runtime even when the trigger works. Mark this as "trigger OK, runtime broken" versus "trigger broken".
4. Does the routine need a permission that a headless run cannot grant (file access prompts, a tool that asks for confirmation, an MCP server that needs interactive login)? Check `.mcp.json` and the permission settings. A routine that waits on a prompt nobody answers looks exactly like "did not fire".
5. Check the machine itself. Mac: `pmset -g` for sleep settings; launchd does not wake a sleeping Mac, and a missed StartCalendarInterval job runs late, when the Mac wakes. Windows: `powercfg /a` and the task's "Wake the computer to run this task" setting; a task without it does not fire while the laptop sleeps, and "Run only when user is logged on" tasks do not fire on the lock screen unless configured. A task scheduled at 07:00 on a laptop that sleeps at night fires late or not at all.
6. Look at what I fixed before. Search my project for notes, logs, or commits mentioning these routines (grep for the task names and for words like "schedule", "cron", "launchd", "schtasks", "did not run"). List the previous fixes and whether each one addressed the trigger layer or the runtime layer. If the same fix was applied twice, say so. That means it was the wrong layer.
Write a table: routine, scheduler type, last real run, failure layer (never installed / trigger / runtime secrets / runtime permission / machine asleep / unknown), evidence.
## Part 3: Rebuild on a scheduler that does not depend on the app
Do this only after showing me the Part 2 table and getting my OK.
For each routine I want to keep, create a small runner script in my project at `ops/routines/<routine>.sh` (Mac, Linux) or `ops/routines/<routine>.ps1` (Windows). The script must:
- `cd` into my project folder,
- set PATH explicitly so `claude`, `node`, and `python3` are found (find their real paths now with `which` on Mac or `where.exe` / `Get-Command` on Windows, and hardcode them),
- load any needed keys from ONE env file that the script reads (`.env` in the project or one file in my home folder; pick one, never two),
- run `claude -p "<the routine prompt>" --permission-mode acceptEdits` (or the flags that match what the routine needs). The routine's prompt must be fully written inside the script or in a `.md` file the script passes in. It must be self-contained: every rule the routine must follow is written in it, not "read file X and follow it",
- append start time, end time, and exit code to `ops/routines/logs/<routine>.log`,
- after `claude -p` finishes, check that the artifact the routine is supposed to produce exists and was modified in the last few minutes. If not, write `FAILED: artifact missing` to the log and, if I have a notification channel (Telegram bot, `osascript -e 'display notification'` on Mac, `msg * "text"` or a BurntToast toast on Windows), send me one line. Never rely on the routine itself to report that it failed. The check lives in the shell, outside the AI run.
Then register it:
Mac: create `~/Library/LaunchAgents/com.<myname>.<routine>.plist` that runs the `.sh` script, with StartCalendarInterval for the schedule and StandardOutPath and StandardErrorPath pointing to the log folder. Load it with `launchctl bootout gui/$(id -u) <plist>` if it already exists, then `launchctl bootstrap gui/$(id -u) <plist>`, then `launchctl kickstart -k gui/$(id -u)/com.<myname>.<routine>` to fire it right now. If the Mac sleeps at that hour, tell me and either move the time or run `sudo pmset repeat wakeorpoweron MTWRFSU HH:MM` after I agree.
Windows: register with `schtasks /create /tn "<routine>" /tr "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"<full path to .ps1>\"" /sc DAILY /st HH:MM /f` (or the `/sc` that fits: HOURLY, WEEKLY). Then open the task in Task Scheduler or use PowerShell `Set-ScheduledTask` to set: "Run whether user is logged on or not" if I want it to fire on the lock screen (this needs my Windows password once, entered by me, never by you), "Wake the computer to run this task" if the laptop sleeps, and "Run task as soon as possible after a scheduled start is missed". Fire it now with `schtasks /run /tn "<routine>"`, then read `schtasks /query /tn "<routine>" /fo LIST /v` and confirm "Last Result" is 0.
Either platform: show me the log lines from that test run and the artifact it produced. "Done" means I see a real artifact from a real scheduler-triggered run, not "the script is written".
Finally, delete or disable the old desktop app task so two schedulers do not run the same routine. Note in the report exactly what you removed.
## Part 4: Report
End `ops/routines-audit-<YYYY-MM-DD>.md` with:
- The operating system and the Part 2 table.
- For each rebuilt routine: scheduler entry (plist path or Task Scheduler name), script path, schedule, log path, the timestamp of the successful test run, and the artifact it produced.
- The one thing you could not verify, if any.
- One sentence on how I check next week that they are still running without asking you (Mac: `tail ops/routines/logs/*.log`; Windows: `Get-Content ops\routines\logs\*.log -Tail 5`).
Do not summarize what you plan to do. Do it, and show the evidence.
התבנית פשוטה ומורכבת משני חלקים. חלק ראשון, סקריפט הרצה: הוא נכנס לתיקיית הפרויקט, קובע PATH מפורש כדי שהמחשב ימצא את claude, מריץ אותו, רושם ללוג שעת התחלה, שעת סיום וקוד יציאה, ואז בודק שהתוצר באמת נוצר ועודכן עכשיו. חלק שני, רשומה במתזמן שקוראת לסקריפט הזה בשעה שקבעתם.
The pattern has two parts. First, a runner script: it moves into your project folder, sets PATH explicitly so the machine can find claude, runs it, logs the start time, the end time and the exit code, then checks that the artifact really exists and was just updated. Second, a scheduler entry that calls that script at the hour you chose.
הבדיקה אחרי ההרצה היא הלב של העניין. היא יושבת ב-shell, בסקריפט עצמו, מחוץ להרצה של ה-AI, כי שגרה שנפלה היא בדיוק השגרה שלא תדווח לכם שהיא נפלה.
The check after the run is the heart of it. It lives in the shell, outside the AI run, because a routine that failed is exactly the routine that will not tell you it failed.
סקריפט ההרצה. שמרו אותו בתיקיית הפרויקט, החליפו את הנתיבים בשלכם, ותנו לו הרשאת הרצה.
The runner script. Save it in your project folder, swap the placeholder paths for yours, and make it executable.
#!/bin/bash
# Runner for one scheduled routine. Works on Mac and Linux.
# Fill every <PLACEHOLDER> below, then: chmod +x runner.sh
set -uo pipefail
PROJECT="<YOUR-PROJECT-FOLDER>" # e.g. /Users/you/projects/my-system
ROUTINE="<ROUTINE-NAME>" # e.g. daily-tasks (no spaces)
PROMPT_FILE="$PROJECT/<PROMPT-FILE>" # e.g. ops/routines/daily-tasks.md
ARTIFACT="$PROJECT/<ARTIFACT-PATH>" # the file this routine must produce
LOG_DIR="$PROJECT/<LOGS-FOLDER>" # e.g. ops/routines/logs
LOG="$LOG_DIR/$ROUTINE.log"
# A scheduled run does not inherit your shell PATH.
# Run `which claude node python3`, then paste those directories here.
export PATH="<DIR-OF-CLAUDE>:<DIR-OF-NODE>:<DIR-OF-PYTHON3>:/usr/bin:/bin:/usr/sbin:/sbin"
# Optional: ONE env file with the keys this routine needs. Never two.
ENV_FILE="$PROJECT/.env"
if [ -f "$ENV_FILE" ]; then
set -a
. "$ENV_FILE"
set +a
fi
mkdir -p "$LOG_DIR"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG"; }
cd "$PROJECT" || { log "FAILED: cannot cd to $PROJECT"; exit 70; }
log "=== $ROUTINE start ==="
STARTED="$LOG_DIR/.$ROUTINE.started"
touch "$STARTED"
if [ ! -f "$PROMPT_FILE" ]; then
log "FAILED: no prompt file at $PROMPT_FILE"
exit 66
fi
claude -p "$(cat "$PROMPT_FILE")" --permission-mode acceptEdits >> "$LOG" 2>&1
EXIT_CODE=$?
log "=== $ROUTINE end (exit $EXIT_CODE) ==="
# The artifact check lives here, outside the AI run. It is the only proof of a real run.
# Passes only if the artifact was written after this run started.
FRESH=$(find "$ARTIFACT" -newer "$STARTED" 2>/dev/null)
if [ -n "$FRESH" ]; then
log "OK $ARTIFACT"
exit 0
fi
log "FAILED: artifact missing $ARTIFACT"
if command -v osascript >/dev/null 2>&1; then
osascript -e "display notification \"$ROUTINE produced no artifact\" with title \"Routine failed\"" >/dev/null 2>&1
fi
exit 3
ב-Mac, הרשומה של launchd. היא מציינת מה להריץ, באיזו שעה, ולאן לכתוב את הפלט והשגיאות.
On a Mac, the launchd entry. It says what to run, at what time, and where to write output and errors.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
Save as ~/Library/LaunchAgents/com.example.routine.plist
Anything in CAPS below is a placeholder you replace with a real full path.
XML values cannot contain angle brackets, so the placeholders here have none.
Rename the Label too if you want (it must match the file name).
Then run these three commands in Terminal, in this order:
launchctl bootout gui/$(id -u)/com.example.routine
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.routine.plist
launchctl kickstart -k gui/$(id -u)/com.example.routine
Command 1 unloads an older copy. If it prints "No such process", ignore it.
Command 2 loads the job. Command 3 fires it now, so you can read the log today.
-->
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.routine</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>YOUR-PROJECT-FOLDER/PATH-TO/runner.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key><integer>7</integer>
<key>Minute</key><integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>YOUR-PROJECT-FOLDER/LOGS-FOLDER/launchd-stdout.log</string>
<key>StandardErrorPath</key>
<string>YOUR-PROJECT-FOLDER/LOGS-FOLDER/launchd-stderr.log</string>
<key>RunAtLoad</key>
<false/>
</dict>
</plist>
ב-Windows, אותו רעיון דרך Task Scheduler. אחרי הרישום שווה לפתוח את המשימה ולסמן שהיא רצה גם כשאתם לא מחוברים, ושהיא מעירה את המחשב אם הוא ישן.
On Windows, the same idea through Task Scheduler. After registering it, open the task and tick that it runs whether or not you are logged on, and that it wakes the computer if it sleeps.
# Runner for one scheduled routine. Windows PowerShell.
# Fill every <PLACEHOLDER> below, then save as runner.ps1
$Project = "<YOUR-PROJECT-FOLDER>" # e.g. C:\Users\You\projects\my-system
$Routine = "<ROUTINE-NAME>" # e.g. daily-tasks (no spaces)
$PromptFile = Join-Path $Project "<PROMPT-FILE>"
$Artifact = Join-Path $Project "<ARTIFACT-PATH>"
$LogDir = Join-Path $Project "<LOGS-FOLDER>"
$Log = Join-Path $LogDir "$Routine.log"
# Task Scheduler runs with a minimal environment and may not see your PATH.
# Run `Get-Command claude, node, python` in PowerShell, then paste those folders here.
$env:Path = "<DIR-OF-CLAUDE>;<DIR-OF-NODE>;<DIR-OF-PYTHON>;" + $env:Path
# Optional: ONE env file with the keys this routine needs. Never two.
$EnvFile = Join-Path $Project ".env"
if (Test-Path $EnvFile) {
Get-Content $EnvFile | ForEach-Object {
if ($_ -match '^\s*([^#=]+)=(.*)$') {
[Environment]::SetEnvironmentVariable($Matches[1].Trim(), $Matches[2].Trim(), "Process")
}
}
}
New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
function Write-Log($msg) { Add-Content -Path $Log -Value ("[" + (Get-Date -Format "yyyy-MM-dd HH:mm:ss") + "] " + $msg) }
Set-Location $Project
Write-Log "=== $Routine start ==="
$Started = Get-Date
if (-not (Test-Path $PromptFile)) {
Write-Log "FAILED: no prompt file at $PromptFile"
exit 66
}
$Prompt = Get-Content $PromptFile -Raw
claude -p $Prompt --permission-mode acceptEdits *>> $Log
$ExitCode = $LASTEXITCODE
Write-Log "=== $Routine end (exit $ExitCode) ==="
# The artifact check lives here, outside the AI run. It is the only proof of a real run.
# Passes only if the artifact was written after this run started.
$Fresh = (Test-Path $Artifact) -and ((Get-Item $Artifact).LastWriteTime -gt $Started)
if ($Fresh) {
Write-Log "OK $Artifact"
exit 0
}
Write-Log "FAILED: artifact missing $Artifact"
msg * "$Routine produced no artifact. Check $Log" # msg is missing on Windows Home; the log line above is the real signal
# Optional nicer toast, needs the BurntToast module installed:
# New-BurntToastNotification -Text "Routine failed", "$Routine produced no artifact"
exit 3
REGISTER THE ROUTINE ON WINDOWS
1. Open PowerShell and run this one line (replace the placeholders):
schtasks /create /tn "<ROUTINE-NAME>" /tr "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"<YOUR-PROJECT-FOLDER>\<PATH-TO>\runner.ps1\"" /sc DAILY /st <HH:MM> /f
/sc DAILY can be HOURLY or WEEKLY instead. /st uses 24 hour time, so 07:00, not 7am.
/f overwrites an older task with the same name, so this line is safe to run twice.
2. Fire it once now to prove it works:
schtasks /run /tn "<ROUTINE-NAME>"
3. Open Task Scheduler (search for it in the Start menu), find your task,
right click, Properties, and turn on these two settings:
General tab: "Run whether user is logged on or not"
Reason: otherwise the task is skipped whenever your screen is locked or you are signed out.
Windows asks for your Windows password once. You type it, nobody else.
Conditions tab: "Wake the computer to run this task"
Reason: a sleeping laptop skips a 07:00 task. This wakes it for the run.
While you are there, Settings tab: "Run task as soon as possible after a scheduled
start is missed" catches the runs you lost because the machine was off.
4. Confirm the result is 0 (0 means success, anything else is an error code):
schtasks /query /tn "<ROUTINE-NAME>" /v /fo LIST | findstr /i /c:"Last Run Time" /c:"Last Result"
פקודה אחת שמראה לכם את סוף הלוג של כל שגרה. שורה עם קוד יציאה 0 ותוצר מעודכן זה בוקר טוב, וכל דבר אחר דורש שתי דקות.
One command that shows you the tail of every routine's log. A line with exit code 0 and a fresh artifact is a good morning, anything else is worth two minutes of your time.
HOW TO CHECK NEXT WEEK, WITHOUT ASKING CLAUDE
Mac
tail -n 5 <LOGS-FOLDER>/*.log
launchctl print gui/$(id -u)/<LABEL> | grep -E "state|last exit"
Windows
Get-Content <LOGS-FOLDER>\*.log -Tail 5
schtasks /query /tn "<ROUTINE-NAME>" /v /fo LIST | findstr /i /c:"Last Run Time" /c:"Last Result"
What you want to see: a log line from today or yesterday ending in OK, and an exit
code of 0. A line that says "FAILED: artifact missing" means the scheduler fired and
the run did not produce the file. No line at all means the scheduler did not fire, or the machine was asleep at that minute.
לפי סימפטום. רובם נפתרים בשתי דקות.
By symptom. Most of these take two minutes.
השעה עברה ושום דבר לא קרה
האפליקציה הייתה סגורה, או שהתנתקתם. משימות מתוזמנות באפליקציה חיות רק בזמן שהיא פתוחה ואתם מחוברים, ואין שום לוג שיספר לכם את זה. תעבירו את השגרה למתזמן של מערכת ההפעלה.
The hour passed and nothing happened
The app was closed, or you were logged out. App scheduled tasks live only while the app is open with you logged in, and no log will tell you so. Move the routine to the operating system's scheduler.
העברתי ל-launchd וזה עדיין לא רץ בלילה
המחשב ישן. launchd לא מעיר Mac ישן מיוזמתו, אז שגרה שקבועה לשלוש לפנות בוקר על מחשב נייד שנרדם תרוץ באיחור, רק כשהמחשב יתעורר. או שמזיזים את השעה לזמן שבו המחשב ער, או שמגדירים לו התעוררות קבועה. ב-Windows יש סימון ייעודי במשימה שמעיר את המחשב.
I moved it to launchd and it still does not run at night
The machine is asleep. launchd will not wake a sleeping Mac on its own, so a routine set for three in the morning on a laptop that sleeps runs late, only when the Mac wakes. Either move the hour to a time the machine is awake, or set a recurring wake. On Windows there is a dedicated tick in the task that wakes the computer.
בלוג כתוב command not found
הסקריפט לא מצא את claude. הרצה מתוזמנת פותחת סביבה נקייה ולא יורשת את ה-PATH של הטרמינל שלכם. תמצאו את הנתיב האמיתי עם which claude, ותכתבו אותו בתוך הסקריפט במפורש. אותו דבר לגבי node ו-python3.
The log says command not found
The script could not find claude. A scheduled run starts in a clean environment and does not inherit your shell PATH. Find the real path with which claude and write it into the script explicitly. Same for node and python3.
זה התחיל לרוץ ופשוט נתקע
משהו ביקש אישור ואף אחד לא היה שם לענות. הרצה בלי אדם מולה לא יכולה לאשר בקשת גישה לקבצים או חיבור שדורש התחברות. תריצו עם דגל ההרשאות שמתאים למה שהשגרה באמת צריכה, ותורידו ממנה תלות בכלים שדורשים אישור ידני.
It started running and then just hung
Something asked for permission and nobody was there to answer. A headless run cannot approve a file access prompt or a connector that wants an interactive login. Run it with the permission flag that matches what the routine genuinely needs, and take out anything that requires a manual click.
רץ יפה מהטרמינל, נכשל מהמתזמן
כמעט תמיד מפתח שיושב בקובץ .env שאף אחד לא טען. הטרמינל שלכם טוען אותו בשבילכם, המתזמן לא. תגרמו לסקריפט עצמו לטעון קובץ אחד עם המפתחות, ותשאירו קובץ אחד בלבד. עם שניים תמיד תתבלבלו איזה מהם באמת נטען.
Runs fine from the terminal, fails from the scheduler
Almost always a key sitting in a .env file that nobody loaded. Your terminal loads it for you, the scheduler does not. Make the script itself load one file of keys, and keep exactly one. Two files is how you start chasing your own tail.
קיבלתי את אותו מייל פעמיים
שני מתזמנים מריצים את אותה שגרה, בדרך כלל המשימה הישנה באפליקציה שנשארה דלוקה לצד החדשה. תכבו או תמחקו אחת מהן, ותרשמו לעצמכם מה הורדתם. הכפילות הזאת גם מבזבזת טוקנים בשקט.
I got the same email twice
Two schedulers are running the same routine, usually the old app task left enabled next to the new one. Disable or delete one of them, and write down what you removed. That duplicate is also burning tokens quietly.
שגרה טובה לא מבקשת מכם אמון, היא מוכיחה את עצמה: קובץ, שורת לוג, מייל שהגיע. תבנו אותה ככה פעם אחת, ותשכחו ממנה בשקט הנכון.
A good routine does not ask for your trust, it proves itself: a file, a log line, an email that landed. Build it that way once, and you get to forget about it for the right reason.