@xopcai/xopc 0.0.178 → 0.0.180

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 (450) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-BzGX__8I.js → activity-store-DFKtQDgE.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BzxntcaZ.js → agent-avatar-dicebear-CcTvB_4W.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-DgGj9bu6.js +2 -0
  6. package/dist/gateway/static/root/assets/{api-hi6f2Xtp.js → api-CUClAvuL.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-fTY1F7ac.js → app-management-settings-panel-Ib-cWKHM.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-BZ-IxQfB.js → appearance-settings-CRSN8WuA.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-B5xahuT-.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-ZSLLG8wB.js → archive-plugin-BBF9zspN.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-D4YktqIF.js → attachment-load-D3QQfA7w.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-BUYrvMmD.js +6 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-BIkPxfxj.js → binary-plugins-D78XOjJ3.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-Q3v_YQom.js → block-editor-D_VVXlYX.js} +46 -46
  15. package/dist/gateway/static/root/assets/browser-settings-page-Cjw07q9h.js +8 -0
  16. package/dist/gateway/static/root/assets/{browser-workflow-inputs-M5lTEW1I.js → browser-workflow-inputs-_gu08MA4.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-workflows-page-B3T1KYk4.js → browser-workflows-page-58DBMXgG.js} +2 -2
  18. package/dist/gateway/static/root/assets/capabilities-settings-panel-D_dfVxHY.js +7 -0
  19. package/dist/gateway/static/root/assets/{capability-presets-api-DE09c0VB.js → capability-presets-api-DhCn9rPv.js} +1 -1
  20. package/dist/gateway/static/root/assets/capability-presets-settings-panel-LWWIYUT7.js +1 -0
  21. package/dist/gateway/static/root/assets/{channel-recipient-api-CFR5FBfS.js → channel-recipient-api-DYtoNV5A.js} +1 -1
  22. package/dist/gateway/static/root/assets/channels-settings-Cyj5OunL.js +1 -0
  23. package/dist/gateway/static/root/assets/channels-status-swr-TEFnV0IG.js +1 -0
  24. package/dist/gateway/static/root/assets/{connector-logo-B1mD-3pM.js → connector-logo-CxIXnifA.js} +1 -1
  25. package/dist/gateway/static/root/assets/connectors-page-0TobCpBB.js +2 -0
  26. package/dist/gateway/static/root/assets/desktop-pet-CwVSLL6N.js +1 -0
  27. package/dist/gateway/static/root/assets/desktop-pet-settings-BOIp4q0Z.js +1 -0
  28. package/dist/gateway/static/root/assets/{directory-picker-path-field-BYQJ2XUS.js → directory-picker-path-field-C8_lsW6S.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dreaming-settings-BXcb8fwx.js → dreaming-settings-Da9FeWQl.js} +3 -3
  30. package/dist/gateway/static/root/assets/{extension-debug-page-O1Xu1r4Q.js → extension-debug-page-CMNnSJP6.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-C2Jraq8l.js → extension-page-t0pJqLvM.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-settings-page-DcXQDTpG.js → extension-settings-page-aiR-tKnW.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-api-DmPIZrvg.js → gateway-config-api-CkyQBD6r.js} +1 -1
  34. package/dist/gateway/static/root/assets/gateway-settings-BIZfAgfB.js +1 -0
  35. package/dist/gateway/static/root/assets/{gateway-startup-retry-BZEkOdPm.js → gateway-startup-retry-CSU7UvzG.js} +1 -1
  36. package/dist/gateway/static/root/assets/goals-settings-Dx9uTyWF.js +1 -0
  37. package/dist/gateway/static/root/assets/{heartbeat-settings-BtKu2NWT.js → heartbeat-settings-Cnr5ORXL.js} +1 -1
  38. package/dist/gateway/static/root/assets/{image-generation-api-05Gg8wsU.js → image-generation-api-BR6Kb77X.js} +1 -1
  39. package/dist/gateway/static/root/assets/index-B0Tdge_q.css +1 -0
  40. package/dist/gateway/static/root/assets/index-BA56bQ68.js +224 -0
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CfmDR9Sc.js → keyboard-shortcuts-settings-D76uYKeQ.js} +1 -1
  42. package/dist/gateway/static/root/assets/local-app-workbench-page-DSUNtLHg.js +2 -0
  43. package/dist/gateway/static/root/assets/{local-apps-page-Df8BW1A_.js → local-apps-page-BsLnojTh.js} +1 -1
  44. package/dist/gateway/static/root/assets/{locale-store-CTwSy7yW.js → locale-store-BNC8HUCI.js} +1 -1
  45. package/dist/gateway/static/root/assets/logs-page-yI8kpQtO.js +7 -0
  46. package/dist/gateway/static/root/assets/{markdown-split-B3FvKbaP.js → markdown-split-D6smTQWD.js} +1 -1
  47. package/dist/gateway/static/root/assets/{media-plugins-DsjrvvB6.js → media-plugins-D1TmMF0A.js} +1 -1
  48. package/dist/gateway/static/root/assets/messages-H_iJjnEM.js +3 -0
  49. package/dist/gateway/static/root/assets/{notes-page-tuzIwy3c.js → notes-page-Vt-diFf0.js} +1 -1
  50. package/dist/gateway/static/root/assets/notes-workbench-BD297EZt.js +4 -0
  51. package/dist/gateway/static/root/assets/outcome-detail-page-C5i_ZR9a.js +1 -0
  52. package/dist/gateway/static/root/assets/{page-tabs-ke9s4nYi.js → page-tabs-BnSzIjH0.js} +1 -1
  53. package/dist/gateway/static/root/assets/{preview-open-alternatives-Cp1eI4S9.js → preview-open-alternatives-CF12Eqi4.js} +1 -1
  54. package/dist/gateway/static/root/assets/product-delivery-BVG-eWQO.js +1 -0
  55. package/dist/gateway/static/root/assets/{product-open-page-dXQCMAtH.js → product-open-page-Du0TE_CU.js} +1 -1
  56. package/dist/gateway/static/root/assets/project-detail-page-D1HGz7Dy.js +1 -0
  57. package/dist/gateway/static/root/assets/projects-page-CqP2TnW-.js +1 -0
  58. package/dist/gateway/static/root/assets/remote-access-hub-BXdVJLS3.js +1 -0
  59. package/dist/gateway/static/root/assets/{save-bar-controls-Bl30zjHc.js → save-bar-controls-B53UNtDM.js} +1 -1
  60. package/dist/gateway/static/root/assets/{schedule-field-DqhmXQKo.js → schedule-field-C3dIMN5q.js} +1 -1
  61. package/dist/gateway/static/root/assets/{schema-form-DkUCy6vf.js → schema-form-BKvpxqof.js} +1 -1
  62. package/dist/gateway/static/root/assets/{schemas-DgQq6Z5S.js → schemas-C6onAggk.js} +2 -2
  63. package/dist/gateway/static/root/assets/sessions-page-CPAwDdl5.js +1 -0
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-C-jGsoft.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-form-section-C6ZbNpdy.js → settings-form-section-kt6GIS32.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-loading-skeleton-Bk58_cr7.js → settings-loading-skeleton-85eUPcKz.js} +1 -1
  67. package/dist/gateway/static/root/assets/{settings-page-k8iE_NdX.js → settings-page-Di5x6Xrc.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-page-layout-DgFSya2e.js → settings-page-layout-CkkCee_x.js} +1 -1
  69. package/dist/gateway/static/root/assets/{setup-status-panel-B_KDlyZA.js → setup-status-panel-uxEE6gAB.js} +1 -1
  70. package/dist/gateway/static/root/assets/{share-preview-page-CV7nL_J9.js → share-preview-page-BtLEstaI.js} +1 -1
  71. package/dist/gateway/static/root/assets/shares-settings-2mcsMWgn.js +1 -0
  72. package/dist/gateway/static/root/assets/skill-reload-api-ocDwsrEt.js +1 -0
  73. package/dist/gateway/static/root/assets/skills-page-9_jfsFU5.js +2 -0
  74. package/dist/gateway/static/root/assets/{skills-page.utils-kahBIHg0.js → skills-page.utils-C2SHvq8V.js} +1 -1
  75. package/dist/gateway/static/root/assets/{system-settings-panel-JV3-MG5F.js → system-settings-panel-CIJ66cUy.js} +1 -1
  76. package/dist/gateway/static/root/assets/{theme-store-DFLyzoLO.js → theme-store-ClDa_Bci.js} +1 -1
  77. package/dist/gateway/static/root/assets/time-picker-D0zAsHOo.js +1 -0
  78. package/dist/gateway/static/root/assets/{typed-models-lib-60Aqo-UJ.js → typed-models-lib-GsmwmB40.js} +1 -1
  79. package/dist/gateway/static/root/assets/{use-channel-catalog-CnTkHDnw.js → use-channel-catalog-BQz3K7xj.js} +1 -1
  80. package/dist/gateway/static/root/assets/user-context-page-Bn4BLg4W.js +1 -0
  81. package/dist/gateway/static/root/assets/{voice-api-key-field-CNa8qUgS.js → voice-api-key-field-Blaxsbb3.js} +1 -1
  82. package/dist/gateway/static/root/assets/work-copy-Cwyan9Sn.js +1 -0
  83. package/dist/gateway/static/root/assets/work-discovery-page-iJ9RBSpu.js +1 -0
  84. package/dist/gateway/static/root/assets/work-item-detail-page-CqTH7PQX.js +1 -0
  85. package/dist/gateway/static/root/assets/work-page-H3m99ccS.js +3 -0
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-yV_x595t.js → workflow-run-setup-panel-CTG4RpRE.js} +2 -2
  87. package/dist/gateway/static/root/assets/workflows-page-BxZSKMfv.js +11 -0
  88. package/dist/gateway/static/root/index.html +9 -10
  89. package/dist/package.js +1 -1
  90. package/dist/packages/gateway-contract/src/outcomes.js +137 -0
  91. package/dist/packages/gateway-contract/src/product-delivery.js +1 -0
  92. package/dist/packages/gateway-contract/src/work-intake.js +85 -0
  93. package/dist/src/activity/service.d.ts +1 -0
  94. package/dist/src/activity/service.js +4 -1
  95. package/dist/src/agent/agent-manager.d.ts +4 -1
  96. package/dist/src/agent/agent-manager.js +21 -7
  97. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
  98. package/dist/src/agent/code-intelligence/binary.js +1 -1
  99. package/dist/src/agent/context/execution-scope.d.ts +1 -1
  100. package/dist/src/agent/context/execution-scope.js +6 -4
  101. package/dist/src/agent/embedded/model-runtime.js +1 -1
  102. package/dist/src/agent/embedded/run-for-session.d.ts +2 -0
  103. package/dist/src/agent/embedded/run-for-session.js +3 -1
  104. package/dist/src/agent/goals/post-turn.js +7 -6
  105. package/dist/src/agent/image/tool-model-config.js +1 -1
  106. package/dist/src/agent/inbound/turn-dispatcher.d.ts +6 -1
  107. package/dist/src/agent/inbound/turn-dispatcher.js +5 -2
  108. package/dist/src/agent/ipc/inbox.js +1 -1
  109. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +2 -0
  110. package/dist/src/agent/lifecycle/timeout-wrapper.js +39 -9
  111. package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -2
  112. package/dist/src/agent/mcp/bundle-mcp-runtime.js +6 -1
  113. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +1 -1
  114. package/dist/src/agent/mcp/mcp-stdio-transport.js +1 -1
  115. package/dist/src/agent/mcp/mcp-transport-config.d.ts +2 -0
  116. package/dist/src/agent/mcp/mcp-transport-config.js +10 -3
  117. package/dist/src/agent/mcp/mcp-transport.d.ts +1 -0
  118. package/dist/src/agent/mcp/mcp-transport.js +5 -2
  119. package/dist/src/agent/memory/dreaming/config.js +1 -1
  120. package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -0
  121. package/dist/src/agent/memory/user-context-coordinator.js +17 -1
  122. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +1 -1
  123. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +6 -2
  124. package/dist/src/agent/outcomes/{task-evaluation.d.ts → execution-evaluation.d.ts} +3 -3
  125. package/dist/src/agent/outcomes/{task-evaluation.js → execution-evaluation.js} +5 -5
  126. package/dist/src/agent/outcomes/execution-verifier.d.ts +29 -0
  127. package/dist/src/agent/outcomes/{task-verifier.js → execution-verifier.js} +4 -4
  128. package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
  129. package/dist/src/agent/service/direct-turn-helpers.js +1 -0
  130. package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -0
  131. package/dist/src/agent/service/process-direct-one-shot.js +4 -1
  132. package/dist/src/agent/service/process-direct-streaming.js +3 -1
  133. package/dist/src/agent/service.d.ts +1 -0
  134. package/dist/src/agent/service.js +5 -2
  135. package/dist/src/agent/session/session-inspector.js +1 -1
  136. package/dist/src/agent/skills/config.js +6 -0
  137. package/dist/src/agent/skills/filesystem-watcher.d.ts +4 -0
  138. package/dist/src/agent/skills/filesystem-watcher.js +16 -7
  139. package/dist/src/agent/skills/hub-lock.js +1 -1
  140. package/dist/src/agent/skills/index.d.ts +10 -7
  141. package/dist/src/agent/skills/index.js +56 -47
  142. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  143. package/dist/src/agent/skills/skill-manager.d.ts +5 -2
  144. package/dist/src/agent/skills/skill-manager.js +10 -5
  145. package/dist/src/agent/skills/skill-sources.d.ts +18 -0
  146. package/dist/src/agent/skills/skill-sources.js +143 -0
  147. package/dist/src/agent/skills/types.d.ts +25 -2
  148. package/dist/src/agent/tools/delegate-tool.js +2 -1
  149. package/dist/src/agent/tools/executor.d.ts +2 -0
  150. package/dist/src/agent/tools/executor.js +18 -11
  151. package/dist/src/agent/tools/factory.js +18 -1
  152. package/dist/src/agent/tools/goal-tool.js +5 -3
  153. package/dist/src/agent/tools/index.d.ts +1 -0
  154. package/dist/src/agent/tools/index.js +2 -1
  155. package/dist/src/agent/tools/managed-job-tool.d.ts +2 -0
  156. package/dist/src/agent/tools/managed-job-tool.js +160 -0
  157. package/dist/src/agent/tools/todo-tool.d.ts +5 -0
  158. package/dist/src/agent/tools/todo-tool.js +16 -4
  159. package/dist/src/agent/tools/update-plan-tool.d.ts +1 -0
  160. package/dist/src/agent/tools/update-plan-tool.js +6 -0
  161. package/dist/src/agent/workspace-runtime/registry.d.ts +3 -0
  162. package/dist/src/agent/workspace-runtime/registry.js +3 -1
  163. package/dist/src/agent-runtime/index.js +1 -1
  164. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  165. package/dist/src/auth/credentials.d.ts +9 -1
  166. package/dist/src/auth/credentials.js +112 -56
  167. package/dist/src/auth/model-credential-store.js +7 -22
  168. package/dist/src/auth/oauth-provider-lock.d.ts +5 -0
  169. package/dist/src/auth/oauth-provider-lock.js +91 -0
  170. package/dist/src/auth/profiles/store.js +1 -1
  171. package/dist/src/auth/sync-provider-auth.js +2 -2
  172. package/dist/src/automations/domain/defaults.d.ts +8 -1
  173. package/dist/src/automations/domain/defaults.js +9 -2
  174. package/dist/src/automations/domain/index.js +2 -2
  175. package/dist/src/automations/domain/types.d.ts +33 -7
  176. package/dist/src/automations/domain/validation.d.ts +8 -0
  177. package/dist/src/automations/domain/validation.js +2 -0
  178. package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -1
  179. package/dist/src/automations/index.js +2 -2
  180. package/dist/src/automations/service/action-executor.d.ts +2 -2
  181. package/dist/src/automations/service/action-executor.js +144 -34
  182. package/dist/src/automations/service/automation-service.d.ts +4 -0
  183. package/dist/src/automations/service/automation-service.js +197 -18
  184. package/dist/src/automations/storage/automation-run-repository.d.ts +1 -0
  185. package/dist/src/automations/storage/automation-run-repository.js +37 -7
  186. package/dist/src/automations/storage/index.js +2 -2
  187. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  188. package/dist/src/browser/providers/cloakbrowser.js +2 -2
  189. package/dist/src/channels/attachments/voice-stt-webchat.d.ts +0 -3
  190. package/dist/src/channels/attachments/voice-stt-webchat.js +1 -24
  191. package/dist/src/chat-commands/builtins/goal.js +5 -4
  192. package/dist/src/cli/commands/agents.js +1 -1
  193. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  194. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  195. package/dist/src/cli/commands/goal.js +6 -5
  196. package/dist/src/cli/commands/models.js +1 -1
  197. package/dist/src/cli/commands/tunnel.js +3 -3
  198. package/dist/src/cli/utils/oauth-login.js +1 -7
  199. package/dist/src/config/agent-profile.js +1 -1
  200. package/dist/src/config/index.js +4 -4
  201. package/dist/src/config/loader.js +1 -1
  202. package/dist/src/config/models-json.js +1 -1
  203. package/dist/src/config/schema.d.ts +3 -0
  204. package/dist/src/config/schema.js +2 -1
  205. package/dist/src/connectors/learning-coordinator.js +7 -1
  206. package/dist/src/connectors/source-change-publisher.d.ts +17 -0
  207. package/dist/src/connectors/source-change-publisher.js +148 -0
  208. package/dist/src/discussions/analyzer.d.ts +35 -0
  209. package/dist/src/discussions/analyzer.js +127 -0
  210. package/dist/src/discussions/index.d.ts +7 -0
  211. package/dist/src/discussions/index.js +7 -0
  212. package/dist/src/discussions/live-worker.d.ts +33 -0
  213. package/dist/src/discussions/live-worker.js +148 -0
  214. package/dist/src/discussions/pipeline.d.ts +33 -0
  215. package/dist/src/discussions/pipeline.js +205 -0
  216. package/dist/src/discussions/project-inference.d.ts +13 -0
  217. package/dist/src/discussions/project-inference.js +19 -0
  218. package/dist/src/discussions/repository.d.ts +29 -0
  219. package/dist/src/discussions/repository.js +255 -0
  220. package/dist/src/discussions/service.d.ts +51 -0
  221. package/dist/src/discussions/service.js +335 -0
  222. package/dist/src/discussions/transcript.d.ts +3 -0
  223. package/dist/src/discussions/transcript.js +15 -0
  224. package/dist/src/discussions/types.d.ts +116 -0
  225. package/dist/src/discussions/types.js +10 -0
  226. package/dist/src/discussions/worker.d.ts +18 -0
  227. package/dist/src/discussions/worker.js +74 -0
  228. package/dist/src/extensions/activation-context.js +2 -1
  229. package/dist/src/extensions/lockfile.js +1 -1
  230. package/dist/src/extensions/sdk/testing.js +1 -1
  231. package/dist/src/gateway/agents-admin.js +3 -3
  232. package/dist/src/gateway/chat-stream/mapper.js +53 -3
  233. package/dist/src/gateway/chat-stream/protocol.d.ts +17 -1
  234. package/dist/src/gateway/file-path-classifier.js +1 -1
  235. package/dist/src/gateway/hono/app.js +8 -3
  236. package/dist/src/gateway/hono/lib/config-payload.js +2 -2
  237. package/dist/src/gateway/hono/middleware/auth.js +2 -2
  238. package/dist/src/gateway/hono/middleware/logger.js +1 -1
  239. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +1 -1
  240. package/dist/src/gateway/hono/oauth-async.js +1 -7
  241. package/dist/src/gateway/hono/oauth.js +1 -7
  242. package/dist/src/gateway/hono/routes/agents.js +1 -1
  243. package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
  244. package/dist/src/gateway/hono/routes/connectors.js +79 -0
  245. package/dist/src/gateway/hono/routes/discussions.d.ts +3 -0
  246. package/dist/src/gateway/hono/routes/discussions.js +177 -0
  247. package/dist/src/gateway/hono/routes/execution-receipts.d.ts +3 -0
  248. package/dist/src/gateway/hono/routes/execution-receipts.js +163 -0
  249. package/dist/src/gateway/hono/routes/exposure.js +1 -1
  250. package/dist/src/gateway/hono/routes/goals.js +3 -288
  251. package/dist/src/gateway/hono/routes/home.d.ts +2 -102
  252. package/dist/src/gateway/hono/routes/home.js +8 -424
  253. package/dist/src/gateway/hono/routes/index.js +6 -2
  254. package/dist/src/gateway/hono/routes/memory.js +7 -7
  255. package/dist/src/gateway/hono/routes/models.js +1 -1
  256. package/dist/src/gateway/hono/routes/notes.js +30 -0
  257. package/dist/src/gateway/hono/routes/projects.js +8 -152
  258. package/dist/src/gateway/hono/routes/shares.js +1 -1
  259. package/dist/src/gateway/hono/routes/status.js +2 -2
  260. package/dist/src/gateway/hono/routes/tunnel.js +3 -3
  261. package/dist/src/gateway/hono/routes/voice.js +1 -1
  262. package/dist/src/gateway/hono/routes/work.d.ts +3 -0
  263. package/dist/src/gateway/hono/routes/work.js +207 -0
  264. package/dist/src/gateway/hono/routes/you.js +13 -15
  265. package/dist/src/gateway/index.js +2 -2
  266. package/dist/src/gateway/runtime-config.js +2 -2
  267. package/dist/src/gateway/security/audit.js +2 -2
  268. package/dist/src/gateway/security/index.js +1 -1
  269. package/dist/src/gateway/service/config-coordinator.js +2 -2
  270. package/dist/src/gateway/service/run-gateway-agent.js +46 -51
  271. package/dist/src/gateway/service.d.ts +8 -1
  272. package/dist/src/gateway/service.js +142 -15
  273. package/dist/src/goals/goal-queue-store.d.ts +1 -0
  274. package/dist/src/goals/goal-queue-store.js +5 -1
  275. package/dist/src/goals/goal-queue-types.d.ts +11 -1
  276. package/dist/src/goals/goal-runner.js +10 -6
  277. package/dist/src/goals/goal-service.d.ts +2 -15
  278. package/dist/src/goals/goal-service.js +9 -42
  279. package/dist/src/goals/goal-store.d.ts +1 -18
  280. package/dist/src/goals/goal-store.js +25 -231
  281. package/dist/src/goals/goal-workflow-judge.js +1 -1
  282. package/dist/src/goals/index.d.ts +0 -4
  283. package/dist/src/goals/index.js +1 -3
  284. package/dist/src/goals/types.d.ts +4 -66
  285. package/dist/src/notes/agent-context.js +1 -1
  286. package/dist/src/notes/service.d.ts +1 -0
  287. package/dist/src/notes/service.js +10 -1
  288. package/dist/src/notes/types.d.ts +1 -0
  289. package/dist/src/proactive/events/product-event-bridge.d.ts +7 -0
  290. package/dist/src/proactive/events/product-event-bridge.js +84 -0
  291. package/dist/src/proactive/execution/context.d.ts +27 -11
  292. package/dist/src/proactive/execution/context.js +259 -25
  293. package/dist/src/proactive/execution/repository.js +18 -5
  294. package/dist/src/proactive/execution/types.d.ts +7 -1
  295. package/dist/src/proactive/execution/worker.js +7 -6
  296. package/dist/src/proactive/inbox/repository.js +8 -2
  297. package/dist/src/proactive/index.d.ts +4 -2
  298. package/dist/src/proactive/index.js +5 -3
  299. package/dist/src/proactive/temporal/worker.d.ts +16 -0
  300. package/dist/src/proactive/temporal/worker.js +110 -0
  301. package/dist/src/projects/project-loop.js +3 -3
  302. package/dist/src/providers/auth-runtime/oauth.js +12 -0
  303. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  304. package/dist/src/providers/index.js +2 -2
  305. package/dist/src/providers/model-registry.js +1 -1
  306. package/dist/src/providers/register-runtime-providers.js +1 -1
  307. package/dist/src/share/share-zip.js +1 -1
  308. package/dist/src/share/site-proxy.js +1 -1
  309. package/dist/src/storage/sqlite/activity-repository.d.ts +1 -0
  310. package/dist/src/storage/sqlite/activity-repository.js +4 -1
  311. package/dist/src/storage/sqlite/connector-sync-policy-repository.d.ts +20 -0
  312. package/dist/src/storage/sqlite/connector-sync-policy-repository.js +50 -0
  313. package/dist/src/storage/sqlite/execution-receipt-repository.d.ts +146 -0
  314. package/dist/src/storage/sqlite/execution-receipt-repository.js +235 -0
  315. package/dist/src/storage/sqlite/index.d.ts +4 -2
  316. package/dist/src/storage/sqlite/index.js +6 -4
  317. package/dist/src/storage/sqlite/knowledge-repository.d.ts +3 -0
  318. package/dist/src/storage/sqlite/knowledge-repository.js +9 -1
  319. package/dist/src/storage/sqlite/memory-records-repository.js +1 -1
  320. package/dist/src/storage/sqlite/migrations/075_connector_sync_policies.sql +13 -0
  321. package/dist/src/storage/sqlite/migrations/076_meeting_preparation_scenario.sql +29 -0
  322. package/dist/src/storage/sqlite/migrations/077_proactive_insight_fingerprints.sql +4 -0
  323. package/dist/src/storage/sqlite/migrations/078_discussion_captures.sql +64 -0
  324. package/dist/src/storage/sqlite/migrations/079_discussion_follow_up_scenario.sql +29 -0
  325. package/dist/src/storage/sqlite/migrations/080_task_outcome_context.sql +15 -0
  326. package/dist/src/storage/sqlite/migrations/081_project_monitoring_policies.sql +10 -0
  327. package/dist/src/storage/sqlite/migrations/082_one_click_live_discussions.sql +100 -0
  328. package/dist/src/storage/sqlite/migrations/083_session_task_plans.sql +9 -0
  329. package/dist/src/storage/sqlite/migrations/084_work_intake_lifecycle.sql +26 -0
  330. package/dist/src/storage/sqlite/migrations/085_task_outcome_projection.sql +19 -0
  331. package/dist/src/storage/sqlite/migrations/086_outcome_aggregates.sql +168 -0
  332. package/dist/src/storage/sqlite/migrations/087_context_snapshots.sql +21 -0
  333. package/dist/src/storage/sqlite/migrations/088_automation_execution_deadlines.sql +5 -0
  334. package/dist/src/storage/sqlite/migrations/089_automation_run_leases.sql +8 -0
  335. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  336. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  337. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  338. package/dist/src/storage/sqlite/notes-repository.js +9 -0
  339. package/dist/src/storage/sqlite/schema.js +1 -1
  340. package/dist/src/storage/sqlite/schema.sql +89 -44
  341. package/dist/src/storage/sqlite/session-repository.js +1 -1
  342. package/dist/src/storage/sqlite/session-task-plan-repository.d.ts +20 -0
  343. package/dist/src/storage/sqlite/session-task-plan-repository.js +77 -0
  344. package/dist/src/tui/backends/embedded-backend.d.ts +2 -0
  345. package/dist/src/tui/backends/embedded-backend.js +12 -8
  346. package/dist/src/tui/tui-backend.d.ts +2 -0
  347. package/dist/src/tui/tui-oauth-login.js +1 -7
  348. package/dist/src/tui/tui-picker-overlay.js +1 -0
  349. package/dist/src/tui/tui-picker-services.d.ts +1 -0
  350. package/dist/src/tui/tui-skills-autocomplete.d.ts +6 -2
  351. package/dist/src/tui/tui-skills-autocomplete.js +10 -6
  352. package/dist/src/tui/tui-startup-resources.d.ts +3 -1
  353. package/dist/src/tui/tui-startup-resources.js +4 -3
  354. package/dist/src/tui/tui.js +4 -1
  355. package/dist/src/tunnel/frpc-binary.js +1 -1
  356. package/dist/src/tunnel/frpc-extract.js +1 -1
  357. package/dist/src/tunnel/index.js +2 -2
  358. package/dist/src/user-context/context-compiler.d.ts +31 -0
  359. package/dist/src/user-context/context-compiler.js +51 -0
  360. package/dist/src/voice/local/model-files.js +1 -1
  361. package/dist/src/voice/stt/config.d.ts +4 -0
  362. package/dist/src/voice/stt/config.js +26 -0
  363. package/dist/src/voice/stt/index.d.ts +1 -0
  364. package/dist/src/voice/stt/index.js +2 -1
  365. package/dist/src/voice/stt/list-providers.js +1 -1
  366. package/dist/src/work/attention-governor.d.ts +20 -0
  367. package/dist/src/work/attention-governor.js +46 -0
  368. package/dist/src/work/execution-context.d.ts +16 -0
  369. package/dist/src/work/execution-context.js +66 -0
  370. package/dist/src/work/home-query-service.d.ts +147 -0
  371. package/dist/src/work/home-query-service.js +389 -0
  372. package/dist/src/work/index.d.ts +14 -0
  373. package/dist/src/work/index.js +15 -0
  374. package/dist/src/work/outcome-contract-definition.d.ts +8 -0
  375. package/dist/src/work/outcome-contract-definition.js +15 -0
  376. package/dist/src/work/outcome-execution-service.d.ts +27 -0
  377. package/dist/src/work/outcome-execution-service.js +60 -0
  378. package/dist/src/work/outcome-projection-service.d.ts +7 -0
  379. package/dist/src/work/outcome-projection-service.js +51 -0
  380. package/dist/src/work/outcome-receipt-service.d.ts +13 -0
  381. package/dist/src/work/outcome-receipt-service.js +55 -0
  382. package/dist/src/work/outcome-repository.d.ts +50 -0
  383. package/dist/src/work/outcome-repository.js +112 -0
  384. package/dist/src/work/outcome-run-coordinator.d.ts +25 -0
  385. package/dist/src/work/outcome-run-coordinator.js +117 -0
  386. package/dist/src/work/project-monitoring-service.d.ts +21 -0
  387. package/dist/src/work/project-monitoring-service.js +76 -0
  388. package/dist/src/work/project-operating-view-service.d.ts +10 -0
  389. package/dist/src/work/project-operating-view-service.js +46 -0
  390. package/dist/src/work/work-intake-repository.d.ts +49 -0
  391. package/dist/src/work/work-intake-repository.js +97 -0
  392. package/dist/src/work/work-intake-service.d.ts +26 -0
  393. package/dist/src/work/work-intake-service.js +171 -0
  394. package/dist/src/work/work-value-metrics-service.d.ts +4 -0
  395. package/dist/src/work/work-value-metrics-service.js +88 -0
  396. package/dist/src/work-items/work-item-service.d.ts +0 -2
  397. package/dist/src/work-items/work-item-service.js +0 -28
  398. package/dist/src/workflows/service/workflow-run-service.js +2 -2
  399. package/dist/src/workflows/service/workflow-run-service.types.d.ts +3 -1
  400. package/dist/src/workflows/service/workflow-session-bridge.js +2 -2
  401. package/package.json +1 -1
  402. package/dist/gateway/static/root/assets/agents-DC9F12Kw.js +0 -2
  403. package/dist/gateway/static/root/assets/apps-page-5bKr05Fa.js +0 -1
  404. package/dist/gateway/static/root/assets/automation-suggestion-card-B7mxFRtf.js +0 -1
  405. package/dist/gateway/static/root/assets/automations-page-Dg6dmt5g.js +0 -6
  406. package/dist/gateway/static/root/assets/browser-settings-page-BHoo6Rpq.js +0 -8
  407. package/dist/gateway/static/root/assets/capabilities-settings-panel-BlsqN8Fu.js +0 -7
  408. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJeT8_B4.js +0 -1
  409. package/dist/gateway/static/root/assets/channels-settings-C4VVjYEm.js +0 -1
  410. package/dist/gateway/static/root/assets/channels-status-swr-vdf8kB16.js +0 -1
  411. package/dist/gateway/static/root/assets/circle-alert-BEjgurr2.js +0 -1
  412. package/dist/gateway/static/root/assets/connectors-page-DNcrDThX.js +0 -2
  413. package/dist/gateway/static/root/assets/desktop-pet-B1urphOZ.js +0 -1
  414. package/dist/gateway/static/root/assets/desktop-pet-settings-DTL6J3EP.js +0 -1
  415. package/dist/gateway/static/root/assets/gateway-settings-DmObBx9b.js +0 -1
  416. package/dist/gateway/static/root/assets/goal-create-dialog-BRhmmBe9.js +0 -1
  417. package/dist/gateway/static/root/assets/goal-detail-page-C1k7_s_O.js +0 -4
  418. package/dist/gateway/static/root/assets/goals-config-api-Fwu1wjEP.js +0 -1
  419. package/dist/gateway/static/root/assets/goals-page-hOu9uA3q.js +0 -2
  420. package/dist/gateway/static/root/assets/goals-settings-DY-JjvHz.js +0 -1
  421. package/dist/gateway/static/root/assets/index-C0CGebQ1.js +0 -212
  422. package/dist/gateway/static/root/assets/index-eqq25gvV.css +0 -1
  423. package/dist/gateway/static/root/assets/local-app-workbench-page-EjsNT7nJ.js +0 -2
  424. package/dist/gateway/static/root/assets/logs-page-Dswjlraa.js +0 -7
  425. package/dist/gateway/static/root/assets/messages-DP6tPKk-.js +0 -3
  426. package/dist/gateway/static/root/assets/notes-workbench-DSh3-hMY.js +0 -4
  427. package/dist/gateway/static/root/assets/product-delivery-BTRT9kCS.js +0 -1
  428. package/dist/gateway/static/root/assets/project-detail-page-D0QPRHR_.js +0 -1
  429. package/dist/gateway/static/root/assets/projects-page-CI5Vz62F.js +0 -1
  430. package/dist/gateway/static/root/assets/remote-access-hub-S1jpzBS5.js +0 -1
  431. package/dist/gateway/static/root/assets/sessions-page-CTm66k7h.js +0 -1
  432. package/dist/gateway/static/root/assets/settings-advanced-gate-CU52AUVD.js +0 -1
  433. package/dist/gateway/static/root/assets/shares-settings-DK6XK95e.js +0 -1
  434. package/dist/gateway/static/root/assets/skill-reload-api-Bvv_u4ii.js +0 -1
  435. package/dist/gateway/static/root/assets/skills-page-BGHvVbay.js +0 -2
  436. package/dist/gateway/static/root/assets/time-picker-XwpxdZFr.js +0 -1
  437. package/dist/gateway/static/root/assets/user-context-page-DBCMk-Vn.js +0 -1
  438. package/dist/gateway/static/root/assets/work-discovery-page-C1UIdsCl.js +0 -1
  439. package/dist/gateway/static/root/assets/work-item-detail-page-DEAQepB8.js +0 -1
  440. package/dist/gateway/static/root/assets/work-page-D5qYmCTq.js +0 -3
  441. package/dist/gateway/static/root/assets/workflows-page-yrK17ZZ5.js +0 -11
  442. package/dist/src/agent/outcomes/task-verifier.d.ts +0 -29
  443. package/dist/src/gateway/hono/routes/task-outcomes.d.ts +0 -3
  444. package/dist/src/gateway/hono/routes/task-outcomes.js +0 -109
  445. package/dist/src/goals/goal-contract-draft.d.ts +0 -15
  446. package/dist/src/goals/goal-contract-draft.js +0 -112
  447. package/dist/src/goals/goal-evidence-review.d.ts +0 -15
  448. package/dist/src/goals/goal-evidence-review.js +0 -89
  449. package/dist/src/storage/sqlite/task-outcome-repository.d.ts +0 -90
  450. package/dist/src/storage/sqlite/task-outcome-repository.js +0 -138
