@tnotesjs/core 0.6.1 → 0.8.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 (92) hide show
  1. package/commands/BaseCommand.ts +58 -0
  2. package/commands/build/BuildCommand.ts +25 -0
  3. package/commands/build/PreviewCommand.ts +29 -0
  4. package/commands/build/index.ts +8 -0
  5. package/commands/dev/DevCommand.ts +75 -0
  6. package/commands/dev/index.ts +7 -0
  7. package/commands/git/PullCommand.ts +25 -0
  8. package/commands/git/PushCommand.ts +64 -0
  9. package/commands/git/index.ts +8 -0
  10. package/commands/index.ts +11 -0
  11. package/commands/init-sub-repo/InitSubRepoCommand.ts +206 -0
  12. package/commands/init-sub-repo/index.ts +1 -0
  13. package/commands/misc/HelpCommand.ts +104 -0
  14. package/commands/misc/index.ts +7 -0
  15. package/commands/models.ts +87 -0
  16. package/commands/note/CreateNoteCommand.ts +160 -0
  17. package/commands/note/RenameNoteCommand.ts +147 -0
  18. package/commands/note/UpdateNoteConfigCommand.ts +78 -0
  19. package/commands/note/index.ts +9 -0
  20. package/commands/registry.ts +47 -0
  21. package/commands/update/UpdateCommand.ts +219 -0
  22. package/commands/update/index.ts +7 -0
  23. package/commands/update-completed-count/UpdateCompletedCountCommand.ts +208 -0
  24. package/commands/update-completed-count/index.ts +5 -0
  25. package/config/templates.ts +0 -5
  26. package/dist/{chunk-5F5RJ2HV.cjs → chunk-7FEANCT6.cjs} +16 -7
  27. package/dist/chunk-AGVER5MX.cjs +1746 -0
  28. package/dist/{chunk-TJ4527KA.cjs → chunk-BL22KD4V.cjs} +324 -950
  29. package/dist/{chunk-56PKXCOX.js → chunk-GWG75A5M.js} +13 -4
  30. package/dist/{chunk-DUTS75WQ.js → chunk-XNO3PCEH.js} +374 -1000
  31. package/dist/chunk-ZEQS64PE.js +1746 -0
  32. package/dist/cli/index.cjs +76 -155
  33. package/dist/cli/index.js +10 -89
  34. package/dist/markdown/index.cjs +8 -12
  35. package/dist/markdown/index.d.cts +1 -1
  36. package/dist/markdown/index.d.ts +1 -1
  37. package/dist/markdown/index.js +7 -11
  38. package/dist/{types-CwBWwNVv.d.ts → types-C_d0fFeD.d.ts} +8 -1
  39. package/dist/{types-CpsEy8lA.d.cts → types-MRBGgJTX.d.cts} +8 -1
  40. package/dist/vitepress/config/index.cjs +402 -178
  41. package/dist/vitepress/config/index.js +392 -168
  42. package/dist/workspace/index.cjs +4 -1202
  43. package/dist/workspace/index.d.cts +2 -2
  44. package/dist/workspace/index.d.ts +2 -2
  45. package/dist/workspace/index.js +4 -1202
  46. package/markdown/components.ts +86 -0
  47. package/markdown/index.ts +17 -0
  48. package/markdown/noteFormatter.test.ts +44 -0
  49. package/markdown/noteFormatter.ts +237 -0
  50. package/package.json +7 -3
  51. package/services/file-watcher/folderChangeHandler.ts +19 -15
  52. package/services/file-watcher/globalUpdateCoordinator.ts +21 -27
  53. package/services/file-watcher/service.ts +1 -6
  54. package/services/index.ts +0 -1
  55. package/services/note/service.ts +4 -6
  56. package/services/readme/service.ts +11 -18
  57. package/services/reconcileToc.ts +20 -0
  58. package/utils/index.ts +0 -9
  59. package/{services/toc → utils}/moveTocInside.test.ts +1 -1
  60. package/vitepress/components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue +9 -18
  61. package/vitepress/components/EnWordList/EnWordList.vue +16 -662
  62. package/vitepress/components/Footprints/Footprints.vue +15 -537
  63. package/vitepress/components/Mermaid/Mermaid.vue +13 -588
  64. package/vitepress/components/MindmapPreview/MindmapPreview.vue +12 -434
  65. package/vitepress/components/MindmapPreview/markdown.ts +1 -1
  66. package/vitepress/components/NotesTable/NotesTable.vue +11 -130
  67. package/vitepress/components/constants.ts +2 -2
  68. package/vitepress/components/sidebar.data.ts +8 -5
  69. package/vitepress/configs/markdown.config.ts +170 -26
  70. package/vitepress/plugins/sidebarStructurePlugin.ts +242 -145
  71. package/vitepress/theme/index.ts +9 -13
  72. package/vitepress/theme/styles/base.scss +15 -0
  73. package/workspace/atomic.ts +113 -0
  74. package/workspace/errors.ts +27 -0
  75. package/workspace/index.ts +40 -0
  76. package/workspace/mutationQueue.ts +28 -0
  77. package/workspace/paths.ts +64 -0
  78. package/workspace/reconcile.test.ts +300 -0
  79. package/workspace/reconcile.ts +95 -0
  80. package/workspace/scanner.ts +292 -0
  81. package/workspace/types.ts +224 -0
  82. package/workspace/workspace.test.ts +333 -0
  83. package/workspace/workspace.ts +1020 -0
  84. package/dist/chunk-3R7QSABB.cjs +0 -502
  85. package/dist/chunk-CZXRQPFJ.js +0 -11
  86. package/dist/chunk-HXED7KVT.cjs +0 -11
  87. package/dist/chunk-U6IBLREL.js +0 -502
  88. package/services/toc/index.ts +0 -5
  89. package/services/toc/service.ts +0 -759
  90. package/utils/migrateReadmeToToc.test.ts +0 -111
  91. package/utils/migrateReadmeToToc.ts +0 -135
  92. package/vitepress/components/EnWordList/RightClickMenu.vue +0 -93
@@ -5,15 +5,16 @@
5
5
 
6
6
 
7
7
 
8
-
9
- var _chunkTJ4527KAcjs = require('../../chunk-TJ4527KA.cjs');
8
+ var _chunkBL22KD4Vcjs = require('../../chunk-BL22KD4V.cjs');
10
9
 
11
10
 
12
11
  var _chunkMZIXIY2Ycjs = require('../../chunk-MZIXIY2Y.cjs');
13
- require('../../chunk-3R7QSABB.cjs');
14
12
 
15
13
 
16
- var _chunkHXED7KVTcjs = require('../../chunk-HXED7KVT.cjs');
14
+ var _chunkAGVER5MXcjs = require('../../chunk-AGVER5MX.cjs');
15
+
16
+
17
+ var _chunk7FEANCT6cjs = require('../../chunk-7FEANCT6.cjs');
17
18
 
18
19
  // vitepress/config/index.ts
