agentleFS
chendrizzychendrizzy/self-cycle/self-refresh/SKILL.md

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.

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
  1. Distinctive:

    Write a continuation prompt describing the actual outstanding work, then run:

    line 15
  2. Distinctive:

    NOT established, and the four-minute failure above remains unexplained — its cause is unrecoverable because the engine logged its verdict …

    line 110
  3. Very specific:

    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 …

    line 116
  4. Very specific:

    Only backspace clears Claude Code's input box (ctrl+u/ctrl+w/escape do not).

    line 132
  5. Very specific:

    If a session came back from a restart but was never re-prompted, doctor re-arms the delivery.

    line 159
  6. Very specific:

    Use the same ENGINE path as above.

    line 160

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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 /goal is 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 typing claude into a shell have no binding; only cmux-launched agent sessions do. Check with cmux 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.

  1. Reads the pane's tracked resume command (cmux surface resume show), which carries your session id, so --resume reopens this conversation.
  2. cmux respawn-pane --workspace <ws> --surface <id> --command "/bin/zsh -lc '<resume>'". Two details matter here. --surface resolves inside the default workspace, so without --workspace cmux answers Surface not found for 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/bin or ~/.volta/bin). The conversation survives that, but every PATH-dependent hook in the restored session silently breaks — seen as a flood of Stop hook error: /bin/sh: node: command not found.
  3. 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.
  4. 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 holds JUNK/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 /compact or 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 user record carrying a unique nonce, then an assistant turn 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.

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 cmux call 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.
  • abort stops 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.
  • doctor retires 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 cmux binary 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-key are 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 backspace clears Claude Code's input box (ctrl+u/ctrl+w/escape do not).
  • cmux send delivers 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 send of 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-screen cannot help: the elision is the rendering.
  • The claude_code status 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 died

If a session came back from a restart but was never re-prompted, doctor re-arms the delivery. Use the same ENGINE path as above.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.