@aglyn/plugins-workflows 1.0.0-beta.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +52 -0
  3. package/package.json +53 -0
  4. package/src/index.d.ts +18 -0
  5. package/src/index.js +19 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/automation-step-fields.component.d.ts +74 -0
  8. package/src/lib/components/automation-step-fields.component.js +1210 -0
  9. package/src/lib/components/automation-step-fields.component.js.map +1 -0
  10. package/src/lib/components/host-actions-card.component.d.ts +15 -0
  11. package/src/lib/components/host-actions-card.component.js +1229 -0
  12. package/src/lib/components/host-actions-card.component.js.map +1 -0
  13. package/src/lib/components/host-activity-card.component.d.ts +84 -0
  14. package/src/lib/components/host-activity-card.component.js +280 -0
  15. package/src/lib/components/host-activity-card.component.js.map +1 -0
  16. package/src/lib/components/host-run-history-card.component.d.ts +40 -0
  17. package/src/lib/components/host-run-history-card.component.js +284 -0
  18. package/src/lib/components/host-run-history-card.component.js.map +1 -0
  19. package/src/lib/components/host-webhooks-card.component.d.ts +15 -0
  20. package/src/lib/components/host-webhooks-card.component.js +421 -0
  21. package/src/lib/components/host-webhooks-card.component.js.map +1 -0
  22. package/src/lib/components/host-workflows-card.component.d.ts +18 -0
  23. package/src/lib/components/host-workflows-card.component.js +952 -0
  24. package/src/lib/components/host-workflows-card.component.js.map +1 -0
  25. package/src/lib/components/run-quota-line.component.d.ts +27 -0
  26. package/src/lib/components/run-quota-line.component.js +72 -0
  27. package/src/lib/components/run-quota-line.component.js.map +1 -0
  28. package/src/lib/components/use-automation-step-pickers.d.ts +27 -0
  29. package/src/lib/components/use-automation-step-pickers.js +205 -0
  30. package/src/lib/components/use-automation-step-pickers.js.map +1 -0
  31. package/src/lib/components/workflow-zones.d.ts +36 -0
  32. package/src/lib/components/workflow-zones.js +19 -0
  33. package/src/lib/components/workflow-zones.js.map +1 -0
  34. package/src/lib/components/workflows-console-page.d.ts +25 -0
  35. package/src/lib/components/workflows-console-page.js +112 -0
  36. package/src/lib/components/workflows-console-page.js.map +1 -0
  37. package/src/lib/components/workflows-console-sections.d.ts +34 -0
  38. package/src/lib/components/workflows-console-sections.js +50 -0
  39. package/src/lib/components/workflows-console-sections.js.map +1 -0
  40. package/src/lib/constants/bundle-common.d.ts +8 -0
  41. package/src/lib/constants/bundle-common.js +9 -0
  42. package/src/lib/constants/bundle-common.js.map +1 -0
  43. package/src/lib/declarations.server.d.ts +41 -0
  44. package/src/lib/declarations.server.js +54 -0
  45. package/src/lib/declarations.server.js.map +1 -0
  46. package/src/lib/engine/crm-action-steps.d.ts +129 -0
  47. package/src/lib/engine/crm-action-steps.js +432 -0
  48. package/src/lib/engine/crm-action-steps.js.map +1 -0
  49. package/src/lib/engine/flow-enrollments.d.ts +264 -0
  50. package/src/lib/engine/flow-enrollments.js +386 -0
  51. package/src/lib/engine/flow-enrollments.js.map +1 -0
  52. package/src/lib/engine/run-event-actions.d.ts +232 -0
  53. package/src/lib/engine/run-event-actions.js +1392 -0
  54. package/src/lib/engine/run-event-actions.js.map +1 -0
  55. package/src/lib/engine/run-event-automations.d.ts +28 -0
  56. package/src/lib/engine/run-event-automations.js +37 -0
  57. package/src/lib/engine/run-event-automations.js.map +1 -0
  58. package/src/lib/engine/run-event-workflows.d.ts +75 -0
  59. package/src/lib/engine/run-event-workflows.js +311 -0
  60. package/src/lib/engine/run-event-workflows.js.map +1 -0
  61. package/src/lib/engine/workflow-steps.d.ts +107 -0
  62. package/src/lib/engine/workflow-steps.js +124 -0
  63. package/src/lib/engine/workflow-steps.js.map +1 -0
  64. package/src/lib/plugin.d.ts +33 -0
  65. package/src/lib/plugin.js +94 -0
  66. package/src/lib/plugin.js.map +1 -0
  67. package/src/lib/server-automation-drafts.d.ts +90 -0
  68. package/src/lib/server-automation-drafts.js +429 -0
  69. package/src/lib/server-automation-drafts.js.map +1 -0
  70. package/src/lib/server-console.d.ts +27 -0
  71. package/src/lib/server-console.js +35 -0
  72. package/src/lib/server-console.js.map +1 -0
  73. package/src/lib/server.d.ts +29 -0
  74. package/src/lib/server.js +298 -0
  75. package/src/lib/server.js.map +1 -0
