<!-- codsh-publication:grok-cli-dsh-rewrite:ticket-23 --> ## Parent https://github.com/Blackman99/codsh/issues/132 **Ticket:** 23 **Status:** ready-for-agent **User Stories:** 15, 18, 70(见父规格) ## What to build 用户复制回答/代码,诊断终端问题,并在 SSH、tmux 或包装连接中得到真实可用的复制、通知和恢复行为。 ## Acceptance criteria - [ ] 原文/代码复制使用对应平台、tmux、OSC 52 或明确的文件后备,不能未送达仍宣称复制成功。 - [ ] Doctor 以可读/机器可读结果报告检测事实;需要修改外部配置的修复须明确确认并可恢复。 - [ ] wrap、掉线、通知焦点和终端复原使用真实子进程/终端验证,不仅检查 ANSI 字符串。 - [ ] 未验证的终端/平台如实列出,后续平台票复验;实现不修改用户真实终端配置作为测试手段。 ## Blocked by - #145 — Ticket 13: 命令行与纯文本自动化兼容 - #152 — Ticket 20: 鼠标、搜索与阅读位置 - #153 — Ticket 21: 完整内容、工具卡与差异阅读 ## Delivery contract 用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。
Activity
feat(rust): clipboard delivery, terminal doctor, wrap, and notificati…
Blackman99 commentedon Sep 25, 2026
已集成到
rewrite/grok-dsh-20260920:c59e676(剪贴板投递、终端诊断、wrap与终端通知,已 rebase 到 #208 的 7ba4372 之上,两边改动均保留)。实现
rust/src/clipboard.rs、terminal_env.rs):按平台原生工具(pbcopy / clip.exe / wl-copy / xclip→xsel,3 秒超时)→ tmuxload-buffer→ OSC 52(tmux 内同时发普通与 passthrough 形式)→ 文件兜底($GROK_HOME/last-copy.txt或GROK_COPY_FILE,0600)。结果分为 Confirmed / TmuxBuffer / Unverified / Unreachable,只有原生工具成功才显示 “Copied!”;OSC 52 明确标注 “unconfirmed”,全都失败时显示 “Clipboard unreachable … saved to …”,从不假报成功。SSH/容器无显示时不信任原生工具。所有复制入口(复制块、原文、交互、记忆、会话导出)统一走此路径;新增/copy [N] [path]。rust/src/doctor.rs):codsh --rust doctor [--json]与/doctor(别名 terminal-setup/check/info)输出人读文本和codsh.doctor.v1JSON(终端、复用器、远程、tmux 版本与选项、剪贴板计划、发现项、未验证项)。doctor fix [ids]只改~/.tmux.conf:非 TTY 必须--yes,TTY 需[y/N]确认;写前备份.tmux.conf.codsh-backup-<时间戳>,保留权限与 CRLF,打印撤销命令;拒绝符号链接和冲突配置;不会自动执行tmux source-file。rust/src/wrap.rs):codsh --rust wrap <命令>在 PTY 中运行远程会话,转发输入、窗口大小、信号,拦截 OSC 52 并经上面的投递链写入本地剪贴板(去重、拒绝剪贴板读取请求),退出/断线后恢复终端状态(鼠标、焦点、粘贴括号、键盘协议、备用屏幕等)并报告恢复了什么;退出码为子进程码或 128+信号。rust/src/notifications.rs):[ui.notifications]支持 method(auto/osc9/osc99/osc777/bel/off)、condition、idle_threshold_secs、events 与 hooks;聚焦时静默,失焦超过阈值才发,重新聚焦取消待发。未实现的键会给出配置警告。另有 SSH 一次性提示与GROK_EXIT_TIMEOUT_SECS退出看门狗。检查(本机 Linux,mock 模型,隔离临时 HOME)
python3 scripts/rust-terminal-pty-test.py(新增,真实 PTY/子进程):26/26 通过。覆盖 wrap 的环境与尺寸、键盘输入、SIGWINCH 转发、SIGKILL 断线退出码 137、拆分及 tmux 包装的 OSC 52 仅转发一次、断线后终端恢复与 termios 还原、127/2 拒绝;doctor 的 JSON/文本、无--yes拒绝、TTY 提示拒绝、--yes带备份应用(权限 0640 保留、未执行 source-file)、冲突拒绝;TUI 中的焦点上报开关、聚焦静默、失焦通知并运行 hook、重新聚焦取消、/copy与/copy 2 <path>、/doctor、无路由时如实报告 “Clipboard unreachable”、SSH 提示只出现一次。rust-plain-json-test.py、rust-usage-pty-test.py通过。pnpm run typecheck通过;pnpm test2580 passed / 15 skipped(rebase 后)。rebase 前有一次rust-monitor.spec.mjs计时抖动失败,单独重跑 28/28 两次通过。cargo test --locked -p codsh-rust:696 passed,4 个既有失败(2 个 filesystem_sandbox、privacy、voice,与本票无关,基线即如此);cargo test --locked --workspace --exclude codsh-rust:1043 passed;cargo fmt --check干净;cargo clippy --locked -p codsh-rust --all-targets -- -A dead_code -A clippy::needless_return0 警告;pnpm run build与pnpm run build:rust成功。未验证
wrap ssh ...。rust-nav-pty-test.py、rust-content-pty-test.py、rust-session-data-pty-test.py本机无法运行,未执行。未改动
main、npm 发布、默认版本均未改动。
后续
#155 已不再阻塞 #201,但 #201 仍被 #199 阻塞;#211 仍被其他票据阻塞。