remnote-bridge 0.1.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 (135) hide show
  1. package/dist/cli/commands/connect.d.ts +12 -0
  2. package/dist/cli/commands/connect.js +124 -0
  3. package/dist/cli/commands/disconnect.d.ts +11 -0
  4. package/dist/cli/commands/disconnect.js +100 -0
  5. package/dist/cli/commands/edit-rem.d.ts +13 -0
  6. package/dist/cli/commands/edit-rem.js +83 -0
  7. package/dist/cli/commands/edit-tree.d.ts +14 -0
  8. package/dist/cli/commands/edit-tree.js +67 -0
  9. package/dist/cli/commands/health.d.ts +12 -0
  10. package/dist/cli/commands/health.js +100 -0
  11. package/dist/cli/commands/install-skill.d.ts +6 -0
  12. package/dist/cli/commands/install-skill.js +39 -0
  13. package/dist/cli/commands/read-context.d.ts +20 -0
  14. package/dist/cli/commands/read-context.js +77 -0
  15. package/dist/cli/commands/read-globe.d.ts +16 -0
  16. package/dist/cli/commands/read-globe.js +60 -0
  17. package/dist/cli/commands/read-rem.d.ts +16 -0
  18. package/dist/cli/commands/read-rem.js +80 -0
  19. package/dist/cli/commands/read-tree.d.ts +17 -0
  20. package/dist/cli/commands/read-tree.js +85 -0
  21. package/dist/cli/commands/search.d.ts +12 -0
  22. package/dist/cli/commands/search.js +65 -0
  23. package/dist/cli/config.d.ts +55 -0
  24. package/dist/cli/config.js +139 -0
  25. package/dist/cli/daemon/daemon.d.ts +11 -0
  26. package/dist/cli/daemon/daemon.js +186 -0
  27. package/dist/cli/daemon/dev-server.d.ts +26 -0
  28. package/dist/cli/daemon/dev-server.js +81 -0
  29. package/dist/cli/daemon/pid.d.ts +34 -0
  30. package/dist/cli/daemon/pid.js +67 -0
  31. package/dist/cli/daemon/send-request.d.ts +24 -0
  32. package/dist/cli/daemon/send-request.js +92 -0
  33. package/dist/cli/handlers/context-read-handler.d.ts +18 -0
  34. package/dist/cli/handlers/context-read-handler.js +24 -0
  35. package/dist/cli/handlers/edit-handler.d.ts +30 -0
  36. package/dist/cli/handlers/edit-handler.js +133 -0
  37. package/dist/cli/handlers/globe-read-handler.d.ts +17 -0
  38. package/dist/cli/handlers/globe-read-handler.js +23 -0
  39. package/dist/cli/handlers/read-handler.d.ts +16 -0
  40. package/dist/cli/handlers/read-handler.js +78 -0
  41. package/dist/cli/handlers/rem-cache.d.ts +19 -0
  42. package/dist/cli/handlers/rem-cache.js +63 -0
  43. package/dist/cli/handlers/tree-edit-handler.d.ts +30 -0
  44. package/dist/cli/handlers/tree-edit-handler.js +188 -0
  45. package/dist/cli/handlers/tree-parser.d.ts +95 -0
  46. package/dist/cli/handlers/tree-parser.js +506 -0
  47. package/dist/cli/handlers/tree-read-handler.d.ts +28 -0
  48. package/dist/cli/handlers/tree-read-handler.js +53 -0
  49. package/dist/cli/main.d.ts +7 -0
  50. package/dist/cli/main.js +300 -0
  51. package/dist/cli/protocol.d.ts +39 -0
  52. package/dist/cli/protocol.js +35 -0
  53. package/dist/cli/server/config-server.d.ts +26 -0
  54. package/dist/cli/server/config-server.js +363 -0
  55. package/dist/cli/server/ws-server.d.ts +68 -0
  56. package/dist/cli/server/ws-server.js +335 -0
  57. package/dist/cli/utils/output.d.ts +11 -0
  58. package/dist/cli/utils/output.js +13 -0
  59. package/dist/mcp/daemon-client.d.ts +31 -0
  60. package/dist/mcp/daemon-client.js +99 -0
  61. package/dist/mcp/index.d.ts +7 -0
  62. package/dist/mcp/index.js +68 -0
  63. package/dist/mcp/instructions.d.ts +1 -0
  64. package/dist/mcp/instructions.js +249 -0
  65. package/dist/mcp/resources/edit-tree-guide.d.ts +1 -0
  66. package/dist/mcp/resources/edit-tree-guide.js +197 -0
  67. package/dist/mcp/resources/error-reference.d.ts +1 -0
  68. package/dist/mcp/resources/error-reference.js +132 -0
  69. package/dist/mcp/resources/outline-format.d.ts +1 -0
  70. package/dist/mcp/resources/outline-format.js +104 -0
  71. package/dist/mcp/resources/rem-object-fields.d.ts +1 -0
  72. package/dist/mcp/resources/rem-object-fields.js +331 -0
  73. package/dist/mcp/resources/separator-flashcard.d.ts +1 -0
  74. package/dist/mcp/resources/separator-flashcard.js +120 -0
  75. package/dist/mcp/tools/edit-tools.d.ts +5 -0
  76. package/dist/mcp/tools/edit-tools.js +47 -0
  77. package/dist/mcp/tools/infra-tools.d.ts +5 -0
  78. package/dist/mcp/tools/infra-tools.js +43 -0
  79. package/dist/mcp/tools/read-tools.d.ts +5 -0
  80. package/dist/mcp/tools/read-tools.js +195 -0
  81. package/dist/mcp/types.d.ts +12 -0
  82. package/dist/mcp/types.js +4 -0
  83. package/docs/instruction/connect.md +158 -0
  84. package/docs/instruction/disconnect.md +146 -0
  85. package/docs/instruction/edit-rem.md +509 -0
  86. package/docs/instruction/edit-tree.md +419 -0
  87. package/docs/instruction/health.md +159 -0
  88. package/docs/instruction/overall.md +751 -0
  89. package/docs/instruction/read-context.md +353 -0
  90. package/docs/instruction/read-globe.md +206 -0
  91. package/docs/instruction/read-rem.md +476 -0
  92. package/docs/instruction/read-tree.md +428 -0
  93. package/docs/instruction/search.md +196 -0
  94. package/package.json +41 -0
  95. package/remnote-plugin/package.json +48 -0
  96. package/remnote-plugin/postcss.config.js +5 -0
  97. package/remnote-plugin/public/bridge-icon.svg +8 -0
  98. package/remnote-plugin/public/manifest.json +22 -0
  99. package/remnote-plugin/src/bridge/message-router.ts +57 -0
  100. package/remnote-plugin/src/bridge/websocket-client.ts +245 -0
  101. package/remnote-plugin/src/index.css +1 -0
  102. package/remnote-plugin/src/services/breadcrumb.ts +26 -0
  103. package/remnote-plugin/src/services/create-rem.ts +59 -0
  104. package/remnote-plugin/src/services/delete-rem.ts +29 -0
  105. package/remnote-plugin/src/services/index.ts +16 -0
  106. package/remnote-plugin/src/services/move-rem.ts +39 -0
  107. package/remnote-plugin/src/services/powerup-filter.ts +31 -0
  108. package/remnote-plugin/src/services/read-context.ts +368 -0
  109. package/remnote-plugin/src/services/read-globe.ts +197 -0
  110. package/remnote-plugin/src/services/read-rem.ts +284 -0
  111. package/remnote-plugin/src/services/read-tree.ts +222 -0
  112. package/remnote-plugin/src/services/rem-builder.ts +124 -0
  113. package/remnote-plugin/src/services/reorder-children.ts +61 -0
  114. package/remnote-plugin/src/services/search.ts +56 -0
  115. package/remnote-plugin/src/services/write-rem-fields.ts +254 -0
  116. package/remnote-plugin/src/settings.ts +12 -0
  117. package/remnote-plugin/src/style.css +45 -0
  118. package/remnote-plugin/src/test-scripts/AGENTS.md +46 -0
  119. package/remnote-plugin/src/test-scripts/test-actions.ts +230 -0
  120. package/remnote-plugin/src/test-scripts/test-powerup-rendering.ts +722 -0
  121. package/remnote-plugin/src/test-scripts/test-rem-type-mapping.ts +283 -0
  122. package/remnote-plugin/src/test-scripts/test-richtext-builder.ts +207 -0
  123. package/remnote-plugin/src/test-scripts/test-richtext-matrix.ts +332 -0
  124. package/remnote-plugin/src/test-scripts/test-richtext-remaining.ts +245 -0
  125. package/remnote-plugin/src/test-scripts/test-rw-fields.ts +399 -0
  126. package/remnote-plugin/src/types.ts +419 -0
  127. package/remnote-plugin/src/utils/elision.ts +45 -0
  128. package/remnote-plugin/src/utils/index.ts +10 -0
  129. package/remnote-plugin/src/utils/tree-serializer.ts +269 -0
  130. package/remnote-plugin/src/widgets/bridge_widget.tsx +170 -0
  131. package/remnote-plugin/src/widgets/index.tsx +82 -0
  132. package/remnote-plugin/tailwind.config.js +7 -0
  133. package/remnote-plugin/tsconfig.json +21 -0
  134. package/remnote-plugin/webpack.config.js +125 -0
  135. package/skill/SKILL.md +428 -0
