@xopcai/xopc 0.0.84 → 0.0.86

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 (418) 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/feishu/src/plugin.d.ts +2 -0
  4. package/dist/extensions/feishu/src/plugin.js +10 -0
  5. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  6. package/dist/extensions/feishu/src/workflow-progress.d.ts +27 -0
  7. package/dist/extensions/feishu/src/workflow-progress.js +99 -0
  8. package/dist/extensions/feishu/src/workflow-progress.js.map +1 -0
  9. package/dist/extensions/telegram/src/plugin.d.ts +2 -0
  10. package/dist/extensions/telegram/src/plugin.js +11 -1
  11. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  12. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  13. package/dist/extensions/telegram/src/workflow-progress.d.ts +24 -0
  14. package/dist/extensions/telegram/src/workflow-progress.js +73 -0
  15. package/dist/extensions/telegram/src/workflow-progress.js.map +1 -0
  16. package/dist/extensions/telegram/xopc.extension.json +1 -1
  17. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +158 -0
  18. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -0
  19. package/dist/extensions/weixin/src/api/api.js +2 -2
  20. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  21. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  22. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  23. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  24. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  25. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  26. package/dist/extensions/weixin/src/plugin.d.ts +2 -0
  27. package/dist/extensions/weixin/src/plugin.js +11 -1
  28. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  29. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  30. package/dist/extensions/weixin/src/workflow-progress.d.ts +26 -0
  31. package/dist/extensions/weixin/src/workflow-progress.js +99 -0
  32. package/dist/extensions/weixin/src/workflow-progress.js.map +1 -0
  33. package/dist/gateway/static/root/assets/agents-mS3_HpRI.js +222 -0
  34. package/dist/gateway/static/root/assets/apps-page-DrfytjOb.js +1 -0
  35. package/dist/gateway/static/root/assets/channels-settings-BG6b9KrW.js +1 -0
  36. package/dist/gateway/static/root/assets/channels-status-swr-Bs5kMCMI.js +8 -0
  37. package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +1 -0
  38. package/dist/gateway/static/root/assets/cron-api-BuVcZ5zR.js +1 -0
  39. package/dist/gateway/static/root/assets/cron-page-BMrloeFH.js +1 -0
  40. package/dist/gateway/static/root/assets/dist-BTWC-BTN.js +45 -0
  41. package/dist/gateway/static/root/assets/{dist-CqNMNhJM.js → dist-CKU1OOTf.js} +1 -1
  42. package/dist/gateway/static/root/assets/{extension-debug-page-gf2L0kY_.js → extension-debug-page-BdW_46sN.js} +1 -1
  43. package/dist/gateway/static/root/assets/extension-page-DW47KI82.js +1 -0
  44. package/dist/gateway/static/root/assets/extension-settings-page-B-W4x2xP.js +1 -0
  45. package/dist/gateway/static/root/assets/fetch-B2MYHbWg.js +1 -0
  46. package/dist/gateway/static/root/assets/{field-primitives-DTtlp-l8.js → field-primitives-DPG-oJmx.js} +1 -1
  47. package/dist/gateway/static/root/assets/heartbeat-config-api-C8dNts9i.js +1 -0
  48. package/dist/gateway/static/root/assets/index-BmVYculr.js +4700 -0
  49. package/dist/gateway/static/root/assets/index-ew_2L2We.css +1 -0
  50. package/dist/gateway/static/root/assets/logs-page-sTsVWz0X.js +1 -0
  51. package/dist/gateway/static/root/assets/sessions-page-FaG_Vlkb.js +1 -0
  52. package/dist/gateway/static/root/assets/settings-form-section-DuvRQW--.js +1 -0
  53. package/dist/gateway/static/root/assets/settings-page-Bet1OerL.js +3 -0
  54. package/dist/gateway/static/root/assets/share-preview-page-BtG2kLDh.js +2 -0
  55. package/dist/gateway/static/root/assets/skills-page-DhUO235y.js +2 -0
  56. package/dist/gateway/static/root/assets/theme-store-DryYl3qD.js +1 -0
  57. package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +3 -0
  58. package/dist/gateway/static/root/assets/utils-BY7bU1DT.js +1 -0
  59. package/dist/gateway/static/root/assets/voice-api-key-field-CGEydndO.js +1 -0
  60. package/dist/gateway/static/root/index.html +7 -6
  61. package/dist/package.js +1 -1
  62. package/dist/src/agent/agent-manager.js +7 -7
  63. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  64. package/dist/src/agent/context/workspace-seed.js +3 -3
  65. package/dist/src/agent/embedded/map-stream-events.js +6 -0
  66. package/dist/src/agent/embedded/map-stream-events.js.map +1 -1
  67. package/dist/src/agent/embedded/subscribe-session.js +24 -0
  68. package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
  69. package/dist/src/agent/embedded/types.d.ts +19 -0
  70. package/dist/src/agent/goals/goal-locale.js +2 -2
  71. package/dist/src/agent/goals/goal-run-store.js +4 -4
  72. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  73. package/dist/src/agent/goals/post-turn.js +2 -2
  74. package/dist/src/agent/image/load-image-media.js +2 -2
  75. package/dist/src/agent/ipc/bus.js +1 -1
  76. package/dist/src/agent/ipc/inbox.js +2 -2
  77. package/dist/src/agent/ipc/socket.js +1 -1
  78. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  79. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  80. package/dist/src/agent/memory/dreaming/events.js +1 -1
  81. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  82. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  83. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  84. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  85. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  86. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  87. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  88. package/dist/src/agent/models/manager.js +1 -1
  89. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  90. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  91. package/dist/src/agent/reply/startup-context.d.ts +3 -0
  92. package/dist/src/agent/reply/startup-context.js +25 -2
  93. package/dist/src/agent/reply/startup-context.js.map +1 -1
  94. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  95. package/dist/src/agent/sandbox/path-policy.js +2 -2
  96. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  97. package/dist/src/agent/service.d.ts +1 -0
  98. package/dist/src/agent/service.js +10 -4
  99. package/dist/src/agent/service.js.map +1 -1
  100. package/dist/src/agent/session/session-inspector.js +1 -1
  101. package/dist/src/agent/skills/config.js +1 -1
  102. package/dist/src/agent/skills/hub-hash.js +2 -2
  103. package/dist/src/agent/skills/hub-lock.js +1 -1
  104. package/dist/src/agent/skills/hub-pull.js +3 -3
  105. package/dist/src/agent/skills/index.js +1 -1
  106. package/dist/src/agent/skills/managed-store.js +1 -1
  107. package/dist/src/agent/skills/scanner.js +1 -1
  108. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  109. package/dist/src/agent/skills/skill-manager.js +1 -1
  110. package/dist/src/agent/tools/create-share-tool.d.ts +27 -0
  111. package/dist/src/agent/tools/create-share-tool.js +237 -0
  112. package/dist/src/agent/tools/create-share-tool.js.map +1 -0
  113. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  114. package/dist/src/agent/tools/factory.js +35 -1
  115. package/dist/src/agent/tools/factory.js.map +1 -1
  116. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  117. package/dist/src/agent/tools/index.d.ts +2 -0
  118. package/dist/src/agent/tools/index.js +3 -1
  119. package/dist/src/agent/tools/send-media.js +1 -1
  120. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  121. package/dist/src/agent/tools/workflow-tool.d.ts +41 -0
  122. package/dist/src/agent/tools/workflow-tool.js +271 -0
  123. package/dist/src/agent/tools/workflow-tool.js.map +1 -0
  124. package/dist/src/agent/tools/write.js +1 -1
  125. package/dist/src/agent/workflow/builtins/audit-repo.d.ts +13 -0
  126. package/dist/src/agent/workflow/builtins/audit-repo.js +156 -0
  127. package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -0
  128. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +13 -0
  129. package/dist/src/agent/workflow/builtins/debug-incident.js +155 -0
  130. package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -0
  131. package/dist/src/agent/workflow/builtins/index.d.ts +17 -0
  132. package/dist/src/agent/workflow/builtins/index.js +38 -0
  133. package/dist/src/agent/workflow/builtins/index.js.map +1 -0
  134. package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +14 -0
  135. package/dist/src/agent/workflow/builtins/multi-perspective-review.js +149 -0
  136. package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -0
  137. package/dist/src/agent/workflow/builtins/pr-review.d.ts +12 -0
  138. package/dist/src/agent/workflow/builtins/pr-review.js +156 -0
  139. package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -0
  140. package/dist/src/agent/workflow/builtins/research.d.ts +13 -0
  141. package/dist/src/agent/workflow/builtins/research.js +160 -0
  142. package/dist/src/agent/workflow/builtins/research.js.map +1 -0
  143. package/dist/src/agent/workflow/catalog.d.ts +56 -0
  144. package/dist/src/agent/workflow/catalog.js +159 -0
  145. package/dist/src/agent/workflow/catalog.js.map +1 -0
  146. package/dist/src/agent/workflow/channel-capability.d.ts +76 -0
  147. package/dist/src/agent/workflow/channel-capability.js +1 -0
  148. package/dist/src/agent/workflow/index.d.ts +11 -0
  149. package/dist/src/agent/workflow/index.js +10 -0
  150. package/dist/src/agent/workflow/last-run-memory.d.ts +42 -0
  151. package/dist/src/agent/workflow/last-run-memory.js +60 -0
  152. package/dist/src/agent/workflow/last-run-memory.js.map +1 -0
  153. package/dist/src/agent/workflow/parser.d.ts +20 -0
  154. package/dist/src/agent/workflow/parser.js +146 -0
  155. package/dist/src/agent/workflow/parser.js.map +1 -0
  156. package/dist/src/agent/workflow/progress-broker.d.ts +80 -0
  157. package/dist/src/agent/workflow/progress-broker.js +263 -0
  158. package/dist/src/agent/workflow/progress-broker.js.map +1 -0
  159. package/dist/src/agent/workflow/runtime.d.ts +31 -0
  160. package/dist/src/agent/workflow/runtime.js +301 -0
  161. package/dist/src/agent/workflow/runtime.js.map +1 -0
  162. package/dist/src/agent/workflow/snapshot.d.ts +18 -0
  163. package/dist/src/agent/workflow/snapshot.js +144 -0
  164. package/dist/src/agent/workflow/snapshot.js.map +1 -0
  165. package/dist/src/agent/workflow/structured-output-tool.d.ts +33 -0
  166. package/dist/src/agent/workflow/structured-output-tool.js +58 -0
  167. package/dist/src/agent/workflow/structured-output-tool.js.map +1 -0
  168. package/dist/src/agent/workflow/subagent-runner.d.ts +42 -0
  169. package/dist/src/agent/workflow/subagent-runner.js +104 -0
  170. package/dist/src/agent/workflow/subagent-runner.js.map +1 -0
  171. package/dist/src/agent/workflow/types.d.ts +145 -0
  172. package/dist/src/agent/workflow/types.js +1 -0
  173. package/dist/src/auth/credentials.js +3 -3
  174. package/dist/src/auth/profiles/store.js +1 -1
  175. package/dist/src/auth/sync-provider-auth.js +1 -1
  176. package/dist/src/browser/cache-dir-policy.js +1 -1
  177. package/dist/src/browser/cdp-local-launcher.js +2 -2
  178. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  179. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  180. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  181. package/dist/src/browser/stealth.js +1 -1
  182. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  183. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  184. package/dist/src/channels/outbound/persist-store.js +1 -1
  185. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  186. package/dist/src/channels/pairing/pairing-store.js +2 -2
  187. package/dist/src/chat-commands/builtins/config.js +2 -2
  188. package/dist/src/chat-commands/builtins/model.js +40 -23
  189. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  190. package/dist/src/chat-commands/builtins/system.js +30 -15
  191. package/dist/src/chat-commands/builtins/system.js.map +1 -1
  192. package/dist/src/chat-commands/builtins/workflow.d.ts +18 -0
  193. package/dist/src/chat-commands/builtins/workflow.js +172 -0
  194. package/dist/src/chat-commands/builtins/workflow.js.map +1 -0
  195. package/dist/src/chat-commands/context.js +1 -1
  196. package/dist/src/chat-commands/format-output.d.ts +28 -0
  197. package/dist/src/chat-commands/format-output.js +45 -0
  198. package/dist/src/chat-commands/format-output.js.map +1 -0
  199. package/dist/src/chat-commands/index.d.ts +1 -0
  200. package/dist/src/chat-commands/index.js +3 -1
  201. package/dist/src/chat-commands/index.js.map +1 -1
  202. package/dist/src/cli/commands/config.js +2 -2
  203. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  204. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  205. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  206. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  207. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  208. package/dist/src/cli/commands/extension-dev.js +1 -1
  209. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  210. package/dist/src/cli/commands/extension-pack.js +1 -1
  211. package/dist/src/cli/commands/gateway/lifecycle.js +10 -4
  212. package/dist/src/cli/commands/gateway/lifecycle.js.map +1 -1
  213. package/dist/src/cli/commands/gateway/shared.js +1 -1
  214. package/dist/src/cli/commands/image.js +1 -1
  215. package/dist/src/cli/commands/init.js +4 -4
  216. package/dist/src/cli/commands/onboard.js +2 -2
  217. package/dist/src/cli/commands/tunnel.js +2 -2
  218. package/dist/src/cli/utils/gateway-client.js +1 -1
  219. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  220. package/dist/src/config/agent-profile.js +1 -1
  221. package/dist/src/config/gateway-bind.js +1 -1
  222. package/dist/src/config/index.js +5 -5
  223. package/dist/src/config/loader.js +2 -2
  224. package/dist/src/config/models-json.js +2 -2
  225. package/dist/src/config/paths-state.js +1 -1
  226. package/dist/src/config/profile.js +2 -2
  227. package/dist/src/config/public-url.d.ts +28 -0
  228. package/dist/src/config/public-url.js +103 -0
  229. package/dist/src/config/public-url.js.map +1 -0
  230. package/dist/src/config/schema.d.ts +82 -0
  231. package/dist/src/config/schema.js +130 -1
  232. package/dist/src/config/schema.js.map +1 -1
  233. package/dist/src/config/workspace-path.js +1 -1
  234. package/dist/src/cron/executor.js +2 -2
  235. package/dist/src/cron/persistence.js +1 -1
  236. package/dist/src/cron/run-log-store.js +1 -1
  237. package/dist/src/daemon/constants.js +1 -1
  238. package/dist/src/daemon/install-plan.js +3 -3
  239. package/dist/src/daemon/install-plan.js.map +1 -1
  240. package/dist/src/daemon/launchd.js +2 -2
  241. package/dist/src/daemon/schtasks.js +38 -1
  242. package/dist/src/daemon/schtasks.js.map +1 -1
  243. package/dist/src/daemon/systemd.js +2 -2
  244. package/dist/src/extensions/bundle-mcp.js +1 -1
  245. package/dist/src/extensions/discover-extensions.js +1 -1
  246. package/dist/src/extensions/health.js +1 -1
  247. package/dist/src/extensions/loader.js +1 -1
  248. package/dist/src/extensions/lockfile.js +2 -2
  249. package/dist/src/gateway/agents-admin.js +2 -2
  250. package/dist/src/gateway/file-path-classifier.js +2 -2
  251. package/dist/src/gateway/heartbeat/service.js +1 -1
  252. package/dist/src/gateway/hono/app.js +33 -2
  253. package/dist/src/gateway/hono/app.js.map +1 -1
  254. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  255. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  256. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  257. package/dist/src/gateway/hono/oauth.js +1 -1
  258. package/dist/src/gateway/hono/routes/agents.js +1 -1
  259. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  260. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  261. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  262. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  263. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  264. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  265. package/dist/src/gateway/hono/routes/models.js +1 -1
  266. package/dist/src/gateway/hono/routes/shares.js +631 -34
  267. package/dist/src/gateway/hono/routes/shares.js.map +1 -1
  268. package/dist/src/gateway/hono/routes/site-shares.d.ts +3 -0
  269. package/dist/src/gateway/hono/routes/site-shares.js +228 -0
  270. package/dist/src/gateway/hono/routes/site-shares.js.map +1 -0
  271. package/dist/src/gateway/hono/routes/tunnel.js +97 -8
  272. package/dist/src/gateway/hono/routes/tunnel.js.map +1 -1
  273. package/dist/src/gateway/hono/routes/workspace.js +5 -5
  274. package/dist/src/gateway/hono/sse.js +2 -2
  275. package/dist/src/gateway/host.d.ts +3 -1
  276. package/dist/src/gateway/host.js +3 -1
  277. package/dist/src/gateway/host.js.map +1 -1
  278. package/dist/src/gateway/lock.js +3 -3
  279. package/dist/src/gateway/ports.d.ts +6 -0
  280. package/dist/src/gateway/ports.js +38 -2
  281. package/dist/src/gateway/ports.js.map +1 -1
  282. package/dist/src/gateway/public-url.d.ts +8 -0
  283. package/dist/src/gateway/public-url.js +10 -0
  284. package/dist/src/gateway/public-url.js.map +1 -0
  285. package/dist/src/gateway/security/origin-check.d.ts +9 -1
  286. package/dist/src/gateway/security/origin-check.js +4 -0
  287. package/dist/src/gateway/security/origin-check.js.map +1 -1
  288. package/dist/src/gateway/server.js +15 -0
  289. package/dist/src/gateway/server.js.map +1 -1
  290. package/dist/src/gateway/service/agent-runner.js +2 -2
  291. package/dist/src/gateway/service/marketplace-service.js +2 -2
  292. package/dist/src/gateway/service/run-gateway-agent.js +2 -2
  293. package/dist/src/gateway/service.js +3 -2
  294. package/dist/src/gateway/service.js.map +1 -1
  295. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  296. package/dist/src/heartbeat/index.js +1 -1
  297. package/dist/src/i18n/goals-bundle.js +1 -1
  298. package/dist/src/i18n/index.d.ts +1 -0
  299. package/dist/src/i18n/index.js +2 -1
  300. package/dist/src/i18n/locales/share-tool.en.js +15 -0
  301. package/dist/src/i18n/locales/share-tool.en.js.map +1 -0
  302. package/dist/src/i18n/locales/share-tool.zh.js +15 -0
  303. package/dist/src/i18n/locales/share-tool.zh.js.map +1 -0
  304. package/dist/src/i18n/share-tool-bundle.d.ts +20 -0
  305. package/dist/src/i18n/share-tool-bundle.js +56 -0
  306. package/dist/src/i18n/share-tool-bundle.js.map +1 -0
  307. package/dist/src/infra/gateway-processes.js +1 -0
  308. package/dist/src/infra/gateway-processes.js.map +1 -1
  309. package/dist/src/infra/restart.js +2 -2
  310. package/dist/src/infra/update-check.js +1 -1
  311. package/dist/src/infra/update-lock.js +3 -3
  312. package/dist/src/infra/update-runner.js +1 -1
  313. package/dist/src/infra/update-startup.js +2 -2
  314. package/dist/src/infra/write-file-atomic.js +2 -2
  315. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  316. package/dist/src/providers/index.js +2 -2
  317. package/dist/src/providers/model-registry.js +1 -1
  318. package/dist/src/session/config-store.js +2 -2
  319. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  320. package/dist/src/session/parity/sessions-json-file.js +1 -1
  321. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  322. package/dist/src/session/parity/transcript-paths.js +1 -1
  323. package/dist/src/session/search-index-cache.js +1 -1
  324. package/dist/src/session/search-index.js +1 -1
  325. package/dist/src/session/session-title.js +3 -2
  326. package/dist/src/session/session-title.js.map +1 -1
  327. package/dist/src/session/store.js +5 -5
  328. package/dist/src/share/share-auto.d.ts +74 -0
  329. package/dist/src/share/share-auto.js +247 -0
  330. package/dist/src/share/share-auto.js.map +1 -0
  331. package/dist/src/share/share-config.js +63 -4
  332. package/dist/src/share/share-config.js.map +1 -1
  333. package/dist/src/share/share-landing.d.ts +28 -2
  334. package/dist/src/share/share-landing.js +155 -34
  335. package/dist/src/share/share-landing.js.map +1 -1
  336. package/dist/src/share/share-store.d.ts +48 -4
  337. package/dist/src/share/share-store.js +322 -51
  338. package/dist/src/share/share-store.js.map +1 -1
  339. package/dist/src/share/share-thumbnail.d.ts +35 -0
  340. package/dist/src/share/share-thumbnail.js +277 -0
  341. package/dist/src/share/share-thumbnail.js.map +1 -0
  342. package/dist/src/share/share-types.d.ts +68 -10
  343. package/dist/src/share/share-types.js +18 -1
  344. package/dist/src/share/share-types.js.map +1 -1
  345. package/dist/src/share/share-url.js +1 -1
  346. package/dist/src/share/share-zip.d.ts +35 -0
  347. package/dist/src/share/share-zip.js +303 -0
  348. package/dist/src/share/share-zip.js.map +1 -0
  349. package/dist/src/share/site-proxy.d.ts +35 -0
  350. package/dist/src/share/site-proxy.js +234 -0
  351. package/dist/src/share/site-proxy.js.map +1 -0
  352. package/dist/src/share/site-share-config.d.ts +11 -0
  353. package/dist/src/share/site-share-config.js +103 -0
  354. package/dist/src/share/site-share-config.js.map +1 -0
  355. package/dist/src/share/site-share-router.d.ts +23 -0
  356. package/dist/src/share/site-share-router.js +147 -0
  357. package/dist/src/share/site-share-router.js.map +1 -0
  358. package/dist/src/share/site-share-store.d.ts +53 -0
  359. package/dist/src/share/site-share-store.js +400 -0
  360. package/dist/src/share/site-share-store.js.map +1 -0
  361. package/dist/src/share/site-share-types.d.ts +103 -0
  362. package/dist/src/share/site-share-types.js +41 -0
  363. package/dist/src/share/site-share-types.js.map +1 -0
  364. package/dist/src/share/site-static-serve.d.ts +10 -0
  365. package/dist/src/share/site-static-serve.js +145 -0
  366. package/dist/src/share/site-static-serve.js.map +1 -0
  367. package/dist/src/tui/clipboard-image.js +3 -3
  368. package/dist/src/tui/theme-manager.js +1 -1
  369. package/dist/src/tui/tui-commands.js +18 -0
  370. package/dist/src/tui/tui-commands.js.map +1 -1
  371. package/dist/src/tui/tui-keybindings-file.js +1 -1
  372. package/dist/src/tui/tui-scoped-models.js +2 -2
  373. package/dist/src/tui/tui-settings.js +1 -1
  374. package/dist/src/tui/tui-workflow-slash.d.ts +32 -0
  375. package/dist/src/tui/tui-workflow-slash.js +63 -0
  376. package/dist/src/tui/tui-workflow-slash.js.map +1 -0
  377. package/dist/src/tui/tui.js +2 -2
  378. package/dist/src/tunnel/enable-lan-pairing.js +1 -1
  379. package/dist/src/tunnel/frpc-binary.js +3 -3
  380. package/dist/src/tunnel/frpc-config.js +1 -1
  381. package/dist/src/tunnel/frpc-extract.js +1 -1
  382. package/dist/src/tunnel/index.js +2 -2
  383. package/dist/src/tunnel/pair-context.d.ts +7 -1
  384. package/dist/src/tunnel/pair-context.js +25 -9
  385. package/dist/src/tunnel/pair-context.js.map +1 -1
  386. package/dist/src/tunnel/pair-url.d.ts +14 -1
  387. package/dist/src/tunnel/pair-url.js +14 -1
  388. package/dist/src/tunnel/pair-url.js.map +1 -1
  389. package/dist/src/tunnel/tunnel-service.js +2 -2
  390. package/dist/src/tunnel/tunnel-state.js +1 -1
  391. package/dist/src/utils/logger/audit.js +1 -1
  392. package/dist/src/utils/logger/log-store.js +1 -1
  393. package/dist/src/utils/logger/rotation.js +1 -1
  394. package/dist/src/voice/tts/audio.js +1 -1
  395. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  396. package/package.json +3 -2
  397. package/dist/gateway/static/root/assets/agents-tR-nNP04.js +0 -222
  398. package/dist/gateway/static/root/assets/apps-page-BDw6SP-d.js +0 -1
  399. package/dist/gateway/static/root/assets/button-KafIU8dx.js +0 -1
  400. package/dist/gateway/static/root/assets/channels-settings-DEFd-jj1.js +0 -1
  401. package/dist/gateway/static/root/assets/channels-status-swr-DI5FHdGe.js +0 -8
  402. package/dist/gateway/static/root/assets/cron-api-BSqY8LwW.js +0 -1
  403. package/dist/gateway/static/root/assets/cron-page-D7lVDjcR.js +0 -1
  404. package/dist/gateway/static/root/assets/dist-C57OMHW8.js +0 -48
  405. package/dist/gateway/static/root/assets/extension-page-CQo2Xsmg.js +0 -1
  406. package/dist/gateway/static/root/assets/extension-settings-page-CZf0WoZg.js +0 -1
  407. package/dist/gateway/static/root/assets/fetch-2iRFmd3n.js +0 -3
  408. package/dist/gateway/static/root/assets/heartbeat-config-api-B0drdQEJ.js +0 -1
  409. package/dist/gateway/static/root/assets/index-0Gt3TG4j.js +0 -4693
  410. package/dist/gateway/static/root/assets/index-BuFldCsB.css +0 -1
  411. package/dist/gateway/static/root/assets/logs-page-DMuORLfC.js +0 -1
  412. package/dist/gateway/static/root/assets/sessions-page-_UO8g6NN.js +0 -1
  413. package/dist/gateway/static/root/assets/settings-form-section-DkmHkknc.js +0 -1
  414. package/dist/gateway/static/root/assets/settings-page-Cz8FoW_A.js +0 -3
  415. package/dist/gateway/static/root/assets/skills-page-HrUOxF7H.js +0 -2
  416. package/dist/gateway/static/root/assets/theme-store-D01dJt95.js +0 -1
  417. package/dist/gateway/static/root/assets/utils-BFwcR6pL.js +0 -1
  418. package/dist/gateway/static/root/assets/voice-api-key-field-JF8-aqc5.js +0 -1
