remnote-bridge 0.1.13 → 0.1.15

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 (42) hide show
  1. package/README.md +147 -28
  2. package/README.zh-CN.md +374 -0
  3. package/dist/cli/commands/health.js +231 -112
  4. package/dist/cli/commands/read-rem-in-tree.js +84 -0
  5. package/dist/cli/config.js +2 -0
  6. package/dist/cli/daemon/registry.js +8 -0
  7. package/dist/cli/handlers/edit-handler.js +14 -0
  8. package/dist/cli/handlers/patch-engine.js +347 -0
  9. package/dist/cli/handlers/read-handler.js +2 -53
  10. package/dist/cli/handlers/rem-field-filter.js +102 -0
  11. package/dist/cli/handlers/tree-edit-handler.js +67 -7
  12. package/dist/cli/handlers/tree-read-handler.js +4 -1
  13. package/dist/cli/handlers/tree-rem-read-handler.js +73 -0
  14. package/dist/cli/main.js +53 -2
  15. package/dist/cli/server/ws-server.js +9 -1
  16. package/dist/mcp/daemon-client.js +22 -2
  17. package/dist/mcp/instructions.js +99 -58
  18. package/dist/mcp/tools/edit-tools.js +7 -2
  19. package/dist/mcp/tools/infra-tools.js +20 -11
  20. package/dist/mcp/tools/read-tools.js +88 -2
  21. package/package.json +1 -1
  22. package/remnote-plugin/dist/index-sandbox.js +24 -24
  23. package/remnote-plugin/dist/index.js +24 -24
  24. package/remnote-plugin/dist/manifest.json +1 -1
  25. package/remnote-plugin/package.json +1 -1
  26. package/remnote-plugin/public/manifest.json +1 -1
  27. package/remnote-plugin/src/bridge/message-router.ts +3 -0
  28. package/remnote-plugin/src/services/read-rem-in-tree.ts +43 -0
  29. package/remnote-plugin/src/services/read-rem.ts +31 -16
  30. package/remnote-plugin/src/services/read-tree.ts +5 -0
  31. package/remnote-plugin/src/settings.ts +1 -1
  32. package/skills/remnote-bridge/SKILL.md +50 -8
  33. package/skills/remnote-bridge/instructions/connect.md +31 -8
  34. package/skills/remnote-bridge/instructions/disconnect.md +5 -0
  35. package/skills/remnote-bridge/instructions/edit-tree.md +117 -51
  36. package/skills/remnote-bridge/instructions/health.md +81 -53
  37. package/skills/remnote-bridge/instructions/overall.md +39 -8
  38. package/skills/remnote-bridge/instructions/read-rem-in-tree.md +100 -0
  39. package/skills/remnote-bridge/instructions/read-rem.md +30 -11
  40. package/skills/remnote-bridge-test/SKILL.md +847 -0
  41. package/skills/remnote-bridge-test/references/regression-suite.md +960 -0
  42. package/skills/remnote-bridge-test/references/verification-guide.md +161 -0
