Skip to content

[Grok/dsh 23] 剪贴板、终端诊断与远程终端包装 #155

Description

@Blackman99

Parent

#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

Delivery contract

用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。

Activity

  1. Blackman99 commented on Sep 25, 2026

    @Blackman99
    OwnerAuthor

    已集成到 rewrite/grok-dsh-20260920:c59e676(剪贴板投递、终端诊断、wrap 与终端通知,已 rebase 到 #208 的 7ba4372 之上,两边改动均保留)。

    实现

    • 剪贴板投递(rust/src/clipboard.rs、terminal_env.rs):按平台原生工具(pbcopy / clip.exe / wl-copy / xclip→xsel,3 秒超时)→ tmux load-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.v1 JSON(终端、复用器、远程、tmux 版本与选项、剪贴板计划、发现项、未验证项)。doctor fix [ids] 只改 ~/.tmux.conf:非 TTY 必须 --yes,TTY 需 [y/N] 确认;写前备份 .tmux.conf.codsh-backup-<时间戳>,保留权限与 CRLF,打印撤销命令;拒绝符号链接和冲突配置;不会自动执行 tmux source-file。
    • wrap(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 退出看门狗。
    • 启动器环境白名单补充终端/复用器/SSH/显示相关变量;补全、README、README.zh、CONTEXT 与 changeset 已更新。

    检查(本机 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 test 2580 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_return 0 警告;pnpm run build 与 pnpm run build:rust 成功。

    未验证

    • macOS pbcopy 与 Windows clip.exe 原生通道(仅用 Linux 假工具测试);macOS/Windows 整体未运行。
    • 真实终端(iTerm2、Kitty、Ghostty、WezTerm、Alacritty、Apple Terminal、Windows Terminal、VS Code/Cursor/Zed)对 OSC 52 和通知的实际接受情况。
    • 真实 tmux 的 set-clipboard/allow-passthrough 行为(测试用假 tmux)、真实 SSH 会话下的 wrap ssh ...。
    • 真实 Wayland/X11 显示服务器上的 wl-copy/xclip/xsel。
    • OSC 9/99/777 的桌面通知是否真正弹出(只校验发出的字节)。
    • 已更新但仅限 macOS 的 PTY 测试 rust-nav-pty-test.py、rust-content-pty-test.py、rust-session-data-pty-test.py 本机无法运行,未执行。
    • 测试从未触碰真实用户配置(全部隔离 HOME/GROK_HOME)。

    未改动

    main、npm 发布、默认版本均未改动。

    后续

    #155 已不再阻塞 #201,但 #201 仍被 #199 阻塞;#211 仍被其他票据阻塞。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions