@xopcai/xopc 0.0.90 → 0.0.91

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 (290) hide show
  1. package/README.md +36 -12
  2. package/README.zh-CN.md +36 -12
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  5. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  6. package/dist/extensions/telegram/src/plugin.js +1 -1
  7. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  8. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  9. package/dist/extensions/telegram/xopc.extension.json +1 -1
  10. package/dist/extensions/weixin/src/api/api.js +2 -2
  11. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  12. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  13. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  14. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  15. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  16. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  17. package/dist/extensions/weixin/src/plugin.js +1 -1
  18. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  19. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  20. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +41 -0
  21. package/dist/gateway/static/root/assets/agents-bVWUlrlD.js +222 -0
  22. package/dist/gateway/static/root/assets/apps-page-CIC8bmvZ.js +1 -0
  23. package/dist/gateway/static/root/assets/{attachment-preview-renderer-CpyoFbs4.js → attachment-preview-renderer-DBAxQXb-.js} +2 -2
  24. package/dist/gateway/static/root/assets/{attachment-process-heavy-CqVriadb.js → attachment-process-heavy-Csq3TrrP.js} +4 -4
  25. package/dist/gateway/static/root/assets/channels-settings-C8G8RAAP.js +1 -0
  26. package/dist/gateway/static/root/assets/{channels-status-swr-BrtH2VzC.js → channels-status-swr-CYWL5DLD.js} +1 -1
  27. package/dist/gateway/static/root/assets/copy-Dv6d4Dvw.js +1 -0
  28. package/dist/gateway/static/root/assets/{cron-api-CyqbgfHM.js → cron-api-TVqLlGAC.js} +1 -1
  29. package/dist/gateway/static/root/assets/cron-page-BtcFYlvv.js +1 -0
  30. package/dist/gateway/static/root/assets/dist-CUV1uY5f.js +1 -0
  31. package/dist/gateway/static/root/assets/{extension-debug-page-D6Ak0STa.js → extension-debug-page-mTLHRDp1.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-Q0P3d6DW.js → extension-page-iI8BI7WK.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-CL55LwU_.js → extension-settings-page-ByXcdubM.js} +1 -1
  34. package/dist/gateway/static/root/assets/{fetch-Dqa9iTWl.js → fetch-BWtQq_Ys.js} +1 -1
  35. package/dist/gateway/static/root/assets/{field-primitives-HUR6JElP.js → field-primitives-BsZ-4VT5.js} +1 -1
  36. package/dist/gateway/static/root/assets/{heartbeat-config-api-DusckjUX.js → heartbeat-config-api-WjTsRLCU.js} +1 -1
  37. package/dist/gateway/static/root/assets/{index-BYcGfwcE.js → index-CKkR-v9U.js} +85 -81
  38. package/dist/gateway/static/root/assets/index-VlELBY99.css +1 -0
  39. package/dist/gateway/static/root/assets/logs-page-ClnIpxfd.js +1 -0
  40. package/dist/gateway/static/root/assets/note-detail-page-B91pLkEI.css +1 -0
  41. package/dist/gateway/static/root/assets/note-detail-page-DJ2Mb4x7.js +179 -0
  42. package/dist/gateway/static/root/assets/note-time-JLBPSLzK.js +1 -0
  43. package/dist/gateway/static/root/assets/notes-page-BE-75qz9.js +1 -0
  44. package/dist/gateway/static/root/assets/{pdf-BnEvgIXZ.js → pdf-epILhEOn.js} +1 -1
  45. package/dist/gateway/static/root/assets/preload-helper-zJ_50EbN.js +1 -0
  46. package/dist/gateway/static/root/assets/sessions-page-bJJkWtTl.js +1 -0
  47. package/dist/gateway/static/root/assets/{settings-form-section-a0qGVOlr.js → settings-form-section-DSYCknxM.js} +1 -1
  48. package/dist/gateway/static/root/assets/settings-page-WcMXLq2U.js +3 -0
  49. package/dist/gateway/static/root/assets/share-preview-page-awRqs4hV.js +2 -0
  50. package/dist/gateway/static/root/assets/skills-page-Lu-i1JG7.js +2 -0
  51. package/dist/gateway/static/root/assets/{theme-store-C0Ehmdo5.js → theme-store-BC-42BoZ.js} +1 -1
  52. package/dist/gateway/static/root/assets/toast-z0toXu32.js +1 -0
  53. package/dist/gateway/static/root/assets/url-CY1RQKTU.js +3 -0
  54. package/dist/gateway/static/root/assets/{utils-DRQryzdn.js → utils-DX3TQuap.js} +1 -1
  55. package/dist/gateway/static/root/assets/vendor-codemirror-DYoKfS8f.js +45 -0
  56. package/dist/gateway/static/root/assets/{voice-api-key-field-D0viACE2.js → voice-api-key-field-B5uKlDqA.js} +1 -1
  57. package/dist/gateway/static/root/assets/{workflow-page.utils-DnG8JBhV.js → workflow-page.utils-ClC37yEp.js} +1 -1
  58. package/dist/gateway/static/root/assets/workflows-page-C7VhIXtR.js +27 -0
  59. package/dist/gateway/static/root/index.html +10 -8
  60. package/dist/package.js +1 -1
  61. package/dist/src/agent/agent-manager.js +7 -7
  62. package/dist/src/agent/agent-scope.js +1 -1
  63. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  64. package/dist/src/agent/context/workspace-seed.js +2 -2
  65. package/dist/src/agent/goals/goal-run-store.js +4 -4
  66. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  67. package/dist/src/agent/goals/post-turn.js +2 -2
  68. package/dist/src/agent/image/load-image-media.js +2 -2
  69. package/dist/src/agent/ipc/bus.js +1 -1
  70. package/dist/src/agent/ipc/inbox.js +2 -2
  71. package/dist/src/agent/ipc/socket.js +1 -1
  72. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  73. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  74. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  75. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  76. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  77. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  78. package/dist/src/agent/memory/dreaming/events.js +1 -1
  79. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  80. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  81. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  82. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  83. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  84. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  85. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  86. package/dist/src/agent/models/manager.js +1 -1
  87. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  88. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  89. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  90. package/dist/src/agent/sandbox/path-policy.js +2 -2
  91. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  92. package/dist/src/agent/service.js +4 -4
  93. package/dist/src/agent/session/session-inspector.js +1 -1
  94. package/dist/src/agent/skills/config.js +1 -1
  95. package/dist/src/agent/skills/hub-hash.js +2 -2
  96. package/dist/src/agent/skills/hub-lock.js +1 -1
  97. package/dist/src/agent/skills/hub-pull.js +2 -2
  98. package/dist/src/agent/skills/index.js +1 -1
  99. package/dist/src/agent/skills/managed-store.js +1 -1
  100. package/dist/src/agent/skills/scanner.js +1 -1
  101. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  102. package/dist/src/agent/skills/skill-manager.js +1 -1
  103. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  104. package/dist/src/agent/tools/factory.js +1 -1
  105. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  106. package/dist/src/agent/tools/send-media.js +1 -1
  107. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  108. package/dist/src/agent/tools/workflow-tool.js +1 -1
  109. package/dist/src/agent/tools/write.js +1 -1
  110. package/dist/src/agent/workflow/catalog.js +1 -1
  111. package/dist/src/auth/credentials.js +3 -3
  112. package/dist/src/auth/profiles/store.js +1 -1
  113. package/dist/src/auth/sync-provider-auth.js +1 -1
  114. package/dist/src/browser/cache-dir-policy.js +1 -1
  115. package/dist/src/browser/cdp-local-launcher.js +2 -2
  116. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  117. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  118. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  119. package/dist/src/browser/stealth.js +1 -1
  120. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  121. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  122. package/dist/src/channels/outbound/persist-store.js +1 -1
  123. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  124. package/dist/src/channels/pairing/pairing-store.js +2 -2
  125. package/dist/src/chat-commands/agent-edit.js +2 -2
  126. package/dist/src/chat-commands/builtins/config.js +2 -2
  127. package/dist/src/chat-commands/context.js +1 -1
  128. package/dist/src/cli/commands/config.js +1 -1
  129. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  130. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  131. package/dist/src/cli/commands/doctor/checks/session-integrity.js +2 -2
  132. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  133. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  134. package/dist/src/cli/commands/extension-dev.js +1 -1
  135. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  136. package/dist/src/cli/commands/extension-pack.js +1 -1
  137. package/dist/src/cli/commands/gateway/logs.js +1 -1
  138. package/dist/src/cli/commands/image.js +1 -1
  139. package/dist/src/cli/commands/init.js +4 -4
  140. package/dist/src/cli/commands/onboard.js +1 -1
  141. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  142. package/dist/src/commands/agents.config.js +1 -1
  143. package/dist/src/config/agent-profile.js +1 -1
  144. package/dist/src/config/gateway-bind.js +1 -1
  145. package/dist/src/config/index.js +5 -5
  146. package/dist/src/config/loader.js +2 -2
  147. package/dist/src/config/models-json.js +2 -2
  148. package/dist/src/config/paths-state.js +1 -1
  149. package/dist/src/config/profile.js +2 -2
  150. package/dist/src/config/workspace-path.js +1 -1
  151. package/dist/src/cron/executor.js +2 -2
  152. package/dist/src/cron/persistence.js +1 -1
  153. package/dist/src/cron/run-log-store.js +1 -1
  154. package/dist/src/daemon/constants.js +1 -1
  155. package/dist/src/daemon/install-plan.js +2 -2
  156. package/dist/src/daemon/launchd.js +2 -2
  157. package/dist/src/daemon/schtasks.js +2 -2
  158. package/dist/src/daemon/systemd.js +2 -2
  159. package/dist/src/extensions/bundle-mcp.js +1 -1
  160. package/dist/src/extensions/discover-extensions.js +1 -1
  161. package/dist/src/extensions/health.js +1 -1
  162. package/dist/src/extensions/loader.js +1 -1
  163. package/dist/src/extensions/lockfile.js +2 -2
  164. package/dist/src/extensions/update.js +1 -1
  165. package/dist/src/gateway/agents-admin.js +3 -3
  166. package/dist/src/gateway/file-path-classifier.js +2 -2
  167. package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
  168. package/dist/src/gateway/hono/lib/config-payload.js +2 -1
  169. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  170. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  171. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  172. package/dist/src/gateway/hono/middleware/auth.js +1 -2
  173. package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
  174. package/dist/src/gateway/hono/oauth.js +1 -1
  175. package/dist/src/gateway/hono/routes/agents.js +1 -1
  176. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  177. package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +2 -2
  178. package/dist/src/gateway/hono/routes/config-patch/gateway.js +12 -0
  179. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  180. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  181. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  182. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  183. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  184. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  185. package/dist/src/gateway/hono/routes/models.js +1 -1
  186. package/dist/src/gateway/hono/routes/notes.d.ts +3 -0
  187. package/dist/src/gateway/hono/routes/notes.js +274 -0
  188. package/dist/src/gateway/hono/routes/notes.js.map +1 -0
  189. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  190. package/dist/src/gateway/hono/routes/shares.js +1 -1
  191. package/dist/src/gateway/hono/routes/workspace.js +4 -4
  192. package/dist/src/gateway/lock.js +3 -3
  193. package/dist/src/gateway/ports.js +1 -1
  194. package/dist/src/gateway/service/agent-runner.js +2 -2
  195. package/dist/src/gateway/service/marketplace-service.js +2 -2
  196. package/dist/src/gateway/service.d.ts +3 -0
  197. package/dist/src/gateway/service.js +11 -1
  198. package/dist/src/gateway/service.js.map +1 -1
  199. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  200. package/dist/src/gateway/workspace-ripgrep.d.ts +6 -0
  201. package/dist/src/gateway/workspace-ripgrep.js +62 -11
  202. package/dist/src/gateway/workspace-ripgrep.js.map +1 -1
  203. package/dist/src/infra/brew.js +1 -1
  204. package/dist/src/infra/package-json.js +1 -1
  205. package/dist/src/infra/package-update-steps.js +1 -1
  206. package/dist/src/infra/path-env.js +2 -2
  207. package/dist/src/infra/restart.js +2 -2
  208. package/dist/src/infra/stable-node-path.js +1 -1
  209. package/dist/src/infra/update-check.js +1 -1
  210. package/dist/src/infra/update-global.js +1 -1
  211. package/dist/src/infra/update-lock.js +3 -3
  212. package/dist/src/infra/update-runner.js +1 -1
  213. package/dist/src/infra/update-startup.js +2 -2
  214. package/dist/src/infra/write-file-atomic.js +2 -2
  215. package/dist/src/notes/attachment-ref.d.ts +9 -0
  216. package/dist/src/notes/attachment-ref.js +27 -0
  217. package/dist/src/notes/attachment-ref.js.map +1 -0
  218. package/dist/src/notes/index.d.ts +4 -0
  219. package/dist/src/notes/index.js +4 -0
  220. package/dist/src/notes/note-attachment-sync.d.ts +7 -0
  221. package/dist/src/notes/note-attachment-sync.js +46 -0
  222. package/dist/src/notes/note-attachment-sync.js.map +1 -0
  223. package/dist/src/notes/note-index-meta.d.ts +14 -0
  224. package/dist/src/notes/note-index-meta.js +87 -0
  225. package/dist/src/notes/note-index-meta.js.map +1 -0
  226. package/dist/src/notes/paths.d.ts +5 -0
  227. package/dist/src/notes/paths.js +23 -0
  228. package/dist/src/notes/paths.js.map +1 -0
  229. package/dist/src/notes/service.d.ts +42 -0
  230. package/dist/src/notes/service.js +331 -0
  231. package/dist/src/notes/service.js.map +1 -0
  232. package/dist/src/notes/store.d.ts +33 -0
  233. package/dist/src/notes/store.js +317 -0
  234. package/dist/src/notes/store.js.map +1 -0
  235. package/dist/src/notes/types.d.ts +162 -0
  236. package/dist/src/notes/types.js +1 -0
  237. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  238. package/dist/src/providers/index.js +2 -2
  239. package/dist/src/providers/model-registry.js +1 -1
  240. package/dist/src/session/config-store.js +2 -2
  241. package/dist/src/session/init-session-turn.js +2 -2
  242. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  243. package/dist/src/session/parity/sessions-json-file.js +1 -1
  244. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  245. package/dist/src/session/parity/transcript-paths.js +1 -1
  246. package/dist/src/session/resolve-session.js +4 -4
  247. package/dist/src/session/search-index-cache.js +1 -1
  248. package/dist/src/session/search-index.js +1 -1
  249. package/dist/src/session/session-title.js +2 -2
  250. package/dist/src/session/store.js +6 -6
  251. package/dist/src/share/share-auto.js +2 -2
  252. package/dist/src/share/share-store.js +3 -3
  253. package/dist/src/share/share-thumbnail.js +2 -2
  254. package/dist/src/share/share-zip.js +1 -1
  255. package/dist/src/share/site-share-store.js +3 -3
  256. package/dist/src/share/site-static-serve.js +1 -1
  257. package/dist/src/tui/clipboard-image.js +3 -3
  258. package/dist/src/tui/theme-manager.js +1 -1
  259. package/dist/src/tui/tui-keybindings-file.js +1 -1
  260. package/dist/src/tui/tui-scoped-models.js +2 -2
  261. package/dist/src/tui/tui-settings.js +1 -1
  262. package/dist/src/tui/tui.js +3 -3
  263. package/dist/src/tunnel/frpc-binary.js +3 -3
  264. package/dist/src/tunnel/frpc-config.js +1 -1
  265. package/dist/src/tunnel/frpc-extract.js +1 -1
  266. package/dist/src/tunnel/tunnel-state.js +1 -1
  267. package/dist/src/utils/logger/audit.js +1 -1
  268. package/dist/src/utils/logger/log-store.js +1 -1
  269. package/dist/src/utils/logger/rotation.js +1 -1
  270. package/dist/src/voice/tts/audio.js +1 -1
  271. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  272. package/dist/src/workflows/store/event-store.js +1 -1
  273. package/dist/src/workflows/store/run-store.js +1 -1
  274. package/package.json +1 -1
  275. package/dist/gateway/static/root/assets/agents-cPvvYLXo.js +0 -222
  276. package/dist/gateway/static/root/assets/apps-page-Bk1_P5FJ.js +0 -1
  277. package/dist/gateway/static/root/assets/channels-settings-CZoeQwHz.js +0 -1
  278. package/dist/gateway/static/root/assets/cron-page-BpLdiQN8.js +0 -1
  279. package/dist/gateway/static/root/assets/dist-BTWC-BTN.js +0 -45
  280. package/dist/gateway/static/root/assets/dist-BpAiK86n.js +0 -1
  281. package/dist/gateway/static/root/assets/eye-DAfL1U7M.js +0 -1
  282. package/dist/gateway/static/root/assets/index-V7MQ7834.css +0 -1
  283. package/dist/gateway/static/root/assets/logs-page-_HcZ2fgK.js +0 -1
  284. package/dist/gateway/static/root/assets/sessions-page-iezSMjho.js +0 -1
  285. package/dist/gateway/static/root/assets/settings-page-C9_nYQwM.js +0 -3
  286. package/dist/gateway/static/root/assets/share-preview-page-DExl7CJy.js +0 -2
  287. package/dist/gateway/static/root/assets/skills-page-BlgGD93t.js +0 -2
  288. package/dist/gateway/static/root/assets/url-fxyYANfA.js +0 -3
  289. package/dist/gateway/static/root/assets/vendor-codemirror-D0yxdRpg.js +0 -58
  290. package/dist/gateway/static/root/assets/workflows-page-BvMobnJP.js +0 -27
