@xopcai/xopc 0.0.269 → 0.0.272

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 (293) hide show
  1. package/dist/browser-ext/dist/assets/{auth-cwEj8rFb.js → auth-C1QI-uMG.js} +65 -14
  2. package/dist/browser-ext/dist/background.js +23 -2
  3. package/dist/browser-ext/dist/pairing-handoff.js +51 -0
  4. package/dist/browser-ext/dist/sidepanel.html +1 -1
  5. package/dist/browser-ext/dist/sidepanel.js +39 -27
  6. package/dist/browser-ext/manifest.json +12 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/gateway/static/root/assets/{activity-store-DcwCSY6s.js → activity-store-DffqjeqQ.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D0NBOWC4.js → agent-avatar-dicebear-Cwj4HCYY.js} +1 -1
  10. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-6CLfLxVc.js +1 -0
  11. package/dist/gateway/static/root/assets/agents-B6mu64fY.js +1 -0
  12. package/dist/gateway/static/root/assets/{api-eaPO-mdr.js → api-CGLdye4i.js} +1 -1
  13. package/dist/gateway/static/root/assets/{app-management-settings-panel-E3xm2teY.js → app-management-settings-panel-BLujSbaw.js} +1 -1
  14. package/dist/gateway/static/root/assets/{appearance-settings-CiZOjgls.js → appearance-settings-BXMcueb8.js} +1 -1
  15. package/dist/gateway/static/root/assets/apps-page-BEgy4hY3.js +1 -0
  16. package/dist/gateway/static/root/assets/{archive-plugin-D09yo_Hc.js → archive-plugin-D4bUampf.js} +1 -1
  17. package/dist/gateway/static/root/assets/{attachment-load-CNYb8Qru.js → attachment-load-CBGNA2Ys.js} +1 -1
  18. package/dist/gateway/static/root/assets/{automations-page-DsrfW5ii.js → automations-page-dQyolNmy.js} +1 -1
  19. package/dist/gateway/static/root/assets/automations-workspace-DxRFrmrV.js +6 -0
  20. package/dist/gateway/static/root/assets/{binary-plugins-OWlaGqlY.js → binary-plugins-bbvp81h2.js} +1 -1
  21. package/dist/gateway/static/root/assets/{block-editor-CVND3M6r.js → block-editor-C8e6Wri4.js} +3 -3
  22. package/dist/gateway/static/root/assets/{browser-automation-inputs-D7IzVK_J.js → browser-automation-inputs-oJWJtQa6.js} +1 -1
  23. package/dist/gateway/static/root/assets/{browser-automations-page-CQ6cCpIv.js → browser-automations-page-CAcJQSjN.js} +2 -2
  24. package/dist/gateway/static/root/assets/browser-settings-page-TLAlqcPo.js +8 -0
  25. package/dist/gateway/static/root/assets/capabilities-settings-panel-z-K_jrZz.js +8 -0
  26. package/dist/gateway/static/root/assets/channels-settings-Dzrk33aB.js +1 -0
  27. package/dist/gateway/static/root/assets/{channels-status-swr-D4JrgJKa.js → channels-status-swr-CfOPNnVr.js} +1 -1
  28. package/dist/gateway/static/root/assets/{chat-terminal-dock-BUjnhT7C.js → chat-terminal-dock-9ZOl92kh.js} +2 -2
  29. package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +1 -0
  30. package/dist/gateway/static/root/assets/connectors-page-B1dIoRNi.js +2 -0
  31. package/dist/gateway/static/root/assets/cron-expression-C26e13YU.js +2 -0
  32. package/dist/gateway/static/root/assets/date-picker-Dj6FRLF9.js +1 -0
  33. package/dist/gateway/static/root/assets/{dependency-picker-Z6Nf0Wjq.js → dependency-picker-D1q89tVc.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-C0F5Iqnc.js → desktop-pet-DfqZBvhp.js} +1 -1
  35. package/dist/gateway/static/root/assets/{desktop-pet-settings-Bj_W6HL1.js → desktop-pet-settings-HCEh2MOm.js} +1 -1
  36. package/dist/gateway/static/root/assets/device-pairing-wizard-CPth92s6.js +1 -0
  37. package/dist/gateway/static/root/assets/{extension-debug-page-Ba09EnAn.js → extension-debug-page-C8cAWVoK.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-page-C88aGXJs.js → extension-page-5N87Vaym.js} +1 -1
  39. package/dist/gateway/static/root/assets/extension-settings-page-D85SAUFP.js +1 -0
  40. package/dist/gateway/static/root/assets/{gateway-config-swr-bjzk_4hn.js → gateway-config-swr-BjsDnB_n.js} +1 -1
  41. package/dist/gateway/static/root/assets/gateway-settings-Dqx8PmcT.js +1 -0
  42. package/dist/gateway/static/root/assets/{gateway-startup-retry-DrbIzFyB.js → gateway-startup-retry-BIf0eLWX.js} +1 -1
  43. package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +1 -0
  44. package/dist/gateway/static/root/assets/heartbeat-settings-BpDWGE1a.js +1 -0
  45. package/dist/gateway/static/root/assets/home-page-DJaqpC8-.js +1 -0
  46. package/dist/gateway/static/root/assets/{image-generation-api-CBWU9Ner.js → image-generation-api-1m8xTVS_.js} +1 -1
  47. package/dist/gateway/static/root/assets/index-C6PmD0cK.js +74 -0
  48. package/dist/gateway/static/root/assets/index-DKy1Qn1_.css +2 -0
  49. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B8Z7kKQY.js → keyboard-shortcuts-settings-Byy8mCSq.js} +1 -1
  50. package/dist/gateway/static/root/assets/local-app-workbench-page-l2AEiG2C.js +2 -0
  51. package/dist/gateway/static/root/assets/{local-apps-page-CLSfzkRp.js → local-apps-page-BPo0wBgM.js} +1 -1
  52. package/dist/gateway/static/root/assets/locale-store-CRNble2Z.js +1 -0
  53. package/dist/gateway/static/root/assets/logs-page-X5FdLlXK.js +2 -0
  54. package/dist/gateway/static/root/assets/management-settings-DT6NoIjm.js +1 -0
  55. package/dist/gateway/static/root/assets/{markdown-view-DIcfrLmG.js → markdown-view-AglreSOj.js} +1 -1
  56. package/dist/gateway/static/root/assets/{media-plugins-CSv6-xTA.js → media-plugins-Bzka9qXu.js} +1 -1
  57. package/dist/gateway/static/root/assets/message-circle-Badhj-4D.js +1 -0
  58. package/dist/gateway/static/root/assets/message-square-fVE7Ghj1.js +1 -0
  59. package/dist/gateway/static/root/assets/{messages-BRjoarIr.js → messages-DH_HCgmw.js} +3 -3
  60. package/dist/gateway/static/root/assets/note-detail-panel-BUJPoaGZ.js +5 -0
  61. package/dist/gateway/static/root/assets/notes-page-BwFpWRuo.js +8 -0
  62. package/dist/gateway/static/root/assets/{page-tabs-BfV-PQa5.js → page-tabs-Ys0p65Lt.js} +1 -1
  63. package/dist/gateway/static/root/assets/popover-select-Dz_Qis2R.js +1 -0
  64. package/dist/gateway/static/root/assets/{preview-open-alternatives-DQS7NFpg.js → preview-open-alternatives-iknB5xEp.js} +1 -1
  65. package/dist/gateway/static/root/assets/proactive-card-BPZDgNNR.js +1 -0
  66. package/dist/gateway/static/root/assets/proactive-page-CxdZR-p2.js +1 -0
  67. package/dist/gateway/static/root/assets/{product-open-page-BIhjZLKg.js → product-open-page-W1o3f-kz.js} +1 -1
  68. package/dist/gateway/static/root/assets/project-detail-page-BU1RKAcy.js +1 -0
  69. package/dist/gateway/static/root/assets/projects-page-z0X0tL8G.js +1 -0
  70. package/dist/gateway/static/root/assets/{registry-api-CwveUfe8.js → registry-api-DmYFpjsH.js} +1 -1
  71. package/dist/gateway/static/root/assets/remote-access-hub-NNTut2I8.js +1 -0
  72. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DMQ0wpNg.js → runtime-tools-settings-panel-DP1XyYO8.js} +1 -1
  73. package/dist/gateway/static/root/assets/{schema-form-C91g2PRU.js → schema-form-BMYKdzsH.js} +1 -1
  74. package/dist/gateway/static/root/assets/sessions-page-B6SsHlz5.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-BQu8bAcN.js +1 -0
  76. package/dist/gateway/static/root/assets/{settings-form-section-Cem6L49Y.js → settings-form-section-2LGjz7bu.js} +1 -1
  77. package/dist/gateway/static/root/assets/{settings-page-afDUxqlV.js → settings-page-7DjpC9_C.js} +1 -1
  78. package/dist/gateway/static/root/assets/setup-status-panel-Dj9jFWJt.js +1 -0
  79. package/dist/gateway/static/root/assets/{share-preview-page-CVEVHksg.js → share-preview-page-BxYdSi8c.js} +1 -1
  80. package/dist/gateway/static/root/assets/shares-settings-CMqE0KuK.js +1 -0
  81. package/dist/gateway/static/root/assets/skill-reload-api-BXqSJymN.js +1 -0
  82. package/dist/gateway/static/root/assets/{skills-page-CNrq1W6C.js → skills-page-DNEScMZH.js} +1 -1
  83. package/dist/gateway/static/root/assets/skills-page.utils-q88l65YU.js +1 -0
  84. package/dist/gateway/static/root/assets/{system-settings-panel-BLE8PxWE.js → system-settings-panel-8NIssGKj.js} +1 -1
  85. package/dist/gateway/static/root/assets/task-detail-page-L6dp9v2y.js +1 -0
  86. package/dist/gateway/static/root/assets/{theme-store-BejLVjIT.js → theme-store-BXZG3S25.js} +1 -1
  87. package/dist/gateway/static/root/assets/tunnel-api-CWsRPM84.js +1 -0
  88. package/dist/gateway/static/root/assets/{use-autosave-DmgEA8Qb.js → use-autosave-BwQuoTQU.js} +1 -1
  89. package/dist/gateway/static/root/assets/user-model-page-D4BucMrZ.js +2 -0
  90. package/dist/gateway/static/root/assets/{voice-api-key-field-sZ0J83SF.js → voice-api-key-field-Bd03Ic0s.js} +1 -1
  91. package/dist/gateway/static/root/assets/{voice-config-api-BEbz3avx.js → voice-config-api-gggUp3u9.js} +1 -1
  92. package/dist/gateway/static/root/assets/{work-discovery-overlay-BXnAlbmO.js → work-discovery-overlay-DF8PR_pK.js} +1 -1
  93. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BkwFey0a.js → workflow-run-setup-panel-BiAAWlir.js} +2 -2
  94. package/dist/gateway/static/root/assets/workflows-page-DryKUMfA.js +6 -0
  95. package/dist/gateway/static/root/index.html +15 -11
  96. package/dist/package.js +1 -1
  97. package/dist/packages/gateway-contract/src/device-pairing.js +2 -1
  98. package/dist/packages/gateway-contract/src/notifications.js +2 -2
  99. package/dist/packages/gateway-contract/src/proactive.js +22 -6
  100. package/dist/packages/gateway-contract/src/session-identity.js +37 -0
  101. package/dist/src/agent/memory/compaction-chunks.d.ts +18 -0
  102. package/dist/src/agent/memory/compaction-chunks.js +53 -0
  103. package/dist/src/agent/memory/compaction-request.d.ts +12 -0
  104. package/dist/src/agent/memory/compaction-request.js +72 -0
  105. package/dist/src/agent/memory/compaction.d.ts +3 -0
  106. package/dist/src/agent/memory/compaction.js +166 -118
  107. package/dist/src/agent/service.js +1 -0
  108. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  109. package/dist/src/agent/tool-manuals/xopc-use.js +19 -1
  110. package/dist/src/agent/tools/factory.js +1 -0
  111. package/dist/src/agent/tools/xopc-use-tool.d.ts +3 -2
  112. package/dist/src/agent/tools/xopc-use-tool.js +48 -4
  113. package/dist/src/browser/automations/schema.d.ts +1 -1
  114. package/dist/src/browser/automations/service.d.ts +1 -1
  115. package/dist/src/browser/native-messaging-host.js +3 -1
  116. package/dist/src/cli/commands/connectors.js +1 -1
  117. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  118. package/dist/src/cli/commands/tunnel.js +5 -0
  119. package/dist/src/connectors/connected-source-ingestion.js +1 -1
  120. package/dist/src/connectors/connected-source-normalizers.js +3 -0
  121. package/dist/src/connectors/connection-recovery-service.js +1 -1
  122. package/dist/src/connectors/health.js +1 -1
  123. package/dist/src/gateway/heartbeat/service.js +1 -1
  124. package/dist/src/gateway/hono/app.js +1 -0
  125. package/dist/src/gateway/hono/middleware/auth.d.ts +1 -2
  126. package/dist/src/gateway/hono/middleware/auth.js +49 -31
  127. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +11 -15
  128. package/dist/src/gateway/hono/routes/browser-session.d.ts +3 -0
  129. package/dist/src/gateway/hono/routes/browser-session.js +43 -0
  130. package/dist/src/gateway/hono/routes/capabilities.js +1 -1
  131. package/dist/src/gateway/hono/routes/connectors.js +1 -1
  132. package/dist/src/gateway/hono/routes/devices.js +61 -96
  133. package/dist/src/gateway/hono/routes/exposure.js +3 -7
  134. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  135. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  136. package/dist/src/gateway/hono/routes/models.js +60 -1
  137. package/dist/src/gateway/hono/routes/notes.js +3 -7
  138. package/dist/src/gateway/hono/routes/proactive-control.js +31 -24
  139. package/dist/src/gateway/hono/routes/sessions.js +11 -0
  140. package/dist/src/gateway/hono/routes/shares.js +8 -20
  141. package/dist/src/gateway/hono/routes/site-shares.js +4 -8
  142. package/dist/src/gateway/hono/routes/tunnel.js +13 -13
  143. package/dist/src/gateway/image-generation-setup.d.ts +17 -0
  144. package/dist/src/gateway/image-generation-setup.js +30 -21
  145. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  146. package/dist/src/gateway/rate-limit/buckets.js +10 -0
  147. package/dist/src/gateway/runtime-config.js +2 -0
  148. package/dist/src/gateway/security/browser-session.d.ts +5 -0
  149. package/dist/src/gateway/security/browser-session.js +45 -0
  150. package/dist/src/gateway/security/gateway-principal.d.ts +1 -0
  151. package/dist/src/gateway/service.d.ts +1 -0
  152. package/dist/src/gateway/service.js +21 -11
  153. package/dist/src/heartbeat/index.js +1 -1
  154. package/dist/src/infra/rate-limit/keyed-store.d.ts +3 -0
  155. package/dist/src/infra/rate-limit/keyed-store.js +9 -2
  156. package/dist/src/notifications/web-push.js +1 -1
  157. package/dist/src/proactive/actions/service.js +4 -2
  158. package/dist/src/proactive/execution/authorization.d.ts +2 -0
  159. package/dist/src/proactive/execution/authorization.js +39 -1
  160. package/dist/src/proactive/execution/context.d.ts +4 -0
  161. package/dist/src/proactive/execution/context.js +51 -5
  162. package/dist/src/proactive/execution/insight.js +3 -1
  163. package/dist/src/proactive/execution/repository.js +15 -5
  164. package/dist/src/proactive/execution/types.d.ts +2 -0
  165. package/dist/src/proactive/execution/worker.js +7 -2
  166. package/dist/src/proactive/experience.d.ts +69 -0
  167. package/dist/src/proactive/experience.js +90 -0
  168. package/dist/src/proactive/follow-ups.d.ts +123 -0
  169. package/dist/src/proactive/follow-ups.js +169 -0
  170. package/dist/src/proactive/inbox/cards.js +35 -6
  171. package/dist/src/proactive/inbox/delivery.js +4 -2
  172. package/dist/src/proactive/inbox/digest.js +2 -2
  173. package/dist/src/proactive/inbox/lifecycle.js +4 -1
  174. package/dist/src/proactive/inbox/notification-policy.js +4 -2
  175. package/dist/src/proactive/inbox/repository.js +17 -11
  176. package/dist/src/proactive/inbox/types.d.ts +2 -0
  177. package/dist/src/proactive/inbox/worker.js +1 -1
  178. package/dist/src/proactive/index.js +2 -2
  179. package/dist/src/proactive/mail-thread.d.ts +13 -0
  180. package/dist/src/proactive/mail-thread.js +54 -0
  181. package/dist/src/proactive/policy/service.d.ts +3 -5
  182. package/dist/src/proactive/policy/service.js +3 -5
  183. package/dist/src/proactive/scenarios/control.d.ts +4 -7
  184. package/dist/src/proactive/scenarios/control.js +3 -4
  185. package/dist/src/proactive/scenarios/preview.js +1 -1
  186. package/dist/src/proactive/scenarios/prompt-composer.js +2 -0
  187. package/dist/src/proactive/service.js +1 -1
  188. package/dist/src/proactive/temporal/worker.d.ts +1 -0
  189. package/dist/src/proactive/temporal/worker.js +18 -4
  190. package/dist/src/realtime/runtime.d.ts +2 -1
  191. package/dist/src/realtime/runtime.js +9 -3
  192. package/dist/src/realtime/tickets.d.ts +1 -0
  193. package/dist/src/realtime/tickets.js +3 -0
  194. package/dist/src/session/store.d.ts +2 -0
  195. package/dist/src/session/store.js +17 -2
  196. package/dist/src/session/types.d.ts +2 -1
  197. package/dist/src/storage/sqlite/browser-session-repository.d.ts +17 -0
  198. package/dist/src/storage/sqlite/browser-session-repository.js +54 -0
  199. package/dist/src/storage/sqlite/device-pairing-approval.js +2 -1
  200. package/dist/src/storage/sqlite/device-pairing-repository.d.ts +4 -10
  201. package/dist/src/storage/sqlite/device-pairing-repository.js +10 -62
  202. package/dist/src/storage/sqlite/index.d.ts +1 -1
  203. package/dist/src/storage/sqlite/index.js +2 -2
  204. package/dist/src/storage/sqlite/migrations/162_proactive_product.sql +7 -0
  205. package/dist/src/storage/sqlite/migrations/163_proactive_follow_ups.sql +29 -0
  206. package/dist/src/storage/sqlite/migrations/164_browser_sessions.sql +8 -0
  207. package/dist/src/storage/sqlite/migrations/165_device_pairing_target.sql +40 -0
  208. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  209. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  210. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  211. package/dist/src/storage/sqlite/schema.js +1 -1
  212. package/dist/src/storage/sqlite/session-identity-sql.d.ts +2 -0
  213. package/dist/src/storage/sqlite/session-identity-sql.js +18 -0
  214. package/dist/src/storage/sqlite/session-repository.js +26 -22
  215. package/dist/src/tasks/home-query-service.js +1 -1
  216. package/dist/src/tasks/index.js +4 -4
  217. package/dist/src/tui/tui-startup-resources.js +1 -1
  218. package/dist/src/tunnel/auth-policy.d.ts +3 -0
  219. package/dist/src/tunnel/auth-policy.js +8 -0
  220. package/dist/src/tunnel/broker-client.d.ts +5 -15
  221. package/dist/src/tunnel/broker-client.js +37 -49
  222. package/dist/src/tunnel/frpc-binary.d.ts +8 -6
  223. package/dist/src/tunnel/frpc-binary.js +76 -88
  224. package/dist/src/tunnel/frpc-config.d.ts +2 -1
  225. package/dist/src/tunnel/frpc-config.js +29 -12
  226. package/dist/src/tunnel/frpc-release.d.ts +27 -0
  227. package/dist/src/tunnel/frpc-release.js +30 -0
  228. package/dist/src/tunnel/gateway-lifecycle.js +8 -2
  229. package/dist/src/tunnel/index.js +2 -1
  230. package/dist/src/tunnel/registration-proof.d.ts +19 -0
  231. package/dist/src/tunnel/registration-proof.js +37 -0
  232. package/dist/src/tunnel/tunnel-persist.js +3 -1
  233. package/dist/src/tunnel/tunnel-service.d.ts +1 -0
  234. package/dist/src/tunnel/tunnel-service.js +35 -8
  235. package/dist/src/tunnel/tunnel-state.js +11 -5
  236. package/dist/src/tunnel/tunnel-types.d.ts +2 -0
  237. package/dist/src/tunnel/well-known.js +5 -1
  238. package/dist/src/user-context/config.js +2 -2
  239. package/dist/src/utils/logger/redact.js +4 -0
  240. package/dist/src/voice/dashscope/streaming-stt-session.js +1 -0
  241. package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +1 -0
  242. package/dist/src/voice/dashscope/streaming-tts-stream.js +8 -0
  243. package/dist/src/voice/realtime/agentBroker.js +1 -1
  244. package/dist/src/voice/realtime/agentEngine.js +1 -1
  245. package/dist/src/voice/realtime/pcm-output-gain.d.ts +2 -0
  246. package/dist/src/voice/realtime/pcm-output-gain.js +16 -0
  247. package/dist/src/voice/realtime/runtime.d.ts +1 -0
  248. package/dist/src/voice/realtime/runtime.js +21 -3
  249. package/dist/src/voice/realtime/runtime.types.d.ts +1 -0
  250. package/dist/src/workflows/service/workflow-run-service.js +3 -1
  251. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
  252. package/dist/src/workflows/service/workflow-session-bridge.js +1 -0
  253. package/package.json +4 -4
  254. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-qKCezlBg.js +0 -1
  255. package/dist/gateway/static/root/assets/agents-BMhnZKhP.js +0 -1
  256. package/dist/gateway/static/root/assets/apps-page-DduJDWGY.js +0 -1
  257. package/dist/gateway/static/root/assets/automations-workspace-X7hNHCjW.js +0 -6
  258. package/dist/gateway/static/root/assets/browser-settings-page-BZ7nK_pN.js +0 -8
  259. package/dist/gateway/static/root/assets/capabilities-settings-panel-BfKvJO1C.js +0 -7
  260. package/dist/gateway/static/root/assets/channels-settings-D1UDxJuA.js +0 -1
  261. package/dist/gateway/static/root/assets/connectors-page-C2nuqs_O.js +0 -2
  262. package/dist/gateway/static/root/assets/cron-expression-DlyRIyUn.js +0 -2
  263. package/dist/gateway/static/root/assets/date-picker-CU-ij_yE.js +0 -1
  264. package/dist/gateway/static/root/assets/extension-settings-page-CMyt0A32.js +0 -1
  265. package/dist/gateway/static/root/assets/gateway-settings-ogv8ZbvG.js +0 -1
  266. package/dist/gateway/static/root/assets/heartbeat-settings-BnrMRKaZ.js +0 -1
  267. package/dist/gateway/static/root/assets/home-page-CbcJCREd.js +0 -1
  268. package/dist/gateway/static/root/assets/index-7PZ6jmhy.css +0 -2
  269. package/dist/gateway/static/root/assets/index-CfyyA9-g.js +0 -74
  270. package/dist/gateway/static/root/assets/local-app-workbench-page-D5XVZnK1.js +0 -2
  271. package/dist/gateway/static/root/assets/locale-store-BQ2HKTWb.js +0 -1
  272. package/dist/gateway/static/root/assets/logs-page-CWDU1AGN.js +0 -2
  273. package/dist/gateway/static/root/assets/management-settings-CuFNgQUy.js +0 -1
  274. package/dist/gateway/static/root/assets/mobile-pairing-wizard-C7d_ztgp.js +0 -1
  275. package/dist/gateway/static/root/assets/note-detail-panel-D5JuBLyt.js +0 -5
  276. package/dist/gateway/static/root/assets/notes-page-C5-ccCi4.js +0 -8
  277. package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +0 -1
  278. package/dist/gateway/static/root/assets/proactive-page-fHjPigmx.js +0 -1
  279. package/dist/gateway/static/root/assets/project-detail-page-6v_khvEt.js +0 -1
  280. package/dist/gateway/static/root/assets/projects-page-CCy1aK4V.js +0 -1
  281. package/dist/gateway/static/root/assets/remote-access-hub-pkqKRnch.js +0 -1
  282. package/dist/gateway/static/root/assets/sessions-page-Cr4E4cap.js +0 -1
  283. package/dist/gateway/static/root/assets/settings-advanced-gate-D1JRDRyL.js +0 -1
  284. package/dist/gateway/static/root/assets/setup-status-panel-Cc_iP_vv.js +0 -1
  285. package/dist/gateway/static/root/assets/shares-settings-BrMECMAB.js +0 -1
  286. package/dist/gateway/static/root/assets/skill-reload-api-DuqIDYjc.js +0 -1
  287. package/dist/gateway/static/root/assets/skills-page.utils-D1wGfm22.js +0 -1
  288. package/dist/gateway/static/root/assets/task-detail-page-m0oXUKl2.js +0 -1
  289. package/dist/gateway/static/root/assets/tunnel-api-Dur80zSQ.js +0 -1
  290. package/dist/gateway/static/root/assets/user-model-page-Dl10D_5q.js +0 -2
  291. package/dist/gateway/static/root/assets/workflows-page-CswgoIFU.js +0 -6
  292. package/dist/src/proactive/actions/workflow.d.ts +0 -15
  293. package/dist/src/proactive/actions/workflow.js +0 -88
