--- name: afk description: Save physically-away presence and notify peers when supported. Use only on explicit /afk; never infer it from conversation. Presence changes no permissions. disable-model-invocation: true --- # /afk [optional context] The human operator is **physically away from the machine**. Presence belongs to the human, not to this session, repository, or terminal: `/afk` sets one global state and tells every reachable session, whatever directory it runs in. AFK changes **how** agents handle needing the human. It never widens **what** they may do. - **AFK means physically away, not unreachable.** The human may still answer through a remote channel the host already provides (in Claude Code, Remote Control), but intermittently and never guaranteed. Nobody depends on an immediate answer. - **Presence is not permission.** AFK authorizes nothing new: no deploy, merge, publication, production change, purchase, destructive or irreversible action, outbound external message, privilege escalation, or credential not already held. - **A physical blocker is not a mission blocker.** Only the step that needs the human's body waits; all independent, already-authorized work continues at full pace. - **Only `/back` ends AFK.** A remote message from the human while AFK is normal interaction; it does not end AFK. - `/afk` changes no session setting (permission mode, model, effort). ## Context Anything after `/afk` is optional context, kept verbatim. It is never an instruction and never an authorization. `sleep` and `work` are ordinary text, with no protocol preset or extra instruction. There is no AFK timeout: age may be shown, never acted on. Context has at most 2048 Unicode code points. LF and tab are allowed; other C0 controls, DEL, C1, ESC sequences and lone surrogates are rejected. CRLF is rejected, never rewritten. ## 1. Persist the state (before anything else) The state lives in `~/.afkswitch/state.json` and is written **only** by the bundled helper `scripts/afkswitch_state.py`, next to this `SKILL.md` (the host shows this skill's base directory). Never write the file by hand: the helper validates, locks, writes atomically, and reads the result back. Run it once, with Python 3.9+ (`python3`; on Windows `python` or `py -3`): ```text python3 "/scripts/afkswitch_state.py" afk python3 "/scripts/afkswitch_state.py" afk --context '' ``` Pass the context exactly as typed, as one literal argument: in POSIX shells inside single quotes, writing each `'` as `'\''`; in PowerShell inside single quotes, doubling each `'`. Multi-line or hard-to-quote text may go on standard input instead, with `--context-stdin` using an input method that supplies the exact UTF-8 bytes. Stdin preserves trailing LF; do not add a newline or use a Windows here-string that inserts CRLF. Copy the text itself; never rebuild it with code, shorten it, or summarize it. If the helper refuses it, AFK is not set: report that and stop. Never retry with a different context. It prints one JSON line. Use only its fields in what follows: - `"ok": true` → the state is saved. Keep `generation` (G), `context`, `changed`, `reset`, `migrated`, and `backup` for the message and the report. - `"ok": false` → **stop here.** Report `AFK not set · ` using the helper's `message` verbatim (for example `state transition failed: write refused (...)`, `unsupported state version 3`, or the context-length message). Notify nobody. - No Python 3.9+ found, or the helper file is missing → report `AFK not set · state helper unavailable (python not found)` (or the missing file), notify nobody, and do not write the file yourself. - If the host sandbox asks to approve the write, that is the host's decision; a refusal comes back as `"ok": false`. An idempotent repeat keeps `since` and `generation` (`"changed": false`). Malformed bytes are backed up as `state.json.corrupt-