@elevasis/sdk 1.20.2 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/dist/cli.cjs +4220 -1583
  2. package/dist/index.d.ts +1035 -481
  3. package/dist/index.js +7381 -4187
  4. package/dist/node/index.d.ts +1 -3
  5. package/dist/node/index.js +40 -49
  6. package/dist/test-utils/index.d.ts +699 -123
  7. package/dist/test-utils/index.js +3826 -630
  8. package/dist/worker/index.js +3616 -442
  9. package/package.json +3 -3
  10. package/reference/_navigation.md +9 -7
  11. package/reference/_reference-manifest.json +1 -1
  12. package/reference/claude-config/hooks/post-edit-validate.mjs +98 -98
  13. package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +188 -188
  14. package/reference/claude-config/hooks/tool-failure-recovery.mjs +73 -73
  15. package/reference/claude-config/registries/graph-skills.json +4 -4
  16. package/reference/claude-config/registries/knowledge-flags.json +0 -2
  17. package/reference/claude-config/rules/active-change-index.md +80 -80
  18. package/reference/claude-config/rules/agent-start-here.md +277 -273
  19. package/reference/claude-config/rules/deployment.md +57 -57
  20. package/reference/claude-config/rules/error-handling.md +56 -56
  21. package/reference/claude-config/rules/execution.md +40 -40
  22. package/reference/claude-config/rules/frontend.md +4 -4
  23. package/reference/claude-config/rules/observability.md +31 -31
  24. package/reference/claude-config/rules/operations.md +29 -17
  25. package/reference/claude-config/rules/organization-model.md +108 -40
  26. package/reference/claude-config/rules/organization-os.md +115 -113
  27. package/reference/claude-config/rules/package-taxonomy.md +33 -33
  28. package/reference/claude-config/rules/platform.md +42 -42
  29. package/reference/claude-config/rules/shared-types.md +49 -46
  30. package/reference/claude-config/rules/task-tracking.md +47 -47
  31. package/reference/claude-config/rules/ui.md +200 -200
  32. package/reference/claude-config/rules/vibe.md +235 -231
  33. package/reference/claude-config/scripts/statusline-command.js +18 -18
  34. package/reference/claude-config/settings.json +34 -34
  35. package/reference/claude-config/skills/deploy/{SKILL.md → skill.md} +156 -156
  36. package/reference/claude-config/skills/dsp/SKILL.md +66 -66
  37. package/reference/claude-config/skills/elevasis/SKILL.md +235 -235
  38. package/reference/claude-config/skills/explore/SKILL.md +6 -6
  39. package/reference/claude-config/skills/git-sync/SKILL.md +126 -126
  40. package/reference/claude-config/skills/knowledge/SKILL.md +330 -271
  41. package/reference/claude-config/skills/knowledge/operations/codify-level-a.md +100 -100
  42. package/reference/claude-config/skills/knowledge/operations/codify-level-b.md +159 -158
  43. package/reference/claude-config/skills/knowledge/operations/customers.md +109 -109
  44. package/reference/claude-config/skills/knowledge/operations/features.md +76 -113
  45. package/reference/claude-config/skills/knowledge/operations/goals.md +118 -118
  46. package/reference/claude-config/skills/knowledge/operations/identity.md +93 -93
  47. package/reference/claude-config/skills/knowledge/operations/labels.md +94 -89
  48. package/reference/claude-config/skills/knowledge/operations/offerings.md +109 -109
  49. package/reference/claude-config/skills/knowledge/operations/roles.md +99 -99
  50. package/reference/claude-config/skills/knowledge/operations/techStack.md +30 -30
  51. package/reference/claude-config/skills/project/SKILL.md +1088 -1088
  52. package/reference/claude-config/skills/run-ui/SKILL.md +73 -73
  53. package/reference/claude-config/skills/save/SKILL.md +3 -3
  54. package/reference/claude-config/skills/setup/SKILL.md +275 -275
  55. package/reference/claude-config/skills/status/SKILL.md +59 -59
  56. package/reference/claude-config/skills/submit-request/SKILL.md +180 -180
  57. package/reference/claude-config/skills/sync/SKILL.md +47 -47
  58. package/reference/claude-config/skills/tutorial/SKILL.md +259 -259
  59. package/reference/claude-config/skills/tutorial/progress-template.md +74 -74
  60. package/reference/claude-config/skills/tutorial/technical.md +1303 -1306
  61. package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -890
  62. package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +27 -27
  63. package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +30 -30
  64. package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +73 -73
  65. package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +86 -86
  66. package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +55 -55
  67. package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +97 -97
  68. package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +112 -112
  69. package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +93 -93
  70. package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +58 -58
  71. package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +56 -56
  72. package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +71 -71
  73. package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
  74. package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +59 -59
  75. package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +42 -42
  76. package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +60 -60
  77. package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +37 -37
  78. package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +34 -34
  79. package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +38 -38
  80. package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +32 -32
  81. package/reference/claude-config/sync-notes/2026-05-09-command-system.md +33 -33
  82. package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +69 -69
  83. package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +30 -0
  84. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +42 -0
  85. package/reference/claude-config/sync-notes/README.md +43 -43
  86. package/reference/cli.mdx +808 -668
  87. package/reference/concepts.mdx +146 -146
  88. package/reference/deployment/api.mdx +297 -297
  89. package/reference/deployment/command-center.mdx +209 -209
  90. package/reference/deployment/index.mdx +195 -195
  91. package/reference/deployment/provided-features.mdx +107 -93
  92. package/reference/deployment/ui-execution.mdx +250 -250
  93. package/reference/examples/organization-model.ts +147 -84
  94. package/reference/framework/agent.mdx +156 -156
  95. package/reference/framework/index.mdx +195 -195
  96. package/reference/framework/interaction-guidance.mdx +182 -182
  97. package/reference/framework/memory.mdx +326 -326
  98. package/reference/framework/project-structure.mdx +282 -282
  99. package/reference/framework/tutorial-system.mdx +135 -135
  100. package/reference/getting-started.mdx +142 -142
  101. package/reference/index.mdx +106 -106
  102. package/reference/packages/core/src/README.md +14 -14
  103. package/reference/packages/core/src/business/README.md +2 -2
  104. package/reference/packages/core/src/knowledge/README.md +33 -32
  105. package/reference/packages/core/src/organization-model/README.md +149 -109
  106. package/reference/packages/core/src/test-utils/README.md +37 -37
  107. package/reference/packages/ui/src/api/README.md +18 -18
  108. package/reference/packages/ui/src/app/README.md +24 -24
  109. package/reference/packages/ui/src/auth/README.md +18 -18
  110. package/reference/packages/ui/src/components/README.md +24 -24
  111. package/reference/packages/ui/src/execution/README.md +16 -16
  112. package/reference/packages/ui/src/features/README.md +28 -28
  113. package/reference/packages/ui/src/graph/README.md +16 -16
  114. package/reference/packages/ui/src/hooks/README.md +23 -23
  115. package/reference/packages/ui/src/initialization/README.md +19 -19
  116. package/reference/packages/ui/src/knowledge/README.md +31 -31
  117. package/reference/packages/ui/src/organization/README.md +18 -18
  118. package/reference/packages/ui/src/profile/README.md +19 -19
  119. package/reference/packages/ui/src/provider/README.md +32 -32
  120. package/reference/packages/ui/src/router/README.md +18 -18
  121. package/reference/packages/ui/src/sse/README.md +13 -13
  122. package/reference/packages/ui/src/test-utils/README.md +7 -7
  123. package/reference/packages/ui/src/theme/README.md +23 -23
  124. package/reference/packages/ui/src/theme/presets/README.md +19 -19
  125. package/reference/packages/ui/src/types/README.md +16 -16
  126. package/reference/packages/ui/src/utils/README.md +18 -18
  127. package/reference/packages/ui/src/zustand/README.md +18 -18
  128. package/reference/platform-tools/adapters-integration.mdx +301 -301
  129. package/reference/platform-tools/adapters-platform.mdx +553 -553
  130. package/reference/platform-tools/index.mdx +217 -217
  131. package/reference/platform-tools/type-safety.mdx +82 -82
  132. package/reference/resources/index.mdx +349 -349
  133. package/reference/resources/patterns.mdx +449 -449
  134. package/reference/resources/types.mdx +116 -116
  135. package/reference/roadmap.mdx +165 -165
  136. package/reference/runtime.mdx +173 -173
  137. package/reference/scaffold/core/organization-graph.mdx +110 -89
  138. package/reference/scaffold/core/organization-model.mdx +226 -171
  139. package/reference/scaffold/index.mdx +67 -67
  140. package/reference/scaffold/operations/propagation-pipeline.md +77 -77
  141. package/reference/scaffold/operations/scaffold-maintenance.md +10 -10
  142. package/reference/scaffold/operations/workflow-recipes.md +138 -138
  143. package/reference/scaffold/recipes/add-a-feature.md +310 -88
  144. package/reference/scaffold/recipes/add-a-resource.md +137 -117
  145. package/reference/scaffold/recipes/customize-crm-actions.md +439 -439
  146. package/reference/scaffold/recipes/customize-knowledge-browser.md +384 -0
  147. package/reference/scaffold/recipes/customize-organization-model.md +281 -118
  148. package/reference/scaffold/recipes/extend-a-base-entity.md +8 -8
  149. package/reference/scaffold/recipes/extend-crm.md +40 -39
  150. package/reference/scaffold/recipes/extend-lead-gen.md +400 -401
  151. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +118 -114
  152. package/reference/scaffold/recipes/index.md +47 -46
  153. package/reference/scaffold/recipes/query-the-knowledge-graph.md +227 -0
  154. package/reference/scaffold/reference/contracts.md +2389 -2121
  155. package/reference/scaffold/reference/feature-registry.md +9 -20
  156. package/reference/scaffold/reference/glossary.md +76 -76
  157. package/reference/scaffold/ui/composition-extensibility.mdx +233 -233
  158. package/reference/scaffold/ui/customization.md +243 -243
  159. package/reference/scaffold/ui/feature-flags-and-gating.md +46 -46
  160. package/reference/scaffold/ui/feature-shell.mdx +72 -72
  161. package/reference/scaffold/ui/recipes.md +221 -213
  162. package/reference/spine/spine-primer.md +96 -96
  163. package/reference/templates/index.mdx +47 -47
  164. package/reference/troubleshooting.mdx +223 -223