19
20
  var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
@@ -62,12 +63,10 @@ function getHeadConfig(config, githubPageUrl) {
62
63
  }
63
64
 
64
65
  // vitepress/configs/markdown.config.ts
65
-
66
66
  var _markdownitcontainer = require('markdown-it-container'); var _markdownitcontainer2 = _interopRequireDefault(_markdownitcontainer);
67
67
  var _markdownitlinkattributes = require('markdown-it-link-attributes'); var _markdownitlinkattributes2 = _interopRequireDefault(_markdownitlinkattributes);
68
68
  var _markdownittasklists = require('markdown-it-task-lists'); var _markdownittasklists2 = _interopRequireDefault(_markdownittasklists);
69
69
 
70
-
71
70
  // vitepress/components/MindmapPreview/markdown.ts
72
71
  function cleanHeadingText(value) {
73
72
  return value.trim().replace(/\s+#+\s*$/, "").trim();
@@ -89,19 +88,6 @@ function parseMindmapFence(openLine) {
89
88
  }
90
89
  return options;
91
90
  }
92
- function parseMindmapReference(line) {
93
- const match = line.trim().match(/^<<<\s+(.+?)\s*$/);
94
- if (!match) return null;
95
- let rest = match[1].trim();
96
- let title;
97
- const titleMatch = rest.match(/\s+\[([^\]]+)\]\s*$/);
98
- if (titleMatch) {
99
- title = cleanHeadingText(titleMatch[1]) || void 0;
100
- rest = rest.slice(0, titleMatch.index).trim();
101
- }
102
- const path6 = rest.replace(/^(?:"([\s\S]*)"|'([\s\S]*)')$/, "$1$2").trim();
103
- return path6 ? { path: path6, title } : null;
104
- }
105
91
  function normalizeMindmapMarkdown(source, options = {}) {
106
92
  const lines = source.replace(/\r\n?/g, "\n").split("\n");
107
93
  let existingTitle = "";
@@ -124,6 +110,79 @@ ${body.join("\n")}
124
110
  `;
125
111
  }
126
112
 
113
+ // node_modules/.pnpm/@tnotesjs+ui@0.1.1_vue@3.5.31_typescript@5.9.3_/node_modules/@tnotesjs/ui/src/components/Footprints/parse.ts
114
+ function parseFootprintsDatetime(meta) {
115
+ const m = meta.trim().match(
116
+ /^(\d{4})-(\d{1,2})-(\d{1,2})(?:\s+(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?)?$/
117
+ );
118
+ if (!m) return [];
119
+ const parts = [Number(m[1]), Number(m[2]), Number(m[3])];
120
+ if (m[4] !== void 0) {
121
+ parts.push(Number(m[4]), Number(m[5]));
122
+ if (m[6] !== void 0) parts.push(Number(m[6]));
123
+ }
124
+ return parts;
125
+ }
126
+ function parseFootprintsSource(source) {
127
+ const normalized = source.replace(/\r\n?/g, "\n");
128
+ const lines = normalized.split("\n");
129
+ const open = _optionalChain([lines, 'access', _8 => _8[0], 'optionalAccess', _9 => _9.match, 'call', _10 => _10(/^ {0,3}:{3,}\s*footprints(?:\s+(.*))?$/i)]);
130
+ const times = parseFootprintsDatetime((_nullishCoalesce(_optionalChain([open, 'optionalAccess', _11 => _11[1]]), () => ( ""))).trim());
131
+ let end = lines.length - 1;
132
+ while (end > 0 && !/^ {0,3}:{3,}\s*$/.test(lines[end])) end -= 1;
133
+ const bodyLines = lines.slice(1, end);
134
+ const paragraphs = [];
135
+ const images = [];
136
+ let otherInfo = "";
137
+ let buf = [];
138
+ let inOther = false;
139
+ const flush = () => {
140
+ const text = buf.join("\n").trim();
141
+ buf = [];
142
+ if (!text) return;
143
+ if (inOther) {
144
+ otherInfo = otherInfo ? `${otherInfo}
145
+ ${text}` : text;
146
+ return;
147
+ }
148
+ const imgOnly = text.match(/^!\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)$/);
149
+ if (imgOnly) {
150
+ images.push(imgOnly[2]);
151
+ return;
152
+ }
153
+ const parts = text.split("\n");
154
+ let allImg = true;
155
+ const blockImgs = [];
156
+ for (const line of parts) {
157
+ const m = line.trim().match(/^!\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)$/);
158
+ if (m) blockImgs.push(m[2]);
159
+ else if (line.trim()) {
160
+ allImg = false;
161
+ break;
162
+ }
163
+ }
164
+ if (allImg && blockImgs.length) {
165
+ images.push(...blockImgs);
166
+ return;
167
+ }
168
+ paragraphs.push(text);
169
+ };
170
+ for (const line of bodyLines) {
171
+ if (line.trim() === "---") {
172
+ flush();
173
+ inOther = true;
174
+ continue;
175
+ }
176
+ if (line.trim() === "") {
177
+ flush();
178
+ continue;
179
+ }
180
+ buf.push(line);
181
+ }
182
+ flush();
183
+ return { times, paragraphs, images, otherInfo };
184
+ }
185
+
127
186
  // vitepress/configs/markdown.config.ts
128
187
  function esc(s = "") {
129
188
  return s.replace(
@@ -141,11 +200,14 @@ var simpleMermaidMarkdown = (md) => {
141
200
  const fence = md.renderer.rules.fence ? md.renderer.rules.fence.bind(md.renderer.rules) : () => "";
142
201
  md.renderer.rules.fence = (tokens, index, options, env, slf) => {
143
202
  const token = tokens[index];
144
- if (token.info.trim() === "mermaid") {
203
+ const parts = token.info.trim().split(/\s+/).filter(Boolean);
204
+ if (parts[0] === "mermaid") {
145
205
  try {
206
+ const centered = parts.slice(1).some((part) => part.toLowerCase() === "center");
146
207
  const key = `mermaid-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
147
208
  const content = token.content;
148
- return `<Mermaid id="${key}" graph="${encodeURIComponent(content)}" />`;
209
+ const centerAttr = centered ? ' :center="true"' : "";
210
+ return `<Mermaid id="${key}" graph="${encodeURIComponent(content)}"${centerAttr} />`;
149
211
  } catch (err) {
150
212
  return `<pre>${err}</pre>`;
151
213
  }
