ocean-brain 0.5.0 → 0.6.1

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 (81) hide show
  1. package/dist/mcp.js +660 -31
  2. package/package.json +2 -1
  3. package/server/client/dist/assets/{Calendar-BU9XgX2N.js → Calendar-BJHLksEZ.js} +1 -1
  4. package/server/client/dist/assets/{Callout-C6tVCxOT.js → Callout-wFx9oCas.js} +1 -1
  5. package/server/client/dist/assets/Graph-9piERaNR.js +1 -0
  6. package/server/client/dist/assets/{Image-DxWhlIDG.js → Image-DK0lnaK2.js} +1 -1
  7. package/server/client/dist/assets/{Image.es-BjGK7y6Y.js → Image.es-Be7par_j.js} +1 -1
  8. package/server/client/dist/assets/Note-CC9ybxXL.js +21 -0
  9. package/server/client/dist/assets/{Plus.es-EcmtS_uw.js → Plus.es-BKm7uDYu.js} +1 -1
  10. package/server/client/dist/assets/Reminders-DRxA8v98.js +1 -0
  11. package/server/client/dist/assets/Search-BunSQrqv.js +1 -0
  12. package/server/client/dist/assets/{SurfaceCard-CO0oVxeL.js → SurfaceCard-FhlC8VSR.js} +1 -1
  13. package/server/client/dist/assets/Tag-z_crJ5JP.js +1 -0
  14. package/server/client/dist/assets/TagNotes-D7wIJ4jy.js +1 -0
  15. package/server/client/dist/assets/{Trash.es-DmwfSy3l.js → Trash.es-ByMVwx0d.js} +1 -1
  16. package/server/client/dist/assets/ViewNotes-Duo9XmcJ.js +1 -0
  17. package/server/client/dist/assets/Views-D4Z_O9Kd.js +1 -0
  18. package/server/client/dist/assets/{image.api-DeF9ck7g.js → image.api-B5Qi-Txv.js} +1 -1
  19. package/server/client/dist/assets/{index-BZUGWdOU.css → index-Cd81UxEh.css} +1 -1
  20. package/server/client/dist/assets/index-cHJQCo8V.js +1 -0
  21. package/server/client/dist/assets/index-nYj7BL3a.js +327 -0
  22. package/server/client/dist/assets/manage-image-detail-DcZggB1M.js +1 -0
  23. package/server/client/dist/assets/manage-image-glbtBibn.js +1 -0
  24. package/server/client/dist/assets/{mcp-Bh743HBz.js → mcp-BBUpQdS9.js} +1 -1
  25. package/server/client/dist/assets/{note-core-Z6kqulGB.js → note-core-DMZcZ4yV.js} +53 -53
  26. package/server/client/dist/assets/{note-vendor-i1M2FSI2.js → note-vendor-uuJO2MTD.js} +1 -1
  27. package/server/client/dist/assets/{placeholder-XQqo1Fvr.js → placeholder-B_qb_qkc.js} +5 -5
  28. package/server/client/dist/assets/properties-CiyQv6Tb.js +1 -0
  29. package/server/client/dist/assets/trash-CQnj4Rmv.js +1 -0
  30. package/server/client/dist/assets/{useReminderMutate-D21PurIS.js → useReminderMutate-CSKliBcc.js} +1 -1
  31. package/server/client/dist/assets/view-dashboard-B5fKgvk_.js +99 -0
  32. package/server/client/dist/index.html +4 -4
  33. package/server/dist/features/note/graphql/note.field.resolver.js +2 -0
  34. package/server/dist/features/note/graphql/note.field.resolver.js.map +1 -1
  35. package/server/dist/features/note/graphql/note.mutation.resolver.js +119 -0
  36. package/server/dist/features/note/graphql/note.mutation.resolver.js.map +1 -1
  37. package/server/dist/features/note/graphql/note.query.resolver.js +14 -0
  38. package/server/dist/features/note/graphql/note.query.resolver.js.map +1 -1
  39. package/server/dist/features/note/graphql/note.type-defs.js +100 -0
  40. package/server/dist/features/note/graphql/note.type-defs.js.map +1 -1
  41. package/server/dist/features/note/http/mcp.js +394 -1
  42. package/server/dist/features/note/http/mcp.js.map +1 -1
  43. package/server/dist/features/note/services/markdown-intent-write.js +495 -0
  44. package/server/dist/features/note/services/markdown-intent-write.js.map +1 -0
  45. package/server/dist/features/note/services/markdown-patch.js +601 -0
  46. package/server/dist/features/note/services/markdown-patch.js.map +1 -0
  47. package/server/dist/features/note/services/properties.js +874 -0
  48. package/server/dist/features/note/services/properties.js.map +1 -0
  49. package/server/dist/features/note/services/snapshot.js +94 -12
  50. package/server/dist/features/note/services/snapshot.js.map +1 -1
  51. package/server/dist/features/note/services/trash.js +70 -2
  52. package/server/dist/features/note/services/trash.js.map +1 -1
  53. package/server/dist/features/note/services/write.js +21 -7
  54. package/server/dist/features/note/services/write.js.map +1 -1
  55. package/server/dist/features/view/graphql/view.query.resolver.js +31 -1
  56. package/server/dist/features/view/graphql/view.query.resolver.js.map +1 -1
  57. package/server/dist/features/view/graphql/view.type-defs.js +57 -1
  58. package/server/dist/features/view/graphql/view.type-defs.js.map +1 -1
  59. package/server/dist/features/view/services/workspace.js +367 -43
  60. package/server/dist/features/view/services/workspace.js.map +1 -1
  61. package/server/dist/modules/blocknote.js +367 -7
  62. package/server/dist/modules/blocknote.js.map +1 -1
  63. package/server/dist/routes/mcp.js +21 -1
  64. package/server/dist/routes/mcp.js.map +1 -1
  65. package/server/prisma/migrations/20260527073000_0017_note_properties/migration.sql +105 -0
  66. package/server/prisma/migrations/20260531073000_0018_view_query/migration.sql +3 -0
  67. package/server/prisma/schema.prisma +226 -130
  68. package/server/client/dist/assets/Graph-Dond2hGK.js +0 -1
  69. package/server/client/dist/assets/Note-Cr6GtXUM.js +0 -21
  70. package/server/client/dist/assets/Reminders-BlLLT_x0.js +0 -1
  71. package/server/client/dist/assets/Search-CrZ0ap8x.js +0 -1
  72. package/server/client/dist/assets/Tag-vws5AfNW.js +0 -1
  73. package/server/client/dist/assets/TagNotes-Fmf1Kgim.js +0 -1
  74. package/server/client/dist/assets/ViewNotes-BALN7IfH.js +0 -1
  75. package/server/client/dist/assets/Views-Ccc_Ml5U.js +0 -1
  76. package/server/client/dist/assets/index-BSVE2cGd.js +0 -1
  77. package/server/client/dist/assets/index-BvKBTjQq.js +0 -246
  78. package/server/client/dist/assets/manage-image-IoTXaMBP.js +0 -1
  79. package/server/client/dist/assets/manage-image-detail-BRTXwOsh.js +0 -1
  80. package/server/client/dist/assets/trash-hiJIg6-c.js +0 -1
  81. package/server/client/dist/assets/view-dashboard-BuaZ4MvI.js +0 -90
