agent 

Joint 把 Cursor、Claude Code、Codex CLI 的实时终端同步到你的手机——不只是看进度,你可以直接在手机上回复它,就像坐在电脑前打字一样。

开源自托管 · 你的数据只经过你自己的服务器

场景

agent 卡在「要不要继续?」上, 等了你 40 分钟。

完成通知在这个场景里毫无用处——任务根本没完成。你需要的不是「看到」,是「回复」。

00:00

你让 agent 跑一个大重构,然后去吃饭。

00:03

它停在 Do you want to proceed? (y/n) 上。

00:43

你回到电脑前。40 分钟,什么都没发生。

产品模型

两条通道

一条负责告诉你发生了什么,一条负责让你把话说回去。

emit

事件通知,零开销

以 hook 的形式挂在工具里,只在离散事件(需要确认、任务结束、出错)触发时推送一条通知。不常驻、不拦截输出。

run

PTY 包裹,实时双向

用伪终端包住你的命令,把整屏输出同步到手机;你在手机上打的字会原样写回本地终端,和坐在电脑前敲键盘没有区别。

joint-notify run --tool claude-code -- claude
   │
   ├── PTY ──▶ @xterm/headless ──▶ 当前这一屏 ──▶ 手机
   │
   └──────────────  你在手机上输入的按键  ◀──────────────

兼容性

支持你在用的那一个

hook 会写进各自的配置文件;而 run 本来就能包裹任意命令行工具。

Cursor

~/.cursor/hooks.json

  • 支持完成通知
  • 支持实时会话
  • 覆盖风险:追加写入,已有 hook 不受影响

Claude Code

~/.claude/settings.json

  • 支持完成通知
  • 支持实时会话
  • 覆盖风险:会修改 settings.json,建议先备份

Codex CLI

~/.codex/config.toml

  • 支持完成通知
  • 支持实时会话
  • 覆盖风险:可能覆盖已有的 notify 命令,安装前请确认

任意 CLI 命令

无需配置文件

  • 不提供事件通知
  • 支持实时会话
  • 覆盖风险:无覆盖风险

技术细节

为什么手机上看着不乱

桌面端先用 @xterm/headless 把原始字节流解释成「当前这一屏」,再同步到手机。进度条、spinner、TUI 是刷新后的画面,不是一堆重复行。

朴素 ANSI 剥离

⠋ Building  12%
⠙ Building  27%
⠹ Building  48%
⠸ Building  61%
⠼ Building  88%
⠴ Building 100%

Joint

⠴ Building 100%
✔ 12 files changed

Do you want to proceed? (y/n)
▍

安全模型

把权限边界摆在明面上

你装之前一定会想这个问题,所以我们不把它藏进文档深处。

我们做了什么

  • 配对验证码只存 HMAC 摘要
  • 验证码 5 次猜错即作废
  • 按 IP 限流
  • 设备令牌可随时吊销
  • 会话之间按 sessionId 隔离

边界在哪

  • 手机账号 = 你所有已配对机器上正在运行的 run 会话的键盘
  • run 会话内可以执行任意输入
  • 只有你主动 run 起来的会话会被同步

还没做的

  • 生产环境必须自行配置 HTTPS/WSS
  • 用户令牌 180 天有效期,暂无服务端吊销名单
阅读完整安全模型

开始使用

四步,一步都不藏

第一步会劝退一部分人。这是自托管的固有代价,我们选择写清楚,而不是藏起来。

1

部署后端

手动部署,暂无一键命令

自托管,数据只经过你自己的服务器。

查看部署教程
2

安装手机 App

TestFlight / Android APK

填入你的后端地址,邮箱登录。

查看构建状态
3

配对电脑

输入手机上的 6 位配对码

下载桌面连接器完成配对。

查看详细教程
4

开启 Hook 或实时会话

joint-notify run -- <你的命令>

或勾选你在用的工具,让 hook 自动生效。

查看详细教程

准备好让 agent 找得到你了?