Repeatedly run a check command or script on a configurable interval until a condition is met, a timeout is reached, or an actionable exit code is returned. Use when the user asks to loop, wait, poll, watch, retry, check periodically, wait for CI, wait for approval, wait for a service, or keep checking a PR before continuing.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Repeatedly run a check command or script on a configurable interval until a condition is met, a timeout is reached, or an actionable exit code is returned. Use when the user asks to loop, wait, poll, watch, retry, check periodically, wait for CI, wait for approval, wait for a service, or keep checking a PR before continuing.
compatibility
Includes Bash scripts for macOS/Linux/Git Bash and PowerShell scripts for Windows PowerShell 5.1 or PowerShell 7+. GitHub PR examples require the GitHub CLI.
Loop Skill
Create a controlled loop that repeatedly runs a check command, waits between attempts, and lets the agent continue when a condition is met or when the check reports an actionable state.
Do not use this skill for explaining programming-language loop syntax. Use it when the user wants the agent to run commands over time, such as:
"wait until the service is healthy"
"poll the PR every 5 minutes"
"retry this command until it succeeds"
"watch for CI failures, merge conflicts, or approval"
"keep checking until the deploy finishes"
Safety model
This skill intentionally does not pre-approve shell tools. Loops can execute arbitrary user-supplied commands repeatedly, so the agent must be explicit about what will run.
Always:
Prefer a short, auditable check script over a long inline command.
For PowerShell, default to a detached worker plus Wait-LoopDetached.ps1 when the agent should wake up and continue. Only call loop.ps1 attached when you have positive evidence the loop is short-lived or the user explicitly wants live terminal output.
For detached PowerShell loops, always pair with in the same owner/orchestrator process. Independent background handoff is not supported because unmanaged detached workers can outlive the session.
Start-LoopDetached.ps1
Wait-LoopDetached.ps1
Run --dry-run first for non-trivial or destructive workflows.
Use --timeout or --max-tries unless the user explicitly asks for an unbounded loop.
Route actionable states through --stop-exit-codes so the agent can fix issues before deciding whether to restart or finish.
Decide whether the workflow is single-shot or watch-until-terminal before starting the loop.
Quote command strings for the shell that will execute them. For complex logic, write a temporary script and pass that script as the check command.
Stateful checks must be non-consuming: peek first, act next, and acknowledge only after the action succeeds.
For long PowerShell watch-until-terminal workflows, use Start-LoopDetached.ps1 -WatchUntilTerminal so the worker timeout defaults to unbounded unless an explicit -TimeoutSeconds is supplied.
Keep individual check/action/ack commands bounded. A session-bound worker checks owner liveness between commands and sleeps; it cannot abandon while a child command is still running.
Stateful check rule
If follow-up work requires agent reasoning or dynamic action, the check must be non-consuming. It may emit an event ID, details, or an artifact path and then exit with a stop/action code, but it must not advance markers or mutate source state. Leave --action / -ActionCommand unset so the loop stops, then the agent can inspect details, edit code, validate, push, reply, or otherwise complete the response. After that succeeds, run an explicit ack command. Restart the loop only when the workflow is meant to keep watching.
Consuming checks are only safe for automation-only workflows where the check script itself fully handles the work atomically before marking it done. That is not appropriate for PR review response, CI repair, merge-conflict repair, or any workflow where the agent must reason about what happened.
Pattern
Safe when
Example
Non-consuming check
The agent must act dynamically afterward.
PR review arrives, CI fails, merge conflict appears.
Consuming check
The script fully completes the work atomically without agent reasoning.
Delete expired temp files and mark cleanup complete.
Agent todo guardrail
For agent-reasoned stateful loops, create todos before starting the loop or immediately after it exits with an actionable code. The todos should make the acknowledgement step explicit so it is not lost during a long repair or review-response flow:
Inspect the emitted event details or artifact.
Handle the event and complete any required validation, push, reply, or external update.
Run the exact ack command that advances the marker.
Restart the loop only for watch-until-terminal workflows; otherwise continue with the next instruction or final response.
This guardrail is not required for simple stateless waits, such as polling a local service until it is healthy.
For long detached watch-until-terminal workflows, also create a cleanup todo such as loop-cleanup:<watch-or-work-id>. Resolve it before final response or PR handoff by running Invoke-LoopCleanup.ps1 -WhatIf, inspecting the report, and then using -Apply only when the report shows eligible final-success or abandoned runs. Mark the cleanup todo done only after safe deletion, a no-op report, or an explicit recorded skip for ambiguous or diagnostically useful runs.
Runner selection
Use the runner that matches the active shell. For PowerShell, detached mode is the default because attached terminal output can become stale from the agent's point of view if the loop lives longer than expected. Pair detached workers with the quiet waiter when the agent should sleep until the loop needs attention.
Environment
Runner
macOS, Linux, Git Bash, WSL
scripts/loop.sh
Windows PowerShell 5.1 or PowerShell 7+ observed watch
scripts/Start-LoopDetached.ps1 plus attached quiet scripts/Wait-LoopDetached.ps1
Short-lived/debug PowerShell exception
scripts/loop.ps1 attached, only when quick live output is more important than durable state
Detached workers are session-bound background processes, not independent daemons. The launcher records the owner process in the run manifest; if that owner exits, the worker writes an abandoned terminal result and exits the next time it checks ownership. Start the worker and the quiet waiter from the same owner/orchestrator process so the worker has a live owner for the whole observed watch.
Do not start a detached worker and return only the run directory as a handoff. If the agent should wake up later, Wait-LoopDetached.ps1 must remain attached through the host CLI task UI. Do not wrap Wait-LoopDetached.ps1 in Start-Job, Start-Process, &, or another shell-side detacher; that removes it from the tool-completion channel and leaves unmanaged processes behind.
Use this observed-watch pattern when the agent should wake up:
-WatchUntilTerminal records watchMode = 'watch-until-terminal' and defaults the worker timeout to 0 when -TimeoutSeconds is not explicitly supplied. Use it for long watches where elapsed wall-clock time should not end the logical watch. If you explicitly pass -TimeoutSeconds, that value wins and is recorded in the manifest so the final timeout is explainable.
Wait-LoopDetached.ps1 is intentionally quiet while waiting. It emits one final status JSON object, with waiter metadata and lastWake metadata for final/actionable/abandoned wakeups, then exits. lastWake includes the generic wake classification, exit code, loop status, check-reported status/event, summary, attempt, detected timestamp, and event path when available; domain skills own the meaning of their status/event labels. By default it treats final, actionable, crashed, abandoned, and three consecutive stalled polls as wakeup states and has no waiter-side freshness timeout (-TimeoutSeconds 0, also available through the legacy -MaxAttachedSeconds alias). Its exit code mirrors the underlying loop outcome where possible: 0 for success, configured actionable stop codes for actionable, 124 for loop timeout/max tries, and 125 for abandoned owner or persistent stall. Exit 122 is only emitted when an explicit waiter timeout is passed with -TimeoutSeconds / -MaxAttachedSeconds; in that opt-in mode, inspect the emitted status JSON and either continue waiting with a live owner or stop the workflow. If the detached worker has -ActionCommand, the waiter stays attached while action/ack runs and exits 0 only after that automation succeeds. When interactivity matters during a long wait, background the waiter command through the host CLI task UI; do not replace it with detached-only status polling.
The detached run directory is the source of truth; the attached waiter is only a transport. If Get-LoopStatus.ps1 cannot be invoked (missing, throws, returns empty, returns malformed JSON, exits non-zero), the waiter falls back to reading manifest.json, last-result.json, and events\*.json directly from the run directory. When that durable read yields an actionable, final, or abandoned classification, the waiter exits through the normal path with the configured actionable code, 0 for terminal success, or 125 for abandonment, and waiter.exitReason = 'status_read_fallback'; the emitted JSON also carries waiterFallbackSource = 'durable_files', waiterFallbackDurableSources (lastResult, latestEvent, or both), and waiterErrors describing what the helper read failed with. This is the recovery path for missed re-review / approval / +1 events that the loop worker finalized but the helper-based status read could not surface. Exit 121 (waiter_internal_error) is reserved for the case where both the helper and the durable read fail to yield a usable classification; the waiter still emits JSON with a lastResult snapshot when one is on disk, and waiterFallbackSource is then one of previous_status_read, durable_files_unclassified, last_result_on_disk, or stub_only.
Use Invoke-LoopCleanup.ps1 to prune old detached run directories. It reports by default; pass -Apply to delete eligible old final-success or abandoned runs. It skips live runs using PID plus process start-time validation and retains actionable, failed, crashed, stalled, ambiguous, locked, and diagnostically useful runs by default.
The detached launcher writes a run directory containing manifest.json, loop.pid, stdout.log, stderr.log, last-result.json, heartbeat.json, and immutable event files under events\. manifest.json records both the worker PID/start time and owner PID/start time so status checks can reject recycled PIDs and refuse owner-dead runs. Use -Quiet to suppress loop chatter in redirected logs. Use -Force only when intentionally reusing an explicit -RunDir whose prior loop is known to be stopped.
PowerShell attached exception
Only use attached mode when the loop is expected to complete quickly, the user explicitly wants live terminal output, or you are debugging the check command. If duration is uncertain, do not use attached mode. Attached loops can become stale from the agent's perspective if they remain alive too long.
Condition was satisfied and optional action succeeded.
1
General failure.
2
Invalid runner arguments.
3
Check command was not found or not executable.
121
Wait-LoopDetached.ps1 could neither read status via Get-LoopStatus.ps1 nor recover an actionable/final/abandoned classification from a direct read of the run directory. The waiter still emits JSON; inspect waiterError, waiterErrors, waiterFallbackSource, and any lastResult snapshot before deciding whether to continue with a live owner or stop. When the helper read fails but the durable run directory does carry an actionable, final, or abandoned result, the waiter exits with the normal actionable/0/125 code and waiter.exitReason = 'status_read_fallback' instead of 121.
122
Opt-in waiter timeout before the detached worker reached a wakeup state; only emitted when Wait-LoopDetached.ps1 -TimeoutSeconds / -MaxAttachedSeconds is greater than 0.
124
Timeout or max tries reached.
125
Detached waiter detected an abandoned owner or persistent stalled state.
Checks can return domain-specific codes. Use --stop-exit-codes / -StopExitCode for codes that should stop the loop so the agent can act. For PR checks, use:
Code
Meaning
10
Waiting for review, checks, or mergeability.
11
Branch is behind the base branch.
20
CI or required checks are failing.
21
Merge conflicts detected.
22
PR is closed without being merged.
23
GitHub CLI/auth/API error.
24
Review changes requested.
Loop environment
Every check, action, and on-retry command receives:
Variable
Meaning
LOOP_ATTEMPT
Current attempt number, starting at 1.
LOOP_ELAPSED_SECONDS
Elapsed wall-clock seconds since the loop started.
LOOP_REMAINING_SECONDS
Seconds until timeout, or 0 for unbounded loops.
Action, ack, and on-retry commands additionally receive:
Variable
Meaning
LOOP_CHECK_EXIT_CODE
Check exit code that triggered the action, ack, or retry hook.
Standard workflow
Identify the condition that should be checked.
Decide whether this is a single-shot loop or a watch-until-terminal loop.
Decide which exit codes mean "keep waiting" and which mean "agent must act".
For stateful checks, design a peek -> act -> ack flow:
Peek/check reads state and reports new actionable work without advancing markers.
If the agent must reason, the loop exits with a stop/action code and the agent handles the work outside the runner.
If the work is automation-only, ActionCommand may handle it inside the runner.
Ack advances the marker only after the agent or action succeeds.
For agent-reasoned stateful checks, create todos that include the exact ack command and whether to restart or finish after ack.
Run a dry run.
Start the loop. For PowerShell, use Start-LoopDetached.ps1 by default and immediately run attached quiet Wait-LoopDetached.ps1 on the returned run directory from the same owner/orchestrator process.
If the loop exits with an actionable code, or detached status reports actionable, and no action is configured, handle the work, validate it, explicitly ack any stateful marker, then restart only if this is a watch-until-terminal loop.
If the loop exits 0, or detached status reports a final success, continue with the requested success action or final report.
Before final response after starting a detached worker, confirm that the waiter completed or remains managed by the host CLI task UI.
Use this pattern when the agent needs to inspect the event and take dynamic action, such as responding to PR review comments, fixing CI, or resolving merge conflicts. The check only reports that new work exists and preserves enough details for the agent.
When the loop exits 31, or detached status reports actionable for that stop code, inspect event.json, complete the work, validate it, then explicitly acknowledge. Restart only if the loop is intended to keep watching:
Use --ack / -AckCommand when the action is a deterministic command that fully handles the work without agent reasoning. The check must still not advance the marker when it finds actionable work.
If the action fails, ack does not run and the marker remains unchanged. If ack fails, the loop exits non-zero so the same work can be detected again after the ack problem is fixed.
If the loop exits with 20 or 21, or detached status reports actionable for those stop codes, inspect the failure, fix CI or conflicts, push, and restart the loop. If it exits 11, update the branch and restart the loop. If it exits 0 or detached status reports final success, the action has run.
Use last-result.json as the source of truth for the latest attempt. Get-LoopStatus.ps1 reports starting, running, stalled (process alive but heartbeat stale), crashed (process gone without a terminal event), actionable, or final.
Clean up old detached runs
Run cleanup as an explicit maintenance step for long detached watches:
Use this only when you know the loop should finish quickly or you need live output while debugging. If it may run for a while, use detached mode instead.