@@ -0,0 +1,100 @@
1
+ # read-rem-in-tree — 子树大纲 + 节点属性一次获取
2
+
3
+ > `read_tree` + `read_rem` 的完美结合体。一次调用同时获取 Markdown 大纲和每个节点的完整 RemObject JSON,建立双重缓存。
4
+
5
+ ---
6
+
7
+ ## 适用场景
8
+
9
+ - 需要同时查看子树结构和节点详细属性(如批量编辑前的全量读取)
10
+ - 一次调用建立 tree 缓存(供 `edit_tree`)和 rem 缓存(供 `edit_rem`)
11
+ - 替代连续调用 `read_tree` + 多次 `read_rem` 的场景
12
+
13
+ ## 不适用场景
14
+
15
+ - 只需大纲不需属性 → 用 `read_tree`(更轻量)
16
+ - 只需单个 Rem 属性 → 用 `read_rem`
17
+ - 大规模子树(>50 节点) → 每节点 40+ SDK 调用,性能开销大
18
+
19
+ ---
20
+
21
+ ## 命令格式
22
+
23
+ ```bash
24
+ # 人类模式
25
+ remnote-bridge read-rem-in-tree <remId> [options]
26
+
27
+ # JSON 模式
28
+ remnote-bridge --json read-rem-in-tree '{"remId":"...","depth":3,"maxNodes":50}'
29
+ ```
30
+
31
+ ## 参数
32
+
33
+ | 参数 | 类型 | 默认值 | 说明 |
34
+ |:-----|:-----|:-------|:-----|
35
+ | `remId` | string | **必需** | 子树根节点的 Rem ID |
36
+ | `depth` | number | 3 | 递归展开深度(-1 = 无限) |
37
+ | `maxNodes` | number | **50** | 全局节点总预算(注意比 read_tree 的 200 低) |
38
+ | `maxSiblings` | number | 20 | 单个父节点下最大可见子节点数 |
39
+ | `ancestorLevels` | number | 0 | 向上追溯祖先层数(上限 10) |
40
+ | `fields` | string[] | - | RemObject 字段过滤(只返回指定子集) |
41
+ | `full` | boolean | false | 返回全部 51 个 RemObject 字段 |
42
+ | `includePowerup` | boolean | false | 包含 Powerup 系统数据 |
43
+
44
+ ## 输出
45
+
46
+ ### JSON 模式
47
+
48
+ ```jsonc
49
+ {
50
+ "ok": true,
51
+ "command": "read-rem-in-tree",
52
+ "data": {
53
+ "rootId": "kLr...",
54
+ "depth": 3,
55
+ "nodeCount": 15,
56
+ "outline": "# 数据结构 <!--kLr type:concept doc-->\n ...",
57
+ "remObjects": {
58
+ "kLr": { "id": "kLr", "text": [...], "type": "concept", ... },
59
+ "ABC": { "id": "ABC", "text": [...], ... }
60
+ }
61
+ },
62
+ "ancestors": [...], // 可选
63
+ "cacheOverridden": {...}, // 可选
64
+ "powerupFiltered": {...} // 可选
65
+ }
66
+ ```
67
+
68
+ ### 核心字段
69
+
70
+ - `outline`:Markdown 大纲文本,与 `read_tree` 输出格式完全一致
71
+ - `remObjects`:扁平 map `{ remId → RemObject }`,每个 RemObject 与 `read_rem` 输出一致
72
+ - 默认启用 Token Slimming(省略默认值字段)
73
+ - `fields` / `full` 参数控制过滤行为
74
+
75
+ ## 缓存行为
76
+
77
+ | 缓存 Key | 内容 | 用途 |
78
+ |:---------|:-----|:-----|
79
+ | `tree:{remId}` | outline 大纲文本 | `edit_tree` 前置缓存 |
80
+ | `tree-depth:{remId}` 等 | 读取参数 | `edit_tree` 乐观并发检测 |
81
+ | `rem:{nodeRemId}` | 完整 RemObject(N 个) | `edit_rem` 前置缓存 |
82
+
83
+ 总缓存条目:1(tree) + 3(参数) + N(rem) ≈ N+4。注意 LRU 上限 200。
84
+
85
+ ## 典型工作流
86
+
87
+ ```
88
+ read_rem_in_tree → 一次获取全部信息
89
+
90
+ edit_tree 结构编辑(tree 缓存已就绪)
91
+ +
92
+ edit_rem 属性编辑(rem 缓存已就绪)
93
+ ```
94
+
95
+ ## 关联工具
96
+
97
+ - `read_tree`:只需大纲,更轻量
98
+ - `read_rem`:只需单个 Rem 属性
99
+ - `edit_tree`:结构编辑(需先 read_tree 或 read_rem_in_tree)
100
+ - `edit_rem`:属性编辑(需先 read_rem 或 read_rem_in_tree)
@@ -9,7 +9,8 @@
9
9
  `read-rem` 通过 Rem ID 读取一个 Rem 的所有可获取属性,返回标准化的 RemObject。读取结果会被缓存在 daemon 内存中,供后续 `edit-rem` 使用。
10
10
 
11
11
  核心能力:
12
- - 返回 51 个字段的完整 Rem 数据(默认 33 个,Portal 简化 8 个,`--full` 时 51 个)
12
+ - **Token Slimming**(默认模式):省略处于默认值的字段,典型普通 Rem 仅输出 5-6 个差异字段,大幅减少 AI token 消耗。未显示的字段即为默认值
13
+ - Portal 简化 8 个字段,`--full` 时全部 51 个字段
13
14
  - 支持 `--fields` 指定字段子集
14
15
  - 支持 Powerup 噪音过滤(默认过滤)
15
16
  - 自动缓存,为 `edit-rem` 建立编辑基础
