ocean-brain 0.13.3 → 0.15.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 (177) hide show
  1. package/README.md +66 -2
  2. package/dist/mcp.js +439 -480
  3. package/package.json +3 -2
  4. package/server/client/dist/assets/ArrowClockwise.es-BwtKWcmj.js +1 -0
  5. package/server/client/dist/assets/{ArrowRight.es-BlNsZQFs.js → ArrowRight.es-E09Lfefr.js} +1 -1
  6. package/server/client/dist/assets/{AuxiliaryPanelHeader-HAttwVby.js → AuxiliaryPanelHeader-Bys98BJJ.js} +1 -1
  7. package/server/client/dist/assets/Calendar-BOhJYi8K.js +25 -0
  8. package/server/client/dist/assets/Callout-CAH1ua9B.js +1 -0
  9. package/server/client/dist/assets/{CaretUp.es-C8iY5OlB.js → CaretUp.es-DSWjIa-J.js} +1 -1
  10. package/server/client/dist/assets/{CheckCircle.es-Dqr3WImn.js → CheckCircle.es-Cou6rItm.js} +1 -1
  11. package/server/client/dist/assets/{Copy.es-fMv0ETir.js → Copy.es-ftEldGIL.js} +1 -1
  12. package/server/client/dist/assets/{File.es-CHtXXafR.js → File.es-DlKAX1uO.js} +1 -1
  13. package/server/client/dist/assets/{FileText.es-DPIwDCEe.js → FileText.es-D6JM_MqM.js} +1 -1
  14. package/server/client/dist/assets/{FlowArrow.es-Dxee98ir.js → FlowArrow.es-BRWXqf9A.js} +1 -1
  15. package/server/client/dist/assets/{Graph-hVj6vAYJ.js → Graph-BaqGi3M7.js} +1 -1
  16. package/server/client/dist/assets/{Graph-CdEu8eAn.js → Graph-L-d0cdMk.js} +1 -1
  17. package/server/client/dist/assets/{Image.es-CjXY1JVf.js → Image.es-Bh2mTNtr.js} +1 -1
  18. package/server/client/dist/assets/{Info.es-CYxg-Vku.js → Info.es-Bwz4CSvS.js} +1 -1
  19. package/server/client/dist/assets/Integration-C-rva2X9.js +1 -0
  20. package/server/client/dist/assets/{LinkSimple.es-B-P-7Iem.js → LinkSimple.es-iJvLf-MB.js} +1 -1
  21. package/server/client/dist/assets/Note-OO_uh2a7.js +19 -0
  22. package/server/client/dist/assets/{NotePropertiesPanel-6P7UfRBR.js → NotePropertiesPanel-BFWjxL_w.js} +1 -1
  23. package/server/client/dist/assets/{Plus.es-Dy6onD-Z.js → Plus.es-Dmb3oijD.js} +1 -1
  24. package/server/client/dist/assets/{Reminders-DnuALBL6.js → Reminders-CtpFtvu6.js} +1 -1
  25. package/server/client/dist/assets/{Search-AaD1Mt0d.js → Search-t48pkUg-.js} +2 -2
  26. package/server/client/dist/assets/{SurfaceCard-D5QxOte_.js → SurfaceCard-zdJ8k1o0.js} +1 -1
  27. package/server/client/dist/assets/{Tag-B2Qiq1Hv.js → Tag-BL2h3ZaX.js} +1 -1
  28. package/server/client/dist/assets/TagNotes-BpRTCEBf.js +1 -0
  29. package/server/client/dist/assets/Trash.es-DFnO8iF5.js +1 -0
  30. package/server/client/dist/assets/{ViewChip-BVkZAXyx.js → ViewChip-BdPhSEvG.js} +1 -1
  31. package/server/client/dist/assets/{Views-B5oh8GVM.js → Views-BoO6vgnF.js} +1 -1
  32. package/server/client/dist/assets/WarningCircle.es-BAvgGuQK.js +1 -0
  33. package/server/client/dist/assets/{abnfDiagram-N423BO3Z-D44O4T7q.js → abnfDiagram-N423BO3Z-CPgGmCbn.js} +1 -1
  34. package/server/client/dist/assets/app-OGsLwSqJ.js +151 -0
  35. package/server/client/dist/assets/app-yYMsgUrz.css +1 -0
  36. package/server/client/dist/assets/{arc-Cil9fXuW.js → arc-DqTgRpuF.js} +1 -1
  37. package/server/client/dist/assets/{architectureDiagram-T3A2C74G-Cjq6ayF2.js → architectureDiagram-T3A2C74G-rTYMAQ-J.js} +1 -1
  38. package/server/client/dist/assets/{blockDiagram-VBNYF7ZC-B2Xm5N0i.js → blockDiagram-VBNYF7ZC-BOluytVz.js} +1 -1
  39. package/server/client/dist/assets/{c4Diagram-5PPSVZJV-Dp0y-lCR.js → c4Diagram-5PPSVZJV-C8gbPpcb.js} +1 -1
  40. package/server/client/dist/assets/{calendar-data-wB0ifXdo.js → calendar-data-CwVF7Pz3.js} +1 -1
  41. package/server/client/dist/assets/channel--aI9fJWX.js +1 -0
  42. package/server/client/dist/assets/{chunk-2GRJ4B5K-CWaaNkFx.js → chunk-2GRJ4B5K-CRER5Ka0.js} +1 -1
  43. package/server/client/dist/assets/{chunk-2Q5K7J3B-Ces-xz2S.js → chunk-2Q5K7J3B-hxmJWGu_.js} +1 -1
  44. package/server/client/dist/assets/{chunk-5RXB4S5H-B-4Chlfc.js → chunk-5RXB4S5H-Bpr5Us8Y.js} +1 -1
  45. package/server/client/dist/assets/{chunk-5VM5RSS4-C8_HVwuz.js → chunk-5VM5RSS4-CKUz9fAb.js} +1 -1
  46. package/server/client/dist/assets/{chunk-6Q2QTUOP-xZ8ofRqk.js → chunk-6Q2QTUOP-B8XEOHPN.js} +1 -1
  47. package/server/client/dist/assets/{chunk-GF5L2VYU-Bpa43a7s.js → chunk-GF5L2VYU-BBUD-HJi.js} +1 -1
  48. package/server/client/dist/assets/{chunk-JWPE2WC7-DsyTXbuq.js → chunk-JWPE2WC7-Dq6_B8-d.js} +1 -1
  49. package/server/client/dist/assets/{chunk-KBJHAD2P-BDhjm9-8.js → chunk-KBJHAD2P--2VZEwNJ.js} +1 -1
  50. package/server/client/dist/assets/{chunk-RYQCIY6F-Cn-jdp6I.js → chunk-RYQCIY6F-CKCwnKiC.js} +1 -1
  51. package/server/client/dist/assets/{chunk-XXDRQBXY-BKsc_0wh.js → chunk-XXDRQBXY-VDufR1Oi.js} +1 -1
  52. package/server/client/dist/assets/classDiagram-JCYQIIEL-BsbwE38V.js +1 -0
  53. package/server/client/dist/assets/classDiagram-v2-OCEON4UE-BsbwE38V.js +1 -0
  54. package/server/client/dist/assets/{cose-bilkent-JH36ORCC-jmn3Q4zj.js → cose-bilkent-JH36ORCC-D4nqOx8S.js} +1 -1
  55. package/server/client/dist/assets/{cynefinDiagram-MW4NZA55-BpLstuBJ.js → cynefinDiagram-MW4NZA55-CUuLMs-6.js} +1 -1
  56. package/server/client/dist/assets/{dagre-VZM6K2ZE-B5ft5Yzm.js → dagre-VZM6K2ZE-CUSkhZgS.js} +1 -1
  57. package/server/client/dist/assets/{diagram-7IWD3JNH-B_W9IsWZ.js → diagram-7IWD3JNH-D95eVcKx.js} +4 -4
  58. package/server/client/dist/assets/{diagram-B4RE2ZJO-32chS3GX.js → diagram-B4RE2ZJO-7OH_fb0K.js} +1 -1
  59. package/server/client/dist/assets/{diagram-LBJQPF4R-Bqupdb3-.js → diagram-LBJQPF4R-D9UwEIMd.js} +1 -1
  60. package/server/client/dist/assets/{diagram-Q27KOJAE-BD8jKBsv.js → diagram-Q27KOJAE-Dx7WFDuX.js} +1 -1
  61. package/server/client/dist/assets/{diagram-UB23O5K3-C40jAU8D.js → diagram-UB23O5K3-D2BYwAKT.js} +1 -1
  62. package/server/client/dist/assets/{ebnfDiagram-BXEA7PRR-BQfW9mFA.js → ebnfDiagram-BXEA7PRR-DbeA-fk4.js} +1 -1
  63. package/server/client/dist/assets/{erDiagram-JOGREHBK-ILZnLzz2.js → erDiagram-JOGREHBK-jWW-ICGO.js} +1 -1
  64. package/server/client/dist/assets/{flowDiagram-UKHOOZJN-CDmwr2dI.js → flowDiagram-UKHOOZJN-68iZdxxw.js} +1 -1
  65. package/server/client/dist/assets/{ganttDiagram-PKOTCBZU-DBcrUc49.js → ganttDiagram-PKOTCBZU-CxwY3VXg.js} +1 -1
  66. package/server/client/dist/assets/{gitGraphDiagram-DS77QQ5N-_xO6__FK.js → gitGraphDiagram-DS77QQ5N-Ci6o5MfZ.js} +1 -1
  67. package/server/client/dist/assets/{image.api-ChvlfuZg.js → image.api-CHuhmq_G.js} +1 -1
  68. package/server/client/dist/assets/index-CuCzOHJ6.js +1 -0
  69. package/server/client/dist/assets/{infoDiagram-6WML65LV-CuIIcu-L.js → infoDiagram-6WML65LV-DY7aMdjV.js} +1 -1
  70. package/server/client/dist/assets/integrations-B5SIEnG_.js +1 -0
  71. package/server/client/dist/assets/{ishikawaDiagram-WSZJBQD7-BVtRGTOj.js → ishikawaDiagram-WSZJBQD7-Bh5qKh1d.js} +1 -1
  72. package/server/client/dist/assets/{journeyDiagram-NVQOT4AX-D5-Nzb2N.js → journeyDiagram-NVQOT4AX-B_svXTTT.js} +1 -1
  73. package/server/client/dist/assets/{kanban-definition-27J2QSJJ-DmOhgC8H.js → kanban-definition-27J2QSJJ-CaJslHGg.js} +1 -1
  74. package/server/client/dist/assets/manage-image-Kd-7IGfB.js +1 -0
  75. package/server/client/dist/assets/{manage-image-detail-Dw3tAW3h.js → manage-image-detail-HU0QLP-t.js} +1 -1
  76. package/server/client/dist/assets/mcp-BQ418pyx.js +5 -0
  77. package/server/client/dist/assets/{mcp-admin-adapter-D0R8p9az.js → mcp-admin-adapter-CUakQ_Xm.js} +1 -1
  78. package/server/client/dist/assets/{mermaid.core-C2tL9tq7.js → mermaid.core-BfUQM5vF.js} +4 -4
  79. package/server/client/dist/assets/{mindmap-definition-FAOFIHXS-DuvsPqrh.js → mindmap-definition-FAOFIHXS-DGbkJda2.js} +1 -1
  80. package/server/client/dist/assets/{note-core-YhYEmI_R.js → note-core-DRBsBf9H.js} +9 -9
  81. package/server/client/dist/assets/{note-runtime-B3ats-dC.js → note-runtime-ztZvXRIu.js} +16 -16
  82. package/server/client/dist/assets/{note-ui-BtzPk8gA.js → note-ui-CRcP5BjO.js} +1 -1
  83. package/server/client/dist/assets/{pegDiagram-VL7TDLO6-D64crEZV.js → pegDiagram-VL7TDLO6-Bip6zQct.js} +1 -1
  84. package/server/client/dist/assets/{pieDiagram-7S7Q4E2Y--kl7vopC.js → pieDiagram-7S7Q4E2Y-CjfjGY8Y.js} +1 -1
  85. package/server/client/dist/assets/{placeholder-B5uPsE7-.js → placeholder-D7JKnpuh.js} +1 -1
  86. package/server/client/dist/assets/{properties-B7Fv95qY.js → properties-CtagYHMr.js} +1 -1
  87. package/server/client/dist/assets/{quadrantDiagram-CIZ2JOQS-DuvJ4M2y.js → quadrantDiagram-CIZ2JOQS-B6F1yUT-.js} +1 -1
  88. package/server/client/dist/assets/{railroadDiagram-AXF67PYL-BMKmCOY7.js → railroadDiagram-AXF67PYL-D-0fLe0F.js} +1 -1
  89. package/server/client/dist/assets/{requirementDiagram-LRYGKXZP-DY1eJcy0.js → requirementDiagram-LRYGKXZP-tm4mnCyJ.js} +1 -1
  90. package/server/client/dist/assets/route-preload.js +2 -2
  91. package/server/client/dist/assets/{sankeyDiagram-W5VNT64P-C3Ka4GKM.js → sankeyDiagram-W5VNT64P-DSBWFurb.js} +1 -1
  92. package/server/client/dist/assets/search-B5tCkhwj.js +1 -0
  93. package/server/client/dist/assets/{search-admin-adapter-Daf7e2YQ.js → search-admin-adapter-Be9xSY88.js} +1 -1
  94. package/server/client/dist/assets/{sequenceDiagram-SI44F4Z6-Bhpwtk2s.js → sequenceDiagram-SI44F4Z6-KrwjjJIV.js} +1 -1
  95. package/server/client/dist/assets/{sizeCapture-X5ZJPWSS-BFta71TW.js → sizeCapture-X5ZJPWSS-DL2cn_Q6.js} +1 -1
  96. package/server/client/dist/assets/{stateDiagram-OKZ733FA-D6GCn1io.js → stateDiagram-OKZ733FA-CKuNDH85.js} +1 -1
  97. package/server/client/dist/assets/{stateDiagram-v2-UEYNNEHI-g4yinGDn.js → stateDiagram-v2-UEYNNEHI-BFaj2wbM.js} +1 -1
  98. package/server/client/dist/assets/{swimlanes-SLNWSIFB-DLFvOjUl.js → swimlanes-SLNWSIFB-5S17nqhK.js} +2 -2
  99. package/server/client/dist/assets/swimlanesDiagram-ULZ7WXOC-dexsHJq2.js +8 -0
  100. package/server/client/dist/assets/{tag.api-DEUROVKQ.js → tag.api-DGfi8hWL.js} +1 -1
  101. package/server/client/dist/assets/time-Kh6oav5R.js +361 -0
  102. package/server/client/dist/assets/{timeline-definition-Z64GVDOM-DTSIekSM.js → timeline-definition-Z64GVDOM-CU1hp_7d.js} +3 -3
  103. package/server/client/dist/assets/{trash-BHida7BG.js → trash-Di2BWyUO.js} +1 -1
  104. package/server/client/dist/assets/url-Bp8sXMb4.js +1 -0
  105. package/server/client/dist/assets/{useNoteMutate-BjvZUmtX.js → useNoteMutate-BQj6jHhV.js} +3 -3
  106. package/server/client/dist/assets/{useReminderMutate-C5n-5LM-.js → useReminderMutate-jubqwSD9.js} +1 -1
  107. package/server/client/dist/assets/{vennDiagram-T6HMQDX7-CMNqSI2X.js → vennDiagram-T6HMQDX7-MoiVLnil.js} +1 -1
  108. package/server/client/dist/assets/{wardleyDiagram-T6FBY63Y-DV-JOYqB.js → wardleyDiagram-T6FBY63Y-cZkfdI6C.js} +1 -1
  109. package/server/client/dist/assets/{xychartDiagram-ELKLHX3M-BUIniF4m.js → xychartDiagram-ELKLHX3M-B63hxD-r.js} +1 -1
  110. package/server/client/dist/index.html +6 -6
  111. package/server/dist/app.js +11 -1
  112. package/server/dist/features/app-gateway/access.js +73 -0
  113. package/server/dist/features/app-gateway/database.js +20 -0
  114. package/server/dist/features/app-gateway/gateway.js +208 -0
  115. package/server/dist/features/integration/access-events.js +17 -0
  116. package/server/dist/features/integration/auth.js +21 -0
  117. package/server/dist/features/integration/manifest.js +116 -0
  118. package/server/dist/features/integration/note-sync.js +156 -0
  119. package/server/dist/features/integration/schema.js +54 -0
  120. package/server/dist/features/integration/service.js +246 -0
  121. package/server/dist/features/integration/status-report.js +22 -0
  122. package/server/dist/features/mcp-admin/service.js +19 -83
  123. package/server/dist/features/note/graphql/note.field.resolver.js +1 -1
  124. package/server/dist/features/note/graphql/note.mutation.resolver.js +20 -12
  125. package/server/dist/features/note/graphql/note.query.resolver.js +10 -1
  126. package/server/dist/features/note/graphql/note.type-defs.js +13 -1
  127. package/server/dist/features/note/http/authoring.js +493 -0
  128. package/server/dist/features/note/http/mcp.js +15 -463
  129. package/server/dist/features/note/services/authoring.js +17 -1
  130. package/server/dist/features/note/services/change-events.js +26 -0
  131. package/server/dist/features/note/services/markdown-intent-write.js +1 -0
  132. package/server/dist/features/note/services/markdown-read.js +85 -0
  133. package/server/dist/features/note/services/properties.js +36 -30
  134. package/server/dist/features/note/services/search.js +17 -0
  135. package/server/dist/features/search/graphql/resolver.js +10 -1
  136. package/server/dist/features/search/graphql/type-defs.js +3 -0
  137. package/server/dist/features/search/search-manager.js +4 -7
  138. package/server/dist/features/tag/graphql/tag.query.resolver.js +10 -0
  139. package/server/dist/features/tag/graphql/tag.type-defs.js +1 -0
  140. package/server/dist/features/view/graphql/mcp.query.resolver.js +22 -0
  141. package/server/dist/features/view/graphql/view.query.resolver.js +2 -0
  142. package/server/dist/features/view/graphql/view.type-defs.js +27 -0
  143. package/server/dist/features/view/services/mcp-read.js +142 -0
  144. package/server/dist/features/view/services/workspace.js +12 -4
  145. package/server/dist/modules/auth-guard.js +24 -1
  146. package/server/dist/modules/integration-token.js +27 -0
  147. package/server/dist/modules/mcp-auth.js +37 -23
  148. package/server/dist/modules/mcp-token.js +6 -25
  149. package/server/dist/modules/server-events.js +3 -0
  150. package/server/dist/routes/api.js +2 -0
  151. package/server/dist/routes/apps.js +163 -0
  152. package/server/dist/routes/graphql.js +2 -1
  153. package/server/dist/routes/index.js +2 -0
  154. package/server/dist/routes/integrations.js +137 -0
  155. package/server/dist/routes/mcp.js +29 -9
  156. package/server/prisma/migrations/20260917120000_0020_plugin_installations/migration.sql +39 -0
  157. package/server/prisma/migrations/20260917150000_0021_integration_connections/migration.sql +29 -0
  158. package/server/prisma/migrations/20260919090000_0022_integration_proxy_url/migration.sql +2 -0
  159. package/server/prisma/schema.prisma +36 -10
  160. package/server/client/dist/assets/Calendar-DwQBllfw.js +0 -25
  161. package/server/client/dist/assets/Callout-CcYyvHQP.js +0 -1
  162. package/server/client/dist/assets/Note-CpzLtGVM.js +0 -19
  163. package/server/client/dist/assets/TagNotes-B27G1ZVg.js +0 -1
  164. package/server/client/dist/assets/Trash.es-XEcWG_aq.js +0 -1
  165. package/server/client/dist/assets/app-EwvT7bMw.css +0 -1
  166. package/server/client/dist/assets/app-NgiBDISG.js +0 -151
  167. package/server/client/dist/assets/channel-DZFalh-h.js +0 -1
  168. package/server/client/dist/assets/classDiagram-JCYQIIEL-CkEhFvVV.js +0 -1
  169. package/server/client/dist/assets/classDiagram-v2-OCEON4UE-CkEhFvVV.js +0 -1
  170. package/server/client/dist/assets/index-CIEap4bu.js +0 -1
  171. package/server/client/dist/assets/manage-image-CSJ3Flgc.js +0 -1
  172. package/server/client/dist/assets/mcp-D8footel.js +0 -5
  173. package/server/client/dist/assets/search-ddYl3qH-.js +0 -1
  174. package/server/client/dist/assets/swimlanesDiagram-ULZ7WXOC-Ci4mcvmo.js +0 -8
  175. package/server/client/dist/assets/time-PxWila4-.js +0 -361
  176. package/server/client/dist/assets/url-DKUMNVCI.js +0 -1
  177. package/server/dist/features/search/note-change.js +0 -16
