software-design-test 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/LICENSE +21 -0
  3. package/README.md +275 -0
  4. package/cordis.patch.yml +23 -0
  5. package/docs/FRAMEWORK.zh-en.md +149 -0
  6. package/docs/INSTALL.zh-en.md +226 -0
  7. package/docs/USAGE.zh-en.md +295 -0
  8. package/icon.svg +21 -0
  9. package/lib/index.js +197 -0
  10. package/lib/self-check.js +313 -0
  11. package/locale/en.json +6 -0
  12. package/locale/zh.json +6 -0
  13. package/package.json +80 -0
  14. package/scripts/capture.mjs +318 -0
  15. package/scripts/guard.mjs +311 -0
  16. package/scripts/report.mjs +484 -0
  17. package/scripts/session.mjs +709 -0
  18. package/scripts/verify.mjs +205 -0
  19. package/skills/observed-test-plan/MATRIX.md +99 -0
  20. package/skills/observed-test-plan/PERMISSIONS.md +109 -0
  21. package/skills/observed-test-plan/PLAN-TEMPLATE.md +93 -0
  22. package/skills/observed-test-plan/SKILL.md +135 -0
  23. package/skills/observed-ui-test/BANNED-INPUTS.md +161 -0
  24. package/skills/observed-ui-test/EVIDENCE.md +113 -0
  25. package/skills/observed-ui-test/FRAMEWORK.md +181 -0
  26. package/skills/observed-ui-test/LEVELS.md +137 -0
  27. package/skills/observed-ui-test/REPORT-TEMPLATE.md +111 -0
  28. package/skills/observed-ui-test/SKILL.md +210 -0
  29. package/skills/software-design-test/DEFECTS.md +205 -0
  30. package/skills/software-design-test/HEURISTICS.md +236 -0
  31. package/skills/software-design-test/PERSONAS-SCENARIOS.md +159 -0
  32. package/skills/software-design-test/SKILL.md +211 -0
  33. package/skills/software-design-test/SOURCES.md +118 -0
  34. package/skills/software-design-test/TEST-CONTENT.md +257 -0
  35. package/skills/software-design-test/WORKFLOW.md +293 -0