@@ -163,28 +225,14 @@ function configureMindmapFence(md) {
163
225
  const info = token.info.trim();
164
226
  const fenceOptions = parseMindmapFence(info);
165
227
  if (!fenceOptions) return fence(tokens, index, options, env, slf);
166
- let content = token.content;
167
- const firstNonEmptyLine = _nullishCoalesce(content.split("\n").find((line) => line.trim()), () => ( ""));
168
- const reference = parseMindmapReference(firstNonEmptyLine);
169
- if (reference) {
170
- const possibleRel = _optionalChain([env, 'optionalAccess', _8 => _8.relativePath]) || _optionalChain([env, 'optionalAccess', _9 => _9.path]) || _optionalChain([env, 'optionalAccess', _10 => _10.filePath]) || _optionalChain([env, 'optionalAccess', _11 => _11.file]) || "";
171
- const refFullPath = _path2.default.isAbsolute(reference.path) ? reference.path : _path2.default.resolve(process.cwd(), possibleRel ? _path2.default.dirname(possibleRel) : "", reference.path);
172
- try {
173
- content = _fs2.default.readFileSync(refFullPath, "utf8");
174
- } catch (error) {
175
- const message = error instanceof Error ? error.message : String(error);
176
- content = `- Failed to load referenced file: ${reference.path}
177
- - Error: ${message}`;
178
- }
179
- }
180
- content = normalizeMindmapMarkdown(content, {
181
- title: fenceOptions.title || _optionalChain([reference, 'optionalAccess', _12 => _12.title])
228
+ const content = normalizeMindmapMarkdown(token.content, {
229
+ title: fenceOptions.title
182
230
  });
183
231
  const props = [
184
232
  `content="${encodeURIComponent(content.trim())}"`,
185
233
  fenceOptions.initialExpandLevel === void 0 ? "" : `:initialExpandLevel="${fenceOptions.initialExpandLevel}"`
186
234
  ].filter(Boolean).join(" ");
187
- return `<MindmapPreview ${props}></MindmapPreview>
235
+ return `<Mindmap ${props}></Mindmap>
188
236
  `;
189
237
  };
190
238
  }
@@ -246,6 +294,114 @@ function configureSwiperContainer(md) {
246
294
  }
247
295
  });
248
296
  }
297
+ function escapeHtmlText(s) {
298
+ return s.replace(
299
+ /[&<>"']/g,
300
+ (ch) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[ch]
301
+ );
302
+ }
303
+ function extractFootprintsPayloadFromTokens(tokens, idx) {
304
+ const meta = String(tokens[idx].info || "").trim().replace(/^footprints\s*/i, "");
305
+ const times = parseFootprintsDatetime(meta);
306
+ const paragraphs = [];
307
+ const images = [];
308
+ let otherInfo = "";
309
+ let inOther = false;
310
+ for (let i = idx + 1; i < tokens.length; i++) {
311
+ const t = tokens[i];
312
+ if (t.type === "container_footprints_close") break;
313
+ if (t.type !== "inline") continue;
314
+ const childImgs = [];
315
+ if (Array.isArray(t.children)) {
316
+ for (const c of t.children) {
317
+ if (c.type === "image") {
318
+ const src = _optionalChain([c, 'access', _12 => _12.attrGet, 'optionalCall', _13 => _13("src")]) || _optionalChain([c, 'access', _14 => _14.attrs, 'optionalAccess', _15 => _15.find, 'call', _16 => _16((a) => a[0] === "src"), 'optionalAccess', _17 => _17[1]]);
319
+ if (src) childImgs.push(src);
320
+ }
321
+ }
322
+ }
323
+ const content = String(t.content || "").trim();
324
+ if (content === "---") {
325
+ inOther = true;
326
+ continue;
327
+ }
328
+ if (childImgs.length) {
329
+ const withoutImgs = content.replace(/!\[[^\]]*\]\([^)]+\)/g, "").trim();
330
+ if (!withoutImgs) {
331
+ images.push(...childImgs);
332
+ continue;
333
+ }
334
+ }
335
+ const imgOnly = content.match(/^!\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)$/);
336
+ if (imgOnly) {
337
+ images.push(imgOnly[2]);
338
+ continue;
339
+ }
340
+ if (!content) continue;
341
+ if (inOther) otherInfo = otherInfo ? `${otherInfo}
342
+ ${content}` : content;
343
+ else paragraphs.push(content);
344
+ }
345
+ return { times, paragraphs, images, otherInfo };
346
+ }
347
+ function configureFootprintsContainer(md) {
348
+ md.use(_markdownitcontainer2.default, "footprints", {
349
+ validate: (params) => /^footprints(\s|$)/i.test(params.trim()),
350
+ render: (tokens, idx, _opts, env) => {
351
+ if (tokens[idx].nesting !== 1) return "";
352
+ let payload = extractFootprintsPayloadFromTokens(tokens, idx);
353
+ const startLine = _nullishCoalesce(_optionalChain([tokens, 'access', _18 => _18[idx], 'access', _19 => _19.map, 'optionalAccess', _20 => _20[0]]), () => ( 0));
354
+ let endLine = startLine;
355
+ for (let i = idx + 1; i < tokens.length; i++) {
356
+ if (tokens[i].type === "container_footprints_close") {
357
+ endLine = _nullishCoalesce(_optionalChain([tokens, 'access', _21 => _21[i], 'access', _22 => _22.map, 'optionalAccess', _23 => _23[0]]), () => ( endLine));
358
+ break;
359
+ }
360
+ }
361
+ const raw = String(_nullishCoalesce(_nullishCoalesce(_optionalChain([env, 'optionalAccess', _24 => _24.src]), () => ( _optionalChain([env, 'optionalAccess', _25 => _25.source]))), () => ( "")));
362
+ if (raw && endLine > startLine) {
363
+ const slice = raw.split(/\r?\n/).slice(startLine, endLine + 1).join("\n");
364
+ const fromSource = parseFootprintsSource(
365
+ slice.includes(":::") ? slice : `::: ${tokens[idx].info}
366
+ ${slice}
367
+ :::`
368
+ );
369
+ if (!payload.paragraphs.length && fromSource.paragraphs.length) {
370
+ payload = { ...payload, paragraphs: fromSource.paragraphs };
371
+ }
372
+ if (!payload.images.length && fromSource.images.length) {
373
+ payload = { ...payload, images: fromSource.images };
374
+ }
375
+ if (!payload.otherInfo && fromSource.otherInfo) {
376
+ payload = { ...payload, otherInfo: fromSource.otherInfo };
377
+ }
378
+ if (!payload.times.length && fromSource.times.length) {
379
+ payload = { ...payload, times: fromSource.times };
380
+ }
381
+ }
382
+ for (let i = idx + 1; i < tokens.length; i++) {
383
+ if (tokens[i].type === "container_footprints_close") break;
384
+ tokens[i].hidden = true;
385
+ tokens[i].content = "";
386
+ if (Array.isArray(tokens[i].children)) {
387
+ for (const child of tokens[i].children) {
388
+ child.hidden = true;
389
+ child.content = "";
390
+ }
391
+ tokens[i].children = [];
392
+ }
393
+ }
394
+ const enc = (value) => encodeURIComponent(JSON.stringify(value)).replace(/'/g, "%27");
395
+ const bindExpr = (value) => "JSON.parse(decodeURIComponent('" + enc(value) + "'))";
396
+ const imageSlot = payload.images.map((src, i) => {
397
+ return '<img src="' + escapeHtmlText(src) + '" @click="openModal(' + String(i) + ')" />';
398
+ }).join("\n");
399
+ const openTag = '<Footprints :times="' + bindExpr(payload.times) + '" :paragraphs="' + bindExpr(payload.paragraphs) + '" :other-info="' + bindExpr(payload.otherInfo) + '">';
400
+ if (!payload.images.length) return openTag + "</Footprints>\n";
401
+ return openTag + '\n<template #image-list="{ openModal }">\n' + imageSlot + "\n</template>\n</Footprints>\n";
402
+ }
403
+ });
404
+ }
249
405
  function getMarkdownConfig() {
250
406
  const markdown = {
251
407
  lineNumbers: true,
@@ -265,9 +421,10 @@ function getMarkdownConfig() {
265
421
  }
266
422
  });
267
423
  configureSwiperContainer(md);
424
+ configureFootprintsContainer(md);
268
425
  },
269
426
  anchor: {
270
- slugify: _chunkHXED7KVTcjs.generateAnchor
427
+ slugify: _chunk7FEANCT6cjs.generateAnchor
271
428
  },
272
429
  image: {
273
430
  lazyLoading: true
@@ -500,7 +657,7 @@ function buildProgressPlugin(options = {}) {
500
657
  globalLastOutputTime = 0;
501
658
  globalTransformEndTime = 0;
502
659
  globalLastHookTime = Date.now();
503
- globalOutDir = _optionalChain([config, 'access', _13 => _13.build, 'optionalAccess', _14 => _14.outDir]) || "dist";
660
+ globalOutDir = _optionalChain([config, 'access', _26 => _26.build, 'optionalAccess', _27 => _27.outDir]) || "dist";
504
661
  interceptOutput();
505
662
  globalStallTimer = setInterval(() => {
506
663
  if (!globalIsBuilding || globalLastPercent <= 0 || globalLastPercent >= 0.98)
@@ -673,7 +830,7 @@ function getNoteByConfigIdPlugin() {
673
830
  name: "tnotes-get-note-by-config-id",
674
831
  configureServer(server) {
675
832
  server.middlewares.use(async (req, res, next) => {
676
- if (_optionalChain([req, 'access', _15 => _15.url, 'optionalAccess', _16 => _16.startsWith, 'call', _17 => _17("/__tnotes_get_note?")]) && req.method === "GET") {
833
+ if (_optionalChain([req, 'access', _28 => _28.url, 'optionalAccess', _29 => _29.startsWith, 'call', _30 => _30("/__tnotes_get_note?")]) && req.method === "GET") {
677
834
  try {
678
835
  const url = new URL(req.url, `http://${req.headers.host}`);
679
836
  const configId = url.searchParams.get("configId");
@@ -688,7 +845,7 @@ function getNoteByConfigIdPlugin() {
688
845
  );
689
846
  return;
690
847
  }
691
- const noteIndexCache = _chunkTJ4527KAcjs.NoteIndexCache.getInstance();
848
+ const noteIndexCache = _chunkBL22KD4Vcjs.NoteIndexCache.getInstance();
692
849
  if (!noteIndexCache.isInitialized()) {
693
850
  res.statusCode = 503;
694
851
  res.setHeader("Content-Type", "application/json");
@@ -729,11 +886,11 @@ function getNoteByConfigIdPlugin() {
729
886
  }
730
887
  })
731
888
  );
