@xopcai/xopc 0.0.222 → 0.0.224

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 (213) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/telegram/xopc.extension.json +1 -1
  4. package/dist/gateway/static/root/assets/{activity-store-NItGQmvR.js → activity-store--GBciH10.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DsR_2U9-.js → agent-avatar-dicebear-K7V4XXt7.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-BsxTpXyq.js +68 -0
  7. package/dist/gateway/static/root/assets/{api-53ZXsuyr.js → api-HoIz_ija.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-BCzVX09V.js → app-management-settings-panel-xQCmkAHh.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-DgSpwqQI.js → appearance-settings-BRoeA4kU.js} +1 -1
  10. package/dist/gateway/static/root/assets/apps-page-BXgpBA8w.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-D8o8CP9Y.js → archive-plugin-CteCVsBP.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-BQHcAR6J.js → attachment-load-D7xNA2jB.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-CswK3HFb.js → automations-page-BD1vK7r5.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-workspace-wrgf-z7D.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-BlpyTJ1b.js → binary-plugins-C3DaJa0W.js} +1 -1
  16. package/dist/gateway/static/root/assets/block-editor-lTkcHTve.js +184 -0
  17. package/dist/gateway/static/root/assets/browser-settings-page-zhzNkeVG.js +8 -0
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-Bi6RSSpD.js → browser-workflow-inputs-1UZ0vnIy.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-CZNOOQY4.js → browser-workflows-page-BHuJOF4M.js} +2 -2
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-DuCmg2Ej.js +7 -0
  21. package/dist/gateway/static/root/assets/{capability-presets-api-pC2fno7r.js → capability-presets-api-yNqTIuyd.js} +1 -1
  22. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DjiP3mQQ.js +3 -0
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-B5Szgu_z.js → channel-recipient-api-krezGsKc.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-B4AtvQHk.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-DMxB7slL.js +1 -0
  26. package/dist/gateway/static/root/assets/{chat-terminal-dock-2fpzufzt.js → chat-terminal-dock-BRrL2iHA.js} +2 -2
  27. package/dist/gateway/static/root/assets/connectors-page-fmda2NEP.js +2 -0
  28. package/dist/gateway/static/root/assets/{cron-expression-VePLfPUR.js → cron-expression-Bl-2DzBQ.js} +1 -1
  29. package/dist/gateway/static/root/assets/{date-picker-CJegmPTJ.js → date-picker-CxTl6Wlz.js} +1 -1
  30. package/dist/gateway/static/root/assets/{dependency-picker-B2o9unBk.js → dependency-picker-DSl0mOPa.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-BH4Np-ay.js → desktop-pet-DTeCmCdb.js} +1 -1
  32. package/dist/gateway/static/root/assets/{desktop-pet-settings-Duu3ctxD.js → desktop-pet-settings-BNebxg0V.js} +1 -1
  33. package/dist/gateway/static/root/assets/{directory-picker-path-field-BBCUZOg2.js → directory-picker-path-field-Dn9XpmXY.js} +1 -1
  34. package/dist/gateway/static/root/assets/dist-DaxPZj9e.js +1 -0
  35. package/dist/gateway/static/root/assets/{dist-DY4Af0fY.js → dist-J_ySZvz0.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-debug-page-DS_o3F97.js → extension-debug-page-D-J-eOTb.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-page-BTLBZdCq.js → extension-page-CpST24nU.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-settings-page-KTGrYbgk.js → extension-settings-page-4nQXFnFq.js} +1 -1
  39. package/dist/gateway/static/root/assets/floating-ui.dom-B7uQOZZW.js +1 -0
  40. package/dist/gateway/static/root/assets/{gateway-config-api-D3YJVfzY.js → gateway-config-api-BHWHduDi.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-config-swr-BzTbnu4O.js → gateway-config-swr-yUxMMVjK.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-settings-B8--s3yC.js → gateway-settings-BimMKmkM.js} +1 -1
  43. package/dist/gateway/static/root/assets/{gateway-startup-retry-B2zpkNvi.js → gateway-startup-retry-9mrsL84j.js} +1 -1
  44. package/dist/gateway/static/root/assets/heartbeat-settings-MUJ3mEC9.js +1 -0
  45. package/dist/gateway/static/root/assets/home-page-DSM6aPHF.js +1 -0
  46. package/dist/gateway/static/root/assets/{image-generation-api-BXRjz-iY.js → image-generation-api-CgFAGDi8.js} +1 -1
  47. package/dist/gateway/static/root/assets/index-B3zYJBhK.js +74 -0
  48. package/dist/gateway/static/root/assets/index-D3_xSYKd.css +2 -0
  49. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-D-Ib-suu.js → keyboard-shortcuts-settings-6Ar5rfX4.js} +1 -1
  50. package/dist/gateway/static/root/assets/local-app-workbench-page-tzM0wTL8.js +2 -0
  51. package/dist/gateway/static/root/assets/{local-apps-page-Bsy1lvAc.js → local-apps-page-B5n-x544.js} +1 -1
  52. package/dist/gateway/static/root/assets/{locale-store-iKjqemWG.js → locale-store-CPylQjH9.js} +1 -1
  53. package/dist/gateway/static/root/assets/logs-page-CgoQlera.js +2 -0
  54. package/dist/gateway/static/root/assets/{management-settings-D-akydG4.js → management-settings-CXBLyU-0.js} +1 -1
  55. package/dist/gateway/static/root/assets/{markdown-split-DHH4Cu2i.js → markdown-split-CtmQemJi.js} +1 -1
  56. package/dist/gateway/static/root/assets/markdown-view-CUsob4Pz.js +69 -0
  57. package/dist/gateway/static/root/assets/{media-plugins-BwHtUXkj.js → media-plugins-Dsd-IEOW.js} +1 -1
  58. package/dist/gateway/static/root/assets/messages-B82nsi9k.js +3 -0
  59. package/dist/gateway/static/root/assets/notes-api-CfKZYrBC.js +1 -0
  60. package/dist/gateway/static/root/assets/{notes-page-BxM1p6hz.js → notes-page-BKbOTE2n.js} +1 -1
  61. package/dist/gateway/static/root/assets/notes-workbench-BScELo01.js +4 -0
  62. package/dist/gateway/static/root/assets/oauth-authorization-window-Cdolr2wE.js +1 -0
  63. package/dist/gateway/static/root/assets/{popover-select-BzdnTy3h.js → popover-select-CccGri5Y.js} +1 -1
  64. package/dist/gateway/static/root/assets/{product-open-page-DrfWH1ir.js → product-open-page-DqB9bsDB.js} +1 -1
  65. package/dist/gateway/static/root/assets/project-detail-page-DUoyty8X.js +1 -0
  66. package/dist/gateway/static/root/assets/projects-page-PeXUdGdO.js +1 -0
  67. package/dist/gateway/static/root/assets/{registry-api-Cx3JxXSL.js → registry-api-B_5D8epF.js} +1 -1
  68. package/dist/gateway/static/root/assets/remote-access-hub-sHho-uXP.js +1 -0
  69. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DF7syQRd.js → runtime-tools-settings-panel-DBTH_t0O.js} +1 -1
  70. package/dist/gateway/static/root/assets/{schema-form-BQ_qRIsM.js → schema-form-CqMKAwV0.js} +1 -1
  71. package/dist/gateway/static/root/assets/sessions-page-DyvNgaP9.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-advanced-gate-CnYf1R7z.js +1 -0
  73. package/dist/gateway/static/root/assets/{settings-form-section-BBHGOQHU.js → settings-form-section-dPriuuYq.js} +1 -1
  74. package/dist/gateway/static/root/assets/{settings-loading-skeleton-CiwjP2-b.js → settings-loading-skeleton-B-Mbm8Va.js} +1 -1
  75. package/dist/gateway/static/root/assets/{settings-page-Rl9waapk.js → settings-page-Dyj3w-Ml.js} +1 -1
  76. package/dist/gateway/static/root/assets/setup-status-panel-C4FxY5J3.js +1 -0
  77. package/dist/gateway/static/root/assets/share-preview-page-emEdx7YL.js +2 -0
  78. package/dist/gateway/static/root/assets/shares-settings-BQBVq-sN.js +1 -0
  79. package/dist/gateway/static/root/assets/skill-reload-api-BFoEpQ4I.js +1 -0
  80. package/dist/gateway/static/root/assets/{skills-page-YbtR_zEU.js → skills-page-BNtYnrRT.js} +1 -1
  81. package/dist/gateway/static/root/assets/{skills-page.utils-DTmx2Zza.js → skills-page.utils-DjnbNFs5.js} +1 -1
  82. package/dist/gateway/static/root/assets/{system-settings-panel-BZDJcKdS.js → system-settings-panel-DDStf-jZ.js} +1 -1
  83. package/dist/gateway/static/root/assets/task-detail-page-ZVwr8KbS.js +1 -0
  84. package/dist/gateway/static/root/assets/{theme-store-BOD2D0dJ.js → theme-store-BN-32Fz5.js} +1 -1
  85. package/dist/gateway/static/root/assets/{use-autosave-Be9aR9qA.js → use-autosave-C2mKZ-ua.js} +1 -1
  86. package/dist/gateway/static/root/assets/user-context-page-CHjIinCW.js +1 -0
  87. package/dist/gateway/static/root/assets/{voice-api-key-field-IMc3Ua6C.js → voice-api-key-field-D7OHeQby.js} +1 -1
  88. package/dist/gateway/static/root/assets/{work-discovery-overlay-TC-xQenr.js → work-discovery-overlay-CIiXie7F.js} +1 -1
  89. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-B2auxcRv.js → workflow-run-setup-panel-9_dAGW3_.js} +2 -2
  90. package/dist/gateway/static/root/assets/workflows-page-DXpYJxao.js +5 -0
  91. package/dist/gateway/static/root/index.html +15 -14
  92. package/dist/package.js +1 -1
  93. package/dist/src/agent/agent-instance-gateway.d.ts +3 -0
  94. package/dist/src/agent/agent-manager.d.ts +3 -0
  95. package/dist/src/agent/agent-manager.js +30 -24
  96. package/dist/src/agent/embedded/index.d.ts +1 -1
  97. package/dist/src/agent/embedded/index.js +2 -2
  98. package/dist/src/agent/embedded/run-for-session.js +101 -62
  99. package/dist/src/agent/embedded/run-turn.js +56 -28
  100. package/dist/src/agent/embedded/runs.d.ts +16 -29
  101. package/dist/src/agent/embedded/runs.js +44 -65
  102. package/dist/src/agent/embedded/types.d.ts +4 -0
  103. package/dist/src/agent/orchestration/agent-run-supervisor.d.ts +28 -0
  104. package/dist/src/agent/orchestration/agent-run-supervisor.js +49 -0
  105. package/dist/src/agent/orchestration/agent-turn-policy.d.ts +18 -0
  106. package/dist/src/agent/orchestration/agent-turn-policy.js +36 -0
  107. package/dist/src/agent/orchestration/llm-turn-retry.d.ts +5 -0
  108. package/dist/src/agent/orchestration/llm-turn-retry.js +34 -4
  109. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +10 -1
  110. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +25 -4
  111. package/dist/src/agent/service/async-queue.d.ts +16 -3
  112. package/dist/src/agent/service/async-queue.js +29 -11
  113. package/dist/src/agent/service/process-direct-streaming.js +27 -4
  114. package/dist/src/agent/service.js +1 -0
  115. package/dist/src/agent/tools/exec-command.d.ts +2 -0
  116. package/dist/src/agent/tools/exec-command.js +70 -7
  117. package/dist/src/auth/oauth/index.js +3 -3
  118. package/dist/src/auth/oauth/registry.d.ts +2 -0
  119. package/dist/src/auth/oauth/registry.js +20 -12
  120. package/dist/src/auth/oauth/xopc-cloud.d.ts +1 -0
  121. package/dist/src/auth/oauth/xopc-cloud.js +32 -16
  122. package/dist/src/cli/commands/channels.js +1 -1
  123. package/dist/src/cli/commands/connectors.js +1 -1
  124. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  125. package/dist/src/cli/commands/models.js +1 -1
  126. package/dist/src/cli/commands/onboard.js +1 -1
  127. package/dist/src/cli/commands/tunnel.js +4 -5
  128. package/dist/src/config/agent-profile.js +1 -1
  129. package/dist/src/config/schema.d.ts +18 -0
  130. package/dist/src/config/schema.js +19 -1
  131. package/dist/src/extensions/sdk/index.js +1 -1
  132. package/dist/src/gateway/agents-admin.js +1 -1
  133. package/dist/src/gateway/hono/app.js +2 -1
  134. package/dist/src/gateway/hono/oauth-async.d.ts +1 -0
  135. package/dist/src/gateway/hono/oauth-async.js +11 -4
  136. package/dist/src/gateway/hono/routes/config.js +10 -0
  137. package/dist/src/gateway/hono/routes/host-fs.js +40 -1
  138. package/dist/src/gateway/hono/routes/media.js +33 -1
  139. package/dist/src/gateway/hono/routes/notes.js +162 -7
  140. package/dist/src/gateway/hono/routes/shares.js +141 -6
  141. package/dist/src/gateway/hono/routes/tunnel.js +47 -10
  142. package/dist/src/gateway/hono/routes/voice.d.ts +2 -6
  143. package/dist/src/gateway/hono/routes/voice.js +20 -4
  144. package/dist/src/gateway/hono/routes/workflows.js +2 -2
  145. package/dist/src/gateway/run-loop.js +3 -0
  146. package/dist/src/gateway/server.d.ts +3 -0
  147. package/dist/src/gateway/server.js +30 -5
  148. package/dist/src/gateway/service.js +4 -4
  149. package/dist/src/notes/service.d.ts +6 -2
  150. package/dist/src/notes/service.js +36 -4
  151. package/dist/src/providers/index.js +2 -2
  152. package/dist/src/share/note-share-service.d.ts +67 -0
  153. package/dist/src/share/note-share-service.js +283 -0
  154. package/dist/src/share/share-config.js +32 -3
  155. package/dist/src/share/share-landing.d.ts +5 -1
  156. package/dist/src/share/share-landing.js +28 -1
  157. package/dist/src/share/share-store.d.ts +34 -5
  158. package/dist/src/share/share-store.js +125 -19
  159. package/dist/src/share/share-thumbnail.js +4 -2
  160. package/dist/src/share/share-types.d.ts +52 -14
  161. package/dist/src/share/share-types.js +9 -0
  162. package/dist/src/share/share-zip.d.ts +2 -2
  163. package/dist/src/tui/backends/embedded-backend.js +1 -1
  164. package/dist/src/tunnel/env.d.ts +12 -6
  165. package/dist/src/tunnel/env.js +34 -26
  166. package/dist/src/tunnel/gateway-lifecycle.js +2 -13
  167. package/dist/src/tunnel/index.d.ts +1 -1
  168. package/dist/src/tunnel/index.js +2 -2
  169. package/dist/src/tunnel/tunnel-audit.d.ts +1 -1
  170. package/dist/src/tunnel/tunnel-config.d.ts +1 -1
  171. package/dist/src/tunnel/tunnel-config.js +9 -4
  172. package/dist/src/tunnel/tunnel-service.d.ts +1 -1
  173. package/dist/src/tunnel/tunnel-service.js +3 -0
  174. package/dist/src/tunnel/well-known.d.ts +1 -1
  175. package/dist/src/tunnel/well-known.js +1 -1
  176. package/dist/src/tunnel/xopc-cloud-registration.d.ts +9 -0
  177. package/dist/src/tunnel/xopc-cloud-registration.js +42 -0
  178. package/dist/src/voice/stt/transcribe-core.js +17 -1
  179. package/dist/src/voice/stt/types.d.ts +1 -1
  180. package/package.json +2 -2
  181. package/dist/gateway/static/root/assets/agents-DijFbC4G.js +0 -68
  182. package/dist/gateway/static/root/assets/apps-page-BFAmf9hq.js +0 -1
  183. package/dist/gateway/static/root/assets/automations-workspace-B8us5JBf.js +0 -6
  184. package/dist/gateway/static/root/assets/block-editor-C3mwGsms.js +0 -184
  185. package/dist/gateway/static/root/assets/browser-settings-page-BeBd17-3.js +0 -8
  186. package/dist/gateway/static/root/assets/capabilities-settings-panel-Bv0z3KRq.js +0 -7
  187. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BczD-pWE.js +0 -3
  188. package/dist/gateway/static/root/assets/channels-settings-2KQYq6xl.js +0 -1
  189. package/dist/gateway/static/root/assets/channels-status-swr-ByRbxC6z.js +0 -1
  190. package/dist/gateway/static/root/assets/connectors-page-PB1boaNy.js +0 -2
  191. package/dist/gateway/static/root/assets/dist-C230izr8.js +0 -1
  192. package/dist/gateway/static/root/assets/heartbeat-settings-5YQ5BUwp.js +0 -1
  193. package/dist/gateway/static/root/assets/home-page-DfIVWJl3.js +0 -1
  194. package/dist/gateway/static/root/assets/index-BXGC3VFm.css +0 -2
  195. package/dist/gateway/static/root/assets/index-jqDCfet4.js +0 -74
  196. package/dist/gateway/static/root/assets/local-app-workbench-page-CAb0odzu.js +0 -2
  197. package/dist/gateway/static/root/assets/logs-page-CFxKbDZl.js +0 -2
  198. package/dist/gateway/static/root/assets/markdown-view-DYkxMtJA.js +0 -69
  199. package/dist/gateway/static/root/assets/messages-kx5W39dO.js +0 -3
  200. package/dist/gateway/static/root/assets/notes-api-DJizatxh.js +0 -1
  201. package/dist/gateway/static/root/assets/notes-workbench-BGjEC89c.js +0 -4
  202. package/dist/gateway/static/root/assets/project-detail-page-Dj9kEQwg.js +0 -1
  203. package/dist/gateway/static/root/assets/projects-page-CBRy5Ezz.js +0 -1
  204. package/dist/gateway/static/root/assets/remote-access-hub-DSwz9RBh.js +0 -1
  205. package/dist/gateway/static/root/assets/sessions-page-WtattyVX.js +0 -1
  206. package/dist/gateway/static/root/assets/settings-advanced-gate-CNAz_q1F.js +0 -1
  207. package/dist/gateway/static/root/assets/setup-status-panel-CNo4Ajhn.js +0 -1
  208. package/dist/gateway/static/root/assets/share-preview-page-B7PI3yZ6.js +0 -2
  209. package/dist/gateway/static/root/assets/shares-settings-DpOH0zWB.js +0 -1
  210. package/dist/gateway/static/root/assets/skill-reload-api-BOf4xCat.js +0 -1
  211. package/dist/gateway/static/root/assets/task-detail-page-DrMX5Yhj.js +0 -1
  212. package/dist/gateway/static/root/assets/user-context-page-ewIK2ddC.js +0 -1
  213. package/dist/gateway/static/root/assets/workflows-page-Bdn82kFQ.js +0 -5
