在使用 Claude Code、Codex 或 DeepSeek Harness 等 AI 编程助手执行长时间任务时,我们往往需要离开电脑处理其他事务。本教程为这些 Agent 一键配置桌面弹窗提醒与手机远程交互:任务完成时在电脑上弹窗提醒,并把 AI 最后输出的一段话推送到手机;需要用户确认或选择时通过手机 ntfy 推送完成交互确认;还可以在手机端直接发送文字继续对话(远程续聊),让你无需一直盯着终端。整个过程只需安装一个包、运行一次安装命令。
前置教程
- ClaudeCode安装及配置国内大模型完整教程
- Codex 安装与DeepSeek v4 Flash接入教程,本教程在已安装并配置好 Claude Code 或 Codex 的基础上进行扩展配置。
- DeepSeek Harness 安装与使用教程,如需 DSH(DeepSeek Harness)手机交互,需先安装并运行 DSH。
资源下载
- ntfy 手机客户端 iOS 下载
- ntfy 手机客户端 Android Github 下载
- ntfy 手机客户端 Android 网盘下载
- a4phone npm 包,本教程的核心依赖包。
- a4phone 源码 (GitHub),开源项目,可查看实现细节或参与贡献。
- a4phone 源码 (GitCode),国内可访问的源码镜像仓库。
- a4phone 源码 网盘下载
相关文档
- a4phone 项目总览与快速开始,a4phone 文档库入口,包含项目简介、功能全景、安装与快速开始。
- a4phone 版本更新说明,记录 a4phone 各版本的新增功能、问题修复与升级说明。
- a4phone 命令参考,全部
a4p命令速查表。 - a4phone 配置说明,配置文件与状态文件详解。
1. 方案简介
a4phone 是一个通过 ntfy.sh 实现 Claude Code / Codex / DSH(DeepSeek Harness)远程手机交互的 npm 包,安装后自动处理三类事件,并额外提供远程续聊能力:
| 事件 | 行为 |
|---|---|
| Stop(任务完成) | 电脑弹窗 + 手机推送完成信息(含目录、会话、AI 最后输出) |
AskUserQuestion(AI 提问,Codex 为 request_user_input) |
电脑弹窗 + 手机显示选项按钮可点选 |
| PermissionRequest(权限请求) | 电脑弹窗 + 手机 Approve/Deny/Always Approve |
| DSH 交互(1.1.6 起支持) | DSH 任务完成(turn/end)/ 提问(ask_user_question)/ 审批(approval/request)→ 手机交互 |
| DSH 远程续聊(1.2.0 起支持) | 手机发文字 → 直接注入 DSH 正在运行的会话 → 回复推回手机(桌面会话同步可见) |
| 远程续聊(新增能力) | 手机向主话题发文字,自动恢复最近会话继续对话 |
| 自动更新提醒(1.3.0 起支持) | 守护进程周期检查 npm 新版本并推送手机提醒;其他命令发现新版本时终端提示 + 手机推送(1.4.0 起) |
| 开机自启(1.4.0 起支持) | a4p setup 默认启动守护进程并注册 Windows 开机自启,登录自动运行 |
1.1 工作流程
触发事件] --> B{a4phone Hook
拦截并分类事件} B -->|Stop 任务完成| C[系统通知
+ 手机推送] C --> D[推送 AI
最后输出] B -->|提问 / 权限请求| E{交互模式} E -->|外出模式| F[ntfy.sh
推送手机] F --> G[手机点选按钮] G --> H[决策注入
AI 助手] E -->|终端优先| I[终端提问
交互确认] style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#ebdef0 style C fill:#d5f5e3 style D fill:#d6eaf8 style E fill:#fdebd0 style F fill:#fadbd8 style G fill:#d5f5e3 style H fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style I fill:#d6eaf8
2. 安装
2.1 前置条件
- AI 编程助手已安装并可用:Claude Code、Codex 或 DeepSeek Harness(DSH)能在终端正常启动会话。
- Node.js 环境:版本 18 或以上。
- 手机设备:运行 iOS 或 Android 的智能手机,用于接收通知。
- Claude Code / Codex 已登录可用:远程续聊按最近会话的 agent 自动选择续聊方式(
claude --resume、codex exec resume或 DSH 进程内注入),需要对应 CLI 已登录且正常配置(如接入国内大模型也可)。 - (可选)DSH 已安装运行:如需 DSH 手机交互,先安装并运行 DeepSeek Harness(
~/.dsh/profiles/web目录存在),a4p setup检测到后会自动挂载插件;未安装则自动跳过该步骤。
2.2 安装 ntfy App
2.3 安装 a4phone
npm install -g a4phone
2.4 运行安装引导
a4p setup
安装引导自动完成:
- 生成独一无二的话题名称(如
a4p-xxxx),写入配置~/.a4phone/config.json,无需手动准备。 - 注册 Hook:在
~/.claude/settings.json自动写入三个 Hook(Stop / AskUserQuestion / PermissionRequest),并同时在~/.codex/config.toml末尾追加 Codex Hook(见第 7 章)。 - 挂载 DSH 插件:检测到 DSH 环境(
~/.dsh/profiles/web存在)时,把 a4phone 内置的dsh-hook插件挂载到~/.dsh/profiles/web/cordis.patch.yml(详见第 8 章)。 - 默认启动续聊守护进程:自动运行
a4p listen(后台无窗口),手机续聊开箱即用(1.4.0 起)。 - 默认注册开机自启(Windows):登录时自动运行续聊守护进程,无需手动配置(1.4.0 起,详见 5.2 节)。
- 显示二维码:终端打印订阅二维码,或粘贴话题内容完成订阅。

