@xopcai/xopc 0.0.196 → 0.0.199

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 (258) 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-BwmdJ5pv.js → activity-store-DYVN1hRp.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B1oxPli_.js → agent-avatar-dicebear-Bt70bZjv.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-D19uNmJf.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-BM1hNzjw.js → api-B8mzbAle.js} +1 -1
  7. package/dist/gateway/static/root/assets/app-management-settings-panel-B4x7JfL8.js +1 -0
  8. package/dist/gateway/static/root/assets/appearance-settings-Dwdagf-Q.js +1 -0
  9. package/dist/gateway/static/root/assets/apps-page-DkTiesxe.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-BdE4Mati.js → archive-plugin-Cv0VXKLm.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-CTzaQcLV.js → attachment-load-CgidKrXn.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-BR6qMOVr.js +6 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-B25zTNxl.js → binary-plugins-DN3CQgIq.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-Cdrf2awF.js → block-editor-BwkSl1F_.js} +46 -46
  15. package/dist/gateway/static/root/assets/browser-settings-page-CDFQWAxI.js +8 -0
  16. package/dist/gateway/static/root/assets/browser-workflow-inputs-_ndaecsf.js +1 -0
  17. package/dist/gateway/static/root/assets/{browser-workflows-page-Wx9FrbK-.js → browser-workflows-page-C_I31wLm.js} +2 -2
  18. package/dist/gateway/static/root/assets/button-CSEbl4zT.js +1 -0
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-D41mssOq.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-BoOzFotX.js → capability-presets-api-Dy1jZJKs.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BXgCyuu2.js +3 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-_8IiTxRB.js → channel-recipient-api-D-9qiuio.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-DV5BhAeu.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-B4Rbh3bM.js +1 -0
  25. package/dist/gateway/static/root/assets/connectors-api-5FEBYguL.js +1 -0
  26. package/dist/gateway/static/root/assets/connectors-page-C_qkEN0T.js +2 -0
  27. package/dist/gateway/static/root/assets/copy-Dv6d4Dvw.js +1 -0
  28. package/dist/gateway/static/root/assets/cron-expression-SEFx5rnr.js +2 -0
  29. package/dist/gateway/static/root/assets/date-picker-D4zCUQJL.js +1 -0
  30. package/dist/gateway/static/root/assets/dependency-picker-DpQAxS2k.js +1 -0
  31. package/dist/gateway/static/root/assets/{desktop-pet-BOb8sEhN.js → desktop-pet-B_5G3lQl.js} +1 -1
  32. package/dist/gateway/static/root/assets/desktop-pet-settings-ClEyoUJe.js +1 -0
  33. package/dist/gateway/static/root/assets/directory-picker-path-field-AsFWmOjG.js +1 -0
  34. package/dist/gateway/static/root/assets/dist-BPoKqzeH.js +1 -0
  35. package/dist/gateway/static/root/assets/dist-DY4Af0fY.js +1 -0
  36. package/dist/gateway/static/root/assets/{extension-debug-page-p83TmZFd.js → extension-debug-page-C22Y2o5l.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-page-DMQ3ovxA.js → extension-page-C61Ikawk.js} +1 -1
  38. package/dist/gateway/static/root/assets/extension-settings-page-WlWWcDFr.js +1 -0
  39. package/dist/gateway/static/root/assets/external-link-DjqjBmc3.js +1 -0
  40. package/dist/gateway/static/root/assets/form-field-width-DJw_jULe.js +1 -0
  41. package/dist/gateway/static/root/assets/gateway-config-api-ByIOMQdc.js +1 -0
  42. package/dist/gateway/static/root/assets/gateway-config-swr-jB0hAhWO.js +1 -0
  43. package/dist/gateway/static/root/assets/gateway-settings-CzzS9A17.js +1 -0
  44. package/dist/gateway/static/root/assets/{gateway-startup-retry--2njcDpC.js → gateway-startup-retry-C-fRlHCL.js} +1 -1
  45. package/dist/gateway/static/root/assets/globe-DSSGFWFn.js +1 -0
  46. package/dist/gateway/static/root/assets/heartbeat-settings-B4A_CXUL.js +1 -0
  47. package/dist/gateway/static/root/assets/home-page-FVGYYPWo.js +3 -0
  48. package/dist/gateway/static/root/assets/index-CGbKTCST.js +152 -0
  49. package/dist/gateway/static/root/assets/index-CR233S0Q.css +1 -0
  50. package/dist/gateway/static/root/assets/interaction-BmQogeqz.js +1 -0
  51. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BQb06_jl.js → keyboard-shortcuts-settings-BD_TFz0_.js} +1 -1
  52. package/dist/gateway/static/root/assets/loader-circle-CifKLtgG.js +1 -0
  53. package/dist/gateway/static/root/assets/local-app-workbench-page-BNpkigNb.js +2 -0
  54. package/dist/gateway/static/root/assets/local-apps-page-BwbUeLfm.js +1 -0
  55. package/dist/gateway/static/root/assets/{locale-store-Bjvw7jtg.js → locale-store-xULEcFVs.js} +1 -1
  56. package/dist/gateway/static/root/assets/logs-page-DXP9OQQt.js +2 -0
  57. package/dist/gateway/static/root/assets/management-settings-CW2VpqtT.js +1 -0
  58. package/dist/gateway/static/root/assets/{markdown-split-Db-KrpOQ.js → markdown-split-B1M9KO16.js} +1 -1
  59. package/dist/gateway/static/root/assets/{media-plugins-CHN66qs0.js → media-plugins-B_QlNdqZ.js} +1 -1
  60. package/dist/gateway/static/root/assets/messages-3qRsLZuX.js +3 -0
  61. package/dist/gateway/static/root/assets/{notes-page-CJtKZM0P.js → notes-page-BTbD4GmH.js} +1 -1
  62. package/dist/gateway/static/root/assets/notes-workbench-JRiq7QDW.js +4 -0
  63. package/dist/gateway/static/root/assets/page-tabs-BaEQMYm_.js +1 -0
  64. package/dist/gateway/static/root/assets/popover-select-BzdnTy3h.js +1 -0
  65. package/dist/gateway/static/root/assets/preview-open-alternatives-CeqtArlZ.js +1 -0
  66. package/dist/gateway/static/root/assets/{product-open-page--RnCc9bb.js → product-open-page-DnalBZZs.js} +1 -1
  67. package/dist/gateway/static/root/assets/project-detail-page-CjWA13aE.js +1 -0
  68. package/dist/gateway/static/root/assets/projects-page-jsCkScbG.js +1 -0
  69. package/dist/gateway/static/root/assets/remote-access-hub-CGPJTEkM.js +1 -0
  70. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Bg1W2__k.js → runtime-tools-settings-panel-cGkBEfg4.js} +4 -4
  71. package/dist/gateway/static/root/assets/schema-form-CmsrLlxu.js +1 -0
  72. package/dist/gateway/static/root/assets/sessions-page-BBHzziMd.js +1 -0
  73. package/dist/gateway/static/root/assets/settings-advanced-gate-2cGg8-9h.js +1 -0
  74. package/dist/gateway/static/root/assets/settings-form-draft-Dy10ldo8.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-form-section-DUWCbaMJ.js +1 -0
  76. package/dist/gateway/static/root/assets/{settings-loading-skeleton-BS36Mjzz.js → settings-loading-skeleton-Bvy5rdMY.js} +1 -1
  77. package/dist/gateway/static/root/assets/{settings-page-BDSd7F9Y.js → settings-page-cZSAwsRR.js} +1 -1
  78. package/dist/gateway/static/root/assets/settings-page-layout-BRQNel6r.js +1 -0
  79. package/dist/gateway/static/root/assets/settings-shell-dialog-layer-BU3UuiJr.js +1 -0
  80. package/dist/gateway/static/root/assets/setup-status-panel-Cf06b66-.js +1 -0
  81. package/dist/gateway/static/root/assets/share-preview-page-BzA2NCAH.js +2 -0
  82. package/dist/gateway/static/root/assets/shares-settings-xlNKydYY.js +1 -0
  83. package/dist/gateway/static/root/assets/skill-reload-api-C5Xu93c_.js +1 -0
  84. package/dist/gateway/static/root/assets/skills-page-Bvde7_i5.js +2 -0
  85. package/dist/gateway/static/root/assets/{skills-page.utils-CnbJncdL.js → skills-page.utils-vXSqHR7g.js} +1 -1
  86. package/dist/gateway/static/root/assets/system-settings-panel-9cQGOGCK.js +1 -0
  87. package/dist/gateway/static/root/assets/task-detail-page-Bkno4tTe.js +1 -0
  88. package/dist/gateway/static/root/assets/{theme-store-DtxpMC5S.js → theme-store-CHQRiuCF.js} +1 -1
  89. package/dist/gateway/static/root/assets/tool-activity-R8V9l6nk.js +1 -0
  90. package/dist/gateway/static/root/assets/typed-models-lib-q5-Vfqd8.js +1 -0
  91. package/dist/gateway/static/root/assets/use-autosave-7XfKULPI.js +1 -0
  92. package/dist/gateway/static/root/assets/user-context-page-CZ9m9aC_.js +1 -0
  93. package/dist/gateway/static/root/assets/voice-api-key-field-DXr21v-3.js +1 -0
  94. package/dist/gateway/static/root/assets/work-discovery-overlay-CeG7g_DZ.js +1 -0
  95. package/dist/gateway/static/root/assets/work-discovery-page-CQWZD03N.js +1 -0
  96. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BEmugHfL.js → workflow-run-setup-panel-DSQQZP9T.js} +2 -2
  97. package/dist/gateway/static/root/assets/workflows-page-Cs-MXFJ1.js +5 -0
  98. package/dist/gateway/static/root/assets/working-directory-picker-modal-D-IgcHPp.js +1 -0
  99. package/dist/gateway/static/root/index.html +23 -8
  100. package/dist/package.js +1 -1
  101. package/dist/packages/gateway-contract/src/tasks.js +54 -2
  102. package/dist/src/agent/agent-manager.d.ts +1 -0
  103. package/dist/src/agent/agent-manager.js +1 -0
  104. package/dist/src/agent/embedded/execution-context.d.ts +2 -0
  105. package/dist/src/agent/embedded/execution-context.js +11 -0
  106. package/dist/src/agent/embedded/index.d.ts +3 -1
  107. package/dist/src/agent/embedded/index.js +5 -3
  108. package/dist/src/agent/embedded/run-turn.js +15 -9
  109. package/dist/src/agent/embedded/session-runner.d.ts +6 -11
  110. package/dist/src/agent/embedded/session-runner.js +25 -36
  111. package/dist/src/agent/embedded/transcript-runtime.d.ts +35 -0
  112. package/dist/src/agent/embedded/transcript-runtime.js +66 -0
  113. package/dist/src/agent/embedded/types.d.ts +3 -1
  114. package/dist/src/agent/service.d.ts +15 -0
  115. package/dist/src/agent/service.js +31 -0
  116. package/dist/src/agent/service.types.d.ts +1 -0
  117. package/dist/src/agent/tools/factory.d.ts +2 -0
  118. package/dist/src/agent/tools/factory.js +2 -1
  119. package/dist/src/agent/tools/xopc-use-tool.d.ts +1 -0
  120. package/dist/src/agent/tools/xopc-use-tool.js +56 -6
  121. package/dist/src/automations/domain/validation.d.ts +40 -0
  122. package/dist/src/automations/draft/automation-draft-validator.d.ts +4 -1
  123. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  124. package/dist/src/config/agent-profile.js +1 -1
  125. package/dist/src/config/rules.js +2 -2
  126. package/dist/src/gateway/agents-admin.js +1 -1
  127. package/dist/src/gateway/hono/app.d.ts +2 -0
  128. package/dist/src/gateway/hono/app.js +10 -3
  129. package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
  130. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +8 -1
  131. package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -1
  132. package/dist/src/gateway/hono/routes/config.js +9 -0
  133. package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
  134. package/dist/src/gateway/hono/routes/home.d.ts +1 -1
  135. package/dist/src/gateway/hono/routes/home.js +2 -2
  136. package/dist/src/gateway/hono/routes/index.js +2 -0
  137. package/dist/src/gateway/hono/routes/projects.js +67 -1
  138. package/dist/src/gateway/hono/routes/side-chats.d.ts +3 -0
  139. package/dist/src/gateway/hono/routes/side-chats.js +173 -0
  140. package/dist/src/gateway/hono/routes/tasks.js +112 -19
  141. package/dist/src/gateway/host.d.ts +9 -1
  142. package/dist/src/gateway/host.js +22 -5
  143. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  144. package/dist/src/gateway/rate-limit/buckets.js +12 -0
  145. package/dist/src/gateway/runtime-config.js +6 -5
  146. package/dist/src/gateway/security/audit.js +0 -7
  147. package/dist/src/gateway/server.js +4 -1
  148. package/dist/src/gateway/service/agent-runner.d.ts +4 -0
  149. package/dist/src/gateway/service/agent-runner.js +15 -1
  150. package/dist/src/gateway/service/run-gateway-agent.js +1 -1
  151. package/dist/src/gateway/service.d.ts +5 -0
  152. package/dist/src/gateway/service.js +38 -8
  153. package/dist/src/gateway/side-chat/context-snapshot.d.ts +11 -0
  154. package/dist/src/gateway/side-chat/context-snapshot.js +108 -0
  155. package/dist/src/gateway/side-chat/index.d.ts +5 -0
  156. package/dist/src/gateway/side-chat/index.js +4 -0
  157. package/dist/src/gateway/side-chat/manager.d.ts +45 -0
  158. package/dist/src/gateway/side-chat/manager.js +198 -0
  159. package/dist/src/gateway/side-chat/run-service.d.ts +22 -0
  160. package/dist/src/gateway/side-chat/run-service.js +110 -0
  161. package/dist/src/gateway/side-chat/types.d.ts +61 -0
  162. package/dist/src/gateway/side-chat/types.js +1 -0
  163. package/dist/src/proactive/actions/service.d.ts +2 -0
  164. package/dist/src/proactive/actions/service.js +80 -0
  165. package/dist/src/proactive/execution/insight.js +20 -0
  166. package/dist/src/proactive/execution/repository.js +8 -2
  167. package/dist/src/proactive/execution/types.d.ts +14 -0
  168. package/dist/src/proactive/inbox/repository.js +59 -9
  169. package/dist/src/proactive/inbox/service.d.ts +2 -2
  170. package/dist/src/proactive/inbox/service.js +7 -2
  171. package/dist/src/proactive/inbox/types.d.ts +14 -0
  172. package/dist/src/proactive/inbox/worker.js +2 -0
  173. package/dist/src/proactive/scenarios/prompt-composer.js +2 -2
  174. package/dist/src/routing/session-key-utils.d.ts +0 -1
  175. package/dist/src/routing/session-key-utils.js +1 -6
  176. package/dist/src/routing/session-key.js +2 -2
  177. package/dist/src/storage/sqlite/migrations/118_task_board_rank.sql +6 -0
  178. package/dist/src/storage/sqlite/migrations/119_proactive_disposition.sql +13 -0
  179. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  180. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  181. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  182. package/dist/src/storage/sqlite/schema.js +1 -1
  183. package/dist/src/tasks/home-query-service.d.ts +29 -0
  184. package/dist/src/tasks/home-query-service.js +291 -7
  185. package/dist/src/tasks/index.d.ts +1 -0
  186. package/dist/src/tasks/index.js +5 -4
  187. package/dist/src/tasks/project-monitoring-service.d.ts +9 -0
  188. package/dist/src/tasks/project-monitoring-service.js +41 -3
  189. package/dist/src/tasks/project-operating-view-service.d.ts +2 -2
  190. package/dist/src/tasks/project-operating-view-service.js +47 -21
  191. package/dist/src/tasks/task-application-service.js +99 -6
  192. package/dist/src/tasks/task-change-events.d.ts +13 -0
  193. package/dist/src/tasks/task-change-events.js +29 -0
  194. package/dist/src/tasks/task-read-model-projector.js +2 -1
  195. package/dist/src/tasks/task-repository.d.ts +7 -0
  196. package/dist/src/tasks/task-repository.js +29 -6
  197. package/dist/src/tunnel/enable-lan-pairing.js +15 -26
  198. package/dist/src/tunnel/pair-context.js +1 -1
  199. package/dist/src/tunnel/pair-url.js +1 -1
  200. package/dist/src/tunnel/tunnel-qr.d.ts +0 -7
  201. package/dist/src/tunnel/tunnel-qr.js +2 -19
  202. package/package.json +4 -2
  203. package/dist/gateway/static/root/assets/agents-VoFNMGL3.js +0 -68
  204. package/dist/gateway/static/root/assets/app-management-settings-panel-vmuJ_Z6i.js +0 -1
  205. package/dist/gateway/static/root/assets/appearance-settings-BMlEoe-G.js +0 -1
  206. package/dist/gateway/static/root/assets/apps-page-CsNB6mv_.js +0 -1
  207. package/dist/gateway/static/root/assets/automations-page-CW1YWgiX.js +0 -6
  208. package/dist/gateway/static/root/assets/browser-settings-page-BMTmGMM6.js +0 -8
  209. package/dist/gateway/static/root/assets/browser-workflow-inputs-BsmHy0ks.js +0 -1
  210. package/dist/gateway/static/root/assets/capabilities-settings-panel-C5l85__e.js +0 -7
  211. package/dist/gateway/static/root/assets/capability-presets-settings-panel-9T2KXAs1.js +0 -3
  212. package/dist/gateway/static/root/assets/channels-settings-DquD4BPQ.js +0 -1
  213. package/dist/gateway/static/root/assets/channels-status-swr-DPaJSYX_.js +0 -1
  214. package/dist/gateway/static/root/assets/connectors-api-BC-4ftOM.js +0 -1
  215. package/dist/gateway/static/root/assets/connectors-page-7zUxVHQg.js +0 -2
  216. package/dist/gateway/static/root/assets/cron-expression-BycQlU8Q.js +0 -2
  217. package/dist/gateway/static/root/assets/dependency-picker-BvYqHRz0.js +0 -1
  218. package/dist/gateway/static/root/assets/desktop-pet-settings-DStgPb82.js +0 -1
  219. package/dist/gateway/static/root/assets/directory-picker-path-field-DUUr9sq0.js +0 -1
  220. package/dist/gateway/static/root/assets/extension-settings-page-BcSKEU8s.js +0 -1
  221. package/dist/gateway/static/root/assets/gateway-config-api-C-MmtCc7.js +0 -1
  222. package/dist/gateway/static/root/assets/gateway-settings-CuaRDWbg.js +0 -1
  223. package/dist/gateway/static/root/assets/heartbeat-settings-Dm8TrfGa.js +0 -1
  224. package/dist/gateway/static/root/assets/home-page-BYhDbUvI.js +0 -3
  225. package/dist/gateway/static/root/assets/index-BzPwnXho.js +0 -150
  226. package/dist/gateway/static/root/assets/index-CFFYvilx.css +0 -1
  227. package/dist/gateway/static/root/assets/local-app-workbench-page-CHk4x0kR.js +0 -2
  228. package/dist/gateway/static/root/assets/local-apps-page-DQtsxjGs.js +0 -1
  229. package/dist/gateway/static/root/assets/logs-page-CDqIY72S.js +0 -2
  230. package/dist/gateway/static/root/assets/management-settings-D7itDEHl.js +0 -1
  231. package/dist/gateway/static/root/assets/messages-DQ5X6cXp.js +0 -3
  232. package/dist/gateway/static/root/assets/notes-workbench-epHGeKd5.js +0 -4
  233. package/dist/gateway/static/root/assets/page-tabs-HXweXqYE.js +0 -1
  234. package/dist/gateway/static/root/assets/preview-open-alternatives-Dob6Oe2l.js +0 -1
  235. package/dist/gateway/static/root/assets/project-detail-page-BxOD5-zj.js +0 -1
  236. package/dist/gateway/static/root/assets/projects-page-D-9AhrH5.js +0 -1
  237. package/dist/gateway/static/root/assets/remote-access-hub-CSUNXLKM.js +0 -1
  238. package/dist/gateway/static/root/assets/schema-form-BI4rVt3u.js +0 -1
  239. package/dist/gateway/static/root/assets/sessions-page-BxOUBMca.js +0 -1
  240. package/dist/gateway/static/root/assets/settings-advanced-gate-DAvTIbgw.js +0 -1
  241. package/dist/gateway/static/root/assets/settings-form-section-C7rzhi7x.js +0 -1
  242. package/dist/gateway/static/root/assets/settings-page-layout-CTMmZcwj.js +0 -1
  243. package/dist/gateway/static/root/assets/setup-status-panel-D1v-2Ci-.js +0 -1
  244. package/dist/gateway/static/root/assets/share-preview-page-BeCxg6eb.js +0 -2
  245. package/dist/gateway/static/root/assets/shares-settings-CXL1EldF.js +0 -1
  246. package/dist/gateway/static/root/assets/skill-reload-api-BxwkKgVw.js +0 -1
  247. package/dist/gateway/static/root/assets/skills-page-CyfjEM4D.js +0 -2
  248. package/dist/gateway/static/root/assets/system-settings-panel-CAv0Yk0Y.js +0 -1
  249. package/dist/gateway/static/root/assets/task-detail-page-DGTVJs_N.js +0 -1
  250. package/dist/gateway/static/root/assets/typed-models-lib-DomX3Szl.js +0 -1
  251. package/dist/gateway/static/root/assets/use-autosave-BLc4gfG0.js +0 -1
  252. package/dist/gateway/static/root/assets/user-context-page-C2kQENTK.js +0 -1
  253. package/dist/gateway/static/root/assets/voice-api-key-field-BijmpPjb.js +0 -1
  254. package/dist/gateway/static/root/assets/work-discovery-overlay-D7w2JFFq.js +0 -1
  255. package/dist/gateway/static/root/assets/work-discovery-page-XtoPgPUS.js +0 -1
  256. package/dist/gateway/static/root/assets/workflows-page-D_K2xOWq.js +0 -5
  257. package/dist/src/gateway/ensure-network-cors.d.ts +0 -3
  258. package/dist/src/gateway/ensure-network-cors.js +0 -23
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
19
19
  export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