@@ -1,8 +1,8 @@
1
+ import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
1
2
  import { createLogger } from "../utils/logger/index.js";
2
3
  import { init_logger } from "../utils/logger.js";
3
- import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
4
- import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
5
4
  import path from "node:path";
5
+ import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
6
6
  //#region src/infra/restart.ts
7
7
  /**
8
8
  * Gateway restart coordination — OpenClaw-aligned SIGUSR1 authorization and restart intent.
@@ -1,5 +1,5 @@
1
- import fs from "node:fs/promises";
2
1
  import path from "node:path";
2
+ import fs from "node:fs/promises";
3
3
  //#region src/infra/stable-node-path.ts
4
4
  /** Resolve Homebrew Cellar node paths to stable opt/bin symlinks. */
5
5
  async function resolveStableNodePath(nodePath) {
@@ -1,7 +1,7 @@
1
1
  import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
2
  import { channelToNpmTag } from "./update-channels.js";
3
- import { access, readFile } from "node:fs/promises";
4
3
  import { dirname, join } from "node:path";
4
+ import { access, readFile } from "node:fs/promises";
5
5
  import { fileURLToPath } from "node:url";
6
6
  //#region src/infra/update-check.ts
7
7
  init_package_version();
@@ -2,9 +2,9 @@ import { resolveExecPathBinPrepend } from "./path-env.js";
2
2
  import { readPackageVersion } from "./package-json.js";
3
3
  import { applyPathPrepend } from "./path-prepend.js";
4
4
  import { createDefaultCommandRunner } from "./run-command.js";
5
+ import path from "node:path";
5
6
  import fs from "node:fs";
6
7
  import fs$1 from "node:fs/promises";
7
- import path from "node:path";
8
8
  //#region src/infra/update-global.ts
9
9
  const XOPC_PACKAGE_NAME = "@xopcai/xopc";
10
10
  const GLOBAL_RENAME_PREFIX = ".";
@@ -1,9 +1,9 @@
1
- import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
1
+ import { init_paths_state, resolveUpdateLockPath } from "../config/paths-state.js";
2
2
  import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
- import { init_paths_state, resolveUpdateLockPath } from "../config/paths-state.js";
5
- import { mkdir, readFile, unlink } from "node:fs/promises";
4
+ import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
6
5
  import { dirname } from "node:path";
6
+ import { mkdir, readFile, unlink } from "node:fs/promises";
7
7
  //#region src/infra/update-lock.ts
8
8
  init_write_file_atomic();
9
9
  init_paths_state();
@@ -8,8 +8,8 @@ import { runGlobalPackageUpdateSteps } from "./package-update-steps.js";
8
8
  import { resolveStableNodePath } from "./stable-node-path.js";
9
9
  import { trimLogTail } from "./update-log.js";
10
10
  import { maybeRestartGatewayAfterUpdate } from "./update-restart.js";
11
- import fs from "node:fs/promises";
12
11
  import path from "node:path";
12
+ import fs from "node:fs/promises";
13
13
  //#region src/infra/update-runner.ts
14
14
  const DEFAULT_TIMEOUT_MS = 2700 * 1e3;
15
15
  const MAX_LOG_CHARS = 8e3;
@@ -1,8 +1,8 @@
1
1
  import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
2
- import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
2
+ import { init_paths_state, resolveUpdateCheckStatePath } from "../config/paths-state.js";
3
3
  import { createLogger } from "../utils/logger/index.js";
4
4
  import { init_logger } from "../utils/logger.js";
5
- import { init_paths_state, resolveUpdateCheckStatePath } from "../config/paths-state.js";
5
+ import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
6
6
  import { acquireUpdateLock } from "./update-lock.js";
7
7
  import { normalizeUpdateChannel } from "./update-channels.js";
8
8
  import { compareSemver, detectInstallKind, resolveNpmChannelTag, resolvePackageRoot } from "./update-check.js";
@@ -1,8 +1,8 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import { randomUUID } from "node:crypto";
2
+ import path from "node:path";
3
3
  import { chmodSync, closeSync, copyFileSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeFileSync } from "node:fs";
4
+ import { randomUUID } from "node:crypto";
4
5
  import { chmod, copyFile, mkdir, open, rename, rm } from "node:fs/promises";
5
- import path from "node:path";
6
6
  //#region src/infra/write-file-atomic.ts
7
7
  /**
8
8
  * Durable single-file writes: temp file → fsync → rename to target.
@@ -0,0 +1,9 @@
1
+ /** Canonical persisted reference: xopc-attachment://notes/{noteId}/{attachmentId} */
2
+ export declare const NOTE_ATTACHMENT_SCHEME = "xopc-attachment";
3
+ export type ParsedNoteAttachmentRef = {
4
+ noteId: string;
5
+ attachmentId: string;
6
+ };
7
+ export declare function buildNoteAttachmentRef(noteId: string, attachmentId: string): string;
8
+ export declare function parseNoteAttachmentTarget(target: string, expectedNoteId?: string): ParsedNoteAttachmentRef | null;
9
+ export declare function attachmentIdFromTarget(target: string, noteId: string): string | undefined;
@@ -0,0 +1,27 @@
1
+ //#region src/notes/attachment-ref.ts
2
+ /** Canonical persisted reference: xopc-attachment://notes/{noteId}/{attachmentId} */
3
+ const NOTE_ATTACHMENT_SCHEME = "xopc-attachment";
4
+ const CANONICAL_REF = /^xopc-attachment:\/\/notes\/([^/]+)\/([^/?#]+)$/i;
5
+ function buildNoteAttachmentRef(noteId, attachmentId) {
6
+ return `${NOTE_ATTACHMENT_SCHEME}://notes/${encodeURIComponent(noteId)}/${encodeURIComponent(attachmentId)}`;
7
+ }
8
+ function parseNoteAttachmentTarget(target, expectedNoteId) {
9
+ const trimmed = target.trim();
10
+ if (!trimmed) return null;
11
+ const canonical = trimmed.split("?")[0].match(CANONICAL_REF);
12
+ if (!canonical) return null;
13
+ const noteId = decodeURIComponent(canonical[1]);
14
+ const attachmentId = decodeURIComponent(canonical[2]);
15
+ if (expectedNoteId && noteId !== expectedNoteId) return null;
16
+ return {
17
+ noteId,
18
+ attachmentId
19
+ };
20
+ }
21
+ function attachmentIdFromTarget(target, noteId) {
22
+ return parseNoteAttachmentTarget(target, noteId)?.attachmentId;
23
+ }
24
+ //#endregion
25
+ export { NOTE_ATTACHMENT_SCHEME, attachmentIdFromTarget, buildNoteAttachmentRef, parseNoteAttachmentTarget };
26
+
27
+ //# sourceMappingURL=attachment-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-ref.js","names":[],"sources":["../../../src/notes/attachment-ref.ts"],"sourcesContent":["/** Canonical persisted reference: xopc-attachment://notes/{noteId}/{attachmentId} */\nexport const NOTE_ATTACHMENT_SCHEME = 'xopc-attachment';\n\nconst CANONICAL_REF =\n /^xopc-attachment:\\/\\/notes\\/([^/]+)\\/([^/?#]+)$/i;\n\nexport type ParsedNoteAttachmentRef = {\n noteId: string;\n attachmentId: string;\n};\n\nexport function buildNoteAttachmentRef(noteId: string, attachmentId: string): string {\n return `${NOTE_ATTACHMENT_SCHEME}://notes/${encodeURIComponent(noteId)}/${encodeURIComponent(attachmentId)}`;\n}\n\nexport function parseNoteAttachmentTarget(\n target: string,\n expectedNoteId?: string,\n): ParsedNoteAttachmentRef | null {\n const trimmed = target.trim();\n if (!trimmed) return null;\n\n const canonical = trimmed.split('?')[0].match(CANONICAL_REF);\n if (!canonical) return null;\n\n const noteId = decodeURIComponent(canonical[1]);\n const attachmentId = decodeURIComponent(canonical[2]);\n if (expectedNoteId && noteId !== expectedNoteId) return null;\n return { noteId, attachmentId };\n}\n\nexport function attachmentIdFromTarget(target: string, noteId: string): string | undefined {\n return parseNoteAttachmentTarget(target, noteId)?.attachmentId;\n}\n"],"mappings":";;AACA,MAAa,yBAAyB;AAEtC,MAAM,gBACJ;AAOF,SAAgB,uBAAuB,QAAgB,cAA8B;AACnF,QAAO,GAAG,uBAAuB,WAAW,mBAAmB,OAAO,CAAC,GAAG,mBAAmB,aAAa;;AAG5G,SAAgB,0BACd,QACA,gBACgC;CAChC,MAAM,UAAU,OAAO,MAAM;AAC7B,KAAI,CAAC,QAAS,QAAO;CAErB,MAAM,YAAY,QAAQ,MAAM,IAAI,CAAC,GAAG,MAAM,cAAc;AAC5D,KAAI,CAAC,UAAW,QAAO;CAEvB,MAAM,SAAS,mBAAmB,UAAU,GAAG;CAC/C,MAAM,eAAe,mBAAmB,UAAU,GAAG;AACrD,KAAI,kBAAkB,WAAW,eAAgB,QAAO;AACxD,QAAO;EAAE;EAAQ;EAAc;;AAGjC,SAAgB,uBAAuB,QAAgB,QAAoC;AACzF,QAAO,0BAA0B,QAAQ,OAAO,EAAE"}
@@ -0,0 +1,4 @@
1
+ export { NotesStore } from './store.js';
2
+ export { NotesService } from './service.js';
3
+ export { resolveNotesDir, resolveNotesIndexPath, resolveNoteItemPath, resolveNoteMediaDir, resolveNoteHistoryDir } from './paths.js';
4
+ export type { Note, NoteKind, NoteStatus, NoteAttachment, NoteAiMeta, NoteAiDeepMeta, NoteIndexEntry, NoteSnapshot, NoteSnapshotEntry, NotesIndexFile, NotesListQuery, CaptureSource, CaptureChannel, CreateNoteParams, SnapshotTrigger, } from './types.js';
@@ -0,0 +1,4 @@
1
+ import { resolveNoteHistoryDir, resolveNoteItemPath, resolveNoteMediaDir, resolveNotesDir, resolveNotesIndexPath } from "./paths.js";
2
+ import { NotesStore } from "./store.js";
3
+ import { NotesService } from "./service.js";
4
+ export { NotesService, NotesStore, resolveNoteHistoryDir, resolveNoteItemPath, resolveNoteMediaDir, resolveNotesDir, resolveNotesIndexPath };
@@ -0,0 +1,7 @@
1
+ import type { Note, NoteAttachment } from './types.js';
2
+ /** Attachment ids referenced in note markdown, blocks, or plain text. */
3
+ export declare function collectReferencedAttachmentIds(note: Pick<Note, 'id' | 'text' | 'blocks'>): Set<string>;
4
+ export declare function partitionAttachmentsByReference(note: Pick<Note, 'id' | 'text' | 'blocks' | 'attachments'>): {
5
+ kept: NoteAttachment[];
6
+ removed: NoteAttachment[];
7
+ };
@@ -0,0 +1,46 @@
1
+ import { attachmentIdFromTarget } from "./attachment-ref.js";
2
+ import { notePlainText } from "./note-index-meta.js";
3
+ //#region src/notes/note-attachment-sync.ts
4
+ const MARKDOWN_IMAGE = /!\[([^\]]*)\]\(([^)]+)\)/g;
5
+ const MARKDOWN_LINK = /(?<!!)\[([^\]]*)\]\(([^)]+)\)/g;
6
+ const BARE_ATTACHMENT_REF = /xopc-attachment:\/\/notes\/([^/]+)\/([^/?#"'\s)]+)/gi;
7
+ /** Attachment ids referenced in note markdown, blocks, or plain text. */
8
+ function collectReferencedAttachmentIds(note) {
9
+ const ids = /* @__PURE__ */ new Set();
10
+ for (const block of note.blocks ?? []) if (block.type === "image") ids.add(block.attachmentId);
11
+ const source = notePlainText(note);
12
+ if (!source.trim()) return ids;
13
+ for (const match of source.matchAll(MARKDOWN_IMAGE)) {
14
+ const target = match[2];
15
+ if (typeof target !== "string") continue;
16
+ const attachmentId = attachmentIdFromTarget(target, note.id);
17
+ if (attachmentId) ids.add(attachmentId);
18
+ }
19
+ for (const match of source.matchAll(MARKDOWN_LINK)) {
20
+ const target = match[2];
21
+ if (typeof target !== "string") continue;
22
+ const attachmentId = attachmentIdFromTarget(target, note.id);
23
+ if (attachmentId) ids.add(attachmentId);
24
+ }
25
+ for (const match of source.matchAll(BARE_ATTACHMENT_REF)) {
26
+ if (decodeURIComponent(match[1]) !== note.id) continue;
27
+ ids.add(decodeURIComponent(match[2]));
28
+ }
29
+ return ids;
30
+ }
31
+ function partitionAttachmentsByReference(note) {
32
+ const referenced = collectReferencedAttachmentIds(note);
33
+ const attachments = note.attachments ?? [];
34
+ const kept = [];
35
+ const removed = [];
36
+ for (const attachment of attachments) if (referenced.has(attachment.id)) kept.push(attachment);
37
+ else removed.push(attachment);
38
+ return {
39
+ kept,
40
+ removed
41
+ };
42
+ }
43
+ //#endregion
44
+ export { collectReferencedAttachmentIds, partitionAttachmentsByReference };
45
+
46
+ //# sourceMappingURL=note-attachment-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-attachment-sync.js","names":[],"sources":["../../../src/notes/note-attachment-sync.ts"],"sourcesContent":["import type { Note, NoteAttachment } from './types.js';\nimport { attachmentIdFromTarget } from './attachment-ref.js';\nimport { notePlainText } from './note-index-meta.js';\n\nconst MARKDOWN_IMAGE = /!\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\nconst MARKDOWN_LINK = /(?<!!)\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\nconst BARE_ATTACHMENT_REF = /xopc-attachment:\\/\\/notes\\/([^/]+)\\/([^/?#\"'\\s)]+)/gi;\n\n/** Attachment ids referenced in note markdown, blocks, or plain text. */\nexport function collectReferencedAttachmentIds(\n note: Pick<Note, 'id' | 'text' | 'blocks'>,\n): Set<string> {\n const ids = new Set<string>();\n\n for (const block of note.blocks ?? []) {\n if (block.type === 'image') ids.add(block.attachmentId);\n }\n\n const source = notePlainText(note);\n if (!source.trim()) return ids;\n\n for (const match of source.matchAll(MARKDOWN_IMAGE)) {\n const target = match[2];\n if (typeof target !== 'string') continue;\n const attachmentId = attachmentIdFromTarget(target, note.id);\n if (attachmentId) ids.add(attachmentId);\n }\n\n for (const match of source.matchAll(MARKDOWN_LINK)) {\n const target = match[2];\n if (typeof target !== 'string') continue;\n const attachmentId = attachmentIdFromTarget(target, note.id);\n if (attachmentId) ids.add(attachmentId);\n }\n\n for (const match of source.matchAll(BARE_ATTACHMENT_REF)) {\n const noteId = decodeURIComponent(match[1]);\n if (noteId !== note.id) continue;\n ids.add(decodeURIComponent(match[2]));\n }\n\n return ids;\n}\n\nexport function partitionAttachmentsByReference(\n note: Pick<Note, 'id' | 'text' | 'blocks' | 'attachments'>,\n): { kept: NoteAttachment[]; removed: NoteAttachment[] } {\n const referenced = collectReferencedAttachmentIds(note);\n const attachments = note.attachments ?? [];\n const kept: NoteAttachment[] = [];\n const removed: NoteAttachment[] = [];\n\n for (const attachment of attachments) {\n if (referenced.has(attachment.id)) {\n kept.push(attachment);\n } else {\n removed.push(attachment);\n }\n }\n\n return { kept, removed };\n}\n"],"mappings":";;;AAIA,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AACtB,MAAM,sBAAsB;;AAG5B,SAAgB,+BACd,MACa;CACb,MAAM,sBAAM,IAAI,KAAa;AAE7B,MAAK,MAAM,SAAS,KAAK,UAAU,EAAE,CACnC,KAAI,MAAM,SAAS,QAAS,KAAI,IAAI,MAAM,aAAa;CAGzD,MAAM,SAAS,cAAc,KAAK;AAClC,KAAI,CAAC,OAAO,MAAM,CAAE,QAAO;AAE3B,MAAK,MAAM,SAAS,OAAO,SAAS,eAAe,EAAE;EACnD,MAAM,SAAS,MAAM;AACrB,MAAI,OAAO,WAAW,SAAU;EAChC,MAAM,eAAe,uBAAuB,QAAQ,KAAK,GAAG;AAC5D,MAAI,aAAc,KAAI,IAAI,aAAa;;AAGzC,MAAK,MAAM,SAAS,OAAO,SAAS,cAAc,EAAE;EAClD,MAAM,SAAS,MAAM;AACrB,MAAI,OAAO,WAAW,SAAU;EAChC,MAAM,eAAe,uBAAuB,QAAQ,KAAK,GAAG;AAC5D,MAAI,aAAc,KAAI,IAAI,aAAa;;AAGzC,MAAK,MAAM,SAAS,OAAO,SAAS,oBAAoB,EAAE;AAExD,MADe,mBAAmB,MAAM,GAC9B,KAAK,KAAK,GAAI;AACxB,MAAI,IAAI,mBAAmB,MAAM,GAAG,CAAC;;AAGvC,QAAO;;AAGT,SAAgB,gCACd,MACuD;CACvD,MAAM,aAAa,+BAA+B,KAAK;CACvD,MAAM,cAAc,KAAK,eAAe,EAAE;CAC1C,MAAM,OAAyB,EAAE;CACjC,MAAM,UAA4B,EAAE;AAEpC,MAAK,MAAM,cAAc,YACvB,KAAI,WAAW,IAAI,WAAW,GAAG,CAC/B,MAAK,KAAK,WAAW;KAErB,SAAQ,KAAK,WAAW;AAI5B,QAAO;EAAE;EAAM;EAAS"}
@@ -0,0 +1,14 @@
1
+ import type { Note } from './types.js';
2
+ export { parseNoteAttachmentTarget, buildNoteAttachmentRef } from './attachment-ref.js';
3
+ export declare function notePlainText(note: Pick<Note, 'id' | 'text' | 'blocks'>): string;
4
+ export declare function stripMediaFromPlainText(text: string): string;
5
+ export declare function extractAttachmentFileNames(note: Pick<Note, 'attachments'>): string[] | undefined;
6
+ export declare function extractCoverAttachmentId(note: Note): string | undefined;
7
+ export declare function buildNoteSnippet(note: Pick<Note, 'id' | 'text' | 'blocks'>): string | undefined;
8
+ export declare function buildNoteIndexMeta(note: Note): {
9
+ snippet?: string;
10
+ coverAttachmentId?: string;
11
+ voiceAttachmentId?: string;
12
+ voiceDurationSec?: number;
13
+ attachmentNames?: string[];
14
+ };
@@ -0,0 +1,87 @@
1
+ import { attachmentIdFromTarget, buildNoteAttachmentRef, parseNoteAttachmentTarget } from "./attachment-ref.js";
2
+ //#region src/notes/note-index-meta.ts
3
+ const SNIPPET_LENGTH = 100;
4
+ const MARKDOWN_IMAGE = /!\[([^\]]*)\]\(([^)]+)\)/g;
5
+ const MARKDOWN_LINK = /(?<!!)\[([^\]]*)\]\(([^)]+)\)/g;
6
+ const BARE_ATTACHMENT_REF = /xopc-attachment:\/\/notes\/[^/]+\/[^/?#"'\s)]+/gi;
7
+ function notePlainText(note) {
8
+ if (note.text?.trim()) return note.text;
9
+ return note.blocks?.map((block) => {
10
+ if (block.type === "divider") return "";
11
+ if (block.type === "todo") return block.text;
12
+ if (block.type === "image") return `![${block.alt ?? ""}](${buildNoteAttachmentRef(note.id, block.attachmentId)})`;
13
+ return block.text;
14
+ }).join(" ") ?? "";
15
+ }
16
+ function isNoteMediaTarget(target) {
17
+ return parseNoteAttachmentTarget(target) !== null;
18
+ }
19
+ function stripMediaFromPlainText(text) {
20
+ let result = text.replace(MARKDOWN_IMAGE, " ");
21
+ result = result.replace(MARKDOWN_LINK, (full, _alt, target) => {
22
+ if (typeof target !== "string") return full;
23
+ return isNoteMediaTarget(target) ? " " : full;
24
+ });
25
+ result = result.replace(BARE_ATTACHMENT_REF, " ");
26
+ return result.replace(/\s+/g, " ").trim();
27
+ }
28
+ function extractAttachmentFileNames(note) {
29
+ const names = note.attachments?.map((item) => item.fileName.trim().toLowerCase()).filter(Boolean);
30
+ if (!names?.length) return void 0;
31
+ return [...new Set(names)];
32
+ }
33
+ function extractCoverAttachmentId(note) {
34
+ for (const block of note.blocks ?? []) {
35
+ if (block.type !== "image") continue;
36
+ const attachment = note.attachments?.find((item) => item.id === block.attachmentId);
37
+ if (!attachment || attachment.type === "image") return block.attachmentId;
38
+ }
39
+ const text = notePlainText(note);
40
+ if (!text.trim()) return void 0;
41
+ for (const match of text.matchAll(MARKDOWN_IMAGE)) {
42
+ const target = match[2];
43
+ if (typeof target !== "string") continue;
44
+ const attachmentId = attachmentIdFromTarget(target, note.id);
45
+ if (!attachmentId) continue;
46
+ const attachment = note.attachments?.find((item) => item.id === attachmentId);
47
+ if (!attachment || attachment.type === "image") return attachmentId;
48
+ }
49
+ for (const match of text.matchAll(BARE_ATTACHMENT_REF)) {
50
+ const parsed = parseNoteAttachmentTarget(match[0], note.id);
51
+ if (!parsed) continue;
52
+ const attachment = note.attachments?.find((item) => item.id === parsed.attachmentId);
53
+ if (!attachment || attachment.type === "image") return parsed.attachmentId;
54
+ }
55
+ }
56
+ function buildNoteSnippet(note) {
57
+ const text = notePlainText(note);
58
+ if (!text.trim()) return void 0;
59
+ const clean = stripMediaFromPlainText(text);
60
+ if (!clean) return void 0;
61
+ return clean.length > SNIPPET_LENGTH ? `${clean.slice(0, SNIPPET_LENGTH)}…` : clean;
62
+ }
63
+ function extractVoiceAttachment(note) {
64
+ const audio = note.attachments?.find((a) => a.type === "audio");
65
+ if (!audio) return {};
66
+ return {
67
+ voiceAttachmentId: audio.id,
68
+ voiceDurationSec: audio.duration
69
+ };
70
+ }
71
+ function buildNoteIndexMeta(note) {
72
+ const coverAttachmentId = extractCoverAttachmentId(note);
73
+ const snippet = buildNoteSnippet(note);
74
+ const attachmentNames = extractAttachmentFileNames(note);
75
+ const { voiceAttachmentId, voiceDurationSec } = extractVoiceAttachment(note);
76
+ return {
77
+ snippet,
78
+ coverAttachmentId,
79
+ voiceAttachmentId,
80
+ voiceDurationSec,
81
+ attachmentNames
82
+ };
83
+ }
84
+ //#endregion
85
+ export { buildNoteAttachmentRef, buildNoteIndexMeta, buildNoteSnippet, extractAttachmentFileNames, extractCoverAttachmentId, notePlainText, parseNoteAttachmentTarget, stripMediaFromPlainText };
86
+
87
+ //# sourceMappingURL=note-index-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-index-meta.js","names":[],"sources":["../../../src/notes/note-index-meta.ts"],"sourcesContent":["import type { Note } from './types.js';\nimport {\n attachmentIdFromTarget,\n buildNoteAttachmentRef,\n parseNoteAttachmentTarget,\n} from './attachment-ref.js';\n\nconst SNIPPET_LENGTH = 100;\nconst MARKDOWN_IMAGE = /!\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\nconst MARKDOWN_LINK = /(?<!!)\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\nconst BARE_ATTACHMENT_REF = /xopc-attachment:\\/\\/notes\\/[^/]+\\/[^/?#\"'\\s)]+/gi;\n\nexport { parseNoteAttachmentTarget, buildNoteAttachmentRef } from './attachment-ref.js';\n\nexport function notePlainText(note: Pick<Note, 'id' | 'text' | 'blocks'>): string {\n if (note.text?.trim()) return note.text;\n return (\n note.blocks\n ?.map((block) => {\n if (block.type === 'divider') return '';\n if (block.type === 'todo') return block.text;\n if (block.type === 'image') {\n const alt = block.alt ?? '';\n return `![${alt}](${buildNoteAttachmentRef(note.id, block.attachmentId)})`;\n }\n return block.text;\n })\n .join(' ') ?? ''\n );\n}\n\nfunction isNoteMediaTarget(target: string): boolean {\n return parseNoteAttachmentTarget(target) !== null;\n}\n\nexport function stripMediaFromPlainText(text: string): string {\n let result = text.replace(MARKDOWN_IMAGE, ' ');\n result = result.replace(MARKDOWN_LINK, (full, _alt, target) => {\n if (typeof target !== 'string') return full;\n return isNoteMediaTarget(target) ? ' ' : full;\n });\n result = result.replace(BARE_ATTACHMENT_REF, ' ');\n return result.replace(/\\s+/g, ' ').trim();\n}\n\nexport function extractAttachmentFileNames(note: Pick<Note, 'attachments'>): string[] | undefined {\n const names = note.attachments?.map((item) => item.fileName.trim().toLowerCase()).filter(Boolean);\n if (!names?.length) return undefined;\n return [...new Set(names)];\n}\n\nexport function extractCoverAttachmentId(note: Note): string | undefined {\n for (const block of note.blocks ?? []) {\n if (block.type !== 'image') continue;\n const attachment = note.attachments?.find((item) => item.id === block.attachmentId);\n if (!attachment || attachment.type === 'image') return block.attachmentId;\n }\n\n const text = notePlainText(note);\n if (!text.trim()) return undefined;\n\n for (const match of text.matchAll(MARKDOWN_IMAGE)) {\n const target = match[2];\n if (typeof target !== 'string') continue;\n const attachmentId = attachmentIdFromTarget(target, note.id);\n if (!attachmentId) continue;\n const attachment = note.attachments?.find((item) => item.id === attachmentId);\n if (!attachment || attachment.type === 'image') return attachmentId;\n }\n\n for (const match of text.matchAll(BARE_ATTACHMENT_REF)) {\n const parsed = parseNoteAttachmentTarget(match[0], note.id);\n if (!parsed) continue;\n const attachment = note.attachments?.find((item) => item.id === parsed.attachmentId);\n if (!attachment || attachment.type === 'image') return parsed.attachmentId;\n }\n\n return undefined;\n}\n\nexport function buildNoteSnippet(note: Pick<Note, 'id' | 'text' | 'blocks'>): string | undefined {\n const text = notePlainText(note);\n if (!text.trim()) return undefined;\n const clean = stripMediaFromPlainText(text);\n if (!clean) return undefined;\n return clean.length > SNIPPET_LENGTH ? `${clean.slice(0, SNIPPET_LENGTH)}…` : clean;\n}\n\nfunction extractVoiceAttachment(note: Note): { voiceAttachmentId?: string; voiceDurationSec?: number } {\n const audio = note.attachments?.find((a) => a.type === 'audio');\n if (!audio) return {};\n return { voiceAttachmentId: audio.id, voiceDurationSec: audio.duration };\n}\n\nexport function buildNoteIndexMeta(note: Note): {\n snippet?: string;\n coverAttachmentId?: string;\n voiceAttachmentId?: string;\n voiceDurationSec?: number;\n attachmentNames?: string[];\n} {\n const coverAttachmentId = extractCoverAttachmentId(note);\n const snippet = buildNoteSnippet(note);\n const attachmentNames = extractAttachmentFileNames(note);\n const { voiceAttachmentId, voiceDurationSec } = extractVoiceAttachment(note);\n return {\n snippet,\n coverAttachmentId,\n voiceAttachmentId,\n voiceDurationSec,\n attachmentNames,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function resolveNotesDir(): string;
2
+ export declare function resolveNotesIndexPath(): string;
3
+ export declare function resolveNoteItemPath(noteId: string): string;
4
+ export declare function resolveNoteMediaDir(noteId: string): string;
5
+ export declare function resolveNoteHistoryDir(noteId: string): string;
@@ -0,0 +1,23 @@
1
+ import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
2
+ import { join } from "node:path";
3
+ //#region src/notes/paths.ts
4
+ init_paths_state();
5
+ function resolveNotesDir() {
6
+ return join(resolveStateDir(), "notes");
7
+ }
8
+ function resolveNotesIndexPath() {
9
+ return join(resolveNotesDir(), "index.json");
10
+ }
11
+ function resolveNoteItemPath(noteId) {
12
+ return join(resolveNotesDir(), "items", `${noteId}.json`);
13
+ }
14
+ function resolveNoteMediaDir(noteId) {
15
+ return join(resolveNotesDir(), "media", noteId);
16
+ }
17
+ function resolveNoteHistoryDir(noteId) {
18
+ return join(resolveNotesDir(), "history", noteId);
19
+ }
20
+ //#endregion
21
+ export { resolveNoteHistoryDir, resolveNoteItemPath, resolveNoteMediaDir, resolveNotesDir, resolveNotesIndexPath };
22
+
23
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","names":[],"sources":["../../../src/notes/paths.ts"],"sourcesContent":["import { join } from 'node:path';\n\nimport { resolveStateDir } from '../config/paths-state.js';\n\nexport function resolveNotesDir(): string {\n return join(resolveStateDir(), 'notes');\n}\n\nexport function resolveNotesIndexPath(): string {\n return join(resolveNotesDir(), 'index.json');\n}\n\nexport function resolveNoteItemPath(noteId: string): string {\n return join(resolveNotesDir(), 'items', `${noteId}.json`);\n}\n\nexport function resolveNoteMediaDir(noteId: string): string {\n return join(resolveNotesDir(), 'media', noteId);\n}\n\nexport function resolveNoteHistoryDir(noteId: string): string {\n return join(resolveNotesDir(), 'history', noteId);\n}\n"],"mappings":";;;kBAE2D;AAE3D,SAAgB,kBAA0B;AACxC,QAAO,KAAK,iBAAiB,EAAE,QAAQ;;AAGzC,SAAgB,wBAAgC;AAC9C,QAAO,KAAK,iBAAiB,EAAE,aAAa;;AAG9C,SAAgB,oBAAoB,QAAwB;AAC1D,QAAO,KAAK,iBAAiB,EAAE,SAAS,GAAG,OAAO,OAAO;;AAG3D,SAAgB,oBAAoB,QAAwB;AAC1D,QAAO,KAAK,iBAAiB,EAAE,SAAS,OAAO;;AAGjD,SAAgB,sBAAsB,QAAwB;AAC5D,QAAO,KAAK,iBAAiB,EAAE,WAAW,OAAO"}
@@ -0,0 +1,42 @@
1
+ import { NotesStore } from './store.js';
2
+ import type { CaptureSource, CreateNoteParams, Note, NoteAiPatch, NoteAttachment, NoteBlock, NoteIndexEntry, NoteSnapshot, NoteSnapshotEntry, NotesListQuery, SnapshotTrigger } from './types.js';
3
+ export declare class NotesService {
4
+ private store;
5
+ private lastSnapshotAt;
6
+ constructor(store: NotesStore);
7
+ initialize(): Promise<void>;
8
+ quickCapture(text: string, source: CaptureSource): Promise<Note>;
9
+ createNote(params: CreateNoteParams): Promise<Note>;
10
+ getNote(id: string): Promise<Note | null>;
11
+ updateNote(id: string, patch: Partial<Note>, trigger?: SnapshotTrigger): Promise<Note | null>;
12
+ private reconcileAttachments;
13
+ syncNote(id: string, patch: Partial<Note>, baseRemoteVersion?: number): Promise<{
14
+ note: Note | null;
15
+ conflict: boolean;
16
+ }>;
17
+ createAiEditPatch(id: string, instruction: string, blocks?: NoteBlock[]): Promise<{
18
+ message: string;
19
+ patch: NoteAiPatch;
20
+ } | null>;
21
+ deleteNote(id: string): Promise<boolean>;
22
+ listNotes(query?: NotesListQuery): Promise<{
23
+ items: NoteIndexEntry[];
24
+ total: number;
25
+ }>;
26
+ addAttachment(noteId: string, file: {
27
+ name: string;
28
+ buffer: Buffer;
29
+ mimeType: string;
30
+ duration?: number;
31
+ }): Promise<NoteAttachment | null>;
32
+ getAttachmentPath(noteId: string, attachmentId: string): Promise<{
33
+ filePath: string;
34
+ mimeType: string;
35
+ fileName: string;
36
+ } | null>;
37
+ listNoteHistory(noteId: string): Promise<NoteSnapshotEntry[]>;
38
+ getNoteSnapshot(noteId: string, timestamp: number): Promise<NoteSnapshot | null>;
39
+ restoreNoteSnapshot(noteId: string, timestamp: number): Promise<Note | null>;
40
+ flush(): Promise<void>;
41
+ private maybeSaveSnapshot;
42
+ }