2.5 手机订阅
用手机 ntfy App 扫描终端二维码,或手动添加订阅并输入话题名称(如 a4p-xxxx)完成订阅。

重要:订阅完成后,务必在订阅设置中开启 "即时交付"(详见 9.2 节),否则消息需手动下拉刷新才能收到,提问/权限请求的交互也无法实时弹出。


3. 核心逻辑
- 拦截:Claude Code 触发事件时,Hook 调用
a4p hook(Codex 为a4p hook codex)。 - DSH 拦截:DeepSeek Harness 由 a4phone 内置的
dsh-hook插件直接监听会话事件(session/event、tools/execute、approval/request),复用同一 a4phone 话题与模式,无需单独的 hook 命令。 - 推送:
a4phone把通知推送到你的专属话题(ntfy.sh/话题名)。 - 点选:手机 ntfy App 收到带按钮的通知,你点击按钮。
- 回传:决策通过响应话题(
话题名-response)回传。 - 注入:Hook 收到决策后注入回 AI 助手(提问答案 / 权限 approve-deny)。
- 续聊:手机向主话题(
话题名)发送文字,守护进程a4p listen恢复最近会话继续对话,结果推回手机。
a4phone 只使用两个话题分工协作:
| 话题 | 用途 |
|---|---|
话题名 |
主话题,推送任务完成、提问、权限请求等通知;同时是远程续聊的对话通道 |
话题名-response |
响应话题,手机点按钮决策回传;也可自由文本/编号回复 |
提问回传方式:
- 按钮点选(选项 ≤ 3 个):手机通知上直接点按钮,ntfy App 自动 POST 回传,无需订阅响应话题。
- 编号回复 / 自由作答(选项 > 3 个自动降级为编号列表,或想自由回答):向响应话题
话题名-response发送编号(如「3」)或文字;若未订阅响应话题,可浏览器打开https://ntfy.sh/话题名-response直接回复(1.4.2 起提问推送自带该浏览器链接提示)。 - 注意:回复纯数字(如「3」)需要 a4phone ≥ 1.4.1——1.4.1 修复了纯数字被
JSON.parse误判为 JSON 对象而导致编号回复丢失的问题;按钮模式回按钮 label 即可。
格式说明:提问(PreToolUse 事件)Claude Code 返回
hookEventName: "PreToolUse"+permissionDecision: "allow"+updatedInput.answers(改写工具输入注入答案);Codex 因提问工具request_user_input忽略输入里的 answers,改用permissionDecision: "deny"+permissionDecisionReason把答案写进阻断原因,让模型直接采用答案继续。权限请求返回hookEventName: "PermissionRequest"+decision.behavior。两者是不同的事件 schema,a4phone 已正确处理。