@@ -1 +1 @@
1
- export declare const xopcUseManual = "# XOPC Use Tool Manual\n\n## Purpose\n\n`xopc_use` operates first-class XOPC product objects without editing SQLite or product files directly.\nLoad this manual before a non-trivial mutation.\n\n```json\n{\n \"mode\": \"project | automation | note | task | task_run | local_app | settings\",\n \"command\": \"...\",\n \"args\": {},\n \"dryRun\": false\n}\n```\n\nSend one object command per call. Inspect the returned JSON `ok` field; a tool call can\ncomplete successfully while the product command returns `ok: false`.\n\n## Object routing\n\n| Object | Tool |\n| --- | --- |\n| Project, milestone, project update | `xopc_use` mode `project` |\n| Automation | `xopc_use` mode `automation` |\n| Task intent and lifecycle | `xopc_use` mode `task` |\n| Task execution attempt, receipt, events and waits | `xopc_use` mode `task_run` |\n| Note | `xopc_use` mode `note` |\n| Local app | `xopc_use` mode `local_app` |\n| Settings jump target | `xopc_use` mode `settings` |\n| Workflow run | dedicated `workflow` tool; pass `taskId` to link it to a Task |\n| Session, memory, skill, connected app or workspace file | its dedicated tool |\n\nDo not emulate Workflow APIs through `xopc_use`. A Task is durable intent;\na TaskRun is one execution attempt; a WorkflowRun is a procedure execution and may belong\nto a TaskRun. Never treat these three objects as interchangeable.\n\n## Reliable protocol\n\n1. Use `list` then `get` when an id is unknown.\n2. Read the current `version` before a Task mutation.\n3. Use `dryRun: true` for broad Project changes or uncertain mutations.\n4. Mutate once with the exact id and current concurrency token.\n5. Verify the returned object and preserve any \u201COpen in xopc\u201D delivery link.\n6. On a conflict, read again and reconsider the operation; do not blindly retry.\n\nTimestamps are Unix epoch milliseconds. Array fields are arrays of strings. Omission\npreserves a patchable field; an empty array intentionally clears it. Prefer explicit\n`projectId`, `taskId`, `runId`, `noteId`, and `localAppId` fields over `id`.\n\n## Projects\n\nCommands: `list`, `get`, `create`, `update`, `resolve_workspace`,\n`list_milestones`, `create_milestone`, `update_milestone`, `list_updates`,\nand `create_update`.\n\nProject statuses: `planned`, `active`, `paused`, `completed`, `cancelled`,\n`archived`. Health values: `unknown`, `on_track`, `at_risk`, `off_track`.\n\nA Project defines bounded shared context for related work. Its durable planning fields are `outcome`,\n`successCriteria`, `scope`, `nonGoals`, `ownerId`, `targetAt`, and `health`.\nUse `brief` for a concise description and `instructions` for durable operating guidance.\n\n### Create\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create\",\n \"args\": {\n \"name\": \"AI Product Research\",\n \"outcome\": \"Choose a validated product direction\",\n \"successCriteria\": [\"Ten customer interviews\", \"Decision recorded\"],\n \"scope\": { \"market\": \"developer tools\" },\n \"nonGoals\": [\"Build the production product\"],\n \"health\": \"on_track\",\n \"targetAt\": 1760000000000,\n \"workspaceRoot\": \"/path/to/repo\"\n }\n}\n```\n\n### Update\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"update\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"status\": \"active\",\n \"health\": \"at_risk\",\n \"successCriteria\": [\"Ten interviews\", \"Evidence-backed decision\"]\n }\n}\n```\n\n### Resolve a workspace\n\nUse `autoCreate: false` for lookup. Set it to true only when creating a Project is authorized.\n\n```json\n{ \"mode\": \"project\", \"command\": \"resolve_workspace\", \"args\": { \"workspacePath\": \"/path/to/repo\", \"autoCreate\": false } }\n```\n\n### Milestones\n\nMilestone statuses: `planned`, `active`, `completed`, `cancelled`.\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create_milestone\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"title\": \"Finish discovery\",\n \"status\": \"active\",\n \"targetAt\": 1760000000000,\n \"sortOrder\": 10\n }\n}\n```\n\nUse `list_milestones` with `projectId`. Use `update_milestone` with both\n`projectId` and `milestoneId`. Milestone deletion is intentionally not exposed.\n\n### Immutable project updates\n\nProject updates are append-only progress snapshots. They also update Project health.\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create_update\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"health\": \"on_track\",\n \"summary\": \"Discovery is complete\",\n \"progress\": [\"Interviewed ten users\"],\n \"risks\": [\"Pricing remains unvalidated\"],\n \"nextSteps\": [\"Run pricing tests\"]\n }\n}\n```\n\nUse `list_updates` with `projectId` and optional `limit`. Updates cannot be edited.\n\n## Automations\n\nCommands: `list`, `get`, `create`, `update`, `delete`, `run`, `pause`,\n`resume`, and `history`.\n\nAutomation `create` automatically uses the current session Project when `projectId` is\nomitted. An explicit `projectId` takes precedence and is validated before mutation. Use an\nexplicit id when creating for a Project other than the current session Project.\n\n### Create in the current Project\n\n`trigger` and `action` use the same shapes as the Automation product API.\n\n```json\n{\n \"mode\": \"automation\",\n \"command\": \"create\",\n \"args\": {\n \"name\": \"Daily project review\",\n \"trigger\": { \"kind\": \"schedule\", \"schedule\": { \"kind\": \"cron\", \"expr\": \"0 9 * * 1-5\", \"tz\": \"Asia/Shanghai\" } },\n \"action\": { \"kind\": \"agent\", \"instruction\": \"Review the current project and summarize risks.\" }\n }\n}\n```\n\nTo override the inherited Project, add `\"projectId\": \"project_id\"` to `args`.\nThe create payload may also be nested under `args.automation`; top-level `args.projectId`\nhas precedence.\n\n### List and history\n\n`list` and unqualified `history` inherit the current session Project. Pass an explicit\n`projectId` to query another Project. Pass `automationId` to `history` for one Automation.\n\n### Update and operate\n\nUse `automationId` for `get`, `update`, `delete`, `run`, `pause`, and `resume`.\nFor `update`, patch fields may be direct args or nested under `args.patch`. Supplying a new\n`projectId` reassigns the Automation after validating the target Project.\n\n## Tasks\n\nCommands: `list`, `get`, `create`, `update_dependencies`, `add_context`,\n`remove_context`, `command`, and `delete`.\n\nTask phases are `backlog`, `ready`, `active`, `review`, and `closed`.\nOperational state is projected separately as `idle`, `queued`, `running`, `waiting`,\n`verifying`, `succeeded`, `failed`, or `cancelled`. Never send either value as a\nfree-form status update.\n\n`task.get` returns the Task, its projected `model`, dependencies, dependents, context,\nauthority grants, TaskRuns, receipts, and waits.\nThe projected model is the correct source for current operational state and attention items.\n\n`delete` permanently removes the Task and its contracts, waits, context links, TaskRuns,\nreceipts, and Task-owned execution records. It does not delete linked Sessions, workspace files,\nor external artifacts. Cancel an active TaskRun before deletion, and use `dryRun: true` when\nthe user's intent is ambiguous.\n\n```json\n{ \"mode\": \"task\", \"command\": \"delete\", \"args\": { \"taskId\": \"task_id\" }, \"dryRun\": true }\n```\n\n### Capture or start\n\n`createMode` defaults to `capture`, which creates a backlog Task without executing it.\nUse `start` only when immediate execution is intended.\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"create\",\n \"args\": {\n \"objective\": \"Complete the customer research report\",\n \"projectId\": \"project_id\",\n \"createMode\": \"capture\",\n \"priority\": \"high\",\n \"expectedOutputs\": [\"Research report\"],\n \"acceptanceCriteria\": [\"Sources are cited\"],\n \"constraints\": [\"Do not contact customers without approval\"],\n \"dependsOnTaskIds\": []\n }\n}\n```\n\n### Dependencies\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"update_dependencies\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"expectedVersion\": 3,\n \"dependsOnTaskIds\": [\"dependency_task_id\"]\n }\n}\n```\n\n### Context links\n\nUse `add_context` to link a document, file, URL, session, memory, Task, artifact, or source\nas `input`, `reference`, `constraint`, `deliverable`, or `evidence` context.\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"add_context\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"targetKind\": \"file\",\n \"targetId\": \"/path/to/spec.md\",\n \"role\": \"input\",\n \"title\": \"Product specification\",\n \"pinned\": true,\n \"retrievalPolicy\": {},\n \"metadata\": {}\n }\n}\n```\n\nUse `remove_context` with `taskId` and the exact `edgeId` returned by `task.get`.\nDo not add authority grants through this tool; an Agent must not authorize itself.\n\n### Typed lifecycle commands\n\nEvery command requires `taskId`, the Task's current `expectedVersion`, a `type`, and\ntype-specific fields inside `commandArgs`.\n\nSupported command types:\n\n- `mark_ready`\n- `start`: `{ \"executor\": { \"kind\": \"agent\", \"agentId\": \"main\" } }`\n- `request_review`\n- `close`: `{ \"resolution\": \"done | cancelled | duplicate | wont_do\" }`\n- `reopen`: `{ \"phase\": \"ready | active\" }`\n- `add_wait`: `{ \"wait\": { \"kind\": \"dependency | approval | input | schedule | external | paused\", \"reason\": \"...\", \"condition\": {} } }`\n- `resolve_wait`: `{ \"waitId\": \"wait_id\", \"resolution\": {} }`\n- `delegate`: `{ \"agentId\": \"agent_id\" }`\n- `revise_contract`: `{ \"contract\": { ...complete contract... } }`\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"command\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"expectedVersion\": 3,\n \"type\": \"start\",\n \"commandArgs\": {\n \"executor\": { \"kind\": \"agent\", \"agentId\": \"main\" }\n }\n }\n}\n```\n\nContract revision is replacement, not a patch. Read the Task and preserve all contract fields\nthe user did not ask to change. Resolve a wait through `resolve_wait`; do not directly mutate\na TaskRun or manufacture a phase transition.\n\n## TaskRuns\n\nTaskRun inspection is read-only except for explicit cancellation. Other execution state is\ncontrolled by Task commands and the runtime coordinator.\n\n### List attempts for a Task\n\n```json\n{ \"mode\": \"task_run\", \"command\": \"list\", \"args\": { \"taskId\": \"task_id\", \"limit\": 20 } }\n```\n\nThe result contains run attempts, finalized receipts, and active waits.\n\n### Inspect one attempt\n\n```json\n{ \"mode\": \"task_run\", \"command\": \"get\", \"args\": { \"runId\": \"run_id\" } }\n```\n\nThe result contains the TaskRun, its receipt when terminal, ordered events, and active Task waits.\n\n### Cancel an attempt\n\nRead the run first, then pass its current version. Cancellation creates a terminal receipt.\n\n```json\n{\n \"mode\": \"task_run\",\n \"command\": \"cancel\",\n \"args\": { \"runId\": \"run_id\", \"expectedVersion\": 2, \"reason\": \"User cancelled execution\" }\n}\n```\n\nDo not guess commands such as retry, force-complete, heartbeat, or transition; they are not Agent APIs.\n\n## Notes\n\nCommands: `list`, `get`, `create`, `append`, `preview_edit`, `update`, and `delete`.\nUse Notes for durable prose and reference material, not as a Task substitute. Prefer `append`\nwhen preserving user content. Use `preview_edit` before a canonical rewrite.\n\n```json\n{ \"mode\": \"note\", \"command\": \"create\", \"args\": { \"title\": \"Decision\", \"markdown\": \"...\", \"projectId\": \"project_id\" } }\n```\n\n```json\n{ \"mode\": \"note\", \"command\": \"append\", \"args\": { \"noteId\": \"note_id\", \"heading\": \"AI synthesis\", \"content\": \"...\" } }\n```\n\nUse `update` with `status: \"trashed\"` for a recoverable removal. `delete` permanently\nremoves the Note and its stored snapshots and media; use `dryRun: true` first when the\nuser's intent is ambiguous.\n\n```json\n{ \"mode\": \"note\", \"command\": \"delete\", \"args\": { \"noteId\": \"note_id\" }, \"dryRun\": true }\n```\n\n## Local apps and settings\n\nLocal app commands are `list`, `get`, `create`, and `validate`. Installation,\nactivation, rollback, and uninstall remain product runtime operations.\n\nSettings supports only `open` and returns an exact product jump target without changing config.\n\n## Error recovery\n\n| Result | Recovery |\n| --- | --- |\n| service unavailable | Stop retrying and report the unavailable capability. |\n| not found | Re-list in the intended scope; do not invent another id. |\n| conflict | Read the current object and reassess using its latest version. |\n| waiting | Inspect the Task projection and TaskRun waits; resolve only the real blocker. |\n| invalid command or state | Read the object and use only a documented transition. |\n| unsupported operation | Use the dedicated tool or product UI; never write storage directly. |\n\n## Deliberate boundaries\n\n- Project deletion and milestone deletion are not Agent APIs.\n- TaskRun mutation is internal to execution coordination except for optimistic cancellation.\n- Project updates are immutable.\n- Workflow and Automation operations remain in their dedicated tools.\n- Only the documented Task and TaskRun commands are valid; do not infer hidden aliases.\n";
1
+ export declare const xopcUseManual = "# XOPC Use Tool Manual\n\n## Purpose\n\n`xopc_use` operates first-class XOPC product objects without editing SQLite or product files directly.\nLoad this manual before a non-trivial mutation.\n\n```json\n{\n \"mode\": \"project | proactive | automation | note | task | task_run | local_app | settings\",\n \"command\": \"...\",\n \"args\": {},\n \"dryRun\": false\n}\n```\n\nSend one object command per call. Inspect the returned JSON `ok` field; a tool call can\ncomplete successfully while the product command returns `ok: false`.\n\n## Proactive delegation\n\nUse mode proactive only for explicit user delegation. Inspect list before start; edit existing subscriptions instead of duplicating them.\nFor one email thread, call mail_sources, then follow_up with sourceItemId, instructions and dueAt (ISO timestamp).\nUse update_follow_up with the current expectedRevision to pause, resume, adjust the deadline or end the delegation.\nOn a communication card, continue_card with its id reads current work and binds this conversation to the delegation.\nUse the returned exact connectionId when retrieving or replying to the thread. Review current recipients and the full draft with the user and retain connector confirmation for sending. Never mark sent from an approval alone; require a successful provider receipt. The delegation continues watching synchronized replies until explicitly ended.\n\n## Object routing\n\n| Object | Tool |\n| --- | --- |\n| Project, milestone, project update | `xopc_use` mode `project` |\n| Automation | `xopc_use` mode `automation` |\n| Task intent and lifecycle | `xopc_use` mode `task` |\n| Task execution attempt, receipt, events and waits | `xopc_use` mode `task_run` |\n| Note | `xopc_use` mode `note` |\n| Local app | `xopc_use` mode `local_app` |\n| Settings jump target | `xopc_use` mode `settings` |\n| Workflow run | dedicated `workflow` tool; pass `taskId` to link it to a Task |\n| Session, memory, skill, connected app or workspace file | its dedicated tool |\n\nDo not emulate Workflow APIs through `xopc_use`. A Task is durable intent;\na TaskRun is one execution attempt; a WorkflowRun is a procedure execution and may belong\nto a TaskRun. Never treat these three objects as interchangeable.\n\n## Reliable protocol\n\n1. Use `list` then `get` when an id is unknown.\n2. Read the current `version` before a Task mutation.\n3. Use `dryRun: true` for broad Project changes or uncertain mutations.\n4. Mutate once with the exact id and current concurrency token.\n5. Verify the returned object and preserve any \u201COpen in xopc\u201D delivery link.\n6. On a conflict, read again and reconsider the operation; do not blindly retry.\n\nTimestamps are Unix epoch milliseconds. Array fields are arrays of strings. Omission\npreserves a patchable field; an empty array intentionally clears it. Prefer explicit\n`projectId`, `taskId`, `runId`, `noteId`, and `localAppId` fields over `id`.\n\n## Proactive delegated work\n\nUse mode `proactive` for work the user asks the assistant to keep following.\nUse `list` before starting; update existing delegations instead of duplicating them.\n- `start`: {scenarioKey: \"project_delivery_risk\" | \"meeting_preparation\" | \"discussion_follow_up\", projectId?: string, instructions: string}.\n- `update`: {id, expectedRevision, userInstructions?, enabled?, completedAt?}. Read the revision from list. completedAt is an ISO timestamp; ending work also sets enabled false.\n- `check`: {id}, for project checks.\n- `get_card`: {id}, reads the current authorized artifact and action state before discussing it.\nInstructions adjust what to watch; they never grant new action permissions. Distinguish a task being created from its work being completed. Do not claim a draft was sent.\n\n## Projects\n\nCommands: `list`, `get`, `create`, `update`, `resolve_workspace`,\n`list_milestones`, `create_milestone`, `update_milestone`, `list_updates`,\nand `create_update`.\n\nProject statuses: `planned`, `active`, `paused`, `completed`, `cancelled`,\n`archived`. Health values: `unknown`, `on_track`, `at_risk`, `off_track`.\n\nA Project defines bounded shared context for related work. Its durable planning fields are `outcome`,\n`successCriteria`, `scope`, `nonGoals`, `ownerId`, `targetAt`, and `health`.\nUse `brief` for a concise description and `instructions` for durable operating guidance.\n\n### Create\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create\",\n \"args\": {\n \"name\": \"AI Product Research\",\n \"outcome\": \"Choose a validated product direction\",\n \"successCriteria\": [\"Ten customer interviews\", \"Decision recorded\"],\n \"scope\": { \"market\": \"developer tools\" },\n \"nonGoals\": [\"Build the production product\"],\n \"health\": \"on_track\",\n \"targetAt\": 1760000000000,\n \"workspaceRoot\": \"/path/to/repo\"\n }\n}\n```\n\n### Update\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"update\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"status\": \"active\",\n \"health\": \"at_risk\",\n \"successCriteria\": [\"Ten interviews\", \"Evidence-backed decision\"]\n }\n}\n```\n\n### Resolve a workspace\n\nUse `autoCreate: false` for lookup. Set it to true only when creating a Project is authorized.\n\n```json\n{ \"mode\": \"project\", \"command\": \"resolve_workspace\", \"args\": { \"workspacePath\": \"/path/to/repo\", \"autoCreate\": false } }\n```\n\n### Milestones\n\nMilestone statuses: `planned`, `active`, `completed`, `cancelled`.\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create_milestone\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"title\": \"Finish discovery\",\n \"status\": \"active\",\n \"targetAt\": 1760000000000,\n \"sortOrder\": 10\n }\n}\n```\n\nUse `list_milestones` with `projectId`. Use `update_milestone` with both\n`projectId` and `milestoneId`. Milestone deletion is intentionally not exposed.\n\n### Immutable project updates\n\nProject updates are append-only progress snapshots. They also update Project health.\n\n```json\n{\n \"mode\": \"project\",\n \"command\": \"create_update\",\n \"args\": {\n \"projectId\": \"project_id\",\n \"health\": \"on_track\",\n \"summary\": \"Discovery is complete\",\n \"progress\": [\"Interviewed ten users\"],\n \"risks\": [\"Pricing remains unvalidated\"],\n \"nextSteps\": [\"Run pricing tests\"]\n }\n}\n```\n\nUse `list_updates` with `projectId` and optional `limit`. Updates cannot be edited.\n\n## Automations\n\nCommands: `list`, `get`, `create`, `update`, `delete`, `run`, `pause`,\n`resume`, and `history`.\n\nAutomation `create` automatically uses the current session Project when `projectId` is\nomitted. An explicit `projectId` takes precedence and is validated before mutation. Use an\nexplicit id when creating for a Project other than the current session Project.\n\n### Create in the current Project\n\n`trigger` and `action` use the same shapes as the Automation product API.\n\n```json\n{\n \"mode\": \"automation\",\n \"command\": \"create\",\n \"args\": {\n \"name\": \"Daily project review\",\n \"trigger\": { \"kind\": \"schedule\", \"schedule\": { \"kind\": \"cron\", \"expr\": \"0 9 * * 1-5\", \"tz\": \"Asia/Shanghai\" } },\n \"action\": { \"kind\": \"agent\", \"instruction\": \"Review the current project and summarize risks.\" }\n }\n}\n```\n\nTo override the inherited Project, add `\"projectId\": \"project_id\"` to `args`.\nThe create payload may also be nested under `args.automation`; top-level `args.projectId`\nhas precedence.\n\n### List and history\n\n`list` and unqualified `history` inherit the current session Project. Pass an explicit\n`projectId` to query another Project. Pass `automationId` to `history` for one Automation.\n\n### Update and operate\n\nUse `automationId` for `get`, `update`, `delete`, `run`, `pause`, and `resume`.\nFor `update`, patch fields may be direct args or nested under `args.patch`. Supplying a new\n`projectId` reassigns the Automation after validating the target Project.\n\n## Tasks\n\nCommands: `list`, `get`, `create`, `update_dependencies`, `add_context`,\n`remove_context`, `command`, and `delete`.\n\nTask phases are `backlog`, `ready`, `active`, `review`, and `closed`.\nOperational state is projected separately as `idle`, `queued`, `running`, `waiting`,\n`verifying`, `succeeded`, `failed`, or `cancelled`. Never send either value as a\nfree-form status update.\n\n`task.get` returns the Task, its projected `model`, dependencies, dependents, context,\nauthority grants, TaskRuns, receipts, and waits.\nThe projected model is the correct source for current operational state and attention items.\n\n`delete` permanently removes the Task and its contracts, waits, context links, TaskRuns,\nreceipts, and Task-owned execution records. It does not delete linked Sessions, workspace files,\nor external artifacts. Cancel an active TaskRun before deletion, and use `dryRun: true` when\nthe user's intent is ambiguous.\n\n```json\n{ \"mode\": \"task\", \"command\": \"delete\", \"args\": { \"taskId\": \"task_id\" }, \"dryRun\": true }\n```\n\n### Capture or start\n\n`createMode` defaults to `capture`, which creates a backlog Task without executing it.\nUse `start` only when immediate execution is intended.\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"create\",\n \"args\": {\n \"objective\": \"Complete the customer research report\",\n \"projectId\": \"project_id\",\n \"createMode\": \"capture\",\n \"priority\": \"high\",\n \"expectedOutputs\": [\"Research report\"],\n \"acceptanceCriteria\": [\"Sources are cited\"],\n \"constraints\": [\"Do not contact customers without approval\"],\n \"dependsOnTaskIds\": []\n }\n}\n```\n\n### Dependencies\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"update_dependencies\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"expectedVersion\": 3,\n \"dependsOnTaskIds\": [\"dependency_task_id\"]\n }\n}\n```\n\n### Context links\n\nUse `add_context` to link a document, file, URL, session, memory, Task, artifact, or source\nas `input`, `reference`, `constraint`, `deliverable`, or `evidence` context.\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"add_context\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"targetKind\": \"file\",\n \"targetId\": \"/path/to/spec.md\",\n \"role\": \"input\",\n \"title\": \"Product specification\",\n \"pinned\": true,\n \"retrievalPolicy\": {},\n \"metadata\": {}\n }\n}\n```\n\nUse `remove_context` with `taskId` and the exact `edgeId` returned by `task.get`.\nDo not add authority grants through this tool; an Agent must not authorize itself.\n\n### Typed lifecycle commands\n\nEvery command requires `taskId`, the Task's current `expectedVersion`, a `type`, and\ntype-specific fields inside `commandArgs`.\n\nSupported command types:\n\n- `mark_ready`\n- `start`: `{ \"executor\": { \"kind\": \"agent\", \"agentId\": \"main\" } }`\n- `request_review`\n- `close`: `{ \"resolution\": \"done | cancelled | duplicate | wont_do\" }`\n- `reopen`: `{ \"phase\": \"ready | active\" }`\n- `add_wait`: `{ \"wait\": { \"kind\": \"dependency | approval | input | schedule | external | paused\", \"reason\": \"...\", \"condition\": {} } }`\n- `resolve_wait`: `{ \"waitId\": \"wait_id\", \"resolution\": {} }`\n- `delegate`: `{ \"agentId\": \"agent_id\" }`\n- `revise_contract`: `{ \"contract\": { ...complete contract... } }`\n\n```json\n{\n \"mode\": \"task\",\n \"command\": \"command\",\n \"args\": {\n \"taskId\": \"task_id\",\n \"expectedVersion\": 3,\n \"type\": \"start\",\n \"commandArgs\": {\n \"executor\": { \"kind\": \"agent\", \"agentId\": \"main\" }\n }\n }\n}\n```\n\nContract revision is replacement, not a patch. Read the Task and preserve all contract fields\nthe user did not ask to change. Resolve a wait through `resolve_wait`; do not directly mutate\na TaskRun or manufacture a phase transition.\n\n## TaskRuns\n\nTaskRun inspection is read-only except for explicit cancellation. Other execution state is\ncontrolled by Task commands and the runtime coordinator.\n\n### List attempts for a Task\n\n```json\n{ \"mode\": \"task_run\", \"command\": \"list\", \"args\": { \"taskId\": \"task_id\", \"limit\": 20 } }\n```\n\nThe result contains run attempts, finalized receipts, and active waits.\n\n### Inspect one attempt\n\n```json\n{ \"mode\": \"task_run\", \"command\": \"get\", \"args\": { \"runId\": \"run_id\" } }\n```\n\nThe result contains the TaskRun, its receipt when terminal, ordered events, and active Task waits.\n\n### Cancel an attempt\n\nRead the run first, then pass its current version. Cancellation creates a terminal receipt.\n\n```json\n{\n \"mode\": \"task_run\",\n \"command\": \"cancel\",\n \"args\": { \"runId\": \"run_id\", \"expectedVersion\": 2, \"reason\": \"User cancelled execution\" }\n}\n```\n\nDo not guess commands such as retry, force-complete, heartbeat, or transition; they are not Agent APIs.\n\n## Notes\n\nCommands: `list`, `get`, `create`, `append`, `preview_edit`, `update`, and `delete`.\nUse Notes for durable prose and reference material, not as a Task substitute. Prefer `append`\nwhen preserving user content. Use `preview_edit` before a canonical rewrite.\n\n```json\n{ \"mode\": \"note\", \"command\": \"create\", \"args\": { \"title\": \"Decision\", \"markdown\": \"...\", \"projectId\": \"project_id\" } }\n```\n\n```json\n{ \"mode\": \"note\", \"command\": \"append\", \"args\": { \"noteId\": \"note_id\", \"heading\": \"AI synthesis\", \"content\": \"...\" } }\n```\n\nUse `update` with `status: \"trashed\"` for a recoverable removal. `delete` permanently\nremoves the Note and its stored snapshots and media; use `dryRun: true` first when the\nuser's intent is ambiguous.\n\n```json\n{ \"mode\": \"note\", \"command\": \"delete\", \"args\": { \"noteId\": \"note_id\" }, \"dryRun\": true }\n```\n\n## Local apps and settings\n\nLocal app commands are `list`, `get`, `create`, and `validate`. Installation,\nactivation, rollback, and uninstall remain product runtime operations.\n\nSettings supports only `open` and returns an exact product jump target without changing config.\n\n## Error recovery\n\n| Result | Recovery |\n| --- | --- |\n| service unavailable | Stop retrying and report the unavailable capability. |\n| not found | Re-list in the intended scope; do not invent another id. |\n| conflict | Read the current object and reassess using its latest version. |\n| waiting | Inspect the Task projection and TaskRun waits; resolve only the real blocker. |\n| invalid command or state | Read the object and use only a documented transition. |\n| unsupported operation | Use the dedicated tool or product UI; never write storage directly. |\n\n## Deliberate boundaries\n\n- Project deletion and milestone deletion are not Agent APIs.\n- TaskRun mutation is internal to execution coordination except for optimistic cancellation.\n- Project updates are immutable.\n- Workflow and Automation operations remain in their dedicated tools.\n- Only the documented Task and TaskRun commands are valid; do not infer hidden aliases.\n";
@@ -8,7 +8,7 @@ Load this manual before a non-trivial mutation.
8
8
 
