文档

smelt 是一个跑在 Mac 上的桌面工作台:内嵌真终端,专为「同时开着好几个 Claude Code 会话」这件事设计。这页文档只讲怎么用,架构细节不在这——smelt 现在还是 working prototype,接口和默认行为可能会变。

快速开始

GitHub Releases 下载 Smelt.dmg,拖进 应用程序文件夹,打开即可,只支持 Apple Silicon Mac。

退出 smelt 甚至它崩溃了,里面跑着的 shell(包括正在干活的 claude)不会被杀掉, 后台继续活着;重新打开 smelt,之前的分屏布局和终端会话都会自动恢复,不用重新 cd 进项目、重新跑一遍命令。注意这只扛得住"关 smelt",扛不住重启电脑——重启会 把所有进程一起带走。

想从源码构建、或者想搞清楚内部是怎么拼起来的,看开发文档

打开项目

smelt 没有独立的"项目列表"——项目就是某个会话的工作目录(cwd),跟着会话走, 没有单独的项目配置文件。打开一个项目有几种方式:

  • 拖拽:把项目文件夹(或文件)直接拖进窗口,会以该目录为 cwd 开一个新会话。
  • 侧栏底部"打开项目"按钮,或 Cmd+K 命令面板里的"打开项目…":弹系统原生的 文件夹选择框,选中后开新会话。
  • 项目分组行右侧的 +:在这个项目已有的 cwd 下继续开新的终端,或执行设置里 配置的启动命令(默认含 Claude Code / Codex / Copilot)。 启动项在设置 →「启动」里按 显示名 + 命令 自由增删改。
  • 顶栏的 + 新建标签:不弹选择框,直接继承当前会话的 cwd。

首次启动、还没有任何存档会话时,界面是空态页,提供"新建会话"和"打开项目…"两个 入口。侧栏里的项目分组是根据各会话的 cwd 动态派生、去重展示的,随会话一起存进 ~/.smelt/workspace.json,下次打开原样恢复。

功能一览

终端

  • 完整 ANSI / 256 色 / 24-bit 真彩色,Nerd Font 图标正常显示
  • 能跑交互式程序和全屏 TUI:claudevimhtop 都是真跑起来,不是阉割版伪终端
  • 10000 行滚动回看,鼠标滚轮 / Shift+PageUp / Shift+PageDown 翻页
  • 中文输入法(IME)原生支持
  • 拖拽框选复制,双击选词,三击选行
  • Cmd+C 复制选区,Cmd+V 粘贴剪贴板

工作台外壳

  • 多标签,每个标签独立 PTY / 历史 / 焦点,+ 新建、× 关闭
  • 分屏布局,窗口结构会自动存档,下次打开原样恢复
  • 每个会话主区顶部是一排视图标签,鼠标点击切换(无独立快捷键):终端(默认舞台)/ 任务总览 / 文件树 / Git diff / Skill / 历史会话
  • 每个会话按状态着色:灰=空闲、蓝=运行中、绿=任务刚完成待查看、橙=需要你处理、 红=等你批准操作(优先级最高),多开几个 agent 时一眼看出该管哪个
  • 菜单栏(Dock 之外)常驻一个图标,点击不弹菜单,只是把 smelt 主窗口前置唤出

文件树视图

  • 支持文件名 / 内容混合搜索:一次搜索同时匹配文件名和文件内容,文件名命中排前、 内容命中排后并显示行号 + 预览;点击结果会打开对应文件,但不会自动跳转/定位 到命中的那一行
  • .md 文件顶部有"编辑 / 预览"切换(其他文件类型没有这个切换),预览按 markdown 渲染标题、列表、代码块等;编辑和预览共享同一份内容,随时切回继续改
  • 右键文件/目录 →"发送到终端":把路径转成相对项目根的 @路径 提及文本,写入 当前激活终端的输入框(不自动回车);在文件内容里选中一段文字右键 → "发送选中内容到终端",发送的是选区文本(带文件名 + 代码块包裹)。两者都固定 发给当前激活终端,不支持选择目标
  • Cmd+S 保存:未保存时文件名旁有一个脏点提示;切换到其他未保存文件会弹 "取消 / 不保存直接切换 / 保存并切换"三选一确认框;磁盘内容被外部改过时会提示 "文件已被外部修改,再按一次 Cmd+S 强制覆盖"

Git diff 视图

  • 改动一眼看清

任务总览

  • 侧栏「任务面板」进入:按待办 / 执行中 / 遇到阻碍 / 待确认 / 已完成分列的状态看板,支持拖动卡片跨列改状态、新建 (按队列 / 仅一次 / 每小时 / 每天)、运行、手动改状态;单次任务跑完进入「待审查」,重复任务会排到下一次执行
  • 新建弹窗支持 ⌘V 粘贴图片随首包发给 agent(卡片上显示缩略图);主按钮「创建并继续」 保持弹窗批量建任务
  • 顶部「自动认领中 / 暂停」控制后续自动执行(暂停不打断已运行任务);同目录的 auto_run 待办串行领取,不用守着终端

