@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.
- package/LICENSE +105 -0
- package/PLUGIN.mdl +475 -0
- package/README.md +15 -0
- package/dist/lib/neutral/RoutineArticle-UNTMV4CC.mjs +95 -0
- package/dist/lib/neutral/RoutineArticle-UNTMV4CC.mjs.map +7 -0
- package/dist/lib/neutral/RoutineCompanion-ZZ6WMY7I.mjs +249 -0
- package/dist/lib/neutral/RoutineCompanion-ZZ6WMY7I.mjs.map +7 -0
- package/dist/lib/neutral/RoutinePlugin.mjs +10 -0
- package/dist/lib/neutral/RoutinePlugin.mjs.map +7 -0
- package/dist/lib/neutral/RoutinePlugin.node.mjs +1133 -0
- package/dist/lib/neutral/RoutinePlugin.node.mjs.map +7 -0
- package/dist/lib/neutral/RoutinePlugin.workerd.mjs +36 -0
- package/dist/lib/neutral/RoutinePlugin.workerd.mjs.map +7 -0
- package/dist/lib/neutral/RoutineSettings-ZJOM4F3S.mjs +48 -0
- package/dist/lib/neutral/RoutineSettings-ZJOM4F3S.mjs.map +7 -0
- package/dist/lib/neutral/RoutineTraceCompanion-5U6R7LJE.mjs +236 -0
- package/dist/lib/neutral/RoutineTraceCompanion-5U6R7LJE.mjs.map +7 -0
- package/dist/lib/neutral/SkillArticle-WWDNKW2Z.mjs +27 -0
- package/dist/lib/neutral/SkillArticle-WWDNKW2Z.mjs.map +7 -0
- package/dist/lib/neutral/app-graph-builder-FALWLZTI.mjs +90 -0
- package/dist/lib/neutral/app-graph-builder-FALWLZTI.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +25 -0
- package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/node.mjs +19 -0
- package/dist/lib/neutral/capabilities/node.mjs.map +7 -0
- package/dist/lib/neutral/chunk-674LDIUJ.mjs +9 -0
- package/dist/lib/neutral/chunk-674LDIUJ.mjs.map +7 -0
- package/dist/lib/neutral/chunk-CNYAPXUW.mjs +65 -0
- package/dist/lib/neutral/chunk-CNYAPXUW.mjs.map +7 -0
- package/dist/lib/neutral/chunk-HLO4LYXT.mjs +44 -0
- package/dist/lib/neutral/chunk-HLO4LYXT.mjs.map +7 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/neutral/chunk-ODQDVFMZ.mjs +8 -0
- package/dist/lib/neutral/chunk-ODQDVFMZ.mjs.map +7 -0
- package/dist/lib/neutral/chunk-R7J2MU2M.mjs +263 -0
- package/dist/lib/neutral/chunk-R7J2MU2M.mjs.map +7 -0
- package/dist/lib/neutral/chunk-WLNL77C7.mjs +14 -0
- package/dist/lib/neutral/chunk-WLNL77C7.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +1921 -0
- package/dist/lib/neutral/components/index.mjs.map +7 -0
- package/dist/lib/neutral/containers/index.mjs +17 -0
- package/dist/lib/neutral/containers/index.mjs.map +7 -0
- package/dist/lib/neutral/create-object-V23KVDMJ.mjs +25 -0
- package/dist/lib/neutral/create-object-V23KVDMJ.mjs.map +7 -0
- package/dist/lib/neutral/create-routine-I67BYJA2.mjs +38 -0
- package/dist/lib/neutral/create-routine-I67BYJA2.mjs.map +7 -0
- package/dist/lib/neutral/create-trigger-from-template-U3KNS77V.mjs +70 -0
- package/dist/lib/neutral/create-trigger-from-template-U3KNS77V.mjs.map +7 -0
- package/dist/lib/neutral/hooks/index.mjs +47 -0
- package/dist/lib/neutral/hooks/index.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +27 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/layer-specs-ADQCTTRT.mjs +135 -0
- package/dist/lib/neutral/layer-specs-ADQCTTRT.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/meta.mjs +8 -0
- package/dist/lib/neutral/meta.mjs.map +7 -0
- package/dist/lib/neutral/navigation-resolver-KQIWUH6F.mjs +18 -0
- package/dist/lib/neutral/navigation-resolver-KQIWUH6F.mjs.map +7 -0
- package/dist/lib/neutral/operation-handler-QKLJSDCQ.mjs +13 -0
- package/dist/lib/neutral/operation-handler-QKLJSDCQ.mjs.map +7 -0
- package/dist/lib/neutral/operations/index.mjs +8 -0
- package/dist/lib/neutral/operations/index.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +16 -0
- package/dist/lib/neutral/plugin.mjs.map +7 -0
- package/dist/lib/neutral/react-surface-GMO7I7YE.mjs +67 -0
- package/dist/lib/neutral/react-surface-GMO7I7YE.mjs.map +7 -0
- package/dist/lib/neutral/registry-sync-PHBU6CH2.mjs +86 -0
- package/dist/lib/neutral/registry-sync-PHBU6CH2.mjs.map +7 -0
- package/dist/lib/neutral/run-routine-HJWXIWLJ.mjs +37 -0
- package/dist/lib/neutral/run-routine-HJWXIWLJ.mjs.map +7 -0
- package/dist/lib/neutral/templates-IIUCEBAX.mjs +49 -0
- package/dist/lib/neutral/templates-IIUCEBAX.mjs.map +7 -0
- package/dist/lib/neutral/testing.mjs +8 -0
- package/dist/lib/neutral/testing.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +115 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/lib/neutral/trigger-runtime-controller-7FOTH2NP.mjs +77 -0
- package/dist/lib/neutral/trigger-runtime-controller-7FOTH2NP.mjs.map +7 -0
- package/dist/lib/neutral/types/index.mjs +17 -0
- package/dist/lib/neutral/types/index.mjs.map +7 -0
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/RoutinePlugin.d.ts +4 -0
- package/dist/types/src/RoutinePlugin.d.ts.map +1 -0
- package/dist/types/src/RoutinePlugin.node.d.ts +4 -0
- package/dist/types/src/RoutinePlugin.node.d.ts.map +1 -0
- package/dist/types/src/RoutinePlugin.test.d.ts +2 -0
- package/dist/types/src/RoutinePlugin.test.d.ts.map +1 -0
- package/dist/types/src/RoutinePlugin.workerd.d.ts +4 -0
- package/dist/types/src/RoutinePlugin.workerd.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts +5 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/create-object.d.ts +5 -0
- package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
- package/dist/types/src/capabilities/create-object.test.d.ts +2 -0
- package/dist/types/src/capabilities/create-object.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +12 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/layer-specs.d.ts +5 -0
- package/dist/types/src/capabilities/layer-specs.d.ts.map +1 -0
- package/dist/types/src/capabilities/navigation-resolver.d.ts +5 -0
- package/dist/types/src/capabilities/navigation-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/node.d.ts +9 -0
- package/dist/types/src/capabilities/node.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/registry-sync.d.ts +21 -0
- package/dist/types/src/capabilities/registry-sync.d.ts.map +1 -0
- package/dist/types/src/capabilities/templates.d.ts +5 -0
- package/dist/types/src/capabilities/templates.d.ts.map +1 -0
- package/dist/types/src/capabilities/trigger-runtime-controller.d.ts +5 -0
- package/dist/types/src/capabilities/trigger-runtime-controller.d.ts.map +1 -0
- package/dist/types/src/capabilities/trigger-runtime-controller.test.d.ts +2 -0
- package/dist/types/src/capabilities/trigger-runtime-controller.test.d.ts.map +1 -0
- package/dist/types/src/commands/index.d.ts +2 -0
- package/dist/types/src/commands/index.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/create/index.d.ts +25 -0
- package/dist/types/src/commands/trigger/create/index.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/create/queue.d.ts +13 -0
- package/dist/types/src/commands/trigger/create/queue.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/create/subscription.d.ts +15 -0
- package/dist/types/src/commands/trigger/create/subscription.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/create/timer.d.ts +13 -0
- package/dist/types/src/commands/trigger/create/timer.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/index.d.ts +57 -0
- package/dist/types/src/commands/trigger/index.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/list.d.ts +7 -0
- package/dist/types/src/commands/trigger/list.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/options.d.ts +10 -0
- package/dist/types/src/commands/trigger/options.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/remove.d.ts +8 -0
- package/dist/types/src/commands/trigger/remove.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/update/index.d.ts +28 -0
- package/dist/types/src/commands/trigger/update/index.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/update/queue.d.ts +13 -0
- package/dist/types/src/commands/trigger/update/queue.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/update/subscription.d.ts +15 -0
- package/dist/types/src/commands/trigger/update/subscription.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/update/timer.d.ts +13 -0
- package/dist/types/src/commands/trigger/update/timer.d.ts.map +1 -0
- package/dist/types/src/commands/trigger/util.d.ts +46 -0
- package/dist/types/src/commands/trigger/util.d.ts.map +1 -0
- package/dist/types/src/components/CreateRoutinePanel/CreateRoutinePanel.d.ts +14 -0
- package/dist/types/src/components/CreateRoutinePanel/CreateRoutinePanel.d.ts.map +1 -0
- package/dist/types/src/components/CreateRoutinePanel/index.d.ts +2 -0
- package/dist/types/src/components/CreateRoutinePanel/index.d.ts.map +1 -0
- package/dist/types/src/components/InstructionsEditor/InstructionsEditor.d.ts +16 -0
- package/dist/types/src/components/InstructionsEditor/InstructionsEditor.d.ts.map +1 -0
- package/dist/types/src/components/InstructionsEditor/InstructionsEditor.stories.d.ts +17 -0
- package/dist/types/src/components/InstructionsEditor/InstructionsEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/InstructionsEditor/index.d.ts +2 -0
- package/dist/types/src/components/InstructionsEditor/index.d.ts.map +1 -0
- package/dist/types/src/components/MasterDetail/MasterDetail.d.ts +51 -0
- package/dist/types/src/components/MasterDetail/MasterDetail.d.ts.map +1 -0
- package/dist/types/src/components/MasterDetail/MasterDetail.stories.d.ts +16 -0
- package/dist/types/src/components/MasterDetail/MasterDetail.stories.d.ts.map +1 -0
- package/dist/types/src/components/MasterDetail/index.d.ts +2 -0
- package/dist/types/src/components/MasterDetail/index.d.ts.map +1 -0
- package/dist/types/src/components/RoutineForm/RoutineForm.d.ts +25 -0
- package/dist/types/src/components/RoutineForm/RoutineForm.d.ts.map +1 -0
- package/dist/types/src/components/RoutineForm/index.d.ts +2 -0
- package/dist/types/src/components/RoutineForm/index.d.ts.map +1 -0
- package/dist/types/src/components/Schedule/Schedule.d.ts +80 -0
- package/dist/types/src/components/Schedule/Schedule.d.ts.map +1 -0
- package/dist/types/src/components/Schedule/Schedule.stories.d.ts +23 -0
- package/dist/types/src/components/Schedule/Schedule.stories.d.ts.map +1 -0
- package/dist/types/src/components/Schedule/cron.d.ts +44 -0
- package/dist/types/src/components/Schedule/cron.d.ts.map +1 -0
- package/dist/types/src/components/Schedule/cron.test.d.ts +2 -0
- package/dist/types/src/components/Schedule/cron.test.d.ts.map +1 -0
- package/dist/types/src/components/Schedule/index.d.ts +4 -0
- package/dist/types/src/components/Schedule/index.d.ts.map +1 -0
- package/dist/types/src/components/Schedule/types.d.ts +66 -0
- package/dist/types/src/components/Schedule/types.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts +13 -0
- package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts +19 -0
- package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts +21 -0
- package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/TemplateForm.stories.d.ts +16 -0
- package/dist/types/src/components/TemplateEditor/TemplateForm.stories.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/extensions/handlebars-extension.d.ts +12 -0
- package/dist/types/src/components/TemplateEditor/extensions/handlebars-extension.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/extensions/index.d.ts +3 -0
- package/dist/types/src/components/TemplateEditor/extensions/index.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/extensions/xml-extension.d.ts +8 -0
- package/dist/types/src/components/TemplateEditor/extensions/xml-extension.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/index.d.ts +2 -0
- package/dist/types/src/components/TemplateEditor/index.d.ts.map +1 -0
- package/dist/types/src/components/TemplateEditor/types.d.ts +18 -0
- package/dist/types/src/components/TemplateEditor/types.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +24 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +25 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/TriggerKindSelector.d.ts +15 -0
- package/dist/types/src/components/TriggerEditor/TriggerKindSelector.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/TriggerKindSelector.stories.d.ts +15 -0
- package/dist/types/src/components/TriggerEditor/TriggerKindSelector.stories.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/index.d.ts +2 -0
- package/dist/types/src/components/TriggerEditor/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +8 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineArticle/RoutineArticle.d.ts +14 -0
- package/dist/types/src/containers/RoutineArticle/RoutineArticle.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineArticle/RoutineArticle.stories.d.ts +20 -0
- package/dist/types/src/containers/RoutineArticle/RoutineArticle.stories.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineArticle/index.d.ts +2 -0
- package/dist/types/src/containers/RoutineArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.d.ts +17 -0
- package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.stories.d.ts +15 -0
- package/dist/types/src/containers/RoutineCompanion/RoutineCompanion.stories.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineCompanion/index.d.ts +3 -0
- package/dist/types/src/containers/RoutineCompanion/index.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineSettings/RoutineSettings.d.ts +10 -0
- package/dist/types/src/containers/RoutineSettings/RoutineSettings.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineSettings/index.d.ts +2 -0
- package/dist/types/src/containers/RoutineSettings/index.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.d.ts +9 -0
- package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.stories.d.ts +15 -0
- package/dist/types/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.stories.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineTraceCompanion/index.d.ts +2 -0
- package/dist/types/src/containers/RoutineTraceCompanion/index.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineTraceCompanion/runs.d.ts +34 -0
- package/dist/types/src/containers/RoutineTraceCompanion/runs.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineTraceCompanion/runs.test.d.ts +2 -0
- package/dist/types/src/containers/RoutineTraceCompanion/runs.test.d.ts.map +1 -0
- package/dist/types/src/containers/RoutineTraceCompanion/useRoutineRuns.d.ts +11 -0
- package/dist/types/src/containers/RoutineTraceCompanion/useRoutineRuns.d.ts.map +1 -0
- package/dist/types/src/containers/SkillArticle/SkillArticle.d.ts +6 -0
- package/dist/types/src/containers/SkillArticle/SkillArticle.d.ts.map +1 -0
- package/dist/types/src/containers/SkillArticle/index.d.ts +2 -0
- package/dist/types/src/containers/SkillArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +7 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +12 -0
- package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +33 -0
- package/dist/types/src/meta.d.ts.map +1 -0
- package/dist/types/src/operations/create-routine.d.ts +5 -0
- package/dist/types/src/operations/create-routine.d.ts.map +1 -0
- package/dist/types/src/operations/create-trigger-from-template.d.ts +5 -0
- package/dist/types/src/operations/create-trigger-from-template.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +3 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/operations/run-routine.d.ts +5 -0
- package/dist/types/src/operations/run-routine.d.ts.map +1 -0
- package/dist/types/src/paths.d.ts +5 -0
- package/dist/types/src/paths.d.ts.map +1 -0
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/templates/index.d.ts +11 -0
- package/dist/types/src/templates/index.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/test-functions.d.ts +328 -0
- package/dist/types/src/testing/test-functions.d.ts.map +1 -0
- package/dist/types/src/testing.d.ts +2 -0
- package/dist/types/src/testing.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +3 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/types/Routine.d.ts +55 -0
- package/dist/types/src/types/Routine.d.ts.map +1 -0
- package/dist/types/src/types/Routine.test.d.ts +2 -0
- package/dist/types/src/types/Routine.test.d.ts.map +1 -0
- package/dist/types/src/types/RoutineCapabilities.d.ts +44 -0
- package/dist/types/src/types/RoutineCapabilities.d.ts.map +1 -0
- package/dist/types/src/types/RoutineOperation.d.ts +45 -0
- package/dist/types/src/types/RoutineOperation.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +5 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/schema.d.ts +33 -0
- package/dist/types/src/types/schema.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +3 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/util/routines-for-object.d.ts +22 -0
- package/dist/types/src/util/routines-for-object.d.ts.map +1 -0
- package/dist/types/src/util/routines-for-object.test.d.ts +2 -0
- package/dist/types/src/util/routines-for-object.test.d.ts.map +1 -0
- package/dist/types/src/util/run-instructions.d.ts +5 -0
- package/dist/types/src/util/run-instructions.d.ts.map +1 -0
- package/dist/types/src/util/run-instructions.test.d.ts +2 -0
- package/dist/types/src/util/run-instructions.test.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/dx.config.ts +33 -0
- package/package.json +196 -0
- package/src/RoutinePlugin.node.ts +48 -0
- package/src/RoutinePlugin.test.ts +27 -0
- package/src/RoutinePlugin.tsx +58 -0
- package/src/RoutinePlugin.workerd.ts +24 -0
- package/src/capabilities/app-graph-builder.ts +80 -0
- package/src/capabilities/create-object.test.ts +18 -0
- package/src/capabilities/create-object.ts +26 -0
- package/src/capabilities/index.ts +22 -0
- package/src/capabilities/layer-specs.ts +190 -0
- package/src/capabilities/navigation-resolver.ts +21 -0
- package/src/capabilities/node.ts +19 -0
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/react-surface.tsx +66 -0
- package/src/capabilities/registry-sync.ts +114 -0
- package/src/capabilities/templates.ts +17 -0
- package/src/capabilities/trigger-runtime-controller.test.ts +107 -0
- package/src/capabilities/trigger-runtime-controller.ts +126 -0
- package/src/commands/index.ts +5 -0
- package/src/commands/trigger/create/index.ts +14 -0
- package/src/commands/trigger/create/queue.ts +87 -0
- package/src/commands/trigger/create/subscription.ts +126 -0
- package/src/commands/trigger/create/timer.ts +90 -0
- package/src/commands/trigger/index.ts +16 -0
- package/src/commands/trigger/list.ts +69 -0
- package/src/commands/trigger/options.ts +47 -0
- package/src/commands/trigger/remove.ts +45 -0
- package/src/commands/trigger/update/index.ts +14 -0
- package/src/commands/trigger/update/queue.ts +191 -0
- package/src/commands/trigger/update/subscription.ts +278 -0
- package/src/commands/trigger/update/timer.ts +194 -0
- package/src/commands/trigger/util.ts +412 -0
- package/src/components/CreateRoutinePanel/CreateRoutinePanel.tsx +68 -0
- package/src/components/CreateRoutinePanel/index.ts +5 -0
- package/src/components/InstructionsEditor/InstructionsEditor.stories.tsx +69 -0
- package/src/components/InstructionsEditor/InstructionsEditor.tsx +107 -0
- package/src/components/InstructionsEditor/index.ts +5 -0
- package/src/components/MasterDetail/MasterDetail.stories.tsx +100 -0
- package/src/components/MasterDetail/MasterDetail.tsx +175 -0
- package/src/components/MasterDetail/index.ts +5 -0
- package/src/components/RoutineForm/RoutineForm.tsx +293 -0
- package/src/components/RoutineForm/index.ts +5 -0
- package/src/components/Schedule/Schedule.stories.tsx +73 -0
- package/src/components/Schedule/Schedule.tsx +527 -0
- package/src/components/Schedule/cron.test.ts +230 -0
- package/src/components/Schedule/cron.ts +337 -0
- package/src/components/Schedule/index.ts +8 -0
- package/src/components/Schedule/types.ts +124 -0
- package/src/components/TemplateEditor/TemplateEditor.stories.tsx +93 -0
- package/src/components/TemplateEditor/TemplateEditor.tsx +77 -0
- package/src/components/TemplateEditor/TemplateForm.stories.tsx +76 -0
- package/src/components/TemplateEditor/TemplateForm.tsx +204 -0
- package/src/components/TemplateEditor/extensions/handlebars-extension.ts +274 -0
- package/src/components/TemplateEditor/extensions/index.ts +6 -0
- package/src/components/TemplateEditor/extensions/xml-extension.ts +64 -0
- package/src/components/TemplateEditor/index.ts +5 -0
- package/src/components/TemplateEditor/types.tsx +28 -0
- package/src/components/TriggerEditor/TriggerEditor.stories.tsx +122 -0
- package/src/components/TriggerEditor/TriggerEditor.tsx +365 -0
- package/src/components/TriggerEditor/TriggerKindSelector.stories.tsx +42 -0
- package/src/components/TriggerEditor/TriggerKindSelector.tsx +87 -0
- package/src/components/TriggerEditor/index.ts +5 -0
- package/src/components/index.ts +11 -0
- package/src/containers/RoutineArticle/RoutineArticle.stories.tsx +146 -0
- package/src/containers/RoutineArticle/RoutineArticle.tsx +109 -0
- package/src/containers/RoutineArticle/index.ts +5 -0
- package/src/containers/RoutineCompanion/RoutineCompanion.stories.tsx +82 -0
- package/src/containers/RoutineCompanion/RoutineCompanion.tsx +342 -0
- package/src/containers/RoutineCompanion/index.ts +6 -0
- package/src/containers/RoutineSettings/RoutineSettings.tsx +65 -0
- package/src/containers/RoutineSettings/index.ts +5 -0
- package/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.stories.tsx +133 -0
- package/src/containers/RoutineTraceCompanion/RoutineTraceCompanion.tsx +125 -0
- package/src/containers/RoutineTraceCompanion/index.ts +5 -0
- package/src/containers/RoutineTraceCompanion/runs.test.ts +140 -0
- package/src/containers/RoutineTraceCompanion/runs.ts +135 -0
- package/src/containers/RoutineTraceCompanion/useRoutineRuns.ts +50 -0
- package/src/containers/SkillArticle/SkillArticle.tsx +29 -0
- package/src/containers/SkillArticle/index.ts +5 -0
- package/src/containers/index.ts +11 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/useTriggerRuntimeControls.ts +70 -0
- package/src/index.ts +7 -0
- package/src/meta.ts +9 -0
- package/src/operations/create-routine.ts +39 -0
- package/src/operations/create-trigger-from-template.ts +68 -0
- package/src/operations/index.ts +11 -0
- package/src/operations/run-routine.ts +45 -0
- package/src/paths.ts +18 -0
- package/src/plugin.ts +11 -0
- package/src/templates/index.ts +48 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/test-functions.ts +76 -0
- package/src/testing.ts +7 -0
- package/src/translations.ts +125 -0
- package/src/types/Routine.test.ts +51 -0
- package/src/types/Routine.ts +144 -0
- package/src/types/RoutineCapabilities.ts +51 -0
- package/src/types/RoutineOperation.ts +104 -0
- package/src/types/index.ts +9 -0
- package/src/types/schema.ts +31 -0
- package/src/util/index.ts +6 -0
- package/src/util/routines-for-object.test.ts +109 -0
- package/src/util/routines-for-object.ts +89 -0
- package/src/util/run-instructions.test.ts +23 -0
- package/src/util/run-instructions.ts +12 -0
- package/src/vite-env.d.ts +10 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import * as Effect from 'effect/Effect';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
10
|
+
import { Trace, Trigger } from '@dxos/compute';
|
|
11
|
+
import { Database, Feed, Filter, Obj, Ref } from '@dxos/echo';
|
|
12
|
+
import { FeedTraceSink } from '@dxos/functions-runtime';
|
|
13
|
+
import { ClientPlugin } from '@dxos/plugin-client/testing';
|
|
14
|
+
import { RoutinePlugin } from '@dxos/plugin-routine/testing';
|
|
15
|
+
import { corePlugins } from '@dxos/plugin-testing';
|
|
16
|
+
import { type Space, useQuery, useSpaces } from '@dxos/react-client/echo';
|
|
17
|
+
import { Loading, withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
18
|
+
|
|
19
|
+
import { translations } from '#translations';
|
|
20
|
+
import { Routine } from '#types';
|
|
21
|
+
|
|
22
|
+
import { RoutineTraceCompanion } from './RoutineTraceCompanion';
|
|
23
|
+
|
|
24
|
+
const types = [Routine.Routine, Trigger.Trigger, Feed.Feed, Trace.Message];
|
|
25
|
+
|
|
26
|
+
// Fixed base so the seeded runs render deterministically across reloads.
|
|
27
|
+
const BASE = new Date('2026-06-26T09:00:00Z').getTime();
|
|
28
|
+
|
|
29
|
+
const event = (type: string, offset: number, data: unknown = { key: 'summarize' }): Trace.Event => ({
|
|
30
|
+
type,
|
|
31
|
+
timestamp: BASE + offset,
|
|
32
|
+
data,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/** Build a single-message run whose events match the routine's trigger. */
|
|
36
|
+
const runMessage = (opts: {
|
|
37
|
+
pid: string;
|
|
38
|
+
trigger: Ref.Ref<Trigger.Trigger>;
|
|
39
|
+
events: Trace.Event[];
|
|
40
|
+
processName?: string;
|
|
41
|
+
}) =>
|
|
42
|
+
Obj.make(Trace.Message, {
|
|
43
|
+
meta: { pid: opts.pid, processName: opts.processName, trigger: opts.trigger },
|
|
44
|
+
isEphemeral: false,
|
|
45
|
+
events: opts.events,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/** Seed a routine, its backing trace feed, and a spread of success/failure/pending runs. */
|
|
49
|
+
const seed = (space: Space) =>
|
|
50
|
+
Effect.gen(function* () {
|
|
51
|
+
const trigger = Trigger.make({ enabled: true });
|
|
52
|
+
space.db.add(Routine.make({ name: 'Summarize Notes', trigger }));
|
|
53
|
+
const feed = space.db.add(
|
|
54
|
+
Feed.make({ kind: FeedTraceSink.TRACE_FEED_KIND, name: 'Execution Trace', namespace: 'trace' }),
|
|
55
|
+
);
|
|
56
|
+
yield* Effect.promise(() => space.db.flush({ indexes: true }));
|
|
57
|
+
|
|
58
|
+
const triggerRef = Ref.make(trigger);
|
|
59
|
+
const messages = [
|
|
60
|
+
runMessage({
|
|
61
|
+
pid: 'run-0001',
|
|
62
|
+
trigger: triggerRef,
|
|
63
|
+
processName: 'summarize-notes',
|
|
64
|
+
events: [
|
|
65
|
+
event(Trace.OperationStart.key, 0),
|
|
66
|
+
event('tool.call', 800, { tool: 'fetch' }),
|
|
67
|
+
event(Trace.OperationEnd.key, 2500, { key: 'summarize', outcome: 'success' }),
|
|
68
|
+
],
|
|
69
|
+
}),
|
|
70
|
+
runMessage({
|
|
71
|
+
pid: 'run-0002',
|
|
72
|
+
trigger: triggerRef,
|
|
73
|
+
events: [
|
|
74
|
+
event(Trace.OperationStart.key, -60_000),
|
|
75
|
+
event(Trace.OperationEnd.key, -57_400, { key: 'summarize', outcome: 'failure' }),
|
|
76
|
+
],
|
|
77
|
+
}),
|
|
78
|
+
runMessage({
|
|
79
|
+
pid: 'run-0003',
|
|
80
|
+
trigger: triggerRef,
|
|
81
|
+
events: [event(Trace.OperationStart.key, -300_000)],
|
|
82
|
+
}),
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
yield* Feed.append(feed, messages).pipe(Effect.provide(Database.layer(space.db)));
|
|
86
|
+
yield* Effect.promise(() => space.db.flush({ indexes: true }));
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const withCompanion = () =>
|
|
90
|
+
withPluginManager({
|
|
91
|
+
plugins: [
|
|
92
|
+
...corePlugins(),
|
|
93
|
+
ClientPlugin({
|
|
94
|
+
types,
|
|
95
|
+
onClientInitialized: ({ client }) =>
|
|
96
|
+
Effect.gen(function* () {
|
|
97
|
+
yield* Effect.promise(() => client.halo.createIdentity());
|
|
98
|
+
const space = yield* Effect.promise(() => client.spaces.create());
|
|
99
|
+
yield* Effect.promise(() => space.waitUntilReady());
|
|
100
|
+
yield* seed(space);
|
|
101
|
+
}),
|
|
102
|
+
}),
|
|
103
|
+
RoutinePlugin(),
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const DefaultStory = () => {
|
|
108
|
+
const spaces = useSpaces();
|
|
109
|
+
const space = spaces[spaces.length - 1];
|
|
110
|
+
const [routine] = useQuery(space?.db, Filter.type(Routine.Routine));
|
|
111
|
+
if (!routine || !space?.db) {
|
|
112
|
+
return <Loading />;
|
|
113
|
+
}
|
|
114
|
+
return <RoutineTraceCompanion role='article' subject={routine} />;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const meta = {
|
|
118
|
+
title: 'plugins/plugin-routine/containers/RoutineTraceCompanion',
|
|
119
|
+
render: DefaultStory,
|
|
120
|
+
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
121
|
+
parameters: {
|
|
122
|
+
layout: 'fullscreen',
|
|
123
|
+
translations,
|
|
124
|
+
},
|
|
125
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
126
|
+
|
|
127
|
+
export default meta;
|
|
128
|
+
|
|
129
|
+
type Story = StoryObj<typeof meta>;
|
|
130
|
+
|
|
131
|
+
export const Default: Story = {
|
|
132
|
+
decorators: [withCompanion()],
|
|
133
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { Obj } from '@dxos/echo';
|
|
8
|
+
import { Icon, Panel, ScrollArea, Toolbar, useTranslation } from '@dxos/react-ui';
|
|
9
|
+
import { Accordion, Empty, Listbox } from '@dxos/react-ui-list';
|
|
10
|
+
import { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
11
|
+
|
|
12
|
+
import { meta } from '#meta';
|
|
13
|
+
import { Routine } from '#types';
|
|
14
|
+
|
|
15
|
+
import { type RoutineRun, type RunStatus } from './runs';
|
|
16
|
+
import { useRoutineRuns } from './useRoutineRuns';
|
|
17
|
+
|
|
18
|
+
const STATUS_ICONS: Record<RunStatus, string> = {
|
|
19
|
+
success: 'ph--check-circle--regular',
|
|
20
|
+
failure: 'ph--x-circle--regular',
|
|
21
|
+
pending: 'ph--clock--regular',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const STATUS_CLASSES: Record<RunStatus, string> = {
|
|
25
|
+
success: 'text-success-text',
|
|
26
|
+
failure: 'text-error-text',
|
|
27
|
+
pending: 'text-description',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type RoutineTraceCompanionProps = {
|
|
31
|
+
role?: string;
|
|
32
|
+
subject: Routine.Routine;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Companion panel showing the execution trace (runs) of a Routine. */
|
|
36
|
+
export const RoutineTraceCompanion = ({ role, subject }: RoutineTraceCompanionProps) => {
|
|
37
|
+
const { t } = useTranslation(meta.profile.key);
|
|
38
|
+
const db = Obj.getDatabase(subject);
|
|
39
|
+
const runs = useRoutineRuns(db, subject);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Panel.Root role={role}>
|
|
43
|
+
<Panel.Toolbar asChild>
|
|
44
|
+
<Toolbar.Root />
|
|
45
|
+
</Panel.Toolbar>
|
|
46
|
+
<Panel.Content asChild>
|
|
47
|
+
<ScrollArea.Root orientation='vertical'>
|
|
48
|
+
<ScrollArea.Viewport>
|
|
49
|
+
{runs.length === 0 ? (
|
|
50
|
+
<Empty label={t('history.empty.message')} />
|
|
51
|
+
) : (
|
|
52
|
+
<Accordion.Root<RoutineRun> items={runs} getId={getRunId}>
|
|
53
|
+
{({ items }) => (
|
|
54
|
+
<div className='flex flex-col'>
|
|
55
|
+
{items.map((run) => (
|
|
56
|
+
<Accordion.Item key={run.pid} item={run} classNames='border-b border-subdued-separator'>
|
|
57
|
+
<Accordion.ItemHeader hover>
|
|
58
|
+
<Listbox.ItemContent
|
|
59
|
+
icon={
|
|
60
|
+
<Icon icon={STATUS_ICONS[run.status]} size={5} classNames={STATUS_CLASSES[run.status]} />
|
|
61
|
+
}
|
|
62
|
+
title={<span className='tabular-nums'>{formatTimestamp(run.startedAt)}</span>}
|
|
63
|
+
description={`${t(`history.status.${run.status}.label`)} · ${formatDuration(run.duration)}`}
|
|
64
|
+
/>
|
|
65
|
+
</Accordion.ItemHeader>
|
|
66
|
+
{/* Match `ItemContent`'s rail/content grid so the JSON aligns under the title column. */}
|
|
67
|
+
<Accordion.ItemBody classNames='grid grid-cols-[var(--dx-rail-item)_1fr] gap-x-2'>
|
|
68
|
+
<JsonHighlighter
|
|
69
|
+
data={toJsonData(run)}
|
|
70
|
+
classNames='col-start-2 [&_pre]:!text-xs [&_code]:!text-xs'
|
|
71
|
+
/>
|
|
72
|
+
</Accordion.ItemBody>
|
|
73
|
+
</Accordion.Item>
|
|
74
|
+
))}
|
|
75
|
+
</div>
|
|
76
|
+
)}
|
|
77
|
+
</Accordion.Root>
|
|
78
|
+
)}
|
|
79
|
+
</ScrollArea.Viewport>
|
|
80
|
+
</ScrollArea.Root>
|
|
81
|
+
</Panel.Content>
|
|
82
|
+
</Panel.Root>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const formatDuration = (ms: number): string => {
|
|
87
|
+
if (ms < 1000) {
|
|
88
|
+
return `${ms}ms`;
|
|
89
|
+
}
|
|
90
|
+
if (ms < 60_000) {
|
|
91
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
92
|
+
}
|
|
93
|
+
const totalSeconds = Math.round(ms / 1000);
|
|
94
|
+
const mins = Math.floor(totalSeconds / 60);
|
|
95
|
+
const secs = totalSeconds % 60;
|
|
96
|
+
return `${mins}m ${secs}s`;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const formatTimestamp = (ts: number): string =>
|
|
100
|
+
new Date(ts).toLocaleString(undefined, {
|
|
101
|
+
year: 'numeric',
|
|
102
|
+
month: '2-digit',
|
|
103
|
+
day: '2-digit',
|
|
104
|
+
hour: '2-digit',
|
|
105
|
+
minute: '2-digit',
|
|
106
|
+
second: '2-digit',
|
|
107
|
+
hour12: false,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const toJsonData = (run: RoutineRun) => ({
|
|
111
|
+
pid: run.pid,
|
|
112
|
+
startedAt: new Date(run.startedAt).toISOString(),
|
|
113
|
+
duration: run.duration,
|
|
114
|
+
status: run.status,
|
|
115
|
+
...(run.conversation && { conversation: run.conversation.uri }),
|
|
116
|
+
events: run.events.map((evt) => ({
|
|
117
|
+
type: evt.type,
|
|
118
|
+
timestamp: new Date(evt.timestamp).toISOString(),
|
|
119
|
+
...(evt.pid && { pid: evt.pid }),
|
|
120
|
+
...(evt.processName && { processName: evt.processName }),
|
|
121
|
+
data: evt.data,
|
|
122
|
+
})),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const getRunId = (run: RoutineRun) => run.pid;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { Trace } from '@dxos/compute';
|
|
8
|
+
import { Obj, Ref } from '@dxos/echo';
|
|
9
|
+
import { EID, type EntityId } from '@dxos/keys';
|
|
10
|
+
|
|
11
|
+
import { groupIntoRuns } from './runs';
|
|
12
|
+
|
|
13
|
+
const TRIGGER_ID = 'aaaaaaaa-0000-0000-0000-000000000001' as EntityId;
|
|
14
|
+
const OTHER_TRIGGER_ID = 'bbbbbbbb-0000-0000-0000-000000000002' as EntityId;
|
|
15
|
+
|
|
16
|
+
describe('groupIntoRuns', () => {
|
|
17
|
+
test('returns empty for no messages', ({ expect }) => {
|
|
18
|
+
const runs = groupIntoRuns([], new Set([TRIGGER_ID]));
|
|
19
|
+
expect(runs).toHaveLength(0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('returns empty when no messages match trigger ids', ({ expect }) => {
|
|
23
|
+
const msg = makeMessage({ pid: 'p1', triggerEntityId: OTHER_TRIGGER_ID });
|
|
24
|
+
const runs = groupIntoRuns([msg], new Set([TRIGGER_ID]));
|
|
25
|
+
expect(runs).toHaveLength(0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('groups a single successful run', ({ expect }) => {
|
|
29
|
+
const start = makeMessage({
|
|
30
|
+
pid: 'p1',
|
|
31
|
+
triggerEntityId: TRIGGER_ID,
|
|
32
|
+
eventType: Trace.OperationStart.key,
|
|
33
|
+
timestamp: 1000,
|
|
34
|
+
});
|
|
35
|
+
const end = makeMessage({
|
|
36
|
+
pid: 'p1',
|
|
37
|
+
triggerEntityId: TRIGGER_ID,
|
|
38
|
+
eventType: Trace.OperationEnd.key,
|
|
39
|
+
eventOutcome: 'success',
|
|
40
|
+
timestamp: 3000,
|
|
41
|
+
});
|
|
42
|
+
const runs = groupIntoRuns([start, end], new Set([TRIGGER_ID]));
|
|
43
|
+
expect(runs).toHaveLength(1);
|
|
44
|
+
expect(runs[0].pid).toBe('p1');
|
|
45
|
+
expect(runs[0].status).toBe('success');
|
|
46
|
+
expect(runs[0].startedAt).toBe(1000);
|
|
47
|
+
expect(runs[0].duration).toBe(2000);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('marks run as failed when any OperationEnd is failure', ({ expect }) => {
|
|
51
|
+
const start = makeMessage({
|
|
52
|
+
pid: 'p1',
|
|
53
|
+
triggerEntityId: TRIGGER_ID,
|
|
54
|
+
eventType: Trace.OperationStart.key,
|
|
55
|
+
timestamp: 1000,
|
|
56
|
+
});
|
|
57
|
+
const end = makeMessage({
|
|
58
|
+
pid: 'p1',
|
|
59
|
+
triggerEntityId: TRIGGER_ID,
|
|
60
|
+
eventType: Trace.OperationEnd.key,
|
|
61
|
+
eventOutcome: 'failure',
|
|
62
|
+
timestamp: 2000,
|
|
63
|
+
});
|
|
64
|
+
const runs = groupIntoRuns([start, end], new Set([TRIGGER_ID]));
|
|
65
|
+
expect(runs[0].status).toBe('failure');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('marks run as pending when no OperationEnd event present', ({ expect }) => {
|
|
69
|
+
const start = makeMessage({ pid: 'p1', triggerEntityId: TRIGGER_ID, timestamp: 1000 });
|
|
70
|
+
const runs = groupIntoRuns([start], new Set([TRIGGER_ID]));
|
|
71
|
+
expect(runs[0].status).toBe('pending');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('sorts runs newest first', ({ expect }) => {
|
|
75
|
+
const older = makeMessage({ pid: 'p1', triggerEntityId: TRIGGER_ID, timestamp: 1000 });
|
|
76
|
+
const newer = makeMessage({ pid: 'p2', triggerEntityId: TRIGGER_ID, timestamp: 5000 });
|
|
77
|
+
const runs = groupIntoRuns([older, newer], new Set([TRIGGER_ID]));
|
|
78
|
+
expect(runs[0].pid).toBe('p2');
|
|
79
|
+
expect(runs[1].pid).toBe('p1');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('child process messages roll up to root run', ({ expect }) => {
|
|
83
|
+
const parent = makeMessage({ pid: 'p1', triggerEntityId: TRIGGER_ID, timestamp: 1000 });
|
|
84
|
+
const child = makeMessage({ pid: 'p2', parentPid: 'p1', triggerEntityId: TRIGGER_ID, timestamp: 2000 });
|
|
85
|
+
const runs = groupIntoRuns([parent, child], new Set([TRIGGER_ID]));
|
|
86
|
+
// Both messages belong to the same root run 'p1'.
|
|
87
|
+
expect(runs).toHaveLength(1);
|
|
88
|
+
expect(runs[0].pid).toBe('p1');
|
|
89
|
+
expect(runs[0].duration).toBe(1000);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('deep parent chain (>20 levels) resolves to root run', ({ expect }) => {
|
|
93
|
+
const depth = 25;
|
|
94
|
+
const messages: Trace.Message[] = [];
|
|
95
|
+
for (let i = 1; i <= depth; i++) {
|
|
96
|
+
messages.push(
|
|
97
|
+
makeMessage({
|
|
98
|
+
pid: `p${i}`,
|
|
99
|
+
parentPid: i > 1 ? `p${i - 1}` : undefined,
|
|
100
|
+
triggerEntityId: TRIGGER_ID,
|
|
101
|
+
timestamp: i * 1000,
|
|
102
|
+
}),
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
const runs = groupIntoRuns(messages, new Set([TRIGGER_ID]));
|
|
106
|
+
expect(runs).toHaveLength(1);
|
|
107
|
+
expect(runs[0].pid).toBe('p1');
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Minimal Ref whose `.uri` is a valid EID.
|
|
112
|
+
// EntityId is a branded string — the cast on the caller's side is intentional for test fixtures.
|
|
113
|
+
function makeRef(entityId: EntityId): Ref.Ref<never> {
|
|
114
|
+
return Ref.fromURI(EID.make({ entityId })) as Ref.Ref<never>;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Construct a bare-minimum Trace.Message for testing (no ECHO DB required).
|
|
118
|
+
function makeMessage(opts: {
|
|
119
|
+
pid: string;
|
|
120
|
+
parentPid?: string;
|
|
121
|
+
triggerEntityId?: EntityId;
|
|
122
|
+
eventType?: string;
|
|
123
|
+
eventOutcome?: string;
|
|
124
|
+
timestamp?: number;
|
|
125
|
+
}): Trace.Message {
|
|
126
|
+
const event = {
|
|
127
|
+
type: opts.eventType ?? Trace.OperationStart.key,
|
|
128
|
+
timestamp: opts.timestamp ?? Date.now(),
|
|
129
|
+
data: opts.eventOutcome ? { key: 'test', outcome: opts.eventOutcome } : { key: 'test' },
|
|
130
|
+
} as Trace.Event;
|
|
131
|
+
return Obj.make(Trace.Message, {
|
|
132
|
+
meta: {
|
|
133
|
+
pid: opts.pid,
|
|
134
|
+
parentPid: opts.parentPid,
|
|
135
|
+
trigger: opts.triggerEntityId ? makeRef(opts.triggerEntityId) : undefined,
|
|
136
|
+
},
|
|
137
|
+
isEphemeral: false,
|
|
138
|
+
events: [event],
|
|
139
|
+
});
|
|
140
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Trace } from '@dxos/compute';
|
|
6
|
+
import { type Obj, type Ref } from '@dxos/echo';
|
|
7
|
+
import { EID } from '@dxos/keys';
|
|
8
|
+
|
|
9
|
+
export type RunStatus = 'success' | 'failure' | 'pending';
|
|
10
|
+
|
|
11
|
+
export type RunEvent = {
|
|
12
|
+
type: string;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
data: unknown;
|
|
15
|
+
/** Process id that emitted this event; present when a run spawns child processes. */
|
|
16
|
+
pid?: string;
|
|
17
|
+
/** Human-readable process name, if provided by the runtime. */
|
|
18
|
+
processName?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type RoutineRun = {
|
|
22
|
+
/** Root process id. */
|
|
23
|
+
pid: string;
|
|
24
|
+
startedAt: number;
|
|
25
|
+
duration: number;
|
|
26
|
+
status: RunStatus;
|
|
27
|
+
/** All trace events for this run, sorted chronologically. */
|
|
28
|
+
events: RunEvent[];
|
|
29
|
+
/** Ref to the conversation (chat feed) created for this run, if any. */
|
|
30
|
+
conversation?: Ref.Ref<Obj.Unknown>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Groups trace messages into per-run summaries.
|
|
35
|
+
*
|
|
36
|
+
* Only root processes (those whose `meta.parentPid` is absent) are considered
|
|
37
|
+
* run entry points. Child processes contribute their events to the run duration
|
|
38
|
+
* and outcome but do not create separate run entries.
|
|
39
|
+
*
|
|
40
|
+
* The triggerIds set identifies which messages belong to this routine.
|
|
41
|
+
*/
|
|
42
|
+
export const groupIntoRuns = (
|
|
43
|
+
messages: readonly Trace.Message[],
|
|
44
|
+
triggerEntityIds: ReadonlySet<string>,
|
|
45
|
+
): RoutineRun[] => {
|
|
46
|
+
// Filter to messages whose trigger ref matches one of the routine's triggers.
|
|
47
|
+
const relevant = messages.filter((msg) => {
|
|
48
|
+
if (!msg.meta.trigger) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const eid = EID.getEntityId(EID.parse(msg.meta.trigger.uri));
|
|
52
|
+
return eid !== undefined && triggerEntityIds.has(eid);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (relevant.length === 0) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Collect all pids and their parent relationships.
|
|
60
|
+
const pidToParent = new Map<string, string>();
|
|
61
|
+
for (const msg of relevant) {
|
|
62
|
+
if (msg.meta.pid) {
|
|
63
|
+
if (msg.meta.parentPid) {
|
|
64
|
+
pidToParent.set(msg.meta.pid, msg.meta.parentPid);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Find the root pid for a given pid (walk up the parent chain).
|
|
70
|
+
const getRootPid = (pid: string): string => {
|
|
71
|
+
let current = pid;
|
|
72
|
+
const visited = new Set<string>();
|
|
73
|
+
while (!visited.has(current)) {
|
|
74
|
+
visited.add(current);
|
|
75
|
+
const parent = pidToParent.get(current);
|
|
76
|
+
if (!parent) {
|
|
77
|
+
return current;
|
|
78
|
+
}
|
|
79
|
+
current = parent;
|
|
80
|
+
}
|
|
81
|
+
// Cycle detected; return a stable fallback key.
|
|
82
|
+
return current;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Group messages by root pid.
|
|
86
|
+
const byRoot = new Map<string, Trace.Message[]>();
|
|
87
|
+
for (const msg of relevant) {
|
|
88
|
+
if (!msg.meta.pid) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const rootPid = getRootPid(msg.meta.pid);
|
|
92
|
+
const group = byRoot.get(rootPid) ?? [];
|
|
93
|
+
group.push(msg);
|
|
94
|
+
byRoot.set(rootPid, group);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const runs: RoutineRun[] = [];
|
|
98
|
+
for (const [pid, msgs] of byRoot) {
|
|
99
|
+
const allEvents = msgs.flatMap((msg) => msg.events.map((evt) => ({ ...evt, meta: msg.meta })));
|
|
100
|
+
allEvents.sort((left, right) => left.timestamp - right.timestamp);
|
|
101
|
+
|
|
102
|
+
const startedAt = allEvents[0]?.timestamp ?? 0;
|
|
103
|
+
const lastTimestamp = allEvents.at(-1)?.timestamp ?? startedAt;
|
|
104
|
+
const duration = lastTimestamp - startedAt;
|
|
105
|
+
|
|
106
|
+
// Determine status from OperationEnd events — failure beats success.
|
|
107
|
+
let status: RunStatus = 'pending';
|
|
108
|
+
for (const evt of allEvents) {
|
|
109
|
+
if (Trace.isOfType(Trace.OperationEnd, evt)) {
|
|
110
|
+
if (evt.data.outcome === 'failure') {
|
|
111
|
+
status = 'failure';
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
status = 'success';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Grab the conversation ref from any message in this run that has one.
|
|
119
|
+
const conversation = msgs.find((msg) => msg.meta.conversation)?.meta.conversation;
|
|
120
|
+
|
|
121
|
+
const events: RunEvent[] = allEvents.map((evt) => ({
|
|
122
|
+
type: evt.type,
|
|
123
|
+
timestamp: evt.timestamp,
|
|
124
|
+
data: evt.data,
|
|
125
|
+
...(evt.meta.pid && { pid: evt.meta.pid }),
|
|
126
|
+
...(evt.meta.processName && { processName: evt.meta.processName }),
|
|
127
|
+
}));
|
|
128
|
+
|
|
129
|
+
runs.push({ pid, startedAt, duration, status, events, conversation });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Newest first.
|
|
133
|
+
runs.sort((left, right) => right.startedAt - left.startedAt);
|
|
134
|
+
return runs;
|
|
135
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
|
|
7
|
+
import { Trace } from '@dxos/compute';
|
|
8
|
+
import { type Database, Filter, Query } from '@dxos/echo';
|
|
9
|
+
import { FeedTraceSink } from '@dxos/functions-runtime';
|
|
10
|
+
import { EID } from '@dxos/keys';
|
|
11
|
+
import { useQuery } from '@dxos/react-client/echo';
|
|
12
|
+
|
|
13
|
+
import { type Routine } from '#types';
|
|
14
|
+
|
|
15
|
+
import { type RoutineRun, groupIntoRuns } from './runs';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Returns the execution runs for a routine.
|
|
19
|
+
*
|
|
20
|
+
* Reads from the per-space trace feed and filters to messages whose
|
|
21
|
+
* `meta.trigger` ref matches one of the routine's triggers.
|
|
22
|
+
*/
|
|
23
|
+
export const useRoutineRuns = (db: Database.Database | undefined, routine: Routine.Routine): RoutineRun[] => {
|
|
24
|
+
const [traceFeed] = useQuery(db, FeedTraceSink.query);
|
|
25
|
+
|
|
26
|
+
const messages = useQuery(
|
|
27
|
+
db,
|
|
28
|
+
traceFeed ? Query.select(Filter.type(Trace.Message)).from(traceFeed) : Query.select(Filter.nothing()),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const triggerEntityIds = useMemo<ReadonlySet<string>>(() => {
|
|
32
|
+
const ids = new Set<string>();
|
|
33
|
+
for (const triggerRef of routine.triggers) {
|
|
34
|
+
if (!triggerRef) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const uri = triggerRef.uri;
|
|
38
|
+
if (!uri) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const eid = EID.getEntityId(EID.parse(uri));
|
|
42
|
+
if (eid) {
|
|
43
|
+
ids.add(eid);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return ids;
|
|
47
|
+
}, [routine.triggers.map((triggerRef) => triggerRef?.uri ?? '').join('|')]);
|
|
48
|
+
|
|
49
|
+
return useMemo(() => groupIntoRuns(messages, triggerEntityIds), [messages, triggerEntityIds]);
|
|
50
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { type AppSurface } from '@dxos/app-toolkit/ui';
|
|
8
|
+
import { type Skill } from '@dxos/compute';
|
|
9
|
+
import { Panel, Toolbar } from '@dxos/react-ui';
|
|
10
|
+
import { useAttention } from '@dxos/react-ui-attention';
|
|
11
|
+
|
|
12
|
+
import { TemplateEditor } from '#components';
|
|
13
|
+
|
|
14
|
+
export type SkillArticleProps = AppSurface.ObjectArticleProps<Skill.Skill>;
|
|
15
|
+
|
|
16
|
+
export const SkillArticle = ({ role, attendableId, subject }: SkillArticleProps) => {
|
|
17
|
+
const { hasAttention } = useAttention(attendableId);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Panel.Root role={role} classNames='dx-document'>
|
|
21
|
+
<Panel.Toolbar asChild>
|
|
22
|
+
<Toolbar.Root disabled={!hasAttention} />
|
|
23
|
+
</Panel.Toolbar>
|
|
24
|
+
<Panel.Content asChild>
|
|
25
|
+
<TemplateEditor id={subject.id} source={subject.instructions.source} />
|
|
26
|
+
</Panel.Content>
|
|
27
|
+
</Panel.Root>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentType, lazy } from 'react';
|
|
6
|
+
|
|
7
|
+
export const RoutineArticle: ComponentType<any> = lazy(() => import('./RoutineArticle'));
|
|
8
|
+
export const RoutineTraceCompanion: ComponentType<any> = lazy(() => import('./RoutineTraceCompanion'));
|
|
9
|
+
export const RoutineSettings: ComponentType<any> = lazy(() => import('./RoutineSettings'));
|
|
10
|
+
export const RoutineCompanion: ComponentType<any> = lazy(() => import('./RoutineCompanion'));
|
|
11
|
+
export const SkillArticle: ComponentType<any> = lazy(() => import('./SkillArticle'));
|