@open-mercato/core 0.7.1-develop.7193.1.910a5b0a1e → 0.7.1-develop.7195.1.b5efd1d51a
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/.turbo/turbo-build.log +2 -2
- package/AGENTS.md +4 -3
- package/agentic/standalone-guide.md +1 -1
- package/build.mjs +16 -0
- package/dist/bootstrap.js +7 -3
- package/dist/bootstrap.js.map +2 -2
- package/dist/generated/entities/action_log/index.js +2 -0
- package/dist/generated/entities/action_log/index.js.map +2 -2
- package/dist/generated/entities/user/index.js +2 -0
- package/dist/generated/entities/user/index.js.map +2 -2
- package/dist/generated/entities/user_task/index.js +14 -0
- package/dist/generated/entities/user_task/index.js.map +2 -2
- package/dist/generated/entities/workflow_definition/index.js +6 -0
- package/dist/generated/entities/workflow_definition/index.js.map +2 -2
- package/dist/generated/entities/workflow_definition_draft/index.js +25 -0
- package/dist/generated/entities/workflow_definition_draft/index.js.map +7 -0
- package/dist/generated/entities/workflow_definition_metric_rollup/index.js +23 -0
- package/dist/generated/entities/workflow_definition_metric_rollup/index.js.map +7 -0
- package/dist/generated/entities/workflow_instance/index.js +4 -0
- package/dist/generated/entities/workflow_instance/index.js.map +2 -2
- package/dist/generated/entities.ids.generated.js +4 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +39 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/workflowsFixtures.js +477 -2
- package/dist/helpers/integration/workflowsFixtures.js.map +2 -2
- package/dist/helpers/integration/workflowsUi.js +148 -0
- package/dist/helpers/integration/workflowsUi.js.map +7 -0
- package/dist/modules/attachments/lib/createFromBuffer.js +79 -0
- package/dist/modules/attachments/lib/createFromBuffer.js.map +7 -0
- package/dist/modules/audit_logs/data/entities.js +5 -0
- package/dist/modules/audit_logs/data/entities.js.map +2 -2
- package/dist/modules/audit_logs/data/validators.js +1 -0
- package/dist/modules/audit_logs/data/validators.js.map +2 -2
- package/dist/modules/audit_logs/lib/projections.js +2 -1
- package/dist/modules/audit_logs/lib/projections.js.map +2 -2
- package/dist/modules/audit_logs/migrations/Migration20260625120000.js +15 -0
- package/dist/modules/audit_logs/migrations/Migration20260625120000.js.map +7 -0
- package/dist/modules/audit_logs/services/actionLogService.js +3 -0
- package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
- package/dist/modules/auth/data/entities.js +6 -0
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/lib/executionPrincipal.js +140 -0
- package/dist/modules/auth/lib/executionPrincipal.js.map +7 -0
- package/dist/modules/auth/migrations/Migration20260625050000.js +13 -0
- package/dist/modules/auth/migrations/Migration20260625050000.js.map +7 -0
- package/dist/modules/business_rules/components/InlineRuleEditor.js +154 -0
- package/dist/modules/business_rules/components/InlineRuleEditor.js.map +7 -0
- package/dist/modules/business_rules/data/validators.js +6 -0
- package/dist/modules/business_rules/data/validators.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-engine.js +5 -3
- package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
- package/dist/modules/catalog/commands/products.js +5 -0
- package/dist/modules/catalog/commands/products.js.map +2 -2
- package/dist/modules/catalog/workflows.js +19 -0
- package/dist/modules/catalog/workflows.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +3 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/cli.js +80 -0
- package/dist/modules/customer_accounts/cli.js.map +7 -0
- package/dist/modules/customer_accounts/lib/customerRoleAclSync.js +59 -0
- package/dist/modules/customer_accounts/lib/customerRoleAclSync.js.map +7 -0
- package/dist/modules/customer_accounts/setup.js +4 -2
- package/dist/modules/customer_accounts/setup.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +4 -0
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/components/detail/ChangelogEntryRow.js +1 -1
- package/dist/modules/customers/components/detail/ChangelogEntryRow.js.map +2 -2
- package/dist/modules/customers/components/detail/utils.js +2 -0
- package/dist/modules/customers/components/detail/utils.js.map +2 -2
- package/dist/modules/customers/events.js +13 -2
- package/dist/modules/customers/events.js.map +2 -2
- package/dist/modules/customers/lib/link-workflow-task-handler.js +64 -0
- package/dist/modules/customers/lib/link-workflow-task-handler.js.map +7 -0
- package/dist/modules/customers/lib/todoCompatibility.js +1 -1
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/customers/lib/workflowTaskLink.js +9 -0
- package/dist/modules/customers/lib/workflowTaskLink.js.map +7 -0
- package/dist/modules/customers/subscribers/link-workflow-task.js +12 -0
- package/dist/modules/customers/subscribers/link-workflow-task.js.map +7 -0
- package/dist/modules/customers/workflows.js +29 -0
- package/dist/modules/customers/workflows.js.map +7 -0
- package/dist/modules/entities/api/records.js +13 -33
- package/dist/modules/entities/api/records.js.map +3 -3
- package/dist/modules/entities/lib/entityClassification.js +60 -0
- package/dist/modules/entities/lib/entityClassification.js.map +7 -0
- package/dist/modules/sales/commands/documents.js +31 -0
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/events.js +12 -1
- package/dist/modules/sales/events.js.map +2 -2
- package/dist/modules/sales/workflows.js +12 -1
- package/dist/modules/sales/workflows.js.map +2 -2
- package/dist/modules/seeds/cli.js +199 -0
- package/dist/modules/seeds/cli.js.map +7 -0
- package/dist/modules/seeds/examples/sample-seed.json +26 -0
- package/dist/modules/seeds/index.js +12 -0
- package/dist/modules/seeds/index.js.map +7 -0
- package/dist/modules/workflows/acl.js +96 -0
- package/dist/modules/workflows/acl.js.map +2 -2
- package/dist/modules/workflows/ai-agents.js +50 -0
- package/dist/modules/workflows/ai-agents.js.map +7 -0
- package/dist/modules/workflows/ai-tools/authoring-pack.js +582 -0
- package/dist/modules/workflows/ai-tools/authoring-pack.js.map +7 -0
- package/dist/modules/workflows/ai-tools/types.js +43 -0
- package/dist/modules/workflows/ai-tools/types.js.map +7 -0
- package/dist/modules/workflows/ai-tools.js +10 -0
- package/dist/modules/workflows/ai-tools.js.map +7 -0
- package/dist/modules/workflows/api/command-settings/route.js +137 -0
- package/dist/modules/workflows/api/command-settings/route.js.map +7 -0
- package/dist/modules/workflows/api/commands/route.js +72 -0
- package/dist/modules/workflows/api/commands/route.js.map +7 -0
- package/dist/modules/workflows/api/definitions/[id]/callers/route.js +76 -0
- package/dist/modules/workflows/api/definitions/[id]/callers/route.js.map +7 -0
- package/dist/modules/workflows/api/definitions/[id]/context-schema/route.js +134 -0
- package/dist/modules/workflows/api/definitions/[id]/context-schema/route.js.map +7 -0
- package/dist/modules/workflows/api/definitions/[id]/customize/route.js +5 -1
- package/dist/modules/workflows/api/definitions/[id]/customize/route.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/draft/route.js +286 -0
- package/dist/modules/workflows/api/definitions/[id]/draft/route.js.map +7 -0
- package/dist/modules/workflows/api/definitions/[id]/publish/route.js +207 -0
- package/dist/modules/workflows/api/definitions/[id]/publish/route.js.map +7 -0
- package/dist/modules/workflows/api/definitions/[id]/reset-to-code/route.js +5 -0
- package/dist/modules/workflows/api/definitions/[id]/reset-to-code/route.js.map +2 -2
- package/dist/modules/workflows/api/definitions/[id]/route.js +93 -9
- package/dist/modules/workflows/api/definitions/[id]/route.js.map +3 -3
- package/dist/modules/workflows/api/definitions/[id]/test-step/route.js +210 -0
- package/dist/modules/workflows/api/definitions/[id]/test-step/route.js.map +7 -0
- package/dist/modules/workflows/api/definitions/generate/route.js +233 -0
- package/dist/modules/workflows/api/definitions/generate/route.js.map +7 -0
- package/dist/modules/workflows/api/definitions/route.js +61 -113
- package/dist/modules/workflows/api/definitions/route.js.map +2 -2
- package/dist/modules/workflows/api/definitions/serialize.js +9 -0
- package/dist/modules/workflows/api/definitions/serialize.js.map +2 -2
- package/dist/modules/workflows/api/endpoints/route.js +69 -0
- package/dist/modules/workflows/api/endpoints/route.js.map +7 -0
- package/dist/modules/workflows/api/functions/route.js +73 -0
- package/dist/modules/workflows/api/functions/route.js.map +7 -0
- package/dist/modules/workflows/api/grantable-features/route.js +75 -0
- package/dist/modules/workflows/api/grantable-features/route.js.map +7 -0
- package/dist/modules/workflows/api/instances/[id]/context/route.js +180 -0
- package/dist/modules/workflows/api/instances/[id]/context/route.js.map +7 -0
- package/dist/modules/workflows/api/instances/[id]/rerun-step/route.js +184 -0
- package/dist/modules/workflows/api/instances/[id]/rerun-step/route.js.map +7 -0
- package/dist/modules/workflows/api/instances/[id]/retry/route.js +12 -2
- package/dist/modules/workflows/api/instances/[id]/retry/route.js.map +2 -2
- package/dist/modules/workflows/api/instances/[id]/step-through/route.js +148 -0
- package/dist/modules/workflows/api/instances/[id]/step-through/route.js.map +7 -0
- package/dist/modules/workflows/api/instances/[id]/steps/route.js +123 -0
- package/dist/modules/workflows/api/instances/[id]/steps/route.js.map +7 -0
- package/dist/modules/workflows/api/instances/[id]/would-do/route.js +172 -0
- package/dist/modules/workflows/api/instances/[id]/would-do/route.js.map +7 -0
- package/dist/modules/workflows/api/instances/bulk-replay/route.js +117 -0
- package/dist/modules/workflows/api/instances/bulk-replay/route.js.map +7 -0
- package/dist/modules/workflows/api/instances/failure-queue/route.js +165 -0
- package/dist/modules/workflows/api/instances/failure-queue/route.js.map +7 -0
- package/dist/modules/workflows/api/instances/route.js +94 -3
- package/dist/modules/workflows/api/instances/route.js.map +2 -2
- package/dist/modules/workflows/api/metrics/definitions/route.js +188 -0
- package/dist/modules/workflows/api/metrics/definitions/route.js.map +7 -0
- package/dist/modules/workflows/api/openapi.js +415 -4
- package/dist/modules/workflows/api/openapi.js.map +2 -2
- package/dist/modules/workflows/api/portal/tasks/[id]/complete/route.js +132 -0
- package/dist/modules/workflows/api/portal/tasks/[id]/complete/route.js.map +7 -0
- package/dist/modules/workflows/api/portal/tasks/[id]/route.js +97 -0
- package/dist/modules/workflows/api/portal/tasks/[id]/route.js.map +7 -0
- package/dist/modules/workflows/api/portal/tasks/route.js +126 -0
- package/dist/modules/workflows/api/portal/tasks/route.js.map +7 -0
- package/dist/modules/workflows/api/rule-usage/route.js +80 -0
- package/dist/modules/workflows/api/rule-usage/route.js.map +7 -0
- package/dist/modules/workflows/api/task-settings/route.js +107 -0
- package/dist/modules/workflows/api/task-settings/route.js.map +7 -0
- package/dist/modules/workflows/api/tasks/[id]/claim/route.js +27 -16
- package/dist/modules/workflows/api/tasks/[id]/claim/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/[id]/complete/route.js +40 -16
- package/dist/modules/workflows/api/tasks/[id]/complete/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/[id]/reassign/route.js +150 -0
- package/dist/modules/workflows/api/tasks/[id]/reassign/route.js.map +7 -0
- package/dist/modules/workflows/api/tasks/[id]/route.js +39 -6
- package/dist/modules/workflows/api/tasks/[id]/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/[id]/unclaim/route.js +100 -0
- package/dist/modules/workflows/api/tasks/[id]/unclaim/route.js.map +7 -0
- package/dist/modules/workflows/api/tasks/route.js +37 -6
- package/dist/modules/workflows/api/tasks/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/serialize.js +83 -0
- package/dist/modules/workflows/api/tasks/serialize.js.map +7 -0
- package/dist/modules/workflows/api/templates/route.js +69 -0
- package/dist/modules/workflows/api/templates/route.js.map +7 -0
- package/dist/modules/workflows/api/work-inbox/next/route.js +129 -0
- package/dist/modules/workflows/api/work-inbox/next/route.js.map +7 -0
- package/dist/modules/workflows/api/work-inbox/route.js +119 -0
- package/dist/modules/workflows/api/work-inbox/route.js.map +7 -0
- package/dist/modules/workflows/backend/config/workflows/page.js +10 -0
- package/dist/modules/workflows/backend/config/workflows/page.js.map +7 -0
- package/dist/modules/workflows/backend/config/workflows/page.meta.js +35 -0
- package/dist/modules/workflows/backend/config/workflows/page.meta.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/[id]/page.js +6 -271
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +3 -3
- package/dist/modules/workflows/backend/definitions/create/page.js +7 -56
- package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.meta.js +1 -1
- package/dist/modules/workflows/backend/definitions/create/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/page.js +131 -51
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +2606 -677
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +3 -3
- package/dist/modules/workflows/backend/instances/[id]/page.js +532 -421
- package/dist/modules/workflows/backend/instances/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.meta.js +1 -1
- package/dist/modules/workflows/backend/instances/[id]/page.meta.js.map +1 -1
- package/dist/modules/workflows/backend/instances/failure-queue/page.js +211 -0
- package/dist/modules/workflows/backend/instances/failure-queue/page.js.map +7 -0
- package/dist/modules/workflows/backend/instances/failure-queue/page.meta.js +20 -0
- package/dist/modules/workflows/backend/instances/failure-queue/page.meta.js.map +7 -0
- package/dist/modules/workflows/backend/instances/page.js +159 -22
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.meta.js +1 -1
- package/dist/modules/workflows/backend/instances/page.meta.js.map +1 -1
- package/dist/modules/workflows/backend/tasks/[id]/page.js +553 -392
- package/dist/modules/workflows/backend/tasks/[id]/page.js.map +3 -3
- package/dist/modules/workflows/backend/tasks/page.js +8 -250
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.meta.js +1 -0
- package/dist/modules/workflows/backend/tasks/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/work-inbox/page.js +399 -0
- package/dist/modules/workflows/backend/work-inbox/page.js.map +7 -0
- package/dist/modules/workflows/backend/work-inbox/page.meta.js +19 -0
- package/dist/modules/workflows/backend/work-inbox/page.meta.js.map +7 -0
- package/dist/modules/workflows/cli.js +1 -1
- package/dist/modules/workflows/cli.js.map +2 -2
- package/dist/modules/workflows/commands/tasks.js +81 -0
- package/dist/modules/workflows/commands/tasks.js.map +7 -0
- package/dist/modules/workflows/components/ActivitiesEditor.js +281 -287
- package/dist/modules/workflows/components/ActivitiesEditor.js.map +2 -2
- package/dist/modules/workflows/components/ActivityEditDialog.js +220 -0
- package/dist/modules/workflows/components/ActivityEditDialog.js.map +7 -0
- package/dist/modules/workflows/components/AgentSelector.js +115 -0
- package/dist/modules/workflows/components/AgentSelector.js.map +7 -0
- package/dist/modules/workflows/components/AnnotationEditDialog.js +110 -0
- package/dist/modules/workflows/components/AnnotationEditDialog.js.map +7 -0
- package/dist/modules/workflows/components/BusinessRuleUsagePanel.js +71 -0
- package/dist/modules/workflows/components/BusinessRuleUsagePanel.js.map +7 -0
- package/dist/modules/workflows/components/BusinessRulesSelector.js +151 -93
- package/dist/modules/workflows/components/BusinessRulesSelector.js.map +2 -2
- package/dist/modules/workflows/components/ConfigJsonTextarea.js +85 -0
- package/dist/modules/workflows/components/ConfigJsonTextarea.js.map +7 -0
- package/dist/modules/workflows/components/ContextSchemaEditor.js +150 -0
- package/dist/modules/workflows/components/ContextSchemaEditor.js.map +7 -0
- package/dist/modules/workflows/components/DefinitionErrorHandlerField.js +102 -0
- package/dist/modules/workflows/components/DefinitionErrorHandlerField.js.map +7 -0
- package/dist/modules/workflows/components/DefinitionMetadataDrawer.js +377 -0
- package/dist/modules/workflows/components/DefinitionMetadataDrawer.js.map +7 -0
- package/dist/modules/workflows/components/DefinitionMetricsCells.js +132 -0
- package/dist/modules/workflows/components/DefinitionMetricsCells.js.map +7 -0
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +307 -216
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
- package/dist/modules/workflows/components/EdgeEditDialog.js +11 -18
- package/dist/modules/workflows/components/EdgeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js +112 -72
- package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js.map +2 -2
- package/dist/modules/workflows/components/InputDataPanel.js +128 -0
- package/dist/modules/workflows/components/InputDataPanel.js.map +7 -0
- package/dist/modules/workflows/components/InspectorPanel.js +161 -0
- package/dist/modules/workflows/components/InspectorPanel.js.map +7 -0
- package/dist/modules/workflows/components/NodeEditDialog.js +363 -41
- package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js +714 -159
- package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +2 -2
- package/dist/modules/workflows/components/StepsEditor.js.map +2 -2
- package/dist/modules/workflows/components/TemplateGalleryDialog.js +148 -0
- package/dist/modules/workflows/components/TemplateGalleryDialog.js.map +7 -0
- package/dist/modules/workflows/components/TransitionsEditor.js +80 -74
- package/dist/modules/workflows/components/TransitionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/TriggersDialog.js +53 -0
- package/dist/modules/workflows/components/TriggersDialog.js.map +7 -0
- package/dist/modules/workflows/components/TriggersEditor.js +331 -0
- package/dist/modules/workflows/components/TriggersEditor.js.map +7 -0
- package/dist/modules/workflows/components/WorkflowAiDraftDialog.js +278 -0
- package/dist/modules/workflows/components/WorkflowAiDraftDialog.js.map +7 -0
- package/dist/modules/workflows/components/WorkflowCodeView.js +173 -0
- package/dist/modules/workflows/components/WorkflowCodeView.js.map +7 -0
- package/dist/modules/workflows/components/WorkflowCommandPalette.js +62 -0
- package/dist/modules/workflows/components/WorkflowCommandPalette.js.map +7 -0
- package/dist/modules/workflows/components/WorkflowCompensationGhostEdge.js +70 -0
- package/dist/modules/workflows/components/WorkflowCompensationGhostEdge.js.map +7 -0
- package/dist/modules/workflows/components/WorkflowDataMappingEdge.js +36 -0
- package/dist/modules/workflows/components/WorkflowDataMappingEdge.js.map +7 -0
- package/dist/modules/workflows/components/WorkflowGraph.js +4 -2
- package/dist/modules/workflows/components/WorkflowGraph.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowGraphImpl.js +324 -86
- package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +3 -3
- package/dist/modules/workflows/components/WorkflowIconPicker.js +109 -0
- package/dist/modules/workflows/components/WorkflowIconPicker.js.map +7 -0
- package/dist/modules/workflows/components/WorkflowLegend.js +45 -29
- package/dist/modules/workflows/components/WorkflowLegend.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowNodeCard.js +221 -22
- package/dist/modules/workflows/components/WorkflowNodeCard.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowRouteChips.js +111 -0
- package/dist/modules/workflows/components/WorkflowRouteChips.js.map +7 -0
- package/dist/modules/workflows/components/WorkflowSelector.js +108 -88
- package/dist/modules/workflows/components/WorkflowSelector.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowTransitionEdge.js +61 -11
- package/dist/modules/workflows/components/WorkflowTransitionEdge.js.map +2 -2
- package/dist/modules/workflows/components/WorkflowTransitionLabel.js +15 -5
- package/dist/modules/workflows/components/WorkflowTransitionLabel.js.map +2 -2
- package/dist/modules/workflows/components/fields/ActivityArrayEditor.js +88 -21
- package/dist/modules/workflows/components/fields/ActivityArrayEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/ActivityConfigFields.js +615 -0
- package/dist/modules/workflows/components/fields/ActivityConfigFields.js.map +7 -0
- package/dist/modules/workflows/components/fields/ActivityTestPanel.js +191 -0
- package/dist/modules/workflows/components/fields/ActivityTestPanel.js.map +7 -0
- package/dist/modules/workflows/components/fields/AgentInvokeConfigField.js +488 -0
- package/dist/modules/workflows/components/fields/AgentInvokeConfigField.js.map +7 -0
- package/dist/modules/workflows/components/fields/AgentReviewOnBreachField.js +61 -0
- package/dist/modules/workflows/components/fields/AgentReviewOnBreachField.js.map +7 -0
- package/dist/modules/workflows/components/fields/BranchingRoutesEditor.js +227 -0
- package/dist/modules/workflows/components/fields/BranchingRoutesEditor.js.map +7 -0
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +37 -4
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/CommandPicker.js +111 -0
- package/dist/modules/workflows/components/fields/CommandPicker.js.map +7 -0
- package/dist/modules/workflows/components/fields/EndpointPicker.js +235 -0
- package/dist/modules/workflows/components/fields/EndpointPicker.js.map +7 -0
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +2 -2
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/FunctionPicker.js +55 -0
- package/dist/modules/workflows/components/fields/FunctionPicker.js.map +7 -0
- package/dist/modules/workflows/components/fields/MappingArrayEditor.js +38 -15
- package/dist/modules/workflows/components/fields/MappingArrayEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/PortFieldArrayEditor.js +206 -0
- package/dist/modules/workflows/components/fields/PortFieldArrayEditor.js.map +7 -0
- package/dist/modules/workflows/components/fields/RolesMultiSelect.js +53 -0
- package/dist/modules/workflows/components/fields/RolesMultiSelect.js.map +7 -0
- package/dist/modules/workflows/components/fields/RouteOrderEditor.js +130 -0
- package/dist/modules/workflows/components/fields/RouteOrderEditor.js.map +7 -0
- package/dist/modules/workflows/components/fields/SchemaBuilderDialog.js +104 -0
- package/dist/modules/workflows/components/fields/SchemaBuilderDialog.js.map +7 -0
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +2 -2
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/TaskAssignmentField.js +210 -0
- package/dist/modules/workflows/components/fields/TaskAssignmentField.js.map +7 -0
- package/dist/modules/workflows/components/fields/TaskDeadlineFields.js +126 -0
- package/dist/modules/workflows/components/fields/TaskDeadlineFields.js.map +7 -0
- package/dist/modules/workflows/components/fields/TaskDecisionsField.js +218 -0
- package/dist/modules/workflows/components/fields/TaskDecisionsField.js.map +7 -0
- package/dist/modules/workflows/components/fields/TaskEntityBindingsField.js +114 -0
- package/dist/modules/workflows/components/fields/TaskEntityBindingsField.js.map +7 -0
- package/dist/modules/workflows/components/fields/TemplateTextControl.js +64 -0
- package/dist/modules/workflows/components/fields/TemplateTextControl.js.map +7 -0
- package/dist/modules/workflows/components/fields/VariablePickerButton.js +121 -0
- package/dist/modules/workflows/components/fields/VariablePickerButton.js.map +7 -0
- package/dist/modules/workflows/components/fields/ledgerDropTarget.js +35 -0
- package/dist/modules/workflows/components/fields/ledgerDropTarget.js.map +7 -0
- package/dist/modules/workflows/components/fields/useActivityTypeOptions.js +16 -0
- package/dist/modules/workflows/components/fields/useActivityTypeOptions.js.map +7 -0
- package/dist/modules/workflows/components/formConfig.js +39 -10
- package/dist/modules/workflows/components/formConfig.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileDefinitionDetail.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileMetadataSheet.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileTaskForm.js +29 -2
- package/dist/modules/workflows/components/mobile/MobileTaskForm.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileVisualEditor.js +64 -65
- package/dist/modules/workflows/components/mobile/MobileVisualEditor.js.map +2 -2
- package/dist/modules/workflows/components/nodes/AnnotationGroupNode.js +64 -0
- package/dist/modules/workflows/components/nodes/AnnotationGroupNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/AutomatedNode.js +24 -16
- package/dist/modules/workflows/components/nodes/AutomatedNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/EndNode.js +13 -12
- package/dist/modules/workflows/components/nodes/EndNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/ErrorOutputHandle.js +29 -0
- package/dist/modules/workflows/components/nodes/ErrorOutputHandle.js.map +7 -0
- package/dist/modules/workflows/components/nodes/IfElseNode.js +51 -0
- package/dist/modules/workflows/components/nodes/IfElseNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/InvokeAgentNode.js +122 -0
- package/dist/modules/workflows/components/nodes/InvokeAgentNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/NodeOutcomeRows.js +100 -0
- package/dist/modules/workflows/components/nodes/NodeOutcomeRows.js.map +7 -0
- package/dist/modules/workflows/components/nodes/ParallelForkNode.js +18 -14
- package/dist/modules/workflows/components/nodes/ParallelForkNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/ParallelJoinNode.js +18 -14
- package/dist/modules/workflows/components/nodes/ParallelJoinNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/StartNode.js +66 -15
- package/dist/modules/workflows/components/nodes/StartNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/StickyNoteNode.js +54 -0
- package/dist/modules/workflows/components/nodes/StickyNoteNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/SubWorkflowNode.js +107 -41
- package/dist/modules/workflows/components/nodes/SubWorkflowNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/SwitchNode.js +51 -0
- package/dist/modules/workflows/components/nodes/SwitchNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/TriggerCap.js +65 -0
- package/dist/modules/workflows/components/nodes/TriggerCap.js.map +7 -0
- package/dist/modules/workflows/components/nodes/TriggerNode.js +111 -0
- package/dist/modules/workflows/components/nodes/TriggerNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/UserTaskNode.js +43 -17
- package/dist/modules/workflows/components/nodes/UserTaskNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/WaitForConditionNode.js +53 -0
- package/dist/modules/workflows/components/nodes/WaitForConditionNode.js.map +7 -0
- package/dist/modules/workflows/components/nodes/WaitForSignalNode.js +21 -15
- package/dist/modules/workflows/components/nodes/WaitForSignalNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/WaitForTimerNode.js +21 -15
- package/dist/modules/workflows/components/nodes/WaitForTimerNode.js.map +2 -2
- package/dist/modules/workflows/components/nodes/index.js +14 -0
- package/dist/modules/workflows/components/nodes/index.js.map +2 -2
- package/dist/modules/workflows/components/portal/PortalTaskForm.js +196 -0
- package/dist/modules/workflows/components/portal/PortalTaskForm.js.map +7 -0
- package/dist/modules/workflows/components/run/AgentActivityPanel.js +22 -0
- package/dist/modules/workflows/components/run/AgentActivityPanel.js.map +7 -0
- package/dist/modules/workflows/components/run/RerunStepDialog.js +106 -0
- package/dist/modules/workflows/components/run/RerunStepDialog.js.map +7 -0
- package/dist/modules/workflows/components/run/RunEventBadge.js +30 -0
- package/dist/modules/workflows/components/run/RunEventBadge.js.map +7 -0
- package/dist/modules/workflows/components/run/RunGantt.js +130 -0
- package/dist/modules/workflows/components/run/RunGantt.js.map +7 -0
- package/dist/modules/workflows/components/run/RunStatusBadge.js +82 -0
- package/dist/modules/workflows/components/run/RunStatusBadge.js.map +7 -0
- package/dist/modules/workflows/components/run/RunStepInspector.js +116 -0
- package/dist/modules/workflows/components/run/RunStepInspector.js.map +7 -0
- package/dist/modules/workflows/components/run/WouldDoReport.js +52 -0
- package/dist/modules/workflows/components/run/WouldDoReport.js.map +7 -0
- package/dist/modules/workflows/components/run/useAgentLabels.js +28 -0
- package/dist/modules/workflows/components/run/useAgentLabels.js.map +7 -0
- package/dist/modules/workflows/components/run/useLastRunOverlay.js +89 -0
- package/dist/modules/workflows/components/run/useLastRunOverlay.js.map +7 -0
- package/dist/modules/workflows/components/run/useLiveAgentActions.js +41 -0
- package/dist/modules/workflows/components/run/useLiveAgentActions.js.map +7 -0
- package/dist/modules/workflows/components/run/useLiveRunUpdates.js +57 -0
- package/dist/modules/workflows/components/run/useLiveRunUpdates.js.map +7 -0
- package/dist/modules/workflows/components/settings/CommandSettingsPageClient.js +156 -0
- package/dist/modules/workflows/components/settings/CommandSettingsPageClient.js.map +7 -0
- package/dist/modules/workflows/components/work-inbox/EntityContextPanel.js +72 -0
- package/dist/modules/workflows/components/work-inbox/EntityContextPanel.js.map +7 -0
- package/dist/modules/workflows/components/work-inbox/ReassignTaskDialog.js +156 -0
- package/dist/modules/workflows/components/work-inbox/ReassignTaskDialog.js.map +7 -0
- package/dist/modules/workflows/components/work-inbox/StatusChip.js +46 -0
- package/dist/modules/workflows/components/work-inbox/StatusChip.js.map +7 -0
- package/dist/modules/workflows/components/work-inbox/TaskActionNotice.js +53 -0
- package/dist/modules/workflows/components/work-inbox/TaskActionNotice.js.map +7 -0
- package/dist/modules/workflows/components/work-inbox/TaskFormFields.js +261 -0
- package/dist/modules/workflows/components/work-inbox/TaskFormFields.js.map +7 -0
- package/dist/modules/workflows/components/work-inbox/WorkInboxEmptyState.js +27 -0
- package/dist/modules/workflows/components/work-inbox/WorkInboxEmptyState.js.map +7 -0
- package/dist/modules/workflows/data/activity-config-schemas.js +191 -0
- package/dist/modules/workflows/data/activity-config-schemas.js.map +7 -0
- package/dist/modules/workflows/data/activity-config-warnings.js +42 -0
- package/dist/modules/workflows/data/activity-config-warnings.js.map +7 -0
- package/dist/modules/workflows/data/branching-route-warnings.js +65 -0
- package/dist/modules/workflows/data/branching-route-warnings.js.map +7 -0
- package/dist/modules/workflows/data/entities.js +144 -4
- package/dist/modules/workflows/data/entities.js.map +2 -2
- package/dist/modules/workflows/data/metrics-validators.js +35 -0
- package/dist/modules/workflows/data/metrics-validators.js.map +7 -0
- package/dist/modules/workflows/data/task-primitives.js +14 -0
- package/dist/modules/workflows/data/task-primitives.js.map +7 -0
- package/dist/modules/workflows/data/validators.js +504 -61
- package/dist/modules/workflows/data/validators.js.map +3 -3
- package/dist/modules/workflows/di.js +16 -1
- package/dist/modules/workflows/di.js.map +2 -2
- package/dist/modules/workflows/events.js +66 -8
- package/dist/modules/workflows/events.js.map +2 -2
- package/dist/modules/workflows/examples/oze-residential-install-60-nodes.json +1545 -0
- package/dist/modules/workflows/examples/sales-pipeline-definition.json +35 -35
- package/dist/modules/workflows/examples/templates/lead-to-install.json +160 -0
- package/dist/modules/workflows/examples/templates/order-approval.json +230 -0
- package/dist/modules/workflows/examples/templates/task-escalation.json +110 -0
- package/dist/modules/workflows/examples/templates/webhook-integration.json +113 -0
- package/dist/modules/workflows/extension-points.js +1 -1
- package/dist/modules/workflows/extension-points.js.map +2 -2
- package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.js +144 -0
- package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.js.map +7 -0
- package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.meta.js +12 -0
- package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.meta.js.map +7 -0
- package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/page.js +114 -0
- package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/page.js.map +7 -0
- package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/page.meta.js +18 -0
- package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/page.meta.js.map +7 -0
- package/dist/modules/workflows/lib/activity-executor.js +505 -137
- package/dist/modules/workflows/lib/activity-executor.js.map +3 -3
- package/dist/modules/workflows/lib/activity-queue-types.js +3 -1
- package/dist/modules/workflows/lib/activity-queue-types.js.map +2 -2
- package/dist/modules/workflows/lib/activity-registry-bootstrap.js +2 -0
- package/dist/modules/workflows/lib/activity-registry-bootstrap.js.map +7 -0
- package/dist/modules/workflows/lib/activity-registry.js +27 -0
- package/dist/modules/workflows/lib/activity-registry.js.map +7 -0
- package/dist/modules/workflows/lib/activity-types.js +291 -0
- package/dist/modules/workflows/lib/activity-types.js.map +7 -0
- package/dist/modules/workflows/lib/activity-worker-handler.js +456 -32
- package/dist/modules/workflows/lib/activity-worker-handler.js.map +3 -3
- package/dist/modules/workflows/lib/advanced-config.js +31 -0
- package/dist/modules/workflows/lib/advanced-config.js.map +7 -0
- package/dist/modules/workflows/lib/agent-disposition-task.js +198 -0
- package/dist/modules/workflows/lib/agent-disposition-task.js.map +7 -0
- package/dist/modules/workflows/lib/agent-outcome-paths.js +82 -0
- package/dist/modules/workflows/lib/agent-outcome-paths.js.map +7 -0
- package/dist/modules/workflows/lib/agent-result-mapping.js +54 -0
- package/dist/modules/workflows/lib/agent-result-mapping.js.map +7 -0
- package/dist/modules/workflows/lib/agent-review-inspector.js +61 -0
- package/dist/modules/workflows/lib/agent-review-inspector.js.map +7 -0
- package/dist/modules/workflows/lib/agent-review.js +66 -0
- package/dist/modules/workflows/lib/agent-review.js.map +7 -0
- package/dist/modules/workflows/lib/ai-authoring.js +155 -0
- package/dist/modules/workflows/lib/ai-authoring.js.map +7 -0
- package/dist/modules/workflows/lib/ai-draft-runner.js +43 -0
- package/dist/modules/workflows/lib/ai-draft-runner.js.map +7 -0
- package/dist/modules/workflows/lib/annotation-events.js +10 -0
- package/dist/modules/workflows/lib/annotation-events.js.map +7 -0
- package/dist/modules/workflows/lib/branching-routes.js +182 -0
- package/dist/modules/workflows/lib/branching-routes.js.map +7 -0
- package/dist/modules/workflows/lib/breach-routing.js +50 -0
- package/dist/modules/workflows/lib/breach-routing.js.map +7 -0
- package/dist/modules/workflows/lib/bulk-replay.js +101 -0
- package/dist/modules/workflows/lib/bulk-replay.js.map +7 -0
- package/dist/modules/workflows/lib/business-rule-usage.js +91 -0
- package/dist/modules/workflows/lib/business-rule-usage.js.map +7 -0
- package/dist/modules/workflows/lib/caller-graph.js +53 -0
- package/dist/modules/workflows/lib/caller-graph.js.map +7 -0
- package/dist/modules/workflows/lib/code-view-apply.js +86 -0
- package/dist/modules/workflows/lib/code-view-apply.js.map +7 -0
- package/dist/modules/workflows/lib/collect-validation-issues.js +164 -0
- package/dist/modules/workflows/lib/collect-validation-issues.js.map +7 -0
- package/dist/modules/workflows/lib/compensation-ghosts.js +72 -0
- package/dist/modules/workflows/lib/compensation-ghosts.js.map +7 -0
- package/dist/modules/workflows/lib/component-guard.js +7 -0
- package/dist/modules/workflows/lib/component-guard.js.map +7 -0
- package/dist/modules/workflows/lib/condition-handler.js +443 -0
- package/dist/modules/workflows/lib/condition-handler.js.map +7 -0
- package/dist/modules/workflows/lib/context-ledger.js +448 -0
- package/dist/modules/workflows/lib/context-ledger.js.map +7 -0
- package/dist/modules/workflows/lib/crud-form-dialogs-flag.js +8 -0
- package/dist/modules/workflows/lib/crud-form-dialogs-flag.js.map +7 -0
- package/dist/modules/workflows/lib/data-edge-mapping.js +63 -0
- package/dist/modules/workflows/lib/data-edge-mapping.js.map +7 -0
- package/dist/modules/workflows/lib/definition-context-schema.js +56 -0
- package/dist/modules/workflows/lib/definition-context-schema.js.map +7 -0
- package/dist/modules/workflows/lib/definition-edit-safety.js +123 -0
- package/dist/modules/workflows/lib/definition-edit-safety.js.map +7 -0
- package/dist/modules/workflows/lib/definition-error-body.js +33 -0
- package/dist/modules/workflows/lib/definition-error-body.js.map +7 -0
- package/dist/modules/workflows/lib/definition-evaluation.js +79 -0
- package/dist/modules/workflows/lib/definition-evaluation.js.map +7 -0
- package/dist/modules/workflows/lib/definition-grant.js +90 -0
- package/dist/modules/workflows/lib/definition-grant.js.map +7 -0
- package/dist/modules/workflows/lib/definition-json-locations.js +139 -0
- package/dist/modules/workflows/lib/definition-json-locations.js.map +7 -0
- package/dist/modules/workflows/lib/definition-payload.js +31 -0
- package/dist/modules/workflows/lib/definition-payload.js.map +7 -0
- package/dist/modules/workflows/lib/draft-restore.js +49 -0
- package/dist/modules/workflows/lib/draft-restore.js.map +7 -0
- package/dist/modules/workflows/lib/dry-run.js +106 -0
- package/dist/modules/workflows/lib/dry-run.js.map +7 -0
- package/dist/modules/workflows/lib/duration.js +66 -17
- package/dist/modules/workflows/lib/duration.js.map +2 -2
- package/dist/modules/workflows/lib/edge-reattachment.js +79 -0
- package/dist/modules/workflows/lib/edge-reattachment.js.map +7 -0
- package/dist/modules/workflows/lib/edgeFormTransforms.js +7 -11
- package/dist/modules/workflows/lib/edgeFormTransforms.js.map +2 -2
- package/dist/modules/workflows/lib/editor-annotations.js +195 -0
- package/dist/modules/workflows/lib/editor-annotations.js.map +7 -0
- package/dist/modules/workflows/lib/editor-commands.js +103 -0
- package/dist/modules/workflows/lib/editor-commands.js.map +7 -0
- package/dist/modules/workflows/lib/editor-history.js +51 -0
- package/dist/modules/workflows/lib/editor-history.js.map +7 -0
- package/dist/modules/workflows/lib/endpoint-catalog.js +181 -0
- package/dist/modules/workflows/lib/endpoint-catalog.js.map +7 -0
- package/dist/modules/workflows/lib/endpoint-path.js +90 -0
- package/dist/modules/workflows/lib/endpoint-path.js.map +7 -0
- package/dist/modules/workflows/lib/engine-version.js +42 -0
- package/dist/modules/workflows/lib/engine-version.js.map +7 -0
- package/dist/modules/workflows/lib/error-handler.js +132 -0
- package/dist/modules/workflows/lib/error-handler.js.map +7 -0
- package/dist/modules/workflows/lib/error-routing.js +104 -0
- package/dist/modules/workflows/lib/error-routing.js.map +7 -0
- package/dist/modules/workflows/lib/event-logger.js +23 -0
- package/dist/modules/workflows/lib/event-logger.js.map +2 -2
- package/dist/modules/workflows/lib/expression-refs.js +168 -0
- package/dist/modules/workflows/lib/expression-refs.js.map +7 -0
- package/dist/modules/workflows/lib/failure-grouping.js +62 -0
- package/dist/modules/workflows/lib/failure-grouping.js.map +7 -0
- package/dist/modules/workflows/lib/find-definition.js +1 -0
- package/dist/modules/workflows/lib/find-definition.js.map +2 -2
- package/dist/modules/workflows/lib/flow-logic-warnings.js +338 -0
- package/dist/modules/workflows/lib/flow-logic-warnings.js.map +7 -0
- package/dist/modules/workflows/lib/graph-utils.js +328 -77
- package/dist/modules/workflows/lib/graph-utils.js.map +2 -2
- package/dist/modules/workflows/lib/icon-search.js +32 -0
- package/dist/modules/workflows/lib/icon-search.js.map +7 -0
- package/dist/modules/workflows/lib/insert-at-cursor.js +26 -0
- package/dist/modules/workflows/lib/insert-at-cursor.js.map +7 -0
- package/dist/modules/workflows/lib/instance-date-filter.js +28 -0
- package/dist/modules/workflows/lib/instance-date-filter.js.map +7 -0
- package/dist/modules/workflows/lib/interpolation-pipeline.js +271 -0
- package/dist/modules/workflows/lib/interpolation-pipeline.js.map +7 -0
- package/dist/modules/workflows/lib/ledger-drag.js +28 -0
- package/dist/modules/workflows/lib/ledger-drag.js.map +7 -0
- package/dist/modules/workflows/lib/ledger-entry-display.js +66 -0
- package/dist/modules/workflows/lib/ledger-entry-display.js.map +7 -0
- package/dist/modules/workflows/lib/ledger-schema-flatten.js +82 -0
- package/dist/modules/workflows/lib/ledger-schema-flatten.js.map +7 -0
- package/dist/modules/workflows/lib/metrics/definition-metrics.js +110 -0
- package/dist/modules/workflows/lib/metrics/definition-metrics.js.map +7 -0
- package/dist/modules/workflows/lib/metrics/metrics-display.js +26 -0
- package/dist/modules/workflows/lib/metrics/metrics-display.js.map +7 -0
- package/dist/modules/workflows/lib/metrics/rollup-schedule.js +7 -0
- package/dist/modules/workflows/lib/metrics/rollup-schedule.js.map +7 -0
- package/dist/modules/workflows/lib/metrics/rollup-service.js +160 -0
- package/dist/modules/workflows/lib/metrics/rollup-service.js.map +7 -0
- package/dist/modules/workflows/lib/node-config-summary.js +128 -0
- package/dist/modules/workflows/lib/node-config-summary.js.map +7 -0
- package/dist/modules/workflows/lib/node-geometry.js +53 -0
- package/dist/modules/workflows/lib/node-geometry.js.map +7 -0
- package/dist/modules/workflows/lib/node-nudge.js +44 -0
- package/dist/modules/workflows/lib/node-nudge.js.map +7 -0
- package/dist/modules/workflows/lib/node-outcome-rows.js +88 -0
- package/dist/modules/workflows/lib/node-outcome-rows.js.map +7 -0
- package/dist/modules/workflows/lib/node-placement.js +55 -0
- package/dist/modules/workflows/lib/node-placement.js.map +7 -0
- package/dist/modules/workflows/lib/node-type-icons.js +54 -13
- package/dist/modules/workflows/lib/node-type-icons.js.map +2 -2
- package/dist/modules/workflows/lib/nodeFormTransforms.js +329 -19
- package/dist/modules/workflows/lib/nodeFormTransforms.js.map +2 -2
- package/dist/modules/workflows/lib/outcome-routing.js +158 -0
- package/dist/modules/workflows/lib/outcome-routing.js.map +7 -0
- package/dist/modules/workflows/lib/owned-definition.js +107 -0
- package/dist/modules/workflows/lib/owned-definition.js.map +7 -0
- package/dist/modules/workflows/lib/owned-node-changes.js +10 -0
- package/dist/modules/workflows/lib/owned-node-changes.js.map +7 -0
- package/dist/modules/workflows/lib/palette-drag.js +36 -0
- package/dist/modules/workflows/lib/palette-drag.js.map +7 -0
- package/dist/modules/workflows/lib/palette-drop.js +45 -0
- package/dist/modules/workflows/lib/palette-drop.js.map +7 -0
- package/dist/modules/workflows/lib/parallel-handler.js +57 -2
- package/dist/modules/workflows/lib/parallel-handler.js.map +2 -2
- package/dist/modules/workflows/lib/port-contract.js +54 -0
- package/dist/modules/workflows/lib/port-contract.js.map +7 -0
- package/dist/modules/workflows/lib/portal-task-access.js +89 -0
- package/dist/modules/workflows/lib/portal-task-access.js.map +7 -0
- package/dist/modules/workflows/lib/rerun-from-step.js +65 -0
- package/dist/modules/workflows/lib/rerun-from-step.js.map +7 -0
- package/dist/modules/workflows/lib/route-chip-events.js +23 -0
- package/dist/modules/workflows/lib/route-chip-events.js.map +7 -0
- package/dist/modules/workflows/lib/route-chips.js +91 -0
- package/dist/modules/workflows/lib/route-chips.js.map +7 -0
- package/dist/modules/workflows/lib/route-edge.js +17 -0
- package/dist/modules/workflows/lib/route-edge.js.map +7 -0
- package/dist/modules/workflows/lib/route-kinds.js +67 -0
- package/dist/modules/workflows/lib/route-kinds.js.map +7 -0
- package/dist/modules/workflows/lib/route-priority.js +104 -0
- package/dist/modules/workflows/lib/route-priority.js.map +7 -0
- package/dist/modules/workflows/lib/run-duration.js +44 -0
- package/dist/modules/workflows/lib/run-duration.js.map +7 -0
- package/dist/modules/workflows/lib/run-event-tone.js +25 -0
- package/dist/modules/workflows/lib/run-event-tone.js.map +7 -0
- package/dist/modules/workflows/lib/run-execution.js +305 -0
- package/dist/modules/workflows/lib/run-execution.js.map +7 -0
- package/dist/modules/workflows/lib/run-gantt.js +180 -0
- package/dist/modules/workflows/lib/run-gantt.js.map +7 -0
- package/dist/modules/workflows/lib/run-outcome-evidence.js +33 -0
- package/dist/modules/workflows/lib/run-outcome-evidence.js.map +7 -0
- package/dist/modules/workflows/lib/run-outcome.js +48 -0
- package/dist/modules/workflows/lib/run-outcome.js.map +7 -0
- package/dist/modules/workflows/lib/sample-resolver.js +71 -0
- package/dist/modules/workflows/lib/sample-resolver.js.map +7 -0
- package/dist/modules/workflows/lib/seeds.js +1 -1
- package/dist/modules/workflows/lib/seeds.js.map +2 -2
- package/dist/modules/workflows/lib/server-output-contract.js +65 -0
- package/dist/modules/workflows/lib/server-output-contract.js.map +7 -0
- package/dist/modules/workflows/lib/set-variable.js +47 -0
- package/dist/modules/workflows/lib/set-variable.js.map +7 -0
- package/dist/modules/workflows/lib/signal-handler.js +63 -4
- package/dist/modules/workflows/lib/signal-handler.js.map +2 -2
- package/dist/modules/workflows/lib/start-fixtures.js +42 -0
- package/dist/modules/workflows/lib/start-fixtures.js.map +7 -0
- package/dist/modules/workflows/lib/status-colors.js +153 -22
- package/dist/modules/workflows/lib/status-colors.js.map +2 -2
- package/dist/modules/workflows/lib/step-handler.js +529 -53
- package/dist/modules/workflows/lib/step-handler.js.map +3 -3
- package/dist/modules/workflows/lib/step-presentation.js +147 -0
- package/dist/modules/workflows/lib/step-presentation.js.map +7 -0
- package/dist/modules/workflows/lib/step-through.js +26 -0
- package/dist/modules/workflows/lib/step-through.js.map +7 -0
- package/dist/modules/workflows/lib/step-type-conversion.js +167 -0
- package/dist/modules/workflows/lib/step-type-conversion.js.map +7 -0
- package/dist/modules/workflows/lib/subgraph-clipboard.js +114 -0
- package/dist/modules/workflows/lib/subgraph-clipboard.js.map +7 -0
- package/dist/modules/workflows/lib/task-decision-context.js +38 -0
- package/dist/modules/workflows/lib/task-decision-context.js.map +7 -0
- package/dist/modules/workflows/lib/task-decisions.js +49 -0
- package/dist/modules/workflows/lib/task-decisions.js.map +7 -0
- package/dist/modules/workflows/lib/task-entity-access.js +62 -0
- package/dist/modules/workflows/lib/task-entity-access.js.map +7 -0
- package/dist/modules/workflows/lib/task-entity-aliases.js +39 -0
- package/dist/modules/workflows/lib/task-entity-aliases.js.map +7 -0
- package/dist/modules/workflows/lib/task-entity-types.js +36 -0
- package/dist/modules/workflows/lib/task-entity-types.js.map +7 -0
- package/dist/modules/workflows/lib/task-form-registry.js +33 -0
- package/dist/modules/workflows/lib/task-form-registry.js.map +7 -0
- package/dist/modules/workflows/lib/task-form-schema.js +75 -0
- package/dist/modules/workflows/lib/task-form-schema.js.map +7 -0
- package/dist/modules/workflows/lib/task-handler.js +251 -32
- package/dist/modules/workflows/lib/task-handler.js.map +2 -2
- package/dist/modules/workflows/lib/task-inspector-config.js +182 -0
- package/dist/modules/workflows/lib/task-inspector-config.js.map +7 -0
- package/dist/modules/workflows/lib/task-list-query.js +19 -0
- package/dist/modules/workflows/lib/task-list-query.js.map +7 -0
- package/dist/modules/workflows/lib/task-notifications.js +119 -0
- package/dist/modules/workflows/lib/task-notifications.js.map +7 -0
- package/dist/modules/workflows/lib/task-permission-settings.js +43 -0
- package/dist/modules/workflows/lib/task-permission-settings.js.map +7 -0
- package/dist/modules/workflows/lib/task-presets.js +35 -0
- package/dist/modules/workflows/lib/task-presets.js.map +7 -0
- package/dist/modules/workflows/lib/task-quick-action.js +45 -0
- package/dist/modules/workflows/lib/task-quick-action.js.map +7 -0
- package/dist/modules/workflows/lib/task-resolution.js +120 -0
- package/dist/modules/workflows/lib/task-resolution.js.map +7 -0
- package/dist/modules/workflows/lib/task-sla.js +357 -0
- package/dist/modules/workflows/lib/task-sla.js.map +7 -0
- package/dist/modules/workflows/lib/task-visibility-request.js +266 -0
- package/dist/modules/workflows/lib/task-visibility-request.js.map +7 -0
- package/dist/modules/workflows/lib/task-visibility.js +194 -0
- package/dist/modules/workflows/lib/task-visibility.js.map +7 -0
- package/dist/modules/workflows/lib/timer-handler.js +3 -1
- package/dist/modules/workflows/lib/timer-handler.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +148 -20
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- package/dist/modules/workflows/lib/trigger-node.js +121 -0
- package/dist/modules/workflows/lib/trigger-node.js.map +7 -0
- package/dist/modules/workflows/lib/visual-editor-navigation.js +14 -0
- package/dist/modules/workflows/lib/visual-editor-navigation.js.map +7 -0
- package/dist/modules/workflows/lib/work-inbox/empty-state.js +52 -0
- package/dist/modules/workflows/lib/work-inbox/empty-state.js.map +7 -0
- package/dist/modules/workflows/lib/work-inbox/entity-links.js +63 -0
- package/dist/modules/workflows/lib/work-inbox/entity-links.js.map +7 -0
- package/dist/modules/workflows/lib/work-inbox/navigation.js +11 -0
- package/dist/modules/workflows/lib/work-inbox/navigation.js.map +7 -0
- package/dist/modules/workflows/lib/work-inbox/presentation.js +90 -0
- package/dist/modules/workflows/lib/work-inbox/presentation.js.map +7 -0
- package/dist/modules/workflows/lib/work-inbox/provider.js +118 -0
- package/dist/modules/workflows/lib/work-inbox/provider.js.map +7 -0
- package/dist/modules/workflows/lib/work-inbox/query.js +70 -0
- package/dist/modules/workflows/lib/work-inbox/query.js.map +7 -0
- package/dist/modules/workflows/lib/work-inbox/service.js +56 -0
- package/dist/modules/workflows/lib/work-inbox/service.js.map +7 -0
- package/dist/modules/workflows/lib/work-inbox/user-task-source.js +149 -0
- package/dist/modules/workflows/lib/work-inbox/user-task-source.js.map +7 -0
- package/dist/modules/workflows/lib/workflow-command-enablement.js +57 -0
- package/dist/modules/workflows/lib/workflow-command-enablement.js.map +7 -0
- package/dist/modules/workflows/lib/workflow-command-settings.js +54 -0
- package/dist/modules/workflows/lib/workflow-command-settings.js.map +7 -0
- package/dist/modules/workflows/lib/workflow-executor.js +658 -6
- package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
- package/dist/modules/workflows/lib/workflow-function-registry.js +40 -0
- package/dist/modules/workflows/lib/workflow-function-registry.js.map +7 -0
- package/dist/modules/workflows/lib/workflow-safe-commands.js +11 -1
- package/dist/modules/workflows/lib/workflow-safe-commands.js.map +2 -2
- package/dist/modules/workflows/lib/workflow-templates.js +69 -0
- package/dist/modules/workflows/lib/workflow-templates.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260626214855_workflows.js +15 -0
- package/dist/modules/workflows/migrations/Migration20260626214855_workflows.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260626222424_workflows.js +17 -0
- package/dist/modules/workflows/migrations/Migration20260626222424_workflows.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260727074335_workflows.js +15 -0
- package/dist/modules/workflows/migrations/Migration20260727074335_workflows.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260728104038_workflows.js +13 -0
- package/dist/modules/workflows/migrations/Migration20260728104038_workflows.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260728163001_workflows.js +15 -0
- package/dist/modules/workflows/migrations/Migration20260728163001_workflows.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260729061736_workflows.js +13 -0
- package/dist/modules/workflows/migrations/Migration20260729061736_workflows.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260729192652_workflows.js +12 -0
- package/dist/modules/workflows/migrations/Migration20260729192652_workflows.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260730085000_workflows.js +13 -0
- package/dist/modules/workflows/migrations/Migration20260730085000_workflows.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260730092706_workflows.js +13 -0
- package/dist/modules/workflows/migrations/Migration20260730092706_workflows.js.map +7 -0
- package/dist/modules/workflows/notifications.js +38 -10
- package/dist/modules/workflows/notifications.js.map +2 -2
- package/dist/modules/workflows/setup.js +81 -1
- package/dist/modules/workflows/setup.js.map +2 -2
- package/dist/modules/workflows/subscribers/task-assigned-notification.js +19 -27
- package/dist/modules/workflows/subscribers/task-assigned-notification.js.map +2 -2
- package/dist/modules/workflows/subscribers/task-deadline-breached-notification.js +24 -0
- package/dist/modules/workflows/subscribers/task-deadline-breached-notification.js.map +7 -0
- package/dist/modules/workflows/subscribers/task-reminder-notification.js +24 -0
- package/dist/modules/workflows/subscribers/task-reminder-notification.js.map +7 -0
- package/dist/modules/workflows/widgets/injection/pending-work/widget.client.js +73 -0
- package/dist/modules/workflows/widgets/injection/pending-work/widget.client.js.map +7 -0
- package/dist/modules/workflows/widgets/injection/pending-work/widget.js +17 -0
- package/dist/modules/workflows/widgets/injection/pending-work/widget.js.map +7 -0
- package/dist/modules/workflows/widgets/injection-table.js +26 -0
- package/dist/modules/workflows/widgets/injection-table.js.map +2 -2
- package/dist/modules/workflows/workers/workflow-activities.worker.js +61 -39
- package/dist/modules/workflows/workers/workflow-activities.worker.js.map +2 -2
- package/dist/modules/workflows/workers/workflow-definition-metric-rollup.worker.js +40 -0
- package/dist/modules/workflows/workers/workflow-definition-metric-rollup.worker.js.map +7 -0
- package/dist/modules/workflows/workers/workflow-instance-bulk-replay.js +43 -0
- package/dist/modules/workflows/workers/workflow-instance-bulk-replay.js.map +7 -0
- package/dist/modules/workflows/workers/workflow-invoke-agent.worker.js +30 -0
- package/dist/modules/workflows/workers/workflow-invoke-agent.worker.js.map +7 -0
- package/generated/entities/action_log/index.ts +1 -0
- package/generated/entities/user/index.ts +1 -0
- package/generated/entities/user_task/index.ts +7 -0
- package/generated/entities/workflow_definition/index.ts +3 -0
- package/generated/entities/workflow_definition_draft/index.ts +11 -0
- package/generated/entities/workflow_definition_metric_rollup/index.ts +10 -0
- package/generated/entities/workflow_instance/index.ts +2 -0
- package/generated/entities.ids.generated.ts +4 -1
- package/generated/entity-fields-registry.ts +39 -0
- package/jest.setup.ts +13 -0
- package/package.json +8 -7
- package/src/bootstrap.ts +13 -3
- package/src/helpers/integration/workflowsFixtures.ts +765 -5
- package/src/helpers/integration/workflowsUi.ts +318 -0
- package/src/modules/attachments/lib/createFromBuffer.ts +120 -0
- package/src/modules/audit_logs/data/entities.ts +12 -0
- package/src/modules/audit_logs/data/validators.ts +1 -0
- package/src/modules/audit_logs/lib/projections.ts +5 -1
- package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +26 -0
- package/src/modules/audit_logs/migrations/Migration20260625120000.ts +15 -0
- package/src/modules/audit_logs/services/actionLogService.ts +3 -0
- package/src/modules/auth/data/entities.ts +21 -0
- package/src/modules/auth/i18n/de.json +31 -0
- package/src/modules/auth/i18n/en.json +31 -0
- package/src/modules/auth/i18n/es.json +31 -0
- package/src/modules/auth/i18n/ko.json +31 -0
- package/src/modules/auth/i18n/pl.json +31 -0
- package/src/modules/auth/lib/executionPrincipal.ts +235 -0
- package/src/modules/auth/migrations/.snapshot-open-mercato.json +16 -0
- package/src/modules/auth/migrations/Migration20260625050000.ts +21 -0
- package/src/modules/business_rules/components/InlineRuleEditor.tsx +231 -0
- package/src/modules/business_rules/data/validators.ts +6 -0
- package/src/modules/business_rules/i18n/de.json +4 -0
- package/src/modules/business_rules/i18n/en.json +4 -0
- package/src/modules/business_rules/i18n/es.json +4 -0
- package/src/modules/business_rules/i18n/ko.json +4 -0
- package/src/modules/business_rules/i18n/pl.json +4 -0
- package/src/modules/business_rules/lib/rule-engine.ts +15 -1
- package/src/modules/catalog/commands/products.ts +12 -0
- package/src/modules/catalog/i18n/de.json +1 -0
- package/src/modules/catalog/i18n/en.json +1 -0
- package/src/modules/catalog/i18n/es.json +1 -0
- package/src/modules/catalog/i18n/ko.json +1 -0
- package/src/modules/catalog/i18n/pl.json +1 -0
- package/src/modules/catalog/workflows.ts +35 -0
- package/src/modules/customer_accounts/AGENTS.md +11 -0
- package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +2 -0
- package/src/modules/customer_accounts/cli.ts +96 -0
- package/src/modules/customer_accounts/i18n/de.json +5 -0
- package/src/modules/customer_accounts/i18n/en.json +5 -0
- package/src/modules/customer_accounts/i18n/es.json +5 -0
- package/src/modules/customer_accounts/i18n/ko.json +5 -0
- package/src/modules/customer_accounts/i18n/pl.json +5 -0
- package/src/modules/customer_accounts/lib/customerRoleAclSync.ts +92 -0
- package/src/modules/customer_accounts/setup.ts +15 -3
- package/src/modules/customers/commands/deals.ts +5 -0
- package/src/modules/customers/components/detail/ChangelogEntryRow.tsx +4 -2
- package/src/modules/customers/components/detail/utils.ts +2 -0
- package/src/modules/customers/events.ts +21 -3
- package/src/modules/customers/i18n/de.json +4 -0
- package/src/modules/customers/i18n/en.json +4 -0
- package/src/modules/customers/i18n/es.json +4 -0
- package/src/modules/customers/i18n/ko.json +4 -0
- package/src/modules/customers/i18n/pl.json +4 -0
- package/src/modules/customers/lib/link-workflow-task-handler.ts +136 -0
- package/src/modules/customers/lib/todoCompatibility.ts +4 -1
- package/src/modules/customers/lib/workflowTaskLink.ts +23 -0
- package/src/modules/customers/subscribers/link-workflow-task.ts +19 -0
- package/src/modules/customers/workflows.ts +57 -0
- package/src/modules/entities/api/records.ts +18 -62
- package/src/modules/entities/lib/entityClassification.ts +102 -0
- package/src/modules/sales/commands/documents.ts +46 -0
- package/src/modules/sales/events.ts +20 -2
- package/src/modules/sales/i18n/de.json +2 -1
- package/src/modules/sales/i18n/en.json +2 -1
- package/src/modules/sales/i18n/es.json +2 -1
- package/src/modules/sales/i18n/ko.json +2 -1
- package/src/modules/sales/i18n/pl.json +2 -1
- package/src/modules/sales/workflows.ts +12 -1
- package/src/modules/seeds/README.md +86 -0
- package/src/modules/seeds/cli.ts +220 -0
- package/src/modules/seeds/examples/sample-seed.json +26 -0
- package/src/modules/seeds/index.ts +11 -0
- package/src/modules/workflows/AGENTS.md +851 -10
- package/src/modules/workflows/acl.ts +96 -0
- package/src/modules/workflows/ai-agents.ts +80 -0
- package/src/modules/workflows/ai-tools/authoring-pack.ts +798 -0
- package/src/modules/workflows/ai-tools/types.ts +117 -0
- package/src/modules/workflows/ai-tools.ts +20 -0
- package/src/modules/workflows/api/command-settings/route.ts +171 -0
- package/src/modules/workflows/api/commands/route.ts +109 -0
- package/src/modules/workflows/api/definitions/[id]/callers/route.ts +95 -0
- package/src/modules/workflows/api/definitions/[id]/context-schema/route.ts +187 -0
- package/src/modules/workflows/api/definitions/[id]/customize/route.ts +6 -1
- package/src/modules/workflows/api/definitions/[id]/draft/route.ts +395 -0
- package/src/modules/workflows/api/definitions/[id]/publish/route.ts +250 -0
- package/src/modules/workflows/api/definitions/[id]/reset-to-code/route.ts +5 -0
- package/src/modules/workflows/api/definitions/[id]/route.ts +107 -7
- package/src/modules/workflows/api/definitions/[id]/test-step/route.ts +288 -0
- package/src/modules/workflows/api/definitions/generate/route.ts +335 -0
- package/src/modules/workflows/api/definitions/route.ts +88 -113
- package/src/modules/workflows/api/definitions/serialize.ts +9 -0
- package/src/modules/workflows/api/endpoints/route.ts +88 -0
- package/src/modules/workflows/api/functions/route.ts +91 -0
- package/src/modules/workflows/api/grantable-features/route.ts +102 -0
- package/src/modules/workflows/api/instances/[id]/context/route.ts +214 -0
- package/src/modules/workflows/api/instances/[id]/rerun-step/route.ts +226 -0
- package/src/modules/workflows/api/instances/[id]/retry/route.ts +18 -2
- package/src/modules/workflows/api/instances/[id]/step-through/route.ts +195 -0
- package/src/modules/workflows/api/instances/[id]/steps/route.ts +160 -0
- package/src/modules/workflows/api/instances/[id]/would-do/route.ts +216 -0
- package/src/modules/workflows/api/instances/bulk-replay/route.ts +141 -0
- package/src/modules/workflows/api/instances/failure-queue/route.ts +197 -0
- package/src/modules/workflows/api/instances/route.ts +135 -3
- package/src/modules/workflows/api/metrics/definitions/route.ts +262 -0
- package/src/modules/workflows/api/openapi.ts +549 -2
- package/src/modules/workflows/api/portal/tasks/[id]/complete/route.ts +160 -0
- package/src/modules/workflows/api/portal/tasks/[id]/route.ts +124 -0
- package/src/modules/workflows/api/portal/tasks/route.ts +157 -0
- package/src/modules/workflows/api/rule-usage/route.ts +94 -0
- package/src/modules/workflows/api/task-settings/route.ts +138 -0
- package/src/modules/workflows/api/tasks/[id]/claim/route.ts +42 -17
- package/src/modules/workflows/api/tasks/[id]/complete/route.ts +47 -15
- package/src/modules/workflows/api/tasks/[id]/reassign/route.ts +197 -0
- package/src/modules/workflows/api/tasks/[id]/route.ts +57 -6
- package/src/modules/workflows/api/tasks/[id]/unclaim/route.ts +132 -0
- package/src/modules/workflows/api/tasks/route.ts +60 -5
- package/src/modules/workflows/api/tasks/serialize.ts +119 -0
- package/src/modules/workflows/api/templates/route.ts +87 -0
- package/src/modules/workflows/api/work-inbox/next/route.ts +170 -0
- package/src/modules/workflows/api/work-inbox/route.ts +153 -0
- package/src/modules/workflows/backend/config/workflows/page.meta.ts +33 -0
- package/src/modules/workflows/backend/config/workflows/page.tsx +12 -0
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +19 -343
- package/src/modules/workflows/backend/definitions/create/page.meta.ts +1 -1
- package/src/modules/workflows/backend/definitions/create/page.tsx +19 -59
- package/src/modules/workflows/backend/definitions/page.tsx +156 -76
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +3129 -584
- package/src/modules/workflows/backend/instances/[id]/page.meta.ts +1 -1
- package/src/modules/workflows/backend/instances/[id]/page.tsx +711 -539
- package/src/modules/workflows/backend/instances/failure-queue/page.meta.ts +16 -0
- package/src/modules/workflows/backend/instances/failure-queue/page.tsx +311 -0
- package/src/modules/workflows/backend/instances/page.meta.ts +1 -1
- package/src/modules/workflows/backend/instances/page.tsx +218 -38
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +639 -400
- package/src/modules/workflows/backend/tasks/page.meta.ts +7 -0
- package/src/modules/workflows/backend/tasks/page.tsx +20 -333
- package/src/modules/workflows/backend/work-inbox/page.meta.ts +15 -0
- package/src/modules/workflows/backend/work-inbox/page.tsx +506 -0
- package/src/modules/workflows/cli.ts +1 -1
- package/src/modules/workflows/commands/tasks.ts +146 -0
- package/src/modules/workflows/components/ActivitiesEditor.tsx +91 -114
- package/src/modules/workflows/components/ActivityEditDialog.tsx +244 -0
- package/src/modules/workflows/components/AgentSelector.tsx +200 -0
- package/src/modules/workflows/components/AnnotationEditDialog.tsx +157 -0
- package/src/modules/workflows/components/BusinessRuleUsagePanel.tsx +106 -0
- package/src/modules/workflows/components/BusinessRulesSelector.tsx +71 -17
- package/src/modules/workflows/components/ConfigJsonTextarea.tsx +111 -0
- package/src/modules/workflows/components/ContextSchemaEditor.tsx +165 -0
- package/src/modules/workflows/components/DefinitionErrorHandlerField.tsx +133 -0
- package/src/modules/workflows/components/DefinitionMetadataDrawer.tsx +456 -0
- package/src/modules/workflows/components/DefinitionMetricsCells.tsx +212 -0
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +196 -95
- package/src/modules/workflows/components/EdgeEditDialog.tsx +15 -16
- package/src/modules/workflows/components/EdgeEditDialogCrudForm.tsx +130 -80
- package/src/modules/workflows/components/InputDataPanel.tsx +177 -0
- package/src/modules/workflows/components/InspectorPanel.tsx +250 -0
- package/src/modules/workflows/components/NodeEditDialog.tsx +444 -38
- package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +848 -178
- package/src/modules/workflows/components/StepsEditor.tsx +9 -2
- package/src/modules/workflows/components/TemplateGalleryDialog.tsx +205 -0
- package/src/modules/workflows/components/TransitionsEditor.tsx +98 -89
- package/src/modules/workflows/components/TriggersDialog.tsx +83 -0
- package/src/modules/workflows/components/TriggersEditor.tsx +363 -0
- package/src/modules/workflows/components/WorkflowAiDraftDialog.tsx +383 -0
- package/src/modules/workflows/components/WorkflowCodeView.tsx +257 -0
- package/src/modules/workflows/components/WorkflowCommandPalette.tsx +82 -0
- package/src/modules/workflows/components/WorkflowCompensationGhostEdge.tsx +78 -0
- package/src/modules/workflows/components/WorkflowDataMappingEdge.tsx +46 -0
- package/src/modules/workflows/components/WorkflowGraph.tsx +54 -1
- package/src/modules/workflows/components/WorkflowGraphImpl.tsx +463 -37
- package/src/modules/workflows/components/WorkflowIconPicker.tsx +144 -0
- package/src/modules/workflows/components/WorkflowLegend.tsx +59 -33
- package/src/modules/workflows/components/WorkflowNodeCard.tsx +355 -28
- package/src/modules/workflows/components/WorkflowRouteChips.tsx +145 -0
- package/src/modules/workflows/components/WorkflowSelector.tsx +33 -14
- package/src/modules/workflows/components/WorkflowTransitionEdge.tsx +83 -10
- package/src/modules/workflows/components/WorkflowTransitionLabel.tsx +13 -2
- package/src/modules/workflows/components/fields/ActivityArrayEditor.tsx +120 -30
- package/src/modules/workflows/components/fields/ActivityConfigFields.tsx +675 -0
- package/src/modules/workflows/components/fields/ActivityTestPanel.tsx +250 -0
- package/src/modules/workflows/components/fields/AgentInvokeConfigField.tsx +580 -0
- package/src/modules/workflows/components/fields/AgentReviewOnBreachField.tsx +88 -0
- package/src/modules/workflows/components/fields/BranchingRoutesEditor.tsx +323 -0
- package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +36 -4
- package/src/modules/workflows/components/fields/CommandPicker.tsx +158 -0
- package/src/modules/workflows/components/fields/EndpointPicker.tsx +330 -0
- package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +2 -2
- package/src/modules/workflows/components/fields/FunctionPicker.tsx +68 -0
- package/src/modules/workflows/components/fields/MappingArrayEditor.tsx +46 -12
- package/src/modules/workflows/components/fields/PortFieldArrayEditor.tsx +255 -0
- package/src/modules/workflows/components/fields/RolesMultiSelect.tsx +68 -0
- package/src/modules/workflows/components/fields/RouteOrderEditor.tsx +169 -0
- package/src/modules/workflows/components/fields/SchemaBuilderDialog.tsx +139 -0
- package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +2 -2
- package/src/modules/workflows/components/fields/TaskAssignmentField.tsx +355 -0
- package/src/modules/workflows/components/fields/TaskDeadlineFields.tsx +172 -0
- package/src/modules/workflows/components/fields/TaskDecisionsField.tsx +294 -0
- package/src/modules/workflows/components/fields/TaskEntityBindingsField.tsx +156 -0
- package/src/modules/workflows/components/fields/TemplateTextControl.tsx +85 -0
- package/src/modules/workflows/components/fields/VariablePickerButton.tsx +177 -0
- package/src/modules/workflows/components/fields/ledgerDropTarget.ts +55 -0
- package/src/modules/workflows/components/fields/useActivityTypeOptions.ts +19 -0
- package/src/modules/workflows/components/formConfig.tsx +84 -10
- package/src/modules/workflows/components/mobile/MobileDefinitionDetail.tsx +5 -0
- package/src/modules/workflows/components/mobile/MobileMetadataSheet.tsx +10 -0
- package/src/modules/workflows/components/mobile/MobileTaskForm.tsx +55 -19
- package/src/modules/workflows/components/mobile/MobileVisualEditor.tsx +49 -40
- package/src/modules/workflows/components/nodes/AnnotationGroupNode.tsx +81 -0
- package/src/modules/workflows/components/nodes/AutomatedNode.tsx +34 -17
- package/src/modules/workflows/components/nodes/EndNode.tsx +15 -14
- package/src/modules/workflows/components/nodes/ErrorOutputHandle.tsx +32 -0
- package/src/modules/workflows/components/nodes/IfElseNode.tsx +64 -0
- package/src/modules/workflows/components/nodes/InvokeAgentNode.tsx +180 -0
- package/src/modules/workflows/components/nodes/NodeOutcomeRows.tsx +143 -0
- package/src/modules/workflows/components/nodes/ParallelForkNode.tsx +28 -15
- package/src/modules/workflows/components/nodes/ParallelJoinNode.tsx +28 -15
- package/src/modules/workflows/components/nodes/StartNode.tsx +78 -18
- package/src/modules/workflows/components/nodes/StickyNoteNode.tsx +65 -0
- package/src/modules/workflows/components/nodes/SubWorkflowNode.tsx +124 -23
- package/src/modules/workflows/components/nodes/SwitchNode.tsx +64 -0
- package/src/modules/workflows/components/nodes/TriggerCap.tsx +103 -0
- package/src/modules/workflows/components/nodes/TriggerNode.tsx +151 -0
- package/src/modules/workflows/components/nodes/UserTaskNode.tsx +67 -22
- package/src/modules/workflows/components/nodes/WaitForConditionNode.tsx +74 -0
- package/src/modules/workflows/components/nodes/WaitForSignalNode.tsx +31 -17
- package/src/modules/workflows/components/nodes/WaitForTimerNode.tsx +31 -16
- package/src/modules/workflows/components/nodes/index.ts +17 -0
- package/src/modules/workflows/components/portal/PortalTaskForm.tsx +280 -0
- package/src/modules/workflows/components/run/AgentActivityPanel.tsx +48 -0
- package/src/modules/workflows/components/run/RerunStepDialog.tsx +133 -0
- package/src/modules/workflows/components/run/RunEventBadge.tsx +37 -0
- package/src/modules/workflows/components/run/RunGantt.tsx +180 -0
- package/src/modules/workflows/components/run/RunStatusBadge.tsx +112 -0
- package/src/modules/workflows/components/run/RunStepInspector.tsx +176 -0
- package/src/modules/workflows/components/run/WouldDoReport.tsx +93 -0
- package/src/modules/workflows/components/run/useAgentLabels.ts +42 -0
- package/src/modules/workflows/components/run/useLastRunOverlay.ts +150 -0
- package/src/modules/workflows/components/run/useLiveAgentActions.ts +70 -0
- package/src/modules/workflows/components/run/useLiveRunUpdates.ts +89 -0
- package/src/modules/workflows/components/settings/CommandSettingsPageClient.tsx +228 -0
- package/src/modules/workflows/components/work-inbox/EntityContextPanel.tsx +179 -0
- package/src/modules/workflows/components/work-inbox/ReassignTaskDialog.tsx +203 -0
- package/src/modules/workflows/components/work-inbox/StatusChip.tsx +61 -0
- package/src/modules/workflows/components/work-inbox/TaskActionNotice.tsx +77 -0
- package/src/modules/workflows/components/work-inbox/TaskFormFields.tsx +322 -0
- package/src/modules/workflows/components/work-inbox/WorkInboxEmptyState.tsx +43 -0
- package/src/modules/workflows/data/activity-config-schemas.ts +249 -0
- package/src/modules/workflows/data/activity-config-warnings.ts +71 -0
- package/src/modules/workflows/data/branching-route-warnings.ts +129 -0
- package/src/modules/workflows/data/entities.ts +397 -4
- package/src/modules/workflows/data/metrics-validators.ts +51 -0
- package/src/modules/workflows/data/task-primitives.ts +36 -0
- package/src/modules/workflows/data/types.ts +81 -2
- package/src/modules/workflows/data/validators.ts +729 -60
- package/src/modules/workflows/di.ts +22 -0
- package/src/modules/workflows/events.ts +68 -8
- package/src/modules/workflows/examples/oze-residential-install-60-nodes.json +1545 -0
- package/src/modules/workflows/examples/sales-pipeline-definition.json +35 -35
- package/src/modules/workflows/examples/templates/lead-to-install.json +160 -0
- package/src/modules/workflows/examples/templates/order-approval.json +230 -0
- package/src/modules/workflows/examples/templates/task-escalation.json +110 -0
- package/src/modules/workflows/examples/templates/webhook-integration.json +113 -0
- package/src/modules/workflows/extension-points.ts +1 -1
- package/src/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.meta.ts +21 -0
- package/src/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.tsx +212 -0
- package/src/modules/workflows/frontend/[orgSlug]/portal/tasks/page.meta.ts +25 -0
- package/src/modules/workflows/frontend/[orgSlug]/portal/tasks/page.tsx +185 -0
- package/src/modules/workflows/i18n/de.json +1083 -24
- package/src/modules/workflows/i18n/en.json +1081 -22
- package/src/modules/workflows/i18n/es.json +1083 -24
- package/src/modules/workflows/i18n/ko.json +1072 -13
- package/src/modules/workflows/i18n/pl.json +1082 -23
- package/src/modules/workflows/lib/activity-executor.ts +855 -186
- package/src/modules/workflows/lib/activity-queue-types.ts +120 -1
- package/src/modules/workflows/lib/activity-registry-bootstrap.ts +7 -0
- package/src/modules/workflows/lib/activity-registry.ts +89 -0
- package/src/modules/workflows/lib/activity-types.ts +415 -0
- package/src/modules/workflows/lib/activity-worker-handler.ts +744 -35
- package/src/modules/workflows/lib/advanced-config.ts +41 -0
- package/src/modules/workflows/lib/agent-disposition-task.ts +343 -0
- package/src/modules/workflows/lib/agent-outcome-paths.ts +153 -0
- package/src/modules/workflows/lib/agent-result-mapping.ts +88 -0
- package/src/modules/workflows/lib/agent-review-inspector.ts +125 -0
- package/src/modules/workflows/lib/agent-review.ts +171 -0
- package/src/modules/workflows/lib/ai-authoring.ts +402 -0
- package/src/modules/workflows/lib/ai-draft-runner.ts +105 -0
- package/src/modules/workflows/lib/annotation-events.ts +15 -0
- package/src/modules/workflows/lib/branching-routes.ts +280 -0
- package/src/modules/workflows/lib/breach-routing.ts +142 -0
- package/src/modules/workflows/lib/bulk-replay.ts +185 -0
- package/src/modules/workflows/lib/business-rule-usage.ts +154 -0
- package/src/modules/workflows/lib/caller-graph.ts +104 -0
- package/src/modules/workflows/lib/code-view-apply.ts +178 -0
- package/src/modules/workflows/lib/collect-validation-issues.ts +239 -0
- package/src/modules/workflows/lib/compensation-ghosts.ts +134 -0
- package/src/modules/workflows/lib/component-guard.ts +13 -0
- package/src/modules/workflows/lib/condition-handler.ts +658 -0
- package/src/modules/workflows/lib/context-ledger.ts +814 -0
- package/src/modules/workflows/lib/crud-form-dialogs-flag.ts +5 -0
- package/src/modules/workflows/lib/data-edge-mapping.ts +112 -0
- package/src/modules/workflows/lib/definition-context-schema.ts +103 -0
- package/src/modules/workflows/lib/definition-edit-safety.ts +228 -0
- package/src/modules/workflows/lib/definition-error-body.ts +43 -0
- package/src/modules/workflows/lib/definition-evaluation.ts +156 -0
- package/src/modules/workflows/lib/definition-grant.ts +211 -0
- package/src/modules/workflows/lib/definition-json-locations.ts +226 -0
- package/src/modules/workflows/lib/definition-payload.ts +81 -0
- package/src/modules/workflows/lib/draft-restore.ts +72 -0
- package/src/modules/workflows/lib/dry-run.ts +203 -0
- package/src/modules/workflows/lib/duration.ts +138 -24
- package/src/modules/workflows/lib/edge-reattachment.ts +186 -0
- package/src/modules/workflows/lib/edgeFormTransforms.ts +15 -14
- package/src/modules/workflows/lib/editor-annotations.ts +301 -0
- package/src/modules/workflows/lib/editor-commands.ts +205 -0
- package/src/modules/workflows/lib/editor-history.ts +151 -0
- package/src/modules/workflows/lib/endpoint-catalog.ts +283 -0
- package/src/modules/workflows/lib/endpoint-path.ts +134 -0
- package/src/modules/workflows/lib/engine-version.ts +67 -0
- package/src/modules/workflows/lib/error-handler.ts +192 -0
- package/src/modules/workflows/lib/error-routing.ts +236 -0
- package/src/modules/workflows/lib/event-logger.ts +27 -0
- package/src/modules/workflows/lib/expression-refs.ts +291 -0
- package/src/modules/workflows/lib/failure-grouping.ts +134 -0
- package/src/modules/workflows/lib/find-definition.ts +4 -0
- package/src/modules/workflows/lib/flow-logic-warnings.ts +591 -0
- package/src/modules/workflows/lib/graph-utils.ts +620 -110
- package/src/modules/workflows/lib/icon-search.ts +65 -0
- package/src/modules/workflows/lib/insert-at-cursor.ts +53 -0
- package/src/modules/workflows/lib/instance-date-filter.ts +56 -0
- package/src/modules/workflows/lib/interpolation-pipeline.ts +351 -0
- package/src/modules/workflows/lib/ledger-drag.ts +61 -0
- package/src/modules/workflows/lib/ledger-entry-display.ts +89 -0
- package/src/modules/workflows/lib/ledger-schema-flatten.ts +137 -0
- package/src/modules/workflows/lib/metrics/definition-metrics.ts +268 -0
- package/src/modules/workflows/lib/metrics/metrics-display.ts +57 -0
- package/src/modules/workflows/lib/metrics/rollup-schedule.ts +26 -0
- package/src/modules/workflows/lib/metrics/rollup-service.ts +292 -0
- package/src/modules/workflows/lib/node-config-summary.ts +235 -0
- package/src/modules/workflows/lib/node-geometry.ts +168 -0
- package/src/modules/workflows/lib/node-nudge.ts +63 -0
- package/src/modules/workflows/lib/node-outcome-rows.ts +195 -0
- package/src/modules/workflows/lib/node-placement.ts +104 -0
- package/src/modules/workflows/lib/node-type-icons.ts +71 -10
- package/src/modules/workflows/lib/nodeFormTransforms.ts +519 -28
- package/src/modules/workflows/lib/outcome-routing.ts +346 -0
- package/src/modules/workflows/lib/owned-definition.ts +188 -0
- package/src/modules/workflows/lib/owned-node-changes.ts +29 -0
- package/src/modules/workflows/lib/palette-drag.ts +68 -0
- package/src/modules/workflows/lib/palette-drop.ts +114 -0
- package/src/modules/workflows/lib/parallel-handler.ts +79 -2
- package/src/modules/workflows/lib/port-contract.ts +107 -0
- package/src/modules/workflows/lib/portal-task-access.ts +220 -0
- package/src/modules/workflows/lib/rerun-from-step.ts +140 -0
- package/src/modules/workflows/lib/route-chip-events.ts +45 -0
- package/src/modules/workflows/lib/route-chips.ts +177 -0
- package/src/modules/workflows/lib/route-edge.ts +57 -0
- package/src/modules/workflows/lib/route-kinds.ts +166 -0
- package/src/modules/workflows/lib/route-priority.ts +197 -0
- package/src/modules/workflows/lib/run-duration.ts +70 -0
- package/src/modules/workflows/lib/run-event-tone.ts +46 -0
- package/src/modules/workflows/lib/run-execution.ts +598 -0
- package/src/modules/workflows/lib/run-gantt.ts +311 -0
- package/src/modules/workflows/lib/run-outcome-evidence.ts +60 -0
- package/src/modules/workflows/lib/run-outcome.ts +142 -0
- package/src/modules/workflows/lib/sample-resolver.ts +113 -0
- package/src/modules/workflows/lib/seeds.ts +3 -1
- package/src/modules/workflows/lib/server-output-contract.ts +120 -0
- package/src/modules/workflows/lib/set-variable.ts +94 -0
- package/src/modules/workflows/lib/signal-handler.ts +134 -4
- package/src/modules/workflows/lib/start-fixtures.ts +93 -0
- package/src/modules/workflows/lib/status-colors.ts +220 -21
- package/src/modules/workflows/lib/step-handler.ts +744 -68
- package/src/modules/workflows/lib/step-presentation.ts +295 -0
- package/src/modules/workflows/lib/step-through.ts +71 -0
- package/src/modules/workflows/lib/step-type-conversion.ts +263 -0
- package/src/modules/workflows/lib/subgraph-clipboard.ts +214 -0
- package/src/modules/workflows/lib/task-decision-context.ts +76 -0
- package/src/modules/workflows/lib/task-decisions.ts +117 -0
- package/src/modules/workflows/lib/task-entity-access.ts +181 -0
- package/src/modules/workflows/lib/task-entity-aliases.ts +77 -0
- package/src/modules/workflows/lib/task-entity-types.ts +66 -0
- package/src/modules/workflows/lib/task-form-registry.ts +123 -0
- package/src/modules/workflows/lib/task-form-schema.ts +129 -0
- package/src/modules/workflows/lib/task-handler.ts +492 -51
- package/src/modules/workflows/lib/task-inspector-config.ts +348 -0
- package/src/modules/workflows/lib/task-list-query.ts +46 -0
- package/src/modules/workflows/lib/task-notifications.ts +218 -0
- package/src/modules/workflows/lib/task-permission-settings.ts +117 -0
- package/src/modules/workflows/lib/task-presets.ts +95 -0
- package/src/modules/workflows/lib/task-quick-action.ts +111 -0
- package/src/modules/workflows/lib/task-resolution.ts +270 -0
- package/src/modules/workflows/lib/task-sla.ts +628 -0
- package/src/modules/workflows/lib/task-visibility-request.ts +668 -0
- package/src/modules/workflows/lib/task-visibility.ts +627 -0
- package/src/modules/workflows/lib/timer-handler.ts +8 -1
- package/src/modules/workflows/lib/transition-handler.ts +228 -20
- package/src/modules/workflows/lib/trigger-node.ts +272 -0
- package/src/modules/workflows/lib/visual-editor-navigation.ts +29 -0
- package/src/modules/workflows/lib/work-inbox/empty-state.ts +150 -0
- package/src/modules/workflows/lib/work-inbox/entity-links.ts +99 -0
- package/src/modules/workflows/lib/work-inbox/navigation.ts +28 -0
- package/src/modules/workflows/lib/work-inbox/presentation.ts +163 -0
- package/src/modules/workflows/lib/work-inbox/provider.ts +390 -0
- package/src/modules/workflows/lib/work-inbox/query.ts +103 -0
- package/src/modules/workflows/lib/work-inbox/service.ts +122 -0
- package/src/modules/workflows/lib/work-inbox/user-task-source.ts +240 -0
- package/src/modules/workflows/lib/workflow-command-enablement.ts +188 -0
- package/src/modules/workflows/lib/workflow-command-settings.ts +124 -0
- package/src/modules/workflows/lib/workflow-executor.ts +1036 -10
- package/src/modules/workflows/lib/workflow-function-registry.ts +44 -0
- package/src/modules/workflows/lib/workflow-safe-commands.ts +42 -1
- package/src/modules/workflows/lib/workflow-templates.ts +91 -0
- package/src/modules/workflows/migrations/.snapshot-open-mercato.json +2321 -698
- package/src/modules/workflows/migrations/Migration20260626214855_workflows.ts +15 -0
- package/src/modules/workflows/migrations/Migration20260626222424_workflows.ts +17 -0
- package/src/modules/workflows/migrations/Migration20260727074335_workflows.ts +15 -0
- package/src/modules/workflows/migrations/Migration20260728104038_workflows.ts +13 -0
- package/src/modules/workflows/migrations/Migration20260728163001_workflows.ts +36 -0
- package/src/modules/workflows/migrations/Migration20260729061736_workflows.ts +13 -0
- package/src/modules/workflows/migrations/Migration20260729192652_workflows.ts +11 -0
- package/src/modules/workflows/migrations/Migration20260730085000_workflows.ts +13 -0
- package/src/modules/workflows/migrations/Migration20260730092706_workflows.ts +13 -0
- package/src/modules/workflows/notifications.ts +40 -10
- package/src/modules/workflows/setup.ts +128 -0
- package/src/modules/workflows/subscribers/task-assigned-notification.ts +36 -45
- package/src/modules/workflows/subscribers/task-deadline-breached-notification.ts +31 -0
- package/src/modules/workflows/subscribers/task-reminder-notification.ts +31 -0
- package/src/modules/workflows/widgets/injection/pending-work/widget.client.tsx +119 -0
- package/src/modules/workflows/widgets/injection/pending-work/widget.ts +27 -0
- package/src/modules/workflows/widgets/injection-table.ts +52 -2
- package/src/modules/workflows/workers/workflow-activities.worker.ts +95 -42
- package/src/modules/workflows/workers/workflow-definition-metric-rollup.worker.ts +71 -0
- package/src/modules/workflows/workers/workflow-instance-bulk-replay.ts +51 -0
- package/src/modules/workflows/workers/workflow-invoke-agent.worker.ts +72 -0
|
@@ -35,8 +35,14 @@ Use the workflows module for business process automation: defining step-based wo
|
|
|
35
35
|
yarn db:generate
|
|
36
36
|
yarn generate
|
|
37
37
|
yarn workspace @open-mercato/core build
|
|
38
|
+
yarn mercato auth sync-role-acls # after ANY acl.ts change — existing tenants only pick up new grants here
|
|
38
39
|
```
|
|
39
40
|
|
|
41
|
+
Release runbook: adding a feature to `acl.ts` grants it to new tenants through
|
|
42
|
+
`setup.ts` `defaultRoleFeatures`, but **existing** tenants receive nothing until
|
|
43
|
+
`yarn mercato auth sync-role-acls` runs. Run it as part of the deploy for every
|
|
44
|
+
release that touches `acl.ts`.
|
|
45
|
+
|
|
40
46
|
## Execution Architecture
|
|
41
47
|
|
|
42
48
|
```
|
|
@@ -68,6 +74,7 @@ Definition → startWorkflow() → Instance → executeWorkflow() loop
|
|
|
68
74
|
- **UserTask** — human-in-the-loop tasks. MUST have `assignedTo` or `assignedToRoles`; MUST respect `dueDate` for SLA tracking
|
|
69
75
|
- **WorkflowEvent** — immutable audit log. MUST NOT be updated or deleted after creation
|
|
70
76
|
- **WorkflowEventTrigger** — maps domain events to workflow starts. MUST specify `filterConditions` and `contextMapping`
|
|
77
|
+
- **WorkflowDefinitionDraft** — per-user editor autosave (`workflow_definition_drafts`, unique per definition+user+tenant). Served by `api/definitions/[id]/draft` (GET/PUT/DELETE, gated on `workflows.definitions.edit`); MUST NOT mutate the definition or its optimistic lock — only explicit Save does
|
|
71
78
|
|
|
72
79
|
## Step Types
|
|
73
80
|
|
|
@@ -80,6 +87,7 @@ Definition → startWorkflow() → Instance → executeWorkflow() loop
|
|
|
80
87
|
| `SUB_WORKFLOW` | When invoking a nested workflow definition |
|
|
81
88
|
| `WAIT_FOR_SIGNAL` | When the workflow must pause for an external signal (e.g., payment confirmed) |
|
|
82
89
|
| `WAIT_FOR_TIMER` | When the workflow must pause for a duration |
|
|
90
|
+
| `WAIT_FOR_CONDITION` | When the workflow must pause until a predicate over the run context holds — mandatory `timeout` with `onTimeout: 'FAIL'\|'CONTINUE'`, event-driven wake plus a polled backstop |
|
|
83
91
|
| `PARALLEL_FORK` / `PARALLEL_JOIN` | When splitting/merging parallel execution paths |
|
|
84
92
|
|
|
85
93
|
## Activity Types
|
|
@@ -93,12 +101,840 @@ Definition → startWorkflow() → Instance → executeWorkflow() loop
|
|
|
93
101
|
| `EMIT_EVENT` | Emit a domain event to the event bus |
|
|
94
102
|
| `EXECUTE_FUNCTION` | Run a registered custom function |
|
|
95
103
|
| `WAIT` | Delay execution for a configured duration |
|
|
104
|
+
| `SET_VARIABLE` | Write values into workflow context at dot paths (assignments land at top-level context, not namespaced under the activity) |
|
|
105
|
+
|
|
106
|
+
## Context Backbone (contextSchema · ledger · picker · samples · test step)
|
|
107
|
+
|
|
108
|
+
- **`contextSchema`** — optional definition field declaring typed workflow inputs (`{ input: { fields: [{ name, type, label?, required?, options? }] } }`, same field vocabulary as `userTaskConfig.formSchema`). Edited via the definition panel's Context section; feeds the ledger's START entries (`required` → `always`, else `maybe`). Additive — absent stays absent through save round-trips.
|
|
109
|
+
- **`contextSchema` is CANONICAL; `definition.io.inputs` is a read-through alias** — the sub-workflow port contract (`definition.io`, `workflowIoContractSchema`) shares the same field vocabulary. When a definition declares no `contextSchema.input`, the ledger reads `io.inputs` through as its START entries (source label `io.inputs (read-through)`); when both exist, `contextSchema.input` wins. Full `@deprecated` dual-emit for `io.inputs` is deliberate follow-up work — only the ledger read-through ships today. The visual editor carries BOTH `contextSchema` and `io` as pass-through state so neither is stripped by save, drag-autosave, or draft round-trips (`lib/definition-payload.ts`).
|
|
110
|
+
- **Context ledger** — `lib/context-ledger.ts` is PURE (no React/ORM/DI/registry imports): `computeContextLedger` derives per-step incoming entries `{path, type, presence: always|maybe, source, sample?}` as a topological fixpoint over the graph (joins degrade presence to `maybe`; cycles tolerated). Output-contract resolution is an injected seam: the server injects `resolveServerOutputContract` (`lib/server-output-contract.ts` — activity registry + `commandRegistry.outputSchemaOf` + `flattenSchemaToContract` from `lib/ledger-schema-flatten.ts`); the browser never resolves contracts locally, it consumes the API response.
|
|
111
|
+
- **Engine facts (verified — never model these as available):** AUTOMATED steps' sync activity outputs land only in `stepInstance.outputData`, never `instance.context`, and the ledger deliberately advertises none of them. Transition-activity sync outputs DO persist (namespaced under `activityName || activityType`), async outputs land under `${activityId}_result` at resume, SET_VARIABLE writes land at its dot paths.
|
|
112
|
+
- **What lands is the ACTIVITY HANDLER's return, never the command's.** `executeUpdateEntity` returns the envelope `{ executed, commandId, result, logEntryId }` and both merge paths carry it verbatim, so a command's `outputSchema` describes what sits under `result` — the ledger nests it there (`<activity>.result.<path>`). Any new `outputContract` MUST model its handler's envelope the same way; CALL_API's still flattens the endpoint response schema at the activity root while `executeCallApi` returns `{ status, statusText, headers, body, … }` with the response under `body` — a known, unfixed off-by-one-level in the same family.
|
|
113
|
+
- **SUB_WORKFLOW is PATH-DEPENDENT, not silent.** Its two resolution paths disagree and only one merges: a child that terminates inside the parent's own call returns the mapped output as `stepInstance.outputData` only (`handleSubWorkflowStep` → `exitStep`), but a child that PARKS on its first async/agent step parks the parent on `SUB_WORKFLOW_SIGNAL_NAME`, and the child's terminal `resume_subworkflow_parent` job maps the same output and passes it to `sendSignal`, which spreads the payload FLAT into `instance.context`. So `config.outputMapping` target keys genuinely reach the parent context on the async path — the ledger models them as a `subWorkflow` producer with every entry `maybe` (which path runs is a property of the CHILD at runtime, and the mapping drops any target whose source path is undefined) and `unknown`-typed (the source paths address the child's context, and the child's `io.outputs` contract lives on the CHILD definition the pure ledger is never given). Two real contributions stay unmodeled on purpose: with no mapping — or when no mapped source resolves — `mapOutputData` falls back to the WHOLE child context, whose keys cannot be named from the parent definition (a `'*'` wildcard would silence every downstream unresolved-ref warning, so a step declaring no `outputMapping` advertises nothing, unchanged); and `sendSignal`'s `signal_<name>_payload`/`_receivedAt` keys do land but the signal name is `workflows.sub_workflow.completed`, so the dotted flat key is unreachable through `{{context.*}}` resolution (`getNestedValue` splits on `.`).
|
|
114
|
+
- **INVOKE_AGENT is the verified exception** to the AUTOMATED rule: its result IS merged top-level into `instance.context` on every resolution path (step-handler inline branch, `activity-worker-handler` parked resume, agent_orchestrator human dispose → `sendSignal`). The ledger models it as a producer (source kind `invokeAgent`, all entries `maybe` because which keys land is path-dependent): `outputMapping` target keys when declared (machine paths only, `mapAgentResultToContext`), typed from each mapping's source path against the INVOKE_AGENT envelope (`kind`/`disposition`/`agentId`/`proposalId` plus the selected agent's OUTCOME under `data.*` for researcher agents or `proposalPayload.*` for proposal ones) — resolved server-side through the OPTIONAL peer's `agentWorkflowBridge.listAgentOutcomeContracts()` warmed by `ensureWorkflowAgentOutcomeContracts`, `unknown` when the peer is absent; otherwise the legacy fixed keys `agentId`/`agentProposalId`/`<stepId>_agent`; plus, regardless of mapping, the human-dispose keys `disposition`/`proposalId`/`stepId`/`proposalPayload` and the `sendSignal` envelope keys `signal_<signalName>_payload`/`_receivedAt` (`signalConfig.signalName`, default `agent_orchestrator.proposal.ready`).
|
|
115
|
+
- **Prompt-to-draft agent self-validates + is fail-closed on INVOKE_AGENT** — the in-Studio `workflows.workflow_author` agent (spec §9) is object-mode but now allows exactly ONE read-only tool, `workflows.validate_workflow_definition` (draft-shaped, gated on `definitions.create`), run inside the runtime's `enableTools` object-mode loop (`lib/ai-draft-runner.ts` sets `enableTools: true`; a tight `loop.budget` bounds it). The tool re-runs the exact generate-route validation (`workflowDefinitionDataSchema` + `evaluateWorkflowDefinition`) so the model self-corrects a partial config (e.g. missing `INVOKE_AGENT` `config.agentId`/`onResult`) before returning; the route's post-generation `safeParse` stays the trust boundary. `buildWorkflowDraftCatalog` carries a usable-`agents` list (fed from the OPTIONAL `agentWorkflowBridge.listAgentOutcomeContracts?.()`), and `buildWorkflowDraftPrompt` FORBIDS `INVOKE_AGENT` outright when that list is empty — fail-closed, so no agent step is drafted when there is no agent to run.
|
|
116
|
+
- **Context-schema API** — `GET api/definitions/[id]/context-schema` (`?stepId=` narrows; feature `workflows.definitions.view`) serves the server-computed ledger; same id forms as the definition GET (UUID, `code:<workflowId>`, synthetic uuid).
|
|
117
|
+
- **Variable picker + ref warnings** — `lib/expression-refs.ts` (pure) extracts `{{context.*}}` refs and checks them against the ledger; misses surface as Problems-panel WARNINGS, never blocking. `VariablePickerButton` (fed by the API ledger) inserts `{{path}}` at the cursor in activity config fields, mapping value cells, and trigger expressions.
|
|
118
|
+
- **Input data panel + drag-to-insert** — `components/InputDataPanel.tsx` docks the SAME grouped listing (shared helpers in `lib/ledger-entry-display.ts`) beside the node/edge edit dialogs, with samples from `lib/sample-resolver.ts`. Rows are draggable buttons: the drag carries `text/plain` = `{{path}}` (native drop into any input) plus the private `application/x-om-ledger-path` MIME (`lib/ledger-drag.ts`) that template-capable fields intercept via `ledgerDropTargetProps` to insert at the caret in their own mode (`'bare'` for mapping cells). Click and drag are both first-class; drag is an enhancement over the button/keyboard path, never the only way in.
|
|
119
|
+
- **Samples** — `metadata.editor.samples` (`record(stepId, { pinnedAt, source: manual|test, data })`, total ≤64KB via `WORKFLOW_EDITOR_SAMPLES_MAX_CHARS`). Samples are NOT redacted or encrypted — pinned data is stored verbatim in definition metadata; keep the warning copy wherever pinning is offered. Precedence: pin > last test output > ledger placeholder (`lib/sample-resolver.ts`, pure).
|
|
120
|
+
- **Test step** — `POST api/definitions/[id]/test-step` (feature `workflows.definitions.test_run`, dependsOn `definitions.edit`) is MOCK-FIRST: it never calls `entry.execute`. Registry `mock` is `((config, ctx) => unknown) | 'refuse'`; `'refuse'` or a missing mock returns 200 `{ refused: true, reason }`. Config is interpolated via the exported `interpolateVariables` against the caller-supplied sample context.
|
|
121
|
+
|
|
122
|
+
## Error Routing (routes · directives · workflow-level handler)
|
|
123
|
+
|
|
124
|
+
Spec §5.9. Everything here is additive and optional: a definition declaring none of it fails exactly
|
|
125
|
+
as it always did (guarded by a regression test in `lib/__tests__/error-routing.test.ts`).
|
|
126
|
+
|
|
127
|
+
- **`lib/error-routing.ts` is PURE and is the single decision point.** `resolveStepFailureHandling`
|
|
128
|
+
answers, in precedence order: wired **error route** → step **`errorDirective`** → definition-level
|
|
129
|
+
**`errorHandler.stepId`** → `fail`.
|
|
130
|
+
- **Error route** = a transition with `kind: 'error'`. It is reachable ONLY from a failure: every
|
|
131
|
+
normal-routing lookup (`findValidTransitions`, the executor's auto pre-check, `evaluateTransition`'s
|
|
132
|
+
auto-select, the fork/join graph walk) filters through `excludeErrorTransitions`. Following one
|
|
133
|
+
publishes the failure into `context.__error` (a RESERVED context key) and logs `ERROR_ROUTED`. In a
|
|
134
|
+
parallel branch the route is followed with the branch token, so a handled branch failure never
|
|
135
|
+
reaches the instance.
|
|
136
|
+
- **`errorDirective`** on a step: `fail` (default) · `continueWithFallback` · `failureQueue`.
|
|
137
|
+
`continueWithFallback` is the directive form of the transition's legacy `continueOnActivityFailure`
|
|
138
|
+
flag — that flag is untouched and byte-compatible; the directive additionally writes
|
|
139
|
+
`fallbackValue` into context under the failing step's id. A failed step instance is NEVER flipped
|
|
140
|
+
back to COMPLETED; the instance advances while the step stays FAILED.
|
|
141
|
+
- **`failureQueue`** parks the instance: existing `PAUSED` status + engine-owned
|
|
142
|
+
`metadata.attention` marker + `ERROR_PARKED`. No new instance status, and compensation does not run
|
|
143
|
+
because the run is suspended, not terminated. `GET /api/workflows/instances?attention=true` lists
|
|
144
|
+
them; the triage UI is Phase 5.
|
|
145
|
+
- **Workflow-level handler** (`definition.errorHandler`, exactly one form) is an ENGINE CONSTRUCT —
|
|
146
|
+
never an event trigger (the trigger subscriber excludes `workflows.*` by design).
|
|
147
|
+
- `{ stepId }`: last-resort in-instance jump — the executor writes `__error`, moves the cursor and
|
|
148
|
+
executes the handler step (`ERROR_HANDLER_STARTED`). A step never jumps to itself, which is that
|
|
149
|
+
form's recursion guard.
|
|
150
|
+
- `{ workflowId, version? }`: catch-all. `completeWorkflow`'s FAILED branch schedules it **before**
|
|
151
|
+
compensation (so the snapshot is pre-compensation and it still runs when compensation throws),
|
|
152
|
+
logging `ERROR_HANDLER_SCHEDULED` inside the failing transaction and enqueueing a
|
|
153
|
+
`workflow_error_handler` job. The worker starts it as a sub-workflow with initial context
|
|
154
|
+
`{ failedStepId, error, contextSnapshot }` on its own connection. Recursion guard:
|
|
155
|
+
`metadata.errorHandler.depth` (engine-owned — never `context`, which the context PATCH API
|
|
156
|
+
exposes), capped by `WORKFLOW_MAX_ERROR_HANDLER_DEPTH = 1`; over the cap logs
|
|
157
|
+
`ERROR_HANDLER_SKIPPED`.
|
|
158
|
+
- Design rationale and the ordering/durability/recursion/branch decisions:
|
|
159
|
+
`.ai/runs/2026-07-27-workflows-ux-phase2b-3/DESIGN-error-handler.md`.
|
|
160
|
+
|
|
161
|
+
## Agent Outcome Routing (spec §7.2)
|
|
162
|
+
|
|
163
|
+
- **`lib/outcome-routing.ts` (PURE) is the single decision point**, the third member of the family
|
|
164
|
+
`lib/error-routing.ts` and `lib/breach-routing.ts` belong to. The three share the mechanical parts
|
|
165
|
+
through `lib/route-kinds.ts` (`excludeNonNormalTransitions`, the handle ↔ kind round trip) and keep
|
|
166
|
+
their own decision points, because their fallback vocabularies genuinely differ.
|
|
167
|
+
- **The handle set is spec §7.2's FIXED five disposition kinds** — `approved`, `researcher`,
|
|
168
|
+
`rejected`, `guardrailBlocked`, `error` — NOT the selected agent's OUTCOME-schema enum. Enumerating
|
|
169
|
+
from the schema would need a per-value condition on each transition, which is exactly the context
|
|
170
|
+
string-matching §7.2 exists to remove. These five are governance states; the OUTCOME schema is
|
|
171
|
+
domain data.
|
|
172
|
+
- **Precedence** (`resolveAgentOutcomeHandling`): the step wired NO outcome route ⇒ `default`
|
|
173
|
+
(today's normal routing, byte-identical for every pre-existing definition) → a wired route for this
|
|
174
|
+
outcome ⇒ `route` → `approved` unwired ⇒ `default` (§7.2 renders `approved` unconditionally because
|
|
175
|
+
it IS the node's ordinary output) → anything else ⇒ `inherit`, the step's `errorDirective`, which is
|
|
176
|
+
the "unhandled → fail instance" the node face states.
|
|
177
|
+
- **Routing NEVER reads the author-visible `disposition` context key.** `lib/step-handler.ts` (inline
|
|
178
|
+
resolution) and `lib/signal-handler.ts` (every parked resume — the activity worker's and the human
|
|
179
|
+
dispose path alike) write the ENGINE-OWNED `__agentOutcome` marker
|
|
180
|
+
(`WORKFLOW_AGENT_OUTCOME_CONTEXT_KEY`), and `dispatchAgentOutcome` in the executor consumes it —
|
|
181
|
+
clearing it first, so a route looping back through the step cannot re-fire on a stale disposition.
|
|
182
|
+
- **Rejection is a business route, not an error** (§7.2): a rejected proposal routes `rejected`;
|
|
183
|
+
infra failure keeps the retry policy and then the `error` route. Events: `OUTCOME_ROUTED` /
|
|
184
|
+
`OUTCOME_UNHANDLED`.
|
|
185
|
+
- **Guardrail escalation (§7.3).** A runtime guardrail `block` is recognised STRUCTURALLY
|
|
186
|
+
(`isGuardrailBlockedError` — `code === 'agent_guardrail_blocked'` or `guardrailBlocked === true`),
|
|
187
|
+
the same way `isRetryableError` reads `retryable: true`, so `agent_orchestrator` stays an optional
|
|
188
|
+
peer core never imports. The activity worker resumes the parked step down the `guardrailBlocked`
|
|
189
|
+
route **only when the step wired one**; otherwise its fail-stop is byte-identical to before, which
|
|
190
|
+
is what keeps §7.3 additive. Only the guardrail CLASSIFICATION travels into the run context
|
|
191
|
+
(`__guardrailBlock`: phase, kind, guardrail-set version) — never the evidence blob, per
|
|
192
|
+
`agent_orchestrator/AGENTS.md`'s redaction rule.
|
|
193
|
+
- Author-time checks live in `validateOutcomeRoutes` (unknown outcome kind, two routes claiming the
|
|
194
|
+
same kind on one step) and surface through the Problems panel.
|
|
195
|
+
|
|
196
|
+
## Agent Disposition Review & SLAs (spec §7.5)
|
|
197
|
+
|
|
198
|
+
- **The disposition task is a REAL task, built by this module.** `lib/agent-disposition-task.ts`
|
|
199
|
+
owns the row `dispositionService` used to assemble inline — because this module owns the entity,
|
|
200
|
+
the `USER_TASK_CREATED` audit row, the `workflows.task.assigned` event and the SLA scheduler.
|
|
201
|
+
`agent_orchestrator` reaches it through a dynamic import inside its own try/catch, exactly as
|
|
202
|
+
`lib/disposition/resume.ts` reaches `sendSignal`; the peer stays optional in both directions.
|
|
203
|
+
Before this, the row was created unassigned — which under §6.4 is visible only to administrative
|
|
204
|
+
oversight and ACTABLE BY NOBODY (`currentTaskOwnerId` is null ⇒ `ownsTheRow` false), and never
|
|
205
|
+
reached the notification subscriber.
|
|
206
|
+
- **`invokeAgentConfigSchema.review` is the authored half** and `lib/agent-review.ts` (PURE)
|
|
207
|
+
resolves it, delegating assignment to the SAME `resolveTaskAssignment` a USER_TASK uses — so an
|
|
208
|
+
unresolved dynamic assignee falls back to the authored role queue here too. Resolution happens in
|
|
209
|
+
the ACTIVITY EXECUTOR, against the context the step ran with, and the resolved descriptor rides
|
|
210
|
+
the `invoke_agent` queue job; a definition edit while the agent runs cannot retro-change who the
|
|
211
|
+
review belongs to.
|
|
212
|
+
- **A breached disposition deadline ESCALATES; it never decides.** `resolveAgentReviewBreachHandling`
|
|
213
|
+
has no `route` arm and no verdict arm, and that absence is the feature (maintainer decision,
|
|
214
|
+
2026-07-29): notify / reassign / `attention`. `applyBreachHandling` picks the vocabulary from the
|
|
215
|
+
STEP's shape — an AUTOMATED step carrying an INVOKE_AGENT activity gets the escalate-only one — so
|
|
216
|
+
a hand-authored `kind:'slaBreach'` transition on an agent step cannot fire either. Routing the run
|
|
217
|
+
past a proposal nobody answered silently drops the proposed mutation, which is a rejection in
|
|
218
|
+
everything but name, and only a human may reach a verdict. `attention` writes the engine-owned
|
|
219
|
+
`metadata.attention` marker and NOTHING else — no status write, no `errorMessage`: the run is
|
|
220
|
+
already parked on the proposal-ready signal, and a late reviewer is not a failed run.
|
|
221
|
+
- **Closing is not advancing.** `closeAgentDispositionTask` (A7) marks the row COMPLETED with a
|
|
222
|
+
conditional UPDATE when the proposal is disposed. It MUST NOT go through `completeUserTask` — that
|
|
223
|
+
advances the run, and the run resumes on `agent_orchestrator.proposal.ready`.
|
|
224
|
+
- **`workflows.task.detail:context`** (`lib/work-inbox/navigation.ts`) is the task-detail injection
|
|
225
|
+
spot — FROZEN once mounted. It exists because this page can only walk a `formSchema` generically;
|
|
226
|
+
the module that owns a proposal renders it in its own vocabulary (the §7.6 draft card).
|
|
227
|
+
|
|
228
|
+
## Node Outcome Rows (the canvas footer — fidelity gap #4)
|
|
229
|
+
|
|
230
|
+
- **`lib/node-outcome-rows.ts` (PURE) decides what the rows ARE**; `components/nodes/NodeOutcomeRows.tsx`
|
|
231
|
+
only renders them. That split is what makes the progressive-disclosure rule testable without a
|
|
232
|
+
canvas.
|
|
233
|
+
- **An agent node shows its WIRED outcomes plus `approved`, nothing else** (§7.2's fan-explosion
|
|
234
|
+
defense — five agent nodes in a 60-node flow must stay readable), and states the inheritance
|
|
235
|
+
("unhandled → error directive") on the node face.
|
|
236
|
+
- **The user-task half needed NO engine work.** `taskDecisionSchema` already binds each decision to a
|
|
237
|
+
durable `transitionId`, so a decision row's dot IS the route its button takes; the canvas and the
|
|
238
|
+
run agree by construction.
|
|
239
|
+
- **The dot IS the connection handle** — wiring a disposition is drawing a line from the row that
|
|
240
|
+
names it.
|
|
241
|
+
- **The step's DEFAULT route is the footer's last row**, `buildDefaultRouteRow()`. Its handle id is
|
|
242
|
+
still `DEFAULT_SOURCE_HANDLE_ID` (`'source'`, `lib/route-kinds.ts`) — the move is presentation, so
|
|
243
|
+
every stored transition keeps resolving to it. It renders as a row only when a footer renders at
|
|
244
|
+
all; without one the node keeps its own `<Handle>` unchanged. It is named `default`, NOT
|
|
245
|
+
`otherwise`: `resolveAgentOutcomeHandling` returns `{ kind: 'default' }` for a step that wired no
|
|
246
|
+
outcome and for an unwired `approved`, while every OTHER unwired outcome inherits the error
|
|
247
|
+
directive — a row promising "everything else comes here" would be wrong.
|
|
248
|
+
- **Every handle on the canvas is sized from `NODE_HANDLE_CLASS`** (`lib/node-geometry.ts`), footer
|
|
249
|
+
dots included, and every route chip from `ROUTE_CHIP_CLASS` / `ROUTE_CHIP_ICON_CLASS` in the same
|
|
250
|
+
file. MUST NOT spell `!w-3 !h-3` in a node component or a `size-*`/padding class in
|
|
251
|
+
`WorkflowRouteChips`; `nodeHandleGeometry.test.ts` and `routeChips.test.tsx` fail if you do. A chip
|
|
252
|
+
is READ, not aimed at, so it is deliberately larger than a handle. `countOutcomeRows` adds one for the default row, or dagre under-reserves the card.
|
|
253
|
+
- **The LABEL carries the meaning, never the dot colour** (§4.6 acceptance criterion). Two rows paint
|
|
254
|
+
the same red (`rejected`, `guardrailBlocked`), which at 10px and at canvas zoom is not a
|
|
255
|
+
distinction anyone can read, so every row also carries its own GLYPH and every handle is named.
|
|
256
|
+
MUST NOT drop the labels for a denser rendering, and MUST NOT let the collapsed dot-only zoom
|
|
257
|
+
inherit this pattern.
|
|
258
|
+
- Rows are derived from the committed EDGES at render time in `WorkflowGraphImpl` (like the
|
|
259
|
+
compensation badges), so they never enter the document, undo, autosave or `graphToDefinition`.
|
|
260
|
+
`estimateNodeSize` counts them (`NODE_OUTCOME_ROW_HEIGHT`) — a footer makes a card materially
|
|
261
|
+
taller and dagre would otherwise pack ranks into each other.
|
|
262
|
+
|
|
263
|
+
## Node Config Summaries (fidelity gap #6)
|
|
264
|
+
|
|
265
|
+
- **`lib/node-config-summary.ts` (PURE) owns the card's body line.** A step states its
|
|
266
|
+
CONFIGURATION — `customers.deals.update · retries 3×`, `deal_enricher · auto ≥ 0.8`,
|
|
267
|
+
`role: Sales Rep · bound: 1 · 2 decisions` — not two clamped lines of the author's prose, which
|
|
268
|
+
truncate mid-word and cannot say which command runs or what the threshold is.
|
|
269
|
+
- **Nothing new is stored.** Every value is derived from config already on the step, and
|
|
270
|
+
`description` is not lost: it becomes the card's `title=` tooltip. A step with nothing configured
|
|
271
|
+
produces an EMPTY summary and the card renders its description exactly as before, so no node ever
|
|
272
|
+
reads emptier than it did.
|
|
273
|
+
- Command / function / event / agent / signal / sub-workflow ids render `font-mono`; the mockup's
|
|
274
|
+
10.4px mono has no DS equivalent and is NOT reproduced — `text-xs` is the floor.
|
|
275
|
+
|
|
276
|
+
## Canvas Trigger Cap (fidelity gap #5, Direction A)
|
|
277
|
+
|
|
278
|
+
- **`lib/trigger-node.ts` (PURE) derives the model; `components/nodes/TriggerCap.tsx` renders it,
|
|
279
|
+
FOLDED onto the START node.** `WorkflowGraphImpl` injects `buildTriggerNodeModel(...)` into the
|
|
280
|
+
OWNED start node's render-time `data` (`data.trigger` + `data.onOpenTriggers`); `StartNode` floats
|
|
281
|
+
the cap ABSOLUTELY above its pill (`bottom-full`), so the cap adds no height to the terminal and
|
|
282
|
+
never enters the node's measured box. This replaces the earlier separate overlay node
|
|
283
|
+
(`components/nodes/TriggerNode.tsx`, now `@deprecated`) joined by a dashed connector.
|
|
284
|
+
- **Why the fold, not an overlay node.** The overlay node was minted fresh every render and, being
|
|
285
|
+
OUTSIDE the node state, was re-measured by ReactFlow on every render in an unbounded loop that
|
|
286
|
+
pinned the CPU and starved node dragging (the canvas "teleport" bug). Injecting into the OWNED
|
|
287
|
+
start node is loop-safe: its measurement is persisted to state like any real node. As defense in
|
|
288
|
+
depth, `handleNodesChange` also drops changes for nodes the editor does not own
|
|
289
|
+
(`lib/owned-node-changes.ts`).
|
|
290
|
+
- **Still display-only.** The model lives only in render-time `data`, never in the definition, so it
|
|
291
|
+
is absent from the document, undo, drag autosave, the per-user draft and the subgraph clipboard by
|
|
292
|
+
construction — `graphToDefinition` reads steps/edges, not `data.trigger`. Read-only viewers pass no
|
|
293
|
+
`triggers`, so they render no cap.
|
|
294
|
+
- **NO engine change.** The triggers are already on the definition; nothing here is read by the
|
|
295
|
+
executor.
|
|
296
|
+
- **ONE cap summarises every trigger.** Triggers are a definition-level property and every one starts
|
|
297
|
+
the SAME START step. The cap shows a count (`workflows.triggerNode.capCount`) plus the manual/API
|
|
298
|
+
line; the full list lives in the Triggers modal it opens. Model still capped at
|
|
299
|
+
`TRIGGER_NODE_EVENT_LIMIT` (= `ROUTE_CHIP_LIMIT`), enabled first.
|
|
300
|
+
- **What it says must be TRUE.** `POST /api/workflows/instances` → `startWorkflow` needs no trigger,
|
|
301
|
+
so the manual/API line is unconditional and a definition with ZERO event triggers still renders the
|
|
302
|
+
cap. `startWorkflow` throws `DEFINITION_DISABLED` before it looks at a trigger, so a disabled
|
|
303
|
+
definition's cap states ONLY that (amber `PowerOff` + label). MUST NOT draw an event trigger as the
|
|
304
|
+
only way in.
|
|
305
|
+
- **Accessibility (spec §4.6).** The cap IS a `<button>` (`data-testid="workflow-trigger-cap"`) with
|
|
306
|
+
a named `aria-label`; every state pairs its token colour with a glyph and a label — never colour
|
|
307
|
+
alone. Clicking it calls `onOpenTriggers` (the Triggers modal); `stopPropagation` keeps the click
|
|
308
|
+
off the step inspector.
|
|
309
|
+
- **The modal it opens is the ONLY trigger-authoring surface, so it may not lose capability.**
|
|
310
|
+
`TriggersDialog` hosts the inline `components/TriggersEditor.tsx` (a row per trigger, click-to-expand,
|
|
311
|
+
no nested drawer) and `DefinitionTriggersEditor` — the drawer editor that used to own this — has no
|
|
312
|
+
live call site left. "Lighter" there is about CHROME: the event field MUST stay the declared-event
|
|
313
|
+
picker (`EventPatternInput`, #544), because it is now the only place an author can discover which
|
|
314
|
+
events a module declares, and the roadmap for this area is a RICHER picker (payload-schema-driven
|
|
315
|
+
filter/mapping fields), not a text box. It takes no `id`, so its `<Label>` names a wrapping
|
|
316
|
+
`role="group"` via `aria-labelledby` — the same pattern `components/fields/ActivityConfigFields.tsx`
|
|
317
|
+
uses for its id-less pickers — and it COMMITS on selection / Enter / blur rather than per keystroke,
|
|
318
|
+
which every driver of that field (`components/__tests__/triggersEditor.test.tsx`, TC-WF-001,
|
|
319
|
+
TC-WF-008) has to honour.
|
|
320
|
+
- The old overlay-node geometry (`TRIGGER_NODE_*` in `lib/node-geometry.ts`) and helpers
|
|
321
|
+
(`buildTriggerNode`, `buildTriggerEdge`, `TRIGGER_EDGE_DASH_ARRAY`, `WORKFLOW_TRIGGER_NODE_TYPE`)
|
|
322
|
+
remain exported for the deprecated component and its test; they are no longer used by the editor.
|
|
323
|
+
|
|
324
|
+
## User Task Forms (`formSchema`)
|
|
325
|
+
|
|
326
|
+
- **`lib/task-form-schema.ts` is the ONE mapper** behind both form validation and rendering, and
|
|
327
|
+
its type mapping is the exact inverse of the editor's. Before it existed, `validateFormData`
|
|
328
|
+
walked the JSON-Schema shape while `TaskFormFields` walked `formSchema.properties`, so a
|
|
329
|
+
Studio-authored form (`{fields:[…]}`) rendered NOTHING at all — adding required-field validation
|
|
330
|
+
on its own would have made every Studio-authored task uncompletable.
|
|
331
|
+
- **`fields[].label` is OPTIONAL** (widened 2026-07-30). Every consumer already treated it that
|
|
332
|
+
way — the mapper resolves `title: field.label ?? field.name` and the editor list renders
|
|
333
|
+
`field.label || field.name` — while `userTaskConfigSchema` required it, which made the contract
|
|
334
|
+
stricter than the code reading it. That rejected definitions the engine would have run: the AI
|
|
335
|
+
draft schema (`lib/ai-authoring.ts`) and the `create_definition` MCP tool both emit an optional
|
|
336
|
+
label, and the shared integration fixture never sent one, so five specs could never parse.
|
|
337
|
+
An EMPTY label is still rejected — `min(1).optional()`, not `optional()` alone — because a blank
|
|
338
|
+
string defeats the fallback instead of triggering it. A missing label is an authoring-quality
|
|
339
|
+
issue and belongs in the Problems panel, not in a 400.
|
|
340
|
+
- Widening a request schema needs no deprecation window: payloads rejected before are accepted
|
|
341
|
+
now, and nothing previously accepted changes. MUST NOT be re-tightened without one.
|
|
342
|
+
|
|
343
|
+
## Route Kinds (the handle ↔ `kind` round trip)
|
|
344
|
+
|
|
345
|
+
- **`lib/route-kinds.ts` (PURE) is the ONE place a non-normal route kind is registered.** It answers
|
|
346
|
+
both halves of the round trip — which `kind` a connection drawn from a canvas handle compiles to,
|
|
347
|
+
and which source handle a stored transition of that kind re-attaches to — and `graph-utils`
|
|
348
|
+
(`graphToDefinition` + `definitionToGraph`), `lib/edge-reattachment.ts` and the Studio's
|
|
349
|
+
`handleConnect` all read it. MUST NOT add a fourth inline `kind === '…'` special case.
|
|
350
|
+
- Registering a kind here is what makes it SURVIVE a Studio save. Before it existed only `'error'`
|
|
351
|
+
was special-cased, so opening a definition carrying a `kind: 'slaBreach'` route and saving it
|
|
352
|
+
silently downgraded the route to a normal transition and the breach stopped routing.
|
|
353
|
+
- **`kind: 'normal'` and an absent `kind` are the same thing** and both serialize as absent, which is
|
|
354
|
+
what keeps a definition declaring no kinds byte-identical through a save (guarded by
|
|
355
|
+
`lib/__tests__/route-kinds.test.ts`).
|
|
356
|
+
- A kinded route NEVER inherits its source AUTOMATED step's activity — it is not the happy path out
|
|
357
|
+
of that step.
|
|
358
|
+
- **Every route edge is BUILT by `buildWorkflowRouteEdge` (`lib/route-edge.ts`)** — the load path
|
|
359
|
+
(`definitionToGraph`), `handleConnect` and the insert-on-route splice alike. That is render-time
|
|
360
|
+
only (`graphToDefinition` never reads `type`), but it is not cosmetic: creation used to type a
|
|
361
|
+
normal route `smoothstep` while load typed it `workflowTransition`, so a route came out with 90°
|
|
362
|
+
corners until it was saved and reloaded, and `defaultEdgeOptions` cannot correct it (ReactFlow
|
|
363
|
+
merges it UNDER each edge). MUST NOT name a React Flow built-in edge type for a route;
|
|
364
|
+
`lib/__tests__/route-edge.test.ts` scans the module sources for it.
|
|
365
|
+
- `ROUTE_KIND_SOURCE_NODE_TYPES` (`lib/edge-reattachment.ts`) refuses moving a kinded route onto a
|
|
366
|
+
node type that can never reach it (an error route off a step that cannot fail, a breach route off a
|
|
367
|
+
step that carries no deadline) rather than leaving a dead route behind.
|
|
368
|
+
|
|
369
|
+
## Route Identity & Edit Safety
|
|
370
|
+
|
|
371
|
+
- **Transition ids are opaque and durable.** `generateTransitionId()` mints `t_<unique>`; it no longer
|
|
372
|
+
derives ids from endpoints. Legacy `e_<from>_<to>` ids stay valid forever — stored definitions,
|
|
373
|
+
`examples/`, and templates keep their ids through load/save, and the engine treats every transition
|
|
374
|
+
id as an opaque string (`pendingTransition`, `WorkflowBranchInstance.branchKey`). MUST NOT rewrite
|
|
375
|
+
stored ids outside Customize.
|
|
376
|
+
- **Structural edits need a new version.** A `WorkflowInstance` pins `definitionId` and the engine
|
|
377
|
+
re-reads that row on every advance, so `PUT /api/definitions/[id]` refuses a topology change while
|
|
378
|
+
instances are executing. `lib/definition-edit-safety.ts` (PURE) owns the decision: topology =
|
|
379
|
+
step ids + step types + fork/join wiring + transition ids/endpoints/`kind`. Labels, positions,
|
|
380
|
+
activity config, conditions, priorities, triggers and metadata are NOT structural and always save
|
|
381
|
+
in place. Active statuses: `RUNNING`, `PAUSED`, `WAITING_FOR_ACTIVITIES`, `FORKED`, `COMPENSATING`.
|
|
382
|
+
The refusal is a structured 409 (`code: WORKFLOW_STRUCTURAL_EDIT_REQUIRES_NEW_VERSION`) naming the
|
|
383
|
+
publish endpoint as the remedy; the Studio surfaces it as a banner whose "Create version" mints the
|
|
384
|
+
next version and re-applies the rejected edit there.
|
|
385
|
+
- The guard fires on the definition PUT only. The per-user draft route
|
|
386
|
+
(`api/definitions/[id]/draft`) is never blocked — work-in-progress must stay saveable.
|
|
387
|
+
- **Reattachment rides on those durable ids.** Dragging a route endpoint onto another node
|
|
388
|
+
(`onReconnect` → `lib/edge-reattachment.ts`, PURE) re-targets the transition and keeps its
|
|
389
|
+
`transitionId`, label, condition, activities, priority and `kind`. Refusals return a code the
|
|
390
|
+
Studio translates and the edge list is left untouched, which is what snaps the endpoint back:
|
|
391
|
+
self-loop, duplicate route, data-mapping link, an error route moved off a step that can raise one,
|
|
392
|
+
or any graph / fork-join violation the graph does not already have. Reattaching a fork branch
|
|
393
|
+
changes which steps that branch visits, and `WorkflowBranchInstance.branchKey` is the transition
|
|
394
|
+
id — keeping the id is what makes the canvas edit safe, and the edit-safety guard still refuses
|
|
395
|
+
the SAVE while instances are active, so mid-flight runs never see the new wiring.
|
|
396
|
+
|
|
397
|
+
## Step Type Conversion
|
|
398
|
+
|
|
399
|
+
- `lib/step-type-conversion.ts` (PURE) owns "Change type…" (spec §4.5). It speaks the EDITOR's node
|
|
400
|
+
types, not the `stepType` enum, because `invokeAgent` compiles to an AUTOMATED step and converting
|
|
401
|
+
between the two is a real conversion the enum cannot express.
|
|
402
|
+
- **Always preserved:** the step id, its position and all of its wiring (the conversion never touches
|
|
403
|
+
nodes or edges other than the one being converted), plus `label`/`stepName`, `description`,
|
|
404
|
+
`timeout`, `retryPolicy` and `errorDirective`.
|
|
405
|
+
- **Mapped where the types genuinely share semantics:** the activity list between `automated` and
|
|
406
|
+
`invokeAgent`; `signalConfig` between `invokeAgent` and `waitForSignal`; and the "give up after"
|
|
407
|
+
deadline between `waitForSignal` (`signalConfig.timeout`) and `waitForCondition` (`config.timeout`).
|
|
408
|
+
WAIT_FOR_TIMER's `duration` is deliberately NOT a deadline — it is how long to wait on purpose.
|
|
409
|
+
- **Everything else is quarantined, never dropped:** it lands in `node.data.unmappedConfig`, is
|
|
410
|
+
persisted as `step.metadata.unmappedConfig` (an editor-owned bag the engine never reads), renders as
|
|
411
|
+
a collapsed read-only drawer in `NodeEditDialogCrudForm`, and raises the `unmappedStepConfig`
|
|
412
|
+
Problems WARNING. Converting back recovers it, which is precisely why nothing may be discarded.
|
|
413
|
+
- **START and END are not convertible** (in either direction): `validateWorkflowGraph` requires
|
|
414
|
+
exactly one START and at least one END, so converting either breaks an invariant that is invisible
|
|
415
|
+
from the inspector.
|
|
416
|
+
|
|
417
|
+
## Canvas Arrangement
|
|
418
|
+
|
|
419
|
+
- **Manual placement always wins until explicit Tidy.** `graphToDefinition(..., { includePositions: true })`
|
|
420
|
+
writes each node's `_editorPosition`; `definitionToGraph` prefers a stored position and dagre-places
|
|
421
|
+
(LR) only the steps that lack one. `applyAutoLayout` (the Tidy button) is the ONE place that
|
|
422
|
+
overwrites an author's arrangement. Every persistence path — explicit Save, the quiet definition
|
|
423
|
+
autosave, and the per-user draft — uses the same `includePositions` payload builders, so a drag
|
|
424
|
+
survives a save, a draft restore, and a reload identically.
|
|
425
|
+
- **A drag persists once, on drag end.** `WorkflowGraphImpl` classifies each React Flow change batch
|
|
426
|
+
(`WorkflowGraphNodesChangeMeta`) and hands the page `persistable: false` for in-flight drag frames,
|
|
427
|
+
selections and measurements. The quiet autosave additionally skips a PUT whose body is byte-equal to
|
|
428
|
+
the last one it wrote, so no interaction bumps the optimistic-lock token for nothing.
|
|
429
|
+
- **New nodes land deliberately.** `lib/node-placement.ts` (PURE) resolves the position: the cursor
|
|
430
|
+
when a drop position is supplied (drag-from-palette), otherwise after the right-most card, nudged
|
|
431
|
+
down until it clears every existing card.
|
|
432
|
+
- **Scoped re-tidy is deliberately NOT implemented.** Spec §4.1 allows "re-tidy only the affected
|
|
433
|
+
region" on a structural mutation; re-running dagre over an inserted node's neighbourhood cannot be
|
|
434
|
+
bounded without moving nodes outside the region (dagre re-ranks the whole component it is given).
|
|
435
|
+
Until insert-on-edge exists there is no call site either. Placement + collision avoidance covers the
|
|
436
|
+
real need; full Tidy stays explicit.
|
|
437
|
+
|
|
438
|
+
## Undo / Redo
|
|
439
|
+
|
|
440
|
+
- **One stack over the whole editor document.** `lib/editor-history.ts` (PURE) versions
|
|
441
|
+
`{ nodes, edges, metadata }` as SNAPSHOTS — at this scale a snapshot cannot drift out of sync the
|
|
442
|
+
way an inverse-command log can, and the node/edge arrays are already replaced rather than mutated,
|
|
443
|
+
so an entry costs a few references. Cmd/Ctrl+Z undoes, Cmd/Ctrl+Shift+Z redoes, the stack caps at
|
|
444
|
+
`EDITOR_HISTORY_LIMIT = 100`, and a new edit after an undo invalidates the redo branch.
|
|
445
|
+
- **Entries store the document as it was BEFORE the edit, plus a translated label** ("Delete step",
|
|
446
|
+
"Paste"). The label is what the shortcut announces, and a later phase names AI checkpoints in the
|
|
447
|
+
same stack. Because the snapshot is captured up front and committed separately, an asynchronous
|
|
448
|
+
handler (anything behind a confirm dialog) commits only once the edit actually lands — a cancelled
|
|
449
|
+
confirmation leaves no entry.
|
|
450
|
+
- **Every mutating page path commits**: inspector saves, deletes, connects, reattachment, conversion,
|
|
451
|
+
drag end (one entry per drag, from the arrangement the drag started at — not per frame), sample
|
|
452
|
+
pin/unpin, Tidy, paste, duplicate and palette drops. The stack lives in the page, so it survives
|
|
453
|
+
dialog open/close and panel switches.
|
|
454
|
+
- **The definition-panel text fields are deliberately NOT versioned.** They have native input undo,
|
|
455
|
+
and committing per keystroke would evict real structural edits from a 100-entry stack. The
|
|
456
|
+
consequence is that a whole-document replacement — draft restore, template load, Clear canvas —
|
|
457
|
+
RESETS the stack rather than pushing an entry, because undoing into it would restore the graph
|
|
458
|
+
without the panel fields it was saved with.
|
|
459
|
+
- The shortcut is suppressed while a field has focus (the page's existing `isEditing` guard) and
|
|
460
|
+
while a dialog is open, so it never hijacks form input.
|
|
461
|
+
|
|
462
|
+
## Subgraph Clipboard (copy · paste · duplicate)
|
|
463
|
+
|
|
464
|
+
- `lib/subgraph-clipboard.ts` (PURE) owns the portable format. The payload speaks the DEFINITION
|
|
465
|
+
vocabulary, not React Flow's:
|
|
466
|
+
|
|
467
|
+
```json
|
|
468
|
+
{
|
|
469
|
+
"kind": "open-mercato.workflow-subgraph",
|
|
470
|
+
"version": 1,
|
|
471
|
+
"steps": [ /* definition steps, positions as _editorPosition */ ],
|
|
472
|
+
"transitions": [ /* definition transitions, internal to the selection only */ ]
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
The Code view renders the definition JSON, so a fragment copied from the canvas MUST be the shape a
|
|
477
|
+
fragment copied out of the Code view is — that is the whole reason the format is not nodes/edges.
|
|
478
|
+
Readers refuse an unknown `kind` or `version` rather than guessing.
|
|
479
|
+
- **Only transitions internal to the selection travel.** A route with one endpoint outside the
|
|
480
|
+
selection describes a step the payload does not carry, so pasting it could only invent a dangling
|
|
481
|
+
id. Data-mapping links never travel either — their binding lives in the target step's config.
|
|
482
|
+
- **Paste always re-IDs** (`generateStepId` / `generateTransitionId()`) and rewires the internal
|
|
483
|
+
routes onto the new ids, so pasting into the workflow a fragment came from can never collide with
|
|
484
|
+
or silently merge into the original. The new step id reuses the old id's meaningful prefix with the
|
|
485
|
+
generated `_<ms>_<rand>` suffix stripped, so ids stay recognisable without growing on every paste.
|
|
486
|
+
Copies land offset by `SUBGRAPH_PASTE_OFFSET` and arrive selected; the paste is ONE undo entry.
|
|
487
|
+
- **Clipboard access can be denied** (insecure context, no permission). Copy then falls back to an
|
|
488
|
+
in-page buffer and says so; paste reads that buffer. It is never a silent no-op — the reason is
|
|
489
|
+
always surfaced.
|
|
490
|
+
|
|
491
|
+
## Compensation Ghosts (read-only overlay)
|
|
492
|
+
|
|
493
|
+
- **Visualization only — never an engine change.** `lib/compensation-ghosts.ts` (PURE) derives the
|
|
494
|
+
spec §4.4 "dashed reverse, behind a toggle" overlay from the model the engine already executes
|
|
495
|
+
(`activity.compensation.activityId`, LIFO in `lib/compensation-handler.ts`). Nothing here changes
|
|
496
|
+
what runs; MUST NOT grow into editing compensation (that is an Ask-First state-machine change).
|
|
497
|
+
- **A route's activities run LEAVING its source step**, so the compensable step is the route's
|
|
498
|
+
SOURCE (it carries the §4.3 ⛨ badge) and the undo walks back along the route, which is exactly the
|
|
499
|
+
ghost edge that is minted (`target → source`). One ghost per route, however many of its activities
|
|
500
|
+
compensate.
|
|
501
|
+
- **Ghosts never enter the document.** `WorkflowGraphImpl` mints them at RENDER time from the
|
|
502
|
+
committed edges (like the validation-error node decoration), so they are absent from the edge
|
|
503
|
+
state, from undo, from autosave and from `graphToDefinition` — which filters them anyway, so the
|
|
504
|
+
guarantee is testable rather than merely true. They are non-interactive (not selectable,
|
|
505
|
+
reattachable or deletable) so no editing gesture can reach one.
|
|
506
|
+
- **The overlay is off by default** and persisted per author (`om:wf-editor-compensation`), reachable
|
|
507
|
+
from the toolbar and the Cmd+K palette. Its stroke uses the warning token with its OWN dash-dot
|
|
508
|
+
pattern (`10,4,2,4` — distinct from pending `5,5`, error `8,4` and data-mapping `2,3`) and always
|
|
509
|
+
carries an icon + label, per the never-colour-only rule.
|
|
510
|
+
- `graphToDefinition` now preserves `activity.compensation` through the editor round trip. It used to
|
|
511
|
+
drop the field, which meant opening a compensating workflow and saving it silently deleted the
|
|
512
|
+
compensation the engine relies on.
|
|
513
|
+
|
|
514
|
+
## The Form Editor Is Retired (bridge routes)
|
|
515
|
+
|
|
516
|
+
- **The Studio is the only workflow editor** (spec §10). `backend/definitions/create/page.tsx` and
|
|
517
|
+
`backend/definitions/[id]/page.tsx` are BRIDGE ROUTES: their bodies are an immediate
|
|
518
|
+
`router.replace` onto `/backend/definitions/visual-editor[?id=…]`, and their `page.meta.ts` guards
|
|
519
|
+
are untouched so RBAC still applies exactly as before. MUST NOT delete either file — the
|
|
520
|
+
deprecation protocol keeps them for ≥1 minor so bookmarks and third-party links keep working.
|
|
521
|
+
- **Retirement was gated on the Code view.** The spec allows retirement only once the Phase 3 Code
|
|
522
|
+
view exists, because until then there was no non-canvas way to read a definition. Do not reverse
|
|
523
|
+
that order if either surface is ever reworked.
|
|
524
|
+
- `components/formConfig.tsx` (every export), `components/StepsEditor.tsx`,
|
|
525
|
+
`components/TransitionsEditor.tsx` and `components/mobile/MobileDefinitionDetail.tsx` are
|
|
526
|
+
`@deprecated` and have NO call site left in this module. They stay exported for third-party forms
|
|
527
|
+
and are removed one minor after the UPGRADE_NOTES entry — keep `components/__tests__/formConfig.test.ts`
|
|
528
|
+
alive while they are exported.
|
|
529
|
+
- **The list page has one create entry and one edit row action.** "Create Workflow" opens the
|
|
530
|
+
template gallery (its *Blank* card is the empty canvas) and the `edit` row action points at the
|
|
531
|
+
Studio; the old `edit-visual` duplicate is gone. Build every editor href with
|
|
532
|
+
`buildVisualEditorHref` / `WORKFLOW_STUDIO_CREATE_HREF` (`lib/visual-editor-navigation.ts`) rather
|
|
533
|
+
than a literal path, so the next move is a one-line change.
|
|
534
|
+
|
|
535
|
+
## Run Views & Recovery (spec §8.3 · §8.4)
|
|
536
|
+
|
|
537
|
+
- **`lib/run-execution.ts` (PURE) is the single answer to "what did this run do".** The instance
|
|
538
|
+
detail page, the run Gantt and the Studio's "Show last run" overlay all derive from it, so they
|
|
539
|
+
cannot disagree about which steps ran or which routes were taken. Two inputs, deliberately ranked:
|
|
540
|
+
`StepInstance` rows are AUTHORITATIVE for step state (one row per execution, carrying the status,
|
|
541
|
+
both timestamps, the measured duration and the attempt count), and `WorkflowEvent` rows are the
|
|
542
|
+
fallback plus the ONLY source for the taken path — a transition leaves no row of its own. That
|
|
543
|
+
ranking is a bug fix: the detail page reads the newest 100 events, so on a long run an early
|
|
544
|
+
step's `STEP_ENTERED` has fallen off the page and an event-only derivation painted a completed
|
|
545
|
+
step as never-run. `currentStepId`/`instanceStatus` travel ON the `RunExecution` so
|
|
546
|
+
`resolveNodeRunStatus` can answer the START/END conventions without every caller remembering to
|
|
547
|
+
pass them.
|
|
548
|
+
- **`StepInstance` finally has a read surface.** `GET api/instances/[id]/steps` (feature
|
|
549
|
+
`workflows.instances.view`, page size capped at 100) serves the per-step input/output/error/
|
|
550
|
+
duration/attempts the §8.3 inspector and the Gantt need. Before it, `inputData`, `outputData`,
|
|
551
|
+
`executionTimeMs` and `retryCount` were written by the engine and read by nothing.
|
|
552
|
+
- **The run detail is Flow / Timeline / Context / Raw.** Selecting a node inspects it (spec §8.3)
|
|
553
|
+
instead of navigating away; sub-workflow navigation moved INTO the inspector, which lists every
|
|
554
|
+
child a step spawned. The failure banner stays ABOVE the tabs — it is the reason an operator
|
|
555
|
+
opened the run, not one altitude of it.
|
|
556
|
+
- **The Gantt axis is PIECEWISE-LINEAR** (`lib/run-gantt.ts`, PURE). A run that executes for 1s and
|
|
557
|
+
waits three days is 99.999% wait on a linear axis and shows nothing, so slices longer than a
|
|
558
|
+
derived threshold (4× the median slice, floored at 1s) render at the threshold's width and are
|
|
559
|
+
flagged. Time stays monotonic and every bar keeps its TRUE duration in `durationMs` — the
|
|
560
|
+
compression is a rendering decision and MUST NOT reach a label. Lanes follow the engine's
|
|
561
|
+
`branchInstanceId` so a parallel branch reads as one band.
|
|
562
|
+
- **Live run views** ride the DOM Event Bridge: the six `workflows.instance.*` lifecycle events
|
|
563
|
+
carry `clientBroadcast: true`, and `components/run/useLiveRunUpdates.ts` REFETCHES rather than
|
|
564
|
+
patching (the bridge is best-effort and caps a payload at 4KB), throttles the burst every step
|
|
565
|
+
advance produces, and refreshes on `om:bridge:reconnected`. The broadcast payload is instance
|
|
566
|
+
identity and state only — the bridge forwards it to every backoffice connection in the tenant +
|
|
567
|
+
organization WITHOUT evaluating ACL features, which is why the task events stay off it.
|
|
568
|
+
`workflows.instance.paused`/`resumed` are declared but have never had an emit site.
|
|
569
|
+
- **The failure queue is a UNION**, not a filter: attention-parked plus FAILED. The list route ANDs
|
|
570
|
+
its `attention` and `status` filters and cannot express it, hence
|
|
571
|
+
`GET api/instances/failure-queue`. Error grouping (`lib/failure-grouping.ts`, PURE) normalizes
|
|
572
|
+
each message to its SHAPE — ids, numbers, quoted values and timestamps replaced by placeholders —
|
|
573
|
+
and groups on that, keeping the first raw message as the label. Normalization is deliberately
|
|
574
|
+
CONSERVATIVE: over-normalizing merges two genuinely different failures, and an operator who sees a
|
|
575
|
+
merged group cannot tell that half of it will fail again on replay. Grouping runs in JS, so it is
|
|
576
|
+
not a SQL `GROUP BY` — the response reports `scannedCount` and `truncated` instead of implying the
|
|
577
|
+
groups cover everything.
|
|
578
|
+
- **Bulk replay goes through the progress module** (`lib/bulk-replay.ts` + a queue worker), per
|
|
579
|
+
`progress/AGENTS.md`. The worker re-reads every instance under the caller's tenant + organization,
|
|
580
|
+
so a foreign id resolves to nothing and is skipped rather than acted on, and one failing instance
|
|
581
|
+
never aborts the batch — which is the point of a triage surface.
|
|
582
|
+
- **Rerun-from-step does NOT change the step state machine.** The previous attempt's terminal
|
|
583
|
+
`StepInstance` is read for its recorded `stepType` and otherwise untouched; the replay's row is
|
|
584
|
+
created by the engine's own `enterStep`, which already does an unconditional
|
|
585
|
+
`em.create(StepInstance, { … status: 'ACTIVE' … })` on every entry. The cursor move plus
|
|
586
|
+
`executeStep` is the same shape `enterErrorHandlerStep` uses. Four refusals, each a 409 with a
|
|
587
|
+
code: a RUNNING instance (moving its cursor races the execution loop), a step the definition no
|
|
588
|
+
longer declares, a step whose latest attempt is still PENDING/ACTIVE (a queue job and, for an
|
|
589
|
+
agent step, a pending proposal are still addressed to THAT attempt — lifting this needs §7.4's
|
|
590
|
+
addressable resume token), and a step whose type changed since the run (a FAILED instance is not
|
|
591
|
+
"active", so the definition PUT guard permits an in-place structural edit).
|
|
592
|
+
- **Two new ACL features**, both admin/dev: `workflows.instances.rerun_step` (depends on
|
|
593
|
+
`instances.retry` + `instances.update_context` — replaying with EDITED context is exactly those
|
|
594
|
+
two powers together) and `workflows.instances.bulk_ops` (depends on `instances.retry` +
|
|
595
|
+
`instances.cancel`). Existing tenants pick them up only after
|
|
596
|
+
`yarn mercato auth sync-role-acls`.
|
|
597
|
+
- **The Studio overlay is render-time only.** "Show last run" decorates nodes and edges inside
|
|
598
|
+
`WorkflowGraphImpl`, the same rule the compensation ghosts follow, so it never enters the
|
|
599
|
+
document, the undo stack, an autosave or `graphToDefinition` — guarded by
|
|
600
|
+
`lib/__tests__/last-run-overlay.test.ts`. It fetches nothing until the toggle is on.
|
|
601
|
+
|
|
602
|
+
## Per-Definition KPI Rollup (spec §8.5)
|
|
603
|
+
|
|
604
|
+
- **`lib/metrics/definition-metrics.ts` (PURE) owns what the numbers MEAN**;
|
|
605
|
+
`lib/metrics/rollup-service.ts` owns the queries and the upsert. The shape MIRRORS
|
|
606
|
+
`agent_orchestrator`'s `AgentMetricRollup` (tenant/org + logical id + window bounds +
|
|
607
|
+
`computed_at` + a zod-validated `metrics` jsonb) and never imports it — `enterprise` is an
|
|
608
|
+
optional peer. Two deliberate divergences fix latent flaws in the mirror: `window_key` is its
|
|
609
|
+
own column and part of the key (otherwise a 7d and a 30d window can collide on `window_start`
|
|
610
|
+
and overwrite each other), and the key `(tenant, org, workflow_id, window_key, window_start)` is
|
|
611
|
+
DB-enforced UNIQUE (the mirror read-then-inserts with no constraint, so two passes both insert).
|
|
612
|
+
- **The rollup is RECOMPUTED, never incremented.** `writeRollupsForScope` snaps the bounds to
|
|
613
|
+
`WORKFLOW_ROLLUP_BUCKET_MS` (15 min), rebuilds each window from source rows and upserts. Two
|
|
614
|
+
passes in one bucket therefore produce byte-identical rows; a pass after the bucket rolls over
|
|
615
|
+
adds a row rather than mutating history. MUST NOT convert this to an incremental counter.
|
|
616
|
+
- **Only metrics the engine actually populates ship.** `StepInstance.executionTimeMs` is
|
|
617
|
+
deliberately NOT used: `exitStep` writes it on the COMPLETED path only, and every FAILED path
|
|
618
|
+
leaves it null, so a "step p95" would be a success-only latency wearing the wrong name. Run
|
|
619
|
+
duration is `startedAt` → the terminal timestamp instead. `successRate` counts the run's VERDICT
|
|
620
|
+
(`outcome`), never its status: `partial_failure` and `compensated` are their own numbers.
|
|
621
|
+
Mechanism: `apps/docs/docs/framework/workflows/run-outcomes.mdx`.
|
|
622
|
+
- **Every rate reports its denominator, and a zero denominator is `null`, never 0.** "No run
|
|
623
|
+
finished in this window" and "every run failed" are opposite facts.
|
|
624
|
+
- **Dry runs never count**: `isDryRun: false` is on every instance query and tasks are reached only
|
|
625
|
+
through those instances' ids. The same filter was missing from `api/instances/failure-queue` and
|
|
626
|
+
is now there.
|
|
627
|
+
- **A rollup ROW is per-organization, so the read route serves it only for a single-organization
|
|
628
|
+
scope**; a multi-org or tenant-wide scope live-computes over the resolved set, because counts sum
|
|
629
|
+
across organizations but a percentile does not. `GET api/metrics/definitions` (feature
|
|
630
|
+
`workflows.metrics.view`, batch capped at 50 ids) reports `source: 'rollup' | 'live'` per item and
|
|
631
|
+
re-validates every stored row against `workflowDefinitionMetricsSchema`.
|
|
632
|
+
- Scheduled PER ORGANIZATION from `setup.ts` (`@open-mercato/scheduler`, optional peer, best-effort)
|
|
633
|
+
onto the `workflow-definition-metric-rollup` queue. The queue name is a string LITERAL in the
|
|
634
|
+
worker — the generator's AST extractor cannot resolve an imported one — and a test asserts it
|
|
635
|
+
matches `WORKFLOW_DEFINITION_METRIC_ROLLUP_QUEUE`.
|
|
636
|
+
- Still §8.5 and deliberately NOT here: repeated-failure alerts, the process correlation view,
|
|
637
|
+
the triggers reverse lookup, a cross-org overview surface, retention/archival, and the
|
|
638
|
+
stuck / awaiting-disposition-too-long halves of the needs-attention queue (the failed +
|
|
639
|
+
attention-parked halves already ship as `api/instances/failure-queue`).
|
|
640
|
+
|
|
641
|
+
## Dry Run (spec §8.2)
|
|
642
|
+
|
|
643
|
+
- **A dry run is a REAL instance executed by the ordinary engine, not a second interpreter.**
|
|
644
|
+
`WorkflowInstance.isDryRun` (additive boolean column) is written once at start and never mutated.
|
|
645
|
+
A parallel simulator would drift from the engine and its report would stop being evidence about
|
|
646
|
+
the workflow that actually runs.
|
|
647
|
+
- **`isDryRun` is a COLUMN, not a metadata key**, because every isolation decision reads it and a
|
|
648
|
+
jsonb path predicate in a hot filter is both slower and easy to forget. `ExecutionContext.dryRun`
|
|
649
|
+
in `lib/workflow-executor.ts` is `@deprecated` and inert: it never was read, and a per-call flag
|
|
650
|
+
cannot survive an instance parking on a signal and resuming inside a worker — exactly when a leak
|
|
651
|
+
would happen.
|
|
652
|
+
- **One swap point buys the whole guarantee.** `executeActivityByType` in `lib/activity-executor.ts`
|
|
653
|
+
is the ONLY place `entry.execute` is reached, so a dry run swaps it for the registry `mock`
|
|
654
|
+
there — and every effector (command bus, event bus, mailer, webhook fetch, agent bridge) is
|
|
655
|
+
behind it. `mock: 'refuse'` or a missing mock throws `WorkflowDryRunRefusalError`.
|
|
656
|
+
- **A refusal is a STOP, never a failure.** Nothing was attempted, so it must not be absorbed by
|
|
657
|
+
`continueOnActivityFailure`, an error route or an `errorDirective` — `transition-handler` answers
|
|
658
|
+
`dryRunRefused` before any of those are consulted. It is also not retried.
|
|
659
|
+
- **A dry run never enqueues.** A queue job carries no `isDryRun` of its own, so a worker picking it
|
|
660
|
+
up would run the real effector. `executeActivities` forces the sync path — and MUST also report
|
|
661
|
+
`async: false` on the result, or the token parks in `WAITING_FOR_ACTIVITIES` waiting for a job
|
|
662
|
+
that was never enqueued.
|
|
663
|
+
- **USER_TASK suppression is structural.** `handleUserTaskStep` skips the row, so there is no
|
|
664
|
+
`workflows.task.assigned` event, therefore no notification row, no SLA reminder/breach jobs, and
|
|
665
|
+
nothing for any Work Inbox or task-list query to return. Everything above the row still resolves,
|
|
666
|
+
so the report names who the task WOULD have gone to. The step still WAITS.
|
|
667
|
+
- **`INVOKE_AGENT`'s mock names the agent and the disposition it would REQUEST** — never a
|
|
668
|
+
fabricated outcome. A simulation has no model confidence, so it fails closed to `human_review`,
|
|
669
|
+
the same rule `dispositionService` applies to a missing confidence. It carries `invoked: false`
|
|
670
|
+
and a `kind` outside the runtime vocabulary so nothing mistakes it for a real disposition. No
|
|
671
|
+
bridge call means no `AgentRun`, no proposal, and nothing reaching `dispositionService.dispose`.
|
|
672
|
+
- **Business-rule ACTIONS need their own flag.** The rule engine's `dryRun` only suppresses the
|
|
673
|
+
execution LOG — `successActions`/`failureActions` run regardless — so the transition handler
|
|
674
|
+
passes `skipActions` (additive, `packages/core/src/modules/business_rules`). Conditions still
|
|
675
|
+
evaluate, so the run takes the routes it really would.
|
|
676
|
+
- **The "Would do" report is DERIVED from `WorkflowEvent` rows**, never stored twice, so it inherits
|
|
677
|
+
the run views' scoping, ordering and retention. `lib/dry-run.ts` is PURE and owns both the event
|
|
678
|
+
vocabulary (`DRY_RUN_EVENT_TYPES`) and `buildWouldDoReport`; `GET /api/workflows/instances/[id]/would-do`
|
|
679
|
+
serves it and resolves each entry back to its definition `stepId`.
|
|
680
|
+
- **Dry runs are excluded from the instance list by default** (`?dryRun=true` opts in), and the
|
|
681
|
+
agent KPI rollup floors proposal counts to the same runtime runs it already floors run counts to.
|
|
682
|
+
- Starting one needs `workflows.definitions.test_run` ON TOP of `workflows.instances.create` — it is
|
|
683
|
+
the definition author's test loop, not a way to start instances.
|
|
684
|
+
|
|
685
|
+
## Step-Through & Start Fixtures (spec §8.1 · §8.2)
|
|
686
|
+
|
|
687
|
+
- **Step-through is an instance-level `PAUSED` between steps** (`lib/step-through.ts`, PURE) — the
|
|
688
|
+
same shape the `failureQueue` directive uses. NO new instance status and NO new step status, so
|
|
689
|
+
the state machines are untouched. Independent of dry run: a real run can be stepped through, and a
|
|
690
|
+
dry run can be let loose end to end.
|
|
691
|
+
- **The marker is a RELEASE TOKEN, not a paused boolean.** The author releases ONE named step, the
|
|
692
|
+
engine burns the token before running it, and the cursor landing anywhere else pauses again. That
|
|
693
|
+
is what makes it idempotent: replaying `executeWorkflow` after a crash cannot run a step nobody
|
|
694
|
+
released, and a double Continue cannot run two steps.
|
|
695
|
+
- **`POST api/instances/[id]/step-through`** (`continue` | `stop`, feature
|
|
696
|
+
`workflows.definitions.test_run`) mints the token from the instance's OWN `currentStepId` — never
|
|
697
|
+
from the request body — so a client cannot release a step the run is not sitting on. Aborting is
|
|
698
|
+
the existing cancel endpoint; a second way to cancel would be a second place to get compensation
|
|
699
|
+
wrong. The marker is engine-owned: only the feature-gated start flag and this route write it.
|
|
700
|
+
- **END is exempt from the pause**, so a finished step-through reads COMPLETED rather than parked one
|
|
701
|
+
click short of the end.
|
|
702
|
+
- **Start fixtures are named START contexts** (`lib/start-fixtures.ts`, PURE,
|
|
703
|
+
`metadata.editor.fixtures`) and are a DIFFERENT thing from pinned per-step samples — the spec says
|
|
704
|
+
so, and conflating them would make "which wins" unanswerable. Caps are checked against the RESULT,
|
|
705
|
+
so shrinking your way back under a cap always works. Fixture data is stored verbatim and is neither
|
|
706
|
+
redacted nor encrypted; keep the warning copy wherever one is saved.
|
|
707
|
+
|
|
708
|
+
## Code View (stage 2 — two-way sync)
|
|
709
|
+
|
|
710
|
+
- **The safety model, and why it is asymmetric.** Spec §2.2 asks for "two-way live sync"; taken
|
|
711
|
+
literally — mutate the canvas on every keystroke — it is unimplementable safely, because deleting
|
|
712
|
+
the `s` of `"steps"` momentarily produces a document with no steps and applying it would delete
|
|
713
|
+
every node, lose the arrangement and push one undo entry per character. So each direction gets what
|
|
714
|
+
it can actually support: **canvas → code is LIVE** (the panel re-renders from the canvas whenever
|
|
715
|
+
the author has not started editing); **code → canvas needs an explicit Apply** (button or
|
|
716
|
+
Cmd/Ctrl+Enter). Parsing, validation, the issue list and the gutter markers stay LIVE as you type,
|
|
717
|
+
so the feedback loop is immediate even though the commit is not.
|
|
718
|
+
- **`lib/code-view-apply.ts` (PURE) is the gate**, which is what makes the rule testable without a
|
|
719
|
+
canvas. Four escalating refusals, each with its own reason: `unchanged` · `parseError` (carrying
|
|
720
|
+
the line to mark) · `schemaError` · `graphError`. Graph WARNINGS never block, exactly as they never
|
|
721
|
+
block a Save; graph ERRORS do, because a canvas holding a graph the engine would reject is worse
|
|
722
|
+
than no apply — the author has lost the text they typed and now repairs a canvas by hand.
|
|
723
|
+
Validation runs `definitionToGraph(..., { autoLayout: false })`: whether a definition is valid
|
|
724
|
+
cannot depend on running a layout engine over it.
|
|
725
|
+
- **An apply is ONE fully reversible action.** `WorkflowEditorDocument` gained an optional `panel`
|
|
726
|
+
carrying the definition-panel fields the canvas does not hold (triggers, `contextSchema`, `io`,
|
|
727
|
+
`interpolation`, `errorHandler`), because the Code view's Apply replaces the WHOLE definition —
|
|
728
|
+
undoing it without them would restore the graph with somebody else's triggers attached. Entries
|
|
729
|
+
captured before the field existed carry none, and readers then leave the panel alone.
|
|
730
|
+
- **Markers are GUTTER markers, not underlines.** A plain textarea cannot decorate a substring, and
|
|
731
|
+
an overlaid highlight layer drifts out of alignment with the textarea's own text metrics. Each
|
|
732
|
+
marked line carries its severity glyph as well as its DS colour, per the §4.6 colour-only rule, and
|
|
733
|
+
every issue row states its line and focuses it.
|
|
734
|
+
- **`lib/definition-json-locations.ts` (PURE) answers WHERE a node lives** in the JSON text, with a
|
|
735
|
+
minimal tokenizer rather than a regex over `"id": "<value>"` — the author is editing free text, so
|
|
736
|
+
a step id also appears inside `{{context.*}}` templates, inside `fromStepId`, and inside note
|
|
737
|
+
markdown, and a regex would happily point the squiggle at any of them. Ids are attached from the
|
|
738
|
+
PARSED document by array index, so a malformed id cannot desynchronise the scan.
|
|
739
|
+
- **Closing the panel discards an unapplied draft.** Keeping it would let the author reopen the view
|
|
740
|
+
onto text that no longer describes the canvas, with no signal that the two had diverged.
|
|
741
|
+
- **The JSON is the save payload, not a re-serialization.** It is assembled through the same
|
|
742
|
+
`graphToDefinition` + `buildDefinitionPayload` pair `handleSave` uses, so what an author reads is
|
|
743
|
+
byte-for-byte what a Save would persist, and what they apply is the same shape. It is only computed
|
|
744
|
+
while the drawer is open.
|
|
745
|
+
- **Paste reuses the canvas clipboard format** (`lib/subgraph-clipboard.ts`) through the page's own
|
|
746
|
+
`handlePaste`, so a fragment copied from the canvas and a fragment copied out of the Code view are
|
|
747
|
+
the same payload, an unknown payload is refused with the same message, and the paste is ONE undo
|
|
748
|
+
entry. The Copy button copies the WHOLE definition JSON — the document, not a fragment.
|
|
749
|
+
- **The issue list is the Problems panel's list.** Both call the page's `evaluateWorkflowIssues`
|
|
750
|
+
(graph errors + `workflowDefinitionDataSchema` + activity-config and context-ref warnings through
|
|
751
|
+
`collectValidationIssues`), so the two surfaces can never disagree about what is wrong. Severity
|
|
752
|
+
pairs its DS token with an icon AND an `sr-only` name, per the §4.6 colour-only rule.
|
|
753
|
+
- The view is reachable from the toolbar and from the Cmd+K palette (`view.toggleCodeView`); while it
|
|
754
|
+
is open the canvas keyboard bindings are suppressed exactly as they are for a dialog.
|
|
755
|
+
|
|
756
|
+
## Editor Annotations (sticky notes · groups)
|
|
757
|
+
|
|
758
|
+
- **Annotations are documentation and NEVER execution semantics.** `lib/editor-annotations.ts`
|
|
759
|
+
(PURE) owns them; they live in `metadata.editor.annotations`
|
|
760
|
+
(`{ notes: [{id, markdown, position, size}], groups: [{id, name, rect, collapsed?}] }`) and nowhere
|
|
761
|
+
else. `graphToDefinition` filters their nodes out of `steps` AND drops any edge that touches one,
|
|
762
|
+
so a definition carrying a hundred notes serializes byte-identically to one carrying none — a test
|
|
763
|
+
asserts exactly that. `validateWorkflowGraph`, `applyAutoLayout` and the subgraph clipboard skip
|
|
764
|
+
them for the same reason: a note has no routes, no rank and no definition form.
|
|
765
|
+
- **They are still React Flow NODES while the editor is open.** That is what makes a note drag, undo,
|
|
766
|
+
select and autosave exactly like a step without a second code path. The node array is the single
|
|
767
|
+
source of truth; `annotationsFromNodes` derives the persisted shape on every save, draft and quiet
|
|
768
|
+
autosave, and `buildMetadataPayload` writes it back. Omitting its `annotations` argument leaves
|
|
769
|
+
whatever the loaded metadata carried untouched, which keeps non-canvas callers byte-compatible.
|
|
770
|
+
- **A group stores a RECT, not a member-id list.** A region needs no maintenance when a step it
|
|
771
|
+
overlaps is deleted, pasted or converted, and an id list would be a second source of truth the
|
|
772
|
+
engine must never read anyway.
|
|
773
|
+
- **Collapse is visual only** — the body fades and the region shrinks to its header; no step moves and
|
|
774
|
+
no route changes, because a graph-mutating collapse would be execution semantics.
|
|
775
|
+
- Notes and groups are resizable (`NodeResizer`), and a resize persists like a drag: `WorkflowGraphImpl`
|
|
776
|
+
reports `resizing: true` frames as `persistable: false` and only the resizer's final frame
|
|
777
|
+
(`resizing === false`) commits, so one gesture is one autosave and one undo entry. React Flow's own
|
|
778
|
+
measurement changes carry no `resizing` flag and stay non-persistable as before.
|
|
779
|
+
|
|
780
|
+
## Keyboard Path & Accessibility (acceptance criterion)
|
|
781
|
+
|
|
782
|
+
Spec §4.6 makes this an EXPLICIT acceptance criterion, not a polish item: *"Every canvas operation is
|
|
783
|
+
reachable without a pointer… ARIA labeling on nodes/routes/badges… Status is never color-only."*
|
|
784
|
+
Treat a regression here as a broken feature, not a nit.
|
|
785
|
+
|
|
786
|
+
- **The Cmd/Ctrl+K command palette is the complete non-pointer path.** `lib/editor-commands.ts`
|
|
787
|
+
(PURE) builds the descriptors — undo/redo, delete, copy/paste/duplicate, add any step type, add a
|
|
788
|
+
note or group, go to any step, Tidy, every panel toggle, Validate, Start instance, Save — and
|
|
789
|
+
`components/WorkflowCommandPalette.tsx` renders them through the platform's `CommandMenu`
|
|
790
|
+
primitive (`@open-mercato/ui/primitives/command-menu`, `cmdk` + Radix dialog) rather than a second
|
|
791
|
+
palette implementation. A command that cannot run right now is DISABLED with its shortcut shown,
|
|
792
|
+
never hidden: a missing entry reads as "unsupported", a disabled one as "not now". Because the
|
|
793
|
+
descriptors are pure data, dispatch is unit-tested without a dialog or a canvas.
|
|
794
|
+
- **Direct bindings** cover what an author does constantly: `Enter` opens the inspector for the
|
|
795
|
+
selection (step or route), `Del`/`Backspace` deletes it through the same confirm + cleanup flow the
|
|
796
|
+
trash button uses, the arrows nudge it (`Shift` for a coarse step). Nudging follows the drag rule
|
|
797
|
+
(#4248) — a BURST of keystrokes is one arrangement, so `lib/node-nudge.ts` (PURE) moves the nodes
|
|
798
|
+
and the page commits one undo entry plus one autosave once the burst settles.
|
|
799
|
+
- **Guards.** Every binding except Cmd+K is suppressed while a field has focus or a dialog is open, so
|
|
800
|
+
it never hijacks form input, native copy/paste, the caret keys or a dialog's Escape. Cmd+K is
|
|
801
|
+
deliberately EXEMPT from the typing guard — it is the way out of any focus, which is the point of a
|
|
802
|
+
palette. Every dialog keeps `Cmd/Ctrl+Enter` to submit and `Escape` to cancel.
|
|
803
|
+
- **Status is never colour-only.** Each node status pairs its DS token colour with its own icon shape
|
|
804
|
+
AND an `sr-only` name; the card carries `role="group"` with a `{type}: {title} — {status}` label and
|
|
805
|
+
a `data-node-status` hook. Error routes pair red + dashes + a warning icon, completed route labels
|
|
806
|
+
pair green + a check, route chips are labelled buttons and the collapsed semantic-zoom dot row is a
|
|
807
|
+
labelled `role="img"`. `components/__tests__/canvasAccessibility.test.tsx` is the guard.
|
|
808
|
+
- **The `sr-only` status name means a card's TEXT no longer identifies the step**, so a node's own
|
|
809
|
+
label carries `data-slot="workflow-node-title"` (`WORKFLOW_NODE_TITLE_SLOT`, set by
|
|
810
|
+
`WorkflowNodeCard` in both variants and by `StartNode`'s trigger-card branch, which renders its own
|
|
811
|
+
title). In the editor every status name is "Not started", and Playwright's `hasText` is a
|
|
812
|
+
case-insensitive SUBSTRING match, so a whole-card match for a step called "Start" resolved to EVERY
|
|
813
|
+
node on the canvas — plus the START card's cap says "manual / API start". Address the title element
|
|
814
|
+
(`workflowNodeByTitle` in `packages/core/src/helpers/integration/workflowsUi.ts`) rather than the
|
|
815
|
+
card, and MUST NOT drop the slot from a node component that renders its own title.
|
|
816
|
+
|
|
817
|
+
## Step & Route Inspector
|
|
818
|
+
|
|
819
|
+
- **`components/InspectorPanel.tsx` is the ONE shell** both inspectors render
|
|
820
|
+
through (`NodeEditDialogCrudForm`, `EdgeEditDialogCrudForm`). They used to be two
|
|
821
|
+
independent modals that had drifted apart in padding, heading shape and close
|
|
822
|
+
affordance. MUST NOT give either its own chrome again.
|
|
823
|
+
- **Both inspectors now mount `variant="overlay" wide`, at every viewport.** The
|
|
824
|
+
384px `docked` rail could not hold either form — the step's Invoke-Agent /
|
|
825
|
+
timeout / sub-editor sections, nor the route's condition, mapping and activity
|
|
826
|
+
lists — so each opens as the wide Drawer that mirrors the definition metadata
|
|
827
|
+
drawer, with its ledger in a sticky side column. `docked` (an `<aside
|
|
828
|
+
role="complementary">` rendered INSIDE `[data-testid="workflow-editor-row"]`)
|
|
829
|
+
is still a supported variant of the component and is unit-covered, but the
|
|
830
|
+
Studio no longer selects it. `inspectorsDocked` in the page survives as the
|
|
831
|
+
MOUNT-POINT decision (layout row vs. shared dialog stack) and as what the
|
|
832
|
+
editor's shortcut ownership keys off — it is no longer a variant switch.
|
|
833
|
+
- **Every variant carries `data-slot="workflow-inspector"` plus its
|
|
834
|
+
`data-variant`.** That marker is the only stable way a consumer addresses "the
|
|
835
|
+
inspector" without knowing which layout it got, and the integration helper
|
|
836
|
+
`workflowInspector` is built on it. On the `overlay` branch it MUST live on a
|
|
837
|
+
wrapper inside `DrawerContent`, never spread onto `DrawerContent` itself —
|
|
838
|
+
`DrawerContent` sets `data-slot="drawer-content"` before `{...props}`, so a
|
|
839
|
+
spread would clobber it.
|
|
840
|
+
- **Docking is SPATIAL, never a keyboard change.** An open inspector still owns the
|
|
841
|
+
shortcuts: it holds unsaved form values, and every canvas binding either mutates
|
|
842
|
+
the document under it (undo, delete, paste) or would save a graph that omits the
|
|
843
|
+
edit sitting in the rail. Escape from the canvas closes the rail; Escape raised
|
|
844
|
+
inside it is claimed by the panel itself (`stopPropagation`).
|
|
845
|
+
- **Exactly one rail at a time.** With a live canvas a step click can arrive while
|
|
846
|
+
the ROUTE inspector is open, so `handleNodeClick` / `handleEdgeClick` each close
|
|
847
|
+
the other. The modal variant could never reach that state.
|
|
848
|
+
- **The form is KEYED on the inspected record.** `CrudForm` deliberately preserves
|
|
849
|
+
fields the author already edited when `initialValues` changes — right for
|
|
850
|
+
late-arriving field definitions, wrong for re-targeting, where it would carry an
|
|
851
|
+
unsaved edit from step A onto step B and save it there. MUST keep `key={node.id}`
|
|
852
|
+
/ `key={edge.id}`.
|
|
853
|
+
- **The ledger panel's layout follows `wide`.** In the wide Drawer it sits in a
|
|
854
|
+
STICKY right column beside the form, expanded, so a row stays draggable onto
|
|
855
|
+
any parameter at any scroll position. Only the narrow (`docked`) layout stacks
|
|
856
|
+
it under the form and folds it by default (`InputDataPanel defaultCollapsed`) —
|
|
857
|
+
stacked in a 384px column an expanded ledger pushes the form off the top.
|
|
858
|
+
- **Both inspectors pass `density="compact"` to `CrudForm`** (the prop added for
|
|
859
|
+
this rail). `CrudForm`'s default lays groups out for a full-width page, which is
|
|
860
|
+
airy at 384px; compact steps the between-group and between-field spacing and the
|
|
861
|
+
group-card padding one DS step down and changes NOTHING else. MUST NOT reach for
|
|
862
|
+
descendant `[&_…]` overrides on a shared primitive from this module instead — if
|
|
863
|
+
a narrow host needs more, extend the prop where it lives.
|
|
864
|
+
|
|
865
|
+
## Definition Metadata Drawer
|
|
866
|
+
|
|
867
|
+
- **`components/DefinitionMetadataDrawer.tsx` is the ONE definition-metadata form.** The Studio and
|
|
868
|
+
the mobile editor both render it; `components/mobile/MobileMetadataSheet.tsx` is `@deprecated` with
|
|
869
|
+
no call site left. It was a second copy of the same form that never gained `contextSchema`, the
|
|
870
|
+
interpolation mode or the error handler, so mobile authors could not edit them at all — MUST NOT
|
|
871
|
+
reintroduce a per-viewport copy.
|
|
872
|
+
- **It is a Drawer because the canvas is what the page is for.** The form used to render inline above
|
|
873
|
+
the canvas in a `max-h-[45svh]` band (`60svh` compact), i.e. it was designed to eat up to half the
|
|
874
|
+
viewport on the one page whose purpose is the graph, and everything past the second row of fields
|
|
875
|
+
was reachable only by scrolling inside the band. The drawer takes 4/5 of the width (sanctioned) and
|
|
876
|
+
costs the canvas nothing.
|
|
877
|
+
- **Five sections, not tabs.** `Identity` (workflow id + version + name + description — the id and
|
|
878
|
+
version ARE the unique key the engine resolves an instance against, which is why both lock after
|
|
879
|
+
creation), `Presentation` (icon/category/tags), `Availability` (enabled + effective window),
|
|
880
|
+
`Inputs and triggers` (`contextSchema` + triggers), `Runtime behaviour` (interpolation +
|
|
881
|
+
`errorHandler`). Tabs would hide a blank required field behind a navigation step, split the Tab
|
|
882
|
+
order and break Ctrl+F, on a form filled top-to-bottom before the first save.
|
|
883
|
+
- **It starts CLOSED and is never auto-opened on load.** It is a modal overlay: opening it on mount
|
|
884
|
+
would leave the author unable to touch the canvas until they dismiss it. `handleSave` opens it when
|
|
885
|
+
the required id/name are blank, and the toolbar trigger carries a marker (icon + `sr-only` text,
|
|
886
|
+
never colour alone) meanwhile.
|
|
887
|
+
- **Canvas key bindings are suppressed behind it** (`isOverlayOpen` in the page's keydown handler).
|
|
888
|
+
Cmd+S is the deliberate exception — the drawer has no submit of its own to protect, saving the
|
|
889
|
+
workflow IS its primary action. Cmd/Ctrl+Enter saves, Escape closes.
|
|
890
|
+
- The round trip is guarded by `backend/definitions/visual-editor/__tests__/metadataDrawer.test.tsx`:
|
|
891
|
+
open → edit every field → save, asserting each edited value reaches the PUT body AND that every
|
|
892
|
+
pass-through key (`contextSchema`, `io`, `interpolation`, `errorHandler`, unknown metadata keys)
|
|
893
|
+
survives. Fields silently dropped on save are this module's recurring bug class.
|
|
894
|
+
|
|
895
|
+
## Definition Icon Picker
|
|
896
|
+
|
|
897
|
+
- `components/WorkflowIconPicker.tsx` replaces the free-text `metadata.icon` input with a searchable
|
|
898
|
+
grid over the platform's SHARED registry (`LUCIDE_ICON_REGISTRY` from
|
|
899
|
+
`@open-mercato/ui/backend/icons/lucideRegistry`). That registry is generated from the icon names
|
|
900
|
+
actually used across the repo and `AppShell` already loads it on every backend page, so the grid
|
|
901
|
+
adds NOTHING to the editor chunk — importing `lucide-react` wholesale for a field that stores one
|
|
902
|
+
string is the bundle regression this deliberately avoids (#3169).
|
|
903
|
+
- **Free text stays the fallback.** `metadata.icon` has always been an open string, so the picker
|
|
904
|
+
keeps an input: a name the registry does not know is stored verbatim with a warning, never dropped.
|
|
905
|
+
`normalizeIconName` (`lib/icon-search.ts`, PURE) maps every historic spelling — `ShoppingCart`,
|
|
906
|
+
`shopping_cart`, `lucide:shopping-cart` — onto the registry key, which is what makes an existing
|
|
907
|
+
definition open with its icon already selected. Selecting from the grid writes the kebab-case key.
|
|
908
|
+
|
|
909
|
+
## Palette Drops (drag-from-palette · insert-on-route)
|
|
910
|
+
|
|
911
|
+
- **Click stays the keyboard path.** Every palette entry is a `<button>` that appends on click; drag
|
|
912
|
+
is an ENHANCEMENT layered on top (`draggable` + `lib/palette-drag.ts`, which writes a readable
|
|
913
|
+
`text/plain` label plus the private `application/x-om-workflow-palette` payload, mirroring
|
|
914
|
+
`lib/ledger-drag.ts`). Never make an entry drag-only.
|
|
915
|
+
- **The graph resolves the target, the page performs the effect.** `WorkflowGraphImpl` owns the two
|
|
916
|
+
things only React Flow and the DOM can answer — the flow-space cursor position
|
|
917
|
+
(`screenToFlowPosition`) and which route the cursor is over (`document.elementsFromPoint` →
|
|
918
|
+
`.react-flow__edge[data-id]`, exact where geometry over a smooth-step curve would only approximate)
|
|
919
|
+
— and hands the page a plain `WorkflowGraphDropEvent`. The effects live in the PURE
|
|
920
|
+
`lib/palette-drop.ts`, so the xyflow boundary (#3169) is unaffected.
|
|
921
|
+
- **Three drop outcomes**: a step on empty canvas is placed at the cursor via `lib/node-placement.ts`;
|
|
922
|
+
a step on a route is spliced between that route's endpoints; an action on a route is appended to
|
|
923
|
+
that route's activities (the #4244 chips then render it). An action needs a route — dropping one on
|
|
924
|
+
empty canvas says so instead of doing nothing. Each drop is ONE undo entry.
|
|
925
|
+
- **Insert-on-route keeps the original route's data on the FIRST segment** (`from → new step`): a
|
|
926
|
+
condition guards LEAVING its source step and the activities run on the way out, so both belong to
|
|
927
|
+
the segment that still starts where the author put them, an error route stays the error path out of
|
|
928
|
+
that step, and the durable `transitionId` — which `instance.pendingTransition` and
|
|
929
|
+
`WorkflowBranchInstance.branchKey` resolve against — stays attached to it. The second segment
|
|
930
|
+
(`new step → to`) is a fresh unconditional auto route.
|
|
96
931
|
|
|
97
932
|
## Environment
|
|
98
933
|
|
|
99
934
|
| Variable | Effect | Default |
|
|
100
935
|
|----------|--------|---------|
|
|
101
936
|
| `OM_WORKFLOWS_ALLOW_PRIVATE_URLS` | When `1`/`true`/`yes`, bypasses the SSRF guard in `CALL_WEBHOOK` so workflow authors can hit `localhost`, RFC1918, and `.internal` targets. For dev only — MUST remain unset in production. | unset (guard enforced) |
|
|
937
|
+
| `OM_WORKFLOWS_MAX_CONDITION_ATTEMPTS` | Hard cap on WAIT_FOR_CONDITION poll re-enqueues; reaching it forces `CONDITION_TIMED_OUT` so a never-satisfiable predicate cannot saturate the queue. | `1000` |
|
|
102
938
|
| `OM_WORKFLOWS_ENV_INTERPOLATION_ALLOWLIST` | Comma-separated non-secret process env keys allowed for `{{env.*}}` interpolation in workflow activity config. `APP_URL` is always allowed. Never include secrets. | unset (`APP_URL` only) |
|
|
103
939
|
|
|
104
940
|
## DI Services
|
|
@@ -109,17 +945,22 @@ Definition → startWorkflow() → Instance → executeWorkflow() loop
|
|
|
109
945
|
| `stepHandler` | Enter/exit/execute individual steps (called by executor) |
|
|
110
946
|
| `transitionHandler` | Find valid transitions and execute them (called by executor) |
|
|
111
947
|
| `activityExecutor` | Execute or enqueue activities (called by transition handler) |
|
|
948
|
+
| `conditionHandler` | Evaluate and wake WAIT_FOR_CONDITION waiters (`evaluateWaitCondition` from the queue backstop, `wakeConditionWaiters` from a context write) |
|
|
112
949
|
| `eventLogger` | Log workflow events for audit trail |
|
|
113
950
|
|
|
114
951
|
## Adding a New Activity Type
|
|
115
952
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
953
|
+
Activity types are registry-driven: one `ActivityTypeEntry` carries dispatch, validation, form spec, async capability, and dry-run behavior. The definition-schema enum, editor pickers, and OpenAPI derive from the registry (`activityTypeIds()` / `listActivityTypes()`) — there is no enum or hardcoded UI list to edit.
|
|
954
|
+
|
|
955
|
+
1. Register one `ActivityTypeEntry` — built-ins live in `lib/activity-types.ts`; extensions call `registerActivityType` from `lib/activity-registry.ts`. Keep the registering module UI-safe: never import (not even dynamically — Turbopack chunks dynamic imports into the client bundle) a server-only executor from it; reach the executor through a runtime binding seam the server side sets up, as `lib/activity-types.ts` does with `bindActivityExecutor` (bound by `lib/activity-executor.ts` at load).
|
|
956
|
+
2. Add the config zod schema in `data/activity-config-schemas.ts` and pass it as `configSchema` — per-type config validation surfaces as editor/API **warnings** in Phase 1 (non-blocking; strict mode is a later opt-in).
|
|
957
|
+
3. Add the label key `workflows.activities.types.<ID>` to all four locales in `i18n/`.
|
|
958
|
+
4. Declare `form: ActivityFormFieldSpec[]` hints (components resolved from `components/fields/`); the JSON editor stays available as the collapsed "Advanced" escape hatch on every type.
|
|
959
|
+
5. Honor the sync/async contract: `async: { capable: true }` or `{ capable: false, reason }` — non-capable types are refused at enqueue time; optional `executeAsync` (worker-side variant) and `enqueueDelayMs(config)` for delayed queueing.
|
|
960
|
+
6. Optional: `mock` — `((config, ctx) => unknown) | 'refuse'` — powers the mock-first Test step (`'refuse'` and missing mocks return structured refusals; side-effecting types return would-do payloads like `{ sent: false, simulated: true }`), and `outputContract` for the context ledger (UPDATE_ENTITY resolves it via `commandRegistry.outputSchemaOf(commandId)` **nested under `executeUpdateEntity`'s envelope** — `{ executed, commandId, logEntryId, result }` — degrading to `'unknown'` when the command declares none).
|
|
961
|
+
7. Test with both sync and async execution modes.
|
|
962
|
+
|
|
963
|
+
Editor picker registries (both keep free-text fallback): UPDATE_ENTITY only executes commands declared via `registerWorkflowSafeCommands` (`lib/workflow-safe-commands.ts`; `listWorkflowSafeCommands()` backs `GET /api/workflows/commands`); EXECUTE_FUNCTION's picker lists `registerWorkflowFunctions` descriptors (`lib/workflow-function-registry.ts`).
|
|
123
964
|
|
|
124
965
|
## Adding a New Step Type
|
|
125
966
|
|
|
@@ -178,11 +1019,11 @@ When adding new injected widgets, follow this pattern — keep the widget self-c
|
|
|
178
1019
|
|
|
179
1020
|
| Directory | When to modify |
|
|
180
1021
|
|-----------|---------------|
|
|
181
|
-
| `api/` | When adding/modifying REST endpoints for definitions, instances, tasks, events, signals |
|
|
1022
|
+
| `api/` | When adding/modifying REST endpoints for definitions, instances, tasks, events, signals, templates, per-user drafts |
|
|
182
1023
|
| `backend/` | When changing admin pages (definition list, visual editor, instance viewer, task inbox) |
|
|
183
1024
|
| `components/` | When modifying the visual workflow editor (React Flow nodes, edges, dialogs) |
|
|
184
1025
|
| `data/` | When changing ORM entities, validators, or extensions |
|
|
185
|
-
| `examples/` | When adding/updating seed workflow definitions (JSON) |
|
|
1026
|
+
| `examples/` | When adding/updating seed workflow definitions (JSON) or gallery templates (`examples/templates/*.json`; each MUST validate against `workflowDefinitionDataSchema` — a test enforces it) |
|
|
186
1027
|
| `frontend/` | When modifying public-facing workflow pages |
|
|
187
1028
|
| `i18n/` | When adding/updating translations (en, es, de, pl) |
|
|
188
1029
|
| `lib/` | When changing core engine logic (executor, handlers, compensation, signals) |
|
|
@@ -194,7 +1035,7 @@ When adding new injected widgets, follow this pattern — keep the widget self-c
|
|
|
194
1035
|
|
|
195
1036
|
```
|
|
196
1037
|
src/modules/workflows/
|
|
197
|
-
├── acl.ts #
|
|
1038
|
+
├── acl.ts # 27 RBAC features
|
|
198
1039
|
├── ce.ts # Custom entities (empty)
|
|
199
1040
|
├── cli.ts # CLI: seed-demo, start-worker, process-activities
|
|
200
1041
|
├── di.ts # DI: workflowExecutor, stepHandler, transitionHandler, activityExecutor, eventLogger
|