@@ -1,250 +1,250 @@
1
- ---
2
- title: UI Execution
3
- description: Trigger workflow and agent executions from a custom React UI -- Run buttons, input forms, and result displays via @elevasis/ui
4
- loadWhen: "Building a custom UI that triggers resource executions (Run buttons, input forms)"
5
- ---
6
-
7
- `@elevasis/ui` ships a set of components and hooks that let your custom React pages trigger workflow and agent executions without wiring up API calls manually. This page is for template users building interactive resource pages in `external/_template` who want to add Run buttons, input forms, and execution result displays.
8
-
9
- The API comes in three tiers: a convenience one-tag component that handles everything, a controlled form primitive for custom modal chrome, and low-level hooks for fully custom rendering. Most template pages need only the first tier.
10
-
11
- ---
12
-
13
- ## Quick Start -- `ResourceExecuteDialog`
14
-
15
- `ResourceExecuteDialog` combines a modal shell, an input form, mutation state, and result display into a single component. Drop it next to a Button and you have a working Run dialog in about fifteen lines.
16
-
17
- ```tsx
18
- import { useState } from 'react'
19
- import { Button } from '@mantine/core'
20
- import { ResourceExecuteDialog } from '@elevasis/ui/features/operations'
21
- import { useNavigate } from '@tanstack/react-router'
22
-
23
- const resource = {
24
- resourceId: 'qualify-lead-workflow',
25
- resourceType: 'workflow' as const,
26
- name: 'Qualify Lead',
27
- formSchema: {
28
- fields: [
29
- { name: 'email', label: 'Lead email', type: 'text', required: true },
30
- { name: 'company', label: 'Company', type: 'text', required: false },
31
- ],
32
- },
33
- }
34
-
35
- export function QualifyLeadPage() {
36
- const [opened, setOpened] = useState(false)
37
- const navigate = useNavigate()
38
-
39
- return (
40
- <>
41
- <Button onClick={() => setOpened(true)}>Run</Button>
42
-
43
- <ResourceExecuteDialog
44
- opened={opened}
45
- onClose={() => setOpened(false)}
46
- resource={resource}
47
- onViewExecution={(executionId) =>
48
- navigate({ to: '/logs/$executionId', params: { executionId } })
49
- }
50
- />
51
- </>
52
- )
53
- }
54
- ```
55
-
56
- What the user sees when they click Run:
57
-
58
- - A modal opens titled "Run workflow" with the resource ID displayed.
59
- - The form renders one field per entry in `formSchema.fields`. Required fields show validation errors on submit.
60
- - On submit, a loading overlay appears while the POST is in flight.
61
- - On success, a teal confirmation card shows the execution ID. A "View execution" button calls `onViewExecution` with that ID.
62
- - On error, a red alert shows the error message with a "Try again" option.
63
-
64
- If `formSchema` is omitted or has no fields, the form skips to a single "Run" button with the message "This workflow takes no input."
65
-
66
- ---
67
-
68
- ## The Three-Tier API
69
-
70
- | Tier | Component / Hook | Use case |
71
- | --------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------- |
72
- | Convenience | `ResourceExecuteDialog` | One-tag Run button + modal + form. Parent only manages `opened` state. |
73
- | Controlled form | `ResourceExecuteForm` | Custom modal chrome; parent owns the mutation and decides where to show results. |
74
- | Low-level | `ExecuteWorkflowModal` + `useExecuteAsync` | Fully custom rendering, non-standard modal behavior, or composing execution into a larger flow. |
75
-
76
- Start with `ResourceExecuteDialog`. Move down the tiers only when you need something the convenience component cannot do.
77
-
78
- ---
79
-
80
- ## Controlled Usage with `ResourceExecuteForm`
81
-
82
- Use `ResourceExecuteForm` when you want to own the modal or display the result somewhere outside the dialog -- for example, rendering the execution ID inline on the page after submission.
83
-
84
- `ResourceExecuteForm` accepts `onSubmit` and `isPending` from the parent. The parent calls `useExecuteAsync()` directly and passes `mutateAsync` as the submit handler.
85
-
86
- ```tsx
87
- import { useState } from 'react'
88
- import { Modal, Button, Text } from '@mantine/core'
89
- import { ResourceExecuteForm } from '@elevasis/ui/features/operations'
90
- import { useExecuteAsync } from '@elevasis/ui/hooks'
91
-
92
- const formSchema = {
93
- fields: [
94
- { name: 'topic', label: 'Topic', type: 'text', required: true },
95
- ],
96
- }
97
-
98
- export function CustomRunPanel() {
99
- const [opened, setOpened] = useState(false)
100
- const mutation = useExecuteAsync()
101
-
102
- const handleSubmit = async (input: Record<string, unknown>) => {
103
- await mutation.mutateAsync({
104
- resourceId: 'research-agent',
105
- resourceType: 'agent',
106
- input,
107
- })
108
- }
109
-
110
- return (
111
- <>
112
- <Button onClick={() => setOpened(true)}>Run agent</Button>
113
-
114
- {mutation.data && (
115
- <Text size="sm">Started: {mutation.data.executionId}</Text>
116
- )}
117
-
118
- <Modal opened={opened} onClose={() => setOpened(false)} title="Run research agent">
119
- <ResourceExecuteForm
120
- formSchema={formSchema}
121
- onSubmit={handleSubmit}
122
- isPending={mutation.isPending}
123
- disabled={mutation.isPending}
124
- submitLabel="Start research"
125
- />
126
- </Modal>
127
- </>
128
- )
129
- }
130
- ```
131
-
132
- `ResourceExecuteForm` props:
133
-
134
- | Prop | Type | Default | Notes |
135
- | ------------- | ------------------------------------ | -------- | ------------------------------------ |
136
- | `formSchema` | `SerializedExecutionFormSchema` | required | Drives field rendering |
137
- | `onSubmit` | `(input) => void | Promise<void>` | required | Called with mapped field values |
138
- | `isPending` | `boolean` | `false` | Shows loading state on submit button |
139
- | `disabled` | `boolean` | `false` | Disables all fields and button |
140
- | `submitLabel` | `string` | `'Run'` | Button label when not pending |
141
-
142
- ---
143
-
144
- ## Low-Level: Hooks and `ExecuteWorkflowModal`
145
-
146
- For complete rendering control, use `useExecuteAsync` and `ExecuteWorkflowModal` independently. `ExecuteWorkflowModal` is a Mantine Modal pre-wired with a loading overlay, a success card (execution ID + "View execution" button), and an error alert. You pass `children` for the input area.
147
-
148
- ```tsx
149
- import { ExecuteWorkflowModal } from '@elevasis/ui/features/operations'
150
- import { useExecuteAsync } from '@elevasis/ui/hooks'
151
-
152
- const { mutateAsync, isPending, error, data, reset } = useExecuteAsync()
153
-
154
- <ExecuteWorkflowModal
155
- opened={opened}
156
- onClose={() => setOpened(false)}
157
- resource={{ resourceId: 'my-workflow', resourceType: 'workflow', name: 'My Workflow' }}
158
- isPending={isPending}
159
- error={error}
160
- result={data ?? null}
161
- onViewExecution={handleViewExecution}
162
- onReset={reset}
163
- >
164
- {/* your custom form or content here */}
165
- </ExecuteWorkflowModal>
166
- ```
167
-
168
- The modal locks close interactions (click-outside, Escape, close button) while `isPending` is true, preventing accidental dismissal mid-execution.
169
-
170
- Source: `packages/ui/src/features/operations/executions/ExecuteWorkflowModal.tsx`, `packages/ui/src/hooks/executions/useExecuteAsync.ts`
171
-
172
- ---
173
-
174
- ## Zod-Validated Execution with `useExecuteWorkflow`
175
-
176
- `useExecuteWorkflow` wraps `useExecuteAsync` with a Zod parse step before the POST. Use it when you are constructing input programmatically (not from a form) and want to catch schema mismatches before they reach the API.
177
-
178
- ```tsx
179
- import { z } from 'zod'
180
- import { useExecuteWorkflow } from '@elevasis/ui/hooks'
181
-
182
- const inputSchema = z.object({
183
- email: z.string().email(),
184
- score: z.number().min(0).max(100),
185
- })
186
-
187
- function useScoredExecution() {
188
- return useExecuteWorkflow({ schema: inputSchema })
189
- }
190
-
191
- // In a component:
192
- const { execute, isPending, data, error } = useScoredExecution()
193
-
194
- await execute({
195
- resourceId: 'score-lead-workflow',
196
- resourceType: 'workflow',
197
- input: { email: 'lead@example.com', score: 72 },
198
- })
199
- ```
200
-
201
- If `input` fails the Zod parse, `execute` throws synchronously with the message `"Invalid workflow input: ..."` before making any network request. The `mutation` object on the return value is the underlying `useExecuteAsync` mutation, giving you full TanStack Query state if needed.
202
-
203
- Prefer `useExecuteWorkflow` over raw `useExecuteAsync` when:
204
-
205
- - Input is assembled from multiple sources (not a single form submit).
206
- - You want TypeScript inference on the input shape via `z.infer`.
207
- - You want a clear validation error message rather than a 400 from the API.
208
-
209
- Source: `packages/ui/src/hooks/executions/useExecuteWorkflow.ts`
210
-
211
- ---
212
-
213
- ## Input Forms
214
-
215
- `ResourceExecuteDialog` and `ResourceExecuteForm` auto-render form fields from `formSchema.fields`. Each field is a `SerializedFormField` with at minimum `name`, `label`, and `type`.
216
-
217
- Supported field types:
218
-
219
- - `text` -- single-line text input
220
- - `textarea` -- multi-line text input
221
- - `number` -- numeric input
222
- - `select` -- dropdown with `options` array
223
- - `checkbox` -- boolean toggle; defaults to `false`
224
- - `radio` -- radio group with `options` array
225
- - `richtext` -- rich text editor
226
-
227
- Required fields (`required: true`) are validated on submit. Custom field-to-input-key remapping is supported via `formSchema.fieldMappings` -- a `Record<string, string>` that renames field values before they are passed to `onSubmit`.
228
-
229
- If `formSchema` is undefined, an empty object, or has `fields: []`, the form skips rendering fields entirely and shows "This workflow takes no input." with a single Run button.
230
-
231
- ---
232
-
233
- ## Error and Result Handling
234
-
235
- Mutation state flows automatically into the modal chrome when using `ResourceExecuteDialog` or `ExecuteWorkflowModal`:
236
-
237
- - **Success** -- a teal alert card displays the execution ID from `result.executionId`. If `onViewExecution` is provided, a "View execution" button calls it with the ID. This is the recommended way to deep-link to the Execution Logs page.
238
- - **Error** -- a red alert displays `error.message`. A "Try again" button calls `onReset`, which clears the mutation state and re-shows the form.
239
- - **Pending** -- a blur overlay covers the form area while the POST is in flight. The modal cannot be dismissed during this state.
240
-
241
- `useExecuteAsync` also invalidates the executions list query on success (keyed by `organizationId` + `resourceId`), so any `useExecutions` query on the page refreshes automatically.
242
-
243
- ---
244
-
245
- ## Related
246
-
247
- - [REST API](api.mdx) -- trigger executions directly over HTTP, without React
248
- - [Command Center](command-center.mdx) -- built-in managed UI; includes Run buttons for all deployed resources
249
- - [Resource Patterns](../resources/patterns.mdx) -- HITL approval patterns and `approval.create()`
250
- - [Platform Adapters](../platform-tools/adapters-platform.mdx) -- `approval.create()` reference
1
+ ---
2
+ title: UI Execution
3
+ description: Trigger workflow and agent executions from a custom React UI -- Run buttons, input forms, and result displays via @elevasis/ui
4
+ loadWhen: "Building a custom UI that triggers resource executions (Run buttons, input forms)"
5
+ ---
6
+
7
+ `@elevasis/ui` ships a set of components and hooks that let your custom React pages trigger workflow and agent executions without wiring up API calls manually. This page is for template users building interactive resource pages in `external/_template` who want to add Run buttons, input forms, and execution result displays.
8
+
9
+ The API comes in three tiers: a convenience one-tag component that handles everything, a controlled form primitive for custom modal chrome, and low-level hooks for fully custom rendering. Most template pages need only the first tier.
10
+
11
+ ---
12
+
13
+ ## Quick Start -- `ResourceExecuteDialog`
14
+
15
+ `ResourceExecuteDialog` combines a modal shell, an input form, mutation state, and result display into a single component. Drop it next to a Button and you have a working Run dialog in about fifteen lines.
16
+
17
+ ```tsx
18
+ import { useState } from 'react'
19
+ import { Button } from '@mantine/core'
20
+ import { ResourceExecuteDialog } from '@elevasis/ui/features/operations'
21
+ import { useNavigate } from '@tanstack/react-router'
22
+
23
+ const resource = {
24
+ resourceId: 'qualify-lead-workflow',
25
+ resourceType: 'workflow' as const,
26
+ name: 'Qualify Lead',
27
+ formSchema: {
28
+ fields: [
29
+ { name: 'email', label: 'Lead email', type: 'text', required: true },
30
+ { name: 'company', label: 'Company', type: 'text', required: false },
31
+ ],
32
+ },
33
+ }
34
+
35
+ export function QualifyLeadPage() {
36
+ const [opened, setOpened] = useState(false)
37
+ const navigate = useNavigate()
38
+
39
+ return (
40
+ <>
41
+ <Button onClick={() => setOpened(true)}>Run</Button>
42
+
43
+ <ResourceExecuteDialog
44
+ opened={opened}
45
+ onClose={() => setOpened(false)}
46
+ resource={resource}
47
+ onViewExecution={(executionId) =>
48
+ navigate({ to: '/logs/$executionId', params: { executionId } })
49
+ }
50
+ />
51
+ </>
52
+ )
53
+ }
54
+ ```
55
+
56
+ What the user sees when they click Run:
57
+
58
+ - A modal opens titled "Run workflow" with the resource ID displayed.
59
+ - The form renders one field per entry in `formSchema.fields`. Required fields show validation errors on submit.
60
+ - On submit, a loading overlay appears while the POST is in flight.
61
+ - On success, a teal confirmation card shows the execution ID. A "View execution" button calls `onViewExecution` with that ID.
62
+ - On error, a red alert shows the error message with a "Try again" option.
63
+
64
+ If `formSchema` is omitted or has no fields, the form skips to a single "Run" button with the message "This workflow takes no input."
65
+
66
+ ---
67
+
68
+ ## The Three-Tier API
69
+
70
+ | Tier | Component / Hook | Use case |
71
+ | --------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------- |
72
+ | Convenience | `ResourceExecuteDialog` | One-tag Run button + modal + form. Parent only manages `opened` state. |
73
+ | Controlled form | `ResourceExecuteForm` | Custom modal chrome; parent owns the mutation and decides where to show results. |
74
+ | Low-level | `ExecuteWorkflowModal` + `useExecuteAsync` | Fully custom rendering, non-standard modal behavior, or composing execution into a larger flow. |
75
+
76
+ Start with `ResourceExecuteDialog`. Move down the tiers only when you need something the convenience component cannot do.
77
+
78
+ ---
79
+
80
+ ## Controlled Usage with `ResourceExecuteForm`
81
+
82
+ Use `ResourceExecuteForm` when you want to own the modal or display the result somewhere outside the dialog -- for example, rendering the execution ID inline on the page after submission.
83
+
84
+ `ResourceExecuteForm` accepts `onSubmit` and `isPending` from the parent. The parent calls `useExecuteAsync()` directly and passes `mutateAsync` as the submit handler.
85
+
86
+ ```tsx
87
+ import { useState } from 'react'
88
+ import { Modal, Button, Text } from '@mantine/core'
89
+ import { ResourceExecuteForm } from '@elevasis/ui/features/operations'
90
+ import { useExecuteAsync } from '@elevasis/ui/hooks'
91
+
92
+ const formSchema = {
93
+ fields: [
94
+ { name: 'topic', label: 'Topic', type: 'text', required: true },
95
+ ],
96
+ }
97
+
98
+ export function CustomRunPanel() {
99
+ const [opened, setOpened] = useState(false)
100
+ const mutation = useExecuteAsync()
101
+
102
+ const handleSubmit = async (input: Record<string, unknown>) => {
103
+ await mutation.mutateAsync({
104
+ resourceId: 'research-agent',
105
+ resourceType: 'agent',
106
+ input,
107
+ })
108
+ }
109
+
110
+ return (
111
+ <>
112
+ <Button onClick={() => setOpened(true)}>Run agent</Button>
113
+
114
+ {mutation.data && (
115
+ <Text size="sm">Started: {mutation.data.executionId}</Text>
116
+ )}
117
+
118
+ <Modal opened={opened} onClose={() => setOpened(false)} title="Run research agent">
119
+ <ResourceExecuteForm
120
+ formSchema={formSchema}
121
+ onSubmit={handleSubmit}
122
+ isPending={mutation.isPending}
123
+ disabled={mutation.isPending}
124
+ submitLabel="Start research"
125
+ />
126
+ </Modal>
127
+ </>
128
+ )
129
+ }
130
+ ```
131
+
132
+ `ResourceExecuteForm` props:
133
+
134
+ | Prop | Type | Default | Notes |
135
+ | ------------- | ------------------------------------ | -------- | ------------------------------------ |
136
+ | `formSchema` | `SerializedExecutionFormSchema` | required | Drives field rendering |
137
+ | `onSubmit` | `(input) => void | Promise<void>` | required | Called with mapped field values |
138
+ | `isPending` | `boolean` | `false` | Shows loading state on submit button |
139
+ | `disabled` | `boolean` | `false` | Disables all fields and button |
140
+ | `submitLabel` | `string` | `'Run'` | Button label when not pending |
141
+
142
+ ---
143
+
144
+ ## Low-Level: Hooks and `ExecuteWorkflowModal`
145
+
146
+ For complete rendering control, use `useExecuteAsync` and `ExecuteWorkflowModal` independently. `ExecuteWorkflowModal` is a Mantine Modal pre-wired with a loading overlay, a success card (execution ID + "View execution" button), and an error alert. You pass `children` for the input area.
147
+
148
+ ```tsx
149
+ import { ExecuteWorkflowModal } from '@elevasis/ui/features/operations'
150
+ import { useExecuteAsync } from '@elevasis/ui/hooks'
151
+
152
+ const { mutateAsync, isPending, error, data, reset } = useExecuteAsync()
153
+
154
+ <ExecuteWorkflowModal
155
+ opened={opened}
156
+ onClose={() => setOpened(false)}
157
+ resource={{ resourceId: 'my-workflow', resourceType: 'workflow', name: 'My Workflow' }}
158
+ isPending={isPending}
159
+ error={error}
160
+ result={data ?? null}
161
+ onViewExecution={handleViewExecution}
162
+ onReset={reset}
163
+ >
164
+ {/* your custom form or content here */}
165
+ </ExecuteWorkflowModal>
166
+ ```
167
+
168
+ The modal locks close interactions (click-outside, Escape, close button) while `isPending` is true, preventing accidental dismissal mid-execution.
169
+
170
+ Source: `packages/ui/src/features/operations/executions/ExecuteWorkflowModal.tsx`, `packages/ui/src/hooks/executions/useExecuteAsync.ts`
171
+
172
+ ---
173
+
174
+ ## Zod-Validated Execution with `useExecuteWorkflow`
175
+
176
+ `useExecuteWorkflow` wraps `useExecuteAsync` with a Zod parse step before the POST. Use it when you are constructing input programmatically (not from a form) and want to catch schema mismatches before they reach the API.
177
+
178
+ ```tsx
179
+ import { z } from 'zod'
180
+ import { useExecuteWorkflow } from '@elevasis/ui/hooks'
181
+
182
+ const inputSchema = z.object({
183
+ email: z.string().email(),
184
+ score: z.number().min(0).max(100),
185
+ })
186
+
187
+ function useScoredExecution() {
188
+ return useExecuteWorkflow({ schema: inputSchema })
189
+ }
190
+
191
+ // In a component:
192
+ const { execute, isPending, data, error } = useScoredExecution()
193
+
194
+ await execute({
195
+ resourceId: 'score-lead-workflow',
196
+ resourceType: 'workflow',
197
+ input: { email: 'lead@example.com', score: 72 },
198
+ })
199
+ ```
200
+
201
+ If `input` fails the Zod parse, `execute` throws synchronously with the message `"Invalid workflow input: ..."` before making any network request. The `mutation` object on the return value is the underlying `useExecuteAsync` mutation, giving you full TanStack Query state if needed.
202
+
203
+ Prefer `useExecuteWorkflow` over raw `useExecuteAsync` when:
204
+
205
+ - Input is assembled from multiple sources (not a single form submit).
206
+ - You want TypeScript inference on the input shape via `z.infer`.
207
+ - You want a clear validation error message rather than a 400 from the API.
208
+
209
+ Source: `packages/ui/src/hooks/executions/useExecuteWorkflow.ts`
210
+
211
+ ---
212
+
213
+ ## Input Forms
214
+
215
+ `ResourceExecuteDialog` and `ResourceExecuteForm` auto-render form fields from `formSchema.fields`. Each field is a `SerializedFormField` with at minimum `name`, `label`, and `type`.
216
+
217
+ Supported field types:
218
+
219
+ - `text` -- single-line text input
220
+ - `textarea` -- multi-line text input
221
+ - `number` -- numeric input
222
+ - `select` -- dropdown with `options` array
223
+ - `checkbox` -- boolean toggle; defaults to `false`
224
+ - `radio` -- radio group with `options` array
225
+ - `richtext` -- rich text editor
226
+
227
+ Required fields (`required: true`) are validated on submit. Custom field-to-input-key remapping is supported via `formSchema.fieldMappings` -- a `Record<string, string>` that renames field values before they are passed to `onSubmit`.
228
+
229
+ If `formSchema` is undefined, an empty object, or has `fields: []`, the form skips rendering fields entirely and shows "This workflow takes no input." with a single Run button.
230
+
231
+ ---
232
+
233
+ ## Error and Result Handling
234
+
235
+ Mutation state flows automatically into the modal chrome when using `ResourceExecuteDialog` or `ExecuteWorkflowModal`:
236
+
237
+ - **Success** -- a teal alert card displays the execution ID from `result.executionId`. If `onViewExecution` is provided, a "View execution" button calls it with the ID. This is the recommended way to deep-link to the Execution Logs page.
238
+ - **Error** -- a red alert displays `error.message`. A "Try again" button calls `onReset`, which clears the mutation state and re-shows the form.
239
+ - **Pending** -- a blur overlay covers the form area while the POST is in flight. The modal cannot be dismissed during this state.
240
+
241
+ `useExecuteAsync` also invalidates the executions list query on success (keyed by `organizationId` + `resourceId`), so any `useExecutions` query on the page refreshes automatically.
242
+
243
+ ---
244
+
245
+ ## Related
246
+
247
+ - [REST API](api.mdx) -- trigger executions directly over HTTP, without React
248
+ - [Command Center](command-center.mdx) -- built-in managed UI; includes Run buttons for all deployed resources
249
+ - [Resource Patterns](../resources/patterns.mdx) -- HITL approval patterns and `approval.create()`
250
+ - [Platform Adapters](../platform-tools/adapters-platform.mdx) -- `approval.create()` reference