## File: README.md

<h1 align="center">Clawd on Desk</h1>







Clawd lives on your desktop and reacts to what your AI coding agent is doing — in real time. Start a long task, walk away, come back when the crab tells you it's done.

Thinking when you prompt, typing when tools run, grooving or juggling for subagents, reviewing permissions, celebrating when tasks complete, sleeping when you step away. Ships with three built-in themes: **Clawd** (pixel crab), **Calico** (三花猫), and **Cloudling** (云宝), with full support for custom themes and imported Codex Pet animation packs.

> Supports Windows 11, macOS, and Ubuntu/Linux. Windows releases provide separate x64 and ARM64 installers. Source builds require Node.js. Works with **Claude Code**, **Codex CLI**, **Copilot CLI**, **Gemini CLI**, **Antigravity CLI (agy)**, **Cursor Agent**, **CodeBuddy**, **WorkBuddy**, **Kiro CLI**, **Kimi Code CLI (Kimi-CLI)**, **Qwen Code**, **ZCode**, **CodeWhale**, **opencode**, **MiMo Code**, **Pi**, **OpenClaw**, **Hermes Agent**, **Qoder**, **QoderWork**, **QwenWork (千问办公)**, **Reasonix CLI**, and **DeepSeek Harness**.

## Features

### Multi-Agent Support
- **Claude Code** — full integration via command hooks + HTTP permission hooks
- **Codex CLI** — official hooks with JSONL fallback (`~/.codex/sessions/`), auto-synced by default with real permission bubbles
- **Copilot CLI** — optional command hooks via `~/.copilot/hooks/hooks.json` (install from Settings → Agents; see the Copilot guide for manual JSON fallback)
- **Gemini CLI** — optional command hooks via `~/.gemini/settings.json` (install from Settings → Agents or run `npm run install:gemini-hooks`)
- **Antigravity CLI (agy)** — optional command hooks via `~/.gemini/config/hooks.json` (install from Settings → Agents or run `npm run install:antigravity-hooks`); **state-only**: Clawd never pops a permission bubble for agy. Every Allow / Deny / Always-allow choice happens in agy's own terminal menu
- **Cursor Agent** — optional [Cursor IDE hooks](https://cursor.com/docs/agent/hooks) in `~/.cursor/hooks.json` (install from Settings → Agents or run `npm run install:cursor-hooks`)
- **CodeBuddy** — optional Claude Code-compatible command hooks + HTTP permission hooks via `~/.codebuddy/settings.json` (install from Settings → Agents or run `node hooks/codebuddy-install.js`)
- **Custom HTTP agents** — register another local executable in Settings and POST lifecycle events to Clawd's dynamic `/state` endpoint. Registration does not install hooks or make an arbitrary application report automatically; v1 is state-only and leaves permission decisions in the application's own UI. See the [custom HTTP agent guide](docs/guides/custom-agent-http.md).
- **WorkBuddy** — optional Claude Code-compatible command hooks via `~/.workbuddy-ai/settings.json` (current) or `~/.workbuddy/settings.json` (legacy; install from Settings → Agents or run `node hooks/workbuddy-install.js`). State + Notification only: the desktop app resolves permissions in its own native sandbox and GUI, so Clawd does not register a permission hook for it.
- **Kiro CLI** — optional command hooks injected into custom agent configs under `~/.kiro/agents/`, plus an auto-created `clawd` agent that is re-synced from Kiro's built-in `kiro_default` after you install the integration, so you can opt into hooks with minimal behavior drift via `kiro-cli --agent clawd` or `/agent swap clawd`. State hooks are verified on macOS and Windows.
- **Kimi Code CLI (Kimi-CLI)** — optional command hooks via `~/.kimi/config.toml` (`[[hooks]]` entries) (install from Settings → Agents or run `npm run install:kimi-hooks`)
- **Qwen Code** — optional command hooks via `~/.qwen/settings.json` (install from Settings → Agents or run `npm run install:qwen-hooks`); state tracking and Qwen `PermissionRequest` desktop approval bubbles are supported
- **ZCode** — optional state-only hooks via `~/.zcode/cli/config.json` → `hooks.events.*` (install from Settings → Agents or run `npm run install:zcode-hooks`); Phase 1 drives session, prompt, tool, failure, and completion animations without intercepting ZCode permissions. Clawd preserves explicit global or per-hook `enabled:false` settings
- **CodeWhale** — optional state-only lifecycle hooks via `~/.codewhale/config.toml` (`[[hooks.hooks]]` entries) (install from Settings → Agents or run `npm run install:codewhale-hooks`); Phase 1 drives idle, thinking, working, sleeping, error, attention, and sweeping animations only, without permission bubbles or subagent tracking
- **Reasonix CLI** — optional state-only command hooks via `<Reasonix home>/settings.json` (`~/.reasonix/settings.json` on macOS/Linux, `%APPDATA%\reasonix\settings.json` on Windows; install from Settings → Agents or run `npm run install:reasonix-hooks`); Phase 1 drives lifecycle, tool, notification, compaction, and subagent-stop animations while leaving permission decisions in Reasonix's own terminal flow
- **opencode** — optional [plugin integration](https://opencode.ai/docs/plugins) via `~/.config/opencode/opencode.json` (install from Settings → Agents or run `node hooks/opencode-install.js`); zero-latency event streaming and permission bubbles with Allow/Always/Deny. Child sessions spawned by the `task` tool are headless and do not participate in the visible multi-session animation fanout
- **MiMo Code** — optional [plugin integration](https://opencode.ai/docs/plugins) via the effective file under `~/.config/mimocode/` (`config.json` → `mimocode.json` → default `mimocode.jsonc`, later wins; install from Settings → Agents or run `npm run install:mimocode-plugin`); shares the same `@mimo-ai/plugin` SDK and permission behavior as opencode. Its `task` child sessions are likewise headless
- **Pi** — optional global extension via `~/.pi/agent/extensions/clawd-on-desk` (install from Settings → Agents or run `npm run install:pi-extension`); state-only interactive lifecycle and tool activity updates while preserving Pi's default YOLO behavior
- **OpenClaw** — optional state-only plugin integration via `~/.openclaw/openclaw.json` (install from Settings → Agents or run `npm run install:openclaw-plugin`; OpenClaw also needs an initialized config); local `openclaw tui --local` sessions drive Clawd animations, without permission bubbles or terminal focus in Phase 1
- **Hermes Agent** — optional [plugin integration](https://hermes-agent.org/) via Hermes' managed plugin directory (install from Settings → Agents or run `npm run install:hermes-plugin`); state, sessions, SessionEnd, terminal focus, and supported permission bubbles are available
- **Qoder** — optional state-only command hooks via `~/.qoder/settings.json` (install from Settings → Agents or run `npm run install:qoder-hooks`); Phase 1 drives Clawd animations only — Qoder permission prompts are observed as notifications, and every Allow / Deny choice stays in Qoder's own flow
- **QoderWork** — optional state-only command hooks via `~/.qoderwork/settings.json` (install from Settings → Agents or run `npm run install:qoderwork-hooks`); Phase 1 drives Clawd animations and the Session HUD — QoderWork permission events are observed silently as part of the working flow, and every Allow / Deny choice stays in QoderWork's own flow
- **QwenWork (千问办公)** — optional hook-only, state-only command hooks via `~/.QwenWorkCN/settings.json` (install from Settings → Agents or run `npm run install:qwenwork-hooks`, uninstall with `npm run uninstall:qwenwork-hooks`); macOS and Windows desktop only — [qwenwork.cn/download](https://qwenwork.cn/download) has no Linux client, so there is no WSL pairing. Phase 1 drives Clawd animations and the Session HUD; `PermissionRequest` / `PermissionDenied` are observed only and mapped to `working`, the hook's stdout is always `{}`, and Clawd never produces an Allow / Deny — QwenWork's native permission flow stays the only decision maker. No startup recovery: the desktop process is long-lived and does not mean a turn is running
- **DeepSeek Harness** — experimental, web-profile-only integration through a Clawd-managed in-process DSH plugin. Public session events drive Clawd state with per-session ordering, and public blocking `approval/request` calls can show an Allow Once / Deny bubble; no-decision always returns to DSH's native web answerer. `ask_user_question` stays entirely native to DSH, and Clawd never reads DSH projection storage. See the [DeepSeek Harness guide](docs/guides/dsh-setup.md)
- **Multi-agent coexistence** — run all agents simultaneously; Clawd tracks each session independently

### Animations & Interaction
- **Real-time state awareness** — agent hooks and log polling drive Clawd's animations automatically
- **12 animated states** — idle, thinking, typing, building, subagent groove, multi-subagent juggling, error, happy, notification, sweeping, carrying, sleeping
- **Codex Pet imports** — import Codex Pet zip packages from `Settings…` → `Theme`; Clawd adapts their atlas animations into managed themes
- **Eye tracking** — Clawd follows your cursor in idle state, with body lean and shadow stretch
- **Sleep sequence** — yawning, dozing, collapsing, sleeping after 60s idle; mouse movement triggers a startled wake-up animation
- **Click reactions** — double-click for a poke, 4 clicks for a flail
- **Drag from any state** — grab Clawd anytime (Pointer Capture prevents fast-flick drops), release to resume
- **Mini mode** — drag to right edge or right-click "Mini Mode"; Clawd hides at screen edge with peek-on-hover, mini alerts/celebrations, and parabolic jump transitions

### Permission Bubble
- **In-app permission review** — when a permission-capable integration sends a supported request, Clawd can pop a floating bubble card instead of waiting in the terminal; state-only agents keep their native permission flow
- **Allow / deny / agent-native extras** — one-click approve or reject, plus permission rules / `Always` actions when the source agent supports them
- **Permission handling modes** — choose **Ask every time**, confirmation-gated **Question prompts only** (tool-shaped requests from explicitly supported agents), or **Auto-approve**. Auto-approve handles every request the adapter marks automation-eligible—including unrecognized non-empty Claude/Qwen request names—but missing names, unsupported decision shapes, and CodeBuddy questions/plans still defer to the native flow. It downgrades after restart, and each eligible live session can independently choose Ask every time or tools-only. See the [setup guide](docs/guides/setup-guide.md#permission-handling-automation)
- **Optional remote approval** — Telegram and Feishu/Lark can mirror eligible pending requests while the local bubble remains available. A channel failure produces no remote decision and never a denial: the desktop request stays pending, while remote-only requests fall back to the agent only after every available client returns no decision
- **Global hotkeys** — `Ctrl+Shift+Y` to Allow, `Ctrl+Shift+N` to Deny the latest permission bubble (only registered while bubbles are visible)
- **Stacking layout** — multiple permission requests stack upward from the bottom-right corner
- **Auto-dismiss** — if you answer in the terminal first, the bubble disappears automatically
- **Per-agent toggle** — open `Settings…` → `Agents`, pick an agent, and turn off `Show pop-up bubbles` to keep prompts in that agent's own terminal/TUI

### Session Intelligence
- **Multi-session tracking** — sessions across all agents resolve to the highest-priority state
- **Subagent awareness** — headphones groove for 1 subagent, three-ball juggling for 2+
- **Sessions dashboard + HUD** — right-click or tray → `Open Dashboard` to inspect live sessions, recent events, aliases, and jump to a terminal; a compact HUD near Clawd keeps current live sessions visible
- **Subscription quota at a glance** — optional Orbit rings beside the pet and detailed Dashboard bars show the quota windows reported by supported agents. Local Claude collection is off by default and uses Claude Code's [official status-line `rate_limits` payload](https://code.claude.com/docs/en/statusline); it does not make an additional request to Anthropic. See the [data-flow and ownership notes](docs/guides/setup-guide.md#claude-code-subscription-quota-official-status-line-not-scraping).
- **Terminal focus** — Dashboard/HUD actions jump to a specific session's terminal window; notification/attention states auto-focus the relevant terminal
- **Process liveness detection** — detects crashed/exited supported agent processes and cleans up orphan sessions
- **Startup recovery** — if Clawd restarts while any supported agent is still running, it stays awake instead of falling asleep

### Mobile Companion (PWA)
- **Live mirror on your phone** — enable `Settings…` → `Mobile / PWA` and open the pairing URL on your phone; the Clawd Mobile web app shows your agent sessions and their live states in real time
- **Read-only by design** — the LAN bridge only broadcasts state; nothing in the PWA can touch your machine (LAN PWA approval is on the roadmap; Telegram and Feishu/Lark are separate supported channels)
- **LAN-only + token-gated** — pairing requires a token, tokens rotate automatically with a grace window, and access can be regenerated or reset in one click
- **Installable** — it's a PWA: add it to your home screen for an app-like experience
> The mobile companion line — from the first prototype to token rotation — is built and led by core contributor [@Bynlk](https://github.com/Bynlk), who also maintains [clawd-on-mobile](https://github.com/Bynlk/clawd-on-mobile), a sister fork with a native Android app.

### System
- **Click-through** — transparent areas pass clicks to windows below; only Clawd's body is interactive
- **Position memory** — Clawd remembers where you left it across restarts (including mini mode)
- **Single instance lock** — prevents duplicate Clawd windows
- **Auto-start** — Claude Code's SessionStart hook can launch Clawd automatically if it's not running
- **Do Not Disturb** — right-click or tray menu to enter sleep mode; all hook events are silenced until you wake Clawd. Permission bubbles are suppressed during DND — Codex, opencode, and MiMo Code fall back to their native prompts, while Claude Code and CodeBuddy fall back to their built-in permission flow. WorkBuddy uses state + Notification only; Antigravity and Pi are state-only integrations.
- **Sound effects** — short audio cues on task completion and permission requests (toggle via the system tray or Settings; 10s cooldown, auto-muted during DND)
- **System tray** — DND mode, auto-start, check for updates
- **i18n** — English, Simplified Chinese, Traditional Chinese, Korean, Japanese, Brazilian Portuguese, and Spanish UI; switch in Settings → General
- **Auto-update** — checks GitHub releases; Windows installs NSIS updates on quit, macOS/Linux `git pull` + restart when running from a cloned repo

## Animations



| Idle | Thought Bubble | Typing | Building | 1 Subagent | 2+ Subagents |
| --- | --- | --- | --- | --- | --- |
| Calico Idle | Calico Thinking | Calico Typing | Calico Building | Calico Juggling | Calico Conducting |
| Cloudling Idle | Cloudling Thinking | Cloudling Typing | Cloudling Building | Cloudling Juggling | Cloudling Conducting |



Full event-to-state mapping, mini mode, and click reactions: **[docs/guides/state-mapping.md](docs/guides/state-mapping.md)**

## Multi-display

Clawd adapts to multi-monitor setups: proportional sizing uses the display Clawd launches on, portrait monitors get a bounded boost so the pet stays readable on tall narrow screens, and you can drag Clawd across displays.



## Quick Start

For normal use, download the latest prebuilt installer from **[GitHub Releases](https://github.com/rullerzhou-afk/clawd-on-desk/releases/latest)**:

- **Windows**: `Clawd-on-Desk-Setup-<version>-x64.exe` or `Clawd-on-Desk-Setup-<version>-arm64.exe`
- **macOS**: `.dmg`
- **Linux**: `.AppImage` or `.deb`

Launch Clawd after installing it. Fresh installs auto-sync Claude Code and Codex only; install other local agent integrations from **Settings → Agents** when you need them.

Run from source only if you're contributing, testing unreleased code, or debugging integrations. Source installs download Electron/build tooling and can create a large `node_modules` tree.

```bash
# Clone the repo
git clone https://github.com/rullerzhou-afk/clawd-on-desk.git
cd clawd-on-desk

# Install dependencies
npm install

# Start Clawd (auto-registers Claude Code and Codex hooks on launch)
npm start
```

**Claude Code** and **Codex CLI** work out of the box with auto-registered hooks. For **Copilot CLI**, **Gemini CLI**, **Antigravity CLI (agy)**, **Cursor Agent**, **CodeBuddy**, **WorkBuddy**, **Kiro CLI**, **Kimi Code CLI (Kimi-CLI)**, **Qwen Code**, **ZCode**, **CodeWhale**, **opencode**, **MiMo Code**, **Pi**, **OpenClaw**, **Hermes Agent**, **Qoder**, **QoderWork**, **QwenWork (千问办公)**, **Reasonix CLI**, and **DeepSeek Harness**, install the integration from **Settings → Agents** first; Clawd then keeps it synced while it remains enabled. Also covers remote SSH, WSL, and platform-specific notes (macOS / Linux): **[docs/guides/setup-guide.md](docs/guides/setup-guide.md)**

Want to run Claude Code / Codex CLI on a remote server and surface state plus permission bubbles in your local Clawd? Use the in-app **Settings → Remote SSH → Deploy / Repair Hooks**. Full walkthrough, shared-server isolation boundary, Doctor boundary, and FAQ: **[docs/guides/guide-remote-ssh.md](docs/guides/guide-remote-ssh.md)**

For the official `Codex + WSL` status, Clawd's current implementation boundary, and why this is easy to misread, see: **[docs/guides/codex-wsl-clarification.md](docs/guides/codex-wsl-clarification.md)**

## Known Limitations

Some agents have feature gaps (no permission bubble, polling latency, no terminal focus). See the full table: **[docs/guides/known-limitations.md](docs/guides/known-limitations.md)**

## Custom Themes

Clawd supports custom themes — replace the default crab with your own character and animations. If you already have a Codex Pet package, import its zip from `Settings…` → `Theme` → `Import pet zip`; Clawd turns the atlas into a managed theme automatically.

**Quick start:**
1. Scaffold a theme:
   ```bash
   node scripts/create-theme.js my-theme
   # or
   npm run create-theme -- my-theme
   ```
   No argument also works: it creates the next available `my-theme` scaffold in your user themes directory.
2. Edit `theme.json` and create your assets (SVG, GIF, APNG, WebP, PNG, JPG, or JPEG)
3. Restart Clawd or open `Settings…` → `Theme` → select your theme

**Minimum viable theme:** 1 SVG (idle with eye tracking) + 7 GIF/APNG files (thinking, working, error, happy, notification, sleeping, waking). Eye tracking can be disabled to use any format for all states.

Validate your theme before distributing:
```bash
node scripts/validate-theme.js path/to/your-theme
```

Theme cards in `Settings…` → `Theme` now expose capability badges such as `Tracked idle`, `Static theme`, `Mini`, `Direct sleep`, and `No reactions`, so users can tell what a theme supports before switching.

See [docs/guides/guide-theme-creation.md](docs/guides/guide-theme-creation.md) for the full creation guide with tiered paths (beginner → advanced), `theme.json` field reference, and asset guidelines.

> Third-party SVG files are automatically sanitized for security.

### Roadmap

Some things we'd like to explore in the future:

- Codex terminal focus via process tree lookup from `codex.exe` PID
- Theme registry and in-app download
- Hook uninstall script for clean app removal
- LAN PWA mobile companion: in-browser permission approval (in progress, led by [@Bynlk](https://github.com/Bynlk)); Telegram and Feishu/Lark approval are separate supported channels

## Contributing

Clawd on Desk is a community-driven project. Bug reports, feature ideas, and pull requests are all welcome — open an [issue](https://github.com/rullerzhou-afk/clawd-on-desk/issues) to discuss or submit a PR directly.

### Maintainers



| [**@rullerzhou-afk**鹿鹿 · creator](https://github.com/rullerzhou-afk) | [**@YOIMIYA66**maintainer](https://github.com/YOIMIYA66) | [**@Bynlk**core contributor · Mobile / PWA](https://github.com/Bynlk) |
| --- | --- | --- |



### Contributors

Thanks to everyone who has helped make Clawd better:



| [PixelCookie-zyf](https://github.com/PixelCookie-zyf) | [yujiachen-y](https://github.com/yujiachen-y) | [AooooooZzzz](https://github.com/AooooooZzzz) | [purefkh](https://github.com/purefkh) | [Tobeabellwether](https://github.com/Tobeabellwether) | [Jasonhonghh](https://github.com/Jasonhonghh) | [crashchen](https://github.com/crashchen) |
| --- | --- | --- | --- | --- | --- | --- |
| [hongbigtou](https://github.com/hongbigtou) | [InTimmyDate](https://github.com/InTimmyDate) | [NeizhiTouhu](https://github.com/NeizhiTouhu) | [xu3stones-cmd](https://github.com/xu3stones-cmd) | [androidZzT](https://github.com/androidZzT) | [Ye-0413](https://github.com/Ye-0413) | [WanfengzzZ](https://github.com/WanfengzzZ) |
| [TaoXieSZ](https://github.com/TaoXieSZ) | [ssly](https://github.com/ssly) | [stickycandy](https://github.com/stickycandy) | [Rladmsrl](https://github.com/Rladmsrl) | [YOIMIYA66](https://github.com/YOIMIYA66) | [Kevin7Qi](https://github.com/Kevin7Qi) | [sefuzhou770801-hub](https://github.com/sefuzhou770801-hub) |
| [Tonic-Jin](https://github.com/Tonic-Jin) | [seoki180](https://github.com/seoki180) | [sophie-haynes](https://github.com/sophie-haynes) | [PeterShanxin](https://github.com/PeterShanxin) | [CHIANGANGSTER](https://github.com/CHIANGANGSTER) | [JaeHyeon-KAIST](https://github.com/JaeHyeon-KAIST) | [hhhzxyhhh](https://github.com/hhhzxyhhh) |
| [TVpoet](https://github.com/TVpoet) | [zeus6768](https://github.com/zeus6768) | [anhtrinh919](https://github.com/anhtrinh919) | tomaioo | [v-avuso](https://github.com/v-avuso) | [livlign](https://github.com/livlign) | [tongguang2](https://github.com/tongguang2) |
| [Ziy1-Tan](https://github.com/Ziy1-Tan) | [tatsuyanakanogaroinc](https://github.com/tatsuyanakanogaroinc) | [yeonhub](https://github.com/yeonhub) | [joshua-wu](https://github.com/joshua-wu) | [nmsn](https://github.com/nmsn) | [sunnysonx](https://github.com/sunnysonx) | [YuChenYunn](https://github.com/YuChenYunn) |
| [jhseo-b](https://github.com/jhseo-b) | [Hwasowl](https://github.com/Hwasowl) | [XiangZheng2002](https://github.com/XiangZheng2002) | [keiyo118](https://github.com/keiyo118) | [pan93412](https://github.com/pan93412) | [taehwanis](https://github.com/taehwanis) | [linnin233](https://github.com/linnin233) |
| [xiyouMc](https://github.com/xiyouMc) | [Bynlk](https://github.com/Bynlk) | [zxypro1](https://github.com/zxypro1) | [NeroAyase](https://github.com/NeroAyase) | [divergentD](https://github.com/divergentD) | [Ne9roni](https://github.com/Ne9roni) | [QingXB](https://github.com/QingXB) |
| [藤知](https://github.com/29206394) | [Tsdsj](https://github.com/Tsdsj) | [godlockin](https://github.com/godlockin) | [sLingli](https://github.com/sLingli) | [ustin-star](https://github.com/ustin-star) | [cod3hulk](https://github.com/cod3hulk) | [lxgxhsy](https://github.com/lxgxhsy) |
| [rebootcrab-blip](https://github.com/rebootcrab-blip) | [zhaoxv210](https://github.com/zhaoxv210) | [serenNan](https://github.com/serenNan) | [IatomicreactorI](https://github.com/IatomicreactorI) | [quantai1314](https://github.com/quantai1314) | [Git-creat7](https://github.com/Git-creat7) | [undownding](https://github.com/undownding) |
| [chrono-meta](https://github.com/chrono-meta) | [Yike-Ye](https://github.com/Yike-Ye) | [xiaoshidefeng](https://github.com/xiaoshidefeng) | [yanguibao1997](https://github.com/yanguibao1997) | [JasonZH6600](https://github.com/JasonZH6600) | [V1staz](https://github.com/V1staz) | [royhuang91](https://github.com/royhuang91) |
| [Schlaflied](https://github.com/Schlaflied) | [KaiC5504](https://github.com/KaiC5504) | [jiaxuan1101](https://github.com/jiaxuan1101) | [kkirito16](https://github.com/kkirito16) | [200780381](https://github.com/200780381) | [Dxy2326](https://github.com/Dxy2326) | [lurui1997](https://github.com/lurui1997) |
| [JesmonX](https://github.com/JesmonX) | [chen86860](https://github.com/chen86860) | [LinYsssss](https://github.com/LinYsssss) | [He-wei-gui](https://github.com/He-wei-gui) | [liugou27](https://github.com/liugou27) | [YOOGOMJA](https://github.com/YOOGOMJA) | [anupamme](https://github.com/anupamme) |
| [anthonyonazure](https://github.com/anthonyonazure) | [weed33834](https://github.com/weed33834) | [arismarioneves](https://github.com/arismarioneves) | [aaronWool](https://github.com/aaronWool) | [Zamaniego](https://github.com/Zamaniego) |  |  |



## Acknowledgments

- Clawd pixel art reference from [clawd-tank](https://github.com/marciogranzotto/clawd-tank) by [@marciogranzotto](https://github.com/marciogranzotto)
- Shared on [LINUX DO](https://linux.do/) community

## License

Source code is licensed under the [GNU Affero General Public License v3.0](LICENSE) (AGPL-3.0).

**Artwork and bundled theme assets (including `assets/` and `themes/*/assets/`) are NOT covered by AGPL-3.0.** All rights reserved by their respective copyright holders. See [assets/LICENSE](assets/LICENSE) and the notices below for details.

- **Clawd** character is the property of [Anthropic](https://www.anthropic.com). This is an unofficial fan project, not affiliated with or endorsed by Anthropic.
- **Calico cat (三花猫)** artwork by 鹿鹿 ([@rullerzhou-afk](https://github.com/rullerzhou-afk)). All rights reserved.
- **Cloudling (云宝)** artwork by 鹿鹿 ([@rullerzhou-afk](https://github.com/rullerzhou-afk)). All rights reserved. Cloudling's visual direction includes an homage to the OpenAI Codex logo; Codex/OpenAI marks remain the property of OpenAI, and this project is not affiliated with or endorsed by OpenAI.
- **Third-party contributions**: copyright retained by respective artists.

**No cryptocurrency.** This project has no token, coin, NFT, or airdrop, and is not affiliated with any cryptocurrency project.

---

## File: assets/source/cloudling-codex-pet/confirmed/README.md

# Cloudling Confirmed

这里是 Cloudling 当前干净交付面。已确认状态统一放在 `states/`，共用资产统一放在 `library/`；原始探索文件仍保留在 `../`、`../wip/`、`../library/`，方便追溯决策过程。

## 2026-04-27 精修确认

这三个文件是当前优先接入版本：

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| typing | `states/typing-original-polish-v2.svg.html` | 保留原版代码眼、190deg 卡顿旋转和角速度联动；代码眼改为 A/B 档伪随机组合，停止和快停止时只展示 A 档组合。 |
| thinking | `states/thinking-lens-code-v2.svg.html` | 保留放大镜里跑代码的创意，改成轻玻璃镜片 + 代码扫描流；删除中心 pulse 圆、transit 曲线和眨眼矩形补丁。 |
| notification | `states/notification-alert-polish-v2.svg.html` | 保留强提醒摇晃，改成暖色破碎冲击弧 + rim flash；删除 badge / 感叹号气泡。 |

## 2026-04-28 long idle 彩蛋首发

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| long-idle (cloud bush peek) | `states/long-idle-cloud-bush-peek-v1.svg.html` | 双层暖云从左飘入挡住云宝 → 哧溜从左上探头 + 头顶冒问号 → 缩回 → 哧溜从右上再探一次 + 左右扫看眨眼 → 缩回 → 暖云左右散开露出 → idle。9 段叙事 6.2s + 1.0s gap。Cloudling 第一个引入「场景元素」(暖云屏障) 的状态，cartoon 式两边轮流探头是核心笑点。|

## 2026-04-28 sleeping 部件库 (动画前置)

sleeping 走「装扮路线 A」(纯装扮无粒子)。先磨 4 件部件再做动画，部件主库见 `../wip/sleeping-parts-explore.svg.html`，独立可复用静态资产存在 `library/`。

| 部件 | 推荐文件 | 说明 |
|---|---|---|
| 睡帽 v2-d | `../wip/sleeping-parts-explore.svg.html` (part 1) | 弯折 (bend=0.4) + 黄色圆角五角星顶。毛茸茸 cuff 用 18 个圆排在椭圆轨道上 (复用 Cloudling 主体「凸起几何」DNA), 不是 radial spikes。|
| 月亮 v2 (crescent) | `../wip/sleeping-parts-explore.svg.html` (part 2) | 暖月色 (`#FFF4D6→#FFD360→#E89F30`) + mask-based crescent + 4 陨石坑 + 顶部白高光。推翻初版月牙抱枕 (撞色 + 线条杂乱)。|
| day-night toggle | `../wip/sleeping-parts-explore.svg.html` (part 3) | 苹果风灯具开关。light=浅蓝 capsule + 白满月; dark=深紫蓝 capsule + crescent (镜像) + 5 颗星星。两状态都带月亮强化 sleeping 主题。拉绳后续加。|
| 睡眠眼罩 | `library/sleep-mask.svg` | 鹿鹿从 svgrepo.com 扒的真眼罩 path (上平下弧, 不是自建葫芦/胶囊) + 丝绸深蓝 `#22305A` 平涂 + 黑描边 + 闭眼 ⌣ 弧 + 3 根朝下睫毛丝, 左右镜像 ±5° 微下垂。viewBox `0 0 24 24` 跟 Cloudling 主体同坐标系, 直接 `` 叠在云宝双眼上居中。|

## 2026-04-28 idle → sleeping 过渡确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| idle → sleeping transition | `states/idle-to-sleeping-v1.svg.html` | day/night toggle 渐显 → 云宝看到后蹲下蓄力 → Mario bump 顶开关 → 基于原始 `CLOUD_D` 轮廓的 soft-body 渐进压扁/回弹 → 满意笑眼 → 戴帽和眼罩进入 sleeping。1.39s 视觉接触点已开始受压; 删除拉绳三角和碰撞横线; 默认态外观回到原 Cloudling。|

## 2026-04-29 conducting 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| conducting | `states/conducting-task-sparks-v5.svg.html` | 4 颗童话四角 task sparks 围绕云宝被眼神点名 A/B/C/D，依次提亮、移动并归位；云宝保留呼吸、轻摇、点名倾斜和 soft morph，浅色背景下也可读。最终定版采用 V5；V6 的突然收束 / 60% 球化方向不作为最终稿。|

## 2026-04-29 building 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| building | `states/building-shapeshift-loop-v1.svg.html` | 云宝按 `云宝 → 终端 → 模块方块 → 显示器 → 彩色 M 信封 → 微笑云宝` 循环变身。每次先眨眼，闭眼时换形，再睁眼落稳；保留 Cloudling 软体呼吸、轻微回弹、紫蓝 glow 和眼睛主导的活物感。芯片、文件夹方向不入最终稿。|

## 2026-04-29 sweeping 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| sweeping | `states/sweeping-context-cards-orbit-loop-v1.svg.html` | PreCompact / context cleanup 确认版。透明 context cards 从左侧水平进入，保持 0deg 绕过云宝前方，随后切到云宝身后并整齐垫入 stack；三张后 stack 原地压缩、轻闪、淡出。删除横向轨道线和背景大椭圆，云宝保留 3.2s 呼吸、眼神跟随和轻微转向。|

## 2026-04-29 juggling 确认 (复用映射)

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| juggling | `states/cloud-plane-orbit-explore.svg.html` | 复用激进彩蛋槽 2 的纸飞机 orbit。对应 SubagentStart(1) — 1 个 subagent 在工作时纸飞机像小行星绕飞，跟 conducting V5 的 4 颗 task sparks 形成 1 vs 4+ 的事件量级对照。同一 SVG 文件双重承担 (跟 happy burst V6 同时作为 attention 的复用模式一致)。|

## 2026-04-29 drag reaction 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| drag (被拖动反应) | `states/drag-react-v3.svg.html` | clawd `reactions.drag.file` 槽位实现。中心自旋 wobble ±11° / 0.9s alternate ease-in-out + idle 同款呼吸 0.96-1.0 / 5s，两层 pivot 都在身体中心 (12,12)，眼睛切到 library `><` token (cx=9/15, cy=12, stroke 紫蓝渐变 1.25)，云朵外形不变，无 shadow lift（Cloudling 悬浮）。纯 CSS @keyframes 自驱无 JS rAF。接入时窗口跟手由壳子 `move-window-by` 处理，SVG 内部不重复。|

## 2026-04-29 idle → dozing 过渡确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| idle → dozing transition | `states/idle-to-dozing-soft-slump-v1.svg.html` | dozing / 小憩确认版。第一帧严格对齐 `idle-follow` 胶囊眼 (x=7.7/13.7, y=9.5, w=2.6, h=5)；两轮「半闭 → 睁回」模拟真人打盹，最终闭眼先压成薄眼缝再接闭眼弧线，闭眼完成后身体和外形软塌下移到 dozing hold。默认 timing 9.03s (`0.35/1.00/0.30/0.80/1.59/0.55/1.00/1.32/1.88/0.24`)，保留轻呼吸 (1.8% / 3.8s) 与 timing/body 调参拉杆。|

## 2026-04-30 dozing → sleeping 过渡确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| dozing → sleeping transition | `states/dozing-to-sleeping-v1.svg.html` | 小憩 hold → 慢吸气回圆 → 睡帽轻落 → 眼罩滑下接管闭眼 → 对齐 `sleeping-loop-v1` 首帧。末帧为原始 Cloudling path、bodyTilt -6、breath scale 1.02、hat/mask 锁定摆位；Z 字交给 sleeping loop 生成。|

## 2026-04-30 dozing / 打盹循环确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| dozing loop | `states/dozing-loop-v1.svg.html` | 打盹 / 小憩循环。保持 `idle-to-dozing` 末尾软塌闭眼 hold，不加帽子、眼罩或 Z 字；呼吸靠主体轮廓回圆/塌回、整体抬起/下沉、闭眼弧线轻微变化和 halo 扩散共同表达。默认 5.8s 一轮，后段一次更深的睡沉点头。|

## 2026-04-30 sleeping → idle 过渡确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| sleeping → idle transition | `states/sleeping-to-idle-v1.svg.html` | day/night toggle 从 night 轻切回 day，使用散射短线而不是椭圆光斑提示唤醒；眼罩向右上滑走、睡帽向左上滑走，露出参考 dozing 的 Cloudling 本体闭眼，再撑开成 `idle-follow` 胶囊眼。末帧为原始 Cloudling path、bodyTilt 0、scale 1.0、无帽/无眼罩/无 Z 字。|

## 2026-04-30 mini-crabwalk 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-crabwalk | `states/mini-crabwalk-soft-scoot-v1.svg.html` | 右键进入 Mini Mode 前的边缘小挪步确认版。运行时由 clawd `animateWindowX` 移动窗口到屏幕边缘，SVG 内部只做原地软弹赶路循环；云宝小幅 scoot / hop / squash + 轻滚角，眼睛使用 long-idle 同款正常胶囊眼 ↔ 稍宽眼 `widenFactor`，身后三团小云尘在浅色模式下带淡蓝描边/填色以保持可读。|

## 2026-04-30 mini-idle 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-idle | `states/mini-idle-follow-b-v1.svg.html` | Mini Mode 贴边待机确认版。采用 B 方案: 可见中心内收 + 正眼, 不做斜眼; 动态参考正常 idle-follow, 保留眼睛跟随、眨眼、眼色渐变流动、呼吸、边缘距离驱动 scale 和轻微云体旋转。正式文件保留完整 Cloudling, 不内置裁切线/ghost; 运行时窗口贴边负责遮挡。锁定参数: eyeMax 1.85, maxRotDeg 13, distMaxScale 1.09, flowAmp 4.0, recenter 0.15s。|

## 2026-04-30 mini-enter 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-enter | `states/mini-enter-roll-in-v1.svg.html` | Mini Mode 入场确认版。不是 mini-crabwalk 的延续, 而是落到 `mini-idle-follow-b-v1` 前的一次性滚入: 起点完全不露, 从屏幕边缘外滚进来, 软弹 settle, 眼睛从短闭眼睁到 mini-idle B。正式文件保留完整 Cloudling, 不内置裁切线/ghost; WIP 用 `cropX=14.1` 验证 0% 不露。锁定参数: duration 1.25s, startX 15.8, rollDeg 28deg, overshoot 1.2, squash 0.07, eyeOpen 0.64。|

## 2026-05-01 mini-happy 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-happy | `states/mini-happy-full-ring-v1.svg.html` | Mini Mode 完成反馈确认版。选回 V1 的完整 full-ring 强庆祝感: 白芯 runner + 彩虹环 + 少量 sparkle, happy hold 后回到 mini-idle B 眼位。正式文件保留完整 Cloudling, 不内置裁切线/ghost; 贴边遮挡交给运行时窗口位置。锁定参数: duration 3.6s, ringPower 1.25, edgeBias 0.30, bounce 0.040, WIP cropX 14.1; 带隐藏 duration probe。|

## 2026-05-01 mini-alert 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-alert | `states/mini-alert-notification-v1.svg.html` | Mini Mode 通知确认版。选 WIP 的 punchy 档: 强摇晃 + 暖色破碎冲击弧 + rim flash, 不加 badge / 感叹号 / 彩虹 ring, 末帧回到 mini-idle B 胶囊眼。正式文件保留完整 Cloudling, 不内置裁切线/ghost; 贴边遮挡交给运行时窗口位置。锁定参数: duration 2.6s, shakeAngle 16deg, shakeFreqHz 7Hz, jumpY 0.52, squash 0.046, pulseScaleEnd 1.62, rimPower 1.12; 带隐藏 duration probe。|

## 2026-05-01 mini-peek 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-peek | `states/mini-peek-hover-pose-v1.svg.html` | Mini Mode hover peek 确认版。runtime 负责 25px / 200ms 窗口探出; SVG 负责 hover 后眼睛从 mini-idle 基准 (2.20×4.65, centers 7.75/12.15, gap 4.4) morph 到正常 idle-follow 基准 (2.60×5.00, centers 9/15, gap 6), 身体随后 duangduang 衰减回弹。正式文件保留完整 Cloudling, 不内置裁切线/ghost; 贴边遮挡交给运行时窗口位置。锁定参数: eyeReturnDur 0.24s, idleEyeMax 0.50, idleRecenter 0.45s, settleTx -0.22, settleScale 1.012, settleRot -0.65deg, duangPower 1.16, duangDur 1.12s, duangCycles 4.80, rimPower 1.30。|

## 2026-05-01 mini-enter-sleep 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-enter-sleep | `states/mini-enter-sleep-closed-in-v1.svg.html` | DND Mini Mode 入场确认版。复用 `mini-enter-roll-in-v1` 的起点完全不露和 duration probe, 但改成闭眼从边缘外轻轻滑进来 + 小幅困倦 settle; 不做活泼滚入、不睁眼。正式文件保留完整 Cloudling, 贴边遮挡交给运行时窗口位置。锁定参数: duration 1.45s, startX 15.8, rollDeg 8deg, overshoot 0.55, squash 0.035, eyeDrop 0.12。|

## 2026-05-01 mini-sleep 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-sleep | `states/mini-sleep-closed-breath-v1.svg.html` | DND Mini Mode 休眠循环确认版。接 `mini-enter-sleep-closed-in-v1` 末帧, 首帧 tx 0 / rot 0 / scale 1 / 闭眼弧线对齐; 低频呼吸 + 一次睡沉点头 + 左侧 zzz lifecycle, 不加睡帽 / 眼罩 / 场景元素。正式文件保留完整 Cloudling, 贴边遮挡交给运行时窗口位置。锁定参数: period 6.4s, breath 0.050, nodDepth 0.40, nodRot -0.55deg, eyeDrop 0.12, eyeSoft 0.10, zSize 1.90, zOpacity 0.68, zStart 1.40/9.25, zInterval 2.05s。|

## 2026-05-01 mini-working / mini-typing 确认

| 状态 | 推荐文件 | 说明 |
|---|---|---|
| mini-working / mini-typing | `states/mini-typing-thinking-left-eye-v1.svg.html` | Mini Mode 工作中可选态确认版。沿用 `thinking-lens-code-v2` 的轻玻璃放大镜和代码流, 但镜片固定停在左眼, 不再左右换眼; 镜片放大到 1.14, 右侧眯眼移到 x=14.85 的镜片边缘, 镜片内持续纯代码变化, 底眼每 3.6s 轻眨 0.16s 且不打断代码。正式文件保留完整 Cloudling, 不内置裁切线/ghost; 该状态不计入 required mini mode。|

## States

| 状态 | 文件 | 来源 |
|---|---|---|
| idle | `states/idle-follow.svg.html` | `../idle-follow.svg.html` |
| typing baseline | `states/typing.svg.html` | `../typing.svg.html` |
| typing polish | `states/typing-original-polish-v2.svg.html` | `states/typing.svg.html` |
| thinking baseline | `states/thinking.svg.html` | `../wip/thinking.svg.html` |
| thinking polish | `states/thinking-lens-code-v2.svg.html` | `states/thinking.svg.html` |
| notification baseline | `states/notification-pulse-explore.svg.html` | `../wip/notification-pulse-explore.svg.html` |
| notification polish | `states/notification-alert-polish-v2.svg.html` | `states/notification-pulse-explore.svg.html` |
| happy burst | `states/happy-burst-script.svg.html` | `../happy-burst-script.svg.html` |
| 404 error | `states/error-thundercloud-loop-v9-tuned.svg.html` | `../wip/error-thundercloud-loop-v9-tuned.svg.html` |
| cloud-plane orbit | `states/cloud-plane-orbit-explore.svg.html` | `../wip/cloud-plane-orbit-explore.svg.html` |
| long-idle cloud bush peek | `states/long-idle-cloud-bush-peek-v1.svg.html` | `../wip/long-idle-cloud-bush-peek-v2-before-script-rewrite.svg.html` |
| idle → sleeping transition | `states/idle-to-sleeping-v1.svg.html` | `../wip/idle-to-sleeping-v8-preserve-shape-no-line.svg.html` |
| conducting | `states/conducting-task-sparks-v5.svg.html` | `../wip/conducting-task-sparks-v5.svg.html` |
| building | `states/building-shapeshift-loop-v1.svg.html` | `../wip/building-shapeshift-v2/building-shapeshift-building-loop-v1.svg.html` |
| sweeping | `states/sweeping-context-cards-orbit-loop-v1.svg.html` | `../wip/sweeping-context-cards-orbit-loop-v1.svg.html` |
| idle → dozing transition | `states/idle-to-dozing-soft-slump-v1.svg.html` | `../wip/idle-to-dozing-soft-slump-v1.svg.html` |
| dozing loop | `states/dozing-loop-v1.svg.html` | `../wip/dozing-loop-v1.svg.html` |
| dozing → sleeping transition | `states/dozing-to-sleeping-v1.svg.html` | `../wip/dozing-to-sleeping-v1.svg.html` |
| sleeping → idle transition | `states/sleeping-to-idle-v1.svg.html` | `../wip/sleeping-to-idle-v1.svg.html` |
| mini-crabwalk | `states/mini-crabwalk-soft-scoot-v1.svg.html` | `../wip/mini-crabwalk-soft-scoot-v1-lightfix.svg.html` |
| mini-idle | `states/mini-idle-follow-b-v1.svg.html` | `../wip/mini-idle-follow-b-v3.svg.html` |
| mini-enter | `states/mini-enter-roll-in-v1.svg.html` | `../wip/mini-enter-roll-in-v1.svg.html` |
| mini-peek | `states/mini-peek-hover-pose-v1.svg.html` | `../wip/mini-peek-hover-pose-v1.svg.html` |
| mini-enter-sleep | `states/mini-enter-sleep-closed-in-v1.svg.html` | `../wip/mini-enter-sleep-closed-in-v1.svg.html` |
| mini-sleep | `states/mini-sleep-closed-breath-v1.svg.html` | `../wip/mini-sleep-closed-breath-v1.svg.html` |
| mini-happy | `states/mini-happy-full-ring-v1.svg.html` | `../wip/mini-happy-full-ring-v1.svg.html` |
| mini-alert | `states/mini-alert-notification-v1.svg.html` | `../wip/mini-alert-notification-v1.svg.html` |
| mini-working / mini-typing | `states/mini-typing-thinking-left-eye-v1.svg.html` | `../wip/mini-typing-thinking-left-eye-v1.svg.html` |

## Shared Assets

| 资产 | 文件 | 来源 |
|---|---|---|
| V2 软橡胶白静态参考 | `library/draft-rubber-white.svg` | `../library/draft-rubber-white.svg` |
| 眼睛形状库 | `library/eye-shape-library.svg.html` | `../library/eye-shape-library.svg.html` |
| 云朵球化参考 | `library/cloud-morph-explore.svg.html` | `../library/cloud-morph-explore.svg.html` |
| 纸飞机参考 | `library/paper-plane-v9-cloudling.svg.html` | `../library/paper-plane-v9-cloudling.svg.html` |
| 睡眠眼罩 (sleeping 部件) | `library/sleep-mask.svg` | `../library/sleep-mask.svg` |

## Notes

- 白色 Cloudling 状态已经包含浅色背景边缘适配系统。
- 404 error 状态故意保留乌云材质，不套白色 Cloudling 主体。
- 偏好记录：保留强原始概念，再在概念内部精修。不要把代码眼、放大镜代码流、强 notification 能量替换成通用极简动效。
- `states/typing-code-eyes-v2.svg.html` 是被否掉的方向：重设计太多、过度规整，削弱原版 typing 性格。

---

## File: assets/source/cloudling-codex-pet/README.md

# Cloudling 实验目录

实现路线: **全 SVG + JS 驱动** (2026-04-26 锁定, 详见根目录 `CLAUDE.md` 接入方式段). 现有 demo 微调后即生产代码.

## `confirmed/` 最新确认内容

`confirmed/` 是当前干净交付面: 已确认状态统一放在 `confirmed/states/`, 共用资产统一放在 `confirmed/library/`. root / `wip/` / `library/` 保留原始磨制位置和历史上下文, 不作为唯一入口.

2026-04-27 精修确认:

- **`confirmed/states/thinking-lens-code-v2.svg.html`** — thinking 精修版. 保留"放大镜里跑代码", 但改成轻玻璃镜片 + 镜片内代码扫描流; 删除中心 pulse 圆、 transit 曲线和眨眼矩形补丁.
- **`confirmed/states/typing-original-polish-v2.svg.html`** — typing 精修版. 保留原版 190° 卡顿旋转、随机代码眼、角速度联动; 只微调 glyph 线重/比例、token 权重和 90ms soften.
- **`confirmed/states/notification-alert-polish-v2.svg.html`** — notification 精修版. 保留强提醒和摇晃, 改成暖色破碎冲击弧 + rim flash; 删除头顶 badge / 感叹号气泡.

2026-04-28 过渡确认:

- **`confirmed/states/idle-to-sleeping-v1.svg.html`** — idle → sleeping 过渡确认版. day/night toggle 渐显后触发 Mario bump, 云宝从 1.39s 接触点开始逐渐压扁并回弹; 使用原始 `CLOUD_D` 轮廓采样做 soft-body morph, 去掉拉绳三角和碰撞横线, 收尾戴帽和眼罩进入 sleeping.
- **`confirmed/states/carrying-eat-cloud-v5.svg.html`** — carrying / 吃云确认版. 大小不同食物云贴边进入, Cloudling 侧边外鼓包裹并快速同化, 融完后 smile + duang 回弹.
- **`confirmed/states/happy-burst-white-rainbow-ring-v6.svg.html`** — happy burst 精修确认版. 白色 runner / 柔和彩虹能量环, 保持 Cloudling 本体第一视觉.
- **`confirmed/states/happy-burst-rainbow-ring-v5.svg.html`** — happy burst 彩色彩虹环对照确认版, 保留用于比较 V6 克制方向.

2026-04-29 状态确认:

- **`confirmed/states/conducting-task-sparks-v5.svg.html`** — conducting 确认版. 4 颗童话四角 task sparks 被云宝眼神依次点名、提亮并归位; V5 定版, V6 收束/球化方向不作为最终稿.
- **`confirmed/states/building-shapeshift-loop-v1.svg.html`** — building 确认版. 云宝 → 终端 → 模块方块 → 显示器 → 彩色 M 信封 → 微笑云宝循环; 每次先眨眼, 闭眼时换形, 再睁眼落稳.
- **`confirmed/states/sweeping-context-cards-orbit-loop-v1.svg.html`** — sweeping 确认版. 透明 context cards 从左侧进入, 保持水平绕过云宝前方, 切到身后整齐垫入 stack; 三张后 stack 压缩淡出, 云宝保留呼吸和眼神跟随.
- **`confirmed/states/idle-to-dozing-soft-slump-v1.svg.html`** — idle → dozing 过渡确认版. 正常 idle 胶囊眼 → 两次半闭打盹并睁回 → 自然闭眼薄眼缝过渡 → 软塌下移进入小憩; 默认节奏 9.03s, 带轻呼吸和 timing/body 调参拉杆.

2026-04-30 过渡确认:

- **`confirmed/states/dozing-to-sleeping-v1.svg.html`** — dozing → sleeping 过渡确认版. 小憩 hold 慢吸气回圆, 睡帽轻落, 眼罩滑下接管闭眼, 末帧对齐 `sleeping-loop-v1` 首帧.
- **`confirmed/states/sleeping-to-idle-v1.svg.html`** — sleeping → idle 过渡确认版. day/night toggle 从 night 轻切回 day, 散射短线提示唤醒; 眼罩右上滑走、睡帽左上滑走, 露出参考 dozing 的本体闭眼后撑开成 idle 胶囊眼, 末帧对齐 `idle-follow`.
- **`confirmed/states/dozing-loop-v1.svg.html`** — dozing / 打盹循环确认版. 软塌闭眼 hold + 明确呼吸回圆/塌回 + 低频睡沉点头; 不加帽子、眼罩或 Z 字.

2026-04-30 Mini Mode 确认:

- **`confirmed/states/mini-crabwalk-soft-scoot-v1.svg.html`** — mini-crabwalk 确认版. 不是 mini 最终待机态, 而是右键进入 Mini Mode 时窗口挪向屏幕边缘的软弹赶路动画; SVG 内本体只做小幅 scoot / hop / squash + 轻滚角, 身后三团小云尘保留 V1 气质并已修正浅色模式可读性.
- **`confirmed/states/mini-idle-follow-b-v1.svg.html`** — mini-idle 确认版. B 方案可见中心内收 + 正眼, 动态沿用正常 idle 的跟随 / 呼吸 / 眨眼 / 眼色流动 / 距离 scale; 正式文件保留完整 Cloudling, 不内置裁切线或 ghost.
- **`confirmed/states/mini-enter-roll-in-v1.svg.html`** — mini-enter 确认版. 从屏幕边缘外简单滚入 + 软弹 settle + 睁眼接 mini-idle B; 起点在 WIP 裁切模拟中一点不露, 正式文件保留完整 Cloudling.

2026-05-01 Mini Mode 确认:

- **`confirmed/states/mini-happy-full-ring-v1.svg.html`** — mini-happy 确认版. 选回 V1 完整 full-ring 完成反馈: 白芯 runner + 彩虹环 + 少量 sparkle, 锁定参数 duration 3.6s / ringPower 1.25 / edgeBias 0.30 / bounce 0.040; 正式文件保留完整 Cloudling, 不内置裁切线或 ghost.
- **`confirmed/states/mini-alert-notification-v1.svg.html`** — mini-alert 确认版. 选 WIP punchy 档, 保留强摇晃 + 暖色破碎冲击弧 + rim flash; 锁定参数 duration 2.6s / shakeAngle 16deg / shakeFreqHz 7Hz / jumpY 0.52 / squash 0.046 / pulseScaleEnd 1.62 / rimPower 1.12; 正式文件保留完整 Cloudling, 不内置裁切线或 ghost.
- **`confirmed/states/mini-peek-hover-pose-v1.svg.html`** — mini-peek 确认版. runtime 负责 25px / 200ms 窗口探出, SVG 做 hover 后眼睛从 mini-idle 基准 (2.20×4.65, centers 7.75/12.15) morph 到正常 idle-follow 基准 (2.60×5.00, centers 9/15) + 身体 duangduang 衰减回弹; 锁定参数 eyeReturnDur 0.24s / idleEyeMax 0.50 / settleTx -0.22 / settleScale 1.012 / duangPower 1.16 / duangDur 1.12s / rimPower 1.30; 正式文件保留完整 Cloudling, 不内置裁切线或 ghost.
- **`confirmed/states/mini-enter-sleep-closed-in-v1.svg.html`** — mini-enter-sleep 确认版. DND 下闭眼入场, 复用 mini-enter 的起点完全不露和 duration probe, 但改成轻滑入 + 小幅困倦 settle; 锁定参数 duration 1.45s / startX 15.8 / rollDeg 8deg / overshoot 0.55 / squash 0.035 / eyeDrop 0.12; 正式文件保留完整 Cloudling.
- **`confirmed/states/mini-sleep-closed-breath-v1.svg.html`** — mini-sleep 确认版. DND mini 休眠循环, 接 mini-enter-sleep 末帧; 低频呼吸 + 睡沉点头 + 左侧 zzz lifecycle, 锁定参数 period 6.4s / breath 0.050 / nodDepth 0.40 / zSize 1.90 / zStart 1.40,9.25 / zInterval 2.05s; 正式文件保留完整 Cloudling.
- **`confirmed/states/mini-typing-thinking-left-eye-v1.svg.html`** — mini-working / mini-typing 可选态确认版. 沿用 thinking 放大镜代码流, 镜片固定左眼且放大到 1.14, 右眯眼移到镜片边缘, 镜片内持续纯代码变化, 底眼偶尔轻眨; 正式文件保留完整 Cloudling, 不内置裁切线或 ghost.

## 锁定的状态 (confirmed 接入清单)

打开浏览器即可看锁定数值。详细 final spec 见 `docs/cloudling/specs/`，总进度见 `docs/cloudling/state-progress.md`。

- **`confirmed/states/idle-follow.svg.html`** — idle (eye-follow), 鼠标跟随 + 距离 scale + 流动渐变。✅ 锁定 2026-04-25, V3 描边升级 2026-04-26
- **`confirmed/states/long-idle-cloud-bush-peek-v1.svg.html`** — idle-reading / long-idle, 双层暖云屏障 + 两边轮流探头 + 问号。✅ 锁定 2026-04-28
- **`confirmed/states/typing-original-polish-v2.svg.html`** — typing, 原版代码眼低侵入精修: 190° 卡顿旋转 + 8 token 描边代码符号 + 两眼互斥。✅ 精修锁定 2026-04-27
- **`confirmed/states/thinking-lens-code-v2.svg.html`** — thinking, 轻玻璃放大镜 + 镜片内代码扫描流 + 左右眼循环。✅ 精修锁定 2026-04-27
- **`confirmed/states/notification-alert-polish-v2.svg.html`** — notification, 暖色破碎冲击弧 + 强摇晃 + rim flash, 无 badge / 感叹号气泡。✅ 精修锁定 2026-04-27
- **`confirmed/states/carrying-eat-cloud-v5.svg.html`** — carrying / 吃云, 侧边外鼓包裹 + 快速同化 + duang 回弹。✅ 锁定 2026-04-28
- **`confirmed/states/happy-burst-white-rainbow-ring-v6.svg.html`** — happy burst / attention, 白色 runner / 柔和彩虹能量环 + smile 收尾。✅ 精修锁定 2026-04-28
- **`confirmed/states/conducting-task-sparks-v5.svg.html`** — conducting, 4 颗 task sparks 眼神点名归位 + 本体呼吸/轻摇/soft morph。✅ 锁定 2026-04-29
- **`confirmed/states/building-shapeshift-loop-v1.svg.html`** — building, 云宝连续变身为终端/模块/显示器/彩色 M 信封, 用眨眼承接每次换形。✅ 锁定 2026-04-29
- **`confirmed/states/sweeping-context-cards-orbit-loop-v1.svg.html`** — sweeping / PreCompact, 水平 context cards 绕过云宝前方并垫到身后, 3 张 stack 后压缩淡出。✅ 锁定 2026-04-29
- **`confirmed/states/cloud-plane-orbit-explore.svg.html`** — juggling / 激进彩蛋槽 2, 纸飞机像小行星绕飞。✅ 锁定 2026-04-26, 2026-04-29 复用为 juggling
- **`confirmed/states/error-thundercloud-loop-v9-tuned.svg.html`** — error / 404, 稳定漫反射乌云 + C 眼 + 拧毛巾压扁 + 雨势同步。✅ 锁定 2026-04-26
- **`confirmed/states/sleeping-loop-v1.svg.html`** — sleeping, 戴帽 + 眼罩 + 呼吸 / 帽子 sway / Z 字三层叠循环。✅ 锁定 2026-04-28
- **`confirmed/states/idle-to-sleeping-v1.svg.html`** — idle → sleeping 过渡, day/night toggle Mario bump + 原轮廓 soft-body 压扁回弹 + sleeping 装扮收尾。✅ 锁定 2026-04-28
- **`confirmed/states/idle-to-dozing-soft-slump-v1.svg.html`** — idle → dozing, 两次半闭/睁回模拟真人打盹, 最终自然闭眼后软塌下移, 轻呼吸保留活物感。✅ 锁定 2026-04-29
- **`confirmed/states/dozing-loop-v1.svg.html`** — dozing / 打盹循环, 通过云体轮廓、整体缩放/下沉、闭眼弧线和 halo 共同承担呼吸感。✅ 锁定 2026-04-30
- **`confirmed/states/dozing-to-sleeping-v1.svg.html`** — dozing → sleeping, 小憩 hold 慢吸气回圆后睡帽/眼罩自然落定, 末帧接 sleeping loop。✅ 锁定 2026-04-30
- **`confirmed/states/sleeping-to-idle-v1.svg.html`** — sleeping → idle, 日夜开关切回 day 后眼罩/睡帽滑走, 本体闭眼露出并撑开到 idle 胶囊眼。✅ 锁定 2026-04-30
- **`confirmed/states/mini-crabwalk-soft-scoot-v1.svg.html`** — mini-crabwalk / 边缘软弹小挪步, 右键进入 Mini Mode 时配合壳子横移到屏幕边缘; V1 三团小云尘 + long-idle 同款宽眼变化。✅ 锁定 2026-04-30
- **`confirmed/states/mini-idle-follow-b-v1.svg.html`** — mini-idle / 贴边待机, B 方案正眼内收 + eyeMax 1.85 / maxRotDeg 13 / distMaxScale 1.09 / flowAmp 4.0 / recenter 0.15s; 裁切由运行时窗口层负责。✅ 锁定 2026-04-30
- **`confirmed/states/mini-enter-roll-in-v1.svg.html`** — mini-enter / 贴边入场, 从完全不露到滚入 settle, duration 1.25s / startX 15.8 / rollDeg 28 / overshoot 1.2 / squash 0.07 / eyeOpen 0.64。✅ 锁定 2026-04-30
- **`confirmed/states/mini-peek-hover-pose-v1.svg.html`** — mini-peek / hover 探出反应, runtime 做 25px / 200ms 探出, SVG 做眼睛 0.24s 从 mini-idle 基准 morph 到正常 idle-follow 眼形/间距 + 身体 1.12s duangduang 回弹, mini eye 2.20×4.65 centers 7.75/12.15 -> idle eye 2.60×5.00 centers 9/15, settleScale 1.012 / duangPower 1.16。✅ 锁定 2026-05-01
- **`confirmed/states/mini-enter-sleep-closed-in-v1.svg.html`** — mini-enter-sleep / DND 闭眼入场, 从完全不露到闭眼轻滑入, duration 1.45s / rollDeg 8deg / overshoot 0.55 / squash 0.035。✅ 锁定 2026-05-01
- **`confirmed/states/mini-sleep-closed-breath-v1.svg.html`** — mini-sleep / DND 贴边休眠循环, 首帧接 mini-enter-sleep 末帧, breath 0.050 / nodDepth 0.40 / 左侧 zzz lifecycle。✅ 锁定 2026-05-01
- **`confirmed/states/mini-happy-full-ring-v1.svg.html`** — mini-happy / 完成反馈, 完整 full-ring V1 + duration 3.6s / ringPower 1.25 / edgeBias 0.30 / bounce 0.040, 裁切由运行时窗口层负责。✅ 锁定 2026-05-01
- **`confirmed/states/mini-alert-notification-v1.svg.html`** — mini-alert / 通知提醒, punchy 强摇晃 + 暖色破碎冲击弧 + rim flash, duration 2.6s / shakeAngle 16deg / jumpY 0.52 / squash 0.046。✅ 锁定 2026-05-01
- **`confirmed/states/mini-typing-thinking-left-eye-v1.svg.html`** — mini-working / mini-typing 可选态, thinking 放大镜固定左眼 + 纯代码流 + 底眼轻眨, lensScale 1.14 / rightEyeX 14.85 / sweep 1.72s / codeSteps 9。✅ 锁定 2026-05-01
- **`confirmed/states/drag-react-v3.svg.html`** — drag reaction, 中心自旋 wobble + 呼吸 + ＞＜眼。✅ 锁定 2026-04-29

## `library/` 跨状态共用资产

后续状态磨制时**先看这里**, 别重新发明.

- **`eye-shape-library.svg.html`** — 14 种眼睛 (情绪 6: capsule/微笑/大笑/闭眼线/圆点/X · 代码符号 8: `> < _ : = + / \`). 否决: 心形/星形 (太 emoji)
- **`cloud-morph-explore.svg.html`** — 云朵球化 morph 探索, **t=70% sweet spot 已锁定** (彩蛋槽 2 配套). 跨状态视觉原则: morph 70-90% 准形态比 100% 完美形态精致
- **`draft-rubber-white.svg`** — V2 视觉定稿静态参考 (无动画, 软橡胶白 + 紫蓝豆豆眼)

## `wip/` 进行中 / 历史备份

- **`cloud-plane-orbit-explore.svg.html`** — 云朵球化 + 纸飞机小行星轨道调参 demo. 纯循环 orbit, 鹿鹿参数: rx 17.8 / ry 4.9 / tilt -13 / start 0 / rotOffset 123 / 蓝紫清晰; 短尾迹提示轨道, 左右端点放松成云 / 前后掠过球化, 纸飞机假 3D 翻面, idle 眼睛流动 + 眨眼
- **`notification-pulse-explore.svg.html`** — notification 2026-04-26 版. 保留原 ABC 节奏: A 缓扩散、B 6Hz 摇晃 + 密集短弧、C 回落. 2026-04-27 已由 `confirmed/states/notification-alert-polish-v2.svg.html` 精修替代.
- **`error-thundercloud-loop-v9-tuned.svg.html`** — 404 error 锁定版来源 / 调参备份。当前接入文件已提升到 `confirmed/states/error-thundercloud-loop-v9-tuned.svg.html`. 默认参数来自鹿鹿截图: 4.0s loop, 拧从 0.53 开始, 压扁用时占比 0.60, 呼吸幅度 0.070, 雨线数量 8, 雨线斜移 0.40. 保留 v8 稳定材质, 不让乌云颜色/透明度随大雨闪.
- **`error-thundercloud-loop-v1~v8*.svg.html` / `error-thundercloud-*.svg`** — 404 乌云探索过程: 静态崩溃云、无闪电方向、循环拧毛巾、v6 平滑雨线、v7 雨幕对照、v8 冻结材质排查闪频.
- **`paper-plane-face-debug.svg.html`** — 纸飞机单独面片调试页. 顶点 A-F / 面 P1-P5 标注 + checkbox/solo; P3(backFace) 已判定多余并默认关闭
- **`thinking.svg.html`** — thinking v5 锁定版暂存位置, 后续整理时提升到 root
- **`thinking-magnifier-static.svg.html` / `thinking-v3-clip-backup.svg.html` / `thinking.svg.v4-lid-blink.html`** — thinking 镜片方向的静态稿与历史备份, 用来追溯 v5 决断
- **`sleeping-decoration-explore.svg.html`** — sleeping (装扮路线 A: 帽 + 抱枕变体, 纯装扮无粒子. 鹿鹿 2026-04-26 拍板)

## `_archive/` 历史归档

| 子目录 | 内容 | 价值 |
|---|---|---|
| **early-static/** | V2 视觉定稿前的草稿 (flat-white / cloud-explorer / preview screenshot) | 视觉决断历程 |
| **exploration/** | idle 跑偏方向 (eye "诶?" 反应 / 身体呼吸 4 cell / path 法向噪声"幽灵") | 学习教训 — 看到这些方向被否决的原因 |
| **canvas-prototype/** | idle Canvas 调参版 (rotate+scale Canvas) | "调参 ≠ 最终交付"的分工教训 |
| **svg-iteration/** | SVG 早期版本 (idle V1/V2, typing V1/V2/V3) | 状态迭代记录 (跑偏版归档而非删除) |
| **happy/** | happy 磨制过程 4 个探索 (弧形眼锁定 / 空间 B/D / 颜色 4 选 / 节奏累积 vs 水波纹) | happy 决断历程, 4 个对照 demo 都跑得起来 |

## 关键决断历程 (跨状态适用元教训)

锁定多个状态后沉淀的元教训, 后续磨任何状态都适用:

1. **抽象描述节奏没用要看动起来** — 鹿鹿"想象不出来"后立马做能动对照 demo, 节奏只能看不能说 (happy 元教训)
2. **仓促感来自结构, 不是总时长** — V1 (4 段 2.2s) 太快是收尾塞 3 件事; V4 (7 段 2.0s) 同时长但完美. 时长跟结构耦合, 别先调时长 (happy 元教训)
3. **小活泼 ≠ 抖** — 4-8s 缓周期 + 5-10% 微妙幅度 + 眼睛主导身体响应. 软橡胶白质感最忌高频抖, 1Hz+ 必鬼畜 (idle / 弧形眼 元教训)
4. **调参 ≠ 最终交付** — STLabs Canvas 工具链当**调参工具**好用 (调出锁定数值), 调好迁 SVG. 这是分工 (idle 元教训)
5. **token / 视觉元素选型要看视觉语义不光看几何** — `{ }` 否决因"太喜感"跟苹果精致风冲突, `*` 否决因"4 线密集偏闹". 跟苹果精致风原则一致 (typing / eye-shape-library 元教训)
6. **morph 70-90% 准形态比 100% 完美形态精致** — 球化 t=70% 验证. 后续任何 morph 类动作 (拓扑挤压 / 404 / yawn) 都先试 70-90% 不要默认 100% (跨状态原则, 已写进 CLAUDE.md 宪法 §2 脚注)
7. **材质动画和动作动画要拆开排查** — 404 大雨段闪频不是单纯雨线问题, 乌云颜色/透明度/filter 同步跳也会造成闪屏. 先冻结材质, 只留形变和雨势, 再决定要不要恢复颜色变化.
8. **节奏对时不要重写时间线** — notification 原版 ABC 节奏成立, 失败点是视觉语言. 保留强提醒和摇晃, 视觉从"广播波 / badge"精修成暖色破碎冲击弧 + rim flash, 比重做动画更稳.
9. **鹿鹿偏好: 精修胜过大改** — typing 废案 `typing-code-eyes-v2` 证明: 过度规整会削掉原版性格. 正解是保留有趣设定 (代码眼 / 放大镜跑代码 / 强提醒), 在原设定内部修线重、材质、权重和多余装饰.

---

## File: assets/source/agent-icons/README.md

# Agent Icon Sources

Runtime agent icons live in `assets/icons/agents/` and should be exported as 64x64 PNG files named with the agent id, for example `kiro-cli.png`.

This directory stores editable or higher-resolution source assets used to generate those runtime PNG files. Prefer official SVG or high-resolution sources. When an official source is not available yet, keep the best existing asset here as a fallback and replace it when a better source is available.

If both PNG and SVG sources exist for the same agent, the export script uses the PNG source first because Electron's SVG rasterization support is limited. Keep the SVG next to it as the editable source of record. After editing the SVG, refresh the same-name PNG source first, then run `npm run export-agent-icons -- --accept-svg-sources`. The script checks both the selected source hashes and the normalized SVG hashes in `source-manifest.json`, so stale or replaced sources do not silently ship.

The exporter preserves aspect ratio and centers visible artwork inside a 56x56 safe area on a transparent 64x64 canvas. Transparent sources are cropped to their alpha bounds before fitting. Opaque sources keep their complete canvas; the exporter never guesses at background removal.

Sources that would disappear against one of the application's light or dark surfaces use a recorded neutral contrast tile. Their artwork is fitted inside a 40x40 area on a centered 56x56 tile so the same runtime PNG remains identifiable in both color schemes.

An explicitly approved legacy fallback may use `passthrough` export mode to preserve its existing 64x64 PNG byte-for-byte. This exception must be recorded in `source-manifest.json` and covered by an exact-hash test.

When a legacy fallback is selected instead of newly supplied artwork, keep the new canonical PNG/SVG candidates in this directory and record them under the selected source's `archivedSources` manifest entry.

Each generated runtime file is bound to its selected source through `outputs` records in `source-manifest.json`. The exporter records both the runtime SHA-256 and the selected source SHA-256 only after every Agent icon has generated successfully.

Run the export script after changing sources:

```bash
npm run export-agent-icons
```

The runtime folder should not mix canonical source SVGs with generated PNGs. SVG files belong here unless a future runtime requirement needs them in `assets/icons/agents/`.

---

## File: docs/investigations/codex-subagent-session-meta.md

# Codex Subagent Session Metadata

Date: 2026-05-01

## Local Samples

Read from `C:\Users\Ruller\.codex\sessions\2026\05\01\*.jsonl`.

Root session first-line shape:

```json
{
  "type": "session_meta",
  "payload": {
    "source": "cli",
    "originator": "codex-tui",
    "cli_version": "0.128.0"
  }
}
```

Subagent session sample:

```json
{
  "type": "session_meta",
  "payload": {
    "source": {
      "subagent": {
        "thread_spawn": {
          "parent_thread_id": "019de173-e4a3-72a1-9da3-a28fcb3e43e0",
          "depth": 1,
          "agent_path": null,
          "agent_nickname": "Newton",
          "agent_role": "explorer"
        }
      }
    },
    "agent_role": "explorer",
    "agent_nickname": "Newton",
    "originator": "codex-tui"
  }
}
```

The subagent sample was `rollout-2026-05-01T12-16-50-019de1c0-ed8e-73b0-992d-10972022b4ca.jsonl`.

## Conclusions

- `payload.source.subagent` is present in the local subagent sample and is the primary signal.
- `payload.agent_role` is present on the same subagent sample and is a secondary signal.
- Root samples observed on 2026-04-28 through 2026-05-01 use `payload.source: "cli"` and do not carry `agent_role`, `agent_id`, `agent_type`, or `parent_session_id`.
- The subagent `session_meta` first line was 22187 UTF-8 bytes because `base_instructions` is embedded. An 8KB read is not enough; hook-side metadata reading must read in chunks up to a bounded cap and stop at the first newline.
- No local hook stdin dump was available. Current OpenAI Codex hooks documentation (`https://developers.openai.com/codex/hooks`) lists common hook input fields such as `session_id`, `transcript_path`, `cwd`, `hook_event_name`, and `model`, but does not document a root/subagent role field in the hook payload, so Clawd reads `transcript_path` metadata for the hook state path.

## Implementation Notes

- Treat unknown fields as `unknown` and fail open as root/interactive behavior.
- Do not infer subagents from cwd or timing.
- `/permission` must classify subagents, but role and interactivity are separate concerns.
  **PR #448's permission behavior was superseded on 2026-07-31.** Codex uses `headless:true`
  on subagent state sessions to keep background child activity out of HUD/focus/completion
  priority; that presentation marker must not suppress an official `PermissionRequest` from a
  visible Agent thread. `buildPermissionBody` therefore still carries `codex_session_role` (plus
  the child nickname/parent provenance). The interactive exception is limited to the resolved
  Codex adapter plus audited CLI/Desktop originators; `codex_exec`, unknown originators, and an
  explicit or derived `headless:true` stay on no-decision → native fallback, including when the
  permission is the first event and no in-memory session exists yet. Ordinary headless
  sessions still use the existing session gate. Interactive child requests enter the same
  bubble/automation chokepoint as their parent. The state-path guidance above is unchanged.

---

## File: docs/investigations/permission-hook-fail-deny-investigation.md

# PermissionRequest HTTP hook fail-deny

> **状态**：已定位为 Claude Code 上游 bug，跟踪 [anthropics/claude-code#46193](https://github.com/anthropics/claude-code/issues/46193)。
> **影响**：桌宠没在跑时，Claude Code 调用 Edit/Write/Bash 等需要权限确认的工具会被自动 deny，用户看到 "tool use was rejected"。
> **Clawd 侧动作**：**不兜底**，等上游修。临时方案 = 开桌宠。

## TL;DR

- CC 2.1.100 给 Edit/Write/Bash 等所有需要权限的工具都发 `PermissionRequest` hook（用 `permission-debug.log` 实证 `tool=Write`）
- CC 官方文档承诺 HTTP hook 连接失败 → non-blocking → execution continues（已 WebFetch 核实原文）
- 实际行为：桌宠没在跑 → 端口 ECONNREFUSED → CC silently denies tool call → 用户看到 "tool use was rejected"
- **实际行为违反 CC 自己的文档** → 这是 CC bug，不是 Clawd 应该兜底的事

## 现象

桌宠 Electron 主进程**没在跑**时，Claude Code 在任意工作目录里调用 Edit / Write / Bash 等"需要权限确认"的工具，会立刻被自动拒绝，返回如下消息：

> The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file).

用户**没有**手动点击拒绝。Claude Code 把"hook 失败"当成了"用户拒绝"。

## 根因

CC 2.1.100 现在给 Edit/Write/Bash 等所有需要权限的工具都发 `PermissionRequest` hook（matcher 与 `PreToolUse` 共享，覆盖所有工具名）。当 hook 配置为 HTTP 类型且端口无人 listen 时，CC 收到 `ECONNREFUSED` 后会 silently deny tool call，而不是按文档承诺的 non-blocking 行为 fall through 到内置 chat prompt。

这违反 CC 自己的 hook 文档（详见下方"证据链"）。Clawd 无锅。

## 证据链

### 1. CC 给 Edit/Write 发 PermissionRequest（实证）

`%APPDATA%/clawd-on-desk/permission-debug.log` 行 `2026-04-10T10:56:59.529Z`：

```
[2026-04-10T10:56:59.529Z] showing bubble: tool=Write session=807e3e37-...
```

`tool=Write` 走了 `/permission` HTTP 端点 → 证明 CC 现在确实给 Write 发 `PermissionRequest`（而不是只给 Bash）。

### 2. CC 文档承诺 HTTP hook 失败 non-blocking

来源：https://code.claude.com/docs/en/hooks（已 WebFetch 核实，2026-04-10）

> Error handling differs from command hooks: non-2xx responses, connection failures, and timeouts all produce non-blocking errors that allow execution to continue. To block a tool call or deny a permission, return a 2xx response with a JSON body containing `decision: "block"` or a `hookSpecificOutput` with `permissionDecision: "deny"`.

并且 HTTP response handling 表格里明确：

> **Connection failure or timeout**: non-blocking error, execution continues

PermissionRequest matcher 覆盖范围（同一份文档）：

> Matches on tool name, same values as PreToolUse.

PreToolUse matcher 接受 `Bash`, `Edit|Write`, `mcp__.*` 等所有工具名。

### 3. 矛盾：实际行为是 fail-closed deny

桌宠没在跑 → 端口 23333 ECONNREFUSED → CC 拒绝 tool call。这与 (2) 矛盾。

## 排除掉的方向（节省未来调查时间）

| 方向 | 排除依据 |
|------|----------|
| `hooks/install.js` 写错了 url/timeout | 历史无回归 commit；桌宠开着时 hook 完全正常工作 |
| timeout 单位从秒变成毫秒 | 文档明确写秒；如果是单位问题桌宠开着也会失败，但日志大量正常 ack |
| `settings.json` json schema 解析错误 | json 合法且其他 hook 段都正常工作 |
| `80a1670` (DND fail-deny 修复) 的回归 | 那个修复改的是桌宠**运行中且 DND** 的代码路径，桌宠没开时根本到不了那段代码 |
| `091bb59` (移除 PreToolUse HTTP hook for Edit/Write) 的回归 | 091bb59 在 CC 旧版本下是对的；是 CC 后来升级把 Edit/Write 也纳入 PermissionRequest |

## 复现

1. 关闭桌宠（菜单退出 / kill electron 进程）
2. 确认 `127.0.0.1:23333` 无监听：`netstat -ano | grep 23333`
3. 在任意工作目录开 Claude Code session
4. 让 Claude 调用 Edit / Write / Bash 工具
5. 观察：立刻被 deny

恢复：开桌宠 → 23333 监听 → hook 正常 → bubble 弹出 → 用户决定。

## 临时绕过（按推荐度）

1. **开桌宠**（已验证）—— 鹿鹿日常本来就开着，最简单
2. **临时屏蔽 hook**：把 `~/.claude/settings.json` 里的 `PermissionRequest` 段重命名为 `_PermissionRequest`（key 改个名让 CC 找不到），走默认 Y/N 询问。**之后必须改回来**，否则桌宠权限气泡整体失效

## 上下文（结案）

最初由鹿鹿 2026-04-10 发现：当时桌宠没开，Edit 调用一直被自动 deny，本以为是 Clawd 的 bug。诊断过程：
- Claude 用 `permission-debug.log` 实证了 CC 给 Write 发 PermissionRequest
- Codex 在 review 中找到了 CC 文档的 non-blocking 承诺
- Claude WebFetch 核实文档原文（两段 quote）
- 搜了 anthropics/claude-code 18 个相关搜索词，确认没人报过
- 鹿鹿决定发 issue (#46193)，不在 Clawd 侧加 workaround

## 未来要做的事（CC 修好后）

- [ ] 监控 anthropics/claude-code#46193 的 status
- [ ] CC 修了之后：
  - 删除 `README.md` / `README.zh-CN.md` 里 Known Limitations 表格的对应行
  - 把这个文档归档（移到 `docs/archive/` 或在标题加 RESOLVED）
  - 顺手更新 `hooks/install.js:248-250` 那条过时注释（"Edit/Write permissions are handled by Claude Code's own permission mode — not our hook"），写明历史脉络

## 不要做的事

不要在 Clawd 侧加 hook fail-deny 的 workaround：
- ❌ command hook wrapper（包一层脚本检测端口）
- ❌ quit-time unregister + start-time register（崩溃路径漏）
- ❌ 强制 auto-start hook 拉起 Electron（用户体验差 + 冷启动竞态）

这些都是在帮 CC 擦屁股。CC 修好后变成废代码 + 维护负债。

---

## File: docs/guides/codewhale-setup.md

# CodeWhale 适配 Clawd on Desk — 完整开发文档

> 基准：Clawd on Desk v0.8.1（fork from rullerzhou-afk/clawd-on-desk）
> 日期：2026-06-02 ~ 2026-06-03；review 修复：2026-06-11
> 状态：**Phase 1 完成，review 反馈已修复，Phase 2 搁置**

---

## 目录

1. [目标](#1-目标)
2. [已实现功能（Phase 1）](#2-已实现功能phase-1)
3. [文件改动清单](#3-文件改动清单)
4. [新增文件详解](#4-新增文件详解)
5. [修改文件详解](#5-修改文件详解)
6. [事件映射表](#6-事件映射表)
7. [已知限制与未实现功能](#7-已知限制与未实现功能)
8. [常见问题排查](#8-常见问题排查)
9. [使用说明](#9-使用说明)

---

## 1. 目标

让 Clawd on Desk（桌面宠物）能够感知并动画化 CodeWhale 的运行时状态。CodeWhale 是一个基于 DeepSeek API 的 AI 编程代理（TUI/CLI），运行在终端中。

核心目标：
- CodeWhale 开启/结束会话 → 螃蟹 idle/sleeping
- 用户输入 prompt → 螃蟹 thinking
- 调用工具（读文件、写文件、执行命令等）→ 螃蟹 working
- 切换模式/压缩上下文 → 螃蟹 sweeping/attention
- 出错 → 螃蟹 error

---

## 2. 已实现功能（Phase 1：State-Only 集成）

### 2.1 状态感知

螃蟹根据 CodeWhale 的生命周期事件自动切换动画：

| CodeWhale 事件 | 螃蟹动画 | 触发时机 |
|---|---|---|
| `session_start` | idle（空闲） | 启动 CodeWhale 或新建会话 |
| `session_end` | sleeping（睡觉） | 退出 CodeWhale |
| `message_submit` | thinking（思考泡泡） | 用户输入 prompt |
| `tool_call_before` | working（打字/建造） | 工具调用前 |
| `tool_call_after`（成功） | working | 工具调用成功 |
| `tool_call_after`（失败） | error | 工具调用失败 |
| `mode_change`（compact） | sweeping（扫地） | 上下文压缩 |
| `mode_change`（其他） | attention（感叹号） | agent/plan/yolo 切换 |
| `on_error` | error | CodeWhale 发生错误 |

### 2.2 按需安装与同步

- 全新安装默认不会写入 CodeWhale hooks；需要本机 CodeWhale 追踪时，先到 **Settings → Agents → CodeWhale → Install** 安装并启用集成
- 安装且启用后，Clawd 启动时会继续同步 7 个 hooks 条目到 `~/.codewhale/config.toml`
- Settings / Doctor 的 Fix / Repair 会手动重新同步；`npm run install:codewhale-hooks` 仍可用于调试或预注册
- 卸载支持（`npm run uninstall:codewhale-hooks`）

### 2.3 会话标签优化

- HUD 显示 `CodeWhale` 而非工作空间目录名
- 稳定 session ID 缓存：切换模式等无 session id 的事件不会创建重复标签

---

## 3. 文件改动清单

### 3.1 新增文件（4 个）

| 文件 | 行数 | 用途 |
|---|---|---|
| `agents/codewhale.js` | ~40 | Agent 元数据配置 |
| `hooks/codewhale-hook.js` | ~210 | 生命周期 hook 脚本（事件翻译 + HTTP POST） |
| `hooks/codewhale-install.js` | ~350 | 安装脚本（读写 `~/.codewhale/config.toml`） |
| `assets/icons/agents/codewhale.png` | — | 64×64 runtime agent PNG |

### 3.2 修改文件（核心）

| 文件 | 改动行数 | 改动内容 |
|---|---|---|
| `agents/registry.js` | +2 | require + AGENTS 数组注册 |
| `src/prefs.js` | +1 | agents 默认值白名单 |
| `src/integration-sync.js` | +18 | `syncCodewhaleHooks()` 自动同步函数 |
| `src/server-agent-id.js` | +1 | `HOOK_SOURCE_AGENT_IDS` 注册 |
| `src/settings-actions-agents.js` | +1 | `AUTO_REPAIRABLE_AGENT_IDS` |
| `src/settings-agent-order.js` | +1 | `NON_COLLAPSIBLE` 排序 |
| `src/i18n.js` | +5 | 5 种语言的 eventSource 翻译键 |
| `hooks/codewhale-install.js` | 多行 | 幂等注册、legacy orphan cleanup、Windows command quoting、CodeWhale config path resolver |
| `hooks/codewhale-hook.js` | 多行 | session_title + 稳定 session id + session 缓存 + 可测试入口 |
| `src/doctor-detectors/agent-descriptors.js` | 多行 | CodeWhale descriptor |
| `src/doctor-detectors/agent-integrations.js` | 多行 | `codewhale-hooks-toml` Doctor 检查 |
| `hooks/cleanup-integrations.js` | 多行 | managed cleanup 接入 CodeWhale |
| `package.json` | 1 行 | 保留 `npm start` 的 sidecar preflight |

---

## 4. 新增文件详解

### 4.1 `agents/codewhale.js` — Agent 配置

```js
module.exports = {
  id: "codewhale",
  name: "CodeWhale",
  processNames: { win: ["codewhale.exe"], mac: ["codewhale"], linux: ["codewhale"] },
  eventSource: "hook",
  eventMap: { ... },         // snake_case → PascalCase + 动画状态
  capabilities: {
    permissionApproval: false, // Phase 2 需 CodeWhale 源码改动
    sessionEnd: true,
    subagent: false,
  },
  pidField: "codewhale_pid",
};
```

关键字段：
- `eventSource: "hook"` — 告诉 Clawd 此 agent 通过 hooks 感知事件（区别于 `"log-poll"` / `"plugin-event"` / `"extension"`）
- `capabilities.sessionEnd: true` — 会话结束时 Clawd 显示 sleeping 动画而非隐藏
- `permissionApproval: false` — Phase 2（权限审批气泡）需要 CodeWhale 源码改动

### 4.2 `hooks/codewhale-hook.js` — Hook 脚本

这是整合同的核心文件。CodeWhale 在每次生命周期事件触发时调用此脚本。

**架构**：
```
CodeWhale → 设置环境变量 → 调用 hook 脚本 → 翻译事件 → POST /state → Clawd
```

**环境变量**（CodeWhale 传入）：
| 变量 | 含义 | 事件 |
|---|---|---|
| `DEEPSEEK_SESSION_ID` | 会话 ID | 大部分事件 |
| `DEEPSEEK_TOOL_NAME` | 工具名称 | tool_call_before/after |
| `DEEPSEEK_TOOL_SUCCESS` | 工具是否成功 | tool_call_after |
| `DEEPSEEK_MODE` | 当前模式 | mode_change |
| `DEEPSEEK_PREVIOUS_MODE` | 上一个模式 | mode_change |
| `DEEPSEEK_WORKSPACE` | 工作空间路径 | session_start 等 |
| `DEEPSEEK_MODEL` | 模型名称 | session_start 等 |
| `DEEPSEEK_ERROR` | 错误信息 | on_error |

**稳定 Session ID 缓存**：

`mode_change` 等事件可能不带 `DEEPSEEK_SESSION_ID`，如果不处理会导致 Clawd HUD 出现重复标签。解决方案：
1. 首次事件时生成 session id → 写入 `/tmp/codewhale-hook-session`
2. 后续事件从缓存读取
3. `session_end` 时清除缓存

**session_title 覆盖**：

Clawd 默认用 `path.basename(cwd)` 作为 HUD 标签，即工作空间目录名（如 `claude_on_desk`）。hook 脚本通过 `session_title: "CodeWhale"` 覆盖，使 HUD 显示正确的 agent 名。

### 4.3 `hooks/codewhale-install.js` — 安装脚本

操作 `~/.codewhale/config.toml` 的 `[[hooks.hooks]]` 部分：

```toml
[hooks]
enabled = true

[[hooks.hooks]]
# managed by clawd-on-desk
event = "session_start"
command = '''node "/path/to/codewhale-hook.js" session_start'''
background = true
timeout_secs = 5
```

7 个事件全部注册：
- `session_start`（background）
- `session_end`（**非** background，await 确保送达）
- `message_submit`（background）
- `tool_call_before`（background）
- `tool_call_after`（background）
- `mode_change`（background）
- `on_error`（background）

**幂等性**：已存在的 clawd-managed 条目被更新，手动添加的条目保留。

**关键修复**：见 [5.1 节](#51-codewhale-installjs-关键修复)。

### 4.4 `assets/icons/agents/codewhale.png`

64×64 runtime agent PNG。所有 runtime agent PNG 都必须保持 64×64，避免 `test/state-agent-icons.test.js` 失败。

---

## 5. 修改文件详解

### 5.1 `codewhale-install.js` 关键修复

#### 5.1.1 Electron 启动路径

Clawd 启动时 `integration-sync.js` 调用 `codewhale-install.js`，此时 `process.execPath` 是 Electron 二进制路径而非 Node.js。错误 hook command 会变成：
```
electron "/path/to/hook.js" session_start
```
而非正确的：
```
node "/path/to/hook.js" session_start
```

**修复**：
```js
// 修复前
const nodeBin = process.execPath || "node";

// 修复后
const nodeBin = process.versions.electron ? "node" : (process.execPath || "node");
```

检测到 Electron 运行时自动 fallback 到 PATH 中的 `node`。

#### 5.1.2 幂等注册与 legacy cleanup

早期实现把 `# managed by clawd-on-desk` 写在 `[[hooks.hooks]]` 前一行。`parseTomlSections()` 遇到 `[[hooks.hooks]]` 才开启新 section，导致 marker 被归到前一个 section，重复注册会不断追加 hook block，本地复现可见 `7 -> 8 -> 9 -> 10` 增长；卸载也可能只删 `6/7` 个 managed hook，留下孤儿 hook。

当前修复：

- marker 写入 `[[hooks.hooks]]` section 内；
- parser 兼容旧的 marker-before-header 格式；
- marker 丢失但 `command` 指向 `codewhale-hook.js` 的历史 orphan hook 也按 managed hook 清理；
- register 会先删除旧 managed entries，再写入 7 个 canonical entries；
- 第二次 register 返回 `added: 0`、`removed: 0`、`updated: false`，startup sync 不会反复记录无意义日志。

临时副本验证：历史污染配置可从 15 个 Clawd hook 引用收敛到 7 个，第二次注册保持 7 个，卸载后变 0 个。真实用户配置未在验证中写入。

#### 5.1.3 Windows command quoting

hook command 不再手写：

```js
const command = `${nodePath} "${hookPath}" ${event}`;
```

而是复用 `formatNodeHookCommand()`。这样 `C:\Program Files\nodejs\node.exe` 等含空格路径会被正确引用，不会被 shell 拆坏。

#### 5.1.4 Config path

CodeWhale CLI 会尊重 `CODEWHALE_CONFIG_PATH` 和 `DEEPSEEK_CONFIG_PATH`。installer 和 Doctor 现在共用 `resolveCodewhaleConfigPath()`，默认仍是 `~/.codewhale/config.toml`，但显式 env/config path 会优先生效。

### 5.2 `agents/registry.js`

```js
const codewhale = require("./codewhale");
// ...
const AGENTS = [
  // ...
  codewhale,
];
```

### 5.3 `src/prefs.js`

```js
// agents 默认值白名单中新增
"codewhale": { integrationInstalled: false, enabled: false, permissionsEnabled: false, notificationHookEnabled: true },
```

### 5.4 `src/integration-sync.js`

```js
function syncCodewhaleHooks() {
  var r = require('../hooks/codewhale-install.js');
  var result = r.registerCodewhaleHooks({ silent: true });
  // ...
}
```

CodeWhale 只有在 Settings 中安装且启用后才会在 Clawd 启动时自动调用此函数；用户触发 Install / Fix / Repair 时也会调用。

### 5.5 `src/server-agent-id.js`

```js
const HOOK_SOURCE_AGENT_IDS = new Map([
  // ...
  ["codewhale-hook", "codewhale"],
]);
```

将 hook source 字符串 `"codewhale-hook"` 映射到 agent `"codewhale"`。

### 5.6 `src/settings-actions-agents.js`

```js
const AUTO_REPAIRABLE_AGENT_IDS = new Set([
  // ...
  "codewhale",
]);
```

允许设置面板中一键修复 CodeWhale hooks。

### 5.7 `src/settings-agent-order.js`

```js
const NON_COLLAPSIBLE = [
  // ...
  "codewhale",
];
```

确保 CodeWhale 在 agent 列表中显示为可展开项，并露出通知开关。

### 5.8 `package.json`

```json
"start": "node launch.js"
```

CodeWhale 集成本身不需要改动 `npm start`。Telegram legacy sidecar 已退役，源码启动不再预检查、下载或暂存该二进制。

### 5.9 Doctor / Cleanup

CodeWhale 已进入 Doctor descriptor 和 integration checks：

- `src/doctor-detectors/agent-descriptors.js` 使用 `configMode: "codewhale-hooks-toml"`。
- `src/doctor-detectors/agent-integrations.js` 校验 7 个 CodeWhale hook events、script path、broken command，并识别 `[hooks].enabled = false`。
- `hooks/cleanup-integrations.js` 调用 `unregisterCodewhaleHooks()` 清理 canonical hooks 和 legacy orphan hooks。

---

## 6. 事件映射表

| CodeWhale 事件 | 环境变量关键字段 | Clawd 事件 | 动画状态 | 同步模式 |
|---|---|---|---|---|
| `session_start` | DEEPSEEK_SESSION_ID, DEEPSEEK_WORKSPACE, DEEPSEEK_MODE | `SessionStart` | idle | fire-and-forget |
| `session_end` | DEEPSEEK_SESSION_ID | `SessionEnd` | sleeping | **await** |
| `message_submit` | DEEPSEEK_SESSION_ID, DEEPSEEK_MESSAGE(截断) | `UserPromptSubmit` | thinking | fire-and-forget |
| `tool_call_before` | DEEPSEEK_TOOL_NAME | `PreToolUse` | working | fire-and-forget |
| `tool_call_after`（成功） | DEEPSEEK_TOOL_NAME, DEEPSEEK_TOOL_SUCCESS=true | `PostToolUse` | working | fire-and-forget |
| `tool_call_after`（失败） | DEEPSEEK_TOOL_NAME, DEEPSEEK_TOOL_SUCCESS=false | `PostToolUseFailure` | error | fire-and-forget |
| `mode_change`（compact） | DEEPSEEK_MODE=compact | `PreCompact` | sweeping | fire-and-forget |
| `mode_change`（其他） | DEEPSEEK_MODE/ DEEPSEEK_PREVIOUS_MODE | `Stop` | attention | fire-and-forget |
| `on_error` | DEEPSEEK_ERROR | `StopFailure` | error | fire-and-forget |
| `shell_env` | — | — | — | 忽略 |

---

## 7. 已知限制与未实现功能

### 7.1 未实现：权限审批气泡（Phase 2）

**目标**：当 CodeWhale 需要用户确认工具调用时（如执行 shell 命令、写入文件），Clawd 弹出交互式气泡，用户点击"允许"或"拒绝"后回复给 CodeWhale。

**阻塞原因**：

CodeWhale 有两个独立的 hook/事件系统：

| 系统 | 实现 | 事件数 | 是否有审批事件 |
|---|---|---|---|
| Shell Hooks (`[[hooks.hooks]]` in config.toml) | 命令行调用 | 8 个 | ❌ 无 |
| Runtime Events (`HookDispatcher` + sinks) | SSE / Webhook / JSONL | 20+ 个 | ✅ 有 `ApprovalLifecycle` |

审批事件（`ApprovalLifecycle`）只在 Runtime Events 中可用。访问它需要 `codewhale serve --http`（Runtime API），但 **serve 和 TUI 是两个独立进程，不共享 RuntimeThreadManager 实例**。serve 的 SSE 端点看不到 TUI 的审批事件，bridge 收不到任何东西。

**需要的 CodeWhale 源码改动**（不在此项目范围内）：
- 让 TUI 内嵌 HTTP server（类似 `--http` 标志在主命令上）——或——
- 让 serve 和 TUI 共享同一个 RuntimeThreadManager store

**临时方案**：用户保持 `approval_mode = auto` 或 `suggest`，在终端中手动审批。桌宠仅显示状态动画。

### 7.2 未实现：子代理支持（Phase 3）

**目标**：CodeWhale 启动子代理（subagent）时，螃蟹切换到 juggling/building 动画。

**阻塞原因**：CodeWhale 的 sub-agent 机制细节未知。需要研究其 session/task 生命周期事件。

### 7.3 未实现：深度会话集成（Phase 4）

包括：
- HTTP/SSE Runtime API 会话信息获取
- 终端聚焦支持
- Dashboard 增强

### 7.4 图标

当前 `assets/icons/agents/codewhale.png` 是 64×64 runtime PNG。后续可以替换为更正式的 CodeWhale 官方 logo，但尺寸必须保持 64×64。

---

## 8. 常见问题排查

### 8.1 螃蟹不动

1. 确认 Clawd 在运行：`curl http://127.0.0.1:23333/state` 返回 `{"ok":true}`
2. 确认已在 **Settings → Agents → CodeWhale → Install** 安装并启用集成
3. 确认 hooks 已注册：`grep "codewhale-hook" ~/.codewhale/config.toml` 应有 7 个条目
4. 确认 hooks 用的是 `node` 而非 `electron`：同上
5. 手动模拟测试：
   ```bash
   DEEPSEEK_SESSION_ID=test_001 \
   DEEPSEEK_WORKSPACE=/tmp \
   DEEPSEEK_MODE=agent \
   node hooks/codewhale-hook.js session_start
   ```

### 8.2 HUD 标签显示错误（如 `claude_on_desk`）

确认 hook 脚本是修改后的版本（包含 `session_title: "CodeWhale"`）。重启 codewhale 后新会话生效。

### 8.3 多个重复 HUD 标签

旧 session 残留。重启 Clawd 清除，或右键删除。

### 8.4 Hook 命令用了 electron 而非 node

如果已安装且启用的 CodeWhale 集成在 Clawd 启动同步时覆盖了 hooks：
1. 从 **Settings → Agents → CodeWhale → Fix / Repair** 重新同步，或调试时手动运行 `npm run install:codewhale-hooks`
2. 确认 `codewhale-install.js` 使用 `resolveNodeBin()`，不会在 Electron 启动路径里固定写入裸 `node`

### 8.5 安装脚本失败

默认路径下，确保 `~/.codewhale/` 目录存在且 `config.toml` 格式正确。若使用 `CODEWHALE_CONFIG_PATH` 或 `DEEPSEEK_CONFIG_PATH`，installer 会按显式路径写入并创建父目录。

---

## 9. 使用说明

### 9.1 首次启动

```bash
cd clawd-on-desk

# 1. 安装依赖（已完成则跳过）
npm install

# 2. 配置 chrome-sandbox 权限（Linux 必需）
sudo chown root:root node_modules/electron/dist/chrome-sandbox
sudo chmod 4755 node_modules/electron/dist/chrome-sandbox

# 3. 启动桌宠
npm start
```

启动后打开 **Settings → Agents → CodeWhale → Install**。安装且启用后，Clawd 会在后续启动时继续同步 CodeWhale hooks。

如需在启动桌宠前调试 installer，也可以手动执行：

```bash
npm run install:codewhale-hooks
```

### 9.2 日常使用

```bash
# 启动 Clawd
cd clawd-on-desk && npm start

# 启动 CodeWhale（另一个终端）
codewhale

# 或 YOLO 模式
codewhale --yolo
```

### 9.3 卸载

```bash
# 卸载 hooks
npm run uninstall:codewhale-hooks

# 停止桌宠
pkill -f "electron.*clawd-on-desk"
```

### 9.4 调试

```bash
# 查看 Clawd 状态
curl http://127.0.0.1:23333/state

# 查看已注册 hooks
grep "codewhale-hook" ~/.codewhale/config.toml

# 手动触发事件
cd clawd-on-desk
DEEPSEEK_SESSION_ID=debug DEEPSEEK_WORKSPACE=$(pwd) \
  node hooks/codewhale-hook.js session_start
```

---

## File: docs/guides/codex-wsl-clarification.ko-KR.md

# Codex + WSL 현황 정리

최종 확인 날짜: 2026-05-08

이 문서는 자주 뒤섞여서 전달되는 세 가지 질문을 분리해서 설명합니다.

1. OpenAI 공식 문서 기준으로 Codex가 WSL에서 동작하는가.
2. Codex hooks와 `.codex` 상태가 Windows와 WSL 사이에서 자동으로 공유되는가.
3. Clawd가 현재 WSL의 별도 Linux home 안에 있는 Codex 세션을 자동으로 감지할 수 있는가.

이 세 질문의 답은 서로 다릅니다. 대부분의 혼선은 OpenAI의 공식 지원 범위와 Clawd의 현재 구현 범위를 같은 이야기로 받아들이면서 생깁니다.

## TL;DR

- OpenAI는 Codex의 WSL2 실행을 공식적으로 안내합니다.
- 현재 Codex CLI는 hooks를 `[features].hooks = true` feature flag로 활성화합니다. 이전 버전과 일부 문서에서 쓰던 `[features].codex_hooks` 키는 deprecated 되었습니다.
- Clawd는 이제 Codex official hooks를 기본 경로로 사용하고, `~/.codex/sessions` JSONL 폴링을 fallback으로 유지합니다.
- Windows native Codex hooks는 2026-04-26에 로컬에서 검증되었습니다. Windows hook command는 PowerShell의 `&` 호출 연산자를 사용해야 합니다.
- Clawd가 Windows에서 실행되고 Codex가 기본 Linux home을 쓰는 WSL 안에서 실행되면, Clawd는 `/home//.codex/sessions`를 자동으로 읽지 못합니다.
- 따라서 "Codex가 WSL을 지원하지 않는다"는 표현은 부정확합니다. 더 정확한 표현은 "Codex는 공식적으로 WSL2를 지원하지만, Windows에서 실행되는 Clawd는 WSL의 별도 Linux `~/.codex`를 자동으로 수정하거나 폴링하지 않는다. WSL Codex 세션을 보내려면 WSL 안에서 remote mode hooks를 설치하거나 `CODEX_HOME`을 공유해야 한다"입니다.

## 1. OpenAI 공식 현황

### Codex는 공식적으로 WSL2를 지원합니다

OpenAI의 Codex Windows 문서에는 WSL 전용 섹션이 있으며, WSL2 안에서 Codex CLI를 설치하고 실행하는 절차가 직접 나와 있습니다.

- <https://developers.openai.com/codex/windows>

이 문서에는 다음이 포함됩니다.

- `Windows Subsystem for Linux` 섹션
- `Use Codex CLI with WSL` 섹션
- `wsl --install`, WSL 내부 Node.js 설치, `npm i @openai/codex`, `codex` 실행 절차

즉, 제품 차원에서 보면 "Codex는 WSL2를 지원한다"가 맞습니다.

### WSL1은 더 이상 지원되지 않습니다

OpenAI 문서는 다음도 함께 명시합니다.

- WSL1 지원은 Codex `0.114`까지
- Codex `0.115`부터 Linux sandbox가 `bubblewrap`로 바뀌면서 WSL1은 더 이상 지원되지 않음

참고:

- <https://developers.openai.com/codex/windows>
- <https://developers.openai.com/codex/app/windows>

따라서 지금의 정확한 표현은 "WSL2 지원"입니다.

### Codex hooks는 feature flag 뒤에 있습니다

현재 Codex CLI는 hooks를 다음 feature flag로 활성화합니다.

```toml
[features]
hooks = true
```

이전 버전과 일부 문서는 `codex_hooks` 키를 사용했지만, 최신 Codex CLI는 이 키를 deprecated로 안내합니다.

같은 문서는 `hooks.json`, 공통 입력 필드, `PermissionRequest`, `tool_input.description`, 그리고 현재 지원하지 않는 `PermissionRequest` decision 필드가 fail-closed 되는 동작도 설명합니다.

참고:

- <https://developers.openai.com/codex/hooks>

Clawd의 Codex installer는 `~/.codex/hooks.json`를 쓰고, 사용자가 hooks를 명시적으로 끄지 않은 경우 이 feature flag를 켭니다. deprecated된 `codex_hooks` 키가 있으면 `hooks`로 마이그레이션하되, 사용자가 명시한 false 값은 유지합니다.

### WSL과 Windows는 기본적으로 `.codex`를 공유하지 않습니다

OpenAI의 Windows app 문서는 다음도 설명합니다.

- Windows app은 `%USERPROFILE%\.codex`를 사용
- WSL 안의 Codex CLI는 기본적으로 Linux `~/.codex`를 사용
- 그래서 configuration, cached auth, session history가 자동으로 공유되지 않음

OpenAI가 안내하는 공유 방법 중 하나는 다음과 같습니다.

```bash
export CODEX_HOME=/mnt/c/Users/<windows-user>/.codex
```

참고:

- <https://developers.openai.com/codex/app/windows>

즉, 별도 설정이 없다면 WSL 안의 Codex는 Linux home 아래에 로그와 세션 데이터를 쓴다는 뜻입니다.

## 2. Clawd의 현재 구현

### Clawd는 official hooks를 먼저 쓰고 JSONL 폴링을 fallback으로 유지합니다

이 저장소에서 Codex 연동 설정은 [`agents/codex.js`](../../agents/codex.js)에 있습니다.

- `eventSource: "hook+log-poll"`
- `sessionDir: "~/.codex/sessions"`

Official hook 구현은 [`hooks/codex-hook.js`](../../hooks/codex-hook.js)에 있고, fallback monitor는 [`agents/codex-log-monitor.js`](../../agents/codex-log-monitor.js)에 있습니다.

런타임에서는:

- official hooks가 SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, Stop을 처리합니다.
- PermissionRequest는 기본적으로 intercept 모드입니다. Clawd가 실제 Allow/Deny bubble을 띄웁니다. 사용자는 Codex permission mode를 native로 전환해 Codex AutoReview/native prompt가 계속 처리하게 할 수 있습니다.
- JSONL 폴링은 hooks가 꺼진 세션과 web search, context compaction, turn aborted처럼 official hooks가 다루지 않는 이벤트를 위해 계속 켜 둡니다.

Fallback monitor에서 `~`는 현재 실행 중인 프로세스의 `os.homedir()`로 확장됩니다. 즉:

- Clawd가 Windows에서 실행되면 `C:\Users\\.codex\sessions`
- Clawd가 Linux에서 실행되면 `/home//.codex/sessions`

를 읽습니다.

그래서 Windows 호스트에서 실행 중인 Clawd는 WSL Linux home 안의 `/home//.codex/sessions`를 자동으로 읽지 못합니다.

### 현재 Clawd에는 WSL home에 자동 설치하는 경로가 없습니다

현재 메인 프로세스는 호스트 OS의 home에 Codex official hooks를 동기화하고 fallback monitor를 시작합니다. 사용자 설정 가능한 WSL sessionDir도 없고, 기본적으로 `\\wsl$\...`를 스캔하지 않으며, Windows 앱이 `/home//.codex/hooks.json`를 자동으로 수정하지도 않습니다.

현재 상태를 정리하면:

- `Windows native Codex + Windows Clawd`: official hooks로 기본 동작하며 JSONL fallback도 유지
- `WSL2 Codex + Windows Clawd + Linux 기본 home`: 기본값으로는 동작하지 않음. WSL 안에서 remote mode hooks를 설치하거나 remote fallback monitor를 실행해야 함
- `WSL2 Codex + Windows .codex 공유`: OpenAI의 `CODEX_HOME` 문서를 기준으로 보면 설정과 session 상태를 공유할 수 있음

마지막 항목은 OpenAI의 공유 방식과 Clawd의 현재 hook 및 fallback 폴링 동작을 조합한 추론입니다.

### 원격/우회 패턴은 이미 있지만 WSL 기본 지원과는 다릅니다

이 저장소의 원격 배포는 앱의 **Settings → Remote SSH → Deploy / Repair
Hooks**에서 수행합니다. profile별 runtime layout과 전용 ingress, routing
identity를 사용합니다. [`scripts/remote-deploy.sh`](../../scripts/remote-deploy.sh)는
이 보안 transaction에 참여할 수 없으므로 의도적으로 비활성화되었습니다.

또한 [`hooks/codex-remote-monitor.js`](../../hooks/codex-remote-monitor.js)도
유지합니다. 반대편 환경에서 확인된 `<CODEX_HOME>/sessions`를 폴링하며,
Remote SSH에서는 같은 identity-pinned layout 안에서만 실행됩니다.

현재 이 스크립트는 문서상 원격 SSH 시나리오에 맞춰 설명되어 있습니다. 즉, "로그는 다른 쪽에 있고 상태만 돌려보낸다"는 패턴은 이미 있지만, 이것이 곧 "Clawd가 WSL 안의 Codex를 기본값으로 자동 감지한다"는 뜻은 아닙니다.

## 3. 왜 현재 문서가 오해를 만들기 쉬운가

### README의 표현이 실제 경계보다 넓게 읽힐 수 있습니다

현재 README는 다음처럼 보일 수 있습니다.

- `Claude Code와 Codex CLI는 바로 사용할 수 있다`
- setup guide가 `원격 SSH, WSL, 플랫폼별 참고 사항`을 다룬다

참고:

- [`README.ko-KR.md`](../../README.ko-KR.md)

이 표현은 많은 조합에서는 맞지만, 아래 두 경우를 구분해 주지 않습니다.

- Windows 네이티브에서 실행되는 Codex
- 별도 Linux home을 유지하는 WSL2 안에서 실행되는 Codex

### setup guide의 WSL 본문은 주로 Claude Code를 설명합니다

현재 WSL 본문은 [`docs/guides/setup-guide.md`](./setup-guide.md)에 있고, 핵심 내용은 다음입니다.

- WSL 안에서 Claude Code 실행
- WSL로 hooks 파일 복사
- WSL 안에서 Claude hooks 등록

반면 Codex는 주로 원격 SSH 섹션에서 `codex-remote-monitor.js` 형태로 등장합니다.

즉:

- WSL이 아예 문서에 없는 것은 아닙니다.
- 하지만 `Codex + WSL`의 지원 경계는 따로 분명하게 써 두지 않았습니다.

## 4. 현재 가장 정확한 결론

2026-05-08 기준으로 가장 정확한 결론은 다음과 같습니다.

1. OpenAI는 Codex의 WSL2 실행을 공식적으로 지원합니다.
2. 현재 Codex CLI는 `hooks` feature flag를 사용하며, `codex_hooks`는 deprecated 되었습니다.
3. Clawd는 Codex official hooks를 기본 경로로 사용하고 JSONL 폴링을 fallback으로 유지합니다.
4. Clawd는 현재 호스트 머신의 `.codex` home에 hooks를 동기화하고 fallback logs를 폴링합니다.
5. 따라서 Codex가 WSL2 안에서 Linux 기본 `~/.codex`를 사용하면 Windows Clawd는 그 세션을 기본값으로 자동 감지하지 못합니다.
6. 현재 문서의 문제는 "WSL이 전혀 안 적혀 있다"가 아니라 "`Codex + WSL` 경계를 충분히 명시하지 않았다"에 가깝습니다.

## 5. 외부 설명용 권장 문구

이슈나 사용자 답변에 넣을 한 문단이 필요하다면 아래 표현이 가장 안전합니다.

> OpenAI 공식 문서 기준으로 Codex는 WSL2를 지원합니다. Clawd는 Codex official hooks로 통합하며 JSONL 폴링을 fallback으로 유지합니다. Clawd가 Windows에서 실행되고 Codex가 Linux 기본 home을 쓰는 WSL 안에서 실행되면, Clawd는 그 WSL `~/.codex`를 자동으로 수정하거나 폴링하지 않습니다. WSL 안에서 remote mode hooks를 설치하거나, `CODEX_HOME`을 공유하거나, remote fallback monitor를 실행해야 합니다. 현재 문제는 "Codex가 WSL을 지원하지 않는다"기보다 "Clawd의 연동 경계와 문서 설명이 충분히 명확하지 않았다"에 가깝습니다.

## 6. 현재 가능한 경로

지금 목표가 "Windows의 Clawd가 WSL 안의 Codex를 감지하게 만들기"라면 현실적인 경로는 세 가지입니다.

1. OpenAI 문서대로 WSL의 `CODEX_HOME`을 Windows `%USERPROFILE%\.codex`로 맞춘다.
2. WSL 안에서 `node hooks/codex-install.js --remote`를 실행해 Codex official hooks가 WSL localhost forwarding을 통해 Windows Clawd로 POST하게 한다.
3. 이 저장소의 [`hooks/codex-remote-monitor.js`](../../hooks/codex-remote-monitor.js) 패턴을 활용해 WSL 쪽에서 상태를 Windows로 밀어 넣는다.
4. Clawd 자체를 확장해서 `\\wsl$\...` sessionDir를 직접 지원하게 만든다.

이 셋은 의미가 다릅니다.

- 1번은 OpenAI가 공식 문서에서 제시한 공유 방식
- 2번은 Codex hooks가 사용 가능할 때 Clawd에서 지연이 가장 낮은 경로
- 3번은 official hooks가 불가능하거나 꺼진 경우의 fallback
- 4번은 Clawd의 새 기능 추가

## 참고 자료

OpenAI 공식 문서:

- Codex Windows: <https://developers.openai.com/codex/windows>
- Codex Hooks: <https://developers.openai.com/codex/hooks>
- Codex app on Windows: <https://developers.openai.com/codex/app/windows>

저장소 내부 관련 파일:

- [`README.ko-KR.md`](../../README.ko-KR.md)
- [`docs/guides/setup-guide.md`](./setup-guide.md)
- [`agents/codex.js`](../../agents/codex.js)
- [`agents/codex-log-monitor.js`](../../agents/codex-log-monitor.js)
- [`hooks/codex-hook.js`](../../hooks/codex-hook.js)
- [`hooks/codex-install.js`](../../hooks/codex-install.js)
- [`hooks/codex-remote-monitor.js`](../../hooks/codex-remote-monitor.js)

---

## File: docs/guides/codex-wsl-clarification.md

# Codex + WSL Clarification

Last verified: May 8, 2026

This note separates three questions that are easy to conflate:

1. Whether OpenAI officially supports running Codex in WSL.
2. Whether Codex hooks and `.codex` state are shared between Windows and WSL.
3. Whether Clawd can currently auto-detect Codex sessions that live inside WSL's separate Linux home.

Those answers are not the same. Most confusion comes from mixing the official Codex product support story with Clawd's current integration boundaries.

## TL;DR

- OpenAI officially supports running Codex in WSL2.
- Current Codex CLI builds enable hooks through `[features].hooks = true`; older builds and some docs used the deprecated `[features].codex_hooks` key.
- Clawd now uses Codex official hooks as the primary integration and keeps `~/.codex/sessions` JSONL polling as fallback.
- Windows native Codex hooks were verified locally on April 26, 2026; hook commands on Windows must use PowerShell's `&` call operator.
- When Clawd runs on Windows while Codex runs inside WSL with the default Linux home directory, Clawd does not automatically see `/home//.codex/sessions`.
- So "Codex does not support WSL" is inaccurate. The more accurate statement is: "Codex officially supports WSL2, but Windows Clawd does not automatically modify or poll WSL's separate Linux `~/.codex`; install hooks in WSL remote mode or share `CODEX_HOME` when you want WSL Codex sessions to report back."

## 1. OpenAI's current official position

### Codex officially supports WSL2

OpenAI's Windows documentation for Codex includes a dedicated WSL section and explicit instructions for installing and running Codex CLI inside WSL2:

- <https://developers.openai.com/codex/windows>

That page includes:

- a `Windows Subsystem for Linux` section
- a `Use Codex CLI with WSL` section
- explicit steps for `wsl --install`, installing Node.js inside WSL, `npm i @openai/codex`, and then running `codex`

At the product level, this means "Codex supports WSL2" is true.

### WSL1 is no longer supported

OpenAI's Windows documentation also states:

- WSL1 was supported through Codex `0.114`
- starting in Codex `0.115`, the Linux sandbox moved to `bubblewrap`, so WSL1 is no longer supported

References:

- <https://developers.openai.com/codex/windows>
- <https://developers.openai.com/codex/app/windows>

So the precise statement is "supports WSL2", not just "supports WSL".

### Codex hooks are feature-flagged

Current Codex CLI builds enable hooks through:

```toml
[features]
hooks = true
```

Older Codex builds and some documentation used the deprecated `codex_hooks` key.

It also documents `hooks.json`, common input fields, `PermissionRequest`, `tool_input.description`, and the current fail-closed behavior for unsupported PermissionRequest decision fields.

Reference:

- <https://developers.openai.com/codex/hooks>

Clawd's Codex installer writes `~/.codex/hooks.json` and enables this feature flag unless the user explicitly set hooks to `false`. If it sees the deprecated `codex_hooks` key, it migrates it to `hooks` while preserving an explicit false value.

### WSL and Windows do not share `.codex` by default

OpenAI's Windows app documentation also explains that:

- the Windows app uses `%USERPROFILE%\.codex`
- Codex CLI inside WSL uses Linux `~/.codex` by default
- as a result, configuration, cached auth, and session history are not shared automatically

OpenAI documents this sharing option:

```bash
export CODEX_HOME=/mnt/c/Users/<windows-user>/.codex
```

Reference:

- <https://developers.openai.com/codex/app/windows>

That matters because it confirms that a default WSL Codex session writes into Linux home unless the user explicitly changes `CODEX_HOME`.

## 2. Clawd's current implementation

### Clawd uses official hooks first, with JSONL polling as fallback

In this repository, Codex integration is configured in [`agents/codex.js`](../../agents/codex.js):

- `eventSource: "hook+log-poll"`
- `sessionDir: "~/.codex/sessions"`

The official hook implementation is in [`hooks/codex-hook.js`](../../hooks/codex-hook.js), and the fallback monitor is in [`agents/codex-log-monitor.js`](../../agents/codex-log-monitor.js).

At runtime:

- official hooks handle SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, and Stop
- PermissionRequest defaults to intercept mode: Clawd shows a real Allow/Deny bubble. Users can switch Codex permission mode to native if they want Codex AutoReview/native prompts to stay in charge.
- JSONL polling remains active for hook-disabled sessions and events official hooks do not cover, such as web search, compaction, and abort

The fallback monitor expands `~` using the current process's own `os.homedir()`. In practice:

- if Clawd runs on Windows, it polls `C:\Users\\.codex\sessions`
- if Clawd runs on Linux, it polls `/home//.codex/sessions`

So a Windows-hosted Clawd does not automatically poll `/home//.codex/sessions` inside WSL.

### Clawd currently has no automatic "install into WSL home" path

The current main process starts the Codex official-hook sync and fallback monitor for the host OS's own home directory. There is no user-facing WSL session directory setting, no default `\\wsl$\...` path scan, and no automatic edit of `/home//.codex/hooks.json` from the Windows app.

That means:

- `Codex native on Windows + Clawd on Windows`: works out of the box through official hooks, with JSONL fallback
- `Codex in WSL2 + Clawd on Windows + default Linux home`: does not work by default unless hooks are installed inside WSL in remote mode or a remote-side monitor is started
- `Codex in WSL2 + shared Windows Codex home via CODEX_HOME`: inferred to be workable for shared config/session state, because both sides would then point at the same `.codex` directory

The last point is an inference from OpenAI's documented `CODEX_HOME` sharing flow plus Clawd's current hook and fallback polling behavior.

### Clawd has remote-side hooks and a monitor fallback, but not WSL auto-discovery

This repo includes app-controlled deployment through **Settings → Remote SSH
→ Deploy / Repair Hooks**. It resolves the profile runtime layout, installs
Codex hooks there, and routes official hook traffic through a profile-bound
SSH ingress with a dedicated secure marker and routing identity.
[`scripts/remote-deploy.sh`](../../scripts/remote-deploy.sh) is intentionally
disabled because it cannot create or persist that secure profile transaction.

It also ships [`hooks/codex-remote-monitor.js`](../../hooks/codex-remote-monitor.js),
which can poll the resolved `<CODEX_HOME>/sessions` on the other side and POST
state changes back when official hooks are unavailable or disabled. Remote SSH
starts it under the same identity-pinned layout; it must not be launched as a
free-standing scanner for the secure SSH flow.

So the repo already contains "state lives somewhere else, send events back" patterns, but that is not the same as automatic WSL discovery in the desktop app.

## 3. Why the current docs are easy to misread

### The README wording is broader than the current Codex-on-WSL reality

The current README says:

- `Claude Code and Codex CLI work out of the box`
- the setup guide also covers `remote SSH, WSL, and platform-specific notes`

Reference:

- [`README.md`](../../README.md)

That wording is reasonable for many cases, but it does not distinguish between:

- Codex running natively on Windows
- Codex running inside WSL2 while keeping a separate Linux home

### The WSL section in the setup guide mainly discusses Claude Code

The existing WSL section in [`docs/guides/setup-guide.md`](./setup-guide.md) primarily explains:

- running Claude Code inside WSL
- copying hook files into WSL
- registering Claude hooks inside WSL

Codex now appears in the remote SSH section through official hooks first and `codex-remote-monitor.js` as fallback.

So the docs do mention WSL, but they do not clearly spell out the support boundary for `Codex + WSL`.

## 4. The most accurate current conclusion

As of May 8, 2026:

1. OpenAI officially supports Codex in WSL2.
2. Current Codex CLI builds use the `hooks` feature flag; `codex_hooks` is deprecated.
3. Clawd uses official Codex hooks as primary integration and JSONL polling as fallback.
4. Clawd currently syncs hooks and polls fallback logs in the host machine's own `.codex` home.
5. So if Codex runs inside WSL2 and still uses Linux `~/.codex`, Windows Clawd does not auto-detect those sessions by default.
6. The current documentation problem is not "WSL is never mentioned". The problem is that `Codex + WSL` boundaries were not explained explicitly enough.

## 5. Suggested external wording

If you need one concise explanation for users or issue threads, this is the safest wording:

> OpenAI officially supports running Codex in WSL2. Clawd integrates with Codex through official hooks, with JSONL polling kept as fallback. If Clawd runs on Windows while Codex runs in WSL with Linux's default home directory, Clawd will not automatically modify or poll that WSL `~/.codex`; install hooks in WSL remote mode, share `CODEX_HOME`, or run the remote fallback monitor. The current issue is better described as a Clawd integration and documentation boundary, not as OpenAI failing to support Codex on WSL.

## 6. Current workable paths

If the goal is "make Windows Clawd react to Codex running in WSL", the realistic paths today are:

1. Use OpenAI's documented sharing approach and point WSL `CODEX_HOME` at the Windows `%USERPROFILE%\.codex`.
2. Install Codex official hooks inside WSL with `node hooks/codex-install.js --remote`, so WSL Codex POSTs back to Windows Clawd through WSL localhost forwarding.
3. Reuse the repo's fallback remote-side monitor from [`hooks/codex-remote-monitor.js`](../../hooks/codex-remote-monitor.js) and actively send state back to the Windows host.
4. Extend Clawd itself to support an explicit `\\wsl$\...` session directory.

Those options are not equivalent:

- option 1 is an OpenAI-documented sharing flow
- option 2 is the lowest-latency Clawd path when Codex hooks are available inside WSL
- option 3 is the fallback for hook-disabled Codex sessions
- option 4 would be a new Clawd feature, not current default behavior

## References

OpenAI documentation:

- Codex Windows: <https://developers.openai.com/codex/windows>
- Codex Hooks: <https://developers.openai.com/codex/hooks>
- Codex app on Windows: <https://developers.openai.com/codex/app/windows>

Repo files:

- [`README.md`](../../README.md)
- [`docs/guides/setup-guide.md`](./setup-guide.md)
- [`agents/codex.js`](../../agents/codex.js)
- [`agents/codex-log-monitor.js`](../../agents/codex-log-monitor.js)
- [`hooks/codex-hook.js`](../../hooks/codex-hook.js)
- [`hooks/codex-install.js`](../../hooks/codex-install.js)
- [`hooks/codex-remote-monitor.js`](../../hooks/codex-remote-monitor.js)