Skill 管理

  • 统一浏览用户级与项目级 Skill,可新建、导入、编辑、改名、删除
  • 托管 Skill 以 .smelt/skills 为唯一真身,自动同步到 Claude / Codex / Copilot / Grok 的本地目录,并可一键填入当前会话调用

历史会话视图

  • 只读浏览 Claude Code 在本地保存的历史会话记录(~/.claude/projects/<项目>/*.jsonl
  • 表格列:标题、时间(含耗时)、消息数、Tokens;除标题外三列都可以点表头排序
  • 点一行会在右侧展示该会话的完整对话内容(含每轮调用了哪些工具);右键会话条目可 「ACP 继续」或「CLI/TUI 继续」,用协议级续接把那次历史会话接着跑下去

用量统计

  • 顶部标题栏有个饼图图标,点开一个独立窗口
  • 按模型 / 工具 / 项目统计 token 消耗量和工具调用次数,附今日走势和近 12 周的 每日 token 活动热力图;只统计数量,不折算价格
  • 数据来自本地解析 Claude Code 写的 transcript(同上面"历史会话"的 jsonl), 不是解析终端实时输出

桌面宠物(可选)

  • 悬浮小窗,可选接一个 OpenAI 兼容协议的 LLM 当"大脑"(默认预填 DeepSeek,可换 接口地址 / API Key / 模型 / 人设)
  • 能感知鼠标位置和当前前台 app,做出对应反应
  • 纯只读感知,不做任何输入模拟或屏幕截图
  • 是否显示、是否播报状态、宠物颜色和大小(小/中/大),都在设置窗口"桌面宠物" 分区里配置

通知

  • Dock 图标角标:数字是"需要你处理 + 等你批准"的会话总数;只是切过去看一眼不会 清除,要等你真正回应了才清
  • macOS 系统通知(Notification Center):只有 smelt 不在前台时才弹,标题固定 smelt、副标题是"会话名 · 任务名";同一条文本 60 秒内去重,不会被 Claude Code 反复上报的 "waiting for input" 轰炸。仅打包成 smelt.app 后才会真投递, cargo run 开发版没有 bundle id,静默不弹
  • app 在前台但你没在看那个标签页:不弹系统通知,改在窗口内弹一条 toast;正在看 的那个标签直接不提示(你自己看得见)
  • 桌面宠物气泡:同一条消息也会说给宠物听(任务完成 / 卡住太久提醒等),跟系统 通知走不同节流,不算重复打扰

远程访问

在 Mac 上打开开关拿到一个配对码,用 Smelt 手机 App 扫一下,就能看到本机正在跑的 agent 会话,还能(可选)发消息、批准权限。为「电脑上挂着活、人得出门」这种场景做的。

只支持手机 App。 早先的浏览器面板、Cloudflare 隧道、自建 WebRTC 信令都已下线, 跨网只剩 iroh P2P 这一条路。App 在仓库的 mobile/ 目录(Flutter),暂未上架,需要 自己构建。

开启

设置(Cmd+,)→「远程」,两个开关,默认全关

开关作用
开启远程启用 iroh。优先打洞直连,打不通自动走用户配置的自建 relay
允许远程写入配对码持有者可以发消息、批准 / 拒绝权限。切换这个开关不会改变配对码,已配对的手机无需重新扫码

同一页还需填写自建 Relay 地址。Relay 开启共享令牌鉴权时,可点击「随机生成」创建令牌, 然后把复制出的同一令牌同步到 Relay 服务端。配对码和二维码就在分享卡片里。

安全:配对码就是权限

分享之前请把这节读完。

  • 鉴权只有一层:配对码里的 token(128 位随机)。没有密码、没有账号体系、token 也不会过期
  • 一个 token 管这台机器上的全部会话,不是只开放你正在看的那一个。
  • 拿到配对码的人立刻就有对应权限,不需要你再确认一次。开着「允许远程写入」把码发出去, 等于把这台机器上的 agent 交出去。
  • 想收回:关掉「开启远程」开关,或在设置页点「刷新配对 Token」——会换新 token,旧配对码 当场作废。
  • 注意 endpoint_id(配对码的地址那一半)由 ~/.smelt/iroh-secret 决定,重启不变; 真正起鉴权作用、也是唯一能作废的,是 token 那一半。

默认是安全的:两个开关出厂全关,网关只监听本机回环地址。

怎么连

打开「开启远程」,分享卡片会给出 smelt+iroh://<endpoint_id>/?token=<token> 形式的配对码和对应二维码。手机 App 里点 「Scan QR Code to Pair」扫一下即可。

配对码扫一次长期有效endpoint_id 由落盘私钥决定,Mac 重启、换网络都不变。只有主动 「刷新配对 Token」才需要重新扫。

开关状态记在 ~/.smelt/collab.json守护进程自己会读它:守护重启(设置页「重启守护 进程」、无缝升级、崩溃后被拉起)之后会按配置自动把网关和隧道拉回来,不需要开着 GUI,也 不用手动「关掉再打开」。GUI 在旁边每 20 秒核对一次,发现掉了会自动重连并刷新分享卡片里 的配对码。

连接由 iroh 负责:同网段设备直接打洞直连,跨网也走打洞,打洞失败自动回退到用户配置的 自建 relay,网络变好还会自己升级回直连。Smelt 不会回退到公共 relay。宿主不在时约 30 秒 超时报错,不会一直转圈。

局域网直连:不支持。 网关只绑回环地址,同一个 Wi-Fi 下的另一台设备也连不上;跨设备 访问只有 iroh 这一条路(它在同网段本来就会直连,不绕公网)。

部署自建 Relay

Relay 需要一台有公网 IP 和域名的 Linux 云主机,并放行 80/TCP443/TCP7842/UDP。先在 Smelt 的「设置 → 远程」中随机生成令牌,然后在本机仓库执行:

./scripts/deploy-iroh-relay.sh \
  --ssh ubuntu@203.0.113.10 \
  --domain relay.example.com \
  --email admin@example.com \
  --prompt-token

脚本会在本机下载并校验 iroh 官方二进制后上传,不要求云主机能够访问 GitHub;随后配置 Let's Encrypt、共享令牌、QUIC 地址发现和 systemd 自启。它不会修改 Nginx、WireGuard、 UFW 或其他服务,发现端口被占用会直接退出。

完整的 DNS/安全组准备、国内网络下载方案、验证、升级和已有 Nginx 场景见 docs/iroh-relay-deployment.md

手机上能做什么

  • 会话列表按 项目 → 会话 分组,跟 Mac 侧栏一致
  • 点进去是 agent 的对话记录(ACP 协议:消息、工具调用、计划、用量),断线自动重连
  • agent 等你时会推通知

开了「允许远程写入」之后还能:

  • 发消息给 agent
  • 批准 / 拒绝权限请求
  • 回答 agent 的追问(选项按钮 / 文本输入都支持)

几条限制说在前面:

  • 手机上看到的是 ACP 结构化对话,不是终端画面。裸终端(vim/htop 那种)在手机上 看不到——那部分随浏览器面板一起下线了。
  • 只有走 ACP 起的 agent 会话会出现在手机上。
  • 无缝升级 smeltd 之后远程会关掉,需要回设置里重新打开。
  • Android 构建路径尚未验证,目前只在 iOS 上跑通。

还没做的

远程目前做到「一个人用手机遥控自己的 Mac」为止。下面这些在路线图和设计稿里, 都还没动工,别照着找:

  • 手机上看终端画面:现在只有 ACP 对话
  • 局域网直连:网关现在只绑回环,同一个 Wi-Fi 下的另一台设备也连不上。设想里是可以绑 局域网地址(或配合 Tailscale)直连的
  • 联机 review:同事在 diff 上划线写评论,打包成 prompt 喂回你的 agent——看代码的人和 开车的人可以不是同一个。有个坑得先解决:agent 正跑着的时候往终端里塞字节,会被它当成 对当前问题的回答,所以评论必须排队等它空下来才能发
  • 任务认领池:不是再做一个 Jira,而是把「等审批的 agent」「待做的任务」「等 review 的 diff」「跑挂了没人管的会话」这些等人处理的条目都收进一个收件箱,谁有空谁点「我来」
  • IM 卡片:agent 一进入等审批就往飞书推一张卡片,直接在 IM 里点允许 / 拒绝
  • 会话移交:把正在跑的活会话交接给别人(oncall 换班那种)
  • App 上架:现在 App 仍需自己构建;自建 iroh Relay 已有部署脚本和运维说明

出处:远程操作 Roadmapcollaboration.md—— 后者标题里就写着「设计讨论,未动工」,里面的观战席 / 求助广播 / 作战地图都还只是设想。

明确不打算做的:在飞书里内嵌完整终端、自建 WebRTC 信令或 WireGuard 中转(跨网只用 iroh,不再维护独立信令/TURN 协议栈)、重新做浏览器面板、把主 GUI 换成 Electron、 做成一个完整的项目管理工具。

设置窗口

Cmd+, 打开一个 640×560 的独立小窗,左侧分区、右侧内容,共 5 个分区:

  • 外观:深色 / 浅色主题、背景色、背景图片(选择 / 清除)、不透明度滑块 (60%–100%,低于 100% 时窗口转透明)、背景模糊(毛玻璃效果,需配合不透明度)。 目前没有终端字体 / 字号 / 配色主题预设可选。
  • 桌面宠物:显示开关、状态播报开关、"宠物大脑(LLM)"开关及接口地址 / API Key / 模型 / 人设四个输入框(默认接 DeepSeek)、宠物颜色、宠物大小 (小/中/大)。
  • 启动:项目行「+」菜单的快捷启动项列表(每项是显示名 + shell 命令,可自由增删改; 需要全权限就把参数写进命令,例如 claude --dangerously-skip-permissions); 以及 Copilot 响铃通知开关——这个开关改的是 ~/.copilot/settings.json,会 影响这台机器上所有场合(不止 smelt 内)用到的 Copilot CLI,不是 smelt 私有配置。
  • 更新:启动时会自动静默检查一次,这里的"检查更新"按钮用于手动触发;状态 文案会显示检查中 / 已是最新 / 下载中 / 新版本已就绪 / 失败,就绪后有"立即重启 更新"按钮(不点也会在下次正常退出后自动生效)。另有 smeltd 守护进程版本 检测和"重启守护进程"按钮——会断开当前所有终端会话(含正在跑的 agent),且 不可恢复,谨慎点击
  • 远程:「开启远程」「允许远程写入」两个开关、Relay 配置,加一张 显示分享链接的卡片。详见上面的远程访问——尤其是「链接就是权限」那节。

大部分设置项没有"重置"入口,目前只有"主题模式"和"背景模糊"支持一键恢复默认, "更新"分区整页不支持重置;也没有导入 / 导出配置的功能。各分区对应的存储文件见 下面「数据与配置」。

快捷键

全局

快捷键作用
Cmd+K命令面板
Cmd+B切换侧栏
Cmd+[ / Cmd+]循环切换当前会话内的 pane(分屏)
Cmd+1 ~ Cmd+9跳到侧栏第 N 个会话
Cmd+D竖切分屏(右侧并排)
Cmd+Shift+D横切分屏(下方堆叠)
Cmd+W关闭当前 pane(会话只剩一个 pane 时关掉整个会话)
Cmd+S保存文件(仅文件树页生效)
Cmd+Shift+F切换调试 HUD(右上角帧率)
Cmd+Q退出
Cmd+,打开设置窗口

命令面板里还有"新建会话""打开项目…""切换到指定已开会话"这几类命令,超过前 9 个的会话没有对应键盘快捷键,只能靠 Cmd+K 搜文字执行。终端 / 任务总览 / 文件树 / Git diff / Skill / 历史会话这几个视图之间切换,目前也只能鼠标点击,没有快捷键。

终端内

快捷键作用
Cmd+C复制选区
Cmd+V粘贴剪贴板
Shift+PageUp / Shift+PageDown翻滚历史缓冲
Cmd+点击打开光标处识别到的链接

数据与配置

smelt 不建数据库,状态都是本地小文件:

文件内容
~/.smelt/workspace.json分屏布局存档(结构 / 嵌套 / 方向),启动时据此重建
~/.smelt/appearance.json终端外观设置(配色、字体等),所有终端共享一份
~/.smelt/pet.json桌面宠物是否显示、播报、颜色、大小等设置
~/.smelt/llm.json桌面宠物"大脑"LLM 配置(接口地址 / API Key / 模型 / 人设)
~/.smelt/launch.json项目「+」菜单的快捷启动项列表(entries: [{label, command}, …]
~/.smelt/collab.json远程访问开关、写入权限、Relay 地址及可选访问令牌。配对链接和网关 token 是运行时状态,不落盘;配置文件按私密权限保存
~/.smelt/smeltd.socksmeltd 的 Unix socket,workspace 靠它跟守护通信

都是本地文件。「历史会话」和「用量统计」两个视图读的是 Claude Code 自己写在 ~/.claude/projects/**/*.jsonl 里的记录,不是 smelt 自建的数据。

数据默认不出本机——唯一的例外是你自己打开远程访问:开了「开启远程」, agent 会话就会发到你配对过的手机上(优先直连,打不通才经 iroh 中继,中继看到的是加密流量)。 不开就没有任何东西离开这台机器。

常见问题

历史会话页能恢复/继续某次历史对话吗? 能。右键历史会话条目,选择「ACP 继续」(接入结构化对话)或「CLI/TUI 继续」(在终端里 接着跑),smelt 会用协议级续接恢复那次对话的上下文。

支持 Linux / Windows 吗? 目前只做 Mac。GPU 渲染依赖 Metal,暂时没有跨平台计划。

在哪反馈问题?GitHub Issues 提,有 Bug 反馈 和功能建议两个模板;应用内设置页「更新」tab 也有「反馈问题」快捷入口。

想从源码构建、了解内部架构、或者参与开发? 这些不算"怎么用",单独整理在开发文档里。