@@ -0,0 +1,249 @@
1
+ export const SERVER_INSTRUCTIONS = `
2
+ # RemNote Bridge MCP Server — Agent 操作手册
3
+
4
+ RemNote 知识库操作工具集。你可以通过这些工具读取、搜索、编辑用户的 RemNote 笔记和知识结构。不能操控闪卡(Card/Flashcard)本身——闪卡由 RemNote 根据 Rem 属性自动生成;也不能管理 Plugin 或系统配置。
5
+
6
+ ---
7
+
8
+ ## 1. Core Concepts
9
+
10
+ ### Everything is Rem
11
+
12
+ 用户说的"笔记"、"文档"、"文件夹"、"闪卡",底层都是 **Rem**。不同形态通过属性区分:
13
+
14
+ | 用户说的 | 实际上是 | 区分方式 |
15
+ |:---------|:---------|:---------|
16
+ | 笔记 / 条目 | Rem | 最基本的数据单元 |
17
+ | 文档 / 页面 | Rem(\\\`isDocument=true\\\`) | 可独立打开的页面 |
18
+ | 文件夹 | Rem(Document + 子节点全是 Document) | UI 概念,无独立标记 |
19
+ | 闪卡 | Card——由 Rem 属性自动生成 | **不可直接操控** |
20
+
21
+ ### Type 系统
22
+
23
+ Rem 有两个独立维度:**type**(闪卡语义)和 **isDocument**(页面语义),二者互不影响。
24
+
25
+ | type | 含义 | UI 表现 |
26
+ |:-----|:-----|:--------|
27
+ | \\\`concept\\\` | 概念定义 | 文字**加粗** |
28
+ | \\\`descriptor\\\` | 描述/属性 | 文字*斜体* |
29
+ | \\\`default\\\` | 普通 Rem | 正常字重 |
30
+ | \\\`portal\\\` | 嵌入引用容器 | 紫色边框(**只读**,不可设置) |
31
+
32
+ ### Separator 与闪卡创建
33
+
34
+ 分隔符决定 Rem 的 type、backText 和练习方向。创建闪卡的本质是设置正确的分隔符:
35
+
36
+ | 分隔符 | type | 用途 |
37
+ |:-------|:-----|:-----|
38
+ | \\\`::\\\` | concept | 概念定义(双向) |
39
+ | \\\`;;\\\` | descriptor | 描述属性(正向) |
40
+ | \\\`>>\\\` | default | 正向问答 |
41
+ | \\\`<<\\\` | default | 反向问答 |
42
+ | \\\`<>\\\` | default | 双向问答 |
43
+ | \\\`>>>\\\` | default | 多行答案(子 Rem 为答案) |
44
+ | \\\`{{}}\\\` | default | 完形填空 |
45
+
46
+ 完整分隔符-闪卡映射表见 \\\`resource://separator-flashcard\\\`。
47
+
48
+ ### 链接机制
49
+
50
+ | 机制 | 用户操作 | 说明 |
51
+ |:-----|:---------|:-----|
52
+ | Reference \\\`[[\\\` | 文本内引用 | 只是指针,不同步编辑 |
53
+ | Tag \\\`##\\\` | 附加标签 | 分类标记 |
54
+ | Portal \\\`((\\\` | 嵌入实时视图 | 编辑同步,大纲中标为 \\\`type:portal\\\` |
55
+
56
+ ### Powerup 过滤
57
+
58
+ RemNote 的格式设置(标题、高亮、代码等)会注入隐藏的系统 Tag 和子 Rem。这些噪音数据**默认自动过滤**,你通常无需关心。
59
+
60
+ ---
61
+
62
+ ## 2. Session Lifecycle
63
+
64
+ 所有操作都依赖一个活跃的会话。会话 = 守护进程的生命周期。
65
+
66
+ \\\`\\\`\\\`
67
+ connect → 启动 daemon(幂等,重复调用安全)
68
+
69
+ health → 确认三层就绪(daemon / Plugin / SDK)
70
+
71
+ 业务操作(read / search / edit)
72
+
73
+ disconnect → 关闭 daemon,清空所有缓存
74
+ \\\`\\\`\\\`
75
+
76
+ **关键要点**:
77
+ - \\\`connect\\\` 是所有业务操作的前提,未 connect 时任何命令都会报"守护进程未运行"
78
+ - \\\`health\\\` 检查三层状态:daemon 运行 → Plugin 已连接 → SDK 就绪,三者全部通过才能执行业务命令
79
+ - \\\`disconnect\\\` 会销毁所有缓存,之前的 read 结果全部失效
80
+ - daemon 默认 30 分钟无活动自动关闭
81
+
82
+ ---
83
+
84
+ ## 3. Common Scenarios
85
+
86
+ ### 场景 A:探索知识库
87
+
88
+ > 用户说:"帮我看看知识库里有什么"、"有哪些文档"
89
+
90
+ 使用 \\\`read_globe\\\`。它返回知识库中所有 Document 的层级结构鸟瞰图,非 Document 内容不展开。这是了解知识库整体组织的起点。拿到感兴趣的 remId 后,可以用 \\\`read_tree\\\` 深入。
91
+
92
+ ### 场景 B:搜索并深入
93
+
94
+ > 用户说:"搜一下关于 X 的笔记"、"找找 X 在哪里"
95
+
96
+ 先用 \\\`search\\\` 搜索关键词,获得匹配的 Rem 列表(含 remId)。然后根据需要:
97
+ - 用 \\\`read_rem\\\` 查看某条结果的详细属性
98
+ - 用 \\\`read_tree\\\` 展开某条结果的子树结构
99
+
100
+ **注意**:中文等无空格语言搜索效果较差。如果完整词搜索无结果,尝试用单个最具区分度的字搜索;如果仍然无果,改用 \\\`read_globe\\\` → \\\`read_tree\\\` 手动定位。
101
+
102
+ ### 场景 C:了解当前上下文
103
+
104
+ > 用户说:"我现在在看什么"、"当前页面是什么"
105
+
106
+ 使用 \\\`read_context\\\`:
107
+ - **focus 模式**(默认):以用户当前光标所在的 Rem 为中心,构建鱼眼视图——焦点处完全展开,周围递减。焦点行以 \\\`* \\\` 前缀标记。需要用户在 RemNote 中已点击某个 Rem。
108
+ - **page 模式**:以当前打开的页面为根,均匀展开子树。
109
+
110
+ 两种模式都会返回面包屑路径,帮助你理解当前位置在知识库中的层级。
111
+
112
+ ### 场景 D:修改文本或属性
113
+
114
+ > 用户说:"把这个标题改成..."、"把类型改成概念"、"加个高亮"
115
+
116
+ 工作流程:**必须先 read 再 edit**。
117
+
118
+ 1. \\\`read_rem\\\` 获取目标 Rem 的 JSON 属性(建立缓存)
119
+ 2. 在返回的 JSON 文本中定位要修改的部分
120
+ 3. \\\`edit_rem\\\` 用 str_replace 替换:oldStr 精确匹配原文,newStr 是修改后的文本
121
+
122
+ str_replace 操作的是格式化 JSON 文本(2 空格缩进)。oldStr 要包含足够上下文(如字段名 + 值),避免模糊匹配。替换后必须是合法 JSON。
123
+
124
+ ### 场景 E:修改结构(新增/删除/移动/重排)
125
+
126
+ > 用户说:"在这下面加几个子项"、"删掉这个"、"把这个移到那下面"
127
+
128
+ 工作流程:**必须先 read_tree 再 edit_tree**。
129
+
130
+ 1. \\\`read_tree\\\` 获取目标区域的 Markdown 大纲(建立缓存)
131
+ 2. 在大纲中用 str_replace 进行结构修改:
132
+ - **新增**:插入无 remId 注释的新行(通过缩进确定父子关系)
133
+ - **删除**:移除带 remId 的行(必须同时删除所有子行)
134
+ - **移动**:改变行的缩进级别或位置
135
+ - **重排**:调换同级行的顺序
136
+
137
+ **红线**:edit_tree **禁止修改已有行的文字内容**——改内容必须用 edit_rem。edit_tree 只做结构操作。
138
+
139
+ ### 场景 F:创建闪卡
140
+
141
+ > 用户说:"创建一个概念定义"、"做个正向问答卡"
142
+
143
+ 创建闪卡的本质是创建带正确分隔符的 Rem。通过 \\\`edit_tree\\\` 新增行时使用箭头分隔符:
144
+
145
+ - 概念定义:\\\`新概念 → 定义内容\\\`(然后用 edit_rem 将 type 改为 concept)
146
+ - 正向问答:\\\`问题 → 答案\\\`
147
+ - 多行答案:\\\`问题 ↓\\\`(子行自动成为答案)
148
+ - 双向问答:\\\`问题 ↔ 答案\\\`
149
+
150
+ 如果要修改现有 Rem 的闪卡行为(改分隔符类型),使用 \\\`read_rem\\\` → \\\`edit_rem\\\` 修改 type、backText、practiceDirection 等字段。
151
+
152
+ ### 场景 G:排查连接问题
153
+
154
+ > 用户说:"连不上"、"命令报错了"
155
+
156
+ 使用 \\\`health\\\` 检查三层状态,然后对症处理:
157
+ - daemon 未运行 → 执行 \\\`connect\\\`
158
+ - Plugin 未连接 → 提醒用户打开 RemNote 并确认插件已加载
159
+ - SDK 未就绪 → 等待几秒后重试 health
160
+
161
+ ---
162
+
163
+ ## 4. Safety Rules
164
+
165
+ ### 黄金法则:先 read 再 edit
166
+
167
+ - \\\`edit_rem\\\` 前必须先 \\\`read_rem\\\` 同一个 remId
168
+ - \\\`edit_tree\\\` 前必须先 \\\`read_tree\\\` 同一个 remId
169
+
170
+ 跳过 read 直接 edit 会被拒绝。这不是建议,是硬性要求。
171
+
172
+ ### 三道防线
173
+
174
+ 每次 edit 操作都经过三重安全检查:
175
+ 1. **缓存存在**:必须有对应的 read 缓存
176
+ 2. **并发检测**:edit 时重新读取最新数据,与缓存比较。如果 Rem 在 read 之后被外部修改,拒绝编辑——你必须重新 read
177
+ 3. **精确匹配**:oldStr 必须在目标文本中恰好匹配 1 次
178
+
179
+ ### edit_tree 禁止事项
180
+
181
+ - 禁止修改已有行的文字内容(改内容用 edit_rem)
182
+ - 禁止删除根节点
183
+ - 禁止删除有隐藏子节点的行(先用更大 depth 重新 read_tree)
184
+ - 禁止删除父行但保留子行(必须一起删)
185
+ - 禁止修改或删除省略占位符(先用更大参数重新 read_tree 展开)
186
+
187
+ 详细规则见各工具的 description。
188
+
189
+ ---
190
+
191
+ ## 5. Output Format Quick Reference
192
+
193
+ \\\`read_tree\\\`、\\\`read_globe\\\`、\\\`read_context\\\` 返回 Markdown 大纲格式。
194
+
195
+ ### 行结构
196
+
197
+ \\\`\\\`\\\`
198
+ {缩进}{Markdown 前缀}{内容}{箭头}{backText} <!-- {remId} {标记} -->
199
+ \\\`\\\`\\\`
200
+
201
+ - 缩进:每级 2 空格
202
+ - Markdown 前缀:\\\`# \\\`(H1)、\\\`## \\\`(H2)、\\\`### \\\`(H3)、\\\`- [ ] \\\`(待办)、\\\`- [x] \\\`(已完成)、\\\`\\\\\\\`\\\`(代码)
203
+
204
+ ### 关键元数据标记
205
+
206
+ | 标记 | 含义 |
207
+ |:-----|:-----|
208
+ | \\\`type:concept\\\` / \\\`type:descriptor\\\` / \\\`type:portal\\\` | Rem 类型(default 不标记) |
209
+ | \\\`doc\\\` | 是文档页面 |
210
+ | \\\`children:N\\\` | 有 N 个未展开的子节点 |
211
+ | \\\`tag:Name(id)\\\` | 已附加的标签 |
212
+ | \\\`role:card-item\\\` | 多行闪卡的答案行 |
213
+ | \\\`top\\\` | 知识库顶层 Rem |
214
+
215
+ ### 箭头含义
216
+
217
+ - **单行箭头** \\\`→\\\` \\\`←\\\` \\\`↔\\\`:text 与 backText 之间的分隔,方向为 practiceDirection
218
+ - **多行箭头** \\\`↓\\\` \\\`↑\\\` \\\`↕\\\`:表示子节点为答案的多行闪卡
219
+
220
+ ### 省略占位符
221
+
222
+ \\\`\\\`\\\`
223
+ <!--...elided 3 siblings (parent:remIdB range:2-4 total:5)-->
224
+ <!--...elided >=10 nodes (parent:remIdB range:5-14 total:20)-->
225
+ \\\`\\\`\\\`
226
+
227
+ \\\`siblings\\\` 为精确省略(超 maxSiblings),\\\`>=N nodes\\\` 为预算耗尽的非精确省略。
228
+
229
+ 详细格式规范见 \\\`resource://outline-format\\\`。
230
+
231
+ ---
232
+
233
+ ## 6. Error Quick Reference
234
+
235
+ | 错误信息 | 原因 | 恢复操作 |
236
+ |:---------|:-----|:---------|
237
+ | 守护进程未运行 | 未 connect 或 daemon 已超时 | 执行 \\\`connect\\\` |
238
+ | Plugin 未连接 | RemNote 未打开或插件未加载 | 提醒用户打开 RemNote |
239
+ | has not been read yet | 未先执行 read | 先 read 同一个 remId,再重试 edit |
240
+ | has been modified since last read | Rem 在 read 后被外部修改 | 重新 read 获取最新状态,再重试 |
241
+ | old_str not found | oldStr 在文本中不存在 | 检查是否精确匹配(含引号、空格、换行) |
242
+ | old_str matches N locations | oldStr 匹配多处 | 扩大 oldStr 范围,包含更多上下文以唯一定位 |
243
+ | invalid JSON | edit_rem 替换后不是合法 JSON | 检查 newStr 的引号、逗号、括号 |
244
+ | Content modification not allowed | edit_tree 中修改了行内容 | 改用 \\\`edit_rem\\\` 修改内容 |
245
+ | orphan_detected | 删了父行但保留了子行 | 同时删除所有子行 |
246
+ | folded_delete | 删除有隐藏子节点的行 | 用更大 depth 重新 read_tree |
247
+
248
+ 完整错误参考见 \\\`resource://error-reference\\\`。
249
+ `;
@@ -0,0 +1 @@
1
+ export declare const EDIT_TREE_GUIDE_CONTENT = "\n# edit-tree \u64CD\u4F5C\u6307\u5357\n\nedit_tree \u901A\u8FC7 str_replace \u5BF9 Markdown \u5927\u7EB2\u8FDB\u884C\u7ED3\u6784\u7F16\u8F91\uFF08\u884C\u7EA7\u589E/\u5220/\u79FB/\u91CD\u6392\uFF09\uFF0C\u7981\u6B62\u4FEE\u6539\u5DF2\u6709\u884C\u5185\u5BB9\u3002\n\n---\n\n## \u524D\u7F6E\u6761\u4EF6\n\n\u5FC5\u987B\u5148 \\`read_tree\\` \u540C\u4E00\u4E2A remId\uFF0C\u5EFA\u7ACB\u7F13\u5B58\u540E\u624D\u80FD \\`edit_tree\\`\u3002\u8DF3\u8FC7\u4F1A\u89E6\u53D1\u9632\u7EBF 1 \u9519\u8BEF\u3002\n\n---\n\n## \u652F\u6301\u7684\u64CD\u4F5C\n\n### 1. \u65B0\u589E\u884C\n\n\u5728 newStr \u4E2D\u6DFB\u52A0**\u65E0 remId \u6CE8\u91CA**\u7684\u65B0\u884C\u3002\u901A\u8FC7\u7F29\u8FDB\u786E\u5B9A\u7236\u5B50\u5173\u7CFB\u3002\n\n\\`\\`\\`\noldStr:\n \u5B50\u8282\u70B9 A <!--idA-->\n\nnewStr:\n \u65B0\u589E\u8282\u70B9\n \u5B50\u8282\u70B9 A <!--idA-->\n\\`\\`\\`\n\n#### \u65B0\u589E\u884C\u7684 Markdown \u524D\u7F00\n\n| \u524D\u7F00 | \u6548\u679C |\n|------|------|\n| \\`# text\\` | \u521B\u5EFA H1 \u6807\u9898 |\n| \\`## text\\` | \u521B\u5EFA H2 \u6807\u9898 |\n| \\`### text\\` | \u521B\u5EFA H3 \u6807\u9898 |\n| \\`- [ ] text\\` | \u521B\u5EFA\u672A\u5B8C\u6210\u5F85\u529E |\n| \\`- [x] text\\` | \u521B\u5EFA\u5DF2\u5B8C\u6210\u5F85\u529E |\n| \\`\\\\\\`text\\\\\\`\\` | \u521B\u5EFA\u4EE3\u7801\u5757 |\n| \\`---\\` | \u521B\u5EFA\u5206\u9694\u7EBF |\n\n#### \u65B0\u589E\u884C\u7684\u7BAD\u5934\u5206\u9694\u7B26\n\n| \u7BAD\u5934 | \u683C\u5F0F | \u6548\u679C |\n|------|------|------|\n| \\` \u2192 \\` | \\`\u95EE\u9898 \u2192 \u7B54\u6848\\` | \u521B\u5EFA forward \u95EA\u5361\uFF08\u5355\u884C\uFF09 |\n| \\` \u2190 \\` | \\`\u95EE\u9898 \u2190 \u7B54\u6848\\` | \u521B\u5EFA backward \u95EA\u5361\uFF08\u5355\u884C\uFF09 |\n| \\` \u2194 \\` | \\`\u95EE\u9898 \u2194 \u7B54\u6848\\` | \u521B\u5EFA both \u95EA\u5361\uFF08\u5355\u884C\uFF09 |\n| \\` \u2193\\` | \\`\u95EE\u9898 \u2193\\` | \u521B\u5EFA forward \u591A\u884C\u95EA\u5361\uFF08\u5B50\u8282\u70B9\u4E3A\u7B54\u6848\uFF09 |\n| \\` \u2191\\` | \\`\u95EE\u9898 \u2191\\` | \u521B\u5EFA backward \u591A\u884C\u95EA\u5361 |\n| \\` \u2195\\` | \\`\u95EE\u9898 \u2195\\` | \u521B\u5EFA both \u591A\u884C\u95EA\u5361 |\n\n#### \u5D4C\u5957\u65B0\u589E\n\n\u65B0\u589E\u884C\u4E0B\u9762\u53EF\u4EE5\u518D\u5D4C\u5957\u65B0\u589E\u884C\uFF0C\u901A\u8FC7\u7F29\u8FDB\u8868\u793A\u7236\u5B50\u5173\u7CFB\uFF1A\n\n\\`\\`\\`\nnewStr:\n \u7236\u8282\u70B9 \u2193\n \u7B54\u6848\u884C 1\n \u7B54\u6848\u884C 2\n \u5B50\u8282\u70B9 A <!--idA-->\n\\`\\`\\`\n\n\u5D4C\u5957\u65B0\u589E\u884C\u7684\u7236 ID \u901A\u8FC7\u5185\u90E8\u5360\u4F4D\u6807\u8BB0\u7BA1\u7406\uFF0C\u521B\u5EFA\u987A\u5E8F\u4FDD\u8BC1\u4ECE\u6D45\u5230\u6DF1\u3002\n\n### 2. \u5220\u9664\u884C\n\n\u4ECE newStr \u4E2D\u79FB\u9664\u5E26 remId \u7684\u884C\u3002**\u5FC5\u987B\u540C\u65F6\u5220\u9664\u8BE5\u884C\u7684\u6240\u6709\u53EF\u89C1\u5B50\u884C**\uFF0C\u5426\u5219\u62A5 orphan_detected \u9519\u8BEF\u3002\n\n\\`\\`\\`\noldStr:\n \u5B50\u8282\u70B9 A <!--idA-->\n \u5B59\u8282\u70B9 A1 <!--idA1-->\n \u5B50\u8282\u70B9 B <!--idB-->\n\nnewStr:\n \u5B50\u8282\u70B9 B <!--idB-->\n\\`\\`\\`\n\n\u5220\u9664\u64CD\u4F5C\u6309\u6DF1\u5EA6**\u4ECE\u6DF1\u5230\u6D45**\u6267\u884C\uFF08\u5148\u5220\u5B50\u540E\u5220\u7236\uFF09\u3002\n\n### 3. \u79FB\u52A8\u884C\n\n\u6539\u53D8\u884C\u7684\u7F29\u8FDB\u7EA7\u522B\u6216\u4F4D\u7F6E\uFF0C\u4F7F\u5176\u79FB\u52A8\u5230\u65B0\u7684\u7236\u8282\u70B9\u4E0B\uFF1A\n\n\\`\\`\\`\noldStr:\n \u5B50\u8282\u70B9 A <!--idA-->\n \u76EE\u6807\u884C <!--idT-->\n \u5B50\u8282\u70B9 B <!--idB-->\n\nnewStr:\n \u5B50\u8282\u70B9 A <!--idA-->\n \u5B50\u8282\u70B9 B <!--idB-->\n \u76EE\u6807\u884C <!--idT-->\n\\`\\`\\`\n\n### 4. \u91CD\u6392\u884C\n\n\u8C03\u6362\u540C\u7EA7\u884C\u7684\u987A\u5E8F\uFF1A\n\n\\`\\`\\`\noldStr:\n \u5B50\u8282\u70B9 A <!--idA-->\n \u5B50\u8282\u70B9 B <!--idB-->\n \u5B50\u8282\u70B9 C <!--idC-->\n\nnewStr:\n \u5B50\u8282\u70B9 C <!--idC-->\n \u5B50\u8282\u70B9 A <!--idA-->\n \u5B50\u8282\u70B9 B <!--idB-->\n\\`\\`\\`\n\n---\n\n## \u7981\u6B62\u7684\u64CD\u4F5C\n\n| \u64CD\u4F5C | \u9519\u8BEF\u7C7B\u578B | \u9519\u8BEF\u4FE1\u606F | \u66FF\u4EE3\u65B9\u6848 |\n|------|----------|----------|----------|\n| \u4FEE\u6539\u5DF2\u6709\u884C\u5185\u5BB9 | \\`content_modified\\` | Content modification of existing Rem is not allowed in tree edit mode. | \u4F7F\u7528 \\`edit_rem\\` |\n| \u5220\u9664/\u4FEE\u6539\u6839\u8282\u70B9 | \\`root_modified\\` | Root node cannot be changed, deleted or moved. | \u2014 |\n| \u5220\u9664\u6709\u9690\u85CF\u5B50\u8282\u70B9\u7684\u884C | \\`folded_delete\\` | Cannot delete {id} because it has {N} hidden children. | \u7528\u66F4\u5927\u7684 depth \u91CD\u65B0 read_tree |\n| \u5220\u9664\u884C\u4F46\u4FDD\u7559\u5B50\u8282\u70B9 | \\`orphan_detected\\` | Cannot delete {id} because it has children that were not removed. | \u540C\u65F6\u5220\u9664\u6240\u6709\u5B50\u884C |\n| \u5220\u9664/\u4FEE\u6539\u7701\u7565\u5360\u4F4D\u7B26 | \\`elided_modified\\` | Cannot delete or modify elided region directly. | \u7528\u66F4\u5927\u7684 depth/maxSiblings \u91CD\u65B0 read_tree \u5C55\u5F00 |\n| \u7F29\u8FDB\u8DF3\u7EA7 | \\`indent_skip\\` | \u7F29\u8FDB\u8DF3\u7EA7\uFF1A\u884C ... \u7684\u7F29\u8FDB\u7EA7\u522B\u4E3A N\uFF0C\u4F46\u627E\u4E0D\u5230\u4E0A\u4E00\u7EA7\u7684\u7236\u8282\u70B9\u3002 | \u68C0\u67E5\u7F29\u8FDB\u662F\u5426\u6B63\u786E\uFF08\u6BCF\u7EA7 2 \u7A7A\u683C\uFF09 |\n\n---\n\n## \u64CD\u4F5C\u6267\u884C\u987A\u5E8F\n\ndiff \u7B97\u6CD5\u751F\u6210\u7684\u64CD\u4F5C\u6309\u4EE5\u4E0B\u987A\u5E8F\u6392\u5217\u5E76\u6267\u884C\uFF1A\n\n\\`\\`\\`\n1. Create\uFF08\u65B0\u589E\uFF09 \u2014 \u6309\u51FA\u73B0\u987A\u5E8F\uFF0C\u4ECE\u6D45\u5230\u6DF1\n2. Move\uFF08\u79FB\u52A8\uFF09 \u2014 \u7236\u8282\u70B9\u53D8\u66F4\u7684\u884C\n3. Reorder\uFF08\u91CD\u6392\uFF09 \u2014 \u540C\u7236\u8282\u70B9\u5185\u987A\u5E8F\u53D8\u66F4\n4. Delete\uFF08\u5220\u9664\uFF09 \u2014 \u6309\u6DF1\u5EA6\u4ECE\u6DF1\u5230\u6D45\n\\`\\`\\`\n\n---\n\n## practiceDirection \u4FDD\u62A4\u673A\u5236\n\nRemNote SDK \u5B58\u5728\u5DF2\u77E5 bug\uFF1A\\`setIsCardItem(true)\\` \u4F1A\u5077\u5077\u8BBE\u7F6E \\`practiceDirection: \"forward\"\\`\uFF0C\u800C \\`setIsCardItem(false)\\` \u4E0D\u4F1A\u6E05\u9664\u3002\n\n**\u65B0\u589E\u884C\uFF08create\uFF09**\uFF1A\u5F53\u7236\u8282\u70B9\u662F\u591A\u884C\u95EA\u5361\uFF08\u542B \u2193\u2191\u2195 \u7BAD\u5934\uFF09\u65F6\uFF0C\u65B0\u521B\u5EFA\u7684\u5B50\u884C\u9700\u8981 \\`isCardItem: true\\`\u3002\u8BBE\u7F6E\u540E\u7ACB\u5373\u7528 \\`practiceDirection: 'none'\\` \u8986\u76D6 SDK \u526F\u4F5C\u7528\u3002\n\n**\u79FB\u52A8\u884C\uFF08move\uFF09**\uFF1A\n- \u79FB\u5165\u591A\u884C\u7236\u8282\u70B9\uFF1A\u8BBE \\`isCardItem: true\\` + \\`practiceDirection: 'none'\\`\n- \u79FB\u51FA\u591A\u884C\u7236\u8282\u70B9\uFF1A\u8BBE \\`isCardItem: false\\` + \\`practiceDirection: 'none'\\`\n- \u4F8B\u5916\uFF1A\u5982\u679C Rem \u81EA\u8EAB\u6709\u5408\u6CD5\u7684 practiceDirection\uFF08\u7BAD\u5934\u5206\u9694\u7B26\uFF09\uFF0C\u4FDD\u7559\u4E0D\u8986\u76D6\n\n---\n\n## \u793A\u4F8B 1\uFF1A\u5728\u6307\u5B9A\u4F4D\u7F6E\u63D2\u5165\u65B0\u884C\n\n\\`\\`\\`\noldStr:\n \u5B50\u8282\u70B9 A <!--idA-->\n\nnewStr:\n \u65B0\u589E\u884C\n \u5B50\u8282\u70B9 A <!--idA-->\n\\`\\`\\`\n\n\u7ED3\u679C\uFF1A\u5728\u5B50\u8282\u70B9 A \u4E4B\u524D\u63D2\u5165\u4E00\u4E2A\u65B0 Rem\u3002\n\n## \u793A\u4F8B 2\uFF1A\u5220\u9664\u4E00\u4E2A\u5E26\u5B50\u8282\u70B9\u7684\u884C\n\n\\`\\`\\`\noldStr:\n \u5B50\u8282\u70B9 A <!--idA-->\n \u5B59\u8282\u70B9 A1 <!--idA1-->\n \u5B59\u8282\u70B9 A2 <!--idA2-->\n \u5B50\u8282\u70B9 B <!--idB-->\n\nnewStr:\n \u5B50\u8282\u70B9 B <!--idB-->\n\\`\\`\\`\n\n\u7ED3\u679C\uFF1A\u5220\u9664\u5B50\u8282\u70B9 A \u53CA\u5176\u6240\u6709\u5B50\u8282\u70B9\uFF08\u5FC5\u987B\u4E00\u8D77\u5220\u9664\uFF09\u3002\n\n## \u793A\u4F8B 3\uFF1A\u521B\u5EFA\u5E26\u591A\u884C\u95EA\u5361\u7684\u7ED3\u6784\n\n\\`\\`\\`\noldStr:\n \u5B50\u8282\u70B9 A <!--idA-->\n\nnewStr:\n \u4EC0\u4E48\u662F\u7EBF\u6027\u56DE\u5F52\uFF1F \u2193\n \u4E00\u79CD\u57FA\u672C\u7684\u56DE\u5F52\u5206\u6790\u65B9\u6CD5\n \u5047\u8BBE\u56E0\u53D8\u91CF\u4E0E\u81EA\u53D8\u91CF\u5448\u7EBF\u6027\u5173\u7CFB\n \u5B50\u8282\u70B9 A <!--idA-->\n\\`\\`\\`\n\n\u7ED3\u679C\uFF1A\u521B\u5EFA\u4E00\u4E2A\u591A\u884C forward \u95EA\u5361\uFF0C\u95EE\u9898\u4E3A\"\u4EC0\u4E48\u662F\u7EBF\u6027\u56DE\u5F52\uFF1F\"\uFF0C\u4E24\u4E2A\u5B50\u884C\u81EA\u52A8\u6210\u4E3A\u7B54\u6848\uFF08isCardItem=true\uFF09\u3002\n";
@@ -0,0 +1,197 @@
1
+ export const EDIT_TREE_GUIDE_CONTENT = `
2
+ # edit-tree 操作指南
3
+
4
+ edit_tree 通过 str_replace 对 Markdown 大纲进行结构编辑(行级增/删/移/重排),禁止修改已有行内容。
5
+
6
+ ---
7
+
8
+ ## 前置条件
9
+
10
+ 必须先 \\\`read_tree\\\` 同一个 remId,建立缓存后才能 \\\`edit_tree\\\`。跳过会触发防线 1 错误。
11
+
12
+ ---
13
+
14
+ ## 支持的操作
15
+
16
+ ### 1. 新增行
17
+
18
+ 在 newStr 中添加**无 remId 注释**的新行。通过缩进确定父子关系。
19
+
20
+ \\\`\\\`\\\`
21
+ oldStr:
22
+ 子节点 A <!--idA-->
23
+
24
+ newStr:
25
+ 新增节点
26
+ 子节点 A <!--idA-->
27
+ \\\`\\\`\\\`
28
+
29
+ #### 新增行的 Markdown 前缀
30
+
31
+ | 前缀 | 效果 |
32
+ |------|------|
33
+ | \\\`# text\\\` | 创建 H1 标题 |
34
+ | \\\`## text\\\` | 创建 H2 标题 |
35
+ | \\\`### text\\\` | 创建 H3 标题 |
36
+ | \\\`- [ ] text\\\` | 创建未完成待办 |
37
+ | \\\`- [x] text\\\` | 创建已完成待办 |
38
+ | \\\`\\\\\\\`text\\\\\\\`\\\` | 创建代码块 |
39
+ | \\\`---\\\` | 创建分隔线 |
40
+
41
+ #### 新增行的箭头分隔符
42
+
43
+ | 箭头 | 格式 | 效果 |
44
+ |------|------|------|
45
+ | \\\` → \\\` | \\\`问题 → 答案\\\` | 创建 forward 闪卡(单行) |
46
+ | \\\` ← \\\` | \\\`问题 ← 答案\\\` | 创建 backward 闪卡(单行) |
47
+ | \\\` ↔ \\\` | \\\`问题 ↔ 答案\\\` | 创建 both 闪卡(单行) |
48
+ | \\\` ↓\\\` | \\\`问题 ↓\\\` | 创建 forward 多行闪卡(子节点为答案) |
49
+ | \\\` ↑\\\` | \\\`问题 ↑\\\` | 创建 backward 多行闪卡 |
50
+ | \\\` ↕\\\` | \\\`问题 ↕\\\` | 创建 both 多行闪卡 |
51
+
52
+ #### 嵌套新增
53
+
54
+ 新增行下面可以再嵌套新增行,通过缩进表示父子关系:
55
+
56
+ \\\`\\\`\\\`
57
+ newStr:
58
+ 父节点 ↓
59
+ 答案行 1
60
+ 答案行 2
61
+ 子节点 A <!--idA-->
62
+ \\\`\\\`\\\`
63
+
64
+ 嵌套新增行的父 ID 通过内部占位标记管理,创建顺序保证从浅到深。
65
+
66
+ ### 2. 删除行
67
+
68
+ 从 newStr 中移除带 remId 的行。**必须同时删除该行的所有可见子行**,否则报 orphan_detected 错误。
69
+
70
+ \\\`\\\`\\\`
71
+ oldStr:
72
+ 子节点 A <!--idA-->
73
+ 孙节点 A1 <!--idA1-->
74
+ 子节点 B <!--idB-->
75
+
76
+ newStr:
77
+ 子节点 B <!--idB-->
78
+ \\\`\\\`\\\`
79
+
80
+ 删除操作按深度**从深到浅**执行(先删子后删父)。
81
+
82
+ ### 3. 移动行
83
+
84
+ 改变行的缩进级别或位置,使其移动到新的父节点下:
85
+
86
+ \\\`\\\`\\\`
87
+ oldStr:
88
+ 子节点 A <!--idA-->
89
+ 目标行 <!--idT-->
90
+ 子节点 B <!--idB-->
91
+
92
+ newStr:
93
+ 子节点 A <!--idA-->
94
+ 子节点 B <!--idB-->
95
+ 目标行 <!--idT-->
96
+ \\\`\\\`\\\`
97
+
98
+ ### 4. 重排行
99
+
100
+ 调换同级行的顺序:
101
+
102
+ \\\`\\\`\\\`
103
+ oldStr:
104
+ 子节点 A <!--idA-->
105
+ 子节点 B <!--idB-->
106
+ 子节点 C <!--idC-->
107
+
108
+ newStr:
109
+ 子节点 C <!--idC-->
110
+ 子节点 A <!--idA-->
111
+ 子节点 B <!--idB-->
112
+ \\\`\\\`\\\`
113
+
114
+ ---
115
+
116
+ ## 禁止的操作
117
+
118
+ | 操作 | 错误类型 | 错误信息 | 替代方案 |
119
+ |------|----------|----------|----------|
120
+ | 修改已有行内容 | \\\`content_modified\\\` | Content modification of existing Rem is not allowed in tree edit mode. | 使用 \\\`edit_rem\\\` |
121
+ | 删除/修改根节点 | \\\`root_modified\\\` | Root node cannot be changed, deleted or moved. | — |
122
+ | 删除有隐藏子节点的行 | \\\`folded_delete\\\` | Cannot delete {id} because it has {N} hidden children. | 用更大的 depth 重新 read_tree |
123
+ | 删除行但保留子节点 | \\\`orphan_detected\\\` | Cannot delete {id} because it has children that were not removed. | 同时删除所有子行 |
124
+ | 删除/修改省略占位符 | \\\`elided_modified\\\` | Cannot delete or modify elided region directly. | 用更大的 depth/maxSiblings 重新 read_tree 展开 |
125
+ | 缩进跳级 | \\\`indent_skip\\\` | 缩进跳级:行 ... 的缩进级别为 N,但找不到上一级的父节点。 | 检查缩进是否正确(每级 2 空格) |
126
+
127
+ ---
128
+
129
+ ## 操作执行顺序
130
+
131
+ diff 算法生成的操作按以下顺序排列并执行:
132
+
133
+ \\\`\\\`\\\`
134
+ 1. Create(新增) — 按出现顺序,从浅到深
135
+ 2. Move(移动) — 父节点变更的行
136
+ 3. Reorder(重排) — 同父节点内顺序变更
137
+ 4. Delete(删除) — 按深度从深到浅
138
+ \\\`\\\`\\\`
139
+
140
+ ---
141
+
142
+ ## practiceDirection 保护机制
143
+
144
+ RemNote SDK 存在已知 bug:\\\`setIsCardItem(true)\\\` 会偷偷设置 \\\`practiceDirection: "forward"\\\`,而 \\\`setIsCardItem(false)\\\` 不会清除。
145
+
146
+ **新增行(create)**:当父节点是多行闪卡(含 ↓↑↕ 箭头)时,新创建的子行需要 \\\`isCardItem: true\\\`。设置后立即用 \\\`practiceDirection: 'none'\\\` 覆盖 SDK 副作用。
147
+
148
+ **移动行(move)**:
149
+ - 移入多行父节点:设 \\\`isCardItem: true\\\` + \\\`practiceDirection: 'none'\\\`
150
+ - 移出多行父节点:设 \\\`isCardItem: false\\\` + \\\`practiceDirection: 'none'\\\`
151
+ - 例外:如果 Rem 自身有合法的 practiceDirection(箭头分隔符),保留不覆盖
152
+
153
+ ---
154
+
155
+ ## 示例 1:在指定位置插入新行
156
+
157
+ \\\`\\\`\\\`
158
+ oldStr:
159
+ 子节点 A <!--idA-->
160
+
161
+ newStr:
162
+ 新增行
163
+ 子节点 A <!--idA-->
164
+ \\\`\\\`\\\`
165
+
166
+ 结果:在子节点 A 之前插入一个新 Rem。
167
+
168
+ ## 示例 2:删除一个带子节点的行
169
+
170
+ \\\`\\\`\\\`
171
+ oldStr:
172
+ 子节点 A <!--idA-->
173
+ 孙节点 A1 <!--idA1-->
174
+ 孙节点 A2 <!--idA2-->
175
+ 子节点 B <!--idB-->
176
+
177
+ newStr:
178
+ 子节点 B <!--idB-->
179
+ \\\`\\\`\\\`
180
+
181
+ 结果:删除子节点 A 及其所有子节点(必须一起删除)。
182
+
183
+ ## 示例 3:创建带多行闪卡的结构
184
+
185
+ \\\`\\\`\\\`
186
+ oldStr:
187
+ 子节点 A <!--idA-->
188
+
189
+ newStr:
190
+ 什么是线性回归? ↓
191
+ 一种基本的回归分析方法
192
+ 假设因变量与自变量呈线性关系
193
+ 子节点 A <!--idA-->
194
+ \\\`\\\`\\\`
195
+
196
+ 结果:创建一个多行 forward 闪卡,问题为"什么是线性回归?",两个子行自动成为答案(isCardItem=true)。
197
+ `;
@@ -0,0 +1 @@
1
+ export declare const ERROR_REFERENCE_CONTENT = "\n# Error Reference\n\n\u6240\u6709 CLI \u547D\u4EE4\u9519\u8BEF\u7684\u5B8C\u6574\u53C2\u8003\uFF0C\u6309\u7C7B\u522B\u5206\u7EC4\u3002\n\n---\n\n## 1. \u8FDE\u63A5\u4E0E\u4F1A\u8BDD\u9519\u8BEF\n\n| \u9519\u8BEF\u4FE1\u606F | \u89E6\u53D1\u547D\u4EE4 | \u539F\u56E0 | \u6062\u590D\u64CD\u4F5C |\n|:---------|:---------|:-----|:---------|\n| \u5B88\u62A4\u8FDB\u7A0B\u672A\u8FD0\u884C\uFF0C\u8BF7\u5148\u6267\u884C remnote-bridge connect | \u6240\u6709\u4E1A\u52A1\u547D\u4EE4 | \u672A\u6267\u884C connect \u6216 daemon \u5DF2\u8D85\u65F6\u5173\u95ED | \u6267\u884C \\`connect\\` |\n| Plugin \u672A\u8FDE\u63A5 | health / \u4E1A\u52A1\u547D\u4EE4 | RemNote \u672A\u6253\u5F00\u6216\u63D2\u4EF6\u672A\u52A0\u8F7D | \u6253\u5F00 RemNote \u5E76\u786E\u8BA4\u63D2\u4EF6\u52A0\u8F7D |\n| SDK \u672A\u5C31\u7EEA | health | \u77E5\u8BC6\u5E93\u5C1A\u672A\u52A0\u8F7D\u5B8C\u6210 | \u7B49\u5F85\u51E0\u79D2\u540E\u91CD\u8BD5 \\`health\\` |\n| \u8FDE\u63A5\u8D85\u65F6 | connect | daemon \u542F\u52A8\u4F46 Plugin \u672A\u5728\u8D85\u65F6\u65F6\u95F4\u5185\u8FDE\u63A5 | \u786E\u8BA4 RemNote \u5DF2\u6253\u5F00\u3001\u63D2\u4EF6\u5DF2\u52A0\u8F7D\uFF1B\u68C0\u67E5\u7AEF\u53E3\u914D\u7F6E |\n\n---\n\n## 2. \u9632\u7EBF\u9519\u8BEF\uFF08edit_rem / edit_tree \u5171\u7528\uFF09\n\n### \u9632\u7EBF 1\uFF1A\u7F13\u5B58\u5B58\u5728\u6027\n\n| \u9519\u8BEF\u4FE1\u606F | \u89E6\u53D1\u547D\u4EE4 | \u6062\u590D\u64CD\u4F5C |\n|:---------|:---------|:---------|\n| Rem {remId} has not been read yet. Read it first before editing. | edit_rem | \u6267\u884C \\`read_rem\\` \u540C\u4E00\u4E2A remId |\n| Tree rooted at {remId} has not been read yet. Use read-tree first. | edit_tree | \u6267\u884C \\`read_tree\\` \u540C\u4E00\u4E2A remId |\n\n### \u9632\u7EBF 2\uFF1A\u4E50\u89C2\u5E76\u53D1\u68C0\u6D4B\n\n| \u9519\u8BEF\u4FE1\u606F | \u89E6\u53D1\u547D\u4EE4 | \u6062\u590D\u64CD\u4F5C |\n|:---------|:---------|:---------|\n| Rem {remId} has been modified since last read. Please read it again before editing. | edit_rem | \u91CD\u65B0\u6267\u884C \\`read_rem\\` \u83B7\u53D6\u6700\u65B0\u72B6\u6001 |\n| Tree rooted at {remId} has been modified since last read-tree. Please read-tree again. | edit_tree | \u91CD\u65B0\u6267\u884C \\`read_tree\\` \u83B7\u53D6\u6700\u65B0\u72B6\u6001 |\n\n**\u5173\u952E**\uFF1A\u9632\u7EBF 2 \u5931\u8D25\u65F6**\u4E0D\u4F1A\u81EA\u52A8\u66F4\u65B0\u7F13\u5B58**\uFF0C\u5FC5\u987B\u624B\u52A8\u91CD\u65B0 read\u3002\n\n### \u9632\u7EBF 3\uFF1Astr_replace \u7CBE\u786E\u5339\u914D\n\n| \u9519\u8BEF\u4FE1\u606F | \u89E6\u53D1\u547D\u4EE4 | \u6062\u590D\u64CD\u4F5C |\n|:---------|:---------|:---------|\n| old_str not found in the serialized JSON of rem {remId} | edit_rem | \u68C0\u67E5 oldStr \u662F\u5426\u7CBE\u786E\u5339\u914D\uFF08\u542B\u5F15\u53F7\u3001\u7A7A\u683C\u3001\u6362\u884C\uFF09 |\n| old_str not found in the tree outline of {remId} | edit_tree | \u68C0\u67E5 oldStr \u662F\u5426\u7CBE\u786E\u5339\u914D\u7F13\u5B58\u5927\u7EB2 |\n| old_str matches {N} locations in rem {remId}. Make old_str more specific to match exactly once. | edit_rem | \u6269\u5927 oldStr \u8303\u56F4\uFF0C\u5305\u542B\u66F4\u591A\u4E0A\u4E0B\u6587\u4EE5\u552F\u4E00\u5B9A\u4F4D |\n| old_str matches {N} locations in the tree outline of {remId}. Make old_str more specific to match exactly once. | edit_tree | \u6269\u5927 oldStr \u8303\u56F4 |\n\n---\n\n## 3. edit_rem \u4E13\u7528\u9519\u8BEF\n\n| \u9519\u8BEF\u4FE1\u606F | \u539F\u56E0 | \u6062\u590D\u64CD\u4F5C |\n|:---------|:-----|:---------|\n| The replacement produced invalid JSON. Check your new_str for syntax errors. | \u66FF\u6362\u540E\u6587\u672C\u4E0D\u662F\u5408\u6CD5 JSON | \u68C0\u67E5 newStr \u7684\u5F15\u53F7\u3001\u9017\u53F7\u3001\u62EC\u53F7\u5B8C\u6574\u6027 |\n| Failed to update field 'type': Portal \u4E0D\u53EF\u901A\u8FC7 setType() \u8BBE\u7F6E | \u5C1D\u8BD5\u5C06 type \u8BBE\u4E3A portal | Portal \u53EA\u80FD\u901A\u8FC7 SDK \u4E13\u7528 API \u521B\u5EFA\uFF0C\u4E0D\u53EF\u901A\u8FC7 edit_rem \u8BBE\u7F6E |\n| Failed to update field '{field}': ... | SDK setter \u8C03\u7528\u5931\u8D25 | \u68C0\u67E5\u5B57\u6BB5\u503C\u662F\u5426\u5728\u5141\u8BB8\u8303\u56F4\u5185 |\n| Field '{fieldName}' is read-only and was ignored | \u4FEE\u6539\u4E86\u53EA\u8BFB\u5B57\u6BB5 | **\u8B66\u544A**\uFF08\u975E\u963B\u65AD\uFF09\uFF0C\u8BE5\u5B57\u6BB5\u4E0D\u53EF\u4FEE\u6539 |\n| Setting 'todoStatus' without 'isTodo: true' may have no effect | todoStatus \u975E null \u4F46 isTodo=false | \u5148\u5C06 isTodo \u8BBE\u4E3A true |\n\n---\n\n## 4. edit_tree \u4E13\u7528\u9519\u8BEF\n\n| \u9519\u8BEF\u4FE1\u606F | \u9519\u8BEF\u7C7B\u578B | \u539F\u56E0 | \u6062\u590D\u64CD\u4F5C |\n|:---------|:---------|:-----|:---------|\n| Content modification of existing Rem is not allowed in tree edit mode. | \\`content_modified\\` | \u4FEE\u6539\u4E86\u5DF2\u6709\u884C\u7684\u6587\u5B57\u5185\u5BB9 | \u4F7F\u7528 \\`edit_rem\\` \u4FEE\u6539\u5185\u5BB9 |\n| Root node cannot be changed, deleted or moved. | \\`root_modified\\` | \u5C1D\u8BD5\u4FEE\u6539/\u5220\u9664/\u79FB\u52A8\u6839\u8282\u70B9 | \u6839\u8282\u70B9\u4E0D\u53EF\u64CD\u4F5C |\n| Cannot delete {id} because it has {N} hidden children. | \\`folded_delete\\` | \u5220\u9664\u4E86\u6709\u6298\u53E0\uFF08\u672A\u5C55\u5F00\uFF09\u5B50\u8282\u70B9\u7684\u884C | \u7528\u66F4\u5927\u7684 depth \u91CD\u65B0 \\`read_tree\\` |\n| Cannot delete {id} because it has children that were not removed. | \\`orphan_detected\\` | \u5220\u9664\u4E86\u7236\u884C\u4F46\u4FDD\u7559\u4E86\u5B50\u884C | \u5FC5\u987B\u540C\u65F6\u5220\u9664\u6240\u6709\u5B50\u884C |\n| Cannot delete or modify elided region directly. | \\`elided_modified\\` | \u5220\u9664\u6216\u4FEE\u6539\u4E86\u7701\u7565\u5360\u4F4D\u7B26 | \u7528\u66F4\u5927\u7684 depth/maxSiblings \u91CD\u65B0 \\`read_tree\\` \u5C55\u5F00 |\n| \u7F29\u8FDB\u8DF3\u7EA7\uFF1A\u884C ... \u7684\u7F29\u8FDB\u7EA7\u522B\u4E3A N\uFF0C\u4F46\u627E\u4E0D\u5230\u4E0A\u4E00\u7EA7\u7684\u7236\u8282\u70B9\u3002 | \\`indent_skip\\` | \u65B0\u589E\u884C\u7684\u7F29\u8FDB\u4E0D\u6B63\u786E | \u68C0\u67E5\u7F29\u8FDB\uFF08\u6BCF\u7EA7 2 \u7A7A\u683C\uFF09 |\n\n---\n\n## 5. \u8BFB\u53D6\u9519\u8BEF\n\n| \u9519\u8BEF\u4FE1\u606F | \u89E6\u53D1\u547D\u4EE4 | \u539F\u56E0 | \u6062\u590D\u64CD\u4F5C |\n|:---------|:---------|:-----|:---------|\n| Rem not found: {remId} | read_rem / read_tree | remId \u65E0\u6548\u6216 Rem \u5DF2\u88AB\u5220\u9664 | \u4F7F\u7528 \\`search\\` \u91CD\u65B0\u5B9A\u4F4D |\n| \u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u805A\u7126\u7684 Rem | read_context (focus) | \u7528\u6237\u672A\u5728 RemNote \u4E2D\u70B9\u51FB\u4EFB\u4F55 Rem | \u63D0\u9192\u7528\u6237\u5728 RemNote \u4E2D\u70B9\u51FB\u4E00\u4E2A Rem |\n| \u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u9875\u9762 | read_context (page) | RemNote \u672A\u6253\u5F00\u6587\u6863\u9875\u9762 | \u63D0\u9192\u7528\u6237\u6253\u5F00\u4E00\u4E2A\u6587\u6863\u9875\u9762 |\n\n---\n\n## 6. \u641C\u7D22\u9519\u8BEF\n\n| \u9519\u8BEF\u4FE1\u606F | \u89E6\u53D1\u547D\u4EE4 | \u539F\u56E0 | \u6062\u590D\u64CD\u4F5C |\n|:---------|:---------|:-----|:---------|\n| \u641C\u7D22\u65E0\u7ED3\u679C | search | \u5173\u952E\u8BCD\u672A\u5339\u914D\u4EFB\u4F55 Rem | \u4E2D\u6587\u641C\u7D22\u5C1D\u8BD5\u5355\u5B57\u7B56\u7565\uFF1B\u6216\u6539\u7528 \\`read_globe\\` \u2192 \\`read_tree\\` \u624B\u52A8\u5B9A\u4F4D |\n\n---\n\n## \u9519\u8BEF\u8BCA\u65AD\u51B3\u7B56\u6811\n\n\\`\\`\\`\n\u547D\u4EE4\u5931\u8D25\n\u251C\u2500 \"\u5B88\u62A4\u8FDB\u7A0B\u672A\u8FD0\u884C\"\n\u2502 \u2514\u2500 \u6267\u884C connect\n\u2502\n\u251C\u2500 \"Plugin \u672A\u8FDE\u63A5\" / \"SDK \u672A\u5C31\u7EEA\"\n\u2502 \u2514\u2500 \u786E\u8BA4 RemNote \u5DF2\u6253\u5F00 \u2192 health \u68C0\u67E5\n\u2502\n\u251C\u2500 \"has not been read yet\"\n\u2502 \u2514\u2500 \u6267\u884C\u5BF9\u5E94 read \u547D\u4EE4\uFF08read_rem / read_tree\uFF09\n\u2502\n\u251C\u2500 \"has been modified since last read\"\n\u2502 \u2514\u2500 \u91CD\u65B0\u6267\u884C read \u2192 \u7136\u540E\u91CD\u8BD5 edit\n\u2502\n\u251C\u2500 \"old_str not found\"\n\u2502 \u251C\u2500 \u68C0\u67E5\u7A7A\u683C\u3001\u6362\u884C\u3001\u5F15\u53F7\u662F\u5426\u7CBE\u786E\u5339\u914D\n\u2502 \u2514\u2500 \u91CD\u65B0 read \u786E\u8BA4\u5F53\u524D\u5185\u5BB9\n\u2502\n\u251C\u2500 \"old_str matches N locations\"\n\u2502 \u2514\u2500 \u6269\u5927 oldStr\uFF0C\u5305\u542B\u66F4\u591A\u4E0A\u4E0B\u6587\n\u2502\n\u251C\u2500 \"invalid JSON\"\n\u2502 \u2514\u2500 \u68C0\u67E5 newStr \u7684 JSON \u8BED\u6CD5\n\u2502\n\u251C\u2500 \"Content modification not allowed\"\n\u2502 \u2514\u2500 \u6539\u7528 edit_rem \u4FEE\u6539\u5185\u5BB9\n\u2502\n\u251C\u2500 \"orphan_detected\"\n\u2502 \u2514\u2500 \u540C\u65F6\u5220\u9664\u7236\u884C\u7684\u6240\u6709\u5B50\u884C\n\u2502\n\u251C\u2500 \"folded_delete\"\n\u2502 \u2514\u2500 \u7528\u66F4\u5927 depth \u91CD\u65B0 read_tree\n\u2502\n\u251C\u2500 \"Rem not found\"\n\u2502 \u2514\u2500 \u4F7F\u7528 search \u91CD\u65B0\u5B9A\u4F4D\u76EE\u6807 Rem\n\u2502\n\u2514\u2500 \u5176\u4ED6\n \u2514\u2500 \u6267\u884C health \u68C0\u67E5\u7CFB\u7EDF\u72B6\u6001\n\\`\\`\\`\n";
@@ -0,0 +1,132 @@
1
+ export const ERROR_REFERENCE_CONTENT = `
2
+ # Error Reference
3
+
4
+ 所有 CLI 命令错误的完整参考,按类别分组。
5
+
6
+ ---
7
+
8
+ ## 1. 连接与会话错误
9
+
10
+ | 错误信息 | 触发命令 | 原因 | 恢复操作 |
11
+ |:---------|:---------|:-----|:---------|
12
+ | 守护进程未运行,请先执行 remnote-bridge connect | 所有业务命令 | 未执行 connect 或 daemon 已超时关闭 | 执行 \\\`connect\\\` |
13
+ | Plugin 未连接 | health / 业务命令 | RemNote 未打开或插件未加载 | 打开 RemNote 并确认插件加载 |
14
+ | SDK 未就绪 | health | 知识库尚未加载完成 | 等待几秒后重试 \\\`health\\\` |
15
+ | 连接超时 | connect | daemon 启动但 Plugin 未在超时时间内连接 | 确认 RemNote 已打开、插件已加载;检查端口配置 |
16
+
17
+ ---
18
+
19
+ ## 2. 防线错误(edit_rem / edit_tree 共用)
20
+
21
+ ### 防线 1:缓存存在性
22
+
23
+ | 错误信息 | 触发命令 | 恢复操作 |
24
+ |:---------|:---------|:---------|
25
+ | Rem {remId} has not been read yet. Read it first before editing. | edit_rem | 执行 \\\`read_rem\\\` 同一个 remId |
26
+ | Tree rooted at {remId} has not been read yet. Use read-tree first. | edit_tree | 执行 \\\`read_tree\\\` 同一个 remId |
27
+
28
+ ### 防线 2:乐观并发检测
29
+
30
+ | 错误信息 | 触发命令 | 恢复操作 |
31
+ |:---------|:---------|:---------|
32
+ | Rem {remId} has been modified since last read. Please read it again before editing. | edit_rem | 重新执行 \\\`read_rem\\\` 获取最新状态 |
33
+ | Tree rooted at {remId} has been modified since last read-tree. Please read-tree again. | edit_tree | 重新执行 \\\`read_tree\\\` 获取最新状态 |
34
+
35
+ **关键**:防线 2 失败时**不会自动更新缓存**,必须手动重新 read。
36
+
37
+ ### 防线 3:str_replace 精确匹配
38
+
39
+ | 错误信息 | 触发命令 | 恢复操作 |
40
+ |:---------|:---------|:---------|
41
+ | old_str not found in the serialized JSON of rem {remId} | edit_rem | 检查 oldStr 是否精确匹配(含引号、空格、换行) |
42
+ | old_str not found in the tree outline of {remId} | edit_tree | 检查 oldStr 是否精确匹配缓存大纲 |
43
+ | old_str matches {N} locations in rem {remId}. Make old_str more specific to match exactly once. | edit_rem | 扩大 oldStr 范围,包含更多上下文以唯一定位 |
44
+ | old_str matches {N} locations in the tree outline of {remId}. Make old_str more specific to match exactly once. | edit_tree | 扩大 oldStr 范围 |
45
+
46
+ ---
47
+
48
+ ## 3. edit_rem 专用错误
49
+
50
+ | 错误信息 | 原因 | 恢复操作 |
51
+ |:---------|:-----|:---------|
52
+ | The replacement produced invalid JSON. Check your new_str for syntax errors. | 替换后文本不是合法 JSON | 检查 newStr 的引号、逗号、括号完整性 |
53
+ | Failed to update field 'type': Portal 不可通过 setType() 设置 | 尝试将 type 设为 portal | Portal 只能通过 SDK 专用 API 创建,不可通过 edit_rem 设置 |
54
+ | Failed to update field '{field}': ... | SDK setter 调用失败 | 检查字段值是否在允许范围内 |
55
+ | Field '{fieldName}' is read-only and was ignored | 修改了只读字段 | **警告**(非阻断),该字段不可修改 |
56
+ | Setting 'todoStatus' without 'isTodo: true' may have no effect | todoStatus 非 null 但 isTodo=false | 先将 isTodo 设为 true |
57
+
58
+ ---
59
+
60
+ ## 4. edit_tree 专用错误
61
+
62
+ | 错误信息 | 错误类型 | 原因 | 恢复操作 |
63
+ |:---------|:---------|:-----|:---------|
64
+ | Content modification of existing Rem is not allowed in tree edit mode. | \\\`content_modified\\\` | 修改了已有行的文字内容 | 使用 \\\`edit_rem\\\` 修改内容 |
65
+ | Root node cannot be changed, deleted or moved. | \\\`root_modified\\\` | 尝试修改/删除/移动根节点 | 根节点不可操作 |
66
+ | Cannot delete {id} because it has {N} hidden children. | \\\`folded_delete\\\` | 删除了有折叠(未展开)子节点的行 | 用更大的 depth 重新 \\\`read_tree\\\` |
67
+ | Cannot delete {id} because it has children that were not removed. | \\\`orphan_detected\\\` | 删除了父行但保留了子行 | 必须同时删除所有子行 |
68
+ | Cannot delete or modify elided region directly. | \\\`elided_modified\\\` | 删除或修改了省略占位符 | 用更大的 depth/maxSiblings 重新 \\\`read_tree\\\` 展开 |
69
+ | 缩进跳级:行 ... 的缩进级别为 N,但找不到上一级的父节点。 | \\\`indent_skip\\\` | 新增行的缩进不正确 | 检查缩进(每级 2 空格) |
70
+
71
+ ---
72
+
73
+ ## 5. 读取错误
74
+
75
+ | 错误信息 | 触发命令 | 原因 | 恢复操作 |
76
+ |:---------|:---------|:-----|:---------|
77
+ | Rem not found: {remId} | read_rem / read_tree | remId 无效或 Rem 已被删除 | 使用 \\\`search\\\` 重新定位 |
78
+ | 无法获取当前聚焦的 Rem | read_context (focus) | 用户未在 RemNote 中点击任何 Rem | 提醒用户在 RemNote 中点击一个 Rem |
79
+ | 无法获取当前页面 | read_context (page) | RemNote 未打开文档页面 | 提醒用户打开一个文档页面 |
80
+
81
+ ---
82
+
83
+ ## 6. 搜索错误
84
+
85
+ | 错误信息 | 触发命令 | 原因 | 恢复操作 |
86
+ |:---------|:---------|:-----|:---------|
87
+ | 搜索无结果 | search | 关键词未匹配任何 Rem | 中文搜索尝试单字策略;或改用 \\\`read_globe\\\` → \\\`read_tree\\\` 手动定位 |
88
+
89
+ ---
90
+
91
+ ## 错误诊断决策树
92
+
93
+ \\\`\\\`\\\`
94
+ 命令失败
95
+ ├─ "守护进程未运行"
96
+ │ └─ 执行 connect
97
+
98
+ ├─ "Plugin 未连接" / "SDK 未就绪"
99
+ │ └─ 确认 RemNote 已打开 → health 检查
100
+
101
+ ├─ "has not been read yet"
102
+ │ └─ 执行对应 read 命令(read_rem / read_tree)
103
+
104
+ ├─ "has been modified since last read"
105
+ │ └─ 重新执行 read → 然后重试 edit
106
+
107
+ ├─ "old_str not found"
108
+ │ ├─ 检查空格、换行、引号是否精确匹配
109
+ │ └─ 重新 read 确认当前内容
110
+
111
+ ├─ "old_str matches N locations"
112
+ │ └─ 扩大 oldStr,包含更多上下文
113
+
114
+ ├─ "invalid JSON"
115
+ │ └─ 检查 newStr 的 JSON 语法
116
+
117
+ ├─ "Content modification not allowed"
118
+ │ └─ 改用 edit_rem 修改内容
119
+
120
+ ├─ "orphan_detected"
121
+ │ └─ 同时删除父行的所有子行
122
+
123
+ ├─ "folded_delete"
124
+ │ └─ 用更大 depth 重新 read_tree
125
+
126
+ ├─ "Rem not found"
127
+ │ └─ 使用 search 重新定位目标 Rem
128
+
129
+ └─ 其他
130
+ └─ 执行 health 检查系统状态
131
+ \\\`\\\`\\\`
132
+ `;
@@ -0,0 +1 @@
1
+ export declare const OUTLINE_FORMAT_CONTENT = "\n# Markdown \u5927\u7EB2\u683C\u5F0F\u89C4\u8303\n\nread_tree / read_globe / read_context \u7684\u8F93\u51FA\u6838\u5FC3\u662F Markdown \u5927\u7EB2\u6587\u672C\u3002edit_tree \u57FA\u4E8E\u6B64\u5927\u7EB2\u8FDB\u884C\u7ED3\u6784\u7F16\u8F91\u3002\n\n---\n\n## 1. \u884C\u7ED3\u6784\n\n\u6BCF\u884C\u7684\u5B8C\u6574\u683C\u5F0F\u4E3A\uFF1A\n\n\\`\\`\\`\n{\u7F29\u8FDB}{Markdown \u524D\u7F00}{\u5185\u5BB9}{\u7BAD\u5934\u5206\u9694\u7B26}{backText} <!-- {remId} {\u5143\u6570\u636E\u6807\u8BB0} -->\n\\`\\`\\`\n\n- **\u7F29\u8FDB**\uFF1A\u6BCF\u7EA7 2 \u4E2A\u7A7A\u683C\uFF0C\u6839\u8282\u70B9 0 \u4E2A\u7A7A\u683C\n- **remId**\uFF1A\u8BE5\u884C\u5BF9\u5E94\u7684 Rem ID\uFF08edit_tree \u65B0\u589E\u884C\u65E0 remId\uFF09\n- **\u5143\u6570\u636E\u6807\u8BB0**\uFF1A\u7A7A\u683C\u5206\u9694\u7684\u5C5E\u6027\u6807\u8BB0\n\n---\n\n## 2. Markdown \u524D\u7F00\n\n| \u524D\u7F00 | \u542B\u4E49 | \u5BF9\u5E94\u5B57\u6BB5 |\n|:-----|:-----|:---------|\n| \\`# \\` | H1 \u6807\u9898 | fontSize: 'H1' |\n| \\`## \\` | H2 \u6807\u9898 | fontSize: 'H2' |\n| \\`### \\` | H3 \u6807\u9898 | fontSize: 'H3' |\n| \\`- [ ] \\` | \u672A\u5B8C\u6210\u5F85\u529E | isTodo: true, todoStatus: 'Unfinished' |\n| \\`- [x] \\` | \u5DF2\u5B8C\u6210\u5F85\u529E | isTodo: true, todoStatus: 'Finished' |\n| \\`\\\\\\`...\\\\\\`\\` | \u4EE3\u7801\u5757 | isCode: true |\n| \\`---\\` | \u5206\u9694\u7EBF | Divider Powerup |\n\n---\n\n## 3. \u7BAD\u5934\u5206\u9694\u7B26\n\n### \u6709 backText \u7684\u7BAD\u5934\n\n| \u7BAD\u5934 | \u683C\u5F0F | practiceDirection |\n|:-----|:-----|:------------------|\n| \\` \u2192 \\` | text \u2192 backText | forward |\n| \\` \u2190 \\` | text \u2190 backText | backward |\n| \\` \u2194 \\` | text \u2194 backText | both |\n\n### \u591A\u884C\u95EA\u5361\u7684\u7BAD\u5934\n\n| \u7BAD\u5934 | \u683C\u5F0F | practiceDirection | \u8BF4\u660E |\n|:-----|:-----|:------------------|:-----|\n| \\` \u2193\\`\uFF08\u5C3E\u90E8\uFF09 | text \u2193 | forward | \u65E0 backText |\n| \\` \u2191\\`\uFF08\u5C3E\u90E8\uFF09 | text \u2191 | backward | \u65E0 backText |\n| \\` \u2195\\`\uFF08\u5C3E\u90E8\uFF09 | text \u2195 | both | \u65E0 backText |\n| \\` \u2193 \\` | text \u2193 backText | forward | \u6709 backText |\n| \\` \u2191 \\` | text \u2191 backText | backward | \u6709 backText |\n| \\` \u2195 \\` | text \u2195 backText | both | \u6709 backText |\n\n---\n\n## 4. \u5143\u6570\u636E\u6807\u8BB0\n\n| \u6807\u8BB0 | \u542B\u4E49 | \u4F55\u65F6\u51FA\u73B0 |\n|:-----|:-----|:---------|\n| \\`type:concept\\` | concept \u7C7B\u578B | type \u4E0D\u4E3A default \u65F6 |\n| \\`type:descriptor\\` | descriptor \u7C7B\u578B | type \u4E0D\u4E3A default \u65F6 |\n| \\`type:portal\\` | Portal \u7C7B\u578B | type \u4E3A portal \u65F6 |\n| \\`refs:id1,id2,...\\` | Portal \u5F15\u7528\u7684 Rem | \u4EC5 portal |\n| \\`doc\\` | isDocument = true | \u72EC\u7ACB\u4E8E type |\n| \\`top\\` | \u9876\u5C42 Rem | \u65E0\u7236\u8282\u70B9 |\n| \\`children:N\\` | \u6298\u53E0\u5B50\u8282\u70B9\u6570 | \u6DF1\u5EA6\u8D85\u9650\u4E14\u6709\u5B50\u8282\u70B9 |\n| \\`role:card-item\\` | \u591A\u884C\u7B54\u6848\u884C | isCardItem = true |\n| \\`tag:Name(id)\\` | \u6807\u7B7E | \u6BCF\u4E2A tag \u4E00\u4E2A |\n\n---\n\n## 5. \u7701\u7565\u5360\u4F4D\u7B26\n\n### \u7CBE\u786E\u7701\u7565\uFF08sibling \u88C1\u526A\uFF09\n\\`\\`\\`\n<!--...elided {N} siblings (parent:{parentId} range:{from}-{to} total:{total})-->\n\\`\\`\\`\n\n### \u975E\u7CBE\u786E\u7701\u7565\uFF08\u9884\u7B97\u8017\u5C3D\uFF09\n\\`\\`\\`\n<!--...elided >={N} nodes (parent:{parentId} range:{from}-{to} total:{total})-->\n\\`\\`\\`\n\n---\n\n## 6. \u5B8C\u6574\u793A\u4F8B\n\n\\`\\`\\`markdown\n# \u6570\u636E\u7ED3\u6784 <!--kLr type:concept doc top-->\n ## \u7EBF\u6027\u7ED3\u6784 <!--ABC type:concept-->\n \u6570\u7EC4 \u2192 Array <!--DEF-->\n \u94FE\u8868 \u2193 <!--GHI type:concept-->\n \u5355\u5411\u94FE\u8868 <!--JKL role:card-item-->\n \u53CC\u5411\u94FE\u8868 <!--MNO role:card-item-->\n - [x] \u590D\u4E60\u5B8C\u6210 <!--PQR-->\n ## \u6811\u7ED3\u6784 <!--VWX type:concept children:8-->\n <!--...elided 3 siblings (parent:kLr range:3-5 total:6)-->\n \u5D4C\u5165\u89C6\u56FE <!--p01 type:portal refs:ref1,ref2-->\n \u91CD\u8981\u6982\u5FF5 <!--QRS tag:\u6570\u5B66(tag01) tag:\u57FA\u7840(tag02)-->\n\\`\\`\\`\n";