@xopcai/xopc 0.0.312 → 0.0.314

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 (497) hide show
  1. package/dist/browser-ext/dist/assets/{auth-C3yV1y_l.js → auth-DKo-NMUY.js} +18 -1
  2. package/dist/browser-ext/dist/background.js +68 -2
  3. package/dist/browser-ext/dist/sidepanel.html +1 -1
  4. package/dist/browser-ext/dist/sidepanel.js +1 -1
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  7. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  8. package/dist/extensions/telegram/src/plugin.js +2 -2
  9. package/dist/extensions/telegram/xopc.extension.json +1 -1
  10. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BVIJMP8w.js → agent-avatar-dicebear-BFkjfurL.js} +1 -1
  11. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BdOZ6q8Z.js +1 -0
  12. package/dist/gateway/static/root/assets/{agents-D6g_SeWI.js → agents-CCcavsHq.js} +1 -1
  13. package/dist/gateway/static/root/assets/{api-_aHQA8bd.js → api-BYhRsTAc.js} +1 -1
  14. package/dist/gateway/static/root/assets/{app-link-CKueEVbT.js → app-link-nL8iPwEr.js} +1 -1
  15. package/dist/gateway/static/root/assets/{app-management-settings-panel-CLg_aXYG.js → app-management-settings-panel-B4kihr-A.js} +1 -1
  16. package/dist/gateway/static/root/assets/appearance-settings-N9sYmNOx.js +1 -0
  17. package/dist/gateway/static/root/assets/apps-page-BMcy10_s.js +1 -0
  18. package/dist/gateway/static/root/assets/{archive-plugin-CHO3heHX.js → archive-plugin-k_SuYWyV.js} +1 -1
  19. package/dist/gateway/static/root/assets/{attachment-load-BsmsBCI2.js → attachment-load-DRv5QWUK.js} +1 -1
  20. package/dist/gateway/static/root/assets/{automations-page-CftigJlf.js → automations-page-CkJV3DN0.js} +1 -1
  21. package/dist/gateway/static/root/assets/automations-workspace-BEa2doeR.js +7 -0
  22. package/dist/gateway/static/root/assets/{binary-plugins-CRCLWBo2.js → binary-plugins-Dg3h3TA7.js} +1 -1
  23. package/dist/gateway/static/root/assets/{block-editor-D0LDiOTT.js → block-editor-DVhdHntT.js} +29 -29
  24. package/dist/gateway/static/root/assets/{browser-automation-inputs-C611KRBx.js → browser-automation-inputs-BMRYUW8_.js} +1 -1
  25. package/dist/gateway/static/root/assets/{browser-automations-page-Djyv3vy-.js → browser-automations-page-Byv6-FY2.js} +2 -2
  26. package/dist/gateway/static/root/assets/browser-settings-page-DRCHGFpO.js +3 -0
  27. package/dist/gateway/static/root/assets/capabilities-D0S3DuAD.js +1 -0
  28. package/dist/gateway/static/root/assets/capabilities-settings-panel-mxRP0gl0.js +8 -0
  29. package/dist/gateway/static/root/assets/channels-settings-DBt_6GsB.js +1 -0
  30. package/dist/gateway/static/root/assets/{chat-terminal-dock-CIsKqdET.js → chat-terminal-dock-D4AHa51o.js} +2 -2
  31. package/dist/gateway/static/root/assets/{computer-settings-page-C0YL9J7m.js → computer-settings-page-eXPe500D.js} +1 -1
  32. package/dist/gateway/static/root/assets/connector-service-page-BQTFlq_k.js +1 -0
  33. package/dist/gateway/static/root/assets/connectors-page-BKeBWwcI.js +2 -0
  34. package/dist/gateway/static/root/assets/conversation-identity-Cw0n9uzK.js +1 -0
  35. package/dist/gateway/static/root/assets/{date-picker-CDsfv8R0.js → date-picker-7MtovynY.js} +1 -1
  36. package/dist/gateway/static/root/assets/{dependency-picker-DvhPj3CZ.js → dependency-picker-Bj_xkXID.js} +1 -1
  37. package/dist/gateway/static/root/assets/{desktop-pet-Cyg8XMpL.js → desktop-pet-CTmba9zH.js} +1 -1
  38. package/dist/gateway/static/root/assets/desktop-pet-settings-DNM_BlWN.js +1 -0
  39. package/dist/gateway/static/root/assets/device-pairing-wizard-C2XE0QhT.js +1 -0
  40. package/dist/gateway/static/root/assets/{extension-debug-page-D-AVJU3q.js → extension-debug-page-J_olaL7e.js} +1 -1
  41. package/dist/gateway/static/root/assets/{extension-page-DrFoQ9xt.js → extension-page-pK5RvqN8.js} +1 -1
  42. package/dist/gateway/static/root/assets/{extension-settings-page-DxWjESC1.js → extension-settings-page-BwroEN08.js} +1 -1
  43. package/dist/gateway/static/root/assets/files-BK6enEvD.js +1 -0
  44. package/dist/gateway/static/root/assets/{gateway-config-swr-DUDX42qY.js → gateway-config-swr-FuJTIg_a.js} +1 -1
  45. package/dist/gateway/static/root/assets/gateway-settings-CLLDp23J.js +1 -0
  46. package/dist/gateway/static/root/assets/{gateway-startup-retry-Cf8OxlvY.js → gateway-startup-retry-CKg_gu8_.js} +1 -1
  47. package/dist/gateway/static/root/assets/home-page-B5Epb1PH.js +1 -0
  48. package/dist/gateway/static/root/assets/{image-generation-api-D2YorS--.js → image-generation-api-Bo6NZ7zb.js} +1 -1
  49. package/dist/gateway/static/root/assets/{imports-page-BKucJlXI.js → imports-page-C8-hX8gS.js} +1 -1
  50. package/dist/gateway/static/root/assets/index-14F1yGJI.js +89 -0
  51. package/dist/gateway/static/root/assets/index-cB7rWIDY.css +1 -0
  52. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BxLXD-yU.js → keyboard-shortcuts-settings-BkBEjUZD.js} +1 -1
  53. package/dist/gateway/static/root/assets/local-app-workbench-page-6jC3vQpY.js +2 -0
  54. package/dist/gateway/static/root/assets/{local-apps-page-BAsQJQKJ.js → local-apps-page-CrbKIixo.js} +1 -1
  55. package/dist/gateway/static/root/assets/{locale-store-DA0Z5jM_.js → locale-store-CvGwNbml.js} +1 -1
  56. package/dist/gateway/static/root/assets/logs-page-DBHlZts9.js +2 -0
  57. package/dist/gateway/static/root/assets/management-settings-DsUWLu5m.js +1 -0
  58. package/dist/gateway/static/root/assets/{markdown-view-DYGPxPee.js → markdown-view-nXo5nrsv.js} +1 -1
  59. package/dist/gateway/static/root/assets/{media-plugins-CQtQzLyg.js → media-plugins-upxXJ-4l.js} +1 -1
  60. package/dist/gateway/static/root/assets/messages-B_AwRroN.js +3 -0
  61. package/dist/gateway/static/root/assets/note-detail-panel-0Q9TOtJG.js +5 -0
  62. package/dist/gateway/static/root/assets/notes-page-D0NmcwNw.js +8 -0
  63. package/dist/gateway/static/root/assets/page-context-capture-button-DUyA-K4L.js +1 -0
  64. package/dist/gateway/static/root/assets/{page-tabs-B6DjkyMM.js → page-tabs-Cl-NFPNr.js} +1 -1
  65. package/dist/gateway/static/root/assets/{preview-open-alternatives-Dn57uLhr.js → preview-open-alternatives-DX81PwJ3.js} +1 -1
  66. package/dist/gateway/static/root/assets/product-delivery-chCjIpvu.js +1 -0
  67. package/dist/gateway/static/root/assets/{product-open-page-H2YMk8TY.js → product-open-page-CrfIGwm8.js} +1 -1
  68. package/dist/gateway/static/root/assets/project-detail-page-BVfVrYmn.js +1 -0
  69. package/dist/gateway/static/root/assets/projects-page-nM9a9XNS.js +1 -0
  70. package/dist/gateway/static/root/assets/{registry-api-C0DCx3wv.js → registry-api-CHxgohY0.js} +1 -1
  71. package/dist/gateway/static/root/assets/remote-access-hub-C8b_k88G.js +1 -0
  72. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-D3dLOW04.js +5 -0
  73. package/dist/gateway/static/root/assets/scenes-page-DEowreZV.js +2 -0
  74. package/dist/gateway/static/root/assets/{schema-form-CblI9WUA.js → schema-form-ZxuIvD2_.js} +1 -1
  75. package/dist/gateway/static/root/assets/schemas-88fK3zzl.js +64 -0
  76. package/dist/gateway/static/root/assets/sessions-page-B_nPhera.js +1 -0
  77. package/dist/gateway/static/root/assets/settings-advanced-gate-BqhIOuus.js +1 -0
  78. package/dist/gateway/static/root/assets/{settings-form-section-BAaVyxJH.js → settings-form-section-TZRfg4yo.js} +1 -1
  79. package/dist/gateway/static/root/assets/{settings-page-CKNPbm5q.js → settings-page-a8qcJpdZ.js} +1 -1
  80. package/dist/gateway/static/root/assets/{settings-page-layout-DqNCGKxQ.js → settings-page-layout-BfvlRT9q.js} +1 -1
  81. package/dist/gateway/static/root/assets/setup-status-panel-CRj5Ruqn.js +1 -0
  82. package/dist/gateway/static/root/assets/{share-preview-page-BzMfp_HM.js → share-preview-page-DCt1pTWB.js} +1 -1
  83. package/dist/gateway/static/root/assets/shares-settings-BNbXPk--.js +1 -0
  84. package/dist/gateway/static/root/assets/skill-reload-api-CNMCLbav.js +1 -0
  85. package/dist/gateway/static/root/assets/{skills-page-DIht92q6.js → skills-page-BIOcg44X.js} +1 -1
  86. package/dist/gateway/static/root/assets/{skills-page.utils-DLYRiEn3.js → skills-page.utils-CgZdzT4I.js} +1 -1
  87. package/dist/gateway/static/root/assets/{system-settings-panel-yYs4YgYk.js → system-settings-panel-_YaRncA6.js} +1 -1
  88. package/dist/gateway/static/root/assets/task-detail-page-CAcfAG-c.js +1 -0
  89. package/dist/gateway/static/root/assets/tasks-CDR_RVbQ.js +1 -0
  90. package/dist/gateway/static/root/assets/{tunnel-api-BasDYxvx.js → tunnel-api-uOupJOoS.js} +1 -1
  91. package/dist/gateway/static/root/assets/turn-outcome-D0SnyZ3Z.js +1 -0
  92. package/dist/gateway/static/root/assets/{use-autosave-CWAUHhcb.js → use-autosave-BezzHBLE.js} +1 -1
  93. package/dist/gateway/static/root/assets/user-model-page-BFFeneDq.js +2 -0
  94. package/dist/gateway/static/root/assets/{voice-api-key-field-Kc4UlxZs.js → voice-api-key-field-BmYifdwL.js} +1 -1
  95. package/dist/gateway/static/root/assets/{voice-config-api-DTyMdGOR.js → voice-config-api-D_5Q2_A3.js} +1 -1
  96. package/dist/gateway/static/root/assets/{work-discovery-overlay-BPC_c9dO.js → work-discovery-overlay-4DmyEckJ.js} +1 -1
  97. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DBTciOrq.js → workflow-run-setup-panel-DeZe8bTZ.js} +2 -2
  98. package/dist/gateway/static/root/assets/workflows-page-Sv4hEc6W.js +6 -0
  99. package/dist/gateway/static/root/index.html +16 -16
  100. package/dist/package.js +1 -1
  101. package/dist/packages/computer-control-contract/src/index.js +10 -1
  102. package/dist/packages/gateway-contract/src/app-context.js +55 -0
  103. package/dist/packages/gateway-contract/src/automations.js +16 -17
  104. package/dist/packages/gateway-contract/src/capabilities.js +1078 -0
  105. package/dist/packages/gateway-contract/src/extension-capabilities.js +26 -0
  106. package/dist/packages/gateway-contract/src/home.js +3 -3
  107. package/dist/packages/gateway-contract/src/index.js +8 -0
  108. package/dist/packages/gateway-contract/src/product-delivery.js +19 -4
  109. package/dist/packages/gateway-contract/src/scenes.js +199 -0
  110. package/dist/packages/gateway-contract/src/task-runs.js +8 -4
  111. package/dist/packages/gateway-contract/src/tasks.js +5 -4
  112. package/dist/packages/realtime-client/src/index.js +17 -4
  113. package/dist/src/agent/agent-manager.d.ts +1 -0
  114. package/dist/src/agent/agent-manager.js +1 -0
  115. package/dist/src/agent/child-agent-factory.d.ts +2 -0
  116. package/dist/src/agent/child-agent-factory.js +5 -0
  117. package/dist/src/agent/commands/approved-verification.d.ts +14 -0
  118. package/dist/src/agent/commands/approved-verification.js +48 -0
  119. package/dist/src/agent/context/execution-scope.js +2 -1
  120. package/dist/src/agent/context/project-context.js +2 -1
  121. package/dist/src/agent/external-tools/cliProvider.js +123 -75
  122. package/dist/src/agent/external-tools/composio-provider.d.ts +1 -1
  123. package/dist/src/agent/external-tools/composio-provider.js +70 -12
  124. package/dist/src/agent/external-tools/endpoint-provider.js +14 -1
  125. package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -0
  126. package/dist/src/agent/inbound/turn-dispatcher.js +2 -1
  127. package/dist/src/agent/memory/compaction-chunks.d.ts +6 -1
  128. package/dist/src/agent/memory/compaction-chunks.js +16 -3
  129. package/dist/src/agent/memory/compaction-ledger.d.ts +3 -1
  130. package/dist/src/agent/memory/compaction-ledger.js +31 -18
  131. package/dist/src/agent/memory/compaction-request.d.ts +2 -0
  132. package/dist/src/agent/memory/compaction-request.js +6 -1
  133. package/dist/src/agent/memory/compaction.d.ts +19 -1
  134. package/dist/src/agent/memory/compaction.js +112 -30
  135. package/dist/src/agent/service/process-direct-streaming.d.ts +3 -0
  136. package/dist/src/agent/service/process-direct-streaming.js +19 -10
  137. package/dist/src/agent/service.js +1 -0
  138. package/dist/src/agent/service.types.d.ts +1 -0
  139. package/dist/src/agent/skills/config.js +2 -0
  140. package/dist/src/agent/skills/format-skills-prompt.js +14 -1
  141. package/dist/src/agent/skills/index.js +16 -8
  142. package/dist/src/agent/skills/types.d.ts +1 -1
  143. package/dist/src/agent/source-context/app-context.d.ts +4 -0
  144. package/dist/src/agent/source-context/app-context.js +36 -0
  145. package/dist/src/agent/source-context/injector.js +1 -0
  146. package/dist/src/agent/source-context/types.d.ts +5 -1
  147. package/dist/src/agent/tasks/task-judge-service.js +2 -1
  148. package/dist/src/agent/tool-manuals/computer.d.ts +1 -1
  149. package/dist/src/agent/tool-manuals/computer.js +1 -1
  150. package/dist/src/agent/tools/automation-tool.d.ts +12 -1
  151. package/dist/src/agent/tools/automation-tool.js +106 -32
  152. package/dist/src/agent/tools/factory.d.ts +1 -0
  153. package/dist/src/agent/tools/factory.js +6 -1
  154. package/dist/src/agent/tools/scoped-workspace-tools.d.ts +8 -0
  155. package/dist/src/agent/tools/scoped-workspace-tools.js +81 -0
  156. package/dist/src/agent/tools/xopc-use-tool.d.ts +6 -3
  157. package/dist/src/agent/tools/xopc-use-tool.js +997 -908
  158. package/dist/src/agent/workflow/subagent-runner.js +1 -0
  159. package/dist/src/agent-config/index.js +2 -2
  160. package/dist/src/agent-config/schema.d.ts +5 -0
  161. package/dist/src/agent-config/schema.js +14 -10
  162. package/dist/src/automations/api/routes.js +244 -164
  163. package/dist/src/automations/capabilities/drafts.d.ts +4 -0
  164. package/dist/src/automations/capabilities/drafts.js +95 -0
  165. package/dist/src/automations/capabilities/read.d.ts +4 -0
  166. package/dist/src/automations/capabilities/read.js +119 -0
  167. package/dist/src/automations/capabilities/write.d.ts +349 -0
  168. package/dist/src/automations/capabilities/write.js +172 -0
  169. package/dist/src/automations/domain/index.js +2 -2
  170. package/dist/src/automations/domain/validation.d.ts +77 -77
  171. package/dist/src/automations/domain/validation.js +9 -6
  172. package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -2
  173. package/dist/src/automations/index.js +6 -6
  174. package/dist/src/automations/service/automation-service.d.ts +31 -0
  175. package/dist/src/automations/service/automation-service.js +213 -75
  176. package/dist/src/automations/service/index.js +2 -2
  177. package/dist/src/automations/storage/automation-repository.d.ts +2 -0
  178. package/dist/src/automations/storage/automation-repository.js +9 -1
  179. package/dist/src/automations/storage/automation-run-repository.d.ts +4 -1
  180. package/dist/src/automations/storage/automation-run-repository.js +16 -3
  181. package/dist/src/automations/storage/index.js +3 -3
  182. package/dist/src/browser/automations/schema.d.ts +1 -1
  183. package/dist/src/browser/automations/service.d.ts +1 -1
  184. package/dist/src/browser/observation/format.js +4 -0
  185. package/dist/src/capabilities/adapters/http.d.ts +4 -0
  186. package/dist/src/capabilities/adapters/http.js +44 -0
  187. package/dist/src/capabilities/readiness/from-config.js +11 -7
  188. package/dist/src/capabilities/runtime/app-context.d.ts +3 -0
  189. package/dist/src/capabilities/runtime/app-context.js +72 -0
  190. package/dist/src/capabilities/runtime/atomic-operations.d.ts +11 -0
  191. package/dist/src/capabilities/runtime/atomic-operations.js +34 -0
  192. package/dist/src/capabilities/runtime/dispatcher.d.ts +67 -0
  193. package/dist/src/capabilities/runtime/dispatcher.js +170 -0
  194. package/dist/src/capabilities/runtime/errors.d.ts +6 -0
  195. package/dist/src/capabilities/runtime/errors.js +11 -0
  196. package/dist/src/capabilities/runtime/external-operations.d.ts +16 -0
  197. package/dist/src/capabilities/runtime/external-operations.js +92 -0
  198. package/dist/src/capabilities/runtime/product.d.ts +12 -0
  199. package/dist/src/capabilities/runtime/product.js +69 -0
  200. package/dist/src/capabilities/runtime/settings.d.ts +3 -0
  201. package/dist/src/capabilities/runtime/settings.js +27 -0
  202. package/dist/src/channels/index.js +2 -2
  203. package/dist/src/channels/manager.js +1 -1
  204. package/dist/src/cli/cli-log-level-preset.d.ts +2 -0
  205. package/dist/src/cli/cli-log-level-preset.js +4 -0
  206. package/dist/src/cli/command-catalog.js +4 -0
  207. package/dist/src/cli/command-loaders.js +1 -0
  208. package/dist/src/cli/command-manifest.js +4 -0
  209. package/dist/src/cli/commands/channels.js +1 -1
  210. package/dist/src/cli/commands/connectors.js +1 -1
  211. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  212. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  213. package/dist/src/cli/commands/mcp.d.ts +1 -0
  214. package/dist/src/cli/commands/mcp.js +51 -0
  215. package/dist/src/cli/commands/models.js +1 -1
  216. package/dist/src/cli/commands/onboard.js +1 -1
  217. package/dist/src/cli/commands/project.js +1 -1
  218. package/dist/src/computer/broker.d.ts +0 -1
  219. package/dist/src/computer/broker.js +4 -6
  220. package/dist/src/computer/evaluation-harness.d.ts +45 -0
  221. package/dist/src/computer/evaluation-harness.js +108 -0
  222. package/dist/src/computer/model-adapter.d.ts +37 -2
  223. package/dist/src/computer/model-adapter.js +333 -42
  224. package/dist/src/computer/model-policy.d.ts +4 -1
  225. package/dist/src/computer/model-policy.js +11 -3
  226. package/dist/src/computer/release-gate.d.ts +22 -0
  227. package/dist/src/computer/release-gate.js +19 -0
  228. package/dist/src/computer/runtime.js +14 -10
  229. package/dist/src/computer/task-state.d.ts +1 -0
  230. package/dist/src/computer/task-state.js +1 -0
  231. package/dist/src/config/models-json.d.ts +14 -8
  232. package/dist/src/config/models-json.js +1 -1
  233. package/dist/src/config/schema.d.ts +4 -0
  234. package/dist/src/config/schema.js +3 -9
  235. package/dist/src/connectors/composio-sessions.d.ts +4 -2
  236. package/dist/src/connectors/composio-sessions.js +10 -9
  237. package/dist/src/connectors/composio.js +10 -8
  238. package/dist/src/discussions/action-tasks.js +2 -1
  239. package/dist/src/discussions/recording.js +1 -1
  240. package/dist/src/execution-environments/local-worktree-manager.d.ts +1 -0
  241. package/dist/src/execution-environments/local-worktree-manager.js +13 -2
  242. package/dist/src/extensions/activation-context.js +3 -3
  243. package/dist/src/extensions/api.js +1 -1
  244. package/dist/src/extensions/normalize-manifest.js +6 -1
  245. package/dist/src/extensions/sdk/index.js +1 -1
  246. package/dist/src/extensions/sdk/media.js +1 -1
  247. package/dist/src/extensions/types/manifest.d.ts +3 -0
  248. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  249. package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
  250. package/dist/src/gateway/hono/middleware/scopes.js +1 -1
  251. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +5 -2
  252. package/dist/src/gateway/hono/routes/capability-operations.d.ts +3 -0
  253. package/dist/src/gateway/hono/routes/capability-operations.js +52 -0
  254. package/dist/src/gateway/hono/routes/lazy-bundles.js +16 -0
  255. package/dist/src/gateway/hono/routes/local-app-capabilities.d.ts +4 -0
  256. package/dist/src/gateway/hono/routes/local-app-capabilities.js +41 -0
  257. package/dist/src/gateway/hono/routes/local-apps.js +41 -9
  258. package/dist/src/gateway/hono/routes/models.js +2 -2
  259. package/dist/src/gateway/hono/routes/notes.js +215 -146
  260. package/dist/src/gateway/hono/routes/projects.js +217 -374
  261. package/dist/src/gateway/hono/routes/scenes.js +188 -75
  262. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +60 -16
  263. package/dist/src/gateway/hono/routes/session-input-handler.js +43 -1
  264. package/dist/src/gateway/hono/routes/sessions.js +17 -0
  265. package/dist/src/gateway/hono/routes/status.js +1 -1
  266. package/dist/src/gateway/hono/routes/tasks.js +182 -326
  267. package/dist/src/gateway/hono/routes/user-model-refresh.js +1 -1
  268. package/dist/src/gateway/hono/routes/voice.js +4 -4
  269. package/dist/src/gateway/hono/routes/workflows.js +1 -1
  270. package/dist/src/gateway/media-access.js +2 -1
  271. package/dist/src/gateway/mobile-privacy.js +2 -2
  272. package/dist/src/gateway/scenes/host.js +14 -3
  273. package/dist/src/gateway/scenes/mailContext.js +1 -1
  274. package/dist/src/gateway/scenes/slackThreadSource.d.ts +41 -0
  275. package/dist/src/gateway/scenes/slackThreadSource.js +168 -0
  276. package/dist/src/gateway/security/gateway-scopes.d.ts +1 -1
  277. package/dist/src/gateway/security/gateway-scopes.js +5 -0
  278. package/dist/src/gateway/service/app-context-access.d.ts +11 -0
  279. package/dist/src/gateway/service/app-context-access.js +70 -0
  280. package/dist/src/gateway/service/run-gateway-agent.js +11 -2
  281. package/dist/src/gateway/service/session-input-coordinator.js +54 -15
  282. package/dist/src/gateway/service/sessions-api.d.ts +1 -0
  283. package/dist/src/gateway/service/sessions-api.js +3 -0
  284. package/dist/src/gateway/service/task-conversation-query-service.d.ts +3 -1
  285. package/dist/src/gateway/service/task-conversation-query-service.js +32 -3
  286. package/dist/src/gateway/service.d.ts +3 -0
  287. package/dist/src/gateway/service.js +69 -15
  288. package/dist/src/gateway/session-context-summary.js +2 -1
  289. package/dist/src/{tasks/task-outbox-dispatcher.d.ts → infra/domain-outbox-dispatcher.d.ts} +2 -2
  290. package/dist/src/{tasks/task-outbox-dispatcher.js → infra/domain-outbox-dispatcher.js} +10 -9
  291. package/dist/src/infra/operation-context.d.ts +2 -0
  292. package/dist/src/infra/operation-context.js +16 -0
  293. package/dist/src/local-apps/capabilities/contracts.d.ts +2 -0
  294. package/dist/src/local-apps/capabilities/contracts.js +32 -0
  295. package/dist/src/local-apps/capabilities/read.d.ts +3 -0
  296. package/dist/src/local-apps/capabilities/read.js +48 -0
  297. package/dist/src/local-apps/capabilities/runtime.d.ts +16 -0
  298. package/dist/src/local-apps/capabilities/runtime.js +66 -0
  299. package/dist/src/local-apps/capabilities/write.d.ts +3 -0
  300. package/dist/src/local-apps/capabilities/write.js +35 -0
  301. package/dist/src/local-apps/release-lock.d.ts +2 -0
  302. package/dist/src/local-apps/release-lock.js +20 -0
  303. package/dist/src/local-apps/runtime-entry.d.ts +0 -2
  304. package/dist/src/local-apps/runtime-entry.js +1 -14
  305. package/dist/src/local-apps/scaffold.js +4 -1
  306. package/dist/src/local-apps/service.d.ts +24 -1
  307. package/dist/src/local-apps/service.js +186 -43
  308. package/dist/src/local-apps/store.js +0 -2
  309. package/dist/src/mcp/capability-server.d.ts +4 -0
  310. package/dist/src/mcp/capability-server.js +96 -0
  311. package/dist/src/mcp/channel-bridge.js +1 -1
  312. package/dist/src/mcp/gateway-http-client.d.ts +7 -0
  313. package/dist/src/mcp/gateway-http-client.js +27 -5
  314. package/dist/src/media-understanding/openai-compatible-audio.js +1 -1
  315. package/dist/src/notes/agent-context.js +1 -1
  316. package/dist/src/notes/capabilities/read.d.ts +3 -0
  317. package/dist/src/notes/capabilities/read.js +96 -0
  318. package/dist/src/notes/capabilities/write.d.ts +7 -0
  319. package/dist/src/notes/capabilities/write.js +152 -0
  320. package/dist/src/notes/index.js +1 -1
  321. package/dist/src/notes/service.d.ts +12 -4
  322. package/dist/src/notes/service.js +188 -175
  323. package/dist/src/notes/store.d.ts +14 -9
  324. package/dist/src/notes/store.js +81 -21
  325. package/dist/src/notifications/service.d.ts +1 -0
  326. package/dist/src/notifications/service.js +5 -0
  327. package/dist/src/platform/client.d.ts +1 -1
  328. package/dist/src/platform/contracts.d.ts +1 -1
  329. package/dist/src/projects/capabilities/read.d.ts +3 -0
  330. package/dist/src/projects/capabilities/read.js +81 -0
  331. package/dist/src/projects/capabilities/write.d.ts +9 -0
  332. package/dist/src/projects/capabilities/write.js +260 -0
  333. package/dist/src/projects/index.js +2 -2
  334. package/dist/src/projects/project-change-events.d.ts +2 -0
  335. package/dist/src/projects/project-change-events.js +18 -0
  336. package/dist/src/projects/project-service.d.ts +11 -0
  337. package/dist/src/projects/project-service.js +121 -42
  338. package/dist/src/projects/project-store.js +12 -2
  339. package/dist/src/projects/project-workspace-creation.d.ts +3 -0
  340. package/dist/src/projects/project-workspace-creation.js +45 -0
  341. package/dist/src/projects/workspace-project.js +6 -0
  342. package/dist/src/providers/model-catalog-types.d.ts +2 -1
  343. package/dist/src/providers/model-reference-auditor.js +4 -4
  344. package/dist/src/providers/model-supplements.js +13 -3
  345. package/dist/src/providers/presentation.js +3 -3
  346. package/dist/src/providers/xopc-cloud-model-source.js +4 -2
  347. package/dist/src/realtime/runtime.js +4 -0
  348. package/dist/src/scenes/capabilities/read.d.ts +3 -0
  349. package/dist/src/scenes/capabilities/read.js +187 -0
  350. package/dist/src/scenes/capabilities/write.d.ts +3 -0
  351. package/dist/src/scenes/capabilities/write.js +151 -0
  352. package/dist/src/scenes/contracts.d.ts +2 -105
  353. package/dist/src/scenes/contracts.js +3 -88
  354. package/dist/src/scenes/execution.d.ts +1 -1
  355. package/dist/src/scenes/httpServices.d.ts +2 -0
  356. package/dist/src/scenes/inbox.d.ts +1 -0
  357. package/dist/src/scenes/inbox.js +7 -7
  358. package/dist/src/scenes/preferences.d.ts +3 -24
  359. package/dist/src/scenes/preferences.js +8 -30
  360. package/dist/src/scenes/repository.d.ts +1 -0
  361. package/dist/src/scenes/repository.js +7 -3
  362. package/dist/src/scenes/resultNotifications.js +2 -2
  363. package/dist/src/scenes/schedule.d.ts +1 -8
  364. package/dist/src/scenes/schedule.js +3 -15
  365. package/dist/src/scenes/service.d.ts +6 -0
  366. package/dist/src/scenes/service.js +29 -25
  367. package/dist/src/scenes/taskFollowUp/agentExecutor.d.ts +36 -0
  368. package/dist/src/scenes/taskFollowUp/agentExecutor.js +149 -0
  369. package/dist/src/scenes/taskFollowUp/branchInventory.d.ts +38 -0
  370. package/dist/src/scenes/taskFollowUp/branchInventory.js +70 -0
  371. package/dist/src/scenes/taskFollowUp/contracts.d.ts +91 -0
  372. package/dist/src/scenes/taskFollowUp/contracts.js +100 -0
  373. package/dist/src/scenes/taskFollowUp/resources.d.ts +19 -0
  374. package/dist/src/scenes/taskFollowUp/resources.js +97 -0
  375. package/dist/src/scenes/taskFollowUp/service.d.ts +810 -0
  376. package/dist/src/scenes/taskFollowUp/service.js +710 -0
  377. package/dist/src/scenes/taskFollowUp/workspaceFingerprint.d.ts +2 -0
  378. package/dist/src/scenes/taskFollowUp/workspaceFingerprint.js +46 -0
  379. package/dist/src/scenes/templates.d.ts +2 -2
  380. package/dist/src/scenes/templates.js +1 -1
  381. package/dist/src/session/session-find.d.ts +17 -0
  382. package/dist/src/session/session-find.js +56 -0
  383. package/dist/src/session/store.d.ts +4 -0
  384. package/dist/src/session/store.js +43 -7
  385. package/dist/src/share/note-share-revocation.d.ts +3 -0
  386. package/dist/src/share/note-share-revocation.js +26 -0
  387. package/dist/src/storage/sqlite/migrations/190_scene_development.sql +37 -0
  388. package/dist/src/storage/sqlite/migrations/191_scene_task_follow_up.sql +27 -0
  389. package/dist/src/storage/sqlite/migrations/192_capability_operations.sql +20 -0
  390. package/dist/src/storage/sqlite/migrations/193_note_file_cleanup.sql +8 -0
  391. package/dist/src/storage/sqlite/migrations/194_capability_external_outcomes.sql +11 -0
  392. package/dist/src/storage/sqlite/migrations/195_automation_deleted_revisions.sql +4 -0
  393. package/dist/src/storage/sqlite/migrations/196_automation_run_requests.sql +23 -0
  394. package/dist/src/storage/sqlite/migrations/197_note_deletion_cleanup.sql +8 -0
  395. package/dist/src/storage/sqlite/migrations/198_project_workspace_creation.sql +7 -0
  396. package/dist/src/storage/sqlite/migrations/199_scene_resource_events.sql +488 -0
  397. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  398. package/dist/src/storage/sqlite/migrations/runner.js +6 -3
  399. package/dist/src/storage/sqlite/schema.js +1 -1
  400. package/dist/src/storage/sqlite/transaction.d.ts +5 -0
  401. package/dist/src/storage/sqlite/transaction.js +34 -3
  402. package/dist/src/tasks/capabilities/management.d.ts +195 -0
  403. package/dist/src/tasks/capabilities/management.js +111 -0
  404. package/dist/src/tasks/capabilities/read.d.ts +2 -0
  405. package/dist/src/tasks/capabilities/read.js +141 -0
  406. package/dist/src/tasks/capabilities/relations.d.ts +204 -0
  407. package/dist/src/tasks/capabilities/relations.js +140 -0
  408. package/dist/src/tasks/capabilities/runs.d.ts +2 -0
  409. package/dist/src/tasks/capabilities/runs.js +89 -0
  410. package/dist/src/tasks/capabilities/write.d.ts +207 -0
  411. package/dist/src/tasks/capabilities/write.js +107 -0
  412. package/dist/src/tasks/home-query-service.js +3 -2
  413. package/dist/src/tasks/index.d.ts +0 -1
  414. package/dist/src/tasks/index.js +9 -9
  415. package/dist/src/tasks/project-operating-view-service.js +2 -1
  416. package/dist/src/tasks/task-application-service.d.ts +1 -0
  417. package/dist/src/tasks/task-application-service.js +3 -2
  418. package/dist/src/tasks/task-change-events.js +5 -3
  419. package/dist/src/tasks/task-context-assembler.js +2 -1
  420. package/dist/src/tasks/task-deletion-service.js +2 -1
  421. package/dist/src/tasks/task-dependency-service.js +2 -1
  422. package/dist/src/tasks/task-handoff-service.js +2 -1
  423. package/dist/src/tasks/task-read-model-projector.js +2 -1
  424. package/dist/src/tasks/task-repository.d.ts +12 -7
  425. package/dist/src/tasks/task-repository.js +175 -154
  426. package/dist/src/tasks/task-run-coordinator.js +2 -1
  427. package/dist/src/tasks/task-run-dispatcher.js +2 -1
  428. package/dist/src/tasks/task-run-repository.d.ts +1 -0
  429. package/dist/src/tasks/task-run-repository.js +29 -14
  430. package/dist/src/tasks/task-signal-service.js +2 -1
  431. package/dist/src/tui/backends/embedded-backend.js +1 -1
  432. package/dist/src/tui/backends/gateway-realtime-backend.js +1 -1
  433. package/dist/src/tui/tui-commands.js +1 -1
  434. package/dist/src/user-context/config.d.ts +13 -0
  435. package/dist/src/user-context/config.js +2 -0
  436. package/dist/src/voice/platform-catalog.d.ts +1 -1
  437. package/dist/src/voice/realtime/runtime.js +3 -3
  438. package/dist/src/voice/stt/providers/alibaba-transcription.js +1 -1
  439. package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +1 -1
  440. package/dist/src/voice/tts/providers/xopc-cloud-speech.js +1 -1
  441. package/dist/src/work-discovery/incremental-repository.js +1 -1
  442. package/dist/src/work-discovery/index.js +1 -1
  443. package/dist/src/work-discovery/repository.d.ts +1 -1
  444. package/dist/src/work-discovery/repository.js +3 -2
  445. package/dist/src/work-discovery/service.d.ts +4 -0
  446. package/dist/src/work-discovery/service.js +36 -11
  447. package/dist/src/workflows/context/workflow-context.js +3 -2
  448. package/dist/src/workflows/service/workflow-run-service.js +2 -1
  449. package/package.json +6 -2
  450. package/skills/THIRD_PARTY_NOTICES.md +2 -2
  451. package/skills/documents/xlsx/SKILL.md +5 -0
  452. package/skills/engineering/build-xopc-local-app/SKILL.md +2 -0
  453. package/skills/tools/find-skills/SKILL.md +3 -0
  454. package/dist/gateway/static/root/assets/activity-store-DVUTs1fk.js +0 -1
  455. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-K3hTmu9d.js +0 -1
  456. package/dist/gateway/static/root/assets/appearance-settings-CU52MfIT.js +0 -1
  457. package/dist/gateway/static/root/assets/apps-page-ZpA1-6ad.js +0 -1
  458. package/dist/gateway/static/root/assets/automations-workspace-IEAxKRME.js +0 -7
  459. package/dist/gateway/static/root/assets/browser-settings-page-CU4VWsmX.js +0 -3
  460. package/dist/gateway/static/root/assets/capabilities-settings-panel-C9XQk3HL.js +0 -8
  461. package/dist/gateway/static/root/assets/channels-settings-Bqlhjooi.js +0 -1
  462. package/dist/gateway/static/root/assets/connector-service-page-BmH17JnO.js +0 -1
  463. package/dist/gateway/static/root/assets/connectors-page-zkx8Q-e6.js +0 -2
  464. package/dist/gateway/static/root/assets/desktop-pet-settings-CE4GOlMM.js +0 -1
  465. package/dist/gateway/static/root/assets/device-pairing-wizard-CdKJqnnw.js +0 -1
  466. package/dist/gateway/static/root/assets/files-Be5viEFY.js +0 -1
  467. package/dist/gateway/static/root/assets/gateway-realtime-CGOW0-b4.js +0 -1
  468. package/dist/gateway/static/root/assets/gateway-realtime-store-D4um_sV7.js +0 -1
  469. package/dist/gateway/static/root/assets/gateway-settings-CgXp2zq4.js +0 -1
  470. package/dist/gateway/static/root/assets/home-page-D6Idk732.js +0 -1
  471. package/dist/gateway/static/root/assets/index-1wIKA-kM.css +0 -1
  472. package/dist/gateway/static/root/assets/index-PFQHPGgi.js +0 -79
  473. package/dist/gateway/static/root/assets/local-app-workbench-page-BmAqTRb4.js +0 -2
  474. package/dist/gateway/static/root/assets/logs-page-ZjVYXXyM.js +0 -2
  475. package/dist/gateway/static/root/assets/management-settings-CSTkYVOZ.js +0 -1
  476. package/dist/gateway/static/root/assets/messages-4BtQKYlM.js +0 -3
  477. package/dist/gateway/static/root/assets/note-detail-panel-DuXCt-MM.js +0 -5
  478. package/dist/gateway/static/root/assets/notes-page-BjOgBVq5.js +0 -8
  479. package/dist/gateway/static/root/assets/product-delivery-CrAI8ZEa.js +0 -1
  480. package/dist/gateway/static/root/assets/project-detail-page-0zi4-i9X.js +0 -1
  481. package/dist/gateway/static/root/assets/projects-page-B18OxmJj.js +0 -1
  482. package/dist/gateway/static/root/assets/remote-access-hub-z-DxbuaE.js +0 -1
  483. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-DGsBTbo6.js +0 -5
  484. package/dist/gateway/static/root/assets/scenes-page-Bgba03B_.js +0 -1
  485. package/dist/gateway/static/root/assets/schemas-BaskVM5g.js +0 -64
  486. package/dist/gateway/static/root/assets/sessions-page-B1t3bMsm.js +0 -1
  487. package/dist/gateway/static/root/assets/settings-advanced-gate-CBX0Ezhf.js +0 -1
  488. package/dist/gateway/static/root/assets/setup-status-panel-Bw71C2X3.js +0 -1
  489. package/dist/gateway/static/root/assets/shares-settings-BoVDQolc.js +0 -1
  490. package/dist/gateway/static/root/assets/skill-reload-api-DtTptpAt.js +0 -1
  491. package/dist/gateway/static/root/assets/task-detail-page-vgkiGo-D.js +0 -1
  492. package/dist/gateway/static/root/assets/theme-store-CegIlB8d.js +0 -1
  493. package/dist/gateway/static/root/assets/user-model-page-CAGafNfP.js +0 -2
  494. package/dist/gateway/static/root/assets/workflows-page-CSxHVs1p.js +0 -6
  495. package/skills/creative/algorithmic-art/SKILL.md +0 -44
  496. package/skills/creative/algorithmic-art/templates/generator-template.js +0 -27
  497. package/skills/creative/algorithmic-art/templates/viewer.html +0 -27
