remnote-bridge 0.1.15 → 0.1.16
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/dist/cli/commands/edit-tree.js +12 -1
- package/dist/cli/handlers/tree-edit-handler.js +3 -1
- package/dist/cli/handlers/tree-parser.js +17 -0
- package/dist/mcp/instructions.js +5 -3
- package/dist/mcp/tools/edit-tools.js +2 -1
- package/package.json +1 -1
- package/remnote-plugin/dist/index-sandbox.js +19 -19
- package/remnote-plugin/dist/index.js +19 -19
- package/remnote-plugin/src/services/rem-builder.ts +8 -2
- package/remnote-plugin/src/utils/tree-serializer.ts +10 -0
- package/skills/remnote-bridge/SKILL.md +4 -0
- package/skills/remnote-bridge/instructions/edit-tree.md +11 -1
- package/skills/remnote-bridge/instructions/overall.md +10 -0
- package/skills/remnote-bridge-test/SKILL.md +3 -0
- package/skills/remnote-bridge-test/references/regression-suite.md +64 -0
|
@@ -33,7 +33,12 @@ export async function editTreeCommand(remId, options) {
|
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
if (json) {
|
|
36
|
-
jsonOutput({
|
|
36
|
+
jsonOutput({
|
|
37
|
+
ok: true,
|
|
38
|
+
command: 'edit-tree',
|
|
39
|
+
operations: data.operations,
|
|
40
|
+
...(data.templateWarnings?.length && { templateWarnings: data.templateWarnings }),
|
|
41
|
+
});
|
|
37
42
|
}
|
|
38
43
|
else {
|
|
39
44
|
if (data.operations.length === 0) {
|
|
@@ -46,5 +51,11 @@ export async function editTreeCommand(remId, options) {
|
|
|
46
51
|
console.log(` - ${o.type}: ${JSON.stringify(o)}`);
|
|
47
52
|
}
|
|
48
53
|
}
|
|
54
|
+
if (data.templateWarnings?.length) {
|
|
55
|
+
console.log('⚠ 模板/前缀警告:');
|
|
56
|
+
for (const w of data.templateWarnings) {
|
|
57
|
+
console.log(` - ${w}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
49
60
|
}
|
|
50
61
|
}
|
|
@@ -172,7 +172,9 @@ export class TreeEditHandler {
|
|
|
172
172
|
else {
|
|
173
173
|
// ── 普通 Rem 创建路径 ──
|
|
174
174
|
// 解析 Markdown 前缀 + 箭头分隔符 → 属性
|
|
175
|
-
const { cleanContent, powerups, backText, practiceDirection } = parsePowerupPrefix(op.content);
|
|
175
|
+
const { cleanContent, powerups, backText, practiceDirection, warnings: prefixWarnings } = parsePowerupPrefix(op.content);
|
|
176
|
+
if (prefixWarnings?.length)
|
|
177
|
+
templateWarnings.push(...prefixWarnings);
|
|
176
178
|
const createResult = await this.forwardToPlugin('create_rem', {
|
|
177
179
|
content: cleanContent,
|
|
178
180
|
parentId,
|
|
@@ -141,6 +141,7 @@ export function parseMetadata(metadataStr) {
|
|
|
141
141
|
*/
|
|
142
142
|
export function parsePowerupPrefix(rawContent) {
|
|
143
143
|
const powerups = {};
|
|
144
|
+
const warnings = [];
|
|
144
145
|
if (rawContent === '---') {
|
|
145
146
|
return { cleanContent: '', powerups: { addPowerup: 'dv' } };
|
|
146
147
|
}
|
|
@@ -168,6 +169,20 @@ export function parsePowerupPrefix(rawContent) {
|
|
|
168
169
|
powerups.isTodo = true;
|
|
169
170
|
content = content.slice(6);
|
|
170
171
|
}
|
|
172
|
+
// Quote(引用块)
|
|
173
|
+
if (content.startsWith('> ')) {
|
|
174
|
+
powerups.isQuote = true;
|
|
175
|
+
content = content.slice(2);
|
|
176
|
+
}
|
|
177
|
+
// ListItem(有序列表)— 容错 1-9 开头,归一化为 isListItem
|
|
178
|
+
const listItemMatch = content.match(/^([1-9])\. /);
|
|
179
|
+
if (listItemMatch) {
|
|
180
|
+
powerups.isListItem = true;
|
|
181
|
+
content = content.slice(listItemMatch[0].length);
|
|
182
|
+
if (listItemMatch[1] !== '1') {
|
|
183
|
+
warnings.push(`有序列表前缀 "${listItemMatch[0]}" 已归一化为 isListItem(RemNote 自动编号,请统一使用 "1. ")`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
171
186
|
// Code
|
|
172
187
|
if (content.startsWith('`') && content.endsWith('`') && content.length >= 2) {
|
|
173
188
|
powerups.isCode = true;
|
|
@@ -231,6 +246,8 @@ export function parsePowerupPrefix(rawContent) {
|
|
|
231
246
|
result.practiceDirection = practiceDirection;
|
|
232
247
|
if (isMultiline !== undefined)
|
|
233
248
|
result.isMultiline = isMultiline;
|
|
249
|
+
if (warnings.length > 0)
|
|
250
|
+
result.warnings = warnings;
|
|
234
251
|
return result;
|
|
235
252
|
}
|
|
236
253
|
// ────────────────────────── Multiline 检测 ──────────────────────────
|
package/dist/mcp/instructions.js
CHANGED
|
@@ -326,7 +326,9 @@ changes: { "type": "concept", "highlightColor": "Yellow", "fontSize": "H1" }
|
|
|
326
326
|
|
|
327
327
|
新增行(无 remId 注释的行)支持以下格式:
|
|
328
328
|
|
|
329
|
-
**Markdown 前缀**:\`# \` \`## \` \`### \` \`- [ ] \` \`- [x] \` \\\`code\\\` \`---\`
|
|
329
|
+
**Markdown 前缀**:\`# \` \`## \` \`### \` \`- [ ] \` \`- [x] \` \`> \`(引用块) \`1. \`(有序列表) \\\`code\\\` \`---\`
|
|
330
|
+
|
|
331
|
+
> **⚠️ 有序列表必须用 \`1. \` 前缀(Lazy Numbering)**:RemNote 有序列表采用 Lazy Numbering——所有列表项统一写 \`1. \`,RemNote 按层级自动编号(1./2./3./A./B./I./II.)。不要手动编号(如 \`2. \` \`3. \`)。\`2. \`~\`9. \` 会被容错处理(归一化为 isListItem 并返回 templateWarnings 警告),\`10. \` 及以上不会被识别为有序列表。
|
|
330
332
|
|
|
331
333
|
**箭头分隔符**:
|
|
332
334
|
- 单行:\`→\`(forward)\`←\`(backward)\`↔\`(both)——格式 \`text → backText\`
|
|
@@ -502,7 +504,7 @@ tags, sources, positionAmongstSiblings, portalDirectlyIncludedRem
|
|
|
502
504
|
\`\`\`
|
|
503
505
|
|
|
504
506
|
- 缩进:每级 2 空格
|
|
505
|
-
- 前缀:\`# \`(H1)、\`## \`(H2)、\`### \`(H3)、\`- [ ] \`(待办)、\`- [x] \`(已完成)、\\\`...\\\`(代码)、\`---\`(分隔线)
|
|
507
|
+
- 前缀:\`# \`(H1)、\`## \`(H2)、\`### \`(H3)、\`- [ ] \`(待办)、\`- [x] \`(已完成)、\`> \`(引用块)、\`1. \`(有序列表)、\\\`...\\\`(代码)、\`---\`(分隔线)
|
|
506
508
|
|
|
507
509
|
### 元数据标记
|
|
508
510
|
|
|
@@ -537,7 +539,7 @@ tags, sources, positionAmongstSiblings, portalDirectlyIncludedRem
|
|
|
537
539
|
新增行(无 remId 注释的行)在 newStr 中出现时,会被创建为新的 Rem。格式选项:
|
|
538
540
|
|
|
539
541
|
- 纯文本行:\`新内容\`
|
|
540
|
-
- 带前缀:\`# 新标题\`、\`- [ ]
|
|
542
|
+
- 带前缀:\`# 新标题\`、\`- [ ] 新待办\`、\`> 引用内容\`、\`1. 列表项\`
|
|
541
543
|
- 带箭头:\`问题 → 答案\`、\`概念 ↔ 定义\`、\`题目 ↓\`
|
|
542
544
|
- 带元数据注释(metadata-only,无 remId):\`新行 <!--type:concept doc-->\`
|
|
543
545
|
- Portal 行:\`<!--portal refs:id1,id2-->\`
|
|
@@ -71,7 +71,8 @@ export function registerEditTools(server) {
|
|
|
71
71
|
'\\n4. 重排:调换同级行的顺序' +
|
|
72
72
|
'\\n执行顺序:Create → Move → Reorder → Delete' +
|
|
73
73
|
'\\n\\n新增行格式:' +
|
|
74
|
-
'\\n- Markdown 前缀:# / ## / ### / - [ ] / - [x] / `代码` / ---' +
|
|
74
|
+
'\\n- Markdown 前缀:# / ## / ### / - [ ] / - [x] / > / 1. / `代码` / ---' +
|
|
75
|
+
'\\n ⚠️ 有序列表必须用 `1. `(Lazy Numbering):RemNote 自动编号,不要写 `2. ` `3. ` 等。`2.`~`9.` 会被容错归一化并返回 templateWarnings 警告,`10.` 及以上不识别为列表。' +
|
|
75
76
|
'\\n- 箭头分隔符(闪卡):→ ← ↔(单行)、↓ ↑ ↕(多行,带 backText 或子节点为答案)' +
|
|
76
77
|
'\\n- 元数据注释(可选):<!--type:concept--> <!--doc--> <!--tag:Name(id)--> 可组合' +
|
|
77
78
|
'\\n- Portal 创建:<!--portal refs:id1,id2--> 或 <!--portal-->(空 Portal)' +
|