@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
@@ -97,71 +97,6 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
97
97
  allow?: string[];
98
98
  deny?: string[];
99
99
  };
100
- memory: {
101
- mode: "off" | "auto" | "readOnly" | "confirmWrite";
102
- sources: ("session" | "workspace" | "curated" | "userProfile" | "agentProfile" | "connectedSources")[];
103
- writePolicy?: {
104
- userProfile?: "allow" | "confirm" | "deny";
105
- agentProfile?: "allow" | "confirm" | "deny";
106
- curated?: "allow" | "confirm" | "deny";
107
- workspace?: "allow" | "confirm" | "deny";
108
- };
109
- retention?: {
110
- compaction: boolean;
111
- maxAgeDays?: number;
112
- maxItems?: number;
113
- maxChars?: number;
114
- };
115
- privacy?: {
116
- crossAgentSharing: "allow" | "deny" | "readOnly";
117
- sensitiveWritePolicy: "allow" | "confirm" | "deny";
118
- };
119
- providerRouting?: {
120
- searchStrategy: "local-first" | "external-first" | "fanout" | "local-only" | "external-only";
121
- writeStrategy: "local-first" | "external-first" | "local-only" | "external-only" | "write-through";
122
- allowExternalWrites: boolean;
123
- allowedProviderIds?: string[];
124
- autoWriteKinds?: ("user_profile" | "preference" | "boundary" | "relationship" | "project_context" | "commitment" | "routine" | "personal_logistics" | "open_question" | "milestone" | "current_state" | "agent_note" | "workspace_fact" | "daily_note" | "session_summary" | "derived_insight" | "task_lesson" | "tool_preference" | "long_term_goal")[];
125
- };
126
- dreaming?: {
127
- enabled: boolean;
128
- frequency?: string;
129
- timezone?: string;
130
- phases?: {
131
- light?: {
132
- enabled?: boolean;
133
- cron?: string;
134
- lookbackDays?: number;
135
- limit?: number;
136
- dedupeSimilarity?: number;
137
- };
138
- deep?: {
139
- enabled?: boolean;
140
- cron?: string;
141
- minScore?: number;
142
- minRecallCount?: number;
143
- minUniqueQueries?: number;
144
- limit?: number;
145
- recencyHalfLifeDays?: number;
146
- maxAgeDays?: number;
147
- };
148
- rem?: {
149
- enabled?: boolean;
150
- cron?: string;
151
- lookbackDays?: number;
152
- limit?: number;
153
- minPatternStrength?: number;
154
- };
155
- };
156
- };
157
- understanding?: {
158
- enabled?: boolean;
159
- adaptiveCadence?: boolean;
160
- reviewIntervalTurns?: number;
161
- maxHistoryMessages?: number;
162
- maxDurationMs?: number;
163
- };
164
- };
165
100
  workflows: {
166
101
  default?: string;
167
102
  allowed?: string[];
@@ -239,71 +174,6 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
239
174
  allow?: string[];
240
175
  deny?: string[];
241
176
  };
242
- memory?: {
243
- mode: "off" | "auto" | "readOnly" | "confirmWrite";
244
- sources: ("session" | "workspace" | "curated" | "userProfile" | "agentProfile" | "connectedSources")[];
245
- writePolicy?: {
246
- userProfile?: "allow" | "confirm" | "deny";
247
- agentProfile?: "allow" | "confirm" | "deny";
248
- curated?: "allow" | "confirm" | "deny";
249
- workspace?: "allow" | "confirm" | "deny";
250
- };
251
- retention?: {
252
- compaction: boolean;
253
- maxAgeDays?: number;
254
- maxItems?: number;
255
- maxChars?: number;
256
- };
257
- privacy?: {
258
- crossAgentSharing: "allow" | "deny" | "readOnly";
259
- sensitiveWritePolicy: "allow" | "confirm" | "deny";
260
- };
261
- providerRouting?: {
262
- searchStrategy: "local-first" | "external-first" | "fanout" | "local-only" | "external-only";
263
- writeStrategy: "local-first" | "external-first" | "local-only" | "external-only" | "write-through";
264
- allowExternalWrites: boolean;
265
- allowedProviderIds?: string[];
266
- autoWriteKinds?: ("user_profile" | "preference" | "boundary" | "relationship" | "project_context" | "commitment" | "routine" | "personal_logistics" | "open_question" | "milestone" | "current_state" | "agent_note" | "workspace_fact" | "daily_note" | "session_summary" | "derived_insight" | "task_lesson" | "tool_preference" | "long_term_goal")[];
267
- };
268
- dreaming?: {
269
- enabled: boolean;
270
- frequency?: string;
271
- timezone?: string;
272
- phases?: {
273
- light?: {
274
- enabled?: boolean;
275
- cron?: string;
276
- lookbackDays?: number;
277
- limit?: number;
278
- dedupeSimilarity?: number;
279
- };
280
- deep?: {
281
- enabled?: boolean;
282
- cron?: string;
283
- minScore?: number;
284
- minRecallCount?: number;
285
- minUniqueQueries?: number;
286
- limit?: number;
287
- recencyHalfLifeDays?: number;
288
- maxAgeDays?: number;
289
- };
290
- rem?: {
291
- enabled?: boolean;
292
- cron?: string;
293
- lookbackDays?: number;
294
- limit?: number;
295
- minPatternStrength?: number;
296
- };
297
- };
298
- };
299
- understanding?: {
300
- enabled?: boolean;
301
- adaptiveCadence?: boolean;
302
- reviewIntervalTurns?: number;
303
- maxHistoryMessages?: number;
304
- maxDurationMs?: number;
305
- };
306
- };
307
177
  workflows?: {
308
178
  default?: string;
309
179
  allowed?: string[];
@@ -116,7 +116,6 @@ async function buildSafeWebConfigPayload(service, options = {}) {
116
116
  models: e.models,
117
117
  tools: e.tools,
118
118
  skills: e.skills,
119
- memory: e.memory,
120
119
  workflows: e.workflows,
121
120
  boundaries: e.boundaries
122
121
  })),
