@xopcai/xopc 0.0.145 → 0.0.147

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 (380) hide show
  1. package/README.md +2 -2
  2. package/dist/browser-ext/manifest.json +1 -1
  3. package/dist/extensions/demo-memory/src/index.js +6 -4
  4. package/dist/extensions/demo-memory/src/index.js.map +1 -1
  5. package/dist/extensions/telegram/xopc.extension.json +1 -1
  6. package/dist/gateway/static/root/assets/Combination-14nmIgxH.js +41 -0
  7. package/dist/gateway/static/root/assets/activity-store-DXeSSlw1.js +1 -0
  8. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BEUxdhZx.js → agent-avatar-dicebear-CFdJKSjY.js} +1 -1
  9. package/dist/gateway/static/root/assets/agents-DKjbRpbA.js +2 -0
  10. package/dist/gateway/static/root/assets/api-Bs69B5zA.js +1 -0
  11. package/dist/gateway/static/root/assets/{app-management-settings-panel-CRHSZJWi.js → app-management-settings-panel-ag1ViXT_.js} +1 -1
  12. package/dist/gateway/static/root/assets/{appearance-settings-BunADYJb.js → appearance-settings-C6iMpwOM.js} +1 -1
  13. package/dist/gateway/static/root/assets/apps-page-CpX3lBFF.js +1 -0
  14. package/dist/gateway/static/root/assets/{archive-plugin-B6vTkH2A.js → archive-plugin-Dwi3mIBy.js} +1 -1
  15. package/dist/gateway/static/root/assets/{attachment-load-BjZXzaNv.js → attachment-load-BaCDoq40.js} +1 -1
  16. package/dist/gateway/static/root/assets/{automation-suggestion-card-ZDA-Stg1.js → automation-suggestion-card-CwqtFgnw.js} +1 -1
  17. package/dist/gateway/static/root/assets/automations-page-DlupOxFQ.js +6 -0
  18. package/dist/gateway/static/root/assets/{binary-plugins-DYZfLvPz.js → binary-plugins-DoAYhsxa.js} +1 -1
  19. package/dist/gateway/static/root/assets/{block-editor-C3MUlYC9.js → block-editor-Bw72pO7S.js} +31 -31
  20. package/dist/gateway/static/root/assets/browser-settings-page-BwLoUBcZ.js +8 -0
  21. package/dist/gateway/static/root/assets/capability-presets-api-vdbAR65Q.js +1 -0
  22. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BAsKbJgm.js +2 -0
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-fTlTnWB4.js → channel-recipient-api-rTG26jpV.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-CxFWy0cE.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-OKlqTtKJ.js +1 -0
  26. package/dist/gateway/static/root/assets/{connector-logo-BVFNT2zW.js → connector-logo-DIMP4NWY.js} +1 -1
  27. package/dist/gateway/static/root/assets/connectors-page-BjQQwX62.js +2 -0
  28. package/dist/gateway/static/root/assets/{desktop-pet-_jUmoXd3.js → desktop-pet-kQq2e0BN.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-DwGOy4AQ.js → desktop-pet-settings-B6vtozMY.js} +1 -1
  30. package/dist/gateway/static/root/assets/{directory-picker-path-field-akvF0F-u.js → directory-picker-path-field-Dn5-e3v4.js} +1 -1
  31. package/dist/gateway/static/root/assets/dist-C230izr8.js +1 -0
  32. package/dist/gateway/static/root/assets/dist-CxGUk8J-.js +1 -0
  33. package/dist/gateway/static/root/assets/dreaming-settings-BzwIujPG.js +3 -0
  34. package/dist/gateway/static/root/assets/extension-debug-page-D_e_hsEy.js +1 -0
  35. package/dist/gateway/static/root/assets/{extension-page-CwWktRNz.js → extension-page-D15CWHBd.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-CuggWOIl.js → extension-settings-page-D4P0n1om.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-api-B7sxIbza.js → gateway-config-api-B4qZctjG.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-DIv0eKMf.js → gateway-settings-BvndV7TP.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-DtoLihQE.js → gateway-startup-retry-BpgMunEb.js} +1 -1
  40. package/dist/gateway/static/root/assets/{goal-create-dialog-C4Kw0mfS.js → goal-create-dialog-DrVHKXHq.js} +1 -1
  41. package/dist/gateway/static/root/assets/goal-detail-page-PHlCwv68.js +4 -0
  42. package/dist/gateway/static/root/assets/{goals-config-api-B0jm5JaA.js → goals-config-api-B6YJB_ct.js} +1 -1
  43. package/dist/gateway/static/root/assets/goals-page-Hg9uyO6e.js +2 -0
  44. package/dist/gateway/static/root/assets/{goals-settings-N5_iL7es.js → goals-settings-BROWCIcL.js} +1 -1
  45. package/dist/gateway/static/root/assets/{heartbeat-settings-XzH3lbRR.js → heartbeat-settings-CoCwIOIg.js} +1 -1
  46. package/dist/gateway/static/root/assets/index-CxkNzw3e.js +259 -0
  47. package/dist/gateway/static/root/assets/index-DjCSOyaN.css +1 -0
  48. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-Bm_AIYQ7.js +1 -0
  49. package/dist/gateway/static/root/assets/local-app-workbench-page-BJWFcxwG.js +2 -0
  50. package/dist/gateway/static/root/assets/local-apps-page-BsiZMrEf.js +1 -0
  51. package/dist/gateway/static/root/assets/{locale-store-CiM-D9jA.js → locale-store-Bp8joZck.js} +1 -1
  52. package/dist/gateway/static/root/assets/logs-page-DOmK61ey.js +7 -0
  53. package/dist/gateway/static/root/assets/{markdown-split-5rJx5flj.js → markdown-split-Dy7QpaAz.js} +1 -1
  54. package/dist/gateway/static/root/assets/{media-plugins-DYXccwAd.js → media-plugins-3Lxliy9D.js} +1 -1
  55. package/dist/gateway/static/root/assets/messages-CQGpD-dC.js +5 -0
  56. package/dist/gateway/static/root/assets/models-hub-panel-DGCZom4o.js +2 -0
  57. package/dist/gateway/static/root/assets/{notes-page-BgLyndCO.js → notes-page-BJtT4vSf.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-B_bN7cOR.js +4 -0
  59. package/dist/gateway/static/root/assets/{page-tabs-6Al9_sGz.js → page-tabs-DKB6RDre.js} +1 -1
  60. package/dist/gateway/static/root/assets/{preview-open-alternatives-Cm3G72Hv.js → preview-open-alternatives-Br_YhYHp.js} +1 -1
  61. package/dist/gateway/static/root/assets/project-detail-page-Dq8JouJj.js +1 -0
  62. package/dist/gateway/static/root/assets/projects-page-DvfL7fSe.js +1 -0
  63. package/dist/gateway/static/root/assets/remote-access-hub-DqwMXSXP.js +1 -0
  64. package/dist/gateway/static/root/assets/{save-bar-controls-BYtfzu_F.js → save-bar-controls-BgIE9BBh.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schedule-field-CvIRc6yK.js → schedule-field-BXDP-oMz.js} +1 -1
  66. package/dist/gateway/static/root/assets/{schema-form-CQuKx0n7.js → schema-form-Dhv-SmjG.js} +1 -1
  67. package/dist/gateway/static/root/assets/sessions-page-B_mOZkQk.js +1 -0
  68. package/dist/gateway/static/root/assets/settings-advanced-gate-BHGmH6YS.js +1 -0
  69. package/dist/gateway/static/root/assets/{settings-collapsible-section-CF3HHM-t.js → settings-collapsible-section-CUTExnlK.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-form-section-CwWjoRN6.js → settings-form-section-CmnDhsf0.js} +1 -1
  71. package/dist/gateway/static/root/assets/{settings-loading-skeleton-aUFmJa13.js → settings-loading-skeleton-B79dq-XY.js} +1 -1
  72. package/dist/gateway/static/root/assets/{settings-page-B2UUU9TF.js → settings-page-Db8uAv3X.js} +1 -1
  73. package/dist/gateway/static/root/assets/{settings-page-layout-DqpbTWqI.js → settings-page-layout-DaFwstQw.js} +1 -1
  74. package/dist/gateway/static/root/assets/setup-status-panel-BUSEj0KK.js +1 -0
  75. package/dist/gateway/static/root/assets/{share-preview-page-BOhlPsS1.js → share-preview-page-Bi00uXzV.js} +1 -1
  76. package/dist/gateway/static/root/assets/shares-settings-DzsTYfuX.js +1 -0
  77. package/dist/gateway/static/root/assets/skill-reload-api-DSsdU081.js +1 -0
  78. package/dist/gateway/static/root/assets/skills-page-DeB1tQZL.js +2 -0
  79. package/dist/gateway/static/root/assets/{system-settings-panel-CWxSvuwD.js → system-settings-panel-Cxaph7hW.js} +1 -1
  80. package/dist/gateway/static/root/assets/{theme-store-C9Dxcppm.js → theme-store-eCTN1RpG.js} +1 -1
  81. package/dist/gateway/static/root/assets/{typed-models-lib-qROAvqTw.js → typed-models-lib-CcZ_tyFY.js} +1 -1
  82. package/dist/gateway/static/root/assets/{use-channel-catalog-DE9cpn4G.js → use-channel-catalog-C4PWbNoi.js} +1 -1
  83. package/dist/gateway/static/root/assets/user-context-page-QTVMx_hG.js +1 -0
  84. package/dist/gateway/static/root/assets/{user-profile-fields-editor-CWxc0ghP.js → user-profile-fields-editor-CPOO9Jz5.js} +1 -1
  85. package/dist/gateway/static/root/assets/{user-profile-settings-panel-DW-Up6vt.js → user-profile-settings-panel-C8cgtSF7.js} +1 -1
  86. package/dist/gateway/static/root/assets/{utils-D53uRXVr.js → utils-CiZK2KwH.js} +1 -1
  87. package/dist/gateway/static/root/assets/voice-api-key-field-b-YZtvUu.js +1 -0
  88. package/dist/gateway/static/root/assets/work-discovery-page-4zVDOl2G.js +1 -0
  89. package/dist/gateway/static/root/assets/work-item-detail-page-CHe2tfkc.js +1 -0
  90. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-D_x9ELJp.js → workflow-run-setup-panel-8SLCYeXE.js} +2 -2
  91. package/dist/gateway/static/root/assets/workflows-page-DEOFqiWn.js +11 -0
  92. package/dist/gateway/static/root/index.html +10 -9
  93. package/dist/package.js +1 -1
  94. package/dist/src/activity/types.d.ts +1 -1
  95. package/dist/src/agent/agent-instance-gateway.d.ts +1 -1
  96. package/dist/src/agent/agent-manager.d.ts +1 -1
  97. package/dist/src/agent/agent-manager.js +5 -4
  98. package/dist/src/agent/agent-manager.js.map +1 -1
  99. package/dist/src/agent/background-review/coordinator.js +0 -1
  100. package/dist/src/agent/background-review/coordinator.js.map +1 -1
  101. package/dist/src/agent/background-review/settings.d.ts +1 -1
  102. package/dist/src/agent/background-review/settings.js +10 -17
  103. package/dist/src/agent/background-review/settings.js.map +1 -1
  104. package/dist/src/agent/bootstrap/filter-bootstrap-files.d.ts +1 -1
  105. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
  106. package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
  107. package/dist/src/agent/bootstrap/load-bootstrap-files.js +2 -3
  108. package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
  109. package/dist/src/agent/code-intelligence/binary.js +1 -1
  110. package/dist/src/agent/context/project-context.d.ts +14 -0
  111. package/dist/src/agent/context/project-context.js +23 -1
  112. package/dist/src/agent/context/project-context.js.map +1 -1
  113. package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
  114. package/dist/src/agent/context/workspace.d.ts +1 -2
  115. package/dist/src/agent/context/workspace.js +2 -4
  116. package/dist/src/agent/context/workspace.js.map +1 -1
  117. package/dist/src/agent/embedded/run-for-session.js +1 -2
  118. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  119. package/dist/src/agent/embedded/run-turn.js +6 -1
  120. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  121. package/dist/src/agent/embedded/types.d.ts +17 -0
  122. package/dist/src/agent/memory/builtin-memory-store.d.ts +2 -2
  123. package/dist/src/agent/memory/builtin-memory-store.js +2 -2
  124. package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
  125. package/dist/src/agent/memory/builtin-provider.d.ts +1 -3
  126. package/dist/src/agent/memory/builtin-provider.js +21 -48
  127. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  128. package/dist/src/agent/memory/context/planner.js +48 -9
  129. package/dist/src/agent/memory/context/planner.js.map +1 -1
  130. package/dist/src/agent/memory/context/types.d.ts +7 -1
  131. package/dist/src/agent/memory/context-fence.js +1 -1
  132. package/dist/src/agent/memory/context-fence.js.map +1 -1
  133. package/dist/src/agent/memory/create-memory-manager.js +2 -9
  134. package/dist/src/agent/memory/create-memory-manager.js.map +1 -1
  135. package/dist/src/agent/memory/dreaming/config.js +5 -10
  136. package/dist/src/agent/memory/dreaming/config.js.map +1 -1
  137. package/dist/src/agent/memory/dreaming/promotion-lifecycle.js +2 -2
  138. package/dist/src/agent/memory/dreaming/promotion-lifecycle.js.map +1 -1
  139. package/dist/src/agent/memory/dreaming/scope.d.ts +2 -3
  140. package/dist/src/agent/memory/dreaming/scope.js +8 -8
  141. package/dist/src/agent/memory/dreaming/scope.js.map +1 -1
  142. package/dist/src/agent/memory/manager.d.ts +1 -5
  143. package/dist/src/agent/memory/manager.js +2 -23
  144. package/dist/src/agent/memory/manager.js.map +1 -1
  145. package/dist/src/agent/memory/memory-config.d.ts +3 -3
  146. package/dist/src/agent/memory/memory-config.js +9 -14
  147. package/dist/src/agent/memory/memory-config.js.map +1 -1
  148. package/dist/src/agent/memory/types.d.ts +9 -5
  149. package/dist/src/agent/memory/understanding/service.js +21 -8
  150. package/dist/src/agent/memory/understanding/service.js.map +1 -1
  151. package/dist/src/agent/memory/understanding/types.d.ts +5 -0
  152. package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -1
  153. package/dist/src/agent/memory/user-context-coordinator.js +6 -2
  154. package/dist/src/agent/memory/user-context-coordinator.js.map +1 -1
  155. package/dist/src/agent/orchestration/agent-orchestrator.js +2 -2
  156. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  157. package/dist/src/agent/prompt/memory/index.d.ts +1 -2
  158. package/dist/src/agent/prompt/memory/index.js +6 -7
  159. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  160. package/dist/src/agent/prompt/sections/tooling.js +1 -1
  161. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  162. package/dist/src/agent/service/direct-turn-helpers.js +13 -2
  163. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  164. package/dist/src/agent/tools/curated-memory-tool.js +4 -4
  165. package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
  166. package/dist/src/agent/tools/factory.d.ts +1 -1
  167. package/dist/src/agent/tools/factory.js +2 -2
  168. package/dist/src/agent/tools/factory.js.map +1 -1
  169. package/dist/src/agent/tools/memory-tool.js +1 -1
  170. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  171. package/dist/src/agent/workflow/workflow-child-tools.js +2 -3
  172. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -1
  173. package/dist/src/agent/workspace-runtime/registry.d.ts +5 -5
  174. package/dist/src/agent/workspace-runtime/registry.js +6 -11
  175. package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
  176. package/dist/src/agent-manifest/index.js +2 -2
  177. package/dist/src/agent-manifest/prompt.js +1 -7
  178. package/dist/src/agent-manifest/prompt.js.map +1 -1
  179. package/dist/src/agent-manifest/schema.d.ts +0 -598
  180. package/dist/src/agent-manifest/schema.js +2 -143
  181. package/dist/src/agent-manifest/schema.js.map +1 -1
  182. package/dist/src/agent-manifest/validator.js +0 -12
  183. package/dist/src/agent-manifest/validator.js.map +1 -1
  184. package/dist/src/agent-runtime/index.js +1 -1
  185. package/dist/src/agent-runtime/memory-runtime.d.ts +2 -2
  186. package/dist/src/agent-runtime/memory-runtime.js +8 -7
  187. package/dist/src/agent-runtime/memory-runtime.js.map +1 -1
  188. package/dist/src/agent-runtime/runtime-profile.d.ts +2 -0
  189. package/dist/src/agent-runtime/runtime-profile.js +2 -2
  190. package/dist/src/agent-runtime/runtime-profile.js.map +1 -1
  191. package/dist/src/chat-commands/agent-edit.js +1 -2
  192. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  193. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  194. package/dist/src/cli/commands/init.js +0 -22
  195. package/dist/src/cli/commands/init.js.map +1 -1
  196. package/dist/src/cli/templates.d.ts +1 -1
  197. package/dist/src/cli/templates.js +1 -16
  198. package/dist/src/cli/templates.js.map +1 -1
  199. package/dist/src/commands/agents.config.js +0 -10
  200. package/dist/src/commands/agents.config.js.map +1 -1
  201. package/dist/src/config/agent-profile.js +1 -1
  202. package/dist/src/config/index.js +2 -2
  203. package/dist/src/config/paths.d.ts +0 -1
  204. package/dist/src/config/paths.js +1 -2
  205. package/dist/src/config/paths.js.map +1 -1
  206. package/dist/src/config/schema.d.ts +118 -532
  207. package/dist/src/config/schema.js +32 -26
  208. package/dist/src/config/schema.js.map +1 -1
  209. package/dist/src/extensions/loader.js +2 -1
  210. package/dist/src/extensions/loader.js.map +1 -1
  211. package/dist/src/gateway/agents-admin.d.ts +0 -2
  212. package/dist/src/gateway/agents-admin.js +1 -7
  213. package/dist/src/gateway/agents-admin.js.map +1 -1
  214. package/dist/src/gateway/capability-presets-admin.d.ts +0 -2
  215. package/dist/src/gateway/capability-presets-admin.js.map +1 -1
  216. package/dist/src/gateway/chat-stream/mapper.js +26 -0
  217. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  218. package/dist/src/gateway/chat-stream/protocol.d.ts +16 -1
  219. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +0 -1
  220. package/dist/src/gateway/dreaming-automation-reconciler.js +41 -63
  221. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -1
  222. package/dist/src/gateway/heartbeat/service.js +1 -1
  223. package/dist/src/gateway/hono/app.js +3 -1
  224. package/dist/src/gateway/hono/app.js.map +1 -1
  225. package/dist/src/gateway/hono/lib/config-payload.d.ts +0 -130
  226. package/dist/src/gateway/hono/lib/config-payload.js +0 -1
  227. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  228. package/dist/src/gateway/hono/routes/agents.js +6 -12
  229. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  230. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +6 -0
  231. package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
  232. package/dist/src/gateway/hono/routes/capability-presets.js +2 -2
  233. package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -1
  234. package/dist/src/gateway/hono/routes/dreaming.js +9 -20
  235. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  236. package/dist/src/gateway/hono/routes/index.js +4 -0
  237. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  238. package/dist/src/gateway/hono/routes/local-apps.d.ts +5 -0
  239. package/dist/src/gateway/hono/routes/local-apps.js +99 -0
  240. package/dist/src/gateway/hono/routes/local-apps.js.map +1 -0
  241. package/dist/src/gateway/hono/routes/memory.js +48 -65
  242. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  243. package/dist/src/gateway/hono/routes/projects.js +2 -2
  244. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  245. package/dist/src/gateway/hono/routes/work-discovery.d.ts +3 -0
  246. package/dist/src/gateway/hono/routes/work-discovery.js +150 -0
  247. package/dist/src/gateway/hono/routes/work-discovery.js.map +1 -0
  248. package/dist/src/gateway/hono/routes/you.d.ts +3 -0
  249. package/dist/src/gateway/hono/routes/you.js +358 -91
  250. package/dist/src/gateway/hono/routes/you.js.map +1 -1
  251. package/dist/src/gateway/service.d.ts +3 -0
  252. package/dist/src/gateway/service.js +12 -0
  253. package/dist/src/gateway/service.js.map +1 -1
  254. package/dist/src/heartbeat/index.js +1 -1
  255. package/dist/src/knowledge/connected-knowledge-pipeline.js +9 -5
  256. package/dist/src/knowledge/connected-knowledge-pipeline.js.map +1 -1
  257. package/dist/src/local-apps/acceptance.d.ts +30 -0
  258. package/dist/src/local-apps/acceptance.js +93 -0
  259. package/dist/src/local-apps/acceptance.js.map +1 -0
  260. package/dist/src/local-apps/index.d.ts +5 -0
  261. package/dist/src/local-apps/index.js +4 -0
  262. package/dist/src/local-apps/preview-runtime-bridge.d.ts +4 -0
  263. package/dist/src/local-apps/preview-runtime-bridge.js +171 -0
  264. package/dist/src/local-apps/preview-runtime-bridge.js.map +1 -0
  265. package/dist/src/local-apps/runtime-entry.d.ts +8 -0
  266. package/dist/src/local-apps/runtime-entry.js +25 -0
  267. package/dist/src/local-apps/runtime-entry.js.map +1 -0
  268. package/dist/src/local-apps/scaffold.d.ts +8 -0
  269. package/dist/src/local-apps/scaffold.js +122 -0
  270. package/dist/src/local-apps/scaffold.js.map +1 -0
  271. package/dist/src/local-apps/service.d.ts +37 -0
  272. package/dist/src/local-apps/service.js +553 -0
  273. package/dist/src/local-apps/service.js.map +1 -0
  274. package/dist/src/local-apps/store.d.ts +44 -0
  275. package/dist/src/local-apps/store.js +195 -0
  276. package/dist/src/local-apps/store.js.map +1 -0
  277. package/dist/src/local-apps/types.d.ts +105 -0
  278. package/dist/src/local-apps/types.js +1 -0
  279. package/dist/src/storage/sqlite/index.d.ts +3 -2
  280. package/dist/src/storage/sqlite/index.js +4 -3
  281. package/dist/src/storage/sqlite/memory-index-repository.d.ts +2 -3
  282. package/dist/src/storage/sqlite/memory-index-repository.js +16 -20
  283. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
  284. package/dist/src/storage/sqlite/memory-records-repository.d.ts +18 -10
  285. package/dist/src/storage/sqlite/memory-records-repository.js +79 -34
  286. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
  287. package/dist/src/storage/sqlite/memory-reference-consent-repository.d.ts +27 -0
  288. package/dist/src/storage/sqlite/memory-reference-consent-repository.js +109 -0
  289. package/dist/src/storage/sqlite/memory-reference-consent-repository.js.map +1 -0
  290. package/dist/src/storage/sqlite/migrations/038_user_owned_memory.sql +68 -0
  291. package/dist/src/storage/sqlite/migrations/039_memory_reference_consents.sql +19 -0
  292. package/dist/src/storage/sqlite/migrations/040_local_apps.sql +32 -0
  293. package/dist/src/storage/sqlite/migrations/041_local_app_release_lifecycle.sql +17 -0
  294. package/dist/src/storage/sqlite/migrations/042_work_discovery.sql +41 -0
  295. package/dist/src/storage/sqlite/migrations/043_local_app_acceptance_runs.sql +16 -0
  296. package/dist/src/storage/sqlite/migrations/044_repair_work_discovery_foreign_keys.sql +75 -0
  297. package/dist/src/storage/sqlite/migrations/045_extension_ui_grants.sql +13 -0
  298. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  299. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  300. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  301. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  302. package/dist/src/storage/sqlite/schema.js +1 -1
  303. package/dist/src/storage/sqlite/schema.sql +20 -0
  304. package/dist/src/user-context/config.d.ts +227 -0
  305. package/dist/src/user-context/config.js +158 -0
  306. package/dist/src/user-context/config.js.map +1 -0
  307. package/dist/src/user-context/import.d.ts +1 -1
  308. package/dist/src/user-context/import.js +6 -1
  309. package/dist/src/user-context/import.js.map +1 -1
  310. package/dist/src/user-context/owner.d.ts +5 -0
  311. package/dist/src/user-context/owner.js +9 -0
  312. package/dist/src/user-context/owner.js.map +1 -0
  313. package/dist/src/user-context/projection.d.ts +11 -9
  314. package/dist/src/user-context/projection.js +74 -47
  315. package/dist/src/user-context/projection.js.map +1 -1
  316. package/dist/src/user-context/runtime.d.ts +13 -0
  317. package/dist/src/user-context/runtime.js +36 -0
  318. package/dist/src/user-context/runtime.js.map +1 -0
  319. package/dist/src/work-discovery/analyzer.d.ts +11 -0
  320. package/dist/src/work-discovery/analyzer.js +171 -0
  321. package/dist/src/work-discovery/analyzer.js.map +1 -0
  322. package/dist/src/work-discovery/index.d.ts +5 -0
  323. package/dist/src/work-discovery/index.js +5 -0
  324. package/dist/src/work-discovery/probe.d.ts +12 -0
  325. package/dist/src/work-discovery/probe.js +335 -0
  326. package/dist/src/work-discovery/probe.js.map +1 -0
  327. package/dist/src/work-discovery/repository.d.ts +11 -0
  328. package/dist/src/work-discovery/repository.js +100 -0
  329. package/dist/src/work-discovery/repository.js.map +1 -0
  330. package/dist/src/work-discovery/service.d.ts +30 -0
  331. package/dist/src/work-discovery/service.js +387 -0
  332. package/dist/src/work-discovery/service.js.map +1 -0
  333. package/dist/src/work-discovery/types.d.ts +114 -0
  334. package/dist/src/work-discovery/types.js +1 -0
  335. package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
  336. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  337. package/package.json +5 -3
  338. package/skills/engineering/build-xopc-local-app/SKILL.md +45 -0
  339. package/skills/engineering/build-xopc-local-app/references/app-contract.md +33 -0
  340. package/skills/engineering/build-xopc-local-app/scripts/validate-local-app.mjs +72 -0
  341. package/dist/gateway/static/root/assets/Combination-DolwnuKi.js +0 -41
  342. package/dist/gateway/static/root/assets/activity-center-store-3l9ahUqb.js +0 -1
  343. package/dist/gateway/static/root/assets/agents-1bpT0xRO.js +0 -2
  344. package/dist/gateway/static/root/assets/apps-page-Cc4JgVUQ.js +0 -1
  345. package/dist/gateway/static/root/assets/automations-page-mb0fdVpq.js +0 -6
  346. package/dist/gateway/static/root/assets/browser-settings-page-Bb0xhaMN.js +0 -8
  347. package/dist/gateway/static/root/assets/capability-presets-api-BV76yN9a.js +0 -1
  348. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CUcGKZqC.js +0 -2
  349. package/dist/gateway/static/root/assets/channels-settings-BlSDMGdy.js +0 -1
  350. package/dist/gateway/static/root/assets/channels-status-swr-CJauF1CW.js +0 -1
  351. package/dist/gateway/static/root/assets/connectors-page-CMgAFGvb.js +0 -2
  352. package/dist/gateway/static/root/assets/dist-C99RGfAH.js +0 -1
  353. package/dist/gateway/static/root/assets/dreaming-settings-BLetQiYY.js +0 -3
  354. package/dist/gateway/static/root/assets/extension-debug-page-Cof2ncxE.js +0 -1
  355. package/dist/gateway/static/root/assets/goal-detail-page-BMmzYpZL.js +0 -4
  356. package/dist/gateway/static/root/assets/goals-page-CGeT77PC.js +0 -2
  357. package/dist/gateway/static/root/assets/index-CSLF84-Q.css +0 -1
  358. package/dist/gateway/static/root/assets/index-I-ZCenVw.js +0 -259
  359. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-x_v0nrIi.js +0 -1
  360. package/dist/gateway/static/root/assets/logs-page-BSh1t8cD.js +0 -7
  361. package/dist/gateway/static/root/assets/messages-Cb1VMeqP.js +0 -5
  362. package/dist/gateway/static/root/assets/models-hub-panel-BNpTenAI.js +0 -2
  363. package/dist/gateway/static/root/assets/notes-workbench-teklkhcE.js +0 -4
  364. package/dist/gateway/static/root/assets/project-detail-page-CCB_dKoh.js +0 -1
  365. package/dist/gateway/static/root/assets/projects-page-VOAFAHYj.js +0 -1
  366. package/dist/gateway/static/root/assets/remote-access-hub-USYu64Ru.js +0 -1
  367. package/dist/gateway/static/root/assets/sessions-page-oGC8O5h_.js +0 -1
  368. package/dist/gateway/static/root/assets/settings-advanced-gate-D4rP66R1.js +0 -1
  369. package/dist/gateway/static/root/assets/setup-status-panel-Ck9keROI.js +0 -1
  370. package/dist/gateway/static/root/assets/shares-settings-BYLsCuqj.js +0 -1
  371. package/dist/gateway/static/root/assets/skill-reload-api-BNHUyVML.js +0 -1
  372. package/dist/gateway/static/root/assets/skills-page-CpXbQH4n.js +0 -2
  373. package/dist/gateway/static/root/assets/user-context-page-DbNEK4Yp.js +0 -1
  374. package/dist/gateway/static/root/assets/voice-api-key-field-Cs7MOrg0.js +0 -1
  375. package/dist/gateway/static/root/assets/work-item-detail-page-D1ziG1Pp.js +0 -1
  376. package/dist/gateway/static/root/assets/workflows-page-DHGV_n6i.js +0 -11
  377. package/dist/src/agent/context/workspace-templates/MEMORY.md +0 -33
  378. package/dist/src/agent/memory/access-policy.d.ts +0 -12
  379. package/dist/src/agent/memory/access-policy.js +0 -44
  380. package/dist/src/agent/memory/access-policy.js.map +0 -1