20
20
 
21
21
  /** Latest schema version this release supports (increment when adding migrations). */
22
- export const XOPC_DB_SCHEMA_VERSION = 117;
22
+ export const XOPC_DB_SCHEMA_VERSION = 119;
23
23
 
24
24
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
25
25
 
@@ -32,7 +32,7 @@ function ensureXopcDatabaseSchema(db, options = {}) {
32
32
  currentVersion = 11;
33
33
  }
34
34
  applyPendingMigrations(db, {
35
- targetVersion: 117,
35
+ targetVersion: 119,
36
36
  databasePath: options.databasePath
37
37
  });
38
38
  }
@@ -6,12 +6,25 @@ import type { NotesService } from '../notes/service.js';
6
6
  import type { ProactiveInboxService } from '../proactive/inbox/service.js';
7
7
  import type { ProjectService } from '../projects/project-service.js';
8
8
  import type { SessionIndex } from '../session/manager.js';
9
+ import type { WorkflowRunSummary } from '../workflows/domain/index.js';
9
10
  import type { WorkflowRunService } from '../workflows/service/workflow-run-service.js';
10
11
  import { type TaskReadModel } from './task-read-model-projector.js';
11
12
  type HomeDecision = HomeResponse['decisions'][number];
12
13
  type HomeAttention = HomeResponse['attention'][number];
