@xopcai/xopc 0.0.302 → 0.0.306

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 (364) hide show
  1. package/README.md +4 -4
  2. package/README.zh-CN.md +4 -4
  3. package/dist/browser-ext/dist/assets/{auth-B_9ZuGDx.js → auth-C3yV1y_l.js} +67 -22
  4. package/dist/browser-ext/dist/background.js +4 -4
  5. package/dist/browser-ext/dist/sidepanel.html +1 -1
  6. package/dist/browser-ext/dist/sidepanel.js +3 -3
  7. package/dist/browser-ext/manifest.json +1 -1
  8. package/dist/extensions/feishu/xopc.extension.json +0 -3
  9. package/dist/extensions/telegram/xopc.extension.json +1 -4
  10. package/dist/extensions/weixin/xopc.extension.json +0 -3
  11. package/dist/gateway/static/root/assets/{activity-store-DCi5rh4e.js → activity-store-DLtim-_I.js} +1 -1
  12. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-C0zP6W2B.js → agent-avatar-dicebear-iQXtiilH.js} +1 -1
  13. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CxOv4ivK.js +1 -0
  14. package/dist/gateway/static/root/assets/agents-DzKx7z3k.js +1 -0
  15. package/dist/gateway/static/root/assets/{api-CAV9PN9i.js → api-DfSU0-lD.js} +1 -1
  16. package/dist/gateway/static/root/assets/api-gpHh07OL.js +1 -0
  17. package/dist/gateway/static/root/assets/app-management-settings-panel-BpYFKz7B.js +1 -0
  18. package/dist/gateway/static/root/assets/{appearance-settings-ZFjV_opr.js → appearance-settings-BQfR5vrq.js} +1 -1
  19. package/dist/gateway/static/root/assets/apps-page-BceB7JHZ.js +1 -0
  20. package/dist/gateway/static/root/assets/{archive-plugin-MaKWrpgC.js → archive-plugin-BxOvZ-ZX.js} +1 -1
  21. package/dist/gateway/static/root/assets/{attachment-load-IfqbP2BN.js → attachment-load-B0FzTMAJ.js} +1 -1
  22. package/dist/gateway/static/root/assets/{automations-page-CeI2NGSO.js → automations-page-BpXuPaPg.js} +1 -1
  23. package/dist/gateway/static/root/assets/automations-workspace-Cn_p8zY_.js +6 -0
  24. package/dist/gateway/static/root/assets/{binary-plugins-jvQ6FaBZ.js → binary-plugins-BP7wfpqy.js} +1 -1
  25. package/dist/gateway/static/root/assets/{block-editor-D4ZIVQbk.css → block-editor-BdOTO0Yo.css} +1 -1
  26. package/dist/gateway/static/root/assets/{block-editor-B7U3qlB3.js → block-editor-oMLvdnOQ.js} +3 -3
  27. package/dist/gateway/static/root/assets/{browser-automation-inputs-BGT0xoTv.js → browser-automation-inputs-DTxSZ00u.js} +1 -1
  28. package/dist/gateway/static/root/assets/{browser-automations-page-DvLAwoiQ.js → browser-automations-page-IbJnwEY4.js} +2 -2
  29. package/dist/gateway/static/root/assets/browser-settings-page-CCUO3G23.js +3 -0
  30. package/dist/gateway/static/root/assets/button-CS04eWY9.js +1 -0
  31. package/dist/gateway/static/root/assets/capabilities-settings-panel-BjMb5H2_.js +8 -0
  32. package/dist/gateway/static/root/assets/channels-settings-P22-_i13.js +1 -0
  33. package/dist/gateway/static/root/assets/{channels-status-swr-C_icwbWj.js → channels-status-swr-D2AmAoty.js} +1 -1
  34. package/dist/gateway/static/root/assets/{chat-terminal-dock-BtL71IOs.js → chat-terminal-dock-B-yI3Mi1.js} +2 -2
  35. package/dist/gateway/static/root/assets/{computer-settings-page-Bu6ZJtmS.js → computer-settings-page-CWx_jnng.js} +1 -1
  36. package/dist/gateway/static/root/assets/connectors-page-BLgPORmH.js +2 -0
  37. package/dist/gateway/static/root/assets/cron-expression-DMRRL4Zg.js +2 -0
  38. package/dist/gateway/static/root/assets/date-picker-BSwL0e6E.js +1 -0
  39. package/dist/gateway/static/root/assets/{dependency-picker-BNugauiZ.js → dependency-picker-BQTspLzC.js} +1 -1
  40. package/dist/gateway/static/root/assets/{desktop-pet-DTy_3-OY.js → desktop-pet-C3lFxDF6.js} +1 -1
  41. package/dist/gateway/static/root/assets/desktop-pet-settings-Y8pjpXFE.js +1 -0
  42. package/dist/gateway/static/root/assets/device-pairing-wizard-DM4_GMzo.js +1 -0
  43. package/dist/gateway/static/root/assets/{extension-debug-page-C3F7RiGW.js → extension-debug-page-CVGiGVcR.js} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-page-C0jhcCT_.js → extension-page-g3JtCP_y.js} +1 -1
  45. package/dist/gateway/static/root/assets/{extension-settings-page-CNvJQkrr.js → extension-settings-page-CjpoKV1f.js} +1 -1
  46. package/dist/gateway/static/root/assets/{gateway-config-swr-D5AM8cyQ.js → gateway-config-swr-BSvXXpKM.js} +1 -1
  47. package/dist/gateway/static/root/assets/gateway-realtime-BDCpS7U1.js +1 -0
  48. package/dist/gateway/static/root/assets/gateway-realtime-store-BGmP1obI.js +1 -0
  49. package/dist/gateway/static/root/assets/gateway-settings-CYG9WCZn.js +1 -0
  50. package/dist/gateway/static/root/assets/{gateway-startup-retry-CSJWdnFs.js → gateway-startup-retry-Caf8g3sC.js} +1 -1
  51. package/dist/gateway/static/root/assets/{heartbeat-settings-Cd1VJsHe.js → heartbeat-settings-Cl834-SS.js} +1 -1
  52. package/dist/gateway/static/root/assets/home-page-CB_XVtIM.js +1 -0
  53. package/dist/gateway/static/root/assets/{image-generation-api-BNh604hw.js → image-generation-api-BwEWBUVC.js} +1 -1
  54. package/dist/gateway/static/root/assets/imports-page-CoMlgSIA.js +1 -0
  55. package/dist/gateway/static/root/assets/index-CI37dTAn.css +1 -0
  56. package/dist/gateway/static/root/assets/index-Do9MltC4.js +79 -0
  57. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CNq5D4pe.js +1 -0
  58. package/dist/gateway/static/root/assets/local-app-workbench-page-BxQlEje6.js +2 -0
  59. package/dist/gateway/static/root/assets/{local-apps-page-DyrFxW3G.js → local-apps-page-DQnRA598.js} +1 -1
  60. package/dist/gateway/static/root/assets/{locale-store-DLK05Y1a.js → locale-store-D16nmbaN.js} +1 -1
  61. package/dist/gateway/static/root/assets/logs-page-CT5GrcMs.js +2 -0
  62. package/dist/gateway/static/root/assets/management-settings-DKcO5fQ-.js +1 -0
  63. package/dist/gateway/static/root/assets/{markdown-view-B8maDRWh.js → markdown-view-DCp4BlZP.js} +2 -2
  64. package/dist/gateway/static/root/assets/{media-plugins-5DakFba_.js → media-plugins-Cy64sn_C.js} +1 -1
  65. package/dist/gateway/static/root/assets/messages-C-9oo69N.js +3 -0
  66. package/dist/gateway/static/root/assets/note-detail-panel-5dc3LKTL.js +5 -0
  67. package/dist/gateway/static/root/assets/notes-page-AbwxgXuG.js +8 -0
  68. package/dist/gateway/static/root/assets/{page-tabs-DzJpglJJ.js → page-tabs-CgEoHSVT.js} +1 -1
  69. package/dist/gateway/static/root/assets/{popover-select-DldSX8GX.js → popover-select-9i-ZtHXL.js} +1 -1
  70. package/dist/gateway/static/root/assets/{preview-open-alternatives-Dj6LJsuQ.js → preview-open-alternatives-Ck2uKTbf.js} +1 -1
  71. package/dist/gateway/static/root/assets/{proactive-page-CwudBdrQ.js → proactive-page-Dr1mCJhZ.js} +1 -1
  72. package/dist/gateway/static/root/assets/{product-open-page-CujZXOea.js → product-open-page-DbZvJ5GE.js} +1 -1
  73. package/dist/gateway/static/root/assets/project-detail-page-DnE1zI1c.js +1 -0
  74. package/dist/gateway/static/root/assets/projects-page-BD0nLYxk.js +1 -0
  75. package/dist/gateway/static/root/assets/{registry-api-BMFL4vis.js → registry-api-DcQdwpPu.js} +1 -1
  76. package/dist/gateway/static/root/assets/remote-access-hub-TYuE6A3S.js +1 -0
  77. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DV554qyN.js → runtime-tools-settings-panel-CPwdgWKo.js} +2 -2
  78. package/dist/gateway/static/root/assets/{schema-form-Bh2Er67B.js → schema-form-8psK4cFO.js} +1 -1
  79. package/dist/gateway/static/root/assets/sessions-page-BcWDQQFX.js +1 -0
  80. package/dist/gateway/static/root/assets/settings-advanced-gate-DzGQX6Hq.js +1 -0
  81. package/dist/gateway/static/root/assets/{settings-form-section-BsdM7P1d.js → settings-form-section-D_Gsz5rl.js} +1 -1
  82. package/dist/gateway/static/root/assets/{settings-page-3yEAqoME.js → settings-page-C_Tj_mkZ.js} +1 -1
  83. package/dist/gateway/static/root/assets/setup-status-panel-CE2X89qN.js +1 -0
  84. package/dist/gateway/static/root/assets/share-preview-page-B_M_oPsT.js +2 -0
  85. package/dist/gateway/static/root/assets/shares-settings-BL4H9Iym.js +1 -0
  86. package/dist/gateway/static/root/assets/skill-reload-api-WMKIgUOp.js +1 -0
  87. package/dist/gateway/static/root/assets/skills-page-DYgwzl5B.js +2 -0
  88. package/dist/gateway/static/root/assets/{skills-page.utils-dHBD7YqU.js → skills-page.utils-Cuh6s2HM.js} +1 -1
  89. package/dist/gateway/static/root/assets/{system-settings-panel-lItR5Kah.js → system-settings-panel-aassGyNb.js} +1 -1
  90. package/dist/gateway/static/root/assets/task-detail-page-BjeRslap.js +1 -0
  91. package/dist/gateway/static/root/assets/theme-store-RUBQBsFP.js +1 -0
  92. package/dist/gateway/static/root/assets/tunnel-api-DJYcPWIV.js +1 -0
  93. package/dist/gateway/static/root/assets/{use-autosave-DO50_g_S.js → use-autosave-QGYG7oMZ.js} +1 -1
  94. package/dist/gateway/static/root/assets/user-model-page-PrRsd4go.js +2 -0
  95. package/dist/gateway/static/root/assets/{voice-api-key-field-k7tWLXzM.js → voice-api-key-field-D1s0gIRW.js} +1 -1
  96. package/dist/gateway/static/root/assets/{voice-config-api-bZqN8-UF.js → voice-config-api-D2goEn5e.js} +1 -1
  97. package/dist/gateway/static/root/assets/{work-discovery-overlay-BHI6gO_u.js → work-discovery-overlay-DkFW9aJ6.js} +1 -1
  98. package/dist/gateway/static/root/assets/workflow-run-setup-panel-BYToUPUY.js +3 -0
  99. package/dist/gateway/static/root/assets/workflows-page-Z8iZe9YP.js +6 -0
  100. package/dist/gateway/static/root/index.html +14 -12
  101. package/dist/package.js +1 -1
  102. package/dist/packages/gateway-contract/src/device-pairing.js +100 -7
  103. package/dist/packages/gateway-contract/src/gateway-scopes.js +53 -0
  104. package/dist/packages/gateway-contract/src/index.js +2 -0
  105. package/dist/packages/realtime-client/src/index.js +14 -2
  106. package/dist/packages/realtime-protocol/src/index.js +18 -14
  107. package/dist/src/agent/agent-instance-gateway.d.ts +2 -0
  108. package/dist/src/agent/agent-manager.d.ts +2 -0
  109. package/dist/src/agent/agent-manager.js +40 -12
  110. package/dist/src/agent/agent-scope.d.ts +4 -1
  111. package/dist/src/agent/agent-scope.js +19 -3
  112. package/dist/src/agent/commands/command-isolation.js +11 -9
  113. package/dist/src/agent/commands/command-registry.js +18 -33
  114. package/dist/src/agent/context/audit.js +12 -2
  115. package/dist/src/agent/context/coordinator.d.ts +13 -3
  116. package/dist/src/agent/context/coordinator.js +27 -11
  117. package/dist/src/agent/context/execution-context.js +42 -22
  118. package/dist/src/agent/context/execution-context.types.d.ts +4 -2
  119. package/dist/src/agent/context/execution-scope.d.ts +2 -2
  120. package/dist/src/agent/context/execution-scope.js +1 -1
  121. package/dist/src/agent/context/project-context.d.ts +2 -2
  122. package/dist/src/agent/context/project-context.js +3 -3
  123. package/dist/src/agent/embedded/run-for-session.d.ts +1 -0
  124. package/dist/src/agent/embedded/run-for-session.js +7 -1
  125. package/dist/src/agent/inbound/attachment-pipeline.d.ts +2 -0
  126. package/dist/src/agent/inbound/attachment-pipeline.js +3 -3
  127. package/dist/src/agent/inbound/inbound-loop.js +1 -0
  128. package/dist/src/agent/inbound/turn-dispatcher.js +3 -3
  129. package/dist/src/agent/mcp/mcp-stdio-transport.js +5 -2
  130. package/dist/src/agent/memory/compaction-promotion.js +7 -2
  131. package/dist/src/agent/memory/create-memory-manager.js +1 -0
  132. package/dist/src/agent/memory/manager.d.ts +6 -0
  133. package/dist/src/agent/memory/manager.js +74 -39
  134. package/dist/src/agent/memory/runtime.d.ts +3 -3
  135. package/dist/src/agent/memory/runtime.js +11 -4
  136. package/dist/src/agent/orchestration/agent-orchestrator.js +4 -1
  137. package/dist/src/agent/prompt/cache-boundary.d.ts +2 -0
  138. package/dist/src/agent/prompt/cache-boundary.js +10 -1
  139. package/dist/src/agent/service/build-direct-message-content.d.ts +1 -0
  140. package/dist/src/agent/service/build-direct-message-content.js +2 -1
  141. package/dist/src/agent/service/direct-turn-helpers.js +3 -2
  142. package/dist/src/agent/service/process-direct-streaming.d.ts +3 -1
  143. package/dist/src/agent/service/process-direct-streaming.js +3 -2
  144. package/dist/src/agent/service/webchat-tts.d.ts +0 -4
  145. package/dist/src/agent/service/webchat-tts.js +20 -19
  146. package/dist/src/agent/tools/factory.js +3 -3
  147. package/dist/src/agent/tools/knowledge-memory-tool.d.ts +2 -2
  148. package/dist/src/agent/tools/knowledge-memory-tool.js +7 -7
  149. package/dist/src/browser/native-messaging-host.js +2 -2
  150. package/dist/src/channels/attachments/voice-stt-webchat.d.ts +3 -0
  151. package/dist/src/channels/attachments/voice-stt-webchat.js +22 -9
  152. package/dist/src/cli/commands/agent.js +2 -0
  153. package/dist/src/cli/commands/config.js +8 -9
  154. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  155. package/dist/src/cli/commands/extension-marketplace.js +69 -44
  156. package/dist/src/cli/commands/extension-pack.js +0 -2
  157. package/dist/src/cli/commands/extension.js +4 -25
  158. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  159. package/dist/src/cli/commands/onboard/gateway.js +2 -1
  160. package/dist/src/cli/commands/update.js +1 -1
  161. package/dist/src/cli/utils/init-workspace-core.js +5 -2
  162. package/dist/src/config/index.js +2 -2
  163. package/dist/src/config/loader.d.ts +1 -0
  164. package/dist/src/config/loader.js +14 -1
  165. package/dist/src/config/schema.d.ts +10 -3
  166. package/dist/src/config/schema.js +10 -2
  167. package/dist/src/execution-environments/local-worktree-manager.js +17 -15
  168. package/dist/src/execution-environments/store.js +4 -2
  169. package/dist/src/execution-environments/types.d.ts +3 -0
  170. package/dist/src/execution-environments/types.js +2 -1
  171. package/dist/src/execution-environments/worktree-safety.d.ts +8 -0
  172. package/dist/src/execution-environments/worktree-safety.js +43 -0
  173. package/dist/src/extensions/activation-planner.d.ts +1 -1
  174. package/dist/src/extensions/activation-planner.js +1 -1
  175. package/dist/src/extensions/api-version.d.ts +4 -0
  176. package/dist/src/extensions/api-version.js +15 -0
  177. package/dist/src/extensions/api.d.ts +3 -9
  178. package/dist/src/extensions/api.js +26 -32
  179. package/dist/src/extensions/config-validation.d.ts +8 -0
  180. package/dist/src/extensions/config-validation.js +25 -0
  181. package/dist/src/extensions/extension-registry-impl.d.ts +20 -9
  182. package/dist/src/extensions/extension-registry-impl.js +79 -11
  183. package/dist/src/extensions/hooks.d.ts +1 -1
  184. package/dist/src/extensions/index.d.ts +2 -1
  185. package/dist/src/extensions/install-transaction.d.ts +2 -0
  186. package/dist/src/extensions/install-transaction.js +32 -21
  187. package/dist/src/extensions/install.js +18 -1
  188. package/dist/src/extensions/loader.d.ts +5 -5
  189. package/dist/src/extensions/loader.js +109 -47
  190. package/dist/src/extensions/lockfile.d.ts +3 -5
  191. package/dist/src/extensions/lockfile.js +41 -14
  192. package/dist/src/extensions/normalize-manifest.js +6 -60
  193. package/dist/src/extensions/sdk/index.d.ts +3 -2
  194. package/dist/src/extensions/sdk/index.js +2 -2
  195. package/dist/src/extensions/sdk/testing.js +0 -4
  196. package/dist/src/extensions/security.js +5 -7
  197. package/dist/src/extensions/types/core.d.ts +0 -5
  198. package/dist/src/extensions/types/index.d.ts +1 -1
  199. package/dist/src/extensions/types/manifest.d.ts +1 -25
  200. package/dist/src/extensions/types/providers.d.ts +1 -1
  201. package/dist/src/extensions/types/registration.d.ts +0 -12
  202. package/dist/src/extensions/update.js +71 -30
  203. package/dist/src/gateway/heartbeat/service.js +2 -2
  204. package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -1
  205. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +47 -10
  206. package/dist/src/gateway/hono/routes/devices.js +10 -7
  207. package/dist/src/gateway/hono/routes/endpoint-compatibility.js +6 -0
  208. package/dist/src/gateway/hono/routes/extension-gateway.js +0 -33
  209. package/dist/src/gateway/hono/routes/imports.js +1 -1
  210. package/dist/src/gateway/hono/routes/lazy-bundles.js +0 -1
  211. package/dist/src/gateway/hono/routes/local-apps.js +1 -1
  212. package/dist/src/gateway/hono/routes/realtime.js +30 -8
  213. package/dist/src/gateway/hono/routes/update.js +2 -2
  214. package/dist/src/gateway/hono/routes/user-model.js +25 -6
  215. package/dist/src/gateway/index.js +5 -2
  216. package/dist/src/gateway/lock.d.ts +2 -0
  217. package/dist/src/gateway/lock.js +31 -14
  218. package/dist/src/gateway/run-loop.js +3 -2
  219. package/dist/src/gateway/security/gateway-scopes.d.ts +2 -5
  220. package/dist/src/gateway/security/gateway-scopes.js +3 -45
  221. package/dist/src/gateway/security/index.js +2 -1
  222. package/dist/src/gateway/service/config-coordinator.js +1 -1
  223. package/dist/src/gateway/service.js +11 -7
  224. package/dist/src/heartbeat/index.js +1 -1
  225. package/dist/src/imports/importService.d.ts +1 -1
  226. package/dist/src/imports/inventory.js +16 -2
  227. package/dist/src/imports/productImport.js +5 -5
  228. package/dist/src/imports/types.d.ts +3 -3
  229. package/dist/src/infra/exec.d.ts +2 -2
  230. package/dist/src/infra/exec.js +32 -27
  231. package/dist/src/infra/gateway-processes.js +1 -1
  232. package/dist/src/infra/run-command.js +15 -50
  233. package/dist/src/infra/update-restart.js +1 -1
  234. package/dist/src/infra/update-runner.js +2 -2
  235. package/dist/src/infra/update-startup.js +1 -1
  236. package/dist/src/knowledge/connected-knowledge-pipeline.js +13 -3
  237. package/dist/src/knowledge-memory/domain.d.ts +17 -1
  238. package/dist/src/knowledge-memory/index.js +2 -2
  239. package/dist/src/knowledge-memory/repository.d.ts +26 -4
  240. package/dist/src/knowledge-memory/repository.js +171 -36
  241. package/dist/src/mcp/channel-bridge.js +7 -3
  242. package/dist/src/media-understanding/registry.js +6 -1
  243. package/dist/src/migrations/knowledge-memory-read-policy-config.d.ts +2 -0
  244. package/dist/src/migrations/knowledge-memory-read-policy-config.js +48 -0
  245. package/dist/src/migrations/runner.js +2 -1
  246. package/dist/src/process/bounded-output.d.ts +10 -0
  247. package/dist/src/process/bounded-output.js +41 -0
  248. package/dist/src/process/kill-tree.d.ts +6 -17
  249. package/dist/src/process/kill-tree.js +43 -75
  250. package/dist/src/process/process-spec.d.ts +39 -0
  251. package/dist/src/process/process-spec.js +13 -0
  252. package/dist/src/process/run-process.d.ts +4 -0
  253. package/dist/src/process/run-process.js +97 -0
  254. package/dist/src/providers/plugin-registry.d.ts +1 -1
  255. package/dist/src/providers/plugin-registry.js +6 -0
  256. package/dist/src/realtime/runtime.js +3 -1
  257. package/dist/src/session/store.js +1 -1
  258. package/dist/src/storage/sqlite/device-pairing-approval.js +1 -1
  259. package/dist/src/storage/sqlite/index.d.ts +1 -1
  260. package/dist/src/storage/sqlite/index.js +2 -2
  261. package/dist/src/storage/sqlite/migrations/180_execution_environment_ownership.sql +7 -0
  262. package/dist/src/storage/sqlite/migrations/181_knowledge_item_status_events.sql +12 -0
  263. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  264. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  265. package/dist/src/storage/sqlite/schema.js +1 -1
  266. package/dist/src/storage/sqlite/schema.sql +13 -0
  267. package/dist/src/storage/sqlite/transcript-repository.d.ts +4 -0
  268. package/dist/src/storage/sqlite/transcript-repository.js +36 -1
  269. package/dist/src/tui/backends/embedded-backend.d.ts +24 -8
  270. package/dist/src/tui/backends/embedded-backend.js +114 -10
  271. package/dist/src/tui/backends/gateway-realtime-backend.d.ts +18 -0
  272. package/dist/src/tui/backends/gateway-realtime-backend.js +32 -5
  273. package/dist/src/tui/components/assistant-message.d.ts +4 -1
  274. package/dist/src/tui/components/assistant-message.js +10 -2
  275. package/dist/src/tui/components/cell-render-mode.d.ts +4 -0
  276. package/dist/src/tui/components/cell-render-mode.js +1 -0
  277. package/dist/src/tui/components/chat-log.d.ts +17 -4
  278. package/dist/src/tui/components/chat-log.js +68 -50
  279. package/dist/src/tui/components/custom-editor.d.ts +2 -2
  280. package/dist/src/tui/components/custom-editor.js +5 -1
  281. package/dist/src/tui/components/pending-input-preview.d.ts +9 -0
  282. package/dist/src/tui/components/pending-input-preview.js +33 -0
  283. package/dist/src/tui/components/semantic-cell.d.ts +17 -0
  284. package/dist/src/tui/components/semantic-cell.js +29 -0
  285. package/dist/src/tui/components/tool-execution.d.ts +5 -1
  286. package/dist/src/tui/components/tool-execution.js +33 -10
  287. package/dist/src/tui/components/transcript-overlay.d.ts +29 -0
  288. package/dist/src/tui/components/transcript-overlay.js +114 -0
  289. package/dist/src/tui/components/tui-bottom-bar.js +3 -1
  290. package/dist/src/tui/components/user-message.d.ts +5 -1
  291. package/dist/src/tui/components/user-message.js +12 -1
  292. package/dist/src/tui/extension-host/load-extensions.d.ts +1 -1
  293. package/dist/src/tui/extension-host/runtime-context.js +2 -1
  294. package/dist/src/tui/extension-host/runtime.d.ts +1 -1
  295. package/dist/src/tui/format-tui-hotkeys.js +8 -1
  296. package/dist/src/tui/tui-agent-events.js +31 -0
  297. package/dist/src/tui/tui-backend.d.ts +23 -11
  298. package/dist/src/tui/tui-backend.js +1 -9
  299. package/dist/src/tui/tui-chat-input-state.d.ts +25 -0
  300. package/dist/src/tui/tui-chat-input-state.js +36 -0
  301. package/dist/src/tui/tui-command-formatters.js +2 -1
  302. package/dist/src/tui/tui-commands.js +1 -1
  303. package/dist/src/tui/tui-types.d.ts +2 -1
  304. package/dist/src/tui/tui-types.js +2 -1
  305. package/dist/src/tui/tui.js +122 -30
  306. package/dist/src/tui/xopc-tui-keybindings.d.ts +23 -3
  307. package/dist/src/tui/xopc-tui-keybindings.js +22 -2
  308. package/dist/src/user-context/access-policy.d.ts +2 -2
  309. package/dist/src/user-context/access-policy.js +10 -2
  310. package/dist/src/user-context/config.d.ts +23 -6
  311. package/dist/src/user-context/config.js +54 -7
  312. package/dist/src/voice/platform-streams.js +11 -1
  313. package/dist/src/voice/realtime/omniEngine.js +13 -1
  314. package/dist/src/voice/realtime/runtime.js +2 -1
  315. package/dist/src/voice/tts/audio.js +1 -1
  316. package/dist/src/voice/tts/speech-registry.js +6 -1
  317. package/package.json +9 -7
  318. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-D0ITeUFb.js +0 -1
  319. package/dist/gateway/static/root/assets/agents-DcfWhk2S.js +0 -1
  320. package/dist/gateway/static/root/assets/api-fPapljyb.js +0 -1
  321. package/dist/gateway/static/root/assets/app-management-settings-panel-U3yDRzKF.js +0 -1
  322. package/dist/gateway/static/root/assets/apps-page-FgMHY1Pr.js +0 -1
  323. package/dist/gateway/static/root/assets/automations-workspace-DxaiBwrD.js +0 -6
  324. package/dist/gateway/static/root/assets/browser-settings-page-CHrfg3BX.js +0 -3
  325. package/dist/gateway/static/root/assets/button-CGlRPNzi.js +0 -1
  326. package/dist/gateway/static/root/assets/capabilities-settings-panel-DpYDPk_o.js +0 -8
  327. package/dist/gateway/static/root/assets/channels-settings-DMq-NBUQ.js +0 -1
  328. package/dist/gateway/static/root/assets/connectors-page-LsEiI9L5.js +0 -2
  329. package/dist/gateway/static/root/assets/cron-expression-B25FHn4w.js +0 -2
  330. package/dist/gateway/static/root/assets/date-picker-CzVHO7z9.js +0 -1
  331. package/dist/gateway/static/root/assets/desktop-pet-settings-CXfnejTb.js +0 -1
  332. package/dist/gateway/static/root/assets/device-pairing-wizard-CxKwfncn.js +0 -1
  333. package/dist/gateway/static/root/assets/gateway-settings-CQTcIvlZ.js +0 -1
  334. package/dist/gateway/static/root/assets/home-page-B_uyfCGq.js +0 -1
  335. package/dist/gateway/static/root/assets/imports-page-DXNfRmk9.js +0 -1
  336. package/dist/gateway/static/root/assets/index-BAqVpc1H.css +0 -1
  337. package/dist/gateway/static/root/assets/index-hlU8MUEz.js +0 -79
  338. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CgW5_XVP.js +0 -1
  339. package/dist/gateway/static/root/assets/local-app-workbench-page-C4h3qDRL.js +0 -2
  340. package/dist/gateway/static/root/assets/logs-page-Goy_QHfL.js +0 -2
  341. package/dist/gateway/static/root/assets/management-settings-DgQyGEpR.js +0 -1
  342. package/dist/gateway/static/root/assets/messages-C9h8SImu.js +0 -3
  343. package/dist/gateway/static/root/assets/note-detail-panel-lcZby9NY.js +0 -5
  344. package/dist/gateway/static/root/assets/notes-page-CDGPPI-W.js +0 -8
  345. package/dist/gateway/static/root/assets/project-detail-page-CyAf_sK-.js +0 -1
  346. package/dist/gateway/static/root/assets/projects-page-BW5m_HhZ.js +0 -1
  347. package/dist/gateway/static/root/assets/remote-access-hub-B4JgwB0s.js +0 -1
  348. package/dist/gateway/static/root/assets/sessions-page-D5SmvlQ1.js +0 -1
  349. package/dist/gateway/static/root/assets/settings-advanced-gate-DDALROy_.js +0 -1
  350. package/dist/gateway/static/root/assets/setup-status-panel-BOHNZ-S3.js +0 -1
  351. package/dist/gateway/static/root/assets/share-preview-page-wV056nz2.js +0 -2
  352. package/dist/gateway/static/root/assets/shares-settings-io4NzfJL.js +0 -1
  353. package/dist/gateway/static/root/assets/skill-reload-api-CERFaxLj.js +0 -1
  354. package/dist/gateway/static/root/assets/skills-page-CtwUqvsE.js +0 -2
  355. package/dist/gateway/static/root/assets/task-detail-page-CCKc67a-.js +0 -1
  356. package/dist/gateway/static/root/assets/theme-store-KfFEGMlp.js +0 -1
  357. package/dist/gateway/static/root/assets/tunnel-api-DPyLgmWw.js +0 -1
  358. package/dist/gateway/static/root/assets/user-model-page-CcnGgH1n.js +0 -2
  359. package/dist/gateway/static/root/assets/workflow-run-setup-panel-jEMtNIG8.js +0 -3
  360. package/dist/gateway/static/root/assets/workflows-page-CX4bcAD-.js +0 -6
  361. package/dist/src/extensions/when-context.d.ts +0 -6
  362. package/dist/src/extensions/when-context.js +0 -26
  363. package/dist/src/extensions/when-expression.d.ts +0 -11
  364. package/dist/src/extensions/when-expression.js +0 -213
