Sleepwing for Claude Code (macOS): setup, what each hook does, and honest limits
Claude Code runs for minutes, then stops — sometimes finished, sometimes waiting for a permission, sometimes failed. This page is the setup guide: which official hooks Sleepwing installs, what the pet does in each state, and where the coverage ends. If you'd rather not install an app, the free DIY hook is further down and it's a perfectly good answer.
Setup (about a minute)
- Install the notarized beta — download and unzip, or
brew install --cask lttxzmj/tap/sleepwing(macOS 14+, Apple Silicon). - Open Sleepwing's Integrations page and connect Claude Code. It merges its own commands into the existing
hooksobject in~/.claude/settings.jsonand leaves unrelated hooks of yours alone; removing the integration deletes only Sleepwing's own entries. - Run any task in Claude Code and watch the pet change state.
The installed commands all point at one local relay script, so the shape in your settings file is the ordinary official one (Claude Code hooks docs) — nothing proprietary, and you can read it before and after.
What each hook does
Sleepwing subscribes to eight official events, and each one maps to exactly one thing on your desktop:
UserPromptSubmit— a turn starts: the pet switches to working and the session shows up in the menu bar.PreToolUse/PostToolUse— still working; these keep a long run from looking stalled.PermissionRequest— waiting for you. This is the state worth leaving your desk for, because nothing moves until you answer.Notification— also waiting for you, but only for the attention-bearing types:permission_prompt,idle_prompt,elicitation_dialog,agent_needs_input. Other notification types are ignored on purpose so the pet doesn't cry wolf.Stop— finished.StopFailure— failed, handled as a content-free failure rather than a completion. ASessionEndarriving at the same moment cannot immediately erase it, so a failed run doesn't get quietly reported as done.SessionEnd— the session is cleared from the list.
Clicking Open task on a waiting session returns you to the exact terminal tab in Terminal.app or iTerm2. That works because the relay records the session's controlling tty device name (for example ttys012) — not terminal contents, not working directories, not window titles. macOS asks once for automation consent; terminals without scripting support fall back to activating the app.
While Claude Code is working, that time counts toward small breaks — water, stretch, look away — and the break timer pauses the moment a session is waiting on you, so you're not nudged to rest while the agent needs an answer.
Honest limits
- Claude Code is a supported integration. The failure path has been exercised in a real session; a full verified end-to-end lifecycle in our acceptance window exists for pi, Codex and OpenCode, not yet for Claude Code. Treat the state machine as supported, not as a measured reliability number.
- Hook delivery is best-effort and never blocks Claude Code. If the app isn't running, events are dropped rather than queued — you lose a notification, not a turn.
- Exact-tab return covers Terminal.app and iTerm2; other terminals activate the app and you pick the tab.
- Apple Silicon, macOS 14+. No Intel build, no Linux, no Windows.
If you'd rather not install an app
Two free options, in order of effort. Both are legitimate; use one if it fits.
The terminal bell. In Claude Code run /config and enable the notification/bell preference; Terminal.app and iTerm2 can both post a system notification on a bell. One session in one terminal, zero files touched.
A DIY hook. Claude Code hooks can run any command. A minimal ~/.claude/settings.json that plays one sound when the agent needs you and another when it stops:
{
"hooks": {
"Notification": [{ "hooks": [{ "type": "command",
"command": "afplay /System/Library/Sounds/Glass.aiff" }] }],
"Stop": [{ "hooks": [{ "type": "command",
"command": "afplay /System/Library/Sounds/Funk.aiff" }] }]
}
}
Merge this into your existing hooks object rather than replacing the file. Honest limits: every Notification sounds the same, so a permission ask and an idle prompt are indistinguishable; nothing tells you which project just finished; and you'll rebuild it per agent, since Codex, Cursor and Gemini CLI each use a different hook format.
⬇ Download the notarized beta (macOS 14+, Apple Silicon)
中文速览
Claude Code 跑长任务时会静默停下——可能是完成、可能在等你确认权限、也可能失败。Sleepwing 桌宠通过官方 hooks 接入:在「连接」页一键把命令合并进 ~/.claude/settings.json(保留你已有的 hooks,卸载只删自己的条目)。各事件对应一种状态:UserPromptSubmit/PreToolUse/PostToolUse 为「工作中」,PermissionRequest 与 Notification(仅 permission_prompt、idle_prompt、elicitation_dialog、agent_needs_input 四类)为「等你」,Stop 为「完成」,StopFailure 按无内容的失败处理、不会被同时到达的 SessionEnd 抹成完成。点「打开任务」可跳回 Terminal.app / iTerm2 的确切标签页(依据 tty 设备名,不读终端内容与路径;首次需系统授权;其他终端退化为激活应用)。如实说明:Claude Code 目前标注为「支持接入」,完整生命周期的验收数据来自 pi / Codex / OpenCode;hook 投递为尽力而为,应用未运行时丢事件而不排队。不想装应用:终端铃声(/config)或自己写 hooks 播音效(上面有可复制配置,注意合并而非覆盖)就够用——单 Agent 场景推荐先用它们。零外联、无账户、无遥测,hook 在本地脱敏后只留下「提供方、会话编号、状态、时间、可选的短任务标签、本地跳回路由」。免费 Beta。