@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
@@ -12,28 +12,39 @@ function isVoiceLikeAttachment(att) {
12
12
  if (att.type === "voice") return true;
13
13
  return (att.mimeType?.toLowerCase() ?? "").startsWith("audio/");
14
14
  }
15
+ /** True when the user explicitly asks the agent to inspect the original recording. */
16
+ function requestsOriginalVoiceInspection(text) {
17
+ const normalized = text.trim();
18
+ if (!normalized) return false;
19
+ return /(?:分析|检查|听|辨别|识别|判断|检测|对比|提取).{0,12}(?:原始|原声)?(?:语音|音频|录音|声音)/u.test(normalized) || /(?:原始|原声)?(?:语音|音频|录音|声音).{0,12}(?:分析|检查|听|辨别|识别|判断|检测|对比|音质|音色|语气|情绪|口音|噪声|杂音|背景声|说话人|声纹)/u.test(normalized) || /\b(?:analy[sz]e|inspect|listen\s+to|check|identify|compare|detect)\b.{0,40}\b(?:(?:original|raw)\s+)?(?:audio|recording|voice(?:\s+(?:clip|message))?)\b/iu.test(normalized) || /\b(?:(?:original|raw)\s+)?(?:audio|recording|voice(?:\s+(?:clip|message))?)\b.{0,40}\b(?:analy[sz]e|inspect|listen|quality|tone|emotion|accent|noise|background|speaker|voiceprint)\b/iu.test(normalized);
20
+ }
15
21
  async function mergeVoiceTranscriptsIntoUserText(prepared, userText, sttConfig, opts) {
16
22
  if (!prepared?.length) return {
17
23
  text: userText,
18
24
  inboundVoice: false,
19
- voiceTranscripts: []
25
+ voiceTranscripts: [],
26
+ transcribedMediaUris: []
20
27
  };
21
28
  if (!prepared.some(isVoiceLikeAttachment)) return {
22
29
  text: userText,
23
30
  inboundVoice: false,
24
- voiceTranscripts: []
31
+ voiceTranscripts: [],
32
+ transcribedMediaUris: []
25
33
  };
26
34
  if (opts?.skipVoiceTranscription === true) return {
27
35
  text: userText,
28
36
  inboundVoice: true,
29
- voiceTranscripts: []
37
+ voiceTranscripts: [],
38
+ transcribedMediaUris: []
30
39
  };
31
40
  if (!isSTTAvailable(sttConfig)) return {
32
41
  text: userText,
33
42
  inboundVoice: true,
34
- voiceTranscripts: []
43
+ voiceTranscripts: [],
44
+ transcribedMediaUris: []
35
45
  };
36
46
  const transcripts = [];
47
+ const transcribedMediaUris = [];
37
48
  for (const att of prepared) {
38
49
  if (!isVoiceLikeAttachment(att)) continue;
39
50
  let buf = null;
@@ -56,12 +67,13 @@ async function mergeVoiceTranscriptsIntoUserText(prepared, userText, sttConfig,
56
67
  continue;
57
68
  }
58
69
  try {
59
- const r = await transcribe(buf, sttConfig, {
70
+ const transcript = (await transcribe(buf, sttConfig, {
60
71
  language: sttConfig.provider === "alibaba" ? "zh" : void 0,
61
72
  mime: att.mimeType,
62
73
  fileName: att.name
63
- });
64
- transcripts.push(r.text.trim() || "[Voice: no speech detected]");
74
+ })).text.trim();
75
+ transcripts.push(transcript || "[Voice: no speech detected]");
76
+ if (transcript && "uri" in att && att.uri?.trim()) transcribedMediaUris.push(att.uri.trim());
65
77
  } catch (error) {
66
78
  const errorMessage = error instanceof Error ? error.message : String(error);
67
79
  log.error({
@@ -78,8 +90,9 @@ async function mergeVoiceTranscriptsIntoUserText(prepared, userText, sttConfig,
78
90
  return {
79
91
  text: [transcripts.filter(Boolean).join("\n"), userText.trim()].filter(Boolean).join("\n\n") || userText,
80
92
  inboundVoice: true,
81
- voiceTranscripts: transcripts
93
+ voiceTranscripts: transcripts,
94
+ transcribedMediaUris
82
95
  };
83
96
  }
84
97
  //#endregion
85
- export { isVoiceLikeAttachment, mergeVoiceTranscriptsIntoUserText };
98
+ export { isVoiceLikeAttachment, mergeVoiceTranscriptsIntoUserText, requestsOriginalVoiceInspection };
@@ -77,6 +77,7 @@ function createAgentCommand(_ctx) {
77
77
  extensionLoader.setConfig(config);
78
78
  extensionLoader.setRuntimeContext({ bus });
79
79
  await extensionLoader.loadByActivationPlan();
80
+ await extensionLoader.startServices();
80
81
  const n = extensionLoader.getRegistry().extensions.size;
81
82
  if (n > 0) log.info({ count: n }, "Extensions loaded");
82
83
  } catch (error) {
@@ -120,6 +121,7 @@ function createAgentCommand(_ctx) {
120
121
  running = false;
121
122
  bus.shutdown();
122
123
  await agent.stop();
124
+ await extensionLoader?.shutdown();
123
125
  };
124
126
  process.on("SIGINT", shutdown);
125
127
  process.on("SIGTERM", shutdown);
@@ -1,17 +1,16 @@
1
1
  import { ConfigSchema, init_schema } from "../../config/schema.js";
2
- import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
3
2
  import { resolveGatewayLocalClientHost } from "../../config/gateway-bind.js";
4
3
  import { formatExamples, register } from "../registry.js";
5
4
  import { existsSync, readFileSync } from "fs";
6
5
  import { Command } from "commander";
7
6
  //#region src/cli/commands/config.ts
8
- init_write_file_atomic();
9
7
  init_schema();
10
8
  const MISSING_CONFIG_HINT = "Run: xopc setup, xopc onboard, or xopc init";
11
9
  async function loadConfigDeps() {
12
- const [{ loadConfig }, { createLogger }] = await Promise.all([import("../../config/index.js"), import("../../utils/logger.js")]);
10
+ const [{ loadConfig, saveConfig }, { createLogger }] = await Promise.all([import("../../config/index.js"), import("../../utils/logger.js")]);
13
11
  return {
14
12
  loadConfig,
13
+ saveConfig,
15
14
  log: createLogger("ConfigCommand")
16
15
  };
17
16
  }
@@ -108,7 +107,7 @@ function createConfigCommand(ctx) {
108
107
  console.log(typeof value === "object" ? JSON.stringify(value, null, 2) : value);
109
108
  });
110
109
  cmd.command("set <path> <value>").description("Set a config value by dot path").action(async (path, value) => {
111
- const { loadConfig, log } = await loadConfigDeps();
110
+ const { loadConfig, saveConfig, log } = await loadConfigDeps();
112
111
  if (!existsSync(ctx.configPath)) {
113
112
  log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);
114
113
  process.exit(1);
@@ -121,11 +120,11 @@ function createConfigCommand(ctx) {
121
120
  }
122
121
  const config = loadConfig(ctx.configPath);
123
122
  setNestedValue(config, path, parsedValue);
124
- await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));
123
+ await saveConfig(config, ctx.configPath);
125
124
  log.info({ path }, `Config updated`);
126
125
  });
127
126
  cmd.command("unset <path>").description("Remove a config value by dot path").action(async (path) => {
128
- const { loadConfig, log } = await loadConfigDeps();
127
+ const { loadConfig, saveConfig, log } = await loadConfigDeps();
129
128
  if (!existsSync(ctx.configPath)) {
130
129
  log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);
131
130
  process.exit(1);
@@ -138,7 +137,7 @@ function createConfigCommand(ctx) {
138
137
  }, config);
139
138
  if (target && typeof target === "object" && lastKey in target) {
140
139
  delete target[lastKey];
141
- await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));
140
+ await saveConfig(config, ctx.configPath);
142
141
  log.info({ path }, `Config removed`);
143
142
  } else {
144
143
  log.error({ path }, `Config path not found`);
@@ -152,7 +151,7 @@ function createConfigCommand(ctx) {
152
151
  if (!await runConfigValidate(ctx.configPath)) process.exit(1);
153
152
  });
154
153
  cmd.command("token").description("Generate or view the gateway auth token").option("--generate", "Generate a new token").option("--show", "Show the current token (unmasked)").action(async (options) => {
155
- const { loadConfig, log } = await loadConfigDeps();
154
+ const { loadConfig, saveConfig, log } = await loadConfigDeps();
156
155
  if (!existsSync(ctx.configPath)) {
157
156
  log.error(`Config file not found. ${MISSING_CONFIG_HINT}`);
158
157
  process.exit(1);
@@ -171,7 +170,7 @@ function createConfigCommand(ctx) {
171
170
  mode: "token",
172
171
  token: newToken
173
172
  };
174
- await writeTextAtomic(ctx.configPath, JSON.stringify(config, null, 2));
173
+ await saveConfig(config, ctx.configPath);
175
174
  log.info("New gateway token generated");
176
175
  console.log(`Token: ${newToken.slice(0, 8)}...${newToken.slice(-8)}`);
177
176
  console.log("\nUse \"xopc config token --show\" to view the full token");
@@ -53,7 +53,7 @@ async function checkDatabaseSchema(ctx) {
53
53
  id: "database-schema",
54
54
  label: "Database schema",
55
55
  status: "pass",
56
- message: `SQLite schema v${status.dbVersion} (current release v179).`,
56
+ message: `SQLite schema v${status.dbVersion} (current release v181).`,
57
57
  hints: []
58
58
  };
59
59
  }
@@ -2,14 +2,14 @@ import { init_paths, resolveExtensionsDir } from "../../config/paths.js";
2
2
  import { init_loader, loadConfig } from "../../config/loader.js";
3
3
  import { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl, verifyStoreArtifactSha256 } from "../../agent/skills/marketplace/adapters/store/store-api-client.js";
4
4
  import { getContextWithOpts } from "../context.js";
5
- import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
6
- import { installFromLocal, installFromNpm, peekExtensionManifestFromStoreZip } from "../../extensions/install.js";
7
- import { commitStagedExtensionInstall, finalizeStagedExtensionInstall, rollbackStagedExtensionInstall, stageExtensionStoreZip } from "../../extensions/install-transaction.js";
5
+ import { computeExtensionDirectoryIntegrity, getExtensionLockfileManager } from "../../extensions/lockfile.js";
6
+ import { peekExtensionManifestFromStoreZip } from "../../extensions/install.js";
7
+ import { commitStagedExtensionInstall, finalizeStagedExtensionInstall, rollbackStagedExtensionInstall, stageExtensionLocal, stageExtensionNpm, stageExtensionStoreZip } from "../../extensions/install-transaction.js";
8
8
  import { fetchRegistry, findExtension, getExtensionMarketplaceStoreBaseUrl, listExtensions, searchExtensions } from "../../extensions/marketplace.js";
9
9
  import { colors } from "../utils/colors.js";
10
10
  import { validateExtensionPackageDirectory } from "./extension-pack.js";
11
11
  import { join, resolve } from "node:path";
12
- import { existsSync, readFileSync, rmSync, statSync } from "node:fs";
12
+ import { existsSync, readFileSync, statSync } from "node:fs";
13
13
  import { execSync } from "node:child_process";
14
14
  import { createHash } from "node:crypto";
15
15
  import semver from "semver";
@@ -111,9 +111,24 @@ async function upsertNpmExtensionLock(lock, targetDir, result, spec) {
111
111
  version: ver,
112
112
  resolved,
113
113
  source: "npm",
114
+ installedIntegrity: computeExtensionDirectoryIntegrity(join(targetDir, result.extensionId)),
114
115
  ...readInstalledSnapshots(targetDir, result.extensionId)
115
116
  });
116
117
  }
118
+ async function commitStagedWithLock(transaction, force, lock, writeLock) {
119
+ const lockSnapshot = await lock.load();
120
+ let lockWriteStarted = false;
121
+ try {
122
+ commitStagedExtensionInstall(transaction, force);
123
+ lockWriteStarted = true;
124
+ await writeLock();
125
+ } catch (error) {
126
+ rollbackStagedExtensionInstall(transaction);
127
+ if (lockWriteStarted) await lock.save(lockSnapshot);
128
+ throw error;
129
+ }
130
+ finalizeStagedExtensionInstall(transaction);
131
+ }
117
132
  async function installExtensionFromStoreWithLock(params) {
118
133
  try {
119
134
  const { downloadUrl, version, sha256 } = await resolveExtensionZipDownloadUrl(params.storeBase, params.packageName, params.version);
@@ -134,6 +149,13 @@ async function installExtensionFromStoreWithLock(params) {
134
149
  error: "Install cancelled"
135
150
  };
136
151
  const transaction = await stageExtensionStoreZip(buf, params.targetDir);
152
+ if (params.expectedExtensionId && transaction.extensionId !== params.expectedExtensionId) {
153
+ rollbackStagedExtensionInstall(transaction);
154
+ return {
155
+ ok: false,
156
+ error: `Expected extension ${params.expectedExtensionId}, received ${transaction.extensionId}`
157
+ };
158
+ }
137
159
  const lockSnapshot = await params.lock.load();
138
160
  let lockWriteStarted = false;
139
161
  try {
@@ -146,6 +168,7 @@ async function installExtensionFromStoreWithLock(params) {
146
168
  source: "store",
147
169
  artifactUrl: downloadUrl,
148
170
  integrity: actualIntegrity,
171
+ installedIntegrity: computeExtensionDirectoryIntegrity(transaction.targetDir),
149
172
  ...readInstalledSnapshots(params.targetDir, transaction.extensionId)
150
173
  });
151
174
  } catch (err) {
@@ -222,36 +245,41 @@ function createExtensionInstallCommand() {
222
245
  if (npmExplicit) {
223
246
  const spec = installTarget;
224
247
  console.log(colors.cyan("📦"), `Installing from npm: ${spec}…`);
225
- const result = await installFromNpm(spec, targetDir);
226
- if (!result.ok) {
227
- console.error(colors.red("error:"), result.error ?? "install failed");
248
+ try {
249
+ const transaction = await stageExtensionNpm(spec, targetDir);
250
+ await commitStagedWithLock(transaction, opts.force, lock, () => upsertNpmExtensionLock(lock, targetDir, {
251
+ ok: true,
252
+ extensionId: transaction.extensionId,
253
+ targetDir: transaction.targetDir
254
+ }, spec));
255
+ console.log(colors.green("✓"), transaction.extensionId, "(npm)");
256
+ } catch (error) {
257
+ console.error(colors.red("error:"), error instanceof Error ? error.message : String(error));
228
258
  process.exit(1);
229
259
  }
230
- await upsertNpmExtensionLock(lock, targetDir, result, spec);
231
- console.log(colors.green("✓"), result.extensionId ?? "ok", "(npm)");
232
260
  return;
233
261
  }
234
262
  if (looksLikeLocalPath(installTarget)) {
235
263
  const sourceDir = resolve(process.cwd(), installTarget);
236
- if (opts.force) {
237
- const manifestPath = join(sourceDir, MANIFEST);
238
- if (existsSync(manifestPath)) try {
239
- const raw = readFileSync(manifestPath, "utf-8");
240
- const m = JSON.parse(raw);
241
- const extId = typeof m.id === "string" && m.id && !m.id.includes("/") && !m.id.includes("\\") ? m.id : void 0;
242
- if (extId && existsSync(join(targetDir, extId))) rmSync(join(targetDir, extId), {
243
- recursive: true,
244
- force: true
245
- });
246
- } catch {}
247
- }
248
264
  console.log(colors.cyan("📂"), "Installing from local directory…");
249
- const result = await installFromLocal(sourceDir, targetDir);
250
- if (!result.ok) {
251
- console.error(colors.red("error:"), result.error ?? "install failed");
265
+ try {
266
+ const transaction = await stageExtensionLocal(sourceDir, targetDir);
267
+ const snapshots = readInstalledSnapshots(transaction.stagingRoot, transaction.extensionId);
268
+ const version = typeof snapshots.manifest?.version === "string" ? snapshots.manifest.version : "0.0.0";
269
+ await commitStagedWithLock(transaction, opts.force, lock, () => lock.upsert(transaction.extensionId, {
270
+ name: transaction.extensionId,
271
+ version,
272
+ resolved: sourceDir,
273
+ source: "local",
274
+ localPath: sourceDir,
275
+ installedIntegrity: computeExtensionDirectoryIntegrity(transaction.targetDir),
276
+ ...readInstalledSnapshots(targetDir, transaction.extensionId)
277
+ }));
278
+ console.log(colors.green("✓"), transaction.extensionId);
279
+ } catch (error) {
280
+ console.error(colors.red("error:"), error instanceof Error ? error.message : String(error));
252
281
  process.exit(1);
253
282
  }
254
- console.log(colors.green("✓"), result.extensionId ?? "ok");
255
283
  return;
256
284
  }
257
285
  console.error(colors.red("error:"), "Extension installs require an explicit source: store:<id>, npm:<package>, or a local directory path.");
@@ -346,15 +374,13 @@ function createExtensionUpdateCommand() {
346
374
  if (entry.source === "store") {
347
375
  const pkgName = entry.resolved?.trim() || id;
348
376
  console.log(colors.cyan("Updating"), id, "←", `store:${pkgName}`);
349
- if (existsSync(join(targetDir, id))) rmSync(join(targetDir, id), {
350
- recursive: true,
351
- force: true
352
- });
353
377
  const r = await installExtensionFromStoreWithLock({
354
378
  storeBase,
355
379
  packageName: pkgName,
380
+ expectedExtensionId: id,
356
381
  targetDir,
357
382
  lock,
383
+ force: true,
358
384
  yes: true
359
385
  });
360
386
  if (r.ok === false) {
@@ -374,23 +400,22 @@ function createExtensionUpdateCommand() {
374
400
  continue;
375
401
  }
376
402
  console.log(colors.cyan("Updating"), id, "←", spec);
377
- if (existsSync(join(targetDir, id))) rmSync(join(targetDir, id), {
378
- recursive: true,
379
- force: true
380
- });
381
- const result = await installFromNpm(spec, targetDir);
382
- if (!result.ok) {
383
- console.error(colors.red("error:"), result.error ?? id);
403
+ try {
404
+ const transaction = await stageExtensionNpm(spec, targetDir);
405
+ if (transaction.extensionId !== id) {
406
+ rollbackStagedExtensionInstall(transaction);
407
+ throw new Error(`Expected extension ${id}, received ${transaction.extensionId}`);
408
+ }
409
+ await commitStagedWithLock(transaction, true, lock, () => upsertNpmExtensionLock(lock, targetDir, {
410
+ ok: true,
411
+ extensionId: transaction.extensionId,
412
+ targetDir: transaction.targetDir
413
+ }, spec));
414
+ console.log(colors.green("✓"), id);
415
+ } catch (error) {
416
+ console.error(colors.red("error:"), error instanceof Error ? error.message : String(error));
384
417
  process.exit(1);
385
418
  }
386
- await lock.upsert(id, {
387
- name: id,
388
- version: entry.version,
389
- resolved: spec,
390
- source: "npm",
391
- ...readInstalledSnapshots(targetDir, id)
392
- });
393
- console.log(colors.green("✓"), id);
394
419
  }
395
420
  });
396
421
  }
@@ -57,11 +57,9 @@ function collectContributionPaths(manifest, extRoot) {
57
57
  if (ui?.icon) out.push(join(extRoot, ui.icon));
58
58
  const c = ui?.contributions;
59
59
  if (!c) return out;
60
- for (const p of c.sidebarPanels ?? []) if (p.entrypoint) out.push(join(extRoot, p.entrypoint));
61
60
  for (const p of c.settingsPanels ?? []) if (p.entrypoint) out.push(join(extRoot, p.entrypoint));
62
61
  for (const p of c.chatWidgets ?? []) if (p.entrypoint) out.push(join(extRoot, p.entrypoint));
63
62
  for (const p of c.pages ?? []) if (p.entrypoint) out.push(join(extRoot, p.entrypoint));
64
- for (const p of c.statusBarItems ?? []) if (p.entrypoint) out.push(join(extRoot, p.entrypoint));
65
63
  return out;
66
64
  }
67
65
  function resolveMainFile(root, main) {
@@ -6,7 +6,7 @@ import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
6
6
  import { checkEngineCompatibility } from "../../extensions/engine-check.js";
7
7
  import { ExtensionLoader } from "../../extensions/loader.js";
8
8
  import { getContextWithOpts } from "../context.js";
9
- import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
9
+ import { computeExtensionDirectoryIntegrity, getExtensionLockfileManager } from "../../extensions/lockfile.js";
10
10
  import { checkAllExtensionsHealth, getExtensionHealthChecker } from "../../extensions/health.js";
11
11
  import { collectExtensionPackageDependencyIssues } from "../../extensions/package-contract.js";
12
12
  import { colors } from "../utils/colors.js";
@@ -15,8 +15,7 @@ import { createExtensionDevCommand } from "./extension-dev.js";
15
15
  import { createExtensionPackCommand } from "./extension-pack.js";
16
16
  import { createExtensionInstallCommand, createExtensionPublishCommand, createExtensionSearchCommand, createExtensionUpdateCommand } from "./extension-marketplace.js";
17
17
  import { join } from "node:path";
18
- import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
19
- import { createHash } from "node:crypto";
18
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
20
19
  import { Command } from "commander";
21
20
  //#region src/cli/commands/extension.ts
22
21
  init_loader();
@@ -52,26 +51,6 @@ function createExtensionListCommand() {
52
51
  }
53
52
  });
54
53
  }
55
- function hashInstalledExtensionDir(extensionDir) {
56
- if (!existsSync(extensionDir)) return void 0;
57
- const hash = createHash("sha256");
58
- const walk = (dir, prefix = "") => {
59
- const entries = readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.name !== "node_modules").sort((a, b) => a.name.localeCompare(b.name));
60
- for (const entry of entries) {
61
- const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
62
- const full = join(dir, entry.name);
63
- if (entry.isDirectory()) walk(full, rel);
64
- else if (entry.isFile()) {
65
- const st = statSync(full);
66
- hash.update(`file\0${rel}\0${st.size}\0`);
67
- hash.update(readFileSync(full));
68
- hash.update("\0");
69
- }
70
- }
71
- };
72
- walk(extensionDir);
73
- return `dir-sha256-${hash.digest("base64")}`;
74
- }
75
54
  function readJson(path) {
76
55
  try {
77
56
  const raw = JSON.parse(readFileSync(path, "utf-8"));
@@ -397,7 +376,7 @@ function createExtensionDoctorCommand() {
397
376
  ...entry,
398
377
  manifest: readJson(join(extensionDir, "xopc.extension.json")),
399
378
  packageJson: readJson(join(extensionDir, "package.json")),
400
- installedIntegrity: hashInstalledExtensionDir(extensionDir)
379
+ installedIntegrity: computeExtensionDirectoryIntegrity(extensionDir)
401
380
  });
402
381
  }
403
382
  for (const enabledId of enabledIds) if (!lockedIds.has(enabledId) && !existsSync(join(lockDir, enabledId))) if (options.fix && extensionsConfig) {
@@ -441,7 +420,7 @@ function createExtensionDoctorCommand() {
441
420
  source: "local",
442
421
  manifest,
443
422
  packageJson,
444
- installedIntegrity: hashInstalledExtensionDir(extensionDir)
423
+ installedIntegrity: computeExtensionDirectoryIntegrity(extensionDir)
445
424
  });
446
425
  }
447
426
  }
@@ -3,8 +3,8 @@ import { loadConfig } from "../../../config/loader.js";
3
3
  import "../../../config/index.js";
4
4
  import { isRestartEnabled } from "../../../config/commands.flags.js";
5
5
  import { resolveGatewayService } from "../../../daemon/service.js";
6
- import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "../../../infra/restart.js";
7
6
  import { findVerifiedGatewayListenerPidsOnPortSync, formatGatewayPidList, signalVerifiedGatewayPidSync } from "../../../infra/gateway-processes.js";
7
+ import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "../../../infra/restart.js";
8
8
  import { runServiceRestart, runServiceStop } from "./lifecycle-core.js";
9
9
  import { DEFAULT_RESTART_HEALTH_ATTEMPTS, renderGatewayPortHealthDiagnostics, waitForGatewayHealthyListener } from "./restart-health.js";
10
10
  import { parsePortFromArgs, renderGatewayServiceStartHints, resolveGatewayPortFromConfig } from "./shared.js";
@@ -1,9 +1,10 @@
1
- import { GatewayLockError, acquireGatewayLock } from "../../../gateway/lock.js";
1
+ import { GatewayLockError, acquireGatewayLock, init_lock } from "../../../gateway/lock.js";
2
2
  import { confirm } from "@inquirer/prompts";
3
3
  //#region src/cli/commands/onboard/gateway.ts
4
4
  /**
5
5
  * Gateway Configuration and Startup for Onboarding
6
6
  */
7
+ init_lock();
7
8
  function isInteractive() {
8
9
  return process.stdin.isTTY && process.stdout.isTTY;
9
10
  }
@@ -2,9 +2,9 @@ import { PACKAGE_VERSION, init_package_version } from "../../package-version.js"
2
2
  import { loadConfig } from "../../config/loader.js";
3
3
  import { formatExamples, register } from "../registry.js";
4
4
  import "../../config/index.js";
5
- import { acquireUpdateLock } from "../../infra/update-lock.js";
6
5
  import { normalizeUpdateChannel } from "../../infra/update-channels.js";
7
6
  import { compareSemver, resolveNpmChannelTag } from "../../infra/update-check.js";
7
+ import { acquireUpdateLock } from "../../infra/update-lock.js";
8
8
  import { formatUpdateApiResult, resolveUpdateInstallSurface, runGatewayUpdateWithPostSteps } from "../../infra/update-runner.js";
9
9
  import { Command } from "commander";
10
10
  //#region src/cli/commands/update.ts
@@ -1,5 +1,5 @@
1
1
  import { ConfigSchema, init_schema } from "../../config/schema.js";
2
- import { init_loader, saveConfig } from "../../config/loader.js";
2
+ import { assertConfigRewriteSafeForRunningGateway, init_loader, saveConfig } from "../../config/loader.js";
3
3
  import { ensureStarterAgentsInitialized } from "../../agent/starter-agents.js";
4
4
  import { runBootstrapMigrationsSync } from "../../migrations/runner.js";
5
5
  import { dirname } from "node:path";
@@ -73,7 +73,10 @@ async function initWorkspaceCore(options) {
73
73
  let needsWrite = configCreated || starterResult.changed;
74
74
  if (!needsWrite) needsWrite = await serializeConfig(await readDiskConfig(configPath, assertChannelPlugins), assertChannelPlugins) !== await serializeConfig(nextFinal, assertChannelPlugins);
75
75
  if (needsWrite) if (assertChannelPlugins) await saveConfig(nextFinal, configPath);
76
- else writeFileSync(configPath, `${JSON.stringify(nextFinal, null, 2)}\n`, "utf8");
76
+ else {
77
+ assertConfigRewriteSafeForRunningGateway(configPath);
78
+ writeFileSync(configPath, `${JSON.stringify(nextFinal, null, 2)}\n`, "utf8");
79
+ }
77
80
  return {
78
81
  config: nextFinal,
79
82
  token,
@@ -8,7 +8,7 @@ import { resolveDefaultAgentWorkspaceDir } from "./workspace-defaults.js";
8
8
  import { resolveAgentDir as resolveAgentDir$1, resolveAgentHomeDir as resolveAgentHomeDir$1, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
9
9
  import { extractProfileAgentId, resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "./agent-profile.js";
10
10
  import { FILENAMES, WORKSPACE_FILES, existsSync, hasBundledExtensionManifest, init_paths, resolveAgentAuthProfilesPath, resolveAgentDir, resolveAgentHomeDir, resolveAgentProfileDir, resolveAgentProfileMarkdownPath, resolveAuthProfilesPath, resolveBinDir, resolveBundledExtensionsDir, resolveBundledSkillsDir, resolveConfigPath, resolveCredentialsDir, resolveExtensionSdkPath, resolveExtensionsDir, resolveExtensionsLockPath, resolveInboxDir, resolveInboxMessagePath, resolveInboxPendingDir, resolveInboxProcessedDir, resolveLogPath, resolveLogsDir, resolveMcpOAuthPath, resolveModelsJsonPath, resolveNodeBinDir, resolveNodeBinPath, resolveNodeToolsDir, resolveNpmBinPath, resolveOAuthPath, resolvePidPath, resolveSkillPath, resolveSkillsCachePath, resolveSkillsDir, resolveSkillsLockPath, resolveSocketPath, resolveStatusPath, resolveToolsDir, resolveWorkspaceExtensionsDir, resolveWorkspaceFile, resolveWorkspaceStateDir, resolveWorkspaceStatePath, resolveXopcBinPath } from "./paths.js";
11
- import { init_loader, loadConfig, saveConfig } from "./loader.js";
11
+ import { assertConfigRewriteSafeForRunningGateway, init_loader, loadConfig, saveConfig } from "./loader.js";
12
12
  import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_config_value, resolveConfigValue, resolveHeaders, testApiKeyResolution } from "./resolve-config-value.js";
13
13
  import { CustomModelSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig } from "./models-json.js";
14
14
  import { canonicalizeConfiguredMcpServer, isKnownCliMcpTypeAlias, normalizeConfiguredMcpServers, resolveXopcMcpTransportAlias } from "./mcp-config-normalize.js";
@@ -27,4 +27,4 @@ init_workspace_path();
27
27
  init_models_json();
28
28
  init_resolve_config_value();
29
29
  //#endregion
30
- export { AgentImageGenerationModelSchema, AgentModelRefSchema, AgentModelsSchema, AgentsConfigSchema, BASE_RELOAD_RULES, BindingMatchSchema, BindingRuleSchema, BindingsConfigSchema, BrowserConfigSchema, ChannelsConfigSchema, CommandsConfigSchema, ConfigHotReloader, ConfigSchema, ConnectorsConfigSchema, CustomModelSchema, ENV_VARS, ExperimentalConfigSchema, ExtensionSecurityConfigSchema, ExtensionSlotsConfigSchema, ExtensionsConfigSchema, FILENAMES, GatewayAuthRateLimitSchema, GatewayAuthSchema, GatewayBindModeSchema, GatewayChannelConnectDeferModeSchema, GatewayConfigSchema, GatewayModeSchema, GatewayRemoteSchema, GatewaySecuritySchema, GatewayTailscaleConsentSchema, GatewayTailscaleSchema, GatewayTlsSchema, GatewayTrustedProxySchema, GatewayWebchatConfigSchema, HeartbeatConfigSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, McpConfigSchema, McpOAuthConfigSchema, McpServerSchema, MediaUnderstandingCapabilitiesSchema, MediaUnderstandingModelSchema, MessagesConfigSchema, ModelCatalogConfigSchema, ModelOverrideSchema, ModelsDevConfigSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProfileManager, ProviderAuthConfigSchema, ProviderAzureConfigSchema, ProviderConfigSchema, ProviderRequestOverridesSchema, ProvidersConfigSchema, RuntimeToolsConfigSchema, STTConfigSchema, STTFallbackConfigSchema, STTProviderConfigSchema, SearchProviderEntrySchema, SessionConfigSchema, SessionDmScopeSchema, SessionResetByTypeSchema, SessionResetConfigSchema, SessionResetModeSchema, SessionScopeSchema, SessionStorageConfigSchema, TTSConfigSchema, TTSEdgeConfigSchema, TTSFallbackConfigSchema, TTSModelOverridesConfigSchema, TTSProviderConfigSchema, TTSSummarizationConfigSchema, TelegramAccountConfigSchema, TelegramConfigSchema, TelegramGroupConfigSchema, TelegramTopicConfigSchema, ToolsConfigSchema, ToolsMediaAudioConfigSchema, ToolsMediaConfigSchema, TuiConfigSchema, TunnelConfigSchema, TunnelConsentSchema, UpdateAutoConfigSchema, UpdateConfigSchema, VercelGatewayRoutingSchema, VoiceConfigSchema, VoiceRefinementConfigSchema, WORKSPACE_FILES, WebSearchConfigSchema, WebToolsConfigSchema, WebsiteBlocklistSchema, WeixinAccountConfigSchema, WeixinConfigSchema, WorkspaceConfigSchema, WorkspaceImportConfigSchema, XOPC_DB_FILENAME, applyConfigOverrides, buildReloadPlan, canonicalizeConfiguredMcpServer, clearConfigValueCache, createProfile, deleteProfile, diffConfigPaths, existsSync, expandWorkspacePathString, extractProfileAgentId, formatThinkingLevels, getAgentDefaultImageGenerationModelConfig, getAgentDefaultImageModelConfig, getAgentDefaultModelRef, getAllowedCommands, getCacheStats, getConfigOverrides, getCurrentProfile, getDefaultModelValues, resolveModelsJsonPath as getModelsJsonPath, getProfileManager, getProfileNameFromDir, getSwitchCommand, getWorkspacePath, hasBundledExtensionManifest, isKnownCliMcpTypeAlias, listAgentProfileMarkdownDirs, listAgentWorkspaceDirs, listProfiles, listThinkingLevels, loadConfig, loadModelsJson, matchReloadRule, modelsJsonExists, normalizeConfiguredMcpServers, normalizeElevatedMode, normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel, normalizeWorkspaceDir, parseModelRef, resetConfigOverrides, resolveAgentAuthProfilesPath, resolveAgentDir, resolveAgentDir$1 as resolveAgentDirFromConfig, resolveAgentHomeDir, resolveAgentHomeDir$1 as resolveAgentHomeDirFromConfig, resolveAgentProfileDir, resolveAgentProfileMarkdownPath, resolveAgentWorkspaceDir, resolveAuthProfilesPath, resolveBinDir, resolveBundledExtensionsDir, resolveBundledSkillsDir, resolveConfigPath, resolveConfigValue, resolveCredentialsDir, resolveDefaultAgentWorkspaceDir, resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession, resolveExtensionSdkPath, resolveExtensionsDir, resolveExtensionsLockPath, resolveHeaders, resolveHomeDir, resolveInboxDir, resolveInboxMessagePath, resolveInboxPendingDir, resolveInboxProcessedDir, resolveLogPath, resolveLogsDir, resolveMcpOAuthPath, resolveModelsJsonPath, resolveNodeBinDir, resolveNodeBinPath, resolveNodeToolsDir, resolveNpmBinPath, resolveOAuthPath, resolvePidPath, resolveProfileStateDir, resolveSkillPath, resolveSkillsCachePath, resolveSkillsDir, resolveSkillsLockPath, resolveSocketPath, resolveStateDir, resolveStatusPath, resolveToolsDir, resolveWorkspaceExtensionsDir, resolveWorkspaceFile, resolveWorkspaceRoot, resolveWorkspaceStateDir, resolveWorkspaceStatePath, resolveXopcBinPath, resolveXopcCloudCatalogCachePath, resolveXopcDatabasePath, resolveXopcMcpTransportAlias, saveConfig, saveModelsJson, setConfigOverride, testApiKeyResolution, thinkLevelToNumber, unsetConfigOverride, validateModelsConfig };
30
+ export { AgentImageGenerationModelSchema, AgentModelRefSchema, AgentModelsSchema, AgentsConfigSchema, BASE_RELOAD_RULES, BindingMatchSchema, BindingRuleSchema, BindingsConfigSchema, BrowserConfigSchema, ChannelsConfigSchema, CommandsConfigSchema, ConfigHotReloader, ConfigSchema, ConnectorsConfigSchema, CustomModelSchema, ENV_VARS, ExperimentalConfigSchema, ExtensionSecurityConfigSchema, ExtensionSlotsConfigSchema, ExtensionsConfigSchema, FILENAMES, GatewayAuthRateLimitSchema, GatewayAuthSchema, GatewayBindModeSchema, GatewayChannelConnectDeferModeSchema, GatewayConfigSchema, GatewayModeSchema, GatewayRemoteSchema, GatewaySecuritySchema, GatewayTailscaleConsentSchema, GatewayTailscaleSchema, GatewayTlsSchema, GatewayTrustedProxySchema, GatewayWebchatConfigSchema, HeartbeatConfigSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, McpConfigSchema, McpOAuthConfigSchema, McpServerSchema, MediaUnderstandingCapabilitiesSchema, MediaUnderstandingModelSchema, MessagesConfigSchema, ModelCatalogConfigSchema, ModelOverrideSchema, ModelsDevConfigSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProfileManager, ProviderAuthConfigSchema, ProviderAzureConfigSchema, ProviderConfigSchema, ProviderRequestOverridesSchema, ProvidersConfigSchema, RuntimeToolsConfigSchema, STTConfigSchema, STTFallbackConfigSchema, STTProviderConfigSchema, SearchProviderEntrySchema, SessionConfigSchema, SessionDmScopeSchema, SessionResetByTypeSchema, SessionResetConfigSchema, SessionResetModeSchema, SessionScopeSchema, SessionStorageConfigSchema, TTSConfigSchema, TTSEdgeConfigSchema, TTSFallbackConfigSchema, TTSModelOverridesConfigSchema, TTSProviderConfigSchema, TTSSummarizationConfigSchema, TelegramAccountConfigSchema, TelegramConfigSchema, TelegramGroupConfigSchema, TelegramTopicConfigSchema, ToolsConfigSchema, ToolsMediaAudioConfigSchema, ToolsMediaConfigSchema, TuiConfigSchema, TunnelConfigSchema, TunnelConsentSchema, UpdateAutoConfigSchema, UpdateConfigSchema, VercelGatewayRoutingSchema, VoiceConfigSchema, VoiceRefinementConfigSchema, WORKSPACE_FILES, WebSearchConfigSchema, WebToolsConfigSchema, WebsiteBlocklistSchema, WeixinAccountConfigSchema, WeixinConfigSchema, WorkspaceConfigSchema, WorkspaceImportConfigSchema, XOPC_DB_FILENAME, applyConfigOverrides, assertConfigRewriteSafeForRunningGateway, buildReloadPlan, canonicalizeConfiguredMcpServer, clearConfigValueCache, createProfile, deleteProfile, diffConfigPaths, existsSync, expandWorkspacePathString, extractProfileAgentId, formatThinkingLevels, getAgentDefaultImageGenerationModelConfig, getAgentDefaultImageModelConfig, getAgentDefaultModelRef, getAllowedCommands, getCacheStats, getConfigOverrides, getCurrentProfile, getDefaultModelValues, resolveModelsJsonPath as getModelsJsonPath, getProfileManager, getProfileNameFromDir, getSwitchCommand, getWorkspacePath, hasBundledExtensionManifest, isKnownCliMcpTypeAlias, listAgentProfileMarkdownDirs, listAgentWorkspaceDirs, listProfiles, listThinkingLevels, loadConfig, loadModelsJson, matchReloadRule, modelsJsonExists, normalizeConfiguredMcpServers, normalizeElevatedMode, normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel, normalizeWorkspaceDir, parseModelRef, resetConfigOverrides, resolveAgentAuthProfilesPath, resolveAgentDir, resolveAgentDir$1 as resolveAgentDirFromConfig, resolveAgentHomeDir, resolveAgentHomeDir$1 as resolveAgentHomeDirFromConfig, resolveAgentProfileDir, resolveAgentProfileMarkdownPath, resolveAgentWorkspaceDir, resolveAuthProfilesPath, resolveBinDir, resolveBundledExtensionsDir, resolveBundledSkillsDir, resolveConfigPath, resolveConfigValue, resolveCredentialsDir, resolveDefaultAgentWorkspaceDir, resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession, resolveExtensionSdkPath, resolveExtensionsDir, resolveExtensionsLockPath, resolveHeaders, resolveHomeDir, resolveInboxDir, resolveInboxMessagePath, resolveInboxPendingDir, resolveInboxProcessedDir, resolveLogPath, resolveLogsDir, resolveMcpOAuthPath, resolveModelsJsonPath, resolveNodeBinDir, resolveNodeBinPath, resolveNodeToolsDir, resolveNpmBinPath, resolveOAuthPath, resolvePidPath, resolveProfileStateDir, resolveSkillPath, resolveSkillsCachePath, resolveSkillsDir, resolveSkillsLockPath, resolveSocketPath, resolveStateDir, resolveStatusPath, resolveToolsDir, resolveWorkspaceExtensionsDir, resolveWorkspaceFile, resolveWorkspaceRoot, resolveWorkspaceStateDir, resolveWorkspaceStatePath, resolveXopcBinPath, resolveXopcCloudCatalogCachePath, resolveXopcDatabasePath, resolveXopcMcpTransportAlias, saveConfig, saveModelsJson, setConfigOverride, testApiKeyResolution, thinkLevelToNumber, unsetConfigOverride, validateModelsConfig };
@@ -1,4 +1,5 @@
1
1
  import { type Config } from './schema.js';
2
+ export declare function assertConfigRewriteSafeForRunningGateway(path: string): void;
2
3
  /**
3
4
  * Load configuration from file
4
5
  * @param configPath Optional custom config path, defaults to XOPC_CONFIG_PATH or ~/.xopc/xopc.json
@@ -6,10 +6,21 @@ import { init_paths, resolveConfigPath } from "./paths.js";
6
6
  import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
7
7
  import { assertChannelPluginConfigs, init_validate_channel_configs } from "./validate-channel-configs.js";
8
8
  import { init_resolution, setActivePlatformDiscovery } from "../platform/resolution.js";
9
+ import { init_lock, isGatewayConfigLockedByAnotherProcessSync } from "../gateway/lock.js";
9
10
  import { dirname } from "path";
10
11
  import { existsSync, mkdirSync, promises, readFileSync } from "fs";
11
12
  import { config } from "dotenv";
12
13
  //#region src/config/loader.ts
14
+ function assertConfigRewriteSafeForRunningGateway(path) {
15
+ if (!existsSync(path) || !isGatewayConfigLockedByAnotherProcessSync(path)) return;
16
+ try {
17
+ const raw = JSON.parse(readFileSync(path, "utf8"));
18
+ if (!Array.isArray(raw.userContext?.knowledgeMemory?.sources)) return;
19
+ } catch {
20
+ return;
21
+ }
22
+ throw new Error("Configuration update deferred: restart the running gateway before rewriting the legacy memory policy.");
23
+ }
13
24
  function activateConfig(configValue) {
14
25
  setActivePlatformDiscovery(configValue.platform.mode === "connected" ? configValue.platform.discovery : void 0);
15
26
  return configValue;
@@ -63,6 +74,7 @@ function loadConfig(configPath) {
63
74
  */
64
75
  async function saveConfig(config, configPath) {
65
76
  const path = configPath || process.env.XOPC_CONFIG_PATH || resolveConfigPath();
77
+ assertConfigRewriteSafeForRunningGateway(path);
66
78
  const dir = dirname(path);
67
79
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
68
80
  const validated = ConfigSchema.parse(config);
@@ -84,9 +96,10 @@ var init_loader = __esmMin((() => {
84
96
  init_logger();
85
97
  init_validate_channel_configs();
86
98
  init_resolution();
99
+ init_lock();
87
100
  log = createLogger("ConfigLoader");
88
101
  CONFIG_BACKUP_COUNT = 10;
89
102
  }));
90
103
  //#endregion
91
104
  init_loader();
92
- export { init_loader, loadConfig, resolveConfigPath, saveConfig };
105
+ export { assertConfigRewriteSafeForRunningGateway, init_loader, loadConfig, resolveConfigPath, saveConfig };
@@ -1494,18 +1494,24 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1494
1494
  staleRetentionDays: z.ZodDefault<z.ZodNumber>;
1495
1495
  }, z.core.$strict>>;
1496
1496
  }, z.core.$strict>>;
1497
- knowledgeMemory: z.ZodDefault<z.ZodObject<{
1497
+ knowledgeMemory: z.ZodDefault<z.ZodPreprocess<z.ZodObject<{
1498
1498
  enabled: z.ZodDefault<z.ZodBoolean>;
1499
1499
  writePolicy: z.ZodDefault<z.ZodEnum<{
1500
1500
  allow: "allow";
1501
1501
  confirm: "confirm";
1502
1502
  deny: "deny";
1503
1503
  }>>;
1504
- sources: z.ZodDefault<z.ZodArray<z.ZodEnum<{
1504
+ readScopes: z.ZodDefault<z.ZodArray<z.ZodEnum<{
1505
1505
  project: "project";
1506
1506
  session: "session";
1507
+ agent: "agent";
1507
1508
  workspace: "workspace";
1509
+ global: "global";
1510
+ }>>>;
1511
+ contentSources: z.ZodDefault<z.ZodArray<z.ZodEnum<{
1512
+ memory: "memory";
1508
1513
  connector: "connector";
1514
+ local_import: "local_import";
1509
1515
  }>>>;
1510
1516
  searchStrategy: z.ZodDefault<z.ZodEnum<{
1511
1517
  "local-first": "local-first";
@@ -1514,6 +1520,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1514
1520
  "local-only": "local-only";
1515
1521
  "external-only": "external-only";
1516
1522
  }>>;
1523
+ searchTimeoutMs: z.ZodDefault<z.ZodNumber>;
1517
1524
  writeStrategy: z.ZodDefault<z.ZodEnum<{
1518
1525
  "local-first": "local-first";
1519
1526
  "external-first": "external-first";
@@ -1524,7 +1531,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1524
1531
  allowExternalWrites: z.ZodDefault<z.ZodBoolean>;
1525
1532
  allowedProviderIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
1526
1533
  autoWriteKinds: z.ZodOptional<z.ZodArray<z.ZodString>>;
1527
- }, z.core.$strict>>;
1534
+ }, z.core.$strict>>>;
1528
1535
  contextPlanning: z.ZodDefault<z.ZodObject<{
1529
1536
  enabled: z.ZodDefault<z.ZodBoolean>;
1530
1537
  maxAssertions: z.ZodDefault<z.ZodNumber>;
@@ -1,7 +1,7 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
+ import { ComputerConfigSchema, init_config } from "../computer/config.js";
2
3
  import { AgentModelsOverrideSchema, AgentsConfigSchema as AgentsConfigSchema$1, DEFAULT_AGENT_MODEL_REF, ImageGenerationRouteSchema, ModelRouteSchema } from "../agent-config/schema.js";
3
4
  import { init_agent_config } from "../agent-config/index.js";
4
- import { ComputerConfigSchema, init_config } from "../computer/config.js";
5
5
  import { DEFAULT_CONTEXT_COMPACTION_POLICY, UserContextConfigSchema, init_config as init_config$1 } from "../user-context/config.js";
6
6
  import { init_default_model } from "./default-model.js";
7
7
  import { init_public_url, validatePublicUrl } from "./public-url.js";
@@ -1074,8 +1074,16 @@ workDiscoveryOnboarding: z.boolean().default(true) }).strict().default({ workDis
1074
1074
  knowledgeMemory: {
1075
1075
  enabled: true,
1076
1076
  writePolicy: "confirm",
1077
- sources: ["session", "workspace"],
1077
+ readScopes: [
1078
+ "global",
1079
+ "agent",
1080
+ "workspace",
1081
+ "project",
1082
+ "session"
1083
+ ],
1084
+ contentSources: ["memory", "local_import"],
1078
1085
  searchStrategy: "fanout",
1086
+ searchTimeoutMs: 2e3,
1079
1087
  writeStrategy: "local-first",
1080
1088
  allowExternalWrites: false
1081
1089
  },