732
- _chunkTJ4527KAcjs.logger.debug(
889
+ _chunkBL22KD4Vcjs.logger.debug(
733
890
  `\u67E5\u8BE2\u7B14\u8BB0: configId=${configId}, noteIndex=${noteItem.noteIndex}`
734
891
  );
735
892
  } catch (error) {
736
- _chunkTJ4527KAcjs.logger.error("\u67E5\u8BE2\u7B14\u8BB0\u5931\u8D25:", error);
893
+ _chunkBL22KD4Vcjs.logger.error("\u67E5\u8BE2\u7B14\u8BB0\u5931\u8D25:", error);
737
894
  res.statusCode = 500;
738
895
  res.setHeader("Content-Type", "application/json");
739
896
  res.end(
@@ -783,7 +940,7 @@ function getDocIdFromFile(input) {
783
940
  ) ? _path2.default.win32 : _path2.default;
784
941
  const absoluteFile = pathApi.isAbsolute(input.absoluteOrRelativeFile) ? input.absoluteOrRelativeFile : pathApi.join(input.srcDir, input.absoluteOrRelativeFile);
785
942
  let relFile = slash(pathApi.relative(input.srcDir, absoluteFile));
786
- if (_optionalChain([input, 'access', _18 => _18.rewrites, 'optionalAccess', _19 => _19[relFile]])) {
943
+ if (_optionalChain([input, 'access', _31 => _31.rewrites, 'optionalAccess', _32 => _32[relFile]])) {
787
944
  relFile = input.rewrites[relFile];
788
945
  }
789
946
  let id = slash(_path2.default.posix.join(input.base, relFile));
@@ -812,8 +969,8 @@ function* splitPageIntoSections(html) {
812
969
  const level = parseInt(result[i], 10) - 1;
813
970
  const heading = result[i + 1];
814
971
  const headingResult = headingContentRegex.exec(heading);
815
- const title = clearHtmlTags(_nullishCoalesce(_optionalChain([headingResult, 'optionalAccess', _20 => _20[1]]), () => ( ""))).trim();
816
- const anchor = _nullishCoalesce(_optionalChain([headingResult, 'optionalAccess', _21 => _21[2]]), () => ( ""));
972
+ const title = clearHtmlTags(_nullishCoalesce(_optionalChain([headingResult, 'optionalAccess', _33 => _33[1]]), () => ( ""))).trim();
973
+ const anchor = _nullishCoalesce(_optionalChain([headingResult, 'optionalAccess', _34 => _34[2]]), () => ( ""));
817
974
  const content = result[i + 2];
818
975
  if (!title || !content) continue;
819
976
  let titles = parentTitles.slice(0, level);
@@ -836,7 +993,7 @@ function getLocaleForPath(site, page) {
836
993
  if (normalizedPage.startsWith(normalizedPrefix)) {
837
994
  return localePath;
838
995
  }
839
- if (_optionalChain([localeConfig, 'optionalAccess', _22 => _22.lang]) && normalizedPage === prefix.replace(/\/$/, "")) {
996
+ if (_optionalChain([localeConfig, 'optionalAccess', _35 => _35.lang]) && normalizedPage === prefix.replace(/\/$/, "")) {
840
997
  return localePath;
841
998
  }
842
999
  }
@@ -860,13 +1017,13 @@ async function renderPageHtml(siteConfig, md, absoluteFile) {
860
1017
  cleanUrls: _nullishCoalesce(siteConfig.cleanUrls, () => ( false)),
861
1018
  frontmatter: {}
862
1019
  };
863
- const options = _nullishCoalesce(_optionalChain([siteConfig, 'access', _23 => _23.site, 'access', _24 => _24.themeConfig, 'optionalAccess', _25 => _25.search, 'optionalAccess', _26 => _26.options]), () => ( {}));
1020
+ const options = _nullishCoalesce(_optionalChain([siteConfig, 'access', _36 => _36.site, 'access', _37 => _37.themeConfig, 'optionalAccess', _38 => _38.search, 'optionalAccess', _39 => _39.options]), () => ( {}));
864
1021
  const mdRaw = await _promises2.default.readFile(absoluteFile, "utf-8");
865
1022
  if (options._render) {
866
1023
  return await options._render(mdRaw, env, md);
867
1024
  }
868
1025
  const html = md.render(mdRaw, env);
869
- return _optionalChain([env, 'access', _27 => _27.frontmatter, 'optionalAccess', _28 => _28.search]) === false ? "" : html;
1026
+ return _optionalChain([env, 'access', _40 => _40.frontmatter, 'optionalAccess', _41 => _41.search]) === false ? "" : html;
870
1027
  }
871
1028
  async function indexPage(siteConfig, md, page, index) {
872
1029
  const absoluteFile = _path2.default.join(siteConfig.srcDir, page);
@@ -898,7 +1055,7 @@ async function buildLocalSearchIndexSnapshot(siteConfig, md) {
898
1055
  siteConfig.userConfig,
899
1056
  siteConfig.logger
900
1057
  );
901
- const options = _nullishCoalesce(_optionalChain([siteConfig, 'access', _29 => _29.site, 'access', _30 => _30.themeConfig, 'optionalAccess', _31 => _31.search, 'optionalAccess', _32 => _32.options]), () => ( {}));
1058
+ const options = _nullishCoalesce(_optionalChain([siteConfig, 'access', _42 => _42.site, 'access', _43 => _43.themeConfig, 'optionalAccess', _44 => _44.search, 'optionalAccess', _45 => _45.options]), () => ( {}));
902
1059
  const indexByLocale = /* @__PURE__ */ new Map();
903
1060
  for (const page of pages) {
904
1061
  const locale = getLocaleForPath(siteConfig.site, page);
@@ -907,7 +1064,7 @@ async function buildLocalSearchIndexSnapshot(siteConfig, md) {
907
1064
  index = new (0, _minisearch2.default)({
908
1065
  fields: ["title", "titles", "text"],
909
1066
  storeFields: ["title", "titles"],
910
- ..._optionalChain([options, 'access', _33 => _33.miniSearch, 'optionalAccess', _34 => _34.options])
1067
+ ..._optionalChain([options, 'access', _46 => _46.miniSearch, 'optionalAccess', _47 => _47.options])
911
1068
  });
912
1069
  indexByLocale.set(locale, index);
913
1070
  }
@@ -1172,7 +1329,7 @@ function localSearchReindexPlugin() {
1172
1329
 
1173
1330
  // vitepress/plugins/renameNotePlugin.ts
1174
1331
  function renameNotePlugin() {
1175
- const renameCommand = new (0, _chunkTJ4527KAcjs.RenameNoteCommand)();
1332
+ const renameCommand = new (0, _chunkBL22KD4Vcjs.RenameNoteCommand)();
1176
1333
  return {
1177
1334
  name: "tnotes-rename-note",
1178
1335
  configureServer(server) {
@@ -1249,58 +1406,90 @@ function normalizeCount(value) {
1249
1406
  }
1250
1407
  return count;
1251
1408
  }
1252
- function getCreatedNotePayload(notes) {
1253
- return notes.map((note) => ({
1254
- index: note.index,
1255
- dirName: note.dirName,
1256
- link: `/notes/${encodeURIComponent(note.dirName)}/README`
1257
- }));
1258
- }
1259
- function buildNoteReadmeLink(note) {
1260
- return `/notes/${encodeURIComponent(note.dirName)}/README`;
1261
- }
1262
- function resolveDeleteRedirectUrl(noteService, previousNoteIndex) {
1263
- if (!previousNoteIndex) return "/";
1264
- const previousNote = noteService.getNoteByIndex(previousNoteIndex);
1265
- if (!previousNote) return "/";
1266
- return buildNoteReadmeLink(previousNote);
1409
+ function buildNoteReadmeLink(dirName) {
1410
+ return `/notes/${encodeURIComponent(dirName)}/README`;
1267
1411
  }
1268
1412
  async function withSuspendedWatcher(task) {
1269
- const watcher = _chunkTJ4527KAcjs.FileWatcherService.getInstance();
1413
+ const watcher = _chunkBL22KD4Vcjs.FileWatcherService.getInstance();
1270
1414
  try {
1271
- _optionalChain([watcher, 'optionalAccess', _35 => _35.suspend, 'call', _36 => _36()]);
1415
+ _optionalChain([watcher, 'optionalAccess', _48 => _48.suspend, 'call', _49 => _49()]);
1272
1416
  return await task();
1273
1417
  } finally {
1274
- _optionalChain([watcher, 'optionalAccess', _37 => _37.unsuspend, 'call', _38 => _38()]);
1418
+ _optionalChain([watcher, 'optionalAccess', _50 => _50.unsuspend, 'call', _51 => _51()]);
1275
1419
  }
1276
1420
  }
1277
- function sidebarStructurePlugin() {
1278
- const noteService = _chunkTJ4527KAcjs.NoteService.getInstance();
1279
- const tocService = _chunkTJ4527KAcjs.TocService.getInstance();
1280
- async function createNotes(count) {
1281
- const notes = [];
1282
- const usedIndexes = /* @__PURE__ */ new Set();
1283
- for (const note of noteService.getAllNotes()) {
1284
- const index = parseInt(note.index, 10);
1285
- if (!isNaN(index)) {
1286
- usedIndexes.add(index);
1421
+ function collectRefs(snapshot) {
1422
+ const byLine = /* @__PURE__ */ new Map();
1423
+ const orderedIndexes = [];
1424
+ let order = 0;
1425
+ const walk = (nodes) => {
1426
+ for (const node of nodes) {
1427
+ if (node.kind === "folder") {
1428
+ walk(node.children);
1429
+ continue;
1287
1430
  }
1288
- }
1289
- for (let i = 0; i < count; i++) {
1290
- const note = await noteService.createNote({
1291
- title: "new",
1292
- usedIndexes
1431
+ const subtree = [];
1432
+ const collect = (n) => {
1433
+ if (n.kind === "note") subtree.push(n.noteIndex);
1434
+ for (const child of n.children) collect(child);
1435
+ };
1436
+ collect(node);
1437
+ byLine.set(node.tocLineIndex, {
1438
+ tocLineIndex: node.tocLineIndex,
1439
+ ref: { type: "note", noteUuid: "" },
1440
+ subtreeIndexes: subtree,
1441
+ orderIndex: order
1293
1442
  });
1294
- const index = parseInt(note.index, 10);
1295
- if (!isNaN(index)) {
1296
- usedIndexes.add(index);
1297
- }
1298
- notes.push(note);
1443
+ orderedIndexes.push(...subtree);
1444
+ order += 1;
1299
1445
  }
1300
- return notes;
1446
+ };
1447
+ walk(snapshot.toc);
1448
+ return { byLine, orderedIndexes };
1449
+ }
1450
+ function noteUuidForIndex(snapshot, index) {
1451
+ const note = snapshot.notes.find((item) => item.index === index);
1452
+ if (!note) throw new Error(`\u672A\u627E\u5230\u7B14\u8BB0: ${index}`);
1453
+ return note.uuid;
1454
+ }
1455
+ function previousNoteIndex(snapshot, entry) {
1456
+ if (!entry) return null;
1457
+ const entries = [...collectRefs(snapshot).byLine.values()].sort(
1458
+ (a, b) => a.orderIndex - b.orderIndex
1459
+ );
1460
+ let cursor = 0;
1461
+ for (const item of entries) {
1462
+ if (item === entry) return cursor > 0 ? collectRefs(snapshot).orderedIndexes[cursor - 1] : null;
1463
+ cursor += item.subtreeIndexes.length;
1301
1464
  }
1465
+ return null;
1466
+ }
1467
+ function isNoteInSubtree(snapshot, lineIndex, noteIndex) {
1468
+ const entry = collectRefs(snapshot).byLine.get(lineIndex);
1469
+ return entry ? entry.subtreeIndexes.includes(noteIndex) : false;
1470
+ }
1471
+ function folderPathAtLine(snapshot, lineIndex) {
1472
+ const result = [];
1473
+ const walk = (nodes, path5) => {
1474
+ for (const node of nodes) {
1475
+ if (node.kind === "folder") {
1476
+ if (node.tocLineIndex === lineIndex) {
1477
+ result.push(...[...path5, node.title]);
1478
+ return true;
1479
+ }
1480
+ if (walk(node.children, [...path5, node.title])) return true;
1481
+ }
1482
+ }
1483
+ return false;
1484
+ };
1485
+ walk(snapshot.toc, []);
1486
+ if (result.length === 0) throw new Error(`\u672A\u627E\u5230\u76EE\u5F55\u884C: ${lineIndex}`);
1487
+ return result;
1488
+ }
1489
+ function sidebarStructurePlugin() {
1490
+ const workspace = _chunkAGVER5MXcjs.createWorkspace.call(void 0, { rootPath: _chunkBL22KD4Vcjs.ROOT_DIR_PATH });
1302
1491
  async function refreshTocAndSidebar() {
1303
- await tocService.regenerateSidebar();
1492
+ await workspace.toc.reconcileFromFiles();
1304
1493
  }
1305
1494
  return {
1306
1495
  name: "tnotes-sidebar-structure",
@@ -1327,22 +1516,27 @@ function sidebarStructurePlugin() {
1327
1516
  try {
1328
1517
  const data = await readJsonBody(req);
1329
1518
  const result = await withSuspendedWatcher(async () => {
1519
+ const snapshot = await workspace.inspect();
1330
1520
  if (pathname === "/__tnotes_sidebar_delete_note") {
1331
1521
  const noteIndex = String(data.noteIndex || "");
1332
1522
  if (!noteIndex) throw new Error("Missing noteIndex");
1333
- const previousNoteIndex = await tocService.getPreviousNoteIndexBeforeDelete(noteIndex);
1334
- await tocService.deleteNoteFromToc(noteIndex);
1335
- await noteService.deleteNote(noteIndex);
1523
+ const refs = collectRefs(snapshot);
1524
+ const deletedRef = [...refs.byLine.values()].find(
1525
+ (item) => item.subtreeIndexes.includes(noteIndex)
1526
+ );
1527
+ const previous = previousNoteIndex(snapshot, deletedRef);
1528
+ await workspace.toc.deleteEntry({
1529
+ entry: { type: "note", noteUuid: noteUuidForIndex(snapshot, noteIndex) },
1530
+ expectedSnapshotRevision: snapshot.revision
1531
+ });
1336
1532
  await refreshTocAndSidebar();
1337
1533
  scheduleNoteSearchReindex("api:delete-note");
1534
+ const redirectDir = previous ? _optionalChain([snapshot, 'access', _52 => _52.notes, 'access', _53 => _53.find, 'call', _54 => _54((item) => item.index === previous), 'optionalAccess', _55 => _55.dirName]) : void 0;
1338
1535
  return {
1339
1536
  success: true,
1340
1537
  sidebarChanged: true,
1341
- redirectUrl: resolveDeleteRedirectUrl(
1342
- noteService,
1343
- previousNoteIndex
1344
- ),
1345
- redirectNoteIndex: previousNoteIndex,
1538
+ redirectUrl: redirectDir ? buildNoteReadmeLink(redirectDir) : "/",
1539
+ redirectNoteIndex: previous,
1346
1540
  deletedNoteIndexes: [noteIndex],
1347
1541
  message: "\u7B14\u8BB0\u5DF2\u5220\u9664"
1348
1542
  };
@@ -1353,22 +1547,26 @@ function sidebarStructurePlugin() {
1353
1547
  throw new Error("Missing tocLineIndex");
1354
1548
  }
1355
1549
  const currentNoteIndex = String(data.currentNoteIndex || "");
1356
- const previousNoteIndex = await tocService.getPreviousNoteIndexBeforeEntryDelete(
1550
+ const inSubtree = currentNoteIndex ? isNoteInSubtree(snapshot, tocLineIndex, currentNoteIndex) : false;
1551
+ const entry = collectRefs(snapshot).byLine.get(tocLineIndex);
1552
+ const previous = previousNoteIndex(snapshot, entry);
1553
+ const preview = await workspace.toc.previewDelete({
1554
+ type: "line",
1357
1555
  tocLineIndex
1358
- );
1359
- const inSubtree = currentNoteIndex && await tocService.isNoteInTocEntrySubtree(
1360
- tocLineIndex,
1361
- currentNoteIndex
1362
- );
1363
- const deletedNoteIndexes = await tocService.deleteTocEntryCascade(tocLineIndex);
1556
+ });
1557
+ await workspace.toc.deleteEntry({
1558
+ entry: { type: "line", tocLineIndex },
1559
+ expectedSnapshotRevision: snapshot.revision
1560
+ });
1364
1561
  await refreshTocAndSidebar();
1365
1562
  scheduleNoteSearchReindex("api:delete-entry");
1563
+ const redirectDir = inSubtree && previous ? _optionalChain([snapshot, 'access', _56 => _56.notes, 'access', _57 => _57.find, 'call', _58 => _58((item) => item.index === previous), 'optionalAccess', _59 => _59.dirName]) : void 0;
1366
1564
  return {
1367
1565
  success: true,
1368
1566
  sidebarChanged: true,
1369
- redirectUrl: inSubtree ? resolveDeleteRedirectUrl(noteService, previousNoteIndex) : void 0,
1370
- redirectNoteIndex: inSubtree ? previousNoteIndex : null,
1371
- deletedNoteIndexes,
1567
+ redirectUrl: redirectDir ? buildNoteReadmeLink(redirectDir) : void 0,
1568
+ redirectNoteIndex: inSubtree ? previous : null,
1569
+ deletedNoteIndexes: preview.notes.map((note) => note.index),
1372
1570
  message: "\u5DF2\u5220\u9664"
1373
1571
  };
1374
1572
  }
@@ -1378,7 +1576,11 @@ function sidebarStructurePlugin() {
1378
1576
  if (!Number.isInteger(tocLineIndex) || tocLineIndex < 0) {
1379
1577
  throw new Error("Missing tocLineIndex");
1380
1578
  }
1381
- await tocService.renameFolderInToc(tocLineIndex, newTitle);
1579
+ await workspace.toc.renameGroup({
1580
+ folderPath: folderPathAtLine(snapshot, tocLineIndex),
1581
+ title: newTitle,
1582
+ expectedSnapshotRevision: snapshot.revision
1583
+ });
1382
1584
  await refreshTocAndSidebar();
1383
1585
  return {
1384
1586
  success: true,
@@ -1387,8 +1589,20 @@ function sidebarStructurePlugin() {
1387
1589
  };
1388
1590
  }
1389
1591
  if (pathname === "/__tnotes_sidebar_reorder") {
1390
- if (data.node_uuid && data.action === "prependChild" && !data.target_uuid) {
1391
- await tocService.prependToRootByNodeId(String(data.node_uuid));
1592
+ const awaitMove = async (source2, target, placement2) => {
1593
+ await workspace.toc.move({
1594
+ source: source2,
1595
+ target,
1596
+ placement: placement2,
1597
+ expectedSnapshotRevision: snapshot.revision
1598
+ });
1599
+ };
1600
+ if (typeof data.node_uuid === "string" && data.action === "prependChild" && !data.target_uuid) {
1601
+ await awaitMove(
1602
+ { type: "note", noteUuid: data.node_uuid },
1603
+ { type: "line", tocLineIndex: 0 },
1604
+ data.placement === "after" ? "after" : "before"
1605
+ );
1392
1606
  await refreshTocAndSidebar();
1393
1607
  return {
1394
1608
  success: true,
@@ -1396,18 +1610,12 @@ function sidebarStructurePlugin() {
1396
1610
  message: "\u6392\u5E8F\u5DF2\u66F4\u65B0"
1397
1611
  };
1398
1612
  }
1399
- if (data.node_uuid && data.target_uuid && (data.action === "moveAfter" || data.action === "prependChild")) {
1400
- if (data.action === "moveAfter") {
1401
- await tocService.moveAfterByNodeId(
1402
- String(data.node_uuid),
1403
- String(data.target_uuid)
1404
- );
1405
- } else {
1406
- await tocService.prependChildByNodeId(
1407
- String(data.node_uuid),
1408
- String(data.target_uuid)
1409
- );
1410
- }
1613
+ if (typeof data.node_uuid === "string" && typeof data.target_uuid === "string" && (data.action === "moveAfter" || data.action === "prependChild")) {
1614
+ await awaitMove(
1615
+ { type: "note", noteUuid: data.node_uuid },
1616
+ { type: "note", noteUuid: data.target_uuid },
1617
+ data.action === "prependChild" ? "inside" : "after"
1618
+ );
1411
1619
  await refreshTocAndSidebar();
1412
1620
  return {
1413
1621
  success: true,
@@ -1420,27 +1628,32 @@ function sidebarStructurePlugin() {
1420
1628
  throw new Error("Missing dragTocLineIndex");
1421
1629
  }
1422
1630
  const placement = data.targetType === "group" || data.placement === "inside" ? "inside" : data.placement === "after" ? "after" : "before";
1631
+ const source = { type: "line", tocLineIndex: dragTocLineIndex };
1423
1632
  if (data.targetTocLineIndex !== void 0 && data.targetTocLineIndex !== null) {
1424
- await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1425
- targetTocLineIndex: Number(data.targetTocLineIndex),
1633
+ await awaitMove(
1634
+ source,
1635
+ { type: "line", tocLineIndex: Number(data.targetTocLineIndex) },
1426
1636
  placement
1427
- });
1637
+ );
1428
1638
  } else if (Array.isArray(data.targetFolderPath) && data.targetFolderPath.length > 0) {
1429
- await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1430
- targetType: "folder",
1431
- targetFolderPath: data.targetFolderPath.map(String),
1639
+ await awaitMove(
1640
+ source,
1641
+ {
1642
+ type: "folder",
1643
+ folderPath: data.targetFolderPath.map(String)
1644
+ },
1432
1645
  placement
1433
- });
1646
+ );
1434
1647
  } else {
1435
- const targetNoteIndex = String(
1648
+ const targetNoteIndex2 = String(
1436
1649
  data.targetNoteIndex || data.targetGroupNoteIndex || ""
1437
1650
  );
1438
- if (!targetNoteIndex) throw new Error("Missing targetNoteIndex");
1439
- await tocService.moveTocEntryByLineIndex(dragTocLineIndex, {
1440
- targetType: "note",
1441
- targetNoteIndex,
1651
+ if (!targetNoteIndex2) throw new Error("Missing targetNoteIndex");
1652
+ await awaitMove(
1653
+ source,
1654
+ { type: "note", noteUuid: noteUuidForIndex(snapshot, targetNoteIndex2) },
1442
1655
  placement
1443
- });
1656
+ );
1444
1657
  }
1445
1658
  await refreshTocAndSidebar();
1446
1659
  return {
@@ -1455,10 +1668,13 @@ function sidebarStructurePlugin() {
1455
1668
  if (!Number.isInteger(parentTocLineIndex) || parentTocLineIndex < 0) {
1456
1669
  throw new Error("Missing parentTocLineIndex");
1457
1670
  }
1458
- await tocService.insertFolderUnderParent(
1459
- parentTocLineIndex,
1460
- title
1461
- );
1671
+ const sibling = collectRefs(snapshot).byLine.get(parentTocLineIndex);
1672
+ if (!sibling) throw new Error("\u672A\u627E\u5230\u76EE\u5F55\u884C");
1673
+ await workspace.toc.createGroup({
1674
+ title,
1675
+ placement: sibling.ref.type === "note" ? { type: "note", targetNoteUuid: sibling.ref.noteUuid, placement: "inside" } : { type: "root", placement: "end" },
1676
+ expectedSnapshotRevision: snapshot.revision
1677
+ });
1462
1678
  await refreshTocAndSidebar();
1463
1679
  return {
1464
1680
  success: true,
@@ -1467,40 +1683,48 @@ function sidebarStructurePlugin() {
1467
1683
  };
1468
1684
  }
1469
1685
  const count = normalizeCount(data.count);
1470
- const notes = await createNotes(count);
1471
- if (data.targetNoteIndex) {
1472
- const placement = data.placement === "after" ? "after" : "before";
1473
- await tocService.insertNotesAroundNote(
1474
- String(data.targetNoteIndex),
1475
- notes,
1476
- placement
1477
- );
1478
- } else if (data.parentTocLineIndex !== void 0 && data.parentTocLineIndex !== null) {
1479
- await tocService.insertNotesUnderTocLine(
1480
- Number(data.parentTocLineIndex),
1481
- notes
1482
- );
1483
- } else if (Array.isArray(data.parentFolderPath) && data.parentFolderPath.length > 0) {
1484
- await tocService.insertNotesUnderFolder(
1485
- data.parentFolderPath.map(String),
1486
- notes
1487
- );
1488
- } else if (data.parentNoteIndex) {
1489
- await tocService.insertNotesUnderParent(
1490
- String(data.parentNoteIndex),
1491
- notes
1492
- );
1493
- } else {
1494
- for (const note of notes) {
1495
- await tocService.appendNoteToToc(note.index);
1686
+ const targetNoteIndex = String(
1687
+ data.targetNoteIndex || data.targetGroupNoteIndex || ""
1688
+ );
1689
+ const parentLine = data.parentTocLineIndex !== void 0 && data.parentTocLineIndex !== null ? Number(data.parentTocLineIndex) : null;
1690
+ const created = [];
1691
+ for (let i = 0; i < count; i++) {
1692
+ let placement;
1693
+ if (targetNoteIndex) {
1694
+ placement = {
1695
+ type: "note",
1696
+ targetNoteUuid: noteUuidForIndex(snapshot, targetNoteIndex),
1697
+ placement: data.placement === "after" ? "after" : "before"
1698
+ };
1699
+ } else if (parentLine !== null) {
1700
+ const sibling = collectRefs(snapshot).byLine.get(parentLine);
1701
+ if (sibling && sibling.ref.type === "note") {
1702
+ placement = {
1703
+ type: "note",
1704
+ targetNoteUuid: sibling.ref.noteUuid,
1705
+ placement: "inside"
1706
+ };
1707
+ }
1496
1708
  }
1709
+ const result2 = await workspace.notes.create({
1710
+ title: "new",
1711
+ placement,
1712
+ expectedSnapshotRevision: snapshot.revision
1713
+ });
1714
+ created.push({
1715
+ index: result2.value.index,
1716
+ dirName: result2.value.dirName
1717
+ });
1497
1718
  }
1498
1719
  await refreshTocAndSidebar();
1499
1720
  scheduleNoteSearchReindex("api:create-notes");
1500
1721
  return {
1501
1722
  success: true,
1502
1723
  sidebarChanged: true,
1503
- createdNotes: getCreatedNotePayload(notes),
1724
+ createdNotes: created.map((note) => ({
1725
+ ...note,
1726
+ link: buildNoteReadmeLink(note.dirName)
1727
+ })),
1504
1728
  message: "\u7B14\u8BB0\u5DF2\u521B\u5EFA"
1505
1729
  };
1506
1730
  });
@@ -1523,7 +1747,7 @@ function updateConfigPlugin() {
1523
1747
  return {
1524
1748
  name: "tnotes-update-config",
1525
1749
  configureServer(server) {
1526
- updateCommand = new (0, _chunkTJ4527KAcjs.UpdateNoteConfigCommand)();
1750
+ updateCommand = new (0, _chunkBL22KD4Vcjs.UpdateNoteConfigCommand)();
1527
1751
  server.middlewares.use(async (req, res, next) => {
1528
1752
  if (req.url === "/__tnotes_update_config" && req.method === "POST") {
1529
1753
  let body = "";
@@ -1603,7 +1827,7 @@ function defineNotesConfig(overrides = {}) {
1603
1827
  getNoteByConfigIdPlugin(),
1604
1828
  fileWatcherBridgePlugin(),
1605
1829
  localSearchReindexPlugin(),
1606
- ..._optionalChain([overrideVite, 'optionalAccess', _39 => _39.plugins]) || []
1830
+ ..._optionalChain([overrideVite, 'optionalAccess', _60 => _60.plugins]) || []
1607
1831
  ],
1608
1832
  server: {
1609
1833
  // 显式同时监听 IPv4 / IPv6,避免 Node 18+ 在 Windows 下偶发只绑定 ::1
@@ -1612,7 +1836,7 @@ function defineNotesConfig(overrides = {}) {
1612
1836
  watch: {
1613
1837
  ignored: IGNORE_LIST
1614
1838
  },
1615
- ..._optionalChain([overrideVite, 'optionalAccess', _40 => _40.server])
1839
+ ..._optionalChain([overrideVite, 'optionalAccess', _61 => _61.server])
1616
1840
  },
1617
1841
  css: {
1618
1842
  preprocessorOptions: {
@@ -1620,26 +1844,26 @@ function defineNotesConfig(overrides = {}) {
1620
1844
  silenceDeprecations: ["legacy-js-api"]
1621
1845
  }
1622
1846
  },
1623
- ..._optionalChain([overrideVite, 'optionalAccess', _41 => _41.css])
1847
+ ..._optionalChain([overrideVite, 'optionalAccess', _62 => _62.css])
1624
1848
  },
1625
1849
  build: {
1626
1850
  chunkSizeWarningLimit: 1e3,
1627
- ..._optionalChain([overrideVite, 'optionalAccess', _42 => _42.build])
1851
+ ..._optionalChain([overrideVite, 'optionalAccess', _63 => _63.build])
1628
1852
  },
1629
1853
  define: {
1630
1854
  __TNOTES_REPO_NAME__: JSON.stringify(config.repoName),
1631
1855
  __TNOTES_AUTHOR__: JSON.stringify(config.author),
1632
1856
  __TNOTES_IGNORE_DIRS__: JSON.stringify(config.ignore_dirs),
1633
1857
  __TNOTES_ROOT_ITEM__: JSON.stringify(config.root_item),
1634
- ..._optionalChain([overrideVite, 'optionalAccess', _43 => _43.define])
1858
+ ..._optionalChain([overrideVite, 'optionalAccess', _64 => _64.define])
1635
1859
  },
1636
1860
  resolve: {
1637
1861
  dedupe: ["vue", "vitepress"],
1638
- ..._optionalChain([overrideVite, 'optionalAccess', _44 => _44.resolve])
1862
+ ..._optionalChain([overrideVite, 'optionalAccess', _65 => _65.resolve])
1639
1863
  },
1640
1864
  optimizeDeps: {
1641
1865
  include: [...DEFAULT_OPTIMIZE_DEPS_INCLUDE],
1642
- ..._optionalChain([overrideVite, 'optionalAccess', _45 => _45.optimizeDeps])
1866
+ ..._optionalChain([overrideVite, 'optionalAccess', _66 => _66.optimizeDeps])
1643
1867
  }
1644
1868
  },
1645
1869
  transformPageData(pageData, ctx) {