4. 手机查看 AI 最后输出
任务完成后,推送的内容不再只有"任务已完成 + 目录 + AI 最后输出的一段话,一起推送过来,你离开电脑也能看到实际结果。
原理:Claude Code 的 Stop Hook 输入中带有 transcript_path,指向本次会话的 JSONL 会话记录。a4phone 解析该记录,取出最后一条 AI 回复文本(Claude Code 取 assistant 消息的 text 块;Codex 取 response_item 中的 assistant 消息,task_complete 事件仅作文件稳定时的兜底),截断到 1000 字符后随推送发出。
手机收到的任务完成通知形如:
任务已完成
目录: C:\项目目录
会话: 296e77be
AI 最后输出:
已经补充了 .gitignore 中缺失的缓存目录条目,并验证了所有 ?? 标记的未跟踪文件……
会话记录文件可能很大,a4phone 只截取最后一段文本的前 1000 字符,兼顾推送长度限制与可读性。
5. 手机远程续聊
5.1 续聊闭环
远程续聊是整套方案的进阶能力:任务结束后,你不需要回到电脑前,直接在手机向主话题发一条文字,即可恢复最近一次会话(Claude Code / Codex / DSH)继续对话,新的回复会自动推回手机。如果续聊过程中 AI 再次提问或请求权限,仍会推送手机交互,形成完整的远程对话闭环。
发送文字] --> B[ntfy.sh
消息服务器] B --> C[守护进程
a4p listen] C --> D[恢复最近会话
headless 续聊] D --> E[AI 处理
新请求] E --> F[Hook
拦截结果] F --> G[结果推送
回手机] G --> A style A fill:#fadbd8 style B fill:#fadbd8 style C fill:#ebdef0 style D fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style E fill:#ffecd6 style F fill:#ebdef0 style G fill:#d5f5e3

