chainlesschain 0.163.7 → 0.163.8

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 (181) hide show
  1. package/package.json +2 -1
  2. package/src/assets/web-panel/assets/{AIOps-axqQfwv8.js → AIOps-CavM7W3k.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-DV-Ro0By.js → ActionButton-CUvZGabQ.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-Bt72WEVu.js → Analytics-DeBnWnbe.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-BtepG55E.js → AppLayout-DbI5kxvd.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-B7KaJ7S_.js → Artifacts-D93bigKm.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-FNFaUg7A.js → Audit-CBNvfUZa.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-DFb6J2wQ.js → BackgroundAgents-CJLyh_YU.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-CC7YBhyj.js → Backup-D_0yoehD.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-RkgTNVtj.js → BaseInput-TJxmbObW.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-hHEmGZy-.js → Chat-CE0dto1q.js} +5 -5
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CAP9YhHv.js → ChatBubbleRenderer-CZ5-yYiD.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-z5wXOQP1.js → Checkbox-Ck1RVIVo.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DVaDJnxy.js → Codegen-qpoyf6DK.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-CJmaRDR5.js → Col-DUyPWjIE.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DF29_2bI.js → Community-D_S1BemS.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-DtkQkBzn.js → Compact-BjxeK-Gc.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-xoHDxp7I.js → Compliance-Dd3CEJsu.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-BUm-R7ht.js → Cowork-B4QG7-ad.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-Cgl14ZkB.js → Cron-BtZnids5.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BNcbmoqh.js → Crosschain-CHPfCBFD.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-Bwja0Zo9.js → DID-DT8DCEOK.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-Bk5XjEdJ.js → Dashboard-COQab5_U.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-Ci36Oitq.js → Dropdown-BY1PsQuU.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer--U04ZN4q.js → EmailListRenderer-CsuAuaq3.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2gNPR2s.js → FamilyGuardDashboard-BqpinD-j.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-C4KghYn7.js → Federation-D0gkfQFv.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-QL7x_Q_0.js → FormItemContext-BqgE-axK.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-F3Ryltwm.js → GenericCardRenderer-D0hJ2KvC.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-2HassK5k.js → Git-CmMB0uPY.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-DoBIp7oe.js → Governance-BnVEI0Dk.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference--W01QhZ-.js → Inference-YTAMihRP.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DmvwqGpT.js → KnowledgeGraph-0ax7VHop.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-BBJ4yAel.js → Logs-B9TRcokL.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-yySN5YNM.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-D5lNngSI.js → Marketplace-B6CSuD_H.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-CkEVOMKH.js → McpTools-CjMXvOVU.js} +4 -4
  38. package/src/assets/web-panel/assets/{Memory-B1Ow1xVE.js → Memory-CXRF71U3.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-SgYbUfb6.js → MobileBridge-DQgNp_oS.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-BWdOvQAj.js → MobileProjects-DlPwcCbq.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-DcTXSSma.js → Mtc-6hDTRPe1.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-Dt3WG4oj.js → MtcAudit-BlVHU1DS.js} +2 -2
  43. package/src/assets/web-panel/assets/{Multisig-B9B38UZx.js → Multisig-DP9pzEbV.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-B0S4GGvG.js → NLProgramming-Djorh8EV.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-DZ5U58Ng.js → Notes-oLZ-JkUg.js} +4 -4
  46. package/src/assets/web-panel/assets/{NotificationSettings-PjL5ZW34.js → NotificationSettings-Cg288VH3.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DrAX2ESt.js → OrderTableRenderer-Bb1O3Ofr.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-Cv1GYs-c.js → Organization-CBdo-bHs.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Bbkp_PL3.js → Overflow-qZdnVumx.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-BD8QUgoZ.js → P2P-D4kNfGNQ.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-BO-2PeaB.js → PdhVaultBrowser-DnlMemM7.js} +5 -5
  52. package/src/assets/web-panel/assets/{Permissions-D_OPVa02.js → Permissions-DHucHFBJ.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-mh-pEmaB.js → PersonalDataHub-BovlOIPR.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-6JC2EDdb.js → Pipeline-Deru3CQY.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-CUshzUAG.js → Privacy-Bq5oTTbU.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-Cs2Aalri.js → ProjectInit-BfzxVWAz.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-1ak49tcj.js → ProjectSettings-CKC6XBtH.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-BV4oApsm.js → Projects-CMolGhae.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-CXXxvafH.js → Providers-C_jx4TWX.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-PTcDsF58.js → QrScannerModal-BdIHeVGC.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-CDwucrJw.js → QuickAsk-BwZwAcPD.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-CJlLVRXR.js → Recommend-BNTt0L-m.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-DlN-ETsO.js → RemoteSession-Biyn2-Ro.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-DI23LR6m.js → Reputation-D6VpG32B.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-Cl7UQMrM.js → Row-D_74OvQQ.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-CexHNfh8.js → RssFeed-BTr0a-BQ.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-BneBWvRN.js → Search-C3MCFoNU.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-DX7Phgrp.js → Security-CqW9aJ6s.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-BWXO8Mte.js → Services-Cw5GNaHF.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-DCyOjKPJ.js → Skeleton-DZps5qeY.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CXqERsTB.js → Skills-C6NQ1znT.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-bhbrbz8E.js → Sla-DFP8G2Sh.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-3IPU0HBZ.js → SpeechSettings-ESt6MB6v.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-DBNTQLbM.js → SyncSettings-BHnN98aM.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-quP0bkN-.js → Tasks-NiSCaOf-.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-BouWmgho.js → Templates-DsKFhW2C.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-qv0D9s7z.js → Tenant-CQ0E0ze5.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-BxvbE8BB.js → Terminal-D_rBu_by.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-D-IeLnJ2.js → TimelineRenderer-D3Vm4Po4.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-CFMKKyVG.js → Tokens-DNTxRH6q.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-L8as3UuJ.js → Trigger-Dgprz1ms.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-MxmA4VZG.js → Trust-B2rUnVBD.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-C0VvJYRi.js → UkeySign-DEGQNc6_.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-Bf5QZj8N.js → VideoEditing-jlsAx3Eh.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-BIJ9riRz.js → Wallet-8jQih1ij.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-B8p9Mhkw.js → WebAuthn-XLeO6xIB.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-BVsuaPen.js → WorkflowEditor-De_dgDAG.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BfkjoKpV.js → chat-CI19R_Sk.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DeAlsWK8.js → colors-DsYTOYN3.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-Cs97bz5j.js → compact-item-CM3-t_Qr.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-BqbG60LH.js → createContext-BjxlBRZv.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-S1ld2LwU.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-i_RY0b1X.js → hasIn-RDaWX_4i.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-U4f5izHz.js → index-9R6BxAr0.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-0-agYlWL.js → index-B-Z8eFUJ.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-B1CbOH1i.js → index-B0PMlbMs.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DqBgBpgp.js → index-B5REnKt8.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BcUXAB2s.js → index-B7WBt_4T.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CIG8fQ2_.js → index-B9O9YyWE.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-gyFpvL7l.js → index-BCnZyIMA.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-yObj1O4n.js → index-BGqqJfL0.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DiSkx4UB.js → index-BHNYPO0b.js} +3 -3
  103. package/src/assets/web-panel/assets/{index-Bm7lLR4c.js → index-BKJr-TZp.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BOVkf1K3.js → index-BN6UPD2E.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BESLFt4q.js → index-Bi46Xu4u.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CE2VtTlp.js → index-BlT2VAEK.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DmbfhJUP.js → index-C0yx-jtQ.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BYUVuwKt.js → index-C4gkzxkw.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CeWoNHau.js → index-CVQMeiwH.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-PT_5sBMA.js → index-Cd3euP_4.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CgsqdnRV.js → index-Cd9OJhHG.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-B-3tEpTc.js → index-CiECJi-Q.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BkBi5TmC.js → index-CjTrRt13.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-D2B4VPyP.js → index-CnHH7bnD.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-dIHr4B_u.js → index-Cpqm1qfU.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B5UkyA3c.js → index-CyOGN6a5.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Dk7-v4hP.js → index-D0zcy54x.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-ZxO_-E8a.js → index-D6sm5-Xq.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-B-JVTrpr.js → index-DIUnNOjG.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Dk2qouAz.js → index-DX7tuWVJ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BuLQobzW.js → index-DXXtGMUJ.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DUUrv141.js → index-DcPFB8qJ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-D9evtvg2.js → index-DoQA0-52.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-COdGA-8n.js → index-Drlnwr8F.js} +1 -1
  125. package/src/assets/web-panel/assets/index-Drz6yq0m.js +1 -0
  126. package/src/assets/web-panel/assets/{index-CED2PL_y.js → index-Dsij_KsN.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-79V_zv1s.js → index-Dxge-xWl.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CG3PRyAL.js → index-DyIWssPC.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-YXgLng0K.js → index-IeiL9RKc.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-s1opAL-M.js → index-nAH87mQP.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Cf3WCLmy.js → index-pPL66J85.js} +1 -1
  132. package/src/assets/web-panel/assets/index-uWiUs7S_.js +1 -0
  133. package/src/assets/web-panel/assets/{initDefaultProps-C9h9yKL3.js → initDefaultProps-BTL88of4.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BvmLsPdu.js → motion-BUB2pXwB.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-CoL4ekU1.js → move-egCkkOMm.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-C4pMy6xV.js → mtc-parser-DAWhZC8c.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-DPuJfNxx.js → omit-CvOxe_6d.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-D0KEeaK2.js → pickAttrs-DZUSLZ5Z.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BpkyINxt.js → placementArrow-BERxGNMY.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-DQI_wOq8.js → responsiveObserve-DZuDfZ9n.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-DYfdDiRg.js → slide-DO756sgI.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-B5dtvb0D.js → statusUtils-BRQlIz28.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-CF310mSj.js → styleChecker-DCSfdybl.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-D1Qp4BLp.js → useFlexGapSupport-LD8dWVve.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-C7_iyvJK.js → useFs-BX9uW2LK.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-DZUt_fIm.js → usePersonalDataHub-BPSlPuHU.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-D3dsi0lZ.js → vnode-BmOILC9V.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-WdbOlvdQ.js → zoom-1iKowKGg.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +3 -3
  151. package/src/commands/automation.js +103 -1
  152. package/src/commands/team-merge-review.js +937 -0
  153. package/src/commands/team.js +2 -0
  154. package/src/data/changelog.json +14 -1
  155. package/src/lib/agent-schedule-store.js +139 -28
  156. package/src/lib/agent-team/team-merge-review-store.js +765 -0
  157. package/src/lib/agent-team/team-merge-review-transaction.js +1223 -0
  158. package/src/lib/agent-team/team-merge-review.js +1847 -0
  159. package/src/lib/automation-center-incidents.js +314 -0
  160. package/src/lib/automation-center-runtime.js +448 -0
  161. package/src/lib/automation-center.js +182 -38
  162. package/src/lib/automation-engine.js +41 -0
  163. package/src/lib/automation-execution-authority.js +241 -12
  164. package/src/lib/automation-execution-incident.js +737 -0
  165. package/src/lib/cowork-cron.js +85 -14
  166. package/src/lib/scheduler-kernel/agenda-adapter.js +17 -7
  167. package/src/lib/scheduler-kernel/automation-adapter.js +105 -11
  168. package/src/lib/scheduler-kernel/automation-event-adapter.js +87 -11
  169. package/src/lib/scheduler-kernel/contract.js +91 -0
  170. package/src/lib/scheduler-kernel/cowork-cron-adapter.js +12 -1
  171. package/src/lib/scheduler-kernel/loop-adapter.js +7 -1
  172. package/src/lib/scheduler-kernel/routine-adapter.js +7 -1
  173. package/src/lib/scheduler-kernel/runtime-control-capabilities.js +31 -0
  174. package/src/lib/scheduler-kernel/runtime.js +176 -3
  175. package/src/lib/scheduler-kernel/store.js +1253 -45
  176. package/src/runtime/agent-core.js +10 -0
  177. package/src/runtime/mcp-config.js +81 -10
  178. package/src/assets/web-panel/assets/MarkdownRenderer-BLCZMzhJ.js +0 -1
  179. package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +0 -1
  180. package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +0 -1
  181. package/src/assets/web-panel/assets/index-ChVT0p9u.js +0 -1
@@ -0,0 +1,448 @@
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ RUNTIME_PAUSE_RESUME,
4
+ SchedulerKernelError,
5
+ canonicalJson,
6
+ normalizeIdentifier,
7
+ normalizeRuntimeControlCapability,
8
+ } from "./scheduler-kernel/contract.js";
9
+ import {
10
+ RUNTIME_CONTROL_JOB_KINDS,
11
+ RUNTIME_CONTROL_OCCURRENCE_STATUSES,
12
+ } from "./scheduler-kernel/store.js";
13
+
14
+ export const AUTOMATION_CENTER_RUNTIME_SCHEMA =
15
+ "chainlesschain.automation-center-runtime/v1";
16
+ export const AUTOMATION_CENTER_RUNTIME_ACTION_ERROR_SCHEMA =
17
+ "chainlesschain.automation-center-runtime-action-error/v1";
18
+ export const AUTOMATION_CENTER_RUNTIME_SCHEMA_VERSION = 1;
19
+
20
+ const ACTIONS = Object.freeze(["pause", "resume"]);
21
+ const ACTION_SET = new Set(ACTIONS);
22
+ const SAFE_RUNTIME_ERROR_CODES = new Set([
23
+ "AUTOMATION_CENTER_RUNTIME_STORE_REQUIRED",
24
+ "AUTOMATION_CENTER_RUNTIME_CAPABILITY_REQUIRED",
25
+ "AUTOMATION_CENTER_RUNTIME_INVALID_ARGUMENT",
26
+ "AUTOMATION_CENTER_RUNTIME_ACTION_UNSUPPORTED",
27
+ "AUTOMATION_CENTER_RUNTIME_NOT_FOUND",
28
+ "AUTOMATION_CENTER_RUNTIME_KIND_UNSUPPORTED",
29
+ "AUTOMATION_CENTER_RUNTIME_TERMINAL",
30
+ "AUTOMATION_CENTER_RUNTIME_FENCE_CONFLICT",
31
+ "AUTOMATION_CENTER_RUNTIME_CAPABILITY_UNSUPPORTED",
32
+ "AUTOMATION_CENTER_RUNTIME_CAPABILITY_MISMATCH",
33
+ "AUTOMATION_CENTER_RUNTIME_REVISION_CONFLICT",
34
+ "AUTOMATION_CENTER_RUNTIME_STATE_CONFLICT",
35
+ ]);
36
+ const OCCURRENCE_ID_PATTERN = /^occ_[0-9a-f]{64}$/u;
37
+ const JOB_KIND_SET = new Set(RUNTIME_CONTROL_JOB_KINDS);
38
+ const TERMINAL_STATUSES = new Set(["succeeded", "dead_letter"]);
39
+
40
+ function runtimeError(code, message, details = undefined) {
41
+ const error = new SchedulerKernelError(code, message, details);
42
+ error.retryable = false;
43
+ return error;
44
+ }
45
+
46
+ function requireStore(schedulerStore) {
47
+ if (
48
+ !schedulerStore ||
49
+ typeof schedulerStore.listRuntimeControlOccurrences !== "function" ||
50
+ typeof schedulerStore.getOccurrence !== "function" ||
51
+ typeof schedulerStore.getOccurrenceControl !== "function" ||
52
+ typeof schedulerStore.getJob !== "function"
53
+ ) {
54
+ throw runtimeError(
55
+ "AUTOMATION_CENTER_RUNTIME_STORE_REQUIRED",
56
+ "A scheduler store with runtime-control reads is required",
57
+ );
58
+ }
59
+ return schedulerStore;
60
+ }
61
+
62
+ function requireCapabilityResolver(capabilityForKind) {
63
+ if (typeof capabilityForKind !== "function") {
64
+ throw runtimeError(
65
+ "AUTOMATION_CENTER_RUNTIME_CAPABILITY_REQUIRED",
66
+ "A runtime-control capability resolver is required",
67
+ );
68
+ }
69
+ return capabilityForKind;
70
+ }
71
+
72
+ function capabilityFor(resolver, jobKind) {
73
+ return normalizeRuntimeControlCapability(resolver(jobKind));
74
+ }
75
+
76
+ function supportsRuntimeControl(capability) {
77
+ return (
78
+ capability.pauseResume === RUNTIME_PAUSE_RESUME.CHECKPOINT_V1 &&
79
+ capability.safePoints.length > 0
80
+ );
81
+ }
82
+
83
+ function assertExpectedInteger(value, field, { positive = false } = {}) {
84
+ const minimum = positive ? 1 : 0;
85
+ if (!Number.isSafeInteger(value) || value < minimum) {
86
+ throw runtimeError(
87
+ "AUTOMATION_CENTER_RUNTIME_INVALID_ARGUMENT",
88
+ `${field} must be a ${positive ? "positive" : "non-negative"} integer`,
89
+ );
90
+ }
91
+ return value;
92
+ }
93
+
94
+ function actionPreview(item, action) {
95
+ return {
96
+ executor: "cli",
97
+ argv: [
98
+ "automation",
99
+ "center-runtime-action",
100
+ item.id,
101
+ action,
102
+ "--expected-fence",
103
+ String(item.fence),
104
+ "--expected-control-revision",
105
+ String(item.control?.revision ?? 0),
106
+ "--json",
107
+ ],
108
+ mutates: true,
109
+ };
110
+ }
111
+
112
+ function projectedAction(item, capability, action) {
113
+ if (!supportsRuntimeControl(capability)) {
114
+ return {
115
+ id: action,
116
+ available: false,
117
+ reason: "runtime_control_unsupported",
118
+ preview: null,
119
+ };
120
+ }
121
+ const available =
122
+ (action === "pause" && item.runtimeStatus === "running") ||
123
+ (action === "resume" && item.runtimeStatus === "paused");
124
+ let reason = null;
125
+ if (!available) {
126
+ if (action === "pause") {
127
+ reason =
128
+ item.runtimeStatus === "pause_requested"
129
+ ? "pause_already_requested"
130
+ : item.runtimeStatus === "paused"
131
+ ? "already_paused"
132
+ : "occurrence_not_running";
133
+ } else {
134
+ reason = "occurrence_not_paused";
135
+ }
136
+ }
137
+ return {
138
+ id: action,
139
+ available,
140
+ reason,
141
+ preview: available ? actionPreview(item, action) : null,
142
+ };
143
+ }
144
+
145
+ function projectOccurrence(item, resolver) {
146
+ const capability = capabilityFor(resolver, item.jobKind);
147
+ return {
148
+ id: item.id,
149
+ jobId: item.jobId,
150
+ jobKind: item.jobKind,
151
+ status: item.runtimeStatus,
152
+ occurrenceStatus: item.occurrenceStatus,
153
+ scheduledFor: item.scheduledFor,
154
+ attempt: item.attempt,
155
+ maxAttempts: item.maxAttempts,
156
+ fence: item.fence,
157
+ controlRevision: item.control?.revision ?? 0,
158
+ createdAt: item.createdAt,
159
+ updatedAt: item.updatedAt,
160
+ runtimeControl: supportsRuntimeControl(capability)
161
+ ? {
162
+ pauseResume: capability.pauseResume,
163
+ safePoints: [...capability.safePoints],
164
+ }
165
+ : null,
166
+ actions: ACTIONS.map((action) => projectedAction(item, capability, action)),
167
+ };
168
+ }
169
+
170
+ export function buildAutomationCenterRuntimeProjection(
171
+ schedulerStore,
172
+ {
173
+ capabilityForKind,
174
+ statuses = RUNTIME_CONTROL_OCCURRENCE_STATUSES,
175
+ jobKinds = RUNTIME_CONTROL_JOB_KINDS,
176
+ limit = 50,
177
+ } = {},
178
+ ) {
179
+ const store = requireStore(schedulerStore);
180
+ const resolver = requireCapabilityResolver(capabilityForKind);
181
+ const items = store
182
+ .listRuntimeControlOccurrences({ statuses, jobKinds, limit })
183
+ .map((item) => projectOccurrence(item, resolver));
184
+ return {
185
+ schema: AUTOMATION_CENTER_RUNTIME_SCHEMA,
186
+ schemaVersion: AUTOMATION_CENTER_RUNTIME_SCHEMA_VERSION,
187
+ items,
188
+ };
189
+ }
190
+
191
+ function deterministicRequestId({
192
+ occurrenceId,
193
+ action,
194
+ expectedFence,
195
+ capability,
196
+ expectedControlRevision,
197
+ }) {
198
+ const digest = createHash("sha256")
199
+ .update("chainlesschain.automation-center-runtime.request.v1\0", "utf8")
200
+ .update(
201
+ canonicalJson(
202
+ {
203
+ action,
204
+ capability,
205
+ expectedControlRevision,
206
+ expectedFence,
207
+ occurrenceId,
208
+ },
209
+ "automationCenterRuntime.request",
210
+ ),
211
+ "utf8",
212
+ )
213
+ .digest("hex");
214
+ return `automation-center-runtime:${action}:${digest}`;
215
+ }
216
+
217
+ function sameCapability(left, right) {
218
+ return (
219
+ canonicalJson(left, "runtimeControl.persisted") ===
220
+ canonicalJson(right, "runtimeControl.current")
221
+ );
222
+ }
223
+
224
+ function sanitizeActionResult({
225
+ action,
226
+ requestId,
227
+ deduplicated,
228
+ occurrence,
229
+ control,
230
+ jobKind,
231
+ }) {
232
+ return {
233
+ schema: AUTOMATION_CENTER_RUNTIME_SCHEMA,
234
+ schemaVersion: AUTOMATION_CENTER_RUNTIME_SCHEMA_VERSION,
235
+ authority: "cli",
236
+ ok: true,
237
+ action,
238
+ requestId,
239
+ deduplicated: deduplicated === true,
240
+ occurrence: {
241
+ id: occurrence.id,
242
+ jobId: occurrence.jobId,
243
+ jobKind,
244
+ status: occurrence.status,
245
+ attempt: occurrence.attempt,
246
+ maxAttempts: occurrence.maxAttempts,
247
+ fence: occurrence.fence,
248
+ scheduledFor: occurrence.scheduledFor,
249
+ updatedAt: occurrence.updatedAt,
250
+ },
251
+ control: {
252
+ state: control.state,
253
+ revision: control.revision,
254
+ expectedFence: control.expectedFence,
255
+ requestedAt: control.requestedAt,
256
+ pausedAt: control.pausedAt,
257
+ resumedAt: control.resumedAt,
258
+ updatedAt: control.updatedAt,
259
+ },
260
+ };
261
+ }
262
+
263
+ export function runAutomationCenterRuntimeAction(
264
+ schedulerStore,
265
+ {
266
+ capabilityForKind,
267
+ occurrenceId,
268
+ action,
269
+ expectedFence,
270
+ expectedControlRevision,
271
+ } = {},
272
+ ) {
273
+ const store = requireStore(schedulerStore);
274
+ const resolver = requireCapabilityResolver(capabilityForKind);
275
+ const id = normalizeIdentifier(occurrenceId, "occurrenceId");
276
+ const normalizedAction = normalizeIdentifier(action, "action", {
277
+ maxLength: 16,
278
+ });
279
+ if (!ACTION_SET.has(normalizedAction)) {
280
+ throw runtimeError(
281
+ "AUTOMATION_CENTER_RUNTIME_ACTION_UNSUPPORTED",
282
+ "Runtime action must be pause or resume",
283
+ );
284
+ }
285
+ const fence = assertExpectedInteger(expectedFence, "expectedFence", {
286
+ positive: true,
287
+ });
288
+ const revision = assertExpectedInteger(
289
+ expectedControlRevision,
290
+ "expectedControlRevision",
291
+ );
292
+
293
+ // Every mutation starts from fresh durable evidence. Full occurrence/job
294
+ // records stay inside this trusted boundary and are never returned.
295
+ const occurrence = store.getOccurrence(id);
296
+ if (!occurrence) {
297
+ throw runtimeError(
298
+ "AUTOMATION_CENTER_RUNTIME_NOT_FOUND",
299
+ `Scheduler occurrence does not exist: ${id}`,
300
+ );
301
+ }
302
+ const job = store.getJob(occurrence.jobId);
303
+ if (!job || !JOB_KIND_SET.has(job.kind)) {
304
+ throw runtimeError(
305
+ "AUTOMATION_CENTER_RUNTIME_KIND_UNSUPPORTED",
306
+ "Scheduler occurrence kind is not Automation Center controllable",
307
+ );
308
+ }
309
+ if (TERMINAL_STATUSES.has(occurrence.status)) {
310
+ throw runtimeError(
311
+ "AUTOMATION_CENTER_RUNTIME_TERMINAL",
312
+ `Scheduler occurrence is terminal: ${id}`,
313
+ );
314
+ }
315
+ if (occurrence.fence !== fence) {
316
+ throw runtimeError(
317
+ "AUTOMATION_CENTER_RUNTIME_FENCE_CONFLICT",
318
+ `Scheduler occurrence fence changed: ${id}`,
319
+ { expectedFence: fence, actualFence: occurrence.fence },
320
+ );
321
+ }
322
+
323
+ const capability = capabilityFor(resolver, job.kind);
324
+ if (!supportsRuntimeControl(capability)) {
325
+ throw runtimeError(
326
+ "AUTOMATION_CENTER_RUNTIME_CAPABILITY_UNSUPPORTED",
327
+ "Scheduler runtime does not declare checkpoint pause/resume",
328
+ );
329
+ }
330
+ const control = store.getOccurrenceControl(id);
331
+ if (control && !sameCapability(control.capability, capability)) {
332
+ throw runtimeError(
333
+ "AUTOMATION_CENTER_RUNTIME_CAPABILITY_MISMATCH",
334
+ `Scheduler runtime-control capability changed: ${id}`,
335
+ );
336
+ }
337
+ const requestId = deterministicRequestId({
338
+ occurrenceId: id,
339
+ action: normalizedAction,
340
+ expectedFence: fence,
341
+ capability,
342
+ expectedControlRevision: revision,
343
+ });
344
+
345
+ const priorRequestId =
346
+ normalizedAction === "pause"
347
+ ? control?.pauseRequestId
348
+ : control?.resumeRequestId;
349
+ if (priorRequestId === requestId) {
350
+ return sanitizeActionResult({
351
+ action: normalizedAction,
352
+ requestId,
353
+ deduplicated: true,
354
+ occurrence,
355
+ control,
356
+ jobKind: job.kind,
357
+ });
358
+ }
359
+
360
+ const actualRevision = control?.revision ?? 0;
361
+ if (actualRevision !== revision) {
362
+ throw runtimeError(
363
+ "AUTOMATION_CENTER_RUNTIME_REVISION_CONFLICT",
364
+ `Scheduler occurrence control revision changed: ${id}`,
365
+ { expectedRevision: revision, actualRevision },
366
+ );
367
+ }
368
+
369
+ let result;
370
+ if (normalizedAction === "pause") {
371
+ if (occurrence.status !== "running" || control !== null) {
372
+ throw runtimeError(
373
+ "AUTOMATION_CENTER_RUNTIME_STATE_CONFLICT",
374
+ `Scheduler occurrence is not pausable: ${id}`,
375
+ );
376
+ }
377
+ const nextControl = store.requestOccurrencePause({
378
+ occurrenceId: id,
379
+ expectedFence: fence,
380
+ expectedRevision: revision,
381
+ requestId,
382
+ capability,
383
+ });
384
+ result = {
385
+ occurrence: store.getOccurrence(id),
386
+ control: nextControl,
387
+ deduplicated: nextControl.deduplicated,
388
+ };
389
+ } else {
390
+ if (
391
+ occurrence.status !== "retry_wait" ||
392
+ control?.state !== "paused" ||
393
+ control.expectedFence !== fence
394
+ ) {
395
+ throw runtimeError(
396
+ "AUTOMATION_CENTER_RUNTIME_STATE_CONFLICT",
397
+ `Scheduler occurrence is not resumable: ${id}`,
398
+ );
399
+ }
400
+ result = store.resumeOccurrence({
401
+ occurrenceId: id,
402
+ expectedRevision: revision,
403
+ requestId,
404
+ });
405
+ result.deduplicated = result.control.deduplicated;
406
+ }
407
+
408
+ return sanitizeActionResult({
409
+ action: normalizedAction,
410
+ requestId,
411
+ deduplicated: result.deduplicated,
412
+ occurrence: result.occurrence,
413
+ control: result.control,
414
+ jobKind: job.kind,
415
+ });
416
+ }
417
+
418
+ export function automationCenterRuntimeActionErrorEnvelope(
419
+ error,
420
+ { occurrenceId = null, action = null } = {},
421
+ ) {
422
+ const candidateCode =
423
+ typeof error?.code === "string"
424
+ ? error.code.slice(0, 128)
425
+ : "AUTOMATION_CENTER_RUNTIME_ACTION_FAILED";
426
+ const code = SAFE_RUNTIME_ERROR_CODES.has(candidateCode)
427
+ ? candidateCode
428
+ : "AUTOMATION_CENTER_RUNTIME_ACTION_FAILED";
429
+ return {
430
+ schema: AUTOMATION_CENTER_RUNTIME_ACTION_ERROR_SCHEMA,
431
+ schemaVersion: AUTOMATION_CENTER_RUNTIME_SCHEMA_VERSION,
432
+ authority: "cli",
433
+ ok: false,
434
+ occurrenceId:
435
+ typeof occurrenceId === "string" &&
436
+ OCCURRENCE_ID_PATTERN.test(occurrenceId)
437
+ ? occurrenceId
438
+ : null,
439
+ action: ACTION_SET.has(action) ? action : null,
440
+ error: {
441
+ code,
442
+ // Runtime error details can contain fences and internal scheduler state.
443
+ // Keep the IDE-facing error envelope intentionally minimal.
444
+ message: "Automation Center runtime action failed",
445
+ retryable: error?.retryable === true,
446
+ },
447
+ };
448
+ }