@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,144 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ // @import-as-namespace
6
+
7
+ import * as Schema from 'effect/Schema';
8
+
9
+ import { Instructions, Runnable, Trigger } from '@dxos/compute';
10
+ // Operation is imported so TypeScript can name Operation.PersistentOperation in the emitted .d.ts
11
+ // (Runnable is an alias for Operation.PersistentOperation, so Routine's class type references it).
12
+ // eslint-disable-next-line unused-imports/no-unused-imports
13
+ import { Operation } from '@dxos/compute';
14
+ import { Annotation, DXN, Obj, Ref, Type } from '@dxos/echo';
15
+ import { LabelAnnotation } from '@dxos/echo/internal';
16
+
17
+ import { runInstructionsRef } from '../util/run-instructions';
18
+
19
+ const Kinds = ['runnable', 'instructions'] as const;
20
+ export const Kind = Schema.Literal(...Kinds);
21
+ export type Kind = (typeof Kinds)[number];
22
+
23
+ const RunnableSpec = Schema.Struct({
24
+ kind: Schema.Literal('runnable'),
25
+ runnable: Ref.Ref(Runnable.Runnable),
26
+ });
27
+
28
+ const InstructionsSpec = Schema.Struct({
29
+ kind: Schema.Literal('instructions'),
30
+ instructions: Ref.Ref(Instructions.Instructions),
31
+ });
32
+
33
+ const RoutineSpec = Schema.Union(RunnableSpec, InstructionsSpec);
34
+
35
+ /**
36
+ * User-facing routine: a thin aggregate of an action (`runnable`) and the triggers that fire it.
37
+ * App-level only — EDGE stays unaware of it (triggers point directly at the runnable).
38
+ */
39
+ export class Routine extends Type.makeObject<Routine>(DXN.make('org.dxos.type.routine', '0.2.0'))(
40
+ Schema.Struct({
41
+ name: Schema.String.pipe(Schema.optional),
42
+ description: Schema.String.pipe(Schema.optional),
43
+
44
+ /**
45
+ * The action to run: either an Operation (`spec.runnable`, bound directly) or the routine's own owned
46
+ * Instructions (`spec.instructions`). For an Operation action the trigger's `runnable` points at this
47
+ * Operation. For an Instructions action `spec.instructions` is the owned Instructions object (the operation
48
+ * is implicitly the static RunInstructions, so no separate operation ref is stored), and the trigger's
49
+ * `runnable` is RunInstructions with this instructions bound as its input.
50
+ */
51
+ // TODO(burdon): Change to Array? Or handle that case with a ComputeGraph runnable.
52
+ spec: RoutineSpec.pipe(Schema.optional),
53
+
54
+ /**
55
+ * Explicit membership, bi-directional with `trigger.runnable → runnable`. Required (not derived by query)
56
+ * because the runnable may be a shared registry operation referenced by multiple automations, which would
57
+ * conflate triggers. MVP enforces length <= 1.
58
+ */
59
+ triggers: Schema.Array(Ref.Ref(Trigger.Trigger)),
60
+ }).pipe(
61
+ LabelAnnotation.set(['name']),
62
+ Annotation.IconAnnotation.set({ icon: 'ph--lightning--regular', hue: 'amber' }),
63
+ ),
64
+ ) {}
65
+
66
+ /** Returns true when value is a Routine object. */
67
+ export const instanceOf = (value: unknown): value is Routine => Obj.instanceOf(Routine, value);
68
+
69
+ /**
70
+ * The owned Instructions ref of an instructions-action routine, or undefined for an operation action.
71
+ * Classification is explicit in `spec.kind`, so this needs no `.target` dereference; callers resolve the ref
72
+ * reactively (`useObject`) or asynchronously (`Database.load`) as appropriate.
73
+ */
74
+ export const instructionsRef = (routine: Pick<Routine, 'spec'>): Ref.Ref<Instructions.Instructions> | undefined =>
75
+ routine.spec?.kind === 'instructions' ? routine.spec.instructions : undefined;
76
+
77
+ /** The Operation (runnable) ref of an operation-action routine, or undefined for an instructions action. */
78
+ export const runnableRef = (routine: Pick<Routine, 'spec'>): Ref.Ref<Runnable.Runnable> | undefined =>
79
+ routine.spec?.kind === 'runnable' ? routine.spec.runnable : undefined;
80
+
81
+ /** Strip a stale `instructions` binding from a trigger input. */
82
+ const withoutInstructions = (input: Record<string, unknown> | undefined): Record<string, unknown> | undefined => {
83
+ if (!input || !('instructions' in input)) {
84
+ return input;
85
+ }
86
+ const { instructions: _drop, ...rest } = input;
87
+ return rest;
88
+ };
89
+
90
+ /**
91
+ * Wire the routine's owned triggers to dispatch its current action (`spec`): an instructions action sets each
92
+ * trigger's `runnable` to RunInstructions with the owned instructions bound into `input`; an operation action
93
+ * binds the operation directly and drops any stale instructions binding. Call after the action (`spec`) changes
94
+ * so a trigger never keeps a binding for the previous action.
95
+ */
96
+ export const wireTriggers = (routine: Routine): void => {
97
+ const instructions = instructionsRef(routine);
98
+ const fn = instructions ? runInstructionsRef() : runnableRef(routine);
99
+ for (const ref of routine.triggers) {
100
+ const trigger = ref.target;
101
+ if (!trigger) {
102
+ continue;
103
+ }
104
+ Obj.update(trigger, (trigger) => {
105
+ trigger.runnable = fn;
106
+ const base = withoutInstructions(trigger.input);
107
+ trigger.input = instructions ? { input: {}, ...base, instructions } : base;
108
+ });
109
+ }
110
+ };
111
+
112
+ /**
113
+ * Creates a fully-wired in-memory routine graph. `instructions` and `trigger` are optional extras beyond the
114
+ * schema fields: when provided they are parented under the routine and wired together (runnable, trigger
115
+ * runnable, the trigger's instructions input binding, and the `triggers` ref) so that a single `Database.add`
116
+ * cascades the whole graph. `triggers` defaults to `[]` so callers that supply a `trigger` need not provide it.
117
+ */
118
+ export const make = ({
119
+ instructions,
120
+ trigger,
121
+ triggers = [],
122
+ ...props
123
+ }: Omit<Obj.MakeProps<typeof Routine>, 'triggers'> & {
124
+ triggers?: ReadonlyArray<Ref.Ref<Trigger.Trigger>>;
125
+ instructions?: Instructions.Instructions;
126
+ trigger?: Trigger.Trigger;
127
+ }): Routine => {
128
+ const routine = Obj.make(Routine, { ...props, triggers });
129
+ if (instructions) {
130
+ Obj.setParent(instructions, routine);
131
+ Obj.update(routine, (routine) => {
132
+ routine.spec = { kind: 'instructions', instructions: Ref.make(instructions) };
133
+ });
134
+ }
135
+ if (trigger) {
136
+ Obj.setParent(trigger, routine);
137
+ Obj.update(routine, (routine) => {
138
+ routine.triggers.push(Ref.make(trigger));
139
+ });
140
+ // Wire the trigger's `runnable`/`input` from the action (`spec`); preserves any template-provided input.
141
+ wireTriggers(routine);
142
+ }
143
+ return routine;
144
+ };
@@ -0,0 +1,51 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import type * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import type { Database, Obj } from '@dxos/echo';
9
+ import type { DelegationStrategy } from '@dxos/functions-runtime';
10
+
11
+ import * as Routine from './Routine';
12
+
13
+ /**
14
+ * Optional supervisor strategy for the agent chat service. When contributed (by a plugin that knows
15
+ * the agent/plan model, e.g. plugin-assistant), the conversational agent delegates outstanding work
16
+ * to sub-agents and folds their results back into the conversation. Consumed by the AgentService
17
+ * LayerSpec; absent by default (a plain conversational agent).
18
+ */
19
+ export const AgentDelegationStrategy = Capability.make<DelegationStrategy>(
20
+ 'org.dxos.plugin.routine.capability.agentDelegationStrategy',
21
+ );
22
+
23
+ /**
24
+ * An automation template contributed by a plugin. The create dialog and the per-object "Automations"
25
+ * companion list contributed templates (`Capability.getAll(RoutineCapabilities.Template)`) and run the
26
+ * chosen template's `scaffold` to build the automation.
27
+ */
28
+ export type Template = {
29
+ /** Stable id (e.g. 'org.dxos.routine.blank'). */
30
+ id: string;
31
+ /** Human-readable label shown in the picker. */
32
+ label: string;
33
+ /** Optional Phosphor icon name. */
34
+ icon?: string;
35
+ /**
36
+ * Whether this template applies to the given companion subject. The subject is the object whose
37
+ * "Automations" companion is open, or undefined in the global create dialog. Templates that need a
38
+ * specific subject (e.g. a feed-bearing Mailbox) gate themselves here. Defaults to always-applies.
39
+ */
40
+ appliesTo?: (subject?: Obj.Unknown) => boolean;
41
+ /**
42
+ * Build the routine as a fully-wired in-memory {@link Routine.Routine} graph — the routine plus its owned
43
+ * trigger and instructions, assembled by `Routine.make`. The create flow persists it with a single
44
+ * `Database.add` (which cascades the owned children); scaffold must NOT call `Database.add` itself.
45
+ * `Database.Service` may still be used for read-only lookups (e.g. loading a feed ref). `subject` is set
46
+ * when scaffolding from an object's companion.
47
+ */
48
+ scaffold: (ctx: { name?: string; subject?: Obj.Unknown }) => Effect.Effect<Routine.Routine, Error, Database.Service>;
49
+ };
50
+
51
+ export const Template = Capability.make<Template>('org.dxos.plugin.routine.capability.template');
@@ -0,0 +1,104 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // @import-as-namespace
6
+
7
+ import * as Schema from 'effect/Schema';
8
+
9
+ import { Capability } from '@dxos/app-framework';
10
+ import { Chat } from '@dxos/assistant-toolkit';
11
+ import { Instructions, Operation } from '@dxos/compute';
12
+ import { Database, DXN, Obj, Ref, Type } from '@dxos/echo';
13
+ // Value-side `EID` import keeps TS declaration emit portable — `TriggerTemplate`
14
+ // references `EID.Schema` and the inferred `CreateTriggerFromTemplate` type
15
+ // otherwise needs a transitive `@dxos/keys` import that's hard for d.ts emit to surface.
16
+ import { EID as _EchoURIReference } from '@dxos/keys';
17
+
18
+ import { meta } from '#meta';
19
+
20
+ import * as Routine from './Routine';
21
+ import { TriggerTemplate } from './schema';
22
+ export { _EchoURIReference };
23
+
24
+ const makeKey = (name: string) => DXN.make(`${meta.profile.key}.operation.${name}`);
25
+
26
+ export const CreateTriggerFromTemplate = Operation.make({
27
+ meta: {
28
+ key: makeKey('createTriggerFromTemplate'),
29
+ name: 'Create Trigger From Template',
30
+ icon: 'ph--lightning--regular',
31
+ },
32
+ services: [Capability.Service],
33
+ input: Schema.Struct({
34
+ db: Database.Database,
35
+ template: TriggerTemplate,
36
+ enabled: Schema.optional(Schema.Boolean),
37
+ scriptName: Schema.optional(Schema.String),
38
+ input: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.Any })),
39
+ }),
40
+ output: Schema.Void,
41
+ });
42
+
43
+ // The single creation entrypoint for every path (create dialog, companion, sidebar) so placement and
44
+ // ownership are established in one place. Output mirrors `SpaceCapabilities.CreateObjectResult`.
45
+ export const CreateRoutine = Operation.make({
46
+ meta: {
47
+ key: makeKey('createAutomation'),
48
+ name: 'Create Routine',
49
+ icon: 'ph--lightning--regular',
50
+ },
51
+ services: [Capability.Service],
52
+ input: Schema.Struct({
53
+ db: Database.Database,
54
+ templateId: Schema.String,
55
+ name: Schema.optional(Schema.String),
56
+ subject: Schema.optional(Obj.Unknown),
57
+ }),
58
+ output: Schema.Struct({
59
+ id: Schema.String,
60
+ subject: Schema.Array(Schema.String),
61
+ object: Obj.Unknown,
62
+ }),
63
+ });
64
+
65
+ export const RunPromptInNewChat = Operation.make({
66
+ meta: {
67
+ key: makeKey('runPromptInNewChat'),
68
+ name: 'Run Prompt In New Chat',
69
+ icon: 'ph--chat-text--regular',
70
+ },
71
+ services: [Capability.Service],
72
+ input: Schema.Struct({
73
+ db: Database.Database,
74
+ /** Context objects to bind to the new chat. */
75
+ objects: Schema.optional(Schema.Array(Obj.Unknown)),
76
+ /** Skill keys to look up and bind to the new chat. */
77
+ skills: Schema.optional(Schema.Array(Schema.String)),
78
+ /** Raw instructions or an existing Routine object reference. */
79
+ instructions: Schema.Union(Schema.String, Ref.Ref(Instructions.Instructions)),
80
+ /**
81
+ * When true, skips opening the chat: runs the Agent prompt operation against the new chat via the compute runtime (traced).
82
+ */
83
+ background: Schema.optional(Schema.Boolean),
84
+ }),
85
+ output: Schema.Struct({
86
+ object: Type.getSchema(Chat.Chat),
87
+ }),
88
+ });
89
+
90
+ // Runs a routine's `runnable` directly (bypassing its triggers). The runnable receives no input;
91
+ // the trigger-driven path is what supplies event-mapped input, so manual runs target runnables that
92
+ // need none.
93
+ export const RunRoutine = Operation.make({
94
+ meta: {
95
+ key: makeKey('runAutomation'),
96
+ name: 'Run Routine',
97
+ icon: 'ph--play--regular',
98
+ },
99
+ services: [Capability.Service],
100
+ input: Schema.Struct({
101
+ routine: Ref.Ref(Routine.Routine),
102
+ }),
103
+ output: Schema.Void,
104
+ });
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './schema';
6
+
7
+ export * as Routine from './Routine';
8
+ export * as RoutineCapabilities from './RoutineCapabilities';
9
+ export * as RoutineOperation from './RoutineOperation';
@@ -0,0 +1,31 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+
7
+ import { Database } from '@dxos/echo';
8
+
9
+ import { meta } from '#meta';
10
+
11
+ export const TriggerTemplate = Schema.Union(
12
+ Schema.Struct({ type: Schema.Literal('timer'), cron: Schema.String }),
13
+ Schema.Struct({ type: Schema.Literal('feed'), feed: Schema.Any }),
14
+ );
15
+
16
+ export namespace AutomationAction {
17
+ export class CreateTriggerFromTemplate extends Schema.TaggedClass<CreateTriggerFromTemplate>()(
18
+ `${meta.profile.key}.action.create-trigger-from-template`,
19
+ {
20
+ input: Schema.Struct({
21
+ db: Database.Database,
22
+ template: TriggerTemplate,
23
+ enabled: Schema.optional(Schema.Boolean),
24
+ // TODO(wittjosiah): Improve how this lookup is done.
25
+ scriptName: Schema.optional(Schema.String),
26
+ input: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.Any })),
27
+ }),
28
+ output: Schema.Void,
29
+ },
30
+ ) {}
31
+ }
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './routines-for-object';
6
+ export * from './run-instructions';
@@ -0,0 +1,109 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+ import { describe, test } from 'vitest';
7
+
8
+ import { Instructions, Trigger } from '@dxos/compute';
9
+ import { type Database, DXN, Feed, Obj, Ref, Type } from '@dxos/echo';
10
+ import { EffectEx } from '@dxos/effect';
11
+ import { EID, URI } from '@dxos/keys';
12
+ import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
13
+ import { ClientPlugin, initializeIdentity } from '@dxos/plugin-client/testing';
14
+ import { createComposerTestApp } from '@dxos/plugin-testing/harness';
15
+
16
+ import { Routine } from '#types';
17
+
18
+ import { connectedRoutinesQuery, routinesForObject } from './routines-for-object';
19
+
20
+ // A minimal feed-annotated host (like a mailbox): an object holding a `feed` ref.
21
+ const FeedHost = Type.makeObject(DXN.make('org.dxos.test.feedHost', '0.1.0'))(
22
+ Schema.Struct({
23
+ name: Schema.optional(Schema.String),
24
+ feed: Ref.Ref(Feed.Feed),
25
+ }),
26
+ );
27
+
28
+ const types = [Routine.Routine, Trigger.Trigger, Instructions.Instructions, Feed.Feed, FeedHost];
29
+
30
+ const initSpace = async (harness: Awaited<ReturnType<typeof createComposerTestApp>>) => {
31
+ const { personalSpace } = await EffectEx.runAndForwardErrors(
32
+ initializeIdentity(harness.get(ClientCapabilities.Client)),
33
+ );
34
+ await harness.waitForEvent(ClientEvents.SpacesReady);
35
+ return personalSpace.db;
36
+ };
37
+
38
+ const connectedIds = (db: Database.Database, object: Obj.Unknown) =>
39
+ db
40
+ .query(connectedRoutinesQuery(object))
41
+ .run()
42
+ .then((routines) => routines.map((routine) => routine.id).sort());
43
+
44
+ // Build a space-qualified ref like the RefField object picker does (from the entity's fully-qualified URI),
45
+ // rather than the bare ref `Ref.make` produces — this is the encoding real triggers carry, and it exercises
46
+ // the reverse-ref EID normalization that lets qualified refs match a space-less anchor.
47
+ const qualifiedRef = (db: Database.Database, object: Obj.Unknown) =>
48
+ Ref.fromURI(URI.make(EID.make({ spaceId: db.spaceId, entityId: object.id })));
49
+
50
+ describe('routines connected to an object', () => {
51
+ test('input-ref: trigger whose nested input references the object', async ({ expect }) => {
52
+ await using harness = await createComposerTestApp({ plugins: [ClientPlugin({ types })] });
53
+ const db = await initSpace(harness);
54
+
55
+ const target = db.add(Routine.make({ name: 'target', triggers: [] }));
56
+ const other = db.add(Routine.make({ name: 'other', triggers: [] }));
57
+ // The target ref is nested in the trigger's untyped `input` record, and is space-qualified like a
58
+ // picker-created ref.
59
+ const trigger = db.add(Trigger.make({ input: { subject: qualifiedRef(db, target) } }));
60
+ const owner = db.add(Routine.make({ name: 'owner', triggers: [Ref.make(trigger)] }));
61
+ await db.flush();
62
+
63
+ expect(routinesForObject(target, [owner, other]).map((routine) => routine.id)).toEqual([owner.id]);
64
+ expect(routinesForObject(other, [owner])).toEqual([]);
65
+
66
+ // Poll to absorb index latency; the query resolves via the reverse-ref index.
67
+ await expect.poll(() => connectedIds(db, target), { timeout: 5_000 }).toEqual([owner.id]);
68
+ await expect.poll(() => connectedIds(db, other), { timeout: 5_000 }).toEqual([]);
69
+ });
70
+
71
+ test("feed-ref: feed trigger bound to the object's feed", async ({ expect }) => {
72
+ await using harness = await createComposerTestApp({ plugins: [ClientPlugin({ types })] });
73
+ const db = await initSpace(harness);
74
+
75
+ const feed = db.add(Feed.make());
76
+ const host = db.add(Obj.make(FeedHost, { name: 'mailbox', feed: Ref.make(feed) }));
77
+ const other = db.add(Routine.make({ name: 'other', triggers: [] }));
78
+ // Picker-created feed refs are space-qualified (unlike `Trigger.specFeed`'s bare `Ref.make`); the host's
79
+ // own feed ref is bare (code-created). They must still match through the reverse-ref index.
80
+ const feedTrigger = db.add(Trigger.make({ spec: { kind: 'feed', feed: qualifiedRef(db, feed) } }));
81
+ const owner = db.add(Routine.make({ name: 'feed-owner', triggers: [Ref.make(feedTrigger)] }));
82
+ await db.flush();
83
+
84
+ expect(routinesForObject(host, [owner, other]).map((routine) => routine.id)).toEqual([owner.id]);
85
+
86
+ await expect.poll(() => connectedIds(db, host), { timeout: 5_000 }).toEqual([owner.id]);
87
+ });
88
+
89
+ test('instructions-ref: routine whose runnable instructions list the object in their `objects`', async ({
90
+ expect,
91
+ }) => {
92
+ await using harness = await createComposerTestApp({ plugins: [ClientPlugin({ types })] });
93
+ const db = await initSpace(harness);
94
+
95
+ const target = db.add(Routine.make({ name: 'target', triggers: [] }));
96
+ const other = db.add(Routine.make({ name: 'other', triggers: [] }));
97
+ // The routine's action is owned instructions that bind the object as a context object — the second
98
+ // connection path (O ← Instructions.objects ← Routine via spec.instructions), with no trigger involved.
99
+ const instructions = db.add(Instructions.make({ objects: [qualifiedRef(db, target)] }));
100
+ const owner = db.add(Routine.make({ name: 'owner', instructions }));
101
+ await db.flush();
102
+
103
+ expect(routinesForObject(target, [owner, other]).map((routine) => routine.id)).toEqual([owner.id]);
104
+ expect(routinesForObject(other, [owner])).toEqual([]);
105
+
106
+ await expect.poll(() => connectedIds(db, target), { timeout: 5_000 }).toEqual([owner.id]);
107
+ await expect.poll(() => connectedIds(db, other), { timeout: 5_000 }).toEqual([]);
108
+ });
109
+ });
@@ -0,0 +1,89 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Instructions, Trigger } from '@dxos/compute';
6
+ import { Filter, Obj, Query, Ref } from '@dxos/echo';
7
+
8
+ import { Routine } from '#types';
9
+
10
+ /**
11
+ * Reactive query for all routines connected to an object O, via two structural paths:
12
+ *
13
+ * 1. **Trigger path** (two hops): O is referenced by a Trigger (via `input` or `spec.feed`), and that
14
+ * Trigger is referenced by a Routine's `triggers` array.
15
+ * 2. **Instructions path** (two hops): O is listed in an Instructions' `objects` context array, and those
16
+ * Instructions are the Routine's action (`spec.instructions`). Both hops traverse `Ref` fields, so they are
17
+ * fully queryable — no JavaScript parent-symbol traversal needed.
18
+ *
19
+ * ECHO's reverse-ref index is structural — it tracks every `Ref` regardless of schema path, including
20
+ * nested untyped records and union fields — so all variants are covered.
21
+ */
22
+ export const connectedRoutinesQuery = (object: Obj.Unknown): Query.Query<Routine.Routine> => {
23
+ // Trigger path: O ← Trigger (any ref path, incl. nested `input`) ← Routine.triggers.
24
+ const byInput = Query.select(Filter.id(object.id)).referencedBy(Trigger.Trigger);
25
+ // Feed variant: O's feed ← Trigger.spec.feed ← Routine.triggers.
26
+ // `.reference('feed')` is empty for objects without a feed prop, so this adds nothing for non-feed objects.
27
+ const byFeed = Query.select(Filter.id(object.id)).reference('feed').referencedBy(Trigger.Trigger);
28
+ const byTrigger = Query.all(byInput, byFeed).referencedBy(Routine.Routine, 'triggers');
29
+
30
+ // Instructions path: O ← Instructions.objects ← Routine (via `spec.instructions`). The second hop drops the
31
+ // property key: the instructions ref is nested in the `spec` union, and the reverse-ref index is structural,
32
+ // so a keyless `referencedBy` matches it (a routine only references its own owned instructions here).
33
+ const byInstructions = Query.select(Filter.id(object.id))
34
+ .referencedBy(Instructions.Instructions, 'objects')
35
+ .referencedBy(Routine.Routine);
36
+
37
+ return Query.all(byTrigger, byInstructions);
38
+ };
39
+
40
+ /**
41
+ * Pure predicate equivalent of {@link connectedRoutinesQuery}, over a pre-queried list of routines.
42
+ * Kept for unit tests (asserting the query and predicate agree) and the deferred quick-association check.
43
+ */
44
+ export const routinesForObject = (object: Obj.Unknown, routines: Routine.Routine[]): Routine.Routine[] =>
45
+ routines.filter((routine) => routineReferencesObject(routine, object));
46
+
47
+ export const routineReferencesObject = (routine: Routine.Routine, object: Obj.Unknown): boolean =>
48
+ referencesViaTrigger(routine, object) || referencesViaInstructions(routine, object);
49
+
50
+ /** Trigger path: a trigger's `input` references O, or a feed trigger is bound to O's feed. */
51
+ const referencesViaTrigger = (routine: Routine.Routine, object: Obj.Unknown): boolean => {
52
+ const objectFeedId = getFeedId(object);
53
+ return routine.triggers.some((ref) => {
54
+ const trigger = ref.target;
55
+ if (!Obj.instanceOf(Trigger.Trigger, trigger)) {
56
+ return false;
57
+ }
58
+
59
+ if (trigger.spec?.kind === 'feed' && objectFeedId && trigger.spec.feed?.target?.id === objectFeedId) {
60
+ return true;
61
+ }
62
+
63
+ return trigger.input != null && referencesId(trigger.input, object.id);
64
+ });
65
+ };
66
+
67
+ /** Instructions path: the routine's owned instructions list O in their `objects` context array. */
68
+ const referencesViaInstructions = (routine: Routine.Routine, object: Obj.Unknown): boolean =>
69
+ Routine.instructionsRef(routine)?.target?.objects?.some((ref) => ref.target?.id === object.id) ?? false;
70
+
71
+ /** The feed id a feed-annotated object points at (e.g. `mailbox.feed`), if any. */
72
+ const getFeedId = (object: Obj.Unknown): string | undefined => {
73
+ const feedRef = (object as { feed?: Ref.Ref<unknown> }).feed;
74
+ return Ref.isRef(feedRef) ? feedRef.target?.id : undefined;
75
+ };
76
+
77
+ /** Recursively scan a value for a Ref whose target is the given object id. */
78
+ const referencesId = (value: unknown, id: string): boolean => {
79
+ if (Ref.isRef(value)) {
80
+ return value.target?.id === id;
81
+ }
82
+ if (Array.isArray(value)) {
83
+ return value.some((entry) => referencesId(entry, id));
84
+ }
85
+ if (value && typeof value === 'object') {
86
+ return Object.values(value).some((entry) => referencesId(entry, id));
87
+ }
88
+ return false;
89
+ };
@@ -0,0 +1,23 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { describe, test } from 'vitest';
6
+
7
+ import { RunInstructions } from '@dxos/assistant-toolkit';
8
+ import { Ref, URI } from '@dxos/echo';
9
+
10
+ import { isRunInstructions, runInstructionsRef } from './run-instructions';
11
+
12
+ describe('RunInstructions registry reference', () => {
13
+ test('runInstructionsRef targets the RunInstructions registry DXN', ({ expect }) => {
14
+ const ref = runInstructionsRef();
15
+ expect(ref.uri).toBe(RunInstructions.meta.key);
16
+ expect(isRunInstructions(ref)).toBe(true);
17
+ });
18
+
19
+ test('isRunInstructions rejects other refs and non-refs', ({ expect }) => {
20
+ expect(isRunInstructions(undefined)).toBe(false);
21
+ expect(isRunInstructions(Ref.fromURI(URI.make('dxn:org.dxos.test.otherOperation')))).toBe(false);
22
+ });
23
+ });
@@ -0,0 +1,12 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { RunInstructions } from '@dxos/assistant-toolkit';
6
+ import { Ref } from '@dxos/echo';
7
+
8
+ /** A ref to the shared RunInstructions operation in the registry (resolved via the registry, not the database). */
9
+ export const runInstructionsRef = () => Ref.fromURI(RunInstructions.meta.key);
10
+
11
+ /** Whether a trigger's `function` ref targets the registry RunInstructions operation (i.e. an instructions action). */
12
+ export const isRunInstructions = (fn: unknown): boolean => Ref.isRef(fn) && fn.uri === RunInstructions.meta.key;
@@ -0,0 +1,10 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ //
4
+ // Copyright 2026 DXOS.org
5
+ //
6
+
7
+ declare module '*.mdl?raw' {
8
+ const content: string;
9
+ export default content;
10
+ }