@xopcai/xopc 0.0.127 → 0.0.129

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 (334) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CgGgO4OV.js → agent-avatar-dicebear-DHzfg5D-.js} +1 -1
  4. package/dist/gateway/static/root/assets/agents-CMxKKFQD.js +2 -0
  5. package/dist/gateway/static/root/assets/app-management-settings-panel-ptk9c5BN.js +1 -0
  6. package/dist/gateway/static/root/assets/{appearance-settings-BnHQW7Hv.js → appearance-settings-bYeEj3IW.js} +1 -1
  7. package/dist/gateway/static/root/assets/apps-page-DdZvDf5B.js +1 -0
  8. package/dist/gateway/static/root/assets/{archive-plugin-5NXT7Zqv.js → archive-plugin-Dy6lsTHw.js} +1 -1
  9. package/dist/gateway/static/root/assets/{attachment-load-DghwhYe0.js → attachment-load-qOtBYR6Y.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automation-suggestion-card-DYmESgwl.js → automation-suggestion-card-BFH-RfaV.js} +1 -1
  11. package/dist/gateway/static/root/assets/automations-page-B8JTjkCr.js +4 -0
  12. package/dist/gateway/static/root/assets/{binary-plugins-DSbPKdWX.js → binary-plugins-DJvi_thc.js} +1 -1
  13. package/dist/gateway/static/root/assets/{block-editor-CoZ-_np-.js → block-editor-DlMnizlt.js} +4 -4
  14. package/dist/gateway/static/root/assets/browser-settings-page-slHLiZgi.js +8 -0
  15. package/dist/gateway/static/root/assets/capability-presets-api-D4q7vHVJ.js +1 -0
  16. package/dist/gateway/static/root/assets/capability-presets-settings-panel-Dng8Grpv.js +1 -0
  17. package/dist/gateway/static/root/assets/channel-recipient-api-BrW5Kcgc.js +1 -0
  18. package/dist/gateway/static/root/assets/channels-settings-KIsISXw0.js +1 -0
  19. package/dist/gateway/static/root/assets/{code-editor-gbRgS14t.js → code-editor--tMO38Tr.js} +1 -1
  20. package/dist/gateway/static/root/assets/connectors-page-C5fx4Qs9.js +2 -0
  21. package/dist/gateway/static/root/assets/desktop-pet-Jmdn6q47.js +1 -0
  22. package/dist/gateway/static/root/assets/{desktop-pet-settings-npJ0Oh5p.js → desktop-pet-settings-B-u63N4e.js} +1 -1
  23. package/dist/gateway/static/root/assets/{directory-picker-path-field-BR2ItBuf.js → directory-picker-path-field-8p1ehIHn.js} +1 -1
  24. package/dist/gateway/static/root/assets/dreaming-settings-CCkKP-I4.js +3 -0
  25. package/dist/gateway/static/root/assets/{extension-debug-page-Tl0f1rNv.js → extension-debug-page-DJ1ABK95.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-Ck7QuwE3.js → extension-page-CP9P2lGM.js} +1 -1
  27. package/dist/gateway/static/root/assets/extension-settings-page-DnhU-tx0.js +1 -0
  28. package/dist/gateway/static/root/assets/fetch-BMjlW0g1.js +1 -0
  29. package/dist/gateway/static/root/assets/gateway-config-api-CjxDn46s.js +1 -0
  30. package/dist/gateway/static/root/assets/gateway-settings-TING7224.js +1 -0
  31. package/dist/gateway/static/root/assets/{gateway-startup-retry-Yh8h3hkj.js → gateway-startup-retry-CY5W2Pp4.js} +1 -1
  32. package/dist/gateway/static/root/assets/goal-create-dialog-2lPbGfp3.js +1 -0
  33. package/dist/gateway/static/root/assets/goal-detail-page-DHWVRafk.js +4 -0
  34. package/dist/gateway/static/root/assets/goals-config-api-BqhuxG8P.js +1 -0
  35. package/dist/gateway/static/root/assets/goals-page-CMk-9ZYN.js +2 -0
  36. package/dist/gateway/static/root/assets/goals-settings-BHzOAU_l.js +1 -0
  37. package/dist/gateway/static/root/assets/heartbeat-settings-BQIm0P3V.js +1 -0
  38. package/dist/gateway/static/root/assets/{html-workspace-editor-DV90ddkE.js → html-workspace-editor-COqmtESs.js} +1 -1
  39. package/dist/gateway/static/root/assets/index-C4k6QSXw.js +257 -0
  40. package/dist/gateway/static/root/assets/index-EKmpPvZj.css +1 -0
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CfQrt_Rb.js → keyboard-shortcuts-settings-BrENZzM7.js} +1 -1
  42. package/dist/gateway/static/root/assets/logs-page-BiL302Ve.js +2 -0
  43. package/dist/gateway/static/root/assets/{markdown-editor-BFOjBBla.js → markdown-editor-jD1LPiP-.js} +2 -2
  44. package/dist/gateway/static/root/assets/{markdown-split-BwiMdCf_.js → markdown-split-BYF4ReGM.js} +1 -1
  45. package/dist/gateway/static/root/assets/{media-plugins-DhoizyZv.js → media-plugins-CpQDz-QJ.js} +1 -1
  46. package/dist/gateway/static/root/assets/messages-YzjnURPJ.js +3 -0
  47. package/dist/gateway/static/root/assets/models-hub-panel-CFPpl3Cq.js +2 -0
  48. package/dist/gateway/static/root/assets/notes-page-BurgcdVZ.js +1 -0
  49. package/dist/gateway/static/root/assets/notes-workbench-BAELRM_O.js +2 -0
  50. package/dist/gateway/static/root/assets/{page-tabs-DDC2t4Z8.js → page-tabs-RnYYOIWO.js} +1 -1
  51. package/dist/gateway/static/root/assets/{preview-open-alternatives-BTmk-XDM.js → preview-open-alternatives-CTRt06Ri.js} +1 -1
  52. package/dist/gateway/static/root/assets/project-detail-page-iXX1Ceo2.js +1 -0
  53. package/dist/gateway/static/root/assets/projects-page-GDVTFAY7.js +1 -0
  54. package/dist/gateway/static/root/assets/remote-access-hub-BUrbUnwv.js +1 -0
  55. package/dist/gateway/static/root/assets/{save-bar-controls-DqU-yKIh.js → save-bar-controls-c4pZeikq.js} +1 -1
  56. package/dist/gateway/static/root/assets/{schedule-field-CUttkoSB.js → schedule-field-Cb6R7iuP.js} +1 -1
  57. package/dist/gateway/static/root/assets/{schema-form-CVSQA9nI.js → schema-form-BqET_hEP.js} +1 -1
  58. package/dist/gateway/static/root/assets/sessions-page-CiOreA2k.js +1 -0
  59. package/dist/gateway/static/root/assets/settings-advanced-gate-C-qvptlu.js +1 -0
  60. package/dist/gateway/static/root/assets/{settings-collapsible-section-CK7ogS-P.js → settings-collapsible-section-DuOvqNsI.js} +1 -1
  61. package/dist/gateway/static/root/assets/{settings-form-section-Bugp38Fa.js → settings-form-section-DptSsbWd.js} +1 -1
  62. package/dist/gateway/static/root/assets/settings-loading-skeleton-BlVfBCb9.js +1 -0
  63. package/dist/gateway/static/root/assets/{settings-page-layout-DBRWwdhh.js → settings-page-layout-DVt69dJJ.js} +1 -1
  64. package/dist/gateway/static/root/assets/settings-page-xQx2Pkg5.js +1 -0
  65. package/dist/gateway/static/root/assets/setup-status-panel-DWB8VdLK.js +1 -0
  66. package/dist/gateway/static/root/assets/share-preview-page-8m_ACH0z.js +2 -0
  67. package/dist/gateway/static/root/assets/shares-settings-CgxfhNxI.js +1 -0
  68. package/dist/gateway/static/root/assets/skill-reload-api-BBFUOxmf.js +1 -0
  69. package/dist/gateway/static/root/assets/skills-page-bo695odu.js +2 -0
  70. package/dist/gateway/static/root/assets/{system-settings-panel-DJ6YuLqR.js → system-settings-panel-CW22OkZ4.js} +1 -1
  71. package/dist/gateway/static/root/assets/{typed-models-lib-B0T7N8Km.js → typed-models-lib-BqpGAKxV.js} +1 -1
  72. package/dist/gateway/static/root/assets/url-DFGNSBNT.js +1 -0
  73. package/dist/gateway/static/root/assets/use-channel-catalog-CPdJ0o0i.js +1 -0
  74. package/dist/gateway/static/root/assets/user-profile-settings-panel-CERVLuaW.js +1 -0
  75. package/dist/gateway/static/root/assets/{utils-CehXcWAY.js → utils-BnmysurA.js} +1 -1
  76. package/dist/gateway/static/root/assets/vendor-codemirror-C1WKjCk5.js +45 -0
  77. package/dist/gateway/static/root/assets/voice-api-key-field-Jr3jvPcB.js +1 -0
  78. package/dist/gateway/static/root/assets/work-item-detail-page-B-8rex4u.js +1 -0
  79. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-c4jeaohQ.js → workflow-run-setup-panel-Ci9GSPnS.js} +2 -2
  80. package/dist/gateway/static/root/assets/{workflow-start-dialog-ENRHjoqa.js → workflow-start-dialog-BhDj8pqH.js} +1 -1
  81. package/dist/gateway/static/root/assets/workflows-page-Brb3UGvs.js +18 -0
  82. package/dist/gateway/static/root/index.html +7 -6
  83. package/dist/package.js +1 -1
  84. package/dist/src/agent/agent-manager.d.ts +3 -0
  85. package/dist/src/agent/agent-manager.js +14 -6
  86. package/dist/src/agent/agent-manager.js.map +1 -1
  87. package/dist/src/agent/capabilities/definitions.d.ts +14 -0
  88. package/dist/src/agent/capabilities/definitions.js +19 -0
  89. package/dist/src/agent/capabilities/definitions.js.map +1 -1
  90. package/dist/src/agent/goals/post-turn.js +23 -2
  91. package/dist/src/agent/goals/post-turn.js.map +1 -1
  92. package/dist/src/agent/messaging/command-handler.d.ts +4 -0
  93. package/dist/src/agent/messaging/command-handler.js +6 -0
  94. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  95. package/dist/src/agent/service.d.ts +2 -0
  96. package/dist/src/agent/service.js +23 -0
  97. package/dist/src/agent/service.js.map +1 -1
  98. package/dist/src/agent/skills/hub-lock.d.ts +5 -5
  99. package/dist/src/agent/skills/hub-lock.js +12 -12
  100. package/dist/src/agent/skills/hub-lock.js.map +1 -1
  101. package/dist/src/agent/skills/hub-pull.d.ts +15 -0
  102. package/dist/src/agent/skills/hub-pull.js +299 -24
  103. package/dist/src/agent/skills/hub-pull.js.map +1 -1
  104. package/dist/src/agent/skills/index.js +4 -40
  105. package/dist/src/agent/skills/index.js.map +1 -1
  106. package/dist/src/agent/skills/install-target.d.ts +3 -0
  107. package/dist/src/agent/skills/install-target.js +11 -0
  108. package/dist/src/agent/skills/install-target.js.map +1 -0
  109. package/dist/src/agent/skills/managed-store.d.ts +5 -3
  110. package/dist/src/agent/skills/managed-store.js +10 -9
  111. package/dist/src/agent/skills/managed-store.js.map +1 -1
  112. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +5 -3
  113. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -1
  114. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +21 -1
  115. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +62 -6
  116. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
  117. package/dist/src/agent/skills/marketplace/resolve-adapter.js +1 -1
  118. package/dist/src/agent/skills/marketplace/resolve-adapter.js.map +1 -1
  119. package/dist/src/agent/skills/skill-manage-ops.js +2 -2
  120. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  121. package/dist/src/agent/skills/skill-manager.js +1 -6
  122. package/dist/src/agent/skills/skill-manager.js.map +1 -1
  123. package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
  124. package/dist/src/agent/skills/workspace-skills-dir.js +5 -1
  125. package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -1
  126. package/dist/src/agent/tools/automation-tool.d.ts +6 -6
  127. package/dist/src/agent/tools/browser/tool/schemas.d.ts +20 -20
  128. package/dist/src/agent/tools/composio-tool.d.ts +3 -3
  129. package/dist/src/agent/tools/desktop-pet-tool.d.ts +7 -7
  130. package/dist/src/agent/tools/factory.d.ts +3 -0
  131. package/dist/src/agent/tools/factory.js +6 -1
  132. package/dist/src/agent/tools/factory.js.map +1 -1
  133. package/dist/src/agent/tools/goal-tool.d.ts +16 -16
  134. package/dist/src/agent/tools/index.d.ts +1 -0
  135. package/dist/src/agent/tools/index.js +2 -1
  136. package/dist/src/agent/tools/skill-install-tool.d.ts +28 -0
  137. package/dist/src/agent/tools/skill-install-tool.js +81 -0
  138. package/dist/src/agent/tools/skill-install-tool.js.map +1 -0
  139. package/dist/src/agent/tools/skill-manage-tool.js +3 -6
  140. package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
  141. package/dist/src/agent/tools/tool-manual-tool.d.ts +2 -2
  142. package/dist/src/agent/tools/xopc-use-tool.d.ts +5 -5
  143. package/dist/src/automations/domain/types.d.ts +1 -0
  144. package/dist/src/automations/draft/automation-draft-service.js +1 -1
  145. package/dist/src/automations/service/automation-service.js +9 -0
  146. package/dist/src/automations/service/automation-service.js.map +1 -1
  147. package/dist/src/browser/schemas.d.ts +52 -52
  148. package/dist/src/capabilities/store-connector.d.ts +17 -0
  149. package/dist/src/capabilities/store-connector.js +191 -0
  150. package/dist/src/capabilities/store-connector.js.map +1 -0
  151. package/dist/src/chat-commands/builtins/skill.d.ts +1 -0
  152. package/dist/src/chat-commands/builtins/skill.js +132 -0
  153. package/dist/src/chat-commands/builtins/skill.js.map +1 -0
  154. package/dist/src/chat-commands/context.d.ts +3 -0
  155. package/dist/src/chat-commands/context.js +2 -0
  156. package/dist/src/chat-commands/context.js.map +1 -1
  157. package/dist/src/chat-commands/index.d.ts +1 -0
  158. package/dist/src/chat-commands/index.js +3 -1
  159. package/dist/src/chat-commands/index.js.map +1 -1
  160. package/dist/src/chat-commands/types.d.ts +17 -0
  161. package/dist/src/cli/command-loaders.js +1 -0
  162. package/dist/src/cli/command-loaders.js.map +1 -1
  163. package/dist/src/cli/command-manifest.js +4 -0
  164. package/dist/src/cli/command-manifest.js.map +1 -1
  165. package/dist/src/cli/commands/agent.js +2 -2
  166. package/dist/src/cli/commands/connectors.d.ts +4 -0
  167. package/dist/src/cli/commands/connectors.js +96 -0
  168. package/dist/src/cli/commands/connectors.js.map +1 -0
  169. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  170. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  171. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  172. package/dist/src/cli/commands/models.js +1 -1
  173. package/dist/src/cli/commands/onboard.js +1 -1
  174. package/dist/src/cli/commands/profile.js +1 -1
  175. package/dist/src/cli/commands/skills.js +1 -1
  176. package/dist/src/cli/commands/tunnel.js +1 -1
  177. package/dist/src/cli/commands/update.js +1 -1
  178. package/dist/src/cli/extension-cli-register.js +1 -1
  179. package/dist/src/config/agent-profile.js +1 -1
  180. package/dist/src/config/index.js +1 -1
  181. package/dist/src/config/schema.js +2 -2
  182. package/dist/src/config/schema.js.map +1 -1
  183. package/dist/src/connectors/health.js +1 -1
  184. package/dist/src/connectors/install.js +3 -1
  185. package/dist/src/connectors/install.js.map +1 -1
  186. package/dist/src/connectors/materialize.js +2 -0
  187. package/dist/src/connectors/materialize.js.map +1 -1
  188. package/dist/src/connectors/types.d.ts +19 -1
  189. package/dist/src/extensions/install.js +1 -1
  190. package/dist/src/extensions/types/manifest.d.ts +1 -1
  191. package/dist/src/extensions/update.js +5 -3
  192. package/dist/src/extensions/update.js.map +1 -1
  193. package/dist/src/gateway/agents-admin.js +1 -1
  194. package/dist/src/gateway/chat-stream/mapper.js +5 -1
  195. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  196. package/dist/src/gateway/chat-stream/protocol.d.ts +2 -0
  197. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  198. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  199. package/dist/src/gateway/hono/middleware/auth.d.ts +2 -2
  200. package/dist/src/gateway/hono/middleware/logger.d.ts +1 -1
  201. package/dist/src/gateway/hono/middleware/route-errors.d.ts +1 -1
  202. package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +2 -2
  203. package/dist/src/gateway/hono/routes/capabilities.d.ts +3 -0
  204. package/dist/src/gateway/hono/routes/capabilities.js +79 -0
  205. package/dist/src/gateway/hono/routes/capabilities.js.map +1 -0
  206. package/dist/src/gateway/hono/routes/commands-skills.js +81 -3
  207. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  208. package/dist/src/gateway/hono/routes/connectors.js +2 -2
  209. package/dist/src/gateway/hono/routes/goals.js +212 -3
  210. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  211. package/dist/src/gateway/hono/routes/index.js +2 -0
  212. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  213. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  214. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  215. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  216. package/dist/src/gateway/hono/routes/mobile.d.ts +3 -0
  217. package/dist/src/gateway/hono/routes/mobile.js +113 -0
  218. package/dist/src/gateway/hono/routes/mobile.js.map +1 -0
  219. package/dist/src/gateway/hono/routes/projects.js +17 -0
  220. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  221. package/dist/src/gateway/hono/routes/workspace.js +4 -1
  222. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  223. package/dist/src/gateway/hono/sse.d.ts +3 -3
  224. package/dist/src/gateway/run-loop.js +1 -1
  225. package/dist/src/gateway/service/marketplace-service.d.ts +23 -1
  226. package/dist/src/gateway/service/marketplace-service.js +57 -6
  227. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  228. package/dist/src/gateway/service.d.ts +2 -0
  229. package/dist/src/gateway/service.js +12 -2
  230. package/dist/src/gateway/service.js.map +1 -1
  231. package/dist/src/goals/goal-contract-draft.d.ts +15 -0
  232. package/dist/src/goals/goal-contract-draft.js +114 -0
  233. package/dist/src/goals/goal-contract-draft.js.map +1 -0
  234. package/dist/src/goals/goal-evidence-review.d.ts +15 -0
  235. package/dist/src/goals/goal-evidence-review.js +91 -0
  236. package/dist/src/goals/goal-evidence-review.js.map +1 -0
  237. package/dist/src/goals/goal-runner.js +3 -1
  238. package/dist/src/goals/goal-runner.js.map +1 -1
  239. package/dist/src/goals/goal-service.d.ts +17 -1
  240. package/dist/src/goals/goal-service.js +44 -3
  241. package/dist/src/goals/goal-service.js.map +1 -1
  242. package/dist/src/goals/goal-store.d.ts +18 -1
  243. package/dist/src/goals/goal-store.js +190 -1
  244. package/dist/src/goals/goal-store.js.map +1 -1
  245. package/dist/src/goals/index.d.ts +4 -0
  246. package/dist/src/goals/index.js +3 -1
  247. package/dist/src/goals/types.d.ts +42 -0
  248. package/dist/src/mcp/channel-bridge.js +1 -1
  249. package/dist/src/mobile/notification-service.d.ts +8 -0
  250. package/dist/src/mobile/notification-service.js +139 -0
  251. package/dist/src/mobile/notification-service.js.map +1 -0
  252. package/dist/src/mobile/notification-store.d.ts +28 -0
  253. package/dist/src/mobile/notification-store.js +134 -0
  254. package/dist/src/mobile/notification-store.js.map +1 -0
  255. package/dist/src/mobile/notification-types.d.ts +37 -0
  256. package/dist/src/mobile/notification-types.js +11 -0
  257. package/dist/src/mobile/notification-types.js.map +1 -0
  258. package/dist/src/storage/sqlite/migrations/026_goal_contracts.sql +10 -0
  259. package/dist/src/storage/sqlite/migrations/027_mobile_notifications.sql +43 -0
  260. package/dist/src/storage/sqlite/migrations/028_goal_evidence_requirements.sql +47 -0
  261. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  262. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  263. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  264. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  265. package/dist/src/storage/sqlite/schema.js +1 -1
  266. package/dist/src/storage/sqlite/schema.sql +44 -0
  267. package/dist/src/tui/tui-startup-resources.js +1 -1
  268. package/package.json +1 -1
  269. package/skills/THIRD_PARTY_NOTICES.md +16 -0
  270. package/skills/creative/algorithmic-art/SKILL.md +37 -0
  271. package/skills/creative/algorithmic-art/templates/generator-template.js +27 -0
  272. package/skills/creative/algorithmic-art/templates/viewer.html +27 -0
  273. package/skills/documents/doc-coauthoring/SKILL.md +40 -0
  274. package/skills/documents/doc-coauthoring/references/reader-review.md +9 -0
  275. package/skills/documents/docx/SKILL.md +40 -0
  276. package/skills/documents/docx/references/editing-checklist.md +8 -0
  277. package/skills/documents/docx/scripts/inspect_ooxml.py +36 -0
  278. package/skills/documents/docx/scripts/render_docx.py +33 -0
  279. package/skills/documents/pdf/SKILL.md +47 -0
  280. package/skills/documents/pdf/references/operations.md +16 -0
  281. package/skills/documents/pdf/scripts/inspect_pdf.py +41 -0
  282. package/skills/documents/pdf/scripts/render_pdf.py +32 -0
  283. package/skills/documents/pptx/SKILL.md +41 -0
  284. package/skills/documents/pptx/references/qa-checklist.md +6 -0
  285. package/skills/documents/pptx/scripts/inspect_ooxml.py +34 -0
  286. package/skills/documents/pptx/scripts/render_pptx.py +33 -0
  287. package/skills/engineering/define-goal/SKILL.md +41 -0
  288. package/skills/engineering/define-goal/references/objective-rubric.md +12 -0
  289. package/dist/gateway/static/root/assets/agents-k59l7NMb.js +0 -2
  290. package/dist/gateway/static/root/assets/app-management-settings-panel-DeQsTsyy.js +0 -1
  291. package/dist/gateway/static/root/assets/apps-page-BG9b4abG.js +0 -1
  292. package/dist/gateway/static/root/assets/automations-page-De8mVutL.js +0 -4
  293. package/dist/gateway/static/root/assets/browser-settings-page-C_ZRa4LF.js +0 -8
  294. package/dist/gateway/static/root/assets/capability-presets-api-hny224j-.js +0 -1
  295. package/dist/gateway/static/root/assets/capability-presets-settings-panel-Drc0qLsw.js +0 -1
  296. package/dist/gateway/static/root/assets/channel-recipient-api-DAlOHxKJ.js +0 -1
  297. package/dist/gateway/static/root/assets/channels-settings-CA20zBV9.js +0 -1
  298. package/dist/gateway/static/root/assets/connectors-page-qMyMB5te.js +0 -2
  299. package/dist/gateway/static/root/assets/desktop-pet-XG6Vb_fZ.js +0 -1
  300. package/dist/gateway/static/root/assets/dreaming-settings-CkUZ997f.js +0 -3
  301. package/dist/gateway/static/root/assets/extension-settings-page-3RMhQtZ3.js +0 -1
  302. package/dist/gateway/static/root/assets/fetch-pg2ErdAk.js +0 -1
  303. package/dist/gateway/static/root/assets/gateway-config-api-DbG97ia2.js +0 -1
  304. package/dist/gateway/static/root/assets/gateway-settings-B8cyqKk-.js +0 -1
  305. package/dist/gateway/static/root/assets/goal-create-dialog-DmeW7Zz3.js +0 -1
  306. package/dist/gateway/static/root/assets/goal-detail-page-DrTyGbVD.js +0 -1
  307. package/dist/gateway/static/root/assets/goals-config-api-CxCWGIBB.js +0 -1
  308. package/dist/gateway/static/root/assets/goals-page-DV1bJhIh.js +0 -2
  309. package/dist/gateway/static/root/assets/goals-settings-9DrfOkP5.js +0 -1
  310. package/dist/gateway/static/root/assets/heartbeat-settings-KaDpZrv0.js +0 -1
  311. package/dist/gateway/static/root/assets/index-C2F0Clvm.js +0 -256
  312. package/dist/gateway/static/root/assets/index-COQSX5d_.css +0 -1
  313. package/dist/gateway/static/root/assets/logs-page-C9dpiNTF.js +0 -2
  314. package/dist/gateway/static/root/assets/messages-DmnbiNxU.js +0 -3
  315. package/dist/gateway/static/root/assets/models-hub-panel-zdCdmBmH.js +0 -2
  316. package/dist/gateway/static/root/assets/notes-page-MpGeFfPt.js +0 -1
  317. package/dist/gateway/static/root/assets/notes-workbench-DYCM3yd2.js +0 -2
  318. package/dist/gateway/static/root/assets/project-detail-page-Cu0ElRnS.js +0 -1
  319. package/dist/gateway/static/root/assets/projects-page-DakNaUjZ.js +0 -1
  320. package/dist/gateway/static/root/assets/remote-access-hub-DYKjt7L9.js +0 -1
  321. package/dist/gateway/static/root/assets/sessions-page-CcGHDsz1.js +0 -1
  322. package/dist/gateway/static/root/assets/settings-advanced-gate-CuFdeKNu.js +0 -1
  323. package/dist/gateway/static/root/assets/settings-page-0AJoUvxi.js +0 -1
  324. package/dist/gateway/static/root/assets/setup-status-panel-D6a_hEk7.js +0 -1
  325. package/dist/gateway/static/root/assets/share-preview-page-BtsuETKF.js +0 -2
  326. package/dist/gateway/static/root/assets/shares-settings-CcEFT7S9.js +0 -1
  327. package/dist/gateway/static/root/assets/skill-reload-api-BcN_RuTD.js +0 -1
  328. package/dist/gateway/static/root/assets/skills-page-BbRZZZA5.js +0 -2
  329. package/dist/gateway/static/root/assets/use-channel-catalog-C6vrxdzZ.js +0 -1
  330. package/dist/gateway/static/root/assets/user-profile-settings-panel-DZ0nKMgj.js +0 -1
  331. package/dist/gateway/static/root/assets/vendor-codemirror-BvNgyE1Q.js +0 -45
  332. package/dist/gateway/static/root/assets/voice-api-key-field-2QKflCx8.js +0 -1
  333. package/dist/gateway/static/root/assets/work-item-detail-page-DfJnuWq1.js +0 -1
  334. package/dist/gateway/static/root/assets/workflows-page-BJwwFTm_.js +0 -18