@@ -1,38 +1,55 @@
1
- import { createLogger } from "../../../utils/logger/index.js";
2
- import { init_logger } from "../../../utils/logger.js";
3
1
  import { getSqliteDatabase } from "../../../storage/sqlite/transaction.js";
2
+ import { ProductReadContracts, ProjectDeleteOutputSchema, ProjectMilestoneDeleteOutputSchema, ProjectMilestoneOutputSchema, ProjectMutationOutputSchema, ProjectResolveWorkspaceOutputSchema, ProjectUpdateOutputSchema } from "../../../../packages/gateway-contract/src/capabilities.js";
3
+ import { init_src } from "../../../../packages/gateway-contract/src/index.js";
4
+ import { TaskRepository } from "../../../tasks/task-repository.js";
4
5
  import { getSessionMetadata } from "../../../storage/sqlite/session-read-repository.js";
5
6
  import { loadTranscriptRowsForSession } from "../../../storage/sqlite/transcript-repository.js";
6
7
  import "../../../storage/sqlite/index.js";
7
8
  import { ActivityService } from "../../../activity/service.js";
8
9
  import "../../../activity/index.js";
9
10
  import { resolveEffectiveAgentProfile } from "../../../config/agent-profile.js";
10
- import { TaskRepository } from "../../../tasks/task-repository.js";
11
11
  import { TaskReadModelProjector } from "../../../tasks/task-read-model-projector.js";
