remnote-bridge 0.1.12 → 0.1.14
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.
- package/README.md +141 -28
- package/README.zh-CN.md +368 -0
- package/dist/cli/commands/edit-rem.js +5 -5
- package/dist/cli/commands/health.js +231 -112
- package/dist/cli/commands/read-rem-in-tree.js +84 -0
- package/dist/cli/commands/read-rem.js +3 -1
- package/dist/cli/config.js +2 -0
- package/dist/cli/daemon/registry.js +8 -0
- package/dist/cli/handlers/edit-handler.js +49 -140
- package/dist/cli/handlers/patch-engine.js +347 -0
- package/dist/cli/handlers/read-handler.js +5 -57
- package/dist/cli/handlers/rem-cache.js +10 -5
- package/dist/cli/handlers/rem-field-filter.js +102 -0
- package/dist/cli/handlers/tree-edit-handler.js +67 -7
- package/dist/cli/handlers/tree-read-handler.js +4 -1
- package/dist/cli/handlers/tree-rem-read-handler.js +73 -0
- package/dist/cli/main.js +71 -12
- package/dist/cli/server/ws-server.js +9 -1
- package/dist/mcp/daemon-client.js +22 -2
- package/dist/mcp/format.js +43 -0
- package/dist/mcp/index.js +0 -55
- package/dist/mcp/instructions.js +447 -284
- package/dist/mcp/resources/edit-rem-guide.js +37 -157
- package/dist/mcp/resources/edit-tree-guide.js +1 -1
- package/dist/mcp/resources/error-reference.js +9 -13
- package/dist/mcp/resources/rem-object-fields.js +3 -3
- package/dist/mcp/tools/edit-tools.js +76 -10
- package/dist/mcp/tools/infra-tools.js +30 -33
- package/dist/mcp/tools/read-tools.js +221 -26
- package/package.json +1 -1
- package/remnote-plugin/dist/index-sandbox.js +24 -24
- package/remnote-plugin/dist/index.js +24 -24
- package/remnote-plugin/src/bridge/message-router.ts +3 -0
- package/remnote-plugin/src/services/read-rem-in-tree.ts +43 -0
- package/remnote-plugin/src/services/read-rem.ts +15 -0
- package/remnote-plugin/src/services/read-tree.ts +5 -0
- package/skills/remnote-bridge/SKILL.md +71 -38
- package/skills/remnote-bridge/instructions/connect.md +12 -1
- package/skills/remnote-bridge/instructions/disconnect.md +5 -0
- package/skills/remnote-bridge/instructions/edit-rem.md +105 -347
- package/skills/remnote-bridge/instructions/edit-tree.md +71 -2
- package/skills/remnote-bridge/instructions/health.md +81 -53
- package/skills/remnote-bridge/instructions/overall.md +55 -21
- package/skills/remnote-bridge/instructions/read-rem-in-tree.md +100 -0
- package/skills/remnote-bridge/instructions/read-rem.md +35 -16
- package/skills/remnote-bridge/instructions/search.md +4 -4
- package/skills/remnote-bridge/instructions/setup.md +5 -6
- package/skills/remnote-bridge-test/SKILL.md +847 -0
- package/skills/remnote-bridge-test/references/regression-suite.md +960 -0
- package/skills/remnote-bridge-test/references/verification-guide.md +161 -0
|
@@ -0,0 +1,960 @@
|
|
|
1
|
+
# 回归测试基线
|
|
2
|
+
|
|
3
|
+
固定的回归测试用例集。按级别组织,前序级别不过则后续全部跳过。
|
|
4
|
+
|
|
5
|
+
**本文件是活的**:随着功能增加,往对应级别里追加新用例。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 使用方式
|
|
10
|
+
|
|
11
|
+
### 全量回归(发布前)
|
|
12
|
+
|
|
13
|
+
从 L1 逐级跑到 L5,全部 PASS 才算通过。
|
|
14
|
+
|
|
15
|
+
### 快速回归(小改后)
|
|
16
|
+
|
|
17
|
+
只跑 L1 + 受影响级别。例如改了 edit-tree → 跑 L1 + L2 + L3。
|
|
18
|
+
|
|
19
|
+
### 选择性回归
|
|
20
|
+
|
|
21
|
+
用户指定跑哪些用例。
|
|
22
|
+
|
|
23
|
+
### 双接口执行
|
|
24
|
+
|
|
25
|
+
**每个用例必须在 MCP 和 Skill 两个接口各跑一遍**:
|
|
26
|
+
- MCP:用 MCP 测试模板(prompt 禁止 Bash/Read,只用 `mcp__remnote-bridge__*`)
|
|
27
|
+
- Skill:用 Skill 测试模板(prompt 禁止 MCP 工具,只用 Bash + Read 执行 CLI)
|
|
28
|
+
|
|
29
|
+
隔离通过 prompt 纪律实现,审计时检查 subagent 是否违反工具限制。一侧过另一侧不过 → 说明对应接口的文档有问题。
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 级别定义
|
|
34
|
+
|
|
35
|
+
| 级别 | 主题 | 典型规模 | 覆盖工具 |
|
|
36
|
+
|:-----|:-----|:---------|:---------|
|
|
37
|
+
| **L1** | 基础设施 + 导航 | — | health, connect, disconnect, read_globe, read_context, search |
|
|
38
|
+
| **L2** | 单页面真实任务 | 10-20 行输出 | read_tree, edit_tree, read_rem, edit_rem |
|
|
39
|
+
| **L3** | 多步工作流 | 20-40 行输出 | 组合使用读写工具 + search |
|
|
40
|
+
| **L4** | 大规模真实任务 | 40+ 行输出 | 全工具协调 |
|
|
41
|
+
| **L5** | 极端边界 + 错误恢复 | — | 防线触发、大树省略、并发检测 |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## L1 基础设施 + 导航
|
|
46
|
+
|
|
47
|
+
> 连接不通一切白搭。
|
|
48
|
+
|
|
49
|
+
### L1-01: 连接生命周期
|
|
50
|
+
|
|
51
|
+
> ⚠️ **不可并行**:此用例执行 connect/disconnect,会干扰其他 subagent 的连接状态。必须单独串行执行。
|
|
52
|
+
|
|
53
|
+
**task_description**:
|
|
54
|
+
```
|
|
55
|
+
检查 RemNote 工具的连接状态并验证完整的连接/断开生命周期。
|
|
56
|
+
|
|
57
|
+
1. 检查系统健康状态(health)
|
|
58
|
+
2. 如果未连接,建立连接(connect)
|
|
59
|
+
3. 再次检查健康状态,确认 daemon / Plugin / SDK 三层都正常
|
|
60
|
+
4. 断开连接(disconnect)
|
|
61
|
+
5. 检查健康状态,确认已断开(daemon 应不再运行)
|
|
62
|
+
6. 重新连接,确保恢复正常
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**验证**:无需 Chrome(纯基础设施)。检查 subagent 是否正确理解三层依赖、正确执行生命周期。
|
|
66
|
+
|
|
67
|
+
**断言**:
|
|
68
|
+
- [ ] 正确调用 health 并解读三层状态
|
|
69
|
+
- [ ] connect 成功启动 daemon
|
|
70
|
+
- [ ] disconnect 后 health 显示断开
|
|
71
|
+
- [ ] 重连后三层恢复
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### L1-02: 探索 + 搜索 + 上下文
|
|
76
|
+
|
|
77
|
+
**task_description**:
|
|
78
|
+
```
|
|
79
|
+
综合使用导航和搜索工具探索知识库。
|
|
80
|
+
|
|
81
|
+
1. 确认连接正常(health 三层就绪)
|
|
82
|
+
2. 获取知识库的全局文档鸟瞰图(read_globe)
|
|
83
|
+
3. 从结果中找到名为"MCP 测试"的文档,报告它的 remId
|
|
84
|
+
4. 搜索关键词"测试",报告搜到多少条结果
|
|
85
|
+
5. 获取当前上下文信息(read_context)
|
|
86
|
+
6. 综合报告:
|
|
87
|
+
- read_globe 返回了多少个顶层文档
|
|
88
|
+
- search 返回了多少条匹配
|
|
89
|
+
- read_context 返回了什么面包屑路径
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**验证**:subagent 能正确使用三个导航工具并综合报告结果。
|
|
93
|
+
|
|
94
|
+
**断言**:
|
|
95
|
+
- [ ] read_globe 成功,返回文档鸟瞰图
|
|
96
|
+
- [ ] 正确识别"MCP 测试"文档及其 remId
|
|
97
|
+
- [ ] search 成功返回结果
|
|
98
|
+
- [ ] read_context 成功返回上下文信息
|
|
99
|
+
- [ ] 综合报告包含三个工具的关键输出
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## L2 单页面真实任务
|
|
104
|
+
|
|
105
|
+
> 模拟用户实际会让 AI 做的单页面操作。
|
|
106
|
+
|
|
107
|
+
### L2-01: 生成一章学习笔记
|
|
108
|
+
|
|
109
|
+
**task_description**:
|
|
110
|
+
```
|
|
111
|
+
在测试页面下创建"机器学习基础"学习笔记结构。
|
|
112
|
+
|
|
113
|
+
1. 确认连接正常
|
|
114
|
+
2. 读取测试页面的子树(read_tree)
|
|
115
|
+
3. 在测试页面下创建以下结构(edit_tree):
|
|
116
|
+
|
|
117
|
+
{prefix} 机器学习基础 (H1 标题)
|
|
118
|
+
## 监督学习
|
|
119
|
+
分类 → 预测离散标签
|
|
120
|
+
回归 → 预测连续值
|
|
121
|
+
过拟合 → 模型在训练集表现好但泛化差 (Yellow 高亮)
|
|
122
|
+
## 无监督学习
|
|
123
|
+
聚类 → 将相似数据分组
|
|
124
|
+
降维 → 减少特征维度同时保留信息
|
|
125
|
+
## 模型评估
|
|
126
|
+
准确率 → 正确预测占总预测的比例
|
|
127
|
+
精确率 → 预测为正例中实际为正例的比例
|
|
128
|
+
召回率 → 实际正例中被正确预测的比例 (Yellow 高亮)
|
|
129
|
+
|
|
130
|
+
4. 重新读取子树,确认:
|
|
131
|
+
- 根节点是 H1 标题
|
|
132
|
+
- 3 个 H2 章节都在
|
|
133
|
+
- 每章下的知识点数量和内容正确
|
|
134
|
+
- 闪卡方向(→)正确
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Chrome 验证**:
|
|
138
|
+
- ⬜ 根节点 "{prefix} 机器学习基础" 为 H1 大标题
|
|
139
|
+
- ⬜ 3 个 H2 章节标题存在
|
|
140
|
+
- ⬜ 监督学习下 3 个知识点、无监督学习下 2 个、模型评估下 3 个
|
|
141
|
+
- ⬜ 有箭头分隔符和 backText
|
|
142
|
+
- ⬜ "过拟合"和"召回率"节点有 Yellow 高亮
|
|
143
|
+
|
|
144
|
+
**注意**:高亮需要通过 edit_rem 单独设置(edit_tree 新增行不支持 highlightColor),subagent 需要:创建结构后 → read_rem 获取目标节点 → edit_rem 设置 highlightColor=Yellow。
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### L2-02: 批量生成闪卡组
|
|
149
|
+
|
|
150
|
+
**task_description**:
|
|
151
|
+
```
|
|
152
|
+
帮用户做 8 张日语 N3 语法闪卡,涵盖所有闪卡类型。
|
|
153
|
+
|
|
154
|
+
1. 确认连接正常
|
|
155
|
+
2. 读取测试页面的子树
|
|
156
|
+
3. 在测试页面下创建以下闪卡(edit_tree):
|
|
157
|
+
|
|
158
|
+
{prefix} 日语 N3 语法 (H2 标题)
|
|
159
|
+
|
|
160
|
+
a. 4 张概念定义(concept ↔ 双向):
|
|
161
|
+
~ために ↔ 表示目的,"为了……" <!--type:concept-->
|
|
162
|
+
~ようにする ↔ 表示努力做到,"尽量……" <!--type:concept-->
|
|
163
|
+
~ことにする ↔ 表示决定做某事 <!--type:concept-->
|
|
164
|
+
~ことになる ↔ 表示(被)决定做某事 <!--type:concept-->
|
|
165
|
+
|
|
166
|
+
b. 2 张正向问答(→):
|
|
167
|
+
「彼は医者になるために勉強しています」的语法点 → ~ために(表示目的)
|
|
168
|
+
「毎日運動するようにしている」的语法点 → ~ようにする(表示习惯性努力)
|
|
169
|
+
|
|
170
|
+
c. 2 张多行闪卡(↓ + 答案行):
|
|
171
|
+
~ために的三个用法 ↓
|
|
172
|
+
目的:試験に合格するために勉強する
|
|
173
|
+
原因:風邪のために学校を休んだ
|
|
174
|
+
利益:家族のために働く
|
|
175
|
+
~ようにする vs ~ことにする的区别 ↓
|
|
176
|
+
ようにする:渐进的努力/习惯养成
|
|
177
|
+
ことにする:明确的一次性决定
|
|
178
|
+
共同点:都表示主观意愿
|
|
179
|
+
|
|
180
|
+
4. 重新读取子树确认:
|
|
181
|
+
- 8 张闪卡都存在
|
|
182
|
+
- 概念定义(前 4 张)是加粗的 concept 类型
|
|
183
|
+
- 正向问答(第 5-6 张)有 → 方向
|
|
184
|
+
- 多行闪卡(第 7-8 张)有 ↓ 方向,子行作为答案
|
|
185
|
+
5. 对任意 2 张概念定义闪卡执行 read_rem,验证 type=concept、practiceDirection=both、backText 内容正确
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Chrome 验证**:
|
|
189
|
+
- ⬜ 标题 "{prefix} 日语 N3 语法" 为 H2
|
|
190
|
+
- ⬜ 4 张概念定义加粗(concept),有 :: 分隔
|
|
191
|
+
- ⬜ 2 张正向问答有 >> 分隔
|
|
192
|
+
- ⬜ 2 张多行闪卡展开后有 3 个答案行
|
|
193
|
+
- ⬜ 总共 8 张闪卡 + 标题 = 9 个直接子节点
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
### L2-03: 批量格式化整理
|
|
198
|
+
|
|
199
|
+
**task_description**:
|
|
200
|
+
```
|
|
201
|
+
创建 5 个知识点后批量修改它们的属性。
|
|
202
|
+
|
|
203
|
+
1. 确认连接正常
|
|
204
|
+
2. 读取测试页面的子树
|
|
205
|
+
3. 创建 5 个节点(edit_tree):
|
|
206
|
+
{prefix} 线性代数
|
|
207
|
+
{prefix} 微积分
|
|
208
|
+
{prefix} 概率论
|
|
209
|
+
{prefix} 离散数学
|
|
210
|
+
{prefix} 复习清单
|
|
211
|
+
|
|
212
|
+
4. 重新读取子树,获取 5 个节点的 remId
|
|
213
|
+
5. 逐个读取(read_rem)+ 修改(edit_rem):
|
|
214
|
+
- "线性代数":type=concept + highlightColor=Yellow
|
|
215
|
+
- "微积分":type=concept + highlightColor=Yellow
|
|
216
|
+
- "概率论":type=concept + highlightColor=Yellow
|
|
217
|
+
- "离散数学":fontSize=H1
|
|
218
|
+
- "复习清单":isTodo=true + todoStatus=Unfinished
|
|
219
|
+
|
|
220
|
+
6. 逐个 read_rem 确认所有属性已生效
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Chrome 验证**:
|
|
224
|
+
- ⬜ 前 3 个节点加粗(concept)+ 黄色高亮背景
|
|
225
|
+
- ⬜ "离散数学"为 H1 大标题
|
|
226
|
+
- ⬜ "复习清单"前面有未勾选复选框
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### L2-04: 删除 + 重建子树
|
|
231
|
+
|
|
232
|
+
**task_description**:
|
|
233
|
+
```
|
|
234
|
+
创建一个 3 层结构,删除中间子树后重建不同内容。
|
|
235
|
+
|
|
236
|
+
1. 确认连接正常
|
|
237
|
+
2. 读取测试页面的子树
|
|
238
|
+
3. 创建以下 3 层结构(edit_tree):
|
|
239
|
+
|
|
240
|
+
{prefix} 编程语言
|
|
241
|
+
Python
|
|
242
|
+
动态类型
|
|
243
|
+
解释执行
|
|
244
|
+
Java
|
|
245
|
+
静态类型
|
|
246
|
+
编译执行
|
|
247
|
+
Rust
|
|
248
|
+
所有权系统
|
|
249
|
+
零成本抽象
|
|
250
|
+
|
|
251
|
+
4. 读取子树确认 3 层结构完整(根 → 3 子 → 每子 2 孙 = 共 10 节点)
|
|
252
|
+
5. 删除 "Java" 整个子树(含 "静态类型" 和 "编译执行" 两个孙节点)
|
|
253
|
+
注意:edit_tree 删除时必须同时删除父和子,不能留下孤儿节点
|
|
254
|
+
6. 读取子树确认 Java 子树已消失(剩 7 节点)
|
|
255
|
+
7. 在 Python 和 Rust 之间的位置(即 Rust 之前)新增:
|
|
256
|
+
Go
|
|
257
|
+
并发原生支持
|
|
258
|
+
垃圾回收
|
|
259
|
+
|
|
260
|
+
注意:因为不能在有子节点的 Rem 和其 children 之间插入,
|
|
261
|
+
新节点应插在同级兄弟末尾(Rust 之后),然后如果需要调整顺序则重排
|
|
262
|
+
|
|
263
|
+
8. 读取最终结构确认:根下有 Python、Go、Rust(或 Python、Rust、Go)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Chrome 验证**:
|
|
267
|
+
- ⬜ "Java" 子树已消失
|
|
268
|
+
- ⬜ "Go" 节点存在且有 2 个子节点
|
|
269
|
+
- ⬜ 总共 10 个节点(根 + 3 子 + 每子 2 孙)
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## L3 多步工作流
|
|
274
|
+
|
|
275
|
+
> 多步骤组合链路,模拟真实的知识整理流程。
|
|
276
|
+
|
|
277
|
+
### L3-01: 搜索定位 → 整理 → 验证
|
|
278
|
+
|
|
279
|
+
**task_description**:
|
|
280
|
+
```
|
|
281
|
+
搜索已有内容,整理为结构化知识树。
|
|
282
|
+
|
|
283
|
+
1. 确认连接正常
|
|
284
|
+
2. 读取测试页面的子树
|
|
285
|
+
3. 先创建一些"原始笔记"作为搜索素材(edit_tree):
|
|
286
|
+
{prefix} raw-uniquetoken-ml-001 线性回归是最基本的回归模型
|
|
287
|
+
{prefix} raw-uniquetoken-ml-002 逻辑回归用于二分类问题
|
|
288
|
+
{prefix} raw-uniquetoken-ml-003 决策树通过特征分裂做预测
|
|
289
|
+
|
|
290
|
+
4. 搜索关键词 "uniquetoken-ml"(search)
|
|
291
|
+
5. 确认搜到 3 条结果
|
|
292
|
+
|
|
293
|
+
6. 创建一个新的结构化文档来整理这些知识(edit_tree):
|
|
294
|
+
{prefix} 机器学习模型整理 <!--doc-->
|
|
295
|
+
回归模型 ↔ 预测连续值的模型 <!--type:concept-->
|
|
296
|
+
线性回归 → 最基本的回归模型,假设线性关系 <!--type:descriptor-->
|
|
297
|
+
分类模型 ↔ 预测离散标签的模型 <!--type:concept-->
|
|
298
|
+
逻辑回归 → 用于二分类问题 <!--type:descriptor-->
|
|
299
|
+
树模型 ↔ 基于特征分裂的模型 <!--type:concept-->
|
|
300
|
+
决策树 → 通过特征分裂做预测 <!--type:descriptor-->
|
|
301
|
+
|
|
302
|
+
7. 读取新创建的文档子树,验证:
|
|
303
|
+
- 是 Document(isDocument=true)
|
|
304
|
+
- 3 个概念(concept)都有双向闪卡
|
|
305
|
+
- 3 个描述(descriptor)都有正向闪卡
|
|
306
|
+
- CDF 结构正确(descriptor 是 concept 的子节点)
|
|
307
|
+
|
|
308
|
+
8. 用 read_rem 抽查 2 个节点,确认 type 和 practiceDirection 正确
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Chrome 验证**:
|
|
312
|
+
- ⬜ "{prefix} 机器学习模型整理" 是可独立打开的文档页面
|
|
313
|
+
- ⬜ 3 个概念加粗(concept),有 :: 双向分隔
|
|
314
|
+
- ⬜ 3 个描述有 ;; 或 >> 正向分隔
|
|
315
|
+
- ⬜ 层级正确:概念 → 描述(descriptor 在 concept 下)
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
### L3-02: 知识体系构建(CDF + Portal)
|
|
320
|
+
|
|
321
|
+
> ⚠️ **不可并行**:此用例涉及 16+ 节点创建 + Portal 创建,高频操作可能导致 Plugin 连接中断。必须单独串行执行。
|
|
322
|
+
|
|
323
|
+
**task_description**:
|
|
324
|
+
```
|
|
325
|
+
从零搭建"数据结构与算法"知识树,使用 CDF 格式 + Portal 引用。
|
|
326
|
+
|
|
327
|
+
1. 确认连接正常
|
|
328
|
+
2. 读取测试页面子树
|
|
329
|
+
|
|
330
|
+
3. 第一步:创建 5 个核心概念 + 描述属性(edit_tree)
|
|
331
|
+
|
|
332
|
+
{prefix} 数据结构与算法 (H1 标题)
|
|
333
|
+
数组 ↔ 连续内存存储的线性结构 <!--type:concept-->
|
|
334
|
+
时间复杂度 → 访问 O(1),插入/删除 O(n) <!--type:descriptor-->
|
|
335
|
+
使用场景 → 需要快速随机访问的场景 <!--type:descriptor-->
|
|
336
|
+
链表 ↔ 非连续内存的链式结构 <!--type:concept-->
|
|
337
|
+
时间复杂度 → 访问 O(n),插入/删除 O(1) <!--type:descriptor-->
|
|
338
|
+
使用场景 → 频繁插入删除的场景 <!--type:descriptor-->
|
|
339
|
+
栈 ↔ 后进先出(LIFO)的线性结构 <!--type:concept-->
|
|
340
|
+
实现方式 → 数组或链表均可实现 <!--type:descriptor-->
|
|
341
|
+
使用场景 → 函数调用栈、括号匹配、撤销操作 <!--type:descriptor-->
|
|
342
|
+
队列 ↔ 先进先出(FIFO)的线性结构 <!--type:concept-->
|
|
343
|
+
实现方式 → 数组(循环队列)或链表 <!--type:descriptor-->
|
|
344
|
+
使用场景 → 任务调度、BFS、消息队列 <!--type:descriptor-->
|
|
345
|
+
树 ↔ 非线性层次结构 <!--type:concept-->
|
|
346
|
+
二叉搜索树 → 左小右大的二叉树 <!--type:descriptor-->
|
|
347
|
+
使用场景 → 层次数据、搜索、排序 <!--type:descriptor-->
|
|
348
|
+
|
|
349
|
+
4. 读取子树获取"数组"和"链表"的 remId
|
|
350
|
+
|
|
351
|
+
5. 第二步:创建 Portal 对比视图(edit_tree)
|
|
352
|
+
在"数据结构与算法"的子节点末尾新增一个 Portal,引用"数组"和"链表":
|
|
353
|
+
<!--portal refs:{数组remId},{链表remId}-->
|
|
354
|
+
|
|
355
|
+
6. 读取最终结构确认:
|
|
356
|
+
- 5 个 concept 都加粗
|
|
357
|
+
- 10 个 descriptor 都有正向闪卡
|
|
358
|
+
- Portal 存在且引用了数组和链表
|
|
359
|
+
- 总节点数正确(1 根 + 5 概念 + 10 描述 + 1 Portal = 17)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Chrome 验证**:
|
|
363
|
+
- ⬜ H1 标题 "{prefix} 数据结构与算法"
|
|
364
|
+
- ⬜ 5 个概念加粗(concept),有 :: 双向分隔
|
|
365
|
+
- ⬜ 10 个描述属性有正向分隔
|
|
366
|
+
- ⬜ Portal 区域存在(紫色边框),显示数组和链表内容
|
|
367
|
+
- ⬜ 总共约 17 个节点
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
### L3-03: 移动 + 重排 + 重组
|
|
372
|
+
|
|
373
|
+
**task_description**:
|
|
374
|
+
```
|
|
375
|
+
创建 10 个平级节点后按规则重组。
|
|
376
|
+
|
|
377
|
+
1. 确认连接正常
|
|
378
|
+
2. 读取测试页面子树
|
|
379
|
+
3. 创建 10 个平级节点(edit_tree):
|
|
380
|
+
{prefix} A
|
|
381
|
+
{prefix} B
|
|
382
|
+
{prefix} C
|
|
383
|
+
{prefix} D
|
|
384
|
+
{prefix} E
|
|
385
|
+
{prefix} F
|
|
386
|
+
{prefix} G
|
|
387
|
+
{prefix} H
|
|
388
|
+
{prefix} I
|
|
389
|
+
{prefix} J
|
|
390
|
+
|
|
391
|
+
4. 读取子树获取所有 remId
|
|
392
|
+
|
|
393
|
+
5. 重组操作(分多次 edit_tree):
|
|
394
|
+
|
|
395
|
+
a. 先在末尾新增两个分组父节点:
|
|
396
|
+
{prefix} 第一组
|
|
397
|
+
{prefix} 第二组
|
|
398
|
+
|
|
399
|
+
b. 读取子树获取新节点的 remId
|
|
400
|
+
|
|
401
|
+
c. 将 A、B、C 移到"第一组"下面(通过调整缩进)
|
|
402
|
+
d. 将 D、E、F 移到"第二组"下面
|
|
403
|
+
|
|
404
|
+
e. 将 G-J 重排为 J、G、H、I 的顺序
|
|
405
|
+
|
|
406
|
+
6. 读取最终结构确认:
|
|
407
|
+
- "第一组"下有 A、B、C
|
|
408
|
+
- "第二组"下有 D、E、F
|
|
409
|
+
- 顶层剩余节点顺序为 J、G、H、I、第一组、第二组(或合理的最终顺序)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**Chrome 验证**:
|
|
413
|
+
- ⬜ "第一组"展开后有 A、B、C 三个子节点
|
|
414
|
+
- ⬜ "第二组"展开后有 D、E、F 三个子节点
|
|
415
|
+
- ⬜ G-J 重排后顺序变化
|
|
416
|
+
- ⬜ 总共 12 个节点(10 原始 + 2 分组)
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
### L3-04: 富文本标注修改 + read-rem-in-tree 验证
|
|
421
|
+
|
|
422
|
+
> ⚠️ **不可并行**:此用例涉及多次 edit_rem + read_rem_in_tree,高频操作。必须单独串行执行。
|
|
423
|
+
|
|
424
|
+
**task_description**:
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
在测试页面下完成以下任务:
|
|
428
|
+
|
|
429
|
+
阶段 1:创建带初始标注的节点
|
|
430
|
+
|
|
431
|
+
1. 确认连接正常
|
|
432
|
+
2. 读取测试页面子树
|
|
433
|
+
3. 创建以下结构(edit_tree):
|
|
434
|
+
|
|
435
|
+
{prefix} 化学笔记
|
|
436
|
+
化学键 ↔ 原子间的强相互作用 <!--type:concept-->
|
|
437
|
+
共价键 → 共用电子对形成的化学键 <!--type:descriptor-->
|
|
438
|
+
离子键 → 阴阳离子间的静电引力 <!--type:descriptor-->
|
|
439
|
+
金属键 → 金属阳离子与自由电子间的作用 <!--type:descriptor-->
|
|
440
|
+
化学反应 ↔ 物质转变为新物质的过程 <!--type:concept-->
|
|
441
|
+
氧化还原 → 电子转移的反应 <!--type:descriptor-->
|
|
442
|
+
酸碱反应 → 质子转移的反应 <!--type:descriptor-->
|
|
443
|
+
速率因素 ↓ <!--type:descriptor-->
|
|
444
|
+
温度
|
|
445
|
+
浓度
|
|
446
|
+
催化剂
|
|
447
|
+
溶液 ↔ 均匀混合物 <!--type:concept-->
|
|
448
|
+
浓度 → 溶质与溶液的比值 <!--type:descriptor-->
|
|
449
|
+
溶解度 → 一定温度下饱和溶液中溶质的量 <!--type:descriptor-->
|
|
450
|
+
|
|
451
|
+
4. 使用 read_rem_in_tree 一次性读取全部节点(maxNodes=30)
|
|
452
|
+
5. 对以下节点施加初始标注(edit_rem):
|
|
453
|
+
- "化学键" concept:highlightColor = "Yellow"
|
|
454
|
+
- "共价键" descriptor 的 backText:["共用", {"h": 3, "i": "m", "text": "电子对"}, "形成的化学键"]
|
|
455
|
+
- "化学反应" concept:highlightColor = "Blue"
|
|
456
|
+
- "氧化还原" descriptor 的 backText:[{"b": true, "i": "m", "text": "电子转移"}, "的反应"]
|
|
457
|
+
|
|
458
|
+
阶段 2:修改已有标注
|
|
459
|
+
|
|
460
|
+
6. 再次使用 read_rem_in_tree 读取最新状态
|
|
461
|
+
7. 修改标注(edit_rem):
|
|
462
|
+
a. "化学键":改 highlightColor 从 Yellow 到 Red
|
|
463
|
+
b. "共价键":给 backText 中"电子对"额外加粗(h + b 组合)→
|
|
464
|
+
["共用", {"b": true, "h": 3, "i": "m", "text": "电子对"}, "形成的化学键"]
|
|
465
|
+
c. "氧化还原":把 backText 改为纯文本(移除粗体)→ ["电子转移的反应"]
|
|
466
|
+
d. "溶液" concept:新增 highlightColor = "Green"
|
|
467
|
+
e. "浓度" descriptor 的 backText 改为:
|
|
468
|
+
[{"i": "m", "text": "溶质", "u": true}, "与", {"i": "m", "text": "溶液", "u": true}, "的比值"]
|
|
469
|
+
|
|
470
|
+
阶段 3:验证修改
|
|
471
|
+
|
|
472
|
+
8. 使用 read_rem_in_tree 读取验证
|
|
473
|
+
9. 从 remObjects 逐项验证:
|
|
474
|
+
- "化学键" highlightColor = "Red"(从 Yellow 改来)
|
|
475
|
+
- "共价键" backText 中"电子对"同时有 h:3 和 b:true
|
|
476
|
+
- "氧化还原" backText 是纯字符串,无格式对象
|
|
477
|
+
- "溶液" highlightColor = "Green"(新增)
|
|
478
|
+
- "浓度" backText 中"溶质"和"溶液"有 u:true
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**Chrome 验证**:
|
|
482
|
+
- ⬜ "化学键" 红色整行高亮(从黄色改来)
|
|
483
|
+
- ⬜ "共价键" backText 中"电子对"黄色荧光+粗体
|
|
484
|
+
- ⬜ "氧化还原" 纯文本,无格式
|
|
485
|
+
- ⬜ "溶液" 绿色整行高亮
|
|
486
|
+
- ⬜ "浓度" backText 中"溶质"和"溶液"有下划线
|
|
487
|
+
|
|
488
|
+
**断言**:
|
|
489
|
+
- [ ] read_rem_in_tree 成功返回 outline + remObjects
|
|
490
|
+
- [ ] edit_rem 修改 highlightColor 生效(Yellow→Red)
|
|
491
|
+
- [ ] edit_rem 修改 RichText(添加 b+h 组合)生效
|
|
492
|
+
- [ ] edit_rem 移除格式(还原纯文本)生效
|
|
493
|
+
- [ ] edit_rem 新增 highlightColor 生效
|
|
494
|
+
- [ ] edit_rem 添加下划线(u:true)生效
|
|
495
|
+
- [ ] 最终 read_rem_in_tree 返回的 remObjects 与预期一致
|
|
496
|
+
|
|
497
|
+
**工具选择检查**:
|
|
498
|
+
- [ ] 阶段 1 使用 read_rem_in_tree(而非 read_tree + N×read_rem)
|
|
499
|
+
- [ ] 阶段 2 使用 read_rem_in_tree 重新读取(而非逐个 read_rem)
|
|
500
|
+
- [ ] edit_rem 前未冗余调用 read_rem(缓存已由 read_rem_in_tree 建立)
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
## L4 大规模真实任务
|
|
505
|
+
|
|
506
|
+
> 模拟用户让 AI 做的大规模知识整理任务。
|
|
507
|
+
|
|
508
|
+
### L4-01: 10 张多行闪卡
|
|
509
|
+
|
|
510
|
+
> ⚠️ **不可并行**:此用例创建 45+ 节点,高频操作。必须单独串行执行。
|
|
511
|
+
|
|
512
|
+
**task_description**:
|
|
513
|
+
```
|
|
514
|
+
帮用户把 10 个计算机科学概念做成完整的 CDF 闪卡组。
|
|
515
|
+
|
|
516
|
+
1. 确认连接正常
|
|
517
|
+
2. 读取测试页面子树
|
|
518
|
+
|
|
519
|
+
3. 创建以下完整知识结构(edit_tree,可分多次):
|
|
520
|
+
|
|
521
|
+
{prefix} 计算机科学核心概念 (H1 标题)
|
|
522
|
+
|
|
523
|
+
操作系统 ↔ 管理计算机硬件与软件资源的系统软件 <!--type:concept-->
|
|
524
|
+
核心功能 ↓ <!--type:descriptor-->
|
|
525
|
+
进程管理与调度
|
|
526
|
+
内存分配与回收
|
|
527
|
+
文件系统管理
|
|
528
|
+
|
|
529
|
+
编译器 ↔ 将高级语言转换为机器码的程序 <!--type:concept-->
|
|
530
|
+
编译阶段 ↓ <!--type:descriptor-->
|
|
531
|
+
词法分析:源码→Token
|
|
532
|
+
语法分析:Token→AST
|
|
533
|
+
代码生成:AST→目标代码
|
|
534
|
+
|
|
535
|
+
数据库 ↔ 有组织地存储和管理数据的系统 <!--type:concept-->
|
|
536
|
+
ACID 特性 ↓ <!--type:descriptor-->
|
|
537
|
+
原子性(Atomicity)
|
|
538
|
+
一致性(Consistency)
|
|
539
|
+
隔离性(Isolation)
|
|
540
|
+
持久性(Durability)
|
|
541
|
+
|
|
542
|
+
计算机网络 ↔ 互连的计算设备集合 <!--type:concept-->
|
|
543
|
+
TCP/IP 四层模型 ↓ <!--type:descriptor-->
|
|
544
|
+
应用层
|
|
545
|
+
传输层
|
|
546
|
+
网络层
|
|
547
|
+
链路层
|
|
548
|
+
|
|
549
|
+
算法复杂度 ↔ 衡量算法效率的数学工具 <!--type:concept-->
|
|
550
|
+
常见复杂度 ↓ <!--type:descriptor-->
|
|
551
|
+
O(1) 常数时间
|
|
552
|
+
O(log n) 对数时间
|
|
553
|
+
O(n) 线性时间
|
|
554
|
+
O(n²) 平方时间
|
|
555
|
+
|
|
556
|
+
密码学 ↔ 研究信息加密与解密的学科 <!--type:concept-->
|
|
557
|
+
基本分类 ↓ <!--type:descriptor-->
|
|
558
|
+
对称加密:AES、DES
|
|
559
|
+
非对称加密:RSA、ECC
|
|
560
|
+
哈希函数:SHA-256、MD5
|
|
561
|
+
|
|
562
|
+
人工智能 ↔ 模拟人类智能的计算机系统 <!--type:concept-->
|
|
563
|
+
主要分支 ↓ <!--type:descriptor-->
|
|
564
|
+
机器学习
|
|
565
|
+
自然语言处理
|
|
566
|
+
计算机视觉
|
|
567
|
+
|
|
568
|
+
分布式系统 ↔ 多个独立计算机协同工作的系统 <!--type:concept-->
|
|
569
|
+
核心挑战 ↓ <!--type:descriptor-->
|
|
570
|
+
一致性
|
|
571
|
+
可用性
|
|
572
|
+
分区容错性(CAP 定理)
|
|
573
|
+
|
|
574
|
+
软件工程 ↔ 系统化开发和维护软件的工程学科 <!--type:concept-->
|
|
575
|
+
开发方法 ↓ <!--type:descriptor-->
|
|
576
|
+
瀑布模型
|
|
577
|
+
敏捷开发
|
|
578
|
+
DevOps
|
|
579
|
+
|
|
580
|
+
计算理论 ↔ 研究计算本质和极限的数学理论 <!--type:concept-->
|
|
581
|
+
核心概念 ↓ <!--type:descriptor-->
|
|
582
|
+
图灵机
|
|
583
|
+
可计算性
|
|
584
|
+
NP 完全问题
|
|
585
|
+
|
|
586
|
+
4. 读取完整子树确认结构
|
|
587
|
+
|
|
588
|
+
5. 逐个 read_rem 验证至少 5 个 concept 节点:
|
|
589
|
+
- type=concept
|
|
590
|
+
- practiceDirection=both
|
|
591
|
+
- backText 内容正确
|
|
592
|
+
|
|
593
|
+
6. 逐个 read_rem 验证至少 5 个 descriptor 节点:
|
|
594
|
+
- type=descriptor
|
|
595
|
+
- practiceDirection=forward
|
|
596
|
+
- 子节点(答案行)存在
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
**Chrome 验证**:
|
|
600
|
+
- ⬜ H1 标题存在
|
|
601
|
+
- ⬜ 10 个概念加粗(concept),有 :: 双向分隔
|
|
602
|
+
- ⬜ 10 个描述属性有多行答案(展开后可见)
|
|
603
|
+
- ⬜ 每个多行闪卡有 3-4 个答案行
|
|
604
|
+
- ⬜ 总共约 45+ 节点
|
|
605
|
+
|
|
606
|
+
---
|
|
607
|
+
|
|
608
|
+
### L4-02: 完整课程笔记
|
|
609
|
+
|
|
610
|
+
> ⚠️ **不可并行**:此用例创建 20+ 节点 + 多次 edit_rem。必须单独串行执行。
|
|
611
|
+
|
|
612
|
+
**task_description**:
|
|
613
|
+
```
|
|
614
|
+
创建"线性代数"课程笔记——3 个章节文档,每章含概念和描述,混合格式属性。
|
|
615
|
+
|
|
616
|
+
1. 确认连接正常
|
|
617
|
+
2. 读取测试页面子树
|
|
618
|
+
|
|
619
|
+
3. 创建课程根节点和 3 个章节(edit_tree):
|
|
620
|
+
|
|
621
|
+
{prefix} 线性代数 (H1 标题)
|
|
622
|
+
|
|
623
|
+
第一章 向量空间 <!--doc-->
|
|
624
|
+
向量空间 ↔ 满足封闭性和线性组合的集合 <!--type:concept-->
|
|
625
|
+
维度 → 基向量的个数 <!--type:descriptor-->
|
|
626
|
+
基 → 线性无关且能张成空间的向量组 <!--type:descriptor-->
|
|
627
|
+
线性无关 → 不存在非零系数使线性组合为零 <!--type:descriptor-->
|
|
628
|
+
子空间 ↔ 向量空间中满足封闭性的子集 <!--type:concept-->
|
|
629
|
+
零空间 → Ax=0 的解集 <!--type:descriptor-->
|
|
630
|
+
|
|
631
|
+
第二章 线性变换 <!--doc-->
|
|
632
|
+
线性变换 ↔ 保持加法和标量乘法的映射 <!--type:concept-->
|
|
633
|
+
矩阵表示 → 每个线性变换对应一个矩阵 <!--type:descriptor-->
|
|
634
|
+
核 → 映射到零向量的原像集合 <!--type:descriptor-->
|
|
635
|
+
像 → 值域,所有输出的集合 <!--type:descriptor-->
|
|
636
|
+
特征值 ↔ 使 Av=λv 成立的标量 λ <!--type:concept-->
|
|
637
|
+
特征向量 → 对应特征值的非零向量 v <!--type:descriptor-->
|
|
638
|
+
|
|
639
|
+
第三章 内积空间 <!--doc-->
|
|
640
|
+
内积 ↔ 满足正定性/对称性/线性性的二元函数 <!--type:concept-->
|
|
641
|
+
范数 → 由内积诱导的长度 ‖v‖=√⟨v,v⟩ <!--type:descriptor-->
|
|
642
|
+
正交 → 内积为零的两个向量 <!--type:descriptor-->
|
|
643
|
+
正交投影 ↔ 向子空间投影的线性变换 <!--type:concept-->
|
|
644
|
+
最小二乘 → 通过正交投影求近似解 <!--type:descriptor-->
|
|
645
|
+
|
|
646
|
+
4. 设置格式属性(read_rem + edit_rem):
|
|
647
|
+
- 对"向量空间"(概念)和"特征值"(概念)设 highlightColor=Green(简单)
|
|
648
|
+
- 对"线性变换"(概念)设 highlightColor=Yellow(中等)
|
|
649
|
+
- 对"内积"(概念)设 highlightColor=Red(困难)
|
|
650
|
+
- 选一个 descriptor 设 isTodo=true + todoStatus=Unfinished(待复习标记)
|
|
651
|
+
|
|
652
|
+
5. 读取完整子树确认:
|
|
653
|
+
- 3 个章节是 Document(isDocument=true)
|
|
654
|
+
- CDF 结构正确
|
|
655
|
+
- 格式属性生效
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
**Chrome 验证**:
|
|
659
|
+
- ⬜ H1 标题 "{prefix} 线性代数"
|
|
660
|
+
- ⬜ 3 个章节是可独立打开的文档页面
|
|
661
|
+
- ⬜ 概念加粗,描述有正向分隔
|
|
662
|
+
- ⬜ 高亮颜色正确(Green/Yellow/Red)
|
|
663
|
+
- ⬜ 有一个节点带待办复选框
|
|
664
|
+
- ⬜ 总共约 20+ 节点
|
|
665
|
+
|
|
666
|
+
---
|
|
667
|
+
|
|
668
|
+
### L4-03: 大规模创建 + 批量富文本标注 + 读取验证
|
|
669
|
+
|
|
670
|
+
> ⚠️ **不可并行**:此用例创建 35+ 节点 + 多次 edit_rem + 2 次 read_rem_in_tree。必须单独串行执行。
|
|
671
|
+
|
|
672
|
+
**task_description**:
|
|
673
|
+
```
|
|
674
|
+
在测试页面下完成以下任务:
|
|
675
|
+
|
|
676
|
+
阶段 1:创建 30+ 节点知识结构
|
|
677
|
+
|
|
678
|
+
1. 确认连接正常(health 三层就绪)
|
|
679
|
+
2. 读取测试页面子树(read_tree)
|
|
680
|
+
3. 在测试页面下创建以下结构(edit_tree,可分多次):
|
|
681
|
+
|
|
682
|
+
# {prefix} 生物学笔记
|
|
683
|
+
## 细胞生物学
|
|
684
|
+
细胞膜 ↔ 选择性透过的磷脂双分子层 <!--type:concept-->
|
|
685
|
+
功能 → 保护细胞、控制物质进出 <!--type:descriptor-->
|
|
686
|
+
组成 → 磷脂、蛋白质、糖类 <!--type:descriptor-->
|
|
687
|
+
细胞核 ↔ 含遗传物质的细胞控制中心 <!--type:concept-->
|
|
688
|
+
功能 → 储存 DNA、控制基因表达 <!--type:descriptor-->
|
|
689
|
+
结构 → 核膜、核仁、染色质 <!--type:descriptor-->
|
|
690
|
+
线粒体 ↔ 细胞的能量工厂 <!--type:concept-->
|
|
691
|
+
功能 → 有氧呼吸产生 ATP <!--type:descriptor-->
|
|
692
|
+
特点 → 含自身 DNA,双层膜结构 <!--type:descriptor-->
|
|
693
|
+
## 遗传学
|
|
694
|
+
DNA ↔ 脱氧核糖核酸,遗传信息载体 <!--type:concept-->
|
|
695
|
+
结构 → 双螺旋,碱基配对 A-T, G-C <!--type:descriptor-->
|
|
696
|
+
复制 → 半保留复制 <!--type:descriptor-->
|
|
697
|
+
RNA ↔ 核糖核酸,参与蛋白质合成 <!--type:concept-->
|
|
698
|
+
类型 ↓ <!--type:descriptor-->
|
|
699
|
+
mRNA:信使 RNA
|
|
700
|
+
tRNA:转运 RNA
|
|
701
|
+
rRNA:核糖体 RNA
|
|
702
|
+
基因表达 ↔ 从 DNA 到蛋白质的过程 <!--type:concept-->
|
|
703
|
+
转录 → DNA → mRNA <!--type:descriptor-->
|
|
704
|
+
翻译 → mRNA → 蛋白质 <!--type:descriptor-->
|
|
705
|
+
## 生态学
|
|
706
|
+
生态系统 ↔ 生物群落与无机环境的统一体 <!--type:concept-->
|
|
707
|
+
组成 → 生产者、消费者、分解者、无机环境 <!--type:descriptor-->
|
|
708
|
+
能量流动 → 单向流动,逐级递减 <!--type:descriptor-->
|
|
709
|
+
食物链 ↔ 生物之间的营养关系 <!--type:concept-->
|
|
710
|
+
规律 → 能量沿食物链传递效率 10%-20% <!--type:descriptor-->
|
|
711
|
+
碳循环 ↔ 碳元素在生态系统中的循环 <!--type:concept-->
|
|
712
|
+
路径 ↓ <!--type:descriptor-->
|
|
713
|
+
光合作用固定 CO₂
|
|
714
|
+
呼吸作用释放 CO₂
|
|
715
|
+
分解者分解有机物
|
|
716
|
+
|
|
717
|
+
4. 读取子树确认结构完整(约 35+ 节点)
|
|
718
|
+
|
|
719
|
+
阶段 2:批量富文本标注(课本划重点)
|
|
720
|
+
|
|
721
|
+
5. 使用 read_rem_in_tree 读取整棵子树(maxNodes 设为 50),一次获取所有节点的 RemObject
|
|
722
|
+
|
|
723
|
+
6. 从 remObjects 中找到以下节点的 remId,然后逐个 edit_rem 设置格式:
|
|
724
|
+
|
|
725
|
+
a. 行级高亮(整行背景色):
|
|
726
|
+
- "细胞膜" 节点:highlightColor = "Yellow"
|
|
727
|
+
- "DNA" 节点:highlightColor = "Red"
|
|
728
|
+
- "生态系统" 节点:highlightColor = "Green"
|
|
729
|
+
|
|
730
|
+
b. 行内荧光标注(修改 backText 字段中的 RichText):
|
|
731
|
+
- "细胞核"的 "功能" descriptor:把 backText 改为
|
|
732
|
+
[{"h": 3, "i": "m", "text": "储存 DNA"}, "、控制基因表达"]
|
|
733
|
+
- "基因表达"的 "转录" descriptor:把 backText 改为
|
|
734
|
+
["DNA → ", {"b": true, "h": 1, "i": "m", "text": "mRNA"}]
|
|
735
|
+
|
|
736
|
+
c. 粗体 + 下划线组合:
|
|
737
|
+
- "线粒体"的 "功能" descriptor:把 backText 改为
|
|
738
|
+
[{"b": true, "i": "m", "text": "有氧呼吸"}, "产生 ", {"i": "m", "text": "ATP", "u": true}]
|
|
739
|
+
|
|
740
|
+
d. 文字颜色:
|
|
741
|
+
- "食物链"的 "规律" descriptor:把 backText 改为
|
|
742
|
+
["能量沿食物链传递效率 ", {"i": "m", "tc": 1, "text": "10%-20%"}]
|
|
743
|
+
|
|
744
|
+
阶段 3:读取验证
|
|
745
|
+
|
|
746
|
+
7. 再次使用 read_rem_in_tree 读取整棵子树(maxNodes=50)
|
|
747
|
+
8. 从返回的 remObjects 中验证:
|
|
748
|
+
- "细胞膜" 节点的 highlightColor 是否为 "Yellow"
|
|
749
|
+
- "DNA" 节点的 highlightColor 是否为 "Red"
|
|
750
|
+
- "生态系统" 节点的 highlightColor 是否为 "Green"
|
|
751
|
+
- 被修改 backText 的节点,backText 字段是否包含预期的格式化对象(h、b、u、tc 字段)
|
|
752
|
+
|
|
753
|
+
9. 报告所有验证结果
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
**Chrome 验证**:
|
|
757
|
+
- ⬜ 35+ 节点内容正确
|
|
758
|
+
- ⬜ H1 根 → 3 个 H2 章节 → concept → descriptor 层级正确
|
|
759
|
+
- ⬜ concept 加粗,descriptor 正常字重
|
|
760
|
+
- ⬜ 细胞膜黄色、DNA 红色、生态系统绿色整行高亮
|
|
761
|
+
- ⬜ "储存 DNA" 黄色荧光底色
|
|
762
|
+
- ⬜ "mRNA" 粗体+红色荧光
|
|
763
|
+
- ⬜ "有氧呼吸"粗体,"ATP"下划线
|
|
764
|
+
- ⬜ "10%-20%" 红色文字
|
|
765
|
+
|
|
766
|
+
**断言**:
|
|
767
|
+
- [ ] edit_tree 成功创建 35+ 节点结构
|
|
768
|
+
- [ ] read_rem_in_tree 成功返回全部节点的 remObjects(nodeCount ≥ 35)
|
|
769
|
+
- [ ] edit_rem 设置 highlightColor 生效(3 个节点)
|
|
770
|
+
- [ ] edit_rem 修改 RichText 行内高亮(h 字段)生效
|
|
771
|
+
- [ ] edit_rem 修改 RichText 粗体+下划线组合生效
|
|
772
|
+
- [ ] edit_rem 修改 RichText 文字颜色(tc 字段)生效
|
|
773
|
+
- [ ] 最终 read_rem_in_tree 返回的 remObjects 中所有标注与预期一致
|
|
774
|
+
|
|
775
|
+
**工具选择检查**:
|
|
776
|
+
- [ ] 阶段 2 使用 read_rem_in_tree(而非 read_tree + N×read_rem)
|
|
777
|
+
- [ ] edit_rem 前未冗余调用 read_rem
|
|
778
|
+
|
|
779
|
+
---
|
|
780
|
+
|
|
781
|
+
## L5 极端边界 + 错误恢复
|
|
782
|
+
|
|
783
|
+
> 测试防线触发、大树省略、并发检测等边界场景。
|
|
784
|
+
|
|
785
|
+
### L5-01: 防线触发 + 恢复
|
|
786
|
+
|
|
787
|
+
**task_description**:
|
|
788
|
+
```
|
|
789
|
+
故意触发各种防线错误,理解错误信息,然后正确恢复。
|
|
790
|
+
|
|
791
|
+
1. 确认连接正常
|
|
792
|
+
2. 读取测试页面的子树
|
|
793
|
+
3. 创建节点:{prefix} 防线测试
|
|
794
|
+
|
|
795
|
+
独立测试每个场景:
|
|
796
|
+
|
|
797
|
+
场景 A — 未 read 就 edit:
|
|
798
|
+
a1. 对一个已知 remId 直接尝试 edit_rem(不先 read_rem)
|
|
799
|
+
a2. 观察错误信息(应提示"has not been read yet")
|
|
800
|
+
a3. 先 read_rem,然后正确 edit_rem
|
|
801
|
+
a4. 确认修改成功
|
|
802
|
+
|
|
803
|
+
场景 B — 非法枚举值:
|
|
804
|
+
b1. read_rem 某个节点
|
|
805
|
+
b2. 尝试将 type 设为 "invalid"
|
|
806
|
+
b3. 观察错误信息(应提示非法值)
|
|
807
|
+
b4. 用正确值 "concept" 重试
|
|
808
|
+
b5. 确认修改成功
|
|
809
|
+
|
|
810
|
+
场景 C — edit_tree 修改行内容(content_modified 防线):
|
|
811
|
+
c1. read_tree 测试页面
|
|
812
|
+
c2. 尝试通过 edit_tree 修改已有行的文字内容
|
|
813
|
+
c3. 观察错误信息(应提示 content_modified)
|
|
814
|
+
c4. 改用 edit_rem 修改文字
|
|
815
|
+
c5. 确认修改成功
|
|
816
|
+
|
|
817
|
+
报告每个场景的:错误信息全文、恢复操作、最终结果。
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
**验证**:subagent 能理解错误信息并正确恢复。
|
|
821
|
+
|
|
822
|
+
**断言**:
|
|
823
|
+
- [ ] 场景 A:触发"未 read"错误 → read 后成功编辑
|
|
824
|
+
- [ ] 场景 B:触发"非法值"错误 → 正确值重试成功
|
|
825
|
+
- [ ] 场景 C:触发 content_modified → 改用 edit_rem 成功
|
|
826
|
+
|
|
827
|
+
---
|
|
828
|
+
|
|
829
|
+
### L5-02: 大树省略
|
|
830
|
+
|
|
831
|
+
**task_description**:
|
|
832
|
+
```
|
|
833
|
+
测试 read_tree 的 maxSiblings 省略行为。
|
|
834
|
+
|
|
835
|
+
1. 确认连接正常
|
|
836
|
+
2. 读取测试页面子树
|
|
837
|
+
3. 创建父节点:{prefix} 大树测试
|
|
838
|
+
4. 在父节点下创建 25 个子节点(edit_tree,可能需要分多次):
|
|
839
|
+
{prefix} 子节点-01 到 {prefix} 子节点-25
|
|
840
|
+
提示:每次 edit_tree 创建一批,在已有最后一个兄弟之后追加新行
|
|
841
|
+
|
|
842
|
+
5. 用默认参数读取父节点的子树(read_tree)
|
|
843
|
+
确认输出中包含省略占位符(<!--...elided ... siblings-->)
|
|
844
|
+
记录省略了多少个节点
|
|
845
|
+
|
|
846
|
+
6. 用 maxSiblings=30 读取同一棵子树
|
|
847
|
+
确认所有 25 个子节点都完整可见,无省略
|
|
848
|
+
|
|
849
|
+
7. 在子节点末尾新增一个节点(edit_tree):
|
|
850
|
+
{prefix} 子节点-26
|
|
851
|
+
确认操作在省略存在的情况下仍然成功
|
|
852
|
+
|
|
853
|
+
8. 最终用 maxSiblings=30 读取确认 26 个子节点全部存在
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
**Chrome 验证**:
|
|
857
|
+
- ⬜ 父节点下有 26 个子节点(展开确认)
|
|
858
|
+
|
|
859
|
+
---
|
|
860
|
+
|
|
861
|
+
### L5-03: 并发检测(三阶段 subagent)
|
|
862
|
+
|
|
863
|
+
> ⚠️ **不可并行**:三个阶段必须严格串行执行。
|
|
864
|
+
>
|
|
865
|
+
> **执行方式特殊**:此用例拆为 3 个 subagent 串行执行(Phase A → B → C),模拟"外部修改"场景。主 agent 只负责调度,**不直接调用 MCP 工具**。
|
|
866
|
+
|
|
867
|
+
**Phase A — 创建数据并建立缓存(Subagent 1)**:
|
|
868
|
+
```
|
|
869
|
+
1. 确认连接正常(health)
|
|
870
|
+
2. 读取测试页面子树(read_tree)
|
|
871
|
+
3. 创建节点(edit_tree):{prefix} 并发测试目标
|
|
872
|
+
4. 重新读取子树(read_tree),确认节点存在并建立 tree 缓存
|
|
873
|
+
5. 报告新节点的 remId
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
**Phase B — 模拟外部修改(Subagent 2)**:
|
|
877
|
+
```
|
|
878
|
+
1. 确认连接正常(health)
|
|
879
|
+
2. 读取 Phase A 报告的 remId 对应的节点(read_rem)
|
|
880
|
+
3. 修改其文本为 "{prefix} 已被外部修改"(edit_rem,changes: {text: "{prefix} 已被外部修改"})
|
|
881
|
+
4. 确认修改成功
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
> 此操作通过 edit_rem 修改了节点文本,但 daemon 中的 tree 缓存(Phase A 建立的)未被更新——edit_rem 只更新 rem 级别的缓存,不影响 tree 缓存。
|
|
885
|
+
|
|
886
|
+
**Phase C — 验证并发检测(Subagent 3)**:
|
|
887
|
+
```
|
|
888
|
+
1. 确认连接正常(health)
|
|
889
|
+
2. **不要重新 read_tree**——直接用 daemon 中 Phase A 的旧 tree 缓存
|
|
890
|
+
3. 尝试 edit_tree,oldStr 包含原始文本 "{prefix} 并发测试目标"
|
|
891
|
+
→ 预期失败:edit_tree 会重新从 Plugin 读取当前树状态,发现文本已变为
|
|
892
|
+
"{prefix} 已被外部修改",oldStr 在当前大纲中找不到匹配
|
|
893
|
+
→ 应返回 "old_str not found" 错误
|
|
894
|
+
4. 记录错误信息全文
|
|
895
|
+
5. 重新读取子树(read_tree)获取最新缓存
|
|
896
|
+
6. 用正确的当前文本重试 edit_tree(如:在 "{prefix} 已被外部修改" 后新增一个兄弟节点)
|
|
897
|
+
7. 确认操作成功
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
**主 agent 调度流程**:
|
|
901
|
+
|
|
902
|
+
1. 派 Subagent 1 执行 Phase A → 从 transcript 中提取新节点 remId
|
|
903
|
+
2. 派 Subagent 2 执行 Phase B(传入 remId)
|
|
904
|
+
3. 派 Subagent 3 执行 Phase C(传入原始文本和 remId)
|
|
905
|
+
4. 审计三个 transcript → Chrome 验收 → 判定
|
|
906
|
+
|
|
907
|
+
**验证**:Phase C 步骤 3 触发 "old_str not found" 错误(证明 edit_tree 的重读对比机制正确检测到了变更),步骤 6-7 恢复成功。
|
|
908
|
+
|
|
909
|
+
**断言**:
|
|
910
|
+
- [ ] Phase A:成功创建节点并建立 tree 缓存
|
|
911
|
+
- [ ] Phase B:成功通过 edit_rem 修改文本(模拟外部变更)
|
|
912
|
+
- [ ] Phase C-3:edit_tree 返回 "old_str not found" 错误(并发检测生效)
|
|
913
|
+
- [ ] Phase C-6:重新 read_tree 后操作成功(恢复路径正常)
|
|
914
|
+
|
|
915
|
+
---
|
|
916
|
+
|
|
917
|
+
## 工具覆盖检查
|
|
918
|
+
|
|
919
|
+
| 工具/命令 | 出现的用例 |
|
|
920
|
+
|:----------|:-----------|
|
|
921
|
+
| health | L1-01, L1-02(及所有用例第 1 步) |
|
|
922
|
+
| connect / disconnect | L1-01 |
|
|
923
|
+
| read_globe | L1-02 |
|
|
924
|
+
| read_context | L1-02 |
|
|
925
|
+
| search | L1-02, L3-01 |
|
|
926
|
+
| read_tree | L2-01~04, L3-01~03, L4-01~02, L5-01~03 |
|
|
927
|
+
| edit_tree | L2-01~02, L2-04, L3-01~03, L4-01~02, L5-01~03 |
|
|
928
|
+
| read_rem | L2-02~03, L3-01, L4-01~02, L5-01 |
|
|
929
|
+
| edit_rem | L2-03, L3-04, L4-02, L4-03, L5-01 |
|
|
930
|
+
| read_rem_in_tree | L3-04, L4-03 |
|
|
931
|
+
| addon | (独立管理命令,按需手动测) |
|
|
932
|
+
| setup / clean | (破坏性命令,不适合自动化) |
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
## 维护指南
|
|
937
|
+
|
|
938
|
+
### 新增回归用例
|
|
939
|
+
|
|
940
|
+
当新功能稳定后,把它的测试用例加到对应级别里:
|
|
941
|
+
|
|
942
|
+
1. 确定属于哪个级别(基础 → 复杂)
|
|
943
|
+
2. 编写 task_description(参照已有格式)
|
|
944
|
+
3. 列出 Chrome 验证点
|
|
945
|
+
4. 加到对应级别下,编号递增
|
|
946
|
+
|
|
947
|
+
### 退役用例
|
|
948
|
+
|
|
949
|
+
功能被移除时,把对应用例标记为 `[RETIRED]` 并注明原因,而非直接删除。
|
|
950
|
+
|
|
951
|
+
### {prefix} 替换
|
|
952
|
+
|
|
953
|
+
执行时把 `{prefix}` 替换为带接口区分的前缀:
|
|
954
|
+
|
|
955
|
+
| 接口 | 格式 | 示例 |
|
|
956
|
+
|:-----|:-----|:-----|
|
|
957
|
+
| MCP | `[日期-级别编号]` | `[0317-L2-01]` |
|
|
958
|
+
| Skill | `[日期-级别编号s]` | `[0317-L2-01s]` |
|
|
959
|
+
|
|
960
|
+
Skill 接口加 `s` 后缀,避免两个 subagent 在同一页面下创建的数据混淆。
|