@@ -1 +1 @@
1
- {"version":3,"file":"materialize.js","names":[],"sources":["../../../src/connectors/materialize.ts"],"sourcesContent":["import { McpServerSchema } from '../config/schema.js';\nimport { createConnectorSecretReference } from './secret-store.js';\nimport type { ConnectorDefinition, ConnectorInstallInput, ManagedConnectorMarker } from './types.js';\n\nconst SERVER_ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;\nconst TEMPLATE_PATTERN = /^\\{\\{(secrets|config)\\.([A-Za-z0-9_.-]+)\\}\\}$/;\n\nexport function assertValidConnectorServerId(serverId: string): void {\n if (!SERVER_ID_PATTERN.test(serverId)) {\n throw new Error('Connector server name must start with a lowercase letter and only contain lowercase letters, numbers, dashes, and underscores.');\n }\n}\n\nfunction readInputValue(\n definition: ConnectorDefinition,\n input: ConnectorInstallInput,\n scope: 'secrets' | 'config',\n key: string,\n): unknown {\n if (scope === 'secrets') {\n return createConnectorSecretReference(definition.id, key);\n }\n return input.config?.[key];\n}\n\nfunction resolveTemplateValue(value: unknown, definition: ConnectorDefinition, input: ConnectorInstallInput): unknown {\n if (typeof value !== 'string') {\n return value;\n }\n const match = TEMPLATE_PATTERN.exec(value.trim());\n if (!match) {\n return value;\n }\n return readInputValue(definition, input, match[1] as 'secrets' | 'config', match[2]);\n}\n\nfunction materializeTemplate(value: unknown, definition: ConnectorDefinition, input: ConnectorInstallInput): unknown {\n const resolved = resolveTemplateValue(value, definition, input);\n if (Array.isArray(resolved)) {\n return resolved.map((item) => materializeTemplate(item, definition, input));\n }\n if (resolved && typeof resolved === 'object') {\n const output: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(resolved as Record<string, unknown>)) {\n const materializedChild = materializeTemplate(child, definition, input);\n if (materializedChild !== undefined) {\n output[key] = materializedChild;\n }\n }\n return output;\n }\n return resolved;\n}\n\nfunction assertRequiredInputs(definition: ConnectorDefinition, input: ConnectorInstallInput): void {\n for (const secret of definition.setup.secrets ?? []) {\n const value = input.secrets?.[secret.key];\n if (secret.required && (typeof value !== 'string' || value.trim().length === 0)) {\n throw new Error(`Missing required secret: ${secret.key}`);\n }\n }\n for (const field of definition.setup.config ?? []) {\n const value = input.config?.[field.key];\n if (field.required && (value === undefined || value === null || value === '')) {\n throw new Error(`Missing required config: ${field.key}`);\n }\n }\n}\n\nexport function materializeConnectorMcpServer(\n definition: ConnectorDefinition,\n input: ConnectorInstallInput,\n): { serverId: string; server: Record<string, unknown> } {\n assertRequiredInputs(definition, input);\n if (definition.runtime.type !== 'mcp') {\n throw new Error(`Unsupported connector runtime: ${definition.runtime.type}`);\n }\n\n const rawServerId = materializeTemplate(definition.runtime.serverId, definition, input);\n if (typeof rawServerId !== 'string') {\n throw new Error('Connector server name must be a string.');\n }\n const serverId = rawServerId.trim();\n assertValidConnectorServerId(serverId);\n\n const rawServer = materializeTemplate(definition.runtime.serverTemplate, definition, input);\n if (!rawServer || typeof rawServer !== 'object' || Array.isArray(rawServer)) {\n throw new Error('Connector MCP server template must resolve to a JSON object.');\n }\n\n const marker: ManagedConnectorMarker = {\n managed: true,\n connectorId: definition.id,\n version: definition.version,\n displayName: definition.displayName,\n ...(input.config && Object.keys(input.config).length > 0 ? { config: input.config } : {}),\n };\n const server = {\n ...(rawServer as Record<string, unknown>),\n xopcConnector: marker,\n };\n const parsed = McpServerSchema.safeParse(server);\n if (!parsed.success) {\n throw new Error(parsed.error.issues[0]?.message ?? 'Invalid MCP server config.');\n }\n return { serverId, server };\n}\n\nexport function isManagedConnectorServer(server: unknown): server is Record<string, unknown> & { xopcConnector: ManagedConnectorMarker } {\n if (!server || typeof server !== 'object' || Array.isArray(server)) {\n return false;\n }\n const marker = (server as Record<string, unknown>).xopcConnector;\n return Boolean(\n marker &&\n typeof marker === 'object' &&\n !Array.isArray(marker) &&\n (marker as Record<string, unknown>).managed === true &&\n typeof (marker as Record<string, unknown>).connectorId === 'string',\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"materialize.js","names":[],"sources":["../../../src/connectors/materialize.ts"],"sourcesContent":["import { McpServerSchema } from '../config/schema.js';\nimport { createConnectorSecretReference } from './secret-store.js';\nimport type { ConnectorDefinition, ConnectorInstallInput, ManagedConnectorMarker } from './types.js';\n\nconst SERVER_ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;\nconst TEMPLATE_PATTERN = /^\\{\\{(secrets|config)\\.([A-Za-z0-9_.-]+)\\}\\}$/;\n\nexport function assertValidConnectorServerId(serverId: string): void {\n if (!SERVER_ID_PATTERN.test(serverId)) {\n throw new Error('Connector server name must start with a lowercase letter and only contain lowercase letters, numbers, dashes, and underscores.');\n }\n}\n\nfunction readInputValue(\n definition: ConnectorDefinition,\n input: ConnectorInstallInput,\n scope: 'secrets' | 'config',\n key: string,\n): unknown {\n if (scope === 'secrets') {\n return createConnectorSecretReference(definition.id, key);\n }\n return input.config?.[key];\n}\n\nfunction resolveTemplateValue(value: unknown, definition: ConnectorDefinition, input: ConnectorInstallInput): unknown {\n if (typeof value !== 'string') {\n return value;\n }\n const match = TEMPLATE_PATTERN.exec(value.trim());\n if (!match) {\n return value;\n }\n return readInputValue(definition, input, match[1] as 'secrets' | 'config', match[2]);\n}\n\nfunction materializeTemplate(value: unknown, definition: ConnectorDefinition, input: ConnectorInstallInput): unknown {\n const resolved = resolveTemplateValue(value, definition, input);\n if (Array.isArray(resolved)) {\n return resolved.map((item) => materializeTemplate(item, definition, input));\n }\n if (resolved && typeof resolved === 'object') {\n const output: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(resolved as Record<string, unknown>)) {\n const materializedChild = materializeTemplate(child, definition, input);\n if (materializedChild !== undefined) {\n output[key] = materializedChild;\n }\n }\n return output;\n }\n return resolved;\n}\n\nfunction assertRequiredInputs(definition: ConnectorDefinition, input: ConnectorInstallInput): void {\n for (const secret of definition.setup.secrets ?? []) {\n const value = input.secrets?.[secret.key];\n if (secret.required && (typeof value !== 'string' || value.trim().length === 0)) {\n throw new Error(`Missing required secret: ${secret.key}`);\n }\n }\n for (const field of definition.setup.config ?? []) {\n const value = input.config?.[field.key];\n if (field.required && (value === undefined || value === null || value === '')) {\n throw new Error(`Missing required config: ${field.key}`);\n }\n }\n}\n\nexport function materializeConnectorMcpServer(\n definition: ConnectorDefinition,\n input: ConnectorInstallInput,\n): { serverId: string; server: Record<string, unknown> } {\n assertRequiredInputs(definition, input);\n if (definition.runtime.type !== 'mcp') {\n throw new Error(`Unsupported connector runtime: ${definition.runtime.type}`);\n }\n\n const rawServerId = materializeTemplate(definition.runtime.serverId, definition, input);\n if (typeof rawServerId !== 'string') {\n throw new Error('Connector server name must be a string.');\n }\n const serverId = rawServerId.trim();\n assertValidConnectorServerId(serverId);\n\n const rawServer = materializeTemplate(definition.runtime.serverTemplate, definition, input);\n if (!rawServer || typeof rawServer !== 'object' || Array.isArray(rawServer)) {\n throw new Error('Connector MCP server template must resolve to a JSON object.');\n }\n\n const marker: ManagedConnectorMarker = {\n managed: true,\n connectorId: definition.id,\n version: definition.version,\n displayName: definition.displayName,\n source: definition.source,\n artifactSha256: definition.provenance?.sha256,\n ...(input.config && Object.keys(input.config).length > 0 ? { config: input.config } : {}),\n };\n const server = {\n ...(rawServer as Record<string, unknown>),\n xopcConnector: marker,\n };\n const parsed = McpServerSchema.safeParse(server);\n if (!parsed.success) {\n throw new Error(parsed.error.issues[0]?.message ?? 'Invalid MCP server config.');\n }\n return { serverId, server };\n}\n\nexport function isManagedConnectorServer(server: unknown): server is Record<string, unknown> & { xopcConnector: ManagedConnectorMarker } {\n if (!server || typeof server !== 'object' || Array.isArray(server)) {\n return false;\n }\n const marker = (server as Record<string, unknown>).xopcConnector;\n return Boolean(\n marker &&\n typeof marker === 'object' &&\n !Array.isArray(marker) &&\n (marker as Record<string, unknown>).managed === true &&\n typeof (marker as Record<string, unknown>).connectorId === 'string',\n );\n}\n"],"mappings":"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"}
@@ -2,6 +2,12 @@ export type ConnectorKind = 'mcp' | 'cli' | 'http' | 'channel' | 'browser' | 'ex
2
2
  export type ConnectorCategory = 'code' | 'docs' | 'browser' | 'data' | 'automation' | 'custom';
3
3
  export type ConnectorCapability = 'tools' | 'resources' | 'prompts' | 'context' | 'channel' | 'events' | 'ui' | 'memory_source' | 'workflows' | 'auth.apiKey' | 'auth.oauth' | 'runtime.mcp.stdio' | 'runtime.mcp.sse' | 'runtime.mcp.streamableHttp';
4
4
  export type ConnectorAuthMode = 'none' | 'apiKey' | 'oauth';
5
+ export type ConnectorPermissions = {
6
+ data?: string[];
7
+ networkDomains?: string[];
8
+ localExec?: boolean;
9
+ filesystem?: string[];
10
+ };
5
11
  export type ConnectorSecretReference = {
6
12
  xopcSecretRef: {
7
13
  provider: string;
@@ -27,6 +33,11 @@ export type ConnectorRuntimeDefinition = {
27
33
  type: 'mcp';
28
34
  serverId: string;
29
35
  serverTemplate: Record<string, unknown>;
36
+ localPackage?: {
37
+ registry: 'npm';
38
+ name: string;
39
+ version: string;
40
+ };
30
41
  } | {
31
42
  type: 'channel';
32
43
  channelId: string;
@@ -48,7 +59,7 @@ export type ConnectorDefinition = {
48
59
  description: string;
49
60
  category: ConnectorCategory;
50
61
  kind: ConnectorKind;
51
- source: 'builtin' | 'extension' | 'custom' | 'registry';
62
+ source: 'builtin' | 'extension' | 'custom' | 'registry' | 'store';
52
63
  capabilities: ConnectorCapability[];
53
64
  tags?: string[];
54
65
  auth: {
@@ -59,6 +70,11 @@ export type ConnectorDefinition = {
59
70
  config?: ConnectorConfigField[];
60
71
  };
61
72
  runtime: ConnectorRuntimeDefinition;
73
+ permissions?: ConnectorPermissions;
74
+ provenance?: {
75
+ packageName: string;
76
+ sha256: string;
77
+ };
62
78
  };
63
79
  export type ConnectorInstallInput = {
64
80
  secrets?: Record<string, unknown>;
@@ -144,4 +160,6 @@ export type ManagedConnectorMarker = {
144
160
  lastError?: string;
145
161
  displayName?: string;
146
162
  config?: Record<string, unknown>;
163
+ source?: ConnectorDefinition['source'];
164
+ artifactSha256?: string;
147
165
  };
@@ -3,8 +3,8 @@ import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
4
  import { init_paths, resolveBundledExtensionsDir, resolveExtensionsDir as resolveExtensionsDir$1 } from "../config/paths.js";
5
5
  import { checkEngineCompatibility } from "./engine-check.js";
6
- import { collectExtensionPackageDependencyIssues } from "./package-contract.js";
7
6
  import { MAX_EXTENSION_STORE_ZIP_BYTES } from "./store-zip-limits.js";
7
+ import { collectExtensionPackageDependencyIssues } from "./package-contract.js";
8
8
  import { dirname, isAbsolute, join, resolve, sep } from "path";
9
9
  import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
10
10
  import { execSync } from "child_process";
@@ -174,7 +174,7 @@ export interface ChatWidgetMatch {
174
174
  export interface PageContribution {
175
175
  id: string;
176
176
  title: string;
177
- /** Relative path; host may mount under `/apps/` (see Phase 2). */
177
+ /** Relative path; host may mount under `/extensions/` (see Phase 2). */
178
178
  path: string;
179
179
  entrypoint: string;
180
180
  showInNav?: boolean;
@@ -2,10 +2,10 @@ import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { init_paths, resolveBundledExtensionsDir, resolveExtensionsDir } from "../config/paths.js";
4
4
  import { init_loader, loadConfig } from "../config/loader.js";
5
+ import { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl, verifyStoreArtifactSha256 } from "../agent/skills/marketplace/adapters/store/store-api-client.js";
5
6
  import { getExtensionLockfileManager } from "./lockfile.js";
6
7
  import { installExtensionFromStoreZip, installFromNpm } from "./install.js";
7
8
  import { findExtension } from "./marketplace.js";
8
- import { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl } from "../agent/skills/marketplace/adapters/store/store-api-client.js";
9
9
  import { join } from "node:path";
10
10
  import { existsSync, readFileSync, readdirSync, rmSync } from "node:fs";
11
11
  import semver from "semver";
@@ -51,8 +51,10 @@ async function upsertNpmExtensionLock(lock, targetDir, result, spec) {
51
51
  }
52
52
  async function installExtensionFromStoreWithLock(params) {
53
53
  try {
54
- const { downloadUrl, version } = await resolveExtensionZipDownloadUrl(params.storeBase, params.packageName, params.version);
55
- const result = await installExtensionFromStoreZip(await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl), params.targetDir);
54
+ const { downloadUrl, version, sha256 } = await resolveExtensionZipDownloadUrl(params.storeBase, params.packageName, params.version);
55
+ const buf = await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl);
56
+ verifyStoreArtifactSha256(buf, sha256);
57
+ const result = await installExtensionFromStoreZip(buf, params.targetDir);
56
58
  if (!result.ok || !result.extensionId) return {
57
59
  ok: false,
58
60
  error: result.error ?? "install failed"
@@ -1 +1 @@
1
- {"version":3,"file":"update.js","names":["marketplace.findExtension"],"sources":["../../../src/extensions/update.ts"],"sourcesContent":["/**\n * Post-update extension sync — refresh lockfile-managed npm / store extensions.\n */\n\nimport { existsSync, readFileSync, readdirSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport semver from 'semver';\n\nimport {\n downloadExtensionStoreZipBuffer,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n} from '../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport type { Config } from '../config/schema.js';\nimport { resolveBundledExtensionsDir, resolveExtensionsDir } from '../config/paths.js';\nimport { loadConfig } from '../config/loader.js';\nimport type { UpdateChannel } from '../infra/update-channels.js';\nimport { createLogger } from '../utils/logger.js';\nimport {\n installExtensionFromStoreZip,\n installFromNpm,\n type InstallResult,\n} from './install.js';\nimport {\n getExtensionLockfileManager,\n type ExtensionLockEntry,\n} from './lockfile.js';\nimport * as marketplace from './marketplace.js';\n\nconst log = createLogger('ExtensionUpdate');\n\nconst MANIFEST = 'xopc.extension.json';\n\nexport type ExtensionUpdateLogger = {\n info?: (message: string) => void;\n warn?: (message: string) => void;\n error?: (message: string) => void;\n};\n\nexport type ExtensionUpdateStatus = 'updated' | 'unchanged' | 'skipped' | 'error';\n\nexport type ExtensionUpdateOutcome = {\n extensionId: string;\n status: ExtensionUpdateStatus;\n message: string;\n currentVersion?: string;\n nextVersion?: string;\n};\n\nexport type ExtensionChannelSyncSummary = {\n skippedBundled: string[];\n warnings: string[];\n};\n\nexport type ExtensionPostUpdateResult = {\n status: 'ok' | 'error' | 'skipped';\n outcomes: ExtensionUpdateOutcome[];\n channelSync?: ExtensionChannelSyncSummary;\n};\n\nfunction readInstalledExtensionVersion(targetDir: string, extensionId: string): string | undefined {\n const manifestPath = join(targetDir, extensionId, MANIFEST);\n if (!existsSync(manifestPath)) {\n return undefined;\n }\n try {\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8')) as { version?: string };\n const version = typeof raw.version === 'string' ? semver.valid(raw.version) : null;\n return version ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function resolveNpmPackageForId(extensionId: string): Promise<string | undefined> {\n const found = await marketplace.findExtension(extensionId);\n return found?.npmPackage;\n}\n\nasync function upsertNpmExtensionLock(\n lock: ReturnType<typeof getExtensionLockfileManager>,\n targetDir: string,\n result: InstallResult,\n spec: string,\n): Promise<void> {\n if (!result.extensionId) return;\n const reg = await marketplace.findExtension(result.extensionId);\n const resolved = reg?.npmPackage ?? spec;\n let ver = reg?.version ?? '0.0.0';\n try {\n const raw = readFileSync(join(targetDir, result.extensionId, MANIFEST), 'utf-8');\n const m = JSON.parse(raw) as { version?: string };\n const mv = typeof m.version === 'string' ? semver.valid(m.version) : null;\n if (mv) ver = mv;\n } catch {\n // keep registry / fallback version\n }\n await lock.upsert(result.extensionId, {\n name: result.extensionId,\n version: ver,\n resolved,\n source: 'npm',\n });\n}\n\nasync function installExtensionFromStoreWithLock(params: {\n storeBase: string;\n packageName: string;\n version?: string;\n targetDir: string;\n lock: ReturnType<typeof getExtensionLockfileManager>;\n}): Promise<{ ok: true; extensionId: string; version: string } | { ok: false; error: string }> {\n try {\n const { downloadUrl, version } = await resolveExtensionZipDownloadUrl(\n params.storeBase,\n params.packageName,\n params.version,\n );\n const buf = await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl);\n const result = await installExtensionFromStoreZip(buf, params.targetDir);\n if (!result.ok || !result.extensionId) {\n return { ok: false, error: result.error ?? 'install failed' };\n }\n await params.lock.upsert(result.extensionId, {\n name: result.extensionId,\n version,\n resolved: params.packageName,\n source: 'store',\n });\n return { ok: true, extensionId: result.extensionId, version };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction listBundledExtensionIds(): Set<string> {\n const ids = new Set<string>();\n const bundledDir = resolveBundledExtensionsDir();\n if (!bundledDir || !existsSync(bundledDir)) {\n return ids;\n }\n for (const entry of readdirSync(bundledDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n ids.add(entry.name);\n }\n }\n return ids;\n}\n\nexport async function syncExtensionsForUpdateChannel(params: {\n channel: UpdateChannel;\n config?: Config;\n logger?: ExtensionUpdateLogger;\n}): Promise<{ skipIds: Set<string>; summary: ExtensionChannelSyncSummary }> {\n const logger = params.logger ?? {};\n const summary: ExtensionChannelSyncSummary = {\n skippedBundled: [],\n warnings: [],\n };\n const skipIds = new Set<string>();\n\n if (params.channel !== 'dev') {\n return { skipIds, summary };\n }\n\n const lock = getExtensionLockfileManager();\n const data = await lock.load();\n const bundledIds = listBundledExtensionIds();\n\n for (const extensionId of Object.keys(data.extensions)) {\n if (!bundledIds.has(extensionId)) {\n continue;\n }\n skipIds.add(extensionId);\n summary.skippedBundled.push(extensionId);\n logger.info?.(`Skipping \"${extensionId}\" on dev channel (bundled copy preferred).`);\n }\n\n return { skipIds, summary };\n}\n\nasync function updateSingleExtension(params: {\n extensionId: string;\n entry: ExtensionLockEntry;\n targetDir: string;\n storeBase: string;\n lock: ReturnType<typeof getExtensionLockfileManager>;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<ExtensionUpdateOutcome> {\n const { extensionId, entry, targetDir, storeBase, lock, timeoutMs, logger } = params;\n const currentVersion = readInstalledExtensionVersion(targetDir, extensionId);\n\n if (entry.source === 'store') {\n const pkgName = entry.resolved?.trim() || extensionId;\n if (existsSync(join(targetDir, extensionId))) {\n rmSync(join(targetDir, extensionId), { recursive: true, force: true });\n }\n const result = await installExtensionFromStoreWithLock({\n storeBase,\n packageName: pkgName,\n targetDir,\n lock,\n });\n if (result.ok === false) {\n logger.error?.(`Failed to update ${extensionId}: ${result.error}`);\n return {\n extensionId,\n status: 'error',\n message: result.error,\n currentVersion,\n };\n }\n const nextVersion = result.version;\n const status =\n currentVersion && nextVersion && currentVersion === nextVersion ? 'unchanged' : 'updated';\n return {\n extensionId,\n status,\n currentVersion,\n nextVersion,\n message:\n status === 'unchanged'\n ? `${extensionId} is up to date (${currentVersion}).`\n : `Updated ${extensionId}: ${currentVersion ?? 'unknown'} -> ${nextVersion}.`,\n };\n }\n\n if (entry.source !== 'npm') {\n return {\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (source: ${entry.source}).`,\n };\n }\n\n const spec = entry.resolved?.trim() || (await resolveNpmPackageForId(extensionId));\n if (!spec) {\n return {\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (could not resolve npm package).`,\n };\n }\n\n if (existsSync(join(targetDir, extensionId))) {\n rmSync(join(targetDir, extensionId), { recursive: true, force: true });\n }\n\n const installResult = await installFromNpm(spec, targetDir, timeoutMs);\n if (!installResult.ok) {\n const message = installResult.error ?? 'npm install failed';\n logger.error?.(`Failed to update ${extensionId}: ${message}`);\n return {\n extensionId,\n status: 'error',\n message,\n currentVersion,\n };\n }\n\n await upsertNpmExtensionLock(lock, targetDir, installResult, spec);\n const nextVersion =\n (installResult.extensionId\n ? readInstalledExtensionVersion(targetDir, installResult.extensionId)\n : undefined) ?? entry.version;\n const resolvedId = installResult.extensionId ?? extensionId;\n const status =\n currentVersion && nextVersion && currentVersion === nextVersion ? 'unchanged' : 'updated';\n return {\n extensionId: resolvedId,\n status,\n currentVersion,\n nextVersion,\n message:\n status === 'unchanged'\n ? `${resolvedId} is up to date (${currentVersion}).`\n : `Updated ${resolvedId}: ${currentVersion ?? 'unknown'} -> ${nextVersion}.`,\n };\n}\n\nexport async function updateNpmInstalledExtensions(params: {\n extensionIds?: string[];\n skipIds?: Set<string>;\n config?: Config;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<{ outcomes: ExtensionUpdateOutcome[]; status: 'ok' | 'error' | 'skipped' }> {\n const logger = params.logger ?? {};\n const config = params.config ?? loadConfig();\n const targetDir = resolveExtensionsDir();\n const storeBase = resolveExtensionsStoreBaseUrl(config);\n const lock = getExtensionLockfileManager();\n const data = await lock.load();\n\n const ids = params.extensionIds?.length\n ? params.extensionIds\n : Object.keys(data.extensions);\n\n if (ids.length === 0) {\n return { outcomes: [], status: 'skipped' };\n }\n\n const outcomes: ExtensionUpdateOutcome[] = [];\n let hasError = false;\n\n for (const extensionId of ids) {\n if (params.skipIds?.has(extensionId)) {\n outcomes.push({\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (channel sync).`,\n });\n continue;\n }\n\n const entry = data.extensions[extensionId];\n if (!entry) {\n outcomes.push({\n extensionId,\n status: 'skipped',\n message: `No lockfile entry for \"${extensionId}\".`,\n });\n continue;\n }\n\n const outcome = await updateSingleExtension({\n extensionId,\n entry,\n targetDir,\n storeBase,\n lock,\n timeoutMs: params.timeoutMs,\n logger,\n });\n outcomes.push(outcome);\n if (outcome.status === 'error') {\n hasError = true;\n } else if (outcome.status === 'updated') {\n log.info(\n { extensionId: outcome.extensionId, nextVersion: outcome.nextVersion },\n outcome.message,\n );\n }\n }\n\n return { outcomes, status: hasError ? 'error' : 'ok' };\n}\n\nexport async function runPostUpdateExtensionSync(params: {\n channel: UpdateChannel;\n config?: Config;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<ExtensionPostUpdateResult> {\n const logger = params.logger ?? {\n info: (message) => log.info(message),\n warn: (message) => log.warn(message),\n error: (message) => log.error(message),\n };\n\n const channelSyncResult = await syncExtensionsForUpdateChannel({\n channel: params.channel,\n config: params.config,\n logger,\n });\n\n const updateResult = await updateNpmInstalledExtensions({\n skipIds: channelSyncResult.skipIds,\n config: params.config,\n timeoutMs: params.timeoutMs,\n logger,\n });\n\n return {\n status: updateResult.status,\n outcomes: updateResult.outcomes,\n channelSync: channelSyncResult.summary,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"update.js","names":["marketplace.findExtension"],"sources":["../../../src/extensions/update.ts"],"sourcesContent":["/**\n * Post-update extension sync — refresh lockfile-managed npm / store extensions.\n */\n\nimport { existsSync, readFileSync, readdirSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport semver from 'semver';\n\nimport {\n downloadExtensionStoreZipBuffer,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n verifyStoreArtifactSha256,\n} from '../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport type { Config } from '../config/schema.js';\nimport { resolveBundledExtensionsDir, resolveExtensionsDir } from '../config/paths.js';\nimport { loadConfig } from '../config/loader.js';\nimport type { UpdateChannel } from '../infra/update-channels.js';\nimport { createLogger } from '../utils/logger.js';\nimport {\n installExtensionFromStoreZip,\n installFromNpm,\n type InstallResult,\n} from './install.js';\nimport {\n getExtensionLockfileManager,\n type ExtensionLockEntry,\n} from './lockfile.js';\nimport * as marketplace from './marketplace.js';\n\nconst log = createLogger('ExtensionUpdate');\n\nconst MANIFEST = 'xopc.extension.json';\n\nexport type ExtensionUpdateLogger = {\n info?: (message: string) => void;\n warn?: (message: string) => void;\n error?: (message: string) => void;\n};\n\nexport type ExtensionUpdateStatus = 'updated' | 'unchanged' | 'skipped' | 'error';\n\nexport type ExtensionUpdateOutcome = {\n extensionId: string;\n status: ExtensionUpdateStatus;\n message: string;\n currentVersion?: string;\n nextVersion?: string;\n};\n\nexport type ExtensionChannelSyncSummary = {\n skippedBundled: string[];\n warnings: string[];\n};\n\nexport type ExtensionPostUpdateResult = {\n status: 'ok' | 'error' | 'skipped';\n outcomes: ExtensionUpdateOutcome[];\n channelSync?: ExtensionChannelSyncSummary;\n};\n\nfunction readInstalledExtensionVersion(targetDir: string, extensionId: string): string | undefined {\n const manifestPath = join(targetDir, extensionId, MANIFEST);\n if (!existsSync(manifestPath)) {\n return undefined;\n }\n try {\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8')) as { version?: string };\n const version = typeof raw.version === 'string' ? semver.valid(raw.version) : null;\n return version ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function resolveNpmPackageForId(extensionId: string): Promise<string | undefined> {\n const found = await marketplace.findExtension(extensionId);\n return found?.npmPackage;\n}\n\nasync function upsertNpmExtensionLock(\n lock: ReturnType<typeof getExtensionLockfileManager>,\n targetDir: string,\n result: InstallResult,\n spec: string,\n): Promise<void> {\n if (!result.extensionId) return;\n const reg = await marketplace.findExtension(result.extensionId);\n const resolved = reg?.npmPackage ?? spec;\n let ver = reg?.version ?? '0.0.0';\n try {\n const raw = readFileSync(join(targetDir, result.extensionId, MANIFEST), 'utf-8');\n const m = JSON.parse(raw) as { version?: string };\n const mv = typeof m.version === 'string' ? semver.valid(m.version) : null;\n if (mv) ver = mv;\n } catch {\n // keep registry / fallback version\n }\n await lock.upsert(result.extensionId, {\n name: result.extensionId,\n version: ver,\n resolved,\n source: 'npm',\n });\n}\n\nasync function installExtensionFromStoreWithLock(params: {\n storeBase: string;\n packageName: string;\n version?: string;\n targetDir: string;\n lock: ReturnType<typeof getExtensionLockfileManager>;\n}): Promise<{ ok: true; extensionId: string; version: string } | { ok: false; error: string }> {\n try {\n const { downloadUrl, version, sha256 } = await resolveExtensionZipDownloadUrl(\n params.storeBase,\n params.packageName,\n params.version,\n );\n const buf = await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl);\n verifyStoreArtifactSha256(buf, sha256);\n const result = await installExtensionFromStoreZip(buf, params.targetDir);\n if (!result.ok || !result.extensionId) {\n return { ok: false, error: result.error ?? 'install failed' };\n }\n await params.lock.upsert(result.extensionId, {\n name: result.extensionId,\n version,\n resolved: params.packageName,\n source: 'store',\n });\n return { ok: true, extensionId: result.extensionId, version };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction listBundledExtensionIds(): Set<string> {\n const ids = new Set<string>();\n const bundledDir = resolveBundledExtensionsDir();\n if (!bundledDir || !existsSync(bundledDir)) {\n return ids;\n }\n for (const entry of readdirSync(bundledDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n ids.add(entry.name);\n }\n }\n return ids;\n}\n\nexport async function syncExtensionsForUpdateChannel(params: {\n channel: UpdateChannel;\n config?: Config;\n logger?: ExtensionUpdateLogger;\n}): Promise<{ skipIds: Set<string>; summary: ExtensionChannelSyncSummary }> {\n const logger = params.logger ?? {};\n const summary: ExtensionChannelSyncSummary = {\n skippedBundled: [],\n warnings: [],\n };\n const skipIds = new Set<string>();\n\n if (params.channel !== 'dev') {\n return { skipIds, summary };\n }\n\n const lock = getExtensionLockfileManager();\n const data = await lock.load();\n const bundledIds = listBundledExtensionIds();\n\n for (const extensionId of Object.keys(data.extensions)) {\n if (!bundledIds.has(extensionId)) {\n continue;\n }\n skipIds.add(extensionId);\n summary.skippedBundled.push(extensionId);\n logger.info?.(`Skipping \"${extensionId}\" on dev channel (bundled copy preferred).`);\n }\n\n return { skipIds, summary };\n}\n\nasync function updateSingleExtension(params: {\n extensionId: string;\n entry: ExtensionLockEntry;\n targetDir: string;\n storeBase: string;\n lock: ReturnType<typeof getExtensionLockfileManager>;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<ExtensionUpdateOutcome> {\n const { extensionId, entry, targetDir, storeBase, lock, timeoutMs, logger } = params;\n const currentVersion = readInstalledExtensionVersion(targetDir, extensionId);\n\n if (entry.source === 'store') {\n const pkgName = entry.resolved?.trim() || extensionId;\n if (existsSync(join(targetDir, extensionId))) {\n rmSync(join(targetDir, extensionId), { recursive: true, force: true });\n }\n const result = await installExtensionFromStoreWithLock({\n storeBase,\n packageName: pkgName,\n targetDir,\n lock,\n });\n if (result.ok === false) {\n logger.error?.(`Failed to update ${extensionId}: ${result.error}`);\n return {\n extensionId,\n status: 'error',\n message: result.error,\n currentVersion,\n };\n }\n const nextVersion = result.version;\n const status =\n currentVersion && nextVersion && currentVersion === nextVersion ? 'unchanged' : 'updated';\n return {\n extensionId,\n status,\n currentVersion,\n nextVersion,\n message:\n status === 'unchanged'\n ? `${extensionId} is up to date (${currentVersion}).`\n : `Updated ${extensionId}: ${currentVersion ?? 'unknown'} -> ${nextVersion}.`,\n };\n }\n\n if (entry.source !== 'npm') {\n return {\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (source: ${entry.source}).`,\n };\n }\n\n const spec = entry.resolved?.trim() || (await resolveNpmPackageForId(extensionId));\n if (!spec) {\n return {\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (could not resolve npm package).`,\n };\n }\n\n if (existsSync(join(targetDir, extensionId))) {\n rmSync(join(targetDir, extensionId), { recursive: true, force: true });\n }\n\n const installResult = await installFromNpm(spec, targetDir, timeoutMs);\n if (!installResult.ok) {\n const message = installResult.error ?? 'npm install failed';\n logger.error?.(`Failed to update ${extensionId}: ${message}`);\n return {\n extensionId,\n status: 'error',\n message,\n currentVersion,\n };\n }\n\n await upsertNpmExtensionLock(lock, targetDir, installResult, spec);\n const nextVersion =\n (installResult.extensionId\n ? readInstalledExtensionVersion(targetDir, installResult.extensionId)\n : undefined) ?? entry.version;\n const resolvedId = installResult.extensionId ?? extensionId;\n const status =\n currentVersion && nextVersion && currentVersion === nextVersion ? 'unchanged' : 'updated';\n return {\n extensionId: resolvedId,\n status,\n currentVersion,\n nextVersion,\n message:\n status === 'unchanged'\n ? `${resolvedId} is up to date (${currentVersion}).`\n : `Updated ${resolvedId}: ${currentVersion ?? 'unknown'} -> ${nextVersion}.`,\n };\n}\n\nexport async function updateNpmInstalledExtensions(params: {\n extensionIds?: string[];\n skipIds?: Set<string>;\n config?: Config;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<{ outcomes: ExtensionUpdateOutcome[]; status: 'ok' | 'error' | 'skipped' }> {\n const logger = params.logger ?? {};\n const config = params.config ?? loadConfig();\n const targetDir = resolveExtensionsDir();\n const storeBase = resolveExtensionsStoreBaseUrl(config);\n const lock = getExtensionLockfileManager();\n const data = await lock.load();\n\n const ids = params.extensionIds?.length\n ? params.extensionIds\n : Object.keys(data.extensions);\n\n if (ids.length === 0) {\n return { outcomes: [], status: 'skipped' };\n }\n\n const outcomes: ExtensionUpdateOutcome[] = [];\n let hasError = false;\n\n for (const extensionId of ids) {\n if (params.skipIds?.has(extensionId)) {\n outcomes.push({\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (channel sync).`,\n });\n continue;\n }\n\n const entry = data.extensions[extensionId];\n if (!entry) {\n outcomes.push({\n extensionId,\n status: 'skipped',\n message: `No lockfile entry for \"${extensionId}\".`,\n });\n continue;\n }\n\n const outcome = await updateSingleExtension({\n extensionId,\n entry,\n targetDir,\n storeBase,\n lock,\n timeoutMs: params.timeoutMs,\n logger,\n });\n outcomes.push(outcome);\n if (outcome.status === 'error') {\n hasError = true;\n } else if (outcome.status === 'updated') {\n log.info(\n { extensionId: outcome.extensionId, nextVersion: outcome.nextVersion },\n outcome.message,\n );\n }\n }\n\n return { outcomes, status: hasError ? 'error' : 'ok' };\n}\n\nexport async function runPostUpdateExtensionSync(params: {\n channel: UpdateChannel;\n config?: Config;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<ExtensionPostUpdateResult> {\n const logger = params.logger ?? {\n info: (message) => log.info(message),\n warn: (message) => log.warn(message),\n error: (message) => log.error(message),\n };\n\n const channelSyncResult = await syncExtensionsForUpdateChannel({\n channel: params.channel,\n config: params.config,\n logger,\n });\n\n const updateResult = await updateNpmInstalledExtensions({\n skipIds: channelSyncResult.skipIds,\n config: params.config,\n timeoutMs: params.timeoutMs,\n logger,\n });\n\n return {\n status: updateResult.status,\n outcomes: updateResult.outcomes,\n channelSync: channelSyncResult.summary,\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
2
1
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
2
+ import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
3
3
  import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
4
4
  import { WORKSPACE_FILES, init_paths, resolveUserProfilePath } from "../config/paths.js";
5
5
  import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
@@ -33,7 +33,11 @@ var ChatStreamMapper = class {
33
33
  })];
34
34
  case "progress": return [this.make("progress", {
35
35
  stage: String(event.stage ?? ""),
36
- message: String(event.message ?? "")
36
+ message: String(event.message ?? ""),
37
+ ...typeof event.detail === "string" ? { detail: event.detail } : {},
38
+ ...typeof event.toolName === "string" ? { toolName: event.toolName } : {},
39
+ ...typeof event.completed === "number" ? { completed: event.completed } : {},
40
+ ...typeof event.total === "number" ? { total: event.total } : {}
37
41
  })];
38
42
  case "compaction": return [this.make("compaction", {
39
43
  status: event.status === "completed" || event.status === "skipped" ? event.status : "started",
@@ -1 +1 @@
1
- {"version":3,"file":"mapper.js","names":["message"],"sources":["../../../../src/gateway/chat-stream/mapper.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { EmbeddedStreamEvent } from '../../agent/embedded/types.js';\nimport type { ChatStreamEvent, ChatStreamStatus } from './protocol.js';\n\nexport type RuntimeStreamEvent = EmbeddedStreamEvent | { type: string; [key: string]: unknown };\n\nexport interface ChatStreamMapperOptions {\n runId: string;\n sessionKey: string;\n channel: string;\n}\n\ntype ToolResultEnvelope = { content?: unknown[]; details?: unknown; text?: string };\n\nexport class ChatStreamMapper {\n private assistantIndex = 0;\n private currentAssistantMessageId: string | undefined;\n private lastAssistantMessageId: string | undefined;\n private currentAssistantText = '';\n private currentAssistantReviewEmitted = false;\n private toolCallToMessageId = new Map<string, string>();\n private turnDiffs: string[] = [];\n private turnDiffFiles = new Set<string>();\n private turnDiffAdded = 0;\n private turnDiffRemoved = 0;\n private started = false;\n private ended = false;\n\n constructor(private readonly opts: ChatStreamMapperOptions) {}\n\n map(input: RuntimeStreamEvent): ChatStreamEvent[] {\n const event = input as { type: string; [key: string]: unknown };\n switch (event.type) {\n case 'agent_start':\n return this.start();\n case 'agent_end':\n return [];\n case 'message_start':\n return this.mapMessageStart(event.message);\n case 'message_update':\n return this.mapMessageUpdate(event);\n case 'message_end':\n return this.mapMessageEnd(event.message);\n case 'tool_execution_start':\n return this.mapToolStart(event);\n case 'tool_execution_update':\n return this.mapToolUpdate(event);\n case 'tool_execution_end':\n return this.mapToolEnd(event);\n case 'user_message':\n return [this.make('user_message', { message: userMessageFromLegacyEvent(event) })];\n case 'user_transcript':\n return [this.make('user_transcript', { text: String(event.text ?? ''), media: event.media })];\n case 'progress':\n return [this.make('progress', { stage: String(event.stage ?? ''), message: String(event.message ?? '') })];\n case 'compaction':\n return [\n this.make('compaction', {\n status: event.status === 'completed' || event.status === 'skipped' ? event.status : 'started',\n tokensBefore: typeof event.tokensBefore === 'number' ? event.tokensBefore : undefined,\n tokensAfter: typeof event.tokensAfter === 'number' ? event.tokensAfter : undefined,\n summary: typeof event.summary === 'string' ? event.summary : undefined,\n }),\n ];\n case 'tts_audio':\n return [\n this.make('tts_audio', {\n uri: String(event.uri ?? ''),\n mimeType: String(event.mimeType ?? 'audio/mpeg'),\n name: String(event.name ?? 'voice.mp3'),\n attachTo: 'last_assistant',\n ...(this.lastAssistantMessageId ? { messageId: this.lastAssistantMessageId } : {}),\n }),\n ];\n case 'clarify_request':\n return [\n this.make('clarify_request', {\n requestId: String(event.requestId ?? ''),\n question: String(event.question ?? ''),\n choices: Array.isArray(event.choices) ? event.choices.filter((x): x is string => typeof x === 'string') : undefined,\n default: typeof event.default === 'string' ? event.default : undefined,\n }),\n ];\n case 'error':\n return [this.make('error', { code: 'AGENT_RUN_ERROR', message: String(event.content ?? event.message ?? 'Unknown error') })];\n default:\n return [];\n }\n }\n\n start(): ChatStreamEvent[] {\n if (this.started) return [];\n this.started = true;\n return [this.make('run_start', { channel: this.opts.channel })];\n }\n\n end(status: ChatStreamStatus, summary?: string): ChatStreamEvent[] {\n if (this.ended) return [];\n this.ended = true;\n return [this.make('run_end', { status, summary })];\n }\n\n error(message: string, code = 'AGENT_RUN_ERROR'): ChatStreamEvent[] {\n return [this.make('error', { code, message })];\n }\n\n private mapMessageStart(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.nextAssistantMessageId();\n this.currentAssistantMessageId = messageId;\n this.currentAssistantText = '';\n this.currentAssistantReviewEmitted = false;\n return [this.make('assistant_message_start', { messageId })];\n }\n\n private mapMessageUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const message = event.message as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const review = extractReview(message);\n if (review && !this.currentAssistantReviewEmitted) {\n this.currentAssistantReviewEmitted = true;\n return [this.make('review', { messageId, review })];\n }\n const delta = event.assistantMessageEvent as { type?: unknown; delta?: unknown } | undefined;\n if (delta?.type === 'text_delta' && typeof delta.delta === 'string' && delta.delta) {\n const text = extractTextFromMessage(message);\n const suffixFromMessage = appendSuffix(this.currentAssistantText, text);\n const suffix = text ? suffixFromMessage : appendSuffix(this.currentAssistantText, delta.delta);\n if (!suffix) {\n if (text) this.currentAssistantText = text;\n return [];\n }\n this.currentAssistantText = text || `${this.currentAssistantText}${suffix}`;\n return [this.make('assistant_delta', { messageId, delta: suffix })];\n }\n if (delta?.type === 'thinking_delta' && typeof delta.delta === 'string' && delta.delta) {\n return [this.make('thinking_delta', { messageId, delta: delta.delta })];\n }\n\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n this.currentAssistantText = text || this.currentAssistantText;\n return suffix ? [this.make('assistant_delta', { messageId, delta: suffix })] : [];\n }\n\n private mapMessageEnd(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const events: ChatStreamEvent[] = [];\n const review = extractReview(message);\n if (review && !this.currentAssistantReviewEmitted) {\n this.currentAssistantReviewEmitted = true;\n events.push(this.make('review', { messageId, review }));\n }\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n if (suffix) events.push(this.make('assistant_delta', { messageId, delta: suffix }));\n this.currentAssistantText = text || this.currentAssistantText;\n events.push(this.make('thinking_end', { messageId }));\n if (this.turnDiffs.length > 0) {\n events.push(\n this.make('turn_diff', {\n messageId,\n files: [...this.turnDiffFiles],\n diff: this.turnDiffs.join('\\n'),\n added: this.turnDiffAdded,\n removed: this.turnDiffRemoved,\n }),\n );\n this.turnDiffs = [];\n this.turnDiffFiles.clear();\n this.turnDiffAdded = 0;\n this.turnDiffRemoved = 0;\n }\n events.push(this.make('assistant_message_end', { messageId, usage: extractUsage(message) }));\n this.lastAssistantMessageId = messageId;\n this.currentAssistantMessageId = undefined;\n this.currentAssistantText = '';\n this.currentAssistantReviewEmitted = false;\n return events;\n }\n\n private mapToolStart(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.ensureAssistantMessageId();\n const toolName = String(event.toolName ?? 'unknown');\n this.toolCallToMessageId.set(toolCallId, messageId);\n const events: ChatStreamEvent[] = [\n this.make('tool_start', {\n messageId,\n toolCallId,\n toolName,\n args: event.args,\n }),\n ];\n if (toolName === 'exec_command') {\n const args = asRecord(event.args);\n events.push(\n this.make('command_started', {\n messageId,\n toolCallId,\n command: String(args?.cmd ?? args?.command ?? ''),\n cwd: typeof args?.cwd === 'string' ? args.cwd : undefined,\n }),\n );\n }\n return events;\n }\n\n private mapToolUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const partial = event.partialResult;\n const details = extractDetails(partial);\n const textDelta = extractText(partial);\n const toolName = String(event.toolName ?? 'unknown');\n const events: ChatStreamEvent[] = [\n this.make('tool_update', {\n messageId,\n toolCallId,\n toolName,\n details,\n textDelta,\n }),\n ];\n if (toolName === 'exec_command') {\n const rec = asRecord(details);\n if (rec?.kind === 'command_output_delta') {\n const stream = rec.stream === 'stderr' ? 'stderr' : 'stdout';\n const delta = typeof rec.delta === 'string' ? rec.delta : '';\n if (delta) {\n events.push(this.make('command_output_delta', { messageId, toolCallId, stream, delta }));\n }\n }\n }\n return events;\n }\n\n private mapToolEnd(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const result = normalizeToolResult(event.result);\n const toolName = String(event.toolName ?? 'unknown');\n const events: ChatStreamEvent[] = [\n this.make('tool_end', {\n messageId,\n toolCallId,\n toolName,\n status: event.isError ? 'error' : 'success',\n result,\n errorMessage: event.isError ? result?.text : undefined,\n }),\n ];\n const details = asRecord(result?.details);\n if (toolName === 'exec_command' && details) {\n events.push(\n this.make('command_completed', {\n messageId,\n toolCallId,\n command: typeof details.command === 'string' ? details.command : '',\n cwd: typeof details.cwd === 'string' ? details.cwd : undefined,\n exitCode: typeof details.exitCode === 'number' ? details.exitCode : null,\n durationMs: typeof details.durationMs === 'number' ? details.durationMs : undefined,\n timedOut: details.timedOut === true,\n truncated: details.truncated === true,\n }),\n );\n }\n if (toolName === 'apply_patch' && details) {\n const changes = Array.isArray(details.changes) ? details.changes : [];\n const diff = typeof details.diff === 'string' ? details.diff : '';\n const added = typeof details.added === 'number' ? details.added : 0;\n const removed = typeof details.removed === 'number' ? details.removed : 0;\n if (diff || changes.length > 0) {\n this.recordPatchDiff(details);\n events.push(this.make('patch_applied', { messageId, toolCallId, changes, diff, added, removed }));\n }\n }\n if (toolName === 'update_plan' && details) {\n const plan = extractTurnPlan(details);\n if (plan) {\n events.push(this.make('turn_plan', { messageId, ...plan }));\n }\n }\n return events;\n }\n\n private ensureAssistantMessageId(): string {\n if (!this.currentAssistantMessageId) {\n this.currentAssistantMessageId = this.nextAssistantMessageId();\n }\n return this.currentAssistantMessageId;\n }\n\n private nextAssistantMessageId(): string {\n this.assistantIndex += 1;\n return `msg_${this.opts.runId.replace(/[^a-zA-Z0-9_-]/g, '_')}_${this.assistantIndex}`;\n }\n\n private make<T extends ChatStreamEvent['type']>(\n type: T,\n payload: Extract<ChatStreamEvent, { type: T }>['payload'],\n ): Extract<ChatStreamEvent, { type: T }> {\n return {\n type,\n runId: this.opts.runId,\n sessionKey: this.opts.sessionKey,\n timestamp: Date.now(),\n payload,\n } as Extract<ChatStreamEvent, { type: T }>;\n }\n\n private recordPatchDiff(details: Record<string, unknown>): void {\n const diff = typeof details.diff === 'string' ? details.diff : '';\n if (diff) this.turnDiffs.push(diff);\n if (typeof details.added === 'number') this.turnDiffAdded += details.added;\n if (typeof details.removed === 'number') this.turnDiffRemoved += details.removed;\n const changes = Array.isArray(details.changes) ? details.changes : [];\n for (const change of changes) {\n const rec = asRecord(change);\n const path = typeof rec?.moveTo === 'string'\n ? rec.moveTo\n : typeof rec?.path === 'string'\n ? rec.path\n : undefined;\n if (path) this.turnDiffFiles.add(path);\n }\n }\n}\n\nfunction userMessageFromLegacyEvent(event: { [key: string]: unknown }): unknown {\n return {\n role: 'user',\n content: event.content ?? [],\n attachments: event.media,\n timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),\n };\n}\n\nfunction extractTextFromMessage(message: AgentMessage): string {\n return extractText((message as { content?: unknown }).content);\n}\n\nfunction extractReview(message: AgentMessage): unknown {\n const metadata = (message as { metadata?: unknown }).metadata;\n const metadataReview = asRecord(metadata)?.review;\n if (isReviewBlock(metadataReview)) return metadataReview;\n const content = (message as { content?: unknown }).content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (isReviewBlock(block)) return block;\n }\n }\n return undefined;\n}\n\nfunction isReviewBlock(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n && (value as { type?: unknown }).type === 'review';\n}\n\nfunction extractText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (!Array.isArray(value)) return undefined;\n const text = value\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const rec = block as { type?: unknown; text?: unknown };\n return rec.type === 'text' && typeof rec.text === 'string' ? rec.text : '';\n })\n .join('');\n return text || undefined;\n}\n\nfunction appendSuffix(base: string, next: string | undefined): string {\n if (!next) return '';\n if (!base) return next;\n if (next === base || base.endsWith(next)) return '';\n if (next.startsWith(base)) return next.slice(base.length);\n const max = Math.min(base.length, next.length, 512);\n for (let overlap = max; overlap > 0; overlap--) {\n if (base.slice(-overlap) === next.slice(0, overlap)) return next.slice(overlap);\n }\n return next;\n}\n\nfunction extractUsage(message: AgentMessage): AssistantMessageEndEventPayload['usage'] {\n const usage = (message as { usage?: unknown }).usage;\n if (!usage || typeof usage !== 'object') return undefined;\n const rec = usage as Record<string, unknown>;\n return {\n inputTokens: typeof rec.inputTokens === 'number' ? rec.inputTokens : undefined,\n outputTokens: typeof rec.outputTokens === 'number' ? rec.outputTokens : undefined,\n totalTokens: typeof rec.totalTokens === 'number' ? rec.totalTokens : undefined,\n cost: typeof rec.cost === 'number' ? rec.cost : undefined,\n };\n}\n\ntype AssistantMessageEndEventPayload = Extract<ChatStreamEvent, { type: 'assistant_message_end' }>['payload'];\n\nfunction extractDetails(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined;\n return (value as Record<string, unknown>).details;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction normalizeToolResult(value: unknown): ToolResultEnvelope | undefined {\n if (value == null) return undefined;\n if (typeof value === 'string') return { text: value };\n if (typeof value !== 'object') return { text: String(value) };\n const rec = value as Record<string, unknown>;\n return {\n content: Array.isArray(rec.content) ? rec.content : undefined,\n details: rec.details,\n text: extractText(rec.content) ?? (typeof rec.text === 'string' ? rec.text : undefined),\n };\n}\n\nfunction extractTurnPlan(details: Record<string, unknown>): { explanation?: string; plan: { step: string; status: 'pending' | 'in_progress' | 'completed' }[] } | undefined {\n const rawPlan = Array.isArray(details.plan) ? details.plan : [];\n const plan = rawPlan\n .map((item) => {\n const rec = asRecord(item);\n const step = typeof rec?.step === 'string' ? rec.step.trim() : '';\n const status = rec?.status;\n if (!step || (status !== 'pending' && status !== 'in_progress' && status !== 'completed')) {\n return undefined;\n }\n return { step, status };\n })\n .filter((item): item is { step: string; status: 'pending' | 'in_progress' | 'completed' } => Boolean(item));\n if (plan.length === 0) return undefined;\n const explanation = typeof details.explanation === 'string' && details.explanation.trim()\n ? details.explanation.trim()\n : undefined;\n return { explanation, plan };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mapper.js","names":["message"],"sources":["../../../../src/gateway/chat-stream/mapper.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { EmbeddedStreamEvent } from '../../agent/embedded/types.js';\nimport type { ChatStreamEvent, ChatStreamStatus } from './protocol.js';\n\nexport type RuntimeStreamEvent = EmbeddedStreamEvent | { type: string; [key: string]: unknown };\n\nexport interface ChatStreamMapperOptions {\n runId: string;\n sessionKey: string;\n channel: string;\n}\n\ntype ToolResultEnvelope = { content?: unknown[]; details?: unknown; text?: string };\n\nexport class ChatStreamMapper {\n private assistantIndex = 0;\n private currentAssistantMessageId: string | undefined;\n private lastAssistantMessageId: string | undefined;\n private currentAssistantText = '';\n private currentAssistantReviewEmitted = false;\n private toolCallToMessageId = new Map<string, string>();\n private turnDiffs: string[] = [];\n private turnDiffFiles = new Set<string>();\n private turnDiffAdded = 0;\n private turnDiffRemoved = 0;\n private started = false;\n private ended = false;\n\n constructor(private readonly opts: ChatStreamMapperOptions) {}\n\n map(input: RuntimeStreamEvent): ChatStreamEvent[] {\n const event = input as { type: string; [key: string]: unknown };\n switch (event.type) {\n case 'agent_start':\n return this.start();\n case 'agent_end':\n return [];\n case 'message_start':\n return this.mapMessageStart(event.message);\n case 'message_update':\n return this.mapMessageUpdate(event);\n case 'message_end':\n return this.mapMessageEnd(event.message);\n case 'tool_execution_start':\n return this.mapToolStart(event);\n case 'tool_execution_update':\n return this.mapToolUpdate(event);\n case 'tool_execution_end':\n return this.mapToolEnd(event);\n case 'user_message':\n return [this.make('user_message', { message: userMessageFromLegacyEvent(event) })];\n case 'user_transcript':\n return [this.make('user_transcript', { text: String(event.text ?? ''), media: event.media })];\n case 'progress':\n return [\n this.make('progress', {\n stage: String(event.stage ?? ''),\n message: String(event.message ?? ''),\n ...(typeof event.detail === 'string' ? { detail: event.detail } : {}),\n ...(typeof event.toolName === 'string' ? { toolName: event.toolName } : {}),\n ...(typeof event.completed === 'number' ? { completed: event.completed } : {}),\n ...(typeof event.total === 'number' ? { total: event.total } : {}),\n }),\n ];\n case 'compaction':\n return [\n this.make('compaction', {\n status: event.status === 'completed' || event.status === 'skipped' ? event.status : 'started',\n tokensBefore: typeof event.tokensBefore === 'number' ? event.tokensBefore : undefined,\n tokensAfter: typeof event.tokensAfter === 'number' ? event.tokensAfter : undefined,\n summary: typeof event.summary === 'string' ? event.summary : undefined,\n }),\n ];\n case 'tts_audio':\n return [\n this.make('tts_audio', {\n uri: String(event.uri ?? ''),\n mimeType: String(event.mimeType ?? 'audio/mpeg'),\n name: String(event.name ?? 'voice.mp3'),\n attachTo: 'last_assistant',\n ...(this.lastAssistantMessageId ? { messageId: this.lastAssistantMessageId } : {}),\n }),\n ];\n case 'clarify_request':\n return [\n this.make('clarify_request', {\n requestId: String(event.requestId ?? ''),\n question: String(event.question ?? ''),\n choices: Array.isArray(event.choices) ? event.choices.filter((x): x is string => typeof x === 'string') : undefined,\n default: typeof event.default === 'string' ? event.default : undefined,\n }),\n ];\n case 'error':\n return [this.make('error', { code: 'AGENT_RUN_ERROR', message: String(event.content ?? event.message ?? 'Unknown error') })];\n default:\n return [];\n }\n }\n\n start(): ChatStreamEvent[] {\n if (this.started) return [];\n this.started = true;\n return [this.make('run_start', { channel: this.opts.channel })];\n }\n\n end(status: ChatStreamStatus, summary?: string): ChatStreamEvent[] {\n if (this.ended) return [];\n this.ended = true;\n return [this.make('run_end', { status, summary })];\n }\n\n error(message: string, code = 'AGENT_RUN_ERROR'): ChatStreamEvent[] {\n return [this.make('error', { code, message })];\n }\n\n private mapMessageStart(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.nextAssistantMessageId();\n this.currentAssistantMessageId = messageId;\n this.currentAssistantText = '';\n this.currentAssistantReviewEmitted = false;\n return [this.make('assistant_message_start', { messageId })];\n }\n\n private mapMessageUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const message = event.message as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const review = extractReview(message);\n if (review && !this.currentAssistantReviewEmitted) {\n this.currentAssistantReviewEmitted = true;\n return [this.make('review', { messageId, review })];\n }\n const delta = event.assistantMessageEvent as { type?: unknown; delta?: unknown } | undefined;\n if (delta?.type === 'text_delta' && typeof delta.delta === 'string' && delta.delta) {\n const text = extractTextFromMessage(message);\n const suffixFromMessage = appendSuffix(this.currentAssistantText, text);\n const suffix = text ? suffixFromMessage : appendSuffix(this.currentAssistantText, delta.delta);\n if (!suffix) {\n if (text) this.currentAssistantText = text;\n return [];\n }\n this.currentAssistantText = text || `${this.currentAssistantText}${suffix}`;\n return [this.make('assistant_delta', { messageId, delta: suffix })];\n }\n if (delta?.type === 'thinking_delta' && typeof delta.delta === 'string' && delta.delta) {\n return [this.make('thinking_delta', { messageId, delta: delta.delta })];\n }\n\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n this.currentAssistantText = text || this.currentAssistantText;\n return suffix ? [this.make('assistant_delta', { messageId, delta: suffix })] : [];\n }\n\n private mapMessageEnd(raw: unknown): ChatStreamEvent[] {\n const message = raw as AgentMessage | undefined;\n if (message?.role !== 'assistant') return [];\n const messageId = this.ensureAssistantMessageId();\n const events: ChatStreamEvent[] = [];\n const review = extractReview(message);\n if (review && !this.currentAssistantReviewEmitted) {\n this.currentAssistantReviewEmitted = true;\n events.push(this.make('review', { messageId, review }));\n }\n const text = extractTextFromMessage(message);\n const suffix = appendSuffix(this.currentAssistantText, text);\n if (suffix) events.push(this.make('assistant_delta', { messageId, delta: suffix }));\n this.currentAssistantText = text || this.currentAssistantText;\n events.push(this.make('thinking_end', { messageId }));\n if (this.turnDiffs.length > 0) {\n events.push(\n this.make('turn_diff', {\n messageId,\n files: [...this.turnDiffFiles],\n diff: this.turnDiffs.join('\\n'),\n added: this.turnDiffAdded,\n removed: this.turnDiffRemoved,\n }),\n );\n this.turnDiffs = [];\n this.turnDiffFiles.clear();\n this.turnDiffAdded = 0;\n this.turnDiffRemoved = 0;\n }\n events.push(this.make('assistant_message_end', { messageId, usage: extractUsage(message) }));\n this.lastAssistantMessageId = messageId;\n this.currentAssistantMessageId = undefined;\n this.currentAssistantText = '';\n this.currentAssistantReviewEmitted = false;\n return events;\n }\n\n private mapToolStart(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.ensureAssistantMessageId();\n const toolName = String(event.toolName ?? 'unknown');\n this.toolCallToMessageId.set(toolCallId, messageId);\n const events: ChatStreamEvent[] = [\n this.make('tool_start', {\n messageId,\n toolCallId,\n toolName,\n args: event.args,\n }),\n ];\n if (toolName === 'exec_command') {\n const args = asRecord(event.args);\n events.push(\n this.make('command_started', {\n messageId,\n toolCallId,\n command: String(args?.cmd ?? args?.command ?? ''),\n cwd: typeof args?.cwd === 'string' ? args.cwd : undefined,\n }),\n );\n }\n return events;\n }\n\n private mapToolUpdate(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const partial = event.partialResult;\n const details = extractDetails(partial);\n const textDelta = extractText(partial);\n const toolName = String(event.toolName ?? 'unknown');\n const events: ChatStreamEvent[] = [\n this.make('tool_update', {\n messageId,\n toolCallId,\n toolName,\n details,\n textDelta,\n }),\n ];\n if (toolName === 'exec_command') {\n const rec = asRecord(details);\n if (rec?.kind === 'command_output_delta') {\n const stream = rec.stream === 'stderr' ? 'stderr' : 'stdout';\n const delta = typeof rec.delta === 'string' ? rec.delta : '';\n if (delta) {\n events.push(this.make('command_output_delta', { messageId, toolCallId, stream, delta }));\n }\n }\n }\n return events;\n }\n\n private mapToolEnd(event: { [key: string]: unknown }): ChatStreamEvent[] {\n const toolCallId = String(event.toolCallId ?? '');\n if (!toolCallId) return [];\n const messageId = this.toolCallToMessageId.get(toolCallId) ?? this.ensureAssistantMessageId();\n const result = normalizeToolResult(event.result);\n const toolName = String(event.toolName ?? 'unknown');\n const events: ChatStreamEvent[] = [\n this.make('tool_end', {\n messageId,\n toolCallId,\n toolName,\n status: event.isError ? 'error' : 'success',\n result,\n errorMessage: event.isError ? result?.text : undefined,\n }),\n ];\n const details = asRecord(result?.details);\n if (toolName === 'exec_command' && details) {\n events.push(\n this.make('command_completed', {\n messageId,\n toolCallId,\n command: typeof details.command === 'string' ? details.command : '',\n cwd: typeof details.cwd === 'string' ? details.cwd : undefined,\n exitCode: typeof details.exitCode === 'number' ? details.exitCode : null,\n durationMs: typeof details.durationMs === 'number' ? details.durationMs : undefined,\n timedOut: details.timedOut === true,\n truncated: details.truncated === true,\n }),\n );\n }\n if (toolName === 'apply_patch' && details) {\n const changes = Array.isArray(details.changes) ? details.changes : [];\n const diff = typeof details.diff === 'string' ? details.diff : '';\n const added = typeof details.added === 'number' ? details.added : 0;\n const removed = typeof details.removed === 'number' ? details.removed : 0;\n if (diff || changes.length > 0) {\n this.recordPatchDiff(details);\n events.push(this.make('patch_applied', { messageId, toolCallId, changes, diff, added, removed }));\n }\n }\n if (toolName === 'update_plan' && details) {\n const plan = extractTurnPlan(details);\n if (plan) {\n events.push(this.make('turn_plan', { messageId, ...plan }));\n }\n }\n return events;\n }\n\n private ensureAssistantMessageId(): string {\n if (!this.currentAssistantMessageId) {\n this.currentAssistantMessageId = this.nextAssistantMessageId();\n }\n return this.currentAssistantMessageId;\n }\n\n private nextAssistantMessageId(): string {\n this.assistantIndex += 1;\n return `msg_${this.opts.runId.replace(/[^a-zA-Z0-9_-]/g, '_')}_${this.assistantIndex}`;\n }\n\n private make<T extends ChatStreamEvent['type']>(\n type: T,\n payload: Extract<ChatStreamEvent, { type: T }>['payload'],\n ): Extract<ChatStreamEvent, { type: T }> {\n return {\n type,\n runId: this.opts.runId,\n sessionKey: this.opts.sessionKey,\n timestamp: Date.now(),\n payload,\n } as Extract<ChatStreamEvent, { type: T }>;\n }\n\n private recordPatchDiff(details: Record<string, unknown>): void {\n const diff = typeof details.diff === 'string' ? details.diff : '';\n if (diff) this.turnDiffs.push(diff);\n if (typeof details.added === 'number') this.turnDiffAdded += details.added;\n if (typeof details.removed === 'number') this.turnDiffRemoved += details.removed;\n const changes = Array.isArray(details.changes) ? details.changes : [];\n for (const change of changes) {\n const rec = asRecord(change);\n const path = typeof rec?.moveTo === 'string'\n ? rec.moveTo\n : typeof rec?.path === 'string'\n ? rec.path\n : undefined;\n if (path) this.turnDiffFiles.add(path);\n }\n }\n}\n\nfunction userMessageFromLegacyEvent(event: { [key: string]: unknown }): unknown {\n return {\n role: 'user',\n content: event.content ?? [],\n attachments: event.media,\n timestamp: typeof event.timestamp === 'number' ? event.timestamp : Date.now(),\n };\n}\n\nfunction extractTextFromMessage(message: AgentMessage): string {\n return extractText((message as { content?: unknown }).content);\n}\n\nfunction extractReview(message: AgentMessage): unknown {\n const metadata = (message as { metadata?: unknown }).metadata;\n const metadataReview = asRecord(metadata)?.review;\n if (isReviewBlock(metadataReview)) return metadataReview;\n const content = (message as { content?: unknown }).content;\n if (Array.isArray(content)) {\n for (const block of content) {\n if (isReviewBlock(block)) return block;\n }\n }\n return undefined;\n}\n\nfunction isReviewBlock(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n && (value as { type?: unknown }).type === 'review';\n}\n\nfunction extractText(value: unknown): string | undefined {\n if (typeof value === 'string') return value;\n if (!Array.isArray(value)) return undefined;\n const text = value\n .map((block) => {\n if (!block || typeof block !== 'object') return '';\n const rec = block as { type?: unknown; text?: unknown };\n return rec.type === 'text' && typeof rec.text === 'string' ? rec.text : '';\n })\n .join('');\n return text || undefined;\n}\n\nfunction appendSuffix(base: string, next: string | undefined): string {\n if (!next) return '';\n if (!base) return next;\n if (next === base || base.endsWith(next)) return '';\n if (next.startsWith(base)) return next.slice(base.length);\n const max = Math.min(base.length, next.length, 512);\n for (let overlap = max; overlap > 0; overlap--) {\n if (base.slice(-overlap) === next.slice(0, overlap)) return next.slice(overlap);\n }\n return next;\n}\n\nfunction extractUsage(message: AgentMessage): AssistantMessageEndEventPayload['usage'] {\n const usage = (message as { usage?: unknown }).usage;\n if (!usage || typeof usage !== 'object') return undefined;\n const rec = usage as Record<string, unknown>;\n return {\n inputTokens: typeof rec.inputTokens === 'number' ? rec.inputTokens : undefined,\n outputTokens: typeof rec.outputTokens === 'number' ? rec.outputTokens : undefined,\n totalTokens: typeof rec.totalTokens === 'number' ? rec.totalTokens : undefined,\n cost: typeof rec.cost === 'number' ? rec.cost : undefined,\n };\n}\n\ntype AssistantMessageEndEventPayload = Extract<ChatStreamEvent, { type: 'assistant_message_end' }>['payload'];\n\nfunction extractDetails(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined;\n return (value as Record<string, unknown>).details;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction normalizeToolResult(value: unknown): ToolResultEnvelope | undefined {\n if (value == null) return undefined;\n if (typeof value === 'string') return { text: value };\n if (typeof value !== 'object') return { text: String(value) };\n const rec = value as Record<string, unknown>;\n return {\n content: Array.isArray(rec.content) ? rec.content : undefined,\n details: rec.details,\n text: extractText(rec.content) ?? (typeof rec.text === 'string' ? rec.text : undefined),\n };\n}\n\nfunction extractTurnPlan(details: Record<string, unknown>): { explanation?: string; plan: { step: string; status: 'pending' | 'in_progress' | 'completed' }[] } | undefined {\n const rawPlan = Array.isArray(details.plan) ? details.plan : [];\n const plan = rawPlan\n .map((item) => {\n const rec = asRecord(item);\n const step = typeof rec?.step === 'string' ? rec.step.trim() : '';\n const status = rec?.status;\n if (!step || (status !== 'pending' && status !== 'in_progress' && status !== 'completed')) {\n return undefined;\n }\n return { step, status };\n })\n .filter((item): item is { step: string; status: 'pending' | 'in_progress' | 'completed' } => Boolean(item));\n if (plan.length === 0) return undefined;\n const explanation = typeof details.explanation === 'string' && details.explanation.trim()\n ? details.explanation.trim()\n : undefined;\n return { explanation, plan };\n}\n"],"mappings":"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"}
@@ -120,6 +120,8 @@ export type ProgressEvent = ChatStreamEnvelope<'progress', {
120
120
  message: string;
121
121
  detail?: string;
122
122
  toolName?: string;
123
+ completed?: number;
124
+ total?: number;
123
125
  }>;
124
126
  export type CompactionEvent = ChatStreamEnvelope<'compaction', {
125
127
  status: 'started' | 'completed' | 'skipped';
@@ -170,7 +170,7 @@ async function buildSafeWebConfigPayload(service, options = {}) {
170
170
  channelConnectDeferSkipIds: Array.isArray(config.gateway?.channelConnectDeferSkipIds) ? config.gateway.channelConnectDeferSkipIds : [],
171
171
  share: resolveShareConfig(config.gateway?.share),
172
172
  publicUrl: config.gateway?.publicUrl ?? null,
173
- skillsMarketplaceProvider: config.gateway?.skillsMarketplaceProvider ?? "skillhub",
173
+ skillsMarketplaceProvider: config.gateway?.skillsMarketplaceProvider ?? "store",
174
174
  skillsStoreBaseUrl: config.gateway?.skillsStoreBaseUrl ?? "https://store.xopc.ai"
175
175
  },
176
176
  browser: buildSafeBrowserConfigForWeb(config.browser),
@@ -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 ?? 'skillhub',\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 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 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 tools: safeToolsWebForGet(config),\n bindings: Array.isArray(config.bindings) ? config.bindings : [],\n mcp: buildSafeMcpConfigForWeb(config),\n };\n}\n"],"mappings":"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"}
@@ -12,12 +12,12 @@ export interface AuthConfig {
12
12
  }
13
13
  /** Exported for gateway security tests. */
14
14
  export declare function isQueryTokenAllowedPath(path: string, method: string): boolean;
15
- export declare function auth(config?: AuthConfig): import("hono/dist/types/types.js").MiddlewareHandler<any, string, {}, (Response & import("hono/dist/types/types.js").TypedResponse<{
15
+ export declare function auth(config?: AuthConfig): import("hono").MiddlewareHandler<any, string, {}, (Response & import("hono").TypedResponse<{
16
16
  error: string;
17
17
  code: string;
18
18
  message: string;
19
19
  retryAfter: number;
20
- }, 429, "json">) | (Response & import("hono/dist/types/types.js").TypedResponse<{
20
+ }, 429, "json">) | (Response & import("hono").TypedResponse<{
21
21
  error: string;
22
22
  code: string;
23
23
  message: string;
@@ -2,4 +2,4 @@ export interface LoggerMiddlewareConfig {
2
2
  trustedProxies?: string[];
3
3
  allowRealIpFallback?: boolean;
4
4
  }
5
- export declare function logger(config?: LoggerMiddlewareConfig): import("hono/dist/types/types.js").MiddlewareHandler<any, string, {}, Response>;
5
+ export declare function logger(config?: LoggerMiddlewareConfig): import("hono").MiddlewareHandler<any, string, {}, Response>;
@@ -1,5 +1,5 @@
1
1
  import type { Context } from 'hono';
2
- export declare function routeErrorMiddleware(): import("hono/dist/types/types.js").MiddlewareHandler<any, string, {}, Response>;
2
+ export declare function routeErrorMiddleware(): import("hono").MiddlewareHandler<any, string, {}, Response>;
3
3
  export declare function registerGatewayOnError(app: {
4
4
  onError: (handler: (err: Error, c: Context) => Response | Promise<Response>) => void;
5
5
  }): void;
@@ -8,11 +8,11 @@ export type StrictRateLimitDeps = {
8
8
  allowRealIpFallback?: boolean;
9
9
  };
10
10
  };
11
- export declare function createStrictRateLimitMiddleware(deps: StrictRateLimitDeps): import("hono/dist/types/types.js").MiddlewareHandler<any, string, {}, Response & import("hono/dist/types/types.js").TypedResponse<{
11
+ export declare function createStrictRateLimitMiddleware(deps: StrictRateLimitDeps): import("hono").MiddlewareHandler<any, string, {}, Response & import("hono").TypedResponse<{
12
12
  error: string;
13
13
  code: string;
14
14
  }, 429, "json">>;
15
- export declare function createChannelRateLimitMiddleware(deps: StrictRateLimitDeps): import("hono/dist/types/types.js").MiddlewareHandler<any, string, {}, Response & import("hono/dist/types/types.js").TypedResponse<{
15
+ export declare function createChannelRateLimitMiddleware(deps: StrictRateLimitDeps): import("hono").MiddlewareHandler<any, string, {}, Response & import("hono").TypedResponse<{
16
16
  error: string;
17
17
  code: string;
18
18
  }, 429, "json">>;
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ export declare function registerCapabilityRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void;