@dxos/plugin-routine 0.10.0 → 0.11.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 (320) hide show
  1. package/PLUGIN.mdl +18 -13
  2. package/dist/lib/RoutinePlugin.mjs +2 -0
  3. package/dist/lib/RoutinePlugin.node.mjs +894 -0
  4. package/dist/lib/RoutinePlugin.node.mjs.map +1 -0
  5. package/dist/lib/RoutinePlugin.workerd.mjs +20 -0
  6. package/dist/lib/RoutinePlugin.workerd.mjs.map +1 -0
  7. package/dist/lib/capabilities/node.mjs +12 -0
  8. package/dist/lib/capabilities/node.mjs.map +1 -0
  9. package/dist/lib/capabilities.mjs +14 -0
  10. package/dist/lib/capabilities.mjs.map +1 -0
  11. package/dist/lib/chunk-RoutineArticle.mjs +79 -0
  12. package/dist/lib/chunk-RoutineArticle.mjs.map +1 -0
  13. package/dist/lib/chunk-RoutineCompanion.mjs +192 -0
  14. package/dist/lib/chunk-RoutineCompanion.mjs.map +1 -0
  15. package/dist/lib/chunk-RoutinePlugin.mjs +38 -0
  16. package/dist/lib/chunk-RoutinePlugin.mjs.map +1 -0
  17. package/dist/lib/chunk-RoutineSettings.mjs +50 -0
  18. package/dist/lib/chunk-RoutineSettings.mjs.map +1 -0
  19. package/dist/lib/chunk-RoutineTraceCompanion.mjs +208 -0
  20. package/dist/lib/chunk-RoutineTraceCompanion.mjs.map +1 -0
  21. package/dist/lib/chunk-SkillArticle.mjs +28 -0
  22. package/dist/lib/chunk-SkillArticle.mjs.map +1 -0
  23. package/dist/lib/chunk-app-graph-builder.mjs +71 -0
  24. package/dist/lib/chunk-app-graph-builder.mjs.map +1 -0
  25. package/dist/lib/chunk-create-object.mjs +23 -0
  26. package/dist/lib/chunk-create-object.mjs.map +1 -0
  27. package/dist/lib/chunk-create-routine.mjs +34 -0
  28. package/dist/lib/chunk-create-routine.mjs.map +1 -0
  29. package/dist/lib/chunk-create-trigger-from-template.mjs +48 -0
  30. package/dist/lib/chunk-create-trigger-from-template.mjs.map +1 -0
  31. package/dist/lib/chunk-layer-specs.mjs +179 -0
  32. package/dist/lib/chunk-layer-specs.mjs.map +1 -0
  33. package/dist/lib/{neutral/chunk-HLO4LYXT.mjs → chunk-meta.mjs} +19 -27
  34. package/dist/lib/chunk-meta.mjs.map +1 -0
  35. package/dist/lib/chunk-operation-handler.mjs +11 -0
  36. package/dist/lib/chunk-operation-handler.mjs.map +1 -0
  37. package/dist/lib/chunk-paths.mjs +11 -0
  38. package/dist/lib/chunk-paths.mjs.map +1 -0
  39. package/dist/lib/chunk-react-surface.mjs +64 -0
  40. package/dist/lib/chunk-react-surface.mjs.map +1 -0
  41. package/dist/lib/chunk-registry-sync.mjs +104 -0
  42. package/dist/lib/chunk-registry-sync.mjs.map +1 -0
  43. package/dist/lib/chunk-run-routine.mjs +57 -0
  44. package/dist/lib/chunk-run-routine.mjs.map +1 -0
  45. package/dist/lib/chunk-templates.mjs +37 -0
  46. package/dist/lib/chunk-templates.mjs.map +1 -0
  47. package/dist/lib/chunk-trigger-runtime-controller.mjs +73 -0
  48. package/dist/lib/chunk-trigger-runtime-controller.mjs.map +1 -0
  49. package/dist/lib/chunk-types.mjs +149 -0
  50. package/dist/lib/chunk-types.mjs.map +1 -0
  51. package/dist/lib/chunk-util.mjs +142 -0
  52. package/dist/lib/chunk-util.mjs.map +1 -0
  53. package/dist/lib/components.mjs +1645 -0
  54. package/dist/lib/components.mjs.map +1 -0
  55. package/dist/lib/containers.mjs +11 -0
  56. package/dist/lib/containers.mjs.map +1 -0
  57. package/dist/lib/hooks.mjs +37 -0
  58. package/dist/lib/hooks.mjs.map +1 -0
  59. package/dist/lib/index.mjs +5 -0
  60. package/dist/lib/meta.mjs +2 -0
  61. package/dist/lib/operations.mjs +7 -0
  62. package/dist/lib/operations.mjs.map +1 -0
  63. package/dist/lib/plugin.mjs +9 -0
  64. package/dist/lib/plugin.mjs.map +1 -0
  65. package/dist/lib/testing.mjs +2 -0
  66. package/dist/lib/translations.mjs +110 -0
  67. package/dist/lib/translations.mjs.map +1 -0
  68. package/dist/lib/types.mjs +2 -0
  69. package/dist/types/src/RoutinePlugin.d.ts.map +1 -1
  70. package/dist/types/src/RoutinePlugin.node.d.ts.map +1 -1
  71. package/dist/types/src/RoutinePlugin.workerd.d.ts.map +1 -1
  72. package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
  73. package/dist/types/src/capabilities/create-object.d.ts +1 -1
  74. package/dist/types/src/capabilities/index.d.ts +0 -1
  75. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  76. package/dist/types/src/capabilities/layer-specs.d.ts +1 -1
  77. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  78. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  79. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  80. package/dist/types/src/capabilities/registry-sync.d.ts +1 -1
  81. package/dist/types/src/capabilities/templates.d.ts +1 -1
  82. package/dist/types/src/capabilities/trigger-runtime-controller.d.ts +1 -1
  83. package/dist/types/src/commands/trigger/create/{queue.d.ts → feed.d.ts} +2 -2
  84. package/dist/types/src/commands/trigger/create/feed.d.ts.map +1 -0
  85. package/dist/types/src/commands/trigger/update/{queue.d.ts → feed.d.ts} +2 -2
  86. package/dist/types/src/commands/trigger/update/feed.d.ts.map +1 -0
  87. package/dist/types/src/commands/trigger/util.d.ts +1 -1
  88. package/dist/types/src/commands/trigger/util.d.ts.map +1 -1
  89. package/dist/types/src/components/InstructionsEditor/InstructionsEditor.d.ts +7 -5
  90. package/dist/types/src/components/InstructionsEditor/InstructionsEditor.d.ts.map +1 -1
  91. package/dist/types/src/components/InstructionsEditor/InstructionsEditor.stories.d.ts +3 -3
  92. package/dist/types/src/components/InstructionsEditor/InstructionsEditor.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/RoutineCard/RoutineCard.d.ts +9 -0
  94. package/dist/types/src/components/RoutineCard/RoutineCard.d.ts.map +1 -0
  95. package/dist/types/src/components/RoutineCard/RoutineCard.stories.d.ts +21 -0
  96. package/dist/types/src/components/RoutineCard/RoutineCard.stories.d.ts.map +1 -0
  97. package/dist/types/src/components/RoutineCard/index.d.ts +2 -0
  98. package/dist/types/src/components/RoutineCard/index.d.ts.map +1 -0
  99. package/dist/types/src/components/RoutineForm/RoutineForm.d.ts +7 -2
  100. package/dist/types/src/components/RoutineForm/RoutineForm.d.ts.map +1 -1
  101. package/dist/types/src/components/Schedule/Schedule.d.ts +2 -26
  102. package/dist/types/src/components/Schedule/Schedule.d.ts.map +1 -1
  103. package/dist/types/src/components/Schedule/days.d.ts +24 -0
  104. package/dist/types/src/components/Schedule/days.d.ts.map +1 -0
  105. package/dist/types/src/components/Schedule/describe-schedule.d.ts +3 -0
  106. package/dist/types/src/components/Schedule/describe-schedule.d.ts.map +1 -0
  107. package/dist/types/src/components/Schedule/index.d.ts +2 -0
  108. package/dist/types/src/components/Schedule/index.d.ts.map +1 -1
  109. package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts +1 -1
  110. package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts.map +1 -1
  111. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +1 -2
  112. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
  113. package/dist/types/src/components/TriggerEditor/TriggerKindSelector.d.ts +5 -2
  114. package/dist/types/src/components/TriggerEditor/TriggerKindSelector.d.ts.map +1 -1
  115. package/dist/types/src/components/TriggerEditor/trigger-kind-icon.d.ts +5 -0
  116. package/dist/types/src/components/TriggerEditor/trigger-kind-icon.d.ts.map +1 -0
  117. package/dist/types/src/components/index.d.ts +1 -1
  118. package/dist/types/src/components/index.d.ts.map +1 -1
  119. package/dist/types/src/containers/RoutineArticle/RoutineArticle.d.ts +5 -10
  120. package/dist/types/src/containers/RoutineArticle/RoutineArticle.d.ts.map +1 -1
  121. package/dist/types/src/containers/RoutineArticle/RoutineArticle.stories.d.ts +6 -2
  122. package/dist/types/src/containers/RoutineArticle/RoutineArticle.stories.d.ts.map +1 -1
  123. package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.d.ts +4 -12
  124. package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.d.ts.map +1 -1
  125. package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.stories.d.ts.map +1 -1
  126. package/dist/types/src/containers/RoutineSettings/RoutineSettings.d.ts +4 -8
  127. package/dist/types/src/containers/RoutineSettings/RoutineSettings.d.ts.map +1 -1
  128. package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.d.ts +5 -3
  129. package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.d.ts.map +1 -1
  130. package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.stories.d.ts.map +1 -1
  131. package/dist/types/src/containers/RoutineTraceCompanion/useRoutineRuns.d.ts +1 -1
  132. package/dist/types/src/containers/RoutineTraceCompanion/useRoutineRuns.d.ts.map +1 -1
  133. package/dist/types/src/containers/SkillArticle/SkillArticle.d.ts +4 -1
  134. package/dist/types/src/containers/SkillArticle/SkillArticle.d.ts.map +1 -1
  135. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +1 -1
  136. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -1
  137. package/dist/types/src/index.d.ts +1 -0
  138. package/dist/types/src/index.d.ts.map +1 -1
  139. package/dist/types/src/operations/run-routine.d.ts.map +1 -1
  140. package/dist/types/src/operations/run-routine.test.d.ts +2 -0
  141. package/dist/types/src/operations/run-routine.test.d.ts.map +1 -0
  142. package/dist/types/src/paths.d.ts.map +1 -1
  143. package/dist/types/src/templates/index.d.ts +1 -1
  144. package/dist/types/src/templates/index.d.ts.map +1 -1
  145. package/dist/types/src/testing/test-functions.d.ts +30 -6
  146. package/dist/types/src/testing/test-functions.d.ts.map +1 -1
  147. package/dist/types/src/translations.d.ts.map +1 -1
  148. package/dist/types/src/types/RoutineCapabilities.d.ts +9 -3
  149. package/dist/types/src/types/RoutineCapabilities.d.ts.map +1 -1
  150. package/dist/types/src/types/RoutineOperation.d.ts +2 -3
  151. package/dist/types/src/types/RoutineOperation.d.ts.map +1 -1
  152. package/dist/types/src/types/index.d.ts +0 -1
  153. package/dist/types/src/types/index.d.ts.map +1 -1
  154. package/dist/types/src/util/index.d.ts +1 -0
  155. package/dist/types/src/util/index.d.ts.map +1 -1
  156. package/dist/types/src/util/routines-for-object.d.ts +6 -3
  157. package/dist/types/src/util/routines-for-object.d.ts.map +1 -1
  158. package/dist/types/src/util/wire.d.ts +21 -0
  159. package/dist/types/src/util/wire.d.ts.map +1 -0
  160. package/dist/types/src/util/wire.test.d.ts +2 -0
  161. package/dist/types/src/util/wire.test.d.ts.map +1 -0
  162. package/dist/types/tsconfig.tsbuildinfo +1 -1
  163. package/dx.config.ts +3 -2
  164. package/package.json +73 -71
  165. package/src/RoutinePlugin.node.ts +1 -2
  166. package/src/RoutinePlugin.tsx +2 -4
  167. package/src/RoutinePlugin.workerd.ts +1 -2
  168. package/src/capabilities/app-graph-builder.ts +9 -7
  169. package/src/capabilities/create-object.ts +2 -2
  170. package/src/capabilities/index.ts +0 -1
  171. package/src/capabilities/layer-specs.ts +78 -12
  172. package/src/capabilities/{react-surface.tsx → react-surface.ts} +18 -22
  173. package/src/capabilities/trigger-runtime-controller.test.ts +12 -18
  174. package/src/capabilities/trigger-runtime-controller.ts +22 -25
  175. package/src/commands/trigger/create/{queue.ts → feed.ts} +1 -1
  176. package/src/commands/trigger/create/index.ts +2 -2
  177. package/src/commands/trigger/update/{queue.ts → feed.ts} +1 -1
  178. package/src/commands/trigger/update/index.ts +2 -2
  179. package/src/commands/trigger/util.ts +1 -2
  180. package/src/components/InstructionsEditor/InstructionsEditor.stories.tsx +7 -6
  181. package/src/components/InstructionsEditor/InstructionsEditor.tsx +31 -19
  182. package/src/components/RoutineCard/RoutineCard.stories.tsx +95 -0
  183. package/src/components/RoutineCard/RoutineCard.tsx +60 -0
  184. package/src/components/{MasterDetail → RoutineCard}/index.ts +1 -1
  185. package/src/components/RoutineForm/RoutineForm.tsx +60 -52
  186. package/src/components/Schedule/Schedule.stories.tsx +1 -1
  187. package/src/components/Schedule/Schedule.tsx +4 -73
  188. package/src/components/Schedule/days.ts +18 -0
  189. package/src/components/Schedule/describe-schedule.ts +64 -0
  190. package/src/components/Schedule/index.ts +2 -0
  191. package/src/components/TemplateEditor/TemplateEditor.stories.tsx +1 -1
  192. package/src/components/TemplateEditor/TemplateForm.tsx +1 -1
  193. package/src/components/TriggerEditor/TriggerEditor.stories.tsx +3 -3
  194. package/src/components/TriggerEditor/TriggerEditor.tsx +79 -66
  195. package/src/components/TriggerEditor/TriggerKindSelector.tsx +4 -30
  196. package/src/components/TriggerEditor/trigger-kind-icon.ts +38 -0
  197. package/src/components/index.ts +1 -1
  198. package/src/containers/RoutineArticle/RoutineArticle.stories.tsx +78 -19
  199. package/src/containers/RoutineArticle/RoutineArticle.tsx +8 -4
  200. package/src/containers/RoutineCompanion/RoutineCompanion.stories.tsx +5 -4
  201. package/src/containers/RoutineCompanion/RoutineCompanion.tsx +11 -7
  202. package/src/containers/RoutineSettings/RoutineSettings.tsx +22 -33
  203. package/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.stories.tsx +6 -5
  204. package/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.tsx +3 -1
  205. package/src/containers/RoutineTraceCompanion/useRoutineRuns.ts +3 -5
  206. package/src/containers/SkillArticle/SkillArticle.tsx +2 -0
  207. package/src/hooks/useTriggerRuntimeControls.ts +2 -2
  208. package/src/index.ts +1 -0
  209. package/src/operations/create-routine.ts +1 -1
  210. package/src/operations/create-trigger-from-template.ts +2 -2
  211. package/src/operations/run-routine.test.ts +150 -0
  212. package/src/operations/run-routine.ts +18 -2
  213. package/src/paths.ts +5 -5
  214. package/src/templates/index.ts +5 -3
  215. package/src/translations.ts +5 -6
  216. package/src/types/RoutineCapabilities.ts +10 -4
  217. package/src/types/RoutineOperation.ts +7 -6
  218. package/src/types/index.ts +0 -1
  219. package/src/util/index.ts +1 -0
  220. package/src/util/routines-for-object.test.ts +37 -5
  221. package/src/util/routines-for-object.ts +33 -8
  222. package/src/util/wire.test.ts +77 -0
  223. package/src/util/wire.ts +76 -0
  224. package/dist/lib/neutral/RoutineArticle-UNTMV4CC.mjs +0 -95
  225. package/dist/lib/neutral/RoutineArticle-UNTMV4CC.mjs.map +0 -7
  226. package/dist/lib/neutral/RoutineCompanion-ZZ6WMY7I.mjs +0 -249
  227. package/dist/lib/neutral/RoutineCompanion-ZZ6WMY7I.mjs.map +0 -7
  228. package/dist/lib/neutral/RoutinePlugin.mjs +0 -10
  229. package/dist/lib/neutral/RoutinePlugin.mjs.map +0 -7
  230. package/dist/lib/neutral/RoutinePlugin.node.mjs +0 -1133
  231. package/dist/lib/neutral/RoutinePlugin.node.mjs.map +0 -7
  232. package/dist/lib/neutral/RoutinePlugin.workerd.mjs +0 -36
  233. package/dist/lib/neutral/RoutinePlugin.workerd.mjs.map +0 -7
  234. package/dist/lib/neutral/RoutineSettings-ZJOM4F3S.mjs +0 -48
  235. package/dist/lib/neutral/RoutineSettings-ZJOM4F3S.mjs.map +0 -7
  236. package/dist/lib/neutral/RoutineTraceCompanion-5U6R7LJE.mjs +0 -236
  237. package/dist/lib/neutral/RoutineTraceCompanion-5U6R7LJE.mjs.map +0 -7
  238. package/dist/lib/neutral/SkillArticle-WWDNKW2Z.mjs +0 -27
  239. package/dist/lib/neutral/SkillArticle-WWDNKW2Z.mjs.map +0 -7
  240. package/dist/lib/neutral/app-graph-builder-FALWLZTI.mjs +0 -90
  241. package/dist/lib/neutral/app-graph-builder-FALWLZTI.mjs.map +0 -7
  242. package/dist/lib/neutral/capabilities/index.mjs +0 -25
  243. package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
  244. package/dist/lib/neutral/capabilities/node.mjs +0 -19
  245. package/dist/lib/neutral/capabilities/node.mjs.map +0 -7
  246. package/dist/lib/neutral/chunk-674LDIUJ.mjs +0 -9
  247. package/dist/lib/neutral/chunk-674LDIUJ.mjs.map +0 -7
  248. package/dist/lib/neutral/chunk-HLO4LYXT.mjs.map +0 -7
  249. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
  250. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
  251. package/dist/lib/neutral/chunk-P3TDQKOO.mjs +0 -8
  252. package/dist/lib/neutral/chunk-P3TDQKOO.mjs.map +0 -7
  253. package/dist/lib/neutral/chunk-R7J2MU2M.mjs +0 -263
  254. package/dist/lib/neutral/chunk-R7J2MU2M.mjs.map +0 -7
  255. package/dist/lib/neutral/chunk-WLNL77C7.mjs +0 -14
  256. package/dist/lib/neutral/chunk-WLNL77C7.mjs.map +0 -7
  257. package/dist/lib/neutral/chunk-YGWSAKLD.mjs +0 -65
  258. package/dist/lib/neutral/chunk-YGWSAKLD.mjs.map +0 -7
  259. package/dist/lib/neutral/components/index.mjs +0 -1921
  260. package/dist/lib/neutral/components/index.mjs.map +0 -7
  261. package/dist/lib/neutral/containers/index.mjs +0 -17
  262. package/dist/lib/neutral/containers/index.mjs.map +0 -7
  263. package/dist/lib/neutral/create-object-V23KVDMJ.mjs +0 -25
  264. package/dist/lib/neutral/create-object-V23KVDMJ.mjs.map +0 -7
  265. package/dist/lib/neutral/create-routine-6QBY6TWF.mjs +0 -38
  266. package/dist/lib/neutral/create-routine-6QBY6TWF.mjs.map +0 -7
  267. package/dist/lib/neutral/create-trigger-from-template-U3KNS77V.mjs +0 -70
  268. package/dist/lib/neutral/create-trigger-from-template-U3KNS77V.mjs.map +0 -7
  269. package/dist/lib/neutral/hooks/index.mjs +0 -47
  270. package/dist/lib/neutral/hooks/index.mjs.map +0 -7
  271. package/dist/lib/neutral/index.mjs +0 -27
  272. package/dist/lib/neutral/index.mjs.map +0 -7
  273. package/dist/lib/neutral/layer-specs-2TWJU5HI.mjs +0 -135
  274. package/dist/lib/neutral/layer-specs-2TWJU5HI.mjs.map +0 -7
  275. package/dist/lib/neutral/meta.json +0 -1
  276. package/dist/lib/neutral/meta.mjs +0 -8
  277. package/dist/lib/neutral/meta.mjs.map +0 -7
  278. package/dist/lib/neutral/navigation-resolver-KQIWUH6F.mjs +0 -18
  279. package/dist/lib/neutral/navigation-resolver-KQIWUH6F.mjs.map +0 -7
  280. package/dist/lib/neutral/operation-handler-QKLJSDCQ.mjs +0 -13
  281. package/dist/lib/neutral/operation-handler-QKLJSDCQ.mjs.map +0 -7
  282. package/dist/lib/neutral/operations/index.mjs +0 -8
  283. package/dist/lib/neutral/operations/index.mjs.map +0 -7
  284. package/dist/lib/neutral/plugin.mjs +0 -16
  285. package/dist/lib/neutral/plugin.mjs.map +0 -7
  286. package/dist/lib/neutral/react-surface-GMO7I7YE.mjs +0 -67
  287. package/dist/lib/neutral/react-surface-GMO7I7YE.mjs.map +0 -7
  288. package/dist/lib/neutral/registry-sync-DYPOC7ZG.mjs +0 -86
  289. package/dist/lib/neutral/registry-sync-DYPOC7ZG.mjs.map +0 -7
  290. package/dist/lib/neutral/run-routine-AEWO6SYD.mjs +0 -37
  291. package/dist/lib/neutral/run-routine-AEWO6SYD.mjs.map +0 -7
  292. package/dist/lib/neutral/templates-IIUCEBAX.mjs +0 -49
  293. package/dist/lib/neutral/templates-IIUCEBAX.mjs.map +0 -7
  294. package/dist/lib/neutral/testing.mjs +0 -8
  295. package/dist/lib/neutral/testing.mjs.map +0 -7
  296. package/dist/lib/neutral/translations.mjs +0 -115
  297. package/dist/lib/neutral/translations.mjs.map +0 -7
  298. package/dist/lib/neutral/trigger-runtime-controller-WIDDFGQT.mjs +0 -77
  299. package/dist/lib/neutral/trigger-runtime-controller-WIDDFGQT.mjs.map +0 -7
  300. package/dist/lib/neutral/types/index.mjs +0 -17
  301. package/dist/lib/neutral/types/index.mjs.map +0 -7
  302. package/dist/types/src/capabilities/navigation-resolver.d.ts +0 -5
  303. package/dist/types/src/capabilities/navigation-resolver.d.ts.map +0 -1
  304. package/dist/types/src/commands/trigger/create/queue.d.ts.map +0 -1
  305. package/dist/types/src/commands/trigger/update/queue.d.ts.map +0 -1
  306. package/dist/types/src/components/MasterDetail/MasterDetail.d.ts +0 -51
  307. package/dist/types/src/components/MasterDetail/MasterDetail.d.ts.map +0 -1
  308. package/dist/types/src/components/MasterDetail/MasterDetail.stories.d.ts +0 -16
  309. package/dist/types/src/components/MasterDetail/MasterDetail.stories.d.ts.map +0 -1
  310. package/dist/types/src/components/MasterDetail/index.d.ts +0 -2
  311. package/dist/types/src/components/MasterDetail/index.d.ts.map +0 -1
  312. package/dist/types/src/types/Routine.d.ts +0 -55
  313. package/dist/types/src/types/Routine.d.ts.map +0 -1
  314. package/dist/types/src/types/Routine.test.d.ts +0 -2
  315. package/dist/types/src/types/Routine.test.d.ts.map +0 -1
  316. package/src/capabilities/navigation-resolver.ts +0 -21
  317. package/src/components/MasterDetail/MasterDetail.stories.tsx +0 -100
  318. package/src/components/MasterDetail/MasterDetail.tsx +0 -175
  319. package/src/types/Routine.test.ts +0 -51
  320. package/src/types/Routine.ts +0 -144