@@ -1,87 +1,23 @@
1
- import models from "../../models.js";
2
- import { issueMcpToken, verifyMcpToken } from "../../modules/mcp-token.js";
3
- const MCP_ENABLED_CACHE_KEY = "MCP_ENABLED";
4
- const toStatus = (enabled, activeToken) => {
5
- if (!activeToken) {
6
- return {
7
- enabled,
8
- hasActiveToken: false,
9
- token: null
10
- };
1
+ import { MCP_CONNECTION_ID } from "../integration/manifest.js";
2
+ import { createIntegrationService } from "../integration/service.js";
3
+ const createMcpAdminService = (integrations = createIntegrationService()) => ({
4
+ async getStatus() {
5
+ const integration = await integrations.get(MCP_CONNECTION_ID);
6
+ return { enabled: integration.enabled, hasActiveToken: integration.token !== null, token: integration.token };
7
+ },
8
+ async setEnabled(enabled) {
9
+ await integrations.update(MCP_CONNECTION_ID, { enabled });
10
+ },
11
+ rotateToken: () => integrations.rotateToken(MCP_CONNECTION_ID),
12
+ revokeActiveToken: () => integrations.revokeToken(MCP_CONNECTION_ID),
13
+ async validatePresentedToken(token) {
14
+ const integration = await integrations.get(MCP_CONNECTION_ID);
15
+ if (!integration.token) return { ok: false, reason: "not_configured" };
16
+ const principal = await integrations.authenticate(token);
17
+ if (!principal || principal.connectionId !== MCP_CONNECTION_ID) return { ok: false, reason: "forbidden" };
18
+ return { ok: true, permissions: principal.permissions };
11
19
  }
12
- return {
13
- enabled,
14
- hasActiveToken: true,
15
- token: {
16
- id: String(activeToken.id),
17
- createdAt: activeToken.createdAt.toISOString(),
18
- lastUsedAt: activeToken.lastUsedAt ? activeToken.lastUsedAt.toISOString() : null
19
- }
20
- };
21
- };
22
- const createMcpAdminService = (db = models) => {
23
- return {
24
- async getStatus() {
25
- const enabledCache = await db.cache.findUnique({ where: { key: MCP_ENABLED_CACHE_KEY } });
26
- const activeToken = await db.mcpToken.findFirst({
27
- where: { revokedAt: null },
28
- orderBy: { createdAt: "desc" }
29
- });
30
- return toStatus(enabledCache?.value === "true", activeToken);
31
- },
32
- async setEnabled(enabled) {
33
- await db.cache.upsert({
34
- where: { key: MCP_ENABLED_CACHE_KEY },
35
- update: { value: String(enabled) },
36
- create: {
37
- key: MCP_ENABLED_CACHE_KEY,
38
- value: String(enabled)
39
- }
40
- });
41
- },
42
- async rotateToken() {
43
- const now = /* @__PURE__ */ new Date();
44
- const issued = issueMcpToken();
45
- await db.$transaction(async (transaction) => {
46
- await transaction.mcpToken.updateMany({
47
- where: { revokedAt: null },
48
- data: { revokedAt: now }
49
- });
50
- await transaction.mcpToken.create({ data: { tokenHash: issued.hash } });
51
- });
52
- return { token: issued.plaintext };
53
- },
54
- async revokeActiveToken() {
55
- await db.mcpToken.updateMany({
56
- where: { revokedAt: null },
57
- data: { revokedAt: /* @__PURE__ */ new Date() }
58
- });
59
- },
60
- async validatePresentedToken(token) {
61
- const activeToken = await db.mcpToken.findFirst({
62
- where: { revokedAt: null },
63
- orderBy: { createdAt: "desc" }
64
- });
65
- if (!activeToken) {
66
- return {
67
- ok: false,
68
- reason: "not_configured"
69
- };
70
- }
71
- if (!verifyMcpToken(activeToken.tokenHash, token)) {
72
- return {
73
- ok: false,
74
- reason: "forbidden"
75
- };
76
- }
77
- await db.mcpToken.update({
78
- where: { id: activeToken.id },
79
- data: { lastUsedAt: /* @__PURE__ */ new Date() }
80
- });
81
- return { ok: true };
82
- }
83
- };
84
- };
20
+ });
85
21
  export {
86
22
  createMcpAdminService
87
23
  };
@@ -4,7 +4,7 @@ import { renderNoteSnapshotContentAsMarkdown } from "../../../features/note/serv
4
4
  import models from "../../../models.js";
5
5
  const noteFieldResolvers = {
6
6
  tags: async (note) => models.tag.findMany({ where: { notes: { some: { id: note.id } } } }),
7
- properties: async (note) => listNoteProperties(note.id),
7
+ properties: async (note, { keys }) => listNoteProperties(note.id, keys ?? note.selectedPropertyKeys),
8
8
  contentPreview: (note) => buildNoteContentPreview(note.content),
9
9
  contentAsMarkdown: async (note) => {
10
10
  const { blocksToMarkdown } = await import("../../../modules/blocknote.js");
@@ -1,4 +1,5 @@
1
1
  import { GraphQLError } from "graphql";
2
+ import { emitNoteChange } from "../../../features/note/services/change-events.js";
2
3
  import { extractBlocksByType, parseNoteContent } from "../../../features/note/services/content-blocks.js";
3
4
  import { replaceNoteReferences } from "../../../features/note/services/note-reference-index.js";
4
5
  import {
@@ -18,7 +19,6 @@ import {
18
19
  isMissingNoteVersionError,
19
20
  isNoteVersionConflictError
20
21
  } from "../../../features/note/services/write-conflict.js";
21
- import { notifySemanticSearchNoteChanged } from "../../../features/search/note-change.js";
22
22
  import models from "../../../models.js";
23
23
  const PLACEHOLDER_PREFIX = "{%";
24
24
  const PLACEHOLDER_SUFFIX = "%}";
@@ -83,7 +83,7 @@ const noteMutationResolvers = {
83
83
  await replaceNoteReferences(tx, createdNote.id, replacedContent);
84
84
  return noteResult2;
85
85
  });
86
- notifySemanticSearchNoteChanged(noteResult.id);
86
+ emitNoteChange({ type: "note.created", noteId: noteResult.id });
87
87
  return noteResult;
88
88
  },
89
89
  updateNote: async (_, {
@@ -112,7 +112,7 @@ const noteMutationResolvers = {
112
112
  if (!updatedNote) {
113
113
  throw "NOT FOUND";
114
114
  }
115
- notifySemanticSearchNoteChanged(updatedNote.id);
115
+ emitNoteChange({ type: "note.updated", noteId: updatedNote.id });
116
116
  return updatedNote;
117
117
  } catch (error) {
118
118
  if (isNoteVersionConflictError(error)) {
@@ -146,7 +146,7 @@ const noteMutationResolvers = {
146
146
  if (!trashedNote) {
147
147
  throw "NOT FOUND";
148
148
  }
149
- notifySemanticSearchNoteChanged(Number(id));
149
+ emitNoteChange({ type: "note.deleted", noteId: Number(id) });
150
150
  return true;
151
151
  },
152
152
  restoreNoteSnapshot: async (_, { id, expectedUpdatedAt }, context) => {
@@ -158,7 +158,7 @@ const noteMutationResolvers = {
158
158
  if (!note) {
159
159
  throw "NOT FOUND";
160
160
  }
161
- notifySemanticSearchNoteChanged(note.id);
161
+ emitNoteChange({ type: "note.updated", noteId: note.id });
162
162
  return note;
163
163
  } catch (error) {
164
164
  if (isNoteVersionConflictError(error)) {
@@ -185,7 +185,7 @@ const noteMutationResolvers = {
185
185
  if (!note) {
186
186
  throw "NOT FOUND";
187
187
  }
188
- notifySemanticSearchNoteChanged(note.id);
188
+ emitNoteChange({ type: "note.created", noteId: note.id });
189
189
  return note;
190
190
  },
191
191
  purgeTrashedNote: async (_, { id }) => {
@@ -193,7 +193,6 @@ const noteMutationResolvers = {
193
193
  if (!purgedNote) {
194
194
  throw "NOT FOUND";
195
195
  }
196
- notifySemanticSearchNoteChanged(Number(id));
197
196
  return true;
198
197
  },
199
198
  createNotePropertyKey: async (_, { input }) => {
@@ -272,6 +271,7 @@ const noteMutationResolvers = {
272
271
  if (!note) {
273
272
  throw "NOT FOUND";
274
273
  }
274
+ emitNoteChange({ type: "note.updated", noteId: note.id, affectsSearchIndex: false });
275
275
  return note;
276
276
  } catch (error) {
277
277
  if (error instanceof InvalidNotePropertyInputError) {
@@ -307,10 +307,14 @@ const noteMutationResolvers = {
307
307
  throw error;
308
308
  }
309
309
  },
310
- pinNote: (_, { id, pinned }) => models.note.update({
311
- where: { id: Number(id) },
312
- data: { pinned: Boolean(pinned) }
313
- }),
310
+ pinNote: async (_, { id, pinned }) => {
311
+ const note = await models.note.update({
312
+ where: { id: Number(id) },
313
+ data: { pinned: Boolean(pinned) }
314
+ });
315
+ emitNoteChange({ type: "note.updated", noteId: note.id, affectsSearchIndex: false });
316
+ return note;
317
+ },
314
318
  reorderNotes: async (_, { notes }) => {
315
319
  const updatePromises = notes.map(
316
320
  ({ id, order }) => models.note.update({
@@ -318,7 +322,11 @@ const noteMutationResolvers = {
318
322
  data: { order }
319
323
  })
320
324
  );
321
- return Promise.all(updatePromises);
325
+ const updatedNotes = await Promise.all(updatePromises);
326
+ for (const note of updatedNotes) {
327
+ emitNoteChange({ type: "note.updated", noteId: note.id, affectsSearchIndex: false });
328
+ }
329
+ return updatedNotes;
322
330
  }
323
331
  };
324
332
  export {
@@ -1,3 +1,4 @@
1
+ import { emitNoteChange } from "../../../features/note/services/change-events.js";
1
2
  import { getNoteCleanupPreview, listNoteCleanupCandidates } from "../../../features/note/services/cleanup.js";
2
3
  import {
3
4
  buildNoteGraph,
@@ -21,6 +22,7 @@ import {
21
22
  import { getTrashedNoteById, listTrashedNotes } from "../../../features/note/services/trash.js";
22
23
  import models from "../../../models.js";
23
24
  import { runDataMaintenanceInBackground } from "../../../modules/data-maintenance.js";
25
+ import { readMarkdownRange } from "../services/markdown-read.js";
24
26
  const MAX_SQLITE_INT_ID = 2147483647;
25
27
  const isValidNoteIdString = (id) => {
26
28
  if (!/^[1-9]\d*$/.test(id)) {
@@ -292,7 +294,7 @@ const createNoteQueryResolver = (deps = {
292
294
  return note;
293
295
  }
294
296
  try {
295
- return await deps.updateNoteContent({
297
+ const updatedNote = await deps.updateNoteContent({
296
298
  id: note.id,
297
299
  updatedAt: note.updatedAt,
298
300
  content: newContent,
@@ -301,6 +303,8 @@ const createNoteQueryResolver = (deps = {
301
303
  content: newContent
302
304
  })
303
305
  });
306
+ emitNoteChange({ type: "note.updated", noteId: updatedNote.id });
307
+ return updatedNote;
304
308
  } catch (error) {
305
309
  if (deps.isRecordNotFoundError(error)) {
306
310
  return note;
@@ -386,6 +390,11 @@ const noteQueryResolvers = {
386
390
  }),
387
391
  backReferences: createBackReferencesQueryResolver(),
388
392
  note: createNoteQueryResolver(),
393
+ noteRead: async (_, { id, ...input }) => {
394
+ const note = await createNoteQueryResolver()(_, { id });
395
+ const { blocksToMarkdown } = await import("../../../modules/blocknote.js");
396
+ return { note, ...readMarkdownRange(await blocksToMarkdown(note.content), note.updatedAt, input) };
397
+ },
389
398
  noteCleanupCandidates: async (_, {
390
399
  query,
391
400
  pagination = {
@@ -106,7 +106,7 @@ const noteType = gql`
106
106
  order: Int!
107
107
  layout: NoteLayout!
108
108
  tags: [Tag!]!
109
- properties: [NoteProperty!]!
109
+ properties(keys: [String!]): [NoteProperty!]!
110
110
  }
111
111
 
112
112
  type NoteProperty {
@@ -269,6 +269,17 @@ const noteQuery = gql`
269
269
  links: [GraphLink!]!
270
270
  }
271
271
 
272
+ type NoteContentRange { start: Int!, end: Int!, totalLength: Int!, sectionEnd: Int!, hasMore: Boolean!, nextOffset: Int }
273
+ type NoteHeadingCandidate { heading: String!, level: Int!, start: Int!, end: Int! }
274
+ type NoteReadResult {
275
+ status: String!
276
+ reason: String
277
+ message: String
278
+ note: Note!
279
+ markdown: String!
280
+ contentRange: NoteContentRange
281
+ candidates: [NoteHeadingCandidate!]!
282
+ }
272
283
  type Query {
273
284
  allNotes(searchFilter: SearchFilterInput, pagination: PaginationInput): Notes!
274
285
  tagNotes(searchFilter: SearchFilterInput, pagination: PaginationInput): Notes!
@@ -278,6 +289,7 @@ const noteQuery = gql`
278
289
  imageNotes(src: String!): [Note!]!
279
290
  backReferences(id: ID!): [Note]!
280
291
  note(id: ID!): Note!
292
+ noteRead(id: ID!, offset: Int, maxLength: Int, heading: String, expectedUpdatedAt: String): NoteReadResult!
281
293
  noteCleanupCandidates(query: String, pagination: PaginationInput): [NoteCleanupCandidate!]!
282
294
  noteCleanupPreview(id: ID!): NoteCleanupPreview
283
295
  noteSnapshots(id: ID!, limit: Int): [NoteSnapshot!]!