@@ -0,0 +1,495 @@
1
+ import models from "../../../models.js";
2
+ import {
3
+ blocksToMarkdown,
4
+ countReferenceInlinesFromContentJson,
5
+ extractLiteralAngleBracketTextTokens,
6
+ extractTagIdsFromContentJson,
7
+ hasLiteralAngleBracketTextTokenLoss,
8
+ hasNumericTildeRangeMarkerLoss,
9
+ hasNumericTildeRangeMarkers,
10
+ hasUnsupportedMarkdownBlocks,
11
+ markdownToBlocksJson
12
+ } from "../../../modules/blocknote.js";
13
+ import {
14
+ buildMarkdownAppendPlan,
15
+ buildMarkdownPatchPlan,
16
+ buildMarkdownReplacePlan,
17
+ calculateMarkdownSha256
18
+ } from "./markdown-patch.js";
19
+ import {
20
+ InvalidNotePropertyInputError,
21
+ resolveNotePropertiesPatchValueTypes,
22
+ updateNotePropertiesWithVersionGuardAndSnapshot,
23
+ validateNotePropertiesPatchValues
24
+ } from "./properties.js";
25
+ import { MCP_SNAPSHOT_META } from "./snapshot.js";
26
+ import { updateNoteWithVersionGuardAndSnapshot } from "./write.js";
27
+ import {
28
+ isInvalidNoteVersionError,
29
+ isMissingNoteVersionError,
30
+ isNoteVersionConflictError,
31
+ parseNoteVersion
32
+ } from "./write-conflict.js";
33
+ const serializeNoteSnapshot = async (note, renderMarkdown) => {
34
+ return {
35
+ id: String(note.id),
36
+ title: note.title,
37
+ updatedAt: note.updatedAt.toISOString(),
38
+ markdown: await renderMarkdown(note.content)
39
+ };
40
+ };
41
+ const isRecord = (value) => {
42
+ return typeof value === "object" && value !== null;
43
+ };
44
+ const serializeSnapshot = (snapshot) => {
45
+ const meta = isRecord(snapshot) && isRecord(snapshot.meta) ? snapshot.meta : {};
46
+ const label = typeof meta.label === "string" ? meta.label : "MCP";
47
+ return {
48
+ id: isRecord(snapshot) && snapshot.id !== void 0 ? String(snapshot.id) : "",
49
+ label,
50
+ createdAt: isRecord(snapshot) && typeof snapshot.createdAt === "string" ? snapshot.createdAt : ""
51
+ };
52
+ };
53
+ const toDryRun = (plan) => ({
54
+ status: "dry_run",
55
+ note: plan.note,
56
+ ...plan.match ? { match: plan.match } : {},
57
+ ...plan.placement ? { placement: plan.placement } : {},
58
+ proposed: plan.proposed,
59
+ warnings: plan.warnings
60
+ });
61
+ const toTagIds = (tagIds) => {
62
+ return tagIds.map((tagId) => Number(tagId)).filter((tagId) => Number.isSafeInteger(tagId) && tagId > 0);
63
+ };
64
+ const baselineMismatchFailure = () => ({
65
+ status: "failed",
66
+ reason: "BASELINE_MISMATCH",
67
+ message: "The markdown write baseline does not match the current note."
68
+ });
69
+ const missingBaselineFailure = () => ({
70
+ status: "failed",
71
+ reason: "MISSING_BASELINE",
72
+ message: "expectedUpdatedAt or baseMarkdownSha256 is required for markdown writes."
73
+ });
74
+ const unsupportedMarkdownStructureFailure = () => ({
75
+ status: "failed",
76
+ reason: "UNSUPPORTED_MARKDOWN_STRUCTURE",
77
+ message: "This note contains BlockNote content that cannot be safely represented as Markdown."
78
+ });
79
+ const referenceStructureFailure = () => ({
80
+ status: "failed",
81
+ reason: "REFERENCE_STRUCTURE_DECREASED",
82
+ message: "The markdown write would reduce structured note reference links."
83
+ });
84
+ const markdownImportLossyFailure = () => ({
85
+ status: "failed",
86
+ reason: "MARKDOWN_IMPORT_LOSSY",
87
+ message: "The markdown write would lose literal text during Markdown import."
88
+ });
89
+ const invalidPropertyInputFailure = (error) => ({
90
+ status: "failed",
91
+ reason: "INVALID_PROPERTY_INPUT",
92
+ message: error.message
93
+ });
94
+ const mapGuardedWriteError = (error) => {
95
+ if (isNoteVersionConflictError(error) || isInvalidNoteVersionError(error)) {
96
+ return baselineMismatchFailure();
97
+ }
98
+ if (isMissingNoteVersionError(error)) {
99
+ return missingBaselineFailure();
100
+ }
101
+ return null;
102
+ };
103
+ const resolveMetadataPropertyPatch = async (deps, patch) => {
104
+ if (patch === void 0) {
105
+ return void 0;
106
+ }
107
+ if (!deps.resolvePropertyPatch || !deps.validatePropertyPatch) {
108
+ throw new Error("Metadata property patch dependencies are not configured.");
109
+ }
110
+ try {
111
+ const resolvedPatch = await deps.resolvePropertyPatch(patch);
112
+ return deps.validatePropertyPatch(resolvedPatch);
113
+ } catch (error) {
114
+ if (error instanceof InvalidNotePropertyInputError) {
115
+ return invalidPropertyInputFailure(error);
116
+ }
117
+ throw error;
118
+ }
119
+ };
120
+ const noteVersionMatches = (expectedUpdatedAt, currentUpdatedAt) => {
121
+ try {
122
+ const expectedTimestamp = parseNoteVersion(expectedUpdatedAt);
123
+ return expectedTimestamp !== null && expectedTimestamp === currentUpdatedAt.getTime();
124
+ } catch {
125
+ return false;
126
+ }
127
+ };
128
+ const getUnsupportedSourceFailure = (deps, note) => {
129
+ if (deps.hasUnsupportedMarkdownBlocks?.(note.content)) {
130
+ return unsupportedMarkdownStructureFailure();
131
+ }
132
+ return null;
133
+ };
134
+ const applyMarkdownPlan = async (deps, input) => {
135
+ const content = await deps.parseMarkdownToContentJson(input.plan.afterMarkdown);
136
+ const literalAngleBracketTokens = extractLiteralAngleBracketTextTokens(input.plan.afterMarkdown);
137
+ const shouldCheckMarkdownImportLoss = literalAngleBracketTokens.length > 0 || hasNumericTildeRangeMarkers(input.plan.afterMarkdown);
138
+ if (shouldCheckMarkdownImportLoss) {
139
+ const importedMarkdown = await deps.renderMarkdown(content);
140
+ if (hasLiteralAngleBracketTextTokenLoss(input.plan.afterMarkdown, importedMarkdown) || hasNumericTildeRangeMarkerLoss(input.plan.afterMarkdown, importedMarkdown)) {
141
+ return markdownImportLossyFailure();
142
+ }
143
+ }
144
+ const beforeReferenceCount = deps.countReferenceInlines?.(input.beforeContentJson) ?? 0;
145
+ const afterReferenceCount = deps.countReferenceInlines?.(content) ?? 0;
146
+ if (input.policy?.preserveReferences !== false && afterReferenceCount < beforeReferenceCount) {
147
+ return referenceStructureFailure();
148
+ }
149
+ const tagIds = toTagIds(deps.extractTagIds(content));
150
+ let updateResult;
151
+ try {
152
+ updateResult = await deps.updateNote({
153
+ id: input.noteId,
154
+ data: {
155
+ content,
156
+ tagIds
157
+ },
158
+ expectedUpdatedAt: input.expectedUpdatedAt ?? input.noteUpdatedAt,
159
+ snapshotMeta: MCP_SNAPSHOT_META,
160
+ ...input.force ? { force: true } : {}
161
+ });
162
+ } catch (error) {
163
+ const mappedError = mapGuardedWriteError(error);
164
+ if (mappedError) {
165
+ return mappedError;
166
+ }
167
+ throw error;
168
+ }
169
+ if (!updateResult) {
170
+ return {
171
+ status: "failed",
172
+ reason: "TARGET_NOT_FOUND",
173
+ message: "The requested note was not found."
174
+ };
175
+ }
176
+ return {
177
+ status: "applied",
178
+ note: {
179
+ id: String(updateResult.note.id),
180
+ updatedAt: updateResult.note.updatedAt.toISOString()
181
+ },
182
+ change: {
183
+ summary: input.summary,
184
+ changedLineCount: input.plan.proposed.changedLineCount,
185
+ changedCharCount: input.plan.proposed.changedCharCount
186
+ },
187
+ snapshot: serializeSnapshot(updateResult.snapshot)
188
+ };
189
+ };
190
+ const mapPlanResult = async (deps, input) => {
191
+ if (input.plan.status !== "dry_run") {
192
+ return input.plan;
193
+ }
194
+ if (input.dryRun ?? true) {
195
+ return toDryRun(input.plan);
196
+ }
197
+ return applyMarkdownPlan(deps, {
198
+ noteId: input.noteId,
199
+ noteUpdatedAt: input.noteUpdatedAt,
200
+ beforeContentJson: input.beforeContentJson,
201
+ plan: input.plan,
202
+ expectedUpdatedAt: input.expectedUpdatedAt,
203
+ policy: input.policy,
204
+ summary: input.summary,
205
+ ...input.force ? { force: true } : {}
206
+ });
207
+ };
208
+ const createMarkdownIntentWriteService = (deps) => ({
209
+ patchNoteMarkdown: async (input) => {
210
+ const note = await deps.findNoteById(input.id);
211
+ if (!note) {
212
+ return {
213
+ status: "failed",
214
+ reason: "TARGET_NOT_FOUND",
215
+ message: "The requested note was not found."
216
+ };
217
+ }
218
+ const unsupportedFailure = getUnsupportedSourceFailure(deps, note);
219
+ if (unsupportedFailure) {
220
+ return unsupportedFailure;
221
+ }
222
+ const noteSnapshot = await serializeNoteSnapshot(note, deps.renderMarkdown);
223
+ const plan = buildMarkdownPatchPlan({
224
+ note: noteSnapshot,
225
+ expectedUpdatedAt: input.expectedUpdatedAt,
226
+ baseMarkdownSha256: input.baseMarkdownSha256,
227
+ intent: input.intent,
228
+ selector: input.selector,
229
+ operation: input.operation,
230
+ policy: input.policy
231
+ });
232
+ return mapPlanResult(deps, {
233
+ noteId: input.id,
234
+ noteUpdatedAt: noteSnapshot.updatedAt,
235
+ beforeContentJson: note.content,
236
+ plan,
237
+ dryRun: input.dryRun,
238
+ expectedUpdatedAt: input.expectedUpdatedAt,
239
+ policy: input.policy,
240
+ summary: input.intent
241
+ });
242
+ },
243
+ appendNoteMarkdown: async (input) => {
244
+ const note = await deps.findNoteById(input.id);
245
+ if (!note) {
246
+ return {
247
+ status: "failed",
248
+ reason: "TARGET_NOT_FOUND",
249
+ message: "The requested note was not found."
250
+ };
251
+ }
252
+ const unsupportedFailure = getUnsupportedSourceFailure(deps, note);
253
+ if (unsupportedFailure) {
254
+ return unsupportedFailure;
255
+ }
256
+ const noteSnapshot = await serializeNoteSnapshot(note, deps.renderMarkdown);
257
+ const plan = buildMarkdownAppendPlan({
258
+ note: noteSnapshot,
259
+ expectedUpdatedAt: input.expectedUpdatedAt,
260
+ baseMarkdownSha256: input.baseMarkdownSha256,
261
+ intent: input.intent,
262
+ insertion: input.insertion,
263
+ placement: input.placement,
264
+ separator: input.separator,
265
+ policy: input.policy
266
+ });
267
+ return mapPlanResult(deps, {
268
+ noteId: input.id,
269
+ noteUpdatedAt: noteSnapshot.updatedAt,
270
+ beforeContentJson: note.content,
271
+ plan,
272
+ dryRun: input.dryRun,
273
+ expectedUpdatedAt: input.expectedUpdatedAt,
274
+ policy: input.policy,
275
+ summary: input.intent
276
+ });
277
+ },
278
+ replaceNoteMarkdown: async (input) => {
279
+ const note = await deps.findNoteById(input.id);
280
+ if (!note) {
281
+ return {
282
+ status: "failed",
283
+ reason: "TARGET_NOT_FOUND",
284
+ message: "The requested note was not found."
285
+ };
286
+ }
287
+ const unsupportedFailure = getUnsupportedSourceFailure(deps, note);
288
+ if (unsupportedFailure) {
289
+ return unsupportedFailure;
290
+ }
291
+ const noteSnapshot = await serializeNoteSnapshot(note, deps.renderMarkdown);
292
+ const plan = buildMarkdownReplacePlan({
293
+ note: noteSnapshot,
294
+ expectedUpdatedAt: input.expectedUpdatedAt,
295
+ baseMarkdownSha256: input.baseMarkdownSha256,
296
+ intent: input.intent,
297
+ replacement: input.replacement,
298
+ policy: input.policy
299
+ });
300
+ return mapPlanResult(deps, {
301
+ noteId: input.id,
302
+ noteUpdatedAt: noteSnapshot.updatedAt,
303
+ beforeContentJson: note.content,
304
+ plan,
305
+ dryRun: input.dryRun,
306
+ expectedUpdatedAt: input.expectedUpdatedAt,
307
+ policy: input.policy,
308
+ summary: input.intent
309
+ });
310
+ },
311
+ updateNoteMetadata: async (input) => {
312
+ const note = await deps.findNoteById(input.id);
313
+ if (!note) {
314
+ return {
315
+ status: "failed",
316
+ reason: "TARGET_NOT_FOUND",
317
+ message: "The requested note was not found."
318
+ };
319
+ }
320
+ if (!noteVersionMatches(input.expectedUpdatedAt, note.updatedAt)) {
321
+ return {
322
+ status: "failed",
323
+ reason: input.expectedUpdatedAt ? "BASELINE_MISMATCH" : "MISSING_BASELINE",
324
+ message: "The metadata update baseline does not match the current note."
325
+ };
326
+ }
327
+ const nextTitle = input.title?.trim();
328
+ const resolvedPropertyPatch = await resolveMetadataPropertyPatch(deps, input.properties);
329
+ if (resolvedPropertyPatch && "status" in resolvedPropertyPatch) {
330
+ return resolvedPropertyPatch;
331
+ }
332
+ if (input.title !== void 0 && !nextTitle) {
333
+ return {
334
+ status: "failed",
335
+ reason: "EMPTY_REPLACEMENT",
336
+ message: "Note title must not be empty."
337
+ };
338
+ }
339
+ if (nextTitle === note.title && (input.layout === void 0 || input.layout === note.layout) && resolvedPropertyPatch === void 0) {
340
+ return {
341
+ status: "failed",
342
+ reason: "NOOP",
343
+ message: "The metadata update would not change the note."
344
+ };
345
+ }
346
+ return {
347
+ status: "dry_run",
348
+ note: {
349
+ id: String(note.id),
350
+ title: note.title,
351
+ updatedAt: note.updatedAt.toISOString()
352
+ },
353
+ proposed: {
354
+ ...nextTitle !== void 0 ? { title: nextTitle } : {},
355
+ ...input.layout !== void 0 ? { layout: input.layout } : {},
356
+ ...resolvedPropertyPatch ? { properties: resolvedPropertyPatch } : {}
357
+ },
358
+ warnings: []
359
+ };
360
+ },
361
+ applyNoteMetadata: async (input) => {
362
+ const preview = await createMarkdownIntentWriteService(deps).updateNoteMetadata(input);
363
+ if (preview.status !== "dry_run") {
364
+ return preview;
365
+ }
366
+ if (input.properties !== void 0) {
367
+ if (!deps.updateProperties) {
368
+ throw new Error("Metadata property write dependency is not configured.");
369
+ }
370
+ let updateResult2;
371
+ try {
372
+ updateResult2 = await deps.updateProperties({
373
+ id: input.id,
374
+ patch: preview.proposed.properties ?? { set: [], deleteKeys: [] },
375
+ expectedUpdatedAt: input.expectedUpdatedAt,
376
+ noteData: {
377
+ ...preview.proposed.title !== void 0 ? { title: preview.proposed.title } : {},
378
+ ...preview.proposed.layout !== void 0 ? { layout: preview.proposed.layout } : {}
379
+ },
380
+ snapshotMeta: MCP_SNAPSHOT_META
381
+ });
382
+ } catch (error) {
383
+ const mappedError = mapGuardedWriteError(error);
384
+ if (mappedError) {
385
+ return mappedError;
386
+ }
387
+ if (error instanceof InvalidNotePropertyInputError) {
388
+ return invalidPropertyInputFailure(error);
389
+ }
390
+ throw error;
391
+ }
392
+ if (!updateResult2) {
393
+ return {
394
+ status: "failed",
395
+ reason: "TARGET_NOT_FOUND",
396
+ message: "The requested note was not found."
397
+ };
398
+ }
399
+ return {
400
+ status: "applied",
401
+ note: {
402
+ id: String(updateResult2.note.id),
403
+ title: updateResult2.note.title,
404
+ layout: updateResult2.note.layout,
405
+ updatedAt: updateResult2.note.updatedAt.toISOString()
406
+ },
407
+ snapshot: serializeSnapshot(updateResult2.snapshot)
408
+ };
409
+ }
410
+ let updateResult;
411
+ try {
412
+ updateResult = await deps.updateNote({
413
+ id: input.id,
414
+ data: {
415
+ ...preview.proposed.title !== void 0 ? { title: preview.proposed.title } : {},
416
+ ...preview.proposed.layout !== void 0 ? { layout: preview.proposed.layout } : {}
417
+ },
418
+ expectedUpdatedAt: input.expectedUpdatedAt,
419
+ snapshotMeta: MCP_SNAPSHOT_META
420
+ });
421
+ } catch (error) {
422
+ const mappedError = mapGuardedWriteError(error);
423
+ if (mappedError) {
424
+ return mappedError;
425
+ }
426
+ throw error;
427
+ }
428
+ if (!updateResult) {
429
+ return {
430
+ status: "failed",
431
+ reason: "TARGET_NOT_FOUND",
432
+ message: "The requested note was not found."
433
+ };
434
+ }
435
+ return {
436
+ status: "applied",
437
+ note: {
438
+ id: String(updateResult.note.id),
439
+ title: updateResult.note.title,
440
+ layout: updateResult.note.layout,
441
+ updatedAt: updateResult.note.updatedAt.toISOString()
442
+ },
443
+ snapshot: serializeSnapshot(updateResult.snapshot)
444
+ };
445
+ }
446
+ });
447
+ const defaultMarkdownIntentWriteService = createMarkdownIntentWriteService({
448
+ findNoteById: (id) => models.note.findUnique({
449
+ where: { id },
450
+ select: {
451
+ id: true,
452
+ title: true,
453
+ content: true,
454
+ layout: true,
455
+ updatedAt: true
456
+ }
457
+ }),
458
+ renderMarkdown: blocksToMarkdown,
459
+ parseMarkdownToContentJson: markdownToBlocksJson,
460
+ extractTagIds: extractTagIdsFromContentJson,
461
+ countReferenceInlines: countReferenceInlinesFromContentJson,
462
+ hasUnsupportedMarkdownBlocks,
463
+ updateNote: updateNoteWithVersionGuardAndSnapshot,
464
+ resolvePropertyPatch: resolveNotePropertiesPatchValueTypes,
465
+ validatePropertyPatch: validateNotePropertiesPatchValues,
466
+ updateProperties: updateNotePropertiesWithVersionGuardAndSnapshot
467
+ });
468
+ const patchNoteMarkdown = async (input) => {
469
+ return defaultMarkdownIntentWriteService.patchNoteMarkdown(input);
470
+ };
471
+ const appendNoteMarkdown = async (input) => {
472
+ return defaultMarkdownIntentWriteService.appendNoteMarkdown(input);
473
+ };
474
+ const replaceNoteMarkdown = async (input) => {
475
+ return defaultMarkdownIntentWriteService.replaceNoteMarkdown(input);
476
+ };
477
+ const updateNoteMetadata = async (input) => {
478
+ if (input.dryRun ?? true) {
479
+ return defaultMarkdownIntentWriteService.updateNoteMetadata(input);
480
+ }
481
+ return defaultMarkdownIntentWriteService.applyNoteMetadata(input);
482
+ };
483
+ const calculateNoteMarkdownSha256 = (markdown) => {
484
+ return calculateMarkdownSha256(markdown);
485
+ };
486
+ export {
487
+ appendNoteMarkdown,
488
+ calculateNoteMarkdownSha256,
489
+ createMarkdownIntentWriteService,
490
+ defaultMarkdownIntentWriteService,
491
+ patchNoteMarkdown,
492
+ replaceNoteMarkdown,
493
+ updateNoteMetadata
494
+ };
495
+ //# sourceMappingURL=markdown-intent-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/features/note/services/markdown-intent-write.ts"],"sourcesContent":["import models, { type NoteLayout } from '~/models.js';\nimport {\n blocksToMarkdown,\n countReferenceInlinesFromContentJson,\n extractLiteralAngleBracketTextTokens,\n extractTagIdsFromContentJson,\n hasLiteralAngleBracketTextTokenLoss,\n hasNumericTildeRangeMarkerLoss,\n hasNumericTildeRangeMarkers,\n hasUnsupportedMarkdownBlocks,\n markdownToBlocksJson,\n} from '~/modules/blocknote.js';\nimport type {\n MarkdownAppendPlanResult,\n MarkdownChangeDryRun,\n MarkdownChangeFailure,\n MarkdownChangePlan,\n MarkdownPatchOperation,\n MarkdownPatchPlanResult,\n MarkdownPatchSelector,\n MarkdownReplacePlanResult,\n} from './markdown-patch.js';\nimport {\n buildMarkdownAppendPlan,\n buildMarkdownPatchPlan,\n buildMarkdownReplacePlan,\n calculateMarkdownSha256,\n} from './markdown-patch.js';\nimport {\n InvalidNotePropertyInputError,\n type NotePropertiesByKeyPatchInput,\n type NotePropertiesPatchInput,\n resolveNotePropertiesPatchValueTypes,\n updateNotePropertiesWithVersionGuardAndSnapshot,\n validateNotePropertiesPatchValues,\n} from './properties.js';\nimport { MCP_SNAPSHOT_META } from './snapshot.js';\nimport { type GuardedNoteWriteResult, updateNoteWithVersionGuardAndSnapshot } from './write.js';\nimport {\n isInvalidNoteVersionError,\n isMissingNoteVersionError,\n isNoteVersionConflictError,\n parseNoteVersion,\n} from './write-conflict.js';\n\ninterface MarkdownIntentNoteRecord {\n id: number;\n title: string;\n content: string;\n layout: NoteLayout;\n updatedAt: Date;\n}\n\ninterface MarkdownIntentWriteDeps {\n findNoteById: (id: number) => Promise<MarkdownIntentNoteRecord | null>;\n renderMarkdown: (contentJson: string) => Promise<string>;\n parseMarkdownToContentJson: (markdown: string) => Promise<string>;\n extractTagIds: (contentJson: string) => string[];\n countReferenceInlines?: (contentJson: string) => number;\n hasUnsupportedMarkdownBlocks?: (contentJson: string) => boolean;\n updateNote: (input: {\n id: number;\n data: {\n title?: string;\n content?: string;\n layout?: NoteLayout;\n tagIds?: number[];\n };\n expectedUpdatedAt: string;\n snapshotMeta?: string;\n force?: boolean;\n }) => Promise<GuardedNoteWriteResult | null>;\n resolvePropertyPatch?: (patch: NotePropertiesByKeyPatchInput) => Promise<NotePropertiesPatchInput>;\n validatePropertyPatch?: (patch: NotePropertiesPatchInput) => Promise<NotePropertiesPatchInput>;\n updateProperties?: (input: {\n id: number;\n patch: NotePropertiesPatchInput;\n expectedUpdatedAt: string;\n noteData?: {\n title?: string;\n layout?: NoteLayout;\n };\n snapshotMeta?: string;\n }) => Promise<{\n note: {\n id: number;\n title: string;\n layout: NoteLayout;\n updatedAt: Date;\n };\n snapshot: unknown;\n } | null>;\n}\n\nexport interface MarkdownWritePolicy {\n allowNoop?: boolean;\n maxChangedChars?: number;\n maxChangedLines?: number;\n preserveReferences?: boolean | 'warn';\n preserveTags?: boolean | 'warn';\n}\n\nexport interface PatchNoteMarkdownInput {\n id: number;\n expectedUpdatedAt?: string;\n baseMarkdownSha256?: string;\n intent: string;\n selector: MarkdownPatchSelector;\n operation: MarkdownPatchOperation;\n policy?: MarkdownWritePolicy;\n dryRun?: boolean;\n}\n\nexport interface AppendNoteMarkdownInput {\n id: number;\n expectedUpdatedAt?: string;\n baseMarkdownSha256?: string;\n intent: string;\n insertion: string;\n placement?:\n | {\n type: 'end';\n }\n | {\n type: 'after_heading';\n heading: string;\n level?: number;\n };\n separator?: '\\n\\n' | '\\n';\n policy?: MarkdownWritePolicy;\n dryRun?: boolean;\n}\n\nexport interface ReplaceNoteMarkdownInput {\n id: number;\n expectedUpdatedAt?: string;\n baseMarkdownSha256?: string;\n intent: string;\n replacement: string;\n policy?: MarkdownWritePolicy;\n dryRun?: boolean;\n}\n\nexport interface UpdateNoteMetadataInput {\n id: number;\n expectedUpdatedAt: string;\n title?: string;\n layout?: NoteLayout;\n properties?: NotePropertiesByKeyPatchInput;\n}\n\nexport interface AppliedMarkdownWriteResult {\n status: 'applied';\n note: {\n id: string;\n updatedAt: string;\n };\n change: {\n summary: string;\n changedLineCount: number;\n changedCharCount: number;\n };\n snapshot: {\n id: string;\n label: string;\n createdAt: string;\n };\n}\n\nexport interface MetadataUpdatePreview {\n status: 'dry_run';\n note: {\n id: string;\n title: string;\n updatedAt: string;\n };\n proposed: {\n title?: string;\n layout?: NoteLayout;\n properties?: NotePropertiesPatchInput;\n };\n warnings: string[];\n}\n\nexport interface AppliedMetadataUpdateResult {\n status: 'applied';\n note: {\n id: string;\n title: string;\n layout: NoteLayout;\n updatedAt: string;\n };\n snapshot: {\n id: string;\n label: string;\n createdAt: string;\n };\n}\n\nexport type MarkdownIntentWriteResult =\n | MarkdownChangeDryRun\n | AppliedMarkdownWriteResult\n | MarkdownChangeFailure\n | Extract<MarkdownPatchPlanResult, { status: 'needs_disambiguation' }>;\n\nexport type MetadataUpdateResult = MetadataUpdatePreview | AppliedMetadataUpdateResult | MarkdownChangeFailure;\n\nconst serializeNoteSnapshot = async (\n note: MarkdownIntentNoteRecord,\n renderMarkdown: (contentJson: string) => Promise<string>,\n) => {\n return {\n id: String(note.id),\n title: note.title,\n updatedAt: note.updatedAt.toISOString(),\n markdown: await renderMarkdown(note.content),\n };\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null;\n};\n\nconst serializeSnapshot = (snapshot: unknown) => {\n const meta = isRecord(snapshot) && isRecord(snapshot.meta) ? snapshot.meta : {};\n const label = typeof meta.label === 'string' ? meta.label : 'MCP';\n\n return {\n id: isRecord(snapshot) && snapshot.id !== undefined ? String(snapshot.id) : '',\n label,\n createdAt: isRecord(snapshot) && typeof snapshot.createdAt === 'string' ? snapshot.createdAt : '',\n };\n};\n\nconst toDryRun = (plan: MarkdownChangePlan): MarkdownChangeDryRun => ({\n status: 'dry_run',\n note: plan.note,\n ...(plan.match ? { match: plan.match } : {}),\n ...(plan.placement ? { placement: plan.placement } : {}),\n proposed: plan.proposed,\n warnings: plan.warnings,\n});\n\nconst toTagIds = (tagIds: string[]) => {\n return tagIds.map((tagId) => Number(tagId)).filter((tagId) => Number.isSafeInteger(tagId) && tagId > 0);\n};\n\nconst baselineMismatchFailure = (): MarkdownChangeFailure => ({\n status: 'failed',\n reason: 'BASELINE_MISMATCH',\n message: 'The markdown write baseline does not match the current note.',\n});\n\nconst missingBaselineFailure = (): MarkdownChangeFailure => ({\n status: 'failed',\n reason: 'MISSING_BASELINE',\n message: 'expectedUpdatedAt or baseMarkdownSha256 is required for markdown writes.',\n});\n\nconst unsupportedMarkdownStructureFailure = (): MarkdownChangeFailure => ({\n status: 'failed',\n reason: 'UNSUPPORTED_MARKDOWN_STRUCTURE',\n message: 'This note contains BlockNote content that cannot be safely represented as Markdown.',\n});\n\nconst referenceStructureFailure = (): MarkdownChangeFailure => ({\n status: 'failed',\n reason: 'REFERENCE_STRUCTURE_DECREASED',\n message: 'The markdown write would reduce structured note reference links.',\n});\n\nconst markdownImportLossyFailure = (): MarkdownChangeFailure => ({\n status: 'failed',\n reason: 'MARKDOWN_IMPORT_LOSSY',\n message: 'The markdown write would lose literal text during Markdown import.',\n});\n\nconst invalidPropertyInputFailure = (error: InvalidNotePropertyInputError): MarkdownChangeFailure => ({\n status: 'failed',\n reason: 'INVALID_PROPERTY_INPUT',\n message: error.message,\n});\n\nconst mapGuardedWriteError = (error: unknown): MarkdownChangeFailure | null => {\n if (isNoteVersionConflictError(error) || isInvalidNoteVersionError(error)) {\n return baselineMismatchFailure();\n }\n\n if (isMissingNoteVersionError(error)) {\n return missingBaselineFailure();\n }\n\n return null;\n};\n\nconst resolveMetadataPropertyPatch = async (\n deps: MarkdownIntentWriteDeps,\n patch: NotePropertiesByKeyPatchInput | undefined,\n): Promise<NotePropertiesPatchInput | MarkdownChangeFailure | undefined> => {\n if (patch === undefined) {\n return undefined;\n }\n\n if (!deps.resolvePropertyPatch || !deps.validatePropertyPatch) {\n throw new Error('Metadata property patch dependencies are not configured.');\n }\n\n try {\n const resolvedPatch = await deps.resolvePropertyPatch(patch);\n return deps.validatePropertyPatch(resolvedPatch);\n } catch (error) {\n if (error instanceof InvalidNotePropertyInputError) {\n return invalidPropertyInputFailure(error);\n }\n\n throw error;\n }\n};\n\nconst noteVersionMatches = (expectedUpdatedAt: string | undefined, currentUpdatedAt: Date) => {\n try {\n const expectedTimestamp = parseNoteVersion(expectedUpdatedAt);\n\n return expectedTimestamp !== null && expectedTimestamp === currentUpdatedAt.getTime();\n } catch {\n return false;\n }\n};\n\nconst getUnsupportedSourceFailure = (deps: MarkdownIntentWriteDeps, note: MarkdownIntentNoteRecord) => {\n if (deps.hasUnsupportedMarkdownBlocks?.(note.content)) {\n return unsupportedMarkdownStructureFailure();\n }\n\n return null;\n};\n\nconst applyMarkdownPlan = async (\n deps: MarkdownIntentWriteDeps,\n input: {\n noteId: number;\n noteUpdatedAt: string;\n beforeContentJson: string;\n plan: Extract<MarkdownPatchPlanResult, { status: 'dry_run' }>;\n expectedUpdatedAt?: string;\n policy?: MarkdownWritePolicy;\n summary: string;\n force?: boolean;\n },\n): Promise<AppliedMarkdownWriteResult | MarkdownChangeFailure> => {\n const content = await deps.parseMarkdownToContentJson(input.plan.afterMarkdown);\n const literalAngleBracketTokens = extractLiteralAngleBracketTextTokens(input.plan.afterMarkdown);\n const shouldCheckMarkdownImportLoss =\n literalAngleBracketTokens.length > 0 || hasNumericTildeRangeMarkers(input.plan.afterMarkdown);\n\n if (shouldCheckMarkdownImportLoss) {\n const importedMarkdown = await deps.renderMarkdown(content);\n\n if (\n hasLiteralAngleBracketTextTokenLoss(input.plan.afterMarkdown, importedMarkdown) ||\n hasNumericTildeRangeMarkerLoss(input.plan.afterMarkdown, importedMarkdown)\n ) {\n return markdownImportLossyFailure();\n }\n }\n\n const beforeReferenceCount = deps.countReferenceInlines?.(input.beforeContentJson) ?? 0;\n const afterReferenceCount = deps.countReferenceInlines?.(content) ?? 0;\n\n if (input.policy?.preserveReferences !== false && afterReferenceCount < beforeReferenceCount) {\n return referenceStructureFailure();\n }\n\n const tagIds = toTagIds(deps.extractTagIds(content));\n let updateResult: GuardedNoteWriteResult | null;\n\n try {\n updateResult = await deps.updateNote({\n id: input.noteId,\n data: {\n content,\n tagIds,\n },\n expectedUpdatedAt: input.expectedUpdatedAt ?? input.noteUpdatedAt,\n snapshotMeta: MCP_SNAPSHOT_META,\n ...(input.force ? { force: true } : {}),\n });\n } catch (error) {\n const mappedError = mapGuardedWriteError(error);\n\n if (mappedError) {\n return mappedError;\n }\n\n throw error;\n }\n\n if (!updateResult) {\n return {\n status: 'failed',\n reason: 'TARGET_NOT_FOUND',\n message: 'The requested note was not found.',\n };\n }\n\n return {\n status: 'applied',\n note: {\n id: String(updateResult.note.id),\n updatedAt: updateResult.note.updatedAt.toISOString(),\n },\n change: {\n summary: input.summary,\n changedLineCount: input.plan.proposed.changedLineCount,\n changedCharCount: input.plan.proposed.changedCharCount,\n },\n snapshot: serializeSnapshot(updateResult.snapshot),\n };\n};\n\nconst mapPlanResult = async (\n deps: MarkdownIntentWriteDeps,\n input: {\n noteId: number;\n noteUpdatedAt: string;\n beforeContentJson: string;\n plan: MarkdownPatchPlanResult | MarkdownAppendPlanResult | MarkdownReplacePlanResult;\n dryRun?: boolean;\n expectedUpdatedAt?: string;\n policy?: MarkdownWritePolicy;\n summary: string;\n force?: boolean;\n },\n): Promise<MarkdownIntentWriteResult> => {\n if (input.plan.status !== 'dry_run') {\n return input.plan;\n }\n\n if (input.dryRun ?? true) {\n return toDryRun(input.plan);\n }\n\n return applyMarkdownPlan(deps, {\n noteId: input.noteId,\n noteUpdatedAt: input.noteUpdatedAt,\n beforeContentJson: input.beforeContentJson,\n plan: input.plan,\n expectedUpdatedAt: input.expectedUpdatedAt,\n policy: input.policy,\n summary: input.summary,\n ...(input.force ? { force: true } : {}),\n });\n};\n\nexport const createMarkdownIntentWriteService = (deps: MarkdownIntentWriteDeps) => ({\n patchNoteMarkdown: async (input: PatchNoteMarkdownInput): Promise<MarkdownIntentWriteResult> => {\n const note = await deps.findNoteById(input.id);\n\n if (!note) {\n return {\n status: 'failed',\n reason: 'TARGET_NOT_FOUND',\n message: 'The requested note was not found.',\n };\n }\n\n const unsupportedFailure = getUnsupportedSourceFailure(deps, note);\n\n if (unsupportedFailure) {\n return unsupportedFailure;\n }\n\n const noteSnapshot = await serializeNoteSnapshot(note, deps.renderMarkdown);\n const plan = buildMarkdownPatchPlan({\n note: noteSnapshot,\n expectedUpdatedAt: input.expectedUpdatedAt,\n baseMarkdownSha256: input.baseMarkdownSha256,\n intent: input.intent,\n selector: input.selector,\n operation: input.operation,\n policy: input.policy,\n });\n\n return mapPlanResult(deps, {\n noteId: input.id,\n noteUpdatedAt: noteSnapshot.updatedAt,\n beforeContentJson: note.content,\n plan,\n dryRun: input.dryRun,\n expectedUpdatedAt: input.expectedUpdatedAt,\n policy: input.policy,\n summary: input.intent,\n });\n },\n\n appendNoteMarkdown: async (input: AppendNoteMarkdownInput): Promise<MarkdownIntentWriteResult> => {\n const note = await deps.findNoteById(input.id);\n\n if (!note) {\n return {\n status: 'failed',\n reason: 'TARGET_NOT_FOUND',\n message: 'The requested note was not found.',\n };\n }\n\n const unsupportedFailure = getUnsupportedSourceFailure(deps, note);\n\n if (unsupportedFailure) {\n return unsupportedFailure;\n }\n\n const noteSnapshot = await serializeNoteSnapshot(note, deps.renderMarkdown);\n const plan = buildMarkdownAppendPlan({\n note: noteSnapshot,\n expectedUpdatedAt: input.expectedUpdatedAt,\n baseMarkdownSha256: input.baseMarkdownSha256,\n intent: input.intent,\n insertion: input.insertion,\n placement: input.placement,\n separator: input.separator,\n policy: input.policy,\n });\n\n return mapPlanResult(deps, {\n noteId: input.id,\n noteUpdatedAt: noteSnapshot.updatedAt,\n beforeContentJson: note.content,\n plan,\n dryRun: input.dryRun,\n expectedUpdatedAt: input.expectedUpdatedAt,\n policy: input.policy,\n summary: input.intent,\n });\n },\n\n replaceNoteMarkdown: async (input: ReplaceNoteMarkdownInput): Promise<MarkdownIntentWriteResult> => {\n const note = await deps.findNoteById(input.id);\n\n if (!note) {\n return {\n status: 'failed',\n reason: 'TARGET_NOT_FOUND',\n message: 'The requested note was not found.',\n };\n }\n\n const unsupportedFailure = getUnsupportedSourceFailure(deps, note);\n\n if (unsupportedFailure) {\n return unsupportedFailure;\n }\n\n const noteSnapshot = await serializeNoteSnapshot(note, deps.renderMarkdown);\n const plan = buildMarkdownReplacePlan({\n note: noteSnapshot,\n expectedUpdatedAt: input.expectedUpdatedAt,\n baseMarkdownSha256: input.baseMarkdownSha256,\n intent: input.intent,\n replacement: input.replacement,\n policy: input.policy,\n });\n\n return mapPlanResult(deps, {\n noteId: input.id,\n noteUpdatedAt: noteSnapshot.updatedAt,\n beforeContentJson: note.content,\n plan,\n dryRun: input.dryRun,\n expectedUpdatedAt: input.expectedUpdatedAt,\n policy: input.policy,\n summary: input.intent,\n });\n },\n\n updateNoteMetadata: async (input: UpdateNoteMetadataInput): Promise<MetadataUpdateResult> => {\n const note = await deps.findNoteById(input.id);\n\n if (!note) {\n return {\n status: 'failed',\n reason: 'TARGET_NOT_FOUND',\n message: 'The requested note was not found.',\n };\n }\n\n if (!noteVersionMatches(input.expectedUpdatedAt, note.updatedAt)) {\n return {\n status: 'failed',\n reason: input.expectedUpdatedAt ? 'BASELINE_MISMATCH' : 'MISSING_BASELINE',\n message: 'The metadata update baseline does not match the current note.',\n };\n }\n\n const nextTitle = input.title?.trim();\n const resolvedPropertyPatch = await resolveMetadataPropertyPatch(deps, input.properties);\n\n if (resolvedPropertyPatch && 'status' in resolvedPropertyPatch) {\n return resolvedPropertyPatch;\n }\n\n if (input.title !== undefined && !nextTitle) {\n return {\n status: 'failed',\n reason: 'EMPTY_REPLACEMENT',\n message: 'Note title must not be empty.',\n };\n }\n\n if (\n nextTitle === note.title &&\n (input.layout === undefined || input.layout === note.layout) &&\n resolvedPropertyPatch === undefined\n ) {\n return {\n status: 'failed',\n reason: 'NOOP',\n message: 'The metadata update would not change the note.',\n };\n }\n\n return {\n status: 'dry_run',\n note: {\n id: String(note.id),\n title: note.title,\n updatedAt: note.updatedAt.toISOString(),\n },\n proposed: {\n ...(nextTitle !== undefined ? { title: nextTitle } : {}),\n ...(input.layout !== undefined ? { layout: input.layout } : {}),\n ...(resolvedPropertyPatch ? { properties: resolvedPropertyPatch } : {}),\n },\n warnings: [],\n };\n },\n\n applyNoteMetadata: async (input: UpdateNoteMetadataInput): Promise<MetadataUpdateResult> => {\n const preview = await createMarkdownIntentWriteService(deps).updateNoteMetadata(input);\n\n if (preview.status !== 'dry_run') {\n return preview;\n }\n\n if (input.properties !== undefined) {\n if (!deps.updateProperties) {\n throw new Error('Metadata property write dependency is not configured.');\n }\n\n let updateResult: Awaited<ReturnType<NonNullable<MarkdownIntentWriteDeps['updateProperties']>>>;\n\n try {\n updateResult = await deps.updateProperties({\n id: input.id,\n patch: preview.proposed.properties ?? { set: [], deleteKeys: [] },\n expectedUpdatedAt: input.expectedUpdatedAt,\n noteData: {\n ...(preview.proposed.title !== undefined ? { title: preview.proposed.title } : {}),\n ...(preview.proposed.layout !== undefined ? { layout: preview.proposed.layout } : {}),\n },\n snapshotMeta: MCP_SNAPSHOT_META,\n });\n } catch (error) {\n const mappedError = mapGuardedWriteError(error);\n\n if (mappedError) {\n return mappedError;\n }\n\n if (error instanceof InvalidNotePropertyInputError) {\n return invalidPropertyInputFailure(error);\n }\n\n throw error;\n }\n\n if (!updateResult) {\n return {\n status: 'failed',\n reason: 'TARGET_NOT_FOUND',\n message: 'The requested note was not found.',\n };\n }\n\n return {\n status: 'applied',\n note: {\n id: String(updateResult.note.id),\n title: updateResult.note.title,\n layout: updateResult.note.layout,\n updatedAt: updateResult.note.updatedAt.toISOString(),\n },\n snapshot: serializeSnapshot(updateResult.snapshot),\n };\n }\n\n let updateResult: GuardedNoteWriteResult | null;\n\n try {\n updateResult = await deps.updateNote({\n id: input.id,\n data: {\n ...(preview.proposed.title !== undefined ? { title: preview.proposed.title } : {}),\n ...(preview.proposed.layout !== undefined ? { layout: preview.proposed.layout } : {}),\n },\n expectedUpdatedAt: input.expectedUpdatedAt,\n snapshotMeta: MCP_SNAPSHOT_META,\n });\n } catch (error) {\n const mappedError = mapGuardedWriteError(error);\n\n if (mappedError) {\n return mappedError;\n }\n\n throw error;\n }\n\n if (!updateResult) {\n return {\n status: 'failed',\n reason: 'TARGET_NOT_FOUND',\n message: 'The requested note was not found.',\n };\n }\n\n return {\n status: 'applied',\n note: {\n id: String(updateResult.note.id),\n title: updateResult.note.title,\n layout: updateResult.note.layout,\n updatedAt: updateResult.note.updatedAt.toISOString(),\n },\n snapshot: serializeSnapshot(updateResult.snapshot),\n };\n },\n});\n\nexport const defaultMarkdownIntentWriteService = createMarkdownIntentWriteService({\n findNoteById: (id) =>\n models.note.findUnique({\n where: { id },\n select: {\n id: true,\n title: true,\n content: true,\n layout: true,\n updatedAt: true,\n },\n }),\n renderMarkdown: blocksToMarkdown,\n parseMarkdownToContentJson: markdownToBlocksJson,\n extractTagIds: extractTagIdsFromContentJson,\n countReferenceInlines: countReferenceInlinesFromContentJson,\n hasUnsupportedMarkdownBlocks,\n updateNote: updateNoteWithVersionGuardAndSnapshot,\n resolvePropertyPatch: resolveNotePropertiesPatchValueTypes,\n validatePropertyPatch: validateNotePropertiesPatchValues,\n updateProperties: updateNotePropertiesWithVersionGuardAndSnapshot,\n});\n\nexport const patchNoteMarkdown = async (input: PatchNoteMarkdownInput) => {\n return defaultMarkdownIntentWriteService.patchNoteMarkdown(input);\n};\n\nexport const appendNoteMarkdown = async (input: AppendNoteMarkdownInput) => {\n return defaultMarkdownIntentWriteService.appendNoteMarkdown(input);\n};\n\nexport const replaceNoteMarkdown = async (input: ReplaceNoteMarkdownInput) => {\n return defaultMarkdownIntentWriteService.replaceNoteMarkdown(input);\n};\n\nexport const updateNoteMetadata = async (input: UpdateNoteMetadataInput & { dryRun?: boolean }) => {\n if (input.dryRun ?? true) {\n return defaultMarkdownIntentWriteService.updateNoteMetadata(input);\n }\n\n return defaultMarkdownIntentWriteService.applyNoteMetadata(input);\n};\n\nexport const calculateNoteMarkdownSha256 = (markdown: string) => {\n return calculateMarkdownSha256(markdown);\n};\n"],"mappings":"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","names":["updateResult"]}