@@ -72,20 +73,17 @@ remnote-bridge read-rem --json '{"remId":"kLrIOHJLyMd8Y2lyA"}'
72
73
  "data": {
73
74
  "id": "kLrIOHJLyMd8Y2lyA",
74
75
  "text": [{ "i": "m", "text": "示例文本", "b": true }],
75
- "backText": null,
76
76
  "type": "concept",
77
- "isDocument": false,
78
77
  "parent": "parentRemId",
79
- "fontSize": null,
80
- "highlightColor": null,
81
- "isTodo": false,
82
- "todoStatus": null,
83
- "...": "(共 33 个字段,--full 时 51 个)"
78
+ "createdAt": 1709712000000,
79
+ "updatedAt": 1709712000000
84
80
  },
85
81
  "timestamp": "2026-03-06T10:00:00.000Z"
86
82
  }
87
83
  ```
88
84
 
85
+ > **Token Slimming**:默认模式省略了 backText(null)、isDocument(false)、fontSize(null) 等处于默认值的字段。未出现的字段即为默认值。`--full` 可输出全部 51 个字段。
86
+
89
87
  ### 成功(含缓存覆盖提示)
90
88
 
91
89
  当该 Rem 之前已有缓存时,输出中附加 `cacheOverridden` 字段:
@@ -159,7 +157,7 @@ remnote-bridge read-rem --json '{"remId":"kLrIOHJLyMd8Y2lyA"}'
159
157
  │ ├─ --full → 返回全部 51 字段
160
158
  │ ├─ --fields → 返回指定字段 + id
161
159
  │ ├─ type=portal → Portal 简化模式(返回 8 个关键字段)
162
- │ └─ 默认 → 排除 R-F 字段(返回 33 字段)
160
+ │ └─ 默认 → 排除 R-F 字段 + Token Slimming(省略匹配默认值的字段)
163
161
  └─ 附加 _cacheOverridden 元数据(若之前有缓存)
164
162
  4. CLI 格式化输出(人类模式 pretty-print / JSON 模式单行)
165
163
  ```
@@ -376,11 +374,32 @@ text | number | date | checkbox | single_select | multi_select | url | image | t
376
374
 
377
375
  | 模式 | 输出字段数 | 说明 |
378
376
  |------|:----------:|------|
379
- | 默认 | 33 | RW + R 字段,覆盖常用场景 |
377
+ | 默认(Token Slimming) | 5-6(典型) | 省略匹配默认值的字段,仅输出有差异的字段。始终输出:id、text、parent、createdAt、updatedAt |
380
378
  | Portal 简化 | 8 | type=portal 时自动使用(id、type、portalType、portalDirectlyIncludedRem、parent、positionAmongstSiblings、createdAt、updatedAt)。`--full` / `--fields` 可覆盖 |
381
- | `--full` | 51 | 全部字段(含 R-F 低频字段) |
379
+ | `--full` | 51 | 全部字段(含 R-F 低频字段),不省略默认值 |
382
380
  | `--fields` | 自选 + id | 仅返回指定字段(始终包含 id) |
383
381
 
382
+ ### 默认值参考表
383
+
384
+ 默认模式下,以下字段在值匹配默认值时被省略。**未出现在输出中的字段即为默认值。**
385
+
386
+ | 字段 | 默认值 | 字段 | 默认值 |
387
+ |------|--------|------|--------|
388
+ | `backText` | `null` | `type` | `"default"` |
389
+ | `isDocument` | `false` | `fontSize` | `null` |
390
+ | `highlightColor` | `null` | `isTodo` | `false` |
391
+ | `todoStatus` | `null` | `isCode` | `false` |
392
+ | `isQuote` | `false` | `isListItem` | `false` |
393
+ | `isCardItem` | `false` | `isTable` | `false` |
394
+ | `isSlot` | `false` | `isProperty` | `false` |
395
+ | `portalType` | `null` | `portalDirectlyIncludedRem` | `[]` |
396
+ | `propertyType` | `null` | `enablePractice` | `false` |
397
+ | `practiceDirection` | `"forward"` | `tags` | `[]` |
398
+ | `sources` | `[]` | `aliases` | `[]` |
399
+ | `remsBeingReferenced` | `[]` | `remsReferencingThis` | `[]` |
400
+ | `taggedRem` | `[]` | `descendants` | `[]` |
401
+ | `siblingRem` | `[]` | `positionAmongstSiblings` | `null` |
402
+
384
403
  ### R-F 字段列表(默认不输出,`--full` 时输出)
385
404
 
386
405
  ```