Skip to content

feat: 添加可见终端与受控 PTY 能力 - #142

Open
Nothing1596 wants to merge 8 commits into
Rvosy:devfrom
Nothing1596:feat/terminal-tauri
Open

Nothing1596 wants to merge 8 commits into
Rvosy:devfrom
Nothing1596:feat/terminal-tauri

Conversation

@Nothing1596

Copy link
Copy Markdown
Contributor

背景

这个 PR 为 Sakura 增加一项默认关闭的可见终端能力,让桌宠可以在用户明确授权后执行和继续操作终端进程。

该功能定位为桌宠的可选增强能力,不是独立的 Agent CLI 或终端产品。首版优先保证权限边界、进程生命周期和跨线程稳定性,不提供 OS 级沙箱。

主要改动

权限契约

  • 增加工具组元数据和 ONCE / PROCESS 两种授权范围。
  • 每条新的 terminal_exec 命令都必须确认,即使开启了完整访问权限。
  • 高风险和未知命令不提供进程级授权;进程级授权仅覆盖同一 session_id 的读取、写入和停止。
  • 内置风险分类器识别显式 shell、提权、关机、破坏性文件操作和 Git 写操作。
  • 进程退出、崩溃、功能关闭或 Sakura 退出时立即撤销进程授权。

终端工具与 Python 接线

  • 新增 terminal_execterminal_readterminal_writeterminal_stop 四个模型工具。
  • 命令采用 argv-first,不隐式经过 shell;需要 shell 时必须显式调用 zsh -lcpowershell -Command 等,并按高风险处理。
  • TerminalManager 统一管理设置、会话、输出清洗、长度限制和授权状态。
  • Qt 主线程持有终端宿主 QProcess,worker 通过 queued signal 和请求 ID 通信,避免跨线程操作 Qt process/socket。
  • 终端输出会剥离 ANSI 和危险控制字符、执行敏感信息脱敏,并作为不可信外部内容返回模型;原始输出不进入聊天历史和运行日志。

可见 PTY 宿主

  • 新增轻量 sakura-terminal Tauri 程序,Rust 端使用 portable-pty 0.9.0,前端使用固定版本的 xterm.js 构建产物。
  • Python 与宿主通过带协议版本和随机 nonce 的 JSONL 通信;Webview 不能自行创建进程。
  • 首版限制为一个终端窗口和一个活动进程,Rust 保留 1 MiB 环形缓冲区并持续排空 PTY 输出。
  • 修复父进程退出后的 Tauri 孤儿进程问题,并用可提前唤醒的等待机制避免长超时线程堆积。
  • 终端关闭时回收活动进程;窗口关闭在普通会话中只隐藏,在存在待确认命令时自动取消该命令。

确认体验

  • 终端命令不再占用桌宠输入栏中的通用确认卡,避免内容截断和布局紊乱。
  • 确认界面移动到独立终端窗口,显示完整 argv、工作目录、风险等级和可用授权范围。
  • Sakura 每次启动后只播放一次终端权限语音提示,后续确认保留字幕但不重复播报。
  • Rust 和 Python 都校验当前 approval ID 与允许范围,过期或伪造的确认结果会被忽略。

设置与打包

  • 增加默认关闭的“终端能力”设置和默认工作目录。
  • 禁用功能时若仍有活动进程或待确认命令,会拒绝保存并提示用户先停止或取消。
  • 增加 macOS / Windows 的 Tauri 构建路径和许可证归档,不要求发布环境安装 Node.js。

用户流程

  1. 用户在设置中显式启用终端能力。
  2. 用户要求桌宠执行需要终端的任务。
  3. 主模型调用 terminal_exec,Sakura 打开独立终端确认窗口。
  4. 用户查看完整命令、目录和风险后,选择“仅执行本次”“允许此进程继续交互”或“取消”。
  5. 授权后命令在可见 PTY 中运行;模型可继续读取输出,或在授权范围内与同一进程交互。

安全边界

  • 默认关闭,所有新命令始终需要确认。
  • 命令以当前 Sakura 用户权限执行,本 PR 不提供容器或 OS 沙箱。
  • Webview 只能操作当前会话或提交当前待确认动作,不能自行 spawn。
  • 进程级授权不继承到新命令或新会话。
  • Windows 下暂未使用 Job Object 约束衍生进程,相关进程树回收仍需后续真机强化。

验证

  • Python unit + integration:1283 passed, 1 skipped
  • 定向 Qt UI:7 passed
  • Rust:8 passed
  • macOS arm64 发布构建成功。
  • 使用真实 sakura-terminal 二进制完成协议 v2 初始化、确认显示、确认清除和正常退出 smoke。
  • 已验证终端确认不会固定桌宠输入栏,快速确认会等待 ChatWorker 清理后再执行,普通工具确认面板不受影响。

已知限制与后续

  • 当前仍是非沙箱能力,风险分类器只用于辅助审批,不能替代系统隔离。
  • 需要补 Windows x64 真机 ConPTY、交互式进程和衍生进程回收 smoke。
  • macOS 全量 UI 测试文件仍会在既有窗口置顶测试处触发段错误;本 PR 相关 UI 用例已单独通过。

@Nothing1596
Nothing1596 marked this pull request as ready for review July 14, 2026 05:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant