@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,412 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Prompt from '@effect/cli/Prompt';
6
+ import * as Ansi from '@effect/printer-ansi/Ansi';
7
+ import * as Console from 'effect/Console';
8
+ import * as Effect from 'effect/Effect';
9
+ import * as Match from 'effect/Match';
10
+ import * as Option from 'effect/Option';
11
+ import type * as Schema from 'effect/Schema';
12
+ import * as SchemaAST from 'effect/SchemaAST';
13
+
14
+ import { FormBuilder } from '@dxos/cli-util';
15
+ import { Operation, Trigger } from '@dxos/compute';
16
+ // eslint-disable-next-line unused-imports/no-unused-imports
17
+ import { Annotation, Database, Entity, Feed, Filter, Obj, Query, type QueryAST, Ref, Scope, Type } from '@dxos/echo';
18
+ import { SchemaEx } from '@dxos/effect';
19
+ import { DXN } from '@dxos/keys';
20
+ import { FeedAnnotation } from '@dxos/schema';
21
+
22
+ export type TriggerRemoteStatus = 'available' | 'not available' | 'n/a';
23
+
24
+ /**
25
+ * Determines the remote status of a trigger.
26
+ * Only timer/cron triggers can be checked for remote availability.
27
+ */
28
+ export const getTriggerRemoteStatus = (trigger: Trigger.Trigger, remoteCronIds: string[]): TriggerRemoteStatus => {
29
+ if (trigger.spec?.kind !== 'timer') {
30
+ return 'n/a';
31
+ }
32
+ return remoteCronIds.includes(trigger.id) ? 'available' : 'not available';
33
+ };
34
+
35
+ /**
36
+ * Pretty prints a trigger with ANSI colors.
37
+ */
38
+ export const printTrigger = Effect.fn(function* (trigger: Trigger.Trigger, remoteStatus?: TriggerRemoteStatus) {
39
+ const fn = trigger.runnable && (yield* Database.load(trigger.runnable));
40
+
41
+ return FormBuilder.make({
42
+ title: trigger.id,
43
+ }).pipe(
44
+ FormBuilder.set(
45
+ 'status',
46
+ trigger.enabled ? 'enabled' : 'disabled',
47
+ trigger.enabled ? Ansi.green : Ansi.blackBright,
48
+ ),
49
+ FormBuilder.option('kind', Option.fromNullable(trigger.spec?.kind)),
50
+ FormBuilder.option(
51
+ 'remote',
52
+ Option.fromNullable(remoteStatus),
53
+ Match.type<TriggerRemoteStatus>().pipe(
54
+ Match.withReturnType<Ansi.Ansi>(),
55
+ Match.when('available', () => Ansi.green),
56
+ Match.when('not available', () => Ansi.yellow),
57
+ Match.when('n/a', () => Ansi.blackBright),
58
+ Match.exhaustive,
59
+ ),
60
+ ),
61
+ FormBuilder.when(
62
+ fn,
63
+ FormBuilder.nest(
64
+ 'function',
65
+ FormBuilder.make().pipe(
66
+ FormBuilder.set('key', Obj.getMeta(fn as Operation.PersistentOperation).key),
67
+ FormBuilder.set('dxn', Obj.getURI(fn as Obj.Unknown)),
68
+ ),
69
+ ),
70
+ ),
71
+ FormBuilder.nestedOption('spec', Option.fromNullable(trigger.spec).pipe(Option.map(printSpec))),
72
+ FormBuilder.build,
73
+ );
74
+ });
75
+
76
+ const printSpec = <T extends Trigger.Spec>(spec: T): FormBuilder.FormBuilder => {
77
+ switch (spec.kind) {
78
+ case 'timer':
79
+ return printTimer(spec);
80
+ case 'subscription':
81
+ return printSubscription(spec);
82
+ case 'webhook':
83
+ return printWebhook(spec);
84
+ case 'feed':
85
+ return printFeed(spec);
86
+ default:
87
+ return FormBuilder.make({}).pipe(FormBuilder.set('unknown', 'Unknown spec type'));
88
+ }
89
+ };
90
+
91
+ const printTimer = (spec: Trigger.TimerSpec) => FormBuilder.make({}).pipe(FormBuilder.set('cron', spec.cron));
92
+
93
+ const printSubscription = (spec: Trigger.SubscriptionSpec) =>
94
+ FormBuilder.make({}).pipe(FormBuilder.set('query', spec.query?.raw ?? '[Query AST]'));
95
+
96
+ const printWebhook = (spec: Trigger.WebhookSpec) =>
97
+ FormBuilder.make({}).pipe(FormBuilder.set('method', spec.method), FormBuilder.set('port', spec.port));
98
+
99
+ const printFeed = (spec: Trigger.FeedSpec) =>
100
+ FormBuilder.make({}).pipe(FormBuilder.set('feed', spec.feed ? spec.feed.uri.toString() : '(none)'));
101
+
102
+ /**
103
+ * Prompts for input values based on an Effect schema.
104
+ * First shows a multi-select to choose which properties to specify,
105
+ * then prompts for values of the selected properties.
106
+ * Required properties are automatically included and cannot be unselected.
107
+ * @param schema - The Effect schema to prompt for
108
+ * @param defaults - Optional default values to use as initial values and pre-select optional properties
109
+ */
110
+ export const promptForSchemaInput = Effect.fn(function* (
111
+ schema: Schema.Schema.AnyNoContext | undefined,
112
+ defaults?: Record<string, any> | undefined,
113
+ ) {
114
+ if (!schema) {
115
+ return {};
116
+ }
117
+
118
+ const ast = schema.ast;
119
+
120
+ // Check if it's a struct/object type
121
+ if (!SchemaAST.isTypeLiteral(ast)) {
122
+ return {};
123
+ }
124
+
125
+ const properties = SchemaEx.getProperties(ast);
126
+ if (properties.length === 0) {
127
+ return {};
128
+ }
129
+
130
+ // Separate required and optional properties
131
+ const requiredProperties: typeof properties = [];
132
+ const optionalProperties: typeof properties = [];
133
+
134
+ for (const prop of properties) {
135
+ if (prop.isOptional) {
136
+ optionalProperties.push(prop);
137
+ } else {
138
+ requiredProperties.push(prop);
139
+ }
140
+ }
141
+
142
+ // Build property info
143
+ const propertyInfo = properties.map((prop) => {
144
+ const key = prop.name.toString();
145
+ return {
146
+ prop,
147
+ key,
148
+ isRequired: !prop.isOptional,
149
+ };
150
+ });
151
+
152
+ // Multi-select: show all properties and let user select which optional ones to include
153
+ const selectedKeys = new Set<string>();
154
+
155
+ // Required properties are automatically selected
156
+ for (const info of propertyInfo) {
157
+ if (info.isRequired) {
158
+ selectedKeys.add(info.key);
159
+ }
160
+ }
161
+
162
+ // Show required properties that will be automatically included
163
+ if (requiredProperties.length > 0) {
164
+ const requiredNames = requiredProperties.map((p) => {
165
+ const info = propertyInfo.find((i) => i.prop === p);
166
+ return info?.key ?? p.name.toString();
167
+ });
168
+ yield* Console.log(`Required properties (will be included): ${requiredNames.join(', ')}`);
169
+ }
170
+
171
+ // For optional properties, use multi-select to choose which ones to include
172
+ if (optionalProperties.length > 0) {
173
+ const optionalInfo = propertyInfo.filter((info) => !info.isRequired);
174
+ const choices = optionalInfo.map((info) => {
175
+ const hasDefault = defaults?.[info.key] !== undefined;
176
+ const defaultText = hasDefault ? ` (current: ${JSON.stringify(defaults[info.key])})` : '';
177
+ return {
178
+ title: `${info.key}${defaultText}`,
179
+ value: info.key,
180
+ description: hasDefault ? 'Has default value' : undefined,
181
+ };
182
+ });
183
+
184
+ const selected = yield* Prompt.multiSelect({
185
+ message: 'Select optional properties to include:',
186
+ choices,
187
+ });
188
+
189
+ // Add selected optional properties to selectedKeys
190
+ for (const key of selected) {
191
+ selectedKeys.add(String(key));
192
+ }
193
+ }
194
+
195
+ // If no properties selected (shouldn't happen if there are required ones), return empty
196
+ if (selectedKeys.size === 0) {
197
+ return {};
198
+ }
199
+
200
+ // Prompt for values of selected properties
201
+ const inputObj: Record<string, any> = {};
202
+
203
+ for (const info of propertyInfo) {
204
+ if (!selectedKeys.has(info.key)) {
205
+ continue;
206
+ }
207
+
208
+ const key = info.key;
209
+ const propType = info.prop.type;
210
+ const schemaDefault = Option.getOrUndefined(SchemaAST.getDefaultAnnotation(propType));
211
+ const defaultValue = defaults?.[key] ?? schemaDefault;
212
+
213
+ if (SchemaAST.isBooleanKeyword(propType)) {
214
+ const initialValue =
215
+ typeof defaultValue === 'boolean' ? defaultValue : typeof schemaDefault === 'boolean' ? schemaDefault : false;
216
+ const value = yield* Prompt.confirm({
217
+ message: `${info.key}${defaults?.[key] !== undefined ? ` (current: ${defaults[key]})` : ''}:`,
218
+ initial: initialValue,
219
+ });
220
+ inputObj[key] = value;
221
+ } else if (SchemaAST.isNumberKeyword(propType)) {
222
+ const currentValue = typeof defaultValue === 'number' ? String(defaultValue) : '';
223
+ const valueStr = yield* Prompt.text({
224
+ message: `${info.key}${currentValue ? ` (current: ${currentValue}, press Enter to keep)` : ''}:`,
225
+ }).pipe(Prompt.run);
226
+ inputObj[key] = valueStr === '' && defaultValue !== undefined ? defaultValue : parseFloat(valueStr) || 0;
227
+ } else if (SchemaAST.isStringKeyword(propType)) {
228
+ const currentValue = typeof defaultValue === 'string' ? defaultValue : '';
229
+ const valueStr = yield* Prompt.text({
230
+ message: `${info.key}${currentValue ? ` (current: ${currentValue}, press Enter to keep)` : ''}:`,
231
+ }).pipe(Prompt.run);
232
+ inputObj[key] = valueStr === '' && defaultValue !== undefined ? defaultValue : valueStr;
233
+ } else if (Ref.isRefType(propType)) {
234
+ const isDefaultTemplate =
235
+ typeof defaultValue === 'string' && defaultValue.startsWith('{{') && defaultValue.endsWith('}}');
236
+ const useTemplate = yield* Prompt.confirm({
237
+ message: `Use a template to specify ${info.key}?${isDefaultTemplate ? ' (current: template)' : ''}`,
238
+ initial: isDefaultTemplate,
239
+ });
240
+ if (useTemplate) {
241
+ const currentValue = typeof defaultValue === 'string' ? defaultValue : '';
242
+ const templateStr = yield* Prompt.text({
243
+ message: `${info.key} template${currentValue ? ` (current: ${currentValue}, press Enter to keep)` : ''}:`,
244
+ }).pipe(Prompt.run);
245
+ inputObj[key] = templateStr === '' && defaultValue !== undefined ? defaultValue : templateStr;
246
+ } else {
247
+ const annotation = Annotation.ReferenceAnnotation.getFromAst(propType).pipe(Option.getOrThrow);
248
+ const objects = yield* Database.query(Filter.type(DXN.make(annotation.typename))).run;
249
+ if (objects.length === 0) {
250
+ inputObj[key] = undefined;
251
+ } else {
252
+ const selected = yield* Prompt.select({
253
+ message: `Select ${info.key}:`,
254
+ choices: objects.map((obj: Entity.Any) => ({
255
+ title: Entity.getLabel(obj) ?? obj.id,
256
+ value: Ref.make(obj),
257
+ description: Entity.getDescription(obj),
258
+ })),
259
+ });
260
+ inputObj[key] = selected;
261
+ }
262
+ }
263
+ } else {
264
+ // For other types, prompt as string and let validation handle it
265
+ const currentValue = defaultValue !== undefined ? String(defaultValue) : '';
266
+ const valueStr = yield* Prompt.text({
267
+ message: `${info.key}${currentValue ? ` (current: ${currentValue}, press Enter to keep)` : ''}:`,
268
+ }).pipe(Prompt.run);
269
+ inputObj[key] = valueStr === '' && defaultValue !== undefined ? defaultValue : valueStr;
270
+ }
271
+ }
272
+
273
+ return inputObj;
274
+ });
275
+
276
+ /**
277
+ * Selects a function interactively from available functions in the database.
278
+ * Queries the database for functions and prompts the user to select one.
279
+ */
280
+ export const selectFunction = Effect.fn(function* () {
281
+ const allFunctions = yield* Database.query(Filter.type(Operation.PersistentOperation)).run;
282
+ // Hide internal operations: only operations annotated visible are user-bindable as trigger actions.
283
+ const functions = allFunctions.filter((fn) => Operation.isVisible(fn));
284
+
285
+ if (functions.length === 0) {
286
+ return yield* Effect.fail(new Error('No functions available'));
287
+ }
288
+
289
+ const selected = yield* Prompt.select({
290
+ message: 'Select a function:',
291
+ choices: functions.map((fn: Operation.PersistentOperation) => ({
292
+ title: fn.name ?? fn.id,
293
+ value: fn.id,
294
+ description: fn.description,
295
+ })),
296
+ });
297
+
298
+ return String(selected);
299
+ });
300
+
301
+ /**
302
+ * Selects a trigger interactively from available triggers.
303
+ * If kind is provided, filters triggers by that kind.
304
+ * Queries the database for triggers and prompts the user to select one.
305
+ */
306
+ export const selectTrigger = Effect.fn(function* (kind?: Trigger.Kind) {
307
+ const triggers = yield* Database.query(
308
+ Query.select(Filter.type(Trigger.Trigger)).debugLabel('cli.trigger.selectTrigger'),
309
+ ).run;
310
+ const filteredTriggers = kind ? triggers.filter((trigger) => trigger.spec?.kind === kind) : triggers;
311
+
312
+ if (filteredTriggers.length === 0) {
313
+ return yield* Effect.fail(new Error(kind ? `No ${kind} triggers available` : 'No triggers available'));
314
+ }
315
+
316
+ const choices = yield* Effect.all(
317
+ filteredTriggers.map((trigger) =>
318
+ Effect.gen(function* () {
319
+ const fn = trigger.runnable ? yield* Database.load(trigger.runnable) : undefined;
320
+ const functionName =
321
+ fn && Obj.instanceOf(Operation.PersistentOperation, fn)
322
+ ? (fn.name ?? Obj.getMeta(fn).key ?? fn.id)
323
+ : undefined;
324
+ const title = functionName ?? trigger.id;
325
+ const description = `${trigger.enabled ? 'enabled' : 'disabled'} - ${trigger.spec?.kind ?? 'unknown'}`;
326
+
327
+ return {
328
+ title,
329
+ value: trigger.id,
330
+ description,
331
+ };
332
+ }),
333
+ ),
334
+ );
335
+
336
+ const selected = yield* Prompt.select({
337
+ message: kind ? `Select a ${kind} trigger:` : 'Select a trigger:',
338
+ choices,
339
+ });
340
+
341
+ return String(selected);
342
+ });
343
+
344
+ /**
345
+ * Selects a feed interactively from available feeds in the database.
346
+ * Queries schemas with FeedAnnotation, then queries objects of those types,
347
+ * and returns the chosen Feed object.
348
+ */
349
+ export const selectFeed = Effect.fn(function* () {
350
+ // Query schema registry for schemas with FeedAnnotation.
351
+ const schemas = yield* Database.query(Query.select(Filter.type(Type.Type)).from(Scope.space(), Scope.registry())).run;
352
+
353
+ // Filter schemas that have FeedAnnotation.
354
+ const feedSchemas = schemas.filter((type) => {
355
+ const schema = Type.getSchema(type);
356
+ const annotation = FeedAnnotation.get(schema);
357
+ return Option.isSome(annotation) && annotation.value === true;
358
+ });
359
+
360
+ if (feedSchemas.length === 0) {
361
+ return yield* Effect.fail(new Error('No schemas with Feed annotation found'));
362
+ }
363
+
364
+ // Collect all Feed objects referenced by host objects.
365
+ const feedChoices: Array<{ title: string; value: Feed.Feed; description?: string }> = [];
366
+
367
+ // Process each feed schema, resolving the Feed object reference.
368
+ for (const schema of feedSchemas) {
369
+ yield* Effect.gen(function* () {
370
+ const objects = yield* Database.query(Filter.type(Type.getURI(schema))).run;
371
+
372
+ for (const obj of objects) {
373
+ // Access the feed property (which is a Ref<Feed>).
374
+ const feedRef = (obj as any).feed as Ref.Ref<any> | undefined;
375
+ if (!feedRef) {
376
+ continue;
377
+ }
378
+
379
+ const feedObj = yield* Effect.promise(() => feedRef.tryLoad());
380
+ if (!feedObj || !Obj.instanceOf(Feed.Feed, feedObj)) {
381
+ continue;
382
+ }
383
+
384
+ const label = Obj.getLabel(obj) ?? obj.id;
385
+ const description = Obj.getTypename(obj);
386
+
387
+ feedChoices.push({
388
+ title: label,
389
+ value: feedObj,
390
+ description,
391
+ });
392
+ }
393
+ }).pipe(Effect.catchAll(() => Effect.void));
394
+ }
395
+
396
+ if (feedChoices.length === 0) {
397
+ return yield* Effect.fail(new Error('No objects with feed properties found'));
398
+ }
399
+
400
+ const selected = yield* Prompt.select({
401
+ message: 'Select a feed:',
402
+ choices: feedChoices,
403
+ });
404
+
405
+ return selected as Feed.Feed;
406
+ });
407
+
408
+ /**
409
+ * Pretty prints trigger removal result with ANSI colors.
410
+ */
411
+ export const printTriggerRemoved = (id: string) =>
412
+ FormBuilder.make({ title: 'Trigger removed' }).pipe(FormBuilder.set('id', id), FormBuilder.build);
@@ -0,0 +1,68 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import React, { useCallback, useMemo } from 'react';
6
+
7
+ import { useCapabilities } from '@dxos/app-framework/ui';
8
+ import { type SpaceCapabilities } from '@dxos/plugin-space';
9
+ import { useTranslation } from '@dxos/react-ui';
10
+ import { SearchList, useSearchListResults } from '@dxos/react-ui-search';
11
+
12
+ import { meta } from '#meta';
13
+ import { RoutineCapabilities } from '#types';
14
+
15
+ export type CreateRoutinePanelProps = SpaceCapabilities.CreateObjectCustomPanelProps & {
16
+ /** Optional override (primarily for stories/tests). Defaults to RoutineCapabilities.Template. */
17
+ templates?: RoutineCapabilities.Template[];
18
+ };
19
+
20
+ /**
21
+ * Create panel for routines: a SearchList picker over contributed templates. Selecting one submits
22
+ * `{ templateId }`; plugin-routine's CreateObjectEntry.createObject resolves the templateId and runs the
23
+ * template's `scaffold`.
24
+ */
25
+ export const CreateRoutinePanel = ({ onCreateObject, templates: templatesProp }: CreateRoutinePanelProps) => {
26
+ const { t } = useTranslation(meta.profile.key);
27
+ const capabilityTemplates = useCapabilities(RoutineCapabilities.Template);
28
+ const templates = templatesProp ?? capabilityTemplates;
29
+ // The global create dialog has no subject, so subject-required templates (e.g. CRM, which needs a
30
+ // Mailbox) are excluded; they are offered from the relevant object's Automation companion instead.
31
+ const sorted = useMemo(
32
+ () =>
33
+ [...templates]
34
+ .filter((template) => template.appliesTo?.(undefined) ?? true)
35
+ .sort((a, b) => a.label.localeCompare(b.label)),
36
+ [templates],
37
+ );
38
+ const { results, handleSearch } = useSearchListResults({ items: sorted, extract: (template) => template.label });
39
+
40
+ const handleSelect = useCallback(
41
+ (templateId: string) => {
42
+ void onCreateObject({ templateId });
43
+ },
44
+ [onCreateObject],
45
+ );
46
+
47
+ return (
48
+ <SearchList.Root onSearch={handleSearch}>
49
+ <SearchList.Input
50
+ classNames='mb-form-gap'
51
+ autoFocus
52
+ data-testid='create-automation-panel.template-input'
53
+ placeholder={t('create-panel.template.placeholder')}
54
+ />
55
+ <SearchList.Viewport>
56
+ {results.map((template) => (
57
+ <SearchList.Item
58
+ key={template.id}
59
+ value={template.id}
60
+ label={template.label}
61
+ icon={template.icon ?? 'ph--lightning--regular'}
62
+ onSelect={() => handleSelect(template.id)}
63
+ />
64
+ ))}
65
+ </SearchList.Viewport>
66
+ </SearchList.Root>
67
+ );
68
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './CreateRoutinePanel';
@@ -0,0 +1,69 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React from 'react';
7
+
8
+ import { Instructions, Skill } from '@dxos/compute';
9
+ import { Filter, Ref } from '@dxos/echo';
10
+ import { type Space, useQuery } from '@dxos/react-client/echo';
11
+ import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
12
+ import { Loading, withLayout, withTheme } from '@dxos/react-ui/testing';
13
+ import { Text } from '@dxos/schema';
14
+
15
+ import { translations } from '#translations';
16
+
17
+ import { InstructionsEditor } from './InstructionsEditor';
18
+
19
+ const types = [Instructions.Instructions, Skill.Skill, Text.Text];
20
+
21
+ const DefaultStory = () => {
22
+ const { space } = useClientStory();
23
+ const [instructions] = useQuery(space?.db, Filter.type(Instructions.Instructions));
24
+ if (!space || !instructions) {
25
+ return <Loading />;
26
+ }
27
+
28
+ return <InstructionsEditor db={space.db} instructions={instructions} />;
29
+ };
30
+
31
+ const withSeededSpace = (seed: (space: Space) => void) =>
32
+ withClientProvider({
33
+ createIdentity: true,
34
+ createSpace: true,
35
+ types,
36
+ onCreateSpace: async ({ space }) => seed(space),
37
+ });
38
+
39
+ const meta = {
40
+ title: 'plugins/plugin-routine/components/InstructionsEditor',
41
+ render: DefaultStory,
42
+ decorators: [withTheme(), withLayout({ layout: 'column' })],
43
+ parameters: {
44
+ translations,
45
+ },
46
+ } satisfies Meta<typeof DefaultStory>;
47
+
48
+ export default meta;
49
+
50
+ type Story = StoryObj<typeof meta>;
51
+
52
+ /** A routine with no skills or context objects: the form shows empty add affordances. */
53
+ export const Default: Story = {
54
+ decorators: [
55
+ withSeededSpace((space) => {
56
+ space.db.add(Instructions.make({ name: 'Summarize notes' }));
57
+ }),
58
+ ],
59
+ };
60
+
61
+ /** A routine seeded with a context object: the Objects field renders the populated ref slot. */
62
+ export const WithObject: Story = {
63
+ decorators: [
64
+ withSeededSpace((space) => {
65
+ const subject = space.db.add(Text.make({ content: 'Meeting notes' }));
66
+ space.db.add(Instructions.make({ name: 'Summarize notes', objects: [Ref.make(subject)] }));
67
+ }),
68
+ ],
69
+ };
@@ -0,0 +1,107 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Option from 'effect/Option';
6
+ import React, { useCallback, useMemo } from 'react';
7
+
8
+ import { Instructions, Skill } from '@dxos/compute';
9
+ import { type Database, Entity, Obj, Type } from '@dxos/echo';
10
+ import { HiddenAnnotation } from '@dxos/echo/Annotation';
11
+ import { Form } from '@dxos/react-ui-form';
12
+
13
+ const INSTRUCTIONS_SCHEMA = Type.getSchema(Instructions.Instructions);
14
+
15
+ // Owned-routine action fields surfaced for editing — the prompt text, the agent's `skills`,
16
+ // and the context `objects` bound to its session at run. All live on the Instructions schema,
17
+ // so a single form edits them together.
18
+ const INSTRUCTIONS_FIELDS = new Set(['text', 'skills', 'objects']);
19
+
20
+ export type InstructionsEditorProps = {
21
+ db?: Database.Database;
22
+ instructions: Instructions.Instructions;
23
+ readonly?: boolean;
24
+ };
25
+
26
+ /**
27
+ * Sub-form: edits the owned Instructions in place — its `text` (Markdown), `skills`, and the
28
+ * context `objects` bound to its session at run, all fields of the Instructions schema. A bare Form.Root +
29
+ * FieldSet (no Viewport) keeps these fields left-aligned with the sibling general/action forms; the
30
+ * rendered fields are written back so selections persist to the instructions.
31
+ */
32
+ export const InstructionsEditor = ({ db: dbProp, instructions, readonly }: InstructionsEditorProps) => {
33
+ // A draft routine is not yet attached to a database, so fall back to the explicit `db` for ref queries.
34
+ const db = dbProp ?? Obj.getDatabase(instructions);
35
+
36
+ // `objects` is optional; normalize to an array so the ref-array field renders its add affordance.
37
+ const defaultValues = useMemo<Partial<Instructions.Instructions>>(
38
+ () => ({ ...Obj.getSnapshot(instructions), objects: instructions.objects ? [...instructions.objects] : [] }),
39
+ [instructions],
40
+ );
41
+
42
+ const handleValuesChanged = useCallback(
43
+ (values: Partial<Instructions.Instructions>, { isValid }: { isValid: boolean }) => {
44
+ // Skip while invalid (e.g. an empty ref slot just added by a skills/objects array field) so a
45
+ // partial selection isn't persisted; the write lands once the slot is filled.
46
+ if (!isValid) {
47
+ return;
48
+ }
49
+
50
+ Obj.update(instructions, (instructions) => {
51
+ if (values.text) {
52
+ instructions.text = values.text;
53
+ }
54
+ instructions.skills = [...(values.skills ?? [])];
55
+ instructions.objects = [...(values.objects ?? [])];
56
+ });
57
+ },
58
+ [instructions],
59
+ );
60
+
61
+ return (
62
+ <Form.Root
63
+ key={instructions.id}
64
+ schema={INSTRUCTIONS_SCHEMA}
65
+ db={db}
66
+ readonly={readonly}
67
+ defaultValues={defaultValues}
68
+ getOptions={getRefOptions}
69
+ onValuesChanged={handleValuesChanged}
70
+ >
71
+ <Form.FieldSet filter={(props) => props.filter((prop) => INSTRUCTIONS_FIELDS.has(prop.name.toString()))} />
72
+ </Form.Root>
73
+ );
74
+ };
75
+
76
+ // System objects (e.g. SpaceProperties) carry `HiddenAnnotation` on their type; they are infrastructure,
77
+ // not user content, so they are excluded from the context picker.
78
+ const isSystemObject = (object: Entity.Any): boolean => {
79
+ if (!Obj.isObject(object)) {
80
+ return false;
81
+ }
82
+ const typeEntity = Obj.getType(object);
83
+ if (!typeEntity) {
84
+ return false;
85
+ }
86
+
87
+ return HiddenAnnotation.get(Type.getSchema(typeEntity)).pipe(Option.getOrElse(() => false));
88
+ };
89
+
90
+ // Ref-picker options shared by the routine form's skill and object fields: surface a secondary line
91
+ // per candidate — a Skill's registry key, otherwise the object's typename — and sort by label, so the
92
+ // pickers present refs consistently. Falls back to the type placeholder (then URI) for unlabelled objects,
93
+ // matching the default RefField; system objects are excluded.
94
+ const getRefOptions = (
95
+ results: Entity.Any[],
96
+ { getTypePlaceholder }: { getTypePlaceholder?: (typename: string) => string } = {},
97
+ ): { id: string; label: string; description?: string }[] =>
98
+ results
99
+ .filter((entity) => !isSystemObject(entity))
100
+ .map((entity) => {
101
+ const id = Entity.getURI(entity, { prefer: 'named' });
102
+ const typename = Entity.getTypename(entity);
103
+ const label = Entity.getLabel(entity) ?? (typename ? getTypePlaceholder?.(typename) : undefined) ?? id;
104
+ const description = Obj.instanceOf(Skill.Skill, entity) ? Obj.getMeta(entity).key : typename;
105
+ return { id, label, description };
106
+ })
107
+ .sort((left, right) => left.label.localeCompare(right.label));
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './InstructionsEditor';