@@ -37,6 +37,7 @@ export { createSkillInstallTool, type SkillInstallToolDeps, type SkillInstallToo
37
37
  export { createToolManualTool } from './tool-manual-tool.js';
38
38
  export { createDesktopPetTool, type DesktopPetCreateDetails } from './desktop-pet-tool.js';
39
39
  export { createCodeIntelligenceTools } from '../code-intelligence/tools.js';
40
+ export { createManagedJobTool } from './managed-job-tool.js';
40
41
  export { createImageTool, resolveImageModelConfigForTool } from './image-tool.js';
41
42
  export { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from './image-generate-tool.js';
42
43
  export { truncateHead, truncateTail, truncateLine, formatSize, type TruncationResult, type TruncationOptions, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES, GREP_MAX_LINE_LENGTH, } from './truncate.js';
@@ -41,7 +41,8 @@ import { createSkillInstallTool } from "./skill-install-tool.js";
41
41
  import { createToolManualTool } from "./tool-manual-tool.js";
42
42
  import { createDesktopPetTool } from "./desktop-pet-tool.js";
43
43
  import { createCodeIntelligenceTools } from "../code-intelligence/tools.js";
44
+ import { createManagedJobTool } from "./managed-job-tool.js";
44
45
  import { resolveImageModelConfigForTool } from "../image/tool-model-config.js";
45
46
  import { createImageTool } from "./image-tool.js";
46
47
  import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
47
- export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createBrowserRecipeTool, createClarifyTool, createCodeIntelligenceTools, createComposioTools, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDesktopPetTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
48
+ export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createBrowserRecipeTool, createClarifyTool, createCodeIntelligenceTools, createComposioTools, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDesktopPetTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createManagedJobTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
@@ -0,0 +1,2 @@
1
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ export declare function createManagedJobTool(workspace: string, getSessionKey: () => string | undefined, getSkillPassthroughEnvVarNames?: () => string[]): AgentTool;
@@ -0,0 +1,160 @@
1
+ import { resolveGlobalSingleton } from "../../utils/global-singleton.js";
2
+ import { evaluateExecPolicy } from "../sandbox/exec-policy.js";
3
+ import { resolve } from "node:path";
4
+ import { spawn } from "node:child_process";
5
+ import { randomUUID } from "node:crypto";
6
+ import { Type } from "@sinclair/typebox";
7
+ //#region src/agent/tools/managed-job-tool.ts
8
+ const MANAGED_JOB_REGISTRY_KEY = Symbol.for("xopc.managedJobRegistry");
9
+ const DEFAULT_MAX_RUNTIME_MS = 60 * 6e4;
10
+ const MAX_RUNTIME_MS = 1440 * 6e4;
11
+ const MAX_CAPTURE_CHARS = 2e5;
12
+ var ManagedJobRegistry = class {
13
+ jobs = /* @__PURE__ */ new Map();
14
+ start(owner, command, cwd, env, maxRuntimeMs) {
15
+ this.prune();
16
+ const id = randomUUID();
17
+ const child = spawn(command, [], {
18
+ shell: true,
19
+ cwd,
20
+ env,
21
+ detached: process.platform !== "win32"
22
+ });
23
+ const job = {
24
+ id,
25
+ owner,
26
+ command,
27
+ cwd,
28
+ status: "running",
29
+ process: child,
30
+ pid: child.pid,
31
+ createdAtMs: Date.now(),
32
+ stdout: "",
33
+ stderr: "",
34
+ timeout: setTimeout(() => this.stop(job, "timed_out"), maxRuntimeMs)
35
+ };
36
+ job.timeout.unref?.();
37
+ const append = (stream, value) => {
38
+ const next = `${job[stream]}${String(value)}`;
39
+ job[stream] = next.length > MAX_CAPTURE_CHARS ? next.slice(-MAX_CAPTURE_CHARS) : next;
40
+ };
41
+ child.stdout?.on("data", (value) => append("stdout", value));
42
+ child.stderr?.on("data", (value) => append("stderr", value));
43
+ child.on("error", (error) => append("stderr", `\n${error.message}`));
44
+ child.on("close", (exitCode) => {
45
+ if (job.status === "running") job.status = exitCode === 0 ? "succeeded" : "failed";
46
+ job.exitCode = exitCode;
47
+ job.endedAtMs = Date.now();
48
+ clearTimeout(job.timeout);
49
+ });
50
+ this.jobs.set(id, job);
51
+ return this.view(job);
52
+ }
53
+ get(owner, id) {
54
+ const job = this.jobs.get(id);
55
+ return job?.owner === owner ? this.view(job) : void 0;
56
+ }
57
+ list(owner) {
58
+ return [...this.jobs.values()].filter((job) => job.owner === owner).toSorted((a, b) => b.createdAtMs - a.createdAtMs).slice(0, 50).map((job) => this.view(job));
59
+ }
60
+ cancel(owner, id) {
61
+ const job = this.jobs.get(id);
62
+ if (!job || job.owner !== owner) return void 0;
63
+ if (job.status === "running") this.stop(job, "cancelled");
64
+ return this.view(job);
65
+ }
66
+ stop(job, status) {
67
+ if (job.status !== "running") return;
68
+ job.status = status;
69
+ job.endedAtMs = Date.now();
70
+ clearTimeout(job.timeout);
71
+ if (job.pid && process.platform !== "win32") try {
72
+ process.kill(-job.pid, "SIGTERM");
73
+ return;
74
+ } catch {}
75
+ job.process.kill("SIGTERM");
76
+ }
77
+ view(job) {
78
+ const outputLength = job.stdout.length + job.stderr.length;
79
+ return {
80
+ id: job.id,
81
+ command: job.command,
82
+ cwd: job.cwd,
83
+ status: job.status,
84
+ pid: job.pid,
85
+ createdAtMs: job.createdAtMs,
86
+ endedAtMs: job.endedAtMs,
87
+ exitCode: job.exitCode,
88
+ stdout: job.stdout,
89
+ stderr: job.stderr,
90
+ durationMs: (job.endedAtMs ?? Date.now()) - job.createdAtMs,
91
+ outputTruncated: outputLength >= MAX_CAPTURE_CHARS
92
+ };
93
+ }
94
+ prune() {
95
+ if (this.jobs.size < 500) return;
96
+ const removable = [...this.jobs.values()].filter((job) => job.status !== "running").toSorted((a, b) => a.createdAtMs - b.createdAtMs).slice(0, Math.max(1, this.jobs.size - 400));
97
+ for (const job of removable) this.jobs.delete(job.id);
98
+ }
99
+ };
100
+ const ManagedJobSchema = Type.Union([
101
+ Type.Object({
102
+ action: Type.Literal("start"),
103
+ command: Type.String(),
104
+ cwd: Type.Optional(Type.String()),
105
+ maxRuntimeMs: Type.Optional(Type.Number())
106
+ }),
107
+ Type.Object({
108
+ action: Type.Literal("status"),
109
+ jobId: Type.String()
110
+ }),
111
+ Type.Object({ action: Type.Literal("list") }),
112
+ Type.Object({
113
+ action: Type.Literal("cancel"),
114
+ jobId: Type.String()
115
+ })
116
+ ]);
117
+ function registry() {
118
+ return resolveGlobalSingleton(MANAGED_JOB_REGISTRY_KEY, () => new ManagedJobRegistry());
119
+ }
120
+ function result(value) {
121
+ return {
122
+ content: [{
123
+ type: "text",
124
+ text: JSON.stringify(value, null, 2)
125
+ }],
126
+ details: {}
127
+ };
128
+ }
129
+ function createManagedJobTool(workspace, getSessionKey, getSkillPassthroughEnvVarNames) {
130
+ return {
131
+ name: "managed_job",
132
+ label: "Managed Job",
133
+ description: "Start and manage commands expected to outlive a single tool call. Start returns a jobId immediately; use status/list/cancel to observe or stop it.",
134
+ parameters: ManagedJobSchema,
135
+ supportsParallel: true,
136
+ idempotent: false,
137
+ async execute(_toolCallId, input) {
138
+ const owner = getSessionKey() ?? "default";
139
+ if (input.action === "list") return result(registry().list(owner));
140
+ if (input.action === "status") return result(registry().get(owner, input.jobId) ?? { error: "Managed job not found" });
141
+ if (input.action === "cancel") return result(registry().cancel(owner, input.jobId) ?? { error: "Managed job not found" });
142
+ const command = String(input.command ?? "").trim();
143
+ if (!command) return result({ error: "command is required" });
144
+ const policy = evaluateExecPolicy({
145
+ command,
146
+ cwd: input.cwd?.trim() ? resolve(workspace, input.cwd.trim()) : workspace,
147
+ allowedEnvVars: getSkillPassthroughEnvVarNames?.() ?? []
148
+ });
149
+ if (!policy.allowed) return result({ error: `Sandbox blocked command: ${policy.reason}` });
150
+ const rawMax = Number(input.maxRuntimeMs ?? DEFAULT_MAX_RUNTIME_MS);
151
+ const maxRuntimeMs = Math.min(MAX_RUNTIME_MS, Math.max(1e3, Number.isFinite(rawMax) ? rawMax : DEFAULT_MAX_RUNTIME_MS));
152
+ return result(registry().start(owner, command, policy.effectiveCwd, {
153
+ ...policy.sanitizedEnv,
154
+ COLUMNS: "200"
155
+ }, maxRuntimeMs));
156
+ }
157
+ };
158
+ }
159
+ //#endregion
160
+ export { createManagedJobTool };
@@ -16,6 +16,11 @@ export declare class TodoStore {
16
16
  export interface CreateTodoToolOptions {
17
17
  /** Resolve session key for isolated lists; defaults to a single in-memory list. */
18
18
  getSessionKey?: () => string | null | undefined;
19
+ repository?: {
20
+ isAvailable?: () => boolean;
21
+ read: (sessionKey: string) => TodoItem[];
22
+ write: (sessionKey: string, items: TodoItem[]) => void;
23
+ };
19
24
  }
20
25
  /**
21
26
  * In-session task list for multi-step work. One {@link TodoStore} per session key.
@@ -97,8 +97,17 @@ function resolveSessionKey(getSessionKey) {
97
97
  function createTodoTool(options) {
98
98
  const getSessionKey = options?.getSessionKey ?? (() => "default");
99
99
  const stores = /* @__PURE__ */ new Map();
100
- const getStore = () => {
101
- const key = resolveSessionKey(getSessionKey);
100
+ const activeRepository = () => {
101
+ const repository = options?.repository;
102
+ return repository && (repository.isAvailable?.() ?? true) ? repository : void 0;
103
+ };
104
+ const getStore = (key) => {
105
+ const repository = activeRepository();
106
+ if (repository) {
107
+ const store = new TodoStore();
108
+ store.write(repository.read(key), false);
109
+ return store;
110
+ }
102
111
  let s = stores.get(key);
103
112
  if (!s) {
104
113
  s = new TodoStore();
@@ -112,8 +121,10 @@ function createTodoTool(options) {
112
121
  description: "Plan and track tasks for complex multi-step work.\n\nUSAGE:\n- Provide `todos` array to write/update tasks\n- Omit `todos` to read the current list\n- Set `merge: true` to update existing items by id without replacing the whole list\n- Each item needs: id (unique string), content (task description), status\n- Valid statuses: pending, in_progress, completed, cancelled\n\nWHEN TO USE:\n- At the start of complex tasks (3+ steps) to plan your approach\n- After completing each step to update progress\n- When the user asks about progress or remaining work\n\nBEST PRACTICES:\n- Keep only one item in_progress at a time\n- Use merge=true to update status without rewriting the whole list\n- Create concrete, actionable items (not vague goals)",
113
122
  parameters: TodoSchema,
114
123
  async execute(_toolCallId, params, _signal) {
115
- const store = getStore();
124
+ let store;
116
125
  try {
126
+ const key = resolveSessionKey(getSessionKey);
127
+ store = getStore(key);
117
128
  if (params.todos === void 0) {
118
129
  const items = store.read();
119
130
  return {
@@ -126,6 +137,7 @@ function createTodoTool(options) {
126
137
  }
127
138
  const p = params;
128
139
  const items = store.write(p.todos, p.merge ?? false);
140
+ activeRepository()?.write(key, items);
129
141
  return {
130
142
  content: [{
131
143
  type: "text",
@@ -139,7 +151,7 @@ function createTodoTool(options) {
139
151
  type: "text",
140
152
  text: `Error: ${error instanceof Error ? error.message : String(error)}`
141
153
  }],
142
- details: { items: store.read() }
154
+ details: { items: store?.read() ?? [] }
143
155
  };
144
156
  }
145
157
  }
@@ -1,6 +1,7 @@
1
1
  import type { AgentTool } from '@earendil-works/pi-agent-core';
2
2
  export type TurnPlanStatus = 'pending' | 'in_progress' | 'completed';
3
3
  export interface TurnPlanStep {
4
+ id?: string;
4
5
  step: string;
5
6
  status: TurnPlanStatus;
6
7
  }
@@ -6,6 +6,10 @@ const VALID_STATUSES = new Set([
6
6
  "completed"
7
7
  ]);
8
8
  const PlanStepSchema = Type.Object({
9
+ id: Type.Optional(Type.String({
10
+ minLength: 1,
11
+ description: "Stable identifier for this step"
12
+ })),
9
13
  step: Type.String({
10
14
  minLength: 1,
11
15
  description: "Short task step"
@@ -28,11 +32,13 @@ function normalizePlan(raw) {
28
32
  if (!Array.isArray(raw)) throw new Error("plan must be an array");
29
33
  const plan = raw.map((item) => {
30
34
  const rec = item && typeof item === "object" ? item : {};
35
+ const id = typeof rec.id === "string" && rec.id.trim() ? rec.id.trim() : void 0;
31
36
  const step = String(rec.step ?? "").trim();
32
37
  const statusRaw = String(rec.status ?? "").trim();
33
38
  if (!step) throw new Error("each plan item must include a non-empty step");
34
39
  if (!VALID_STATUSES.has(statusRaw)) throw new Error(`invalid plan status: ${statusRaw || "(empty)"}`);
35
40
  return {
41
+ ...id ? { id } : {},
36
42
  step,
37
43
  status: statusRaw
38
44
  };
@@ -34,6 +34,8 @@ export interface WorkspaceRuntimeRegistryOptions {
34
34
  bundledSkillsDir: string;
35
35
  /** Called after a runtime is first created for a workspace. */
36
36
  onRuntimeCreated?: (resolvedPath: string) => void;
37
+ /** Dynamic project trust lookup used by workspace compatibility skills. */
38
+ isWorkspaceTrusted?: (resolvedPath: string) => boolean;
37
39
  }
38
40
  export declare class WorkspaceRuntimeRegistry {
39
41
  private readonly runtimes;
@@ -41,6 +43,7 @@ export declare class WorkspaceRuntimeRegistry {
41
43
  private readonly getConfig;
42
44
  private readonly bundledSkillsDir;
43
45
  private readonly onRuntimeCreated?;
46
+ private readonly isWorkspaceTrusted?;
44
47
  private readonly userContextRuntimes;
45
48
  constructor(opts: WorkspaceRuntimeRegistryOptions);
46
49
  /** Lazily construct and cache an agent-scoped runtime for a workspace. */
@@ -18,11 +18,13 @@ var WorkspaceRuntimeRegistry = class {
18
18
  getConfig;
19
19
  bundledSkillsDir;
20
20
  onRuntimeCreated;
21
+ isWorkspaceTrusted;
21
22
  userContextRuntimes = new UserContextRuntimeRegistry();
22
23
  constructor(opts) {
23
24
  this.getConfig = opts.getConfig;
24
25
  this.bundledSkillsDir = opts.bundledSkillsDir;
25
26
  this.onRuntimeCreated = opts.onRuntimeCreated;
27
+ this.isWorkspaceTrusted = opts.isWorkspaceTrusted;
26
28
  }
27
29
  /** Lazily construct and cache an agent-scoped runtime for a workspace. */
28
30
  getOrCreate(resolvedPath, requestedAgentId) {
@@ -31,7 +33,7 @@ var WorkspaceRuntimeRegistry = class {
31
33
  const existing = this.runtimes.get(runtimeKey);
32
34
  if (existing) return existing;
33
35
  const { builtinMemoryStore, memoryManager } = this.userContextRuntimes.getOrCreate(cfg);
34
- const skillManager = new SkillManager(resolvedPath, this.bundledSkillsDir);
36
+ const skillManager = new SkillManager(resolvedPath, this.bundledSkillsDir, { isWorkspaceTrusted: () => this.isWorkspaceTrusted?.(resolvedPath) === true });
35
37
  const rt = {
36
38
  skillManager,
37
39
  systemPromptBuilder: new SystemPromptBuilder({
@@ -1,7 +1,7 @@
1
- import { buildMemoryRuntime } from "./memory-runtime.js";
2
1
  import { checkBoundary } from "./boundary-guard.js";
3
2
  import { resolveModelRole } from "./model-router.js";
4
3
  import { buildRuntimeToolRegistry } from "./tool-registry.js";
4
+ import { buildMemoryRuntime } from "./memory-runtime.js";
5
5
  import { resolveWorkflow, validateWorkflowForRuntime } from "./workflow-runtime.js";
6
6
  import { buildAgentRuntimeProfile } from "./runtime-profile.js";
7
7
  import { appendAgentRunEvent, createAgentRunTrace, finishAgentRunTrace, hashEffectiveManifest } from "./run-trace.js";
@@ -1,9 +1,9 @@
1
1
  import { buildAgentManifestPromptSection } from "../agent-manifest/prompt.js";
2
2
  import "../agent-manifest/index.js";
3
- import { buildMemoryRuntime } from "./memory-runtime.js";
4
3
  import { checkBoundary } from "./boundary-guard.js";
5
4
  import { resolveModelRole } from "./model-router.js";
6
5
  import { buildRuntimeToolRegistry } from "./tool-registry.js";
6
+ import { buildMemoryRuntime } from "./memory-runtime.js";
7
7
  import { resolveWorkflow, validateWorkflowForRuntime } from "./workflow-runtime.js";
8
8
  //#region src/agent-runtime/runtime-profile.ts
9
9
  function buildAgentRuntimeProfile(params) {
@@ -1,4 +1,5 @@
1
1
  import type { Config } from '../config/schema.js';
2
+ import type { OAuthCredentials } from './oauth/types.js';
2
3
  export type CredentialType = 'api_key' | 'oauth';
3
4
  export interface ApiKeyProfile {
4
5
  type: 'api_key';
@@ -17,6 +18,7 @@ export interface OAuthToken {
17
18
  createdAt: string;
18
19
  updatedAt: string;
19
20
  }
21
+ type OAuthTokenInput = Omit<OAuthToken, 'type' | 'provider' | 'updatedAt'> & Record<string, unknown>;
20
22
  export type CredentialProfile = ApiKeyProfile;
21
23
  export interface AuthProfilesFile {
22
24
  version: number;
@@ -77,6 +79,7 @@ export declare class CredentialResolver {
77
79
  * Load OAuth token for a provider.
78
80
  */
79
81
  loadOAuthToken(provider: string): Promise<OAuthToken | null>;
82
+ private hasUsableOAuthTokenRecord;
80
83
  /**
81
84
  * Load the raw OAuth token record, including expired tokens for status UIs.
82
85
  */
@@ -88,10 +91,14 @@ export declare class CredentialResolver {
88
91
  hasAccess: boolean;
89
92
  hasRefresh: boolean;
90
93
  }>>;
94
+ /**
95
+ * Save raw provider OAuth credentials without converting them to an API key representation.
96
+ */
97
+ saveOAuthCredentials(provider: string, credentials: OAuthCredentials): Promise<void>;
91
98
  /**
92
99
  * Save OAuth token for a provider.
93
100
  */
94
- saveOAuthToken(provider: string, token: Omit<OAuthToken, 'type' | 'provider' | 'updatedAt'>): Promise<void>;
101
+ saveOAuthToken(provider: string, token: OAuthTokenInput): Promise<void>;
95
102
  /**
96
103
  * Delete the OAuth token persisted for a provider.
97
104
  */
@@ -114,3 +121,4 @@ export declare class CredentialResolver {
114
121
  export declare function getCredentialResolver(options?: CredentialResolverOptions): CredentialResolver;
115
122
  export declare function resolveApiKey(provider: string, options?: CredentialResolverOptions): Promise<string | null>;
116
123
  export declare function hasCredentials(provider: string, options?: CredentialResolverOptions): Promise<boolean>;
124
+ export {};
@@ -1,13 +1,41 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
- import { init_paths, resolveAgentAuthProfilesPath, resolveAuthProfilesPath, resolveCredentialsDir, resolveOAuthPath } from "../config/paths.js";
5
4
  import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
6
- import { getOAuthProviderDefinition, init_registry } from "./oauth/registry.js";
5
+ import { init_paths, resolveAgentAuthProfilesPath, resolveAuthProfilesPath, resolveCredentialsDir, resolveOAuthPath } from "../config/paths.js";
7
6
  import { getApiKeyFromEnv, init_env_keys } from "../providers/env-keys.js";
7
+ import { getOAuthProviderDefinition, init_registry } from "./oauth/registry.js";
8
+ import { init_oauth_provider_lock, withOAuthProviderLock } from "./oauth-provider-lock.js";
8
9
  import { dirname, join } from "path";
9
10
  import { mkdir, readFile, readdir, rm } from "fs/promises";
10
11
  //#region src/auth/credentials.ts
12
+ function toOAuthCredentials(token) {
13
+ const { type: _type, provider: _provider, expiresAt, createdAt: _createdAt, updatedAt: _updatedAt, ...providerFields } = token;
14
+ return {
15
+ ...providerFields,
16
+ access: token.access,
17
+ refresh: token.refresh ?? "",
18
+ expires: expiresAt ?? Number.MAX_SAFE_INTEGER
19
+ };
20
+ }
21
+ function normalizeLegacyOAuthToken(token) {
22
+ if (token.provider !== "google-gemini-cli" && token.provider !== "google-antigravity") return token;
23
+ let access = token.access;
24
+ let projectId = token.projectId;
25
+ for (let depth = 0; depth < 5; depth += 1) try {
26
+ const legacy = JSON.parse(access);
27
+ if (typeof legacy.token !== "string" || !legacy.token) break;
28
+ access = legacy.token;
29
+ if (typeof projectId !== "string" && typeof legacy.projectId === "string") projectId = legacy.projectId;
30
+ } catch {
31
+ break;
32
+ }
33
+ return access === token.access ? token : {
34
+ ...token,
35
+ access,
36
+ projectId
37
+ };
38
+ }
11
39
  function getCredentialResolver(options) {
12
40
  if (options) return new CredentialResolver(options);
13
41
  defaultResolver ??= new CredentialResolver();
@@ -19,16 +47,16 @@ async function resolveApiKey(provider, options) {
19
47
  async function hasCredentials(provider, options) {
20
48
  return getCredentialResolver(options).hasCredentials(provider);
21
49
  }
22
- var log, warnedExpiredOAuthTokens, oauthRefreshes, CredentialResolver, defaultResolver;
50
+ var log, warnedExpiredOAuthTokens, CredentialResolver, defaultResolver;
23
51
  var init_credentials = __esmMin((() => {
24
52
  init_write_file_atomic();
25
53
  init_logger();
26
54
  init_env_keys();
27
55
  init_paths();
28
56
  init_registry();
57
+ init_oauth_provider_lock();
29
58
  log = createLogger("Credentials");
30
59
  warnedExpiredOAuthTokens = /* @__PURE__ */ new Set();
31
- oauthRefreshes = /* @__PURE__ */ new Map();
32
60
  CredentialResolver = class {
33
61
  credentialsDir;
34
62
  agentId;
@@ -45,7 +73,11 @@ var init_credentials = __esmMin((() => {
45
73
  */
46
74
  async resolveApiKey(provider) {
47
75
  const normalizedProvider = provider.toLowerCase();
48
- if (getOAuthProviderDefinition(normalizedProvider)?.oauthOnly) return (await this.loadOAuthToken(normalizedProvider))?.access ?? null;
76
+ const oauthDefinition = getOAuthProviderDefinition(normalizedProvider);
77
+ if (oauthDefinition?.oauthOnly) {
78
+ const token = await this.loadOAuthToken(normalizedProvider);
79
+ return token ? oauthDefinition.provider.getApiKey(toOAuthCredentials(token)) : null;
80
+ }
49
81
  if (this.agentId) {
50
82
  const agentKey = await this.loadFromAgentCredentials(normalizedProvider);
51
83
  if (agentKey) {
@@ -70,7 +102,7 @@ var init_credentials = __esmMin((() => {
70
102
  provider,
71
103
  source: "oauth"
72
104
  }, "Resolved API key from OAuth token");
73
- return oauthToken.access;
105
+ return oauthDefinition ? oauthDefinition.provider.getApiKey(toOAuthCredentials(oauthToken)) : oauthToken.access;
74
106
  }
75
107
  const envKey = getApiKeyFromEnv(normalizedProvider);
76
108
  if (envKey) {
@@ -86,19 +118,19 @@ var init_credentials = __esmMin((() => {
86
118
  * Check if a provider has credentials configured
87
119
  */
88
120
  async hasCredentials(provider) {
89
- return await this.resolveApiKey(provider) !== null;
121
+ return await this.resolveApiKeySource(provider) !== null;
90
122
  }
91
123
  /**
92
124
  * Which step in {@link resolveApiKey} would supply the key (no secret material).
93
125
  */
94
126
  async resolveApiKeySource(provider) {
95
127
  const normalizedProvider = provider.toLowerCase();
96
- if (getOAuthProviderDefinition(normalizedProvider)?.oauthOnly) return await this.loadOAuthToken(normalizedProvider) ? "oauth" : null;
128
+ if (getOAuthProviderDefinition(normalizedProvider)?.oauthOnly) return await this.hasUsableOAuthTokenRecord(normalizedProvider) ? "oauth" : null;
97
129
  if (this.agentId) {
98
130
  if (await this.loadFromAgentCredentials(normalizedProvider)) return "agent";
99
131
  }
100
132
  if (await this.loadFromGlobalCredentials(normalizedProvider)) return "global";
101
- if (await this.loadOAuthToken(normalizedProvider)) return "oauth";
133
+ if (await this.hasUsableOAuthTokenRecord(normalizedProvider)) return "oauth";
102
134
  if (getApiKeyFromEnv(normalizedProvider)) return "env";
103
135
  return null;
104
136
  }
@@ -169,42 +201,42 @@ var init_credentials = __esmMin((() => {
169
201
  * Load OAuth token for a provider.
170
202
  */
171
203
  async loadOAuthToken(provider) {
172
- const token = await this.loadOAuthTokenRecord(provider);
204
+ const normalizedProvider = provider.toLowerCase();
205
+ let token = await this.loadOAuthTokenRecord(normalizedProvider);
173
206
  if (!token) return null;
174
- const expiresAt = token.expiresAt ?? Number.POSITIVE_INFINITY;
207
+ let expiresAt = token.expiresAt ?? Number.POSITIVE_INFINITY;
175
208
  if (expiresAt <= Date.now() + 6e4 && token.refresh) {
176
- const definition = getOAuthProviderDefinition(provider);
177
- if (definition) {
178
- let pending = oauthRefreshes.get(provider);
179
- if (!pending) {
180
- pending = definition.provider.refreshToken({
181
- access: token.access,
182
- refresh: token.refresh,
183
- expires: expiresAt
184
- }).then(async (refreshed) => {
185
- const updated = {
186
- ...token,
187
- access: definition.provider.getApiKey(refreshed),
188
- refresh: refreshed.refresh,
189
- expiresAt: refreshed.expires,
190
- scope: Array.isArray(refreshed.scope) ? refreshed.scope.filter((value) => typeof value === "string") : token.scope,
191
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
192
- };
193
- await this.saveOAuthToken(provider, updated);
194
- return updated;
195
- }).finally(() => oauthRefreshes.delete(provider));
196
- oauthRefreshes.set(provider, pending);
197
- }
198
- try {
199
- return await pending;
200
- } catch (err) {
201
- if (expiresAt > Date.now()) {
202
- log.warn({
203
- err,
204
- provider
205
- }, "OAuth refresh failed; using the current access token");
206
- return token;
207
- }
209
+ const definition = getOAuthProviderDefinition(normalizedProvider);
210
+ if (definition) try {
211
+ token = await withOAuthProviderLock(normalizedProvider, async () => {
212
+ const current = await this.loadOAuthTokenRecord(normalizedProvider);
213
+ if (!current) return null;
214
+ if ((current.expiresAt ?? Number.POSITIVE_INFINITY) > Date.now() + 6e4 || !current.refresh) return current;
215
+ const refreshed = await definition.provider.refreshToken(toOAuthCredentials(current));
216
+ const { expires, ...refreshedFields } = refreshed;
217
+ const updated = {
218
+ ...current,
219
+ ...refreshedFields,
220
+ access: refreshed.access,
221
+ refresh: refreshed.refresh,
222
+ expiresAt: expires,
223
+ scope: Array.isArray(refreshed.scope) ? refreshed.scope.filter((value) => typeof value === "string") : current.scope,
224
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
225
+ };
226
+ await this.saveOAuthToken(normalizedProvider, updated);
227
+ return updated;
228
+ });
229
+ if (!token) return null;
230
+ expiresAt = token.expiresAt ?? Number.POSITIVE_INFINITY;
231
+ } catch (err) {
232
+ token = await this.loadOAuthTokenRecord(normalizedProvider) ?? token;
233
+ expiresAt = token.expiresAt ?? Number.POSITIVE_INFINITY;
234
+ if (expiresAt > Date.now()) {
235
+ log.warn({
236
+ err,
237
+ provider: normalizedProvider
238
+ }, "OAuth refresh failed; using the current access token");
239
+ return token;
208
240
  }
209
241
  }
210
242
  }
@@ -221,6 +253,12 @@ var init_credentials = __esmMin((() => {
221
253
  }
222
254
  return token;
223
255
  }
256
+ async hasUsableOAuthTokenRecord(provider) {
257
+ const token = await this.loadOAuthTokenRecord(provider);
258
+ if (!token?.access?.trim()) return null;
259
+ if (token.expiresAt && token.expiresAt <= Date.now() && !token.refresh?.trim()) return null;
260
+ return token;
261
+ }
224
262
  /**
225
263
  * Load the raw OAuth token record, including expired tokens for status UIs.
226
264
  */
@@ -230,7 +268,7 @@ var init_credentials = __esmMin((() => {
230
268
  try {
231
269
  const content = await readFile(oauthPath, "utf-8");
232
270
  const token = JSON.parse(content);
233
- return token.provider === normalizedProvider ? token : null;
271
+ return token.provider === normalizedProvider ? normalizeLegacyOAuthToken(token) : null;
234
272
  } catch {
235
273
  return null;
236
274
  }
@@ -266,28 +304,46 @@ var init_credentials = __esmMin((() => {
266
304
  return tokens.sort((a, b) => a.provider.localeCompare(b.provider));
267
305
  }
268
306
  /**
307
+ * Save raw provider OAuth credentials without converting them to an API key representation.
308
+ */
309
+ async saveOAuthCredentials(provider, credentials) {
310
+ const { access, refresh, expires, scope, ...providerFields } = credentials;
311
+ await this.saveOAuthToken(provider, {
312
+ ...providerFields,
313
+ access,
314
+ refresh,
315
+ expiresAt: expires,
316
+ scope: Array.isArray(scope) ? scope.filter((value) => typeof value === "string") : void 0,
317
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
318
+ });
319
+ }
320
+ /**
269
321
  * Save OAuth token for a provider.
270
322
  */
271
323
  async saveOAuthToken(provider, token) {
272
324
  const normalizedProvider = provider.toLowerCase();
273
- const oauthPath = resolveOAuthPath(normalizedProvider);
274
- await mkdir(dirname(oauthPath), { recursive: true });
275
- const fullToken = {
276
- ...token,
277
- type: "oauth",
278
- provider: normalizedProvider,
279
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
280
- };
281
- await writeTextAtomic(oauthPath, JSON.stringify(fullToken, null, 2));
282
- log.info({ provider: normalizedProvider }, "Saved OAuth token");
325
+ await withOAuthProviderLock(normalizedProvider, async () => {
326
+ const oauthPath = resolveOAuthPath(normalizedProvider);
327
+ await mkdir(dirname(oauthPath), { recursive: true });
328
+ const fullToken = {
329
+ ...token,
330
+ type: "oauth",
331
+ provider: normalizedProvider,
332
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
333
+ };
334
+ await writeTextAtomic(oauthPath, JSON.stringify(fullToken, null, 2));
335
+ log.info({ provider: normalizedProvider }, "Saved OAuth token");
336
+ });
283
337
  }
284
338
  /**
285
339
  * Delete the OAuth token persisted for a provider.
286
340
  */
287
341
  async deleteOAuthToken(provider) {
288
342
  const normalizedProvider = provider.toLowerCase();
289
- await rm(resolveOAuthPath(normalizedProvider), { force: true });
290
- log.info({ provider: normalizedProvider }, "Deleted OAuth token");
343
+ await withOAuthProviderLock(normalizedProvider, async () => {
344
+ await rm(resolveOAuthPath(normalizedProvider), { force: true });
345
+ log.info({ provider: normalizedProvider }, "Deleted OAuth token");
346
+ });
291
347
  }
292
348
  /**
293
349
  * Disconnect the default credential for a provider from local storage.