@@ -17,7 +17,24 @@ const SHARE_CONFIG_DEFAULTS = {
17
17
  "text/markdown",
18
18
  "text/plain",
19
19
  "application/json"
20
- ]
20
+ ],
21
+ directory: {
22
+ enabled: true,
23
+ maxFolderSize: 1073741824,
24
+ maxFileCount: 1e3,
25
+ maxDepth: 20,
26
+ listingCacheMs: 6e4,
27
+ zipConcurrency: 1
28
+ },
29
+ thumbnail: {
30
+ enabled: true,
31
+ concurrency: 2,
32
+ maxBytes: 262144,
33
+ viewportWidth: 1200,
34
+ viewportHeight: 630,
35
+ generationTimeoutMs: 8e3,
36
+ failureCooldownMs: 5 * 6e4
37
+ }
21
38
  };
22
39
  //#endregion
23
40
  export { SHARE_CONFIG_DEFAULTS };
@@ -1 +1 @@
1
- {"version":3,"file":"share-types.js","names":[],"sources":["../../../src/share/share-types.ts"],"sourcesContent":["export interface ShareRecord {\n /** Unique identifier (UUIDv4) for management. */\n id: string;\n /** Cryptographically secure URL token (base64url, 32 bytes). */\n token: string;\n /** Resolved absolute path at creation time. */\n absolutePath: string;\n /** Workspace-relative POSIX path (for display). */\n workspaceRelativePath: string;\n /** Workspace root at creation time (for download-time re-validation). */\n workspaceRoot: string;\n /** File inode at creation time (TOCTOU protection). */\n inode: number;\n /** Whether this share targets a directory. */\n isDirectory: boolean;\n /** Original file name (basename). */\n fileName: string;\n /** File size in bytes (snapshot at creation). */\n fileSize: number;\n /** MIME type. */\n mimeType: string;\n /** ISO creation timestamp. */\n createdAt: string;\n /** ISO expiration timestamp. */\n expiresAt: string;\n /** Maximum allowed views (null = unlimited). */\n maxViews: number | null;\n /** Current view count. */\n viewCount: number;\n /** Whether manually revoked. */\n revoked: boolean;\n /** Gateway token SHA-256 hash prefix (12 chars) of the creator. */\n createdByTokenHash: string;\n /** Optional human-readable description. */\n description?: string;\n}\n\nexport interface CreateShareParams {\n /** Workspace-relative file path. */\n path: string;\n /** Time-to-live in milliseconds (default: 24h). */\n ttlMs?: number;\n /** Maximum view count (null = unlimited). */\n maxViews?: number | null;\n /** Optional description shown on the landing page. */\n description?: string;\n /** Session key to resolve workspace root. */\n sessionKey?: string;\n /** Agent id to resolve workspace root. */\n agentId?: string;\n}\n\nexport interface ShareStoreData {\n version: 1;\n shares: ShareRecord[];\n}\n\nexport type ShareReachability = 'public' | 'lan' | 'local-only';\n\nexport interface ResolvedShareUrl {\n shareUrl: string;\n lanUrl: string | null;\n reachability: ShareReachability;\n reachabilityHint: string | null;\n}\n\nexport interface ShareConfig {\n enabled: boolean;\n defaultTtlMs: number;\n maxTtlMs: number;\n maxActiveShares: number;\n maxFileSize: number;\n inlinePreviewMimes: string[];\n}\n\n/** Default share configuration values. */\nexport const SHARE_CONFIG_DEFAULTS: ShareConfig = {\n enabled: true,\n defaultTtlMs: 86_400_000,\n maxTtlMs: 604_800_000,\n maxActiveShares: 100,\n maxFileSize: 104_857_600,\n inlinePreviewMimes: [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'application/pdf',\n 'text/html',\n 'text/markdown',\n 'text/plain',\n 'application/json',\n ],\n};\n"],"mappings":";;AA4EA,MAAa,wBAAqC;CAChD,SAAS;CACT,cAAc;CACd,UAAU;CACV,iBAAiB;CACjB,aAAa;CACb,oBAAoB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACF"}
1
+ {"version":3,"file":"share-types.js","names":[],"sources":["../../../src/share/share-types.ts"],"sourcesContent":["export type ShareKind = 'file' | 'directory';\n\nexport interface ShareDirectoryMeta {\n /** 'browse' shows a file tree; 'zip-only' hides structure and only offers ZIP. */\n mode: 'browse' | 'zip-only';\n /** Snapshot entry count at creation time (display + sanity guard). */\n entryCount: number;\n /** Whether the symlink filter at scan time was permissive. */\n followSymlinks: boolean;\n /** Maximum traversal depth (defense against recursive symlinks). */\n maxDepth: number;\n}\n\nexport interface ShareRecord {\n /** Unique identifier (UUIDv4) for management. */\n id: string;\n /** Cryptographically secure URL token (base64url, 32 bytes). */\n token: string;\n /** Resolved absolute path at creation time. */\n absolutePath: string;\n /** Workspace-relative POSIX path (for display). */\n workspaceRelativePath: string;\n /** Workspace root at creation time (for download-time re-validation). */\n workspaceRoot: string;\n /** File or directory inode at creation time (TOCTOU protection). */\n inode: number;\n /** Discriminator for downstream branching ('file' | 'directory'). */\n kind: ShareKind;\n /** Original file/folder name (basename). */\n fileName: string;\n /**\n * For files: file size in bytes (snapshot at creation).\n * For directories: sum of file sizes at scan time (display only).\n */\n fileSize: number;\n /** MIME type (directories: 'application/x-directory'). */\n mimeType: string;\n /** ISO creation timestamp. */\n createdAt: string;\n /** ISO expiration timestamp. */\n expiresAt: string;\n /** Maximum allowed downloads (null = unlimited). Counts file/zip/preview events. */\n maxViews: number | null;\n /** Download counter (file-bytes / zip-bytes / preview events). Landing-page renders never count. */\n downloadCount: number;\n /** Whether manually revoked. */\n revoked: boolean;\n /** Gateway token SHA-256 hash prefix (12 chars) of the creator. */\n createdByTokenHash: string;\n /** Optional human-readable description. */\n description?: string;\n /** Directory-only extra fields. */\n directory?: ShareDirectoryMeta;\n /** Thumbnail generation status (lazy + scheduled). */\n thumbnailStatus?: 'pending' | 'ready' | 'failed';\n /** ISO timestamp of the last successful thumbnail render. */\n thumbnailGeneratedAt?: string;\n /** ISO timestamp of the last failed attempt (used for cooldown). */\n thumbnailFailedAt?: string;\n}\n\nexport interface CreateShareParams {\n /** Workspace-relative file path. */\n path: string;\n /** Time-to-live in milliseconds (default: 24h). */\n ttlMs?: number;\n /** Maximum view/download count (null = unlimited). */\n maxViews?: number | null;\n /** Optional description shown on the landing page. */\n description?: string;\n /** Session key to resolve workspace root. */\n sessionKey?: string;\n /** Agent id to resolve workspace root. */\n agentId?: string;\n /** Force directory share semantics (overrides auto-detection). */\n kind?: ShareKind;\n /** Directory: browse vs zip-only. Defaults to 'browse'. */\n directoryMode?: 'browse' | 'zip-only';\n /** Directory: cap on entry count at scan time. */\n maxFileCount?: number;\n /** Directory: cap on total folder size in bytes. */\n maxFolderSize?: number;\n /** Directory: whether to follow symlinks (subject to workspace boundary). */\n followSymlinks?: boolean;\n /** Directory: walk depth cap (default 20). */\n maxDepth?: number;\n}\n\nexport interface ShareStoreData {\n version: 1;\n shares: ShareRecord[];\n}\n\nexport type ShareReachability = 'public' | 'lan' | 'local-only';\n\nexport interface ResolvedShareUrl {\n shareUrl: string;\n lanUrl: string | null;\n reachability: ShareReachability;\n reachabilityHint: string | null;\n}\n\nexport interface ShareDirectoryConfig {\n enabled: boolean;\n maxFolderSize: number;\n maxFileCount: number;\n maxDepth: number;\n listingCacheMs: number;\n zipConcurrency: number;\n}\n\nexport interface ShareThumbnailConfig {\n enabled: boolean;\n concurrency: number;\n /** Hard cap on emitted jpeg bytes. */\n maxBytes: number;\n viewportWidth: number;\n viewportHeight: number;\n /** Per-render timeout (Playwright navigation + screenshot). */\n generationTimeoutMs: number;\n /** Cooldown before a failed token is retried. */\n failureCooldownMs: number;\n /** Optional override for the loopback URL used by the headless renderer. */\n internalGatewayUrl?: string;\n}\n\nexport interface ShareConfig {\n enabled: boolean;\n defaultTtlMs: number;\n maxTtlMs: number;\n maxActiveShares: number;\n maxFileSize: number;\n inlinePreviewMimes: string[];\n directory: ShareDirectoryConfig;\n thumbnail: ShareThumbnailConfig;\n}\n\n/** Default share configuration values. */\nexport const SHARE_CONFIG_DEFAULTS: ShareConfig = {\n enabled: true,\n defaultTtlMs: 86_400_000,\n maxTtlMs: 604_800_000,\n maxActiveShares: 100,\n maxFileSize: 104_857_600,\n inlinePreviewMimes: [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'application/pdf',\n 'text/html',\n 'text/markdown',\n 'text/plain',\n 'application/json',\n ],\n directory: {\n enabled: true,\n maxFolderSize: 1_073_741_824, // 1 GB\n maxFileCount: 1000,\n maxDepth: 20,\n listingCacheMs: 60_000,\n zipConcurrency: 1,\n },\n thumbnail: {\n enabled: true,\n concurrency: 2,\n maxBytes: 262_144, // 256 KB after re-encode\n viewportWidth: 1200,\n viewportHeight: 630,\n generationTimeoutMs: 8_000,\n failureCooldownMs: 5 * 60_000,\n },\n};\n"],"mappings":";;AA0IA,MAAa,wBAAqC;CAChD,SAAS;CACT,cAAc;CACd,UAAU;CACV,iBAAiB;CACjB,aAAa;CACb,oBAAoB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,WAAW;EACT,SAAS;EACT,eAAe;EACf,cAAc;EACd,UAAU;EACV,gBAAgB;EAChB,gBAAgB;EACjB;CACD,WAAW;EACT,SAAS;EACT,aAAa;EACb,UAAU;EACV,eAAe;EACf,gBAAgB;EAChB,qBAAqB;EACrB,mBAAmB,IAAI;EACxB;CACF"}
@@ -1,5 +1,5 @@
1
- import { resolveLanGatewayUrl } from "../tunnel/tunnel-qr.js";
2
1
  import { loadTunnelState } from "../tunnel/tunnel-state.js";
