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
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
`read-rem` 通过 Rem ID 读取一个 Rem 的所有可获取属性,返回标准化的 RemObject。读取结果会被缓存在 daemon 内存中,供后续 `edit-rem` 使用。
|
|
10
10
|
|
|
11
11
|
核心能力:
|
|
12
|
-
-
|
|
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
|
-
"
|
|
80
|
-
"
|
|
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
|
|
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
|
-
|
|
|
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
|
```
|
|
@@ -422,7 +441,7 @@ localUpdatedAt, lastPracticed
|
|
|
422
441
|
| `tags` | `rem.addTag()` / `rem.removeTag()` | **Diff 机制**:对比当前 vs 目标,增删差异项。必须列出完整目标数组,缺少的会被删除 |
|
|
423
442
|
| `sources` | `rem.addSource()` / `rem.removeSource()` | **Diff 机制**:同 tags |
|
|
424
443
|
| `positionAmongstSiblings` | `rem.setParent(parent, position)` | 与 `parent` 联动(见下方说明) |
|
|
425
|
-
| `portalDirectlyIncludedRem` | `rem.addToPortal()` / `rem.removeFromPortal()` |
|
|
444
|
+
| `portalDirectlyIncludedRem` | `rem.addToPortal()` / `rem.removeFromPortal()` | **Portal-W Diff 机制**:仅 type=portal 时可修改。对比当前 vs 目标数组,逐项增删 |
|
|
426
445
|
|
|
427
446
|
### parent + positionAmongstSiblings 联动
|
|
428
447
|
|
|
@@ -434,7 +453,7 @@ localUpdatedAt, lastPracticed
|
|
|
434
453
|
| 只有 `parent` 变更 | `setParent(newParent)` 不带 position(保持末尾) |
|
|
435
454
|
| 只有 `positionAmongstSiblings` 变更 | 获取当前 parent → `setParent(currentParent, newPosition)` |
|
|
436
455
|
|
|
437
|
-
**应在同一次
|
|
456
|
+
**应在同一次 edit-rem 的 changes 中同时传入这两个字段。**
|
|
438
457
|
|
|
439
458
|
---
|
|
440
459
|
|
|
@@ -561,7 +580,7 @@ RemObject 中的 `text` 和 `backText` 字段使用 RichText 格式——一个
|
|
|
561
580
|
|
|
562
581
|
### 序列化确定性
|
|
563
582
|
|
|
564
|
-
RichText 对象元素内部按 **key 字母序排列**(Plugin 端 `sortRichTextKeys()` 处理),确保同一内容的序列化 JSON
|
|
583
|
+
RichText 对象元素内部按 **key 字母序排列**(Plugin 端 `sortRichTextKeys()` 处理),确保同一内容的序列化 JSON 始终一致。这对乐观并发检测至关重要。
|
|
565
584
|
|
|
566
585
|
- `_`(下划线)在 Unicode 中排在所有小写字母之前(`_` = U+005F,`a` = U+0061),所以 `_id` 总是排在第一位
|
|
567
586
|
- 排序由 `Object.keys().sort()` 决定,即 JavaScript 默认的 Unicode 字典序
|
|
@@ -589,11 +608,11 @@ RichText 对象元素内部按 **key 字母序排列**(Plugin 端 `sortRichTex
|
|
|
589
608
|
|------|------|
|
|
590
609
|
| 读取成功 | 完整 JSON 写入缓存 `cache.set('rem:' + remId, fullJson)` |
|
|
591
610
|
| 已有缓存 | 覆盖旧缓存,返回 `cacheOverridden` 元数据 |
|
|
592
|
-
| 缓存用途 | 供 `edit-rem`
|
|
611
|
+
| 缓存用途 | 供 `edit-rem` 的防线检查使用(存在性检查 + 乐观并发检测) |
|
|
593
612
|
| 缓存存储 | daemon 内存中的 LRU 缓存(最大 200 条目) |
|
|
594
613
|
| 缓存清空 | daemon 关闭时自动消失 |
|
|
595
614
|
|
|
596
|
-
**重要**:缓存存储的是 **完整 RemObject
|
|
615
|
+
**重要**:缓存存储的是 **完整 RemObject 对象**(含 R-F 字段),不受 `--fields` / `--full` 选项影响。字段过滤仅作用于返回给 CLI 的输出。
|
|
597
616
|
|
|
598
617
|
---
|
|
599
618
|
|
|
@@ -56,7 +56,7 @@ remnote-bridge search <query> [--limit <N>]
|
|
|
56
56
|
### JSON 模式
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
remnote-bridge search --json '{"query":"机器学习","
|
|
59
|
+
remnote-bridge search --json '{"query":"机器学习","limit":10}'
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
---
|
|
@@ -66,7 +66,7 @@ remnote-bridge search --json '{"query":"机器学习","numResults":10}'
|
|
|
66
66
|
| 字段 | 类型 | 必需 | 说明 |
|
|
67
67
|
|------|------|:----:|------|
|
|
68
68
|
| `query` | string | 是 | 搜索关键词(不能为空) |
|
|
69
|
-
| `
|
|
69
|
+
| `limit` | number | 否 | 结果数量上限(默认 20) |
|
|
70
70
|
|
|
71
71
|
---
|
|
72
72
|
|
|
@@ -159,7 +159,7 @@ remnote-bridge search --json '{"query":"机器学习","numResults":10}'
|
|
|
159
159
|
## 内部流程
|
|
160
160
|
|
|
161
161
|
```
|
|
162
|
-
1. CLI 解析参数(query,
|
|
162
|
+
1. CLI 解析参数(query, limit)
|
|
163
163
|
2. 检查配置:addons.remnote-rag.enabled
|
|
164
164
|
├─ 未启用 → 跳到步骤 4
|
|
165
165
|
└─ 已启用 → 继续步骤 3
|
|
@@ -250,6 +250,6 @@ RemNote 的 Web 版搜索索引按单字符拆分非空格语言的文本。搜
|
|
|
250
250
|
## 注意事项
|
|
251
251
|
|
|
252
252
|
- 搜索结果的 `text` 字段是 Markdown 格式的单行文本(多行换行符已替换为空格)
|
|
253
|
-
- `totalFound` 等于 `results.length`,即实际返回的数量(受 `
|
|
253
|
+
- `totalFound` 等于 `results.length`,即实际返回的数量(受 `limit` 限制)
|
|
254
254
|
- 搜索不会触发缓存写入——search 结果不进入 RemCache
|
|
255
255
|
- 如需获取某个搜索结果的完整属性,需对其 `remId` 执行 `read-rem`
|
|
@@ -83,22 +83,21 @@ remnote-bridge --json setup
|
|
|
83
83
|
|
|
84
84
|
## AI Agent 使用流程
|
|
85
85
|
|
|
86
|
-
setup 会弹出 Chrome
|
|
86
|
+
setup 会弹出 Chrome 窗口,用户只需**登录 RemNote**,然后彻底退出 Chrome。
|
|
87
|
+
|
|
88
|
+
setup 只负责保存登录凭证——配置 dev plugin 是 connect 之后的事(见 `connect.md` 标准模式说明)。
|
|
87
89
|
|
|
88
90
|
### 交互步骤
|
|
89
91
|
|
|
90
92
|
1. 调用 `setup`
|
|
91
93
|
2. **立即告知用户**:
|
|
92
|
-
> 已打开 Chrome
|
|
93
|
-
> 1. 登录 RemNote
|
|
94
|
-
> 2. 在 RemNote 中配置开发插件:点击左下角插件图标 → 开发你的插件 → 输入 connect 输出的 Plugin 服务地址(如 `http://localhost:29101`)
|
|
95
|
-
> 3. 完成后彻底退出 Chrome(macOS 请按 Cmd+Q,仅关窗口不够)
|
|
94
|
+
> 已打开 Chrome 浏览器。请登录 RemNote,完成后彻底退出 Chrome(macOS 请按 Cmd+Q,仅关窗口不够)
|
|
96
95
|
3. 等待 `setup` 命令返回(阻塞式,超时 600 秒)
|
|
97
96
|
4. 收到成功 → 继续执行 `connect --headless`
|
|
98
97
|
|
|
99
98
|
### setup 之后
|
|
100
99
|
|
|
101
|
-
`setup`
|
|
100
|
+
`setup` 只需执行一次。登录凭证已保存,之后每次只需 `connect --headless` 即可自动连接,无需用户操作。
|
|
102
101
|
|
|
103
102
|
如果后续 headless 模式下 Plugin 始终不连接,可能是 RemNote 登录 session 过期,需重新 setup(删除 `~/.remnote-bridge/chrome-profile/.setup-done` 后重新执行)。
|
|
104
103
|
|