@dxos/plugin-routine 0.0.0

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 (403) hide show
  1. package/LICENSE +105 -0
  2. package/PLUGIN.mdl +475 -0
  3. package/README.md +15 -0
  4. package/dist/lib/neutral/RoutineArticle-UNTMV4CC.mjs +95 -0
  5. package/dist/lib/neutral/RoutineArticle-UNTMV4CC.mjs.map +7 -0
  6. package/dist/lib/neutral/RoutineCompanion-ZZ6WMY7I.mjs +249 -0
  7. package/dist/lib/neutral/RoutineCompanion-ZZ6WMY7I.mjs.map +7 -0
  8. package/dist/lib/neutral/RoutinePlugin.mjs +10 -0
  9. package/dist/lib/neutral/RoutinePlugin.mjs.map +7 -0
  10. package/dist/lib/neutral/RoutinePlugin.node.mjs +1133 -0
  11. package/dist/lib/neutral/RoutinePlugin.node.mjs.map +7 -0
  12. package/dist/lib/neutral/RoutinePlugin.workerd.mjs +36 -0
  13. package/dist/lib/neutral/RoutinePlugin.workerd.mjs.map +7 -0
  14. package/dist/lib/neutral/RoutineSettings-ZJOM4F3S.mjs +48 -0
  15. package/dist/lib/neutral/RoutineSettings-ZJOM4F3S.mjs.map +7 -0
  16. package/dist/lib/neutral/RoutineTraceCompanion-5U6R7LJE.mjs +236 -0
  17. package/dist/lib/neutral/RoutineTraceCompanion-5U6R7LJE.mjs.map +7 -0
  18. package/dist/lib/neutral/SkillArticle-WWDNKW2Z.mjs +27 -0
  19. package/dist/lib/neutral/SkillArticle-WWDNKW2Z.mjs.map +7 -0
  20. package/dist/lib/neutral/app-graph-builder-FALWLZTI.mjs +90 -0
  21. package/dist/lib/neutral/app-graph-builder-FALWLZTI.mjs.map +7 -0
  22. package/dist/lib/neutral/capabilities/index.mjs +25 -0
  23. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  24. package/dist/lib/neutral/capabilities/node.mjs +19 -0
  25. package/dist/lib/neutral/capabilities/node.mjs.map +7 -0
  26. package/dist/lib/neutral/chunk-674LDIUJ.mjs +9 -0
  27. package/dist/lib/neutral/chunk-674LDIUJ.mjs.map +7 -0
  28. package/dist/lib/neutral/chunk-CNYAPXUW.mjs +65 -0
  29. package/dist/lib/neutral/chunk-CNYAPXUW.mjs.map +7 -0
  30. package/dist/lib/neutral/chunk-HLO4LYXT.mjs +44 -0
  31. package/dist/lib/neutral/chunk-HLO4LYXT.mjs.map +7 -0
  32. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  33. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  34. package/dist/lib/neutral/chunk-ODQDVFMZ.mjs +8 -0
  35. package/dist/lib/neutral/chunk-ODQDVFMZ.mjs.map +7 -0
  36. package/dist/lib/neutral/chunk-R7J2MU2M.mjs +263 -0
  37. package/dist/lib/neutral/chunk-R7J2MU2M.mjs.map +7 -0
  38. package/dist/lib/neutral/chunk-WLNL77C7.mjs +14 -0
  39. package/dist/lib/neutral/chunk-WLNL77C7.mjs.map +7 -0
  40. package/dist/lib/neutral/components/index.mjs +1921 -0
  41. package/dist/lib/neutral/components/index.mjs.map +7 -0
  42. package/dist/lib/neutral/containers/index.mjs +17 -0
  43. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  44. package/dist/lib/neutral/create-object-V23KVDMJ.mjs +25 -0
  45. package/dist/lib/neutral/create-object-V23KVDMJ.mjs.map +7 -0
  46. package/dist/lib/neutral/create-routine-I67BYJA2.mjs +38 -0
  47. package/dist/lib/neutral/create-routine-I67BYJA2.mjs.map +7 -0
  48. package/dist/lib/neutral/create-trigger-from-template-U3KNS77V.mjs +70 -0
  49. package/dist/lib/neutral/create-trigger-from-template-U3KNS77V.mjs.map +7 -0
  50. package/dist/lib/neutral/hooks/index.mjs +47 -0
  51. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  52. package/dist/lib/neutral/index.mjs +27 -0
  53. package/dist/lib/neutral/index.mjs.map +7 -0
  54. package/dist/lib/neutral/layer-specs-ADQCTTRT.mjs +135 -0
  55. package/dist/lib/neutral/layer-specs-ADQCTTRT.mjs.map +7 -0
  56. package/dist/lib/neutral/meta.json +1 -0
  57. package/dist/lib/neutral/meta.mjs +8 -0
  58. package/dist/lib/neutral/meta.mjs.map +7 -0
  59. package/dist/lib/neutral/navigation-resolver-KQIWUH6F.mjs +18 -0
  60. package/dist/lib/neutral/navigation-resolver-KQIWUH6F.mjs.map +7 -0
  61. package/dist/lib/neutral/operation-handler-QKLJSDCQ.mjs +13 -0
  62. package/dist/lib/neutral/operation-handler-QKLJSDCQ.mjs.map +7 -0
  63. package/dist/lib/neutral/operations/index.mjs +8 -0
  64. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  65. package/dist/lib/neutral/plugin.mjs +16 -0
  66. package/dist/lib/neutral/plugin.mjs.map +7 -0
  67. package/dist/lib/neutral/react-surface-GMO7I7YE.mjs +67 -0
  68. package/dist/lib/neutral/react-surface-GMO7I7YE.mjs.map +7 -0
  69. package/dist/lib/neutral/registry-sync-PHBU6CH2.mjs +86 -0
  70. package/dist/lib/neutral/registry-sync-PHBU6CH2.mjs.map +7 -0
  71. package/dist/lib/neutral/run-routine-HJWXIWLJ.mjs +37 -0
  72. package/dist/lib/neutral/run-routine-HJWXIWLJ.mjs.map +7 -0
  73. package/dist/lib/neutral/templates-IIUCEBAX.mjs +49 -0
  74. package/dist/lib/neutral/templates-IIUCEBAX.mjs.map +7 -0
  75. package/dist/lib/neutral/testing.mjs +8 -0
  76. package/dist/lib/neutral/testing.mjs.map +7 -0
  77. package/dist/lib/neutral/translations.mjs +115 -0
  78. package/dist/lib/neutral/translations.mjs.map +7 -0
  79. package/dist/lib/neutral/trigger-runtime-controller-7FOTH2NP.mjs +77 -0
  80. package/dist/lib/neutral/trigger-runtime-controller-7FOTH2NP.mjs.map +7 -0
  81. package/dist/lib/neutral/types/index.mjs +17 -0
  82. package/dist/lib/neutral/types/index.mjs.map +7 -0
  83. package/dist/types/dx.config.d.ts +28 -0
  84. package/dist/types/dx.config.d.ts.map +1 -0
  85. package/dist/types/src/RoutinePlugin.d.ts +4 -0
  86. package/dist/types/src/RoutinePlugin.d.ts.map +1 -0
  87. package/dist/types/src/RoutinePlugin.node.d.ts +4 -0
  88. package/dist/types/src/RoutinePlugin.node.d.ts.map +1 -0
  89. package/dist/types/src/RoutinePlugin.test.d.ts +2 -0
  90. package/dist/types/src/RoutinePlugin.test.d.ts.map +1 -0
  91. package/dist/types/src/RoutinePlugin.workerd.d.ts +4 -0
  92. package/dist/types/src/RoutinePlugin.workerd.d.ts.map +1 -0
  93. package/dist/types/src/capabilities/app-graph-builder.d.ts +5 -0
  94. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  95. package/dist/types/src/capabilities/create-object.d.ts +5 -0
  96. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  97. package/dist/types/src/capabilities/create-object.test.d.ts +2 -0
  98. package/dist/types/src/capabilities/create-object.test.d.ts.map +1 -0
  99. package/dist/types/src/capabilities/index.d.ts +12 -0
  100. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  101. package/dist/types/src/capabilities/layer-specs.d.ts +5 -0
  102. package/dist/types/src/capabilities/layer-specs.d.ts.map +1 -0
  103. package/dist/types/src/capabilities/navigation-resolver.d.ts +5 -0
  104. package/dist/types/src/capabilities/navigation-resolver.d.ts.map +1 -0
  105. package/dist/types/src/capabilities/node.d.ts +9 -0
  106. package/dist/types/src/capabilities/node.d.ts.map +1 -0
  107. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  108. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  109. package/dist/types/src/capabilities/react-surface.d.ts +5 -0
  110. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  111. package/dist/types/src/capabilities/registry-sync.d.ts +21 -0
  112. package/dist/types/src/capabilities/registry-sync.d.ts.map +1 -0
  113. package/dist/types/src/capabilities/templates.d.ts +5 -0
  114. package/dist/types/src/capabilities/templates.d.ts.map +1 -0
  115. package/dist/types/src/capabilities/trigger-runtime-controller.d.ts +5 -0
  116. package/dist/types/src/capabilities/trigger-runtime-controller.d.ts.map +1 -0
  117. package/dist/types/src/capabilities/trigger-runtime-controller.test.d.ts +2 -0
  118. package/dist/types/src/capabilities/trigger-runtime-controller.test.d.ts.map +1 -0
  119. package/dist/types/src/commands/index.d.ts +2 -0
  120. package/dist/types/src/commands/index.d.ts.map +1 -0
  121. package/dist/types/src/commands/trigger/create/index.d.ts +25 -0
  122. package/dist/types/src/commands/trigger/create/index.d.ts.map +1 -0
  123. package/dist/types/src/commands/trigger/create/queue.d.ts +13 -0
  124. package/dist/types/src/commands/trigger/create/queue.d.ts.map +1 -0
  125. package/dist/types/src/commands/trigger/create/subscription.d.ts +15 -0
  126. package/dist/types/src/commands/trigger/create/subscription.d.ts.map +1 -0
  127. package/dist/types/src/commands/trigger/create/timer.d.ts +13 -0
  128. package/dist/types/src/commands/trigger/create/timer.d.ts.map +1 -0
  129. package/dist/types/src/commands/trigger/index.d.ts +57 -0
  130. package/dist/types/src/commands/trigger/index.d.ts.map +1 -0
  131. package/dist/types/src/commands/trigger/list.d.ts +7 -0
  132. package/dist/types/src/commands/trigger/list.d.ts.map +1 -0
  133. package/dist/types/src/commands/trigger/options.d.ts +10 -0
  134. package/dist/types/src/commands/trigger/options.d.ts.map +1 -0
  135. package/dist/types/src/commands/trigger/remove.d.ts +8 -0
  136. package/dist/types/src/commands/trigger/remove.d.ts.map +1 -0
  137. package/dist/types/src/commands/trigger/update/index.d.ts +28 -0
  138. package/dist/types/src/commands/trigger/update/index.d.ts.map +1 -0
  139. package/dist/types/src/commands/trigger/update/queue.d.ts +13 -0
  140. package/dist/types/src/commands/trigger/update/queue.d.ts.map +1 -0
  141. package/dist/types/src/commands/trigger/update/subscription.d.ts +15 -0
  142. package/dist/types/src/commands/trigger/update/subscription.d.ts.map +1 -0
  143. package/dist/types/src/commands/trigger/update/timer.d.ts +13 -0
  144. package/dist/types/src/commands/trigger/update/timer.d.ts.map +1 -0
  145. package/dist/types/src/commands/trigger/util.d.ts +46 -0
  146. package/dist/types/src/commands/trigger/util.d.ts.map +1 -0
  147. package/dist/types/src/components/CreateRoutinePanel/CreateRoutinePanel.d.ts +14 -0
  148. package/dist/types/src/components/CreateRoutinePanel/CreateRoutinePanel.d.ts.map +1 -0
  149. package/dist/types/src/components/CreateRoutinePanel/index.d.ts +2 -0
  150. package/dist/types/src/components/CreateRoutinePanel/index.d.ts.map +1 -0
  151. package/dist/types/src/components/InstructionsEditor/InstructionsEditor.d.ts +16 -0
  152. package/dist/types/src/components/InstructionsEditor/InstructionsEditor.d.ts.map +1 -0
  153. package/dist/types/src/components/InstructionsEditor/InstructionsEditor.stories.d.ts +17 -0
  154. package/dist/types/src/components/InstructionsEditor/InstructionsEditor.stories.d.ts.map +1 -0
  155. package/dist/types/src/components/InstructionsEditor/index.d.ts +2 -0
  156. package/dist/types/src/components/InstructionsEditor/index.d.ts.map +1 -0
  157. package/dist/types/src/components/MasterDetail/MasterDetail.d.ts +51 -0
  158. package/dist/types/src/components/MasterDetail/MasterDetail.d.ts.map +1 -0
  159. package/dist/types/src/components/MasterDetail/MasterDetail.stories.d.ts +16 -0
  160. package/dist/types/src/components/MasterDetail/MasterDetail.stories.d.ts.map +1 -0
  161. package/dist/types/src/components/MasterDetail/index.d.ts +2 -0
  162. package/dist/types/src/components/MasterDetail/index.d.ts.map +1 -0
  163. package/dist/types/src/components/RoutineForm/RoutineForm.d.ts +25 -0
  164. package/dist/types/src/components/RoutineForm/RoutineForm.d.ts.map +1 -0
  165. package/dist/types/src/components/RoutineForm/index.d.ts +2 -0
  166. package/dist/types/src/components/RoutineForm/index.d.ts.map +1 -0
  167. package/dist/types/src/components/Schedule/Schedule.d.ts +80 -0
  168. package/dist/types/src/components/Schedule/Schedule.d.ts.map +1 -0
  169. package/dist/types/src/components/Schedule/Schedule.stories.d.ts +23 -0
  170. package/dist/types/src/components/Schedule/Schedule.stories.d.ts.map +1 -0
  171. package/dist/types/src/components/Schedule/cron.d.ts +44 -0
  172. package/dist/types/src/components/Schedule/cron.d.ts.map +1 -0
  173. package/dist/types/src/components/Schedule/cron.test.d.ts +2 -0
  174. package/dist/types/src/components/Schedule/cron.test.d.ts.map +1 -0
  175. package/dist/types/src/components/Schedule/index.d.ts +4 -0
  176. package/dist/types/src/components/Schedule/index.d.ts.map +1 -0
  177. package/dist/types/src/components/Schedule/types.d.ts +66 -0
  178. package/dist/types/src/components/Schedule/types.d.ts.map +1 -0
  179. package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts +13 -0
  180. package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts.map +1 -0
  181. package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts +19 -0
  182. package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts.map +1 -0
  183. package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts +21 -0
  184. package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts.map +1 -0
  185. package/dist/types/src/components/TemplateEditor/TemplateForm.stories.d.ts +16 -0
  186. package/dist/types/src/components/TemplateEditor/TemplateForm.stories.d.ts.map +1 -0
  187. package/dist/types/src/components/TemplateEditor/extensions/handlebars-extension.d.ts +12 -0
  188. package/dist/types/src/components/TemplateEditor/extensions/handlebars-extension.d.ts.map +1 -0
  189. package/dist/types/src/components/TemplateEditor/extensions/index.d.ts +3 -0
  190. package/dist/types/src/components/TemplateEditor/extensions/index.d.ts.map +1 -0
  191. package/dist/types/src/components/TemplateEditor/extensions/xml-extension.d.ts +8 -0
  192. package/dist/types/src/components/TemplateEditor/extensions/xml-extension.d.ts.map +1 -0
  193. package/dist/types/src/components/TemplateEditor/index.d.ts +2 -0
  194. package/dist/types/src/components/TemplateEditor/index.d.ts.map +1 -0
  195. package/dist/types/src/components/TemplateEditor/types.d.ts +18 -0
  196. package/dist/types/src/components/TemplateEditor/types.d.ts.map +1 -0
  197. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +24 -0
  198. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -0
  199. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +25 -0
  200. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -0
  201. package/dist/types/src/components/TriggerEditor/TriggerKindSelector.d.ts +15 -0
  202. package/dist/types/src/components/TriggerEditor/TriggerKindSelector.d.ts.map +1 -0
  203. package/dist/types/src/components/TriggerEditor/TriggerKindSelector.stories.d.ts +15 -0
  204. package/dist/types/src/components/TriggerEditor/TriggerKindSelector.stories.d.ts.map +1 -0
  205. package/dist/types/src/components/TriggerEditor/index.d.ts +2 -0
  206. package/dist/types/src/components/TriggerEditor/index.d.ts.map +1 -0
  207. package/dist/types/src/components/index.d.ts +8 -0
  208. package/dist/types/src/components/index.d.ts.map +1 -0
  209. package/dist/types/src/containers/RoutineArticle/RoutineArticle.d.ts +14 -0
  210. package/dist/types/src/containers/RoutineArticle/RoutineArticle.d.ts.map +1 -0
  211. package/dist/types/src/containers/RoutineArticle/RoutineArticle.stories.d.ts +20 -0
  212. package/dist/types/src/containers/RoutineArticle/RoutineArticle.stories.d.ts.map +1 -0
  213. package/dist/types/src/containers/RoutineArticle/index.d.ts +2 -0
  214. package/dist/types/src/containers/RoutineArticle/index.d.ts.map +1 -0
  215. package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.d.ts +17 -0
  216. package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.d.ts.map +1 -0
  217. package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.stories.d.ts +15 -0
  218. package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.stories.d.ts.map +1 -0
  219. package/dist/types/src/containers/RoutineCompanion/index.d.ts +3 -0
  220. package/dist/types/src/containers/RoutineCompanion/index.d.ts.map +1 -0
  221. package/dist/types/src/containers/RoutineSettings/RoutineSettings.d.ts +10 -0
  222. package/dist/types/src/containers/RoutineSettings/RoutineSettings.d.ts.map +1 -0
  223. package/dist/types/src/containers/RoutineSettings/index.d.ts +2 -0
  224. package/dist/types/src/containers/RoutineSettings/index.d.ts.map +1 -0
  225. package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.d.ts +9 -0
  226. package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.d.ts.map +1 -0
  227. package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.stories.d.ts +15 -0
  228. package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.stories.d.ts.map +1 -0
  229. package/dist/types/src/containers/RoutineTraceCompanion/index.d.ts +2 -0
  230. package/dist/types/src/containers/RoutineTraceCompanion/index.d.ts.map +1 -0
  231. package/dist/types/src/containers/RoutineTraceCompanion/runs.d.ts +34 -0
  232. package/dist/types/src/containers/RoutineTraceCompanion/runs.d.ts.map +1 -0
  233. package/dist/types/src/containers/RoutineTraceCompanion/runs.test.d.ts +2 -0
  234. package/dist/types/src/containers/RoutineTraceCompanion/runs.test.d.ts.map +1 -0
  235. package/dist/types/src/containers/RoutineTraceCompanion/useRoutineRuns.d.ts +11 -0
  236. package/dist/types/src/containers/RoutineTraceCompanion/useRoutineRuns.d.ts.map +1 -0
  237. package/dist/types/src/containers/SkillArticle/SkillArticle.d.ts +6 -0
  238. package/dist/types/src/containers/SkillArticle/SkillArticle.d.ts.map +1 -0
  239. package/dist/types/src/containers/SkillArticle/index.d.ts +2 -0
  240. package/dist/types/src/containers/SkillArticle/index.d.ts.map +1 -0
  241. package/dist/types/src/containers/index.d.ts +7 -0
  242. package/dist/types/src/containers/index.d.ts.map +1 -0
  243. package/dist/types/src/hooks/index.d.ts +2 -0
  244. package/dist/types/src/hooks/index.d.ts.map +1 -0
  245. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +12 -0
  246. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -0
  247. package/dist/types/src/index.d.ts +4 -0
  248. package/dist/types/src/index.d.ts.map +1 -0
  249. package/dist/types/src/meta.d.ts +33 -0
  250. package/dist/types/src/meta.d.ts.map +1 -0
  251. package/dist/types/src/operations/create-routine.d.ts +5 -0
  252. package/dist/types/src/operations/create-routine.d.ts.map +1 -0
  253. package/dist/types/src/operations/create-trigger-from-template.d.ts +5 -0
  254. package/dist/types/src/operations/create-trigger-from-template.d.ts.map +1 -0
  255. package/dist/types/src/operations/index.d.ts +3 -0
  256. package/dist/types/src/operations/index.d.ts.map +1 -0
  257. package/dist/types/src/operations/run-routine.d.ts +5 -0
  258. package/dist/types/src/operations/run-routine.d.ts.map +1 -0
  259. package/dist/types/src/paths.d.ts +5 -0
  260. package/dist/types/src/paths.d.ts.map +1 -0
  261. package/dist/types/src/plugin.d.ts +4 -0
  262. package/dist/types/src/plugin.d.ts.map +1 -0
  263. package/dist/types/src/templates/index.d.ts +11 -0
  264. package/dist/types/src/templates/index.d.ts.map +1 -0
  265. package/dist/types/src/testing/index.d.ts +2 -0
  266. package/dist/types/src/testing/index.d.ts.map +1 -0
  267. package/dist/types/src/testing/test-functions.d.ts +328 -0
  268. package/dist/types/src/testing/test-functions.d.ts.map +1 -0
  269. package/dist/types/src/testing.d.ts +2 -0
  270. package/dist/types/src/testing.d.ts.map +1 -0
  271. package/dist/types/src/translations.d.ts +3 -0
  272. package/dist/types/src/translations.d.ts.map +1 -0
  273. package/dist/types/src/types/Routine.d.ts +55 -0
  274. package/dist/types/src/types/Routine.d.ts.map +1 -0
  275. package/dist/types/src/types/Routine.test.d.ts +2 -0
  276. package/dist/types/src/types/Routine.test.d.ts.map +1 -0
  277. package/dist/types/src/types/RoutineCapabilities.d.ts +44 -0
  278. package/dist/types/src/types/RoutineCapabilities.d.ts.map +1 -0
  279. package/dist/types/src/types/RoutineOperation.d.ts +45 -0
  280. package/dist/types/src/types/RoutineOperation.d.ts.map +1 -0
  281. package/dist/types/src/types/index.d.ts +5 -0
  282. package/dist/types/src/types/index.d.ts.map +1 -0
  283. package/dist/types/src/types/schema.d.ts +33 -0
  284. package/dist/types/src/types/schema.d.ts.map +1 -0
  285. package/dist/types/src/util/index.d.ts +3 -0
  286. package/dist/types/src/util/index.d.ts.map +1 -0
  287. package/dist/types/src/util/routines-for-object.d.ts +22 -0
  288. package/dist/types/src/util/routines-for-object.d.ts.map +1 -0
  289. package/dist/types/src/util/routines-for-object.test.d.ts +2 -0
  290. package/dist/types/src/util/routines-for-object.test.d.ts.map +1 -0
  291. package/dist/types/src/util/run-instructions.d.ts +5 -0
  292. package/dist/types/src/util/run-instructions.d.ts.map +1 -0
  293. package/dist/types/src/util/run-instructions.test.d.ts +2 -0
  294. package/dist/types/src/util/run-instructions.test.d.ts.map +1 -0
  295. package/dist/types/tsconfig.tsbuildinfo +1 -0
  296. package/dx.config.ts +33 -0
  297. package/package.json +196 -0
  298. package/src/RoutinePlugin.node.ts +48 -0
  299. package/src/RoutinePlugin.test.ts +27 -0
  300. package/src/RoutinePlugin.tsx +58 -0
  301. package/src/RoutinePlugin.workerd.ts +24 -0
  302. package/src/capabilities/app-graph-builder.ts +80 -0
  303. package/src/capabilities/create-object.test.ts +18 -0
  304. package/src/capabilities/create-object.ts +26 -0
  305. package/src/capabilities/index.ts +22 -0
  306. package/src/capabilities/layer-specs.ts +190 -0
  307. package/src/capabilities/navigation-resolver.ts +21 -0
  308. package/src/capabilities/node.ts +19 -0
  309. package/src/capabilities/operation-handler.ts +16 -0
  310. package/src/capabilities/react-surface.tsx +66 -0
  311. package/src/capabilities/registry-sync.ts +114 -0
  312. package/src/capabilities/templates.ts +17 -0
  313. package/src/capabilities/trigger-runtime-controller.test.ts +107 -0
  314. package/src/capabilities/trigger-runtime-controller.ts +126 -0
  315. package/src/commands/index.ts +5 -0
  316. package/src/commands/trigger/create/index.ts +14 -0
  317. package/src/commands/trigger/create/queue.ts +87 -0
  318. package/src/commands/trigger/create/subscription.ts +126 -0
  319. package/src/commands/trigger/create/timer.ts +90 -0
  320. package/src/commands/trigger/index.ts +16 -0
  321. package/src/commands/trigger/list.ts +69 -0
  322. package/src/commands/trigger/options.ts +47 -0
  323. package/src/commands/trigger/remove.ts +45 -0
  324. package/src/commands/trigger/update/index.ts +14 -0
  325. package/src/commands/trigger/update/queue.ts +191 -0
  326. package/src/commands/trigger/update/subscription.ts +278 -0
  327. package/src/commands/trigger/update/timer.ts +194 -0
  328. package/src/commands/trigger/util.ts +412 -0
  329. package/src/components/CreateRoutinePanel/CreateRoutinePanel.tsx +68 -0
  330. package/src/components/CreateRoutinePanel/index.ts +5 -0
  331. package/src/components/InstructionsEditor/InstructionsEditor.stories.tsx +69 -0
  332. package/src/components/InstructionsEditor/InstructionsEditor.tsx +107 -0
  333. package/src/components/InstructionsEditor/index.ts +5 -0
  334. package/src/components/MasterDetail/MasterDetail.stories.tsx +100 -0
  335. package/src/components/MasterDetail/MasterDetail.tsx +175 -0
  336. package/src/components/MasterDetail/index.ts +5 -0
  337. package/src/components/RoutineForm/RoutineForm.tsx +293 -0
  338. package/src/components/RoutineForm/index.ts +5 -0
  339. package/src/components/Schedule/Schedule.stories.tsx +73 -0
  340. package/src/components/Schedule/Schedule.tsx +527 -0
  341. package/src/components/Schedule/cron.test.ts +230 -0
  342. package/src/components/Schedule/cron.ts +337 -0
  343. package/src/components/Schedule/index.ts +8 -0
  344. package/src/components/Schedule/types.ts +124 -0
  345. package/src/components/TemplateEditor/TemplateEditor.stories.tsx +93 -0
  346. package/src/components/TemplateEditor/TemplateEditor.tsx +77 -0
  347. package/src/components/TemplateEditor/TemplateForm.stories.tsx +76 -0
  348. package/src/components/TemplateEditor/TemplateForm.tsx +204 -0
  349. package/src/components/TemplateEditor/extensions/handlebars-extension.ts +274 -0
  350. package/src/components/TemplateEditor/extensions/index.ts +6 -0
  351. package/src/components/TemplateEditor/extensions/xml-extension.ts +64 -0
  352. package/src/components/TemplateEditor/index.ts +5 -0
  353. package/src/components/TemplateEditor/types.tsx +28 -0
  354. package/src/components/TriggerEditor/TriggerEditor.stories.tsx +122 -0
  355. package/src/components/TriggerEditor/TriggerEditor.tsx +365 -0
  356. package/src/components/TriggerEditor/TriggerKindSelector.stories.tsx +42 -0
  357. package/src/components/TriggerEditor/TriggerKindSelector.tsx +87 -0
  358. package/src/components/TriggerEditor/index.ts +5 -0
  359. package/src/components/index.ts +11 -0
  360. package/src/containers/RoutineArticle/RoutineArticle.stories.tsx +146 -0
  361. package/src/containers/RoutineArticle/RoutineArticle.tsx +109 -0
  362. package/src/containers/RoutineArticle/index.ts +5 -0
  363. package/src/containers/RoutineCompanion/RoutineCompanion.stories.tsx +82 -0
  364. package/src/containers/RoutineCompanion/RoutineCompanion.tsx +342 -0
  365. package/src/containers/RoutineCompanion/index.ts +6 -0
  366. package/src/containers/RoutineSettings/RoutineSettings.tsx +65 -0
  367. package/src/containers/RoutineSettings/index.ts +5 -0
  368. package/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.stories.tsx +133 -0
  369. package/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.tsx +125 -0
  370. package/src/containers/RoutineTraceCompanion/index.ts +5 -0
  371. package/src/containers/RoutineTraceCompanion/runs.test.ts +140 -0
  372. package/src/containers/RoutineTraceCompanion/runs.ts +135 -0
  373. package/src/containers/RoutineTraceCompanion/useRoutineRuns.ts +50 -0
  374. package/src/containers/SkillArticle/SkillArticle.tsx +29 -0
  375. package/src/containers/SkillArticle/index.ts +5 -0
  376. package/src/containers/index.ts +11 -0
  377. package/src/hooks/index.ts +6 -0
  378. package/src/hooks/useTriggerRuntimeControls.ts +70 -0
  379. package/src/index.ts +7 -0
  380. package/src/meta.ts +9 -0
  381. package/src/operations/create-routine.ts +39 -0
  382. package/src/operations/create-trigger-from-template.ts +68 -0
  383. package/src/operations/index.ts +11 -0
  384. package/src/operations/run-routine.ts +45 -0
  385. package/src/paths.ts +18 -0
  386. package/src/plugin.ts +11 -0
  387. package/src/templates/index.ts +48 -0
  388. package/src/testing/index.ts +5 -0
  389. package/src/testing/test-functions.ts +76 -0
  390. package/src/testing.ts +7 -0
  391. package/src/translations.ts +125 -0
  392. package/src/types/Routine.test.ts +51 -0
  393. package/src/types/Routine.ts +144 -0
  394. package/src/types/RoutineCapabilities.ts +51 -0
  395. package/src/types/RoutineOperation.ts +104 -0
  396. package/src/types/index.ts +9 -0
  397. package/src/types/schema.ts +31 -0
  398. package/src/util/index.ts +6 -0
  399. package/src/util/routines-for-object.test.ts +109 -0
  400. package/src/util/routines-for-object.ts +89 -0
  401. package/src/util/run-instructions.test.ts +23 -0
  402. package/src/util/run-instructions.ts +12 -0
  403. package/src/vite-env.d.ts +10 -0
@@ -0,0 +1,190 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Registry as AtomRegistry } from '@effect-atom/atom';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+
9
+ import { OpaqueToolkit } from '@dxos/ai';
10
+ import { Capabilities, Capability } from '@dxos/app-framework';
11
+ import { AppCapabilities } from '@dxos/app-toolkit';
12
+ import { ClientService } from '@dxos/client';
13
+ import { LayerSpec, Operation, OperationHandlerSet } from '@dxos/compute';
14
+ import { ProcessManager } from '@dxos/compute-runtime';
15
+ import { Database, Registry } from '@dxos/echo';
16
+ import {
17
+ FeedTraceSink,
18
+ RemoteFunctionExecutionService,
19
+ TriggerDispatcher,
20
+ TriggerStateStore,
21
+ } from '@dxos/functions-runtime';
22
+ import { invariant } from '@dxos/invariant';
23
+
24
+ //
25
+ // Capability Module
26
+ //
27
+ // Contributes application- and space-affinity `Capabilities.LayerSpec` entries
28
+ // that together replace the former monolithic `RoutineCapabilities.ComputeRuntime`.
29
+ //
30
+ // Specs are declared at module level; runtime state (the `Client`, contributed
31
+ // capability lists, etc.) is resolved via Effect-level requirements rather
32
+ // than captured from an outer scope.
33
+ //
34
+
35
+ /**
36
+ * Gathers contributed {@link Capabilities.OperationHandler} sets from the
37
+ * {@link Capability.Service} and exposes them through the
38
+ * {@link OperationHandlerSet.OperationHandlerProvider} tag so space-affinity
39
+ * specs (e.g. {@link OperationsToRegistrySpec}) can consume them through the
40
+ * normal LayerStack resolution path.
41
+ */
42
+ const OperationHandlerProviderSpec = LayerSpec.make(
43
+ {
44
+ affinity: 'application',
45
+ requires: [Capability.Service],
46
+ provides: [OperationHandlerSet.OperationHandlerProvider],
47
+ },
48
+ () =>
49
+ Layer.unwrapEffect(
50
+ Effect.gen(function* () {
51
+ const operationHandlerSets = yield* Capability.getAll(Capabilities.OperationHandler);
52
+ const mergedOperationHandlers =
53
+ operationHandlerSets.length === 0
54
+ ? OperationHandlerSet.empty
55
+ : OperationHandlerSet.merge(...operationHandlerSets);
56
+ return OperationHandlerSet.provide(mergedOperationHandlers);
57
+ }),
58
+ ),
59
+ );
60
+
61
+ const RegistrySpec = LayerSpec.make(
62
+ {
63
+ affinity: 'application',
64
+ requires: [ClientService],
65
+ provides: [Registry.Service],
66
+ },
67
+ () =>
68
+ Layer.unwrapEffect(
69
+ Effect.gen(function* () {
70
+ const client = yield* ClientService;
71
+ return Layer.succeed(Registry.Service, client.graph.registry);
72
+ }),
73
+ ),
74
+ );
75
+
76
+ const OpaqueToolkitSpec = LayerSpec.make(
77
+ {
78
+ affinity: 'application',
79
+ requires: [Capability.Service],
80
+ provides: [OpaqueToolkit.OpaqueToolkitProvider],
81
+ },
82
+ () =>
83
+ Layer.unwrapEffect(
84
+ Effect.gen(function* () {
85
+ const capabilities = yield* Capability.Service;
86
+ return Layer.succeed(OpaqueToolkit.OpaqueToolkitProvider, {
87
+ getToolkit: () => {
88
+ const toolkits = capabilities.getAll(AppCapabilities.Toolkit);
89
+ return OpaqueToolkit.merge(...toolkits);
90
+ },
91
+ });
92
+ }),
93
+ ),
94
+ );
95
+
96
+ const OperationsToRegistrySpec = LayerSpec.make(
97
+ {
98
+ affinity: 'space',
99
+ requires: [Registry.Service, OperationHandlerSet.OperationHandlerProvider],
100
+ provides: [Registry.Service],
101
+ },
102
+ () =>
103
+ Layer.effect(
104
+ Registry.Service,
105
+ Effect.gen(function* () {
106
+ const handlerSet = yield* OperationHandlerSet.OperationHandlerProvider;
107
+ const registry = yield* Registry.Service;
108
+ const handlers = yield* handlerSet.handlers;
109
+ registry.add(handlers.map(Operation.serialize));
110
+ return registry;
111
+ }),
112
+ ),
113
+ );
114
+
115
+ /**
116
+ * In-memory trigger state. Loses state across restarts but works in both
117
+ * browser and CLI/Node contexts. Hosts that need durable storage should
118
+ * contribute a replacement LayerSpec that provides {@link TriggerStateStore}
119
+ * backed by a persistent `KeyValueStore` (e.g. `BrowserKeyValueStore` or
120
+ * `BunKeyValueStore`).
121
+ */
122
+ const TriggerStateStoreSpec = LayerSpec.make(
123
+ {
124
+ affinity: 'application',
125
+ requires: [],
126
+ provides: [TriggerStateStore],
127
+ },
128
+ () => TriggerStateStore.layerMemory,
129
+ );
130
+
131
+ //
132
+ // Space-affinity specs.
133
+ //
134
+
135
+ const FeedTraceSinkSpec = LayerSpec.make(
136
+ {
137
+ affinity: 'space',
138
+ requires: [Database.Service],
139
+ provides: [FeedTraceSink.FeedTraceSink],
140
+ },
141
+ () => FeedTraceSink.layerLive,
142
+ );
143
+
144
+ /**
145
+ * Space-scoped `RemoteFunctionExecutionService`. When edge agents are enabled
146
+ * (`runtime.client.edgeFeatures.agents`) functions are invoked without a space
147
+ * binding (the edge routes them); otherwise they are scoped to the space. The
148
+ * config is read inside the factory — at slice-materialisation time, once
149
+ * `ClientService` is available — so the owning module does not need the client
150
+ * at activation time and can activate on `SetupProcessManager`.
151
+ */
152
+ const RemoteFunctionExecutionSpec = LayerSpec.make(
153
+ {
154
+ affinity: 'space',
155
+ requires: [ClientService],
156
+ provides: [RemoteFunctionExecutionService],
157
+ },
158
+ (context) =>
159
+ Layer.unwrapEffect(
160
+ Effect.gen(function* () {
161
+ invariant(context.space, 'space context required for RemoteFunctionExecutionService');
162
+ const client = yield* ClientService;
163
+ const edgeAgents = client.config.get('runtime.client.edgeFeatures.agents');
164
+ return RemoteFunctionExecutionService.fromClient(client, edgeAgents ? undefined : context.space);
165
+ }),
166
+ ),
167
+ );
168
+
169
+ const TriggerDispatcherSpec = LayerSpec.make(
170
+ {
171
+ affinity: 'space',
172
+ requires: [Database.Service, TriggerStateStore, ProcessManager.ProcessManagerService, AtomRegistry.AtomRegistry],
173
+ provides: [TriggerDispatcher],
174
+ },
175
+ () => TriggerDispatcher.layer({ timeControl: 'natural' }),
176
+ );
177
+
178
+ export default Capability.makeModule(() =>
179
+ Effect.succeed([
180
+ Capability.contributes(Capabilities.LayerSpec, OperationHandlerProviderSpec),
181
+ Capability.contributes(Capabilities.LayerSpec, RegistrySpec),
182
+ Capability.contributes(Capabilities.LayerSpec, OpaqueToolkitSpec),
183
+ Capability.contributes(Capabilities.LayerSpec, OperationsToRegistrySpec),
184
+ Capability.contributes(Capabilities.LayerSpec, TriggerStateStoreSpec),
185
+ Capability.contributes(Capabilities.LayerSpec, FeedTraceSinkSpec),
186
+ Capability.contributes(Capabilities.LayerSpec, TriggerDispatcherSpec),
187
+ Capability.contributes(Capabilities.LayerSpec, RemoteFunctionExecutionSpec),
188
+ Capability.contributes(Capabilities.TraceSink, ({ resolver }) => FeedTraceSink.makeRoutingSink({ resolver })),
189
+ ]),
190
+ );
@@ -0,0 +1,21 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities, Paths, TypeSection } from '@dxos/app-toolkit';
9
+
10
+ import { Routine } from '#types';
11
+
12
+ export default Capability.makeModule(
13
+ Effect.fnUntraced(function* () {
14
+ return [
15
+ Capability.contributes(
16
+ AppCapabilities.NavigationPathResolver,
17
+ TypeSection.createTypeSectionPathResolver(Routine.Routine, { groupId: Paths.GroupSegments.ai }),
18
+ ),
19
+ ];
20
+ }),
21
+ );
@@ -0,0 +1,19 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+ import { OperationHandlerSet } from '@dxos/compute';
7
+
8
+ export const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));
9
+ export const LayerSpecs = Capability.lazy<void, Capability.Any[]>('LayerSpecs', () => import('./layer-specs'));
10
+ export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
11
+ 'OperationHandler',
12
+ () => import('./operation-handler'),
13
+ );
14
+ export const RegistrySync = Capability.lazy('RegistrySync', () => import('./registry-sync'));
15
+ export const Templates = Capability.lazy('Templates', () => import('./templates'));
16
+ export const TriggerRuntimeController = Capability.lazy(
17
+ 'TriggerRuntimeController',
18
+ () => import('./trigger-runtime-controller'),
19
+ );
@@ -0,0 +1,16 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
+ import type { OperationHandlerSet } from '@dxos/compute';
9
+
10
+ import { RoutineOperationHandlerSet } from '#operations';
11
+
12
+ export default Capability.makeModule<OperationHandlerSet.OperationHandlerSet>(
13
+ Effect.fnUntraced(function* () {
14
+ return Capability.contributes(Capabilities.OperationHandler, RoutineOperationHandlerSet);
15
+ }),
16
+ );
@@ -0,0 +1,66 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import React from 'react';
7
+
8
+ import { Capabilities, Capability } from '@dxos/app-framework';
9
+ import { Surface } from '@dxos/app-framework/ui';
10
+ import { AppSurface, useActiveSpace } from '@dxos/app-toolkit/ui';
11
+ import { Skill } from '@dxos/compute';
12
+
13
+ import { RoutineArticle, RoutineCompanion, RoutineSettings, RoutineTraceCompanion, SkillArticle } from '#containers';
14
+ import { meta } from '#meta';
15
+ import { Routine } from '#types';
16
+
17
+ export default Capability.makeModule(() =>
18
+ Effect.succeed(
19
+ Capability.contributes(Capabilities.ReactSurface, [
20
+ Surface.create({
21
+ id: 'spaceSettingsAutomation',
22
+ filter: AppSurface.literal(AppSurface.Article, `${meta.profile.key}.space-settings-automation`),
23
+ component: () => {
24
+ const space = useActiveSpace();
25
+ if (!space) {
26
+ return null;
27
+ }
28
+
29
+ return <RoutineSettings space={space} />;
30
+ },
31
+ }),
32
+ Surface.create({
33
+ id: 'automation.article',
34
+ filter: AppSurface.object(AppSurface.Article, Routine.Routine),
35
+ component: ({ data, role }) => (
36
+ <RoutineArticle role={role} subject={data.subject} attendableId={data.attendableId} />
37
+ ),
38
+ }),
39
+ Surface.create({
40
+ id: 'companion.automation',
41
+ filter: AppSurface.allOf(
42
+ AppSurface.literal(AppSurface.Article, 'automation'),
43
+ AppSurface.companion(AppSurface.Article),
44
+ ),
45
+ component: ({ data }) => {
46
+ return <RoutineCompanion attendableId={data.attendableId} subject={data.companionTo} />;
47
+ },
48
+ }),
49
+ Surface.create({
50
+ id: 'routine.runs',
51
+ filter: AppSurface.allOf(
52
+ AppSurface.literal(AppSurface.Article, 'runs'),
53
+ AppSurface.companion(AppSurface.Article, Routine.Routine),
54
+ ),
55
+ component: ({ data, role }) => <RoutineTraceCompanion role={role} subject={data.companionTo} />,
56
+ }),
57
+ Surface.create({
58
+ id: 'skill',
59
+ filter: AppSurface.object(AppSurface.Article, Skill.Skill),
60
+ component: ({ data, role }) => (
61
+ <SkillArticle role={role} subject={data.subject} attendableId={data.attendableId} />
62
+ ),
63
+ }),
64
+ ]),
65
+ ),
66
+ );
@@ -0,0 +1,114 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
9
+ import { Operation, Skill } from '@dxos/compute';
10
+ import { log } from '@dxos/log';
11
+ import { ClientCapabilities } from '@dxos/plugin-client';
12
+
13
+ /**
14
+ * Syncs plugin capability contributions into `client.graph.registry`.
15
+ *
16
+ * Watches two capability atoms and imperatively adds entities to the
17
+ * hypergraph registry when they change:
18
+ * - {@link AppCapabilities.SkillDefinition} → instantiates each skill via `def.make()`.
19
+ * - {@link Capabilities.OperationHandler} → serializes each handler via `Operation.serialize`.
20
+ *
21
+ * Skill DB copies (stored in a space when a skill is "enabled") are treated as
22
+ * user forks and are not overwritten. The registry is always used as the source of truth
23
+ * for skill instructions at request time — see `formatSystemPrompt` in `@dxos/assistant`.
24
+ *
25
+ * Note: the plugin framework does not yet expose a teardown hook for capability
26
+ * modules (see the TODO in process-manager-capability.ts), so the subscriptions
27
+ * are not explicitly cancelled. They are effectively scoped to the client's lifetime.
28
+ */
29
+ export default Capability.makeModule(
30
+ Effect.fnUntraced(function* () {
31
+ const client = yield* Capability.get(ClientCapabilities.Client);
32
+ const atomRegistry = yield* Capability.get(Capabilities.AtomRegistry);
33
+ const capabilityManager = yield* Capability.Service;
34
+
35
+ //
36
+ // Skill registration.
37
+ //
38
+
39
+ const skillDefinitionsAtom = capabilityManager.atom(AppCapabilities.SkillDefinition);
40
+ const prevSkillKeys = new Set<string>();
41
+
42
+ atomRegistry.subscribe(
43
+ skillDefinitionsAtom,
44
+ (definitions) => {
45
+ const fresh: Skill.Skill[] = [];
46
+ for (const def of definitions) {
47
+ if (!prevSkillKeys.has(def.key)) {
48
+ prevSkillKeys.add(def.key);
49
+ fresh.push(def.make());
50
+ }
51
+ }
52
+ if (fresh.length > 0) {
53
+ client.graph.registry.add(fresh);
54
+ }
55
+ },
56
+ { immediate: true },
57
+ );
58
+
59
+ //
60
+ // Operation registration.
61
+ //
62
+
63
+ const operationHandlersAtom = capabilityManager.atom(Capabilities.OperationHandler);
64
+ const prevOperationKeys = new Set<string>();
65
+
66
+ atomRegistry.subscribe(
67
+ operationHandlersAtom,
68
+ async (handlerSets) => {
69
+ try {
70
+ const handlers = (await Promise.all(handlerSets.map((set) => set.getHandlers()))).flat();
71
+ const seenKeys = new Set<string>();
72
+ const batch: Operation.PersistentOperation[] = [];
73
+ for (const handler of handlers) {
74
+ const key = handler.meta.key;
75
+ if (!key) {
76
+ log.warn('skipping operation handler without key');
77
+ continue;
78
+ }
79
+ if (seenKeys.has(key)) {
80
+ log('skipping duplicate operation', { key });
81
+ continue;
82
+ }
83
+ seenKeys.add(key);
84
+ if (prevOperationKeys.has(key)) {
85
+ continue;
86
+ }
87
+ if (handler.meta.skipRegistry) {
88
+ prevOperationKeys.add(key);
89
+ continue;
90
+ }
91
+ try {
92
+ batch.push(Operation.serialize(handler));
93
+ } catch {
94
+ log.verbose('skipping operation with unserializable schema', { key });
95
+ prevOperationKeys.add(key);
96
+ }
97
+ }
98
+ if (batch.length > 0) {
99
+ client.graph.registry.add(batch);
100
+ for (const operation of batch) {
101
+ const operationKey = Operation.getKey(operation);
102
+ if (operationKey) {
103
+ prevOperationKeys.add(operationKey);
104
+ }
105
+ }
106
+ }
107
+ } catch (error) {
108
+ log.catch(error);
109
+ }
110
+ },
111
+ { immediate: true },
112
+ );
113
+ }),
114
+ );
@@ -0,0 +1,17 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+
9
+ import { RoutineCapabilities } from '#types';
10
+
11
+ import { defaultTemplates } from '../templates';
12
+
13
+ export default Capability.makeModule(
14
+ Effect.fnUntraced(function* () {
15
+ return defaultTemplates.map((template) => Capability.contributes(RoutineCapabilities.Template, template));
16
+ }),
17
+ );
@@ -0,0 +1,107 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import { describe, test } from 'vitest';
7
+
8
+ import { ServiceResolver } from '@dxos/compute';
9
+ import { Feed, Obj } from '@dxos/echo';
10
+ import { EffectEx } from '@dxos/effect';
11
+ import { TriggerDispatcher } from '@dxos/functions-runtime';
12
+ import type { SpaceId } from '@dxos/keys';
13
+ import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
14
+ import { ClientPlugin, initializeIdentity } from '@dxos/plugin-client/testing';
15
+ import { createComposerTestApp } from '@dxos/plugin-testing/harness';
16
+
17
+ import { RoutinePlugin } from '#plugin';
18
+
19
+ /**
20
+ * Resolve the per-space {@link TriggerDispatcher} from the harness'
21
+ * process-manager runtime. The `LayerStack` caches dispatchers per
22
+ * `{ space }` context, so the returned instance is the same one the
23
+ * controller is driving.
24
+ */
25
+ const getDispatcher = (harness: Awaited<ReturnType<typeof createComposerTestApp>>, spaceId: SpaceId) =>
26
+ harness.runPromise(
27
+ Effect.flatMap(TriggerDispatcher, Effect.succeed).pipe(
28
+ Effect.provide(ServiceResolver.provide({ space: spaceId }, TriggerDispatcher)),
29
+ ),
30
+ );
31
+
32
+ describe('TriggerRuntimeController', () => {
33
+ test('toggles the per-space TriggerDispatcher as computeEnvironment changes', async ({ expect }) => {
34
+ await using harness = await createComposerTestApp({
35
+ plugins: [ClientPlugin({ types: [Feed.Feed] }), RoutinePlugin()],
36
+ });
37
+
38
+ // Creating identity also creates the personal space and emits SpacesReady,
39
+ // which is what gates the TriggerRuntimeController module's activation.
40
+ const { personalSpace } = await EffectEx.runAndForwardErrors(
41
+ initializeIdentity(harness.get(ClientCapabilities.Client)),
42
+ );
43
+ await harness.waitForEvent(ClientEvents.SpacesReady);
44
+
45
+ const dispatcher = await getDispatcher(harness, personalSpace.id);
46
+
47
+ // Observe the dispatcher's `state` atom (the same surface the UI hook
48
+ // exposes through `useTriggerRuntimeControls`).
49
+ const observedStates: boolean[] = [];
50
+ const unsubscribe = harness.registry.subscribe(dispatcher.state, (state) => observedStates.push(state.enabled), {
51
+ immediate: true,
52
+ });
53
+ try {
54
+ // Default `computeEnvironment` is `local`, so the controller should
55
+ // start the dispatcher shortly after the space becomes ready.
56
+ await expect.poll(() => harness.registry.get(dispatcher.state).enabled, { timeout: 5_000 }).toBe(true);
57
+
58
+ // `disabled` → dispatcher should stop.
59
+ Obj.update(personalSpace.properties, (properties) => {
60
+ properties.computeEnvironment = 'disabled';
61
+ });
62
+ await expect.poll(() => harness.registry.get(dispatcher.state).enabled, { timeout: 5_000 }).toBe(false);
63
+
64
+ // Back to `local` → dispatcher should start again.
65
+ Obj.update(personalSpace.properties, (properties) => {
66
+ properties.computeEnvironment = 'local';
67
+ });
68
+ await expect.poll(() => harness.registry.get(dispatcher.state).enabled, { timeout: 5_000 }).toBe(true);
69
+
70
+ // `edge` → dispatcher should stop (triggers run on the edge instead).
71
+ Obj.update(personalSpace.properties, (properties) => {
72
+ properties.computeEnvironment = 'edge';
73
+ });
74
+ await expect.poll(() => harness.registry.get(dispatcher.state).enabled, { timeout: 5_000 }).toBe(false);
75
+
76
+ // The atom subscription should have witnessed every transition.
77
+ expect(observedStates).toEqual(expect.arrayContaining([true, false, true, false]));
78
+ } finally {
79
+ unsubscribe();
80
+ }
81
+ });
82
+
83
+ test('does not re-issue start when computeEnvironment is reasserted to the same value', async ({ expect }) => {
84
+ await using harness = await createComposerTestApp({
85
+ plugins: [ClientPlugin({ types: [Feed.Feed] }), RoutinePlugin()],
86
+ });
87
+
88
+ const { personalSpace } = await EffectEx.runAndForwardErrors(
89
+ initializeIdentity(harness.get(ClientCapabilities.Client)),
90
+ );
91
+ await harness.waitForEvent(ClientEvents.SpacesReady);
92
+
93
+ const dispatcher = await getDispatcher(harness, personalSpace.id);
94
+
95
+ await expect.poll(() => harness.registry.get(dispatcher.state).enabled, { timeout: 5_000 }).toBe(true);
96
+
97
+ // Writing the same `local` value should be a no-op: the controller
98
+ // dedupes via its `lastEnvironment` tracker so the dispatcher stays
99
+ // running without an intervening stop/start flicker.
100
+ Obj.update(personalSpace.properties, (properties) => {
101
+ properties.computeEnvironment = 'local';
102
+ });
103
+ // Give any spurious transition a chance to land before we check.
104
+ await new Promise((resolve) => setTimeout(resolve, 100));
105
+ expect(harness.registry.get(dispatcher.state).enabled).toBe(true);
106
+ });
107
+ });
@@ -0,0 +1,126 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Fiber from 'effect/Fiber';
7
+
8
+ import { Capabilities, Capability } from '@dxos/app-framework';
9
+ import { type ComputeEnvironment } from '@dxos/client-protocol';
10
+ import { ServiceResolver } from '@dxos/compute';
11
+ import { Obj } from '@dxos/echo';
12
+ import { TriggerDispatcher } from '@dxos/functions-runtime';
13
+ import { type SpaceId } from '@dxos/keys';
14
+ import { log } from '@dxos/log';
15
+ import { ClientCapabilities } from '@dxos/plugin-client';
16
+ import { type Space } from '@dxos/react-client/echo';
17
+
18
+ //
19
+ // Capability Module
20
+ //
21
+ // Watches `space.properties.computeEnvironment` for every space and toggles
22
+ // the per-space {@link TriggerDispatcher} accordingly:
23
+ //
24
+ // - `local` → `dispatcher.start()`
25
+ // - `edge` / `disabled` → `dispatcher.stop()`
26
+ //
27
+ // Replaces the in-line watcher that used to live inside the removed
28
+ // `compute-runtime.ts` per-space layer. The dispatcher itself is now
29
+ // contributed unconditionally via `TriggerDispatcherSpec` in `layer-specs.ts`,
30
+ // so this capability is only responsible for driving its lifecycle.
31
+ //
32
+
33
+ /** Trigger execution location the dispatcher should run locally. */
34
+ const LOCAL_ENVIRONMENT: ComputeEnvironment = 'local';
35
+
36
+ export default Capability.makeModule(
37
+ Effect.fnUntraced(function* () {
38
+ const client = yield* Capability.get(ClientCapabilities.Client);
39
+ const runtime = yield* Capability.get(Capabilities.ProcessManagerRuntime);
40
+
41
+ /** Per-space property-subscription unsubscribe, last-seen environment, and in-flight transition fiber. */
42
+ type Tracker = {
43
+ unsubscribe: () => void;
44
+ lastEnvironment?: ComputeEnvironment;
45
+ inFlight?: Fiber.RuntimeFiber<unknown, unknown>;
46
+ };
47
+ const trackers = new Map<SpaceId, Tracker>();
48
+
49
+ /**
50
+ * Resolve the per-space `TriggerDispatcher` from the process-manager
51
+ * runtime and invoke `start()` / `stop()` according to the requested
52
+ * environment. Returns a fiber so the caller can cancel a pending
53
+ * transition when a new one supersedes it.
54
+ */
55
+ const transition = (spaceId: SpaceId, environment: ComputeEnvironment) =>
56
+ runtime.runFork(
57
+ Effect.gen(function* () {
58
+ const dispatcher = yield* TriggerDispatcher;
59
+ yield* environment === LOCAL_ENVIRONMENT ? dispatcher.start() : dispatcher.stop();
60
+ }).pipe(
61
+ Effect.provide(ServiceResolver.provide({ space: spaceId }, TriggerDispatcher)),
62
+ Effect.tapErrorCause((cause) =>
63
+ Effect.sync(() => log.warn('trigger dispatcher transition failed', { spaceId, environment, cause })),
64
+ ),
65
+ ),
66
+ );
67
+
68
+ const apply = (tracker: Tracker, spaceId: SpaceId, environment: ComputeEnvironment): void => {
69
+ if (tracker.lastEnvironment === environment) {
70
+ return;
71
+ }
72
+ tracker.lastEnvironment = environment;
73
+ if (tracker.inFlight) {
74
+ runtime.runFork(Fiber.interrupt(tracker.inFlight));
75
+ }
76
+ tracker.inFlight = transition(spaceId, environment);
77
+ };
78
+
79
+ const install = (space: Space): void => {
80
+ if (trackers.has(space.id)) {
81
+ return;
82
+ }
83
+ // Reserve the slot synchronously so concurrent `client.spaces.subscribe`
84
+ // notifications (e.g. spaces array churn while we await readiness) don't
85
+ // wire a second subscriber for the same space.
86
+ const tracker: Tracker = { unsubscribe: () => {} };
87
+ trackers.set(space.id, tracker);
88
+
89
+ void space
90
+ .waitUntilReady()
91
+ .then(() => {
92
+ // The capability could have been torn down between `set` and the
93
+ // promise resolving; bail out without subscribing in that case.
94
+ if (trackers.get(space.id) !== tracker) {
95
+ return;
96
+ }
97
+ const readEnvironment = (): ComputeEnvironment => space.properties.computeEnvironment ?? LOCAL_ENVIRONMENT;
98
+ tracker.unsubscribe = Obj.subscribe(space.properties, () => apply(tracker, space.id, readEnvironment()));
99
+ apply(tracker, space.id, readEnvironment());
100
+ })
101
+ .catch((err) => log.catch(err));
102
+ };
103
+
104
+ const installAll = (spaces: readonly Space[]): void => {
105
+ for (const space of spaces) {
106
+ install(space);
107
+ }
108
+ };
109
+
110
+ const spacesSubscription = client.spaces.subscribe(installAll);
111
+ installAll(client.spaces.get());
112
+
113
+ return Capability.contributes(Capabilities.Null, null, () =>
114
+ Effect.sync(() => {
115
+ spacesSubscription.unsubscribe();
116
+ for (const tracker of trackers.values()) {
117
+ tracker.unsubscribe();
118
+ if (tracker.inFlight) {
119
+ runtime.runFork(Fiber.interrupt(tracker.inFlight));
120
+ }
121
+ }
122
+ trackers.clear();
123
+ }),
124
+ );
125
+ }),
126
+ );
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './trigger';