2
+ import { resolveLanGatewayUrl } from "../tunnel/tunnel-qr.js";
3
3
  //#region src/share/share-url.ts
4
4
  function resolveShareUrl(token, ctx) {
5
5
  const tunnelState = loadTunnelState();
@@ -0,0 +1,35 @@
1
+ import { Readable } from 'node:stream';
2
+ import type { ShareRecord } from './share-types.js';
3
+ export interface ZipPlanFile {
4
+ /** Path within the archive (POSIX, no leading /, may contain subdirs). */
5
+ zipPath: string;
6
+ /** Absolute filesystem path of the source file. */
7
+ absolutePath: string;
8
+ /** Modification time used for the entry header. */
9
+ mtimeMs: number;
10
+ /** File size in bytes. */
11
+ size: number;
12
+ }
13
+ export interface ZipBuildOptions {
14
+ files: ZipPlanFile[];
15
+ /** Whether to deflate a given entry. Defaults to a sensible heuristic. */
16
+ compress?: (f: ZipPlanFile) => boolean;
17
+ }
18
+ /**
19
+ * Build a streaming ZIP archive as a Node Readable. Files that fail to read
20
+ * are skipped and listed in a synthetic `_xopc_errors.txt` trailer entry.
21
+ */
22
+ export declare function createZipStream(opts: ZipBuildOptions): Readable;
23
+ export interface PlanDirectoryOpts {
24
+ /** Sub-path inside the share to start from ('' for whole share). */
25
+ rootRelativePath: string;
26
+ /** Maximum entries returned. */
27
+ maxFileCount: number;
28
+ /** Maximum aggregate file size. */
29
+ maxFolderSize: number;
30
+ /** Whether symlinks are followed (and re-validated against workspace). */
31
+ followSymlinks: boolean;
32
+ /** Walk depth cap. */
33
+ maxDepth: number;
34
+ }
35
+ export declare function planDirectoryFiles(record: ShareRecord, opts: PlanDirectoryOpts): Promise<ZipPlanFile[]>;
@@ -0,0 +1,303 @@
1
+ import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
2
+ import { relative, resolve } from "node:path";
3
+ import { createReadStream } from "node:fs";
4
+ import { lstat, readdir, realpath, stat } from "node:fs/promises";
5
+ import { Readable, Transform } from "node:stream";
6
+ import { pipeline } from "node:stream/promises";
7
+ import { crc32, createDeflateRaw } from "node:zlib";
8
+ //#region src/share/share-zip.ts
9
+ const SIG_LOCAL = 67324752;
10
+ const SIG_CENTRAL = 33639248;
11
+ const SIG_EOCD = 101010256;
12
+ const SIG_EOCD64 = 101075792;
13
+ const SIG_EOCD64_LOCATOR = 117853008;
14
+ const SIG_DATA_DESCRIPTOR = 134695760;
15
+ const ZIP64_THRESHOLD = 4294967295;
16
+ const COUNT_ZIP64_THRESHOLD = 65535;
17
+ const FLAG_USE_DATA_DESCRIPTOR = 8;
18
+ const FLAG_UTF8 = 2048;
19
+ const METHOD_STORE = 0;
20
+ const METHOD_DEFLATE = 8;
21
+ function dosTime(d) {
22
+ return d.getHours() << 11 | d.getMinutes() << 5 | Math.floor(d.getSeconds() / 2);
23
+ }
24
+ function dosDate(d) {
25
+ return d.getFullYear() - 1980 << 9 | d.getMonth() + 1 << 5 | d.getDate();
26
+ }
27
+ function localFileHeader(name, mtimeDate, method) {
28
+ const buf = Buffer.alloc(30 + name.length);
29
+ buf.writeUInt32LE(SIG_LOCAL, 0);
30
+ buf.writeUInt16LE(45, 4);
31
+ buf.writeUInt16LE(FLAG_USE_DATA_DESCRIPTOR | FLAG_UTF8, 6);
32
+ buf.writeUInt16LE(method, 8);
33
+ buf.writeUInt16LE(dosTime(mtimeDate), 10);
34
+ buf.writeUInt16LE(dosDate(mtimeDate), 12);
35
+ buf.writeUInt32LE(0, 14);
36
+ buf.writeUInt32LE(0, 18);
37
+ buf.writeUInt32LE(0, 22);
38
+ buf.writeUInt16LE(name.length, 26);
39
+ buf.writeUInt16LE(0, 28);
40
+ name.copy(buf, 30);
41
+ return buf;
42
+ }
43
+ function dataDescriptor(crc, compressed, uncompressed) {
44
+ if (compressed > ZIP64_THRESHOLD || uncompressed > ZIP64_THRESHOLD) {
45
+ const buf = Buffer.alloc(24);
46
+ buf.writeUInt32LE(SIG_DATA_DESCRIPTOR, 0);
47
+ buf.writeUInt32LE(crc >>> 0, 4);
48
+ buf.writeBigUInt64LE(BigInt(compressed), 8);
49
+ buf.writeBigUInt64LE(BigInt(uncompressed), 16);
50
+ return buf;
51
+ }
52
+ const buf = Buffer.alloc(16);
53
+ buf.writeUInt32LE(SIG_DATA_DESCRIPTOR, 0);
54
+ buf.writeUInt32LE(crc >>> 0, 4);
55
+ buf.writeUInt32LE(compressed >>> 0, 8);
56
+ buf.writeUInt32LE(uncompressed >>> 0, 12);
57
+ return buf;
58
+ }
59
+ function buildZip64Extra(entry) {
60
+ const fields = [];
61
+ const needUncompressed = entry.uncompressedSize > ZIP64_THRESHOLD;
62
+ const needCompressed = entry.compressedSize > ZIP64_THRESHOLD;
63
+ const needOffset = entry.offset > ZIP64_THRESHOLD;
64
+ if (needUncompressed) fields.push(BigInt(entry.uncompressedSize));
65
+ if (needCompressed) fields.push(BigInt(entry.compressedSize));
66
+ if (needOffset) fields.push(BigInt(entry.offset));
67
+ const buf = Buffer.alloc(4 + fields.length * 8);
68
+ buf.writeUInt16LE(1, 0);
69
+ buf.writeUInt16LE(fields.length * 8, 2);
70
+ for (let i = 0; i < fields.length; i++) buf.writeBigUInt64LE(fields[i], 4 + i * 8);
71
+ return buf;
72
+ }
73
+ function centralHeader(entry) {
74
+ const extra = entry.compressedSize > ZIP64_THRESHOLD || entry.uncompressedSize > ZIP64_THRESHOLD || entry.offset > ZIP64_THRESHOLD ? buildZip64Extra(entry) : Buffer.alloc(0);
75
+ const date = new Date(entry.mtime);
76
+ const buf = Buffer.alloc(46 + entry.name.length + extra.length);
77
+ buf.writeUInt32LE(SIG_CENTRAL, 0);
78
+ buf.writeUInt16LE(45, 4);
79
+ buf.writeUInt16LE(45, 6);
80
+ buf.writeUInt16LE(FLAG_USE_DATA_DESCRIPTOR | FLAG_UTF8, 8);
81
+ buf.writeUInt16LE(entry.method, 10);
82
+ buf.writeUInt16LE(dosTime(date), 12);
83
+ buf.writeUInt16LE(dosDate(date), 14);
84
+ buf.writeUInt32LE(entry.crc32 >>> 0, 16);
85
+ buf.writeUInt32LE(Math.min(entry.compressedSize, 4294967295) >>> 0, 20);
86
+ buf.writeUInt32LE(Math.min(entry.uncompressedSize, 4294967295) >>> 0, 24);
87
+ buf.writeUInt16LE(entry.name.length, 28);
88
+ buf.writeUInt16LE(extra.length, 30);
89
+ buf.writeUInt16LE(0, 32);
90
+ buf.writeUInt16LE(0, 34);
91
+ buf.writeUInt16LE(0, 36);
92
+ buf.writeUInt32LE(0, 38);
93
+ buf.writeUInt32LE(Math.min(entry.offset, 4294967295) >>> 0, 42);
94
+ entry.name.copy(buf, 46);
95
+ extra.copy(buf, 46 + entry.name.length);
96
+ return buf;
97
+ }
98
+ function endOfCentralDir(totalEntries, cdSize, cdOffset, needsZip64) {
99
+ const parts = [];
100
+ if (needsZip64) {
101
+ const eocd64 = Buffer.alloc(56);
102
+ eocd64.writeUInt32LE(SIG_EOCD64, 0);
103
+ eocd64.writeBigUInt64LE(BigInt(44), 4);
104
+ eocd64.writeUInt16LE(45, 12);
105
+ eocd64.writeUInt16LE(45, 14);
106
+ eocd64.writeUInt32LE(0, 16);
107
+ eocd64.writeUInt32LE(0, 20);
108
+ eocd64.writeBigUInt64LE(BigInt(totalEntries), 24);
109
+ eocd64.writeBigUInt64LE(BigInt(totalEntries), 32);
110
+ eocd64.writeBigUInt64LE(BigInt(cdSize), 40);
111
+ eocd64.writeBigUInt64LE(BigInt(cdOffset), 48);
112
+ parts.push(eocd64);
113
+ const locator = Buffer.alloc(20);
114
+ locator.writeUInt32LE(SIG_EOCD64_LOCATOR, 0);
115
+ locator.writeUInt32LE(0, 4);
116
+ locator.writeBigUInt64LE(BigInt(cdOffset + cdSize), 8);
117
+ locator.writeUInt32LE(1, 16);
118
+ parts.push(locator);
119
+ }
120
+ const eocd = Buffer.alloc(22);
121
+ eocd.writeUInt32LE(SIG_EOCD, 0);
122
+ eocd.writeUInt16LE(0, 4);
123
+ eocd.writeUInt16LE(0, 6);
124
+ eocd.writeUInt16LE(Math.min(totalEntries, 65535), 8);
125
+ eocd.writeUInt16LE(Math.min(totalEntries, 65535), 10);
126
+ eocd.writeUInt32LE(Math.min(cdSize, 4294967295) >>> 0, 12);
127
+ eocd.writeUInt32LE(Math.min(cdOffset, 4294967295) >>> 0, 16);
128
+ eocd.writeUInt16LE(0, 20);
129
+ parts.push(eocd);
130
+ return Buffer.concat(parts);
131
+ }
132
+ const NO_COMPRESS_EXT = new Set([
133
+ "zip",
134
+ "gz",
135
+ "bz2",
136
+ "xz",
137
+ "rar",
138
+ "7z",
139
+ "png",
140
+ "jpg",
141
+ "jpeg",
142
+ "gif",
143
+ "webp",
144
+ "avif",
145
+ "heic",
146
+ "mp3",
147
+ "mp4",
148
+ "mkv",
149
+ "mov",
150
+ "webm",
151
+ "ogg",
152
+ "opus",
153
+ "pdf"
154
+ ]);
155
+ function defaultShouldCompress(f) {
156
+ const ext = f.zipPath.split(".").pop()?.toLowerCase() ?? "";
157
+ if (NO_COMPRESS_EXT.has(ext)) return false;
158
+ if (f.size > 32 * 1024 * 1024) return false;
159
+ return true;
160
+ }
161
+ /**
162
+ * Build a streaming ZIP archive as a Node Readable. Files that fail to read
163
+ * are skipped and listed in a synthetic `_xopc_errors.txt` trailer entry.
164
+ */
165
+ function createZipStream(opts) {
166
+ const errors = [];
167
+ const central = [];
168
+ const compress = opts.compress ?? defaultShouldCompress;
169
+ const stream = new Readable({ read() {} });
170
+ let position = 0;
171
+ function pushBuf(buf) {
172
+ position += buf.length;
173
+ stream.push(buf);
174
+ }
175
+ async function emitEntry(file) {
176
+ const nameBuf = Buffer.from(file.zipPath, "utf8");
177
+ const method = compress(file) ? METHOD_DEFLATE : METHOD_STORE;
178
+ const offset = position;
179
+ const mtime = file.mtimeMs > 0 ? file.mtimeMs : Date.now();
180
+ pushBuf(localFileHeader(nameBuf, new Date(mtime), method));
181
+ let uncompressed = 0;
182
+ let compressed = 0;
183
+ let crc = 0;
184
+ const source = createReadStream(file.absolutePath);
185
+ const counter = new Transform({ transform(chunk, _enc, cb) {
186
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
187
+ uncompressed += buf.length;
188
+ crc = crc32(buf, crc);
189
+ cb(null, buf);
190
+ } });
191
+ const sink = new Transform({ transform(chunk, _enc, cb) {
192
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
193
+ compressed += buf.length;
194
+ pushBuf(buf);
195
+ cb();
196
+ } });
197
+ if (method === METHOD_DEFLATE) await pipeline(source, counter, createDeflateRaw({ level: 6 }), sink);
198
+ else await pipeline(source, counter, sink);
199
+ pushBuf(dataDescriptor(crc, compressed, uncompressed));
200
+ central.push({
201
+ name: nameBuf,
202
+ mtime,
203
+ crc32: crc,
204
+ compressedSize: compressed,
205
+ uncompressedSize: uncompressed,
206
+ offset,
207
+ method
208
+ });
209
+ }
210
+ async function emitSyntheticTextEntry(zipPath, content) {
211
+ const nameBuf = Buffer.from(zipPath, "utf8");
212
+ const offset = position;
213
+ const mtime = Date.now();
214
+ pushBuf(localFileHeader(nameBuf, new Date(mtime), METHOD_STORE));
215
+ const buf = Buffer.from(content, "utf8");
216
+ const crc = crc32(buf, 0);
217
+ pushBuf(buf);
218
+ pushBuf(dataDescriptor(crc, buf.length, buf.length));
219
+ central.push({
220
+ name: nameBuf,
221
+ mtime,
222
+ crc32: crc,
223
+ compressedSize: buf.length,
224
+ uncompressedSize: buf.length,
225
+ offset,
226
+ method: METHOD_STORE
227
+ });
228
+ }
229
+ (async () => {
230
+ try {
231
+ for (const file of opts.files) try {
232
+ await emitEntry(file);
233
+ } catch (err) {
234
+ const msg = err instanceof Error ? err.message : String(err);
235
+ errors.push(`${file.zipPath}: ${msg}`);
236
+ }
237
+ if (errors.length > 0) await emitSyntheticTextEntry("_xopc_errors.txt", errors.join("\n"));
238
+ const cdOffset = position;
239
+ let needsZip64 = central.length > COUNT_ZIP64_THRESHOLD;
240
+ for (const entry of central) {
241
+ if (entry.compressedSize > ZIP64_THRESHOLD || entry.uncompressedSize > ZIP64_THRESHOLD || entry.offset > ZIP64_THRESHOLD) needsZip64 = true;
242
+ pushBuf(centralHeader(entry));
243
+ }
244
+ const cdSize = position - cdOffset;
245
+ pushBuf(endOfCentralDir(central.length, cdSize, cdOffset, needsZip64));
246
+ stream.push(null);
247
+ } catch (err) {
248
+ stream.destroy(err instanceof Error ? err : new Error(String(err)));
249
+ }
250
+ })();
251
+ return stream;
252
+ }
253
+ async function planDirectoryFiles(record, opts) {
254
+ if (record.kind !== "directory") return [];
255
+ const rootAbs = resolve(record.absolutePath, opts.rootRelativePath);
256
+ const files = [];
257
+ let totalSize = 0;
258
+ async function walk(dir, depth) {
259
+ if (depth > opts.maxDepth) return;
260
+ if (files.length >= opts.maxFileCount) return;
261
+ const dirents = await readdir(dir, { withFileTypes: true });
262
+ for (const dirent of dirents) {
263
+ if (files.length >= opts.maxFileCount) return;
264
+ const abs = resolve(dir, dirent.name);
265
+ const childLstat = await lstat(abs);
266
+ let stats = childLstat;
267
+ if (childLstat.isSymbolicLink()) {
268
+ if (!opts.followSymlinks) continue;
269
+ const real = await realpath(abs);
270
+ if (!isPathUnderWorkspace(record.workspaceRoot, real)) continue;
271
+ if (relative(record.absolutePath, real).startsWith("..")) continue;
272
+ stats = await stat(abs);
273
+ }
274
+ if (stats.isFile()) {
275
+ totalSize += stats.size;
276
+ if (totalSize > opts.maxFolderSize) throw new Error("zip exceeds maxFolderSize");
277
+ const zipRel = relative(rootAbs, abs).split(/[\\/]/).join("/");
278
+ files.push({
279
+ zipPath: zipRel,
280
+ absolutePath: abs,
281
+ mtimeMs: stats.mtimeMs,
282
+ size: stats.size
283
+ });
284
+ } else if (stats.isDirectory()) await walk(abs, depth + 1);
285
+ }
286
+ }
287
+ const rootLstat = await lstat(rootAbs);
288
+ if (rootLstat.isDirectory()) await walk(rootAbs, 0);
289
+ else if (rootLstat.isFile()) {
290
+ const rootStat = await stat(rootAbs);
291
+ files.push({
292
+ zipPath: relative(record.absolutePath, rootAbs).split(/[\\/]/).join("/"),
293
+ absolutePath: rootAbs,
294
+ mtimeMs: rootStat.mtimeMs,
295
+ size: rootStat.size
296
+ });
297
+ }
298
+ return files;
299
+ }
300
+ //#endregion
301
+ export { createZipStream, planDirectoryFiles };
302
+
303
+ //# sourceMappingURL=share-zip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share-zip.js","names":["pipelineAsync","resolvePath","relPathPosix"],"sources":["../../../src/share/share-zip.ts"],"sourcesContent":["import { createReadStream } from 'node:fs';\nimport { stat, readdir, lstat, realpath } from 'node:fs/promises';\nimport { resolve as resolvePath, relative as relPathPosix } from 'node:path';\nimport { Readable, Transform } from 'node:stream';\nimport { pipeline as pipelineAsync } from 'node:stream/promises';\nimport { createDeflateRaw, crc32 } from 'node:zlib';\n\nimport { isPathUnderWorkspace } from '../gateway/workspace-editor-path.js';\nimport type { ShareRecord } from './share-types.js';\n\n// ── Minimal streaming ZIP encoder (ZIP64-aware) ───────────────────────────────\n//\n// Reference: PKWARE APPNOTE 6.3 §4 and §4.5 (ZIP64 extra field).\n// Uses local headers with `FLAG_USE_DATA_DESCRIPTOR` so we can stream entries\n// without seeking back to patch sizes once the file is fully read.\n\nconst SIG_LOCAL = 0x04034b50;\nconst SIG_CENTRAL = 0x02014b50;\nconst SIG_EOCD = 0x06054b50;\nconst SIG_EOCD64 = 0x06064b50;\nconst SIG_EOCD64_LOCATOR = 0x07064b50;\nconst SIG_DATA_DESCRIPTOR = 0x08074b50;\nconst ZIP64_THRESHOLD = 0xffffffff;\nconst COUNT_ZIP64_THRESHOLD = 0xffff;\n\nconst FLAG_USE_DATA_DESCRIPTOR = 0x0008;\nconst FLAG_UTF8 = 0x0800;\nconst METHOD_STORE = 0;\nconst METHOD_DEFLATE = 8;\n\ninterface CentralEntry {\n name: Buffer;\n mtime: number;\n crc32: number;\n compressedSize: number;\n uncompressedSize: number;\n offset: number;\n method: number;\n}\n\nfunction dosTime(d: Date): number {\n return (d.getHours() << 11) | (d.getMinutes() << 5) | Math.floor(d.getSeconds() / 2);\n}\n\nfunction dosDate(d: Date): number {\n return ((d.getFullYear() - 1980) << 9) | ((d.getMonth() + 1) << 5) | d.getDate();\n}\n\nfunction localFileHeader(name: Buffer, mtimeDate: Date, method: number): Buffer {\n const buf = Buffer.alloc(30 + name.length);\n buf.writeUInt32LE(SIG_LOCAL, 0);\n buf.writeUInt16LE(45, 4); // version needed (4.5 for ZIP64)\n buf.writeUInt16LE(FLAG_USE_DATA_DESCRIPTOR | FLAG_UTF8, 6);\n buf.writeUInt16LE(method, 8);\n buf.writeUInt16LE(dosTime(mtimeDate), 10);\n buf.writeUInt16LE(dosDate(mtimeDate), 12);\n buf.writeUInt32LE(0, 14); // crc — filled in via data descriptor\n buf.writeUInt32LE(0, 18); // compressed size — filled in via data descriptor\n buf.writeUInt32LE(0, 22); // uncompressed size — filled in via data descriptor\n buf.writeUInt16LE(name.length, 26);\n buf.writeUInt16LE(0, 28);\n name.copy(buf, 30);\n return buf;\n}\n\nfunction dataDescriptor(crc: number, compressed: number, uncompressed: number): Buffer {\n const needsZip64 = compressed > ZIP64_THRESHOLD || uncompressed > ZIP64_THRESHOLD;\n if (needsZip64) {\n const buf = Buffer.alloc(24);\n buf.writeUInt32LE(SIG_DATA_DESCRIPTOR, 0);\n buf.writeUInt32LE(crc >>> 0, 4);\n buf.writeBigUInt64LE(BigInt(compressed), 8);\n buf.writeBigUInt64LE(BigInt(uncompressed), 16);\n return buf;\n }\n const buf = Buffer.alloc(16);\n buf.writeUInt32LE(SIG_DATA_DESCRIPTOR, 0);\n buf.writeUInt32LE(crc >>> 0, 4);\n buf.writeUInt32LE(compressed >>> 0, 8);\n buf.writeUInt32LE(uncompressed >>> 0, 12);\n return buf;\n}\n\nfunction buildZip64Extra(entry: CentralEntry): Buffer {\n const fields: bigint[] = [];\n const needUncompressed = entry.uncompressedSize > ZIP64_THRESHOLD;\n const needCompressed = entry.compressedSize > ZIP64_THRESHOLD;\n const needOffset = entry.offset > ZIP64_THRESHOLD;\n if (needUncompressed) fields.push(BigInt(entry.uncompressedSize));\n if (needCompressed) fields.push(BigInt(entry.compressedSize));\n if (needOffset) fields.push(BigInt(entry.offset));\n const buf = Buffer.alloc(4 + fields.length * 8);\n buf.writeUInt16LE(0x0001, 0);\n buf.writeUInt16LE(fields.length * 8, 2);\n for (let i = 0; i < fields.length; i++) buf.writeBigUInt64LE(fields[i], 4 + i * 8);\n return buf;\n}\n\nfunction centralHeader(entry: CentralEntry): Buffer {\n const needsZip64 =\n entry.compressedSize > ZIP64_THRESHOLD ||\n entry.uncompressedSize > ZIP64_THRESHOLD ||\n entry.offset > ZIP64_THRESHOLD;\n\n const extra = needsZip64 ? buildZip64Extra(entry) : Buffer.alloc(0);\n const date = new Date(entry.mtime);\n const buf = Buffer.alloc(46 + entry.name.length + extra.length);\n buf.writeUInt32LE(SIG_CENTRAL, 0);\n buf.writeUInt16LE(45, 4);\n buf.writeUInt16LE(45, 6);\n buf.writeUInt16LE(FLAG_USE_DATA_DESCRIPTOR | FLAG_UTF8, 8);\n buf.writeUInt16LE(entry.method, 10);\n buf.writeUInt16LE(dosTime(date), 12);\n buf.writeUInt16LE(dosDate(date), 14);\n buf.writeUInt32LE(entry.crc32 >>> 0, 16);\n buf.writeUInt32LE(Math.min(entry.compressedSize, 0xffffffff) >>> 0, 20);\n buf.writeUInt32LE(Math.min(entry.uncompressedSize, 0xffffffff) >>> 0, 24);\n buf.writeUInt16LE(entry.name.length, 28);\n buf.writeUInt16LE(extra.length, 30);\n buf.writeUInt16LE(0, 32);\n buf.writeUInt16LE(0, 34);\n buf.writeUInt16LE(0, 36);\n buf.writeUInt32LE(0, 38);\n buf.writeUInt32LE(Math.min(entry.offset, 0xffffffff) >>> 0, 42);\n entry.name.copy(buf, 46);\n extra.copy(buf, 46 + entry.name.length);\n return buf;\n}\n\nfunction endOfCentralDir(\n totalEntries: number,\n cdSize: number,\n cdOffset: number,\n needsZip64: boolean,\n): Buffer {\n const parts: Buffer[] = [];\n\n if (needsZip64) {\n const eocd64 = Buffer.alloc(56);\n eocd64.writeUInt32LE(SIG_EOCD64, 0);\n eocd64.writeBigUInt64LE(BigInt(44), 4);\n eocd64.writeUInt16LE(45, 12);\n eocd64.writeUInt16LE(45, 14);\n eocd64.writeUInt32LE(0, 16);\n eocd64.writeUInt32LE(0, 20);\n eocd64.writeBigUInt64LE(BigInt(totalEntries), 24);\n eocd64.writeBigUInt64LE(BigInt(totalEntries), 32);\n eocd64.writeBigUInt64LE(BigInt(cdSize), 40);\n eocd64.writeBigUInt64LE(BigInt(cdOffset), 48);\n parts.push(eocd64);\n\n const locator = Buffer.alloc(20);\n locator.writeUInt32LE(SIG_EOCD64_LOCATOR, 0);\n locator.writeUInt32LE(0, 4);\n locator.writeBigUInt64LE(BigInt(cdOffset + cdSize), 8);\n locator.writeUInt32LE(1, 16);\n parts.push(locator);\n }\n\n const eocd = Buffer.alloc(22);\n eocd.writeUInt32LE(SIG_EOCD, 0);\n eocd.writeUInt16LE(0, 4);\n eocd.writeUInt16LE(0, 6);\n eocd.writeUInt16LE(Math.min(totalEntries, 0xffff), 8);\n eocd.writeUInt16LE(Math.min(totalEntries, 0xffff), 10);\n eocd.writeUInt32LE(Math.min(cdSize, 0xffffffff) >>> 0, 12);\n eocd.writeUInt32LE(Math.min(cdOffset, 0xffffffff) >>> 0, 16);\n eocd.writeUInt16LE(0, 20);\n parts.push(eocd);\n\n return Buffer.concat(parts);\n}\n\nexport interface ZipPlanFile {\n /** Path within the archive (POSIX, no leading /, may contain subdirs). */\n zipPath: string;\n /** Absolute filesystem path of the source file. */\n absolutePath: string;\n /** Modification time used for the entry header. */\n mtimeMs: number;\n /** File size in bytes. */\n size: number;\n}\n\nexport interface ZipBuildOptions {\n files: ZipPlanFile[];\n /** Whether to deflate a given entry. Defaults to a sensible heuristic. */\n compress?: (f: ZipPlanFile) => boolean;\n}\n\nconst NO_COMPRESS_EXT = new Set([\n 'zip', 'gz', 'bz2', 'xz', 'rar', '7z',\n 'png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'heic',\n 'mp3', 'mp4', 'mkv', 'mov', 'webm', 'ogg', 'opus',\n 'pdf',\n]);\n\nfunction defaultShouldCompress(f: ZipPlanFile): boolean {\n const ext = f.zipPath.split('.').pop()?.toLowerCase() ?? '';\n if (NO_COMPRESS_EXT.has(ext)) return false;\n if (f.size > 32 * 1024 * 1024) return false;\n return true;\n}\n\n/**\n * Build a streaming ZIP archive as a Node Readable. Files that fail to read\n * are skipped and listed in a synthetic `_xopc_errors.txt` trailer entry.\n */\nexport function createZipStream(opts: ZipBuildOptions): Readable {\n const errors: string[] = [];\n const central: CentralEntry[] = [];\n const compress = opts.compress ?? defaultShouldCompress;\n const stream = new Readable({ read() {} });\n let position = 0;\n\n function pushBuf(buf: Buffer): void {\n position += buf.length;\n stream.push(buf);\n }\n\n async function emitEntry(file: ZipPlanFile): Promise<void> {\n const nameBuf = Buffer.from(file.zipPath, 'utf8');\n const method = compress(file) ? METHOD_DEFLATE : METHOD_STORE;\n const offset = position;\n const mtime = file.mtimeMs > 0 ? file.mtimeMs : Date.now();\n pushBuf(localFileHeader(nameBuf, new Date(mtime), method));\n\n let uncompressed = 0;\n let compressed = 0;\n let crc = 0;\n\n const source = createReadStream(file.absolutePath);\n\n const counter = new Transform({\n transform(chunk: Buffer, _enc, cb) {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as unknown as ArrayBufferLike);\n uncompressed += buf.length;\n crc = crc32(buf, crc);\n cb(null, buf);\n },\n });\n\n const sink = new Transform({\n transform(chunk: Buffer, _enc, cb) {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as unknown as ArrayBufferLike);\n compressed += buf.length;\n pushBuf(buf);\n cb();\n },\n });\n\n if (method === METHOD_DEFLATE) {\n await pipelineAsync(source, counter, createDeflateRaw({ level: 6 }), sink);\n } else {\n await pipelineAsync(source, counter, sink);\n }\n\n pushBuf(dataDescriptor(crc, compressed, uncompressed));\n central.push({\n name: nameBuf,\n mtime,\n crc32: crc,\n compressedSize: compressed,\n uncompressedSize: uncompressed,\n offset,\n method,\n });\n }\n\n async function emitSyntheticTextEntry(zipPath: string, content: string): Promise<void> {\n const nameBuf = Buffer.from(zipPath, 'utf8');\n const offset = position;\n const mtime = Date.now();\n pushBuf(localFileHeader(nameBuf, new Date(mtime), METHOD_STORE));\n const buf = Buffer.from(content, 'utf8');\n const crc = crc32(buf, 0);\n pushBuf(buf);\n pushBuf(dataDescriptor(crc, buf.length, buf.length));\n central.push({\n name: nameBuf,\n mtime,\n crc32: crc,\n compressedSize: buf.length,\n uncompressedSize: buf.length,\n offset,\n method: METHOD_STORE,\n });\n }\n\n (async () => {\n try {\n for (const file of opts.files) {\n try {\n await emitEntry(file);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push(`${file.zipPath}: ${msg}`);\n }\n }\n if (errors.length > 0) {\n await emitSyntheticTextEntry('_xopc_errors.txt', errors.join('\\n'));\n }\n\n const cdOffset = position;\n let needsZip64 = central.length > COUNT_ZIP64_THRESHOLD;\n for (const entry of central) {\n if (\n entry.compressedSize > ZIP64_THRESHOLD ||\n entry.uncompressedSize > ZIP64_THRESHOLD ||\n entry.offset > ZIP64_THRESHOLD\n ) {\n needsZip64 = true;\n }\n pushBuf(centralHeader(entry));\n }\n const cdSize = position - cdOffset;\n pushBuf(endOfCentralDir(central.length, cdSize, cdOffset, needsZip64));\n stream.push(null);\n } catch (err) {\n stream.destroy(err instanceof Error ? err : new Error(String(err)));\n }\n })();\n\n return stream;\n}\n\n// ── Planner: walk a directory share into a flat ZipPlanFile list ─────────────\n\nexport interface PlanDirectoryOpts {\n /** Sub-path inside the share to start from ('' for whole share). */\n rootRelativePath: string;\n /** Maximum entries returned. */\n maxFileCount: number;\n /** Maximum aggregate file size. */\n maxFolderSize: number;\n /** Whether symlinks are followed (and re-validated against workspace). */\n followSymlinks: boolean;\n /** Walk depth cap. */\n maxDepth: number;\n}\n\nexport async function planDirectoryFiles(\n record: ShareRecord,\n opts: PlanDirectoryOpts,\n): Promise<ZipPlanFile[]> {\n if (record.kind !== 'directory') return [];\n const rootAbs = resolvePath(record.absolutePath, opts.rootRelativePath);\n const files: ZipPlanFile[] = [];\n let totalSize = 0;\n\n async function walk(dir: string, depth: number): Promise<void> {\n if (depth > opts.maxDepth) return;\n if (files.length >= opts.maxFileCount) return;\n const dirents = await readdir(dir, { withFileTypes: true });\n for (const dirent of dirents) {\n if (files.length >= opts.maxFileCount) return;\n const abs = resolvePath(dir, dirent.name);\n const childLstat = await lstat(abs);\n let stats = childLstat;\n if (childLstat.isSymbolicLink()) {\n if (!opts.followSymlinks) continue;\n const real = await realpath(abs);\n if (!isPathUnderWorkspace(record.workspaceRoot, real)) continue;\n const relToShare = relPathPosix(record.absolutePath, real);\n if (relToShare.startsWith('..')) continue;\n stats = await stat(abs);\n }\n if (stats.isFile()) {\n totalSize += stats.size;\n if (totalSize > opts.maxFolderSize) {\n throw new Error('zip exceeds maxFolderSize');\n }\n const zipRel = relPathPosix(rootAbs, abs).split(/[\\\\/]/).join('/');\n files.push({\n zipPath: zipRel,\n absolutePath: abs,\n mtimeMs: stats.mtimeMs,\n size: stats.size,\n });\n } else if (stats.isDirectory()) {\n await walk(abs, depth + 1);\n }\n }\n }\n\n const rootLstat = await lstat(rootAbs);\n if (rootLstat.isDirectory()) {\n await walk(rootAbs, 0);\n } else if (rootLstat.isFile()) {\n const rootStat = await stat(rootAbs);\n files.push({\n zipPath: relPathPosix(record.absolutePath, rootAbs).split(/[\\\\/]/).join('/'),\n absolutePath: rootAbs,\n mtimeMs: rootStat.mtimeMs,\n size: rootStat.size,\n });\n }\n return files;\n}\n"],"mappings":";;;;;;;;AAgBA,MAAM,YAAY;AAClB,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,aAAa;AACnB,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAC5B,MAAM,kBAAkB;AACxB,MAAM,wBAAwB;AAE9B,MAAM,2BAA2B;AACjC,MAAM,YAAY;AAClB,MAAM,eAAe;AACrB,MAAM,iBAAiB;AAYvB,SAAS,QAAQ,GAAiB;AAChC,QAAQ,EAAE,UAAU,IAAI,KAAO,EAAE,YAAY,IAAI,IAAK,KAAK,MAAM,EAAE,YAAY,GAAG,EAAE;;AAGtF,SAAS,QAAQ,GAAiB;AAChC,QAAS,EAAE,aAAa,GAAG,QAAS,IAAO,EAAE,UAAU,GAAG,KAAM,IAAK,EAAE,SAAS;;AAGlF,SAAS,gBAAgB,MAAc,WAAiB,QAAwB;CAC9E,MAAM,MAAM,OAAO,MAAM,KAAK,KAAK,OAAO;AAC1C,KAAI,cAAc,WAAW,EAAE;AAC/B,KAAI,cAAc,IAAI,EAAE;AACxB,KAAI,cAAc,2BAA2B,WAAW,EAAE;AAC1D,KAAI,cAAc,QAAQ,EAAE;AAC5B,KAAI,cAAc,QAAQ,UAAU,EAAE,GAAG;AACzC,KAAI,cAAc,QAAQ,UAAU,EAAE,GAAG;AACzC,KAAI,cAAc,GAAG,GAAG;AACxB,KAAI,cAAc,GAAG,GAAG;AACxB,KAAI,cAAc,GAAG,GAAG;AACxB,KAAI,cAAc,KAAK,QAAQ,GAAG;AAClC,KAAI,cAAc,GAAG,GAAG;AACxB,MAAK,KAAK,KAAK,GAAG;AAClB,QAAO;;AAGT,SAAS,eAAe,KAAa,YAAoB,cAA8B;AAErF,KADmB,aAAa,mBAAmB,eAAe,iBAClD;EACd,MAAM,MAAM,OAAO,MAAM,GAAG;AAC5B,MAAI,cAAc,qBAAqB,EAAE;AACzC,MAAI,cAAc,QAAQ,GAAG,EAAE;AAC/B,MAAI,iBAAiB,OAAO,WAAW,EAAE,EAAE;AAC3C,MAAI,iBAAiB,OAAO,aAAa,EAAE,GAAG;AAC9C,SAAO;;CAET,MAAM,MAAM,OAAO,MAAM,GAAG;AAC5B,KAAI,cAAc,qBAAqB,EAAE;AACzC,KAAI,cAAc,QAAQ,GAAG,EAAE;AAC/B,KAAI,cAAc,eAAe,GAAG,EAAE;AACtC,KAAI,cAAc,iBAAiB,GAAG,GAAG;AACzC,QAAO;;AAGT,SAAS,gBAAgB,OAA6B;CACpD,MAAM,SAAmB,EAAE;CAC3B,MAAM,mBAAmB,MAAM,mBAAmB;CAClD,MAAM,iBAAiB,MAAM,iBAAiB;CAC9C,MAAM,aAAa,MAAM,SAAS;AAClC,KAAI,iBAAkB,QAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AACjE,KAAI,eAAgB,QAAO,KAAK,OAAO,MAAM,eAAe,CAAC;AAC7D,KAAI,WAAY,QAAO,KAAK,OAAO,MAAM,OAAO,CAAC;CACjD,MAAM,MAAM,OAAO,MAAM,IAAI,OAAO,SAAS,EAAE;AAC/C,KAAI,cAAc,GAAQ,EAAE;AAC5B,KAAI,cAAc,OAAO,SAAS,GAAG,EAAE;AACvC,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,KAAI,iBAAiB,OAAO,IAAI,IAAI,IAAI,EAAE;AAClF,QAAO;;AAGT,SAAS,cAAc,OAA6B;CAMlD,MAAM,QAJJ,MAAM,iBAAiB,mBACvB,MAAM,mBAAmB,mBACzB,MAAM,SAAS,kBAEU,gBAAgB,MAAM,GAAG,OAAO,MAAM,EAAE;CACnE,MAAM,OAAO,IAAI,KAAK,MAAM,MAAM;CAClC,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,KAAK,SAAS,MAAM,OAAO;AAC/D,KAAI,cAAc,aAAa,EAAE;AACjC,KAAI,cAAc,IAAI,EAAE;AACxB,KAAI,cAAc,IAAI,EAAE;AACxB,KAAI,cAAc,2BAA2B,WAAW,EAAE;AAC1D,KAAI,cAAc,MAAM,QAAQ,GAAG;AACnC,KAAI,cAAc,QAAQ,KAAK,EAAE,GAAG;AACpC,KAAI,cAAc,QAAQ,KAAK,EAAE,GAAG;AACpC,KAAI,cAAc,MAAM,UAAU,GAAG,GAAG;AACxC,KAAI,cAAc,KAAK,IAAI,MAAM,gBAAgB,WAAW,KAAK,GAAG,GAAG;AACvE,KAAI,cAAc,KAAK,IAAI,MAAM,kBAAkB,WAAW,KAAK,GAAG,GAAG;AACzE,KAAI,cAAc,MAAM,KAAK,QAAQ,GAAG;AACxC,KAAI,cAAc,MAAM,QAAQ,GAAG;AACnC,KAAI,cAAc,GAAG,GAAG;AACxB,KAAI,cAAc,GAAG,GAAG;AACxB,KAAI,cAAc,GAAG,GAAG;AACxB,KAAI,cAAc,GAAG,GAAG;AACxB,KAAI,cAAc,KAAK,IAAI,MAAM,QAAQ,WAAW,KAAK,GAAG,GAAG;AAC/D,OAAM,KAAK,KAAK,KAAK,GAAG;AACxB,OAAM,KAAK,KAAK,KAAK,MAAM,KAAK,OAAO;AACvC,QAAO;;AAGT,SAAS,gBACP,cACA,QACA,UACA,YACQ;CACR,MAAM,QAAkB,EAAE;AAE1B,KAAI,YAAY;EACd,MAAM,SAAS,OAAO,MAAM,GAAG;AAC/B,SAAO,cAAc,YAAY,EAAE;AACnC,SAAO,iBAAiB,OAAO,GAAG,EAAE,EAAE;AACtC,SAAO,cAAc,IAAI,GAAG;AAC5B,SAAO,cAAc,IAAI,GAAG;AAC5B,SAAO,cAAc,GAAG,GAAG;AAC3B,SAAO,cAAc,GAAG,GAAG;AAC3B,SAAO,iBAAiB,OAAO,aAAa,EAAE,GAAG;AACjD,SAAO,iBAAiB,OAAO,aAAa,EAAE,GAAG;AACjD,SAAO,iBAAiB,OAAO,OAAO,EAAE,GAAG;AAC3C,SAAO,iBAAiB,OAAO,SAAS,EAAE,GAAG;AAC7C,QAAM,KAAK,OAAO;EAElB,MAAM,UAAU,OAAO,MAAM,GAAG;AAChC,UAAQ,cAAc,oBAAoB,EAAE;AAC5C,UAAQ,cAAc,GAAG,EAAE;AAC3B,UAAQ,iBAAiB,OAAO,WAAW,OAAO,EAAE,EAAE;AACtD,UAAQ,cAAc,GAAG,GAAG;AAC5B,QAAM,KAAK,QAAQ;;CAGrB,MAAM,OAAO,OAAO,MAAM,GAAG;AAC7B,MAAK,cAAc,UAAU,EAAE;AAC/B,MAAK,cAAc,GAAG,EAAE;AACxB,MAAK,cAAc,GAAG,EAAE;AACxB,MAAK,cAAc,KAAK,IAAI,cAAc,MAAO,EAAE,EAAE;AACrD,MAAK,cAAc,KAAK,IAAI,cAAc,MAAO,EAAE,GAAG;AACtD,MAAK,cAAc,KAAK,IAAI,QAAQ,WAAW,KAAK,GAAG,GAAG;AAC1D,MAAK,cAAc,KAAK,IAAI,UAAU,WAAW,KAAK,GAAG,GAAG;AAC5D,MAAK,cAAc,GAAG,GAAG;AACzB,OAAM,KAAK,KAAK;AAEhB,QAAO,OAAO,OAAO,MAAM;;AAoB7B,MAAM,kBAAkB,IAAI,IAAI;CAC9B;CAAO;CAAM;CAAO;CAAM;CAAO;CACjC;CAAO;CAAO;CAAQ;CAAO;CAAQ;CAAQ;CAC7C;CAAO;CAAO;CAAO;CAAO;CAAQ;CAAO;CAC3C;CACD,CAAC;AAEF,SAAS,sBAAsB,GAAyB;CACtD,MAAM,MAAM,EAAE,QAAQ,MAAM,IAAI,CAAC,KAAK,EAAE,aAAa,IAAI;AACzD,KAAI,gBAAgB,IAAI,IAAI,CAAE,QAAO;AACrC,KAAI,EAAE,OAAO,KAAK,OAAO,KAAM,QAAO;AACtC,QAAO;;;;;;AAOT,SAAgB,gBAAgB,MAAiC;CAC/D,MAAM,SAAmB,EAAE;CAC3B,MAAM,UAA0B,EAAE;CAClC,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,SAAS,IAAI,SAAS,EAAE,OAAO,IAAI,CAAC;CAC1C,IAAI,WAAW;CAEf,SAAS,QAAQ,KAAmB;AAClC,cAAY,IAAI;AAChB,SAAO,KAAK,IAAI;;CAGlB,eAAe,UAAU,MAAkC;EACzD,MAAM,UAAU,OAAO,KAAK,KAAK,SAAS,OAAO;EACjD,MAAM,SAAS,SAAS,KAAK,GAAG,iBAAiB;EACjD,MAAM,SAAS;EACf,MAAM,QAAQ,KAAK,UAAU,IAAI,KAAK,UAAU,KAAK,KAAK;AAC1D,UAAQ,gBAAgB,SAAS,IAAI,KAAK,MAAM,EAAE,OAAO,CAAC;EAE1D,IAAI,eAAe;EACnB,IAAI,aAAa;EACjB,IAAI,MAAM;EAEV,MAAM,SAAS,iBAAiB,KAAK,aAAa;EAElD,MAAM,UAAU,IAAI,UAAU,EAC5B,UAAU,OAAe,MAAM,IAAI;GACjC,MAAM,MAAM,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAoC;AAC7F,mBAAgB,IAAI;AACpB,SAAM,MAAM,KAAK,IAAI;AACrB,MAAG,MAAM,IAAI;KAEhB,CAAC;EAEF,MAAM,OAAO,IAAI,UAAU,EACzB,UAAU,OAAe,MAAM,IAAI;GACjC,MAAM,MAAM,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAoC;AAC7F,iBAAc,IAAI;AAClB,WAAQ,IAAI;AACZ,OAAI;KAEP,CAAC;AAEF,MAAI,WAAW,eACb,OAAMA,SAAc,QAAQ,SAAS,iBAAiB,EAAE,OAAO,GAAG,CAAC,EAAE,KAAK;MAE1E,OAAMA,SAAc,QAAQ,SAAS,KAAK;AAG5C,UAAQ,eAAe,KAAK,YAAY,aAAa,CAAC;AACtD,UAAQ,KAAK;GACX,MAAM;GACN;GACA,OAAO;GACP,gBAAgB;GAChB,kBAAkB;GAClB;GACA;GACD,CAAC;;CAGJ,eAAe,uBAAuB,SAAiB,SAAgC;EACrF,MAAM,UAAU,OAAO,KAAK,SAAS,OAAO;EAC5C,MAAM,SAAS;EACf,MAAM,QAAQ,KAAK,KAAK;AACxB,UAAQ,gBAAgB,SAAS,IAAI,KAAK,MAAM,EAAE,aAAa,CAAC;EAChE,MAAM,MAAM,OAAO,KAAK,SAAS,OAAO;EACxC,MAAM,MAAM,MAAM,KAAK,EAAE;AACzB,UAAQ,IAAI;AACZ,UAAQ,eAAe,KAAK,IAAI,QAAQ,IAAI,OAAO,CAAC;AACpD,UAAQ,KAAK;GACX,MAAM;GACN;GACA,OAAO;GACP,gBAAgB,IAAI;GACpB,kBAAkB,IAAI;GACtB;GACA,QAAQ;GACT,CAAC;;AAGJ,EAAC,YAAY;AACX,MAAI;AACF,QAAK,MAAM,QAAQ,KAAK,MACtB,KAAI;AACF,UAAM,UAAU,KAAK;YACd,KAAK;IACZ,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,WAAO,KAAK,GAAG,KAAK,QAAQ,IAAI,MAAM;;AAG1C,OAAI,OAAO,SAAS,EAClB,OAAM,uBAAuB,oBAAoB,OAAO,KAAK,KAAK,CAAC;GAGrE,MAAM,WAAW;GACjB,IAAI,aAAa,QAAQ,SAAS;AAClC,QAAK,MAAM,SAAS,SAAS;AAC3B,QACE,MAAM,iBAAiB,mBACvB,MAAM,mBAAmB,mBACzB,MAAM,SAAS,gBAEf,cAAa;AAEf,YAAQ,cAAc,MAAM,CAAC;;GAE/B,MAAM,SAAS,WAAW;AAC1B,WAAQ,gBAAgB,QAAQ,QAAQ,QAAQ,UAAU,WAAW,CAAC;AACtE,UAAO,KAAK,KAAK;WACV,KAAK;AACZ,UAAO,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;;KAEnE;AAEJ,QAAO;;AAkBT,eAAsB,mBACpB,QACA,MACwB;AACxB,KAAI,OAAO,SAAS,YAAa,QAAO,EAAE;CAC1C,MAAM,UAAUC,QAAY,OAAO,cAAc,KAAK,iBAAiB;CACvE,MAAM,QAAuB,EAAE;CAC/B,IAAI,YAAY;CAEhB,eAAe,KAAK,KAAa,OAA8B;AAC7D,MAAI,QAAQ,KAAK,SAAU;AAC3B,MAAI,MAAM,UAAU,KAAK,aAAc;EACvC,MAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,MAAM,CAAC;AAC3D,OAAK,MAAM,UAAU,SAAS;AAC5B,OAAI,MAAM,UAAU,KAAK,aAAc;GACvC,MAAM,MAAMA,QAAY,KAAK,OAAO,KAAK;GACzC,MAAM,aAAa,MAAM,MAAM,IAAI;GACnC,IAAI,QAAQ;AACZ,OAAI,WAAW,gBAAgB,EAAE;AAC/B,QAAI,CAAC,KAAK,eAAgB;IAC1B,MAAM,OAAO,MAAM,SAAS,IAAI;AAChC,QAAI,CAAC,qBAAqB,OAAO,eAAe,KAAK,CAAE;AAEvD,QADmBC,SAAa,OAAO,cAAc,KACvC,CAAC,WAAW,KAAK,CAAE;AACjC,YAAQ,MAAM,KAAK,IAAI;;AAEzB,OAAI,MAAM,QAAQ,EAAE;AAClB,iBAAa,MAAM;AACnB,QAAI,YAAY,KAAK,cACnB,OAAM,IAAI,MAAM,4BAA4B;IAE9C,MAAM,SAASA,SAAa,SAAS,IAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,IAAI;AAClE,UAAM,KAAK;KACT,SAAS;KACT,cAAc;KACd,SAAS,MAAM;KACf,MAAM,MAAM;KACb,CAAC;cACO,MAAM,aAAa,CAC5B,OAAM,KAAK,KAAK,QAAQ,EAAE;;;CAKhC,MAAM,YAAY,MAAM,MAAM,QAAQ;AACtC,KAAI,UAAU,aAAa,CACzB,OAAM,KAAK,SAAS,EAAE;UACb,UAAU,QAAQ,EAAE;EAC7B,MAAM,WAAW,MAAM,KAAK,QAAQ;AACpC,QAAM,KAAK;GACT,SAASA,SAAa,OAAO,cAAc,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,IAAI;GAC5E,cAAc;GACd,SAAS,SAAS;GAClB,MAAM,SAAS;GAChB,CAAC;;AAEJ,QAAO"}
@@ -0,0 +1,35 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ import type { Socket } from 'node:net';
3
+ import type { SiteShareRecord } from './site-share-types.js';
4
+ import type { SiteShareStore } from './site-share-store.js';
5
+ export interface ProxyRequestContext {
6
+ /** Path inside the share to forward (no leading basePrefix). */
7
+ innerPath: string;
8
+ /** Path prefix the share is mounted under (used for Set-Cookie/Location rewrite). For subdomain mode use ''. */
9
+ basePrefix: string;
10
+ /** Client IP for forwarded headers and audit. */
11
+ clientIp: string;
12
+ /** Full request URL (for forwarded proto). */
13
+ originalUrl: URL;
14
+ /** Whether the request reached us via HTTPS at the edge. */
15
+ forwardedProto: 'http' | 'https';
16
+ }
17
+ export interface ProxyResult {
18
+ response: Response;
19
+ }
20
+ /**
21
+ * Forward an HTTP request to the upstream and return a streaming Response.
22
+ * Handles header filtering, forwarded headers, Set-Cookie / Location rewriting,
23
+ * and a per-request timeout.
24
+ */
25
+ export declare function forwardHttpRequest(record: SiteShareRecord, store: SiteShareStore, req: Request, ctx: ProxyRequestContext): Promise<ProxyResult>;
26
+ export declare function handleProxyWebSocketUpgrade(args: {
27
+ record: SiteShareRecord;
28
+ store: SiteShareStore;
29
+ req: IncomingMessage;
30
+ socket: Socket;
31
+ head: Buffer;
32
+ innerPath: string;
33
+ basePrefix: string;
34
+ clientIp: string;
35
+ }): void;