@@ -75,6 +75,32 @@ var ChatStreamMapper = class {
75
75
  choices: Array.isArray(event.choices) ? event.choices.filter((x) => typeof x === "string") : void 0,
76
76
  default: typeof event.default === "string" ? event.default : void 0
77
77
  })];
78
+ case "memory_consent_required": return [this.make("memory_consent_required", { requests: Array.isArray(event.requests) ? event.requests.flatMap((raw) => {
79
+ if (!raw || typeof raw !== "object") return [];
80
+ const request = raw;
81
+ const id = typeof request.id === "string" ? request.id : "";
82
+ const recordId = typeof request.recordId === "string" ? request.recordId : "";
83
+ const statement = typeof request.statement === "string" ? request.statement : "";
84
+ const purpose = typeof request.purpose === "string" ? request.purpose : "";
85
+ return id && recordId && statement ? [{
86
+ id,
87
+ recordId,
88
+ statement,
89
+ purpose
90
+ }] : [];
91
+ }) : [] })];
92
+ case "memory_captured": return [this.make("memory_captured", { records: Array.isArray(event.records) ? event.records.flatMap((raw) => {
93
+ if (!raw || typeof raw !== "object") return [];
94
+ const record = raw;
95
+ const id = typeof record.id === "string" ? record.id : "";
96
+ const content = typeof record.content === "string" ? record.content : "";
97
+ const kind = typeof record.kind === "string" ? record.kind : "";
98
+ return id && content ? [{
99
+ id,
100
+ content,
101
+ kind
102
+ }] : [];
103
+ }) : [] })];
78
104
  case "error": return [this.make("error", {
79
105
  code: "AGENT_RUN_ERROR",
80
106
  message: String(event.content ?? event.message ?? "Unknown error")
@@ -1 +1 @@
1
- {"version":3,"file":"mapper.js","names":["message"],"sources":["../../../../src/gateway/chat-stream/mapper.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { EmbeddedStreamEvent } from '../../agent/embedded/types.js';\nimport type { ChatStreamEvent, ChatStreamStatus } from './protocol.js';\n\nexport type RuntimeStreamEvent = EmbeddedStreamEvent | { type: string; [key: string]: unknown };\n\nexport interface ChatStreamMapperOptions {\n runId: string;\n sessionKey: string;\n channel: string;\n}\n\ntype ToolResultEnvelope = { content?: unknown[]; details?: unknown; text?: string };\n\nexport class ChatStreamMapper {\n private assistantIndex = 0;\n private currentAssistantMessageId: string | undefined;\n private lastAssistantMessageId: string | undefined;\n private currentAssistantText = '';\n private currentAssistantReviewEmitted = false;\n private toolCallToMessageId = new Map<string, string>();\n private turnDiffs: string[] = [];\n private turnDiffFiles = new Set<string>();\n private turnDiffAdded = 0;\n private turnDiffRemoved = 0;\n private started = false;\n private ended = false;\n\n constructor(private readonly opts: ChatStreamMapperOptions) {}\n\n map(input: RuntimeStreamEvent): ChatStreamEvent[] {\n const event = input as { type: string; [key: string]: unknown };\n switch (event.type) {\n case 'agent_start':\n return this.start();\n case 'agent_end':\n return [];\n case 'message_start':\n return this.mapMessageStart(event.message);\n case 'message_update':\n return this.mapMessageUpdate(event);\n case 'message_end':\n return this.mapMessageEnd(event.message);\n case 'tool_execution_start':\n return this.mapToolStart(event);\n case 'tool_execution_update':\n return this.mapToolUpdate(event);\n case 'tool_execution_end':\n return this.mapToolEnd(event);\n case 'review_start':\n return [this.make('review_start', {\n messageId: this.ensureAssistantMessageId(),\n reviewId: String(event.reviewId ?? ''),\n target: String(event.target ?? 'working tree changes'),\n stage: event.stage === 'preparing' ? 'preparing' : 'reviewing',\n })];\n case 'review_delta':\n return [this.make('review_delta', {\n messageId: this.ensureAssistantMessageId(),\n reviewId: String(event.reviewId ?? ''),\n delta: String(event.delta ?? ''),\n })];\n case 'review_end':\n return [this.make('review_end', {\n messageId: this.ensureAssistantMessageId(),\n reviewId: String(event.reviewId ?? ''),\n status: event.status === 'error' ? 'error' : 'complete',\n ...(typeof event.message === 'string' && event.message ? { message: event.message } : {}),\n })];\n case 'user_message':\n return [this.make('user_message', { message: userMessageFromLegacyEvent(event) })];\n case 'user_transcript':\n return [this.make('user_transcript', { text: String(event.text ?? ''), media: event.media })];\n case 'progress':\n return [\n this.make('progress', {\n stage: String(event.stage ?? ''),\n message: String(event.message ?? ''),\n ...(typeof event.detail === 'string' ? { detail: event.detail } : {}),\n ...(typeof event.toolName === 'string' ? { toolName: event.toolName } : {}),\n ...(typeof event.completed === 'number' ? { completed: event.completed } : {}),\n ...(typeof event.total === 'number' ? { total: event.total } : {}),\n }),\n ];\n case 'compaction':\n return [\n this.make('compaction', {\n status: event.status === 'completed' || event.status === 'skipped' ? event.status : 'started',\n tokensBefore: typeof event.tokensBefore === 'number' ? event.tokensBefore : undefined,\n tokensAfter: typeof event.tokensAfter === 'number' ? event.tokensAfter : undefined,\n summary: typeof event.summary === 'string' ? event.summary : undefined,\n }),\n ];\n case 'tts_audio':\n return [\n this.make('tts_audio', {\n uri: String(event.uri ?? ''),\n mimeType: String(event.mimeType ?? 'audio/mpeg'),\n name: String(event.name ?? 'voice.mp3'),\n attachTo: 'last_assistant',\n ...(this.lastAssistantMessageId ? { messageId: this.lastAssistantMessageId } : {}),\n }),\n ];\n case 'clarify_request':\n return [\n this.make('clarify_request', {\n requestId: String(event.requestId ?? ''),\n question: String(event.question ?? ''),\n choices: Array.isArray(event.choices) ? event.choices.filter((x): x is string => typeof x === 'string') : undefined,\n default: typeof event.default === 'string' ? event.default : undefined,\n }),\n ];\n case 'error':\n return [this.make('error', { code: 'AGENT_RUN_ERROR', message: String(event.content ?? event.message ?? 'Unknown error') })];\n default:\n return [];\n }\n }\n\n start(): ChatStreamEvent[] {\n if (this.started) return [];\n this.started = true;\n return [this.make('run_start', { channel: this.opts.channel })];\n }\n\n end(status: ChatStreamStatus, summary?: string): ChatStreamEvent[] {\n if (this.ended) return [];\n this.ended = true;\n return [this.make('run_end', { status, summary })];\n }\n\n error(message: string, code = 'AGENT_RUN_ERROR'): ChatStreamEvent[] {\n return [this.make('error', { code, message })];\n }\n\n private mapMessageStart(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.nextAssistantMessageId();\n this.currentAssistantMessageId = messageId;\n this.currentAssistantText = '';\n this.currentAssistantReviewEmitted = false;\n return [this.make('assistant_message_start', { messageId })];\n }\n\n private mapMessageUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const message = event.message as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const review = extractReview(message);\n if (review && !this.currentAssistantReviewEmitted) {\n this.currentAssistantReviewEmitted = true;\n return [this.make('review', { messageId, review })];\n }\n const delta = event.assistantMessageEvent as { type?: unknown; delta?: unknown } | undefined;\n if (delta?.type === 'text_delta' && typeof delta.delta === 'string' && delta.delta) {\n const text = extractTextFromMessage(message);\n const suffixFromMessage = appendSuffix(this.currentAssistantText, text);\n const suffix = text ? suffixFromMessage : appendSuffix(this.currentAssistantText, delta.delta);\n if (!suffix) {\n if (text) this.currentAssistantText = text;\n return [];\n }\n this.currentAssistantText = text || `${this.currentAssistantText}${suffix}`;\n return [this.make('assistant_delta', { messageId, delta: suffix })];\n }\n if (delta?.type === 'thinking_delta' && typeof delta.delta === 'string' && delta.delta) {\n return [this.make('thinking_delta', { messageId, delta: delta.delta })];\n }\n\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n this.currentAssistantText = text || this.currentAssistantText;\n return suffix ? [this.make('assistant_delta', { messageId, delta: suffix })] : [];\n }\n\n private mapMessageEnd(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const events: ChatStreamEvent[] = [];\n const review = extractReview(message);\n if (review && !this.currentAssistantReviewEmitted) {\n this.currentAssistantReviewEmitted = true;\n events.push(this.make('review', { messageId, review }));\n }\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n if (suffix) events.push(this.make('assistant_delta', { messageId, delta: suffix }));\n this.currentAssistantText = text || this.currentAssistantText;\n events.push(this.make('thinking_end', { messageId }));\n if (this.turnDiffs.length > 0) {\n events.push(\n this.make('turn_diff', {\n messageId,\n files: [...this.turnDiffFiles],\n diff: this.turnDiffs.join('\\n'),\n added: this.turnDiffAdded,\n removed: this.turnDiffRemoved,\n }),\n );\n this.turnDiffs = [];\n this.turnDiffFiles.clear();\n this.turnDiffAdded = 0;\n this.turnDiffRemoved = 0;\n }\n events.push(this.make('assistant_message_end', { messageId, usage: extractUsage(message) }));\n this.lastAssistantMessageId = messageId;\n this.currentAssistantMessageId = undefined;\n this.currentAssistantText = '';\n this.currentAssistantReviewEmitted = false;\n return events;\n }\n\n private mapToolStart(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.ensureAssistantMessageId();\n const toolName = String(event.toolName ?? 'unknown');\n this.toolCallToMessageId.set(toolCallId, messageId);\n const events: ChatStreamEvent[] = [\n this.make('tool_start', {\n messageId,\n toolCallId,\n toolName,\n args: event.args,\n }),\n ];\n if (toolName === 'exec_command') {\n const args = asRecord(event.args);\n events.push(\n this.make('command_started', {\n messageId,\n toolCallId,\n command: String(args?.cmd ?? args?.command ?? ''),\n cwd: typeof args?.cwd === 'string' ? args.cwd : undefined,\n }),\n );\n }\n return events;\n }\n\n private mapToolUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const partial = event.partialResult;\n const details = extractDetails(partial);\n const textDelta = extractText(partial);\n const toolName = String(event.toolName ?? 'unknown');\n const events: ChatStreamEvent[] = [\n this.make('tool_update', {\n messageId,\n toolCallId,\n toolName,\n details,\n textDelta,\n }),\n ];\n if (toolName === 'exec_command') {\n const rec = asRecord(details);\n if (rec?.kind === 'command_output_delta') {\n const stream = rec.stream === 'stderr' ? 'stderr' : 'stdout';\n const delta = typeof rec.delta === 'string' ? rec.delta : '';\n if (delta) {\n events.push(this.make('command_output_delta', { messageId, toolCallId, stream, delta }));\n }\n }\n }\n return events;\n }\n\n private mapToolEnd(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const result = normalizeToolResult(event.result);\n const toolName = String(event.toolName ?? 'unknown');\n const events: ChatStreamEvent[] = [\n this.make('tool_end', {\n messageId,\n toolCallId,\n toolName,\n status: event.isError ? 'error' : 'success',\n result,\n errorMessage: event.isError ? result?.text : undefined,\n }),\n ];\n const details = asRecord(result?.details);\n if (toolName === 'exec_command' && details) {\n events.push(\n this.make('command_completed', {\n messageId,\n toolCallId,\n command: typeof details.command === 'string' ? details.command : '',\n cwd: typeof details.cwd === 'string' ? details.cwd : undefined,\n exitCode: typeof details.exitCode === 'number' ? details.exitCode : null,\n durationMs: typeof details.durationMs === 'number' ? details.durationMs : undefined,\n timedOut: details.timedOut === true,\n truncated: details.truncated === true,\n }),\n );\n }\n if (toolName === 'apply_patch' && details) {\n const changes = Array.isArray(details.changes) ? details.changes : [];\n const diff = typeof details.diff === 'string' ? details.diff : '';\n const added = typeof details.added === 'number' ? details.added : 0;\n const removed = typeof details.removed === 'number' ? details.removed : 0;\n if (diff || changes.length > 0) {\n this.recordPatchDiff(details);\n events.push(this.make('patch_applied', { messageId, toolCallId, changes, diff, added, removed }));\n }\n }\n if (toolName === 'update_plan' && details) {\n const plan = extractTurnPlan(details);\n if (plan) {\n events.push(this.make('turn_plan', { messageId, ...plan }));\n }\n }\n return events;\n }\n\n private ensureAssistantMessageId(): string {\n if (!this.currentAssistantMessageId) {\n this.currentAssistantMessageId = this.nextAssistantMessageId();\n }\n return this.currentAssistantMessageId;\n }\n\n private nextAssistantMessageId(): string {\n this.assistantIndex += 1;\n return `msg_${this.opts.runId.replace(/[^a-zA-Z0-9_-]/g, '_')}_${this.assistantIndex}`;\n }\n\n private make<T extends ChatStreamEvent['type']>(\n type: T,\n payload: Extract<ChatStreamEvent, { type: T }>['payload'],\n ): Extract<ChatStreamEvent, { type: T }> {\n return {\n type,\n runId: this.opts.runId,\n sessionKey: this.opts.sessionKey,\n timestamp: Date.now(),\n payload,\n } as Extract<ChatStreamEvent, { type: T }>;\n }\n\n private recordPatchDiff(details: Record<string, unknown>): void {\n const diff = typeof details.diff === 'string' ? details.diff : '';\n if (diff) this.turnDiffs.push(diff);\n if (typeof details.added === 'number') this.turnDiffAdded += details.added;\n if (typeof details.removed === 'number') this.turnDiffRemoved += details.removed;\n const changes = Array.isArray(details.changes) ? details.changes : [];\n for (const change of changes) {\n const rec = asRecord(change);\n const path = typeof rec?.moveTo === 'string'\n ? rec.moveTo\n : typeof rec?.path === 'string'\n ? rec.path\n : undefined;\n if (path) this.turnDiffFiles.add(path);\n }\n }\n}\n\nfunction userMessageFromLegacyEvent(event: { [key: string]: unknown }): unknown {\n return {\n role: 'user',\n content: event.content ?? [],\n attachments: event.media,\n timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),\n };\n}\n\nfunction extractTextFromMessage(message: AgentMessage): string {\n return extractText((message as { content?: unknown }).content);\n}\n\nfunction extractReview(message: AgentMessage): unknown {\n const metadata = (message as { metadata?: unknown }).metadata;\n const metadataReview = asRecord(metadata)?.review;\n if (isReviewBlock(metadataReview)) return metadataReview;\n const content = (message as { content?: unknown }).content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (isReviewBlock(block)) return block;\n }\n }\n return undefined;\n}\n\nfunction isReviewBlock(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n && (value as { type?: unknown }).type === 'review';\n}\n\nfunction extractText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (!Array.isArray(value)) return undefined;\n const text = value\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const rec = block as { type?: unknown; text?: unknown };\n return rec.type === 'text' && typeof rec.text === 'string' ? rec.text : '';\n })\n .join('');\n return text || undefined;\n}\n\nfunction appendSuffix(base: string, next: string | undefined): string {\n if (!next) return '';\n if (!base) return next;\n if (next === base || base.endsWith(next)) return '';\n if (next.startsWith(base)) return next.slice(base.length);\n const max = Math.min(base.length, next.length, 512);\n for (let overlap = max; overlap > 0; overlap--) {\n if (base.slice(-overlap) === next.slice(0, overlap)) return next.slice(overlap);\n }\n return next;\n}\n\nfunction extractUsage(message: AgentMessage): AssistantMessageEndEventPayload['usage'] {\n const usage = (message as { usage?: unknown }).usage;\n if (!usage || typeof usage !== 'object') return undefined;\n const rec = usage as Record<string, unknown>;\n return {\n inputTokens: typeof rec.inputTokens === 'number' ? rec.inputTokens : undefined,\n outputTokens: typeof rec.outputTokens === 'number' ? rec.outputTokens : undefined,\n totalTokens: typeof rec.totalTokens === 'number' ? rec.totalTokens : undefined,\n cost: typeof rec.cost === 'number' ? rec.cost : undefined,\n };\n}\n\ntype AssistantMessageEndEventPayload = Extract<ChatStreamEvent, { type: 'assistant_message_end' }>['payload'];\n\nfunction extractDetails(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined;\n return (value as Record<string, unknown>).details;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction normalizeToolResult(value: unknown): ToolResultEnvelope | undefined {\n if (value == null) return undefined;\n if (typeof value === 'string') return { text: value };\n if (typeof value !== 'object') return { text: String(value) };\n const rec = value as Record<string, unknown>;\n return {\n content: Array.isArray(rec.content) ? rec.content : undefined,\n details: rec.details,\n text: extractText(rec.content) ?? (typeof rec.text === 'string' ? rec.text : undefined),\n };\n}\n\nfunction extractTurnPlan(details: Record<string, unknown>): { explanation?: string; plan: { step: string; status: 'pending' | 'in_progress' | 'completed' }[] } | undefined {\n const rawPlan = Array.isArray(details.plan) ? details.plan : [];\n const plan = rawPlan\n .map((item) => {\n const rec = asRecord(item);\n const step = typeof rec?.step === 'string' ? rec.step.trim() : '';\n const status = rec?.status;\n if (!step || (status !== 'pending' && status !== 'in_progress' && status !== 'completed')) {\n return undefined;\n }\n return { step, status };\n })\n .filter((item): item is { step: string; status: 'pending' | 'in_progress' | 'completed' } => Boolean(item));\n if (plan.length === 0) return undefined;\n const explanation = typeof details.explanation === 'string' && details.explanation.trim()\n ? details.explanation.trim()\n : undefined;\n return { explanation, plan };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mapper.js","names":["message"],"sources":["../../../../src/gateway/chat-stream/mapper.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { EmbeddedStreamEvent } from '../../agent/embedded/types.js';\nimport type { ChatStreamEvent, ChatStreamStatus } from './protocol.js';\n\nexport type RuntimeStreamEvent = EmbeddedStreamEvent | { type: string; [key: string]: unknown };\n\nexport interface ChatStreamMapperOptions {\n runId: string;\n sessionKey: string;\n channel: string;\n}\n\ntype ToolResultEnvelope = { content?: unknown[]; details?: unknown; text?: string };\n\nexport class ChatStreamMapper {\n private assistantIndex = 0;\n private currentAssistantMessageId: string | undefined;\n private lastAssistantMessageId: string | undefined;\n private currentAssistantText = '';\n private currentAssistantReviewEmitted = false;\n private toolCallToMessageId = new Map<string, string>();\n private turnDiffs: string[] = [];\n private turnDiffFiles = new Set<string>();\n private turnDiffAdded = 0;\n private turnDiffRemoved = 0;\n private started = false;\n private ended = false;\n\n constructor(private readonly opts: ChatStreamMapperOptions) {}\n\n map(input: RuntimeStreamEvent): ChatStreamEvent[] {\n const event = input as { type: string; [key: string]: unknown };\n switch (event.type) {\n case 'agent_start':\n return this.start();\n case 'agent_end':\n return [];\n case 'message_start':\n return this.mapMessageStart(event.message);\n case 'message_update':\n return this.mapMessageUpdate(event);\n case 'message_end':\n return this.mapMessageEnd(event.message);\n case 'tool_execution_start':\n return this.mapToolStart(event);\n case 'tool_execution_update':\n return this.mapToolUpdate(event);\n case 'tool_execution_end':\n return this.mapToolEnd(event);\n case 'review_start':\n return [this.make('review_start', {\n messageId: this.ensureAssistantMessageId(),\n reviewId: String(event.reviewId ?? ''),\n target: String(event.target ?? 'working tree changes'),\n stage: event.stage === 'preparing' ? 'preparing' : 'reviewing',\n })];\n case 'review_delta':\n return [this.make('review_delta', {\n messageId: this.ensureAssistantMessageId(),\n reviewId: String(event.reviewId ?? ''),\n delta: String(event.delta ?? ''),\n })];\n case 'review_end':\n return [this.make('review_end', {\n messageId: this.ensureAssistantMessageId(),\n reviewId: String(event.reviewId ?? ''),\n status: event.status === 'error' ? 'error' : 'complete',\n ...(typeof event.message === 'string' && event.message ? { message: event.message } : {}),\n })];\n case 'user_message':\n return [this.make('user_message', { message: userMessageFromLegacyEvent(event) })];\n case 'user_transcript':\n return [this.make('user_transcript', { text: String(event.text ?? ''), media: event.media })];\n case 'progress':\n return [\n this.make('progress', {\n stage: String(event.stage ?? ''),\n message: String(event.message ?? ''),\n ...(typeof event.detail === 'string' ? { detail: event.detail } : {}),\n ...(typeof event.toolName === 'string' ? { toolName: event.toolName } : {}),\n ...(typeof event.completed === 'number' ? { completed: event.completed } : {}),\n ...(typeof event.total === 'number' ? { total: event.total } : {}),\n }),\n ];\n case 'compaction':\n return [\n this.make('compaction', {\n status: event.status === 'completed' || event.status === 'skipped' ? event.status : 'started',\n tokensBefore: typeof event.tokensBefore === 'number' ? event.tokensBefore : undefined,\n tokensAfter: typeof event.tokensAfter === 'number' ? event.tokensAfter : undefined,\n summary: typeof event.summary === 'string' ? event.summary : undefined,\n }),\n ];\n case 'tts_audio':\n return [\n this.make('tts_audio', {\n uri: String(event.uri ?? ''),\n mimeType: String(event.mimeType ?? 'audio/mpeg'),\n name: String(event.name ?? 'voice.mp3'),\n attachTo: 'last_assistant',\n ...(this.lastAssistantMessageId ? { messageId: this.lastAssistantMessageId } : {}),\n }),\n ];\n case 'clarify_request':\n return [\n this.make('clarify_request', {\n requestId: String(event.requestId ?? ''),\n question: String(event.question ?? ''),\n choices: Array.isArray(event.choices) ? event.choices.filter((x): x is string => typeof x === 'string') : undefined,\n default: typeof event.default === 'string' ? event.default : undefined,\n }),\n ];\n case 'memory_consent_required':\n return [\n this.make('memory_consent_required', {\n requests: Array.isArray(event.requests)\n ? event.requests.flatMap((raw) => {\n if (!raw || typeof raw !== 'object') return [];\n const request = raw as Record<string, unknown>;\n const id = typeof request.id === 'string' ? request.id : '';\n const recordId = typeof request.recordId === 'string' ? request.recordId : '';\n const statement = typeof request.statement === 'string' ? request.statement : '';\n const purpose = typeof request.purpose === 'string' ? request.purpose : '';\n return id && recordId && statement ? [{ id, recordId, statement, purpose }] : [];\n })\n : [],\n }),\n ];\n case 'memory_captured':\n return [\n this.make('memory_captured', {\n records: Array.isArray(event.records)\n ? event.records.flatMap((raw) => {\n if (!raw || typeof raw !== 'object') return [];\n const record = raw as Record<string, unknown>;\n const id = typeof record.id === 'string' ? record.id : '';\n const content = typeof record.content === 'string' ? record.content : '';\n const kind = typeof record.kind === 'string' ? record.kind : '';\n return id && content ? [{ id, content, kind }] : [];\n })\n : [],\n }),\n ];\n case 'error':\n return [this.make('error', { code: 'AGENT_RUN_ERROR', message: String(event.content ?? event.message ?? 'Unknown error') })];\n default:\n return [];\n }\n }\n\n start(): ChatStreamEvent[] {\n if (this.started) return [];\n this.started = true;\n return [this.make('run_start', { channel: this.opts.channel })];\n }\n\n end(status: ChatStreamStatus, summary?: string): ChatStreamEvent[] {\n if (this.ended) return [];\n this.ended = true;\n return [this.make('run_end', { status, summary })];\n }\n\n error(message: string, code = 'AGENT_RUN_ERROR'): ChatStreamEvent[] {\n return [this.make('error', { code, message })];\n }\n\n private mapMessageStart(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.nextAssistantMessageId();\n this.currentAssistantMessageId = messageId;\n this.currentAssistantText = '';\n this.currentAssistantReviewEmitted = false;\n return [this.make('assistant_message_start', { messageId })];\n }\n\n private mapMessageUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const message = event.message as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const review = extractReview(message);\n if (review && !this.currentAssistantReviewEmitted) {\n this.currentAssistantReviewEmitted = true;\n return [this.make('review', { messageId, review })];\n }\n const delta = event.assistantMessageEvent as { type?: unknown; delta?: unknown } | undefined;\n if (delta?.type === 'text_delta' && typeof delta.delta === 'string' && delta.delta) {\n const text = extractTextFromMessage(message);\n const suffixFromMessage = appendSuffix(this.currentAssistantText, text);\n const suffix = text ? suffixFromMessage : appendSuffix(this.currentAssistantText, delta.delta);\n if (!suffix) {\n if (text) this.currentAssistantText = text;\n return [];\n }\n this.currentAssistantText = text || `${this.currentAssistantText}${suffix}`;\n return [this.make('assistant_delta', { messageId, delta: suffix })];\n }\n if (delta?.type === 'thinking_delta' && typeof delta.delta === 'string' && delta.delta) {\n return [this.make('thinking_delta', { messageId, delta: delta.delta })];\n }\n\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n this.currentAssistantText = text || this.currentAssistantText;\n return suffix ? [this.make('assistant_delta', { messageId, delta: suffix })] : [];\n }\n\n private mapMessageEnd(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const events: ChatStreamEvent[] = [];\n const review = extractReview(message);\n if (review && !this.currentAssistantReviewEmitted) {\n this.currentAssistantReviewEmitted = true;\n events.push(this.make('review', { messageId, review }));\n }\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n if (suffix) events.push(this.make('assistant_delta', { messageId, delta: suffix }));\n this.currentAssistantText = text || this.currentAssistantText;\n events.push(this.make('thinking_end', { messageId }));\n if (this.turnDiffs.length > 0) {\n events.push(\n this.make('turn_diff', {\n messageId,\n files: [...this.turnDiffFiles],\n diff: this.turnDiffs.join('\\n'),\n added: this.turnDiffAdded,\n removed: this.turnDiffRemoved,\n }),\n );\n this.turnDiffs = [];\n this.turnDiffFiles.clear();\n this.turnDiffAdded = 0;\n this.turnDiffRemoved = 0;\n }\n events.push(this.make('assistant_message_end', { messageId, usage: extractUsage(message) }));\n this.lastAssistantMessageId = messageId;\n this.currentAssistantMessageId = undefined;\n this.currentAssistantText = '';\n this.currentAssistantReviewEmitted = false;\n return events;\n }\n\n private mapToolStart(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.ensureAssistantMessageId();\n const toolName = String(event.toolName ?? 'unknown');\n this.toolCallToMessageId.set(toolCallId, messageId);\n const events: ChatStreamEvent[] = [\n this.make('tool_start', {\n messageId,\n toolCallId,\n toolName,\n args: event.args,\n }),\n ];\n if (toolName === 'exec_command') {\n const args = asRecord(event.args);\n events.push(\n this.make('command_started', {\n messageId,\n toolCallId,\n command: String(args?.cmd ?? args?.command ?? ''),\n cwd: typeof args?.cwd === 'string' ? args.cwd : undefined,\n }),\n );\n }\n return events;\n }\n\n private mapToolUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const partial = event.partialResult;\n const details = extractDetails(partial);\n const textDelta = extractText(partial);\n const toolName = String(event.toolName ?? 'unknown');\n const events: ChatStreamEvent[] = [\n this.make('tool_update', {\n messageId,\n toolCallId,\n toolName,\n details,\n textDelta,\n }),\n ];\n if (toolName === 'exec_command') {\n const rec = asRecord(details);\n if (rec?.kind === 'command_output_delta') {\n const stream = rec.stream === 'stderr' ? 'stderr' : 'stdout';\n const delta = typeof rec.delta === 'string' ? rec.delta : '';\n if (delta) {\n events.push(this.make('command_output_delta', { messageId, toolCallId, stream, delta }));\n }\n }\n }\n return events;\n }\n\n private mapToolEnd(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const result = normalizeToolResult(event.result);\n const toolName = String(event.toolName ?? 'unknown');\n const events: ChatStreamEvent[] = [\n this.make('tool_end', {\n messageId,\n toolCallId,\n toolName,\n status: event.isError ? 'error' : 'success',\n result,\n errorMessage: event.isError ? result?.text : undefined,\n }),\n ];\n const details = asRecord(result?.details);\n if (toolName === 'exec_command' && details) {\n events.push(\n this.make('command_completed', {\n messageId,\n toolCallId,\n command: typeof details.command === 'string' ? details.command : '',\n cwd: typeof details.cwd === 'string' ? details.cwd : undefined,\n exitCode: typeof details.exitCode === 'number' ? details.exitCode : null,\n durationMs: typeof details.durationMs === 'number' ? details.durationMs : undefined,\n timedOut: details.timedOut === true,\n truncated: details.truncated === true,\n }),\n );\n }\n if (toolName === 'apply_patch' && details) {\n const changes = Array.isArray(details.changes) ? details.changes : [];\n const diff = typeof details.diff === 'string' ? details.diff : '';\n const added = typeof details.added === 'number' ? details.added : 0;\n const removed = typeof details.removed === 'number' ? details.removed : 0;\n if (diff || changes.length > 0) {\n this.recordPatchDiff(details);\n events.push(this.make('patch_applied', { messageId, toolCallId, changes, diff, added, removed }));\n }\n }\n if (toolName === 'update_plan' && details) {\n const plan = extractTurnPlan(details);\n if (plan) {\n events.push(this.make('turn_plan', { messageId, ...plan }));\n }\n }\n return events;\n }\n\n private ensureAssistantMessageId(): string {\n if (!this.currentAssistantMessageId) {\n this.currentAssistantMessageId = this.nextAssistantMessageId();\n }\n return this.currentAssistantMessageId;\n }\n\n private nextAssistantMessageId(): string {\n this.assistantIndex += 1;\n return `msg_${this.opts.runId.replace(/[^a-zA-Z0-9_-]/g, '_')}_${this.assistantIndex}`;\n }\n\n private make<T extends ChatStreamEvent['type']>(\n type: T,\n payload: Extract<ChatStreamEvent, { type: T }>['payload'],\n ): Extract<ChatStreamEvent, { type: T }> {\n return {\n type,\n runId: this.opts.runId,\n sessionKey: this.opts.sessionKey,\n timestamp: Date.now(),\n payload,\n } as Extract<ChatStreamEvent, { type: T }>;\n }\n\n private recordPatchDiff(details: Record<string, unknown>): void {\n const diff = typeof details.diff === 'string' ? details.diff : '';\n if (diff) this.turnDiffs.push(diff);\n if (typeof details.added === 'number') this.turnDiffAdded += details.added;\n if (typeof details.removed === 'number') this.turnDiffRemoved += details.removed;\n const changes = Array.isArray(details.changes) ? details.changes : [];\n for (const change of changes) {\n const rec = asRecord(change);\n const path = typeof rec?.moveTo === 'string'\n ? rec.moveTo\n : typeof rec?.path === 'string'\n ? rec.path\n : undefined;\n if (path) this.turnDiffFiles.add(path);\n }\n }\n}\n\nfunction userMessageFromLegacyEvent(event: { [key: string]: unknown }): unknown {\n return {\n role: 'user',\n content: event.content ?? [],\n attachments: event.media,\n timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),\n };\n}\n\nfunction extractTextFromMessage(message: AgentMessage): string {\n return extractText((message as { content?: unknown }).content);\n}\n\nfunction extractReview(message: AgentMessage): unknown {\n const metadata = (message as { metadata?: unknown }).metadata;\n const metadataReview = asRecord(metadata)?.review;\n if (isReviewBlock(metadataReview)) return metadataReview;\n const content = (message as { content?: unknown }).content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (isReviewBlock(block)) return block;\n }\n }\n return undefined;\n}\n\nfunction isReviewBlock(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n && (value as { type?: unknown }).type === 'review';\n}\n\nfunction extractText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (!Array.isArray(value)) return undefined;\n const text = value\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const rec = block as { type?: unknown; text?: unknown };\n return rec.type === 'text' && typeof rec.text === 'string' ? rec.text : '';\n })\n .join('');\n return text || undefined;\n}\n\nfunction appendSuffix(base: string, next: string | undefined): string {\n if (!next) return '';\n if (!base) return next;\n if (next === base || base.endsWith(next)) return '';\n if (next.startsWith(base)) return next.slice(base.length);\n const max = Math.min(base.length, next.length, 512);\n for (let overlap = max; overlap > 0; overlap--) {\n if (base.slice(-overlap) === next.slice(0, overlap)) return next.slice(overlap);\n }\n return next;\n}\n\nfunction extractUsage(message: AgentMessage): AssistantMessageEndEventPayload['usage'] {\n const usage = (message as { usage?: unknown }).usage;\n if (!usage || typeof usage !== 'object') return undefined;\n const rec = usage as Record<string, unknown>;\n return {\n inputTokens: typeof rec.inputTokens === 'number' ? rec.inputTokens : undefined,\n outputTokens: typeof rec.outputTokens === 'number' ? rec.outputTokens : undefined,\n totalTokens: typeof rec.totalTokens === 'number' ? rec.totalTokens : undefined,\n cost: typeof rec.cost === 'number' ? rec.cost : undefined,\n };\n}\n\ntype AssistantMessageEndEventPayload = Extract<ChatStreamEvent, { type: 'assistant_message_end' }>['payload'];\n\nfunction extractDetails(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined;\n return (value as Record<string, unknown>).details;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction normalizeToolResult(value: unknown): ToolResultEnvelope | undefined {\n if (value == null) return undefined;\n if (typeof value === 'string') return { text: value };\n if (typeof value !== 'object') return { text: String(value) };\n const rec = value as Record<string, unknown>;\n return {\n content: Array.isArray(rec.content) ? rec.content : undefined,\n details: rec.details,\n text: extractText(rec.content) ?? (typeof rec.text === 'string' ? rec.text : undefined),\n };\n}\n\nfunction extractTurnPlan(details: Record<string, unknown>): { explanation?: string; plan: { step: string; status: 'pending' | 'in_progress' | 'completed' }[] } | undefined {\n const rawPlan = Array.isArray(details.plan) ? details.plan : [];\n const plan = rawPlan\n .map((item) => {\n const rec = asRecord(item);\n const step = typeof rec?.step === 'string' ? rec.step.trim() : '';\n const status = rec?.status;\n if (!step || (status !== 'pending' && status !== 'in_progress' && status !== 'completed')) {\n return undefined;\n }\n return { step, status };\n })\n .filter((item): item is { step: string; status: 'pending' | 'in_progress' | 'completed' } => Boolean(item));\n if (plan.length === 0) return undefined;\n const explanation = typeof details.explanation === 'string' && details.explanation.trim()\n ? details.explanation.trim()\n : undefined;\n return { explanation, plan };\n}\n"],"mappings":"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"}
@@ -159,6 +159,21 @@ export type ClarifyRequestEvent = ChatStreamEnvelope<'clarify_request', {
159
159
  choices?: string[];
160
160
  default?: string;
161
161
  }>;
162
+ export type MemoryConsentRequiredEvent = ChatStreamEnvelope<'memory_consent_required', {
163
+ requests: Array<{
164
+ id: string;
165
+ recordId: string;
166
+ statement: string;
167
+ purpose: string;
168
+ }>;
169
+ }>;
170
+ export type MemoryCapturedEvent = ChatStreamEnvelope<'memory_captured', {
171
+ records: Array<{
172
+ id: string;
173
+ content: string;
174
+ kind: string;
175
+ }>;
176
+ }>;
162
177
  export type RunEndEvent = ChatStreamEnvelope<'run_end', {
163
178
  status: ChatStreamStatus;
164
179
  summary?: string;
@@ -168,4 +183,4 @@ export type StreamErrorEvent = ChatStreamEnvelope<'error', {
168
183
  message: string;
169
184
  recoverable?: boolean;
170
185
  }>;
171
- export type ChatStreamEvent = RunStartEvent | UserMessageEvent | UserTranscriptEvent | AssistantMessageStartEvent | AssistantDeltaEvent | ThinkingDeltaEvent | ThinkingEndEvent | ToolStartEvent | ToolUpdateEvent | ToolEndEvent | CommandStartedEvent | CommandOutputDeltaEvent | CommandCompletedEvent | PatchAppliedEvent | TurnPlanUpdatedEvent | TurnDiffEvent | ReviewStartEvent | ReviewDeltaEvent | ReviewEndEvent | ReviewEvent | AssistantMessageEndEvent | ProgressEvent | CompactionEvent | TtsAudioEvent | ClarifyRequestEvent | RunEndEvent | StreamErrorEvent;
186
+ export type ChatStreamEvent = RunStartEvent | UserMessageEvent | UserTranscriptEvent | AssistantMessageStartEvent | AssistantDeltaEvent | ThinkingDeltaEvent | ThinkingEndEvent | ToolStartEvent | ToolUpdateEvent | ToolEndEvent | CommandStartedEvent | CommandOutputDeltaEvent | CommandCompletedEvent | PatchAppliedEvent | TurnPlanUpdatedEvent | TurnDiffEvent | ReviewStartEvent | ReviewDeltaEvent | ReviewEndEvent | ReviewEvent | AssistantMessageEndEvent | ProgressEvent | CompactionEvent | TtsAudioEvent | ClarifyRequestEvent | MemoryConsentRequiredEvent | MemoryCapturedEvent | RunEndEvent | StreamErrorEvent;
@@ -4,7 +4,6 @@ export type DreamingAutomationReconcileResult = {
4
4
  created: string[];
5
5
  updated: string[];
6
6
  disabled: string[];
7
- removed: string[];
8
7
  };
9
8
  export declare function reconcileDreamingAutomations(params: {
10
9
  config: Config;
@@ -1,24 +1,19 @@
1
- import { init_agent_scope, normalizeAgentId } from "../agent/agent-scope.js";
2
1
  import { DREAMING_CRON_NAME, DREAMING_CRON_TAG, DREAMING_LIGHT_CRON_NAME, DREAMING_LIGHT_SWEEP_TOKEN, DREAMING_REM_CRON_NAME, DREAMING_REM_SWEEP_TOKEN, DREAMING_SWEEP_TOKEN } from "../agent/memory/dreaming/constants.js";
3
2
  import { resolveDreamingConfig } from "../agent/memory/dreaming/config.js";
4
3
  import { resolveDreamingAgentScope } from "../agent/memory/dreaming/scope.js";
5
4
  //#region src/gateway/dreaming-automation-reconciler.ts
6
- init_agent_scope();
7
5
  const DREAMING_AUTOMATIONS = [
8
6
  {
9
- id: "system-dreaming-light",
10
7
  phase: "light",
11
8
  name: DREAMING_LIGHT_CRON_NAME,
12
9
  token: DREAMING_LIGHT_SWEEP_TOKEN
13
10
  },
14
11
  {
15
- id: "system-dreaming-deep",
16
12
  phase: "deep",
17
13
  name: DREAMING_CRON_NAME,
18
14
  token: DREAMING_SWEEP_TOKEN
19
15
  },
20
16
  {
21
- id: "system-dreaming-rem",
22
17
  phase: "rem",
23
18
  name: DREAMING_REM_CRON_NAME,
24
19
  token: DREAMING_REM_SWEEP_TOKEN
@@ -37,11 +32,11 @@ function buildTrigger(config, phase) {
37
32
  }
38
33
  };
39
34
  }
40
- function dreamingAutomationId(agentId, phase) {
41
- return `system-dreaming:${normalizeAgentId(agentId)}:${phase}`;
35
+ function dreamingAutomationId(phase) {
36
+ return `system-user-context-dreaming:${phase}`;
42
37
  }
43
- function buildAction(config, agentId, token) {
44
- const scope = resolveDreamingAgentScope(config, agentId);
38
+ function buildAction(config, token) {
39
+ const scope = resolveDreamingAgentScope(config);
45
40
  return {
46
41
  kind: "agent",
47
42
  agentId: scope.agentId,
@@ -58,63 +53,46 @@ async function reconcileDreamingAutomations(params) {
58
53
  const result = {
59
54
  created: [],
60
55
  updated: [],
61
- disabled: [],
62
- removed: []
56
+ disabled: []
63
57
  };
64
- for (const spec of DREAMING_AUTOMATIONS) if (await automationService.remove(spec.id)) result.removed.push(spec.id);
65
- const expectedIds = /* @__PURE__ */ new Set();
66
- const agents = config.agents.list.filter((agent) => agent.enabled !== false);
67
- for (const agent of agents) {
68
- const agentId = normalizeAgentId(agent.id);
69
- const resolved = resolveDreamingConfig(config, agentId);
70
- for (const spec of DREAMING_AUTOMATIONS) {
71
- const id = dreamingAutomationId(agentId, spec.phase);
72
- expectedIds.add(id);
73
- const current = await automationService.get(id);
74
- const enabled = resolved.enabled && resolved.phases[spec.phase].enabled;
75
- if (!resolved.enabled) {
76
- if (current?.enabled) {
77
- await automationService.update(id, { enabled: false });
78
- result.disabled.push(id);
79
- }
80
- continue;
81
- }
82
- const next = {
83
- name: `${spec.name} (${agentId})`,
84
- description: phaseDescription(spec.phase),
85
- enabled,
86
- trigger: buildTrigger(resolved, spec.phase),
87
- action: buildAction(config, agentId, spec.token)
88
- };
89
- if (!current) {
90
- await automationService.create({
91
- id,
92
- ...next,
93
- safety: { mode: "auto_apply" },
94
- afterRun: { kind: "none" },
95
- reliability: { disableAfterConsecutiveFailures: 3 }
96
- });
97
- result.created.push(id);
98
- continue;
99
- }
100
- if (automationNeedsUpdate(current, next)) {
101
- await automationService.update(id, {
102
- ...next,
103
- safety: { mode: "auto_apply" },
104
- afterRun: { kind: "none" },
105
- reliability: { disableAfterConsecutiveFailures: 3 }
106
- });
107
- result.updated.push(id);
58
+ const resolved = resolveDreamingConfig(config);
59
+ for (const spec of DREAMING_AUTOMATIONS) {
60
+ const id = dreamingAutomationId(spec.phase);
61
+ const current = await automationService.get(id);
62
+ const enabled = resolved.enabled && resolved.phases[spec.phase].enabled;
63
+ if (!resolved.enabled) {
64
+ if (current?.enabled) {
65
+ await automationService.update(id, { enabled: false });
66
+ result.disabled.push(id);
108
67
  }
68
+ continue;
109
69
  }
110
- }
111
- const allAutomations = await automationService.list();
112
- for (const automation of allAutomations) {
113
- if (!automation.id.startsWith("system-dreaming:")) continue;
114
- if (expectedIds.has(automation.id)) continue;
115
- if (automation.enabled) {
116
- await automationService.update(automation.id, { enabled: false });
117
- result.disabled.push(automation.id);
70
+ const next = {
71
+ name: spec.name,
72
+ description: phaseDescription(spec.phase),
73
+ enabled,
74
+ trigger: buildTrigger(resolved, spec.phase),
75
+ action: buildAction(config, spec.token)
76
+ };
77
+ if (!current) {
78
+ await automationService.create({
79
+ id,
80
+ ...next,
81
+ safety: { mode: "auto_apply" },
82
+ afterRun: { kind: "none" },
83
+ reliability: { disableAfterConsecutiveFailures: 3 }
84
+ });
85
+ result.created.push(id);
86
+ continue;
87
+ }
88
+ if (automationNeedsUpdate(current, next)) {
89
+ await automationService.update(id, {
90
+ ...next,
91
+ safety: { mode: "auto_apply" },
92
+ afterRun: { kind: "none" },
93
+ reliability: { disableAfterConsecutiveFailures: 3 }
94
+ });
95
+ result.updated.push(id);
118
96
  }
119
97
  }
120
98
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"dreaming-automation-reconciler.js","names":[],"sources":["../../../src/gateway/dreaming-automation-reconciler.ts"],"sourcesContent":["import type { Config } from '../config/schema.js';\nimport { normalizeAgentId } from '../agent/agent-scope.js';\nimport { resolveDreamingConfig, type DreamingResolvedConfig } from '../agent/memory/dreaming/config.js';\nimport { resolveDreamingAgentScope } from '../agent/memory/dreaming/scope.js';\nimport {\n DREAMING_CRON_NAME,\n DREAMING_CRON_TAG,\n DREAMING_LIGHT_CRON_NAME,\n DREAMING_LIGHT_SWEEP_TOKEN,\n DREAMING_REM_CRON_NAME,\n DREAMING_REM_SWEEP_TOKEN,\n DREAMING_SWEEP_TOKEN,\n type DreamingPhaseId,\n} from '../agent/memory/dreaming/constants.js';\nimport type { AutomationService } from '../automations/index.js';\nimport type { Automation, AutomationAction, AutomationTrigger } from '../automations/domain/types.js';\n\ntype DreamingAutomationSpec = {\n id: string;\n phase: DreamingPhaseId;\n name: string;\n token: string;\n};\n\nconst DREAMING_AUTOMATIONS: readonly DreamingAutomationSpec[] = [\n {\n id: 'system-dreaming-light',\n phase: 'light',\n name: DREAMING_LIGHT_CRON_NAME,\n token: DREAMING_LIGHT_SWEEP_TOKEN,\n },\n {\n id: 'system-dreaming-deep',\n phase: 'deep',\n name: DREAMING_CRON_NAME,\n token: DREAMING_SWEEP_TOKEN,\n },\n {\n id: 'system-dreaming-rem',\n phase: 'rem',\n name: DREAMING_REM_CRON_NAME,\n token: DREAMING_REM_SWEEP_TOKEN,\n },\n];\n\nexport type DreamingAutomationReconcileResult = {\n created: string[];\n updated: string[];\n disabled: string[];\n removed: string[];\n};\n\nfunction phaseDescription(phase: DreamingPhaseId): string {\n const label = phase === 'light' ? 'Light sweep' : phase === 'deep' ? 'Deep promotion' : 'REM pattern discovery';\n return `${label} for memory dreaming. ${DREAMING_CRON_TAG}`;\n}\n\nfunction buildTrigger(config: DreamingResolvedConfig, phase: DreamingPhaseId): AutomationTrigger {\n const phaseConfig = config.phases[phase];\n return {\n kind: 'schedule',\n schedule: {\n kind: 'cron',\n expr: phaseConfig.cron,\n ...(config.timezone ? { tz: config.timezone } : {}),\n },\n };\n}\n\nfunction dreamingAutomationId(agentId: string, phase: DreamingPhaseId): string {\n return `system-dreaming:${normalizeAgentId(agentId)}:${phase}`;\n}\n\nfunction buildAction(config: Config, agentId: string, token: string): AutomationAction {\n const scope = resolveDreamingAgentScope(config, agentId);\n return {\n kind: 'agent',\n agentId: scope.agentId,\n instruction: token,\n workingDirectory: scope.workspaceDir,\n timeoutSeconds: 3600,\n };\n}\n\nfunction automationNeedsUpdate(current: Automation, next: {\n name: string;\n description: string;\n enabled: boolean;\n trigger: AutomationTrigger;\n action: AutomationAction;\n}): boolean {\n return (\n current.name !== next.name ||\n current.description !== next.description ||\n current.enabled !== next.enabled ||\n JSON.stringify(current.trigger) !== JSON.stringify(next.trigger) ||\n JSON.stringify(current.action) !== JSON.stringify(next.action) ||\n current.safety?.mode !== 'auto_apply' ||\n current.afterRun?.kind !== 'none' ||\n current.reliability?.disableAfterConsecutiveFailures !== 3\n );\n}\n\nexport async function reconcileDreamingAutomations(params: {\n config: Config;\n automationService: AutomationService;\n}): Promise<DreamingAutomationReconcileResult> {\n const { config, automationService } = params;\n const result: DreamingAutomationReconcileResult = { created: [], updated: [], disabled: [], removed: [] };\n\n for (const spec of DREAMING_AUTOMATIONS) {\n if (await automationService.remove(spec.id)) {\n result.removed.push(spec.id);\n }\n }\n\n const expectedIds = new Set<string>();\n const agents = config.agents.list.filter((agent) => agent.enabled !== false);\n\n for (const agent of agents) {\n const agentId = normalizeAgentId(agent.id);\n const resolved = resolveDreamingConfig(config, agentId);\n\n for (const spec of DREAMING_AUTOMATIONS) {\n const id = dreamingAutomationId(agentId, spec.phase);\n expectedIds.add(id);\n const current = await automationService.get(id);\n const enabled = resolved.enabled && resolved.phases[spec.phase].enabled;\n\n if (!resolved.enabled) {\n if (current?.enabled) {\n await automationService.update(id, { enabled: false });\n result.disabled.push(id);\n }\n continue;\n }\n\n const next = {\n name: `${spec.name} (${agentId})`,\n description: phaseDescription(spec.phase),\n enabled,\n trigger: buildTrigger(resolved, spec.phase),\n action: buildAction(config, agentId, spec.token),\n };\n\n if (!current) {\n await automationService.create({\n id,\n ...next,\n safety: { mode: 'auto_apply' },\n afterRun: { kind: 'none' },\n reliability: { disableAfterConsecutiveFailures: 3 },\n });\n result.created.push(id);\n continue;\n }\n\n if (automationNeedsUpdate(current, next)) {\n await automationService.update(id, {\n ...next,\n safety: { mode: 'auto_apply' },\n afterRun: { kind: 'none' },\n reliability: { disableAfterConsecutiveFailures: 3 },\n });\n result.updated.push(id);\n }\n }\n }\n\n const allAutomations = await automationService.list();\n for (const automation of allAutomations) {\n if (!automation.id.startsWith('system-dreaming:')) {\n continue;\n }\n if (expectedIds.has(automation.id)) {\n continue;\n }\n if (automation.enabled) {\n await automationService.update(automation.id, { enabled: false });\n result.disabled.push(automation.id);\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dreaming-automation-reconciler.js","names":[],"sources":["../../../src/gateway/dreaming-automation-reconciler.ts"],"sourcesContent":["import type { Config } from '../config/schema.js';\nimport { resolveDreamingConfig, type DreamingResolvedConfig } from '../agent/memory/dreaming/config.js';\nimport { resolveDreamingAgentScope } from '../agent/memory/dreaming/scope.js';\nimport {\n DREAMING_CRON_NAME,\n DREAMING_CRON_TAG,\n DREAMING_LIGHT_CRON_NAME,\n DREAMING_LIGHT_SWEEP_TOKEN,\n DREAMING_REM_CRON_NAME,\n DREAMING_REM_SWEEP_TOKEN,\n DREAMING_SWEEP_TOKEN,\n type DreamingPhaseId,\n} from '../agent/memory/dreaming/constants.js';\nimport type { AutomationService } from '../automations/index.js';\nimport type { Automation, AutomationAction, AutomationTrigger } from '../automations/domain/types.js';\n\ntype DreamingAutomationSpec = {\n phase: DreamingPhaseId;\n name: string;\n token: string;\n};\n\nconst DREAMING_AUTOMATIONS: readonly DreamingAutomationSpec[] = [\n {\n phase: 'light',\n name: DREAMING_LIGHT_CRON_NAME,\n token: DREAMING_LIGHT_SWEEP_TOKEN,\n },\n {\n phase: 'deep',\n name: DREAMING_CRON_NAME,\n token: DREAMING_SWEEP_TOKEN,\n },\n {\n phase: 'rem',\n name: DREAMING_REM_CRON_NAME,\n token: DREAMING_REM_SWEEP_TOKEN,\n },\n];\n\nexport type DreamingAutomationReconcileResult = {\n created: string[];\n updated: string[];\n disabled: string[];\n};\n\nfunction phaseDescription(phase: DreamingPhaseId): string {\n const label = phase === 'light' ? 'Light sweep' : phase === 'deep' ? 'Deep promotion' : 'REM pattern discovery';\n return `${label} for memory dreaming. ${DREAMING_CRON_TAG}`;\n}\n\nfunction buildTrigger(config: DreamingResolvedConfig, phase: DreamingPhaseId): AutomationTrigger {\n const phaseConfig = config.phases[phase];\n return {\n kind: 'schedule',\n schedule: {\n kind: 'cron',\n expr: phaseConfig.cron,\n ...(config.timezone ? { tz: config.timezone } : {}),\n },\n };\n}\n\nfunction dreamingAutomationId(phase: DreamingPhaseId): string {\n return `system-user-context-dreaming:${phase}`;\n}\n\nfunction buildAction(config: Config, token: string): AutomationAction {\n const scope = resolveDreamingAgentScope(config);\n return {\n kind: 'agent',\n agentId: scope.agentId,\n instruction: token,\n workingDirectory: scope.workspaceDir,\n timeoutSeconds: 3600,\n };\n}\n\nfunction automationNeedsUpdate(current: Automation, next: {\n name: string;\n description: string;\n enabled: boolean;\n trigger: AutomationTrigger;\n action: AutomationAction;\n}): boolean {\n return (\n current.name !== next.name ||\n current.description !== next.description ||\n current.enabled !== next.enabled ||\n JSON.stringify(current.trigger) !== JSON.stringify(next.trigger) ||\n JSON.stringify(current.action) !== JSON.stringify(next.action) ||\n current.safety?.mode !== 'auto_apply' ||\n current.afterRun?.kind !== 'none' ||\n current.reliability?.disableAfterConsecutiveFailures !== 3\n );\n}\n\nexport async function reconcileDreamingAutomations(params: {\n config: Config;\n automationService: AutomationService;\n}): Promise<DreamingAutomationReconcileResult> {\n const { config, automationService } = params;\n const result: DreamingAutomationReconcileResult = { created: [], updated: [], disabled: [] };\n\n const resolved = resolveDreamingConfig(config);\n\n for (const spec of DREAMING_AUTOMATIONS) {\n const id = dreamingAutomationId(spec.phase);\n const current = await automationService.get(id);\n const enabled = resolved.enabled && resolved.phases[spec.phase].enabled;\n\n if (!resolved.enabled) {\n if (current?.enabled) {\n await automationService.update(id, { enabled: false });\n result.disabled.push(id);\n }\n continue;\n }\n\n const next = {\n name: spec.name,\n description: phaseDescription(spec.phase),\n enabled,\n trigger: buildTrigger(resolved, spec.phase),\n action: buildAction(config, spec.token),\n };\n\n if (!current) {\n await automationService.create({\n id,\n ...next,\n safety: { mode: 'auto_apply' },\n afterRun: { kind: 'none' },\n reliability: { disableAfterConsecutiveFailures: 3 },\n });\n result.created.push(id);\n continue;\n }\n\n if (automationNeedsUpdate(current, next)) {\n await automationService.update(id, {\n ...next,\n safety: { mode: 'auto_apply' },\n afterRun: { kind: 'none' },\n reliability: { disableAfterConsecutiveFailures: 3 },\n });\n result.updated.push(id);\n }\n }\n\n return result;\n}\n"],"mappings":";;;;AAsBA,MAAM,uBAA0D;CAC9D;EACE,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACD;EACE,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACD;EACE,OAAO;EACP,MAAM;EACN,OAAO;EACR;CACF;AAQD,SAAS,iBAAiB,OAAgC;AAExD,QAAO,GADO,UAAU,UAAU,gBAAgB,UAAU,SAAS,mBAAmB,wBACxE,wBAAwB;;AAG1C,SAAS,aAAa,QAAgC,OAA2C;AAE/F,QAAO;EACL,MAAM;EACN,UAAU;GACR,MAAM;GACN,MALgB,OAAO,OAAO,OAKZ;GAClB,GAAI,OAAO,WAAW,EAAE,IAAI,OAAO,UAAU,GAAG,EAAE;GACnD;EACF;;AAGH,SAAS,qBAAqB,OAAgC;AAC5D,QAAO,gCAAgC;;AAGzC,SAAS,YAAY,QAAgB,OAAiC;CACpE,MAAM,QAAQ,0BAA0B,OAAO;AAC/C,QAAO;EACL,MAAM;EACN,SAAS,MAAM;EACf,aAAa;EACb,kBAAkB,MAAM;EACxB,gBAAgB;EACjB;;AAGH,SAAS,sBAAsB,SAAqB,MAMxC;AACV,QACE,QAAQ,SAAS,KAAK,QACtB,QAAQ,gBAAgB,KAAK,eAC7B,QAAQ,YAAY,KAAK,WACzB,KAAK,UAAU,QAAQ,QAAQ,KAAK,KAAK,UAAU,KAAK,QAAQ,IAChE,KAAK,UAAU,QAAQ,OAAO,KAAK,KAAK,UAAU,KAAK,OAAO,IAC9D,QAAQ,QAAQ,SAAS,gBACzB,QAAQ,UAAU,SAAS,UAC3B,QAAQ,aAAa,oCAAoC;;AAI7D,eAAsB,6BAA6B,QAGJ;CAC7C,MAAM,EAAE,QAAQ,sBAAsB;CACtC,MAAM,SAA4C;EAAE,SAAS,EAAE;EAAE,SAAS,EAAE;EAAE,UAAU,EAAE;EAAE;CAE5F,MAAM,WAAW,sBAAsB,OAAO;AAE9C,MAAK,MAAM,QAAQ,sBAAsB;EACvC,MAAM,KAAK,qBAAqB,KAAK,MAAM;EAC3C,MAAM,UAAU,MAAM,kBAAkB,IAAI,GAAG;EAC/C,MAAM,UAAU,SAAS,WAAW,SAAS,OAAO,KAAK,OAAO;AAEhE,MAAI,CAAC,SAAS,SAAS;AACrB,OAAI,SAAS,SAAS;AACpB,UAAM,kBAAkB,OAAO,IAAI,EAAE,SAAS,OAAO,CAAC;AACtD,WAAO,SAAS,KAAK,GAAG;;AAE1B;;EAGF,MAAM,OAAO;GACX,MAAM,KAAK;GACX,aAAa,iBAAiB,KAAK,MAAM;GACzC;GACA,SAAS,aAAa,UAAU,KAAK,MAAM;GAC3C,QAAQ,YAAY,QAAQ,KAAK,MAAM;GACxC;AAED,MAAI,CAAC,SAAS;AACZ,SAAM,kBAAkB,OAAO;IAC7B;IACA,GAAG;IACH,QAAQ,EAAE,MAAM,cAAc;IAC9B,UAAU,EAAE,MAAM,QAAQ;IAC1B,aAAa,EAAE,iCAAiC,GAAG;IACpD,CAAC;AACF,UAAO,QAAQ,KAAK,GAAG;AACvB;;AAGF,MAAI,sBAAsB,SAAS,KAAK,EAAE;AACxC,SAAM,kBAAkB,OAAO,IAAI;IACjC,GAAG;IACH,QAAQ,EAAE,MAAM,cAAc;IAC9B,UAAU,EAAE,MAAM,QAAQ;IAC1B,aAAa,EAAE,iCAAiC,GAAG;IACpD,CAAC;AACF,UAAO,QAAQ,KAAK,GAAG;;;AAI3B,QAAO"}
@@ -1,9 +1,9 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
4
+ import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
4
5
  import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
5
6
  import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
6
- import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
7
7
  import { createHeartbeatWake } from "../../heartbeat/wake.js";
8
8
  import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
9
9
  import { readFile } from "fs/promises";
@@ -17,6 +17,7 @@ import { logContextMiddleware } from "./middleware/log-context.js";
17
17
  import { logger } from "./middleware/logger.js";
18
18
  import { routeErrorMiddleware } from "./middleware/route-errors.js";
19
19
  import { registerPublicExtensionAssetRoutes } from "./routes/auth-registry-extensions.js";
20
+ import { registerPublicLocalAppPreviewRoutes } from "./routes/local-apps.js";
20
21
  import { resetLazyRouteBundlesForTests } from "./routes/lazy-fallback.js";
21
22
  import { registerAuthenticatedRoutes } from "./routes/index.js";
22
23
  import { prewarmStaticUiCache } from "./lib/static-ui.js";
@@ -36,7 +37,7 @@ const log = createLogger("Gateway:App");
36
37
  * with `frame-ancestors 'none'` / `X-Frame-Options: DENY`, or the console cannot embed iframes.
37
38
  */
38
39
  function isExtensionGatewayUiAssetPath(path) {
39
- return /^\/api\/extensions\/[^/]+\/assets\//.test(path);
40
+ return /^\/api\/extensions\/[^/]+\/assets\//.test(path) || /^\/api\/local-apps\/preview\/[^/]+\//.test(path);
40
41
  }
41
42
  function createHonoApp(config) {
42
43
  if (process.env.VITEST) resetLazyRouteBundlesForTests();
@@ -191,6 +192,7 @@ function createHonoApp(config) {
191
192
  });
192
193
  registerPublicGatewayRoutes(app, service);
193
194
  registerPublicExtensionAssetRoutes(app, service);
195
+ registerPublicLocalAppPreviewRoutes(app, service);
194
196
  const authenticated = new Hono();
195
197
  authenticated.use(routeErrorMiddleware());
196
198
  authenticated.use(auth({
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","names":[],"sources":["../../../../src/gateway/hono/app.ts"],"sourcesContent":["import { Hono } from 'hono';\nimport type { Context } from 'hono';\nimport { cors } from 'hono/cors';\nimport { createMiddleware } from 'hono/factory';\nimport { bodyLimit } from 'hono/body-limit';\nimport { getConnInfo } from '@hono/node-server/conninfo';\n\nimport { resolveGatewayEffectiveHost } from '../../config/gateway-bind.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { GatewayService } from '../service.js';\nimport { resolveAllowedBrowserOrigins, resolveGatewayServiceListenPort } from '../host.js';\nimport { loadTunnelState } from '../../tunnel/tunnel-state.js';\nimport { WORK_ITEM_ATTACHMENT_UPLOAD_BODY_MAX_BYTES } from '../../work-items/index.js';\nimport { maxWebchatAgentRequestBodyBytes } from '../chat-limits.js';\nimport { buildGatewayConsoleCspHeader } from '../security/csp.js';\nimport { checkBrowserOrigin } from '../security/origin-check.js';\nimport { isLoopbackIpAddress, isTrustedProxyAddress } from '../client-ip.js';\nimport { resolveReverseProxyPublicUrl } from '../public-url.js';\nimport { auth } from './middleware/auth.js';\nimport { operatorScopes } from './middleware/scopes.js';\nimport {\n createChannelRateLimitMiddleware,\n createStrictRateLimitMiddleware,\n} from './middleware/strict-rate-limit.js';\nimport { logContextMiddleware } from './middleware/log-context.js';\nimport { logger } from './middleware/logger.js';\nimport { routeErrorMiddleware } from './middleware/route-errors.js';\nimport { registerPublicExtensionAssetRoutes } from './routes/auth-registry-extensions.js';\nimport { registerAuthenticatedRoutes } from './routes/index.js';\nimport { registerPublicGatewayRoutes } from './routes/public-gateway.js';\nimport { resetLazyRouteBundlesForTests } from './routes/lazy-fallback.js';\nimport { prewarmStaticUiCache } from './lib/static-ui.js';\nimport { registerSiteShareMiddleware } from '../../share/site-share-router.js';\nconst log = createLogger('Gateway:App');\n\nexport interface HonoAppConfig {\n service: GatewayService;\n}\n\n/**\n * Extension sandbox HTML under `/api/extensions/:id/assets/*` ships its own CSP\n * (`frame-ancestors 'self'`). The global gateway middleware must not overwrite it\n * with `frame-ancestors 'none'` / `X-Frame-Options: DENY`, or the console cannot embed iframes.\n */\nexport function isExtensionGatewayUiAssetPath(path: string): boolean {\n return /^\\/api\\/extensions\\/[^/]+\\/assets\\//.test(path);\n}\n\nexport function createHonoApp(config: HonoAppConfig): Hono {\n if (process.env.VITEST) {\n resetLazyRouteBundlesForTests();\n }\n const { service } = config;\n const app = new Hono();\n\n const gatewayPort = resolveGatewayServiceListenPort(service);\n\n const resolveBrowserOrigins = (): string[] =>\n resolveAllowedBrowserOrigins({\n configuredOrigins: service.currentConfig.gateway.corsOrigins,\n port: gatewayPort,\n bindHost: resolveGatewayEffectiveHost(service.currentConfig),\n tunnelPublicUrl: loadTunnelState()?.publicUrl,\n reverseProxyPublicUrl: resolveReverseProxyPublicUrl(service.currentConfig),\n });\n\n /**\n * TCP source for the in-flight request, normalized for trusted-proxy checks.\n * Returns undefined when the runtime doesn't expose conninfo (tests, mocks).\n */\n const resolveRequestRemoteAddress = (c: Context): string | undefined => {\n try {\n return getConnInfo(c).remote.address;\n } catch {\n return undefined;\n }\n };\n\n /**\n * A request's TCP source qualifies as a \"trusted proxy hop\" when it's\n * loopback (the user's own machine, where any reverse proxy lives) or\n * listed in `gateway.trustedProxies`. We use this signal to safely\n * auto-allow same-host Origins through CSRF without requiring a manual\n * `corsOrigins` entry for every reverse-proxy hostname.\n */\n const isRequestFromTrustedProxy = (c: Context): boolean => {\n const remote = resolveRequestRemoteAddress(c);\n if (!remote) return false;\n if (isLoopbackIpAddress(remote)) return true;\n return isTrustedProxyAddress(remote, service.currentConfig.gateway?.trustedProxies);\n };\n\n app.use(logContextMiddleware());\n app.use(logger({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }));\n\n // Site-share middleware runs BEFORE CORS/CSP — it owns the request when the\n // Host header matches `*.<publicHostSuffix>` (default `*.share.xopc.ai`) or\n // the path starts with `/site/:token/`. Otherwise it falls through.\n registerSiteShareMiddleware(app, service);\n app.use(\n cors({\n origin: (origin) => {\n const allowed = resolveBrowserOrigins();\n if (!origin) {\n return allowed[0] ?? `http://127.0.0.1:${gatewayPort}`;\n }\n const normalized = origin.toLowerCase();\n const hit = allowed.find((entry) => entry.toLowerCase() === normalized);\n if (hit) return origin;\n return allowed.includes('*') ? '*' : '';\n },\n allowMethods: ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS'],\n allowHeaders: ['Content-Type', 'Authorization', 'Accept', 'X-Session-Id', 'Last-Event-ID'],\n credentials: true,\n maxAge: 86400,\n }),\n );\n\n // Build CSP header once at startup (no inline script hashes needed for SPA)\n const gatewayConsoleCsp = buildGatewayConsoleCspHeader();\n\n // Security headers middleware\n app.use(createMiddleware(async (c, next) => {\n await next();\n if (isExtensionGatewayUiAssetPath(c.req.path)) {\n return;\n }\n c.header('X-Frame-Options', 'DENY');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Referrer-Policy', 'strict-origin-when-cross-origin');\n c.header('X-XSS-Protection', '1; mode=block');\n // microphone=(self): allow same-origin chat voice (composer). microphone=() breaks packaged Electron loading the gateway SPA.\n c.header('Permissions-Policy', 'camera=(), microphone=(self), geolocation=()');\n c.header('Content-Security-Policy', gatewayConsoleCsp);\n }));\n\n // Browser Origin check middleware for API routes (CSRF protection).\n // Non-browser requests (no Origin header) pass through — they are\n // authenticated by the token middleware instead.\n const allowHostHeaderOriginFallback =\n service.currentConfig.gateway?.dangerouslyAllowHostHeaderOriginFallback === true;\n app.use('/api/*', createMiddleware(async (c, next) => {\n // Sandboxed extension iframes (no allow-same-origin) send `Origin: null`.\n // `checkBrowserOrigin` rejects that; these routes rely on CSP instead\n // (`registerPublicExtensionAssetRoutes`).\n if (isExtensionGatewayUiAssetPath(c.req.path)) {\n return next();\n }\n\n const origin = c.req.header('origin');\n if (!origin || origin.trim().toLowerCase() === 'null') {\n // Native apps / opaque origins — authenticated via Bearer token\n return next();\n }\n\n const result = checkBrowserOrigin({\n requestHost: c.req.header('host'),\n origin,\n allowedOrigins: resolveBrowserOrigins(),\n allowHostHeaderOriginFallback,\n autoAllowSameHostFromTrustedProxy: isRequestFromTrustedProxy(c),\n isLocalClient: false,\n });\n\n if (!result.ok) {\n log.warn(\n {\n origin,\n requestHost: c.req.header('host'),\n reason: 'reason' in result ? result.reason : 'unknown',\n path: c.req.path,\n method: c.req.method,\n },\n `Browser origin check failed: ${origin} not in allowed list`,\n );\n return c.json({ error: 'Forbidden', message: 'Origin not allowed' }, 403);\n }\n\n return next();\n }));\n\n const DEFAULT_API_BODY_MAX = 1 * 1024 * 1024;\n const SKILL_UPLOAD_BODY_MAX = 10 * 1024 * 1024;\n const NOTE_MEDIA_BODY_MAX = 25 * 1024 * 1024;\n const VOICE_TRANSCRIBE_BODY_MAX = 35 * 1024 * 1024;\n const WEBCHAT_AGENT_BODY_MAX = maxWebchatAgentRequestBodyBytes();\n\n const isNoteMediaUploadRequest = (path: string, method: string, contentType: string | undefined): boolean => {\n if (method !== 'POST') return false;\n if (/^\\/api\\/notes\\/[^/]+\\/media$/.test(path)) return true;\n return path === '/api/notes' && contentType?.includes('multipart/form-data') === true;\n };\n\n const isWorkItemAttachmentUploadRequest = (path: string, method: string, contentType: string | undefined): boolean => {\n if (method !== 'POST' || contentType?.includes('multipart/form-data') !== true) return false;\n return /^\\/api\\/work-items\\/[^/]+\\/attachments$/.test(path)\n || /^\\/api\\/projects\\/[^/]+\\/work-items$/.test(path);\n };\n\n app.use('/api/skills/upload', bodyLimit({\n maxSize: SKILL_UPLOAD_BODY_MAX,\n onError: (c) => {\n log.warn({ path: c.req.path, maxSizeMb: 10 }, 'Request body too large: skills upload exceeds 10MB limit');\n return c.json({ error: 'Skill package too large', maxSize: '10MB' }, 413);\n },\n }));\n\n app.use('/api/*', async (c, next) => {\n const contentType = c.req.header('content-type');\n const maxSize = c.req.path === '/api/agent'\n ? WEBCHAT_AGENT_BODY_MAX\n : c.req.path === '/api/skills/upload'\n ? SKILL_UPLOAD_BODY_MAX\n : c.req.path === '/api/voice/transcribe' || c.req.path === '/api/voice/transcriptions'\n ? VOICE_TRANSCRIBE_BODY_MAX\n : isNoteMediaUploadRequest(c.req.path, c.req.method, contentType)\n ? NOTE_MEDIA_BODY_MAX\n : isWorkItemAttachmentUploadRequest(c.req.path, c.req.method, contentType)\n ? WORK_ITEM_ATTACHMENT_UPLOAD_BODY_MAX_BYTES\n : DEFAULT_API_BODY_MAX;\n const maxSizeMb = Math.ceil(maxSize / (1024 * 1024));\n return bodyLimit({\n maxSize,\n onError: (ctx) => {\n log.warn({ path: ctx.req.path, maxSizeMb }, `Request body too large: exceeds ${maxSizeMb}MB limit`);\n return ctx.json({ error: 'Request body too large', maxSize: `${maxSizeMb}MB` }, 413);\n },\n })(c, next);\n });\n\n registerPublicGatewayRoutes(app, service);\n\n // Extension UI assets are served without auth: sandboxed iframes (no allow-same-origin)\n // have an opaque origin of `null` and cannot forward the ?token= from the parent HTML URL.\n // Security is enforced by the strict CSP (frame-ancestors 'self') on every response.\n registerPublicExtensionAssetRoutes(app, service);\n\n const authenticated = new Hono();\n authenticated.use(routeErrorMiddleware());\n authenticated.use(\n auth({\n getGatewayAuth: () => service.currentConfig.gateway?.auth,\n getResolvedAuth: () => service.getResolvedAuth(),\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n }),\n );\n authenticated.use(operatorScopes());\n\n const strictRateLimitMiddleware = createStrictRateLimitMiddleware({\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n });\n const channelRateLimitMiddleware = createChannelRateLimitMiddleware({\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n });\n\n const sseConfig = {\n service,\n maxSseConnections: service.currentConfig.gateway.maxSseConnections,\n };\n\n registerAuthenticatedRoutes(app, authenticated, {\n service,\n strictRateLimitMiddleware,\n channelRateLimitMiddleware,\n sseConfig,\n });\n\n const prewarm = prewarmStaticUiCache();\n if (prewarm.loaded > 0) {\n log.debug({ loaded: prewarm.loaded, missing: prewarm.missing }, 'Static UI cache prewarmed');\n }\n\n app.route('/', authenticated);\n\n app.notFound((c) => {\n const isApiRoute = c.req.path.startsWith('/api/');\n const fields = { path: c.req.path, method: c.req.method };\n if (isApiRoute) {\n log.warn(fields, 'Route not found');\n } else {\n log.debug(fields, 'Route not found');\n }\n return c.json({ error: 'Not found' }, 404);\n });\n\n app.onError((err, c) => {\n log.error(\n {\n err,\n phase: 'gateway.http.unhandled',\n path: c.req.path,\n method: c.req.method,\n userAgent: c.req.header('user-agent'),\n },\n `Hono error on ${c.req.method} ${c.req.path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return c.json({ error: 'Internal server error' }, 500);\n });\n\n return app;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app.js","names":[],"sources":["../../../../src/gateway/hono/app.ts"],"sourcesContent":["import { Hono } from 'hono';\nimport type { Context } from 'hono';\nimport { cors } from 'hono/cors';\nimport { createMiddleware } from 'hono/factory';\nimport { bodyLimit } from 'hono/body-limit';\nimport { getConnInfo } from '@hono/node-server/conninfo';\n\nimport { resolveGatewayEffectiveHost } from '../../config/gateway-bind.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { GatewayService } from '../service.js';\nimport { resolveAllowedBrowserOrigins, resolveGatewayServiceListenPort } from '../host.js';\nimport { loadTunnelState } from '../../tunnel/tunnel-state.js';\nimport { WORK_ITEM_ATTACHMENT_UPLOAD_BODY_MAX_BYTES } from '../../work-items/index.js';\nimport { maxWebchatAgentRequestBodyBytes } from '../chat-limits.js';\nimport { buildGatewayConsoleCspHeader } from '../security/csp.js';\nimport { checkBrowserOrigin } from '../security/origin-check.js';\nimport { isLoopbackIpAddress, isTrustedProxyAddress } from '../client-ip.js';\nimport { resolveReverseProxyPublicUrl } from '../public-url.js';\nimport { auth } from './middleware/auth.js';\nimport { operatorScopes } from './middleware/scopes.js';\nimport {\n createChannelRateLimitMiddleware,\n createStrictRateLimitMiddleware,\n} from './middleware/strict-rate-limit.js';\nimport { logContextMiddleware } from './middleware/log-context.js';\nimport { logger } from './middleware/logger.js';\nimport { routeErrorMiddleware } from './middleware/route-errors.js';\nimport { registerPublicExtensionAssetRoutes } from './routes/auth-registry-extensions.js';\nimport { registerAuthenticatedRoutes } from './routes/index.js';\nimport { registerPublicGatewayRoutes } from './routes/public-gateway.js';\nimport { registerPublicLocalAppPreviewRoutes } from './routes/local-apps.js';\nimport { resetLazyRouteBundlesForTests } from './routes/lazy-fallback.js';\nimport { prewarmStaticUiCache } from './lib/static-ui.js';\nimport { registerSiteShareMiddleware } from '../../share/site-share-router.js';\nconst log = createLogger('Gateway:App');\n\nexport interface HonoAppConfig {\n service: GatewayService;\n}\n\n/**\n * Extension sandbox HTML under `/api/extensions/:id/assets/*` ships its own CSP\n * (`frame-ancestors 'self'`). The global gateway middleware must not overwrite it\n * with `frame-ancestors 'none'` / `X-Frame-Options: DENY`, or the console cannot embed iframes.\n */\nexport function isExtensionGatewayUiAssetPath(path: string): boolean {\n return /^\\/api\\/extensions\\/[^/]+\\/assets\\//.test(path)\n || /^\\/api\\/local-apps\\/preview\\/[^/]+\\//.test(path);\n}\n\nexport function createHonoApp(config: HonoAppConfig): Hono {\n if (process.env.VITEST) {\n resetLazyRouteBundlesForTests();\n }\n const { service } = config;\n const app = new Hono();\n\n const gatewayPort = resolveGatewayServiceListenPort(service);\n\n const resolveBrowserOrigins = (): string[] =>\n resolveAllowedBrowserOrigins({\n configuredOrigins: service.currentConfig.gateway.corsOrigins,\n port: gatewayPort,\n bindHost: resolveGatewayEffectiveHost(service.currentConfig),\n tunnelPublicUrl: loadTunnelState()?.publicUrl,\n reverseProxyPublicUrl: resolveReverseProxyPublicUrl(service.currentConfig),\n });\n\n /**\n * TCP source for the in-flight request, normalized for trusted-proxy checks.\n * Returns undefined when the runtime doesn't expose conninfo (tests, mocks).\n */\n const resolveRequestRemoteAddress = (c: Context): string | undefined => {\n try {\n return getConnInfo(c).remote.address;\n } catch {\n return undefined;\n }\n };\n\n /**\n * A request's TCP source qualifies as a \"trusted proxy hop\" when it's\n * loopback (the user's own machine, where any reverse proxy lives) or\n * listed in `gateway.trustedProxies`. We use this signal to safely\n * auto-allow same-host Origins through CSRF without requiring a manual\n * `corsOrigins` entry for every reverse-proxy hostname.\n */\n const isRequestFromTrustedProxy = (c: Context): boolean => {\n const remote = resolveRequestRemoteAddress(c);\n if (!remote) return false;\n if (isLoopbackIpAddress(remote)) return true;\n return isTrustedProxyAddress(remote, service.currentConfig.gateway?.trustedProxies);\n };\n\n app.use(logContextMiddleware());\n app.use(logger({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }));\n\n // Site-share middleware runs BEFORE CORS/CSP — it owns the request when the\n // Host header matches `*.<publicHostSuffix>` (default `*.share.xopc.ai`) or\n // the path starts with `/site/:token/`. Otherwise it falls through.\n registerSiteShareMiddleware(app, service);\n app.use(\n cors({\n origin: (origin) => {\n const allowed = resolveBrowserOrigins();\n if (!origin) {\n return allowed[0] ?? `http://127.0.0.1:${gatewayPort}`;\n }\n const normalized = origin.toLowerCase();\n const hit = allowed.find((entry) => entry.toLowerCase() === normalized);\n if (hit) return origin;\n return allowed.includes('*') ? '*' : '';\n },\n allowMethods: ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS'],\n allowHeaders: ['Content-Type', 'Authorization', 'Accept', 'X-Session-Id', 'Last-Event-ID'],\n credentials: true,\n maxAge: 86400,\n }),\n );\n\n // Build CSP header once at startup (no inline script hashes needed for SPA)\n const gatewayConsoleCsp = buildGatewayConsoleCspHeader();\n\n // Security headers middleware\n app.use(createMiddleware(async (c, next) => {\n await next();\n if (isExtensionGatewayUiAssetPath(c.req.path)) {\n return;\n }\n c.header('X-Frame-Options', 'DENY');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Referrer-Policy', 'strict-origin-when-cross-origin');\n c.header('X-XSS-Protection', '1; mode=block');\n // microphone=(self): allow same-origin chat voice (composer). microphone=() breaks packaged Electron loading the gateway SPA.\n c.header('Permissions-Policy', 'camera=(), microphone=(self), geolocation=()');\n c.header('Content-Security-Policy', gatewayConsoleCsp);\n }));\n\n // Browser Origin check middleware for API routes (CSRF protection).\n // Non-browser requests (no Origin header) pass through — they are\n // authenticated by the token middleware instead.\n const allowHostHeaderOriginFallback =\n service.currentConfig.gateway?.dangerouslyAllowHostHeaderOriginFallback === true;\n app.use('/api/*', createMiddleware(async (c, next) => {\n // Sandboxed extension iframes (no allow-same-origin) send `Origin: null`.\n // `checkBrowserOrigin` rejects that; these routes rely on CSP instead\n // (`registerPublicExtensionAssetRoutes`).\n if (isExtensionGatewayUiAssetPath(c.req.path)) {\n return next();\n }\n\n const origin = c.req.header('origin');\n if (!origin || origin.trim().toLowerCase() === 'null') {\n // Native apps / opaque origins — authenticated via Bearer token\n return next();\n }\n\n const result = checkBrowserOrigin({\n requestHost: c.req.header('host'),\n origin,\n allowedOrigins: resolveBrowserOrigins(),\n allowHostHeaderOriginFallback,\n autoAllowSameHostFromTrustedProxy: isRequestFromTrustedProxy(c),\n isLocalClient: false,\n });\n\n if (!result.ok) {\n log.warn(\n {\n origin,\n requestHost: c.req.header('host'),\n reason: 'reason' in result ? result.reason : 'unknown',\n path: c.req.path,\n method: c.req.method,\n },\n `Browser origin check failed: ${origin} not in allowed list`,\n );\n return c.json({ error: 'Forbidden', message: 'Origin not allowed' }, 403);\n }\n\n return next();\n }));\n\n const DEFAULT_API_BODY_MAX = 1 * 1024 * 1024;\n const SKILL_UPLOAD_BODY_MAX = 10 * 1024 * 1024;\n const NOTE_MEDIA_BODY_MAX = 25 * 1024 * 1024;\n const VOICE_TRANSCRIBE_BODY_MAX = 35 * 1024 * 1024;\n const WEBCHAT_AGENT_BODY_MAX = maxWebchatAgentRequestBodyBytes();\n\n const isNoteMediaUploadRequest = (path: string, method: string, contentType: string | undefined): boolean => {\n if (method !== 'POST') return false;\n if (/^\\/api\\/notes\\/[^/]+\\/media$/.test(path)) return true;\n return path === '/api/notes' && contentType?.includes('multipart/form-data') === true;\n };\n\n const isWorkItemAttachmentUploadRequest = (path: string, method: string, contentType: string | undefined): boolean => {\n if (method !== 'POST' || contentType?.includes('multipart/form-data') !== true) return false;\n return /^\\/api\\/work-items\\/[^/]+\\/attachments$/.test(path)\n || /^\\/api\\/projects\\/[^/]+\\/work-items$/.test(path);\n };\n\n app.use('/api/skills/upload', bodyLimit({\n maxSize: SKILL_UPLOAD_BODY_MAX,\n onError: (c) => {\n log.warn({ path: c.req.path, maxSizeMb: 10 }, 'Request body too large: skills upload exceeds 10MB limit');\n return c.json({ error: 'Skill package too large', maxSize: '10MB' }, 413);\n },\n }));\n\n app.use('/api/*', async (c, next) => {\n const contentType = c.req.header('content-type');\n const maxSize = c.req.path === '/api/agent'\n ? WEBCHAT_AGENT_BODY_MAX\n : c.req.path === '/api/skills/upload'\n ? SKILL_UPLOAD_BODY_MAX\n : c.req.path === '/api/voice/transcribe' || c.req.path === '/api/voice/transcriptions'\n ? VOICE_TRANSCRIBE_BODY_MAX\n : isNoteMediaUploadRequest(c.req.path, c.req.method, contentType)\n ? NOTE_MEDIA_BODY_MAX\n : isWorkItemAttachmentUploadRequest(c.req.path, c.req.method, contentType)\n ? WORK_ITEM_ATTACHMENT_UPLOAD_BODY_MAX_BYTES\n : DEFAULT_API_BODY_MAX;\n const maxSizeMb = Math.ceil(maxSize / (1024 * 1024));\n return bodyLimit({\n maxSize,\n onError: (ctx) => {\n log.warn({ path: ctx.req.path, maxSizeMb }, `Request body too large: exceeds ${maxSizeMb}MB limit`);\n return ctx.json({ error: 'Request body too large', maxSize: `${maxSizeMb}MB` }, 413);\n },\n })(c, next);\n });\n\n registerPublicGatewayRoutes(app, service);\n\n // Extension UI assets are served without auth: sandboxed iframes (no allow-same-origin)\n // have an opaque origin of `null` and cannot forward the ?token= from the parent HTML URL.\n // Security is enforced by the strict CSP (frame-ancestors 'self') on every response.\n registerPublicExtensionAssetRoutes(app, service);\n registerPublicLocalAppPreviewRoutes(app, service);\n\n const authenticated = new Hono();\n authenticated.use(routeErrorMiddleware());\n authenticated.use(\n auth({\n getGatewayAuth: () => service.currentConfig.gateway?.auth,\n getResolvedAuth: () => service.getResolvedAuth(),\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n }),\n );\n authenticated.use(operatorScopes());\n\n const strictRateLimitMiddleware = createStrictRateLimitMiddleware({\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n });\n const channelRateLimitMiddleware = createChannelRateLimitMiddleware({\n getTrustedProxyContext: () => ({\n trustedProxies: service.currentConfig.gateway?.trustedProxies,\n allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true,\n }),\n });\n\n const sseConfig = {\n service,\n maxSseConnections: service.currentConfig.gateway.maxSseConnections,\n };\n\n registerAuthenticatedRoutes(app, authenticated, {\n service,\n strictRateLimitMiddleware,\n channelRateLimitMiddleware,\n sseConfig,\n });\n\n const prewarm = prewarmStaticUiCache();\n if (prewarm.loaded > 0) {\n log.debug({ loaded: prewarm.loaded, missing: prewarm.missing }, 'Static UI cache prewarmed');\n }\n\n app.route('/', authenticated);\n\n app.notFound((c) => {\n const isApiRoute = c.req.path.startsWith('/api/');\n const fields = { path: c.req.path, method: c.req.method };\n if (isApiRoute) {\n log.warn(fields, 'Route not found');\n } else {\n log.debug(fields, 'Route not found');\n }\n return c.json({ error: 'Not found' }, 404);\n });\n\n app.onError((err, c) => {\n log.error(\n {\n err,\n phase: 'gateway.http.unhandled',\n path: c.req.path,\n method: c.req.method,\n userAgent: c.req.header('user-agent'),\n },\n `Hono error on ${c.req.method} ${c.req.path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return c.json({ error: 'Internal server error' }, 500);\n });\n\n return app;\n}\n"],"mappings":"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"}