@@ -0,0 +1,894 @@
1
+ import { ActivationEvent, ActivationEvents, Plugin } from "@dxos/app-framework";
2
+ import { AppActivationEvents, AppPlugin } from "@dxos/app-toolkit";
3
+ import { Operation, Routine, Trace, Trigger } from "@dxos/compute";
4
+ import { meta } from "#meta";
5
+ import { Annotation, Database, Entity, Feed, Filter, JsonSchema, Obj, Query, Ref, Scope, Type } from "@dxos/echo";
6
+ import { DXN as DXN$1, EID } from "@dxos/keys";
7
+ import { ClientEvents } from "@dxos/plugin-client";
8
+ import { AppGraphBuilder, LayerSpecs, OperationHandler, RegistrySync, Templates, TriggerRuntimeController } from "#capabilities";
9
+ import * as Command from "@effect/cli/Command";
10
+ import * as Options from "@effect/cli/Options";
11
+ import * as Prompt from "@effect/cli/Prompt";
12
+ import * as Console from "effect/Console";
13
+ import * as Effect from "effect/Effect";
14
+ import * as HashMap from "effect/HashMap";
15
+ import * as Option from "effect/Option";
16
+ import { CommandConfig, Common, FormBuilder, flushAndSync, print, printList, spaceIdWithDefault, spaceLayer, withTypes } from "@dxos/cli-util";
17
+ import * as Ansi from "@effect/printer-ansi/Ansi";
18
+ import * as Match from "effect/Match";
19
+ import * as SchemaAST from "effect/SchemaAST";
20
+ import { SchemaEx } from "@dxos/effect";
21
+ import { FeedAnnotation } from "@dxos/schema";
22
+ import { ClientService } from "@dxos/client";
23
+ import { Context } from "@dxos/context";
24
+ //#region src/commands/trigger/options.ts
25
+ var TriggerId = Options.text("id").pipe(Options.withDescription("The id of the trigger."));
26
+ var Enabled = Options.boolean("enabled", { ifPresent: true }).pipe(Options.withDescription("Whether the trigger is enabled."));
27
+ var Input = Options.keyValueMap("input").pipe(Options.withDescription("Input data to pass to the function. Must match the function's input schema."));
28
+ var Typename = Options.text("typename").pipe(Options.withDescription("The type name to query for the subscription trigger."));
29
+ var Deep = Options.boolean("deep", { ifPresent: true }).pipe(Options.withDescription("Watch changes to nested properties (not just creation)."));
30
+ var Delay = Options.integer("delay").pipe(Options.withDescription("Debounce changes with a delay in milliseconds."));
31
+ var Cron = Options.text("cron").pipe(Options.withDescription("The cron expression to use for the timer trigger."));
32
+ var Feed$1 = Options.text("feed").pipe(Options.withDescription("The EID of the feed for the feed trigger (echo://<spaceId>/<objectId>)."));
33
+ //#endregion
34
+ //#region src/commands/trigger/util.ts
35
+ /**
36
+ * Determines the remote status of a trigger.
37
+ * Only timer/cron triggers can be checked for remote availability.
38
+ */
39
+ var getTriggerRemoteStatus = (trigger, remoteCronIds) => {
40
+ if (trigger.spec?.kind !== "timer") return "n/a";
41
+ return remoteCronIds.includes(trigger.id) ? "available" : "not available";
42
+ };
43
+ /**
44
+ * Pretty prints a trigger with ANSI colors.
45
+ */
46
+ var printTrigger = Effect.fn(function* (trigger, remoteStatus) {
47
+ const fn = trigger.runnable && (yield* Database.load(trigger.runnable));
48
+ return FormBuilder.make({ title: trigger.id }).pipe(FormBuilder.set("status", trigger.enabled ? "enabled" : "disabled", trigger.enabled ? Ansi.green : Ansi.blackBright), FormBuilder.option("kind", Option.fromNullable(trigger.spec?.kind)), FormBuilder.option("remote", Option.fromNullable(remoteStatus), Match.type().pipe(Match.withReturnType(), Match.when("available", () => Ansi.green), Match.when("not available", () => Ansi.yellow), Match.when("n/a", () => Ansi.blackBright), Match.exhaustive)), FormBuilder.when(fn, FormBuilder.nest("function", FormBuilder.make().pipe(FormBuilder.set("key", Obj.getMeta(fn).key), FormBuilder.set("dxn", Obj.getURI(fn))))), FormBuilder.nestedOption("spec", Option.fromNullable(trigger.spec).pipe(Option.map(printSpec))), FormBuilder.build);
49
+ });
50
+ var printSpec = (spec) => {
51
+ switch (spec.kind) {
52
+ case "timer": return printTimer(spec);
53
+ case "subscription": return printSubscription(spec);
54
+ case "webhook": return printWebhook(spec);
55
+ case "feed": return printFeed(spec);
56
+ default: return FormBuilder.make({}).pipe(FormBuilder.set("unknown", "Unknown spec type"));
57
+ }
58
+ };
59
+ var printTimer = (spec) => FormBuilder.make({}).pipe(FormBuilder.set("cron", spec.cron));
60
+ var printSubscription = (spec) => FormBuilder.make({}).pipe(FormBuilder.set("query", spec.query?.raw ?? "[Query AST]"));
61
+ var printWebhook = (spec) => FormBuilder.make({}).pipe(FormBuilder.set("method", spec.method), FormBuilder.set("port", spec.port));
62
+ var printFeed = (spec) => FormBuilder.make({}).pipe(FormBuilder.set("feed", spec.feed ? spec.feed.uri.toString() : "(none)"));
63
+ /**
64
+ * Prompts for input values based on an Effect schema.
65
+ * First shows a multi-select to choose which properties to specify,
66
+ * then prompts for values of the selected properties.
67
+ * Required properties are automatically included and cannot be unselected.
68
+ * @param schema - The Effect schema to prompt for
69
+ * @param defaults - Optional default values to use as initial values and pre-select optional properties
70
+ */
71
+ var promptForSchemaInput = Effect.fn(function* (schema, defaults) {
72
+ if (!schema) return {};
73
+ const ast = schema.ast;
74
+ if (!SchemaAST.isTypeLiteral(ast)) return {};
75
+ const properties = SchemaEx.getProperties(ast);
76
+ if (properties.length === 0) return {};
77
+ const requiredProperties = [];
78
+ const optionalProperties = [];
79
+ for (const prop of properties) if (prop.isOptional) optionalProperties.push(prop);
80
+ else requiredProperties.push(prop);
81
+ const propertyInfo = properties.map((prop) => {
82
+ return {
83
+ prop,
84
+ key: prop.name.toString(),
85
+ isRequired: !prop.isOptional
86
+ };
87
+ });
88
+ const selectedKeys = /* @__PURE__ */ new Set();
89
+ for (const info of propertyInfo) if (info.isRequired) selectedKeys.add(info.key);
90
+ if (requiredProperties.length > 0) {
91
+ const requiredNames = requiredProperties.map((p) => {
92
+ return propertyInfo.find((i) => i.prop === p)?.key ?? p.name.toString();
93
+ });
94
+ yield* Console.log(`Required properties (will be included): ${requiredNames.join(", ")}`);
95
+ }
96
+ if (optionalProperties.length > 0) {
97
+ const choices = propertyInfo.filter((info) => !info.isRequired).map((info) => {
98
+ const hasDefault = defaults?.[info.key] !== void 0;
99
+ const defaultText = hasDefault ? ` (current: ${JSON.stringify(defaults[info.key])})` : "";
100
+ return {
101
+ title: `${info.key}${defaultText}`,
102
+ value: info.key,
103
+ description: hasDefault ? "Has default value" : void 0
104
+ };
105
+ });
106
+ const selected = yield* Prompt.multiSelect({
107
+ message: "Select optional properties to include:",
108
+ choices
109
+ });
110
+ for (const key of selected) selectedKeys.add(String(key));
111
+ }
112
+ if (selectedKeys.size === 0) return {};
113
+ const inputObj = {};
114
+ for (const info of propertyInfo) {
115
+ if (!selectedKeys.has(info.key)) continue;
116
+ const key = info.key;
117
+ const propType = info.prop.type;
118
+ const schemaDefault = Option.getOrUndefined(SchemaAST.getDefaultAnnotation(propType));
119
+ const defaultValue = defaults?.[key] ?? schemaDefault;
120
+ if (SchemaAST.isBooleanKeyword(propType)) {
121
+ const initialValue = typeof defaultValue === "boolean" ? defaultValue : typeof schemaDefault === "boolean" ? schemaDefault : false;
122
+ inputObj[key] = yield* Prompt.confirm({
123
+ message: `${info.key}${defaults?.[key] !== void 0 ? ` (current: ${defaults[key]})` : ""}:`,
124
+ initial: initialValue
125
+ });
126
+ } else if (SchemaAST.isNumberKeyword(propType)) {
127
+ const currentValue = typeof defaultValue === "number" ? String(defaultValue) : "";
128
+ const valueStr = yield* Prompt.text({ message: `${info.key}${currentValue ? ` (current: ${currentValue}, press Enter to keep)` : ""}:` }).pipe(Prompt.run);
129
+ inputObj[key] = valueStr === "" && defaultValue !== void 0 ? defaultValue : parseFloat(valueStr) || 0;
130
+ } else if (SchemaAST.isStringKeyword(propType)) {
131
+ const currentValue = typeof defaultValue === "string" ? defaultValue : "";
132
+ const valueStr = yield* Prompt.text({ message: `${info.key}${currentValue ? ` (current: ${currentValue}, press Enter to keep)` : ""}:` }).pipe(Prompt.run);
133
+ inputObj[key] = valueStr === "" && defaultValue !== void 0 ? defaultValue : valueStr;
134
+ } else if (Ref.isRefType(propType)) {
135
+ const isDefaultTemplate = typeof defaultValue === "string" && defaultValue.startsWith("{{") && defaultValue.endsWith("}}");
136
+ if (yield* Prompt.confirm({
137
+ message: `Use a template to specify ${info.key}?${isDefaultTemplate ? " (current: template)" : ""}`,
138
+ initial: isDefaultTemplate
139
+ })) {
140
+ const currentValue = typeof defaultValue === "string" ? defaultValue : "";
141
+ const templateStr = yield* Prompt.text({ message: `${info.key} template${currentValue ? ` (current: ${currentValue}, press Enter to keep)` : ""}:` }).pipe(Prompt.run);
142
+ inputObj[key] = templateStr === "" && defaultValue !== void 0 ? defaultValue : templateStr;
143
+ } else {
144
+ const annotation = Annotation.ReferenceAnnotation.getFromAst(propType).pipe(Option.getOrThrow);
145
+ const objects = yield* Database.query(Filter.type(DXN$1.make(annotation.typename))).run;
146
+ if (objects.length === 0) inputObj[key] = void 0;
147
+ else inputObj[key] = yield* Prompt.select({
148
+ message: `Select ${info.key}:`,
149
+ choices: objects.map((obj) => ({
150
+ title: Entity.getLabel(obj) ?? obj.id,
151
+ value: Ref.make(obj),
152
+ description: Entity.getDescription(obj)
153
+ }))
154
+ });
155
+ }
156
+ } else {
157
+ const currentValue = defaultValue !== void 0 ? String(defaultValue) : "";
158
+ const valueStr = yield* Prompt.text({ message: `${info.key}${currentValue ? ` (current: ${currentValue}, press Enter to keep)` : ""}:` }).pipe(Prompt.run);
159
+ inputObj[key] = valueStr === "" && defaultValue !== void 0 ? defaultValue : valueStr;
160
+ }
161
+ }
162
+ return inputObj;
163
+ });
164
+ /**
165
+ * Selects a function interactively from available functions in the database.
166
+ * Queries the database for functions and prompts the user to select one.
167
+ */
168
+ var selectFunction = Effect.fn(function* () {
169
+ const functions = (yield* Database.query(Filter.type(Operation.PersistentOperation)).run).filter((fn) => Operation.isVisible(fn));
170
+ if (functions.length === 0) return yield* Effect.fail(/* @__PURE__ */ new Error("No functions available"));
171
+ const selected = yield* Prompt.select({
172
+ message: "Select a function:",
173
+ choices: functions.map((fn) => ({
174
+ title: fn.name ?? fn.id,
175
+ value: fn.id,
176
+ description: fn.description
177
+ }))
178
+ });
179
+ return String(selected);
180
+ });
181
+ /**
182
+ * Selects a trigger interactively from available triggers.
183
+ * If kind is provided, filters triggers by that kind.
184
+ * Queries the database for triggers and prompts the user to select one.
185
+ */
186
+ var selectTrigger = Effect.fn(function* (kind) {
187
+ const triggers = yield* Database.query(Query.select(Filter.type(Trigger.Trigger)).debugLabel("cli.trigger.selectTrigger")).run;
188
+ const filteredTriggers = kind ? triggers.filter((trigger) => trigger.spec?.kind === kind) : triggers;
189
+ if (filteredTriggers.length === 0) return yield* Effect.fail(/* @__PURE__ */ new Error(kind ? `No ${kind} triggers available` : "No triggers available"));
190
+ const choices = yield* Effect.all(filteredTriggers.map((trigger) => Effect.gen(function* () {
191
+ const fn = trigger.runnable ? yield* Database.load(trigger.runnable) : void 0;
192
+ const title = (fn && Obj.instanceOf(Operation.PersistentOperation, fn) ? fn.name ?? Obj.getMeta(fn).key ?? fn.id : void 0) ?? trigger.id;
193
+ const description = `${trigger.enabled ? "enabled" : "disabled"} - ${trigger.spec?.kind ?? "unknown"}`;
194
+ return {
195
+ title,
196
+ value: trigger.id,
197
+ description
198
+ };
199
+ })));
200
+ const selected = yield* Prompt.select({
201
+ message: kind ? `Select a ${kind} trigger:` : "Select a trigger:",
202
+ choices
203
+ });
204
+ return String(selected);
205
+ });
206
+ /**
207
+ * Selects a feed interactively from available feeds in the database.
208
+ * Queries schemas with FeedAnnotation, then queries objects of those types,
209
+ * and returns the chosen Feed object.
210
+ */
211
+ var selectFeed = Effect.fn(function* () {
212
+ const feedSchemas = (yield* Database.query(Query.select(Filter.type(Type.Type)).from(Scope.space(), Scope.registry())).run).filter((type) => {
213
+ const schema = Type.getSchema(type);
214
+ const annotation = FeedAnnotation.get(schema);
215
+ return Option.isSome(annotation) && annotation.value === true;
216
+ });
217
+ if (feedSchemas.length === 0) return yield* Effect.fail(/* @__PURE__ */ new Error("No schemas with Feed annotation found"));
218
+ const feedChoices = [];
219
+ for (const schema of feedSchemas) yield* Effect.gen(function* () {
220
+ const objects = yield* Database.query(Filter.type(Type.getURI(schema))).run;
221
+ for (const obj of objects) {
222
+ const feedRef = obj.feed;
223
+ if (!feedRef) continue;
224
+ const feedObj = yield* Effect.promise(() => feedRef.tryLoad());
225
+ if (!feedObj || !Obj.instanceOf(Feed.Feed, feedObj)) continue;
226
+ const label = Obj.getLabel(obj) ?? obj.id;
227
+ const description = Obj.getTypename(obj);
228
+ feedChoices.push({
229
+ title: label,
230
+ value: feedObj,
231
+ description
232
+ });
233
+ }
234
+ }).pipe(Effect.catchAll(() => Effect.void));
235
+ if (feedChoices.length === 0) return yield* Effect.fail(/* @__PURE__ */ new Error("No objects with feed properties found"));
236
+ return yield* Prompt.select({
237
+ message: "Select a feed:",
238
+ choices: feedChoices
239
+ });
240
+ });
241
+ /**
242
+ * Pretty prints trigger removal result with ANSI colors.
243
+ */
244
+ var printTriggerRemoved = (id) => FormBuilder.make({ title: "Trigger removed" }).pipe(FormBuilder.set("id", id), FormBuilder.build);
245
+ //#endregion
246
+ //#region src/commands/trigger/create/feed.ts
247
+ var feed$1 = Command.make("feed", {
248
+ spaceId: Common.spaceId.pipe(Options.optional),
249
+ enabled: Enabled,
250
+ functionId: Common.functionId.pipe(Options.optional),
251
+ feed: Feed$1.pipe(Options.optional),
252
+ input: Input.pipe(Options.optional)
253
+ }, (options) => Effect.gen(function* () {
254
+ const { json } = yield* CommandConfig;
255
+ const functionId = yield* Option.match(options.functionId, {
256
+ onNone: () => selectFunction(),
257
+ onSome: (id) => Effect.succeed(id)
258
+ });
259
+ const fn = (yield* Database.query(Filter.type(Operation.PersistentOperation)).run).find((fn) => fn.id === functionId);
260
+ if (!fn) return yield* Effect.fail(/* @__PURE__ */ new Error(`Function not found: ${functionId}`));
261
+ const feed = yield* Option.match(options.feed, {
262
+ onNone: () => selectFeed(),
263
+ onSome: (uri) => Database.resolve(EID.parse(uri), Feed.Feed)
264
+ });
265
+ const input = yield* Option.match(options.input, {
266
+ onNone: () => promptForSchemaInput(fn.inputSchema ? JsonSchema.toEffectSchema(fn.inputSchema) : void 0),
267
+ onSome: (value) => Effect.succeed(Object.fromEntries(HashMap.toEntries(value)))
268
+ });
269
+ const enabled = yield* Option.match(options.functionId, {
270
+ onNone: () => Prompt.confirm({
271
+ message: "Enable the trigger?",
272
+ initial: true
273
+ }).pipe(Prompt.run),
274
+ onSome: () => Effect.succeed(options.enabled)
275
+ });
276
+ const trigger = Trigger.make({
277
+ runnable: Ref.make(fn),
278
+ enabled,
279
+ spec: Trigger.specFeed(feed),
280
+ input
281
+ });
282
+ yield* Database.add(trigger);
283
+ if (json) yield* Console.log(JSON.stringify(trigger, null, 2));
284
+ else yield* Console.log(print(yield* printTrigger(trigger)));
285
+ yield* flushAndSync({ indexes: true });
286
+ })).pipe(Command.withDescription("Create a feed trigger."), Command.provide(({ spaceId }) => spaceLayer(spaceId, true)), Command.provideEffectDiscard(() => withTypes(Operation.PersistentOperation, Trigger.Trigger)));
287
+ //#endregion
288
+ //#region src/commands/trigger/create/subscription.ts
289
+ var subscription$1 = Command.make("subscription", {
290
+ spaceId: Common.spaceId.pipe(Options.optional),
291
+ enabled: Enabled,
292
+ functionId: Common.functionId.pipe(Options.optional),
293
+ typename: Typename.pipe(Options.optional),
294
+ deep: Deep.pipe(Options.optional),
295
+ delay: Delay.pipe(Options.optional),
296
+ input: Input.pipe(Options.optional)
297
+ }, (options) => Effect.gen(function* () {
298
+ const { json } = yield* CommandConfig;
299
+ const functionId = yield* Option.match(options.functionId, {
300
+ onNone: () => selectFunction(),
301
+ onSome: (id) => Effect.succeed(id)
302
+ });
303
+ const fn = (yield* Database.query(Filter.type(Operation.PersistentOperation)).run).find((fn) => fn.id === functionId);
304
+ if (!fn) return yield* Effect.fail(/* @__PURE__ */ new Error(`Function not found: ${functionId}`));
305
+ const typename = yield* Option.match(options.typename, {
306
+ onNone: () => Prompt.text({ message: "Enter type name:" }).pipe(Prompt.run),
307
+ onSome: (value) => Effect.succeed(value)
308
+ });
309
+ const subscriptionQuery = Query.select(Filter.type(DXN$1.make(typename)));
310
+ const deepOption = yield* Option.match(options.deep, {
311
+ onNone: () => Prompt.confirm({
312
+ message: "Watch changes to nested properties (deep)?",
313
+ initial: false
314
+ }).pipe(Prompt.run, Effect.map((value) => value ? Option.some(value) : Option.none())),
315
+ onSome: () => Effect.succeed(Option.some(true))
316
+ });
317
+ const delayOption = yield* Option.match(options.delay, {
318
+ onNone: () => Effect.gen(function* () {
319
+ const delayStr = yield* Prompt.text({ message: "Debounce delay in milliseconds (optional, press Enter to skip):" }).pipe(Prompt.run);
320
+ return delayStr === "" ? Option.none() : Option.some(parseInt(delayStr, 10));
321
+ }),
322
+ onSome: (value) => Effect.succeed(Option.some(value))
323
+ });
324
+ const subscriptionOptions = {};
325
+ if (Option.isSome(deepOption)) subscriptionOptions.deep = deepOption.value;
326
+ if (Option.isSome(delayOption)) subscriptionOptions.delay = delayOption.value;
327
+ const input = yield* Option.match(options.input, {
328
+ onNone: () => promptForSchemaInput(fn.inputSchema ? JsonSchema.toEffectSchema(fn.inputSchema) : void 0),
329
+ onSome: (value) => Effect.succeed(Object.fromEntries(HashMap.toEntries(value)))
330
+ });
331
+ const enabled = yield* Option.match(options.functionId, {
332
+ onNone: () => Prompt.confirm({
333
+ message: "Enable the trigger?",
334
+ initial: true
335
+ }).pipe(Prompt.run),
336
+ onSome: () => Effect.succeed(options.enabled)
337
+ });
338
+ const trigger = Trigger.make({
339
+ runnable: Ref.make(fn),
340
+ enabled,
341
+ spec: Trigger.specSubscription(subscriptionQuery, Object.keys(subscriptionOptions).length > 0 ? subscriptionOptions : void 0),
342
+ input
343
+ });
344
+ yield* Database.add(trigger);
345
+ if (json) yield* Console.log(JSON.stringify(trigger, null, 2));
346
+ else yield* Console.log(print(yield* printTrigger(trigger)));
347
+ yield* flushAndSync({ indexes: true });
348
+ })).pipe(Command.withDescription("Create a subscription trigger."), Command.provide(({ spaceId }) => spaceLayer(spaceId, true)), Command.provideEffectDiscard(() => withTypes(Operation.PersistentOperation, Trigger.Trigger)));
349
+ //#endregion
350
+ //#region src/commands/trigger/create/timer.ts
351
+ var timer$1 = Command.make("timer", {
352
+ spaceId: Common.spaceId.pipe(Options.optional),
353
+ enabled: Enabled,
354
+ functionId: Common.functionId.pipe(Options.optional),
355
+ cron: Cron.pipe(Options.optional),
356
+ input: Input.pipe(Options.optional)
357
+ }, (options) => Effect.gen(function* () {
358
+ const { json } = yield* CommandConfig;
359
+ const functionId = yield* Option.match(options.functionId, {
360
+ onNone: () => selectFunction(),
361
+ onSome: (id) => Effect.succeed(id)
362
+ });
363
+ const fn = (yield* Database.query(Filter.type(Operation.PersistentOperation)).run).find((fn) => fn.id === functionId);
364
+ if (!fn) return yield* Effect.fail(/* @__PURE__ */ new Error(`Function not found: ${functionId}`));
365
+ const cron = yield* Option.match(options.cron, {
366
+ onNone: () => Prompt.text({ message: "Enter cron expression:" }).pipe(Prompt.run),
367
+ onSome: (value) => Effect.succeed(value)
368
+ });
369
+ const input = yield* Option.match(options.input, {
370
+ onNone: () => promptForSchemaInput(fn.inputSchema ? JsonSchema.toEffectSchema(fn.inputSchema) : void 0),
371
+ onSome: (value) => Effect.succeed(Object.fromEntries(HashMap.toEntries(value)))
372
+ });
373
+ const enabled = yield* Option.match(options.functionId, {
374
+ onNone: () => Prompt.confirm({
375
+ message: "Enable the trigger?",
376
+ initial: true
377
+ }).pipe(Prompt.run),
378
+ onSome: () => Effect.succeed(options.enabled)
379
+ });
380
+ const trigger = Trigger.make({
381
+ runnable: Ref.make(fn),
382
+ enabled,
383
+ spec: Trigger.specTimer(cron),
384
+ input
385
+ });
386
+ yield* Database.add(trigger);
387
+ if (json) yield* Console.log(JSON.stringify(trigger, null, 2));
388
+ else yield* Console.log(print(yield* printTrigger(trigger)));
389
+ yield* flushAndSync({ indexes: true });
390
+ })).pipe(Command.withDescription("Create a timer trigger."), Command.provide(({ spaceId }) => spaceLayer(spaceId, true)), Command.provideEffectDiscard(() => withTypes(Operation.PersistentOperation, Trigger.Trigger)));
391
+ //#endregion
392
+ //#region src/commands/trigger/create/index.ts
393
+ var create = Command.make("create").pipe(Command.withDescription("Create a trigger."), Command.withSubcommands([
394
+ subscription$1,
395
+ timer$1,
396
+ feed$1
397
+ ]));
398
+ //#endregion
399
+ //#region src/commands/trigger/list.ts
400
+ var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-routine/src/commands/trigger/list.ts";
401
+ var list = Command.make("list", { spaceId: Common.spaceId.pipe(Options.optional) }, Effect.fn(function* ({ spaceId: spaceIdOption }) {
402
+ const { json } = yield* CommandConfig;
403
+ const triggers = yield* Database.query(Query.select(Filter.type(Trigger.Trigger)).debugLabel("cli.trigger.list")).run;
404
+ const remoteCronIds = yield* Effect.gen(function* () {
405
+ const client = yield* ClientService;
406
+ const spaceId = yield* spaceIdWithDefault(spaceIdOption);
407
+ return (yield* Effect.promise(() => client.edge.http.getCronTriggers(Context.default(void 0, {
408
+ "~LogMeta": "~LogMeta",
409
+ F: __dxlog_file,
410
+ L: 34
411
+ }), spaceId)).pipe(Effect.catchAll(() => Effect.succeed({ cronIds: [] })))).cronIds;
412
+ });
413
+ const triggersWithStatus = triggers.map((trigger) => ({
414
+ trigger,
415
+ remoteStatus: getTriggerRemoteStatus(trigger, remoteCronIds)
416
+ }));
417
+ if (json) yield* Console.log(JSON.stringify(triggersWithStatus.map(({ trigger, remoteStatus }) => ({
418
+ ...trigger,
419
+ remoteStatus
420
+ })), null, 2));
421
+ else if (triggersWithStatus.length === 0) yield* Console.log("No triggers found.");
422
+ else {
423
+ const items = yield* Effect.all(triggersWithStatus.map(({ trigger, remoteStatus }) => printTrigger(trigger, remoteStatus)));
424
+ yield* Console.log(printList(items));
425
+ }
426
+ })).pipe(Command.withDescription("List triggers configured on EDGE."), Command.provide(({ spaceId }) => spaceLayer(spaceId, true)));
427
+ //#endregion
428
+ //#region src/commands/trigger/remove.ts
429
+ var remove = Command.make("remove", {
430
+ spaceId: Common.spaceId.pipe(Options.optional),
431
+ id: TriggerId.pipe(Options.optional)
432
+ }, (options) => Effect.gen(function* () {
433
+ const { json } = yield* CommandConfig;
434
+ const triggerId = yield* Option.match(options.id, {
435
+ onNone: () => selectTrigger(),
436
+ onSome: (id) => Effect.succeed(id)
437
+ });
438
+ const dxn = EID.make({ entityId: triggerId });
439
+ const trigger = yield* Database.resolve(Ref.fromURI(dxn), Trigger.Trigger);
440
+ yield* Database.remove(trigger);
441
+ if (json) yield* Console.log(JSON.stringify({
442
+ id: trigger.id,
443
+ removed: true
444
+ }, null, 2));
445
+ else yield* Console.log(print(printTriggerRemoved(trigger.id)));
446
+ })).pipe(Command.withDescription("Remove a trigger."), Command.provide(({ spaceId }) => spaceLayer(spaceId, true)), Command.provideEffectDiscard(() => withTypes(Trigger.Trigger)));
447
+ //#endregion
448
+ //#region src/commands/trigger/update/feed.ts
449
+ var feed = Command.make("feed", {
450
+ spaceId: Common.spaceId.pipe(Options.optional),
451
+ id: TriggerId.pipe(Options.optional),
452
+ enabled: Enabled,
453
+ functionId: Common.functionId.pipe(Options.optional),
454
+ feed: Feed$1.pipe(Options.optional),
455
+ input: Input.pipe(Options.optional)
456
+ }, (options) => Effect.gen(function* () {
457
+ const { json } = yield* CommandConfig;
458
+ const triggerId = yield* Option.match(options.id, {
459
+ onNone: () => selectTrigger("feed"),
460
+ onSome: (id) => Effect.succeed(id)
461
+ });
462
+ const dxn = EID.make({ entityId: triggerId });
463
+ const trigger = yield* Database.resolve(dxn, Trigger.Trigger);
464
+ if (trigger.spec?.kind !== "feed") return yield* Effect.fail(/* @__PURE__ */ new Error(`Invalid trigger type: ${trigger.spec?.kind}`));
465
+ const currentFn = yield* updateFunction$2(trigger, options.functionId);
466
+ yield* updateFeed(trigger, options.feed);
467
+ yield* updateInput$2(trigger, currentFn, options.input);
468
+ yield* updateEnabled$2(trigger, options.id, options.enabled);
469
+ if (json) yield* Console.log(JSON.stringify(trigger, null, 2));
470
+ else yield* Console.log(print(yield* printTrigger(trigger)));
471
+ yield* flushAndSync({ indexes: true });
472
+ })).pipe(Command.withDescription("Update a feed trigger."), Command.provide(({ spaceId }) => spaceLayer(spaceId, true)), Command.provideEffectDiscard(() => withTypes(Operation.PersistentOperation, Trigger.Trigger)));
473
+ /**
474
+ * Handles updating the function for a trigger.
475
+ * Prompts for confirmation if functionId is not provided, then updates the function if confirmed.
476
+ * @returns The current function (either original or newly assigned)
477
+ */
478
+ var updateFunction$2 = Effect.fn(function* (trigger, functionIdOption) {
479
+ let currentFn = trigger.runnable ? yield* Database.load(trigger.runnable) : void 0;
480
+ if (currentFn && !Obj.instanceOf(Operation.PersistentOperation, currentFn)) currentFn = void 0;
481
+ const currentFunctionName = currentFn ? currentFn.name ?? currentFn.id : void 0;
482
+ if (yield* Option.match(functionIdOption, {
483
+ onNone: () => Prompt.confirm({
484
+ message: `Change the function${currentFunctionName ? ` (current: ${currentFunctionName})` : ""}?`,
485
+ initial: false
486
+ }).pipe(Prompt.run),
487
+ onSome: () => Effect.succeed(true)
488
+ })) {
489
+ const functionId = yield* Option.match(functionIdOption, {
490
+ onNone: () => selectFunction(),
491
+ onSome: (id) => Effect.succeed(id)
492
+ });
493
+ const foundFn = (yield* Database.query(Filter.type(Operation.PersistentOperation)).run).find((fn) => fn.id === functionId);
494
+ if (!foundFn || !Obj.instanceOf(Operation.PersistentOperation, foundFn)) return yield* Effect.fail(/* @__PURE__ */ new Error(`Function not found: ${functionId}`));
495
+ Obj.update(trigger, (trigger) => {
496
+ trigger.runnable = Ref.make(foundFn);
497
+ });
498
+ currentFn = foundFn;
499
+ }
500
+ if (!currentFn) {
501
+ const runnableId = (trigger.runnable ? trigger.runnable.uri.toString() : void 0) ?? "unknown";
502
+ return yield* Effect.fail(/* @__PURE__ */ new Error(`Invalid reference for ${runnableId}`));
503
+ }
504
+ return currentFn;
505
+ });
506
+ /**
507
+ * Handles updating the feed reference for a feed trigger.
508
+ * Prompts for confirmation if feed is not provided, then updates the feed if confirmed.
509
+ */
510
+ var updateFeed = Effect.fn(function* (trigger, feedOption) {
511
+ const currentFeed = trigger.spec?.kind === "feed" ? trigger.spec.feed : void 0;
512
+ const currentFeedStr = currentFeed ? currentFeed.uri.toString() : void 0;
513
+ if (yield* Option.match(feedOption, {
514
+ onNone: () => Prompt.confirm({
515
+ message: `Change the feed${currentFeedStr ? ` (current: ${currentFeedStr})` : ""}?`,
516
+ initial: false
517
+ }).pipe(Prompt.run),
518
+ onSome: () => Effect.succeed(true)
519
+ })) {
520
+ const feed = yield* Option.match(feedOption, {
521
+ onNone: () => selectFeed(),
522
+ onSome: (uri) => Database.resolve(EID.parse(uri), Feed.Feed)
523
+ });
524
+ Obj.update(trigger, (trigger) => {
525
+ if (trigger.spec?.kind === "feed") trigger.spec.feed = Ref.make(feed);
526
+ });
527
+ }
528
+ });
529
+ /**
530
+ * Handles updating the input for a trigger.
531
+ * Prompts for confirmation if input is not provided, then updates the input if confirmed.
532
+ */
533
+ var updateInput$2 = Effect.fn(function* (trigger, fn, inputOption) {
534
+ const currentInput = trigger.input;
535
+ const currentInputStr = currentInput ? JSON.stringify(currentInput) : "none";
536
+ if (yield* Option.match(inputOption, {
537
+ onNone: () => Effect.gen(function* () {
538
+ yield* Console.log(`Current input: ${currentInputStr}`);
539
+ return yield* Prompt.confirm({
540
+ message: "Change input?",
541
+ initial: false
542
+ }).pipe(Prompt.run);
543
+ }),
544
+ onSome: () => Effect.succeed(true)
545
+ })) {
546
+ const inputObj = yield* Option.match(inputOption, {
547
+ onNone: () => promptForSchemaInput(fn.inputSchema ? JsonSchema.toEffectSchema(fn.inputSchema) : void 0, currentInput),
548
+ onSome: (value) => Effect.succeed(value)
549
+ });
550
+ Obj.update(trigger, (trigger) => {
551
+ trigger.input = inputObj;
552
+ });
553
+ }
554
+ });
555
+ /**
556
+ * Handles updating the enabled status for a trigger.
557
+ * Prompts for enabled if id is not provided.
558
+ */
559
+ var updateEnabled$2 = Effect.fn(function* (trigger, idOption, enabled) {
560
+ const enabledValue = yield* Option.match(idOption, {
561
+ onNone: () => Prompt.confirm({
562
+ message: "Enable the trigger?",
563
+ initial: trigger.enabled
564
+ }).pipe(Prompt.run),
565
+ onSome: () => Effect.succeed(enabled)
566
+ });
567
+ Obj.update(trigger, (trigger) => {
568
+ trigger.enabled = enabledValue;
569
+ });
570
+ });
571
+ //#endregion
572
+ //#region src/commands/trigger/update/subscription.ts
573
+ var subscription = Command.make("subscription", {
574
+ spaceId: Common.spaceId.pipe(Options.optional),
575
+ id: TriggerId.pipe(Options.optional),
576
+ enabled: Enabled,
577
+ functionId: Common.functionId.pipe(Options.optional),
578
+ typename: Typename.pipe(Options.optional),
579
+ deep: Deep.pipe(Options.optional),
580
+ delay: Delay.pipe(Options.optional),
581
+ input: Input.pipe(Options.optional)
582
+ }, (options) => Effect.gen(function* () {
583
+ const { json } = yield* CommandConfig;
584
+ const triggerId = yield* Option.match(options.id, {
585
+ onNone: () => selectTrigger("subscription"),
586
+ onSome: (id) => Effect.succeed(id)
587
+ });
588
+ const dxn = EID.make({ entityId: triggerId });
589
+ const trigger = yield* Database.resolve(Ref.fromURI(dxn), Trigger.Trigger);
590
+ if (trigger.spec?.kind !== "subscription") return yield* Effect.fail(/* @__PURE__ */ new Error(`Invalid trigger type: ${trigger.spec?.kind}`));
591
+ const currentFn = yield* updateFunction$1(trigger, options.functionId);
592
+ yield* updateSpec(trigger, options.typename, options.deep, options.delay);
593
+ yield* updateInput$1(trigger, currentFn, options.input);
594
+ yield* updateEnabled$1(trigger, options.id, options.enabled);
595
+ if (json) yield* Console.log(JSON.stringify(trigger, null, 2));
596
+ else yield* Console.log(print(yield* printTrigger(trigger)));
597
+ yield* flushAndSync({ indexes: true });
598
+ })).pipe(Command.withDescription("Update a subscription trigger."), Command.provide(({ spaceId }) => spaceLayer(spaceId, true)), Command.provideEffectDiscard(() => withTypes(Operation.PersistentOperation, Trigger.Trigger)));
599
+ /**
600
+ * Extracts the current typename from a subscription trigger's query AST.
601
+ */
602
+ var extractCurrentTypename = (spec) => {
603
+ if (!spec?.query?.ast) return Option.none();
604
+ return Match.value(spec.query.ast).pipe(Match.withReturnType(), Match.when({ type: "select" }, (q) => Match.value(q.filter).pipe(Match.withReturnType(), Match.when({ type: "object" }, (f) => Option.fromNullable(f.typename).pipe(Option.flatMap((dxn) => Option.fromNullable(DXN$1.isDXN(dxn) ? DXN$1.getName(dxn) : void 0)))), Match.orElse(() => Option.none()))), Match.orElse(() => Option.none()));
605
+ };
606
+ /**
607
+ * Handles updating the function for a trigger.
608
+ * Prompts for confirmation if functionId is not provided, then updates the function if confirmed.
609
+ * @returns The current function (either original or newly assigned)
610
+ */
611
+ var updateFunction$1 = Effect.fn(function* (trigger, functionIdOption) {
612
+ let currentFn = trigger.runnable ? yield* Database.load(trigger.runnable) : void 0;
613
+ if (currentFn && !Obj.instanceOf(Operation.PersistentOperation, currentFn)) currentFn = void 0;
614
+ const currentFunctionName = currentFn ? currentFn.name ?? currentFn.id : void 0;
615
+ if (yield* Option.match(functionIdOption, {
616
+ onNone: () => Prompt.confirm({
617
+ message: `Change the function${currentFunctionName ? ` (current: ${currentFunctionName})` : ""}?`,
618
+ initial: false
619
+ }).pipe(Prompt.run),
620
+ onSome: () => Effect.succeed(true)
621
+ })) {
622
+ const functionId = yield* Option.match(functionIdOption, {
623
+ onNone: () => selectFunction(),
624
+ onSome: (id) => Effect.succeed(id)
625
+ });
626
+ const foundFn = (yield* Database.query(Filter.type(Operation.PersistentOperation)).run).find((fn) => fn.id === functionId);
627
+ if (!foundFn || !Obj.instanceOf(Operation.PersistentOperation, foundFn)) return yield* Effect.fail(/* @__PURE__ */ new Error(`Function not found: ${functionId}`));
628
+ Obj.update(trigger, (trigger) => {
629
+ trigger.runnable = Ref.make(foundFn);
630
+ });
631
+ currentFn = foundFn;
632
+ }
633
+ if (!currentFn) {
634
+ const runnableId = trigger.runnable?.uri.toString() ?? "unknown";
635
+ return yield* Effect.fail(/* @__PURE__ */ new Error(`Invalid reference for ${runnableId}`));
636
+ }
637
+ return currentFn;
638
+ });
639
+ /**
640
+ * Handles updating the subscription trigger spec (typename, deep, delay).
641
+ * Prompts for confirmation if no spec options are provided, then updates the spec if confirmed.
642
+ */
643
+ var updateSpec = Effect.fn(function* (trigger, typenameOption, deepOption, delayOption) {
644
+ const currentSpec = trigger.spec?.kind === "subscription" ? trigger.spec : void 0;
645
+ const currentTypename = extractCurrentTypename(currentSpec);
646
+ const currentTypenameStr = Option.getOrUndefined(currentTypename);
647
+ const currentDeep = currentSpec?.options?.deep;
648
+ const currentDelay = currentSpec?.options?.delay;
649
+ const specParts = [];
650
+ if (currentTypenameStr) specParts.push(`typename: ${currentTypenameStr}`);
651
+ if (currentDeep !== void 0) specParts.push(`deep: ${currentDeep}`);
652
+ if (currentDelay !== void 0) specParts.push(`delay: ${currentDelay}`);
653
+ const currentSpecStr = specParts.length > 0 ? specParts.join(", ") : "none";
654
+ if (yield* Option.isSome(typenameOption) || Option.isSome(deepOption) || Option.isSome(delayOption) ? Effect.succeed(true) : Prompt.confirm({
655
+ message: `Change the trigger spec (current: ${currentSpecStr})?`,
656
+ initial: false
657
+ }).pipe(Prompt.run)) {
658
+ const typename = yield* Option.match(typenameOption, {
659
+ onNone: () => Prompt.text({ message: `Enter type name${currentTypenameStr ? ` (current: ${currentTypenameStr})` : ""}:` }).pipe(Prompt.run),
660
+ onSome: (value) => Effect.succeed(value)
661
+ });
662
+ const queryAst = Query.select(Filter.type(DXN$1.make(typename))).ast;
663
+ const deepOptionValue = yield* Option.match(deepOption, {
664
+ onNone: () => Prompt.confirm({
665
+ message: "Watch changes to nested properties (deep)?",
666
+ initial: currentSpec?.options?.deep ?? false
667
+ }).pipe(Prompt.run, Effect.map((value) => value ? Option.some(value) : Option.none())),
668
+ onSome: () => Effect.succeed(Option.some(true))
669
+ });
670
+ const delayOptionValue = yield* Option.match(delayOption, {
671
+ onNone: () => Effect.gen(function* () {
672
+ const currentDelay = currentSpec?.options?.delay;
673
+ const delayStr = yield* Prompt.text({ message: `Debounce delay in milliseconds (optional, press Enter to skip)${currentDelay ? ` (current: ${currentDelay})` : ""}:` }).pipe(Prompt.run);
674
+ return delayStr === "" ? Option.none() : Option.some(parseInt(delayStr, 10));
675
+ }),
676
+ onSome: (value) => Effect.succeed(Option.some(value))
677
+ });
678
+ const subscriptionOptions = {};
679
+ if (Option.isSome(deepOptionValue)) subscriptionOptions.deep = deepOptionValue.value;
680
+ if (Option.isSome(delayOptionValue)) subscriptionOptions.delay = delayOptionValue.value;
681
+ Obj.update(trigger, (trigger) => {
682
+ const spec = trigger.spec;
683
+ if (spec?.kind === "subscription") {
684
+ spec.query = { ast: queryAst };
685
+ spec.options = Object.keys(subscriptionOptions).length > 0 ? subscriptionOptions : void 0;
686
+ }
687
+ });
688
+ }
689
+ });
690
+ /**
691
+ * Handles updating the input for a trigger.
692
+ * Prompts for confirmation if input is not provided, then updates the input if confirmed.
693
+ */
694
+ var updateInput$1 = Effect.fn(function* (trigger, fn, inputOption) {
695
+ const currentInput = trigger.input;
696
+ const currentInputStr = currentInput ? JSON.stringify(currentInput) : "none";
697
+ if (yield* Option.match(inputOption, {
698
+ onNone: () => Effect.gen(function* () {
699
+ yield* Console.log(`Current input: ${currentInputStr}`);
700
+ return yield* Prompt.confirm({
701
+ message: "Change input?",
702
+ initial: false
703
+ }).pipe(Prompt.run);
704
+ }),
705
+ onSome: () => Effect.succeed(true)
706
+ })) {
707
+ const inputObj = yield* Option.match(inputOption, {
708
+ onNone: () => promptForSchemaInput(fn.inputSchema ? JsonSchema.toEffectSchema(fn.inputSchema) : void 0, currentInput),
709
+ onSome: (value) => Effect.succeed(value)
710
+ });
711
+ Obj.update(trigger, (trigger) => {
712
+ trigger.input = inputObj;
713
+ });
714
+ }
715
+ });
716
+ /**
717
+ * Handles updating the enabled status for a trigger.
718
+ * Prompts for enabled if id is not provided.
719
+ */
720
+ var updateEnabled$1 = Effect.fn(function* (trigger, idOption, enabled) {
721
+ const enabledValue = yield* Option.match(idOption, {
722
+ onNone: () => Prompt.confirm({
723
+ message: "Enable the trigger?",
724
+ initial: trigger.enabled
725
+ }).pipe(Prompt.run),
726
+ onSome: () => Effect.succeed(enabled)
727
+ });
728
+ Obj.update(trigger, (trigger) => {
729
+ trigger.enabled = enabledValue;
730
+ });
731
+ });
732
+ //#endregion
733
+ //#region src/commands/trigger/update/timer.ts
734
+ var timer = Command.make("timer", {
735
+ spaceId: Common.spaceId.pipe(Options.optional),
736
+ id: TriggerId.pipe(Options.optional),
737
+ enabled: Enabled,
738
+ functionId: Common.functionId.pipe(Options.optional),
739
+ cron: Cron.pipe(Options.optional),
740
+ input: Input.pipe(Options.optional)
741
+ }, (options) => Effect.gen(function* () {
742
+ const { json } = yield* CommandConfig;
743
+ const triggerId = yield* Option.match(options.id, {
744
+ onNone: () => selectTrigger("timer"),
745
+ onSome: (id) => Effect.succeed(id)
746
+ });
747
+ const dxn = EID.make({ entityId: triggerId });
748
+ const trigger = yield* Database.resolve(Ref.fromURI(dxn), Trigger.Trigger);
749
+ if (!trigger.spec || trigger.spec?.kind !== "timer") return yield* Effect.fail(/* @__PURE__ */ new Error(`Invalid trigger type: ${trigger.spec?.kind}`));
750
+ const currentFn = yield* updateFunction(trigger, options.functionId);
751
+ yield* updateCron(trigger, options.cron);
752
+ yield* updateInput(trigger, currentFn, options.input);
753
+ yield* updateEnabled(trigger, options.id, options.enabled);
754
+ if (json) yield* Console.log(JSON.stringify(trigger, null, 2));
755
+ else yield* Console.log(print(yield* printTrigger(trigger)));
756
+ yield* flushAndSync({ indexes: true });
757
+ })).pipe(Command.withDescription("Update a timer trigger."), Command.provide(({ spaceId }) => spaceLayer(spaceId, true)), Command.provideEffectDiscard(() => withTypes(Operation.PersistentOperation, Trigger.Trigger)));
758
+ /**
759
+ * Handles updating the function for a trigger.
760
+ * Prompts for confirmation if functionId is not provided, then updates the function if confirmed.
761
+ * @returns The current function (either original or newly assigned)
762
+ */
763
+ var updateFunction = Effect.fn(function* (trigger, functionIdOption) {
764
+ let currentFn = trigger.runnable ? yield* Database.load(trigger.runnable) : void 0;
765
+ if (currentFn && !Obj.instanceOf(Operation.PersistentOperation, currentFn)) currentFn = void 0;
766
+ const currentFunctionName = currentFn ? currentFn.name ?? currentFn.id : void 0;
767
+ if (yield* Option.match(functionIdOption, {
768
+ onNone: () => Prompt.confirm({
769
+ message: `Change the function${currentFunctionName ? ` (current: ${currentFunctionName})` : ""}?`,
770
+ initial: false
771
+ }).pipe(Prompt.run),
772
+ onSome: () => Effect.succeed(true)
773
+ })) {
774
+ const functionId = yield* Option.match(functionIdOption, {
775
+ onNone: () => selectFunction(),
776
+ onSome: (id) => Effect.succeed(id)
777
+ });
778
+ const foundFn = (yield* Database.query(Filter.type(Operation.PersistentOperation)).run).find((fn) => fn.id === functionId);
779
+ if (!foundFn || !Obj.instanceOf(Operation.PersistentOperation, foundFn)) return yield* Effect.fail(/* @__PURE__ */ new Error(`Function not found: ${functionId}`));
780
+ Obj.update(trigger, (trigger) => {
781
+ trigger.runnable = Ref.make(foundFn);
782
+ });
783
+ currentFn = foundFn;
784
+ }
785
+ if (!currentFn) {
786
+ const runnableId = trigger.runnable?.uri.toString() ?? "unknown";
787
+ return yield* Effect.fail(/* @__PURE__ */ new Error(`Invalid reference for ${runnableId}`));
788
+ }
789
+ return currentFn;
790
+ });
791
+ /**
792
+ * Handles updating the cron expression for a timer trigger.
793
+ * Prompts for confirmation if cron is not provided, then updates the cron if confirmed.
794
+ */
795
+ var updateCron = Effect.fn(function* (trigger, cronOption) {
796
+ const currentCron = trigger.spec?.kind === "timer" ? trigger.spec.cron : void 0;
797
+ if (yield* Option.match(cronOption, {
798
+ onNone: () => Prompt.confirm({
799
+ message: `Change the cron expression${currentCron ? ` (current: ${currentCron})` : ""}?`,
800
+ initial: false
801
+ }).pipe(Prompt.run),
802
+ onSome: () => Effect.succeed(true)
803
+ })) {
804
+ const cron = yield* Option.match(cronOption, {
805
+ onNone: () => Prompt.text({ message: `Enter cron expression${currentCron ? ` (current: ${currentCron})` : ""}:` }).pipe(Prompt.run),
806
+ onSome: (value) => Effect.succeed(value)
807
+ });
808
+ Obj.update(trigger, (trigger) => {
809
+ if (trigger.spec?.kind === "timer") trigger.spec.cron = cron;
810
+ });
811
+ }
812
+ });
813
+ /**
814
+ * Handles updating the input for a trigger.
815
+ * Prompts for confirmation if input is not provided, then updates the input if confirmed.
816
+ */
817
+ var updateInput = Effect.fn(function* (trigger, fn, inputOption) {
818
+ const currentInput = trigger.input;
819
+ const currentInputStr = currentInput ? JSON.stringify(currentInput) : "none";
820
+ if (yield* Option.match(inputOption, {
821
+ onNone: () => Effect.gen(function* () {
822
+ yield* Console.log(`Current input: ${currentInputStr}`);
823
+ return yield* Prompt.confirm({
824
+ message: "Change input?",
825
+ initial: false
826
+ }).pipe(Prompt.run);
827
+ }),
828
+ onSome: () => Effect.succeed(true)
829
+ })) {
830
+ const inputObj = yield* Option.match(inputOption, {
831
+ onNone: () => promptForSchemaInput(fn.inputSchema ? JsonSchema.toEffectSchema(fn.inputSchema) : void 0, currentInput),
832
+ onSome: (value) => Effect.succeed(value)
833
+ });
834
+ Obj.update(trigger, (trigger) => {
835
+ trigger.input = inputObj;
836
+ });
837
+ }
838
+ });
839
+ /**
840
+ * Handles updating the enabled status for a trigger.
841
+ * Prompts for enabled if id is not provided.
842
+ */
843
+ var updateEnabled = Effect.fn(function* (trigger, idOption, enabled) {
844
+ const enabledValue = yield* Option.match(idOption, {
845
+ onNone: () => Prompt.confirm({
846
+ message: "Enable the trigger?",
847
+ initial: trigger.enabled
848
+ }).pipe(Prompt.run),
849
+ onSome: () => Effect.succeed(enabled)
850
+ });
851
+ Obj.update(trigger, (trigger) => {
852
+ trigger.enabled = enabledValue;
853
+ });
854
+ });
855
+ //#endregion
856
+ //#region src/commands/trigger/update/index.ts
857
+ var update = Command.make("update").pipe(Command.withDescription("Update a trigger."), Command.withSubcommands([
858
+ subscription,
859
+ timer,
860
+ feed
861
+ ]));
862
+ //#endregion
863
+ //#region src/commands/trigger/index.ts
864
+ var trigger = Command.make("trigger").pipe(Command.withDescription("Manage EDGE triggers."), Command.withSubcommands([
865
+ create,
866
+ list,
867
+ remove,
868
+ update
869
+ ]));
870
+ //#endregion
871
+ //#region src/RoutinePlugin.node.ts
872
+ var RoutinePlugin = Plugin.define(meta).pipe(AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }), AppPlugin.addCommandModule({ commands: [trigger] }), AppPlugin.addOperationHandlerModule({ activate: OperationHandler }), AppPlugin.addSchemaModule({ schema: [
873
+ Routine.Routine,
874
+ Operation.PersistentOperation,
875
+ Trigger.Trigger,
876
+ Trace.Message
877
+ ] }), Plugin.addModule({
878
+ id: "automation-templates",
879
+ activatesOn: AppActivationEvents.SetupSchema,
880
+ activate: Templates
881
+ }), Plugin.addModule({
882
+ activatesOn: ActivationEvents.SetupProcessManager,
883
+ activate: LayerSpecs
884
+ }), Plugin.addModule({
885
+ activatesOn: ClientEvents.ClientReady,
886
+ activate: RegistrySync
887
+ }), Plugin.addModule({
888
+ activatesOn: ActivationEvent.allOf(ActivationEvents.ProcessManagerReady, ClientEvents.SpacesReady),
889
+ activate: TriggerRuntimeController
890
+ }), Plugin.make);
891
+ //#endregion
892
+ export { RoutinePlugin, RoutinePlugin as default };
893
+
894
+ //# sourceMappingURL=RoutinePlugin.node.mjs.map