9
9
  \`\`\`json
10
10
  {
11
- "mode": "project | automation | note | task | task_run | local_app | settings",
11
+ "mode": "project | proactive | automation | note | task | task_run | local_app | settings",
12
12
  "command": "...",
13
13
  "args": {},
14
14
  "dryRun": false
@@ -18,6 +18,14 @@ Load this manual before a non-trivial mutation.
18
18
  Send one object command per call. Inspect the returned JSON \`ok\` field; a tool call can
19
19
  complete successfully while the product command returns \`ok: false\`.
20
20
 
21
+ ## Proactive delegation
22
+
23
+ Use mode proactive only for explicit user delegation. Inspect list before start; edit existing subscriptions instead of duplicating them.
24
+ For one email thread, call mail_sources, then follow_up with sourceItemId, instructions and dueAt (ISO timestamp).
25
+ Use update_follow_up with the current expectedRevision to pause, resume, adjust the deadline or end the delegation.
26
+ On a communication card, continue_card with its id reads current work and binds this conversation to the delegation.
27
+ Use the returned exact connectionId when retrieving or replying to the thread. Review current recipients and the full draft with the user and retain connector confirmation for sending. Never mark sent from an approval alone; require a successful provider receipt. The delegation continues watching synchronized replies until explicitly ended.
28
+
21
29
  ## Object routing
22
30
 
23
31
  | Object | Tool |
@@ -49,6 +57,16 @@ Timestamps are Unix epoch milliseconds. Array fields are arrays of strings. Omis
49
57
  preserves a patchable field; an empty array intentionally clears it. Prefer explicit
50
58
  \`projectId\`, \`taskId\`, \`runId\`, \`noteId\`, and \`localAppId\` fields over \`id\`.
51
59
 
60
+ ## Proactive delegated work
61
+
62
+ Use mode \`proactive\` for work the user asks the assistant to keep following.
63
+ Use \`list\` before starting; update existing delegations instead of duplicating them.
64
+ - \`start\`: {scenarioKey: "project_delivery_risk" | "meeting_preparation" | "discussion_follow_up", projectId?: string, instructions: string}.
65
+ - \`update\`: {id, expectedRevision, userInstructions?, enabled?, completedAt?}. Read the revision from list. completedAt is an ISO timestamp; ending work also sets enabled false.
66
+ - \`check\`: {id}, for project checks.
67
+ - \`get_card\`: {id}, reads the current authorized artifact and action state before discussing it.
68
+ Instructions adjust what to watch; they never grant new action permissions. Distinguish a task being created from its work being completed. Do not claim a draft was sent.
69
+
52
70
  ## Projects
53
71
 
54
72
  Commands: \`list\`, \`get\`, \`create\`, \`update\`, \`resolve_workspace\`,
@@ -388,6 +388,7 @@ var AgentToolsFactory = class AgentToolsFactory {
388
388
  ...this.deps.getAutomationService ? [createAutomationTool({ getAutomationService: this.deps.getAutomationService })] : [],
389
389
  ...browserEnabled && this.deps.getBrowserAutomationService ? [createBrowserAutomationTool({ getBrowserAutomationService: this.deps.getBrowserAutomationService })] : [],
390
390
  ...this.deps.getAutomationService || this.deps.getProjectService || this.deps.getNotesService || this.deps.getLocalAppService || this.deps.dispatchTaskEvents || this.deps.dispatchTaskRuns ? [createXopcUseTool({
391
+ getWorkspace: () => this.deps.workspace,
391
392
  getConfig: () => this.deps.getConfig?.(),
392
393
  getCurrentAgentId: () => options.agentId,
393
394
  getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,
@@ -6,12 +6,12 @@ import type { NotesService } from '../../notes/index.js';
6
6
  import { type ProjectService } from '../../projects/index.js';
7
7
  import type { LocalAppService } from '../../local-apps/index.js';
8
8
  declare const XopcUseToolSchema: import("@sinclair/typebox").TObject<{
9
- mode: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"project">, import("@sinclair/typebox").TLiteral<"automation">, import("@sinclair/typebox").TLiteral<"note">, import("@sinclair/typebox").TLiteral<"task">, import("@sinclair/typebox").TLiteral<"task_run">, import("@sinclair/typebox").TLiteral<"local_app">, import("@sinclair/typebox").TLiteral<"settings">]>;
9
+ mode: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"proactive">, import("@sinclair/typebox").TLiteral<"project">, import("@sinclair/typebox").TLiteral<"automation">, import("@sinclair/typebox").TLiteral<"note">, import("@sinclair/typebox").TLiteral<"task">, import("@sinclair/typebox").TLiteral<"task_run">, import("@sinclair/typebox").TLiteral<"local_app">, import("@sinclair/typebox").TLiteral<"settings">]>;
10
10
  command: import("@sinclair/typebox").TString;
11
11
  args: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>>;
12
12
  dryRun: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
13
13
  }>;
14
- export type XopcUseMode = 'project' | 'automation' | 'note' | 'task' | 'task_run' | 'local_app' | 'settings';
14
+ export type XopcUseMode = 'proactive' | 'project' | 'automation' | 'note' | 'task' | 'task_run' | 'local_app' | 'settings';
15
15
  export interface XopcUseToolInput {
16
16
  mode: XopcUseMode;
17
17
  command: string;
@@ -19,6 +19,7 @@ export interface XopcUseToolInput {
19
19
  dryRun?: boolean;
20
20
  }
21
21
  export interface XopcUseToolDeps {
22
+ getWorkspace?: () => string;
22
23
  getConfig?: () => Config | undefined;
23
24
  getCurrentAgentId?: () => string | undefined;
24
25
  getCurrentSessionKey?: () => string | undefined;
@@ -13,11 +13,15 @@ import { TaskRepository } from "../../tasks/task-repository.js";
13
13
  import { TaskReadModelProjector } from "../../tasks/task-read-model-projector.js";
14
14
  import { isValidProjectAgentId, normalizeProjectAgentId, resolveProjectAgentId } from "../../projects/project-agent.js";
15
15
  import "../../projects/index.js";
16
- import { CreateAutomationSchema, UpdateAutomationSchema } from "../../automations/domain/validation.js";
17
- import "../../automations/index.js";
16
+ import { updateControlledSubscription } from "../../proactive/scenarios/control.js";
17
+ import { continueMailFollowUp, mailFollowUpSources, startMailFollowUp, updateMailFollowUp } from "../../proactive/follow-ups.js";
18
18
  import { TaskContextRepository } from "../../tasks/task-context-repository.js";
19
19
  import { TaskDependencyError, TaskDependencyService } from "../../tasks/task-dependency-service.js";
20
20
  import { TaskApplicationService } from "../../tasks/task-application-service.js";
21
+ import { getCard } from "../../proactive/inbox/cards.js";
22
+ import { checkDelegation, delegationOverview, startDelegation } from "../../proactive/experience.js";
23
+ import { CreateAutomationSchema, UpdateAutomationSchema } from "../../automations/domain/validation.js";
24
+ import "../../automations/index.js";
21
25
  import { defineTaskContract } from "../../tasks/task-contract-definition.js";
22
26
  import { TaskDeletionService } from "../../tasks/task-deletion-service.js";
23
27
  import "../../tasks/index.js";
@@ -27,6 +31,7 @@ import { Type } from "@sinclair/typebox";
27
31
  init_resolve_route();
28
32
  const XopcUseToolSchema = Type.Object({
29
33
  mode: Type.Union([
34
+ Type.Literal("proactive"),
30
35
  Type.Literal("project"),
31
36
  Type.Literal("automation"),
32
37
  Type.Literal("note"),
@@ -35,7 +40,7 @@ const XopcUseToolSchema = Type.Object({
35
40
  Type.Literal("local_app"),
36
41
  Type.Literal("settings")
37
42
  ]),
38
- command: Type.String({ description: "Object command. Supports project list/get/create/update/resolve_workspace/list_milestones/create_milestone/update_milestone/list_updates/create_update, automation list/get/create/update/delete/run/pause/resume/history, note list/get/create/append/update/preview_edit/delete, task list/get/create/update_dependencies/add_context/remove_context/command/delete, task_run list/get/cancel, local_app list/get/create/validate, and settings open." }),
43
+ command: Type.String({ description: "Object command. Proactive commands: list, get_card {id}, start {scenarioKey: project_delivery_risk|meeting_preparation|discussion_follow_up, projectId?: string, instructions: string}, update {id, expectedRevision, userInstructions?, enabled?, completedAt?}, check {id}. Also supports mail_sources, follow_up {sourceItemId, instructions, dueAt: ISO timestamp}, update_follow_up {id, expectedRevision, instructions?, dueAt?, status?: watching|paused|completed}, continue_card {id}. continue_card binds the current conversation and returns the exact email account; review the full draft and use connector confirmation before sending. Use proactive only for work the user explicitly delegates; inspect list first and update existing work instead of duplicating it. Supports project list/get/create/update/resolve_workspace/list_milestones/create_milestone/update_milestone/list_updates/create_update, automation list/get/create/update/delete/run/pause/resume/history, note list/get/create/append/update/preview_edit/delete, task list/get/create/update_dependencies/add_context/remove_context/command/delete, task_run list/get/cancel, local_app list/get/create/validate, and settings open." }),
39
44
  args: Type.Optional(Type.Record(Type.String(), Type.Any())),
40
45
  dryRun: Type.Optional(Type.Boolean({ description: "Validate and preview the action without mutating xopc state." }))
41
46
  });
@@ -1793,7 +1798,7 @@ function createXopcUseTool(deps) {
1793
1798
  kind: "xopc_use",
1794
1799
  toolCallId
1795
1800
  }
1796
- }, async () => mode === "project" ? await handleProject(command, args, deps, dryRun) : mode === "automation" ? await handleAutomation(command, args, deps, dryRun) : mode === "note" ? await handleNote(command, args, deps, dryRun) : mode === "task" ? await handleTask(command, args, deps, dryRun) : mode === "task_run" ? await handleTaskRun(command, args, dryRun, deps) : mode === "local_app" ? await handleLocalApp(command, args, deps, dryRun) : mode === "settings" ? handleSettings(command, args) : {
1801
+ }, async () => mode === "proactive" ? handleProactive(command, args, deps, dryRun) : mode === "project" ? await handleProject(command, args, deps, dryRun) : mode === "automation" ? await handleAutomation(command, args, deps, dryRun) : mode === "note" ? await handleNote(command, args, deps, dryRun) : mode === "task" ? await handleTask(command, args, deps, dryRun) : mode === "task_run" ? await handleTaskRun(command, args, dryRun, deps) : mode === "local_app" ? await handleLocalApp(command, args, deps, dryRun) : mode === "settings" ? handleSettings(command, args) : {
1797
1802
  ok: false,
1798
1803
  error: `Unsupported mode: ${String(mode)}`
1799
1804
  });
@@ -1808,5 +1813,44 @@ function createXopcUseTool(deps) {
1808
1813
  }
1809
1814
  };
1810
1815
  }
1816
+ function handleProactive(command, args, deps, dryRun) {
1817
+ const workspace = deps.getWorkspace?.();
1818
+ if (!workspace) throw new Error("Proactive workspace is unavailable");
1819
+ if (command === "list") return delegationOverview(workspace);
1820
+ if (command === "mail_sources") return { sources: mailFollowUpSources(workspace) };
1821
+ if (command === "get_card") return { card: getCard(String(args.id ?? ""), workspace) };
1822
+ if (dryRun) return {
1823
+ requiresConfirmation: true,
1824
+ command,
1825
+ args,
1826
+ scope: workspace
1827
+ };
1828
+ if (command === "follow_up") return startMailFollowUp(workspace, args);
1829
+ if (command === "update_follow_up") {
1830
+ const { id, ...patch } = args;
1831
+ return updateMailFollowUp(workspace, String(id ?? ""), patch);
1832
+ }
1833
+ if (command === "continue_card") {
1834
+ const card = getCard(String(args.id ?? ""), workspace);
1835
+ if (!card.communication || [
1836
+ "withdrawn",
1837
+ "expired",
1838
+ "resolved"
1839
+ ].includes(card.status)) throw new Error("Open a current communication card");
1840
+ const sessionKey = deps.getCurrentSessionKey?.();
1841
+ if (!sessionKey) throw new Error("A conversation is required");
1842
+ return {
1843
+ card,
1844
+ ...continueMailFollowUp(workspace, card.communication.id, sessionKey)
1845
+ };
1846
+ }
1847
+ if (command === "start") return startDelegation(workspace, args);
1848
+ if (command === "update") {
1849
+ const { id, ...patch } = args;
1850
+ return updateControlledSubscription(workspace, String(id ?? ""), patch);
1851
+ }
1852
+ if (command === "check") return checkDelegation(workspace, String(args.id ?? ""));
1853
+ throw new Error("Unsupported proactive command");
1854
+ }
1811
1855
  //#endregion
1812
1856
  export { createXopcUseTool };
@@ -6,9 +6,9 @@ export declare const BrowserAutomationDefinitionSchema: z.ZodObject<{
6
6
  allowedDomains: z.ZodArray<z.ZodString>;
7
7
  risk: z.ZodEnum<{
8
8
  read: "read";
9
+ draft: "draft";
9
10
  sensitive: "sensitive";
10
11
  destructive: "destructive";
11
- draft: "draft";
12
12
  external_effect: "external_effect";
13
13
  }>;
14
14
  inputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -25,7 +25,7 @@ export declare class BrowserAutomationService {
25
25
  id: string;
26
26
  name: string;
27
27
  allowedDomains: string[];
28
- risk: "read" | "sensitive" | "destructive" | "draft" | "external_effect";
28
+ risk: "read" | "draft" | "sensitive" | "destructive" | "external_effect";
29
29
  inputs: Record<string, {
30
30
  type: "string" | "number" | "boolean";
31
31
  required?: boolean;
@@ -35,7 +35,8 @@ function createBrowserNativeBootstrap(configPath, request) {
35
35
  kind: "local-browser",
36
36
  url: gatewayUrl
37
37
  };
38
- const setup = createDevicePairingSetup([route], Date.now(), 3, {
38
+ const setup = createDevicePairingSetup([route], Date.now(), {
39
+ targetKind: "browser",
39
40
  ttlMs: 6e4,
40
41
  enrollment: {
41
42
  issuer: "browser-native-host",
@@ -55,6 +56,7 @@ function createBrowserNativeBootstrap(configPath, request) {
55
56
  gatewayName: os.hostname(),
56
57
  gatewayPublicKey: getGatewayIdentityPublicKeyRaw(identity),
57
58
  routes: [route],
59
+ targetKind: setup.targetKind,
58
60
  expiresAt: setup.expiresAt
59
61
  })).toString("base64url")}`,
60
62
  expiresAt: setup.expiresAt
@@ -1,6 +1,6 @@
1
1
  import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
2
- import { register } from "../registry.js";
3
2
  import { getStoreConnectorInstallPlan, installStoreConnector, listStoreConnectors } from "../../capabilities/store-connector.js";
3
+ import { register } from "../registry.js";
4
4
  import { confirm } from "@inquirer/prompts";
5
5
  import { Command } from "commander";
6
6
  //#region src/cli/commands/connectors.ts
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
52
52
  id: "database-schema",
53
53
  label: "Database schema",
54
54
  status: "pass",
55
- message: `SQLite schema v${status.dbVersion} (current release v161).`,
55
+ message: `SQLite schema v${status.dbVersion} (current release v165).`,
56
56
  hints: []
57
57
  };
58
58
  }
@@ -1,5 +1,6 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { isXopcDatabaseOpen, openXopcDatabase } from "../../storage/sqlite/connection.js";
3
4
  import { loadConfig, saveConfig } from "../../config/loader.js";
4
5
  import { resolveGatewayEffectiveHost } from "../../config/gateway-bind.js";
5
6
  import { ensureFrpcBinary } from "../../tunnel/frpc-binary.js";
@@ -8,6 +9,8 @@ import { loadTunnelState } from "../../tunnel/tunnel-state.js";
8
9
  import { getTunnelService } from "../../tunnel/tunnel-service.js";
9
10
  import { formatExamples, register } from "../registry.js";
10
11
  import "../../config/index.js";
12
+ import { resolveGatewayAuth } from "../../gateway/auth.js";
13
+ import { requireTunnelGatewayToken } from "../../tunnel/auth-policy.js";
11
14
  import { TUNNEL_RISK_SUMMARY_LINES, TunnelConsentError, assertTunnelMayStart, hasValidTunnelConsent } from "../../tunnel/consent.js";
12
15
  import { resolveFrpSubdomainHost } from "../../tunnel/frp-subdomain-host.js";
13
16
  import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, setTunnelEnabledInConfig } from "../../tunnel/tunnel-config.js";
@@ -26,6 +29,7 @@ function resolveGatewayPortHost(config) {
26
29
  };
27
30
  }
28
31
  function resolveGatewayToken(config) {
32
+ requireTunnelGatewayToken(resolveGatewayAuth({ authConfig: config.gateway.auth }));
29
33
  const fromEnv = process.env.XOPC_GATEWAY_TOKEN?.trim();
30
34
  if (fromEnv) return fromEnv;
31
35
  const token = config.gateway.auth?.token?.trim();
@@ -155,6 +159,7 @@ function createTunnelCommand(ctx) {
155
159
  });
156
160
  const config = loadConfig(ctx.configPath);
157
161
  assertTunnelMayStart(config);
162
+ if (!isXopcDatabaseOpen()) openXopcDatabase();
158
163
  const { port, host } = resolveGatewayPortHost(config);
159
164
  const token = resolveGatewayToken(config);
160
165
  const tunnel = getTunnelService();
@@ -6,8 +6,8 @@ import { ComposioSessionsAdapter } from "./composio-sessions.js";
6
6
  import { decodeConnectedSourceCursor, encodeConnectedSourceCursor } from "./connected-source-cursor.js";
7
7
  import { scopeForComposioAction } from "./composio.js";
8
8
  import { getConnectorDefinition } from "./catalog.js";
9
- import { getWorkspacePath } from "../config/workspace-path-helpers.js";
10
9
  import { getConnectorInstance } from "./instances.js";
10
+ import { getWorkspacePath } from "../config/workspace-path-helpers.js";
11
11
  import { KnowledgeIngestionService } from "../knowledge/ingestion-service.js";
12
12
  import { ConnectedKnowledgePipeline } from "../knowledge/connected-knowledge-pipeline.js";
13
13
  import { LocalFolderKnowledgeSourceAdapter } from "../knowledge/local-folder-adapter.js";
@@ -122,6 +122,9 @@ function normalizeCalendar(result) {
122
122
  value: compact({
123
123
  id: externalId,
124
124
  title: text(event, "summary", "title", "name"),
125
+ description: text(event, "description"),
126
+ location: text(event, "location"),
127
+ allDay: Boolean(event.start && typeof event.start === "object" && "date" in event.start),
125
128
  start: occurredAt,
126
129
  end: time(event.end ?? event.endTime ?? event.end_time),
127
130
  organizer: event.organizer,
@@ -13,9 +13,9 @@ import { getConnectorDefinition } from "./catalog.js";
13
13
  import { capabilityActions, isToolInputSchema, missingConnectionCapabilities } from "./connection-capabilities.js";
14
14
  import { connectorPrincipalForSession } from "./principal.js";
15
15
  import { resolveConnectionCandidate } from "./connection-candidates.js";
16
- import { persistConfigMutation } from "../config/config-mutation.js";
17
16
  import { listConnectorInstances } from "./instances.js";
18
17
  import { installConnector } from "./install.js";
18
+ import { persistConfigMutation } from "../config/config-mutation.js";
19
19
  import { randomUUID } from "node:crypto";
20
20
  //#region src/connectors/connection-recovery-service.ts
21
21
  init_logger();
@@ -1,6 +1,6 @@
1
- import { getWorkspacePath } from "../config/workspace-path-helpers.js";
2
1
  import { materializeConnectorMcpServer } from "./materialize.js";
3
2
  import { getConnectorInstance } from "./instances.js";
3
+ import { getWorkspacePath } from "../config/workspace-path-helpers.js";
4
4
  import { listBundleMcpServerCapabilitiesForGateway } from "../agent/mcp/bundle-mcp-gateway.js";
5
5
  //#region src/connectors/health.ts
6
6
  function classifyConnectorHealthError(error) {
@@ -1,9 +1,9 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
4
+ import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
4
5
  import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
5
6
  import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
6
- import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
7
7
  import { createHeartbeatWake } from "../../heartbeat/wake.js";
8
8
  import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
9
9
  import { readFile } from "fs/promises";
@@ -225,6 +225,7 @@ function createHonoApp(config) {
225
225
  authenticated.use(auth({
226
226
  getGatewayAuth: () => service.currentConfig.gateway?.auth,
227
227
  getResolvedAuth: () => service.getResolvedAuth(),
228
+ isPublicTunnelEnabled: () => service.currentConfig.tunnel?.enabled === true,
228
229
  getTrustedProxyContext: () => ({
229
230
  trustedProxies: service.currentConfig.gateway?.trustedProxies,
230
231
  allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true
@@ -4,13 +4,12 @@ export interface AuthConfig {
4
4
  /** Current gateway auth from config (for rate-limit settings); optional. */
5
5
  getGatewayAuth?: () => GatewayAuthConfig | undefined;
6
6
  getResolvedAuth?: () => ResolvedGatewayAuth;
7
+ isPublicTunnelEnabled?: () => boolean;
7
8
  getTrustedProxyContext?: () => {
8
9
  trustedProxies?: string[];
9
10
  allowRealIpFallback?: boolean;
10
11
  };
11
12
  }
12
- /** Exported for gateway security tests. */
13
- export declare function isQueryTokenAllowedPath(path: string, method: string): boolean;
14
13
  export declare function auth(config?: AuthConfig): import("hono").MiddlewareHandler<any, string, {}, (Response & import("hono").TypedResponse<{
15
14
  error: string;
16
15
  code: string;
@@ -5,11 +5,12 @@ import { authenticateDeviceAccessToken, getDevice } from "../../../storage/sqlit
5
5
  import { safeEqualSecret } from "../../security/secret-equal.js";
6
6
  import { resolveClientIpFromRequest } from "../../client-ip.js";
7
7
  import { authPolicyConfig, buckets, resolveAuthRateLimit } from "../../rate-limit/buckets.js";
8
- import { getClientIpFromHeaders } from "../../security/loopback.js";
9
8
  import { resolveAuthTracking } from "../../rate-limit/auth-policy.js";
10
9
  import { isAuthRateLimitGloballyDisabled } from "../../rate-limit/env-flags.js";
11
10
  import "../../rate-limit/index.js";
11
+ import { authenticateBrowserSession } from "../../../storage/sqlite/browser-session-repository.js";
12
12
  import { isChromeExtensionOrigin } from "../../security/origin-check.js";
13
+ import { browserCookieRequestAllowed, readBrowserSessionCookie, writeBrowserSessionCookie } from "../../security/browser-session.js";
13
14
  import { authorizeTrustedProxy } from "../../trusted-proxy.js";
14
15
  import { setGatewayPrincipal } from "../../security/gateway-principal.js";
15
16
  import { createMiddleware } from "hono/factory";
@@ -30,21 +31,6 @@ function extractTokenFromHeader(authHeader) {
30
31
  if (parts.length === 2 && parts[0].toLowerCase() === "bearer") return parts[1];
31
32
  return authHeader;
32
33
  }
33
- /**
34
- * SECURITY: query-string tokens leak into server logs, Referer headers, and
35
- * browser history. We accept them only for avatar `<img>` loads, where an
36
- * Authorization header cannot be set. Realtime WebSocket authentication uses a
37
- * one-time ticket acquired over authenticated HTTP.
38
- */
39
- function extractTokenFromQuery(url) {
40
- return new URL(url).searchParams.get("token");
41
- }
42
- const AGENT_AVATAR_GET_PATH = /^\/api\/agents\/[^/]+\/avatar$/;
43
- /** Exported for gateway security tests. */
44
- function isQueryTokenAllowedPath(path, method) {
45
- if (method === "GET" && AGENT_AVATAR_GET_PATH.test(path)) return true;
46
- return false;
47
- }
48
34
  function resolveRemoteAddress(c) {
49
35
  try {
50
36
  return getConnInfo(c).remote.address;
@@ -53,17 +39,16 @@ function resolveRemoteAddress(c) {
53
39
  }
54
40
  }
55
41
  function resolveMiddlewareClientIp(c, trustedProxies, allowRealIpFallback) {
56
- if (trustedProxies?.length) return resolveClientIpFromRequest({
42
+ return resolveClientIpFromRequest({
57
43
  remoteAddress: resolveRemoteAddress(c),
58
44
  getHeader: (name) => c.req.header(name),
59
45
  trustedProxies,
60
46
  allowRealIpFallback
61
47
  });
62
- return getClientIpFromHeaders({ get: (name) => c.req.header(name) ?? void 0 });
63
48
  }
64
- function buildRateLimitContext(getGatewayAuth, clientIp, origin) {
49
+ function buildRateLimitContext(getGatewayAuth, clientIp, origin, enforce = false) {
65
50
  const cfg = resolveAuthRateLimit(getGatewayAuth?.()?.rateLimit);
66
- if (!(cfg.enabled && !isAuthRateLimitGloballyDisabled())) return {
51
+ if (!(cfg.enabled && (enforce || !isAuthRateLimitGloballyDisabled()))) return {
67
52
  active: false,
68
53
  cfg,
69
54
  trackingKey: void 0
@@ -101,7 +86,18 @@ function blockedResponse(c, retryAfterSec) {
101
86
  }, 429);
102
87
  }
103
88
  function auth(config) {
104
- const { getGatewayAuth, getResolvedAuth, getTrustedProxyContext } = config || {};
89
+ const { getGatewayAuth: readGatewayAuth, getResolvedAuth, getTrustedProxyContext, isPublicTunnelEnabled } = config || {};
90
+ const getGatewayAuth = () => {
91
+ const current = readGatewayAuth?.();
92
+ return isPublicTunnelEnabled?.() ? {
93
+ ...current,
94
+ rateLimit: {
95
+ ...current?.rateLimit,
96
+ enabled: true,
97
+ exemptLoopback: false
98
+ }
99
+ } : current;
100
+ };
105
101
  return createMiddleware(async (c, next) => {
106
102
  const resolvedAuth = getResolvedAuth?.();
107
103
  if (!resolvedAuth) {
@@ -115,13 +111,17 @@ function auth(config) {
115
111
  }, 401);
116
112
  }
117
113
  const authMode = resolvedAuth.mode;
114
+ if (isPublicTunnelEnabled?.() && authMode !== "token") return c.json({
115
+ error: "Unauthorized",
116
+ code: "unsafe_tunnel_auth"
117
+ }, 401);
118
118
  if (authMode === "trusted-proxy") {
119
119
  const proxyContext = getTrustedProxyContext?.();
120
120
  const trustedProxies = proxyContext?.trustedProxies;
121
121
  const trustedProxyConfig = resolvedAuth?.trustedProxy;
122
122
  const clientIp = resolveMiddlewareClientIp(c, trustedProxies, proxyContext?.allowRealIpFallback);
123
123
  const origin = c.req.header("origin");
124
- const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin);
124
+ const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin, isPublicTunnelEnabled?.());
125
125
  if (!trustedProxyConfig) {
126
126
  log.warn({
127
127
  path: c.req.path,
@@ -199,16 +199,34 @@ function auth(config) {
199
199
  const proxyContext = getTrustedProxyContext?.();
200
200
  const clientIp = resolveMiddlewareClientIp(c, proxyContext?.trustedProxies, proxyContext?.allowRealIpFallback);
201
201
  const origin = c.req.header("origin");
202
- const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin);
202
+ const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin, isPublicTunnelEnabled?.());
203
203
  const authHeader = extractTokenFromHeader(c.req.header("authorization"));
204
+ const browserCookie = readBrowserSessionCookie(c);
205
+ if (!authHeader && browserCookie) {
206
+ if (!browserCookieRequestAllowed(c)) return c.json({
207
+ error: "Forbidden",
208
+ code: "csrf_rejected"
209
+ }, 403);
210
+ const session = authenticateBrowserSession(browserCookie, resolvedAuth);
211
+ if (!session) {
212
+ recordFailure(rl);
213
+ return c.json({
214
+ error: "Unauthorized",
215
+ code: "browser_session_expired"
216
+ }, 401);
217
+ }
218
+ if (session.renewed) writeBrowserSessionCookie(c, browserCookie, session.expiresAt);
219
+ setGatewayPrincipal(c, {
220
+ kind: "owner",
221
+ principalId: `browser:${session.sessionId}`,
222
+ browserSessionId: session.sessionId,
223
+ scopes: ["gateway.admin"]
224
+ });
225
+ recordSuccess(rl);
226
+ return next();
227
+ }
204
228
  const requestPath = new URL(c.req.url).pathname;
205
- const queryToken = authMode === "token" && isQueryTokenAllowedPath(requestPath, c.req.method) ? extractTokenFromQuery(c.req.url) : null;
206
- if (!authHeader && queryToken === null && new URL(c.req.url).searchParams.has("token")) log.warn({
207
- path: requestPath,
208
- method: c.req.method,
209
- clientIp
210
- }, "Credential in query string rejected: use Authorization header for this endpoint");
211
- const providedCredential = authHeader || queryToken;
229
+ const providedCredential = authHeader;
212
230
  const browserExtensionOrigin = isChromeExtensionOrigin(origin) ? origin.toLowerCase() : void 0;
213
231
  if (providedCredential && validateCredential(providedCredential, expectedCredential)) {
214
232
  if (browserExtensionOrigin) return c.json({
@@ -294,4 +312,4 @@ function auth(config) {
294
312
  });
295
313
  }
296
314
  //#endregion
297
- export { auth, isQueryTokenAllowedPath };
315
+ export { auth };
@@ -2,7 +2,6 @@ import { createLogger } from "../../../utils/logger/index.js";
2
2
  import { init_logger } from "../../../utils/logger.js";
3
3
  import { resolveClientIpFromRequest } from "../../client-ip.js";
4
4
  import { buckets } from "../../rate-limit/buckets.js";
5
- import { getClientIpFromHeaders } from "../../security/loopback.js";
6
5
  import "../../rate-limit/index.js";
7
6
  import { createMiddleware } from "hono/factory";
8
7
  import { getConnInfo } from "@hono/node-server/conninfo";
@@ -15,21 +14,18 @@ init_logger();
15
14
  const log = createLogger("Hono:StrictRateLimit");
16
15
  function resolveClientIp(c, deps) {
17
16
  const { trustedProxies, allowRealIpFallback } = deps.getTrustedProxyContext();
18
- if (trustedProxies?.length) {
19
- let remoteAddress;
20
- try {
21
- remoteAddress = getConnInfo(c).remote.address;
22
- } catch {
23
- remoteAddress = void 0;
24
- }
25
- return resolveClientIpFromRequest({
26
- remoteAddress,
27
- getHeader: (name) => c.req.header(name),
28
- trustedProxies,
29
- allowRealIpFallback
30
- });
17
+ let remoteAddress;
18
+ try {
19
+ remoteAddress = getConnInfo(c).remote.address;
20
+ } catch {
21
+ remoteAddress = void 0;
31
22
  }
32
- return getClientIpFromHeaders({ get: (name) => c.req.header(name) ?? void 0 });
23
+ return resolveClientIpFromRequest({
24
+ remoteAddress,
25
+ getHeader: (name) => c.req.header(name),
26
+ trustedProxies,
27
+ allowRealIpFallback
28
+ });
33
29
  }
34
30
  function createClientRateLimitMiddleware(deps, options) {
35
31
  return createMiddleware(async (c, next) => {
@@ -0,0 +1,3 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ export declare function registerBrowserSessionRoutes(app: Hono, deps: AuthenticatedRouteDeps): void;