self-refresh
Skill0 starsChanged 58 days agoMITView on GitHub
Make THIS Claude Code session restart itself in place - exit and resume the same conversation in the same cmux pane - and then automatically continue its outstanding work, by arming a detached watchdog that respawns the pane on its tracked resume command and re-prompts the restored session. Use when the user asks a session or agent to self-refresh, self-restart, restart itself, refresh itself, reload, bounce, recycle, cycle itself, or pick up a new Claude Code version without losing the conversation.
In this repository2 other files it gives its agents.
- self-compactSkill
- self-cycleSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 15
Write a continuation prompt describing the actual outstanding work, then run:
- Distinctive: line 110
NOT established, and the four-minute failure above remains unexplained — its cause is unrecoverable because the engine logged its verdict …
- Very specific: line 116
Every cmux call retries 4x with backoff, and the wrapper logs its own four-try exhaustion, so "the socket died" is never confused with "the …
- Very specific: line 132
Only backspace clears Claude Code's input box (ctrl+u/ctrl+w/escape do not).
- Very specific: line 159
If a session came back from a restart but was never re-prompted, doctor re-arms the delivery.
- Very specific: line 160
Use the same ENGINE path as above.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
self-refresh
Restarts your own pane on its cmux-tracked resume command, then re-prompts the restored session so it continues instead of sitting idle. The conversation survives; the process does not.
Do this
Write a continuation prompt describing the actual outstanding work, then run:
ENGINE="${SELFCYCLE_HOME:-$HOME/.claude/skills/self-cycle}/selfcycle.sh"
[ -f "$ENGINE" ] || ENGINE="$HOME/.agents/skills/self-cycle/selfcycle.sh"
bash "$ENGINE" refresh "<continuation prompt>"Make it specific — name the current task, the next concrete step, and what is already done and must not be redone. After the restart this prompt is the only thing steering you.
Then end your turn immediately with one sentence telling the user you armed it. Your pane is about to be killed. Anything you start now is lost, and any background task you are waiting on dies with the process.
Do NOT arm this when
- you are mid-task on work a restart would lose or duplicate
- a
/goalis active and its work is still in flight - you have background tasks, monitors, or subagents whose results you still need
- you are the driver of a multi-session sweep — refresh yourself last, after every other session
Reading the result
SELFCYCLE_ARMED mode=refresh ...— armed; the pane respawns in ~8s.SELFCYCLE_ABORT <reason>— nothing was armed and your pane is safe. Report the reason. The most important one:no cmux resume binding for surface <id>. Respawning without a tracked resume command drops the pane into a bare shell and destroys the conversation, so the engine refuses. Sessions launched by typingclaudeinto a shell have no binding; only cmux-launched agent sessions do. Check withcmux surface resume show.
What the watchdog does
It runs detached (reparented to launchd), so it outlives the process it is about to kill — this is the whole reason a session cannot restart itself synchronously.
- Reads the pane's tracked resume command (
cmux surface resume show), which carries your session id, so--resumereopens this conversation. cmux respawn-pane --workspace <ws> --surface <id> --command "/bin/zsh -lc '<resume>'". Two details matter here.--surfaceresolves inside the default workspace, so without--workspacecmux answersSurface not foundfor a surface it listed moments earlier. And the resume command is relaunched under a login shell: cmux's tracked command runs the agent through a non-login/bin/sh, so the pane would come back with a stripped PATH (no~/.local/bin,/opt/homebrew/binor~/.volta/bin). The conversation survives that, but every PATH-dependent hook in the restored session silently breaks — seen as a flood ofStop hook error: /bin/sh: node: command not found.- Waits for a new claude process (pid different from the one captured at arm time), answering
known-safe blocking dialogs on the way:
Resume from summary?and the folder-trust prompt. It deliberately does not blanket-press Enter — a tool-permission prompt must never be auto-approved by a restart watchdog. - Sends your continuation prompt, then confirms it landed, in two layers:
- keystroke level — it proves the payload positively: after typing, the box must start
with the payload's opening characters; after Enter, it must no longer contain them. It never
asks "is the box empty", because on this TUI that is not observable — an empty box carries
placeholder chrome and the chrome moves. One run read a lone space back; another read back
Press up to edit queued messages, the hint shown once messages are queued — and since our own successful Enter is what queues a message, success painted the box with what an emptiness check scored as failure. That cost 2 duplicate/compacts and 4 duplicate prompts in one cycle. "It changed" is not enough either, in either direction: leftover text sits ahead of our payload, so the box changed but holdsJUNK/compact; and any unrelated repaint after Enter looks like a successful submit. A prefix test catches residue before Enter is ever pressed, and an unreadable box is treated as a failure, never as an empty one — folding those together once fired five blind Enters at a tool-permission dialog. This positive check is possible only because the pointer design caps what is ever typed to/compactor a ~290-char pointer, so the opening characters are always on the❯line and the box never scrolls. A just-respawned pane replaying its transcript will accept the paste but drop the Enter, and the payload-still-there check catches that in seconds without retyping. - transcript level — a new
userrecord carrying a unique nonce, then anassistantturn positioned after that nonce record. Both layers are needed: the transcript alone cannot tell our Enter from a human's, so transcript-only verification once scored an operator's manual rescue as its own success.
- keystroke level — it proves the payload positively: after typing, the box must start
with the payload's opening characters; after Enter, it must no longer contain them. It never
asks "is the box empty", because on this TUI that is not observable — an empty box carries
placeholder chrome and the chrome moves. One run read a lone space back; another read back
Terminal outcome lands in state/selfcycle.log next to the engine.
Healing
- Pane fell back to a bare shell (respawn raced the app): re-issues the respawn, up to 2 times.
- Pane hosts a background agent: respawn is impossible for these. It stops immediately rather than retrying, notifies, and says so — no pretending it worked.
- Non-terminal agent surface: refused at arm time; keystroke injection cannot reach those.
- New pid never appears: it injects anyway. Verification is what proves success, not the pid, so a missing pid costs nothing.
Why it does not stall
- No readiness guessing from chrome. It never reads footer text to decide whether the restored TUI is ready. It injects and re-injects until the transcript proves the prompt was consumed.
- It waits for the input box to exist, and that wait is not an attempt. "The box is empty" and
"there is no box yet" look identical from outside — both read as no text — so typing into a pane
with no box can never verify. Treating that as a failed injection once cost a real refresh its
entire 8-attempt budget in four minutes with nothing delivered. It now polls for a
❯line first, patiently (default 7 minutes,SELFCYCLE_BOX_WAIT_SECS), clearing dialogs while it waits, and only then types. If no box ever appears the pane is genuinely broken, so it stops immediately and notifies rather than retrying into the hard deadline.- How long a restore actually takes, measured: a 12.3 MB transcript rendered its input box and consumed the continuation prompt in 26 seconds total. So "big transcript = slow box" is NOT established, and the four-minute failure above remains unexplained — its cause is unrecoverable because the engine logged its verdict without its observation. Every give-up path now logs a one-line excerpt of what the pane showed, so the next one is diagnosable. Do not treat the readiness wait as the proven cause of that incident; it is correct behaviour on its own terms.
- The continuation prompt is sent on every terminal path, including failures.
- Every
cmuxcall retries 4x with backoff, and the wrapper logs its own four-try exhaustion, so "the socket died" is never confused with "the pane ignored our keystrokes". - A hard 30-minute deadline bounds the watchdog and announces itself in the log and by notify before killing; a per-surface lock stops two cycles racing.
abortstops the running watchdog and retires the envelope — it does not merely free the lock, which would leave an armed refresh free to respawn your pane ~8s after you cancelled it.doctorretires an envelope whose surface no longer hosts that session, rather than re-arming a watchdog that could only fail on a pane that no longer exists.- The
cmuxbinary is resolved and proven responsive (cmux ping→PONG) before arming, so a watchdog that could never inject is refused rather than armed.
Embedded cmux facts (so you need not load the cmux skill)
cmux send/cmux send-keyare focus-independent; the pane need not be focused.cmux surface resume show --surface <id>prints the tracked resume command, or nothing.cmux respawn-pane --surface <id> --command <cmd>relaunches a pane's process.- Only
backspaceclears Claude Code's input box (ctrl+u/ctrl+w/escapedo not). cmux senddelivers an embedded newline as ENTER, so a multi-line prompt sent to a Claude Code pane self-submits line by line. Verified with no Enter pressed at all: a 12-line paste arrived as three separate messages while the rest sat in the box. The engine therefore flattens every prompt to a single line before sending. Write your continuation prompt however you like — it gets flattened for you — but never assume newlines survive. A shell pane behaves the opposite way (newlines are literal text there), so testing injection against a shell proves nothing about a Claude pane.--resume <id>keeps the same session id and appends to the same transcript file, so the verification cursor stays valid across the restart.- A large single paste gets COLLAPSED, and the collapsed form is what submits. Measured: one
cmux sendof 1622 chars rendered as head, an elision, then tail, with the footer offering "paste again to expand" — and a live 1726-char continuation prompt submitted in exactly that shape, losing 72% of its body. Head and tail are also the only parts cheap verification checks (a probe of the first chars, a nonce at the end), so it passed as a clean delivery. The engine sends in ~350-char chunks, which the TUI treats as ordinary typing, and verifies the whole payload in the transcript.read-screencannot help: the elision is the rendering. - The
claude_codestatus pill is not a liveness signal — use the process table.
Recovery
bash "$ENGINE" status # is a cycle armed? recent log lines
bash "$ENGINE" abort # really cancel: kill the watchdog, retire state
bash "$ENGINE" doctor # finish a cycle whose watchdog diedIf a session came back from a restart but was never re-prompted, doctor re-arms the delivery.
Use the same ENGINE path as above.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