13
14
  type HomeBriefingWin = HomeResponse['briefing']['wins'][number];
14
15
  type HomeAutomation = HomeResponse['upcomingAutomations'][number];
16
+ type HomeFocusItem = HomeResponse['focusItems'][number];
17
+ type HomeWorkflowRun = {
18
+ id: string;
19
+ definitionId: string;
20
+ title: string;
21
+ status: WorkflowRunSummary['status'];
22
+ sessionKey?: string;
23
+ createdAtMs: number;
24
+ startedAtMs?: number;
25
+ completedAtMs?: number;
26
+ metrics: WorkflowRunSummary['metrics'];
27
+ };
15
28
  type HomeAutomationRun = {
16
29
  id: string;
17
30
  automationId: string;
@@ -92,6 +105,11 @@ export declare function buildHomeBriefing(input: {
92
105
  recommendation: string;
93
106
  confidence: number;
94
107
  valueScore?: number;
108
+ disposition?: "show_in_work" | "request_approval" | "auto_execute";
109
+ dispositionReason?: string;
110
+ actionStatus?: "failed" | "completed" | "rejected" | "pending" | "approval_required" | "not_authorized" | "executing";
111
+ proposedActionTitle?: string;
112
+ actionError?: string;
95
113
  decision?: {
96
114
  question: string;
97
115
  options: {
@@ -126,6 +144,17 @@ export declare function buildHomeBriefing(input: {
126
144
  name?: string;
127
145
  };
128
146
  };
147
+ export declare function buildHomeFocusItems(input: {
148
+ locale?: string;
149
+ decisions: HomeDecision[];
150
+ attention: HomeAttention[];
151
+ activeWorkflowRuns: HomeWorkflowRun[];
152
+ runningTasks: HomeResponse['tasks']['running'];
153
+ wins: HomeBriefingWin[];
154
+ nextScheduled?: HomeAutomation;
155
+ inboxCount: number;
156
+ nowMs: number;
157
+ }): HomeFocusItem[];
129
158
  export declare class HomeQueryService {
130
159
  #private;
131
160
  private readonly service;
@@ -114,6 +114,273 @@ function buildHomeBriefing(input) {
114
114
  nextScheduled: input.nextScheduled
115
115
  };
116
116
  }
117
+ function homeActionCopy(locale) {
118
+ return locale?.toLowerCase().startsWith("zh") ?? false ? {
119
+ approve: "允许并继续",
120
+ deny: "拒绝",
121
+ review: "查看并处理",
122
+ retry: "重试",
123
+ acknowledge: "暂时忽略",
124
+ viewProgress: "查看进度",
125
+ viewResult: "查看结果",
126
+ viewSchedule: "查看计划",
127
+ runningTask: "任务正在推进",
128
+ runningWorkflow: "工作流正在推进",
129
+ scheduled: "下一项定时工作",
130
+ organizeInbox: "整理收件箱",
131
+ organizeInboxSummary: "把刚捕获的内容整理成笔记、任务或后续行动。",
132
+ openInbox: "去整理",
133
+ startSomething: "今天想推进什么?",
134
+ startSomethingSummary: "把想要的结果交给我,我会从这里开始。",
135
+ askAi: "交给 Agent"
136
+ } : {
137
+ approve: "Allow and continue",
138
+ deny: "Deny",
139
+ review: "Review",
140
+ retry: "Retry",
141
+ acknowledge: "Dismiss",
142
+ viewProgress: "View progress",
143
+ viewResult: "View result",
144
+ viewSchedule: "View schedule",
145
+ runningTask: "Task in progress",
146
+ runningWorkflow: "Workflow in progress",
147
+ scheduled: "Next scheduled work",
148
+ organizeInbox: "Organize your inbox",
149
+ organizeInboxSummary: "Turn recent captures into notes, tasks, or next actions.",
150
+ openInbox: "Organize",
151
+ startSomething: "What would you like to move forward?",
152
+ startSomethingSummary: "Hand me the outcome you want and I’ll take it from here.",
153
+ askAi: "Ask an agent"
154
+ };
155
+ }
156
+ function buildHomeFocusItems(input) {
157
+ const copy = homeActionCopy(input.locale);
158
+ const decisions = input.decisions.map((decision) => {
159
+ const openAction = decision.kind === "agent_judgment" && decision.judgment ? {
160
+ type: "open",
161
+ label: copy.review,
162
+ target: "inbox_judgment",
163
+ targetId: decision.judgment.inboxItemId
164
+ } : decision.kind === "task" ? {
165
+ type: "open",
166
+ label: copy.review,
167
+ target: "task",
168
+ targetId: decision.id.replace(/^task:/, "")
169
+ } : {
170
+ type: "open",
171
+ label: copy.review,
172
+ target: "work"
173
+ };
174
+ const connectorActions = decision.response?.kind === "connector_approval" ? {
175
+ primaryAction: {
176
+ type: "connector_decision",
177
+ label: copy.approve,
178
+ approvalId: decision.response.approvalId,
179
+ decision: "approve"
180
+ },
181
+ secondaryActions: [{
182
+ type: "connector_decision",
183
+ label: copy.deny,
184
+ approvalId: decision.response.approvalId,
185
+ decision: "deny"
186
+ }]
187
+ } : {
188
+ primaryAction: openAction,
189
+ secondaryActions: []
190
+ };
191
+ return {
192
+ id: decision.id,
193
+ kind: "decision",
194
+ priority: decision.urgency === "now" ? 100 : 90,
195
+ title: decision.title,
196
+ summary: decision.detail || copy.review,
197
+ statusLabel: copy.review,
198
+ updatedAt: decision.updatedAt,
199
+ pinnable: false,
200
+ openAction,
201
+ ...connectorActions
202
+ };
203
+ });
204
+ const failures = input.attention.map((item) => ({
205
+ id: item.id,
206
+ kind: "failure",
207
+ priority: 80,
208
+ title: item.title,
209
+ summary: item.detail,
210
+ updatedAt: item.updatedAt,
211
+ pinnable: false,
212
+ openAction: item.kind === "workflow_run" ? item.sessionKey ? {
213
+ type: "open",
214
+ label: copy.review,
215
+ target: "session",
216
+ sessionKey: item.sessionKey
217
+ } : {
218
+ type: "open",
219
+ label: copy.review,
220
+ target: "workflow_run",
221
+ targetId: item.runId
222
+ } : {
223
+ type: "open",
224
+ label: copy.review,
225
+ target: "automation",
226
+ targetId: item.runId
227
+ },
228
+ primaryAction: {
229
+ type: "retry_run",
230
+ label: copy.retry,
231
+ subjectKind: item.kind,
232
+ runId: item.runId
233
+ },
234
+ secondaryActions: [{
235
+ type: "acknowledge_run",
236
+ label: copy.acknowledge,
237
+ subjectKind: item.kind,
238
+ runId: item.runId
239
+ }]
240
+ }));
241
+ const workflows = input.activeWorkflowRuns.map((run) => {
242
+ const openAction = run.sessionKey ? {
243
+ type: "open",
244
+ label: copy.viewProgress,
245
+ target: "session",
246
+ sessionKey: run.sessionKey
247
+ } : {
248
+ type: "open",
249
+ label: copy.viewProgress,
250
+ target: "workflow_run",
251
+ targetId: run.id
252
+ };
253
+ return {
254
+ id: `workflow:${run.id}`,
255
+ kind: "running",
256
+ priority: 60,
257
+ title: run.title,
258
+ summary: copy.runningWorkflow,
259
+ statusLabel: run.metrics.agentCount > 0 ? `${run.metrics.doneAgentCount}/${run.metrics.agentCount}` : void 0,
260
+ updatedAt: run.startedAtMs ?? run.createdAtMs,
261
+ pinnable: true,
262
+ openAction,
263
+ primaryAction: openAction,
264
+ secondaryActions: []
265
+ };
266
+ });
267
+ const tasks = input.runningTasks.map((task) => {
268
+ const openAction = {
269
+ type: "open",
270
+ label: copy.viewProgress,
271
+ target: "task",
272
+ targetId: task.id
273
+ };
274
+ return {
275
+ id: `task:${task.id}`,
276
+ kind: "running",
277
+ priority: 55,
278
+ title: task.title,
279
+ summary: copy.runningTask,
280
+ updatedAt: task.updatedAt,
281
+ pinnable: true,
282
+ openAction,
283
+ primaryAction: openAction,
284
+ secondaryActions: []
285
+ };
286
+ });
287
+ const results = input.wins.map((win) => {
288
+ const openAction = win.kind === "workflow_run" ? {
289
+ type: "open",
290
+ label: copy.viewResult,
291
+ target: "workflow_run",
292
+ targetId: win.id.replace(/^workflow:/, "")
293
+ } : win.kind === "automation_run" ? {
294
+ type: "open",
295
+ label: copy.viewResult,
296
+ target: "automation",
297
+ targetId: win.id.replace(/^automation:/, "")
298
+ } : {
299
+ type: "open",
300
+ label: copy.viewResult,
301
+ target: "task",
302
+ targetId: win.id.replace(/^task:/, "")
303
+ };
304
+ return {
305
+ id: win.id,
306
+ kind: "result",
307
+ priority: 40,
308
+ title: win.title,
309
+ summary: copy.viewResult,
310
+ updatedAt: win.completedAt,
311
+ pinnable: true,
312
+ openAction,
313
+ primaryAction: openAction,
314
+ secondaryActions: []
315
+ };
316
+ });
317
+ const scheduled = input.nextScheduled ? [{
318
+ id: `automation:${input.nextScheduled.id}:scheduled`,
319
+ kind: "scheduled",
320
+ priority: 30,
321
+ title: input.nextScheduled.name || input.nextScheduled.id,
322
+ summary: copy.scheduled,
323
+ statusLabel: new Date(input.nextScheduled.nextRunAt).toLocaleString(input.locale),
324
+ updatedAt: Date.parse(input.nextScheduled.nextRunAt),
325
+ pinnable: true,
326
+ openAction: {
327
+ type: "open",
328
+ label: copy.viewSchedule,
329
+ target: "automation",
330
+ targetId: input.nextScheduled.id
331
+ },
332
+ primaryAction: {
333
+ type: "open",
334
+ label: copy.viewSchedule,
335
+ target: "automation",
336
+ targetId: input.nextScheduled.id
337
+ },
338
+ secondaryActions: []
339
+ }] : [];
340
+ const items = [
341
+ ...decisions,
342
+ ...failures,
343
+ ...workflows,
344
+ ...tasks,
345
+ ...results,
346
+ ...scheduled
347
+ ].sort((left, right) => right.priority - left.priority || right.updatedAt - left.updatedAt);
348
+ if (items.length > 0) return items;
349
+ if (input.inboxCount > 0) return [{
350
+ id: "suggestion:organize-inbox",
351
+ kind: "suggestion",
352
+ priority: 10,
353
+ title: `${copy.organizeInbox} · ${input.inboxCount}`,
354
+ summary: copy.organizeInboxSummary,
355
+ updatedAt: input.nowMs,
356
+ pinnable: false,
357
+ openAction: {
358
+ type: "open",
359
+ label: copy.openInbox,
360
+ target: "inbox"
361
+ },
362
+ primaryAction: {
363
+ type: "open",
364
+ label: copy.openInbox,
365
+ target: "inbox"
366
+ },
367
+ secondaryActions: []
368
+ }];
369
+ return [{
370
+ id: "suggestion:ask-agent",
371
+ kind: "suggestion",
372
+ priority: 10,
373
+ title: copy.startSomething,
374
+ summary: copy.startSomethingSummary,
375
+ updatedAt: input.nowMs,
376
+ pinnable: false,
377
+ primaryAction: {
378
+ type: "ask_ai",
379
+ label: copy.askAi
380
+ },
381
+ secondaryActions: []
382
+ }];
383
+ }
117
384
  var HomeQueryService = class {
118
385
  #runs = new TaskRunRepository();
119
386
  #tasks = new TaskRepository();
@@ -184,7 +451,7 @@ var HomeQueryService = class {
184
451
  kind: "agent_judgment",
185
452
  title: item.insight.title,
186
453
  detail: item.insight.summary,
187
- reason: "decision_needed",
454
+ reason: item.insight.disposition === "request_approval" ? "approval_required" : "decision_needed",
188
455
  urgency: item.insight.urgency === "critical" || item.insight.urgency === "high" ? "now" : "soon",
189
456
  href: `/?judgment=${encodeURIComponent(item.id)}`,
190
457
  updatedAt: Date.parse(item.updatedAt),
@@ -196,7 +463,12 @@ var HomeQueryService = class {
196
463
  recommendation: item.insight.recommendation,
197
464
  confidence: item.insight.confidence,
198
465
  valueScore: item.insight.valueScore,
199
- ...item.insight.decision ? { decision: item.insight.decision } : {}
466
+ disposition: item.insight.disposition,
467
+ dispositionReason: item.insight.dispositionReason,
468
+ ...item.insight.actionStatus ? { actionStatus: item.insight.actionStatus } : {},
469
+ ...item.insight.proposedAction ? { proposedActionTitle: item.insight.proposedAction.input.title } : {},
470
+ ...item.insight.actionError ? { actionError: item.insight.actionError } : {},
471
+ ...item.insight.decision && (!item.insight.proposedAction || item.insight.actionStatus === "approval_required") ? { decision: item.insight.decision } : {}
200
472
  }
201
473
  })),
202
474
  ...activeTasks.map((task) => decisionFromTask(this.#projector.project(task), task.projectId ? projectsById.get(task.projectId)?.name : void 0)).filter((item) => Boolean(item)),
@@ -256,6 +528,10 @@ var HomeQueryService = class {
256
528
  href: "/automations",
257
529
  completedAt: run.endedAtMs ?? run.createdAtMs
258
530
  }))].sort((left, right) => right.completedAt - left.completedAt);
531
+ const runningTasks = tasks.filter((task) => {
532
+ const state = this.#projector.project(task).operationalState;
533
+ return state === "queued" || state === "running" || state === "verifying";
534
+ }).slice(0, 20);
259
535
  const briefing = buildHomeBriefing({
260
536
  locale,
261
537
  decisions,
@@ -267,6 +543,17 @@ var HomeQueryService = class {
267
543
  nowMs
268
544
  });
269
545
  return {
546
+ focusItems: buildHomeFocusItems({
547
+ locale,
548
+ decisions,
549
+ attention,
550
+ activeWorkflowRuns,
551
+ runningTasks,
552
+ wins,
553
+ nextScheduled: upcomingAutomations[0],
554
+ inboxCount: inbox.total,
555
+ nowMs
556
+ }),
270
557
  recentlyOpened: recentlyOpened.items.filter((note) => note.lastOpenedAt),
271
558
  inboxCount: inbox.total,
272
559
  pendingTasks: pendingTasks.items,
@@ -302,14 +589,11 @@ var HomeQueryService = class {
302
589
  recent: workChats.filter((chat) => !chat.active).slice(0, 8)
303
590
  },
304
591
  upcomingAutomations,
305
- tasks: { running: tasks.filter((task) => {
306
- const state = this.#projector.project(task).operationalState;
307
- return state === "queued" || state === "running" || state === "verifying";
308
- }).slice(0, 20) },
592
+ tasks: { running: runningTasks },
309
593
  recentTasks: tasks.flatMap((task) => this.#runs.listReceipts(task.id, 3)).sort((a, b) => b.finalizedAt - a.finalizedAt).slice(0, 8),
310
594
  recentAutomationRuns: automationRuns.slice(0, 5).map(toHomeAutomationRun)
311
595
  };
312
596
  }
313
597
  };
314
598
  //#endregion
315
- export { HomeQueryService, buildHomeBriefing, decisionFromTask };
599
+ export { HomeQueryService, buildHomeBriefing, buildHomeFocusItems, decisionFromTask };
@@ -11,6 +11,7 @@ export * from './project-operating-view-service.js';
11
11
  export * from './project-monitoring-service.js';
12
12
  export * from './task-value-metrics-service.js';
13
13
  export * from './task-application-service.js';
14
+ export * from './task-change-events.js';
14
15
  export * from './task-context-repository.js';
15
16
  export * from './task-dependency-service.js';
16
17
  export * from './task-read-model-projector.js';
@@ -3,8 +3,9 @@ import { TaskRunRepository } from "./task-run-repository.js";
3
3
  import { TaskReadModelProjector } from "./task-read-model-projector.js";
4
4
  import { resolveExecutionContext } from "./execution-context.js";
5
5
  import { AttentionGovernor } from "./attention-governor.js";
6
- import { HomeQueryService, buildHomeBriefing, decisionFromTask } from "./home-query-service.js";
6
+ import { HomeQueryService, buildHomeBriefing, buildHomeFocusItems, decisionFromTask } from "./home-query-service.js";
7
7
  import { TaskContextRepository } from "./task-context-repository.js";
8
+ import { enqueueTaskChanged, enqueueTaskChangedEvent } from "./task-change-events.js";
8
9
  import { TaskDependencyError, TaskDependencyService } from "./task-dependency-service.js";
9
10
  import { TaskApplicationService } from "./task-application-service.js";
10
11
  import { TaskWorkflowCoordinator } from "./task-workflow-coordinator.js";
@@ -12,10 +13,10 @@ import { defineTaskContract } from "./task-contract-definition.js";
12
13
  import { ModelTaskContractPlanner, parseTaskContractResponse } from "./task-contract-planner.js";
13
14
  import { assembleTaskContext, buildTaskExecutionDirective, getTaskContextManifest, getTaskExecutionBrief } from "./task-context-assembler.js";
14
15
  import { TaskRunCoordinator } from "./task-run-coordinator.js";
15
- import { ProjectMonitoringService, decideProactiveDisposition } from "./project-monitoring-service.js";
16
- import { ProjectOperatingViewService, projectTaskLane } from "./project-operating-view-service.js";
16
+ import { ProjectMonitoringService, decideProactiveDisposition, isInQuietHours, nextQuietHoursEnd, proactiveDispositionReason } from "./project-monitoring-service.js";
17
+ import { ProjectOperatingViewService, summarizeProjectOperatingView } from "./project-operating-view-service.js";
17
18
  import { TaskValueMetricsService } from "./task-value-metrics-service.js";
18
19
  import { TaskOutboxDispatcher } from "./task-outbox-dispatcher.js";
19
20
  import { TaskRunDispatcher } from "./task-run-dispatcher.js";
20
21
  import { TaskSignalService } from "./task-signal-service.js";
21
- export { AttentionGovernor, HomeQueryService, ModelTaskContractPlanner, ProjectMonitoringService, ProjectOperatingViewService, TaskApplicationService, TaskContextRepository, TaskDependencyError, TaskDependencyService, TaskOutboxDispatcher, TaskReadModelProjector, TaskRepository, TaskRunCoordinator, TaskRunDispatcher, TaskRunRepository, TaskSignalService, TaskValueMetricsService, TaskWorkflowCoordinator, assembleTaskContext, buildHomeBriefing, buildTaskExecutionDirective, decideProactiveDisposition, decisionFromTask, defineTaskContract, getTaskContextManifest, getTaskExecutionBrief, parseTaskContractResponse, projectTaskLane, resolveExecutionContext };
22
+ export { AttentionGovernor, HomeQueryService, ModelTaskContractPlanner, ProjectMonitoringService, ProjectOperatingViewService, TaskApplicationService, TaskContextRepository, TaskDependencyError, TaskDependencyService, TaskOutboxDispatcher, TaskReadModelProjector, TaskRepository, TaskRunCoordinator, TaskRunDispatcher, TaskRunRepository, TaskSignalService, TaskValueMetricsService, TaskWorkflowCoordinator, assembleTaskContext, buildHomeBriefing, buildHomeFocusItems, buildTaskExecutionDirective, decideProactiveDisposition, decisionFromTask, defineTaskContract, enqueueTaskChanged, enqueueTaskChangedEvent, getTaskContextManifest, getTaskExecutionBrief, isInQuietHours, nextQuietHoursEnd, parseTaskContractResponse, proactiveDispositionReason, resolveExecutionContext, summarizeProjectOperatingView };
@@ -7,6 +7,15 @@ export declare function decideProactiveDisposition(policy: ProjectMonitoringPoli
7
7
  actionId?: string;
8
8
  requiresApproval?: boolean;
9
9
  }): ProactiveDisposition;
10
+ export declare function proactiveDispositionReason(policy: ProjectMonitoringPolicy, input: {
11
+ confidence: number;
12
+ valueScore: number;
13
+ risk: 'low' | 'medium' | 'high';
14
+ actionId?: string;
15
+ requiresApproval?: boolean;
16
+ }, disposition: ProactiveDisposition): string;
17
+ export declare function isInQuietHours(quietHours: QuietHours | undefined, now?: Date): boolean;
18
+ export declare function nextQuietHoursEnd(quietHours: QuietHours | undefined, now?: Date): Date | undefined;
10
19
  export declare class ProjectMonitoringService {
11
20
  #private;
12
21
  get(projectId: string): ProjectMonitoringPolicy;
@@ -2,6 +2,7 @@ import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/
2
2
  import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
3
3
  //#region src/tasks/project-monitoring-service.ts
4
4
  const DEFAULT_SCENARIOS = ["project_delivery_risk", "blocked_work"];
5
+ const SUPPORTED_ACTIONS = new Set(["create_project_task"]);
5
6
  function validHour(value) {
6
7
  return Number.isInteger(value) && value >= 0 && value <= 23;
7
8
  }
@@ -19,10 +20,45 @@ function rowToPolicy(row, scenarios) {
19
20
  }
20
21
  function decideProactiveDisposition(policy, input) {
21
22
  if (policy.mode === "observe" || input.confidence < policy.confidenceThreshold || input.valueScore < .5) return "record_silently";
22
- if (input.requiresApproval || input.risk !== "low") return "request_approval";
23
- if (policy.mode === "auto_low_risk" && input.actionId && policy.allowedActions.includes(input.actionId)) return "auto_execute";
23
+ if (input.actionId) {
24
+ if (input.requiresApproval || input.risk !== "low" || policy.mode === "ask_before_action") return "request_approval";
25
+ if (policy.mode === "auto_low_risk" && policy.allowedActions.includes(input.actionId)) return "auto_execute";
26
+ return "show_in_work";
27
+ }
28
+ if (input.requiresApproval) return "request_approval";
24
29
  return "show_in_work";
25
30
  }
31
+ function proactiveDispositionReason(policy, input, disposition) {
32
+ if (policy.mode === "observe") return "Project monitoring is observe-only";
33
+ if (input.confidence < policy.confidenceThreshold) return `Confidence ${input.confidence} is below threshold ${policy.confidenceThreshold}`;
34
+ if (input.valueScore < .5) return `Value score ${input.valueScore} is below 0.5`;
35
+ if (disposition === "request_approval") return input.risk === "low" ? "Project policy requires approval before acting" : `${input.risk} risk requires approval`;
36
+ if (disposition === "auto_execute") return `Low-risk action ${input.actionId} is explicitly allowed`;
37
+ if (input.actionId && !policy.allowedActions.includes(input.actionId)) return `Action ${input.actionId} is not in the project allowlist`;
38
+ return "Insight passed the project confidence and value gates";
39
+ }
40
+ function hourInTimezone(now, timezone) {
41
+ const hour = new Intl.DateTimeFormat("en-US", {
42
+ timeZone: timezone,
43
+ hour: "2-digit",
44
+ hourCycle: "h23"
45
+ }).formatToParts(now).find((part) => part.type === "hour")?.value;
46
+ return Number(hour);
47
+ }
48
+ function isInQuietHours(quietHours, now = /* @__PURE__ */ new Date()) {
49
+ if (!quietHours || quietHours.startHour === quietHours.endHour) return false;
50
+ const hour = hourInTimezone(now, quietHours.timezone);
51
+ return quietHours.startHour < quietHours.endHour ? hour >= quietHours.startHour && hour < quietHours.endHour : hour >= quietHours.startHour || hour < quietHours.endHour;
52
+ }
53
+ function nextQuietHoursEnd(quietHours, now = /* @__PURE__ */ new Date()) {
54
+ if (!isInQuietHours(quietHours, now)) return void 0;
55
+ const minute = new Date(now);
56
+ minute.setUTCSeconds(0, 0);
57
+ for (let offset = 1; offset <= 2880; offset += 1) {
58
+ const candidate = new Date(minute.getTime() + offset * 6e4);
59
+ if (!isInQuietHours(quietHours, candidate)) return candidate;
60
+ }
61
+ }
26
62
  var ProjectMonitoringService = class {
27
63
  #scenarios = new ProactiveScenarioService();
28
64
  get(projectId) {
@@ -40,9 +76,11 @@ var ProjectMonitoringService = class {
40
76
  configure(input) {
41
77
  if (!getSqliteDatabase().prepare("SELECT 1 FROM projects WHERE project_id = ?").get(input.projectId)) throw new Error("Project not found");
42
78
  if (input.quietHours && (!validHour(input.quietHours.startHour) || !validHour(input.quietHours.endHour) || !input.quietHours.timezone.trim())) throw new Error("Quiet hours need a timezone and integer hours from 0 through 23");
79
+ if (input.quietHours) hourInTimezone(/* @__PURE__ */ new Date(), input.quietHours.timezone);
43
80
  const threshold = input.confidenceThreshold ?? .75;
44
81
  if (!Number.isFinite(threshold) || threshold < 0 || threshold > 1) throw new Error("confidenceThreshold must be between 0 and 1");
45
82
  const allowedActions = [...new Set(input.allowedActions ?? [])].map((action) => action.trim()).filter(Boolean);
83
+ if (allowedActions.some((action) => !SUPPORTED_ACTIONS.has(action))) throw new Error("Unknown proactive action");
46
84
  const scenarios = [...new Set(input.scenarios ?? DEFAULT_SCENARIOS)];
47
85
  const availableScenarios = new Set(this.#scenarios.list().map((scenario) => scenario.key));
48
86
  if (scenarios.some((scenario) => !availableScenarios.has(scenario))) throw new Error("Unknown proactive scenario");
@@ -73,4 +111,4 @@ var ProjectMonitoringService = class {
73
111
  }
74
112
  };
75
113
  //#endregion
76
- export { ProjectMonitoringService, decideProactiveDisposition };
114
+ export { ProjectMonitoringService, decideProactiveDisposition, isInQuietHours, nextQuietHoursEnd, proactiveDispositionReason };
@@ -1,6 +1,6 @@
1
- import type { ProjectOperatingView, ProjectTaskCard } from '@xopcai/gateway-contract';
1
+ import type { ProjectOperatingSummary, ProjectOperatingView } from '@xopcai/gateway-contract';
2
2
  import type { ProjectService } from '../projects/index.js';
3
- export declare function projectTaskLane(card: Pick<ProjectTaskCard, 'phase' | 'operationalState' | 'attention'>): ProjectTaskCard['lane'];
3
+ export declare function summarizeProjectOperatingView(view: ProjectOperatingView): ProjectOperatingSummary;
4
4
  export declare class ProjectOperatingViewService {
5
5
  #private;
6
6
  private readonly projects;
@@ -4,16 +4,33 @@ import { TaskReadModelProjector } from "./task-read-model-projector.js";
4
4
  import { TaskDependencyService } from "./task-dependency-service.js";
5
5
  import { ProjectMonitoringService } from "./project-monitoring-service.js";
6
6
  //#region src/tasks/project-operating-view-service.ts
7
- function projectTaskLane(card) {
8
- if (card.phase === "closed") return "done";
9
- if (card.attention.some((item) => item.kind === "input_required" || item.kind === "approval_required")) return "needs_user";
10
- if ([
11
- "queued",
12
- "running",
13
- "verifying"
14
- ].includes(card.operationalState)) return "moving";
15
- if (card.operationalState === "waiting" || card.operationalState === "blocked") return "waiting";
16
- return "ready";
7
+ function summarizeProjectOperatingView(view) {
8
+ const counts = {
9
+ ready: 0,
10
+ moving: 0,
11
+ waiting: 0,
12
+ needsUser: 0,
13
+ done: 0
14
+ };
15
+ for (const task of view.tasks) {
16
+ if (task.attention.some((item) => item.kind === "input_required" || item.kind === "approval_required")) {
17
+ counts.needsUser += 1;
18
+ continue;
19
+ }
20
+ if (task.phase === "closed") counts.done += 1;
21
+ else if ([
22
+ "queued",
23
+ "running",
24
+ "verifying"
25
+ ].includes(task.operationalState)) counts.moving += 1;
26
+ else if (task.operationalState === "waiting" || task.operationalState === "blocked") counts.waiting += 1;
27
+ else counts.ready += 1;
28
+ }
29
+ return {
30
+ ...view.digest,
31
+ counts,
32
+ updatedAt: Math.max(view.project.updatedAt, ...view.tasks.map((task) => task.updatedAt))
33
+ };
17
34
  }
18
35
  var ProjectOperatingViewService = class {
19
36
  #tasks = new TaskRepository();
@@ -32,7 +49,7 @@ var ProjectOperatingViewService = class {
32
49
  const model = this.#projector.project(task);
33
50
  const latest = this.#runs.getLatestRoot(task.id);
34
51
  const receipt = latest ? this.#runs.getReceipt(latest.id) : void 0;
35
- const base = {
52
+ return {
36
53
  id: task.id,
37
54
  title: task.title,
38
55
  phase: task.phase,
@@ -47,33 +64,42 @@ var ProjectOperatingViewService = class {
47
64
  ...receipt ? { latestVerification: receipt.verification.status } : {},
48
65
  updatedAt: task.updatedAt
49
66
  };
50
- return {
51
- ...base,
52
- lane: projectTaskLane(base)
53
- };
54
67
  });
55
- const recentReceipts = projectTasks.flatMap((task) => this.#runs.listReceipts(task.id, 10)).sort((a, b) => b.finalizedAt - a.finalizedAt).slice(0, 10);
56
- const attentionCount = cards.filter((card) => card.lane === "needs_user").length;
68
+ const recentResults = projectTasks.flatMap((task) => this.#runs.listReceipts(task.id, 10).map((receipt) => ({
69
+ taskId: task.id,
70
+ taskTitle: task.title,
71
+ receipt
72
+ }))).sort((a, b) => b.receipt.finalizedAt - a.receipt.finalizedAt).slice(0, 10);
73
+ const needsUser = (card) => card.attention.some((item) => item.kind === "input_required" || item.kind === "approval_required");
74
+ const moving = (card) => [
75
+ "queued",
76
+ "running",
77
+ "verifying"
78
+ ].includes(card.operationalState);
79
+ const attentionCount = cards.filter((card) => card.attention.length > 0).length;
57
80
  return {
58
81
  project,
59
- tasks: cards.sort((a, b) => b.updatedAt - a.updatedAt),
82
+ tasks: cards,
60
83
  dependencyEdges: this.#dependencies.listProjectEdges(project.id),
61
84
  blockers: cards.flatMap((card) => card.attention.map((item) => ({
62
85
  id: item.sourceId ?? `${card.id}:${item.kind}`,
86
+ taskId: card.id,
63
87
  kind: item.kind,
64
88
  title: card.title,
65
89
  detail: item.summary,
90
+ href: `/tasks/${encodeURIComponent(card.id)}`,
66
91
  updatedAt: card.updatedAt
67
92
  }))),
68
93
  running: project.recentWorkflowRuns.filter((run) => run.status === "queued" || run.status === "running"),
69
- recentReceipts,
94
+ recentResults,
70
95
  digest: {
71
96
  health: cards.length === 0 ? "empty" : attentionCount > 0 ? "attention" : "healthy",
72
- summary: cards.length === 0 ? "No tasks yet" : `${cards.filter((card) => card.lane === "moving").length} moving, ${attentionCount} need attention`
97
+ summary: cards.length === 0 ? "No tasks yet" : `${cards.filter(moving).length} moving, ${attentionCount} need attention`,
98
+ recommendedAction: cards.find(needsUser)?.attention[0]?.summary ?? cards.find((card) => card.attention.length > 0)?.attention[0]?.summary ?? cards.find(moving)?.title ?? cards.find((card) => card.phase === "ready")?.title ?? cards.find((card) => card.phase === "backlog")?.title
73
99
  },
74
100
  monitoring: this.#monitoring.get(project.id)
75
101
  };
76
102
  }
77
103
  };
78
104
  //#endregion
79
- export { ProjectOperatingViewService, projectTaskLane };
105
+ export { ProjectOperatingViewService, summarizeProjectOperatingView };