@@ -0,0 +1,226 @@
1
+ # 安装说明 / Installation
2
+
3
+ > 中英对照:每段中文后跟 `> EN:` 英文。 / Bilingual: each Chinese block is followed by `> EN:`.
4
+ >
5
+ > 插件名 `software-design-test` · 类型:DSH bundle 插件 · 零依赖、零构建、零网络依赖。
6
+ > Package `software-design-test` · a DSH bundle plugin · zero dependencies, no build step.
7
+
8
+ ---
9
+
10
+ ## 0. 前置条件 / Prerequisites
11
+
12
+ 需要装好 DeepSeek Harness(`dsh` 命令可用),并且知道要装进哪个 profile:桌面版一般是 `desktop`。
13
+ 运行插件自带的脚本需要 Node.js ≥ 20.11(Harness 自带运行时即可)。
14
+
15
+ You need a working DeepSeek Harness (`dsh` on PATH) and the profile name — the desktop app uses
16
+ `desktop`. The bundled scripts need Node.js ≥ 20.11, which the Harness runtime already provides.
17
+
18
+ ```bash
19
+ node -v # 需要 >= 20.11 / requires >= 20.11
20
+ dsh --help # 确认 dsh 可用 / confirm dsh works
21
+ ```
22
+
23
+ ---
24
+
25
+ ## 1. 从本地目录安装(推荐)/ Install from a local checkout (recommended)
26
+
27
+ 插件就在本机的工作区里,用 `link:` 直接挂载,改动即时生效、不需要发布:
28
+
29
+ The plugin sits in this machine's workspace; `link:` mounts it directly, so edits take effect without
30
+ publishing:
31
+
32
+ ```bash
33
+ dsh plugin --profile desktop add link:/Users/inception/Documents/deepseek-harness/default-workspace/software-design-test
34
+ ```
35
+
36
+ > `link:` 后面必须是**绝对路径**。 / The path after `link:` must be absolute.
37
+
38
+ > **本机实测的坑 / a trap found on this machine**:PATH 上的 `dsh` 由 `/usr/bin/env node` 启动,
39
+ > 若系统 Node 是 v23(`import.meta.main` 在 Node 24 才存在),CLI 会**静默空转**:
40
+ > 退出码 0、无任何输出、profile 文件也不变。这种情况改用 Harness 应用自带的运行时 CLI:
41
+ > `dsh` on PATH runs under `env node`; with system Node v23 the CLI **silently does nothing**
42
+ > (exit 0, no output, no profile change) because `import.meta.main` only exists from Node 24.
43
+ > Use the runtime CLI the app itself ships:
44
+
45
+ ```bash
46
+ "/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh" plugin --profile desktop \
47
+ add link:/Users/inception/Documents/deepseek-harness/default-workspace/software-design-test
48
+ ```
49
+
50
+ > 或者把系统 Node 升到 ≥ 24 再直接用 `dsh`。 / Or upgrade system Node to ≥ 24 and use `dsh` directly.
51
+
52
+ 装完后重启 Harness(或重启 Web 应用),然后验证:
53
+
54
+ Restart Harness afterwards, then verify:
55
+
56
+ ```bash
57
+ grep -n "software-design-test" ~/.dsh/profiles/desktop/package.json
58
+ ```
59
+
60
+ 期望看到两处 / expect two lines:
61
+
62
+ ```json
63
+ "software-design-test": "link:/Users/inception/Documents/deepseek-harness/default-workspace/software-design-test",
64
+ ```
65
+
66
+ 以及 `dsh.profile.bundles` 数组里的 `"software-design-test"`。
67
+ The dependency spec and the bundle entry in `dsh.profile.bundles`.
68
+
69
+ 最可靠的确认是在对话里用 `/` 菜单或 `skill` 工具,能看到 `observed-ui-test` 与
70
+ `observed-test-plan` 两个技能。
71
+
72
+ The most reliable confirmation: the `/` menu or the `skill` tool lists `observed-ui-test` and
73
+ `observed-test-plan`.
74
+
75
+ > 某些构建下 `dsh --profile desktop --dump-config` 不向标准输出打印内容(本机实测无输出),
76
+ > 所以以 profile 的 `package.json` 与技能列表为准。
77
+ > On some builds `--dump-config` prints nothing to stdout (verified on this machine), so trust the
78
+ > profile `package.json` and the skill list instead.
79
+
80
+ ---
81
+
82
+ ## 2. 从 GitHub 安装 / Install from GitHub
83
+
84
+ ```bash
85
+ dsh plugin --profile desktop add github:Inceptzws/software-design-test
86
+ ```
87
+
88
+ > 需要先把仓库推到 GitHub。包内没有依赖、没有 `prepare`/构建脚本,
89
+ > 所以 pnpm 不会要求 `allowBuilds` 批准。
90
+ > Push the repository first. There are no dependencies and no `prepare`/build script, so pnpm never
91
+ > asks for an `allowBuilds` approval.
92
+
93
+ ---
94
+
95
+ ## 3. 从 npm 安装 / Install from npm
96
+
97
+ ```bash
98
+ dsh plugin add software-design-test
99
+ # 或指定 profile / or with an explicit profile
100
+ dsh plugin --profile desktop add software-design-test
101
+ ```
102
+
103
+ ---
104
+
105
+ ## 4. 在 Harness 界面里安装 / Install from the Harness UI
106
+
107
+ Web / 桌面端侧边栏 → **Plugins** 页面 → **Install bundle** → target 填包名
108
+ `software-design-test`,或填本目录的绝对路径。也可以让 Agent 调用 `plugin_manager` 的
109
+ `install_bundle`(需要 danger-full-access 或逐次批准)。
110
+
111
+ Sidebar → **Plugins** → **Install bundle**, with the package name or the absolute path of this
112
+ directory. The agent can also call `plugin_manager`'s `install_bundle` (needs danger-full-access or a
113
+ per-approval).
114
+
115
+ ---
116
+
117
+ ## 5. 手动挂载(不用 pnpm 时)/ Manual mount without pnpm
118
+
119
+ 把 `cordis.patch.yml` 的内容加进 profile 的配置树,或用启动器的 `--patch` 覆盖文件:
120
+
121
+ Add the contents of `cordis.patch.yml` to the profile's config tree, or use the launcher's `--patch`
122
+ overlay:
123
+
124
+ ```yaml
125
+ - insert:
126
+ - id: observed-ui-test
127
+ name: software-design-test
128
+ ```
129
+
130
+ ```bash
131
+ dsh --profile desktop --patch /absolute/path/to/cordis.patch.yml
132
+ ```
133
+
134
+ > 这种方式要求 `dsh` 能解析到包名 `software-design-test`;如果没装进 profile 的
135
+ > `node_modules`,请优先用第 1 种 `link:` 方式。
136
+ > This still requires the package to be resolvable; prefer the `link:` route above.
137
+
138
+ ---
139
+
140
+ ## 6. 安装后确认 / Post-install checks
141
+
142
+ ```bash
143
+ # 1) profile 依赖与 bundle 列表里有没有这一行 / is it in the profile deps and bundles
144
+ grep -n "software-design-test" ~/.dsh/profiles/desktop/package.json
145
+
146
+ # 2) 技能自检(离线、只读)/ offline self-check
147
+ cd /Users/inception/Documents/deepseek-harness/default-workspace/software-design-test
148
+ node scripts/verify.mjs # 期望 8/8 checks passed
149
+ node --test test/*.test.mjs # 期望 25/25 pass
150
+ ```
151
+
152
+ 在对话里用 `/` 菜单或 `skill` 工具应能看到两个技能:
153
+
154
+ Two skills should be visible from the `/` menu or the `skill` tool:
155
+
156
+ | 技能 Skill | 何时用 When |
157
+ | --- | --- |
158
+ | **`software-design-test`**(重心) | **模拟真实用户测软件**:人物 → 场景 → 任务卡 → 旅程 → 启发式/巡游 → 判定 |
159
+ | `observed-test-plan` | 测试前:权限问卷、范围、元素清单、用例矩阵 |
160
+ | `observed-ui-test` | 执行规则:L1 → L2 → L3、取证协议、报告模板 |
161
+
162
+ ---
163
+
164
+ ## 7. 权限要求 / Permissions
165
+
166
+ - 插件本身**只需要读屏权限**(截屏/录屏),**不需要**辅助功能、输入监控、自动化等控制权限。
167
+ - 系统权限的授予路径见插件内 `skills/observed-test-plan/PERMISSIONS.md`。
168
+ - 测试开始前,Agent 必须先用权限问卷问过用户;没答复就不开始。
169
+
170
+ The plugin needs **screen-capture permission only** — never accessibility, input monitoring or
171
+ automation. Grant paths live in `skills/observed-test-plan/PERMISSIONS.md`. The agent must run the
172
+ permission questionnaire before any test action, and must not start without answers.
173
+
174
+ ---
175
+
176
+ ## 8. 卸载 / Uninstall
177
+
178
+ ```bash
179
+ dsh plugin --profile desktop remove software-design-test
180
+ ```
181
+
182
+ 用 `link:` 安装时,卸载只会断开链接,不会删除本目录。
183
+ With a `link:` install, removing only detaches the link; this directory is left alone.
184
+
185
+ ---
186
+
187
+ ## 9. 故障排查 / Troubleshooting
188
+
189
+ | 现象 Symptom | 原因 Cause | 处理 Fix |
190
+ | --- | --- | --- |
191
+ | `dsh plugin ...` 无输出、退出码 0、profile 完全没变 | 系统 Node 是 v23,`import.meta.main` 不存在,CLI 静默空转 | 用应用自带 CLI:`"/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh" plugin …`,或升级 Node ≥ 24 |
192
+ | profile 的 `package.json` 里没有 `software-design-test` | `add` 没执行成功(路径不是绝对路径 / pnpm 报错) | 重跑 `add`,用**绝对路径**,看 pnpm 的报错 |
193
+ | 依赖有了但技能列表里没有 | 没加进 `dsh.profile.bundles`,或挂载失败 | 检查 `bundles` 数组;看 Harness 启动日志里 `software-design-test:` 开头的报错 |
194
+ | 写入 `~/.dsh/...` 报 `EPERM` | 会话的文件沙箱是 workspace-write,profile 在工作区之外 | 对安装命令放行一次(danger-full-access),或在 Harness 的 Plugins 页面安装 |
195
+ | `dsh --dump-config` 没有输出 | 某些构建下该标志不打印内容 | 改看 profile 的 `package.json` 与技能列表 |
196
+ | `pnpm` 提示 `allowBuilds` | 一般不会出现(零依赖零构建) | 若出现,说明有人加了依赖或构建脚本,检查 `package.json` |
197
+ | 截屏是黑屏/纯桌面 | 没授予屏幕录制权限,或授予后没重启应用 | 系统设置授予后重启应用 |
198
+ | 录屏没有光标 | 录制工具设置问题 | 用截屏补记指针位置,并在报告里注明 |
199
+ | 模拟器截屏失败 | 没有启动模拟器 | 先 `xcrun simctl boot`,或改用真机 + 控制中心录屏 |
200
+
201
+ ---
202
+
203
+ ## 10. 目录结构 / Layout
204
+
205
+ ```text
206
+ software-design-test/
207
+ ├── package.json # dsh.bundle.patch 指向 cordis.patch.yml
208
+ ├── cordis.patch.yml # 挂载一行:id: observed-ui-test
209
+ ├── lib/
210
+ │ ├── index.js # Cordis 插件:注册 ctx.skills provider(挂载即校验)
211
+ │ └── self-check.js # 离线校验:frontmatter、链接、注入 API 扫描
212
+ ├── skills/
213
+ │ ├── observed-ui-test/ # 主技能:框架、三级模式、禁用指令、取证、报告模板
214
+ │ ├── observed-test-plan/# 计划技能:权限问卷、元素清单、用例矩阵
215
+ │ └── software-design-test/ # 模拟技能:工作流、人物场景、启发式巡游、缺陷复现、出处
216
+ ├── scripts/
217
+ │ ├── session.mjs # 会话脚手架 + 权限闸门 + 发现落盘
218
+ │ ├── capture.mjs # 只读截屏/录屏(绝不含输入注入)
219
+ │ ├── guard.mjs # 只读观察输入注入线索(观察注入 ≠ 执行注入)
220
+ │ ├── report.mjs # 生成中英对照报告
221
+ │ └── verify.mjs # 离线自检 8 项
222
+ ├── test/ # node:test 用例(25 条)
223
+ ├── docs/ # 本安装说明、使用说明、框架总览
224
+ ├── locale/{zh,en}.json # Plugins 页面标题与描述
225
+ └── icon.svg
226
+ ```
@@ -0,0 +1,295 @@
1
+ # 使用说明 / Usage
2
+
3
+ > 中英对照:每段中文后跟 `> EN:` 英文。 / Bilingual: each Chinese block is followed by `> EN:`.
4
+ >
5
+ > 一句话:**人操作、屏幕作证、Agent 读图判定。** 中间不允许任何"内部指针指令"。
6
+ > One line: **the human acts, the screen testifies, the agent reads the picture.** No internal
7
+ > pointer directives anywhere in between.
8
+
9
+ ---
10
+
11
+ ## 1. 它解决什么问题 / What it is for
12
+
13
+ 用 DeepSeek Harness 做软件设计时,"改完到底好不好用"通常没人系统验证。这个插件把**人工观察式
14
+ 测试**变成一套可执行、可审计的流程:从真实鼠标键盘操作出发,用录屏与截屏判断功能元素是否完好、
15
+ 工具是否真的能用,最后交出一份中英对照、带证据、能复现的报告。
16
+
17
+ When you design software with DeepSeek Harness, nobody systematically verifies whether the result is
18
+ actually usable. This plugin turns **human-observed testing** into an executable, auditable process:
19
+ real mouse and keyboard input, screen recordings and screenshots as evidence, and a bilingual,
20
+ reproducible report at the end.
21
+
22
+ 适用平台 / Platforms:macOS · Windows · iPhone · iPad · 以及 Android、电视/车机/手表等交互设备。
23
+
24
+ ---
25
+
26
+ ## 2. 五步跑完一轮 / Five steps per round
27
+
28
+ ### 第 0 步 · 说触发词(推荐)/ Say the trigger phrase (recommended)
29
+
30
+ ```text
31
+ 模拟真实用户测试
32
+ ```
33
+
34
+ 或英文 `simulate a real user test` / `run a real-user simulation test`。
35
+ 插件收到后**立即开始真实模拟测试**:一句话确认对象 → 发权限问卷 → 建会话开跑,
36
+ 不再跟你讨论方法论、不再反复确认流程。只有触发词、没给对象时,它只会问一句"测哪个应用/功能?"
37
+
38
+ > Saying the trigger phrase starts the run immediately: one line to confirm the target, then the
39
+ > permission questionnaire, then straight into P1–P9.
40
+
41
+ ### 第 1 步 · 或者点名技能 / Or name the skill directly
42
+
43
+ 在对话里直接说,或用 `/` 菜单:
44
+
45
+ ```text
46
+ 用软件设计测试(模拟真实用户)测一下 <应用名>:先按 observed-test-plan 过权限闸门,
47
+ 再按 software-design-test 建人物、场景、任务卡,最后按三级模式真实操作。
48
+ Test <app> by simulating real users: run the permission gate from observed-test-plan, build
49
+ personas/scenarios/task cards with software-design-test, then execute L1 → L2 → L3.
50
+ ```
51
+
52
+ > EN: Say it in chat or pick the skill from the `/` menu. Both skills are model-invocable, so the
53
+ > agent can also pick them up on its own when the request matches.
54
+
55
+ ### 第 2 步 · 回答权限问卷 / Answer the permission questionnaire
56
+
57
+ Agent 会先发出权限问卷(鼠标、键盘、屏幕录制、截屏、麦克风、系统权限、范围与数据边界、合规确认)。
58
+ **不回答就不开始。** 问答会落盘到会话目录的 `permissions.md`。
59
+
60
+ The agent first asks the permission questionnaire (mouse, keyboard, screen recording, screenshots,
61
+ microphone, OS permissions, scope, data boundary, compliance). **No answers, no start.** The Q&A is
62
+ written into `permissions.md`.
63
+
64
+ > 提示:如果只愿意给截屏、不给录屏,也可以进行,但报告首页会记录"无连续录屏"这个缺口。
65
+ > Tip: screenshots without recording still works, but the gap is recorded on page one of the report.
66
+
67
+ ### 第 3 步 · 建会话 / Create the session
68
+
69
+ ```bash
70
+ cd /Users/inception/Documents/deepseek-harness/default-workspace/software-design-test
71
+ node scripts/session.mjs init ./ui-test-<app>-$(date +%F) --platform macos --app "<应用名>" --tester "<操作者>"
72
+ node scripts/session.mjs gate ./ui-test-<app>-<date> --mouse yes --keyboard L2 \
73
+ --screen-recording yes --screenshot yes --microphone no --os-permission yes --cursor yes \
74
+ --compliance yes --data-boundary "仅测试账号"
75
+ node scripts/capture.mjs check # 确认取证工具可用 / verify capture works
76
+ node scripts/guard.mjs scan ./ui-test-<app>-<date> # 测试前:观察有没有注入工具在跑
77
+ ```
78
+
79
+ ### 第 4 步 · 按 L1 → L2 → L3 执行 / Run L1 → L2 → L3
80
+
81
+ 测试期间:
82
+
83
+ ```bash
84
+ node scripts/capture.mjs record <session> --label L1 --seconds 60 # 录一段
85
+ node scripts/capture.mjs shot <session> --label L1-07-after # 截一张
86
+ node scripts/guard.mjs watch <session> --seconds 600 # 后台盯着注入线索
87
+ ```
88
+
89
+ 测得一条就立刻落盘一条(不要攒到最后回忆):
90
+
91
+ ```bash
92
+ node scripts/session.mjs finding <session> --json '{
93
+ "level":"L1","element":"E-07 工具栏「导出」按钮",
94
+ "title_zh":"导出按钮点击无反应","title_en":"Export button does nothing",
95
+ "steps_zh":"移动鼠标到按钮,悬停 1 秒,单击","steps_en":"Hover 1s, then click",
96
+ "expected_zh":"弹出导出面板","expected_en":"Export dialog opens",
97
+ "actual_zh":"无反应,也没有按下态","actual_en":"No reaction, no pressed state",
98
+ "modes":"L1 fail / L2 fail / L3 ⌘E pass","severity":"S2","kind":"defect",
99
+ "evidence":["evidence/2026-10-04T09-30-12-L1-07-after.png"]
100
+ }'
101
+ ```
102
+
103
+ ### 第 5 步 · 出报告 / Generate the report
104
+
105
+ ```bash
106
+ node scripts/report.mjs build <session> # 生成 report.md(中英对照)
107
+ xattr -c <session>/evidence/*.png 2>/dev/null || true # 可选:清理隔离属性
108
+ ```
109
+
110
+ > EN: `report.md` collects the gate record, coverage, severity counts, per-finding detail with
111
+ > cross-mode differences, unverified items, the evidence index, the injection-watch section and a
112
+ > compliance statement.
113
+
114
+ ---
115
+
116
+ ## 3. 模拟真实用户:本插件的重心 / Simulating a real user: the centerpiece
117
+
118
+ **本插件的重点就是这个**:不是"检查按钮渲染是否正常",而是**按真实用户会怎么用来找问题**。
119
+ "测什么"的完整清单在 [TEST-CONTENT.md](../skills/software-design-test/TEST-CONTENT.md):15 类,
120
+ 含窗口与界面尺寸、鼠标速度与指针、工具栏可读性、目标尺寸、文字、布局、反馈、效率、键盘焦点、
121
+ 可访问性、性能、错误恢复、数据输入、跨设备一致性、视觉打磨,每类都有"怎么看 + 判据"。
122
+ 十步流程(P0–P9)写在 [WORKFLOW.md](../skills/software-design-test/WORKFLOW.md);
123
+ 主技能名与插件名同名,是 `/` 菜单里的直接入口。
124
+
125
+ **三句话记住** / Three lines:
126
+
127
+ 1. **人物**是观察的架子:3–5 个,每个都有依据(访谈/工单/埋点/设计目标/自身体验),
128
+ 并且写明"他会在哪里放弃"。
129
+ 2. **任务卡**里不写答案:新手任务卡写具体点击位置,你测的就变成执行力而不是可发现性。
130
+ 3. **缺陷分四类**:测试者错误、观察错误、产品缺陷、环境故障——**只有第三类算缺陷**。
131
+
132
+ **可直接复制的提示词 / Copy-paste prompt:**
133
+
134
+ ```text
135
+ 按 software-design-test 在这台机器上模拟真实用户找 bug:
136
+ 1) 先跑 observed-test-plan 的权限闸门;
137
+ 2) 建 3 个人物:新手(第一次用)、专家(每天 100 次)、键盘-only(可访问性需求),
138
+ 每个人物写依据和"会在哪里放弃";
139
+ 3) 每人至少一个场景,覆盖"首次成功""出错与恢复""中断"三类;
140
+ 4) 拆成任务卡,成功标准必须是画面上能看见的;
141
+ 5) 用启发式扫一遍:认知走查四问 → 十项可用性启发式 → HICCUPPS(F) → SFDIPOT → 巡游;
142
+ 6) 按 L1 → L2 → L3 真实操作执行,出声思维,录屏 + 点击前后静帧;
143
+ 7) 每条发现写 persona、scenario、task_outcome、复现率与证据;
144
+ 8) 出报告,包含"用户模拟覆盖"一节。
145
+
146
+ 硬性规则不变:不注入鼠标/触摸/按键,不驱动自动化框架;我操作,你观察。
147
+ ```
148
+
149
+ **报告里会多出一节**:`用户模拟覆盖 / User-simulation coverage` —— 计划人物/场景 vs 实际走到的、
150
+ 任务结果分布(通过/部分/失败/受阻/未验证)、每个人物的最坏级别。
151
+
152
+ > EN: The simulation skill adds personas, scenarios, task cards, a journey, heuristic sweeps and the
153
+ > four-way failure classification on top of the same three input modes and the same no-injection rule.
154
+ > The report gains a **User-simulation coverage** section.
155
+
156
+ **常见误区 / Common mistakes**:人物写成完人(什么都顺利)· 只走成功路径 · 任务卡里写出答案 ·
157
+ 观察者引导操作者 · 把模拟结论写成"用户都……"。
158
+ 详见 [DEFECTS.md](../skills/software-design-test/DEFECTS.md) 第八节。
159
+
160
+ ---
161
+
162
+ ## 4. 三级操作模式怎么选 / Choosing the input mode
163
+
164
+ | 级别 | 操作方式 | 主要能抓到 |
165
+ | --- | --- | --- |
166
+ | **L1 仅鼠标** | 只动鼠标:单击、双击、右键、拖拽、滚轮、悬停 | 没有鼠标可达路径、命中区过小、必须悬停才可发现的控件 |
167
+ | **L2 鼠标+键盘(禁快捷键)** | 可打字、Enter、Tab、方向键、退格、空格;禁止一切修饰键组合与功能键 | 键盘导航断链、焦点环错位/丢失、焦点陷阱、Tab 顺序错乱 |
168
+ | **L3 鼠标+键盘+快捷键** | 全部放开;每条功能走"鼠标路径"与"快捷键路径"并比对 | 快捷键失效/冲突、两条路径结果不一致、快捷键提示写错 |
169
+
170
+ > EN: L1 catches missing mouse-reachable paths; L2 catches broken keyboard navigation and focus;
171
+ > L3 compares the menu path with the shortcut path. The difference across modes is itself a finding:
172
+ > pass only at L3 → no mouse path; pass only at L1/L2 → the shortcut path is broken.
173
+
174
+ ---
175
+
176
+ ## 5. Agent 会怎么问、怎么判 / How the agent asks and judges
177
+
178
+ **问答模板(可直接复制给 Agent)/ Copy-paste prompt:**
179
+
180
+ ```text
181
+ 我要用 software-design-test 模拟真实用户测 <应用名> <版本>(<平台>)。
182
+ 请按这个顺序做:
183
+ 1) 先发权限问卷,等我逐条回答(鼠标、键盘级别、录屏、截屏、麦克风、系统权限、范围、数据边界、合规确认);
184
+ 2) 用 session.mjs init 建会话并记录我的答复;
185
+ 3) 只看画面列元素清单与用例矩阵(不要看代码);
186
+ 4) 先跑 L1 全量,再 L2,再 L3,每条失败用例都在 L2/L3 复现一次并登记跨模式差异;
187
+ 5) 每测得一条就写进 findings.jsonl,截图前一张后一张;
188
+ 6) 最后出中英对照报告,含未验证项与权限缺口。
189
+
190
+ 硬性要求:不允许使用任何内部指针指令(不注入鼠标/触摸/按键、不驱动自动化框架、不调用内部句柄);
191
+ 证据只来自录屏与截屏;我操作,你观察。
192
+ ```
193
+
194
+ **判定句式 / Judgement patterns:**
195
+
196
+ - 「L1 做不到,L2/L3 能做到」→ 缺鼠标可达路径(可用性缺陷)。
197
+ - 「L1/L2 能做到,L3 失败」→ 快捷键路径缺陷。
198
+ - 「三级都做不到」→ 功能本身缺陷。
199
+ - 「L1 出现,L2/L3 不出现」→ 与输入方式耦合的状态缺陷。
200
+
201
+ ---
202
+
203
+ ## 6. 关于"观察注入" / About watching for injection
204
+
205
+ 插件自带 `guard.mjs`,它**只读观察**输入注入线索(扫描进程表、扫描计划与发现文本),
206
+ 把命中写进 `evidence/compliance.jsonl`,并在报告第 8 节汇总。它**没有任何注入能力**,
207
+ 也不提供注入子命令。
208
+
209
+ `guard.mjs` **observes** injection directives only — process table and session text — writing hits to
210
+ `evidence/compliance.jsonl` and into section 8 of the report. It has **no injection capability** and
211
+ no injection subcommand.
212
+
213
+ > 意义:纪律不靠自觉。测试前扫一次、测试中盯一遍,"偷偷用脚本点一下"会留下痕迹。
214
+ > Why: discipline should leave a trace. Scan before, watch during — a smuggled scripted click has to
215
+ > show up somewhere.
216
+
217
+ ---
218
+
219
+ ## 7. 常见问题 / FAQ
220
+
221
+ **Q:没有录屏权限怎么办?**
222
+ A:改用逐步截屏(每条用例前后各一张),报告首页会记录"无连续录屏"。
223
+ > EN: Use step-by-step screenshots; the gap is recorded on page one.
224
+
225
+ **Q:只有截屏也不行呢?**
226
+ A:那就无法进行观察式测试——无画面即无证据。停下来,先解决权限。
227
+ > EN: Then the method cannot run: no picture, no evidence. Stop and fix permissions first.
228
+
229
+ **Q:iPhone 真机怎么录?**
230
+ A:控制中心 → 屏幕录制(长按可开麦克风);或用 Mac 的 QuickTime 连续互通录制真机屏幕。
231
+ > EN: Control Centre → Screen Recording, or QuickTime on a Mac via Continuity.
232
+
233
+ **Q:模拟器算不算真机?**
234
+ A:不算。可以在模拟器上发现问题,但报告里必须写"未在真机验证(模拟器)"。
235
+ > EN: No. It can find problems, but the report must say "not verified on real hardware".
236
+
237
+ **Q:为什么不能用 Playwright / Appium / cliclick 帮我点?**
238
+ A:那正是被禁止的"内部指针指令"。一旦允许注入,缺陷就不再是"真实用户会遇到的缺陷"。
239
+ > EN: Those are exactly the banned internal pointer directives. Once injection is allowed, the defects
240
+ > are no longer the ones a real user would hit.
241
+
242
+ **Q:我真的需要自动化回归怎么办?**
243
+ A:那是另一轮工作,另开一轮、另写报告,**不能和本方法的结论混在一起**。
244
+ > EN: That is a different round with a different report; never mix its results with this method's.
245
+
246
+ **Q:用户模拟的结论能当作用户研究吗?**
247
+ A:不能。模拟提高的是发现率,不是结论权威性;高风险功能必须补真人会话,报告里写清"在 P-01 这个
248
+ 模拟视角下",而不是"用户都找不到导出"。
249
+ > EN: No. Simulation raises detection rate, not authority. Keep real sessions for high-risk features and
250
+ > always phrase findings as "under persona P-01", never "all users".
251
+
252
+ **Q:为什么不能用 AI/GUI 智能体替我点一遍?**
253
+ A:它的动作层就是内部指针指令(CDP / XTest / SendInput / 辅助功能驱动)。可以参考它的推理层
254
+ (先描述屏幕状态、按角色与名称定位元素、里程碑、后置条件、自我核查、失败四分类),但手必须是人的。
255
+ > EN: Its act layer is exactly the banned injection; borrow only its reasoning primitives.
256
+
257
+ **Q:被测机器上必须关掉什么?**
258
+ A:自动化框架、宏软件、按键精灵类工具、浏览器自动化扩展、远程控制软件;辅助功能权限不给非必要应用。
259
+ > EN: Automation frameworks, macro utilities, browser automation extensions, remote-control tools;
260
+ > and no unnecessary accessibility grants.
261
+
262
+ **Q:截图里有隐私怎么办?**
263
+ A:测试前就定好数据边界,用测试账号与演示数据;已录到的隐私内容在交付前处理掉。
264
+ > EN: Set the data boundary up front, use a test account and demo data, and scrub anything private
265
+ > before delivery.
266
+
267
+ ---
268
+
269
+ ## 8. 命令速查 / Command cheat sheet
270
+
271
+ ```bash
272
+ # 会话 / session
273
+ node scripts/session.mjs init <dir> --platform macos --app "<app>" [--tester "<name>"] [--force]
274
+ node scripts/session.mjs gate <dir> --mouse yes --keyboard L2 --screen-recording yes --screenshot yes \
275
+ [--microphone no] [--os-permission yes] [--cursor yes] \
276
+ [--compliance yes] [--data-boundary "..."]
277
+ node scripts/session.mjs status <dir>
278
+ node scripts/session.mjs finding <dir> --json '<json>' | --json @file.json | --stdin
279
+ # finding 可带字段 / finding may carry: persona, scenario, task_outcome, heuristic, tour,
280
+ # repro_rate, minimized, modes, severity(S1-S4|U), kind(defect|observation|suspicion|unverified)
281
+
282
+ # 取证 / evidence(只读捕获,绝不注入)
283
+ node scripts/capture.mjs check
284
+ node scripts/capture.mjs shot <dir> --label L1-07-after [--window] [--target macos|ios-sim|android|windows]
285
+ node scripts/capture.mjs record <dir> --label L1 --seconds 60 [--target ...]
286
+
287
+ # 注入观察 / injection watch(观察 ≠ 执行)
288
+ node scripts/guard.mjs scan <dir>
289
+ node scripts/guard.mjs watch <dir> --seconds 600 [--interval 5]
290
+
291
+ # 报告与自检 / report and self-check
292
+ node scripts/report.mjs build <dir> [--out report.md]
293
+ node scripts/verify.mjs
294
+ node --test test/*.test.mjs
295
+ ```
package/icon.svg ADDED
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Observed UI Testing">
2
+ <defs>
3
+ <linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#5B8DEF"/>
5
+ <stop offset="1" stop-color="#7C6CF6"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <rect x="2" y="2" width="60" height="60" rx="14" fill="url(#g)"/>
9
+ <!-- eye: the observation channel -->
10
+ <path d="M8 30c7-9 15-13 24-13s17 4 24 13c-7 9-15 13-24 13S15 39 8 30Z" fill="#fff" opacity="0.95"/>
11
+ <circle cx="32" cy="30" r="8" fill="#1F2A44"/>
12
+ <circle cx="35" cy="27" r="2.6" fill="#fff"/>
13
+ <!-- cursor: real pointer only, no injected events -->
14
+ <path d="M38 34l16 7-7 2.4L44 51l-6-17Z" fill="#fff" stroke="#1F2A44" stroke-width="2.4" stroke-linejoin="round"/>
15
+ <!-- three input modes -->
16
+ <g fill="#fff">
17
+ <circle cx="16" cy="52" r="3"/>
18
+ <circle cx="26" cy="52" r="3" opacity="0.75"/>
19
+ <circle cx="36" cy="52" r="3" opacity="0.5"/>
20
+ </g>
21
+ </svg>