@@ -3,8 +3,9 @@ import { init_logger } from "../utils/logger.js";
3
3
  import { ExecutionEnvironmentConflictError } from "./types.js";
4
4
  import { ExecutionEnvironmentStore } from "./store.js";
5
5
  import { findGitWorktree, inspectGitRepository, resolveGitCommit, runGit } from "./git.js";
6
- import { resolveExecutionWorktreesRoot, resolveManagedWorktreePath } from "./paths.js";
7
- import { dirname, relative, resolve } from "node:path";
6
+ import { resolveManagedWorktreePath } from "./paths.js";
7
+ import { assertManagedWorktreePath, assertNoNestedRegisteredWorktrees, readDirectoryIdentity, sameDirectoryIdentity } from "./worktree-safety.js";
8
+ import { dirname, resolve } from "node:path";
8
9
  import { existsSync } from "node:fs";
9
10
  import { randomUUID } from "node:crypto";
10
11
  import { mkdir, rm, stat } from "node:fs/promises";
@@ -40,12 +41,6 @@ async function isDirectory(path) {
40
41
  return false;
41
42
  }
42
43
  }
43
- function assertManagedPath(rootPath, stateDir) {
44
- const managedRoot = resolveExecutionWorktreesRoot(stateDir);
45
- const candidate = resolve(rootPath);
46
- const child = relative(managedRoot, candidate);
47
- if (!child || child.startsWith("..") || resolve(managedRoot, child) !== candidate) throw new Error(`Refusing to manage worktree outside ${managedRoot}`);
48
- }
49
44
  var LocalWorktreeManager = class {
50
45
  store;
51
46
  stateDir;
@@ -89,7 +84,7 @@ var LocalWorktreeManager = class {
89
84
  const baseSha = await resolveGitCommit(repository.repositoryRoot, baseRef);
90
85
  const environmentId = input.environmentId?.trim() || randomUUID();
91
86
  const rootPath = resolveManagedWorktreePath(input.projectId, environmentId, this.stateDir);
92
- assertManagedPath(rootPath, this.stateDir);
87
+ assertManagedWorktreePath(rootPath, this.stateDir, repository.repositoryRoot);
93
88
  if (existsSync(rootPath)) throw new ExecutionEnvironmentConflictError(`Worktree path already exists: ${rootPath}`);
94
89
  const environment = this.store.create({
95
90
  id: environmentId,
@@ -107,12 +102,15 @@ var LocalWorktreeManager = class {
107
102
  toStatus: "provisioning",
108
103
  reason: "managed worktree provisioning started"
109
104
  });
105
+ let createdDirectory;
110
106
  try {
111
107
  await withRepositoryLock(repository.gitCommonDir, async () => {
112
108
  await mkdir(dirname(rootPath), {
113
109
  recursive: true,
114
110
  mode: 448
115
111
  });
112
+ await mkdir(rootPath, { mode: 448 });
113
+ createdDirectory = await readDirectoryIdentity(rootPath);
116
114
  await runGit(repository.repositoryRoot, [
117
115
  "worktree",
118
116
  "add",
@@ -137,7 +135,7 @@ var LocalWorktreeManager = class {
137
135
  }, "Managed worktree ready");
138
136
  return ready;
139
137
  } catch (error) {
140
- await this.cleanupFailedProvision(repository.repositoryRoot, repository.gitCommonDir, rootPath);
138
+ await this.cleanupFailedProvision(repository.repositoryRoot, repository.gitCommonDir, rootPath, createdDirectory);
141
139
  const failed = this.store.transition({
142
140
  environmentId: environment.id,
143
141
  expectedVersion: provisioning.version,
@@ -235,7 +233,8 @@ var LocalWorktreeManager = class {
235
233
  return deleted;
236
234
  }
237
235
  if (environment.kind !== "managed_worktree" || !environment.repositoryRoot || !environment.gitCommonDir) throw new Error(`Execution environment ${environmentId} is not a managed worktree`);
238
- assertManagedPath(environment.rootPath, this.stateDir);
236
+ if (environment.ownership !== "xopc_created") throw new ExecutionEnvironmentConflictError(`Managed worktree ${environmentId} is not owned by xopc`);
237
+ assertManagedWorktreePath(environment.rootPath, this.stateDir, environment.repositoryRoot);
239
238
  if (this.store.listBindings(environmentId).some((binding) => binding.conversationId !== options?.releaseConversationId)) throw new ExecutionEnvironmentConflictError(`Managed worktree ${environmentId} still has active bindings`);
240
239
  const deleting = environment.status === "deleting" ? environment : this.store.transition({
241
240
  environmentId,
@@ -245,6 +244,8 @@ var LocalWorktreeManager = class {
245
244
  });
246
245
  try {
247
246
  await withRepositoryLock(environment.gitCommonDir, async () => {
247
+ await readDirectoryIdentity(environment.rootPath);
248
+ await assertNoNestedRegisteredWorktrees(environment.repositoryRoot, environment.rootPath);
248
249
  const registered = await findGitWorktree(environment.repositoryRoot, environment.rootPath);
249
250
  if (!registered && existsSync(environment.rootPath)) throw new ExecutionEnvironmentConflictError("Refusing to delete a directory no longer registered as this worktree");
250
251
  if (registered) {
@@ -301,7 +302,7 @@ var LocalWorktreeManager = class {
301
302
  throw error;
302
303
  }
303
304
  }
304
- async cleanupFailedProvision(repositoryRoot, gitCommonDir, rootPath) {
305
+ async cleanupFailedProvision(repositoryRoot, gitCommonDir, rootPath, createdDirectory) {
305
306
  await withRepositoryLock(gitCommonDir, async () => {
306
307
  if (await findGitWorktree(repositoryRoot, rootPath).catch(() => void 0)) {
307
308
  await runGit(repositoryRoot, [
@@ -309,14 +310,15 @@ var LocalWorktreeManager = class {
309
310
  "unlock",
310
311
  rootPath
311
312
  ]).catch(() => "");
312
- await runGit(repositoryRoot, [
313
+ if (!await runGit(repositoryRoot, [
313
314
  "worktree",
314
315
  "remove",
315
316
  "--force",
316
317
  rootPath
317
- ]).catch(() => "");
318
+ ]).then(() => true, () => false) || await findGitWorktree(repositoryRoot, rootPath).catch(() => void 0)) return;
318
319
  }
319
- if (existsSync(rootPath)) await rm(rootPath, {
320
+ const currentDirectory = await readDirectoryIdentity(rootPath);
321
+ if (createdDirectory && sameDirectoryIdentity(createdDirectory, currentDirectory)) await rm(rootPath, {
320
322
  recursive: true,
321
323
  force: true
322
324
  });
@@ -17,6 +17,7 @@ function environmentFromRow(row) {
17
17
  id: row.environment_id,
18
18
  ...row.project_id ? { projectId: row.project_id } : {},
19
19
  kind: row.kind,
20
+ ownership: row.ownership,
20
21
  status: row.status,
21
22
  rootPath: row.root_path,
22
23
  ...row.repository_root ? { repositoryRoot: row.repository_root } : {},
@@ -63,13 +64,14 @@ var ExecutionEnvironmentStore = class {
63
64
  const repositoryRoot = optionalText(input.repositoryRoot);
64
65
  const gitCommonDir = optionalText(input.gitCommonDir);
65
66
  if (input.kind === "managed_worktree" && (!repositoryRoot || !gitCommonDir)) throw new Error("managed_worktree requires repositoryRoot and gitCommonDir");
67
+ const ownership = input.kind === "managed_worktree" ? "xopc_created" : "registered";
66
68
  const now = Date.now();
67
69
  runSqliteWriteTransaction((db) => {
68
70
  db.prepare(`INSERT INTO execution_environments (
69
- environment_id, project_id, kind, status, root_path,
71
+ environment_id, project_id, kind, ownership, status, root_path,
70
72
  repository_root, git_common_dir, base_ref, base_sha, branch_ref,
71
73
  version, created_at, updated_at
72
- ) VALUES (?, ?, ?, 'requested', ?, ?, ?, ?, ?, ?, 1, ?, ?)`).run(id, projectId ?? null, input.kind, rootPath, repositoryRoot ? resolve(repositoryRoot) : null, gitCommonDir ? resolve(gitCommonDir) : null, optionalText(input.baseRef) ?? null, optionalText(input.baseSha) ?? null, optionalText(input.branchRef) ?? null, now, now);
74
+ ) VALUES (?, ?, ?, ?, 'requested', ?, ?, ?, ?, ?, ?, 1, ?, ?)`).run(id, projectId ?? null, input.kind, ownership, rootPath, repositoryRoot ? resolve(repositoryRoot) : null, gitCommonDir ? resolve(gitCommonDir) : null, optionalText(input.baseRef) ?? null, optionalText(input.baseSha) ?? null, optionalText(input.branchRef) ?? null, now, now);
73
75
  db.prepare(`INSERT INTO execution_environment_events (
74
76
  event_id, environment_id, from_status, to_status, reason, metadata_json, created_at
75
77
  ) VALUES (?, ?, NULL, 'requested', 'created', '{}', ?)`).run(randomUUID(), id, now);
@@ -1,11 +1,14 @@
1
1
  export declare const EXECUTION_ENVIRONMENT_KINDS: readonly ["local_checkout", "managed_worktree"];
2
2
  export type ExecutionEnvironmentKind = (typeof EXECUTION_ENVIRONMENT_KINDS)[number];
3
+ export declare const EXECUTION_ENVIRONMENT_OWNERSHIPS: readonly ["registered", "xopc_created"];
4
+ export type ExecutionEnvironmentOwnership = (typeof EXECUTION_ENVIRONMENT_OWNERSHIPS)[number];
3
5
  export declare const EXECUTION_ENVIRONMENT_STATUSES: readonly ["requested", "provisioning", "ready", "degraded", "deleting", "deleted", "error"];
4
6
  export type ExecutionEnvironmentStatus = (typeof EXECUTION_ENVIRONMENT_STATUSES)[number];
5
7
  export interface ExecutionEnvironment {
6
8
  id: string;
7
9
  projectId?: string;
8
10
  kind: ExecutionEnvironmentKind;
11
+ ownership: ExecutionEnvironmentOwnership;
9
12
  status: ExecutionEnvironmentStatus;
10
13
  rootPath: string;
11
14
  repositoryRoot?: string;
@@ -1,5 +1,6 @@
1
1
  //#region src/execution-environments/types.ts
2
2
  const EXECUTION_ENVIRONMENT_KINDS = ["local_checkout", "managed_worktree"];
3
+ const EXECUTION_ENVIRONMENT_OWNERSHIPS = ["registered", "xopc_created"];
3
4
  const EXECUTION_ENVIRONMENT_STATUSES = [
4
5
  "requested",
5
6
  "provisioning",
@@ -51,4 +52,4 @@ function canTransitionExecutionEnvironment(fromStatus, toStatus) {
51
52
  return STATUS_TRANSITIONS[fromStatus].includes(toStatus);
52
53
  }
53
54
  //#endregion
54
- export { EXECUTION_ENVIRONMENT_KINDS, EXECUTION_ENVIRONMENT_STATUSES, ExecutionEnvironmentConflictError, ExecutionEnvironmentNotFoundError, canTransitionExecutionEnvironment };
55
+ export { EXECUTION_ENVIRONMENT_KINDS, EXECUTION_ENVIRONMENT_OWNERSHIPS, EXECUTION_ENVIRONMENT_STATUSES, ExecutionEnvironmentConflictError, ExecutionEnvironmentNotFoundError, canTransitionExecutionEnvironment };
@@ -0,0 +1,8 @@
1
+ export interface DirectoryIdentity {
2
+ dev: number;
3
+ ino: number;
4
+ }
5
+ export declare function assertManagedWorktreePath(rootPath: string, stateDir?: string, repositoryRoot?: string): void;
6
+ export declare function readDirectoryIdentity(path: string): Promise<DirectoryIdentity | undefined>;
7
+ export declare function assertNoNestedRegisteredWorktrees(repositoryRoot: string, rootPath: string): Promise<void>;
8
+ export declare function sameDirectoryIdentity(expected: DirectoryIdentity, actual: DirectoryIdentity | undefined): boolean;
@@ -0,0 +1,43 @@
1
+ import { listGitWorktrees } from "./git.js";
2
+ import { resolveExecutionWorktreesRoot } from "./paths.js";
3
+ import { homedir } from "node:os";
4
+ import { isAbsolute, relative, resolve, sep } from "node:path";
5
+ import { lstat } from "node:fs/promises";
6
+ //#region src/execution-environments/worktree-safety.ts
7
+ function isInside(parent, candidate) {
8
+ const child = relative(parent, candidate);
9
+ return Boolean(child) && !isAbsolute(child) && child !== ".." && !child.startsWith(`..${sep}`) && resolve(parent, child) === candidate;
10
+ }
11
+ function assertManagedWorktreePath(rootPath, stateDir, repositoryRoot) {
12
+ const managedRoot = resolve(resolveExecutionWorktreesRoot(stateDir));
13
+ const candidate = resolve(rootPath);
14
+ if (!isInside(managedRoot, candidate)) throw new Error(`Refusing to manage worktree outside ${managedRoot}`);
15
+ if (candidate === resolve(homedir()) || candidate === resolve("/")) throw new Error(`Refusing to manage protected path ${candidate}`);
16
+ if (repositoryRoot && candidate === resolve(repositoryRoot)) throw new Error("Refusing to manage the repository root as a worktree");
17
+ }
18
+ async function readDirectoryIdentity(path) {
19
+ try {
20
+ const value = await lstat(path);
21
+ if (value.isSymbolicLink()) throw new Error(`Refusing to manage symlinked worktree path: ${path}`);
22
+ if (!value.isDirectory()) throw new Error(`Worktree path is not a directory: ${path}`);
23
+ return {
24
+ dev: value.dev,
25
+ ino: value.ino
26
+ };
27
+ } catch (error) {
28
+ if (error.code === "ENOENT") return void 0;
29
+ throw error;
30
+ }
31
+ }
32
+ async function assertNoNestedRegisteredWorktrees(repositoryRoot, rootPath) {
33
+ const candidate = resolve(rootPath);
34
+ for (const worktree of await listGitWorktrees(repositoryRoot)) {
35
+ const registered = resolve(worktree.path);
36
+ if (registered !== candidate && isInside(candidate, registered)) throw new Error(`Refusing to remove worktree containing registered worktree ${registered}`);
37
+ }
38
+ }
39
+ function sameDirectoryIdentity(expected, actual) {
40
+ return actual?.dev === expected.dev && actual.ino === expected.ino;
41
+ }
42
+ //#endregion
43
+ export { assertManagedWorktreePath, assertNoNestedRegisteredWorktrees, readDirectoryIdentity, sameDirectoryIdentity };
@@ -25,7 +25,7 @@ export declare class ActivationPlanner {
25
25
  getActivatedIds(context: ActivationContext): string[];
26
26
  /**
27
27
  * Split activated ids by manifest `activation.onStartup`.
28
- * Extensions without the field remain on the startup path (backward compatible).
28
+ * Extensions without the field load during startup.
29
29
  */
30
30
  filterActivatedIdsByLoadPhase(activatedIds: readonly string[], phase: ActivationLoadPhase): string[];
31
31
  explainPlan(context: ActivationContext): string;
@@ -131,7 +131,7 @@ var ActivationPlanner = class {
131
131
  }
132
132
  /**
133
133
  * Split activated ids by manifest `activation.onStartup`.
134
- * Extensions without the field remain on the startup path (backward compatible).
134
+ * Extensions without the field load during startup.
135
135
  */
136
136
  filterActivatedIdsByLoadPhase(activatedIds, phase) {
137
137
  return activatedIds.filter((extensionId) => {
@@ -0,0 +1,4 @@
1
+ import { type EngineCheckResult } from './engine-check.js';
2
+ export declare const EXTENSION_API_VERSION = "1.0.0";
3
+ export declare const EXTENSION_UI_API_VERSION = "1.0.0";
4
+ export declare function checkExtensionApiCompatibility(requiredRange: string | undefined, currentVersion: string, engineName: 'extensionApi' | 'extensionUiApi'): EngineCheckResult;
@@ -0,0 +1,15 @@
1
+ import { checkEngineCompatibility } from "./engine-check.js";
2
+ //#region src/extensions/api-version.ts
3
+ const EXTENSION_API_VERSION = "1.0.0";
4
+ const EXTENSION_UI_API_VERSION = "1.0.0";
5
+ function checkExtensionApiCompatibility(requiredRange, currentVersion, engineName) {
6
+ if (!requiredRange) return { compatible: true };
7
+ const result = checkEngineCompatibility(currentVersion, requiredRange);
8
+ if (!result.compatible || result.parseWarning) return {
9
+ ...result,
10
+ reason: result.parseWarning ? `Could not parse engines.${engineName} range: "${requiredRange}"` : `${engineName} version ${currentVersion} does not satisfy engines.${engineName}: "${requiredRange}"`
11
+ };
12
+ return result;
13
+ }
14
+ //#endregion
15
+ export { EXTENSION_API_VERSION, EXTENSION_UI_API_VERSION, checkExtensionApiCompatibility };
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import type { AgentTool } from '@earendil-works/pi-agent-core';
7
7
  import type { Command } from 'commander';
8
- import type { ExtensionApi, ExtensionLogger, ExtensionRuntime, GatewayMethodHandler, HttpRequestHandler, ExtensionCommand, ExtensionCommandHandler, ExtensionReloadHandler, ExtensionService, FlagConfig, FlagValue, ShortcutConfig, HookHandlerMap, ExtensionHookEvent, TuiExtensionRegistrar, ExtensionSendUserMessageOptions, ExtensionUserMessageContent, ExtensionCustomMessage, ExtensionSendMessageOptions } from './types/index.js';
8
+ import type { ExtensionApi, ExtensionLogger, ExtensionRuntime, GatewayMethodHandler, HttpRequestHandler, ExtensionCommand, ExtensionCommandHandler, ExtensionReloadHandler, ExtensionService, HookHandlerMap, ExtensionHookEvent, TuiExtensionRegistrar, ExtensionSendUserMessageOptions, ExtensionUserMessageContent, ExtensionCustomMessage, ExtensionSendMessageOptions } from './types/index.js';
9
9
  import type { CommandContribution, ContractDeclaration } from './types/manifest.js';
10
10
  import type { ChannelPlugin } from '../channels/plugin-types.js';
11
11
  import type { Config } from '../config/config-surface.js';
@@ -38,6 +38,7 @@ export declare class ExtensionApiImpl implements ExtensionApi {
38
38
  private _registeredSpeechProviderIds;
39
39
  private _registeredMediaUnderstandingProviderIds;
40
40
  private _registeredMarketplaceAdapterIds;
41
+ private _providerCleanup;
41
42
  private readonly _manifestCommands;
42
43
  constructor(id: string, name: string, version: string | undefined, source: string, config: Config, extensionConfig: Record<string, unknown>, _logger: ExtensionLogger, _resolvePath: (input: string) => string, _coreRegistry?: ExtensionRegistryImpl, _contracts?: ContractDeclaration, runtime?: ExtensionRuntime);
43
44
  get logger(): ExtensionLogger;
@@ -58,7 +59,7 @@ export declare class ExtensionApiImpl implements ExtensionApi {
58
59
  * return { systemPrompt: event.systemPrompt };
59
60
  * });
60
61
  */
61
- onHook<K extends ExtensionHookEvent>(hookName: K, handler: HookHandlerMap[K], _opts?: {
62
+ onHook<K extends ExtensionHookEvent>(hookName: K, handler: HookHandlerMap[K], opts?: {
62
63
  priority?: number;
63
64
  }): void;
64
65
  /**
@@ -94,10 +95,6 @@ export declare class ExtensionApiImpl implements ExtensionApi {
94
95
  * Register a full ProviderPlugin
95
96
  */
96
97
  registerProvider(plugin: import('./types/providers.js').ProviderPlugin): void;
97
- /**
98
- * Register a full ProviderPlugin (alias for registerProvider)
99
- */
100
- registerProviderPlugin(plugin: import('./types/providers.js').ProviderPlugin): void;
101
98
  registerSpeechProvider(plugin: SpeechProviderPlugin): void;
102
99
  /** Speech provider ids registered through this extension API instance. */
103
100
  getRegisteredSpeechProviderIds(): readonly string[];
@@ -111,9 +108,6 @@ export declare class ExtensionApiImpl implements ExtensionApi {
111
108
  adapter: import('../agent/skills/marketplace/adapter.types.js').SkillsMarketplaceAdapter;
112
109
  displayName?: string;
113
110
  }): void;
114
- registerFlag(_name: string, _config: FlagConfig): void;
115
- getFlag(_name: string): FlagValue;
116
- registerShortcut(_key: string, _config: ShortcutConfig): void;
117
111
  registerTui(register: TuiExtensionRegistrar): void;
118
112
  setLabel(entryId: string, label: string | undefined): void;
119
113
  sendUserMessage(content: ExtensionUserMessageContent, options?: ExtensionSendUserMessageOptions): void;
@@ -1,5 +1,6 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
+ import { getProviderRegistry, init_plugin_registry } from "../providers/plugin-registry.js";
3
4
  import { registerMarketplaceAdapter, unregisterMarketplaceAdapter } from "../agent/skills/marketplace/registry.js";
4
5
  import { registerSpeechProvider } from "../voice/tts/speech-registry.js";
5
6
  import { HOOK_EXECUTION_MODES } from "./types/hooks.js";
@@ -12,6 +13,7 @@ import { isAbsolute, resolve } from "path";
12
13
  import { EventEmitter } from "events";
13
14
  //#region src/extensions/api.ts
14
15
  init_logger();
16
+ init_plugin_registry();
15
17
  var ExtensionApiImpl = class {
16
18
  _tools = /* @__PURE__ */ new Map();
17
19
  _hooks = /* @__PURE__ */ new Map();
@@ -25,6 +27,7 @@ var ExtensionApiImpl = class {
25
27
  _registeredSpeechProviderIds = [];
26
28
  _registeredMediaUnderstandingProviderIds = [];
27
29
  _registeredMarketplaceAdapterIds = [];
30
+ _providerCleanup = [];
28
31
  _manifestCommands = /* @__PURE__ */ new Map();
29
32
  constructor(id, name, version, source, config, extensionConfig, _logger, _resolvePath, _coreRegistry, _contracts = {}, runtime) {
30
33
  this.id = id;
@@ -68,15 +71,17 @@ var ExtensionApiImpl = class {
68
71
  registerHook(event, handler, opts) {
69
72
  this._assertContract("hooks", event);
70
73
  if (!this._hooks.has(event)) this._hooks.set(event, /* @__PURE__ */ new Set());
71
- this._hooks.get(event).add(handler);
72
- if (opts?.once) {
73
- const wrapper = async (...args) => {
74
- await handler(...args);
75
- this._hooks.get(event)?.delete(wrapper);
76
- };
77
- this._hooks.get(event).add(wrapper);
78
- }
79
- this._registry.addHook(event, handler, this.id, opts?.priority ?? 0);
74
+ const hookEvent = event;
75
+ const registeredHandler = opts?.once ? async (...args) => {
76
+ try {
77
+ return await handler(...args);
78
+ } finally {
79
+ this._hooks.get(event)?.delete(registeredHandler);
80
+ this._registry.removeHook(hookEvent, registeredHandler);
81
+ }
82
+ } : handler;
83
+ this._hooks.get(event).add(registeredHandler);
84
+ this._registry.addHook(hookEvent, registeredHandler, this.id, opts?.priority ?? 0);
80
85
  this._logger.info(`Registered hook: ${event}`);
81
86
  }
82
87
  /**
@@ -89,11 +94,12 @@ var ExtensionApiImpl = class {
89
94
  * return { systemPrompt: event.systemPrompt };
90
95
  * });
91
96
  */
92
- onHook(hookName, handler, _opts) {
97
+ onHook(hookName, handler, opts) {
93
98
  this._assertContract("hooks", hookName);
94
99
  const mode = HOOK_EXECUTION_MODES[hookName];
95
100
  if (!this._typedHooks.has(hookName)) this._typedHooks.set(hookName, /* @__PURE__ */ new Set());
96
101
  this._typedHooks.get(hookName).add(handler);
102
+ this._registry.addHook(hookName, handler, this.id, opts?.priority ?? 0);
97
103
  this._logger.debug(`Registered typed hook: ${hookName} (mode: ${mode})`);
98
104
  }
99
105
  /**
@@ -107,14 +113,14 @@ var ExtensionApiImpl = class {
107
113
  registerChannel(registration) {
108
114
  const plugin = registration.plugin;
109
115
  this._assertContract("channels", plugin.id);
110
- this._registry.addChannelPlugin(plugin);
116
+ this._registry.addChannelPlugin(plugin, this.id);
111
117
  for (const migration of plugin.migrations ?? []) this.registerMigration(migration);
112
118
  this._eventBus.emit("channel:register", plugin);
113
119
  this._logger.info(`Registered channel plugin: ${plugin.id}`);
114
120
  }
115
121
  registerHttpRoute(path, handler) {
116
122
  this._assertContract("httpRoutes", path);
117
- this._registry.addHttpRoute(path, handler);
123
+ this._registry.addHttpRoute(path, handler, this.id);
118
124
  this._eventBus.emit("http:route", {
119
125
  path,
120
126
  handler
@@ -154,7 +160,7 @@ var ExtensionApiImpl = class {
154
160
  };
155
161
  commandRegistry.register(definition);
156
162
  this._registeredCommandIds.push(commandId);
157
- this._registry.addCommand(command);
163
+ this._registry.addCommand(command, this.id);
158
164
  this._eventBus.emit("command:register", command);
159
165
  this._logger.info(`Registered chat command: /${command.name}`);
160
166
  }
@@ -200,13 +206,13 @@ var ExtensionApiImpl = class {
200
206
  }
201
207
  registerService(service) {
202
208
  this._assertContract("services", service.id);
203
- this._registry.addService(service);
209
+ this._registry.addService(service, this.id);
204
210
  this._eventBus.emit("service:register", service);
205
211
  this._logger.info(`Registered service: ${service.id}`);
206
212
  }
207
213
  registerGatewayMethod(method, handler) {
208
214
  this._assertContract("gatewayMethods", method);
209
- this._registry.addGatewayMethod(method, handler);
215
+ this._registry.addGatewayMethod(method, handler, this.id);
210
216
  this._eventBus.emit("gateway:method", {
211
217
  method,
212
218
  handler
@@ -244,22 +250,12 @@ var ExtensionApiImpl = class {
244
250
  */
245
251
  registerProvider(plugin) {
246
252
  this._assertContract("providers", plugin.id);
247
- import("../providers/plugin-registry.js").then(({ getProviderRegistry }) => {
248
- getProviderRegistry().register(plugin);
249
- this._logger.info(`Extension registered provider: ${plugin.id}`);
250
- }).catch((err) => {
251
- this._logger.error(`Failed to register provider: ${err instanceof Error ? err.message : String(err)}`);
252
- });
253
- }
254
- /**
255
- * Register a full ProviderPlugin (alias for registerProvider)
256
- */
257
- registerProviderPlugin(plugin) {
258
- this.registerProvider(plugin);
253
+ this._providerCleanup.push(getProviderRegistry().register(plugin));
254
+ this._logger.info(`Extension registered provider: ${plugin.id}`);
259
255
  }
260
256
  registerSpeechProvider(plugin) {
261
257
  this._assertContract("speechProviders", plugin.id);
262
- registerSpeechProvider(plugin);
258
+ this._providerCleanup.push(registerSpeechProvider(plugin));
263
259
  if (!this._registeredSpeechProviderIds.includes(plugin.id)) this._registeredSpeechProviderIds.push(plugin.id);
264
260
  this._logger.info(`Registered speech provider: ${plugin.id}`);
265
261
  }
@@ -269,7 +265,7 @@ var ExtensionApiImpl = class {
269
265
  }
270
266
  registerMediaUnderstandingProvider(plugin) {
271
267
  this._assertContract("mediaUnderstandingProviders", plugin.id);
272
- registerMediaUnderstandingProvider(plugin);
268
+ this._providerCleanup.push(registerMediaUnderstandingProvider(plugin));
273
269
  if (!this._registeredMediaUnderstandingProviderIds.includes(plugin.id)) this._registeredMediaUnderstandingProviderIds.push(plugin.id);
274
270
  this._logger.info(`Registered media understanding provider: ${plugin.id}`);
275
271
  }
@@ -287,9 +283,6 @@ var ExtensionApiImpl = class {
287
283
  if (!this._registeredMarketplaceAdapterIds.includes(adapterId)) this._registeredMarketplaceAdapterIds.push(adapterId);
288
284
  this._logger.info(`Extension registered marketplace adapter: ${adapterId}`);
289
285
  }
290
- registerFlag(_name, _config) {}
291
- getFlag(_name) {}
292
- registerShortcut(_key, _config) {}
293
286
  registerTui(register) {
294
287
  this._assertContract("tui", this.id);
295
288
  this._registry.addTuiRegistration(this.id, register);
@@ -323,6 +316,7 @@ var ExtensionApiImpl = class {
323
316
  this._registry.removeReloadRegistration(this.id);
324
317
  for (const adapterId of this._registeredMarketplaceAdapterIds) unregisterMarketplaceAdapter(adapterId);
325
318
  this._registeredMarketplaceAdapterIds = [];
319
+ for (const cleanup of this._providerCleanup.splice(0).reverse()) cleanup();
326
320
  this._typedEventBus.cleanupAll();
327
321
  this._eventBus.removeAllListeners();
328
322
  this._hooks.clear();
@@ -0,0 +1,8 @@
1
+ export type ExtensionConfigValidationResult = {
2
+ valid: true;
3
+ } | {
4
+ valid: false;
5
+ reason: string;
6
+ errors?: unknown;
7
+ };
8
+ export declare function validateExtensionConfig(schema: Record<string, unknown> | undefined, config: Record<string, unknown>): ExtensionConfigValidationResult;
@@ -0,0 +1,25 @@
1
+ import Ajv from "ajv";
2
+ //#region src/extensions/config-validation.ts
3
+ const validator = new Ajv({
4
+ allErrors: true,
5
+ strict: false
6
+ });
7
+ function validateExtensionConfig(schema, config) {
8
+ if (!schema) return { valid: true };
9
+ try {
10
+ const validate = validator.compile(schema);
11
+ if (validate(config)) return { valid: true };
12
+ return {
13
+ valid: false,
14
+ reason: validator.errorsText(validate.errors, { separator: "; " }),
15
+ errors: validate.errors
16
+ };
17
+ } catch (error) {
18
+ return {
19
+ valid: false,
20
+ reason: error instanceof Error ? error.message : String(error)
21
+ };
22
+ }
23
+ }
24
+ //#endregion
25
+ export { validateExtensionConfig };
@@ -3,8 +3,7 @@
3
3
  * without going through `loader.ts` (which imports back from `api.ts`,
4
4
  * forming a circular cycle).
5
5
  *
6
- * `loader.ts` still re-exports the class for backward-compat; this file is a
7
- * leaf and only depends on the type definitions in `./types/index.js`.
6
+ * This file is a leaf and only depends on the type definitions in `./types/index.js`.
8
7
  */
9
8
  import type { AgentTool } from '@earendil-works/pi-agent-core';
10
9
  import type { ChannelPlugin } from '../channels/plugin-types.js';
@@ -18,6 +17,13 @@ export declare class ExtensionRegistryImpl implements ExtensionRegistry {
18
17
  gatewayMethods: Map<string, GatewayMethodHandler>;
19
18
  tools: Map<string, AgentTool<any, any>>;
20
19
  private toolExtensionIds;
20
+ private hookOwners;
21
+ private hookPriorities;
22
+ private channelOwners;
23
+ private httpRouteOwners;
24
+ private commandOwners;
25
+ private serviceOwners;
26
+ private gatewayMethodOwners;
21
27
  channelPlugins: ChannelPlugin[];
22
28
  private cliRegistrations;
23
29
  private reloadRegistrations;
@@ -26,17 +32,22 @@ export declare class ExtensionRegistryImpl implements ExtensionRegistry {
26
32
  addExtension(record: ExtensionRecord): void;
27
33
  getExtension(id: string): ExtensionRecord | undefined;
28
34
  getEnabledExtensions(): ExtensionRecord[];
29
- addHook(event: ExtensionHookEvent, handler: ExtensionHookHandler, _extensionId: string, _priority?: number): void;
35
+ addHook(event: ExtensionHookEvent, handler: ExtensionHookHandler, extensionId: string, priority?: number): void;
36
+ removeHook(event: ExtensionHookEvent, handler: ExtensionHookHandler): void;
30
37
  getHooks(event: ExtensionHookEvent): ExtensionHookHandler[];
31
- addChannelPlugin(plugin: ChannelPlugin): void;
32
- addHttpRoute(path: string, handler: HttpRequestHandler): void;
33
- getHttpRoute(path: string): HttpRequestHandler | undefined;
34
- addCommand(command: ExtensionCommand): void;
38
+ addChannelPlugin(plugin: ChannelPlugin, extensionId?: string): void;
39
+ addHttpRoute(path: string, handler: HttpRequestHandler, extensionId?: string): void;
40
+ getHttpRoute(extensionId: string, path: string): HttpRequestHandler | undefined;
41
+ addCommand(command: ExtensionCommand, extensionId?: string): void;
35
42
  getCommand(name: string): ExtensionCommand | undefined;
36
- addService(service: ExtensionService): void;
43
+ addService(service: ExtensionService, extensionId?: string): void;
37
44
  getService(id: string): ExtensionService | undefined;
38
- addGatewayMethod(method: string, handler: GatewayMethodHandler): void;
45
+ addGatewayMethod(method: string, handler: GatewayMethodHandler, extensionId?: string): void;
39
46
  getGatewayMethod(method: string): GatewayMethodHandler | undefined;
47
+ getServicesForExtension(extensionId: string): ExtensionService[];
48
+ removeExtensionContributions(extensionId: string): void;
49
+ private removeOwnedEntries;
50
+ private httpRouteKey;
40
51
  addTool(tool: any, extensionId: string): void;
41
52
  removeTool(name: string): void;
42
53
  getTools(): Map<string, any>;