12
- import { ExecutionEnvironmentStore } from "../../../execution-environments/store.js";
13
12
  import { listKnowledgeItems, writeKnowledgeItem } from "../../../knowledge-memory/repository.js";
14
13
  import "../../../knowledge-memory/index.js";
14
+ import { CapabilityError } from "../../../capabilities/runtime/errors.js";
15
+ import "../../../capabilities/runtime/dispatcher.js";
15
16
  import { ProjectWorkspaceConflictError, ProjectWorkspaceMissingError } from "../../../projects/workspace-project.js";
16
17
  import { inferProjectExecutionMode, inferProjectKind } from "../../../projects/project-kind.js";
17
- import { isValidProjectAgentId, normalizeProjectAgentId, resolveProjectAgentId } from "../../../projects/project-agent.js";
18
+ import { ProjectDeletionBlockedError, ProjectWorkspaceInUseError } from "../../../projects/project-service.js";
19
+ import { resolveProjectAgentId } from "../../../projects/project-agent.js";
18
20
  import { inferSuggestedProjectDefaultAgentId } from "../../../projects/project-agent-suggestion.js";
19
21
  import { buildProjectLoopOverview } from "../../../projects/project-loop.js";
20
22
  import "../../../projects/index.js";
21
23
  import { TaskApplicationService } from "../../../tasks/task-application-service.js";
