Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions openspec/changes/add-tui-hyperlinks/manual-test-cases.md
Original file line number Diff line number Diff line change
@@ -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 备注转代码修复
6 changes: 3 additions & 3 deletions openspec/changes/add-tui-hyperlinks/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)。

Expand Down
57 changes: 57 additions & 0 deletions openspec/changes/add-tui-hyperlinks/verification-checklist.md
Original file line number Diff line number Diff line change
@@ -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 备注,转代码修复
2 changes: 1 addition & 1 deletion ports/ftxui/vcpkg.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
Loading