{"owner":"rullerzhou-afk","repo":"clawd-on-desk","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nThis file is the entry point for coding agents working in this repository. Keep it short and operational. Durable architecture lives in `docs/project/`; `docs/plans/` and `docs/investigations/` are historical evidence unless this file explicitly links them.\n\n## Project Overview\n\nClawd 是一个 Electron 桌宠：通过 hook、日志轮询、plugin 和 extension 感知 AI coding agent 的工作状态，并播放像素风动画。当前支持 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、DeepSeek Harness；内置 Clawd / Calico / Cloudling 三套主题，支持用户主题；平台覆盖 Windows、macOS、Linux，UI 支持 en / zh / zh-TW / ko / ja / pt-BR。\n\n## Common Commands\n\n```bash\nnpm start\nnpm run build                  # default Windows package\nnpm run build:win:x64\nnpm run build:win:arm64\nnpm run build:win:all\nnpm run build:mac\nnpm run build:linux\nnpm run build:all\nnpm install\nnpm test\nnpm run verify:electron\nnpm run verify:release\nnpm run audit:assets\nnpm run audit:native-package -- --app-root <extracted-app-root> --target <target-id>\nnpm run create-theme\n\nnpm run install:claude-hooks\nnpm run uninstall:claude-hooks\nnpm run install:cursor-hooks\nnpm run install:gemini-hooks\nnpm run install:antigravity-hooks\nnpm run install:kiro-hooks\nnpm run install:kimi-hooks\nnpm run install:qwen-hooks\nnpm run install:zcode-hooks\nnpm run uninstall:zcode-hooks\nnpm run install:codewhale-hooks\nnpm run uninstall:codewhale-hooks\nnpm run install:pi-extension\nnpm run uninstall:pi-extension\nnpm run install:openclaw-plugin\nnpm run uninstall:openclaw-plugin\nnpm run install:hermes-plugin\nnpm run uninstall:hermes-plugin\nnpm run install:qoder-hooks\nnpm run uninstall:qoder-hooks\nnpm run install:qoderwork-hooks\nnpm run uninstall:qoderwork-hooks\nnpm run install:qwenwork-hooks\nnpm run uninstall:qwenwork-hooks\nnpm run install:reasonix-hooks\nnpm run uninstall:reasonix-hooks\nnpm run install:workbuddy-hooks\nnpm run uninstall:workbuddy-hooks\nnpm run install:dsh\nnpm run uninstall:dsh\nnpm run install:codex-hooks\nnpm run uninstall:codex-hooks\nnpm run install:codex-debug-hooks\nnpm run uninstall:codex-debug-hooks\nnpm run install:mimocode-plugin\nnpm run uninstall:mimocode-plugin\nnode hooks/codebuddy-install.js\nnode hooks/opencode-install.js\n\nbash test-demo.sh [seconds]\nbash test-mini.sh [seconds]\nbash test-macos.sh\nbash test-oneshot-gate.sh [state] [seconds]\n```\n\n新安装默认只把 Claude Code 和 Codex 标记为已安装并启用；其他 agent 默认未安装、未启用。正常启动时，Clawd 只会为 `integrationInstalled=true` 且 `enabled=true` 的 agent 自动同步 Claude / Codex / Copilot / Gemini / Antigravity / Cursor / CodeBuddy / WorkBuddy / Kiro / Kimi / Qwen / ZCode / CodeWhale / Qoder / QoderWork / QwenWork / Reasonix hooks、opencode / MiMo Code / OpenClaw / Hermes plugins 和 Pi extension。Settings Agent 页的 Install 会安装并启用该集成；Uninstall 会卸载 Clawd 管理的 hook/plugin/extension，并同时把该 agent 设为未安装、未启用。单独关闭 enabled 只会跳过启动同步并屏蔽事件/权限入口，不卸载用户已有 hooks / plugins / extensions；重新启用未安装 agent 只打开事件入口，不会写本机集成文件。手动安装命令主要用于调试、重装或远程部署。\nSettings 注册的自定义 HTTP Agent 是独立模型：`customApplications` 是注册真相，对应 `agents[customId]` 必须显式保持 `integrationInstalled=false`。注册只分配 ID 和状态入口，不安装 hook、不观察进程；v1 仅允许已注册且启用的 ID 向 `/state` 上报，`/permission` 永远不提供决定。删除或伪造的 `custom-` ID 必须直接拒绝，不能降级成 Claude Code subagent。\nCopilot CLI 同步走 `<COPILOT_HOME 或 ~/.copilot>/hooks/hooks.json`，marker-based 增量合并只接管含 `copilot-hook.js` 标记的条目，用户其他 entry / 其他 `hooks/*.json` 文件原样保留；hooks.json 或 `settings.json` 顶层 `disableAllHooks: true` 时 doctor 报 warning（不挂 Fix 按钮）。详见 `docs/guides/copilot-setup.md`。\n\n## Read These Docs\n\n- `docs/project/agent-runtime-architecture.md`：运行时架构、模块边界、启动与数据流、多 agent、permission bubble、终端聚焦和自动同步\n- `docs/project/theme-state-ui.md`：状态机、主题系统、settings、mini mode、素材规则、平台限制、待落地 UI 决策\n- `docs/project/release-process.md`：发版 checklist、release note 核对、tag 触发 GitHub 打包和资产确认\n- `docs/guides/copilot-setup.md`：Copilot CLI 自动同步说明、`COPILOT_HOME` 兼容性、手动配置备选模板\n- `docs/guides/dsh-setup.md`：DeepSeek Harness web profile 实验性 plugin-only 状态与普通审批集成\n- `docs/guides/state-mapping.md`：状态 → 动画权威表\n- `docs/guides/guide-theme-creation.md`：主题作者指南\n- `docs/guides/setup-guide.md`：安装、远程 SSH、各 agent 接入\n- `docs/guides/custom-agent-http.md`：自定义 HTTP Agent 的 state-only 接入合约和动态端口发现\n- `docs/guides/known-limitations.md`：用户向已知限制\n- `docs/guides/codex-wsl-clarification.md`：Codex / WSL 路径与 Node 说明\n- `docs/guides/guide-remote-ssh.md`：Remote SSH 用户流程、Codespaces 单会话 transport 与共享主机边界\n- `docs/guides/telegram-approval.md` / `docs/guides/feishu-lark-remote-approval.md`：远程审批设置与失败回退语义\n- `docs/guides/roam-fence.md`：自由漫游与可选围栏\n\n## Runtime Summary\n\n- HTTP hook / plugin 主路径：`src/server.js` → `src/server-route-state.js` → `src/agent-runtime-main.js` → `src/state.js` → IPC；本地 JSONL monitor 直接进入 `agent-runtime-main`，不经过 HTTP server\n- 权限主路径：`src/server-route-permission.js` → `src/permission.js`；本地 bubble、显式 permission automation 与可选 Telegram / 飞书 Lark 远程审批都可能产生真实决定\n- 桌宠的渲染/输入双窗口由 `src/pet-window-runtime.js` 统一创建和定位；浮层排序与 topmost 行为在 `src/floating-window-runtime.js` / `src/topmost-runtime.js`\n- `src/state.js` 生成的 session snapshot 是 Dashboard、HUD/Orbit 与可选通知/presence/mobile consumer 的共享合约，改字段必须检查所有消费者\n- `src/integration-sync.js` 为已安装且启用的 agent 异步同步 hooks / plugins / extensions；Codex official hooks 为 primary，JSONL 轮询保留为 fallback\n- Claude hook 恢复由 `src/claude-settings-watcher.js` 的目录 watcher + 低频只读巡检共同负责；repair 统一经过 `src/claude-hook-operations.js` 队列并复验，连续失败转 `manual-fix-required`。完整 gate、阈值与 source-missing 语义见 `docs/project/agent-runtime-architecture.md`\n- `src/agent-gate.js` 控制各 agent 的安装意图、启用状态、权限气泡开关和 wait-for-input notification 子开关\n- 设置系统主链路是 `src/prefs.js` → `src/settings-controller.js`（唯一写入者）→ `src/settings-store.js`；`settings-actions*` 负责校验和 pre-commit gates，`settings-effect-router.js` 负责 post-commit runtime effects 与广播\n- 启动时还会尝试自动安装 VS Code / Cursor terminal-focus extension，并初始化 updater\n- Remote SSH 通过 effective transport inspection 区分 ordinary parallel SSH 与 serialized transport；后者由 target-scoped coordinator 编排。远程部署只走 Settings，`scripts/remote-deploy.sh` 已 fail-fast 停用\n\n## Core Files\n\n更细的背景见 `docs/project/agent-runtime-architecture.md` 和 `docs/project/theme-state-ui.md`。\n\n| File | Responsibility |\n|------|------|\n| `src/main.js` | Electron composition root：生命周期、上下文组装与各 runtime / IPC 注册器接线 |\n| `src/server.js` + `src/server-route-state.js` + `src/server-route-permission.js` | HTTP 服务、端口发现、`/state` / `/permission` 路由 |\n| `src/agent-runtime-main.js` + `src/integration-sync.js` | local monitor / official hook 仲裁、Codex turn fence、按 gate 的集成同步 |\n| `src/state.js` | 状态机、多会话合并、优先级、自动回退、睡眠/DND |\n| `src/renderer.js` | 动画切换、SVG 预加载、眼球追踪渲染 |\n| `src/permission.js` + `src/permission-automation-policy.js` + `src/session-automation-coordinator.js` | 权限气泡、自动化策略、per-session 授权与决策回包；远程 client 由 `main.js` 注入 |\n| `src/pet-window-runtime.js` + `src/floating-window-runtime.js` + `src/topmost-runtime.js` | 双窗口 owner、浮层重排、z-order / fullscreen / focusability |\n| `src/update-bubble.js` | 更新气泡创建、测高、跟随桌宠定位，避让 HUD / permission stack |\n| `src/dashboard.js` + `src/dashboard-renderer.js` | Sessions Dashboard 窗口、会话列表、别名编辑、终端跳转 |\n| `src/session-hud.js` + `src/session-hud-renderer.js` | 桌宠旁轻量会话 HUD、折叠行、点击跳转 |\n| `src/session-alias.js` | session alias key 规范化、TTL pruning、Kiro cwd scope |\n| `src/theme-loader.js` + `src/theme-runtime.js` | stateless 主题加载/消毒与唯一 active-theme owner |\n| `src/prefs.js` | 偏好 schema、load/save/migrate/validate，设置持久化入口 |\n| `src/settings-actions*.js` + `src/settings-effect-router.js` | 设置 validators / commands / pre-commit gates 与 post-commit runtime effects |\n| `src/settings-controller.js` | 设置系统唯一写入者 |\n| `src/settings-store.js` | 不可变 snapshot store |\n| `src/settings-ui-core.js` + `src/settings-renderer.js` + `src/settings-tab-*.js` | Settings shared UI state、侧栏/tab shell 与各页逻辑 |\n| `src/menu.js` | 托盘 / 右键菜单，串起设置、Dashboard、mini mode、更新入口 |\n| `src/mini.js` | 极简模式入场、滑动、peek、状态映射 |\n| `src/tick.js` | 主循环、鼠标轮询、眼球和 idle/sleep 逻辑 |\n| `src/drag-position.js` | 拖拽落点规范化与跨显示器钳制 |\n| `src/visible-margins.js` | 可视角色边距与 edge pinning 规则 |\n| `src/updater.js` | Git 模式 / `electron-updater` 双路径更新逻辑 |\n| `src/focus.js` | 终端聚焦 |\n| `src/hit-renderer.js` + `src/hit-geometry.js` | 输入窗口命中、拖拽、连击反应 |\n| `src/remote-ssh-runtime.js` | Remote SSH tunnel/ingress 状态机、ordinary health probe、serialized readiness 与重连 |\n| `src/remote-ssh-transport.js` + `src/remote-ssh-transport-coordinator.js` | effective transport inspection、pre-spawn admission、target ownership、drain barrier 与 quarantine |\n| `src/remote-ssh-deploy.js` | Deploy / Repair、身份事务、lease/fencing、wrapper、cleanup 与远端 Codex monitor mutation |\n| `src/remote-ssh-identity.js` + `src/remote-ssh-layout.js` + `src/remote-ssh-ingress.js` | 身份/布局真相与 profile 专属、nonce 校验的本地 ingress |\n| `src/remote-ssh-node.js` + `src/remote-ssh-shell-detect.js` + `src/remote-ssh-local-config.js` | 远端 Node/ shell 探测与本机 SSH config 入口 |\n| `src/remote-ssh-profile.js` | Remote SSH profile schema、校验、默认值和持久化规范化 |\n| `src/remote-ssh-ipc.js` | Remote SSH runtime / deploy / monitor orchestration、intent policy、IPC 状态与进度广播 |\n| `src/remote-ssh-quote.js` | Remote SSH 终端命令与跨平台 shell quoting helper |\n| `agents/registry.js` | agent 注册表 |\n| `agents/codex-log-monitor.js` | Codex JSONL fallback 轮询 |\n| `agents/gemini-log-monitor.js` | legacy Gemini session JSON 轮询器；当前 Gemini hook-only 路径不启动 |\n| `hooks/dsh-install.js` | DeepSeek Harness immutable managed bridge generation、ownership verify、安装 / 修复 / 卸载事务 |\n| `hooks/clawd-hook.js` + `hooks/copilot-hook.js` | Claude Code / Copilot CLI 状态上报脚本 |\n| `hooks/install.js` | Claude hook 注册 / 卸载 |\n| `hooks/auto-start.js` | Claude `SessionStart` 自动拉起 Clawd 的 hook |\n| `hooks/codex-hook.js` / `hooks/codex-install.js` | Codex official hooks 状态与权限审批、安装 / 卸载 |\n| `hooks/cursor-install.js` / `gemini-install.js` / `antigravity-install.js` / `kiro-install.js` / `kimi-install.js` / `qwen-code-install.js` / `codewhale-install.js` / `codebuddy-install.js` / `workbuddy-install.js` / `opencode-install.js` / `pi-install.js` / `openclaw-install.js` / `hermes-install.js` / `qoder-install.js` / `qoderwork-install.js` / `reasonix-install.js` | 各 agent 集成安装逻辑 |\n| `hooks/workbuddy-hook.js` | WorkBuddy state + Notification command hook；无 session_id 时返回合法 stdout 后丢弃事件 |\n| `hooks/zcode-hook.js` / `hooks/zcode-install.js` | ZCode state-only hooks、`hooks.events.*` 增量注册与 Claude-imported Clawd hook 清理 |\n| `hooks/qoder-hook.js` | Qoder state-only 状态上报脚本（Phase 1，stdout 恒为 `{}`） |\n| `hooks/codex-remote-monitor.js` | 远程 Codex JSONL 轮询并通过 SSH 隧道回传（含 token_count 订阅配额的 metadata_only 上报） |\n| `hooks/claude-statusline.js` / `hooks/antigravity-statusline.js` | 各 CLI statusline 适配器：渲染状态行 + 把订阅配额（rate_limits）以 metadata_only POST 上报；Claude 版支持远程部署（`CLAWD_REMOTE=1` 前缀）与 `--chain` 串联模式（原 statusLine 对象保存在 `~/.claude/hooks/clawd-statusline-chain.json`，卸载时恢复） |\n| `extensions/vscode/extension.js` | VS Code / Cursor 终端 tab 聚焦辅助扩展 |\n\n## Constraints\n\n- `agents/registry.js` 的 capabilities 是权限、subagent、session-end 等路由/gate 的权威来源；不得另写名单代替 capability 判定。但 permission automation eligibility 由更窄的 `isKnownPermissionAgent()` 显式判定（`KNOWN_PERMISSION_AGENTS` + explicit opencode-family membership），不得从 `permissionApproval` 自动派生或合并回 registry capabilities\n- Claude Code / CodeBuddy 的阻塞式权限审批走 `POST /permission` HTTP hook；普通状态事件走 command hook\n- permission automation（off / auto-tools / unattended）和 per-session grant 会在 bubble 渲染前产生真实 allow/answer。agent/family eligibility 是显式白名单；工具分类则因 mode/adapter 而异：auto-tools 对 Claude/Qwen 的未知 built-in fail closed，但其他已知 adapter 不都使用逐工具白名单，unattended 还会有意自动放行可作 Allow/Deny 的未知请求。新增 agent、工具或交互类型必须审查 policy + tests，不能从 `permissionApproval` 推导资格或笼统假设“未知请求都会 defer”\n- Telegram / 飞书 Lark 与本地 bubble 是并行决策通道。远程通道超时、断连、未配置或发送失败不得产生远程决定，更不得转成 deny；有本地 bubble 时请求继续 pending，只有 remote-only 且所有可用 client 都无决定时，整体请求才 no-decision 并回到 agent 原生流程\n- WorkBuddy 通过 `~/.workbuddy/settings.json` 的 Claude Code 兼容 command hooks 做 **state + Notification only** 集成：不注册 `/permission`，审批始终留在 WorkBuddy 原生沙箱与 GUI；无 `session_id` 的事件返回合法 stdout 后直接丢弃。当前只支持 macOS/Windows 桌面应用，没有已验证的 Linux/WSL CLI；不要把裸 `Electron` 当 WorkBuddy 进程。\n- Codex 的阻塞式权限审批走 official `PermissionRequest` command hook：hook 脚本长连接 `POST /permission`，只允许 stdout 返回 sanitized `behavior/message`，`updatedInput` / `updatedPermissions` / `interrupt` 必须 omit\n- hook 脚本只允许依赖 Node 内置模块，以及同目录 `hooks/` 下、且登记在 `src/remote-ssh-deploy.js` 的 `HOOK_FILES` 部署清单中的纯 Node helper（如 `server-config.js` / `shared-process.js` / `json-utils.js` / `codex-originator.js` / `codex-subagent-fields.js` / `context-usage.js` / `state-payload-size.js` / `quota-bucket.js` / `claude-rate-limits.js` / `codex-rate-limits.js` / `antigravity-context-usage.js`）；manifest-consistency 测试强制检查依赖闭包，新增 helper 必须登记\n- CJS hook 脚本需要稳定终端 PID 时，必须复用 `hooks/shared-process.js` 的 `createPidResolver()` 及其 lifecycle context；不要复制进程树 walk 或用 `process.ppid` 简化。`getStablePid()` 只是 opencode-family plugin 的内部 resolver\n- opencode 权限不走 `permission.ask` hook，而是 event hook + reverse bridge\n- Pi 通过 `~/.pi/agent/extensions/clawd-on-desk` 的 global extension 推送状态；Clawd 对 Pi 是 **state-only**，不接管权限、不弹权限气泡，也不把 Pi 的默认 YOLO 流程改成手动确认\n- DeepSeek Harness 首发是 **web profile / Windows-first experimental / plugin-only**；packaged-app source loading smoke 已完成，API-backed session/approval smoke 未完成前不得写成 Windows-verified。Clawd-managed in-process plugin 只监听公开 `session/created`、`session/event`、`session/disposed` 与 blocking `approval/request`。状态按 session FIFO 上报并携带上游 seq；Clawd 不读取 `$DSH_HOME/storages` projection。普通审批进入独立 DSH `/permission` adapter，只支持人工 Allow Once / Deny；204 / 断连 / DND / disabled 都由 plugin `next()` 交还 DSH 原生 web answerer。`ask_user_question` 始终留在 DSH 原生 provider；DSH 不进入 `KNOWN_PERMISSION_AGENTS`，auto-tools / unattended / per-session grant 全部 DEFER。安装器通过官方 `dsh plugin --profile web add/remove` 管理 immutable marker-owned generation，foreign 同名包 fail closed；当前冻结支持 npm 发布物 `@deepseek-ai/dsh@0.1.0-rc.6`（integrity `sha512-brpZfED7ieRa2PQ5tUxMhHrM1pb2CmKFVM/f6yMULBDMicahk+Z2OsHgTwTDnoiZm23Ftu9rQz0NN4pflaoJcg==`），`47f9438` 仅是源码调查基线，不代表 rc.6 的 tag/commit 映射。\n- DSH 每个 canonical `DSH_HOME` 的 mutation lock 只有在 owner/schema/token/PID/timestamp/owner-recorded operation timeout 合法、超过该 owner timeout 两倍、且 OS PID probe 明确为 `ESRCH` 时才允许 atomic-rename takeover；live、`EPERM`、unknown、corrupt/foreign owner 一律拒绝并返回精确 lock path。canonical lock 的 owner write/release 禁止 recursive cleanup。无全局 CLI 时生成的手动 npx generation 必须先在同一锁内写 owned reference，手动 add/remove 命令必须显式 pin shell-quoted canonical `DSH_HOME`；malformed/foreign/concurrently replaced reference 一律 fail closed 并保留 generation\n- OpenClaw 通过 `~/.openclaw/openclaw.json` plugin 路径做 state-only 集成；Phase 1 不做 permission bubble / terminal focus，主要支持本地 `openclaw tui --local`\n- Antigravity CLI (agy) 通过 `~/.gemini/config/hooks.json` 做 **state-only** hook 集成（PreInvocation / PostToolUse / PostInvocation / Stop），**不注册 PreToolUse**。agy LLM 会主动调内置 `ask_permission` 工具，触发 agy 自己的 5 选项 native menu（含 \"Persist to settings.json\" 持久白名单），Clawd 不插手权限决策也不双层确认。`agents/antigravity-cli.js` `capabilities.permissionApproval` / `interactiveBubble` 均为 false。\n- Qwen Code 通过 `~/.qwen/settings.json` 做 hook-only 集成（SessionStart / SessionEnd / UserPromptSubmit / PreToolUse / PostToolUse / Stop / Notification / PermissionRequest），支持状态与阻塞式 `PermissionRequest` 权限气泡；`disableAllHooks: true` 时注册条目不会触发。\n- QwenWork (千问办公) 通过 `~/.QwenWorkCN/settings.json` 做 **hook-only / state-only** 集成（agent id `qwenwork`；SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / PostToolUseFailure / Stop / Notification / PermissionRequest / PermissionDenied / SessionEnd）。`PermissionRequest` / `PermissionDenied` 只作为观察映射成 `working`（每任务 40+ 次，映射成 notification 会刷屏），hook stdout 恒为 `{}`：Clawd 不产生 allow/deny，不注册 `/permission`，也不进入 permission automation eligibility，唯一决策者是 QwenWork 原生权限流程；`agents/qwenwork.js` 的 `capabilities.permissionApproval` / `interactiveBubble` 均为 false。Windows command 必须保持 `windowsWrapper:\"portable\"`（QwenWork 经 POSIX shell 执行 command hook），PowerShell `-EncodedCommand` **只**用于识别并原地迁移旧条目，不是当前写入形态。marker 只认 `qwenwork-hook.js`，不得仅凭 `name:\"clawd\"` 删除用户 hook；混合 entry 中第三方 hook 原样保留。session id 命名空间是 `qwenwork:<raw>`；`~/.QwenWorkCN/workspace/<id>` 这类内部工作区 cwd 不做 basename 回退，避免 HUD/Dashboard 显示内部 ID。当前真实支持平台只有 macOS / Windows 桌面端（官方下载页 https://qwenwork.cn/download 只提供 macOS 14+ / Windows 10+ / HarmonyOS 6.1+，没有 Linux 客户端），因此 `processNames.linux`、resolver linux agent name 均为空，也不进 `src/wsl-deploy.js` 的 WSL Pair 映射。桌面主进程长驻、不代表 active turn，`startupRecoveryProcessNames` 全空、无 startup recovery。安装/卸载走 Settings → Agents，或 `npm run install:qwenwork-hooks` / `npm run uninstall:qwenwork-hooks`；卸载必须同时在 `hooks/cleanup-integrations.js` 的 `MANAGED_AGENT_IDS` / `AGENT_CLEANERS` / `byAgent` 里有条目，否则 About cleanup 只会改 prefs、hook 留在磁盘上\n- ZCode 通过 `~/.zcode/cli/config.json` 的 `hooks.events.*` 做 **state-only** 集成（SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / PostToolUseFailure / Stop），不注册 PermissionRequest，stdout 恒为 `{}`。配置必须有 `hooks.enabled=true` 才会执行；安装器只在该字段缺失时补 true，显式 `hooks.enabled=false` 或 Clawd 单项 hook 的 `enabled=false` 必须保留，Doctor warning 且不提供会覆盖用户选择的 Fix。ZCode 导入 Claude 配置后，只清理 `.zcode` 中明确引用 `clawd-hook.js` 的 Clawd-owned 条目，绝不改 `~/.claude/settings.json`\n- Qoder 通过 `~/.qoder/settings.json` 做 **state-only** hook 集成。Clawd 只把 `PermissionRequest` / `PermissionDenied` 当 notification 观察，**不替 Qoder 做权限决策**，hook stdout 恒为 `{}`，由 Qoder 原生权限流程接管；Windows command 必须保持 `windowsWrapper:\"portable\"`，旧 PowerShell encoded 条目只做 Clawd-owned 原地迁移。session id 命名空间是 `qoder:<raw>`；启动恢复只认 CLI 进程 `qodercli` / `qoder-cli`，不认 IDE 进程 `qoder.exe`\n- HTTP 服务端口范围固定为 `127.0.0.1:23333-23337`；运行时端口写入 `~/.clawd/runtime.json`\n- 自定义 HTTP Agent 的 sender 必须读取 `~/.clawd/runtime.json`，不能把 23333 写死；注册不等于已连接。custom v1 只支持 `/state`，不支持 `/permission`\n- CodeBuddy PermissionRequest hook 的所有权只认本机 managed URL 或 marker `clawd-on-desk.permission.v1`；纯 `name:\"clawd\"` 不能触发改写/删除。裸 CLI 和 WSL 默认 preserve，Settings/startup/repair 必须显式传 local/custom permission target\n- Remote SSH 的远端 Node 探测要求 Node >= 14；Node discovery/version validation 只在 `src/remote-ssh-node.js`，ordinary tunnel health 与 serialized readiness 在 `src/remote-ssh-runtime.js`，不得互相复制或从已停用脚本另起实现\n- 注册 Claude Code hook 必须 marker-scoped merge：只可更新/删除含 `clawd-hook.js` / `auto-start.js` marker 的 Clawd-owned entry，不得整体覆盖数组或改动无 marker 的用户 entry\n- 注册 Claude Code statusLine 时只接管空槽或自己的槽（marker `claude-statusline.js`）；远程部署可用 profile 的 `chainStatusline` opt-in 串联既有第三方 statusline（`--chain-existing`），显式关闭时必须从 sidecar 恢复原 statusLine。订阅配额通过 `metadata_only` POST 进入 session-independent `updateAccountQuota` per-source store；不要把 quota 塞进 `updateSession` opts，也不要以 session 存活作为摄入前提\n- Copilot CLI hooks 走按需自动同步：`hooks/copilot-install.js` 在本地启动仅当 Copilot CLI 已安装且已启用时调用；远端由 Settings Remote SSH deploy controller 调用。路径解析尊重 `COPILOT_HOME` env（trimmed 非空才生效，否则 fallback 到 `~/.copilot`）；`hooks/copilot-hook.js` 的 session-state resolver 同样走 env\n- Remote SSH 的 effective transport 由 `ssh -G` 只读检查决定：ordinary SSH 在没有 retained serialized occupancy 时保持 `context:null` 的 parallel 路径；serialized transport 以有效 target key（不是 profile id）互斥。所有 serialized managed SSH/SCP child 必须持 coordinator 发出的有效 connection/operation context，并通过其 pre-spawn gateway 启动；用户交互终端只有命中 serialized/retained occupancy 时才要求 coordinator 判定 target 完全 idle\n- serialized persistent tunnel 使用同一条 SSH 内嵌 readiness；暂停通过 stdin EOF 请求自然退出并等待 `close`。强杀或带 signal 的 outer `ssh.exe` close 不能证明 nested ProxyCommand 已 drain；timeout/未验证 drain 必须 quarantine，期间禁止新 child、mutation、resume 或 interactive terminal\n- mutation 在 deploy-lock acquire-attempted / lock-owned 后遇到 exit 255、EOF/reset、signal 或其他 unknown result 时不得自动 replay、retry、release lock 或恢复连接；必须保留 primary error 并传播 recovery state，必要时要求 `manual_lock_inspection_required`\n- Remote SSH secure hook 必须同时携带 `CLAWD_REMOTE=1` 与 `CLAWD_SSH_REMOTE=1`，只读 layout identity 并 pin 精确端口；identity 缺失/损坏/不可读必须 fail closed，禁止回退端口扫描\n- Remote SSH deploy-lock acquisition 必须原子化；成功 acquire 后的每个 live mutation 都要在同一远端命令内 fencing 校验，cleanup 还必须锁内重读 installId/profileId/runtimeKey/layoutVersion 所有权。无身份、冲突、ownerless/corrupt lock 均不得自动接管\n- 默认 `account-default` 只支持不同 Unix 账号；同 Unix 账号冲突必须阻止。`profile-isolated` 在真实 SSH/CLI 矩阵完成前由 `CLAWD_ENABLE_EXPERIMENTAL_REMOTE_ISOLATION=1` 发布门隐藏；它只隔离用户级 CLI config/session/runtime 与 Clawd 路由，不代表完整 HOME 或同 UID 安全隔离，project 配置/部分 cache/macOS Claude Keychain auth 仍可能共享\n- 禁用 agent 不应卸载 hooks / plugins / extensions：只停止对应 monitor、清理 session / bubble、让 HTTP hook 入口快速 fallback；重新启用未安装 agent 不触发本机 integration sync。卸载集成必须走 Settings Agent 页的 Uninstall / 对应 uninstall 命令，并同时清掉 `integrationInstalled`\n- Kiro 的 `sessionId=\"default\"` 会复用；session alias key 必须按 cwd scope 区分，同时保留旧 `local|kiro-cli|default` 只读 fallback\n- Windows NSIS release 必须产出明确架构的 x64 / ARM64 安装包：`win.artifactName` 保留 `${arch}`，`nsis.buildUniversalInstaller` 保持 `false`\n- 每个 release target 只能保留一个匹配目标架构的 Koffi `koffi.node`；`afterPack` 只允许剪裁 `app.asar.unpacked` 的物理文件，禁止重写 `app.asar`，并必须通过完整 native inventory audit（唯一常设例外是 electron-builder 管理的 Windows ia32 `resources/elevate.exe`）\n- 资源路径统一用 `path.join(__dirname, ...)`\n- 需要编辑发布素材时，先复制到 `assets/source/` 再改，不要直接改工作素材来源不明的文件\n- `assets/source/cloudling-pointer-bridge/` 是 Cloudling 指针桥素材的保留源文件目录；运行时逻辑已内联进主题 SVG，不要把这个 source 目录当临时文件清理\n- 主题状态、sleep/DND、mini mode、状态映射的细节在 `docs/project/theme-state-ui.md`\n- Settings 体系里，store 是唯一真相，controller 是唯一写入者；不要绕开 `settings-controller.js`\n\n## Testing\n\n- 自动化测试使用 Node 内置 test runner：`npm test`\n- `test/*.test.js` 覆盖核心 unit/contract、installer、route、UI/runtime 与 Remote SSH transport/coordinator/identity；部分 fixture 会启动 Node、shell 或 Git Bash 子进程，缺少依赖时可能 skip，不能把全套结果概括成纯逻辑或等价真机验证\n- Remote SSH 真机矩阵与记录在 `scripts/manual/README.md`；Windows OpenSSH + Codespaces stdio 边界及 ordinary-host V15 release gate 不能从 unit tests 互相推断，无法执行时必须明确记录 pending / residual risk\n- Windows Terminal 真机、GUI smoke 与清理必须假定多个 tab/window 共享进程：不得按 PID/进程名 `taskkill`、`Stop-Process` 或宽泛终止 WindowsTerminal、Codex、`cmd.exe`、`ssh.exe`、OpenConsole、conhost。测试终端只能在明确 test-owned session 内 `exit`；无法证明 ownership 就保留现场并请用户手动关闭\n- 当前开发环境是 Windows-first；macOS 特定路径无法在这里手动 QA，改到 mac 逻辑时要用 code-review-first 的方式说明行为变化和残余风险\n- 涉及 Claude Code hook payload 的改动（尤其 `/permission`、`permission_suggestions`、`updatedPermissions`、elicitation 输入）至少用一次真实 Claude Code 验证；`curl` 自编 payload 不够\n- 透明窗口、托盘、真实拖拽、跨平台前台聚焦等 Electron 行为仍以手动验证为主\n\n## High-Risk Gotchas\n\n- `src/pet-window-runtime.js` 的 `hitWin` 必须在 Windows/macOS 保持 focusable（当前为 `focusable: !isLinux`），不要把 Windows 拖拽修复改回去\n- `miniTransitioning` 期间，所有窗口定位路径都必须先检查保护标志，否则 `setPosition()` 可能并发崩\n- DND 会屏蔽 hook 事件并压住 bubble，但**不应替用户做权限决定**：opencode 走 silent drop 回到 TUI 提示，Claude Code / CodeBuddy 走断连回到内置聊天/终端确认，Codex official hook 走 no-decision `{}` 回到原生审批提示；Pi 是 state-only，不进入权限审批链路\n- 隐藏桌宠（petHidden）≠ 免打扰：隐藏只收起宠物/HUD/update bubble/当时 pending 的权限气泡，**隐藏期间新到的权限请求仍照常弹气泡，这是有意设计、不要当 bug 修**；要静默权限气泡走 DND（见上条）。详见 `docs/project/theme-state-ui.md` State Machine 节\n- Session HUD 显示所有非 headless、非 sleeping 的 live session，包括 badge=Done 的 idle session；不要再按 `state !== \"idle\"` 过滤，否则完成后的 Claude Code 会话会从 HUD 消失\n- update bubble 跟随桌宠时要同时避让 Session HUD 和 permission stack；permission bubble 增删、测高、deny-and-focus 后都要触发 update bubble 重排\n- `mini-working` 是可选主题能力，缺失时必须优雅降级\n- `contextMenuOwner` 必须保留 `parent: win`；配合 `closable:false` 才不会把退出流程卡死\n- Windows 前台窗口锁与 process-query 路径依赖 ALT trick + `koffi` FFI；同一 Koffi registry 的 named structs/bindings 必须复用既有缓存，不要重复注册，相关回归通常不是单点逻辑 bug\n- `~/.claude/settings.json` 的 hook 恢复 watcher 必须盯目录而不是文件；原子替换会让文件级 watch 在 Windows 上静默失效\n- Claude watcher 必须同时受 `manageClaudeHooksAutomatically`、`claude-code.integrationInstalled` 和 `claude-code.enabled` 保护；不要让未安装或禁用 Claude Code 后的 watcher 重新写回 hooks\n- 所有进程内对 `~/.claude/settings.json` 的 mutation（启动 reconcile、watcher 自动恢复、周期健康自愈、Settings Install/Enable、Doctor Fix、auto-start 开关、卸载、About 清理）必须经过 `src/claude-hook-operations.js` 的 server-owned 队列；不要绕开队列直接 `require(\"../hooks/install.js\")` 写文件，否则会与其他来源的写入竞态\n- 周期健康巡检（`src/claude-settings-watcher.js`）只读判断用 `src/claude-hook-health.js`；同一 repair signature 连续 3 次修复+复验失败后必须停在 `manual-fix-required`，不再自动 mutation，只保留 5 分钟只读复查；suspicious-shrink 通知同一持续问题只弹一次，不要每轮重复\n- opencode 的 `permission.ask` hook 目前不可用，权限只能走 event hook + bridge\n- Codex CLI official hooks 已接入；JSONL 轮询仍是 fallback，用于 hook 不可用、hook 未覆盖事件（如 WebSearch / compaction / abort）和历史兼容。Windows `commandWindows` 由 PowerShell 解析：legacy 直接命令必须用 `& \"node\" ...` call operator；本机 stable 入口必须保持“固定内联 PowerShell dispatcher → UTF-8/Base64 `codex-hook.js.windows.run` 数据 sidecar → `& $node $target`”形态（JSON manifest 只供 Doctor），不得改回裸 `\"node\" \"hook.js\"`（会 exit 1）、二次 `powershell.exe -File` 或无 BOM `.ps1`\n- Kiro 没有 global hooks，只能注入到 `~/.kiro/agents/*.json`\n- `src/renderer.js` 里给 `<img>` SVG 追加的 `?_t=` cache-bust query 不能删；Chromium 会复用同 URL SVG 的动画时间线，一次性动画会停在末帧\n\n## Do Not Revisit\n\nLanguage 子菜单底部截断是 Electron 透明窗口 + Windows DWM 的底层兼容问题。不要再尝试通过切换 `alwaysOnTop`、透明窗策略或 JS 菜单布局修它。\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nThis file is the entry point for coding agents working in this repository. Keep it short and operational. Durable architecture lives in `docs/project/`; `docs/plans/` and `docs/investigations/` are historical evidence unless this file explicitly links them.\n\n## Project Overview\n\nClawd 是一个 Electron 桌宠：通过 hook、日志轮询、plugin 和 extension 感知 AI coding agent 的工作状态，并播放像素风动画。当前支持 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、DeepSeek Harness；内置 Clawd / Calico / Cloudling 三套主题，支持用户主题；平台覆盖 Windows、macOS、Linux，UI 支持 en / zh / zh-TW / ko / ja / pt-BR。\n\n## Common Commands\n\n```bash\nnpm start\nnpm run build                  # default Windows package\nnpm run build:win:x64\nnpm run build:win:arm64\nnpm run build:win:all\nnpm run build:mac\nnpm run build:linux\nnpm run build:all\nnpm install\nnpm test\nnpm run verify:electron\nnpm run verify:release\nnpm run audit:assets\nnpm run audit:native-package -- --app-root <extracted-app-root> --target <target-id>\nnpm run create-theme\n\nnpm run install:claude-hooks\nnpm run uninstall:claude-hooks\nnpm run install:cursor-hooks\nnpm run install:gemini-hooks\nnpm run install:antigravity-hooks\nnpm run install:kiro-hooks\nnpm run install:kimi-hooks\nnpm run install:qwen-hooks\nnpm run install:zcode-hooks\nnpm run uninstall:zcode-hooks\nnpm run install:codewhale-hooks\nnpm run uninstall:codewhale-hooks\nnpm run install:pi-extension\nnpm run uninstall:pi-extension\nnpm run install:openclaw-plugin\nnpm run uninstall:openclaw-plugin\nnpm run install:hermes-plugin\nnpm run uninstall:hermes-plugin\nnpm run install:qoder-hooks\nnpm run uninstall:qoder-hooks\nnpm run install:qoderwork-hooks\nnpm run uninstall:qoderwork-hooks\nnpm run install:qwenwork-hooks\nnpm run uninstall:qwenwork-hooks\nnpm run install:reasonix-hooks\nnpm run uninstall:reasonix-hooks\nnpm run install:workbuddy-hooks\nnpm run uninstall:workbuddy-hooks\nnpm run install:dsh\nnpm run uninstall:dsh\nnpm run install:codex-hooks\nnpm run uninstall:codex-hooks\nnpm run install:codex-debug-hooks\nnpm run uninstall:codex-debug-hooks\nnpm run install:mimocode-plugin\nnpm run uninstall:mimocode-plugin\nnode hooks/codebuddy-install.js\nnode hooks/opencode-install.js\n\nbash test-demo.sh [seconds]\nbash test-mini.sh [seconds]\nbash test-macos.sh\nbash test-oneshot-gate.sh [state] [seconds]\n```\n\n新安装默认只把 Claude Code 和 Codex 标记为已安装并启用；其他 agent 默认未安装、未启用。正常启动时，Clawd 只会为 `integrationInstalled=true` 且 `enabled=true` 的 agent 自动同步 Claude / Codex / Copilot / Gemini / Antigravity / Cursor / CodeBuddy / WorkBuddy / Kiro / Kimi / Qwen / ZCode / CodeWhale / Qoder / QoderWork / QwenWork / Reasonix hooks、opencode / MiMo Code / OpenClaw / Hermes plugins 和 Pi extension。Settings Agent 页的 Install 会安装并启用该集成；Uninstall 会卸载 Clawd 管理的 hook/plugin/extension，并同时把该 agent 设为未安装、未启用。单独关闭 enabled 只会跳过启动同步并屏蔽事件/权限入口，不卸载用户已有 hooks / plugins / extensions；重新启用未安装 agent 只打开事件入口，不会写本机集成文件。手动安装命令主要用于调试、重装或远程部署。\nSettings 注册的自定义 HTTP Agent 是独立模型：`customApplications` 是注册真相，对应 `agents[customId]` 必须显式保持 `integrationInstalled=false`。注册只分配 ID 和状态入口，不安装 hook、不观察进程；v1 仅允许已注册且启用的 ID 向 `/state` 上报，`/permission` 永远不提供决定。删除或伪造的 `custom-` ID 必须直接拒绝，不能降级成 Claude Code subagent。\nCopilot CLI 同步走 `<COPILOT_HOME 或 ~/.copilot>/hooks/hooks.json`，marker-based 增量合并只接管含 `copilot-hook.js` 标记的条目，用户其他 entry / 其他 `hooks/*.json` 文件原样保留；hooks.json 或 `settings.json` 顶层 `disableAllHooks: true` 时 doctor 报 warning（不挂 Fix 按钮）。详见 `docs/guides/copilot-setup.md`。\n\n## Read These Docs\n\n- `docs/project/agent-runtime-architecture.md`：运行时架构、模块边界、启动与数据流、多 agent、permission bubble、终端聚焦和自动同步\n- `docs/project/theme-state-ui.md`：状态机、主题系统、settings、mini mode、素材规则、平台限制、待落地 UI 决策\n- `docs/project/release-process.md`：发版 checklist、release note 核对、tag 触发 GitHub 打包和资产确认\n- `docs/guides/copilot-setup.md`：Copilot CLI 自动同步说明、`COPILOT_HOME` 兼容性、手动配置备选模板\n- `docs/guides/dsh-setup.md`：DeepSeek Harness web profile 实验性 plugin-only 状态与普通审批集成\n- `docs/guides/state-mapping.md`：状态 → 动画权威表\n- `docs/guides/guide-theme-creation.md`：主题作者指南\n- `docs/guides/setup-guide.md`：安装、远程 SSH、各 agent 接入\n- `docs/guides/custom-agent-http.md`：自定义 HTTP Agent 的 state-only 接入合约和动态端口发现\n- `docs/guides/known-limitations.md`：用户向已知限制\n- `docs/guides/codex-wsl-clarification.md`：Codex / WSL 路径与 Node 说明\n- `docs/guides/guide-remote-ssh.md`：Remote SSH 用户流程、Codespaces 单会话 transport 与共享主机边界\n- `docs/guides/telegram-approval.md` / `docs/guides/feishu-lark-remote-approval.md`：远程审批设置与失败回退语义\n- `docs/guides/roam-fence.md`：自由漫游与可选围栏\n\n## Runtime Summary\n\n- HTTP hook / plugin 主路径：`src/server.js` → `src/server-route-state.js` → `src/agent-runtime-main.js` → `src/state.js` → IPC；本地 JSONL monitor 直接进入 `agent-runtime-main`，不经过 HTTP server\n- 权限主路径：`src/server-route-permission.js` → `src/permission.js`；本地 bubble、显式 permission automation 与可选 Telegram / 飞书 Lark 远程审批都可能产生真实决定\n- 桌宠的渲染/输入双窗口由 `src/pet-window-runtime.js` 统一创建和定位；浮层排序与 topmost 行为在 `src/floating-window-runtime.js` / `src/topmost-runtime.js`\n- `src/state.js` 生成的 session snapshot 是 Dashboard、HUD/Orbit 与可选通知/presence/mobile consumer 的共享合约，改字段必须检查所有消费者\n- `src/integration-sync.js` 为已安装且启用的 agent 异步同步 hooks / plugins / extensions；Codex official hooks 为 primary，JSONL 轮询保留为 fallback\n- Claude hook 恢复由 `src/claude-settings-watcher.js` 的目录 watcher + 低频只读巡检共同负责；repair 统一经过 `src/claude-hook-operations.js` 队列并复验，连续失败转 `manual-fix-required`。完整 gate、阈值与 source-missing 语义见 `docs/project/agent-runtime-architecture.md`\n- `src/agent-gate.js` 控制各 agent 的安装意图、启用状态、权限气泡开关和 wait-for-input notification 子开关\n- 设置系统主链路是 `src/prefs.js` → `src/settings-controller.js`（唯一写入者）→ `src/settings-store.js`；`settings-actions*` 负责校验和 pre-commit gates，`settings-effect-router.js` 负责 post-commit runtime effects 与广播\n- 启动时还会尝试自动安装 VS Code / Cursor terminal-focus extension，并初始化 updater\n- Remote SSH 通过 effective transport inspection 区分 ordinary parallel SSH 与 serialized transport；后者由 target-scoped coordinator 编排。远程部署只走 Settings，`scripts/remote-deploy.sh` 已 fail-fast 停用\n\n## Core Files\n\n更细的背景见 `docs/project/agent-runtime-architecture.md` 和 `docs/project/theme-state-ui.md`。\n\n| File | Responsibility |\n|------|------|\n| `src/main.js` | Electron composition root：生命周期、上下文组装与各 runtime / IPC 注册器接线 |\n| `src/server.js` + `src/server-route-state.js` + `src/server-route-permission.js` | HTTP 服务、端口发现、`/state` / `/permission` 路由 |\n| `src/agent-runtime-main.js` + `src/integration-sync.js` | local monitor / official hook 仲裁、Codex turn fence、按 gate 的集成同步 |\n| `src/state.js` | 状态机、多会话合并、优先级、自动回退、睡眠/DND |\n| `src/renderer.js` | 动画切换、SVG 预加载、眼球追踪渲染 |\n| `src/permission.js` + `src/permission-automation-policy.js` + `src/session-automation-coordinator.js` | 权限气泡、自动化策略、per-session 授权与决策回包；远程 client 由 `main.js` 注入 |\n| `src/pet-window-runtime.js` + `src/floating-window-runtime.js` + `src/topmost-runtime.js` | 双窗口 owner、浮层重排、z-order / fullscreen / focusability |\n| `src/update-bubble.js` | 更新气泡创建、测高、跟随桌宠定位，避让 HUD / permission stack |\n| `src/dashboard.js` + `src/dashboard-renderer.js` | Sessions Dashboard 窗口、会话列表、别名编辑、终端跳转 |\n| `src/session-hud.js` + `src/session-hud-renderer.js` | 桌宠旁轻量会话 HUD、折叠行、点击跳转 |\n| `src/session-alias.js` | session alias key 规范化、TTL pruning、Kiro cwd scope |\n| `src/theme-loader.js` + `src/theme-runtime.js` | stateless 主题加载/消毒与唯一 active-theme owner |\n| `src/prefs.js` | 偏好 schema、load/save/migrate/validate，设置持久化入口 |\n| `src/settings-actions*.js` + `src/settings-effect-router.js` | 设置 validators / commands / pre-commit gates 与 post-commit runtime effects |\n| `src/settings-controller.js` | 设置系统唯一写入者 |\n| `src/settings-store.js` | 不可变 snapshot store |\n| `src/settings-ui-core.js` + `src/settings-renderer.js` + `src/settings-tab-*.js` | Settings shared UI state、侧栏/tab shell 与各页逻辑 |\n| `src/menu.js` | 托盘 / 右键菜单，串起设置、Dashboard、mini mode、更新入口 |\n| `src/mini.js` | 极简模式入场、滑动、peek、状态映射 |\n| `src/tick.js` | 主循环、鼠标轮询、眼球和 idle/sleep 逻辑 |\n| `src/drag-position.js` | 拖拽落点规范化与跨显示器钳制 |\n| `src/visible-margins.js` | 可视角色边距与 edge pinning 规则 |\n| `src/updater.js` | Git 模式 / `electron-updater` 双路径更新逻辑 |\n| `src/focus.js` | 终端聚焦 |\n| `src/hit-renderer.js` + `src/hit-geometry.js` | 输入窗口命中、拖拽、连击反应 |\n| `src/remote-ssh-runtime.js` | Remote SSH tunnel/ingress 状态机、ordinary health probe、serialized readiness 与重连 |\n| `src/remote-ssh-transport.js` + `src/remote-ssh-transport-coordinator.js` | effective transport inspection、pre-spawn admission、target ownership、drain barrier 与 quarantine |\n| `src/remote-ssh-deploy.js` | Deploy / Repair、身份事务、lease/fencing、wrapper、cleanup 与远端 Codex monitor mutation |\n| `src/remote-ssh-identity.js` + `src/remote-ssh-layout.js` + `src/remote-ssh-ingress.js` | 身份/布局真相与 profile 专属、nonce 校验的本地 ingress |\n| `src/remote-ssh-node.js` + `src/remote-ssh-shell-detect.js` + `src/remote-ssh-local-config.js` | 远端 Node/ shell 探测与本机 SSH config 入口 |\n| `src/remote-ssh-profile.js` | Remote SSH profile schema、校验、默认值和持久化规范化 |\n| `src/remote-ssh-ipc.js` | Remote SSH runtime / deploy / monitor orchestration、intent policy、IPC 状态与进度广播 |\n| `src/remote-ssh-quote.js` | Remote SSH 终端命令与跨平台 shell quoting helper |\n| `agents/registry.js` | agent 注册表 |\n| `agents/codex-log-monitor.js` | Codex JSONL fallback 轮询 |\n| `agents/gemini-log-monitor.js` | legacy Gemini session JSON 轮询器；当前 Gemini hook-only 路径不启动 |\n| `hooks/dsh-install.js` | DeepSeek Harness immutable managed bridge generation、ownership verify、安装 / 修复 / 卸载事务 |\n| `hooks/clawd-hook.js` + `hooks/copilot-hook.js` | Claude Code / Copilot CLI 状态上报脚本 |\n| `hooks/install.js` | Claude hook 注册 / 卸载 |\n| `hooks/auto-start.js` | Claude `SessionStart` 自动拉起 Clawd 的 hook |\n| `hooks/codex-hook.js` / `hooks/codex-install.js` | Codex official hooks 状态与权限审批、安装 / 卸载 |\n| `hooks/cursor-install.js` / `gemini-install.js` / `antigravity-install.js` / `kiro-install.js` / `kimi-install.js` / `qwen-code-install.js` / `codewhale-install.js` / `codebuddy-install.js` / `workbuddy-install.js` / `opencode-install.js` / `pi-install.js` / `openclaw-install.js` / `hermes-install.js` / `qoder-install.js` / `qoderwork-install.js` / `reasonix-install.js` | 各 agent 集成安装逻辑 |\n| `hooks/workbuddy-hook.js` | WorkBuddy state + Notification command hook；无 session_id 时返回合法 stdout 后丢弃事件 |\n| `hooks/zcode-hook.js` / `hooks/zcode-install.js` | ZCode state-only hooks、`hooks.events.*` 增量注册与 Claude-imported Clawd hook 清理 |\n| `hooks/qoder-hook.js` | Qoder state-only 状态上报脚本（Phase 1，stdout 恒为 `{}`） |\n| `hooks/codex-remote-monitor.js` | 远程 Codex JSONL 轮询并通过 SSH 隧道回传（含 token_count 订阅配额的 metadata_only 上报） |\n| `hooks/claude-statusline.js` / `hooks/antigravity-statusline.js` | 各 CLI statusline 适配器：渲染状态行 + 把订阅配额（rate_limits）以 metadata_only POST 上报；Claude 版支持远程部署（`CLAWD_REMOTE=1` 前缀）与 `--chain` 串联模式（原 statusLine 对象保存在 `~/.claude/hooks/clawd-statusline-chain.json`，卸载时恢复） |\n| `extensions/vscode/extension.js` | VS Code / Cursor 终端 tab 聚焦辅助扩展 |\n\n## Constraints\n\n- `agents/registry.js` 的 capabilities 是权限、subagent、session-end 等路由/gate 的权威来源；不得另写名单代替 capability 判定。但 permission automation eligibility 由更窄的 `isKnownPermissionAgent()` 显式判定（`KNOWN_PERMISSION_AGENTS` + explicit opencode-family membership），不得从 `permissionApproval` 自动派生或合并回 registry capabilities\n- Claude Code / CodeBuddy 的阻塞式权限审批走 `POST /permission` HTTP hook；普通状态事件走 command hook\n- permission automation（off / auto-tools / unattended）和 per-session grant 会在 bubble 渲染前产生真实 allow/answer。agent/family eligibility 是显式白名单；工具分类则因 mode/adapter 而异：auto-tools 对 Claude/Qwen 的未知 built-in fail closed，但其他已知 adapter 不都使用逐工具白名单，unattended 还会有意自动放行可作 Allow/Deny 的未知请求。新增 agent、工具或交互类型必须审查 policy + tests，不能从 `permissionApproval` 推导资格或笼统假设“未知请求都会 defer”\n- Telegram / 飞书 Lark 与本地 bubble 是并行决策通道。远程通道超时、断连、未配置或发送失败不得产生远程决定，更不得转成 deny；有本地 bubble 时请求继续 pending，只有 remote-only 且所有可用 client 都无决定时，整体请求才 no-decision 并回到 agent 原生流程\n- WorkBuddy 通过 `~/.workbuddy/settings.json` 的 Claude Code 兼容 command hooks 做 **state + Notification only** 集成：不注册 `/permission`，审批始终留在 WorkBuddy 原生沙箱与 GUI；无 `session_id` 的事件返回合法 stdout 后直接丢弃。当前只支持 macOS/Windows 桌面应用，没有已验证的 Linux/WSL CLI；不要把裸 `Electron` 当 WorkBuddy 进程。\n- Codex 的阻塞式权限审批走 official `PermissionRequest` command hook：hook 脚本长连接 `POST /permission`，只允许 stdout 返回 sanitized `behavior/message`，`updatedInput` / `updatedPermissions` / `interrupt` 必须 omit\n- hook 脚本只允许依赖 Node 内置模块，以及同目录 `hooks/` 下、且登记在 `src/remote-ssh-deploy.js` 的 `HOOK_FILES` 部署清单中的纯 Node helper（如 `server-config.js` / `shared-process.js` / `json-utils.js` / `codex-originator.js` / `codex-subagent-fields.js` / `context-usage.js` / `state-payload-size.js` / `quota-bucket.js` / `claude-rate-limits.js` / `codex-rate-limits.js` / `antigravity-context-usage.js`）；manifest-consistency 测试强制检查依赖闭包，新增 helper 必须登记\n- CJS hook 脚本需要稳定终端 PID 时，必须复用 `hooks/shared-process.js` 的 `createPidResolver()` 及其 lifecycle context；不要复制进程树 walk 或用 `process.ppid` 简化。`getStablePid()` 只是 opencode-family plugin 的内部 resolver\n- opencode 权限不走 `permission.ask` hook，而是 event hook + reverse bridge\n- Pi 通过 `~/.pi/agent/extensions/clawd-on-desk` 的 global extension 推送状态；Clawd 对 Pi 是 **state-only**，不接管权限、不弹权限气泡，也不把 Pi 的默认 YOLO 流程改成手动确认\n- DeepSeek Harness 首发是 **web profile / Windows-first experimental / plugin-only**；packaged-app source loading smoke 已完成，API-backed session/approval smoke 未完成前不得写成 Windows-verified。Clawd-managed in-process plugin 只监听公开 `session/created`、`session/event`、`session/disposed` 与 blocking `approval/request`。状态按 session FIFO 上报并携带上游 seq；Clawd 不读取 `$DSH_HOME/storages` projection。普通审批进入独立 DSH `/permission` adapter，只支持人工 Allow Once / Deny；204 / 断连 / DND / disabled 都由 plugin `next()` 交还 DSH 原生 web answerer。`ask_user_question` 始终留在 DSH 原生 provider；DSH 不进入 `KNOWN_PERMISSION_AGENTS`，auto-tools / unattended / per-session grant 全部 DEFER。安装器通过官方 `dsh plugin --profile web add/remove` 管理 immutable marker-owned generation，foreign 同名包 fail closed；当前冻结支持 npm 发布物 `@deepseek-ai/dsh@0.1.0-rc.6`（integrity `sha512-brpZfED7ieRa2PQ5tUxMhHrM1pb2CmKFVM/f6yMULBDMicahk+Z2OsHgTwTDnoiZm23Ftu9rQz0NN4pflaoJcg==`），`47f9438` 仅是源码调查基线，不代表 rc.6 的 tag/commit 映射。\n- DSH 每个 canonical `DSH_HOME` 的 mutation lock 只有在 owner/schema/token/PID/timestamp/owner-recorded operation timeout 合法、超过该 owner timeout 两倍、且 OS PID probe 明确为 `ESRCH` 时才允许 atomic-rename takeover；live、`EPERM`、unknown、corrupt/foreign owner 一律拒绝并返回精确 lock path。canonical lock 的 owner write/release 禁止 recursive cleanup。无全局 CLI 时生成的手动 npx generation 必须先在同一锁内写 owned reference，手动 add/remove 命令必须显式 pin shell-quoted canonical `DSH_HOME`；malformed/foreign/concurrently replaced reference 一律 fail closed 并保留 generation\n- OpenClaw 通过 `~/.openclaw/openclaw.json` plugin 路径做 state-only 集成；Phase 1 不做 permission bubble / terminal focus，主要支持本地 `openclaw tui --local`\n- Antigravity CLI (agy) 通过 `~/.gemini/config/hooks.json` 做 **state-only** hook 集成（PreInvocation / PostToolUse / PostInvocation / Stop），**不注册 PreToolUse**。agy LLM 会主动调内置 `ask_permission` 工具，触发 agy 自己的 5 选项 native menu（含 \"Persist to settings.json\" 持久白名单），Clawd 不插手权限决策也不双层确认。`agents/antigravity-cli.js` `capabilities.permissionApproval` / `interactiveBubble` 均为 false。\n- Qwen Code 通过 `~/.qwen/settings.json` 做 hook-only 集成（SessionStart / SessionEnd / UserPromptSubmit / PreToolUse / PostToolUse / Stop / Notification / PermissionRequest），支持状态与阻塞式 `PermissionRequest` 权限气泡；`disableAllHooks: true` 时注册条目不会触发。\n- QwenWork (千问办公) 通过 `~/.QwenWorkCN/settings.json` 做 **hook-only / state-only** 集成（agent id `qwenwork`；SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / PostToolUseFailure / Stop / Notification / PermissionRequest / PermissionDenied / SessionEnd）。`PermissionRequest` / `PermissionDenied` 只作为观察映射成 `working`（每任务 40+ 次，映射成 notification 会刷屏），hook stdout 恒为 `{}`：Clawd 不产生 allow/deny，不注册 `/permission`，也不进入 permission automation eligibility，唯一决策者是 QwenWork 原生权限流程；`agents/qwenwork.js` 的 `capabilities.permissionApproval` / `interactiveBubble` 均为 false。Windows command 必须保持 `windowsWrapper:\"portable\"`（QwenWork 经 POSIX shell 执行 command hook），PowerShell `-EncodedCommand` **只**用于识别并原地迁移旧条目，不是当前写入形态。marker 只认 `qwenwork-hook.js`，不得仅凭 `name:\"clawd\"` 删除用户 hook；混合 entry 中第三方 hook 原样保留。session id 命名空间是 `qwenwork:<raw>`；`~/.QwenWorkCN/workspace/<id>` 这类内部工作区 cwd 不做 basename 回退，避免 HUD/Dashboard 显示内部 ID。当前真实支持平台只有 macOS / Windows 桌面端（官方下载页 https://qwenwork.cn/download 只提供 macOS 14+ / Windows 10+ / HarmonyOS 6.1+，没有 Linux 客户端），因此 `processNames.linux`、resolver linux agent name 均为空，也不进 `src/wsl-deploy.js` 的 WSL Pair 映射。桌面主进程长驻、不代表 active turn，`startupRecoveryProcessNames` 全空、无 startup recovery。安装/卸载走 Settings → Agents，或 `npm run install:qwenwork-hooks` / `npm run uninstall:qwenwork-hooks`；卸载必须同时在 `hooks/cleanup-integrations.js` 的 `MANAGED_AGENT_IDS` / `AGENT_CLEANERS` / `byAgent` 里有条目，否则 About cleanup 只会改 prefs、hook 留在磁盘上\n- ZCode 通过 `~/.zcode/cli/config.json` 的 `hooks.events.*` 做 **state-only** 集成（SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / PostToolUseFailure / Stop），不注册 PermissionRequest，stdout 恒为 `{}`。配置必须有 `hooks.enabled=true` 才会执行；安装器只在该字段缺失时补 true，显式 `hooks.enabled=false` 或 Clawd 单项 hook 的 `enabled=false` 必须保留，Doctor warning 且不提供会覆盖用户选择的 Fix。ZCode 导入 Claude 配置后，只清理 `.zcode` 中明确引用 `clawd-hook.js` 的 Clawd-owned 条目，绝不改 `~/.claude/settings.json`\n- Qoder 通过 `~/.qoder/settings.json` 做 **state-only** hook 集成。Clawd 只把 `PermissionRequest` / `PermissionDenied` 当 notification 观察，**不替 Qoder 做权限决策**，hook stdout 恒为 `{}`，由 Qoder 原生权限流程接管；Windows command 必须保持 `windowsWrapper:\"portable\"`，旧 PowerShell encoded 条目只做 Clawd-owned 原地迁移。session id 命名空间是 `qoder:<raw>`；启动恢复只认 CLI 进程 `qodercli` / `qoder-cli`，不认 IDE 进程 `qoder.exe`\n- HTTP 服务端口范围固定为 `127.0.0.1:23333-23337`；运行时端口写入 `~/.clawd/runtime.json`\n- 自定义 HTTP Agent 的 sender 必须读取 `~/.clawd/runtime.json`，不能把 23333 写死；注册不等于已连接。custom v1 只支持 `/state`，不支持 `/permission`\n- CodeBuddy PermissionRequest hook 的所有权只认本机 managed URL 或 marker `clawd-on-desk.permission.v1`；纯 `name:\"clawd\"` 不能触发改写/删除。裸 CLI 和 WSL 默认 preserve，Settings/startup/repair 必须显式传 local/custom permission target\n- Remote SSH 的远端 Node 探测要求 Node >= 14；Node discovery/version validation 只在 `src/remote-ssh-node.js`，ordinary tunnel health 与 serialized readiness 在 `src/remote-ssh-runtime.js`，不得互相复制或从已停用脚本另起实现\n- 注册 Claude Code hook 必须 marker-scoped merge：只可更新/删除含 `clawd-hook.js` / `auto-start.js` marker 的 Clawd-owned entry，不得整体覆盖数组或改动无 marker 的用户 entry\n- 注册 Claude Code statusLine 时只接管空槽或自己的槽（marker `claude-statusline.js`）；远程部署可用 profile 的 `chainStatusline` opt-in 串联既有第三方 statusline（`--chain-existing`），显式关闭时必须从 sidecar 恢复原 statusLine。订阅配额通过 `metadata_only` POST 进入 session-independent `updateAccountQuota` per-source store；不要把 quota 塞进 `updateSession` opts，也不要以 session 存活作为摄入前提\n- Copilot CLI hooks 走按需自动同步：`hooks/copilot-install.js` 在本地启动仅当 Copilot CLI 已安装且已启用时调用；远端由 Settings Remote SSH deploy controller 调用。路径解析尊重 `COPILOT_HOME` env（trimmed 非空才生效，否则 fallback 到 `~/.copilot`）；`hooks/copilot-hook.js` 的 session-state resolver 同样走 env\n- Remote SSH 的 effective transport 由 `ssh -G` 只读检查决定：ordinary SSH 在没有 retained serialized occupancy 时保持 `context:null` 的 parallel 路径；serialized transport 以有效 target key（不是 profile id）互斥。所有 serialized managed SSH/SCP child 必须持 coordinator 发出的有效 connection/operation context，并通过其 pre-spawn gateway 启动；用户交互终端只有命中 serialized/retained occupancy 时才要求 coordinator 判定 target 完全 idle\n- serialized persistent tunnel 使用同一条 SSH 内嵌 readiness；暂停通过 stdin EOF 请求自然退出并等待 `close`。强杀或带 signal 的 outer `ssh.exe` close 不能证明 nested ProxyCommand 已 drain；timeout/未验证 drain 必须 quarantine，期间禁止新 child、mutation、resume 或 interactive terminal\n- mutation 在 deploy-lock acquire-attempted / lock-owned 后遇到 exit 255、EOF/reset、signal 或其他 unknown result 时不得自动 replay、retry、release lock 或恢复连接；必须保留 primary error 并传播 recovery state，必要时要求 `manual_lock_inspection_required`\n- Remote SSH secure hook 必须同时携带 `CLAWD_REMOTE=1` 与 `CLAWD_SSH_REMOTE=1`，只读 layout identity 并 pin 精确端口；identity 缺失/损坏/不可读必须 fail closed，禁止回退端口扫描\n- Remote SSH deploy-lock acquisition 必须原子化；成功 acquire 后的每个 live mutation 都要在同一远端命令内 fencing 校验，cleanup 还必须锁内重读 installId/profileId/runtimeKey/layoutVersion 所有权。无身份、冲突、ownerless/corrupt lock 均不得自动接管\n- 默认 `account-default` 只支持不同 Unix 账号；同 Unix 账号冲突必须阻止。`profile-isolated` 在真实 SSH/CLI 矩阵完成前由 `CLAWD_ENABLE_EXPERIMENTAL_REMOTE_ISOLATION=1` 发布门隐藏；它只隔离用户级 CLI config/session/runtime 与 Clawd 路由，不代表完整 HOME 或同 UID 安全隔离，project 配置/部分 cache/macOS Claude Keychain auth 仍可能共享\n- 禁用 agent 不应卸载 hooks / plugins / extensions：只停止对应 monitor、清理 session / bubble、让 HTTP hook 入口快速 fallback；重新启用未安装 agent 不触发本机 integration sync。卸载集成必须走 Settings Agent 页的 Uninstall / 对应 uninstall 命令，并同时清掉 `integrationInstalled`\n- Kiro 的 `sessionId=\"default\"` 会复用；session alias key 必须按 cwd scope 区分，同时保留旧 `local|kiro-cli|default` 只读 fallback\n- Windows NSIS release 必须产出明确架构的 x64 / ARM64 安装包：`win.artifactName` 保留 `${arch}`，`nsis.buildUniversalInstaller` 保持 `false`\n- 每个 release target 只能保留一个匹配目标架构的 Koffi `koffi.node`；`afterPack` 只允许剪裁 `app.asar.unpacked` 的物理文件，禁止重写 `app.asar`，并必须通过完整 native inventory audit（唯一常设例外是 electron-builder 管理的 Windows ia32 `resources/elevate.exe`）\n- 资源路径统一用 `path.join(__dirname, ...)`\n- 需要编辑发布素材时，先复制到 `assets/source/` 再改，不要直接改工作素材来源不明的文件\n- `assets/source/cloudling-pointer-bridge/` 是 Cloudling 指针桥素材的保留源文件目录；运行时逻辑已内联进主题 SVG，不要把这个 source 目录当临时文件清理\n- 主题状态、sleep/DND、mini mode、状态映射的细节在 `docs/project/theme-state-ui.md`\n- Settings 体系里，store 是唯一真相，controller 是唯一写入者；不要绕开 `settings-controller.js`\n\n## Testing\n\n- 自动化测试使用 Node 内置 test runner：`npm test`\n- `test/*.test.js` 覆盖核心 unit/contract、installer、route、UI/runtime 与 Remote SSH transport/coordinator/identity；部分 fixture 会启动 Node、shell 或 Git Bash 子进程，缺少依赖时可能 skip，不能把全套结果概括成纯逻辑或等价真机验证\n- Remote SSH 真机矩阵与记录在 `scripts/manual/README.md`；Windows OpenSSH + Codespaces stdio 边界及 ordinary-host V15 release gate 不能从 unit tests 互相推断，无法执行时必须明确记录 pending / residual risk\n- Windows Terminal 真机、GUI smoke 与清理必须假定多个 tab/window 共享进程：不得按 PID/进程名 `taskkill`、`Stop-Process` 或宽泛终止 WindowsTerminal、Codex、`cmd.exe`、`ssh.exe`、OpenConsole、conhost。测试终端只能在明确 test-owned session 内 `exit`；无法证明 ownership 就保留现场并请用户手动关闭\n- 当前开发环境是 Windows-first；macOS 特定路径无法在这里手动 QA，改到 mac 逻辑时要用 code-review-first 的方式说明行为变化和残余风险\n- 涉及 Claude Code hook payload 的改动（尤其 `/permission`、`permission_suggestions`、`updatedPermissions`、elicitation 输入）至少用一次真实 Claude Code 验证；`curl` 自编 payload 不够\n- 透明窗口、托盘、真实拖拽、跨平台前台聚焦等 Electron 行为仍以手动验证为主\n\n## High-Risk Gotchas\n\n- `src/pet-window-runtime.js` 的 `hitWin` 必须在 Windows/macOS 保持 focusable（当前为 `focusable: !isLinux`），不要把 Windows 拖拽修复改回去\n- `miniTransitioning` 期间，所有窗口定位路径都必须先检查保护标志，否则 `setPosition()` 可能并发崩\n- DND 会屏蔽 hook 事件并压住 bubble，但**不应替用户做权限决定**：opencode 走 silent drop 回到 TUI 提示，Claude Code / CodeBuddy 走断连回到内置聊天/终端确认，Codex official hook 走 no-decision `{}` 回到原生审批提示；Pi 是 state-only，不进入权限审批链路\n- 隐藏桌宠（petHidden）≠ 免打扰：隐藏只收起宠物/HUD/update bubble/当时 pending 的权限气泡，**隐藏期间新到的权限请求仍照常弹气泡，这是有意设计、不要当 bug 修**；要静默权限气泡走 DND（见上条）。详见 `docs/project/theme-state-ui.md` State Machine 节\n- Session HUD 显示所有非 headless、非 sleeping 的 live session，包括 badge=Done 的 idle session；不要再按 `state !== \"idle\"` 过滤，否则完成后的 Claude Code 会话会从 HUD 消失\n- update bubble 跟随桌宠时要同时避让 Session HUD 和 permission stack；permission bubble 增删、测高、deny-and-focus 后都要触发 update bubble 重排\n- `mini-working` 是可选主题能力，缺失时必须优雅降级\n- `contextMenuOwner` 必须保留 `parent: win`；配合 `closable:false` 才不会把退出流程卡死\n- Windows 前台窗口锁与 process-query 路径依赖 ALT trick + `koffi` FFI；同一 Koffi registry 的 named structs/bindings 必须复用既有缓存，不要重复注册，相关回归通常不是单点逻辑 bug\n- `~/.claude/settings.json` 的 hook 恢复 watcher 必须盯目录而不是文件；原子替换会让文件级 watch 在 Windows 上静默失效\n- Claude watcher 必须同时受 `manageClaudeHooksAutomatically`、`claude-code.integrationInstalled` 和 `claude-code.enabled` 保护；不要让未安装或禁用 Claude Code 后的 watcher 重新写回 hooks\n- 所有进程内对 `~/.claude/settings.json` 的 mutation（启动 reconcile、watcher 自动恢复、周期健康自愈、Settings Install/Enable、Doctor Fix、auto-start 开关、卸载、About 清理）必须经过 `src/claude-hook-operations.js` 的 server-owned 队列；不要绕开队列直接 `require(\"../hooks/install.js\")` 写文件，否则会与其他来源的写入竞态\n- 周期健康巡检（`src/claude-settings-watcher.js`）只读判断用 `src/claude-hook-health.js`；同一 repair signature 连续 3 次修复+复验失败后必须停在 `manual-fix-required`，不再自动 mutation，只保留 5 分钟只读复查；suspicious-shrink 通知同一持续问题只弹一次，不要每轮重复\n- opencode 的 `permission.ask` hook 目前不可用，权限只能走 event hook + bridge\n- Codex CLI official hooks 已接入；JSONL 轮询仍是 fallback，用于 hook 不可用、hook 未覆盖事件（如 WebSearch / compaction / abort）和历史兼容。Windows `commandWindows` 由 PowerShell 解析：legacy 直接命令必须用 `& \"node\" ...` call operator；本机 stable 入口必须保持“固定内联 PowerShell dispatcher → UTF-8/Base64 `codex-hook.js.windows.run` 数据 sidecar → `& $node $target`”形态（JSON manifest 只供 Doctor），不得改回裸 `\"node\" \"hook.js\"`（会 exit 1）、二次 `powershell.exe -File` 或无 BOM `.ps1`\n- Kiro 没有 global hooks，只能注入到 `~/.kiro/agents/*.json`\n- `src/renderer.js` 里给 `<img>` SVG 追加的 `?_t=` cache-bust query 不能删；Chromium 会复用同 URL SVG 的动画时间线，一次性动画会停在末帧\n\n## Do Not Revisit\n\nLanguage 子菜单底部截断是 Electron 透明窗口 + Windows DWM 的底层兼容问题。不要再尝试通过切换 `alwaysOnTop`、透明窗策略或 JS 菜单布局修它。\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# AGENTS.md\n\nThis file is the entry point for coding agents working in this repository. Keep it short and operational. Durable architecture lives in `docs/project/`; `docs/plans/` and `docs/investigations/` are historical evidence unless this file explicitly links them.\n\n## Project Overview\n\nClawd 是一个 Electron 桌宠：通过 hook、日志轮询、plugin 和 extension 感知 AI coding agent 的工作状态，并播放像素风动画。当前支持 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、DeepSeek Harness；内置 Clawd / Calico / Cloudling 三套主题，支持用户主题；平台覆盖 Windows、macOS、Linux，UI 支持 en / zh / zh-TW / ko / ja / pt-BR。\n\n## Common Commands\n\n```bash\nnpm start\nnpm run build                  # default Windows package\nnpm run build:win:x64\nnpm run build:win:arm64\nnpm run build:win:all\nnpm run build:mac\nnpm run build:linux\nnpm run build:all\nnpm install\nnpm test\nnpm run verify:electron\nnpm run verify:release\nnpm run audit:assets\nnpm run audit:native-package -- --app-root <extracted-app-root> --target <target-id>\nnpm run create-theme\n\nnpm run install:claude-hooks\nnpm run uninstall:claude-hooks\nnpm run install:cursor-hooks\nnpm run install:gemini-hooks\nnpm run install:antigravity-hooks\nnpm run install:kiro-hooks\nnpm run install:kimi-hooks\nnpm run install:qwen-hooks\nnpm run install:zcode-hooks\nnpm run uninstall:zcode-hooks\nnpm run install:codewhale-hooks\nnpm run uninstall:codewhale-hooks\nnpm run install:pi-extension\nnpm run uninstall:pi-extension\nnpm run install:openclaw-plugin\nnpm run uninstall:openclaw-plugin\nnpm run install:hermes-plugin\nnpm run uninstall:hermes-plugin\nnpm run install:qoder-hooks\nnpm run uninstall:qoder-hooks\nnpm run install:qoderwork-hooks\nnpm run uninstall:qoderwork-hooks\nnpm run install:qwenwork-hooks\nnpm run uninstall:qwenwork-hooks\nnpm run install:reasonix-hooks\nnpm run uninstall:reasonix-hooks\nnpm run install:workbuddy-hooks\nnpm run uninstall:workbuddy-hooks\nnpm run install:dsh\nnpm run uninstall:dsh\nnpm run install:codex-hooks\nnpm run uninstall:codex-hooks\nnpm run install:codex-debug-hooks\nnpm run uninstall:codex-debug-hooks\nnpm run install:mimocode-plugin\nnpm run uninstall:mimocode-plugin\nnode hooks/codebuddy-install.js\nnode hooks/opencode-install.js\n\nbash test-demo.sh [seconds]\nbash test-mini.sh [seconds]\nbash test-macos.sh\nbash test-oneshot-gate.sh [state] [seconds]\n```\n\n新安装默认只把 Claude Code 和 Codex 标记为已安装并启用；其他 agent 默认未安装、未启用。正常启动时，Clawd 只会为 `integrationInstalled=true` 且 `enabled=true` 的 agent 自动同步 Claude / Codex / Copilot / Gemini / Antigravity / Cursor / CodeBuddy / WorkBuddy / Kiro / Kimi / Qwen / ZCode / CodeWhale / Qoder / QoderWork / QwenWork / Reasonix hooks、opencode / MiMo Code / OpenClaw / Hermes plugins 和 Pi extension。Settings Agent 页的 Install 会安装并启用该集成；Uninstall 会卸载 Clawd 管理的 hook/plugin/extension，并同时把该 agent 设为未安装、未启用。单独关闭 enabled 只会跳过启动同步并屏蔽事件/权限入口，不卸载用户已有 hooks / plugins / extensions；重新启用未安装 agent 只打开事件入口，不会写本机集成文件。手动安装命令主要用于调试、重装或远程部署。\nSettings 注册的自定义 HTTP Agent 是独立模型：`customApplications` 是注册真相，对应 `agents[customId]` 必须显式保持 `integrationInstalled=false`。注册只分配 ID 和状态入口，不安装 hook、不观察进程；v1 仅允许已注册且启用的 ID 向 `/state` 上报，`/permission` 永远不提供决定。删除或伪造的 `custom-` ID 必须直接拒绝，不能降级成 Claude Code subagent。\nCopilot CLI 同步走 `<COPILOT_HOME 或 ~/.copilot>/hooks/hooks.json`，marker-based 增量合并只接管含 `copilot-hook.js` 标记的条目，用户其他 entry / 其他 `hooks/*.json` 文件原样保留；hooks.json 或 `settings.json` 顶层 `disableAllHooks: true` 时 doctor 报 warning（不挂 Fix 按钮）。详见 `docs/guides/copilot-setup.md`。\n\n## Read These Docs\n\n- `docs/project/agent-runtime-architecture.md`：运行时架构、模块边界、启动与数据流、多 agent、permission bubble、终端聚焦和自动同步\n- `docs/project/theme-state-ui.md`：状态机、主题系统、settings、mini mode、素材规则、平台限制、待落地 UI 决策\n- `docs/project/release-process.md`：发版 checklist、release note 核对、tag 触发 GitHub 打包和资产确认\n- `docs/guides/copilot-setup.md`：Copilot CLI 自动同步说明、`COPILOT_HOME` 兼容性、手动配置备选模板\n- `docs/guides/dsh-setup.md`：DeepSeek Harness web profile 实验性 plugin-only 状态与普通审批集成\n- `docs/guides/state-mapping.md`：状态 → 动画权威表\n- `docs/guides/guide-theme-creation.md`：主题作者指南\n- `docs/guides/setup-guide.md`：安装、远程 SSH、各 agent 接入\n- `docs/guides/custom-agent-http.md`：自定义 HTTP Agent 的 state-only 接入合约和动态端口发现\n- `docs/guides/known-limitations.md`：用户向已知限制\n- `docs/guides/codex-wsl-clarification.md`：Codex / WSL 路径与 Node 说明\n- `docs/guides/guide-remote-ssh.md`：Remote SSH 用户流程、Codespaces 单会话 transport 与共享主机边界\n- `docs/guides/telegram-approval.md` / `docs/guides/feishu-lark-remote-approval.md`：远程审批设置与失败回退语义\n- `docs/guides/roam-fence.md`：自由漫游与可选围栏\n\n## Runtime Summary\n\n- HTTP hook / plugin 主路径：`src/server.js` → `src/server-route-state.js` → `src/agent-runtime-main.js` → `src/state.js` → IPC；本地 JSONL monitor 直接进入 `agent-runtime-main`，不经过 HTTP server\n- 权限主路径：`src/server-route-permission.js` → `src/permission.js`；本地 bubble、显式 permission automation 与可选 Telegram / 飞书 Lark 远程审批都可能产生真实决定\n- 桌宠的渲染/输入双窗口由 `src/pet-window-runtime.js` 统一创建和定位；浮层排序与 topmost 行为在 `src/floating-window-runtime.js` / `src/topmost-runtime.js`\n- `src/state.js` 生成的 session snapshot 是 Dashboard、HUD/Orbit 与可选通知/presence/mobile consumer 的共享合约，改字段必须检查所有消费者\n- `src/integration-sync.js` 为已安装且启用的 agent 异步同步 hooks / plugins / extensions；Codex official hooks 为 primary，JSONL 轮询保留为 fallback\n- Claude hook 恢复由 `src/claude-settings-watcher.js` 的目录 watcher + 低频只读巡检共同负责；repair 统一经过 `src/claude-hook-operations.js` 队列并复验，连续失败转 `manual-fix-required`。完整 gate、阈值与 source-missing 语义见 `docs/project/agent-runtime-architecture.md`\n- `src/agent-gate.js` 控制各 agent 的安装意图、启用状态、权限气泡开关和 wait-for-input notification 子开关\n- 设置系统主链路是 `src/prefs.js` → `src/settings-controller.js`（唯一写入者）→ `src/settings-store.js`；`settings-actions*` 负责校验和 pre-commit gates，`settings-effect-router.js` 负责 post-commit runtime effects 与广播\n- 启动时还会尝试自动安装 VS Code / Cursor terminal-focus extension，并初始化 updater\n- Remote SSH 通过 effective transport inspection 区分 ordinary parallel SSH 与 serialized transport；后者由 target-scoped coordinator 编排。远程部署只走 Settings，`scripts/remote-deploy.sh` 已 fail-fast 停用\n\n## Core Files\n\n更细的背景见 `docs/project/agent-runtime-architecture.md` 和 `docs/project/theme-state-ui.md`。\n\n| File | Responsibility |\n|------|------|\n| `src/main.js` | Electron composition root：生命周期、上下文组装与各 runtime / IPC 注册器接线 |\n| `src/server.js` + `src/server-route-state.js` + `src/server-route-permission.js` | HTTP 服务、端口发现、`/state` / `/permission` 路由 |\n| `src/agent-runtime-main.js` + `src/integration-sync.js` | local monitor / official hook 仲裁、Codex turn fence、按 gate 的集成同步 |\n| `src/state.js` | 状态机、多会话合并、优先级、自动回退、睡眠/DND |\n| `src/renderer.js` | 动画切换、SVG 预加载、眼球追踪渲染 |\n| `src/permission.js` + `src/permission-automation-policy.js` + `src/session-automation-coordinator.js` | 权限气泡、自动化策略、per-session 授权与决策回包；远程 client 由 `main.js` 注入 |\n| `src/pet-window-runtime.js` + `src/floating-window-runtime.js` + `src/topmost-runtime.js` | 双窗口 owner、浮层重排、z-order / fullscreen / focusability |\n| `src/update-bubble.js` | 更新气泡创建、测高、跟随桌宠定位，避让 HUD / permission stack |\n| `src/dashboard.js` + `src/dashboard-renderer.js` | Sessions Dashboard 窗口、会话列表、别名编辑、终端跳转 |\n| `src/session-hud.js` + `src/session-hud-renderer.js` | 桌宠旁轻量会话 HUD、折叠行、点击跳转 |\n| `src/session-alias.js` | session alias key 规范化、TTL pruning、Kiro cwd scope |\n| `src/theme-loader.js` + `src/theme-runtime.js` | stateless 主题加载/消毒与唯一 active-theme owner |\n| `src/prefs.js` | 偏好 schema、load/save/migrate/validate，设置持久化入口 |\n| `src/settings-actions*.js` + `src/settings-effect-router.js` | 设置 validators / commands / pre-commit gates 与 post-commit runtime effects |\n| `src/settings-controller.js` | 设置系统唯一写入者 |\n| `src/settings-store.js` | 不可变 snapshot store |\n| `src/settings-ui-core.js` + `src/settings-renderer.js` + `src/settings-tab-*.js` | Settings shared UI state、侧栏/tab shell 与各页逻辑 |\n| `src/menu.js` | 托盘 / 右键菜单，串起设置、Dashboard、mini mode、更新入口 |\n| `src/mini.js` | 极简模式入场、滑动、peek、状态映射 |\n| `src/tick.js` | 主循环、鼠标轮询、眼球和 idle/sleep 逻辑 |\n| `src/drag-position.js` | 拖拽落点规范化与跨显示器钳制 |\n| `src/visible-margins.js` | 可视角色边距与 edge pinning 规则 |\n| `src/updater.js` | Git 模式 / `electron-updater` 双路径更新逻辑 |\n| `src/focus.js` | 终端聚焦 |\n| `src/hit-renderer.js` + `src/hit-geometry.js` | 输入窗口命中、拖拽、连击反应 |\n| `src/remote-ssh-runtime.js` | Remote SSH tunnel/ingress 状态机、ordinary health probe、serialized readiness 与重连 |\n| `src/remote-ssh-transport.js` + `src/remote-ssh-transport-coordinator.js` | effective transport inspection、pre-spawn admission、target ownership、drain barrier 与 quarantine |\n| `src/remote-ssh-deploy.js` | Deploy / Repair、身份事务、lease/fencing、wrapper、cleanup 与远端 Codex monitor mutation |\n| `src/remote-ssh-identity.js` + `src/remote-ssh-layout.js` + `src/remote-ssh-ingress.js` | 身份/布局真相与 profile 专属、nonce 校验的本地 ingress |\n| `src/remote-ssh-node.js` + `src/remote-ssh-shell-detect.js` + `src/remote-ssh-local-config.js` | 远端 Node/ shell 探测与本机 SSH config 入口 |\n| `src/remote-ssh-profile.js` | Remote SSH profile schema、校验、默认值和持久化规范化 |\n| `src/remote-ssh-ipc.js` | Remote SSH runtime / deploy / monitor orchestration、intent policy、IPC 状态与进度广播 |\n| `src/remote-ssh-quote.js` | Remote SSH 终端命令与跨平台 shell quoting helper |\n| `agents/registry.js` | agent 注册表 |\n| `agents/codex-log-monitor.js` | Codex JSONL fallback 轮询 |\n| `agents/gemini-log-monitor.js` | legacy Gemini session JSON 轮询器；当前 Gemini hook-only 路径不启动 |\n| `hooks/dsh-install.js` | DeepSeek Harness immutable managed bridge generation、ownership verify、安装 / 修复 / 卸载事务 |\n| `hooks/clawd-hook.js` + `hooks/copilot-hook.js` | Claude Code / Copilot CLI 状态上报脚本 |\n| `hooks/install.js` | Claude hook 注册 / 卸载 |\n| `hooks/auto-start.js` | Claude `SessionStart` 自动拉起 Clawd 的 hook |\n| `hooks/codex-hook.js` / `hooks/codex-install.js` | Codex official hooks 状态与权限审批、安装 / 卸载 |\n| `hooks/cursor-install.js` / `gemini-install.js` / `antigravity-install.js` / `kiro-install.js` / `kimi-install.js` / `qwen-code-install.js` / `codewhale-install.js` / `codebuddy-install.js` / `workbuddy-install.js` / `opencode-install.js` / `pi-install.js` / `openclaw-install.js` / `hermes-install.js` / `qoder-install.js` / `qoderwork-install.js` / `reasonix-install.js` | 各 agent 集成安装逻辑 |\n| `hooks/workbuddy-hook.js` | WorkBuddy state + Notification command hook；无 session_id 时返回合法 stdout 后丢弃事件 |\n| `hooks/zcode-hook.js` / `hooks/zcode-install.js` | ZCode state-only hooks、`hooks.events.*` 增量注册与 Claude-imported Clawd hook 清理 |\n| `hooks/qoder-hook.js` | Qoder state-only 状态上报脚本（Phase 1，stdout 恒为 `{}`） |\n| `hooks/codex-remote-monitor.js` | 远程 Codex JSONL 轮询并通过 SSH 隧道回传（含 token_count 订阅配额的 metadata_only 上报） |\n| `hooks/claude-statusline.js` / `hooks/antigravity-statusline.js` | 各 CLI statusline 适配器：渲染状态行 + 把订阅配额（rate_limits）以 metadata_only POST 上报；Claude 版支持远程部署（`CLAWD_REMOTE=1` 前缀）与 `--chain` 串联模式（原 statusLine 对象保存在 `~/.claude/hooks/clawd-statusline-chain.json`，卸载时恢复） |\n| `extensions/vscode/extension.js` | VS Code / Cursor 终端 tab 聚焦辅助扩展 |\n\n## Constraints\n\n- `agents/registry.js` 的 capabilities 是权限、subagent、session-end 等路由/gate 的权威来源；不得另写名单代替 capability 判定。但 permission automation eligibility 由更窄的 `isKnownPermissionAgent()` 显式判定（`KNOWN_PERMISSION_AGENTS` + explicit opencode-family membership），不得从 `permissionApproval` 自动派生或合并回 registry capabilities\n- Claude Code / CodeBuddy 的阻塞式权限审批走 `POST /permission` HTTP hook；普通状态事件走 command hook\n- permission automation（off / auto-tools / unattended）和 per-session grant 会在 bubble 渲染前产生真实 allow/answer。agent/family eligibility 是显式白名单；工具分类则因 mode/adapter 而异：auto-tools 对 Claude/Qwen 的未知 built-in fail closed，但其他已知 adapter 不都使用逐工具白名单，unattended 还会有意自动放行可作 Allow/Deny 的未知请求。新增 agent、工具或交互类型必须审查 policy + tests，不能从 `permissionApproval` 推导资格或笼统假设“未知请求都会 defer”\n- Telegram / 飞书 Lark 与本地 bubble 是并行决策通道。远程通道超时、断连、未配置或发送失败不得产生远程决定，更不得转成 deny；有本地 bubble 时请求继续 pending，只有 remote-only 且所有可用 client 都无决定时，整体请求才 no-decision 并回到 agent 原生流程\n- WorkBuddy 通过 `~/.workbuddy/settings.json` 的 Claude Code 兼容 command hooks 做 **state + Notification only** 集成：不注册 `/permission`，审批始终留在 WorkBuddy 原生沙箱与 GUI；无 `session_id` 的事件返回合法 stdout 后直接丢弃。当前只支持 macOS/Windows 桌面应用，没有已验证的 Linux/WSL CLI；不要把裸 `Electron` 当 WorkBuddy 进程。\n- Codex 的阻塞式权限审批走 official `PermissionRequest` command hook：hook 脚本长连接 `POST /permission`，只允许 stdout 返回 sanitized `behavior/message`，`updatedInput` / `updatedPermissions` / `interrupt` 必须 omit\n- hook 脚本只允许依赖 Node 内置模块，以及同目录 `hooks/` 下、且登记在 `src/remote-ssh-deploy.js` 的 `HOOK_FILES` 部署清单中的纯 Node helper（如 `server-config.js` / `shared-process.js` / `json-utils.js` / `codex-originator.js` / `codex-subagent-fields.js` / `context-usage.js` / `state-payload-size.js` / `quota-bucket.js` / `claude-rate-limits.js` / `codex-rate-limits.js` / `antigravity-context-usage.js`）；manifest-consistency 测试强制检查依赖闭包，新增 helper 必须登记\n- CJS hook 脚本需要稳定终端 PID 时，必须复用 `hooks/shared-process.js` 的 `createPidResolver()` 及其 lifecycle context；不要复制进程树 walk 或用 `process.ppid` 简化。`getStablePid()` 只是 opencode-family plugin 的内部 resolver\n- opencode 权限不走 `permission.ask` hook，而是 event hook + reverse bridge\n- Pi 通过 `~/.pi/agent/extensions/clawd-on-desk` 的 global extension 推送状态；Clawd 对 Pi 是 **state-only**，不接管权限、不弹权限气泡，也不把 Pi 的默认 YOLO 流程改成手动确认\n- DeepSeek Harness 首发是 **web profile / Windows-first experimental / plugin-only**；packaged-app source loading smoke 已完成，API-backed session/approval smoke 未完成前不得写成 Windows-verified。Clawd-managed in-process plugin 只监听公开 `session/created`、`session/event`、`session/disposed` 与 blocking `approval/request`。状态按 session FIFO 上报并携带上游 seq；Clawd 不读取 `$DSH_HOME/storages` projection。普通审批进入独立 DSH `/permission` adapter，只支持人工 Allow Once / Deny；204 / 断连 / DND / disabled 都由 plugin `next()` 交还 DSH 原生 web answerer。`ask_user_question` 始终留在 DSH 原生 provider；DSH 不进入 `KNOWN_PERMISSION_AGENTS`，auto-tools / unattended / per-session grant 全部 DEFER。安装器通过官方 `dsh plugin --profile web add/remove` 管理 immutable marker-owned generation，foreign 同名包 fail closed；当前冻结支持 npm 发布物 `@deepseek-ai/dsh@0.1.0-rc.6`（integrity `sha512-brpZfED7ieRa2PQ5tUxMhHrM1pb2CmKFVM/f6yMULBDMicahk+Z2OsHgTwTDnoiZm23Ftu9rQz0NN4pflaoJcg==`），`47f9438` 仅是源码调查基线，不代表 rc.6 的 tag/commit 映射。\n- DSH 每个 canonical `DSH_HOME` 的 mutation lock 只有在 owner/schema/token/PID/timestamp/owner-recorded operation timeout 合法、超过该 owner timeout 两倍、且 OS PID probe 明确为 `ESRCH` 时才允许 atomic-rename takeover；live、`EPERM`、unknown、corrupt/foreign owner 一律拒绝并返回精确 lock path。canonical lock 的 owner write/release 禁止 recursive cleanup。无全局 CLI 时生成的手动 npx generation 必须先在同一锁内写 owned reference，手动 add/remove 命令必须显式 pin shell-quoted canonical `DSH_HOME`；malformed/foreign/concurrently replaced reference 一律 fail closed 并保留 generation\n- OpenClaw 通过 `~/.openclaw/openclaw.json` plugin 路径做 state-only 集成；Phase 1 不做 permission bubble / terminal focus，主要支持本地 `openclaw tui --local`\n- Antigravity CLI (agy) 通过 `~/.gemini/config/hooks.json` 做 **state-only** hook 集成（PreInvocation / PostToolUse / PostInvocation / Stop），**不注册 PreToolUse**。agy LLM 会主动调内置 `ask_permission` 工具，触发 agy 自己的 5 选项 native menu（含 \"Persist to settings.json\" 持久白名单），Clawd 不插手权限决策也不双层确认。`agents/antigravity-cli.js` `capabilities.permissionApproval` / `interactiveBubble` 均为 false。\n- Qwen Code 通过 `~/.qwen/settings.json` 做 hook-only 集成（SessionStart / SessionEnd / UserPromptSubmit / PreToolUse / PostToolUse / Stop / Notification / PermissionRequest），支持状态与阻塞式 `PermissionRequest` 权限气泡；`disableAllHooks: true` 时注册条目不会触发。\n- QwenWork (千问办公) 通过 `~/.QwenWorkCN/settings.json` 做 **hook-only / state-only** 集成（agent id `qwenwork`；SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / PostToolUseFailure / Stop / Notification / PermissionRequest / PermissionDenied / SessionEnd）。`PermissionRequest` / `PermissionDenied` 只作为观察映射成 `working`（每任务 40+ 次，映射成 notification 会刷屏），hook stdout 恒为 `{}`：Clawd 不产生 allow/deny，不注册 `/permission`，也不进入 permission automation eligibility，唯一决策者是 QwenWork 原生权限流程；`agents/qwenwork.js` 的 `capabilities.permissionApproval` / `interactiveBubble` 均为 false。Windows command 必须保持 `windowsWrapper:\"portable\"`（QwenWork 经 POSIX shell 执行 command hook），PowerShell `-EncodedCommand` **只**用于识别并原地迁移旧条目，不是当前写入形态。marker 只认 `qwenwork-hook.js`，不得仅凭 `name:\"clawd\"` 删除用户 hook；混合 entry 中第三方 hook 原样保留。session id 命名空间是 `qwenwork:<raw>`；`~/.QwenWorkCN/workspace/<id>` 这类内部工作区 cwd 不做 basename 回退，避免 HUD/Dashboard 显示内部 ID。当前真实支持平台只有 macOS / Windows 桌面端（官方下载页 https://qwenwork.cn/download 只提供 macOS 14+ / Windows 10+ / HarmonyOS 6.1+，没有 Linux 客户端），因此 `processNames.linux`、resolver linux agent name 均为空，也不进 `src/wsl-deploy.js` 的 WSL Pair 映射。桌面主进程长驻、不代表 active turn，`startupRecoveryProcessNames` 全空、无 startup recovery。安装/卸载走 Settings → Agents，或 `npm run install:qwenwork-hooks` / `npm run uninstall:qwenwork-hooks`；卸载必须同时在 `hooks/cleanup-integrations.js` 的 `MANAGED_AGENT_IDS` / `AGENT_CLEANERS` / `byAgent` 里有条目，否则 About cleanup 只会改 prefs、hook 留在磁盘上\n- ZCode 通过 `~/.zcode/cli/config.json` 的 `hooks.events.*` 做 **state-only** 集成（SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / PostToolUseFailure / Stop），不注册 PermissionRequest，stdout 恒为 `{}`。配置必须有 `hooks.enabled=true` 才会执行；安装器只在该字段缺失时补 true，显式 `hooks.enabled=false` 或 Clawd 单项 hook 的 `enabled=false` 必须保留，Doctor warning 且不提供会覆盖用户选择的 Fix。ZCode 导入 Claude 配置后，只清理 `.zcode` 中明确引用 `clawd-hook.js` 的 Clawd-owned 条目，绝不改 `~/.claude/settings.json`\n- Qoder 通过 `~/.qoder/settings.json` 做 **state-only** hook 集成。Clawd 只把 `PermissionRequest` / `PermissionDenied` 当 notification 观察，**不替 Qoder 做权限决策**，hook stdout 恒为 `{}`，由 Qoder 原生权限流程接管；Windows command 必须保持 `windowsWrapper:\"portable\"`，旧 PowerShell encoded 条目只做 Clawd-owned 原地迁移。session id 命名空间是 `qoder:<raw>`；启动恢复只认 CLI 进程 `qodercli` / `qoder-cli`，不认 IDE 进程 `qoder.exe`\n- HTTP 服务端口范围固定为 `127.0.0.1:23333-23337`；运行时端口写入 `~/.clawd/runtime.json`\n- 自定义 HTTP Agent 的 sender 必须读取 `~/.clawd/runtime.json`，不能把 23333 写死；注册不等于已连接。custom v1 只支持 `/state`，不支持 `/permission`\n- CodeBuddy PermissionRequest hook 的所有权只认本机 managed URL 或 marker `clawd-on-desk.permission.v1`；纯 `name:\"clawd\"` 不能触发改写/删除。裸 CLI 和 WSL 默认 preserve，Settings/startup/repair 必须显式传 local/custom permission target\n- Remote SSH 的远端 Node 探测要求 Node >= 14；Node discovery/version validation 只在 `src/remote-ssh-node.js`，ordinary tunnel health 与 serialized readiness 在 `src/remote-ssh-runtime.js`，不得互相复制或从已停用脚本另起实现\n- 注册 Claude Code hook 必须 marker-scoped merge：只可更新/删除含 `clawd-hook.js` / `auto-start.js` marker 的 Clawd-owned entry，不得整体覆盖数组或改动无 marker 的用户 entry\n- 注册 Claude Code statusLine 时只接管空槽或自己的槽（marker `claude-statusline.js`）；远程部署可用 profile 的 `chainStatusline` opt-in 串联既有第三方 statusline（`--chain-existing`），显式关闭时必须从 sidecar 恢复原 statusLine。订阅配额通过 `metadata_only` POST 进入 session-independent `updateAccountQuota` per-source store；不要把 quota 塞进 `updateSession` opts，也不要以 session 存活作为摄入前提\n- Copilot CLI hooks 走按需自动同步：`hooks/copilot-install.js` 在本地启动仅当 Copilot CLI 已安装且已启用时调用；远端由 Settings Remote SSH deploy controller 调用。路径解析尊重 `COPILOT_HOME` env（trimmed 非空才生效，否则 fallback 到 `~/.copilot`）；`hooks/copilot-hook.js` 的 session-state resolver 同样走 env\n- Remote SSH 的 effective transport 由 `ssh -G` 只读检查决定：ordinary SSH 在没有 retained serialized occupancy 时保持 `context:null` 的 parallel 路径；serialized transport 以有效 target key（不是 profile id）互斥。所有 serialized managed SSH/SCP child 必须持 coordinator 发出的有效 connection/operation context，并通过其 pre-spawn gateway 启动；用户交互终端只有命中 serialized/retained occupancy 时才要求 coordinator 判定 target 完全 idle\n- serialized persistent tunnel 使用同一条 SSH 内嵌 readiness；暂停通过 stdin EOF 请求自然退出并等待 `close`。强杀或带 signal 的 outer `ssh.exe` close 不能证明 nested ProxyCommand 已 drain；timeout/未验证 drain 必须 quarantine，期间禁止新 child、mutation、resume 或 interactive terminal\n- mutation 在 deploy-lock acquire-attempted / lock-owned 后遇到 exit 255、EOF/reset、signal 或其他 unknown result 时不得自动 replay、retry、release lock 或恢复连接；必须保留 primary error 并传播 recovery state，必要时要求 `manual_lock_inspection_required`\n- Remote SSH secure hook 必须同时携带 `CLAWD_REMOTE=1` 与 `CLAWD_SSH_REMOTE=1`，只读 layout identity 并 pin 精确端口；identity 缺失/损坏/不可读必须 fail closed，禁止回退端口扫描\n- Remote SSH deploy-lock acquisition 必须原子化；成功 acquire 后的每个 live mutation 都要在同一远端命令内 fencing 校验，cleanup 还必须锁内重读 installId/profileId/runtimeKey/layoutVersion 所有权。无身份、冲突、ownerless/corrupt lock 均不得自动接管\n- 默认 `account-default` 只支持不同 Unix 账号；同 Unix 账号冲突必须阻止。`profile-isolated` 在真实 SSH/CLI 矩阵完成前由 `CLAWD_ENABLE_EXPERIMENTAL_REMOTE_ISOLATION=1` 发布门隐藏；它只隔离用户级 CLI config/session/runtime 与 Clawd 路由，不代表完整 HOME 或同 UID 安全隔离，project 配置/部分 cache/macOS Claude Keychain auth 仍可能共享\n- 禁用 agent 不应卸载 hooks / plugins / extensions：只停止对应 monitor、清理 session / bubble、让 HTTP hook 入口快速 fallback；重新启用未安装 agent 不触发本机 integration sync。卸载集成必须走 Settings Agent 页的 Uninstall / 对应 uninstall 命令，并同时清掉 `integrationInstalled`\n- Kiro 的 `sessionId=\"default\"` 会复用；session alias key 必须按 cwd scope 区分，同时保留旧 `local|kiro-cli|default` 只读 fallback\n- Windows NSIS release 必须产出明确架构的 x64 / ARM64 安装包：`win.artifactName` 保留 `${arch}`，`nsis.buildUniversalInstaller` 保持 `false`\n- 每个 release target 只能保留一个匹配目标架构的 Koffi `koffi.node`；`afterPack` 只允许剪裁 `app.asar.unpacked` 的物理文件，禁止重写 `app.asar`，并必须通过完整 native inventory audit（唯一常设例外是 electron-builder 管理的 Windows ia32 `resources/elevate.exe`）\n- 资源路径统一用 `path.join(__dirname, ...)`\n- 需要编辑发布素材时，先复制到 `assets/source/` 再改，不要直接改工作素材来源不明的文件\n- `assets/source/cloudling-pointer-bridge/` 是 Cloudling 指针桥素材的保留源文件目录；运行时逻辑已内联进主题 SVG，不要把这个 source 目录当临时文件清理\n- 主题状态、sleep/DND、mini mode、状态映射的细节在 `docs/project/theme-state-ui.md`\n- Settings 体系里，store 是唯一真相，controller 是唯一写入者；不要绕开 `settings-controller.js`\n\n## Testing\n\n- 自动化测试使用 Node 内置 test runner：`npm test`\n- `test/*.test.js` 覆盖核心 unit/contract、installer、route、UI/runtime 与 Remote SSH transport/coordinator/identity；部分 fixture 会启动 Node、shell 或 Git Bash 子进程，缺少依赖时可能 skip，不能把全套结果概括成纯逻辑或等价真机验证\n- Remote SSH 真机矩阵与记录在 `scripts/manual/README.md`；Windows OpenSSH + Codespaces stdio 边界及 ordinary-host V15 release gate 不能从 unit tests 互相推断，无法执行时必须明确记录 pending / residual risk\n- Windows Terminal 真机、GUI smoke 与清理必须假定多个 tab/window 共享进程：不得按 PID/进程名 `taskkill`、`Stop-Process` 或宽泛终止 WindowsTerminal、Codex、`cmd.exe`、`ssh.exe`、OpenConsole、conhost。测试终端只能在明确 test-owned session 内 `exit`；无法证明 ownership 就保留现场并请用户手动关闭\n- 当前开发环境是 Windows-first；macOS 特定路径无法在这里手动 QA，改到 mac 逻辑时要用 code-review-first 的方式说明行为变化和残余风险\n- 涉及 Claude Code hook payload 的改动（尤其 `/permission`、`permission_suggestions`、`updatedPermissions`、elicitation 输入）至少用一次真实 Claude Code 验证；`curl` 自编 payload 不够\n- 透明窗口、托盘、真实拖拽、跨平台前台聚焦等 Electron 行为仍以手动验证为主\n\n## High-Risk Gotchas\n\n- `src/pet-window-runtime.js` 的 `hitWin` 必须在 Windows/macOS 保持 focusable（当前为 `focusable: !isLinux`），不要把 Windows 拖拽修复改回去\n- `miniTransitioning` 期间，所有窗口定位路径都必须先检查保护标志，否则 `setPosition()` 可能并发崩\n- DND 会屏蔽 hook 事件并压住 bubble，但**不应替用户做权限决定**：opencode 走 silent drop 回到 TUI 提示，Claude Code / CodeBuddy 走断连回到内置聊天/终端确认，Codex official hook 走 no-decision `{}` 回到原生审批提示；Pi 是 state-only，不进入权限审批链路\n- 隐藏桌宠（petHidden）≠ 免打扰：隐藏只收起宠物/HUD/update bubble/当时 pending 的权限气泡，**隐藏期间新到的权限请求仍照常弹气泡，这是有意设计、不要当 bug 修**；要静默权限气泡走 DND（见上条）。详见 `docs/project/theme-state-ui.md` State Machine 节\n- Session HUD 显示所有非 headless、非 sleeping 的 live session，包括 badge=Done 的 idle session；不要再按 `state !== \"idle\"` 过滤，否则完成后的 Claude Code 会话会从 HUD 消失\n- update bubble 跟随桌宠时要同时避让 Session HUD 和 permission stack；permission bubble 增删、测高、deny-and-focus 后都要触发 update bubble 重排\n- `mini-working` 是可选主题能力，缺失时必须优雅降级\n- `contextMenuOwner` 必须保留 `parent: win`；配合 `closable:false` 才不会把退出流程卡死\n- Windows 前台窗口锁与 process-query 路径依赖 ALT trick + `koffi` FFI；同一 Koffi registry 的 named structs/bindings 必须复用既有缓存，不要重复注册，相关回归通常不是单点逻辑 bug\n- `~/.claude/settings.json` 的 hook 恢复 watcher 必须盯目录而不是文件；原子替换会让文件级 watch 在 Windows 上静默失效\n- Claude watcher 必须同时受 `manageClaudeHooksAutomatically`、`claude-code.integrationInstalled` 和 `claude-code.enabled` 保护；不要让未安装或禁用 Claude Code 后的 watcher 重新写回 hooks\n- 所有进程内对 `~/.claude/settings.json` 的 mutation（启动 reconcile、watcher 自动恢复、周期健康自愈、Settings Install/Enable、Doctor Fix、auto-start 开关、卸载、About 清理）必须经过 `src/claude-hook-operations.js` 的 server-owned 队列；不要绕开队列直接 `require(\"../hooks/install.js\")` 写文件，否则会与其他来源的写入竞态\n- 周期健康巡检（`src/claude-settings-watcher.js`）只读判断用 `src/claude-hook-health.js`；同一 repair signature 连续 3 次修复+复验失败后必须停在 `manual-fix-required`，不再自动 mutation，只保留 5 分钟只读复查；suspicious-shrink 通知同一持续问题只弹一次，不要每轮重复\n- opencode 的 `permission.ask` hook 目前不可用，权限只能走 event hook + bridge\n- Codex CLI official hooks 已接入；JSONL 轮询仍是 fallback，用于 hook 不可用、hook 未覆盖事件（如 WebSearch / compaction / abort）和历史兼容。Windows `commandWindows` 由 PowerShell 解析：legacy 直接命令必须用 `& \"node\" ...` call operator；本机 stable 入口必须保持“固定内联 PowerShell dispatcher → UTF-8/Base64 `codex-hook.js.windows.run` 数据 sidecar → `& $node $target`”形态（JSON manifest 只供 Doctor），不得改回裸 `\"node\" \"hook.js\"`（会 exit 1）、二次 `powershell.exe -File` 或无 BOM `.ps1`\n- Kiro 没有 global hooks，只能注入到 `~/.kiro/agents/*.json`\n- `src/renderer.js` 里给 `<img>` SVG 追加的 `?_t=` cache-bust query 不能删；Chromium 会复用同 URL SVG 的动画时间线，一次性动画会停在末帧\n\n## Do Not Revisit\n\nLanguage 子菜单底部截断是 Electron 透明窗口 + Windows DWM 的底层兼容问题。不要再尝试通过切换 `alwaysOnTop`、透明窗策略或 JS 菜单布局修它。\n","category":"root","tokens":6193}]}