24
+ import { createProductDispatcher } from "../../../capabilities/runtime/product.js";
22
25
  import { defineTaskContract } from "../../../tasks/task-contract-definition.js";
23
26
  import { ProjectOperatingViewService, summarizeProjectOperatingView } from "../../../tasks/project-operating-view-service.js";
24
27
  import "../../../tasks/index.js";
25
- import { getProjectUnderstandingRun } from "../../../work-discovery/repository.js";
26
28
  import { parseActivityIncludeRelated, parseActivityQuery } from "./activity.js";
29
+ import { capabilityHttpContext, capabilityHttpError } from "../../../capabilities/adapters/http.js";
27
30
  import { randomUUID } from "node:crypto";
28
31
  //#region src/gateway/hono/routes/projects.ts
29
- init_logger();
30
- const log = createLogger("Projects");
31
- function parseProjectStatus(raw) {
32
- return raw === "planned" || raw === "active" || raw === "paused" || raw === "completed" || raw === "cancelled" || raw === "archived" ? raw : void 0;
33
- }
34
- function parseProjectExecutionMode(raw) {
35
- return raw === "local_checkout" || raw === "managed_worktree" ? raw : void 0;
32
+ init_src();
33
+ function projectWriteError(c, error) {
34
+ const cause = error instanceof CapabilityError ? error.cause : error;
35
+ if (cause instanceof ProjectWorkspaceConflictError) return c.json({
36
+ ok: false,
37
+ code: "workspace_already_bound",
38
+ error: cause.message,
39
+ project: cause.project
40
+ }, 409);
41
+ if (cause instanceof ProjectWorkspaceMissingError) return c.json({
42
+ ok: false,
43
+ code: "workspace_root_missing",
44
+ error: cause.message,
45
+ workspaceRoot: cause.workspaceRoot
46
+ }, 409);
47
+ if (cause instanceof ProjectWorkspaceInUseError || cause instanceof ProjectDeletionBlockedError) return c.json({
48
+ ok: false,
49
+ code: "execution_environments_exist",
50
+ error: cause.message
51
+ }, 409);
52
+ return capabilityHttpError(c, error);
36
53
  }
37
54
  function parseLimit(raw, fallback = 50) {
38
55
  if (!raw) return void 0;
@@ -43,36 +60,6 @@ function textField(body, key) {
43
60
  const value = body[key];
44
61
  return typeof value === "string" ? value : void 0;
45
62
  }
46
- function optionalTextField(body, key) {
47
- if (!(key in body)) return void 0;
48
- const value = body[key];
49
- return typeof value === "string" ? value : null;
50
- }
51
- function stringListField(body, key) {
52
- const value = body[key];
53
- if (value === void 0) return void 0;
54
- if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) throw new Error(`${key} must be an array of strings`);
55
- return value.map((item) => item.trim()).filter(Boolean);
56
- }
57
- function objectField(body, key) {
58
- const value = body[key];
59
- if (value === void 0) return void 0;
60
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${key} must be an object`);
61
- return value;
62
- }
63
- function optionalNumberField(body, key) {
64
- const value = body[key];
65
- if (value === void 0) return void 0;
66
- if (value === null) return null;
67
- if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${key} must be a finite number`);
68
- return value;
69
- }
70
- function projectHealth(value) {
71
- return value === "unknown" || value === "on_track" || value === "at_risk" || value === "off_track" ? value : void 0;
72
- }
73
- function milestoneStatus(value) {
74
- return value === "planned" || value === "active" || value === "completed" || value === "cancelled" ? value : void 0;
75
- }
76
63
  function resolveEffectiveWorkspaceRoot(service, project) {
77
64
  const fixedRoot = project.workspaceRoot?.trim();
78
65
  if (fixedRoot) return fixedRoot;
@@ -146,113 +133,82 @@ function buildProjectDigestKnowledgeContent(input) {
146
133
  }
147
134
  function registerProjectsRoutes(authenticated, deps) {
148
135
  const { service } = deps;
136
+ const capabilities = createProductDispatcher(void 0, {
137
+ getProjects: () => service.projects,
138
+ getConfig: () => service.currentConfig,
139
+ getWorkDiscovery: () => service.workDiscovery
140
+ });
141
+ const invokeWrite = (c, operation, input) => {
142
+ const caller = capabilityHttpContext(c);
143
+ return capabilities.call(operation, input, caller, {
144
+ ...capabilities.describe(operation, caller),
145
+ idempotencyKey: c.req.header("idempotency-key") ?? randomUUID()
146
+ });
147
+ };
148
+ const readBody = async (c) => {
149
+ const body = await c.req.json().catch(() => {
150
+ throw new CapabilityError("INVALID_INPUT", "Invalid JSON body");
151
+ });
152
+ if (!body || typeof body !== "object" || Array.isArray(body)) throw new CapabilityError("INVALID_INPUT", "Expected an object");
153
+ return body;
154
+ };
155
+ const readOptionalBody = async (c) => {
156
+ const text = await c.req.text();
157
+ if (!text.length) return {};
158
+ let body;
159
+ try {
160
+ body = JSON.parse(text);
161
+ } catch {
162
+ throw new CapabilityError("INVALID_INPUT", "Invalid JSON body");
163
+ }
164
+ if (!body || typeof body !== "object" || Array.isArray(body)) throw new CapabilityError("INVALID_INPUT", "Expected an object");
165
+ return body;
166
+ };
167
+ const milestoneRevision = (c, revision) => {
168
+ if (revision !== void 0) return revision;
169
+ if (c.req.header("idempotency-key")) throw new CapabilityError("INVALID_INPUT", "Stable retries require the original expectedRevision");
170
+ const milestone = service.projects.listMilestones(c.req.param("id")).find((item) => item.id === c.req.param("milestoneId"));
171
+ if (!milestone) throw new CapabilityError("NOT_FOUND", "Milestone not found");
172
+ return milestone.updatedAt;
173
+ };
149
174
  const activity = new ActivityService();
150
175
  const operatingViews = new ProjectOperatingViewService(service.projects);
151
- const environments = new ExecutionEnvironmentStore();
152
176
  authenticated.post("/api/projects", async (c) => {
153
- const body = await c.req.json().catch(() => ({}));
154
- const name = textField(body, "name")?.trim();
155
- const workspaceRoot = textField(body, "workspaceRoot")?.trim();
156
- if (body.autoUnderstand !== void 0 && typeof body.autoUnderstand !== "boolean") return c.json({
157
- ok: false,
158
- error: "autoUnderstand must be a boolean"
159
- }, 400);
160
- if (!name && !workspaceRoot) return c.json({
161
- ok: false,
162
- error: "Missing name"
163
- }, 400);
164
- const executionMode = parseProjectExecutionMode(body.executionMode);
165
- if (body.executionMode !== void 0 && !executionMode) return c.json({
166
- ok: false,
167
- error: "Invalid project execution mode"
168
- }, 400);
169
- const hasDefaultAgentPatch = Object.hasOwn(body, "defaultAgentId");
170
- const explicitDefaultAgentId = normalizeProjectAgentId(textField(body, "defaultAgentId"));
171
- const defaultAgentId = hasDefaultAgentPatch ? explicitDefaultAgentId : inferSuggestedProjectDefaultAgentId({
172
- config: service.currentConfig,
173
- name,
174
- description: textField(body, "description"),
175
- workspaceRoot,
176
- projectKind: textField(body, "projectKind")
177
- });
178
- if (!isValidProjectAgentId(service.currentConfig, defaultAgentId)) return c.json({
179
- ok: false,
180
- error: "Default agent not found"
181
- }, 400);
182
177
  try {
183
- const project = service.projects.create({
184
- name,
185
- description: textField(body, "description"),
186
- defaultAgentId,
187
- workspaceRoot,
188
- createWorkspaceRoot: body.createWorkspaceRoot === true,
189
- projectKind: textField(body, "projectKind"),
190
- executionMode,
191
- brief: textField(body, "brief"),
192
- instructions: textField(body, "instructions"),
193
- outcome: textField(body, "outcome"),
194
- successCriteria: stringListField(body, "successCriteria"),
195
- scope: objectField(body, "scope"),
196
- nonGoals: stringListField(body, "nonGoals"),
197
- health: projectHealth(body.health),
198
- ownerId: textField(body, "ownerId"),
199
- targetAt: optionalNumberField(body, "targetAt") ?? void 0
200
- });
201
- if (body.autoUnderstand === true) try {
202
- deps.service.workDiscovery.startProjectUnderstanding(project.id);
203
- } catch (err) {
204
- log.warn({
205
- err,
206
- projectId: project.id
207
- }, "Project created but understanding could not be queued");
208
- }
178
+ const { project } = ProjectMutationOutputSchema.parse(await invokeWrite(c, "xopc.projects.create", await readBody(c)));
209
179
  return c.json({
210
180
  ok: true,
211
181
  project: enrichProjectWorkspace(service, project)
212
182
  }, 201);
213
183
  } catch (error) {
214
- if (error instanceof ProjectWorkspaceConflictError) return c.json({
215
- ok: false,
216
- code: "workspace_already_bound",
217
- error: error.message,
218
- project: error.project
219
- }, 409);
220
- if (error instanceof ProjectWorkspaceMissingError) return c.json({
221
- ok: false,
222
- code: "workspace_root_missing",
223
- error: error.message,
224
- workspaceRoot: error.workspaceRoot
225
- }, 409);
226
- return c.json({
227
- ok: false,
228
- error: error instanceof Error ? error.message : String(error)
229
- }, 400);
184
+ return projectWriteError(c, error);
230
185
  }
231
186
  });
232
187
  authenticated.get("/api/projects", async (c) => {
233
- const status = parseProjectStatus(c.req.query("status"));
234
- const result = service.projects.list({
235
- ...status ? { status } : {},
236
- search: c.req.query("search"),
237
- sortBy: c.req.query("sortBy"),
238
- sortOrder: c.req.query("sortOrder"),
239
- limit: parseLimit(c.req.query("limit")),
240
- offset: c.req.query("offset") ? Math.max(0, Number.parseInt(c.req.query("offset"), 10) || 0) : void 0
241
- });
242
- const includeOperating = c.req.query("includeOperating") === "true";
243
- return c.json({
244
- ok: true,
245
- ...result,
246
- items: result.items.map((project) => {
247
- const enriched = enrichProjectWorkspace(service, project);
248
- if (!includeOperating) return enriched;
249
- const view = operatingViews.get(project.id);
250
- return {
251
- ...enriched,
252
- operating: view ? summarizeProjectOperatingView(view) : void 0
253
- };
254
- })
255
- });
188
+ try {
189
+ const { includeOperating: _includeOperating, ...input } = c.req.query();
190
+ const result = ProductReadContracts["xopc.projects.list"].output.parse(await capabilities.call("xopc.projects.list", {
191
+ ...input,
192
+ limit: input.limit === void 0 ? void 0 : Number(input.limit),
193
+ offset: input.offset === void 0 ? void 0 : Number(input.offset)
194
+ }, capabilityHttpContext(c)));
195
+ const includeOperating = c.req.query("includeOperating") === "true";
196
+ return c.json({
197
+ ok: true,
198
+ ...result,
199
+ items: result.items.map((project) => {
200
+ const enriched = enrichProjectWorkspace(service, project);
201
+ if (!includeOperating) return enriched;
202
+ const view = operatingViews.get(project.id);
203
+ return {
204
+ ...enriched,
205
+ operating: view ? summarizeProjectOperatingView(view) : void 0
206
+ };
207
+ })
208
+ });
209
+ } catch (error) {
210
+ return capabilityHttpError(c, error);
211
+ }
256
212
  });
257
213
  authenticated.get("/api/projects/suggestions", async (c) => {
258
214
  const conversationId = c.req.query("conversationId")?.trim();
@@ -283,61 +239,16 @@ function registerProjectsRoutes(authenticated, deps) {
283
239
  });
284
240
  });
285
241
  authenticated.post("/api/projects/resolve-workspace", async (c) => {
286
- const body = await c.req.json().catch(() => ({}));
287
- const workspacePath = textField(body, "workspacePath")?.trim();
288
- if (!workspacePath) return c.json({
289
- ok: false,
290
- error: "Missing workspacePath"
291
- }, 400);
292
- const agentId = textField(body, "agentId")?.trim() || "main";
293
- const suggestedDefaultAgentId = inferSuggestedProjectDefaultAgentId({
294
- config: service.currentConfig,
295
- workspaceRoot: workspacePath,
296
- projectKind: textField(body, "projectKind")
297
- });
298
- let match;
299
242
  try {
300
- match = service.projects.resolveOrCreateForWorkspacePath({
301
- workspacePath,
302
- agentId,
303
- defaultAgentId: suggestedDefaultAgentId,
304
- autoCreate: body.autoCreate !== false
305
- });
243
+ const body = await readBody(c);
244
+ return c.json(ProjectResolveWorkspaceOutputSchema.parse(await invokeWrite(c, "xopc.projects.resolve_workspace", {
245
+ ...body,
246
+ agentId: body.agentId ?? "main",
247
+ autoCreate: body.autoCreate ?? true
248
+ })));
306
249
  } catch (error) {
307
- if (error instanceof ProjectWorkspaceConflictError) match = {
308
- project: error.project,
309
- reason: "exact",
310
- created: false
311
- };
312
- else throw error;
250
+ return projectWriteError(c, error);
313
251
  }
314
- if (!match) return c.json({
315
- ok: true,
316
- project: null
317
- });
318
- const conversationId = textField(body, "conversationId")?.trim();
319
- const projectDefaultAgentId = normalizeProjectAgentId(match.project.defaultAgentId);
320
- const shouldBindRequestedSession = !projectDefaultAgentId || projectDefaultAgentId === normalizeProjectAgentId(agentId);
321
- if (conversationId && shouldBindRequestedSession) {
322
- if (!getSessionMetadata(conversationId)) await service.sessionIndexInstance.saveMessages(conversationId, [], { metadata: {
323
- sourceChannel: "tui",
324
- sourceChatId: `default:direct:${conversationId}`,
325
- sessionType: "chat",
326
- projectId: match.project.id,
327
- routing: {
328
- agentId,
329
- source: "tui",
330
- accountId: "default",
331
- peerKind: "direct",
332
- peerId: conversationId
333
- }
334
- } });
335
- service.projects.attachSession(conversationId, match.project.id);
336
- }
337
- return c.json({
338
- ok: true,
339
- ...match
340
- });
341
252
  });
342
253
  authenticated.get("/api/projects/:id/activity", (c) => {
343
254
  const project = service.projects.get(c.req.param("id"));
@@ -474,245 +385,177 @@ function registerProjectsRoutes(authenticated, deps) {
474
385
  blocker: blocked.ok ? blocked.model : created.model
475
386
  }, 201);
476
387
  });
