From 854ee6b5bbec61f20a2475805a46a2b837d7a1cc Mon Sep 17 00:00:00 2001 From: slyxyllt Date: Thu, 3 Sep 2026 08:22:39 +0800 Subject: [PATCH 1/2] fix(ftxui): bump port-version 4->5 to match gitlink f98588b4 PR #38 only moved the submodule gitlink to f98588b4 (hover patch head) but left ports/ftxui/vcpkg.json at port-version 4. Per the rule in portfile.cmake, vcpkg computes its ABI hash from vcpkg.json alone and never re-reads the sources under SOURCE_PATH, so any incremental build with an existing vcpkg_installed would silently keep using the old ftxui and fail to compile (EnableMouseHoverMotion not a member of ftxui::App). Bump to 5 so the hash is invalidated and the rebuilt ftxui 7.0.3#5 (with the hover patch) is actually picked up. --- ports/ftxui/vcpkg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/ftxui/vcpkg.json b/ports/ftxui/vcpkg.json index 3d332aa4..347bf6e9 100644 --- a/ports/ftxui/vcpkg.json +++ b/ports/ftxui/vcpkg.json @@ -1,7 +1,7 @@ { "name": "ftxui", "version-semver": "7.0.3", - "port-version": 4, + "port-version": 5, "description": "C++ Functional Terminal User Interface (shaohaozhi286 fork; adds ACECode TUI selection, input trace, Kitty keyboard lifecycle, and synchronized output (DEC mode 2026) patches — see external/ftxui/ACECODE_PATCHES.md)", "homepage": "https://github.com/shaohaozhi286/FTXUI", "license": "MIT", From 77f682114726cf744521255325cd25ae77c7b50b Mon Sep 17 00:00:00 2001 From: slyxyllt Date: Thu, 3 Sep 2026 08:22:44 +0800 Subject: [PATCH 2/2] docs(openspec): mark add-tui-hyperlinks 6.1-6.3 done, add acceptance docs tasks.md: tick 6.1-6.3 with verification notes (gitlink landed via PR #38, local rebuild ftxui 7.0.3#5 + full unit run 3766 pass / 9 known baseline failures -> zero regression, openspec validate --strict passed). New verification-checklist.md (iTerm2 x15 / Terminal.app x4 / Windows Terminal x4 matrix mapped from spec scenarios) and manual-test-cases.md (B1-B6 prompt + expected-render + action pairs for real-terminal checks). Note: openspec/ is gitignored at repo root; these files are force-added, consistent with existing tracked openspec changes (dbcdf45d). --- .../add-tui-hyperlinks/manual-test-cases.md | 155 ++++++++++++++++++ openspec/changes/add-tui-hyperlinks/tasks.md | 6 +- .../verification-checklist.md | 57 +++++++ 3 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 openspec/changes/add-tui-hyperlinks/manual-test-cases.md create mode 100644 openspec/changes/add-tui-hyperlinks/verification-checklist.md diff --git a/openspec/changes/add-tui-hyperlinks/manual-test-cases.md b/openspec/changes/add-tui-hyperlinks/manual-test-cases.md new file mode 100644 index 00000000..8aea124b --- /dev/null +++ b/openspec/changes/add-tui-hyperlinks/manual-test-cases.md @@ -0,0 +1,155 @@ +# add-tui-hyperlinks 真机验收:提示词 + 用例手册 + +配套 `verification-checklist.md`(勾选表)使用。本文件是操作手册:**每批先复制提示词发给 ACECode,等它回复渲染,再做对应验证动作**。 + +## 前置(每条用例通用) + +- 跑新构建:`./build/macos-x64-release/acecode`(gitlink `f98588b4`,含 hover 补丁 + OSC 8) +- 每批开始前 `/new` 开干净会话,避免旧链接干扰 link-region 命中 +- 素材靠"让模型逐字复述"生成。**若回复里出现代码块包裹或文字被改写**(渲染形态不对),补一句"不要用代码块包裹,逐字复制"重试 +- 链接渲染形态:可点击链接 = 链接色 + 下划线;纯文本 = 普通颜色 + +> ⚠️ 原理备忘:TUI 里**用户消息按纯文本渲染**(不解析 markdown),只有 **assistant 回复**走 markdown 渲染、才产生可点击链接。因此下面每一条"提示词"都是**发给 ACECode 的对话消息**,让它回复出目标 markdown 文本;ACECode 的回复内容即被测对象。请在**真实终端窗口**(iTerm2 / Terminal.app / Windows Terminal)里直接运行 `acecode` 二进制,不要在嵌套终端/重定向环境里跑(会干扰鼠标事件与 OSC 8 探测)。 + +--- + +## B1 标准链接素材(iTerm2 等全部终端的基础批) + +**提示词(复制整段发给 ACECode):** + +``` +逐字输出下面这些 markdown 行作为你的回复正文。不要用代码块包裹,不要增删改任何字符,不要加解释: +--- +- 打开官网:[ACECode 官网](https://example.com) +- 直接点这里:[GitHub](https://github.com) +- 本地文档:[项目说明](/Users/liuxin557/DEV/acecode/README.md) +- 伪装链接测试:[github.com/ACECode](https://evil.example.com) +- 同 host 短写:[github.com/ACECode/issues](https://github.com/ACECode/issues/1) +- 普通文字标签:[安装指南](https://example.com/guide) +裸网址 https://github.com 这一行没有方括号语法,应显示为普通文本 +--- +``` + +**预期渲染**:第 1/2/3/5/6 行(官网/GitHub/本地文档/同 host 短写/安装指南)= 链接色+下划线;**第 4 行(伪装链接)** = 普通文本色、无下划线(label host `github.com` ≠ href host `evil.example.com`,被降级);最后一行裸网址 = 普通文本。 + +**验证动作(对应 checklist 1.1–1.7):** + +| # | 动作 | 预期 | +|---|---|---| +| 1.1 | 左键点击"ACECode 官网" | 默认浏览器打开 example.com | +| 1.2 | 左键点击"GitHub" | 浏览器打开 github.com | +| 1.3 | 左键点击"项目说明" | Finder/文件管理器定位到仓库根 README.md(本地路径,应用内打开) | +| 1.4 | 观察 + 点击"伪装链接测试"行 | 纯文本样式;点击无任何反应(不进可点击区) | +| 1.5 | 点击"同 host 短写"行 | 浏览器打开 github.com/ACECode/issues/1(label host == href host,放行) | +| 1.6 | 点击"安装指南"行 | 浏览器打开 example.com/guide(label 无点号非 URL 形状,放行) | +| 1.7 | 点击"裸网址"行 | 无反应(非链接) | + +--- + +## B2 OSC 8 原生链接(仅白名单终端:iTerm2 / kitty / WezTerm / Windows Terminal) + +**提示词 A(基础,验证 Cmd/Ctrl+点击与悬停):** 先完成 B1,复用 B1 渲染出的链接。 + +**验证动作(对应 checklist 1.9–1.11、3.1):** + +| # | 动作 | 预期 | +|---|---|---| +| 1.9 | Cmd(WinTerm 用 Ctrl)悬停链接 | 终端显示原生超链接样式(手型/下划线增强/URL 提示) | +| 1.10 | Cmd+点击"GitHub"链接 | iTerm2 原生打开浏览器(不经应用内逻辑,URL 是真实 https://github.com) | +| 1.11 | 右键链接 | 原生菜单出现"打开链接 / 拷贝链接" | + +**提示词 B(跨行链接,验证行边界关闭与无多余发射):** + +``` +逐字输出下面内容作为回复正文。不要用代码块包裹,不要改写: +--- +跨行超长链接测试,请点击这一长串:[https://example.com/very/long/path/abcdefghijklmnopqrstuvwxyz/0123456789/abcdefghijklmnopqrstuvwxyz/0123456789/abcdefghijklmnopqrstuvwxyz/0123456789/end](https://example.com/very/long/path/abcdefghijklmnopqrstuvwxyz/0123456789/abcdefghijklmnopqrstuvwxyz/0123456789/abcdefghijklmnopqrstuvwxyz/0123456789/end) +--- +``` + +窗口调窄使该行换行。**验证(1.14–1.15):** 跨行后整串仍是一个链接(悬停/点击/右键均正确,不串到相邻行);若无法肉眼判断,见下方字节级法。 + +**字节级验证(可选,Linux/macOS):** 在 `script -q /tmp/tty.log ./build/macos-x64-release/acecode` 中跑完 B2-B 后退出,检查: + +```bash +# OSC 8 开序列 \x1b]8;;URL\x1b\ 与关序列 \x1b]8;;\x1b\ +python3 - <<'PY' +import re +d = open('/tmp/tty.log','rb').read().decode('utf-8','ignore') +pairs = re.findall(r'\x1b]8;;(.*?)\x1b\\', d) +print('osc8 sequences:', len(pairs)) +PY +``` + +--- + +## B3 悬停气泡(hover motion 终端:iTerm2 / kitty / WezTerm) + +**前提**:B1 素材已渲染。**鼠标不按键**操作。 + +**验证动作(对应 checklist 1.12–1.13、3.4):** + +| # | 动作 | 预期 | +|---|---|---| +| 1.12 | 指针悬停在"GitHub"链接上不动约 300ms | 指针附近浮出气泡,显示真实 URL `https://github.com` | +| 1.12b | 悬停"伪装链接测试"行(纯文本) | 无气泡 | +| 1.13a | 气泡可见时把指针移出链接区域 | 气泡消失 | +| 1.13b | 再悬停出气泡,按 Esc | 气泡消失 | +| 1.13c | 气泡出现后按任意其他键 / 拖动鼠标 | 气泡消失,无布局跳动(dbox 叠加不参与布局) | + +**提示词(可选,若需要无歧义素材:悬停长 URL 看气泡完整值):** + +``` +逐字输出下面内容作为回复正文,不要用代码块包裹: +--- +悬停气泡长 URL 素材:[点我看完整地址](https://example.com/a/very/long/path?query=1&lang=zh#section) +--- +``` + +气泡应显示完整 URL(含 query 与 fragment),而非显示文字。 + +--- + +## B4 Apple Terminal.app 字节级回退(macOS 自带终端) + +**前提**:Terminal.app 不在 OSC 8 / hover 白名单 → 应完全回退。跑同一批 B1 素材。 + +**验证动作(对应 checklist 2.1–2.4):** + +| # | 动作 | 预期 | +|---|---|---| +| 2.1 | 观察链接 | 仍是 TUI 自己的链接色+下划线(应用层样式),无终端原生超链接效果 | +| 2.2 | 左键点击"GitHub" | 浏览器照常打开(应用内 link-region 兜底,不受无 OSC 8 影响) | +| 2.3 | 悬停链接 300ms | **无气泡**、屏幕无抖动/无异常重绘(hover 探测关闭,未发 `?1003`) | +| 2.4 | 点击"项目说明"本地链接 | Finder 打开(与旧版一致) | +| 2.5 | 观察滚动/拖选文本 | 无鼠标事件异常(?1003 未启用,拖选行为与旧版相同) | + +--- + +## B5 Windows Terminal(需要 Windows 构建,另机或 CI 产物) + +用与 B1 相同的素材(OSC 8 在 WinTerm 白名单内)。**对应 checklist 3.1–3.4:** + +| # | 动作 | 预期 | +|---|---|---| +| 3.1 | Ctrl+点击链接 | 系统浏览器打开(OSC 8 原生) | +| 3.2 | 快速移动鼠标划过链接/文本 | 无闪屏、无整屏重绘抖动(hover motion 未开启或安全) | +| 3.3 | 观察"伪装链接测试"行 | 纯文本(降级逻辑与平台无关) | +| 3.4 | 悬停链接约 300ms | 无气泡或按平台行为显示(记录实际) | + +--- + +## B6 6.5 附注核实终端(顺带记录,没有可跳过) + +| 终端 | 做法 | 记录点 | +|---|---|---| +| kitty | 跑 B1+B2+B3 | OSC 8 原生、Cmd+点击、悬停气泡、跨行 | +| WezTerm | 跑 B1+B2 | OSC 8 原生、Ctrl+点击 | +| 老式/经典 conhost | Windows 老控制台跑 B1 | 无 OSC 8、无气泡、无闪屏回归 | + +--- + +## 收尾 + +- 全部符合预期 → `verification-checklist.md` 对应项打勾,勾选 tasks.md 6.4/6.5 → `openspec archive add-tui-hyperlinks` +- 任何 FAIL → 记录终端 + 现象 + 复现素材,回填 tasks.md 备注转代码修复 diff --git a/openspec/changes/add-tui-hyperlinks/tasks.md b/openspec/changes/add-tui-hyperlinks/tasks.md index a6bdcf24..e6105582 100644 --- a/openspec/changes/add-tui-hyperlinks/tasks.md +++ b/openspec/changes/add-tui-hyperlinks/tasks.md @@ -36,9 +36,9 @@ ## 6. 集成与验收 -- [ ] 6.1 更新父仓库 gitlink 指向已 push 的 `feat/osc8-hyperlink` 头;提升 `ports/ftxui/vcpkg.json` 的 port-version。 -- [ ] 6.2 重编 ftxui + `acecode` + `acecode_unit_tests`;跑全量单测 + 新增聚焦测试。 -- [ ] 6.3 `openspec validate add-tui-hyperlinks --strict`。 +- [x] 6.1 更新父仓库 gitlink 指向已 push 的 `feat/osc8-hyperlink` 头;提升 `ports/ftxui/vcpkg.json` 的 port-version。**2026-09-02 完成(gitlink 随 PR #38 落地 master)**:`bbe73202` 将 gitlink 同步至 `f98588b4`(hover 补丁头,master 构建恢复);`ports/ftxui/vcpkg.json` port-version 4→5 补 PR #38 遗漏(portfile.cmake 规则:gitlink 变更必须同步 bump,否则 vcpkg 增量构建静默用旧 ftxui),本地已按 `7.0.3#5` 重建验证,随本分支提交。 +- [x] 6.2 重编 ftxui + `acecode` + `acecode_unit_tests`;跑全量单测 + 新增聚焦测试。**2026-09-02 晚完成**:vcpkg 重建 ftxui `7.0.3#5` 后全量 390 编译单元链接通过;全量单测 3782 跑 3766 过 / 9 失败 == 基线 9 项(BuiltinToolRegistry×2、SettingsCenterRender×1、StateFileTest×1、PtyBackendSpawnTest×1、ManagedRemoteWebProxy×2、WebServerHttp×2)→ 零回归。 +- [x] 6.3 `openspec validate add-tui-hyperlinks --strict`。**2026-09-02 完成**:`Change 'add-tui-hyperlinks' is valid`(strict 模式通过)。 - [ ] 6.4 人工矩阵(用户验证):iTerm2(Cmd+点击可开、原生悬停、右键打开/复制)、Apple Terminal.app(字节级回退:无 OSC 8、应用内点击照常、无悬停回归)、Windows Terminal(Ctrl+点击可开、悬停无闪屏)。 - [ ] 6.5 在验证备注中记录顺带核实的终端(kitty、WezTerm、老式 conhost)。 diff --git a/openspec/changes/add-tui-hyperlinks/verification-checklist.md b/openspec/changes/add-tui-hyperlinks/verification-checklist.md new file mode 100644 index 00000000..17e5a9a6 --- /dev/null +++ b/openspec/changes/add-tui-hyperlinks/verification-checklist.md @@ -0,0 +1,57 @@ +# add-tui-hyperlinks 人工验收矩阵(6.4 / 6.5) + +构建:本地 `build/macos-x64-release/acecode`(gitlink `f98588b4`,master `4708a8e2`) +日期:__________ 验收人:__________ + +> 每条记录终端名 + 结果(PASS / FAIL / N/A + 备注)。FAIL 需附截图或字节流证据。 + +## 终端 1:iTerm2(期望全功能) + +| # | 场景(对应 spec) | 操作 | 期望 | 结果 | +|---|---|---|---|---| +| 1.1 | 点击打开浏览器 | 左键点击聊天区 `https://…` 链接 | 系统默认浏览器打开 URL | ☐ | +| 1.2 | 本地文件不受影响 | 点击 `docs/foo.md` 本地路径链接 | 文件管理器打开,行为与旧版一致 | ☐ | +| 1.3 | 打开失败有提示 | 注入无效 URL / launcher 失败 | 状态栏提示,TUI 不崩 | ☐ | +| 1.4 | 非链接文本 | 点击普通文本 | 走原有选中/兜底,不打开浏览器 | ☐ | +| 1.5 | 伪装 host 降级 | 渲染 `[github.com/foo](https://phish.example.com)` | 纯文本:无链接色/下划线/点击 | ☐ | +| 1.6 | 命名链接可点 | 渲染 `[安装指南](https://…)` | 可点击、保留样式 | ☐ | +| 1.7 | 省略 scheme 保持可点 | 渲染 `[github.com/foo](https://github.com/foo/…)` | 可点击(host 一致) | ☐ | +| 1.8 | 畸形文字降级 | 渲染 URL 形文字无法解析 host | 纯文本 | ☐ | +| 1.9 | OSC 8 原生悬停 | Cmd 悬停链接 | 终端原生下划线/悬停提示出现 | ☐ | +| 1.10 | Cmd+点击 | Cmd+点击链接 | 系统浏览器打开(终端原生) | ☐ | +| 1.11 | 右键菜单 | 右键链接 | 打开/复制等原生菜单可用 | ☐ | +| 1.12 | 悬停气泡 300ms | 无按键悬停链接约 300ms | 指针附近浮层显示真实 URL | ☐ | +| 1.13 | 移开/Esc 隐藏 | 移开指针 或 按 Esc | 气泡消失 | ☐ | +| 1.14 | 行边界关闭 | 链接跨行换行 | 每行行尾关闭,无串链接 | ☐(可选字节级) | +| 1.15 | 无多余发射 | 长链接连续格子 | 无多余 OSC 8 开关 | ☐(可选字节级) | + +## 终端 2:Apple Terminal.app(期望字节级回退) + +| # | 场景 | 操作 | 期望 | 结果 | +|---|---|---|---|---| +| 2.1 | 无 OSC 8 | 悬停/点击渲染链接 | 字节流无 OSC 8 序列(不支持白名单外) | ☐ | +| 2.2 | 应用内点击照常 | 左键点击链接 | 仍走应用内打开(浏览器打开 URL) | ☐ | +| 2.3 | 无悬停回归 | 悬停链接 300ms | 无气泡、无抖动/无异常重绘(hover 探测关) | ☐ | +| 2.4 | 本地文件链接 | 点击文件路径 | 文件管理器打开(与旧版一致) | ☐ | + +## 终端 3:Windows Terminal(期望 Ctrl+点击 + 无闪屏) + +| # | 场景 | 操作 | 期望 | 结果 | +|---|---|---|---|---| +| 3.1 | Ctrl+点击可开 | Ctrl+点击链接 | 系统浏览器打开 | ☐ | +| 3.2 | 悬停无闪屏 | 悬停链接/拖动文本 | 无 ?1003 重绘抖动、无闪屏 | ☐ | +| 3.3 | 伪装 host 降级 | 同 1.5 渲染 | 纯文本 | ☐ | +| 3.4 | 悬停气泡 | 无按键悬停 300ms | 气泡显示真实 URL(WinTerm 支持 hover motion 时) | ☐ | + +## 6.5 附注核实终端(顺带记录,无则 N/A) + +| 终端 | 核实项 | 结果 | +|---|---|---| +| kitty | OSC 8 + hover motion(xterm-kitty 白名单) | ☐ | +| WezTerm | OSC 8 表现 | ☐ | +| 老式/经典 conhost | 无 OSC 8、无 hover、无闪屏回归 | ☐ | + +## 收尾 + +- [ ] 全部 PASS → 在 tasks.md 勾选 6.4/6.5,归档 change(openspec archive) +- [ ] 存在 FAIL → 附证据回填 tasks.md 备注,转代码修复