原理:Stop 事件触发时,a4phone 会把最近会话的 session_id、项目目录和来源 agent 记录到 ~/.a4phone/last.json。续聊时守护进程按最近会话的 agent 自动选择续聊方式:Claude Code 执行 claude --resume <会话ID> --continue -p,Codex 执行 codex exec resume <会话ID> -o <临时文件> -,并把手机发来的文字通过 stdin 管道作为下一条用户消息注入;headless 运行完成后,守护进程把回复推回手机主话题(Codex 用 -o 捕获最后一条回复)。DSH 的续聊方式完全不同——不另起进程,而是通过文件队列把消息交给 dsh web 进程内的插件,直接注入桌面上正在运行的同一个会话(详见 8.3 节),手机消息与 AI 回复都会实时出现在桌面会话里。续聊子进程的 Stop 事件带 A4P_RESUME 标记(DSH 用插件内标记),不会再重复推送"任务已完成"通知,结果统一由守护进程去重推送。
5.2 启动续聊守护进程
a4p listen 会启动一个后台守护进程(无窗口、不占用终端),实时监听主话题,收到手机文字即触发续聊:
a4p listen # 后台启动守护进程(无窗口)
a4p listen --status # 查看守护进程运行状态
a4p listen --stop # 停止守护进程
守护进程启动后终端提示:
续聊守护进程已后台启动(PID: 12345)。
日志: C:\Users\你的用户名\.a4phone\daemon.log
守护进程运行日志写入 ~/.a4phone/daemon.log,手机发文字后日志大致如下:
续聊守护进程已启动,监听: https://ntfy.sh/a4p-xxxx/json
提示:手机向话题 a4p-xxxx 发送文字即可与当前会话交流。
收到续聊请求:帮我总结一下刚才的改动
消息已处理(resume 续聊,退出码 0),结果已推送手机。
守护进程断线会自动重连;续聊请求串行处理,避免并发占用同一会话。
开机常驻方式:
- Windows(推荐,1.4.0 起自动):
a4p setup默认注册开机自启(在启动文件夹写入隐藏脚本,登录时自动运行守护进程,无需管理员权限);可用a4p autostart查看状态、a4p autostart --on/--off手动开关,a4p uninstall自动移除。 - WSL / Linux:
a4p setup不会自动注册,请用tmux或systemd常驻。
5.3 手机向主话题发送续聊消息
续聊不需要单独的续聊话题——你通过二维码订阅的主话题 话题名 就是对话通道:
- 手机 ntfy App 已订阅主话题
话题名(a4p setup生成,扫描二维码即可,无需额外订阅)。 - 在该话题页面输入你要追加的内容并发送(话题名称可用
a4p last或查看~/.a4phone/config.json确认)。 - 守护进程收到后自动恢复最近会话继续对话,结果推送回主话题。
5.4 手动续聊
未启动守护进程时,也可以在电脑上手动续聊:
a4p resume 帮我总结一下刚才的改动
手动续聊与手机续聊走同一套逻辑,适合临时调试或不便常驻守护进程的场景。
5.5 查看最近会话
a4p last
输出最近一次任务完成时记录的会话 ID、项目目录、来源与时间,用于确认续聊的目标会话。
5.6 续聊注意事项
- 支持 Claude Code / Codex / DSH 会话:守护进程按最近会话的 agent 自动选择续聊方式(Claude Code 用
claude --resume,Codex 用codex exec resume,DSH 用进程内插件注入,见 8.3 节)。Codex 续聊需 Codex CLI 已登录、Hook 已信任;DSH 续聊需dsh web正在运行且已挂载新版插件。 - Claude Code 会话独占:一个会话同一时间只能被一个进程占用,续聊前请先结束终端里仍在运行的原会话,否则会冲突。Codex 会话被窗口占用时(thread-store conflict),a4phone 会自动把它 fork 成新线程续聊——不需要关闭原窗口,原会话原样保留,手机对话在 fork 上继续。
- 自动切换外出模式:续聊期间守护进程会自动临时切换为外出模式(手机优先),结束后恢复原模式,保证续聊回合中的提问/权限请求走手机通道。
- 积压合并(1.2.1 起):一轮续聊最长可达
resumeTimeout(默认 30 分钟),期间手机连续发来的多条消息会自动合并为一个批次一次性续聊(不再逐条排队、每条一个独立轮次),保证手机内容一定能送达 AI;积压批次持久化到~/.a4phone/pending-batch.json,守护进程重启/崩溃后自动恢复,不丢消息。 - 续聊耗时:默认超时 30 分钟,可通过配置
~/.a4phone/config.json的resumeTimeout(秒)调整。 - 话题安全:ntfy.sh 公共话题可被知晓话题名的人读写,续聊文字会作为提示词喂给 AI,重要场景建议改用自建 ntfy 服务或访问令牌。
6. 模式切换
a4phone 内置两种交互模式,切换命令简短、即时生效:
a4p out # 外出模式:提问/权限请求优先推送手机,超时终端兜底
a4p home # 终端优先模式(默认):提问/权限请求直接走终端,手机不参与
a4p status # 查看当前模式
机制说明:Claude Code 的提问/权限请求只能接受一个答案来源——Hook 注入了手机答案,终端就不会弹出;反之终端弹出。两者无法同时生效,因此用模式切换。切换即时生效,无需重启会话。
7. Codex 配置
a4p setup 会同时自动配置 Claude Code 和 Codex:
- Claude Code:写入 ~/.claude/settings.json
- Codex:在 ~/.codex/config.toml 末尾追加 Hook 配置(自动保留你已有的模型/提供商等设置)
若需手动配置或核对,a4p setup 写入的 Codex 配置结构如下(启用项在 [features] 表内,Hook 定义为根级别数组):
[features]
hooks = true
# 任务完成
[[hooks.Stop]]
[[hooks.Stop.hooks]]
type = "command"
command = "a4p hook codex"
# AI 提问
[[hooks.PreToolUse]]
matcher = "request_user_input"
[[hooks.PreToolUse.hooks]]
type = "command"
command = "a4p hook codex"
# 权限请求
[[hooks.PermissionRequest]]
[[hooks.PermissionRequest.hooks]]
type = "command"
command = "a4p hook codex"
注意:Codex 的 Hook 启用项必须放在
[features]表内([features] hooks = true),不能写成根级别的裸hooks = true,否则会与[[hooks.*]]冲突导致 TOML 解析错误。提问工具名:Codex 的提问工具叫
request_user_input(不是AskUserQuestion),PreToolUse 的matcher必须匹配该名称 Hook 才会触发。a4p setup会把旧配置中的错误 matcher 就地修正为request_user_input。答案注入方式不同:Codex 端无法像 Claude Code 那样用
updatedInput注入答案(其 handler 忽略输入里的 answers),a4phone 采用"阻断工具调用、把手机答案写进阻断原因"的方式(permissionDecision: "deny"+permissionDecisionReason),让模型看到答案后直接采用继续。信任 Hook:Codex 会话中需运行
/hooks并手动信任(trust)新 Hook。
8. DSH(DeepSeek Harness)配置
从 a4phone 1.1.6 起,a4p setup 检测到 DSH 环境(~/.dsh/profiles/web 目录存在)时,会把本包内置的 dsh-hook 插件自动挂载到 web profile 的 cordis.patch.yml,让 DeepSeek Harness 同样具备手机远程交互。插件复用与 Claude Code / Codex 相同的 a4phone 话题与模式,手机端无需额外订阅。
| Hook | DSH 触发事件 | 手机交互(外出模式) |
|---|---|---|
| 任务完成 | turn/end 且 reason.kind === 'completed' |
系统通知 + 手机推送(含 AI 最后输出) |
| 提问 | ask_user_question 工具调用 |
手机点选选项 / 文字自由作答 |
| 权限请求 | approval/request |
手机 Approve / Deny |
8.1 插件挂载机制
- 插件位于 a4phone 包的
dsh/目录(Cordis 插件,监听 DSH 的session/event、tools/execute、approval/request事件),a4p setup以 insert 形式写入 patch,幂等可重复执行。 - 运行原理:Cordis 是 DSH 的底层插件框架,拉丁语意为「心脏」(词根 cor/cordis,与英语 cordial「衷心的」同源),DSH 本身即构建于其上。dsh-hook 是标准 Cordis 插件(导出
name/inject/apply并声明对@deepseek-ai/cordis的依赖),通过ctx.on监听会话事件流、inject注入tools与approval服务,再以 waterfall 拦截工具执行与审批请求——相当于挂在 DSH 的「心脏」上感知会话并完成手机交互。 - 若检测到旧版手动挂载(指向
C:\ProgramMine\dsh-hook的id: dsh-hook),a4p setup会自动替换为本包路径。 cordis.patch.yml被 DSH 热监视(watchUserPatches),挂载即时生效,无需重启;若插件代码有更新,可重启dsh web使新逻辑生效。- 目前仅挂载到
webprofile;a4p uninstall会同时移除该挂载。
8.2 模式、日志与限制
- 模式切换复用同一套:
a4p out(手机优先)/a4p home(终端优先)。 - Hook 日志:写入
~/.a4phone/dsh-logs/,按事件分类为task-complete.jsonl、question-asked.jsonl、permission-request.jsonl。 - 远程续聊(1.2.0 起支持):手机发文字继续 DSH 会话已实现,见 8.3 节。
机制说明:DSH 插件通过 Cordis 的 waterfall 机制拦截工具与审批——外出模式下返回自定义结果即替换原生提问/审批,把手机答案注入;返回 null 则回退 DSH 原生交互。行为与 Claude Code / Codex 一致。
8.3 DSH 远程续聊
从 a4phone 1.2.0 起,DSH 同样支持手机远程续聊。与其他 Agent 的续聊方式不同,DSH 续聊不另起进程,而是让 dsh web 进程内的插件直接把手机消息注入桌面上正在运行的同一个会话——因此手机消息与 AI 回复都会实时出现在桌面端会话里,手机与桌面看到同一段对话。