@@ -1 +1 @@
1
- {"version":3,"file":"config-payload.js","names":["getModelsJsonPath"],"sources":["../../../../../src/gateway/hono/lib/config-payload.ts"],"sourcesContent":["import {\n listAgentEntries,\n normalizeAgentId,\n resolveDefaultAgentId,\n} from '../../../agent/agent-scope.js';\nimport {\n buildChannelCatalogForConfig,\n buildChannelCatalogFromSnapshot,\n getChannelSetupStatus,\n} from '../../../channels/catalog/channel-catalog-service.js';\nimport { normalizeConfiguredMcpServers } from '../../../config/mcp-config-normalize.js';\nimport type { Config } from '../../../config/schema.js';\nimport {\n GENERIC_MASKED_SECRET,\n maskSecretLength,\n} from './mask-secret-length.js';\nimport { maskTunnelSecretForWeb } from '../../../tunnel/env.js';\nimport { resolveShareConfig } from '../../../share/share-config.js';\nimport {\n resolveGoalsConfigForWeb,\n resolveSessionConfigForWeb,\n resolveUpdateConfigForWeb,\n} from '../../../config/web-patch.js';\nimport { CredentialResolver } from '../../../auth/credentials.js';\nimport { loadModelsJson, getModelsJsonPath } from '../../../config/models-json.js';\nimport { getAllProviders, isProviderConfigured } from '../../../providers/index.js';\nimport { getProviderRegistry } from '../../../providers/plugin-registry.js';\nimport type { GatewayService } from '../../service.js';\nimport { safeToolsWebForGet } from '../../config-tools-web.js';\nimport { buildSafeProvidersConfigForWeb } from './safe-providers-config.js';\nimport { maskSttConfigForWeb, maskTtsConfigForWeb } from './safe-voice-config.js';\n\nfunction readModelsJsonProviderApiKey(providerId: string): string | undefined {\n const { config } = loadModelsJson(getModelsJsonPath());\n const entry = config.providers?.[providerId];\n const key = entry?.apiKey;\n return typeof key === 'string' && key.trim() ? key.trim() : undefined;\n}\n\n/** Length-preserving mask for LLM provider keys in GET `/api/config`. */\nasync function maskLlmProviderApiKeyForWeb(provider: string): Promise<string> {\n const resolver = new CredentialResolver();\n const stored = await resolver.revealGatewayStoredApiKey(provider);\n if (stored) return maskSecretLength(stored);\n\n const fromModelsJson = readModelsJsonProviderApiKey(provider);\n if (fromModelsJson) return maskSecretLength(fromModelsJson);\n\n // Extension plugins manage their own auth; don't show a fake gateway key mask.\n if (getProviderRegistry().has(provider)) return '';\n\n if (await isProviderConfigured(provider)) return GENERIC_MASKED_SECRET;\n return '';\n}\n\n/** MCP block for GET/PATCH `/api/config` (authenticated console editing). */\nexport function buildSafeMcpConfigForWeb(config: Config) {\n const mcp = config.mcp;\n if (!mcp) {\n return { servers: {} as Record<string, Record<string, unknown>> };\n }\n return {\n ...(mcp.sessionIdleTtlMs !== undefined ? { sessionIdleTtlMs: mcp.sessionIdleTtlMs } : {}),\n servers: normalizeConfiguredMcpServers(mcp.servers),\n };\n}\n\nfunction maskBrowserCloudConfigForWeb(cloud: unknown): Record<string, unknown> | null {\n if (!cloud || typeof cloud !== 'object' || Array.isArray(cloud)) {\n return null;\n }\n const raw = cloud as Record<string, unknown>;\n const safe: Record<string, unknown> = {};\n if (typeof raw.apiKey === 'string' && raw.apiKey.trim()) {\n safe.apiKey = maskSecretLength(raw.apiKey);\n }\n if (typeof raw.projectId === 'string' && raw.projectId.trim()) {\n safe.projectId = raw.projectId.trim();\n }\n if (typeof raw.region === 'string' && raw.region.trim()) {\n safe.region = raw.region.trim();\n }\n return Object.keys(safe).length > 0 ? safe : null;\n}\n\nexport function buildSafeBrowserConfigForWeb(browser: unknown) {\n if (!browser || typeof browser !== 'object') {\n return {\n enabled: false,\n headless: false,\n allowPrivateUrls: false,\n commandTimeout: null,\n backend: null,\n cloudProvider: null,\n cloud: null,\n cdpUrl: null,\n extension: null,\n cloakbrowser: null,\n humanize: null,\n humanPreset: null,\n dialogPolicy: null,\n dialogTimeoutSeconds: null,\n };\n }\n\n return {\n enabled: (browser as Record<string, unknown>).enabled !== false,\n headless: (browser as Record<string, unknown>).headless === true,\n allowPrivateUrls: (browser as Record<string, unknown>).allowPrivateUrls === true,\n commandTimeout:\n typeof (browser as Record<string, unknown>).commandTimeout === 'number' &&\n Number.isFinite((browser as Record<string, unknown>).commandTimeout as number)\n ? Math.floor((browser as Record<string, unknown>).commandTimeout as number)\n : null,\n backend:\n (browser as Record<string, unknown>).backend === 'local' ||\n (browser as Record<string, unknown>).backend === 'cdp' ||\n (browser as Record<string, unknown>).backend === 'cloud' ||\n (browser as Record<string, unknown>).backend === 'extension' ||\n (browser as Record<string, unknown>).backend === 'cloakbrowser'\n ? (browser as Record<string, unknown>).backend\n : null,\n cloudProvider:\n (browser as Record<string, unknown>).cloudProvider === 'browserbase' ||\n (browser as Record<string, unknown>).cloudProvider === 'browser-use'\n ? (browser as Record<string, unknown>).cloudProvider\n : null,\n cloud: maskBrowserCloudConfigForWeb((browser as Record<string, unknown>).cloud),\n cdpUrl:\n typeof (browser as Record<string, unknown>).cdpUrl === 'string' &&\n ((browser as Record<string, unknown>).cdpUrl as string).trim()\n ? ((browser as Record<string, unknown>).cdpUrl as string).trim()\n : null,\n extension:\n (browser as Record<string, unknown>).extension &&\n typeof (browser as Record<string, unknown>).extension === 'object' &&\n !Array.isArray((browser as Record<string, unknown>).extension)\n ? (browser as Record<string, unknown>).extension\n : null,\n cloakbrowser:\n (browser as Record<string, unknown>).cloakbrowser &&\n typeof (browser as Record<string, unknown>).cloakbrowser === 'object' &&\n !Array.isArray((browser as Record<string, unknown>).cloakbrowser)\n ? (browser as Record<string, unknown>).cloakbrowser\n : null,\n humanize:\n typeof (browser as Record<string, unknown>).humanize === 'boolean'\n ? (browser as Record<string, unknown>).humanize\n : null,\n humanPreset:\n (browser as Record<string, unknown>).humanPreset === 'default' ||\n (browser as Record<string, unknown>).humanPreset === 'careful'\n ? (browser as Record<string, unknown>).humanPreset\n : null,\n dialogPolicy:\n (browser as Record<string, unknown>).dialogPolicy === 'must_respond' ||\n (browser as Record<string, unknown>).dialogPolicy === 'auto_accept' ||\n (browser as Record<string, unknown>).dialogPolicy === 'auto_dismiss'\n ? (browser as Record<string, unknown>).dialogPolicy\n : null,\n dialogTimeoutSeconds:\n typeof (browser as Record<string, unknown>).dialogTimeoutSeconds === 'number' &&\n Number.isFinite((browser as Record<string, unknown>).dialogTimeoutSeconds as number)\n ? Math.floor((browser as Record<string, unknown>).dialogTimeoutSeconds as number)\n : null,\n };\n}\n\n/** Sanitized config snapshot for GET/PATCH `/api/config` (matches persisted `service.currentConfig`). */\nexport async function buildSafeWebConfigPayload(service: GatewayService, options: { locale?: string } = {}) {\n const config = service.currentConfig;\n const extensionLoader =\n typeof service.getExtensionLoader === 'function' ? service.getExtensionLoader() : undefined;\n const snapshot = extensionLoader?.getManifestSnapshot();\n const catalog = snapshot\n ? buildChannelCatalogFromSnapshot(snapshot, { locale: options.locale })\n : buildChannelCatalogForConfig(config, { locale: options.locale });\n const channelsPayload = Object.fromEntries(\n catalog.entries.map((entry) => {\n const plugin =\n typeof service.getChannelRuntimePlugin === 'function'\n ? service.getChannelRuntimePlugin(entry.id)\n : undefined;\n const channelCfgKey = entry.configPath.startsWith('channels.')\n ? entry.configPath.slice('channels.'.length).split('.')[0] || entry.id\n : entry.id;\n const channelCfg = config.channels?.[channelCfgKey] as Record<string, unknown> | undefined;\n const setupStatus = getChannelSetupStatus(config, entry.id, entry);\n return [\n entry.id,\n {\n enabled: setupStatus.enabled,\n configured: setupStatus.ready,\n setupStatus,\n config: plugin?.configSurface?.buildConfigSurface(config) ?? channelCfg ?? {},\n schema: entry.configSchema,\n uiHints: entry.uiHints,\n },\n ];\n }),\n );\n return {\n agents: {\n defaultId: resolveDefaultAgentId(config),\n list: listAgentEntries(config)\n .filter((e) => e.enabled !== false)\n .map((e) => ({\n id: normalizeAgentId(e.id),\n identity: e.identity,\n workspace: e.workspace,\n models: e.models,\n tools: e.tools,\n skills: e.skills,\n memory: e.memory,\n workflows: e.workflows,\n boundaries: e.boundaries,\n })),\n capabilityPresets: config.agents?.capabilityPresets ?? {},\n },\n channels: channelsPayload,\n providers: Object.fromEntries(\n await Promise.all(\n getAllProviders().map(async (provider) => [\n provider,\n await maskLlmProviderApiKeyForWeb(provider),\n ]),\n ),\n ),\n /** Masked `cfg.providers` for capability keys (image / STT / etc.). */\n providersConfig: buildSafeProvidersConfigForWeb(config.providers),\n gateway: {\n bind: config.gateway?.bind ?? 'loopback',\n customBindHost: config.gateway?.customBindHost,\n port: config.gateway?.port,\n corsOrigins: Array.isArray(config.gateway?.corsOrigins) ? config.gateway.corsOrigins : [],\n trustedProxies: Array.isArray(config.gateway?.trustedProxies)\n ? config.gateway.trustedProxies\n : [],\n allowRealIpFallback: config.gateway?.allowRealIpFallback === true,\n dangerouslyAllowHostHeaderOriginFallback:\n config.gateway?.dangerouslyAllowHostHeaderOriginFallback === true,\n security: {\n strict: config.gateway?.security?.strict === true,\n },\n auth: {\n mode: config.gateway?.auth?.mode || 'token',\n token: config.gateway?.auth?.token ? maskSecretLength(config.gateway.auth.token) : '',\n password: config.gateway?.auth?.password\n ? maskSecretLength(config.gateway.auth.password)\n : '',\n trustedProxy: config.gateway?.auth?.trustedProxy\n ? {\n userHeader: config.gateway.auth.trustedProxy.userHeader,\n requiredHeaders: config.gateway.auth.trustedProxy.requiredHeaders ?? [],\n allowUsers: config.gateway.auth.trustedProxy.allowUsers ?? [],\n allowLoopback: config.gateway.auth.trustedProxy.allowLoopback === true,\n }\n : undefined,\n rateLimit: {\n enabled: config.gateway?.auth?.rateLimit?.enabled !== false,\n maxAttempts:\n typeof config.gateway?.auth?.rateLimit?.maxAttempts === 'number'\n ? config.gateway.auth.rateLimit.maxAttempts\n : 5,\n windowMs:\n typeof config.gateway?.auth?.rateLimit?.windowMs === 'number'\n ? config.gateway.auth.rateLimit.windowMs\n : 900_000,\n blockDurationMs:\n typeof config.gateway?.auth?.rateLimit?.blockDurationMs === 'number'\n ? config.gateway.auth.rateLimit.blockDurationMs\n : typeof config.gateway?.auth?.rateLimit?.lockoutMs === 'number'\n ? config.gateway.auth.rateLimit.lockoutMs\n : 300_000,\n exemptLoopback: config.gateway?.auth?.rateLimit?.exemptLoopback !== false,\n },\n },\n heartbeat: {\n enabled: config.gateway?.heartbeat?.enabled,\n intervalMs: config.gateway?.heartbeat?.intervalMs,\n includeSystemPromptSection: config.gateway?.heartbeat?.includeSystemPromptSection === true,\n target: config.gateway?.heartbeat?.target,\n targetChatId: config.gateway?.heartbeat?.targetChatId,\n prompt: config.gateway?.heartbeat?.prompt,\n ackMaxChars: config.gateway?.heartbeat?.ackMaxChars,\n isolatedSession: config.gateway?.heartbeat?.isolatedSession,\n activeHours: config.gateway?.heartbeat?.activeHours,\n },\n maxSseConnections:\n typeof config.gateway?.maxSseConnections === 'number'\n ? config.gateway.maxSseConnections\n : 100,\n channelConnectDeferMode: config.gateway?.channelConnectDeferMode ?? 'auto',\n channelConnectDeferIds: Array.isArray(config.gateway?.channelConnectDeferIds)\n ? config.gateway.channelConnectDeferIds\n : [],\n channelConnectDeferSkipIds: Array.isArray(config.gateway?.channelConnectDeferSkipIds)\n ? config.gateway.channelConnectDeferSkipIds\n : [],\n share: resolveShareConfig(config.gateway?.share),\n publicUrl: config.gateway?.publicUrl ?? null,\n skillsMarketplaceProvider: config.gateway?.skillsMarketplaceProvider ?? 'store',\n skillsStoreBaseUrl: config.gateway?.skillsStoreBaseUrl ?? 'https://store.xopc.ai',\n },\n browser: buildSafeBrowserConfigForWeb(config.browser),\n goals: resolveGoalsConfigForWeb(config),\n session: resolveSessionConfigForWeb(config),\n tui: {\n defaultAgent: config.tui?.defaultAgent ?? 'coder',\n },\n tunnel: {\n enabled: config.tunnel?.enabled === true,\n autoStart: config.tunnel?.autoStart === true,\n brokerUrl: config.tunnel?.brokerUrl ?? 'https://frp.xopc.ai/api',\n registrationSecret: config.tunnel?.registrationSecret\n ? maskTunnelSecretForWeb(config.tunnel.registrationSecret)\n : '',\n consent: config.tunnel?.consent\n ? {\n version: config.tunnel.consent.version,\n acceptedAt: config.tunnel.consent.acceptedAt,\n }\n : undefined,\n transport: { tls: 'broker_terminated' as const },\n },\n update: {\n ...resolveUpdateConfigForWeb(config),\n },\n stt: maskSttConfigForWeb(config.tools?.media?.audio),\n tts: maskTtsConfigForWeb(config.messages?.tts),\n voice: config.voice,\n tools: safeToolsWebForGet(config),\n bindings: Array.isArray(config.bindings) ? config.bindings : [],\n mcp: buildSafeMcpConfigForWeb(config),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config-payload.js","names":["getModelsJsonPath"],"sources":["../../../../../src/gateway/hono/lib/config-payload.ts"],"sourcesContent":["import {\n listAgentEntries,\n normalizeAgentId,\n resolveDefaultAgentId,\n} from '../../../agent/agent-scope.js';\nimport {\n buildChannelCatalogForConfig,\n buildChannelCatalogFromSnapshot,\n getChannelSetupStatus,\n} from '../../../channels/catalog/channel-catalog-service.js';\nimport { normalizeConfiguredMcpServers } from '../../../config/mcp-config-normalize.js';\nimport type { Config } from '../../../config/schema.js';\nimport {\n GENERIC_MASKED_SECRET,\n maskSecretLength,\n} from './mask-secret-length.js';\nimport { maskTunnelSecretForWeb } from '../../../tunnel/env.js';\nimport { resolveShareConfig } from '../../../share/share-config.js';\nimport {\n resolveGoalsConfigForWeb,\n resolveSessionConfigForWeb,\n resolveUpdateConfigForWeb,\n} from '../../../config/web-patch.js';\nimport { CredentialResolver } from '../../../auth/credentials.js';\nimport { loadModelsJson, getModelsJsonPath } from '../../../config/models-json.js';\nimport { getAllProviders, isProviderConfigured } from '../../../providers/index.js';\nimport { getProviderRegistry } from '../../../providers/plugin-registry.js';\nimport type { GatewayService } from '../../service.js';\nimport { safeToolsWebForGet } from '../../config-tools-web.js';\nimport { buildSafeProvidersConfigForWeb } from './safe-providers-config.js';\nimport { maskSttConfigForWeb, maskTtsConfigForWeb } from './safe-voice-config.js';\n\nfunction readModelsJsonProviderApiKey(providerId: string): string | undefined {\n const { config } = loadModelsJson(getModelsJsonPath());\n const entry = config.providers?.[providerId];\n const key = entry?.apiKey;\n return typeof key === 'string' && key.trim() ? key.trim() : undefined;\n}\n\n/** Length-preserving mask for LLM provider keys in GET `/api/config`. */\nasync function maskLlmProviderApiKeyForWeb(provider: string): Promise<string> {\n const resolver = new CredentialResolver();\n const stored = await resolver.revealGatewayStoredApiKey(provider);\n if (stored) return maskSecretLength(stored);\n\n const fromModelsJson = readModelsJsonProviderApiKey(provider);\n if (fromModelsJson) return maskSecretLength(fromModelsJson);\n\n // Extension plugins manage their own auth; don't show a fake gateway key mask.\n if (getProviderRegistry().has(provider)) return '';\n\n if (await isProviderConfigured(provider)) return GENERIC_MASKED_SECRET;\n return '';\n}\n\n/** MCP block for GET/PATCH `/api/config` (authenticated console editing). */\nexport function buildSafeMcpConfigForWeb(config: Config) {\n const mcp = config.mcp;\n if (!mcp) {\n return { servers: {} as Record<string, Record<string, unknown>> };\n }\n return {\n ...(mcp.sessionIdleTtlMs !== undefined ? { sessionIdleTtlMs: mcp.sessionIdleTtlMs } : {}),\n servers: normalizeConfiguredMcpServers(mcp.servers),\n };\n}\n\nfunction maskBrowserCloudConfigForWeb(cloud: unknown): Record<string, unknown> | null {\n if (!cloud || typeof cloud !== 'object' || Array.isArray(cloud)) {\n return null;\n }\n const raw = cloud as Record<string, unknown>;\n const safe: Record<string, unknown> = {};\n if (typeof raw.apiKey === 'string' && raw.apiKey.trim()) {\n safe.apiKey = maskSecretLength(raw.apiKey);\n }\n if (typeof raw.projectId === 'string' && raw.projectId.trim()) {\n safe.projectId = raw.projectId.trim();\n }\n if (typeof raw.region === 'string' && raw.region.trim()) {\n safe.region = raw.region.trim();\n }\n return Object.keys(safe).length > 0 ? safe : null;\n}\n\nexport function buildSafeBrowserConfigForWeb(browser: unknown) {\n if (!browser || typeof browser !== 'object') {\n return {\n enabled: false,\n headless: false,\n allowPrivateUrls: false,\n commandTimeout: null,\n backend: null,\n cloudProvider: null,\n cloud: null,\n cdpUrl: null,\n extension: null,\n cloakbrowser: null,\n humanize: null,\n humanPreset: null,\n dialogPolicy: null,\n dialogTimeoutSeconds: null,\n };\n }\n\n return {\n enabled: (browser as Record<string, unknown>).enabled !== false,\n headless: (browser as Record<string, unknown>).headless === true,\n allowPrivateUrls: (browser as Record<string, unknown>).allowPrivateUrls === true,\n commandTimeout:\n typeof (browser as Record<string, unknown>).commandTimeout === 'number' &&\n Number.isFinite((browser as Record<string, unknown>).commandTimeout as number)\n ? Math.floor((browser as Record<string, unknown>).commandTimeout as number)\n : null,\n backend:\n (browser as Record<string, unknown>).backend === 'local' ||\n (browser as Record<string, unknown>).backend === 'cdp' ||\n (browser as Record<string, unknown>).backend === 'cloud' ||\n (browser as Record<string, unknown>).backend === 'extension' ||\n (browser as Record<string, unknown>).backend === 'cloakbrowser'\n ? (browser as Record<string, unknown>).backend\n : null,\n cloudProvider:\n (browser as Record<string, unknown>).cloudProvider === 'browserbase' ||\n (browser as Record<string, unknown>).cloudProvider === 'browser-use'\n ? (browser as Record<string, unknown>).cloudProvider\n : null,\n cloud: maskBrowserCloudConfigForWeb((browser as Record<string, unknown>).cloud),\n cdpUrl:\n typeof (browser as Record<string, unknown>).cdpUrl === 'string' &&\n ((browser as Record<string, unknown>).cdpUrl as string).trim()\n ? ((browser as Record<string, unknown>).cdpUrl as string).trim()\n : null,\n extension:\n (browser as Record<string, unknown>).extension &&\n typeof (browser as Record<string, unknown>).extension === 'object' &&\n !Array.isArray((browser as Record<string, unknown>).extension)\n ? (browser as Record<string, unknown>).extension\n : null,\n cloakbrowser:\n (browser as Record<string, unknown>).cloakbrowser &&\n typeof (browser as Record<string, unknown>).cloakbrowser === 'object' &&\n !Array.isArray((browser as Record<string, unknown>).cloakbrowser)\n ? (browser as Record<string, unknown>).cloakbrowser\n : null,\n humanize:\n typeof (browser as Record<string, unknown>).humanize === 'boolean'\n ? (browser as Record<string, unknown>).humanize\n : null,\n humanPreset:\n (browser as Record<string, unknown>).humanPreset === 'default' ||\n (browser as Record<string, unknown>).humanPreset === 'careful'\n ? (browser as Record<string, unknown>).humanPreset\n : null,\n dialogPolicy:\n (browser as Record<string, unknown>).dialogPolicy === 'must_respond' ||\n (browser as Record<string, unknown>).dialogPolicy === 'auto_accept' ||\n (browser as Record<string, unknown>).dialogPolicy === 'auto_dismiss'\n ? (browser as Record<string, unknown>).dialogPolicy\n : null,\n dialogTimeoutSeconds:\n typeof (browser as Record<string, unknown>).dialogTimeoutSeconds === 'number' &&\n Number.isFinite((browser as Record<string, unknown>).dialogTimeoutSeconds as number)\n ? Math.floor((browser as Record<string, unknown>).dialogTimeoutSeconds as number)\n : null,\n };\n}\n\n/** Sanitized config snapshot for GET/PATCH `/api/config` (matches persisted `service.currentConfig`). */\nexport async function buildSafeWebConfigPayload(service: GatewayService, options: { locale?: string } = {}) {\n const config = service.currentConfig;\n const extensionLoader =\n typeof service.getExtensionLoader === 'function' ? service.getExtensionLoader() : undefined;\n const snapshot = extensionLoader?.getManifestSnapshot();\n const catalog = snapshot\n ? buildChannelCatalogFromSnapshot(snapshot, { locale: options.locale })\n : buildChannelCatalogForConfig(config, { locale: options.locale });\n const channelsPayload = Object.fromEntries(\n catalog.entries.map((entry) => {\n const plugin =\n typeof service.getChannelRuntimePlugin === 'function'\n ? service.getChannelRuntimePlugin(entry.id)\n : undefined;\n const channelCfgKey = entry.configPath.startsWith('channels.')\n ? entry.configPath.slice('channels.'.length).split('.')[0] || entry.id\n : entry.id;\n const channelCfg = config.channels?.[channelCfgKey] as Record<string, unknown> | undefined;\n const setupStatus = getChannelSetupStatus(config, entry.id, entry);\n return [\n entry.id,\n {\n enabled: setupStatus.enabled,\n configured: setupStatus.ready,\n setupStatus,\n config: plugin?.configSurface?.buildConfigSurface(config) ?? channelCfg ?? {},\n schema: entry.configSchema,\n uiHints: entry.uiHints,\n },\n ];\n }),\n );\n return {\n agents: {\n defaultId: resolveDefaultAgentId(config),\n list: listAgentEntries(config)\n .filter((e) => e.enabled !== false)\n .map((e) => ({\n id: normalizeAgentId(e.id),\n identity: e.identity,\n workspace: e.workspace,\n models: e.models,\n tools: e.tools,\n skills: e.skills,\n workflows: e.workflows,\n boundaries: e.boundaries,\n })),\n capabilityPresets: config.agents?.capabilityPresets ?? {},\n },\n channels: channelsPayload,\n providers: Object.fromEntries(\n await Promise.all(\n getAllProviders().map(async (provider) => [\n provider,\n await maskLlmProviderApiKeyForWeb(provider),\n ]),\n ),\n ),\n /** Masked `cfg.providers` for capability keys (image / STT / etc.). */\n providersConfig: buildSafeProvidersConfigForWeb(config.providers),\n gateway: {\n bind: config.gateway?.bind ?? 'loopback',\n customBindHost: config.gateway?.customBindHost,\n port: config.gateway?.port,\n corsOrigins: Array.isArray(config.gateway?.corsOrigins) ? config.gateway.corsOrigins : [],\n trustedProxies: Array.isArray(config.gateway?.trustedProxies)\n ? config.gateway.trustedProxies\n : [],\n allowRealIpFallback: config.gateway?.allowRealIpFallback === true,\n dangerouslyAllowHostHeaderOriginFallback:\n config.gateway?.dangerouslyAllowHostHeaderOriginFallback === true,\n security: {\n strict: config.gateway?.security?.strict === true,\n },\n auth: {\n mode: config.gateway?.auth?.mode || 'token',\n token: config.gateway?.auth?.token ? maskSecretLength(config.gateway.auth.token) : '',\n password: config.gateway?.auth?.password\n ? maskSecretLength(config.gateway.auth.password)\n : '',\n trustedProxy: config.gateway?.auth?.trustedProxy\n ? {\n userHeader: config.gateway.auth.trustedProxy.userHeader,\n requiredHeaders: config.gateway.auth.trustedProxy.requiredHeaders ?? [],\n allowUsers: config.gateway.auth.trustedProxy.allowUsers ?? [],\n allowLoopback: config.gateway.auth.trustedProxy.allowLoopback === true,\n }\n : undefined,\n rateLimit: {\n enabled: config.gateway?.auth?.rateLimit?.enabled !== false,\n maxAttempts:\n typeof config.gateway?.auth?.rateLimit?.maxAttempts === 'number'\n ? config.gateway.auth.rateLimit.maxAttempts\n : 5,\n windowMs:\n typeof config.gateway?.auth?.rateLimit?.windowMs === 'number'\n ? config.gateway.auth.rateLimit.windowMs\n : 900_000,\n blockDurationMs:\n typeof config.gateway?.auth?.rateLimit?.blockDurationMs === 'number'\n ? config.gateway.auth.rateLimit.blockDurationMs\n : typeof config.gateway?.auth?.rateLimit?.lockoutMs === 'number'\n ? config.gateway.auth.rateLimit.lockoutMs\n : 300_000,\n exemptLoopback: config.gateway?.auth?.rateLimit?.exemptLoopback !== false,\n },\n },\n heartbeat: {\n enabled: config.gateway?.heartbeat?.enabled,\n intervalMs: config.gateway?.heartbeat?.intervalMs,\n includeSystemPromptSection: config.gateway?.heartbeat?.includeSystemPromptSection === true,\n target: config.gateway?.heartbeat?.target,\n targetChatId: config.gateway?.heartbeat?.targetChatId,\n prompt: config.gateway?.heartbeat?.prompt,\n ackMaxChars: config.gateway?.heartbeat?.ackMaxChars,\n isolatedSession: config.gateway?.heartbeat?.isolatedSession,\n activeHours: config.gateway?.heartbeat?.activeHours,\n },\n maxSseConnections:\n typeof config.gateway?.maxSseConnections === 'number'\n ? config.gateway.maxSseConnections\n : 100,\n channelConnectDeferMode: config.gateway?.channelConnectDeferMode ?? 'auto',\n channelConnectDeferIds: Array.isArray(config.gateway?.channelConnectDeferIds)\n ? config.gateway.channelConnectDeferIds\n : [],\n channelConnectDeferSkipIds: Array.isArray(config.gateway?.channelConnectDeferSkipIds)\n ? config.gateway.channelConnectDeferSkipIds\n : [],\n share: resolveShareConfig(config.gateway?.share),\n publicUrl: config.gateway?.publicUrl ?? null,\n skillsMarketplaceProvider: config.gateway?.skillsMarketplaceProvider ?? 'store',\n skillsStoreBaseUrl: config.gateway?.skillsStoreBaseUrl ?? 'https://store.xopc.ai',\n },\n browser: buildSafeBrowserConfigForWeb(config.browser),\n goals: resolveGoalsConfigForWeb(config),\n session: resolveSessionConfigForWeb(config),\n tui: {\n defaultAgent: config.tui?.defaultAgent ?? 'coder',\n },\n tunnel: {\n enabled: config.tunnel?.enabled === true,\n autoStart: config.tunnel?.autoStart === true,\n brokerUrl: config.tunnel?.brokerUrl ?? 'https://frp.xopc.ai/api',\n registrationSecret: config.tunnel?.registrationSecret\n ? maskTunnelSecretForWeb(config.tunnel.registrationSecret)\n : '',\n consent: config.tunnel?.consent\n ? {\n version: config.tunnel.consent.version,\n acceptedAt: config.tunnel.consent.acceptedAt,\n }\n : undefined,\n transport: { tls: 'broker_terminated' as const },\n },\n update: {\n ...resolveUpdateConfigForWeb(config),\n },\n stt: maskSttConfigForWeb(config.tools?.media?.audio),\n tts: maskTtsConfigForWeb(config.messages?.tts),\n voice: config.voice,\n tools: safeToolsWebForGet(config),\n bindings: Array.isArray(config.bindings) ? config.bindings : [],\n mcp: buildSafeMcpConfigForWeb(config),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;kBAIuC;8BAKuB;kBAcI;kBACiB;gBACC;sBACR;AAM5E,SAAS,6BAA6B,YAAwC;CAC5E,MAAM,EAAE,WAAW,eAAeA,uBAAmB,CAAC;CAEtD,MAAM,OADQ,OAAO,YAAY,cACd;AACnB,QAAO,OAAO,QAAQ,YAAY,IAAI,MAAM,GAAG,IAAI,MAAM,GAAG,KAAA;;;AAI9D,eAAe,4BAA4B,UAAmC;CAE5E,MAAM,SAAS,MAAM,IADA,oBACQ,CAAC,0BAA0B,SAAS;AACjE,KAAI,OAAQ,QAAO,iBAAiB,OAAO;CAE3C,MAAM,iBAAiB,6BAA6B,SAAS;AAC7D,KAAI,eAAgB,QAAO,iBAAiB,eAAe;AAG3D,KAAI,qBAAqB,CAAC,IAAI,SAAS,CAAE,QAAO;AAEhD,KAAI,MAAM,qBAAqB,SAAS,CAAE,QAAO;AACjD,QAAO;;;AAIT,SAAgB,yBAAyB,QAAgB;CACvD,MAAM,MAAM,OAAO;AACnB,KAAI,CAAC,IACH,QAAO,EAAE,SAAS,EAAE,EAA6C;AAEnE,QAAO;EACL,GAAI,IAAI,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,IAAI,kBAAkB,GAAG,EAAE;EACxF,SAAS,8BAA8B,IAAI,QAAQ;EACpD;;AAGH,SAAS,6BAA6B,OAAgD;AACpF,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO;CAET,MAAM,MAAM;CACZ,MAAM,OAAgC,EAAE;AACxC,KAAI,OAAO,IAAI,WAAW,YAAY,IAAI,OAAO,MAAM,CACrD,MAAK,SAAS,iBAAiB,IAAI,OAAO;AAE5C,KAAI,OAAO,IAAI,cAAc,YAAY,IAAI,UAAU,MAAM,CAC3D,MAAK,YAAY,IAAI,UAAU,MAAM;AAEvC,KAAI,OAAO,IAAI,WAAW,YAAY,IAAI,OAAO,MAAM,CACrD,MAAK,SAAS,IAAI,OAAO,MAAM;AAEjC,QAAO,OAAO,KAAK,KAAK,CAAC,SAAS,IAAI,OAAO;;AAG/C,SAAgB,6BAA6B,SAAkB;AAC7D,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;EACL,SAAS;EACT,UAAU;EACV,kBAAkB;EAClB,gBAAgB;EAChB,SAAS;EACT,eAAe;EACf,OAAO;EACP,QAAQ;EACR,WAAW;EACX,cAAc;EACd,UAAU;EACV,aAAa;EACb,cAAc;EACd,sBAAsB;EACvB;AAGH,QAAO;EACL,SAAU,QAAoC,YAAY;EAC1D,UAAW,QAAoC,aAAa;EAC5D,kBAAmB,QAAoC,qBAAqB;EAC5E,gBACE,OAAQ,QAAoC,mBAAmB,YAC/D,OAAO,SAAU,QAAoC,eAAyB,GAC1E,KAAK,MAAO,QAAoC,eAAyB,GACzE;EACN,SACG,QAAoC,YAAY,WAChD,QAAoC,YAAY,SAChD,QAAoC,YAAY,WAChD,QAAoC,YAAY,eAChD,QAAoC,YAAY,iBAC5C,QAAoC,UACrC;EACN,eACG,QAAoC,kBAAkB,iBACtD,QAAoC,kBAAkB,gBAClD,QAAoC,gBACrC;EACN,OAAO,6BAA8B,QAAoC,MAAM;EAC/E,QACE,OAAQ,QAAoC,WAAW,YACrD,QAAoC,OAAkB,MAAM,GACxD,QAAoC,OAAkB,MAAM,GAC9D;EACN,WACG,QAAoC,aACrC,OAAQ,QAAoC,cAAc,YAC1D,CAAC,MAAM,QAAS,QAAoC,UAAU,GACzD,QAAoC,YACvC;EACJ,cACG,QAAoC,gBACrC,OAAQ,QAAoC,iBAAiB,YAC7D,CAAC,MAAM,QAAS,QAAoC,aAAa,GAC5D,QAAoC,eACrC;EACN,UACE,OAAQ,QAAoC,aAAa,YACpD,QAAoC,WACrC;EACN,aACG,QAAoC,gBAAgB,aACpD,QAAoC,gBAAgB,YAChD,QAAoC,cACrC;EACN,cACG,QAAoC,iBAAiB,kBACrD,QAAoC,iBAAiB,iBACrD,QAAoC,iBAAiB,iBACjD,QAAoC,eACrC;EACN,sBACE,OAAQ,QAAoC,yBAAyB,YACrE,OAAO,SAAU,QAAoC,qBAA+B,GAChF,KAAK,MAAO,QAAoC,qBAA+B,GAC/E;EACP;;;AAIH,eAAsB,0BAA0B,SAAyB,UAA+B,EAAE,EAAE;CAC1G,MAAM,SAAS,QAAQ;CAGvB,MAAM,YADJ,OAAO,QAAQ,uBAAuB,aAAa,QAAQ,oBAAoB,GAAG,KAAA,IAClD,qBAAqB;CACvD,MAAM,UAAU,WACZ,gCAAgC,UAAU,EAAE,QAAQ,QAAQ,QAAQ,CAAC,GACrE,6BAA6B,QAAQ,EAAE,QAAQ,QAAQ,QAAQ,CAAC;CACpE,MAAM,kBAAkB,OAAO,YAC7B,QAAQ,QAAQ,KAAK,UAAU;EAC7B,MAAM,SACJ,OAAO,QAAQ,4BAA4B,aACvC,QAAQ,wBAAwB,MAAM,GAAG,GACzC,KAAA;EACN,MAAM,gBAAgB,MAAM,WAAW,WAAW,YAAY,GAC1D,MAAM,WAAW,MAAM,EAAmB,CAAC,MAAM,IAAI,CAAC,MAAM,MAAM,KAClE,MAAM;EACV,MAAM,aAAa,OAAO,WAAW;EACrC,MAAM,cAAc,sBAAsB,QAAQ,MAAM,IAAI,MAAM;AAClE,SAAO,CACL,MAAM,IACN;GACE,SAAS,YAAY;GACrB,YAAY,YAAY;GACxB;GACA,QAAQ,QAAQ,eAAe,mBAAmB,OAAO,IAAI,cAAc,EAAE;GAC7E,QAAQ,MAAM;GACd,SAAS,MAAM;GAChB,CACF;GACD,CACH;AACD,QAAO;EACL,QAAQ;GACN,WAAW,sBAAsB,OAAO;GACxC,MAAM,iBAAiB,OAAO,CAC3B,QAAQ,MAAM,EAAE,YAAY,MAAM,CAClC,KAAK,OAAO;IACX,IAAI,iBAAiB,EAAE,GAAG;IAC1B,UAAU,EAAE;IACZ,WAAW,EAAE;IACb,QAAQ,EAAE;IACV,OAAO,EAAE;IACT,QAAQ,EAAE;IACV,WAAW,EAAE;IACb,YAAY,EAAE;IACf,EAAE;GACL,mBAAmB,OAAO,QAAQ,qBAAqB,EAAE;GAC1D;EACD,UAAU;EACV,WAAW,OAAO,YAChB,MAAM,QAAQ,IACZ,iBAAiB,CAAC,IAAI,OAAO,aAAa,CACxC,UACA,MAAM,4BAA4B,SAAS,CAC5C,CAAC,CACH,CACF;;EAED,iBAAiB,+BAA+B,OAAO,UAAU;EACjE,SAAS;GACP,MAAM,OAAO,SAAS,QAAQ;GAC9B,gBAAgB,OAAO,SAAS;GAChC,MAAM,OAAO,SAAS;GACtB,aAAa,MAAM,QAAQ,OAAO,SAAS,YAAY,GAAG,OAAO,QAAQ,cAAc,EAAE;GACzF,gBAAgB,MAAM,QAAQ,OAAO,SAAS,eAAe,GACzD,OAAO,QAAQ,iBACf,EAAE;GACN,qBAAqB,OAAO,SAAS,wBAAwB;GAC7D,0CACE,OAAO,SAAS,6CAA6C;GAC/D,UAAU,EACR,QAAQ,OAAO,SAAS,UAAU,WAAW,MAC9C;GACD,MAAM;IACJ,MAAM,OAAO,SAAS,MAAM,QAAQ;IACpC,OAAO,OAAO,SAAS,MAAM,QAAQ,iBAAiB,OAAO,QAAQ,KAAK,MAAM,GAAG;IACnF,UAAU,OAAO,SAAS,MAAM,WAC5B,iBAAiB,OAAO,QAAQ,KAAK,SAAS,GAC9C;IACJ,cAAc,OAAO,SAAS,MAAM,eAChC;KACE,YAAY,OAAO,QAAQ,KAAK,aAAa;KAC7C,iBAAiB,OAAO,QAAQ,KAAK,aAAa,mBAAmB,EAAE;KACvE,YAAY,OAAO,QAAQ,KAAK,aAAa,cAAc,EAAE;KAC7D,eAAe,OAAO,QAAQ,KAAK,aAAa,kBAAkB;KACnE,GACD,KAAA;IACJ,WAAW;KACT,SAAS,OAAO,SAAS,MAAM,WAAW,YAAY;KACtD,aACE,OAAO,OAAO,SAAS,MAAM,WAAW,gBAAgB,WACpD,OAAO,QAAQ,KAAK,UAAU,cAC9B;KACN,UACE,OAAO,OAAO,SAAS,MAAM,WAAW,aAAa,WACjD,OAAO,QAAQ,KAAK,UAAU,WAC9B;KACN,iBACE,OAAO,OAAO,SAAS,MAAM,WAAW,oBAAoB,WACxD,OAAO,QAAQ,KAAK,UAAU,kBAC9B,OAAO,OAAO,SAAS,MAAM,WAAW,cAAc,WACpD,OAAO,QAAQ,KAAK,UAAU,YAC9B;KACR,gBAAgB,OAAO,SAAS,MAAM,WAAW,mBAAmB;KACrE;IACF;GACD,WAAW;IACT,SAAS,OAAO,SAAS,WAAW;IACpC,YAAY,OAAO,SAAS,WAAW;IACvC,4BAA4B,OAAO,SAAS,WAAW,+BAA+B;IACtF,QAAQ,OAAO,SAAS,WAAW;IACnC,cAAc,OAAO,SAAS,WAAW;IACzC,QAAQ,OAAO,SAAS,WAAW;IACnC,aAAa,OAAO,SAAS,WAAW;IACxC,iBAAiB,OAAO,SAAS,WAAW;IAC5C,aAAa,OAAO,SAAS,WAAW;IACzC;GACD,mBACE,OAAO,OAAO,SAAS,sBAAsB,WACzC,OAAO,QAAQ,oBACf;GACN,yBAAyB,OAAO,SAAS,2BAA2B;GACpE,wBAAwB,MAAM,QAAQ,OAAO,SAAS,uBAAuB,GACzE,OAAO,QAAQ,yBACf,EAAE;GACN,4BAA4B,MAAM,QAAQ,OAAO,SAAS,2BAA2B,GACjF,OAAO,QAAQ,6BACf,EAAE;GACN,OAAO,mBAAmB,OAAO,SAAS,MAAM;GAChD,WAAW,OAAO,SAAS,aAAa;GACxC,2BAA2B,OAAO,SAAS,6BAA6B;GACxE,oBAAoB,OAAO,SAAS,sBAAsB;GAC3D;EACD,SAAS,6BAA6B,OAAO,QAAQ;EACrD,OAAO,yBAAyB,OAAO;EACvC,SAAS,2BAA2B,OAAO;EAC3C,KAAK,EACH,cAAc,OAAO,KAAK,gBAAgB,SAC3C;EACD,QAAQ;GACN,SAAS,OAAO,QAAQ,YAAY;GACpC,WAAW,OAAO,QAAQ,cAAc;GACxC,WAAW,OAAO,QAAQ,aAAa;GACvC,oBAAoB,OAAO,QAAQ,qBAC/B,uBAAuB,OAAO,OAAO,mBAAmB,GACxD;GACJ,SAAS,OAAO,QAAQ,UACpB;IACE,SAAS,OAAO,OAAO,QAAQ;IAC/B,YAAY,OAAO,OAAO,QAAQ;IACnC,GACD,KAAA;GACJ,WAAW,EAAE,KAAK,qBAA8B;GACjD;EACD,QAAQ,EACN,GAAG,0BAA0B,OAAO,EACrC;EACD,KAAK,oBAAoB,OAAO,OAAO,OAAO,MAAM;EACpD,KAAK,oBAAoB,OAAO,UAAU,IAAI;EAC9C,OAAO,OAAO;EACd,OAAO,mBAAmB,OAAO;EACjC,UAAU,MAAM,QAAQ,OAAO,SAAS,GAAG,OAAO,WAAW,EAAE;EAC/D,KAAK,yBAAyB,OAAO;EACtC"}
@@ -1,4 +1,4 @@
1
- import { MemoryPolicySchema, ToolPolicySetSchema, init_schema } from "../../../agent-manifest/schema.js";
1
+ import { ToolPolicySetSchema, init_schema } from "../../../agent-manifest/schema.js";
2
2
  import { AgentModelsSchema, init_schema as init_schema$1 } from "../../../config/schema.js";
3
3
  import { init_agent_scope, normalizeAgentId } from "../../../agent/agent-scope.js";
4
4
  import { getVoiceModelsConfig } from "../../../config/voice.js";
@@ -236,23 +236,17 @@ function registerAgentsRoutes(authenticated, deps) {
236
236
  ok: false,
237
237
  error: { message: modelsPatch.error }
238
238
  }, 400);
239
- let memoryPatch;
240
- if (Object.hasOwn(body, "memory")) {
241
- const parsedMemory = MemoryPolicySchema.safeParse(body.memory);
242
- if (!parsedMemory.success) return c.json({
243
- ok: false,
244
- error: { message: `memory ${parsedMemory.error.issues[0]?.message ?? "is invalid"}` }
245
- }, 400);
246
- memoryPatch = parsedMemory.data;
247
- }
239
+ if (Object.hasOwn(body, "memory")) return c.json({
240
+ ok: false,
241
+ error: { message: "Agent memory configuration is not supported; use userContext" }
242
+ }, 400);
248
243
  const prep = prepareUpdateAgent(service.currentConfig, id, {
249
244
  workspace: typeof body.workspace === "string" ? body.workspace : void 0,
250
245
  ...extendsPatch !== void 0 ? { extends: extendsPatch } : {},
251
246
  ...modelsPatch !== void 0 ? { models: modelsPatch } : {},
252
247
  setDefault: body.setDefault === true,
253
248
  ...skillsPatch !== void 0 ? { skills: skillsPatch } : {},
254
- ...toolsPatch !== void 0 ? { tools: toolsPatch } : {},
255
- ...memoryPatch !== void 0 ? { memory: memoryPatch } : {}
249
+ ...toolsPatch !== void 0 ? { tools: toolsPatch } : {}
256
250
  });
257
251
  if (prep.ok === false) return c.json({
258
252
  ok: false,
@@ -1 +1 @@
1
- {"version":3,"file":"agents.js","names":[],"sources":["../../../../../src/gateway/hono/routes/agents.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { AgentModelsSchema, type Config } from '../../../config/schema.js';\nimport { MemoryPolicySchema, ToolPolicySetSchema } from '../../../agent-manifest/schema.js';\nimport { getVoiceModelsConfig } from '../../../config/voice.js';\nimport { normalizeAgentId } from '../../../agent/agent-scope.js';\nimport {\n deleteAgentAvatarFile,\n finalizeCreateAgentDirs,\n getGatewayAgentEffectiveManifest,\n listAgentProfileFiles,\n listGatewayAgents,\n prepareCreateAgent,\n prepareDeleteAgent,\n prepareUpdateAgent,\n readAgentAvatarFile,\n readAgentProfileFile,\n readUserProfileFile,\n runAfterDeletePurge,\n writeAgentAvatarFromBase64,\n writeAgentProfileFile,\n writeUserProfileFile,\n type CreateAgentBody,\n} from '../../agents-admin.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nfunction parseProfileFiles(raw: unknown): Record<string, string> | undefined | { error: string } {\n if (raw === undefined) {\n return undefined;\n }\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n return { error: 'profileFiles must be an object' };\n }\n const profileFiles: Record<string, string> = {};\n for (const [name, content] of Object.entries(raw as Record<string, unknown>)) {\n if (typeof content !== 'string') {\n return { error: `profileFiles[\"${name}\"] must be a string` };\n }\n profileFiles[name] = content;\n }\n return profileFiles;\n}\n\nfunction isParseError(value: unknown): value is { error: string } {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'error' in value &&\n typeof (value as { error: string }).error === 'string'\n );\n}\n\nfunction parseCreateAgentBody(raw: unknown): CreateAgentBody | { error: string } {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n return { error: 'each agent must be an object' };\n }\n const body = raw as Record<string, unknown>;\n if (Object.hasOwn(body, 'model')) {\n return { error: 'model is not supported; use models.defaultRole and models.roles' };\n }\n if (Object.hasOwn(body, 'toolsDisable')) {\n return { error: 'toolsDisable was removed; use tools.builtin policies' };\n }\n if (Object.hasOwn(body, 'typedModels')) {\n return { error: 'typedModels is not supported; use models.roles' };\n }\n if (Object.hasOwn(body, 'agentDir')) {\n return { error: 'agentDir was removed from agent manifests' };\n }\n if (Object.hasOwn(body, 'name')) {\n return { error: 'name is not supported; write IDENTITY.md in profileFiles' };\n }\n if (Object.hasOwn(body, 'description')) {\n return { error: 'description is not supported; write IDENTITY.md in profileFiles' };\n }\n const workspace = typeof body.workspace === 'string' ? body.workspace : '';\n const models = Object.hasOwn(body, 'models')\n ? AgentModelsSchema.safeParse(body.models)\n : undefined;\n if (models && !models.success) {\n return { error: `models ${models.error.issues[0]?.message ?? 'is invalid'}` };\n }\n const id = typeof body.id === 'string' ? body.id : undefined;\n const presetIds = Object.hasOwn(body, 'extends')\n ? Array.isArray(body.extends)\n ? body.extends.map((x: unknown) => normalizeAgentId(String(x))).filter(Boolean)\n : null\n : undefined;\n if (presetIds === null) {\n return { error: 'extends must be an array' };\n }\n const skills = Object.hasOwn(body, 'skills')\n ? Array.isArray(body.skills)\n ? body.skills.map((x: unknown) => String(x).trim()).filter(Boolean)\n : null\n : undefined;\n if (skills === null) {\n return { error: 'skills must be an array' };\n }\n const toolsRaw = Object.hasOwn(body, 'tools') ? body.tools : undefined;\n let tools: CreateAgentBody['tools'] | undefined;\n if (toolsRaw !== undefined) {\n if (toolsRaw === null || typeof toolsRaw !== 'object' || Array.isArray(toolsRaw)) {\n return { error: 'tools must be an object' };\n }\n const parsedTools = ToolPolicySetSchema.safeParse(toolsRaw);\n if (!parsedTools.success) {\n return { error: `tools ${parsedTools.error.issues[0]?.message ?? 'is invalid'}` };\n }\n tools = parsedTools.data;\n }\n let profileFiles: Record<string, string> | undefined;\n if (Object.hasOwn(body, 'profileFiles')) {\n const parsed = parseProfileFiles(body.profileFiles);\n if (isParseError(parsed)) {\n return parsed;\n }\n profileFiles = parsed;\n }\n if (!profileFiles?.['IDENTITY.md'] && typeof body.cloneFrom !== 'string') {\n return { error: 'profileFiles.IDENTITY.md is required' };\n }\n const cloneFrom = typeof body.cloneFrom === 'string' ? body.cloneFrom : undefined;\n return {\n workspace,\n ...(models && models.data !== undefined ? { models: models.data } : {}),\n ...(id !== undefined ? { id } : {}),\n ...(presetIds !== undefined ? { extends: presetIds } : {}),\n ...(skills !== undefined ? { skills } : {}),\n ...(tools !== undefined ? { tools } : {}),\n ...(profileFiles !== undefined ? { profileFiles } : {}),\n ...(cloneFrom !== undefined ? { cloneFrom } : {}),\n };\n}\n\ntype PatchModels = {\n defaultRole?: string | null;\n roles?: Record<string, { model: string; fallbacks?: string[]; description?: string }>;\n};\n\nfunction parsePatchModels(raw: unknown): PatchModels | null | undefined | { error: string } {\n if (raw === undefined) {\n return undefined;\n }\n if (raw === null) {\n return null;\n }\n if (typeof raw !== 'object' || Array.isArray(raw)) {\n return { error: 'models must be an object or null' };\n }\n const body = raw as Record<string, unknown>;\n const out: PatchModels = {};\n if (Object.hasOwn(body, 'defaultRole')) {\n out.defaultRole = body.defaultRole === null ? null : String(body.defaultRole ?? '').trim();\n }\n if (Object.hasOwn(body, 'roles')) {\n if (body.roles === null) {\n return { error: 'models.roles must be an object' };\n } else {\n const parsed = AgentModelsSchema.safeParse({ roles: body.roles });\n if (!parsed.success) {\n return { error: `models.roles ${parsed.error.issues[0]?.message ?? 'is invalid'}` };\n }\n out.roles = parsed.data?.roles;\n }\n }\n return out;\n}\n\nexport function registerAgentsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.get('/api/agents', async (c) => {\n const cfg = service.currentConfig as Config;\n const locale = c.req.query('locale') || c.req.header('Accept-Language')?.split(',')[0]?.trim();\n const payload = await listGatewayAgents(cfg, { locale });\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/user-profile', async (c) => {\n const res = await readUserProfileFile();\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: res.data });\n });\n\n authenticated.put('/api/user-profile', strictRateLimitMiddleware, async (c) => {\n let content = '';\n try {\n const body = (await c.req.json()) as { content?: unknown };\n content = typeof body.content === 'string' ? body.content : '';\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n const res = await writeUserProfileFile(content);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: res.data });\n });\n\n authenticated.post('/api/agents', strictRateLimitMiddleware, async (c) => {\n let body: Record<string, unknown> = {};\n try {\n body = (await c.req.json()) as Record<string, unknown>;\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n const parsed = parseCreateAgentBody(body);\n if ('error' in parsed) {\n return c.json({ ok: false, error: { message: parsed.error } }, 400);\n }\n const prep = prepareCreateAgent(service.currentConfig as Config, parsed);\n if (prep.ok === false) {\n return c.json({ ok: false, error: { message: prep.error } }, prep.status ?? 400);\n }\n const { nextConfig, agentId } = prep.data;\n const save = await service.saveConfig(nextConfig);\n if (!save.saved) {\n return c.json({ ok: false, error: { message: save.error ?? 'save failed' } }, 500);\n }\n const finalized = await finalizeCreateAgentDirs(service.currentConfig as Config, agentId, {\n ...(parsed.profileFiles !== undefined ? { profileFiles: parsed.profileFiles } : {}),\n ...(parsed.cloneFrom ? { cloneFrom: parsed.cloneFrom } : {}),\n });\n if (finalized.ok === false) {\n return c.json({ ok: false, error: { message: finalized.error } }, finalized.status ?? 400);\n }\n const locale = c.req.query('locale') || c.req.header('Accept-Language')?.split(',')[0]?.trim();\n const agentsPayload = await listGatewayAgents(service.currentConfig as Config, { locale });\n return c.json({\n ok: true,\n payload: {\n agentId,\n agents: agentsPayload,\n },\n });\n });\n\n authenticated.get('/api/agents/:id/effective-manifest', async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const res = getGatewayAgentEffectiveManifest(service.currentConfig as Config, id);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: res.data });\n });\n\n authenticated.patch('/api/agents/:id', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n let body: Record<string, unknown> = {};\n try {\n body = (await c.req.json()) as Record<string, unknown>;\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n if (Object.hasOwn(body, 'model')) {\n return c.json({ ok: false, error: { message: 'model is not supported; use models.defaultRole and models.roles' } }, 400);\n }\n if (Object.hasOwn(body, 'typedModels')) {\n return c.json({ ok: false, error: { message: 'typedModels is not supported; use models.roles' } }, 400);\n }\n if (Object.hasOwn(body, 'toolsDisable')) {\n return c.json({ ok: false, error: { message: 'toolsDisable was removed; use tools.builtin policies' } }, 400);\n }\n if (Object.hasOwn(body, 'agentDir')) {\n return c.json({ ok: false, error: { message: 'agentDir was removed from agent manifests' } }, 400);\n }\n if (Object.hasOwn(body, 'name')) {\n return c.json({ ok: false, error: { message: 'name is not supported; edit IDENTITY.md' } }, 400);\n }\n if (Object.hasOwn(body, 'description')) {\n return c.json({ ok: false, error: { message: 'description is not supported; edit IDENTITY.md' } }, 400);\n }\n const skillsPatch =\n body.skills === null\n ? null\n : Array.isArray(body.skills)\n ? body.skills.map((x: unknown) => String(x).trim()).filter(Boolean)\n : undefined;\n const extendsPatch = Object.hasOwn(body, 'extends')\n ? Array.isArray(body.extends)\n ? body.extends.map((x: unknown) => String(x).trim()).filter(Boolean)\n : undefined\n : undefined;\n if (Object.hasOwn(body, 'extends') && extendsPatch === undefined) {\n return c.json({ ok: false, error: { message: 'extends must be an array' } }, 400);\n }\n let toolsPatch: CreateAgentBody['tools'] | null | undefined;\n if (Object.hasOwn(body, 'tools')) {\n if (body.tools === null) {\n toolsPatch = null;\n } else if (typeof body.tools === 'object' && !Array.isArray(body.tools)) {\n const parsedTools = ToolPolicySetSchema.safeParse(body.tools);\n if (!parsedTools.success) {\n return c.json({ ok: false, error: { message: `tools ${parsedTools.error.issues[0]?.message ?? 'is invalid'}` } }, 400);\n }\n toolsPatch = parsedTools.data;\n } else {\n return c.json({ ok: false, error: { message: 'tools must be an object or null' } }, 400);\n }\n }\n const modelsPatch = Object.hasOwn(body, 'models') ? parsePatchModels(body.models) : undefined;\n if (isParseError(modelsPatch)) {\n return c.json({ ok: false, error: { message: modelsPatch.error } }, 400);\n }\n let memoryPatch: Config['agents']['list'][number]['memory'] | undefined;\n if (Object.hasOwn(body, 'memory')) {\n const parsedMemory = MemoryPolicySchema.safeParse(body.memory);\n if (!parsedMemory.success) {\n return c.json({ ok: false, error: { message: `memory ${parsedMemory.error.issues[0]?.message ?? 'is invalid'}` } }, 400);\n }\n memoryPatch = parsedMemory.data;\n }\n\n const prep = prepareUpdateAgent(service.currentConfig as Config, id, {\n workspace: typeof body.workspace === 'string' ? body.workspace : undefined,\n ...(extendsPatch !== undefined ? { extends: extendsPatch } : {}),\n ...(modelsPatch !== undefined ? { models: modelsPatch } : {}),\n setDefault: body.setDefault === true,\n ...(skillsPatch !== undefined ? { skills: skillsPatch } : {}),\n ...(toolsPatch !== undefined ? { tools: toolsPatch } : {}),\n ...(memoryPatch !== undefined ? { memory: memoryPatch } : {}),\n });\n if (prep.ok === false) {\n return c.json({ ok: false, error: { message: prep.error } }, prep.status ?? 400);\n }\n const save = await service.saveConfig(prep.data.nextConfig);\n if (!save.saved) {\n return c.json({ ok: false, error: { message: save.error ?? 'save failed' } }, 500);\n }\n const locale = c.req.query('locale') || c.req.header('Accept-Language')?.split(',')[0]?.trim();\n const agentsPayload = await listGatewayAgents(service.currentConfig as Config, { locale });\n return c.json({ ok: true, payload: agentsPayload });\n });\n\n authenticated.delete('/api/agents/:id', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const purge = c.req.query('purge') === '1' || c.req.query('purge') === 'true';\n const prep = prepareDeleteAgent(service.currentConfig as Config, id);\n if (prep.ok === false) {\n return c.json({ ok: false, error: { message: prep.error } }, prep.status ?? 400);\n }\n const { nextConfig, agentId } = prep.data;\n const save = await service.saveConfig(nextConfig);\n if (!save.saved) {\n return c.json({ ok: false, error: { message: save.error ?? 'save failed' } }, 500);\n }\n if (purge) {\n await runAfterDeletePurge(service.currentConfig as Config, agentId);\n }\n const locale = c.req.query('locale') || c.req.header('Accept-Language')?.split(',')[0]?.trim();\n const agentsPayload = await listGatewayAgents(service.currentConfig as Config, { locale });\n return c.json({\n ok: true,\n payload: { agentId, purged: purge, agents: agentsPayload },\n });\n });\n\n authenticated.get('/api/agents/:id/avatar', async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const res = await readAgentAvatarFile(service.currentConfig as Config, id);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return new Response(res.data.buffer, {\n status: 200,\n headers: {\n 'Content-Type': res.data.contentType,\n 'Cache-Control': 'private, max-age=3600',\n },\n });\n });\n\n authenticated.put('/api/agents/:id/avatar', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n let body: Record<string, unknown> = {};\n try {\n body = (await c.req.json()) as Record<string, unknown>;\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n const base64 = typeof body.base64 === 'string' ? body.base64 : '';\n const mimeType = typeof body.mimeType === 'string' ? body.mimeType : '';\n const res = await writeAgentAvatarFromBase64(service.currentConfig as Config, id, base64, mimeType);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: { agentId: res.data.agentId } });\n });\n\n authenticated.delete('/api/agents/:id/avatar', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const res = await deleteAgentAvatarFile(service.currentConfig as Config, id);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: { agentId: res.data.agentId } });\n });\n\n authenticated.get('/api/agents/:id/files', async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const res = await listAgentProfileFiles(service.currentConfig as Config, id);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: res.data });\n });\n\n authenticated.get('/api/agents/:id/files/:name', async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const name = decodeURIComponent(c.req.param('name') ?? '');\n const res = await readAgentProfileFile(service.currentConfig as Config, id, name);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: { agentId: res.data.agentId, name, content: res.data.content } });\n });\n\n authenticated.put('/api/agents/:id/files/:name', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const name = decodeURIComponent(c.req.param('name') ?? '');\n let content = '';\n try {\n const body = (await c.req.json()) as { content?: unknown };\n content = typeof body.content === 'string' ? body.content : '';\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n const res = await writeAgentProfileFile(service.currentConfig as Config, id, name, content);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: { agentId: res.data.agentId, name } });\n });\n\n // GET /api/voice/models - Get available STT/TTS models\n authenticated.get('/api/voice/models', (c) => {\n const models = getVoiceModelsConfig();\n return c.json({ ok: true, payload: { models } });\n });\n\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agents.js","names":[],"sources":["../../../../../src/gateway/hono/routes/agents.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { AgentModelsSchema, type Config } from '../../../config/schema.js';\nimport { ToolPolicySetSchema } from '../../../agent-manifest/schema.js';\nimport { getVoiceModelsConfig } from '../../../config/voice.js';\nimport { normalizeAgentId } from '../../../agent/agent-scope.js';\nimport {\n deleteAgentAvatarFile,\n finalizeCreateAgentDirs,\n getGatewayAgentEffectiveManifest,\n listAgentProfileFiles,\n listGatewayAgents,\n prepareCreateAgent,\n prepareDeleteAgent,\n prepareUpdateAgent,\n readAgentAvatarFile,\n readAgentProfileFile,\n readUserProfileFile,\n runAfterDeletePurge,\n writeAgentAvatarFromBase64,\n writeAgentProfileFile,\n writeUserProfileFile,\n type CreateAgentBody,\n} from '../../agents-admin.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nfunction parseProfileFiles(raw: unknown): Record<string, string> | undefined | { error: string } {\n if (raw === undefined) {\n return undefined;\n }\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n return { error: 'profileFiles must be an object' };\n }\n const profileFiles: Record<string, string> = {};\n for (const [name, content] of Object.entries(raw as Record<string, unknown>)) {\n if (typeof content !== 'string') {\n return { error: `profileFiles[\"${name}\"] must be a string` };\n }\n profileFiles[name] = content;\n }\n return profileFiles;\n}\n\nfunction isParseError(value: unknown): value is { error: string } {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'error' in value &&\n typeof (value as { error: string }).error === 'string'\n );\n}\n\nfunction parseCreateAgentBody(raw: unknown): CreateAgentBody | { error: string } {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n return { error: 'each agent must be an object' };\n }\n const body = raw as Record<string, unknown>;\n if (Object.hasOwn(body, 'model')) {\n return { error: 'model is not supported; use models.defaultRole and models.roles' };\n }\n if (Object.hasOwn(body, 'toolsDisable')) {\n return { error: 'toolsDisable was removed; use tools.builtin policies' };\n }\n if (Object.hasOwn(body, 'typedModels')) {\n return { error: 'typedModels is not supported; use models.roles' };\n }\n if (Object.hasOwn(body, 'agentDir')) {\n return { error: 'agentDir was removed from agent manifests' };\n }\n if (Object.hasOwn(body, 'name')) {\n return { error: 'name is not supported; write IDENTITY.md in profileFiles' };\n }\n if (Object.hasOwn(body, 'description')) {\n return { error: 'description is not supported; write IDENTITY.md in profileFiles' };\n }\n const workspace = typeof body.workspace === 'string' ? body.workspace : '';\n const models = Object.hasOwn(body, 'models')\n ? AgentModelsSchema.safeParse(body.models)\n : undefined;\n if (models && !models.success) {\n return { error: `models ${models.error.issues[0]?.message ?? 'is invalid'}` };\n }\n const id = typeof body.id === 'string' ? body.id : undefined;\n const presetIds = Object.hasOwn(body, 'extends')\n ? Array.isArray(body.extends)\n ? body.extends.map((x: unknown) => normalizeAgentId(String(x))).filter(Boolean)\n : null\n : undefined;\n if (presetIds === null) {\n return { error: 'extends must be an array' };\n }\n const skills = Object.hasOwn(body, 'skills')\n ? Array.isArray(body.skills)\n ? body.skills.map((x: unknown) => String(x).trim()).filter(Boolean)\n : null\n : undefined;\n if (skills === null) {\n return { error: 'skills must be an array' };\n }\n const toolsRaw = Object.hasOwn(body, 'tools') ? body.tools : undefined;\n let tools: CreateAgentBody['tools'] | undefined;\n if (toolsRaw !== undefined) {\n if (toolsRaw === null || typeof toolsRaw !== 'object' || Array.isArray(toolsRaw)) {\n return { error: 'tools must be an object' };\n }\n const parsedTools = ToolPolicySetSchema.safeParse(toolsRaw);\n if (!parsedTools.success) {\n return { error: `tools ${parsedTools.error.issues[0]?.message ?? 'is invalid'}` };\n }\n tools = parsedTools.data;\n }\n let profileFiles: Record<string, string> | undefined;\n if (Object.hasOwn(body, 'profileFiles')) {\n const parsed = parseProfileFiles(body.profileFiles);\n if (isParseError(parsed)) {\n return parsed;\n }\n profileFiles = parsed;\n }\n if (!profileFiles?.['IDENTITY.md'] && typeof body.cloneFrom !== 'string') {\n return { error: 'profileFiles.IDENTITY.md is required' };\n }\n const cloneFrom = typeof body.cloneFrom === 'string' ? body.cloneFrom : undefined;\n return {\n workspace,\n ...(models && models.data !== undefined ? { models: models.data } : {}),\n ...(id !== undefined ? { id } : {}),\n ...(presetIds !== undefined ? { extends: presetIds } : {}),\n ...(skills !== undefined ? { skills } : {}),\n ...(tools !== undefined ? { tools } : {}),\n ...(profileFiles !== undefined ? { profileFiles } : {}),\n ...(cloneFrom !== undefined ? { cloneFrom } : {}),\n };\n}\n\ntype PatchModels = {\n defaultRole?: string | null;\n roles?: Record<string, { model: string; fallbacks?: string[]; description?: string }>;\n};\n\nfunction parsePatchModels(raw: unknown): PatchModels | null | undefined | { error: string } {\n if (raw === undefined) {\n return undefined;\n }\n if (raw === null) {\n return null;\n }\n if (typeof raw !== 'object' || Array.isArray(raw)) {\n return { error: 'models must be an object or null' };\n }\n const body = raw as Record<string, unknown>;\n const out: PatchModels = {};\n if (Object.hasOwn(body, 'defaultRole')) {\n out.defaultRole = body.defaultRole === null ? null : String(body.defaultRole ?? '').trim();\n }\n if (Object.hasOwn(body, 'roles')) {\n if (body.roles === null) {\n return { error: 'models.roles must be an object' };\n } else {\n const parsed = AgentModelsSchema.safeParse({ roles: body.roles });\n if (!parsed.success) {\n return { error: `models.roles ${parsed.error.issues[0]?.message ?? 'is invalid'}` };\n }\n out.roles = parsed.data?.roles;\n }\n }\n return out;\n}\n\nexport function registerAgentsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.get('/api/agents', async (c) => {\n const cfg = service.currentConfig as Config;\n const locale = c.req.query('locale') || c.req.header('Accept-Language')?.split(',')[0]?.trim();\n const payload = await listGatewayAgents(cfg, { locale });\n return c.json({ ok: true, payload });\n });\n\n authenticated.get('/api/user-profile', async (c) => {\n const res = await readUserProfileFile();\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: res.data });\n });\n\n authenticated.put('/api/user-profile', strictRateLimitMiddleware, async (c) => {\n let content = '';\n try {\n const body = (await c.req.json()) as { content?: unknown };\n content = typeof body.content === 'string' ? body.content : '';\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n const res = await writeUserProfileFile(content);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: res.data });\n });\n\n authenticated.post('/api/agents', strictRateLimitMiddleware, async (c) => {\n let body: Record<string, unknown> = {};\n try {\n body = (await c.req.json()) as Record<string, unknown>;\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n const parsed = parseCreateAgentBody(body);\n if ('error' in parsed) {\n return c.json({ ok: false, error: { message: parsed.error } }, 400);\n }\n const prep = prepareCreateAgent(service.currentConfig as Config, parsed);\n if (prep.ok === false) {\n return c.json({ ok: false, error: { message: prep.error } }, prep.status ?? 400);\n }\n const { nextConfig, agentId } = prep.data;\n const save = await service.saveConfig(nextConfig);\n if (!save.saved) {\n return c.json({ ok: false, error: { message: save.error ?? 'save failed' } }, 500);\n }\n const finalized = await finalizeCreateAgentDirs(service.currentConfig as Config, agentId, {\n ...(parsed.profileFiles !== undefined ? { profileFiles: parsed.profileFiles } : {}),\n ...(parsed.cloneFrom ? { cloneFrom: parsed.cloneFrom } : {}),\n });\n if (finalized.ok === false) {\n return c.json({ ok: false, error: { message: finalized.error } }, finalized.status ?? 400);\n }\n const locale = c.req.query('locale') || c.req.header('Accept-Language')?.split(',')[0]?.trim();\n const agentsPayload = await listGatewayAgents(service.currentConfig as Config, { locale });\n return c.json({\n ok: true,\n payload: {\n agentId,\n agents: agentsPayload,\n },\n });\n });\n\n authenticated.get('/api/agents/:id/effective-manifest', async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const res = getGatewayAgentEffectiveManifest(service.currentConfig as Config, id);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: res.data });\n });\n\n authenticated.patch('/api/agents/:id', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n let body: Record<string, unknown> = {};\n try {\n body = (await c.req.json()) as Record<string, unknown>;\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n if (Object.hasOwn(body, 'model')) {\n return c.json({ ok: false, error: { message: 'model is not supported; use models.defaultRole and models.roles' } }, 400);\n }\n if (Object.hasOwn(body, 'typedModels')) {\n return c.json({ ok: false, error: { message: 'typedModels is not supported; use models.roles' } }, 400);\n }\n if (Object.hasOwn(body, 'toolsDisable')) {\n return c.json({ ok: false, error: { message: 'toolsDisable was removed; use tools.builtin policies' } }, 400);\n }\n if (Object.hasOwn(body, 'agentDir')) {\n return c.json({ ok: false, error: { message: 'agentDir was removed from agent manifests' } }, 400);\n }\n if (Object.hasOwn(body, 'name')) {\n return c.json({ ok: false, error: { message: 'name is not supported; edit IDENTITY.md' } }, 400);\n }\n if (Object.hasOwn(body, 'description')) {\n return c.json({ ok: false, error: { message: 'description is not supported; edit IDENTITY.md' } }, 400);\n }\n const skillsPatch =\n body.skills === null\n ? null\n : Array.isArray(body.skills)\n ? body.skills.map((x: unknown) => String(x).trim()).filter(Boolean)\n : undefined;\n const extendsPatch = Object.hasOwn(body, 'extends')\n ? Array.isArray(body.extends)\n ? body.extends.map((x: unknown) => String(x).trim()).filter(Boolean)\n : undefined\n : undefined;\n if (Object.hasOwn(body, 'extends') && extendsPatch === undefined) {\n return c.json({ ok: false, error: { message: 'extends must be an array' } }, 400);\n }\n let toolsPatch: CreateAgentBody['tools'] | null | undefined;\n if (Object.hasOwn(body, 'tools')) {\n if (body.tools === null) {\n toolsPatch = null;\n } else if (typeof body.tools === 'object' && !Array.isArray(body.tools)) {\n const parsedTools = ToolPolicySetSchema.safeParse(body.tools);\n if (!parsedTools.success) {\n return c.json({ ok: false, error: { message: `tools ${parsedTools.error.issues[0]?.message ?? 'is invalid'}` } }, 400);\n }\n toolsPatch = parsedTools.data;\n } else {\n return c.json({ ok: false, error: { message: 'tools must be an object or null' } }, 400);\n }\n }\n const modelsPatch = Object.hasOwn(body, 'models') ? parsePatchModels(body.models) : undefined;\n if (isParseError(modelsPatch)) {\n return c.json({ ok: false, error: { message: modelsPatch.error } }, 400);\n }\n if (Object.hasOwn(body, 'memory')) {\n return c.json({ ok: false, error: { message: 'Agent memory configuration is not supported; use userContext' } }, 400);\n }\n\n const prep = prepareUpdateAgent(service.currentConfig as Config, id, {\n workspace: typeof body.workspace === 'string' ? body.workspace : undefined,\n ...(extendsPatch !== undefined ? { extends: extendsPatch } : {}),\n ...(modelsPatch !== undefined ? { models: modelsPatch } : {}),\n setDefault: body.setDefault === true,\n ...(skillsPatch !== undefined ? { skills: skillsPatch } : {}),\n ...(toolsPatch !== undefined ? { tools: toolsPatch } : {}),\n });\n if (prep.ok === false) {\n return c.json({ ok: false, error: { message: prep.error } }, prep.status ?? 400);\n }\n const save = await service.saveConfig(prep.data.nextConfig);\n if (!save.saved) {\n return c.json({ ok: false, error: { message: save.error ?? 'save failed' } }, 500);\n }\n const locale = c.req.query('locale') || c.req.header('Accept-Language')?.split(',')[0]?.trim();\n const agentsPayload = await listGatewayAgents(service.currentConfig as Config, { locale });\n return c.json({ ok: true, payload: agentsPayload });\n });\n\n authenticated.delete('/api/agents/:id', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const purge = c.req.query('purge') === '1' || c.req.query('purge') === 'true';\n const prep = prepareDeleteAgent(service.currentConfig as Config, id);\n if (prep.ok === false) {\n return c.json({ ok: false, error: { message: prep.error } }, prep.status ?? 400);\n }\n const { nextConfig, agentId } = prep.data;\n const save = await service.saveConfig(nextConfig);\n if (!save.saved) {\n return c.json({ ok: false, error: { message: save.error ?? 'save failed' } }, 500);\n }\n if (purge) {\n await runAfterDeletePurge(service.currentConfig as Config, agentId);\n }\n const locale = c.req.query('locale') || c.req.header('Accept-Language')?.split(',')[0]?.trim();\n const agentsPayload = await listGatewayAgents(service.currentConfig as Config, { locale });\n return c.json({\n ok: true,\n payload: { agentId, purged: purge, agents: agentsPayload },\n });\n });\n\n authenticated.get('/api/agents/:id/avatar', async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const res = await readAgentAvatarFile(service.currentConfig as Config, id);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return new Response(res.data.buffer, {\n status: 200,\n headers: {\n 'Content-Type': res.data.contentType,\n 'Cache-Control': 'private, max-age=3600',\n },\n });\n });\n\n authenticated.put('/api/agents/:id/avatar', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n let body: Record<string, unknown> = {};\n try {\n body = (await c.req.json()) as Record<string, unknown>;\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n const base64 = typeof body.base64 === 'string' ? body.base64 : '';\n const mimeType = typeof body.mimeType === 'string' ? body.mimeType : '';\n const res = await writeAgentAvatarFromBase64(service.currentConfig as Config, id, base64, mimeType);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: { agentId: res.data.agentId } });\n });\n\n authenticated.delete('/api/agents/:id/avatar', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const res = await deleteAgentAvatarFile(service.currentConfig as Config, id);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: { agentId: res.data.agentId } });\n });\n\n authenticated.get('/api/agents/:id/files', async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const res = await listAgentProfileFiles(service.currentConfig as Config, id);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: res.data });\n });\n\n authenticated.get('/api/agents/:id/files/:name', async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const name = decodeURIComponent(c.req.param('name') ?? '');\n const res = await readAgentProfileFile(service.currentConfig as Config, id, name);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: { agentId: res.data.agentId, name, content: res.data.content } });\n });\n\n authenticated.put('/api/agents/:id/files/:name', strictRateLimitMiddleware, async (c) => {\n const id = normalizeAgentId(c.req.param('id') ?? '');\n const name = decodeURIComponent(c.req.param('name') ?? '');\n let content = '';\n try {\n const body = (await c.req.json()) as { content?: unknown };\n content = typeof body.content === 'string' ? body.content : '';\n } catch {\n return c.json({ ok: false, error: { message: 'Invalid JSON' } }, 400);\n }\n const res = await writeAgentProfileFile(service.currentConfig as Config, id, name, content);\n if (res.ok === false) {\n return c.json({ ok: false, error: { message: res.error } }, res.status ?? 400);\n }\n return c.json({ ok: true, payload: { agentId: res.data.agentId, name } });\n });\n\n // GET /api/voice/models - Get available STT/TTS models\n authenticated.get('/api/voice/models', (c) => {\n const models = getVoiceModelsConfig();\n return c.json({ ok: true, payload: { models } });\n });\n\n}\n"],"mappings":"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"}
@@ -228,6 +228,12 @@ function registerAuthRegistryExtensionsRoutes(authenticated, deps) {
228
228
  manifest: ext.manifest
229
229
  });
230
230
  });
231
+ authenticated.get("/api/extensions/:id/ui-grant", (c) => {
232
+ return c.json({ grant: service.localApps.getUiGrant(c.req.param("id")) });
233
+ });
234
+ authenticated.post("/api/extensions/:id/ui-grant", (c) => {
235
+ return c.json({ grant: service.localApps.grantUiPermissions(c.req.param("id")) });
236
+ });
231
237
  authenticated.get("/api/extensions/:id/storage", async (c) => {
232
238
  const store = await loadExtensionStore(c.req.param("id"));
233
239
  return c.json({ keys: Object.keys(store) });
@@ -1 +1 @@
1
- {"version":3,"file":"auth-registry-extensions.js","names":["extensionMarketplace.searchExtensions","extensionMarketplace.listExtensions","extensionMarketplace.fetchRegistry"],"sources":["../../../../../src/gateway/hono/routes/auth-registry-extensions.ts"],"sourcesContent":["import type { Hono } from 'hono';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\n\nimport type { Config as SurfaceConfig } from '../../../config/config-surface.js';\nimport type { GatewayService } from '../../service.js';\nimport { buildWhenContextSnapshot } from '../../../extensions/when-context.js';\nimport * as extensionMarketplace from '../../../extensions/marketplace.js';\nimport { mergeActivationContext } from '../../../extensions/activation-context.js';\nimport { ActivationPlanner } from '../../../extensions/activation-planner.js';\nimport { getAllModels, getAvailableModels, type Model, type Api } from '../../../providers/index.js';\nimport { createOAuthHandler, loadOAuthCredentialsToCache } from '../oauth.js';\nimport { createOAuthAsyncHandler } from '../oauth-async.js';\nimport { extensionAssetMimeType } from '../lib/extension-assets.js';\nimport { loadExtensionStore, saveExtensionStore } from '../lib/extension-store.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nconst EXTENSION_ASSET_CSP =\n \"default-src 'self'; \" +\n \"script-src 'self' 'unsafe-inline'; \" +\n \"style-src 'self' 'unsafe-inline'; \" +\n \"img-src 'self' data: blob:; \" +\n \"connect-src 'none'; \" +\n \"frame-ancestors 'self'; \" +\n \"frame-src 'none'; \" +\n \"base-uri 'none'; \" +\n \"object-src 'none'; \" +\n \"form-action 'none'\";\n\n/** Sandboxed extension iframes send `Origin: null`; echo it (and real origins) so every status includes ACAO. */\nfunction extensionUiAssetCorsAllowOrigin(c: { req: { header: (name: string) => string | undefined } }): string {\n const origin = c.req.header('origin');\n if (origin === 'null') return 'null';\n if (origin) return origin;\n return '*';\n}\n\nfunction rewriteExtensionAssetHtml(html: string, extensionId: string, assetPath: string): string {\n const assetDir = assetPath.includes('/') ? assetPath.slice(0, assetPath.lastIndexOf('/') + 1) : '';\n const assetBase = `/api/extensions/${extensionId}/assets/${assetDir}`;\n\n return html\n .replace(/(<script\\b[^>]*?\\ssrc=)([\"'])(\\.\\/)?([^\"']+)\\2/gi, (_match, tag, quote, _dot, file) => {\n const isAbsolute =\n file.startsWith('/') || file.startsWith('http://') || file.startsWith('https://');\n const resolvedSrc = isAbsolute ? file : `${assetBase}${file}`;\n return `${tag}${quote}${resolvedSrc}${quote} crossorigin=\"anonymous\"`;\n })\n .replace(/(<link\\b[^>]*?\\shref=)([\"'])(\\.\\/)?([^\"']+)\\2/gi, (_match, tag, quote, _dot, file) => {\n const isAbsolute =\n file.startsWith('/') || file.startsWith('http://') || file.startsWith('https://');\n const resolvedHref = isAbsolute ? file : `${assetBase}${file}`;\n return `${tag}${quote}${resolvedHref}${quote}`;\n });\n}\n\nfunction hasNonEmptyConfigSchema(schema: unknown): boolean {\n if (!schema || typeof schema !== 'object') return false;\n const properties = (schema as { properties?: unknown }).properties;\n return Boolean(properties && typeof properties === 'object' && Object.keys(properties).length > 0);\n}\n\n/**\n * Register extension UI asset routes on the public (unauthenticated) app.\n *\n * Sandboxed iframes (`sandbox=\"allow-scripts …\"` without `allow-same-origin`) have an\n * opaque origin of `null`, so sub-resource requests from inside the iframe cannot\n * carry the `?token=` query parameter that was on the parent HTML URL. Putting these\n * routes behind the auth middleware therefore causes every JS/CSS asset to return 401.\n *\n * Security is maintained by the strict Content-Security-Policy returned with every\n * asset (`frame-ancestors 'self'`), which prevents any page other than the gateway\n * console itself from embedding the extension iframes.\n */\nexport function registerPublicExtensionAssetRoutes(app: Hono, service: GatewayService): void {\n app.get('/api/extensions/:id/assets/*', async (c) => {\n const acao = extensionUiAssetCorsAllowOrigin(c);\n const corsHdr = { 'Access-Control-Allow-Origin': acao } as const;\n\n const extensionId = c.req.param('id');\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ error: 'Extensions unavailable' }, 503, corsHdr);\n }\n\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === extensionId);\n if (!ext || !ext.manifest.ui) {\n return c.json({ error: 'Extension not found or has no UI' }, 404, corsHdr);\n }\n\n const prefix = `/api/extensions/${extensionId}/assets/`;\n const assetPathEncoded = c.req.path.startsWith(prefix) ? c.req.path.slice(prefix.length) : '';\n let assetPath = assetPathEncoded;\n try {\n assetPath = decodeURIComponent(assetPathEncoded);\n } catch {\n return c.json({ error: 'Invalid asset path' }, 400, corsHdr);\n }\n\n if (!assetPath || assetPath.includes('..')) {\n return c.json({ error: 'Invalid asset path' }, 400, corsHdr);\n }\n\n const root = resolve(ext.path);\n const fullPath = resolve(root, assetPath);\n const rel = relative(root, fullPath);\n if (rel.startsWith('..') || rel === '') {\n return c.json({ error: 'Path traversal denied' }, 403, corsHdr);\n }\n\n if (!existsSync(fullPath) || !statSync(fullPath).isFile()) {\n return c.json({ error: 'Not found' }, 404, corsHdr);\n }\n\n const rawContent = readFileSync(fullPath);\n const mimeType = extensionAssetMimeType(assetPath);\n\n const body: string | Uint8Array = mimeType.startsWith('text/html')\n ? rewriteExtensionAssetHtml(rawContent.toString('utf-8'), extensionId, assetPath)\n : new Uint8Array(rawContent);\n\n return new Response(body, {\n status: 200,\n headers: {\n 'Content-Type': mimeType,\n 'Content-Security-Policy': EXTENSION_ASSET_CSP,\n 'Cache-Control': 'no-store',\n 'X-Content-Type-Options': 'nosniff',\n 'Access-Control-Allow-Origin': acao,\n },\n });\n });\n}\n\nexport function registerAuthRegistryExtensionsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n // ========== Auth API (/api/auth) ==========\n\n // GET /api/auth/token - Get current gateway token\n authenticated.get('/api/auth/token', (c) => {\n const authToken = service.getAuthToken();\n return c.json({ \n ok: true, \n payload: { \n token: authToken,\n mode: service.getAuthMode(),\n } \n });\n });\n\n // POST /api/auth/token/refresh - Generate new gateway token\n authenticated.post('/api/auth/token/refresh', async (c) => {\n try {\n const newToken = await service.refreshAuthToken();\n return c.json({ \n ok: true, \n payload: { \n token: newToken,\n message: 'Token refreshed successfully. Please update your client configuration.'\n } \n });\n } catch (err) {\n return c.json({ \n ok: false, \n error: err instanceof Error ? err.message : 'Failed to refresh token' \n }, 500);\n }\n });\n\n // ========== OAuth API (/api/auth/oauth) ==========\n authenticated.route('/api/auth/oauth', createOAuthHandler(service));\n\n // ========== Async OAuth API (/api/auth/oauth-async) ==========\n authenticated.route('/api/auth/oauth-async', createOAuthAsyncHandler(service));\n\n // Load OAuth credentials from config into cache on startup\n loadOAuthCredentialsToCache(service);\n\n // ========== Registry API ==========\n \n // GET /api/registry - Full registry for frontend\n authenticated.get('/api/registry', async (c) => {\n const allModels = getAllModels();\n const availableModels = await getAvailableModels();\n const configured = new Set(availableModels.map(m => `${m.provider}/${m.id}`));\n \n // Group models by provider\n const providerMap = new Map<string, Model<Api>[]>();\n for (const model of allModels) {\n const list = providerMap.get(model.provider) ?? [];\n list.push(model);\n providerMap.set(model.provider, list);\n }\n \n return c.json({\n ok: true,\n payload: {\n version: 'pi-ai',\n providers: Array.from(providerMap.entries()).map(([id, models]) => ({\n id,\n name: id.charAt(0).toUpperCase() + id.slice(1),\n configured: models.some(m => configured.has(`${m.provider}/${m.id}`)),\n models: models.map(m => ({\n ref: `${m.provider}/${m.id}`,\n id: m.id,\n name: m.name,\n provider: m.provider,\n reasoning: m.reasoning ?? false,\n input: m.input ?? ['text'],\n contextWindow: m.contextWindow ?? 128000,\n maxTokens: m.maxTokens ?? 4096,\n cost: {\n input: m.cost?.input ?? 0,\n output: m.cost?.output ?? 0,\n },\n available: configured.has(`${m.provider}/${m.id}`),\n })),\n })),\n },\n });\n });\n\n // ========== Extension UI (manifest discovery + static assets) ==========\n\n authenticated.get('/api/extensions', async (c) => {\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ extensions: [] });\n }\n\n const registry = loader.getRegistry();\n const discovered = loader.discoverExtensions();\n const activeIds = new Set<string>();\n for (const [id] of registry.extensions) {\n activeIds.add(id);\n }\n\n loader.setConfig(service.currentConfig as unknown as SurfaceConfig);\n let activationEligibleIds: Set<string> = new Set();\n try {\n const planner = new ActivationPlanner(loader.buildManifestRegistry());\n activationEligibleIds = new Set(\n planner.getActivatedIds(mergeActivationContext(service.currentConfig as unknown as SurfaceConfig)),\n );\n } catch {\n activationEligibleIds = new Set();\n }\n\n const extensions = discovered.map((ext) => ({\n id: ext.manifest.id,\n name: ext.manifest.name,\n description: ext.manifest.description,\n version: ext.manifest.version,\n kind: ext.manifest.kind,\n source: ext.source,\n active: activeIds.has(ext.id),\n activationEligible: activationEligibleIds.has(ext.id),\n hasUi: Boolean(ext.manifest.ui),\n hasConfigSchema: hasNonEmptyConfigSchema(ext.manifest.configSchema),\n ui: ext.manifest.ui\n ? {\n icon: ext.manifest.ui.icon,\n permissions: ext.manifest.ui.permissions,\n contributions: ext.manifest.ui.contributions,\n }\n : undefined,\n }));\n return c.json({ extensions });\n });\n\n /**\n * Built-in (bundled) extension enable/disable — persists `extensions.enabled` / `extensions.disabled`.\n * Body: `{ extensionId: string, enabled: boolean }`\n */\n authenticated.post('/api/extensions/bundled/activation', strictRateLimitMiddleware, async (c) => {\n const body = (await c.req.json().catch(() => null)) as\n | { extensionId?: unknown; enabled?: unknown }\n | null;\n const extensionId =\n typeof body?.extensionId === 'string' ? body.extensionId.trim() : '';\n if (!extensionId) {\n return c.json({ ok: false, error: { message: 'extensionId is required' } }, 400);\n }\n if (typeof body?.enabled !== 'boolean') {\n return c.json({ ok: false, error: { message: 'enabled must be a boolean' } }, 400);\n }\n const result = await service.setBundledExtensionActivationTarget(extensionId, body.enabled);\n if (!result.ok) {\n return c.json({ ok: false, error: { message: result.error ?? 'Request failed' } }, 400);\n }\n return c.json({\n ok: true,\n payload: { requiresGatewayRestart: result.requiresGatewayRestart },\n });\n });\n\n authenticated.get('/api/extensions/:id', async (c) => {\n const extensionId = c.req.param('id');\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ error: 'Extensions unavailable' }, 503);\n }\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === extensionId);\n if (!ext) {\n return c.json({ error: 'Extension not found' }, 404);\n }\n const registry = loader.getRegistry();\n return c.json({\n id: ext.manifest.id,\n name: ext.manifest.name,\n description: ext.manifest.description,\n version: ext.manifest.version,\n kind: ext.manifest.kind,\n source: ext.source,\n path: ext.path,\n active: registry.extensions.has(ext.id),\n manifest: ext.manifest,\n });\n });\n\n authenticated.get('/api/extensions/:id/storage', async (c) => {\n const extensionId = c.req.param('id');\n const store = await loadExtensionStore(extensionId);\n return c.json({ keys: Object.keys(store) });\n });\n\n authenticated.get('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const store = await loadExtensionStore(extensionId);\n if (!(key in store)) {\n return c.json({ error: 'Key not found' }, 404);\n }\n return c.json({ value: store[key] });\n });\n\n authenticated.put('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const body = (await c.req.json().catch(() => null)) as { value?: unknown } | null;\n if (body === null || !('value' in body)) {\n return c.json({ error: 'Request body must contain a \"value\" field' }, 400);\n }\n const store = await loadExtensionStore(extensionId);\n store[key] = body.value;\n await saveExtensionStore(extensionId, store);\n return c.json({ ok: true });\n });\n\n authenticated.delete('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const store = await loadExtensionStore(extensionId);\n delete store[key];\n await saveExtensionStore(extensionId, store);\n return c.json({ ok: true });\n });\n\n authenticated.get('/api/extensions/:id/config', async (c) => {\n const extensionId = c.req.param('id');\n return c.json(await loadExtensionStore(`__config__${extensionId}`));\n });\n\n authenticated.patch('/api/extensions/:id/config', async (c) => {\n const extensionId = c.req.param('id');\n const patch = (await c.req.json().catch(() => null)) as Record<string, unknown> | null;\n if (!patch || typeof patch !== 'object' || Array.isArray(patch)) {\n return c.json({ error: 'Request body must be a JSON object' }, 400);\n }\n const namespace = `__config__${extensionId}`;\n const config = await loadExtensionStore(namespace);\n Object.assign(config, patch);\n await saveExtensionStore(namespace, config);\n return c.json({ ok: true });\n });\n\n authenticated.get('/api/context', (c) => {\n const loader = service.getExtensionLoader();\n const snapshot = buildWhenContextSnapshot(\n service.currentConfig as unknown as SurfaceConfig,\n loader,\n );\n return c.json(snapshot);\n });\n\n authenticated.get('/api/marketplace', async (c) => {\n const q = c.req.query('q');\n const category = c.req.query('category');\n try {\n let extensions;\n if (typeof q === 'string' && q.trim()) {\n extensions = await extensionMarketplace.searchExtensions(q.trim());\n } else if (typeof category === 'string' && category.trim()) {\n extensions = await extensionMarketplace.listExtensions(category.trim());\n } else {\n const reg = await extensionMarketplace.fetchRegistry();\n extensions = reg.extensions;\n }\n return c.json({ ok: true, extensions });\n } catch (err) {\n return c.json(\n {\n ok: false,\n extensions: [],\n error: err instanceof Error ? err.message : 'marketplace fetch failed',\n },\n 500,\n );\n }\n });\n\n authenticated.get('/api/marketplace/packages/:pkgName', async (c) => {\n const raw = c.req.param('pkgName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing package name' }, 400);\n }\n let pkgName: string;\n try {\n pkgName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid package name' }, 400);\n }\n try {\n const payload = await service.marketplace.fetchExtensionPackageDetail(pkgName);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.post('/api/marketplace/install', strictRateLimitMiddleware, async (c) => {\n let body: { name?: unknown; version?: unknown; overwrite?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const name = typeof body.name === 'string' ? body.name.trim() : '';\n const version = typeof body.version === 'string' ? body.version.trim() : undefined;\n const overwrite =\n body.overwrite === true || body.overwrite === 'true' || body.overwrite === '1';\n if (!name) {\n return c.json(\n { ok: false, error: 'Expected { name: string, version?: string, overwrite?: boolean }' },\n 400,\n );\n }\n try {\n const payload = await service.marketplace.installExtension({ name, version, overwrite });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.post('/api/marketplace/uninstall', strictRateLimitMiddleware, async (c) => {\n let body: { extensionId?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const extensionId = typeof body.extensionId === 'string' ? body.extensionId.trim() : '';\n if (!extensionId) {\n return c.json({ ok: false, error: 'Expected { extensionId: string }' }, 400);\n }\n try {\n const payload = await service.marketplace.uninstallExtension(extensionId);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Uninstall failed' },\n 400,\n );\n }\n });\n\n // POST /api/registry/reload — reload gateway config and refresh model list for clients\n authenticated.post('/api/registry/reload', async (c) => {\n try {\n // Reload config\n await service.reloadConfig();\n \n // Reload OAuth credentials from new config\n loadOAuthCredentialsToCache(service);\n \n const models = getAllModels();\n \n // Emit SSE event to all connected clients\n service.emit('registry.updated', { modelCount: models.length });\n \n return c.json({\n ok: true,\n payload: {\n message: 'Registry reloaded',\n modelCount: models.length,\n },\n });\n } catch (err) {\n return c.json({\n error: err instanceof Error ? err.message : 'Failed to reload registry',\n }, 500);\n }\n });\n\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"auth-registry-extensions.js","names":["extensionMarketplace.searchExtensions","extensionMarketplace.listExtensions","extensionMarketplace.fetchRegistry"],"sources":["../../../../../src/gateway/hono/routes/auth-registry-extensions.ts"],"sourcesContent":["import type { Hono } from 'hono';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\n\nimport type { Config as SurfaceConfig } from '../../../config/config-surface.js';\nimport type { GatewayService } from '../../service.js';\nimport { buildWhenContextSnapshot } from '../../../extensions/when-context.js';\nimport * as extensionMarketplace from '../../../extensions/marketplace.js';\nimport { mergeActivationContext } from '../../../extensions/activation-context.js';\nimport { ActivationPlanner } from '../../../extensions/activation-planner.js';\nimport { getAllModels, getAvailableModels, type Model, type Api } from '../../../providers/index.js';\nimport { createOAuthHandler, loadOAuthCredentialsToCache } from '../oauth.js';\nimport { createOAuthAsyncHandler } from '../oauth-async.js';\nimport { extensionAssetMimeType } from '../lib/extension-assets.js';\nimport { loadExtensionStore, saveExtensionStore } from '../lib/extension-store.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nconst EXTENSION_ASSET_CSP =\n \"default-src 'self'; \" +\n \"script-src 'self' 'unsafe-inline'; \" +\n \"style-src 'self' 'unsafe-inline'; \" +\n \"img-src 'self' data: blob:; \" +\n \"connect-src 'none'; \" +\n \"frame-ancestors 'self'; \" +\n \"frame-src 'none'; \" +\n \"base-uri 'none'; \" +\n \"object-src 'none'; \" +\n \"form-action 'none'\";\n\n/** Sandboxed extension iframes send `Origin: null`; echo it (and real origins) so every status includes ACAO. */\nfunction extensionUiAssetCorsAllowOrigin(c: { req: { header: (name: string) => string | undefined } }): string {\n const origin = c.req.header('origin');\n if (origin === 'null') return 'null';\n if (origin) return origin;\n return '*';\n}\n\nfunction rewriteExtensionAssetHtml(html: string, extensionId: string, assetPath: string): string {\n const assetDir = assetPath.includes('/') ? assetPath.slice(0, assetPath.lastIndexOf('/') + 1) : '';\n const assetBase = `/api/extensions/${extensionId}/assets/${assetDir}`;\n\n return html\n .replace(/(<script\\b[^>]*?\\ssrc=)([\"'])(\\.\\/)?([^\"']+)\\2/gi, (_match, tag, quote, _dot, file) => {\n const isAbsolute =\n file.startsWith('/') || file.startsWith('http://') || file.startsWith('https://');\n const resolvedSrc = isAbsolute ? file : `${assetBase}${file}`;\n return `${tag}${quote}${resolvedSrc}${quote} crossorigin=\"anonymous\"`;\n })\n .replace(/(<link\\b[^>]*?\\shref=)([\"'])(\\.\\/)?([^\"']+)\\2/gi, (_match, tag, quote, _dot, file) => {\n const isAbsolute =\n file.startsWith('/') || file.startsWith('http://') || file.startsWith('https://');\n const resolvedHref = isAbsolute ? file : `${assetBase}${file}`;\n return `${tag}${quote}${resolvedHref}${quote}`;\n });\n}\n\nfunction hasNonEmptyConfigSchema(schema: unknown): boolean {\n if (!schema || typeof schema !== 'object') return false;\n const properties = (schema as { properties?: unknown }).properties;\n return Boolean(properties && typeof properties === 'object' && Object.keys(properties).length > 0);\n}\n\n/**\n * Register extension UI asset routes on the public (unauthenticated) app.\n *\n * Sandboxed iframes (`sandbox=\"allow-scripts …\"` without `allow-same-origin`) have an\n * opaque origin of `null`, so sub-resource requests from inside the iframe cannot\n * carry the `?token=` query parameter that was on the parent HTML URL. Putting these\n * routes behind the auth middleware therefore causes every JS/CSS asset to return 401.\n *\n * Security is maintained by the strict Content-Security-Policy returned with every\n * asset (`frame-ancestors 'self'`), which prevents any page other than the gateway\n * console itself from embedding the extension iframes.\n */\nexport function registerPublicExtensionAssetRoutes(app: Hono, service: GatewayService): void {\n app.get('/api/extensions/:id/assets/*', async (c) => {\n const acao = extensionUiAssetCorsAllowOrigin(c);\n const corsHdr = { 'Access-Control-Allow-Origin': acao } as const;\n\n const extensionId = c.req.param('id');\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ error: 'Extensions unavailable' }, 503, corsHdr);\n }\n\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === extensionId);\n if (!ext || !ext.manifest.ui) {\n return c.json({ error: 'Extension not found or has no UI' }, 404, corsHdr);\n }\n\n const prefix = `/api/extensions/${extensionId}/assets/`;\n const assetPathEncoded = c.req.path.startsWith(prefix) ? c.req.path.slice(prefix.length) : '';\n let assetPath = assetPathEncoded;\n try {\n assetPath = decodeURIComponent(assetPathEncoded);\n } catch {\n return c.json({ error: 'Invalid asset path' }, 400, corsHdr);\n }\n\n if (!assetPath || assetPath.includes('..')) {\n return c.json({ error: 'Invalid asset path' }, 400, corsHdr);\n }\n\n const root = resolve(ext.path);\n const fullPath = resolve(root, assetPath);\n const rel = relative(root, fullPath);\n if (rel.startsWith('..') || rel === '') {\n return c.json({ error: 'Path traversal denied' }, 403, corsHdr);\n }\n\n if (!existsSync(fullPath) || !statSync(fullPath).isFile()) {\n return c.json({ error: 'Not found' }, 404, corsHdr);\n }\n\n const rawContent = readFileSync(fullPath);\n const mimeType = extensionAssetMimeType(assetPath);\n\n const body: string | Uint8Array = mimeType.startsWith('text/html')\n ? rewriteExtensionAssetHtml(rawContent.toString('utf-8'), extensionId, assetPath)\n : new Uint8Array(rawContent);\n\n return new Response(body, {\n status: 200,\n headers: {\n 'Content-Type': mimeType,\n 'Content-Security-Policy': EXTENSION_ASSET_CSP,\n 'Cache-Control': 'no-store',\n 'X-Content-Type-Options': 'nosniff',\n 'Access-Control-Allow-Origin': acao,\n },\n });\n });\n}\n\nexport function registerAuthRegistryExtensionsRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n // ========== Auth API (/api/auth) ==========\n\n // GET /api/auth/token - Get current gateway token\n authenticated.get('/api/auth/token', (c) => {\n const authToken = service.getAuthToken();\n return c.json({ \n ok: true, \n payload: { \n token: authToken,\n mode: service.getAuthMode(),\n } \n });\n });\n\n // POST /api/auth/token/refresh - Generate new gateway token\n authenticated.post('/api/auth/token/refresh', async (c) => {\n try {\n const newToken = await service.refreshAuthToken();\n return c.json({ \n ok: true, \n payload: { \n token: newToken,\n message: 'Token refreshed successfully. Please update your client configuration.'\n } \n });\n } catch (err) {\n return c.json({ \n ok: false, \n error: err instanceof Error ? err.message : 'Failed to refresh token' \n }, 500);\n }\n });\n\n // ========== OAuth API (/api/auth/oauth) ==========\n authenticated.route('/api/auth/oauth', createOAuthHandler(service));\n\n // ========== Async OAuth API (/api/auth/oauth-async) ==========\n authenticated.route('/api/auth/oauth-async', createOAuthAsyncHandler(service));\n\n // Load OAuth credentials from config into cache on startup\n loadOAuthCredentialsToCache(service);\n\n // ========== Registry API ==========\n \n // GET /api/registry - Full registry for frontend\n authenticated.get('/api/registry', async (c) => {\n const allModels = getAllModels();\n const availableModels = await getAvailableModels();\n const configured = new Set(availableModels.map(m => `${m.provider}/${m.id}`));\n \n // Group models by provider\n const providerMap = new Map<string, Model<Api>[]>();\n for (const model of allModels) {\n const list = providerMap.get(model.provider) ?? [];\n list.push(model);\n providerMap.set(model.provider, list);\n }\n \n return c.json({\n ok: true,\n payload: {\n version: 'pi-ai',\n providers: Array.from(providerMap.entries()).map(([id, models]) => ({\n id,\n name: id.charAt(0).toUpperCase() + id.slice(1),\n configured: models.some(m => configured.has(`${m.provider}/${m.id}`)),\n models: models.map(m => ({\n ref: `${m.provider}/${m.id}`,\n id: m.id,\n name: m.name,\n provider: m.provider,\n reasoning: m.reasoning ?? false,\n input: m.input ?? ['text'],\n contextWindow: m.contextWindow ?? 128000,\n maxTokens: m.maxTokens ?? 4096,\n cost: {\n input: m.cost?.input ?? 0,\n output: m.cost?.output ?? 0,\n },\n available: configured.has(`${m.provider}/${m.id}`),\n })),\n })),\n },\n });\n });\n\n // ========== Extension UI (manifest discovery + static assets) ==========\n\n authenticated.get('/api/extensions', async (c) => {\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ extensions: [] });\n }\n\n const registry = loader.getRegistry();\n const discovered = loader.discoverExtensions();\n const activeIds = new Set<string>();\n for (const [id] of registry.extensions) {\n activeIds.add(id);\n }\n\n loader.setConfig(service.currentConfig as unknown as SurfaceConfig);\n let activationEligibleIds: Set<string> = new Set();\n try {\n const planner = new ActivationPlanner(loader.buildManifestRegistry());\n activationEligibleIds = new Set(\n planner.getActivatedIds(mergeActivationContext(service.currentConfig as unknown as SurfaceConfig)),\n );\n } catch {\n activationEligibleIds = new Set();\n }\n\n const extensions = discovered.map((ext) => ({\n id: ext.manifest.id,\n name: ext.manifest.name,\n description: ext.manifest.description,\n version: ext.manifest.version,\n kind: ext.manifest.kind,\n source: ext.source,\n active: activeIds.has(ext.id),\n activationEligible: activationEligibleIds.has(ext.id),\n hasUi: Boolean(ext.manifest.ui),\n hasConfigSchema: hasNonEmptyConfigSchema(ext.manifest.configSchema),\n ui: ext.manifest.ui\n ? {\n icon: ext.manifest.ui.icon,\n permissions: ext.manifest.ui.permissions,\n contributions: ext.manifest.ui.contributions,\n }\n : undefined,\n }));\n return c.json({ extensions });\n });\n\n /**\n * Built-in (bundled) extension enable/disable — persists `extensions.enabled` / `extensions.disabled`.\n * Body: `{ extensionId: string, enabled: boolean }`\n */\n authenticated.post('/api/extensions/bundled/activation', strictRateLimitMiddleware, async (c) => {\n const body = (await c.req.json().catch(() => null)) as\n | { extensionId?: unknown; enabled?: unknown }\n | null;\n const extensionId =\n typeof body?.extensionId === 'string' ? body.extensionId.trim() : '';\n if (!extensionId) {\n return c.json({ ok: false, error: { message: 'extensionId is required' } }, 400);\n }\n if (typeof body?.enabled !== 'boolean') {\n return c.json({ ok: false, error: { message: 'enabled must be a boolean' } }, 400);\n }\n const result = await service.setBundledExtensionActivationTarget(extensionId, body.enabled);\n if (!result.ok) {\n return c.json({ ok: false, error: { message: result.error ?? 'Request failed' } }, 400);\n }\n return c.json({\n ok: true,\n payload: { requiresGatewayRestart: result.requiresGatewayRestart },\n });\n });\n\n authenticated.get('/api/extensions/:id', async (c) => {\n const extensionId = c.req.param('id');\n const loader = service.getExtensionLoader();\n if (!loader) {\n return c.json({ error: 'Extensions unavailable' }, 503);\n }\n const discovered = loader.discoverExtensions();\n const ext = discovered.find((e) => e.id === extensionId);\n if (!ext) {\n return c.json({ error: 'Extension not found' }, 404);\n }\n const registry = loader.getRegistry();\n return c.json({\n id: ext.manifest.id,\n name: ext.manifest.name,\n description: ext.manifest.description,\n version: ext.manifest.version,\n kind: ext.manifest.kind,\n source: ext.source,\n path: ext.path,\n active: registry.extensions.has(ext.id),\n manifest: ext.manifest,\n });\n });\n\n authenticated.get('/api/extensions/:id/ui-grant', (c) => {\n return c.json({ grant: service.localApps.getUiGrant(c.req.param('id')) });\n });\n\n authenticated.post('/api/extensions/:id/ui-grant', (c) => {\n return c.json({ grant: service.localApps.grantUiPermissions(c.req.param('id')) });\n });\n\n authenticated.get('/api/extensions/:id/storage', async (c) => {\n const extensionId = c.req.param('id');\n const store = await loadExtensionStore(extensionId);\n return c.json({ keys: Object.keys(store) });\n });\n\n authenticated.get('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const store = await loadExtensionStore(extensionId);\n if (!(key in store)) {\n return c.json({ error: 'Key not found' }, 404);\n }\n return c.json({ value: store[key] });\n });\n\n authenticated.put('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const body = (await c.req.json().catch(() => null)) as { value?: unknown } | null;\n if (body === null || !('value' in body)) {\n return c.json({ error: 'Request body must contain a \"value\" field' }, 400);\n }\n const store = await loadExtensionStore(extensionId);\n store[key] = body.value;\n await saveExtensionStore(extensionId, store);\n return c.json({ ok: true });\n });\n\n authenticated.delete('/api/extensions/:id/storage/:key', async (c) => {\n const extensionId = c.req.param('id');\n const key = decodeURIComponent(c.req.param('key'));\n const store = await loadExtensionStore(extensionId);\n delete store[key];\n await saveExtensionStore(extensionId, store);\n return c.json({ ok: true });\n });\n\n authenticated.get('/api/extensions/:id/config', async (c) => {\n const extensionId = c.req.param('id');\n return c.json(await loadExtensionStore(`__config__${extensionId}`));\n });\n\n authenticated.patch('/api/extensions/:id/config', async (c) => {\n const extensionId = c.req.param('id');\n const patch = (await c.req.json().catch(() => null)) as Record<string, unknown> | null;\n if (!patch || typeof patch !== 'object' || Array.isArray(patch)) {\n return c.json({ error: 'Request body must be a JSON object' }, 400);\n }\n const namespace = `__config__${extensionId}`;\n const config = await loadExtensionStore(namespace);\n Object.assign(config, patch);\n await saveExtensionStore(namespace, config);\n return c.json({ ok: true });\n });\n\n authenticated.get('/api/context', (c) => {\n const loader = service.getExtensionLoader();\n const snapshot = buildWhenContextSnapshot(\n service.currentConfig as unknown as SurfaceConfig,\n loader,\n );\n return c.json(snapshot);\n });\n\n authenticated.get('/api/marketplace', async (c) => {\n const q = c.req.query('q');\n const category = c.req.query('category');\n try {\n let extensions;\n if (typeof q === 'string' && q.trim()) {\n extensions = await extensionMarketplace.searchExtensions(q.trim());\n } else if (typeof category === 'string' && category.trim()) {\n extensions = await extensionMarketplace.listExtensions(category.trim());\n } else {\n const reg = await extensionMarketplace.fetchRegistry();\n extensions = reg.extensions;\n }\n return c.json({ ok: true, extensions });\n } catch (err) {\n return c.json(\n {\n ok: false,\n extensions: [],\n error: err instanceof Error ? err.message : 'marketplace fetch failed',\n },\n 500,\n );\n }\n });\n\n authenticated.get('/api/marketplace/packages/:pkgName', async (c) => {\n const raw = c.req.param('pkgName');\n if (!raw) {\n return c.json({ ok: false, error: 'Missing package name' }, 400);\n }\n let pkgName: string;\n try {\n pkgName = decodeURIComponent(raw);\n } catch {\n return c.json({ ok: false, error: 'Invalid package name' }, 400);\n }\n try {\n const payload = await service.marketplace.fetchExtensionPackageDetail(pkgName);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Marketplace request failed' },\n 502,\n );\n }\n });\n\n authenticated.post('/api/marketplace/install', strictRateLimitMiddleware, async (c) => {\n let body: { name?: unknown; version?: unknown; overwrite?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const name = typeof body.name === 'string' ? body.name.trim() : '';\n const version = typeof body.version === 'string' ? body.version.trim() : undefined;\n const overwrite =\n body.overwrite === true || body.overwrite === 'true' || body.overwrite === '1';\n if (!name) {\n return c.json(\n { ok: false, error: 'Expected { name: string, version?: string, overwrite?: boolean }' },\n 400,\n );\n }\n try {\n const payload = await service.marketplace.installExtension({ name, version, overwrite });\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Install failed' },\n 400,\n );\n }\n });\n\n authenticated.post('/api/marketplace/uninstall', strictRateLimitMiddleware, async (c) => {\n let body: { extensionId?: unknown };\n try {\n body = (await c.req.json()) as typeof body;\n } catch {\n return c.json({ ok: false, error: 'Invalid JSON' }, 400);\n }\n const extensionId = typeof body.extensionId === 'string' ? body.extensionId.trim() : '';\n if (!extensionId) {\n return c.json({ ok: false, error: 'Expected { extensionId: string }' }, 400);\n }\n try {\n const payload = await service.marketplace.uninstallExtension(extensionId);\n return c.json({ ok: true, payload });\n } catch (err) {\n return c.json(\n { ok: false, error: err instanceof Error ? err.message : 'Uninstall failed' },\n 400,\n );\n }\n });\n\n // POST /api/registry/reload — reload gateway config and refresh model list for clients\n authenticated.post('/api/registry/reload', async (c) => {\n try {\n // Reload config\n await service.reloadConfig();\n \n // Reload OAuth credentials from new config\n loadOAuthCredentialsToCache(service);\n \n const models = getAllModels();\n \n // Emit SSE event to all connected clients\n service.emit('registry.updated', { modelCount: models.length });\n \n return c.json({\n ok: true,\n payload: {\n message: 'Registry reloaded',\n modelCount: models.length,\n },\n });\n } catch (err) {\n return c.json({\n error: err instanceof Error ? err.message : 'Failed to reload registry',\n }, 500);\n }\n });\n\n}\n"],"mappings":"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"}