@@ -19,6 +19,15 @@ const ShareThumbnailPatchSchema = z.object({
19
19
  failureCooldownMs: z.number().int().min(0).max(36e5).optional(),
20
20
  internalGatewayUrl: z.string().min(1).optional()
21
21
  });
22
+ const ShareNotePatchSchema = z.object({
23
+ enabled: z.boolean().optional(),
24
+ maxMarkdownBytes: z.number().int().min(1024).max(10485760).optional(),
25
+ maxAttachmentCount: z.number().int().min(0).max(500).optional(),
26
+ maxAttachmentSize: z.number().int().min(1024).max(1073741824).optional(),
27
+ maxTotalSize: z.number().int().min(1024).max(2147483648).optional(),
28
+ assetTicketTtlMs: z.number().int().min(6e4).max(36e5).optional(),
29
+ revokeOnSourceDelete: z.boolean().optional()
30
+ });
22
31
  const ShareConfigPatchSchema = z.object({
23
32
  enabled: z.boolean().optional(),
24
33
  defaultTtlMs: z.number().int().min(6e4).max(6048e5).optional(),
@@ -27,7 +36,8 @@ const ShareConfigPatchSchema = z.object({
27
36
  maxFileSize: z.number().int().min(1048576).max(10737418240).optional(),
28
37
  inlinePreviewMimes: z.array(z.string().min(1)).optional(),
29
38
  directory: ShareDirectoryPatchSchema.optional(),
30
- thumbnail: ShareThumbnailPatchSchema.optional()
39
+ thumbnail: ShareThumbnailPatchSchema.optional(),
40
+ note: ShareNotePatchSchema.optional()
31
41
  });
32
42
  function resolveDirectoryConfig(raw) {
33
43
  const base = SHARE_CONFIG_DEFAULTS.directory;
@@ -57,6 +67,20 @@ function resolveThumbnailConfig(raw) {
57
67
  internalGatewayUrl: patch.internalGatewayUrl ?? base.internalGatewayUrl
58
68
  };
59
69
  }
70
+ function resolveNoteConfig(raw) {
71
+ const base = SHARE_CONFIG_DEFAULTS.note;
72
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { ...base };
73
+ const patch = raw;
74
+ return {
75
+ enabled: patch.enabled ?? base.enabled,
76
+ maxMarkdownBytes: patch.maxMarkdownBytes ?? base.maxMarkdownBytes,
77
+ maxAttachmentCount: patch.maxAttachmentCount ?? base.maxAttachmentCount,
78
+ maxAttachmentSize: patch.maxAttachmentSize ?? base.maxAttachmentSize,
79
+ maxTotalSize: patch.maxTotalSize ?? base.maxTotalSize,
80
+ assetTicketTtlMs: patch.assetTicketTtlMs ?? base.assetTicketTtlMs,
81
+ revokeOnSourceDelete: patch.revokeOnSourceDelete ?? base.revokeOnSourceDelete
82
+ };
83
+ }
60
84
  function resolveShareConfig(raw) {
61
85
  const patch = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
62
86
  return {
@@ -67,7 +91,8 @@ function resolveShareConfig(raw) {
67
91
  maxFileSize: patch.maxFileSize ?? SHARE_CONFIG_DEFAULTS.maxFileSize,
68
92
  inlinePreviewMimes: Array.isArray(patch.inlinePreviewMimes) ? patch.inlinePreviewMimes.filter((x) => typeof x === "string" && x.trim().length > 0) : [...SHARE_CONFIG_DEFAULTS.inlinePreviewMimes],
69
93
  directory: resolveDirectoryConfig(patch.directory),
70
- thumbnail: resolveThumbnailConfig(patch.thumbnail)
94
+ thumbnail: resolveThumbnailConfig(patch.thumbnail),
95
+ note: resolveNoteConfig(patch.note)
71
96
  };
72
97
  }
73
98
  function mergeShareConfigPatch(config, patch) {
@@ -99,7 +124,11 @@ function mergeShareConfigPatch(config, patch) {
99
124
  thumbnail: parsed.data.thumbnail ? {
100
125
  ...current.thumbnail,
101
126
  ...parsed.data.thumbnail
102
- } : current.thumbnail
127
+ } : current.thumbnail,
128
+ note: parsed.data.note ? {
129
+ ...current.note,
130
+ ...parsed.data.note
131
+ } : current.note
103
132
  };
104
133
  if (next.defaultTtlMs > next.maxTtlMs) return {
105
134
  ok: false,
@@ -1,5 +1,5 @@
1
1
  import type { DirectoryListing } from './share-store.js';
2
- import type { ShareRecord } from './share-types.js';
2
+ import type { NoteShareRecord, ShareRecord } from './share-types.js';
3
3
  export interface ShareLandingOgOptions {
4
4
  /** Absolute https/http URL of this landing page (for og:url). Omit if non-public. */
5
5
  absoluteShareUrl?: string | null;
@@ -10,6 +10,10 @@ export interface ShareLandingOgOptions {
10
10
  /** Description override (default: type + size). */
11
11
  description?: string;
12
12
  }
13
+ /** Lightweight public shell for Note shares. Crawlers get metadata; browsers continue to the SPA preview. */
14
+ export declare function renderNoteShareLandingPage(record: NoteShareRecord, previewUrl: string, options?: {
15
+ og?: ShareLandingOgOptions;
16
+ }): string;
13
17
  /** Render the file download confirmation landing page (does not consume downloadCount). */
14
18
  export declare function renderShareLandingPage(record: ShareRecord, downloadPath: string, options?: {
15
19
  /** Path to open the file inline (?inline=1) for browser-native rendering. */
@@ -35,6 +35,33 @@ body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;b
35
35
  .empty{text-align:center;color:#94a3b8;padding:2rem}
36
36
  `;
37
37
  }
38
+ /** Lightweight public shell for Note shares. Crawlers get metadata; browsers continue to the SPA preview. */
39
+ function renderNoteShareLandingPage(record, previewUrl, options) {
40
+ const title = escapeHtml(record.fileName);
41
+ const description = escapeHtml(record.description ?? "A Note shared via xopc");
42
+ const target = escapeHtml(previewUrl);
43
+ return `<!DOCTYPE html>
44
+ <html lang="zh">
45
+ <head>
46
+ <meta charset="utf-8">
47
+ <meta name="viewport" content="width=device-width,initial-scale=1">
48
+ <meta name="referrer" content="no-referrer">
49
+ <meta name="robots" content="noindex,nofollow">
50
+ ${renderOgTags({
51
+ title,
52
+ description,
53
+ url: options?.og?.absoluteShareUrl ?? null,
54
+ image: options?.og?.absoluteThumbnailUrl ?? null
55
+ })}
56
+ <title>${title} — xopc Share</title>
57
+ <meta http-equiv="refresh" content="0;url=${target}">
58
+ </head>
59
+ <body>
60
+ <p><a href="${target}">Open shared Note</a></p>
61
+ <script>location.replace(${JSON.stringify(previewUrl)})<\/script>
62
+ </body>
63
+ </html>`;
64
+ }
38
65
  /** Render the file download confirmation landing page (does not consume downloadCount). */
39
66
  function renderShareLandingPage(record, downloadPath, options) {
40
67
  const fileName = escapeHtml(record.fileName);
@@ -212,4 +239,4 @@ function renderShareExpiredPage(reason) {
212
239
  </html>`;
213
240
  }
214
241
  //#endregion
215
- export { renderFolderLandingPage, renderShareExpiredPage, renderShareLandingPage };
242
+ export { renderFolderLandingPage, renderNoteShareLandingPage, renderShareExpiredPage, renderShareLandingPage };
@@ -1,4 +1,4 @@
1
- import type { ShareRecord, ShareConfig, CreateShareParams } from './share-types.js';
1
+ import type { ShareRecord, ShareConfig, CreateShareParams, WorkspaceShareRecord, NoteShareRecord, DirectoryShareRecord } from './share-types.js';
2
2
  export interface DirectoryListingEntry {
3
3
  name: string;
4
4
  /** Workspace/share-relative POSIX path. */
@@ -32,10 +32,31 @@ export declare class ShareStore {
32
32
  create(params: CreateShareParams & {
33
33
  workspaceRoot: string;
34
34
  gatewayTokenHash: string;
35
- }): Promise<ShareRecord>;
35
+ }): Promise<WorkspaceShareRecord>;
36
36
  private createFileShare;
37
37
  private createDirectoryShare;
38
38
  private buildRecord;
39
+ createNoteShare(input: {
40
+ id: string;
41
+ sourceNoteId: string;
42
+ sourceVersion: number;
43
+ artifactRelativePath: string;
44
+ artifactSize: number;
45
+ attachmentCount: number;
46
+ snapshotRevision?: number;
47
+ fileName: string;
48
+ ttlMs?: number;
49
+ maxViews?: number | null;
50
+ description?: string;
51
+ gatewayTokenHash: string;
52
+ }): NoteShareRecord;
53
+ updateNoteSnapshot(id: string, patch: {
54
+ sourceVersion: number;
55
+ artifactSize: number;
56
+ attachmentCount: number;
57
+ fileName: string;
58
+ }): NoteShareRecord | null;
59
+ getNoteShares(noteId: string): NoteShareRecord[];
39
60
  private persistAndAudit;
40
61
  getById(id: string): ShareRecord | null;
41
62
  getByToken(token: string): ShareRecord | null;
@@ -46,8 +67,15 @@ export declare class ShareStore {
46
67
  };
47
68
  /** Increment download counter (used by directory & file downloads). Debounced persist. */
48
69
  incrementDownloadCount(id: string): void;
70
+ /** Atomically validate and consume one access in the single-threaded store. */
71
+ consumeAccess(id: string): {
72
+ valid: true;
73
+ } | {
74
+ valid: false;
75
+ reason: string;
76
+ };
49
77
  /** Check if the file still exists and inode matches. */
50
- validateFileIntegrity(record: ShareRecord): Promise<{
78
+ validateFileIntegrity(record: WorkspaceShareRecord): Promise<{
51
79
  valid: boolean;
52
80
  reason?: string;
53
81
  }>;
@@ -55,7 +83,7 @@ export declare class ShareStore {
55
83
  * Resolve a child path inside a directory share. Returns the absolute path
56
84
  * if it stays within both the share root and the workspace.
57
85
  */
58
- resolveDirectoryChild(record: ShareRecord, relativePath: string): Promise<{
86
+ resolveDirectoryChild(record: DirectoryShareRecord, relativePath: string): Promise<{
59
87
  ok: true;
60
88
  absolutePath: string;
61
89
  } | {
@@ -63,7 +91,7 @@ export declare class ShareStore {
63
91
  reason: string;
64
92
  }>;
65
93
  /** List a single directory level (cached, share-root-relative). */
66
- listDirectory(record: ShareRecord, relativePath: string): Promise<DirectoryListing>;
94
+ listDirectory(record: DirectoryShareRecord, relativePath: string): Promise<DirectoryListing>;
67
95
  /** Update thumbnail status. Persists immediately so generator restart is safe. */
68
96
  setThumbnailStatus(id: string, status: 'pending' | 'ready' | 'failed'): void;
69
97
  /** Drop the listing cache for a share (used on revoke/update). */
@@ -84,6 +112,7 @@ export declare class ShareStore {
84
112
  private cleanupExpired;
85
113
  shutdown(): void;
86
114
  private resolveAndValidatePath;
115
+ private cleanupNoteArtifact;
87
116
  }
88
117
  export declare function resolveMimeType(fileName: string): string;
89
118
  /** HTTP Content-Type with charset for text-like bodies (browser inline preview). */
@@ -8,7 +8,7 @@ import { logShareAudit } from "./share-audit.js";
8
8
  import { join, relative, resolve } from "node:path";
9
9
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
10
10
  import { randomBytes, randomUUID } from "node:crypto";
11
- import { lstat, readdir, realpath, stat } from "node:fs/promises";
11
+ import { lstat, readdir, realpath, rm, stat } from "node:fs/promises";
12
12
  //#region src/share/share-store.ts
13
13
  init_paths();
14
14
  init_logger();
@@ -166,14 +166,13 @@ var ShareStore = class {
166
166
  const id = randomUUID();
167
167
  const token = randomBytes(32).toString("base64url");
168
168
  const now = /* @__PURE__ */ new Date();
169
- const record = {
169
+ const common = {
170
170
  id,
171
171
  token,
172
172
  absolutePath: input.absolutePath,
173
173
  workspaceRelativePath: input.workspaceRelativePath,
174
174
  workspaceRoot: input.workspaceRoot,
175
175
  inode: input.inode,
176
- kind: input.kind,
177
176
  fileName: input.fileName,
178
177
  fileSize: input.fileSize,
179
178
  mimeType: input.mimeType,
@@ -183,13 +182,78 @@ var ShareStore = class {
183
182
  downloadCount: 0,
184
183
  revoked: false,
185
184
  createdByTokenHash: input.gatewayTokenHash,
186
- description: input.description,
185
+ description: input.description
186
+ };
187
+ const record = input.kind === "directory" ? {
188
+ ...common,
189
+ kind: "directory",
187
190
  directory: input.directory
191
+ } : {
192
+ ...common,
193
+ kind: "file"
188
194
  };
189
195
  this.shares.set(id, record);
190
196
  this.tokenIndex.set(token, id);
191
197
  return record;
192
198
  }
199
+ createNoteShare(input) {
200
+ if (!this.config.enabled || !this.config.note.enabled) throw new Error("Note sharing is disabled");
201
+ if (this.getActiveShares().length >= this.config.maxActiveShares) throw new Error(`Maximum active shares reached (${this.config.maxActiveShares})`);
202
+ const ttlMs = input.ttlMs ?? this.config.defaultTtlMs;
203
+ if (ttlMs < 6e4 || ttlMs > this.config.maxTtlMs) throw new Error(`TTL must be between 60s and ${this.config.maxTtlMs / 1e3}s`);
204
+ if (input.maxViews !== void 0 && input.maxViews !== null && (input.maxViews < 1 || input.maxViews > 1e3)) throw new Error("maxViews must be between 1 and 1000");
205
+ const now = /* @__PURE__ */ new Date();
206
+ const record = {
207
+ id: input.id,
208
+ token: randomBytes(32).toString("base64url"),
209
+ kind: "note",
210
+ fileName: input.fileName,
211
+ fileSize: input.artifactSize,
212
+ mimeType: "application/x-xopc-note",
213
+ workspaceRelativePath: "",
214
+ sourceNoteId: input.sourceNoteId,
215
+ sourceVersion: input.sourceVersion,
216
+ artifactRelativePath: input.artifactRelativePath,
217
+ attachmentCount: input.attachmentCount,
218
+ snapshotRevision: input.snapshotRevision ?? 1,
219
+ assetTicketSecret: randomBytes(32).toString("base64url"),
220
+ createdAt: now.toISOString(),
221
+ expiresAt: new Date(now.getTime() + ttlMs).toISOString(),
222
+ maxViews: input.maxViews ?? null,
223
+ downloadCount: 0,
224
+ revoked: false,
225
+ createdByTokenHash: input.gatewayTokenHash,
226
+ description: input.description
227
+ };
228
+ this.shares.set(record.id, record);
229
+ this.tokenIndex.set(record.token, record.id);
230
+ this.persistAndAudit(record, "share.create", `Note share created: ${record.fileName}`, {
231
+ noteId: record.sourceNoteId,
232
+ sourceVersion: record.sourceVersion,
233
+ attachmentCount: record.attachmentCount,
234
+ ttlMs
235
+ });
236
+ return record;
237
+ }
238
+ updateNoteSnapshot(id, patch) {
239
+ const record = this.shares.get(id);
240
+ if (!record || record.kind !== "note") return null;
241
+ record.sourceVersion = patch.sourceVersion;
242
+ record.fileSize = patch.artifactSize;
243
+ record.attachmentCount = patch.attachmentCount;
244
+ record.fileName = patch.fileName;
245
+ record.snapshotRevision += 1;
246
+ this.persistSync();
247
+ logShareAudit("share.update", {
248
+ shareId: id,
249
+ noteId: record.sourceNoteId,
250
+ snapshotRevision: record.snapshotRevision
251
+ }, `Note share snapshot updated: ${record.fileName}`);
252
+ return record;
253
+ }
254
+ getNoteShares(noteId) {
255
+ return this.getAllShares().filter((record) => record.kind === "note" && record.sourceNoteId === noteId);
256
+ }
193
257
  persistAndAudit(record, event, message, extra) {
194
258
  this.persistSync();
195
259
  logShareAudit(event, {
@@ -229,6 +293,22 @@ var ShareStore = class {
229
293
  record.downloadCount++;
230
294
  this.scheduleDebouncedPersist();
231
295
  }
296
+ /** Atomically validate and consume one access in the single-threaded store. */
297
+ consumeAccess(id) {
298
+ const record = this.shares.get(id);
299
+ if (!record) return {
300
+ valid: false,
301
+ reason: "not_found"
302
+ };
303
+ const validation = this.validateAccess(record);
304
+ if (!validation.valid) return {
305
+ valid: false,
306
+ reason: validation.reason ?? "access_denied"
307
+ };
308
+ record.downloadCount++;
309
+ this.scheduleDebouncedPersist();
310
+ return { valid: true };
311
+ }
232
312
  /** Check if the file still exists and inode matches. */
233
313
  async validateFileIntegrity(record) {
234
314
  try {
@@ -302,7 +382,6 @@ var ShareStore = class {
302
382
  }
303
383
  /** List a single directory level (cached, share-root-relative). */
304
384
  async listDirectory(record, relativePath) {
305
- if (record.kind !== "directory") throw new Error("Not a directory share");
306
385
  const trimmed = (relativePath ?? "").replace(/^\/+/, "");
307
386
  const cacheKey = `${record.id}::${trimmed}`;
308
387
  const cacheTtl = this.config.directory.listingCacheMs;
@@ -376,6 +455,7 @@ var ShareStore = class {
376
455
  const record = this.shares.get(id);
377
456
  if (!record) return false;
378
457
  record.revoked = true;
458
+ this.cleanupNoteArtifact(record);
379
459
  this.invalidateListingCache(id);
380
460
  this.persistSync();
381
461
  logShareAudit("share.revoke", {
@@ -391,6 +471,7 @@ var ShareStore = class {
391
471
  const record = this.shares.get(id);
392
472
  if (record && !record.revoked) {
393
473
  record.revoked = true;
474
+ this.cleanupNoteArtifact(record);
394
475
  this.invalidateListingCache(id);
395
476
  count++;
396
477
  logShareAudit("share.revoke", {
@@ -408,6 +489,7 @@ var ShareStore = class {
408
489
  let count = 0;
409
490
  for (const record of this.shares.values()) if (!record.revoked && now >= new Date(record.expiresAt).getTime()) {
410
491
  record.revoked = true;
492
+ this.cleanupNoteArtifact(record);
411
493
  this.invalidateListingCache(record.id);
412
494
  count++;
413
495
  }
@@ -440,7 +522,7 @@ var ShareStore = class {
440
522
  try {
441
523
  const raw = readFileSync(path, "utf8");
442
524
  const data = JSON.parse(raw);
443
- if (data.version !== 1 || !Array.isArray(data.shares)) return;
525
+ if (data.version !== 1 && data.version !== 2 || !Array.isArray(data.shares)) return;
444
526
  const now = Date.now();
445
527
  let cleaned = 0;
446
528
  for (const record of data.shares) {
@@ -474,7 +556,7 @@ var ShareStore = class {
474
556
  }
475
557
  }
476
558
  writeFileSync(path, `${JSON.stringify({
477
- version: 1,
559
+ version: 2,
478
560
  shares: records
479
561
  }, null, 2)}\n`, "utf8");
480
562
  }
@@ -499,19 +581,23 @@ var ShareStore = class {
499
581
  cleanupExpired() {
500
582
  const now = Date.now();
501
583
  let removed = 0;
502
- for (const [id, record] of this.shares) if (now - new Date(record.expiresAt).getTime() > EXPIRED_RETENTION_MS) {
503
- this.shares.delete(id);
504
- this.tokenIndex.delete(record.token);
505
- this.invalidateListingCache(id);
506
- if (this.onCleanup) try {
507
- this.onCleanup(record);
508
- } catch (err) {
509
- log.warn({
510
- err,
511
- shareId: id
512
- }, "Share cleanup hook threw");
584
+ for (const [id, record] of this.shares) {
585
+ const expiredMs = now - new Date(record.expiresAt).getTime();
586
+ if (expiredMs >= 0) this.cleanupNoteArtifact(record);
587
+ if (expiredMs > EXPIRED_RETENTION_MS) {
588
+ this.shares.delete(id);
589
+ this.tokenIndex.delete(record.token);
590
+ this.invalidateListingCache(id);
591
+ if (this.onCleanup) try {
592
+ this.onCleanup(record);
593
+ } catch (err) {
594
+ log.warn({
595
+ err,
596
+ shareId: id
597
+ }, "Share cleanup hook threw");
598
+ }
599
+ removed++;
513
600
  }
514
- removed++;
515
601
  }
516
602
  if (removed > 0) {
517
603
  this.persistSync();
@@ -543,6 +629,26 @@ var ShareStore = class {
543
629
  if (relToRoot.startsWith("..") || relToRoot.split(/[/\\]/).includes("..")) throw new Error("Path is outside workspace");
544
630
  return abs;
545
631
  }
632
+ cleanupNoteArtifact(record) {
633
+ if (record.kind !== "note") return;
634
+ const expected = join("share-artifacts", record.id);
635
+ if (record.artifactRelativePath !== expected) {
636
+ log.warn({
637
+ shareId: record.id,
638
+ artifactRelativePath: record.artifactRelativePath
639
+ }, "Skipped unsafe Note share artifact cleanup path");
640
+ return;
641
+ }
642
+ rm(join(resolveStateDir(), expected), {
643
+ recursive: true,
644
+ force: true
645
+ }).catch((err) => {
646
+ log.warn({
647
+ err,
648
+ shareId: record.id
649
+ }, "Failed to clean Note share artifact");
650
+ });
651
+ }
546
652
  };
547
653
  async function scanDirectory(root, opts) {
548
654
  let entryCount = 0;
@@ -92,8 +92,10 @@ async function runThumbnail(task, ctx) {
92
92
  if (!target) return;
93
93
  try {
94
94
  let bytes;
95
- if (task.scope === "file") bytes = await renderForFile(target, ctx);
96
- else bytes = await renderForSite(target, ctx);
95
+ if (task.scope === "file") {
96
+ if (!("kind" in target) || target.kind === "note") return;
97
+ bytes = await renderForFile(target, ctx);
98
+ } else bytes = await renderForSite(target, ctx);
97
99
  if (bytes.length > ctx.config.maxBytes) bytes = bytes.subarray(0, ctx.config.maxBytes);
98
100
  await writeFile(getThumbnailPath(task.token), bytes);
99
101
  if (task.scope === "file") getShareStore().setThumbnailStatus(task.recordId, "ready");
@@ -1,4 +1,5 @@
1
- export type ShareKind = 'file' | 'directory';
1
+ export type WorkspaceShareKind = 'file' | 'directory';
2
+ export type ShareKind = WorkspaceShareKind | 'note';
2
3
  export interface ShareDirectoryMeta {
3
4
  /** 'browse' shows a file tree; 'zip-only' hides structure and only offers ZIP. */
4
5
  mode: 'browse' | 'zip-only';
@@ -9,22 +10,14 @@ export interface ShareDirectoryMeta {
9
10
  /** Maximum traversal depth (defense against recursive symlinks). */
10
11
  maxDepth: number;
11
12
  }
12
- export interface ShareRecord {
13
+ interface ShareRecordBase {
13
14
  /** Unique identifier (UUIDv4) for management. */
14
15
  id: string;
15
16
  /** Cryptographically secure URL token (base64url, 32 bytes). */
16
17
  token: string;
17
- /** Resolved absolute path at creation time. */
18
- absolutePath: string;
19
- /** Workspace-relative POSIX path (for display). */
20
- workspaceRelativePath: string;
21
- /** Workspace root at creation time (for download-time re-validation). */
22
- workspaceRoot: string;
23
- /** File or directory inode at creation time (TOCTOU protection). */
24
- inode: number;
25
- /** Discriminator for downstream branching ('file' | 'directory'). */
18
+ /** Discriminator for downstream branching. */
26
19
  kind: ShareKind;
27
- /** Original file/folder name (basename). */
20
+ /** Public display name. Retained as fileName for API compatibility. */
28
21
  fileName: string;
29
22
  /**
30
23
  * For files: file size in bytes (snapshot at creation).
@@ -56,6 +49,40 @@ export interface ShareRecord {
56
49
  /** ISO timestamp of the last failed attempt (used for cooldown). */
57
50
  thumbnailFailedAt?: string;
58
51
  }
52
+ interface WorkspaceShareRecordBase extends ShareRecordBase {
53
+ kind: WorkspaceShareKind;
54
+ /** Resolved absolute path at creation time. */
55
+ absolutePath: string;
56
+ /** Workspace-relative POSIX path (for display). */
57
+ workspaceRelativePath: string;
58
+ /** Workspace root at creation time (for download-time re-validation). */
59
+ workspaceRoot: string;
60
+ /** File or directory inode at creation time (TOCTOU protection). */
61
+ inode: number;
62
+ }
63
+ export interface FileShareRecord extends WorkspaceShareRecordBase {
64
+ kind: 'file';
65
+ directory?: undefined;
66
+ }
67
+ export interface DirectoryShareRecord extends WorkspaceShareRecordBase {
68
+ kind: 'directory';
69
+ directory: ShareDirectoryMeta;
70
+ }
71
+ export interface NoteShareRecord extends ShareRecordBase {
72
+ kind: 'note';
73
+ /** Notes are state-owned objects, not workspace paths. */
74
+ workspaceRelativePath: '';
75
+ sourceNoteId: string;
76
+ sourceVersion: number;
77
+ artifactRelativePath: string;
78
+ attachmentCount: number;
79
+ snapshotRevision: number;
80
+ /** Private HMAC key for short-lived public asset tickets. */
81
+ assetTicketSecret: string;
82
+ directory?: undefined;
83
+ }
84
+ export type WorkspaceShareRecord = FileShareRecord | DirectoryShareRecord;
85
+ export type ShareRecord = WorkspaceShareRecord | NoteShareRecord;
59
86
  export interface CreateShareParams {
60
87
  /** Workspace-relative file path. */
61
88
  path: string;
@@ -70,7 +97,7 @@ export interface CreateShareParams {
70
97
  /** Agent id to resolve workspace root. */
71
98
  agentId?: string;
72
99
  /** Force directory share semantics (overrides auto-detection). */
73
- kind?: ShareKind;
100
+ kind?: WorkspaceShareKind;
74
101
  /** Directory: browse vs zip-only. Defaults to 'browse'. */
75
102
  directoryMode?: 'browse' | 'zip-only';
76
103
  /** Directory: cap on entry count at scan time. */
@@ -83,7 +110,7 @@ export interface CreateShareParams {
83
110
  maxDepth?: number;
84
111
  }
85
112
  export interface ShareStoreData {
86
- version: 1;
113
+ version: 1 | 2;
87
114
  shares: ShareRecord[];
88
115
  }
89
116
  export type ShareReachability = 'public' | 'lan' | 'local-only';
@@ -115,6 +142,15 @@ export interface ShareThumbnailConfig {
115
142
  /** Optional override for the loopback URL used by the headless renderer. */
116
143
  internalGatewayUrl?: string;
117
144
  }
145
+ export interface ShareNoteConfig {
146
+ enabled: boolean;
147
+ maxMarkdownBytes: number;
148
+ maxAttachmentCount: number;
149
+ maxAttachmentSize: number;
150
+ maxTotalSize: number;
151
+ assetTicketTtlMs: number;
152
+ revokeOnSourceDelete: boolean;
153
+ }
118
154
  export interface ShareConfig {
119
155
  enabled: boolean;
120
156
  defaultTtlMs: number;
@@ -124,6 +160,8 @@ export interface ShareConfig {
124
160
  inlinePreviewMimes: string[];
125
161
  directory: ShareDirectoryConfig;
126
162
  thumbnail: ShareThumbnailConfig;
163
+ note: ShareNoteConfig;
127
164
  }
128
165
  /** Default share configuration values. */
129
166
  export declare const SHARE_CONFIG_DEFAULTS: ShareConfig;
167
+ export {};
@@ -34,6 +34,15 @@ const SHARE_CONFIG_DEFAULTS = {
34
34
  viewportHeight: 630,
35
35
  generationTimeoutMs: 8e3,
36
36
  failureCooldownMs: 5 * 6e4
37
+ },
38
+ note: {
39
+ enabled: true,
40
+ maxMarkdownBytes: 2 * 1024 * 1024,
41
+ maxAttachmentCount: 50,
42
+ maxAttachmentSize: 100 * 1024 * 1024,
43
+ maxTotalSize: 250 * 1024 * 1024,
44
+ assetTicketTtlMs: 10 * 6e4,
45
+ revokeOnSourceDelete: true
37
46
  }
38
47
  };
39
48
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { Readable } from 'node:stream';
2
- import type { ShareRecord } from './share-types.js';
2
+ import type { DirectoryShareRecord } from './share-types.js';
3
3
  export interface ZipPlanFile {
4
4
  /** Path within the archive (POSIX, no leading /, may contain subdirs). */
5
5
  zipPath: string;
@@ -32,4 +32,4 @@ export interface PlanDirectoryOpts {
32
32
  /** Walk depth cap. */
33
33
  maxDepth: number;
34
34
  }
35
- export declare function planDirectoryFiles(record: ShareRecord, opts: PlanDirectoryOpts): Promise<ZipPlanFile[]>;
35
+ export declare function planDirectoryFiles(record: DirectoryShareRecord, opts: PlanDirectoryOpts): Promise<ZipPlanFile[]>;
@@ -23,9 +23,9 @@ import { parseModelRef } from "../../agent/models/selection.js";
23
23
  import { buildReviewContext, resolveGitRoot } from "../../review/review-git.js";
24
24
  import { MessageBus, MessageBusShutdownError } from "../../infra/bus/queue.js";
25
25
  import "../../infra/bus/index.js";
26
- import { prependEnvelopeTimestamp } from "../../channels/envelope-timestamp.js";
27
26
  import { getWorkspacePath } from "../../config/workspace-path-helpers.js";
28
27
  import "../../config/index.js";
28
+ import { prependEnvelopeTimestamp } from "../../channels/envelope-timestamp.js";
29
29
  import { buildWorkflowChildTools } from "../../agent/workflow/workflow-child-tools.js";
30
30
  import { WorkflowRunService } from "../../workflows/service/workflow-run-service.js";
31
31
  import { WorkflowSessionBridge } from "../../workflows/service/workflow-session-bridge.js";
@@ -1,12 +1,16 @@
1
1
  import type { Config } from '../config/schema.js';
2
- export declare const TUNNEL_MASKED_SECRET_SENTINELS: readonly ["***", "••••••••••••"];
3
- export type TunnelRegistrationSecretSource = 'env' | 'config' | 'dev_default' | 'missing';
2
+ export type TunnelRegistrationSecretSource = 'config' | 'dev_default' | 'missing';
4
3
  export type TunnelRegistrationSecretMeta = {
5
4
  configured: boolean;
6
5
  source: TunnelRegistrationSecretSource;
7
6
  };
8
- /** True when the broker is the public frp.xopc.ai service (not local dev). */
9
- export declare function isProductionTunnelBroker(brokerUrl: string): boolean;
7
+ export declare const TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE = "TUNNEL_REGISTRATION_SECRET_REQUIRED";
8
+ export declare class TunnelRegistrationSecretError extends Error {
9
+ readonly code = "TUNNEL_REGISTRATION_SECRET_REQUIRED";
10
+ constructor(brokerUrl?: string);
11
+ }
12
+ /** True only for brokers that are safe to use with the built-in development secret. */
13
+ export declare function isLocalDevelopmentTunnelBroker(brokerUrl: string): boolean;
10
14
  export declare function maskTunnelSecretForWeb(secret: string): string;
11
15
  export declare function isMaskedTunnelSecretPatchValue(value: string): boolean;
12
16
  /**
@@ -15,9 +19,11 @@ export declare function isMaskedTunnelSecretPatchValue(value: string): boolean;
15
19
  /** Plaintext registration secret from config file only (never env). */
16
20
  export declare function readTunnelRegistrationSecretFromConfigOnly(config: Config | undefined): string | null;
17
21
  export declare function getTunnelRegistrationSecretMeta(config: Config | undefined, env?: NodeJS.ProcessEnv, brokerUrl?: string): TunnelRegistrationSecretMeta;
22
+ export declare function resolveOptionalTunnelRegistrationSecret(brokerUrl?: string, configSecret?: string): string | undefined;
23
+ export declare function tunnelRegistrationSecretRequiredMessage(brokerUrl?: string): string;
18
24
  /**
19
25
  * Registration secret for Tunnel Broker register API.
20
- * Priority: env `XOPC_TUNNEL_REGISTRATION_SECRET` → `tunnel.registrationSecret` in config dev default (non-production brokers only).
26
+ * Resolve `tunnel.registrationSecret` from config, with a development default for local brokers.
21
27
  */
22
- export declare function resolveTunnelRegistrationSecret(env?: NodeJS.ProcessEnv, brokerUrl?: string, configSecret?: string): string;
28
+ export declare function resolveTunnelRegistrationSecret(brokerUrl?: string, configSecret?: string): string;
23
29
  export declare function resolveTunnelBrokerUrl(configBrokerUrl: string | undefined, env?: NodeJS.ProcessEnv): string;