工作流程:
发送文字] --> B[ntfy.sh
消息服务器] B --> C[守护进程
a4p listen] C --> D[写入文件队列
~/.a4phone/dsh-jobs/req-*.json] D --> E[dsh web 进程内插件
agent.followup 注入会话] E --> F[AI 处理
新请求] F --> G[提取回复
写入 resp-*.json] G --> H[守护进程取回
推送手机] H --> A style A fill:#fadbd8 style B fill:#fadbd8 style C fill:#ebdef0 style D fill:#d5f5e3 style E fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style F fill:#ffecd6 style G fill:#d5f5e3 style H fill:#d5f5e3
机制细节:
- 记录最近会话:插件在每次顶层会话
turn/end(completed)时写入~/.a4phone/last.json(agent: "DSH"),与 Claude Code / Codex 的 Stop Hook 记录方式一致,a4p resume/a4p listen据此路由到 DSH 会话。 - 文件队列协议:a4p 把手机消息原子写入
~/.a4phone/dsh-jobs/req-<id>.json;插件每秒扫描,处理后写resp-<id>.json,a4p 轮询取回并推回手机;插件同时刷新~/.a4phone/dsh-heartbeat.json心跳,a4p 据此快速判断dsh web是否在运行——未运行会立即给出提示,而不是干等 30 分钟超时。 - 注入桌面会话:插件用 DSH 的
agent.followup()把手机文字作为普通user/message写入当前 live 会话(目标会话优先取last.json记录的会话,兜底最近顶层会话),await agent.whenIdle()等待轮次结束,提取最后一条 assistant 文本回推。 - 无会话锁冲突:不另起进程,不存在 Claude Code
--resume式的独占锁问题;续聊轮次内若触发提问/审批,仍走手机交互,形成完整闭环。 - 去重推送:续聊轮次的"任务完成"推送自动跳过(回复已由 a4p 推回手机)。
使用前提:
dsh web正在运行,且已挂载新版dsh-hook插件(a4p setup自动挂载;插件代码更新后需重启dsh web)。- 桌面端至少完成过一轮会话(触发插件记录最近会话,
a4p last显示来源为DSH)。 - 守护进程使用 1.2.0 及以上版本(推荐 1.4.2+;升级后需
a4p listen --stop && a4p listen重启守护进程)。
9. 生效步骤与注意事项
9.1 生效步骤
- 重启会话:Hook 在会话启动时加载并缓存,配置后需完全退出并重新启动 Claude Code / Codex。
- Codex 信任 Hook:Codex 需在会话中运行
/hooks命令,然后手动信任(trust)新安装的 Hook 才会生效。Claude Code 无此步骤。 - DSH 插件热生效:
cordis.patch.yml被 DSH 热监视,挂载即时生效,无需重启dsh web(插件代码有更新时除外)。 - 模式切换即时生效:
a4p out/home切换的是模式文件,Hook 每次触发时实时读取,无需重启会话。
9.2 手机收不到通知
第一步:开启订阅的"即时交付"
ntfy App 对每个订阅默认不启用实时推送,导致消息要手动下拉刷新才能看到。开启后消息即可实时到达:
- 打开 ntfy App,进入会话列表。
- 点击右上角三个点 → 订阅设置。
- 开启 "即时交付"。
开启后,锁屏状态下任务完成通知和提问/权限请求的交互按钮都能实时弹出,无需手动刷新。此设置是整套方案能否"即时交互"的关键,务必开启。主话题
话题名(同时也是续聊对话通道)同样需要开启"即时交付",续聊回复才能实时到达手机。
第二步:确认配置与订阅无误
- 确认手机 ntfy App 已正确订阅了话题(与
a4p setup生成的话题名称一致)。 - 确认手机网络连接正常(ntfy.sh 需要互联网访问)。
- 检查手机通知权限是否对 ntfy App 开放。
- 尝试在浏览器访问
https://ntfy.sh/你的话题名称,看是否能看到消息记录。
第三步:排查 App 长连接断开
如果已开启"即时交付"仍收不到,且浏览器能显示消息、但 App 里看不到,说明推送已成功发到服务器,问题在 App 的常驻连接被系统中断。
ntfy App 靠一条常驻连接接收新消息。当手机锁屏、App 被切到后台、或网络在 Wi-Fi 与流量间切换时,这条连接可能被系统掐断,新消息就都收不到。
解决办法:
- 打开 ntfy App,进入对应话题页面,下拉刷新强制重新建立连接。刷新后若出现之前未收到的消息,说明此前连接断了。
- 让 App 保持活跃连接,防止系统杀后台: - Android:设置 → 应用 → ntfy → 电池/后台限制 → 设为"不受限制"。 - iOS:确保不允许 App 被系统挂起,并保持通知权限开启。
- 部分国产手机(如华为)有额外的"应用启动管理",需手动关闭"自动管理"并开启自启动/后台活动;必要时可用 adb 将应用加入系统休眠白名单:
adb shell dumpsys deviceidle whitelist +io.heckel.ntfy。 - 若订阅了多个话题,确认没有残留旧的(或错误的)话题订阅导致收错频道。
国内网络提示:ntfy.sh 为国外服务,国内网络下长连接可能不稳定,表现为消息需手动刷新才能看到。若遇到此情况,可结合"即时交付"与刷新使用,或在网络稳定时使用。
9.3 Hook 配置后没有生效
- 输入
/hooks查看 Hook 是否被加载(Codex 需确认已信任)。 - 确认 Codex 已设置
hooks = true。 - 确认
matcher匹配正确(如实际触发的是 Bash 权限请求,需匹配Bash而非AskUserQuestion)。 - DSH 侧确认
~/.dsh/profiles/web/cordis.patch.yml中存在id: dsh-hook的 insert 块(a4p setup未检测到 DSH 环境时不会写入)。
9.4 ntfy.sh 限流提示
ntfy.sh 免费托管服务有发布速率/消息保留限制,短时间高频测试可能触发 limited 提示,建议降低推送频率(续聊结果已去重推送,不再重复通知)。
9.5 自动更新提醒(1.3.0 起支持)
a4phone 默认开启版本更新提醒,发现 npm 新版本时主动通知你,避免错过更新:
- 检查机制:守护进程(
a4p listen)启动时及每updateIntervalHours小时(默认 6 小时)检查一次 npm registry(npmmirror 镜像优先、官方 registry 兜底),查询失败静默跳过,不影响正常功能。 - 提醒方式:发现新版本 → 守护进程推送手机提醒(标题
a4phone,含升级命令);其他命令(a4p status/a4p resume等)发现新版本时终端提示 + 手机推送(1.4.0 起)。 - 去重与限频:同一新版本只提醒一次(缓存
~/.a4phone/update-cache.json);升级后立即检查(1.4.2 起,避免旧缓存把升级后的首次检查推迟一整个间隔)。 - 关闭 / 调整:在
~/.a4phone/config.json设"checkUpdates": false关闭;"updateIntervalHours": 12调整检查间隔(小时)。 - 前提:需要 a4phone ≥ 1.3.0 且守护进程/命令运行新版本代码(升级后
a4p listen --stop && a4p listen重启守护进程)。
10. 测试验证
# 发送测试通知到手机
a4p test
# 测试手机交互:切换到外出模式,触发一次提问或权限请求
a4p out
# ...触发 AskUserQuestion 提问或 Bash 权限请求,观察手机是否收到带按钮的通知...
a4p home
# 触发一次任务完成(Stop)事件,验证推送含 AI 最后输出
codex -c "print('test')"
# 测试远程续聊
# 1. 启动守护进程:a4p listen(后台无窗口运行)
# 2. 手机向主话题发送文字,验证恢复会话并回推结果
# 3. 或电脑端手动续聊:a4p resume 帮我总结一下刚才的改动
# 4. 查看最近会话:a4p last
# 测试 DSH 交互(需已安装并运行 DSH)
# 1. 确认插件已挂载:cat ~/.dsh/profiles/web/cordis.patch.yml(应含 id: dsh-hook)
# 2. 外出模式下在 DSH 会话触发提问/审批,观察手机是否收到带按钮的通知
# 3. 完成一个任务回合,验证手机收到任务完成通知(含 AI 最后输出)
# 4. 查看 DSH Hook 日志:~/.a4phone/dsh-logs/
# 测试 DSH 远程续聊(需 a4phone ≥ 1.2.0,dsh web 正在运行)
# 1. 确认最近会话为 DSH:a4p last(来源显示 DSH)
# 2. 手机向主话题发送文字(如"我们刚才在做什么?")
# 3. 预期:桌面端会话里实时出现手机消息与 AI 回复;手机收到 DSH 回复推送
# 4. 守护进程日志:~/.a4phone/daemon.log(显示"DSH 续聊请求已提交")
# 测试多选项编号回复(选项 > 3 个,a4p out 模式下触发 5 选项提问)
# 1. 手机向响应话题发送编号(如 3),AI 应收到对应选项
# 2. 或浏览器打开 https://ntfy.sh/话题名-response 直接回复(无需订阅响应话题)
# 测试自动更新提醒(a4phone ≥ 1.3.0)
# 1. 确认 config.json 的 checkUpdates 为 true(默认开启)
# 2. 守护进程运行中,npm 发布新版本后手机应收到"a4phone 新版本"提醒
# 测试开机自启(a4phone ≥ 1.4.0,Windows)
# 1. a4p autostart # 查看状态(setup 后应为已开启)
# 2. a4p autostart --off / --on # 关闭 / 重新开启
续聊会真实调用 AI 助手(Claude Code / Codex / DSH)消耗一次回复,请确认已配置好后再测试。
11. 常用命令速查
| 命令 | 作用 |
|---|---|
a4p setup |
安装引导:生成话题、注册 Hook、挂载 DSH 插件、启动守护进程、注册开机自启、显示二维码 |
a4p out |
外出模式(手机优先) |
a4p home |
终端优先模式(默认) |
a4p status |
查看当前模式 |
a4p listen |
后台启动续聊守护进程(监听主话题) |
a4p listen --status |
查看守护进程运行状态 |
a4p listen --stop |
停止守护进程 |
a4p autostart |
查看开机自启状态(--on 开启 / --off 关闭) |
a4p resume |
手动续聊最近会话:a4p resume 要追加的内容 |
a4p last |
查看最近会话记录 |
a4p test |
发送测试通知 |
a4p uninstall |
卸载:移除 Claude Code / Codex / DSH Hook、开机自启和配置 |
a4p --version |
查看 a4phone 版本号 |
重新安装:卸载后可再次运行
a4p setup,会生成新话题,需在手机重新订阅。
举手提问