@@ -0,0 +1,25 @@
1
+ import type { ConsolePluginPageProps } from '@aglyn/aglyn';
2
+ /**
3
+ * Automation page (AGL-101/148/149 → AGL-395): the automation surface —
4
+ * workflow builder, event-triggered actions, and webhooks — owned by the
5
+ * workflows plugin and rendered by the shell's generic plugin route. Each card
6
+ * runs its own entitlement check (workflows / actions / webhooks are distinct
7
+ * plan flags), so the shell's resolved `org` doc flows into all three.
8
+ *
9
+ * Sections are ROUTES (AGL-2501). `HubTabs lazy` already mounted one panel, so
10
+ * this is not a read saving — `workflows-console-read-cost.spec.tsx` was
11
+ * written BEFORE the conversion precisely to hold that line, and reports the
12
+ * same counts after. What routing adds is that the URL names the section: it is
13
+ * linkable, the back button walks sections, the breadcrumb says where you are,
14
+ * and "mount only what is open" is structural rather than a `lazy` flag.
15
+ *
16
+ * The section ids are unchanged by the Automation rename: they are the
17
+ * addresses people bookmark and the docs link to. A workflow belongs to the
18
+ * site and an ACTION belongs to the site too; an interaction belongs to the
19
+ * document that holds it and is edited on the element, not here.
20
+ */
21
+ export declare function WorkflowsConsolePage(props: ConsolePluginPageProps): import("react").JSX.Element;
22
+ export declare namespace WorkflowsConsolePage {
23
+ var displayName: string;
24
+ }
25
+ export default WorkflowsConsolePage;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
+ import { HubSections } from "@aglyn/shared-ui-next";
19
+ import { Stack } from "@mui/material";
20
+ import HostActionsCard from "./host-actions-card.component.js";
21
+ import HostWebhooksCard from "./host-webhooks-card.component.js";
22
+ import HostWorkflowsCard from "./host-workflows-card.component.js";
23
+ import RunQuotaLine from "./run-quota-line.component.js";
24
+ /**
25
+ * The body of one workflows section, built only when that section is the one
26
+ * being read (AGL-2501).
27
+ *
28
+ * A function rather than a map of nodes on purpose: a `Record<id, ReactNode>`
29
+ * would CONSTRUCT all three every render, and each card opens its Firestore
30
+ * listens on mount — which is the entire cost this page exists to stop paying.
31
+ * Only the returned branch is ever built.
32
+ */ function sectionBody(section, hostId, org) {
33
+ switch(section){
34
+ case 'workflows':
35
+ return(/*
36
+ * `N runs this month · M included` (AGL-2171), which the run-history
37
+ * mockup puts opposite the heading. The quota silently stops
38
+ * automations running once it is reached, and the only place it was
39
+ * reported was the Billing page.
40
+ */ /*#__PURE__*/ _jsxs(Stack, {
41
+ spacing: 1,
42
+ children: [
43
+ /*#__PURE__*/ _jsx(RunQuotaLine, {
44
+ hostId: hostId,
45
+ org: org,
46
+ counter: "workflowRuns"
47
+ }),
48
+ /*#__PURE__*/ _jsx(HostWorkflowsCard, {
49
+ hostId: hostId,
50
+ org: org
51
+ })
52
+ ]
53
+ }));
54
+ case 'actions':
55
+ return /*#__PURE__*/ _jsxs(Stack, {
56
+ spacing: 1,
57
+ children: [
58
+ /*#__PURE__*/ _jsx(RunQuotaLine, {
59
+ hostId: hostId,
60
+ org: org,
61
+ counter: "actionRuns"
62
+ }),
63
+ /*#__PURE__*/ _jsx(HostActionsCard, {
64
+ hostId: hostId,
65
+ org: org
66
+ })
67
+ ]
68
+ });
69
+ case 'webhooks':
70
+ return /*#__PURE__*/ _jsx(HostWebhooksCard, {
71
+ hostId: hostId,
72
+ org: org
73
+ });
74
+ default:
75
+ return null;
76
+ }
77
+ }
78
+ /**
79
+ * Automation page (AGL-101/148/149 → AGL-395): the automation surface —
80
+ * workflow builder, event-triggered actions, and webhooks — owned by the
81
+ * workflows plugin and rendered by the shell's generic plugin route. Each card
82
+ * runs its own entitlement check (workflows / actions / webhooks are distinct
83
+ * plan flags), so the shell's resolved `org` doc flows into all three.
84
+ *
85
+ * Sections are ROUTES (AGL-2501). `HubTabs lazy` already mounted one panel, so
86
+ * this is not a read saving — `workflows-console-read-cost.spec.tsx` was
87
+ * written BEFORE the conversion precisely to hold that line, and reports the
88
+ * same counts after. What routing adds is that the URL names the section: it is
89
+ * linkable, the back button walks sections, the breadcrumb says where you are,
90
+ * and "mount only what is open" is structural rather than a `lazy` flag.
91
+ *
92
+ * The section ids are unchanged by the Automation rename: they are the
93
+ * addresses people bookmark and the docs link to. A workflow belongs to the
94
+ * site and an ACTION belongs to the site too; an interaction belongs to the
95
+ * document that holds it and is edited on the element, not here.
96
+ */ export function WorkflowsConsolePage(props) {
97
+ const { hostId, org, section, sections, basePath } = props;
98
+ /*
99
+ * Nothing until the URL names a section. The shell redirects a bare hub URL
100
+ * to the landing section and holds a spinner while it does, so this state is
101
+ * transient — and rendering a default section here instead would pay for its
102
+ * listens on a URL that is already being replaced.
103
+ */ if (!section || !(sections == null ? void 0 : sections.length) || !basePath) return null;
104
+ return /*#__PURE__*/ _jsx(HubSections, {
105
+ sections: sections,
106
+ children: sectionBody(section, hostId, org)
107
+ });
108
+ }
109
+ WorkflowsConsolePage.displayName = 'WorkflowsConsolePage';
110
+ export default WorkflowsConsolePage;
111
+
112
+ //# sourceMappingURL=workflows-console-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/workflows-console-page.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport type { AglynOrgBilling, ConsolePluginPageProps } from '@aglyn/aglyn'\nimport { HubSections } from '@aglyn/shared-ui-next'\nimport { Stack } from '@mui/material'\nimport type { ReactNode } from 'react'\nimport HostActionsCard from './host-actions-card.component'\nimport HostWebhooksCard from './host-webhooks-card.component'\nimport HostWorkflowsCard from './host-workflows-card.component'\nimport RunQuotaLine from './run-quota-line.component'\nimport type { WorkflowsConsoleSectionId } from './workflows-console-sections'\n\n/**\n * The body of one workflows section, built only when that section is the one\n * being read (AGL-2501).\n *\n * A function rather than a map of nodes on purpose: a `Record<id, ReactNode>`\n * would CONSTRUCT all three every render, and each card opens its Firestore\n * listens on mount — which is the entire cost this page exists to stop paying.\n * Only the returned branch is ever built.\n */\nfunction sectionBody(\n section: WorkflowsConsoleSectionId,\n hostId: string,\n org: Partial<AglynOrgBilling> | undefined,\n): ReactNode {\n switch (section) {\n case 'workflows':\n return (\n /*\n * `N runs this month · M included` (AGL-2171), which the run-history\n * mockup puts opposite the heading. The quota silently stops\n * automations running once it is reached, and the only place it was\n * reported was the Billing page.\n */\n <Stack spacing={1}>\n <RunQuotaLine hostId={hostId} org={org} counter=\"workflowRuns\" />\n <HostWorkflowsCard hostId={hostId} org={org} />\n </Stack>\n )\n case 'actions':\n return (\n <Stack spacing={1}>\n {/* `actionRunsPerMonth` had NO customer-facing surface at all\n before this — staff panel and usage-alerts only. */}\n <RunQuotaLine hostId={hostId} org={org} counter=\"actionRuns\" />\n <HostActionsCard hostId={hostId} org={org} />\n </Stack>\n )\n case 'webhooks':\n return <HostWebhooksCard hostId={hostId} org={org} />\n default:\n return null\n }\n}\n\n/**\n * Automation page (AGL-101/148/149 → AGL-395): the automation surface —\n * workflow builder, event-triggered actions, and webhooks — owned by the\n * workflows plugin and rendered by the shell's generic plugin route. Each card\n * runs its own entitlement check (workflows / actions / webhooks are distinct\n * plan flags), so the shell's resolved `org` doc flows into all three.\n *\n * Sections are ROUTES (AGL-2501). `HubTabs lazy` already mounted one panel, so\n * this is not a read saving — `workflows-console-read-cost.spec.tsx` was\n * written BEFORE the conversion precisely to hold that line, and reports the\n * same counts after. What routing adds is that the URL names the section: it is\n * linkable, the back button walks sections, the breadcrumb says where you are,\n * and \"mount only what is open\" is structural rather than a `lazy` flag.\n *\n * The section ids are unchanged by the Automation rename: they are the\n * addresses people bookmark and the docs link to. A workflow belongs to the\n * site and an ACTION belongs to the site too; an interaction belongs to the\n * document that holds it and is edited on the element, not here.\n */\nexport function WorkflowsConsolePage(props: ConsolePluginPageProps) {\n const { hostId, org, section, sections, basePath } = props\n\n /*\n * Nothing until the URL names a section. The shell redirects a bare hub URL\n * to the landing section and holds a spinner while it does, so this state is\n * transient — and rendering a default section here instead would pay for its\n * listens on a URL that is already being replaced.\n */\n if (!section || !sections?.length || !basePath) return null\n\n return (\n <HubSections sections={sections}>\n {sectionBody(section as WorkflowsConsoleSectionId, hostId, org)}\n </HubSections>\n )\n}\nWorkflowsConsolePage.displayName = 'WorkflowsConsolePage'\n\nexport default WorkflowsConsolePage\n"],"names":["HubSections","Stack","HostActionsCard","HostWebhooksCard","HostWorkflowsCard","RunQuotaLine","sectionBody","section","hostId","org","spacing","counter","WorkflowsConsolePage","props","sections","basePath","length","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAGA,SAASA,WAAW,QAAQ,wBAAuB;AACnD,SAASC,KAAK,QAAQ,gBAAe;AAErC,OAAOC,qBAAqB,mCAA+B;AAC3D,OAAOC,sBAAsB,oCAAgC;AAC7D,OAAOC,uBAAuB,qCAAiC;AAC/D,OAAOC,kBAAkB,gCAA4B;AAGrD;;;;;;;;CAQC,GACD,SAASC,YACPC,OAAkC,EAClCC,MAAc,EACdC,GAAyC;IAEzC,OAAQF;QACN,KAAK;YACH,OACE;;;;;SAKC,iBACD,MAACN;gBAAMS,SAAS;;kCACd,KAACL;wBAAaG,QAAQA;wBAAQC,KAAKA;wBAAKE,SAAQ;;kCAChD,KAACP;wBAAkBI,QAAQA;wBAAQC,KAAKA;;;;QAG9C,KAAK;YACH,qBACE,MAACR;gBAAMS,SAAS;;kCAGd,KAACL;wBAAaG,QAAQA;wBAAQC,KAAKA;wBAAKE,SAAQ;;kCAChD,KAACT;wBAAgBM,QAAQA;wBAAQC,KAAKA;;;;QAG5C,KAAK;YACH,qBAAO,KAACN;gBAAiBK,QAAQA;gBAAQC,KAAKA;;QAChD;YACE,OAAO;IACX;AACF;AAEA;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASG,qBAAqBC,KAA6B;IAChE,MAAM,EAAEL,MAAM,EAAEC,GAAG,EAAEF,OAAO,EAAEO,QAAQ,EAAEC,QAAQ,EAAE,GAAGF;IAErD;;;;;GAKC,GACD,IAAI,CAACN,WAAW,EAACO,4BAAAA,SAAUE,MAAM,KAAI,CAACD,UAAU,OAAO;IAEvD,qBACE,KAACf;QAAYc,UAAUA;kBACpBR,YAAYC,SAAsCC,QAAQC;;AAGjE;AACAG,qBAAqBK,WAAW,GAAG;AAEnC,eAAeL,qBAAoB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { ConsoleNavSection } from '@aglyn/aglyn';
18
+ export type WorkflowsConsoleSectionId = 'workflows' | 'actions' | 'webhooks';
19
+ /**
20
+ * The workflows console's sections, in rail order (AGL-2501).
21
+ *
22
+ * One list, read twice and never copied: `plugin.ts` registers it on the nav
23
+ * item so the shell can route and gate each section, and the page switches its
24
+ * body on the id the shell resolves back.
25
+ *
26
+ * Ids are the `?tab=` ids this page already deep-linked by, kept deliberately
27
+ * so a bookmark that named a tab names the same section as a route.
28
+ *
29
+ * No `navTabId` on any of them: they inherit the Workflows nav item's gate,
30
+ * which is `nav-tab-workflows`. The per-card ENTITLEMENT checks are unchanged
31
+ * and still live in the cards — workflows, actions and webhooks are distinct
32
+ * plan flags, and a plan is not a release flag.
33
+ */
34
+ export declare const WORKFLOWS_CONSOLE_SECTIONS: readonly ConsoleNavSection[];
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * The workflows console's sections, in rail order (AGL-2501).
18
+ *
19
+ * One list, read twice and never copied: `plugin.ts` registers it on the nav
20
+ * item so the shell can route and gate each section, and the page switches its
21
+ * body on the id the shell resolves back.
22
+ *
23
+ * Ids are the `?tab=` ids this page already deep-linked by, kept deliberately
24
+ * so a bookmark that named a tab names the same section as a route.
25
+ *
26
+ * No `navTabId` on any of them: they inherit the Workflows nav item's gate,
27
+ * which is `nav-tab-workflows`. The per-card ENTITLEMENT checks are unchanged
28
+ * and still live in the cards — workflows, actions and webhooks are distinct
29
+ * plan flags, and a plan is not a release flag.
30
+ */ export const WORKFLOWS_CONSOLE_SECTIONS = [
31
+ {
32
+ id: 'workflows',
33
+ label: 'Workflows'
34
+ },
35
+ {
36
+ id: 'actions',
37
+ label: 'Actions'
38
+ },
39
+ {
40
+ id: 'webhooks',
41
+ label: 'Webhooks'
42
+ }
43
+ ] /*
44
+ * Rail ORDER decides where `/workflows` lands: the shell redirects a bare hub
45
+ * URL to the first section in this list the reader may open (AGL-2501). There
46
+ * is deliberately no separate default constant — a second place to say which
47
+ * section is first is a second place for it to disagree with the rail.
48
+ */ ;
49
+
50
+ //# sourceMappingURL=workflows-console-sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/workflows-console-sections.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConsoleNavSection } from '@aglyn/aglyn'\n\nexport type WorkflowsConsoleSectionId = 'workflows' | 'actions' | 'webhooks'\n\n/**\n * The workflows console's sections, in rail order (AGL-2501).\n *\n * One list, read twice and never copied: `plugin.ts` registers it on the nav\n * item so the shell can route and gate each section, and the page switches its\n * body on the id the shell resolves back.\n *\n * Ids are the `?tab=` ids this page already deep-linked by, kept deliberately\n * so a bookmark that named a tab names the same section as a route.\n *\n * No `navTabId` on any of them: they inherit the Workflows nav item's gate,\n * which is `nav-tab-workflows`. The per-card ENTITLEMENT checks are unchanged\n * and still live in the cards — workflows, actions and webhooks are distinct\n * plan flags, and a plan is not a release flag.\n */\nexport const WORKFLOWS_CONSOLE_SECTIONS: readonly ConsoleNavSection[] = [\n { id: 'workflows', label: 'Workflows' },\n { id: 'actions', label: 'Actions' },\n { id: 'webhooks', label: 'Webhooks' },\n]\n\n/*\n * Rail ORDER decides where `/workflows` lands: the shell redirects a bare hub\n * URL to the first section in this list the reader may open (AGL-2501). There\n * is deliberately no separate default constant — a second place to say which\n * section is first is a second place for it to disagree with the rail.\n */\n"],"names":["WORKFLOWS_CONSOLE_SECTIONS","id","label"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAMD;;;;;;;;;;;;;;CAcC,GACD,OAAO,MAAMA,6BAA2D;IACtE;QAAEC,IAAI;QAAaC,OAAO;IAAY;IACtC;QAAED,IAAI;QAAWC,OAAO;IAAU;IAClC;QAAED,IAAI;QAAYC,OAAO;IAAW;CACrC,CAED;;;;;CAKC,IAPA"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ */
8
+ export declare const BUNDLE_ID = "workflows";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ */ export const BUNDLE_ID = 'workflows';
8
+
9
+ //# sourceMappingURL=bundle-common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/constants/bundle-common.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n */\n\nexport const BUNDLE_ID = 'workflows'\n"],"names":["BUNDLE_ID"],"mappings":"AAAA;;;;;;CAMC,GAED,OAAO,MAAMA,YAAY,YAAW"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type HostEventListener } from '@aglyn/tenant-runtime/host-event-listeners';
18
+ /**
19
+ * The automation engine, as the runtime hears it.
20
+ *
21
+ * Light by construction: the engine is imported when the first event
22
+ * arrives, not when the process starts, so a process that never sees an
23
+ * event pays for this object and nothing else.
24
+ */
25
+ export declare const workflowsHostEventListener: HostEventListener;
26
+ /**
27
+ * The plugin's SERVER declarations: what the server must know at boot,
28
+ * before any door of the plugin has been called.
29
+ *
30
+ * The engine's host-event listener, because the doors that raise the events
31
+ * mostly never load this plugin. A form submission and a page view are core
32
+ * routes; a contact captured by a Stripe webhook is a core capture door. Each
33
+ * calls `emitHostEvent`, and the listener has to be registered before the
34
+ * first of them arrives — which is what running this from both apps'
35
+ * `instrumentation.ts` gives.
36
+ *
37
+ * Also called from the plugin's own API register functions, so a process
38
+ * whose boot did not run it still registers the listener the first time a
39
+ * plugin door loads. Registering twice replaces in place.
40
+ */
41
+ export declare function registerWorkflowsServerDeclarations(): void;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ // The registry from its own module, not the runtime barrel: boot needs the
17
+ // registry and nothing else, and the barrel reaches the data layer.
18
+ import { registerHostEventListener } from "@aglyn/tenant-runtime/host-event-listeners";
19
+ import { BUNDLE_ID } from "./constants/bundle-common.js";
20
+ /**
21
+ * The automation engine, as the runtime hears it.
22
+ *
23
+ * Light by construction: the engine is imported when the first event
24
+ * arrives, not when the process starts, so a process that never sees an
25
+ * event pays for this object and nothing else.
26
+ */ export const workflowsHostEventListener = {
27
+ async onEvent (hostId, event, payload) {
28
+ const { runEventAutomations } = await import("./engine/run-event-automations.js");
29
+ return await runEventAutomations(hostId, event, payload);
30
+ },
31
+ async onDispatch (hostId, automationId, event, payload) {
32
+ const { runSingleAction } = await import("./engine/run-event-actions.js");
33
+ return await runSingleAction(hostId, automationId, event, payload);
34
+ }
35
+ };
36
+ /**
37
+ * The plugin's SERVER declarations: what the server must know at boot,
38
+ * before any door of the plugin has been called.
39
+ *
40
+ * The engine's host-event listener, because the doors that raise the events
41
+ * mostly never load this plugin. A form submission and a page view are core
42
+ * routes; a contact captured by a Stripe webhook is a core capture door. Each
43
+ * calls `emitHostEvent`, and the listener has to be registered before the
44
+ * first of them arrives — which is what running this from both apps'
45
+ * `instrumentation.ts` gives.
46
+ *
47
+ * Also called from the plugin's own API register functions, so a process
48
+ * whose boot did not run it still registers the listener the first time a
49
+ * plugin door loads. Registering twice replaces in place.
50
+ */ export function registerWorkflowsServerDeclarations() {
51
+ registerHostEventListener(BUNDLE_ID, workflowsHostEventListener);
52
+ }
53
+
54
+ //# sourceMappingURL=declarations.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/plugins/workflows/src/lib/declarations.server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// The registry from its own module, not the runtime barrel: boot needs the\n// registry and nothing else, and the barrel reaches the data layer.\nimport {\n type HostEventListener,\n registerHostEventListener,\n} from '@aglyn/tenant-runtime/host-event-listeners'\nimport { BUNDLE_ID } from './constants/bundle-common'\n\n/**\n * The automation engine, as the runtime hears it.\n *\n * Light by construction: the engine is imported when the first event\n * arrives, not when the process starts, so a process that never sees an\n * event pays for this object and nothing else.\n */\nexport const workflowsHostEventListener: HostEventListener = {\n async onEvent(hostId, event, payload) {\n const { runEventAutomations } = await import('./engine/run-event-automations')\n return await runEventAutomations(hostId, event, payload)\n },\n async onDispatch(hostId, automationId, event, payload) {\n const { runSingleAction } = await import('./engine/run-event-actions')\n return await runSingleAction(hostId, automationId, event, payload)\n },\n}\n\n/**\n * The plugin's SERVER declarations: what the server must know at boot,\n * before any door of the plugin has been called.\n *\n * The engine's host-event listener, because the doors that raise the events\n * mostly never load this plugin. A form submission and a page view are core\n * routes; a contact captured by a Stripe webhook is a core capture door. Each\n * calls `emitHostEvent`, and the listener has to be registered before the\n * first of them arrives — which is what running this from both apps'\n * `instrumentation.ts` gives.\n *\n * Also called from the plugin's own API register functions, so a process\n * whose boot did not run it still registers the listener the first time a\n * plugin door loads. Registering twice replaces in place.\n */\nexport function registerWorkflowsServerDeclarations(): void {\n registerHostEventListener(BUNDLE_ID, workflowsHostEventListener)\n}\n"],"names":["registerHostEventListener","BUNDLE_ID","workflowsHostEventListener","onEvent","hostId","event","payload","runEventAutomations","onDispatch","automationId","runSingleAction","registerWorkflowsServerDeclarations"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,2EAA2E;AAC3E,oEAAoE;AACpE,SAEEA,yBAAyB,QACpB,6CAA4C;AACnD,SAASC,SAAS,QAAQ,+BAA2B;AAErD;;;;;;CAMC,GACD,OAAO,MAAMC,6BAAgD;IAC3D,MAAMC,SAAQC,MAAM,EAAEC,KAAK,EAAEC,OAAO;QAClC,MAAM,EAAEC,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC;QAC7C,OAAO,MAAMA,oBAAoBH,QAAQC,OAAOC;IAClD;IACA,MAAME,YAAWJ,MAAM,EAAEK,YAAY,EAAEJ,KAAK,EAAEC,OAAO;QACnD,MAAM,EAAEI,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC;QACzC,OAAO,MAAMA,gBAAgBN,QAAQK,cAAcJ,OAAOC;IAC5D;AACF,EAAC;AAED;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASK;IACdX,0BAA0BC,WAAWC;AACvC"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type CrmActionStep, type CrmActivityLink } from '@aglyn/aglyn/server';
18
+ import type { HostEventPayload } from '@aglyn/tenant-runtime/host-event-listeners';
19
+ /**
20
+ * The CRM steps of an action run (AGL-2605): what `setContactStage`,
21
+ * `addContactTag`, `assignContactOwner`, `createCrmTask` and
22
+ * `logCrmActivity` actually write.
23
+ *
24
+ * Split out of `run-event-actions.ts` because the five share one shape the
25
+ * other server steps do not: each begins by finding THE PERSON the event is
26
+ * about, and each writes either inside the site's facet on that person or a
27
+ * record stamped with the site's scope. One resolver and one scope
28
+ * expression, used five times, rather than five copies drifting apart.
29
+ *
30
+ * ## The person is the event's, never the step's
31
+ *
32
+ * A step carries no contact reference. The contact is whoever the event
33
+ * names — by `contactId` when the emitting door knew the document, and by
34
+ * `email` otherwise, which is what every pre-CRM event carries. Both
35
+ * lookups are scoped to what THIS site may see: a document the id names
36
+ * but the site cannot read is treated as absent, exactly as the scoped
37
+ * query would have treated it, so an event replayed against the wrong site
38
+ * reaches nobody.
39
+ *
40
+ * ## A missing person is a reported no-op
41
+ *
42
+ * Nothing is written and the step's error names the reason, which lands in
43
+ * the run summary beside the trigger — the same place "why didn't it
44
+ * fire?" is answered for every other step. Silence here would make a
45
+ * mis-wired trigger (a form with no email field) indistinguishable from a
46
+ * working one.
47
+ */
48
+ export interface CrmStepEnv {
49
+ hostId: string;
50
+ /** The owning org's billing doc, already read by the run's gate. */
51
+ org: unknown;
52
+ orgId: string | null;
53
+ }
54
+ export interface CrmStepOutcome {
55
+ /** The reason nothing was written, when nothing was. */
56
+ error?: string;
57
+ /** The one fact worth carrying into the run summary. */
58
+ detail?: string;
59
+ /**
60
+ * An event this step's write earned, for the CALLER to fan out under its
61
+ * own depth guard. Not emitted from here: a stage set by an automation is
62
+ * itself a stage change, and the action listening for it must run — but
63
+ * through the same nesting cap a `customEvent` chain has, or an action
64
+ * that sets the stage it listens for would run until the meter ran dry.
65
+ */
66
+ emit?: {
67
+ event: 'contactStageChanged';
68
+ payload: HostEventPayload;
69
+ };
70
+ }
71
+ /**
72
+ * Runs one CRM step for the person the event names. Never throws for a
73
+ * missing person, an unknown owner or a site with no org — those are
74
+ * answered as `error` so the run records them; a Firestore failure
75
+ * propagates to the executor's catch like every other step's would.
76
+ */
77
+ export declare function runCrmActionStep(env: CrmStepEnv, actionId: string, step: CrmActionStep, payload: HostEventPayload, nowMs?: number): Promise<CrmStepOutcome>;
78
+ /**
79
+ * The activity row a `sendEmail` step's message will be logged as, prepared
80
+ * BEFORE the send (AGL-2615): the minted reference whose id rides the
81
+ * message as a tag, the links it files under, and the scope it is stamped
82
+ * with. `null` when the message earns no row.
83
+ */
84
+ export interface PreparedCrmEmailActivity {
85
+ ref: FirebaseFirestore.DocumentReference;
86
+ /** The provider tags the delivery webhook finds the row by. */
87
+ tags: {
88
+ name: string;
89
+ value: string;
90
+ }[];
91
+ link: CrmActivityLink;
92
+ visibleTo: string[];
93
+ }
94
+ /**
95
+ * Whether — and where — an automation's email lands on a timeline.
96
+ *
97
+ * A `sendEmail` step is not a CRM step: it mails whatever address the event
98
+ * carries, to a person who may be nobody the CRM knows. It earns a row on
99
+ * exactly one condition, that the message is ADDRESSED TO THE CONTACT the
100
+ * event is about — the person `resolveEventContact` finds, at the address
101
+ * the row holds. A welcome sequence to a new contact is that; an internal
102
+ * alert routed to a merchant's own address through `toField` is not, and a
103
+ * row for it would put the merchant's inbox on a customer's history.
104
+ *
105
+ * Prepared ahead of the send, for the reason the console route mints its
106
+ * id first: the webhook has nothing but the tags on the message to find
107
+ * the row with. Nothing is written here. A record at the activity ceiling
108
+ * earns no row — the message still goes, because the ceiling bounds the
109
+ * log and not the mail — and neither does a site with no org to hold one.
110
+ *
111
+ * **Never throws.** The row is bookkeeping beside a send, and a lookup that
112
+ * fails must not become a message that never left — the posture every
113
+ * meter beside `sendEmail` takes. A failure here is logged and the message
114
+ * goes out untagged.
115
+ */
116
+ export declare function prepareCrmEmailActivity(env: CrmStepEnv, to: string, payload: HostEventPayload): Promise<PreparedCrmEmailActivity | null>;
117
+ /**
118
+ * Writes the prepared row, once the provider has accepted the message.
119
+ *
120
+ * The same shape the console route logs — `buildCrmEmailActivity` is the
121
+ * one builder — with the automation as its source and nobody as its
122
+ * author. **Never throws**: the message has left, and a row that could not
123
+ * be written is a gap on the timeline rather than a failed step.
124
+ */
125
+ export declare function logCrmEmailActivity(env: CrmStepEnv, prepared: PreparedCrmEmailActivity, message: {
126
+ subject: string;
127
+ body: string;
128
+ to: string;
129
+ }, actionId: string, nowMs?: number): Promise<void>;