债券匠d
本地守护进程, 管理您机器上 tmux 备份的终端会话并将其曝光到 Bondsmith的网络应用 在一个签名的 WebSocket 协议。 完全运行在自己的机器上——没有代码, 终端输出, 或会话数据被发送到任何地方, 除了明确指定的 Bondsmith 账户 与相对.
安装
npm install -g @bondsmith/bondsmithd
需要节点 QQ24和 tmux 3.2或更新(brew install tmux (原始内容存档于2018-09-28). on macOS. node-pty一个本地人
依附,船舶预建了macOS(英特尔和苹果硅)并安装了无
在支持的平台上编译任何内容 .
运行
bondsmithd
在第一次比赛中, bondsmithd 打印配对代码和 URL — 从您的 Bondsmith 账户确认
相信这台机器。 在那之后,我们.., bondsmithd 只是需要运行 邦德史密斯网络应用
以查看和控制此机器上的会话.
从正常的交互外壳开始,而不是从剥去的上下文开始(裸出) launchd/登录项目
引用,最小CI外壳等). 守护者通过自己的 process.env 通到每个
tmux 会话创建, 因此会话继承您的真实 PATH,版本管理器shims
(单位:千美元)mise编号 :nvm和工具 claude 或者说 pnpm 同样的环境,你会打开一个
新终端标签 。 守护进程启动时被剥去的环境意味着同样被剥去的环境
在它所发动的每届会议上.
环境变量( 所有可选) :
PORT=4577 # defaults to 4577
ALLOWED_ORIGINS=https://app.bondsmith.dev
BONDSMITH_RELAY_URL=ws://127.0.0.1:8787 # defaults to production; set this when developing bondsmithd against a local apps/relay
BONDSMITH_RELAY_AUDIENCE=relay.example.com # only if a non-loopback relay's RELAY_AUDIENCE differs from its hostname
BONDSMITH_API_URL 必须是 https://,以及 BONDSMITH_RELAY_URL 必须是 wss://; 平原语 http://
财务报告和审定财务报表 ws:// 仅对回回路服务器接受窗体(127.0.0.1, (中文(简体) ), localhost, (中文(简体) ), [::1]) (中文(简体) ). 中继
URL仅在中继器启用时被选中 。 守护进程拒绝向听众不是的中继器注册
中继 URL 的主机名( 或) BONDSMITH_RELAY_AUDIENCE; 不检查回转中继 .
BONDSMITH_DEV_TUNNEL_TOKEN 也存在,但只适用于遗留的直接连接路径
(单位:千美元)BONDSMITH_RELAY_ENABLED=false)——不应为普通安装手设.
更新
停止运行守护进程, 然后更新并重新开始 :
npm install -g @bondsmith/bondsmithd@latest
bondsmithd
如果你运行它与 npx,使用时 npx @bondsmith/bondsmithd@latest 所以一个缓存的旧拷贝是不会被重用.
当网络应用程序和一个更古老的守护进程出现分歧时, Bondsmith 显示 "无法读取您的留言 守护进程". 先重新装入页面;如果无法修复,则更新守护进程如上.
它会做什么
- 创建、列表、附加和停止 tmux 会话前缀
bondsmith-*。 。 。 . - 从不列举或管理它没有创建的 tmux会话.
- 附加一个真实的 PTY (
tmux attach-session所以无论里面有什么claude, (中文(简体) ),opencode, (中文(简体) ),bash任何事物)的行为都和普通终端一样. - 将tmux本身保持为真相的唯一来源——没有数据库. 重新启动守护进程重新发现 从 tmux 运行会话.
代理状态
经纪人可以告诉邦德史密斯它在做什么 从它的会话面板内运行,通常
从它的一钩. $TMUX_PANE 由 tmux 在每个窗格中设置,所以命令针对会话
属于:
tmux set-option -t "$TMUX_PANE" -q @bondsmith-agent-state "waiting:$(date +%s)"
值为 <state>:<epoch seconds>,状态在哪里 working, (中文(简体) ), waiting (需要用户)或 done (完成一转,显示至用户附着后,打出或调整大小后).
守护进程在它的5秒滴上读取并显示在会话上. 其它东西都被忽略了,就像
未来的报告。 A 类 waiting 或者说 done 一旦窗格多写输出, 报告就会被删除
超过2秒,因为这意味着 代理继续前进。 A 类 working 一旦报告
pane已经沉默了2分钟,因为一个中断或坠毁的特工再也不会报告.
Claude 代码会话, Bondsmith 以简单开头 claude 自行报告(见
计划部分: working 当警告来临的时候, waiting 当它请求许可或失败时
aPI 错误, done 当它完成一个转弯。 没有什么需要安装这些.
对于代理,守护进程没有设置(一个包装器, npx claude,另一个代理人),注意每次会话
邦德史密斯开始 BONDSMITH_SESSION 设置到它的id,所以一个为您所有项目安装的钩子可以
在别处保持沉默 本条目在 ~/.claude/settings.json 报告 Claude 代码会话
等待它请求许可的时刻, 和它结束一个回合时一样:
{
"hooks": {
"PermissionRequest": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "[ -n \"$BONDSMITH_SESSION\" ] && tmux set-option -t \"$TMUX_PANE\" -q @bondsmith-agent-state \"waiting:$(date +%s)\"; exit 0"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "[ -n \"$BONDSMITH_SESSION\" ] && tmux set-option -t \"$TMUX_PANE\" -q @bondsmith-agent-state \"done:$(date +%s)\"; exit 0"
}
]
}
]
}
}
这是可选的, 没有为您编辑您的设置 。 命令除了邦德史密斯之外什么都不做
会话,在守护进程设置之前开始的会话会被它跳过 。 它只报告
waiting 财务报告和审定财务报表 doneA级 working 报告在窗帘静默两分钟后被删除,所以一个是
中断的 Claude 代码从不清除( 它没有运行) Stop 然后,没有钩子可以逃出
自己来的.
一个特工也可以分享它所反对的计划, 邦德史密斯在会议前显示
变化。 写作降级 .bondsmith/plan.md 在会议文件夹中 一旦计划达成一致,
当它改变的时候,它会再次改变。 文件按原样阅读,以32,768个字符剪接;并联,或
路径将忽略会话文件夹。 未跟踪时更改不列出文件 .
守护进程从不写到您的仓库, 所以 git status 仍然显示它 git add . 承诺;
添加 .bondsmith/plan.md 给您的 .gitignore 或者说 .git/info/exclude 来防止这种情况.
钩子可以将计划存储在寄存器外, 在 ~/.bondsmith/plans/<session id>.md时
<session id> 实值 $BONDSMITH_SESSION。它以同样的方式读取并赢得文件夹文件和 tmux
选项,所以写好的计划 永远不会从早先的会话中留下.
Claude Code是守护神自己设置的 当一个会话的命令是 claude (这个单词,不是
后面 npx 或包装; VAR=value 之前的文字是好的,守护进程开始它作为
claude --settings ~/.bondsmith/hooks/claude-settings.json …。该文件增加了钩子
一旦计划模式提出,在批准之前,就把计划储存起来;
另记录代理任务调用( o)TaskCreate, (中文(简体) ), TaskUpdate, (中文(简体) ), TodoWrite改为: ~/.bondsmith/plans/<session id>.tasks.jsonl, (中文(简体) ),
守护进程重放到会话任务列表中(在浏览器中显示在计划下);以及 4
报告代理状态( e)working 以示警告; waiting 根据许可请求,转弯结束,或转弯失败
a API 错误)。 没有 ~/.claude 更改,会话仍然显示您键入的命令和钩子
除了Bondsmith会话之外 什么都不做 克劳德代码 /hooks 菜单中不列出通过的勾钩
--settings虽然他们跑.
第五个钩子手表 Bash呼叫 gh pr create当成功并打印拉动请求 URL 时, URL 是
附加在 tmux 选项 @bondsmith-prs (空位相隔,每间相隔一次,最新保存了20个),守护进程
会议报告 pullRequestUrls匹配 gh pr create 只是作为自己的命令,所以
echo "gh pr create" 或者说 gh pr view 没有记录,一个失败的命令从来没有达到它.
如果命令已经存在, 守护进程就离开命令 --settings,如果已安装 claude 不列出
--settings 内 claude --help (每个守护进程运行一次被请求;如果 claude 无法运行, 已登录
一分钟后再次问,或 BONDSMITH_AGENT_HOOKS 设置为 off, (中文(简体) ), 0, (中文(简体) ), false 或者说 no 地点
守护进程开始 。 每个钩子都有一个超时(5秒的状态报告,10秒的计划和任务列表),所以一个被卡住的命令
无法阻止代理。 计划是写给 ~/.bondsmith/plans 只能由您读取, 和符号链接
方法被替换,而不是遵循。 代理在不经过计划模式的情况下改变的计划是
未见; 钩子的计划一直取胜于文件夹的文档直到下一次批准.
无法写入文件的代理可以设置 tmux 选项, 而不是从会话的窗格中设置 。 文件 当两者同时存在时胜出 :
tmux set-option -t "$TMUX_PANE" -q @bondsmith-plan "$(cat <<'EOF'
# What the session is doing
- step one
- step two
EOF
)"
保持简短: tmux 拒绝超过 16,000 字节的命令( 测量: 16,000 个作品, 17,000个) 以“ 命令太长” 失败, 因此没有存储更长的计划, 面板继续显示上一个 一个 文件没有这样的限制 .
守护进程只在浏览器询问时才读取计划, 因此不同于状态报告, 它没有时间戳 并不会在窗格写出输出时被删除.
没有钩子的特工仍能通过敲响终端铃来引起注意(printf '\a') (中文(简体) ). 钟声
在一次会话中,没有人将它看成是等待,不管它上次的报告怎么说,直到tmux
当某人加入会话时,会清除旗帜。 特工可以按铃 批准或
a 完成的回合工作方式为无可安装.
没有钩子和铃声,会话仍然显示 waiting 一旦它的面板写了东西 然后
沉默了8秒钟。 特工们在工作时动了手脚 需要你时就停手了
设置任何代理。 无法从完成的转弯中得知批准提示, 以及长期无声的命令
看起来像一样。 A 类 working 当代理员继续写时, 钩状报告优先于此, 停止计数
一旦窗帘静了两分钟.
附加到会话中,在会话中打入,重新调整大小,或者在会话中插入文本作为用户的视线, 故重画所引起者被忽略(在3秒内输出),会话读作等待 只有在新输出安静下来之后 当守护进程启动时, 它已经找到的会话数 因此在重启前等待的 显示在它写得更多之后.
tmux 只在没有客户端附着到会话或铃声在窗外时标记铃声 所附客户端开着的 一个终端在浏览器标签中打开的会话, 甚至隐藏 一,算作被看,所以里面的铃声没有被标出;用钩子报告这个案例.
添加代理服务器
守护魔从一个特工的身上 分了每个特工的相同之处.
| 编 | 何处 | 具体探员? |
|---|---|---|
| 代理人报告什么: 状态、计划、任务清单、调取请求(以下渠道) | src/sessions/agent-reports/ | 没有 |
将报告变成UI显示的内容(readSessionReport: 计划和任务清单 getPlan; 注意状态) | agent-reports/, (中文(简体) ), tmux/agent-state.ts | 没有 |
| 认识一个特工的指挥并发动它,所以它报告 | src/sessions/agents/<agent>/ | 对 |
| 特工名单 | AGENT_IDS 内 @bondsmith/local-agent-protocol· ; agents/registry.ts | 每行增加一行 |
一个特工通过这些渠道报道,守护进程在不关心谁写的情况下读取:
| 报告 | 频道 |
|---|---|
| 状态 | tmux 选项 @bondsmith-agent-state =: <working|waiting|done>:<epoch seconds> 在会话的窗帘上; 或按铃; 或无动于衷 |
| 计划 | ~/.bondsmith/plans/<session id>.md,或 .bondsmith/plan.md 在会话文件夹中,或 tmux 选项 @bondsmith-plan |
| 任务列表 | ~/.bondsmith/plans/<session id>.tasks.jsonl一个JSON TaskEvent 附录,每行add, (中文(简体) ), update, (中文(简体) ), remove, (中文(简体) ), replace; 见 agent-reports/task-list.ts(中文(简体) ) |
| 调取请求 | tmux 选项 @bondsmith-prs,空间分隔的 URL |
要添加代理符: 将其ID添加到 AGENT_IDS,这就 registry.ts 在有适配器之前拒绝编译。 一个新的
AgentAdapter 需求 matches(command) 财务报告和审定财务报表 capabilities,每个能力都具有可选功能(report 发射毒剂以便报告; deliverNote 财务报告和审定财务报表
withdrawNote 离开,拿回一张纸条 它在它的下个钩,看 agent-reports/notes.ts) (中文(简体) ). 无用 plainAdapter(id), (中文(简体) ),
就像Codex和opencode今天所做的(它们通过铃声和静板检查报告). 用钩子,把经纪人的
设置和有效载荷映射 agents/<agent>/ 从帮手那里建立钩子命令
agent-reports/hook-commands.ts 财务报告和审定财务报表 agent-reports/hook-scripts.ts;代理文件只注明其位置
负载计划,任务事件和外壳命令都是. agents/claude/ 是一个实例.
生产连通性(现状)
bondsmithd 默认连接到邦德史密斯继电器(BONDSMITH_RELAY_ENABLED=true, (中文(简体) ),
BONDSMITH_RELAY_URL=wss://relay.bondsmith.dev),这就是生产帐户的实际内容
使用 —— 没有涉及dev-tunnel 令牌, 没有真正安装所需的配置 。 覆盖
BONDSMITH_RELAY_URL 仅当本地应用程序/中继实例(见上文“环境变量”)
发展自成一体.
Dev-tunnel-token 要求仅适用于遗留的直接连接路径
(单位:千美元)BONDSMITH_RELAY_ENABLED=false),这仍然是404路由
设计——该路径仅用于本地调试,而非真正的安装.
安保模式
- 每条连接都会与守护进程相对应
ALLOWED_ORIGINS并填写 a 密码握手——由控制器密钥签名的一款新鲜,单用,守护进程发布的挑战 守护进程被当地人明确信任 关于控制器密钥, 见上文“ 对等” 成为信任的第一. - 每个敏感命令和每个敏感读取(会话列表、工作空间状况、 diffs, +) 每一个改变国家的行动)必须作为同一经认证和签名的连接的一部分到达—— 阅读访问不被视为比写访问风险低,因为读取可以曝光会话 元数据和源代码就像写作一样可以改变它.
- 重放保护是连接范围,完全生活在守护进程记忆中——没有关于 它被坚持到磁盘上,所以浏览器重新装入或重新连接总是开始一个干净,独立的 届会.
- 撤销对控制器的信任( 从您的 Bondsmith 账户) 关闭其活动连接 无论是否在会中.
- 只接触过它自己创建的 tmux会话, 命名为
bondsmith-<uuid>。 。 。 . - 所有 tmux/PTY 引用使用 argv 阵列,从不 shell 字符串插入.
- PTY/地铁内容从未被守护进程本身记录或坚持.
- 这不是针对您机器之间的网络路径的保密边界 和 Bondsmith Cloud ——设计假设源,协议行为,守护进程二进制本身 被攻击者充分观察到,并且通过密码签名和 当地的信任决定, 从来不对密码保密。 Dev-tunnel 录取标志描述 上文“生产连接”下的一个例外(一个真正的共享保密机制), 但它只适用于遗留的直接连接路径,而不是真正的安装用途的中继路径.
全部设计细节 : docs/architecture/local-sessions-auth-decision-log.md 输入
债券存储器。 。 。 .
贡献/发展债券
本节针对的是: bondsmith 单列波,不适用于已安装的用户
已发布软件包.
pnpm --filter @bondsmith/bondsmithd dev
这是故意的 没有 部分内容 pnpm dev 编号 : turbo dev 它需要tmux和一个本地模块
在主机上,它是选入工具, 不是一个服务 其余的堆栈依赖.
节点被固定在 1.2.0-beta.15,而不是 1.1.0 稳定释放. 1.1.0预建
darwin-arm64 二进制失败 posix_spawnp failed 在节点 24 (在 macOS 上核实)
15/Apple Silicon)——任何产卵而不只是tmux,崩溃了整个守护进程. 这个 1.2.0-beta
线路有一个在节点24上正确工作的预建. 不要降级到一个 node-pty 稳定释放
不首先确认 pty.spawn(...) 实际在你的节点版本.
为地方发展建立一个 .env 此目录中的文件( 或直接导出 vars ) :
PORT=4577
ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000,http://localhost:4000,http://127.0.0.1:4000
4000号港口被包含在内 因为那是 make devDocker 堆栈服务于网络应用程序
(单位:千美元)docker-compose.dev.yml 地图 4000:4000); 端口 3000 覆盖运行 apps/web 直接通过
pnpm dev:web 换句话说.
网络应用需要 NEXT_PUBLIC_LOCAL_AGENT_DAEMON_URL=ws://127.0.0.1:4577 设置在它读到的地方
从 下 make dev 这就是重击根 .env.local (参见:
docker-compose.dev.yml是因为 env_file(没有) apps/web/.env.local。 。 。 .
出版
pnpm --filter @bondsmith/bondsmithd build 捆绑 @bondsmith/local-agent-protocol 直接输入
dist/index.js (见 tsup.config.ts是因为 noExternal)——已发布的软件包没有 workspace:*
对任何登记册上存在的软件包的依赖和运行时间不依赖。 仅 dist/index.js, (中文(简体) ),
package.json,而该读取器则发布(见 package.json是因为 files); 源图和每个
其他 repo 文件不包括在内.
非目标(现行范围)
没有云执行,没有多机支持,没有会话共享,没有克洛德/OpenCode API 集成, 没有代理输出解析或检测, 没有终端历史存储或会话 记录.