477
- authenticated.post("/api/projects/:id/pin", async (c) => {
388
+ for (const [action, pinned] of [["pin", true], ["unpin", false]]) authenticated.post(`/api/projects/:id/${action}`, async (c) => {
478
389
  try {
479
- const project = service.projects.pin(c.req.param("id"));
390
+ const body = await readOptionalBody(c);
391
+ if (Object.keys(body).some((key) => key !== "expectedVersion")) throw new CapabilityError("INVALID_INPUT", "Unexpected pin input");
392
+ if (body.expectedVersion === void 0 && c.req.header("idempotency-key")) throw new CapabilityError("INVALID_INPUT", "Stable retries require the original expectedVersion");
393
+ const id = c.req.param("id");
394
+ const project = body.expectedVersion === void 0 ? service.projects.get(id) : void 0;
395
+ if (body.expectedVersion === void 0 && !project) throw new CapabilityError("NOT_FOUND", "Project not found");
396
+ const result = ProjectMutationOutputSchema.parse(await invokeWrite(c, "xopc.projects.set_pinned", {
397
+ id,
398
+ pinned,
399
+ expectedVersion: body.expectedVersion ?? project?.version
400
+ }));
480
401
  return c.json({
481
402
  ok: true,
482
- project: enrichProjectWorkspace(service, project)
403
+ project: enrichProjectWorkspace(service, result.project)
483
404
  });
484
405
  } catch (error) {
485
- return c.json({
486
- ok: false,
487
- error: error instanceof Error ? error.message : String(error)
488
- }, 404);
406
+ return capabilityHttpError(c, error);
489
407
  }
490
408
  });
491
- authenticated.post("/api/projects/:id/unpin", async (c) => {
409
+ authenticated.get("/api/projects/:id", async (c) => {
492
410
  try {
493
- const project = service.projects.unpin(c.req.param("id"));
411
+ const { project } = ProductReadContracts["xopc.projects.get"].output.parse(await capabilities.call("xopc.projects.get", { id: c.req.param("id") }, capabilityHttpContext(c)));
494
412
  return c.json({
495
413
  ok: true,
496
414
  project: enrichProjectWorkspace(service, project)
497
415
  });
498
416
  } catch (error) {
499
- return c.json({
500
- ok: false,
501
- error: error instanceof Error ? error.message : String(error)
502
- }, 404);
417
+ return capabilityHttpError(c, error);
503
418
  }
504
419
  });
505
- authenticated.get("/api/projects/:id", async (c) => {
506
- const project = service.projects.getWithDetails(c.req.param("id"));
507
- if (!project) return c.json({
508
- ok: false,
509
- error: "Project not found"
510
- }, 404);
511
- return c.json({
512
- ok: true,
513
- project: enrichProjectWorkspace(service, project)
514
- });
515
- });
516
- authenticated.get("/api/projects/:id/milestones", (c) => {
517
- const project = service.projects.get(c.req.param("id"));
518
- if (!project) return c.json({
519
- ok: false,
520
- error: "Project not found"
521
- }, 404);
522
- return c.json({
523
- ok: true,
524
- items: service.projects.listMilestones(project.id)
525
- });
420
+ authenticated.get("/api/projects/:id/milestones", async (c) => {
421
+ try {
422
+ const { items } = ProductReadContracts["xopc.projects.list_milestones"].output.parse(await capabilities.call("xopc.projects.list_milestones", { id: c.req.param("id") }, capabilityHttpContext(c)));
423
+ return c.json({
424
+ ok: true,
425
+ items
426
+ });
427
+ } catch (error) {
428
+ return capabilityHttpError(c, error);
429
+ }
526
430
  });
527
431
  authenticated.post("/api/projects/:id/milestones", async (c) => {
528
- const body = await c.req.json().catch(() => ({}));
529
- const title = textField(body, "title")?.trim();
530
- if (!title) return c.json({
531
- ok: false,
532
- error: "Missing title"
533
- }, 400);
534
- if (body.status !== void 0 && !milestoneStatus(body.status)) return c.json({
535
- ok: false,
536
- error: "Invalid milestone status"
537
- }, 400);
538
432
  try {
539
- const milestone = service.projects.createMilestone(c.req.param("id"), {
540
- title,
541
- description: textField(body, "description"),
542
- status: milestoneStatus(body.status),
543
- targetAt: optionalNumberField(body, "targetAt") ?? void 0,
544
- sortOrder: optionalNumberField(body, "sortOrder") ?? void 0
545
- });
433
+ const body = await readBody(c);
434
+ const { milestone } = ProjectMilestoneOutputSchema.parse(await invokeWrite(c, "xopc.projects.create_milestone", {
435
+ ...body,
436
+ projectId: c.req.param("id")
437
+ }));
546
438
  return c.json({
547
439
  ok: true,
548
440
  milestone
549
441
  }, 201);
550
442
  } catch (error) {
551
- return c.json({
552
- ok: false,
553
- error: error instanceof Error ? error.message : String(error)
554
- }, 400);
443
+ return capabilityHttpError(c, error);
555
444
  }
556
445
  });
557
446
  authenticated.patch("/api/projects/:id/milestones/:milestoneId", async (c) => {
558
- const body = await c.req.json().catch(() => ({}));
559
- if (body.status !== void 0 && !milestoneStatus(body.status)) return c.json({
560
- ok: false,
561
- error: "Invalid milestone status"
562
- }, 400);
563
447
  try {
564
- const milestone = service.projects.updateMilestone(c.req.param("id"), c.req.param("milestoneId"), {
565
- ...textField(body, "title") !== void 0 ? { title: textField(body, "title") } : {},
566
- ...optionalTextField(body, "description") !== void 0 ? { description: optionalTextField(body, "description") } : {},
567
- ...body.status !== void 0 ? { status: milestoneStatus(body.status) } : {},
568
- ...body.targetAt !== void 0 ? { targetAt: optionalNumberField(body, "targetAt") } : {},
569
- ...body.sortOrder !== void 0 ? { sortOrder: optionalNumberField(body, "sortOrder") } : {}
570
- });
448
+ const { expectedRevision, ...patch } = await readBody(c);
449
+ const { milestone } = ProjectMilestoneOutputSchema.parse(await invokeWrite(c, "xopc.projects.update_milestone", {
450
+ projectId: c.req.param("id"),
451
+ id: c.req.param("milestoneId"),
452
+ expectedRevision: milestoneRevision(c, expectedRevision),
453
+ patch
454
+ }));
571
455
  return c.json({
572
456
  ok: true,
573
457
  milestone
574
458
  });
575
459
  } catch (error) {
576
- return c.json({
577
- ok: false,
578
- error: error instanceof Error ? error.message : String(error)
579
- }, 404);
460
+ return capabilityHttpError(c, error);
580
461
  }
581
462
  });
582
- authenticated.delete("/api/projects/:id/milestones/:milestoneId", (c) => {
583
- return service.projects.deleteMilestone(c.req.param("id"), c.req.param("milestoneId")) ? c.json({ ok: true }) : c.json({
584
- ok: false,
585
- error: "Milestone not found"
586
- }, 404);
463
+ authenticated.delete("/api/projects/:id/milestones/:milestoneId", async (c) => {
464
+ try {
465
+ const raw = await c.req.text();
466
+ let body = {};
467
+ if (raw) {
468
+ try {
469
+ body = JSON.parse(raw);
470
+ } catch {
471
+ throw new CapabilityError("INVALID_INPUT", "Invalid JSON body");
472
+ }
473
+ if (!body || typeof body !== "object" || Array.isArray(body)) throw new CapabilityError("INVALID_INPUT", "Expected an object");
474
+ }
475
+ ProjectMilestoneDeleteOutputSchema.parse(await invokeWrite(c, "xopc.projects.delete_milestone", {
476
+ projectId: c.req.param("id"),
477
+ id: c.req.param("milestoneId"),
478
+ expectedRevision: milestoneRevision(c, body.expectedRevision)
479
+ }));
480
+ return c.json({ ok: true });
481
+ } catch (error) {
482
+ return capabilityHttpError(c, error);
483
+ }
587
484
  });
588
- authenticated.get("/api/projects/:id/updates", (c) => {
589
- const project = service.projects.get(c.req.param("id"));
590
- if (!project) return c.json({
591
- ok: false,
592
- error: "Project not found"
593
- }, 404);
594
- return c.json({
595
- ok: true,
596
- items: service.projects.listUpdates(project.id, parseLimit(c.req.query("limit"), 20))
597
- });
485
+ authenticated.get("/api/projects/:id/updates", async (c) => {
486
+ try {
487
+ const { items } = ProductReadContracts["xopc.projects.list_updates"].output.parse(await capabilities.call("xopc.projects.list_updates", {
488
+ id: c.req.param("id"),
489
+ limit: c.req.query("limit") === void 0 ? void 0 : Number(c.req.query("limit"))
490
+ }, capabilityHttpContext(c)));
491
+ return c.json({
492
+ ok: true,
493
+ items
494
+ });
495
+ } catch (error) {
496
+ return capabilityHttpError(c, error);
497
+ }
598
498
  });
599
499
  authenticated.post("/api/projects/:id/updates", async (c) => {
600
- const body = await c.req.json().catch(() => ({}));
601
- const summary = textField(body, "summary")?.trim();
602
- const health = projectHealth(body.health);
603
- if (!summary || !health) return c.json({
604
- ok: false,
605
- error: "Missing summary or valid health"
606
- }, 400);
607
500
  try {
608
- const update = service.projects.createUpdate(c.req.param("id"), {
609
- health,
610
- summary,
611
- progress: stringListField(body, "progress"),
612
- risks: stringListField(body, "risks"),
613
- nextSteps: stringListField(body, "nextSteps"),
614
- actor: objectField(body, "actor") ?? { kind: "user" }
615
- });
501
+ const body = await readBody(c);
502
+ if (c.req.header("idempotency-key") && body.expectedVersion === void 0) throw new CapabilityError("INVALID_INPUT", "Stable retries require the original expectedVersion");
503
+ const project = service.projects.get(c.req.param("id"));
504
+ if (!project && body.expectedVersion === void 0) throw new CapabilityError("NOT_FOUND", "Project not found");
505
+ const { update } = ProjectUpdateOutputSchema.parse(await invokeWrite(c, "xopc.projects.create_update", {
506
+ ...body,
507
+ projectId: c.req.param("id"),
508
+ expectedVersion: body.expectedVersion === void 0 ? project?.version : body.expectedVersion
509
+ }));
616
510
  return c.json({
617
511
  ok: true,
618
512
  update
619
513
  }, 201);
620
514
  } catch (error) {
621
- return c.json({
622
- ok: false,
623
- error: error instanceof Error ? error.message : String(error)
624
- }, 400);
515
+ return capabilityHttpError(c, error);
625
516
  }
626
517
  });
627
518
  authenticated.patch("/api/projects/:id", async (c) => {
628
- const body = await c.req.json().catch(() => ({}));
629
- const projectId = c.req.param("id");
630
- const status = parseProjectStatus(body.status);
631
- const defaultAgentPatch = optionalTextField(body, "defaultAgentId");
632
- const defaultAgentId = defaultAgentPatch === void 0 ? void 0 : normalizeProjectAgentId(defaultAgentPatch);
633
- if (body.status !== void 0 && !status) return c.json({
634
- ok: false,
635
- error: "Invalid project status"
636
- }, 400);
637
- if (body.health !== void 0 && !projectHealth(body.health)) return c.json({
638
- ok: false,
639
- error: "Invalid project health"
640
- }, 400);
641
- const executionMode = parseProjectExecutionMode(body.executionMode);
642
- if (body.executionMode !== void 0 && !executionMode) return c.json({
643
- ok: false,
644
- error: "Invalid project execution mode"
645
- }, 400);
646
- if (defaultAgentId && !isValidProjectAgentId(service.currentConfig, defaultAgentId)) return c.json({
647
- ok: false,
648
- error: "Default agent not found"
649
- }, 400);
650
- const currentProject = service.projects.get(projectId);
651
- const requestedWorkspaceRoot = optionalTextField(body, "workspaceRoot");
652
- if (currentProject && requestedWorkspaceRoot !== void 0 && requestedWorkspaceRoot !== (currentProject.workspaceRoot ?? null) && environments.list({
653
- projectId,
654
- limit: 1
655
- }).length > 0) return c.json({
656
- ok: false,
657
- code: "execution_environments_exist",
658
- error: "Delete the project execution environments before changing its workspace"
659
- }, 409);
660
519
  try {
661
- const project = service.projects.update(projectId, {
662
- ...textField(body, "name") !== void 0 ? { name: textField(body, "name") } : {},
663
- ...optionalTextField(body, "description") !== void 0 ? { description: optionalTextField(body, "description") } : {},
664
- ...status ? { status } : {},
665
- ...defaultAgentPatch !== void 0 ? { defaultAgentId: defaultAgentId ?? null } : {},
666
- ...optionalTextField(body, "workspaceRoot") !== void 0 ? { workspaceRoot: optionalTextField(body, "workspaceRoot") } : {},
667
- createWorkspaceRoot: body.createWorkspaceRoot === true,
668
- ...executionMode ? { executionMode } : {},
669
- ...optionalTextField(body, "brief") !== void 0 ? { brief: optionalTextField(body, "brief") } : {},
670
- ...optionalTextField(body, "instructions") !== void 0 ? { instructions: optionalTextField(body, "instructions") } : {},
671
- ...optionalTextField(body, "outcome") !== void 0 ? { outcome: optionalTextField(body, "outcome") } : {},
672
- ...body.successCriteria !== void 0 ? { successCriteria: stringListField(body, "successCriteria") } : {},
673
- ...body.scope !== void 0 ? { scope: objectField(body, "scope") } : {},
674
- ...body.nonGoals !== void 0 ? { nonGoals: stringListField(body, "nonGoals") } : {},
675
- ...body.health !== void 0 ? { health: projectHealth(body.health) } : {},
676
- ...optionalTextField(body, "ownerId") !== void 0 ? { ownerId: optionalTextField(body, "ownerId") } : {},
677
- ...body.targetAt !== void 0 ? { targetAt: optionalNumberField(body, "targetAt") } : {}
678
- });
520
+ const { expectedVersion, ...patch } = await readBody(c);
521
+ if (expectedVersion === void 0 && c.req.header("idempotency-key")) throw new CapabilityError("INVALID_INPUT", "Stable retries require the original expectedVersion");
522
+ const id = c.req.param("id");
523
+ const current = expectedVersion === void 0 ? service.projects.get(id) : void 0;
524
+ if (expectedVersion === void 0 && !current) throw new CapabilityError("NOT_FOUND", "Project not found");
525
+ const { project } = ProjectMutationOutputSchema.parse(await invokeWrite(c, "xopc.projects.update", {
526
+ id,
527
+ expectedVersion: expectedVersion === void 0 ? current?.version : expectedVersion,
528
+ patch
529
+ }));
679
530
  return c.json({
680
531
  ok: true,
681
532
  project: enrichProjectWorkspace(service, project)
682
533
  });
683
534
  } catch (error) {
684
- if (error instanceof ProjectWorkspaceConflictError) return c.json({
685
- ok: false,
686
- code: "workspace_already_bound",
687
- error: error.message,
688
- project: error.project
689
- }, 409);
690
- if (error instanceof ProjectWorkspaceMissingError) return c.json({
691
- ok: false,
692
- code: "workspace_root_missing",
693
- error: error.message,
694
- workspaceRoot: error.workspaceRoot
695
- }, 409);
696
- return c.json({
697
- ok: false,
698
- error: error instanceof Error ? error.message : String(error)
699
- }, 404);
535
+ return projectWriteError(c, error);
700
536
  }
701
537
  });
702
538
  authenticated.delete("/api/projects/:id", async (c) => {
703
- const projectId = c.req.param("id");
704
- if (environments.list({
705
- projectId,
706
- limit: 1
707
- }).length > 0) return c.json({
708
- ok: false,
709
- code: "execution_environments_exist",
710
- error: "Delete the project execution environments before deleting the project"
711
- }, 409);
712
- const understandingRun = getProjectUnderstandingRun(projectId);
713
- if (understandingRun) deps.service.workDiscovery.cancelRun(understandingRun.id);
714
- service.projects.delete(projectId);
715
- return c.json({ ok: true });
539
+ try {
540
+ const body = await readOptionalBody(c);
541
+ if (Object.keys(body).some((key) => key !== "expectedVersion")) throw new CapabilityError("INVALID_INPUT", "Unexpected delete input");
542
+ if (body.expectedVersion === void 0 && c.req.header("idempotency-key")) throw new CapabilityError("INVALID_INPUT", "Stable retries require the original expectedVersion");
543
+ const id = c.req.param("id");
544
+ const project = body.expectedVersion === void 0 ? service.projects.get(id) : void 0;
545
+ if (body.expectedVersion === void 0 && !project) throw new CapabilityError("NOT_FOUND", "Project not found");
546
+ const result = ProjectDeleteOutputSchema.parse(await invokeWrite(c, "xopc.projects.delete", {
547
+ id,
548
+ expectedVersion: body.expectedVersion === void 0 ? project?.version : body.expectedVersion
549
+ }));
550
+ return c.json(result);
551
+ } catch (error) {
552
+ if (error instanceof CapabilityError && error.cause instanceof ProjectDeletionBlockedError) return c.json({
553
+ ok: false,
554
+ code: "execution_environments_exist",
555
+ error: error.message
556
+ }, 409);
557
+ return capabilityHttpError(c, error);
558
+ }
716
559
  });
717
560
  authenticated.get("/api/projects/:id/sessions", async (c) => {
718
561
  try {