@elevasis/sdk 1.25.0 → 1.26.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 (60) hide show
  1. package/dist/cli.cjs +18 -116
  2. package/dist/index.d.ts +165 -48
  3. package/dist/index.js +4 -435
  4. package/dist/node/index.d.ts +36 -36
  5. package/dist/test-utils/index.d.ts +99 -38
  6. package/dist/test-utils/index.js +27 -355
  7. package/dist/types/worker/adapters/clickup.d.ts +22 -0
  8. package/dist/types/worker/adapters/index.d.ts +1 -0
  9. package/dist/worker/index.js +32 -354
  10. package/package.json +2 -2
  11. package/reference/_navigation.md +11 -1
  12. package/reference/_reference-manifest.json +70 -0
  13. package/reference/claude-config/rules/organization-model.md +12 -1
  14. package/reference/claude-config/rules/organization-os.md +12 -1
  15. package/reference/claude-config/skills/om/SKILL.md +13 -5
  16. package/reference/claude-config/skills/om/operations/codify-level-a.md +109 -100
  17. package/reference/claude-config/skills/om/operations/customers.md +10 -6
  18. package/reference/claude-config/skills/om/operations/features.md +7 -3
  19. package/reference/claude-config/skills/om/operations/goals.md +10 -6
  20. package/reference/claude-config/skills/om/operations/identity.md +8 -5
  21. package/reference/claude-config/skills/om/operations/labels.md +17 -1
  22. package/reference/claude-config/skills/om/operations/offerings.md +11 -7
  23. package/reference/claude-config/skills/om/operations/roles.md +11 -7
  24. package/reference/claude-config/skills/om/operations/techStack.md +10 -2
  25. package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +32 -0
  26. package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +43 -0
  27. package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +40 -0
  28. package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +61 -0
  29. package/reference/cli-management.mdx +539 -0
  30. package/reference/cli.mdx +4 -532
  31. package/reference/concepts.mdx +134 -146
  32. package/reference/deployment/api.mdx +296 -297
  33. package/reference/deployment/command-center.mdx +208 -209
  34. package/reference/deployment/index.mdx +194 -195
  35. package/reference/deployment/provided-features.mdx +110 -107
  36. package/reference/deployment/ui-execution.mdx +249 -250
  37. package/reference/framework/index.mdx +111 -195
  38. package/reference/framework/resource-documentation.mdx +90 -0
  39. package/reference/framework/tutorial-system.mdx +135 -135
  40. package/reference/getting-started.mdx +141 -142
  41. package/reference/index.mdx +95 -106
  42. package/reference/packages/ui/src/auth/README.md +6 -6
  43. package/reference/platform-tools/adapters-integration.mdx +300 -301
  44. package/reference/platform-tools/adapters-platform.mdx +552 -553
  45. package/reference/platform-tools/index.mdx +216 -217
  46. package/reference/platform-tools/type-safety.mdx +82 -82
  47. package/reference/resources/index.mdx +348 -349
  48. package/reference/resources/patterns.mdx +446 -449
  49. package/reference/resources/types.mdx +115 -116
  50. package/reference/roadmap.mdx +164 -165
  51. package/reference/rules/organization-model.md +14 -0
  52. package/reference/runtime.mdx +172 -173
  53. package/reference/scaffold/operations/propagation-pipeline.md +1 -1
  54. package/reference/scaffold/recipes/extend-lead-gen.md +130 -77
  55. package/reference/scaffold/reference/contracts.md +376 -446
  56. package/reference/scaffold/reference/glossary.md +8 -6
  57. package/reference/scaffold/ui/feature-flags-and-gating.md +59 -46
  58. package/reference/scaffold/ui/feature-shell.mdx +11 -11
  59. package/reference/scaffold/ui/recipes.md +24 -24
  60. package/reference/troubleshooting.mdx +222 -223
@@ -1,349 +1,348 @@
1
- ---
2
- title: Writing Resources
3
- description: Guide to creating descriptor-backed workflows and agents with the Elevasis SDK
4
- loadWhen: "Building or modifying a workflow"
5
- ---
6
-
7
- Resources are the building blocks of your Elevasis project. Resource identity and governance metadata live in the Organization Model under the id-keyed `organizationModel.resources` map; operations code imports those descriptors, attaches executable workflow or agent behavior, and exports a `DeploymentSpec` for deployment.
8
-
9
- This page covers how to structure executable resources, derive runtime IDs from OM descriptors, write step handlers, and assemble the deployment spec without creating a second identity catalog.
10
-
11
- ## WorkflowDefinition
12
-
13
- A workflow is a series of named steps executed in sequence or branching paths. You define it with a `WorkflowDefinition` object.
14
-
15
- A complete workflow definition has four required properties:
16
-
17
- - `config` - metadata about the workflow (name, description, status)
18
- - `contract` - Zod schemas for input and output validation
19
- - `steps` - a record of named step handlers
20
- - `entryPoint` - the name of the first step to execute
21
-
22
- ### Minimal Example
23
-
24
- ```typescript
25
- import { z } from 'zod';
26
- import type { WorkflowDefinition } from '@elevasis/sdk';
27
- import { resourceDescriptors } from '@core/config/organization-model';
28
-
29
- const echoInput = z.object({
30
- message: z.string(),
31
- });
32
-
33
- const echoOutput = z.object({
34
- result: z.string(),
35
- });
36
-
37
- type EchoInput = z.infer<typeof echoInput>;
38
-
39
- const echoWorkflow: WorkflowDefinition = {
40
- config: {
41
- resource: resourceDescriptors.echo,
42
- resourceId: resourceDescriptors.echo.id,
43
- name: 'Echo',
44
- type: resourceDescriptors.echo.kind,
45
- description: 'Returns the input message unchanged',
46
- version: '1.0.0',
47
- status: 'dev',
48
- },
49
- contract: {
50
- inputSchema: echoInput,
51
- outputSchema: echoOutput,
52
- },
53
- steps: {
54
- run: {
55
- id: 'run',
56
- name: 'Run',
57
- description: 'Returns the input message unchanged',
58
- handler: async (input) => {
59
- const { message } = input as EchoInput;
60
- return { result: message };
61
- },
62
- inputSchema: echoInput,
63
- outputSchema: echoOutput,
64
- next: null,
65
- },
66
- },
67
- entryPoint: 'run',
68
- };
69
- ```
70
-
71
- ### config
72
-
73
- The `config` block binds executable behavior to the OM resource descriptor:
74
-
75
- | Field | Type | Description |
76
- | ------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
77
- | `resource` | `ResourceEntry` | OM descriptor from `core/config/organization-model.ts`; owns stable identity, kind, system membership, ownership, and status. |
78
- | `resourceId` | `string` | Derived from `resource.id`. Used by runtime invocation, CLI targeting, execution logs, and dashboard links. Do not invent it here. |
79
- | `name` | `string` | Human-readable display name shown in the dashboard. |
80
- | `type` | `'workflow'` | Derived from `resource.kind` for workflow resources. |
81
- | `description` | `string` | Summary shown in the dashboard and command center. |
82
- | `version` | `string` | Semver string (e.g., `'1.0.0'`). Increment when making breaking changes to the contract. |
83
- | `status` | `'dev' | 'prod'` | Controls runtime availability. Use `'dev'` while building. See [Resource Status](#resource-status). |
84
- | `domains` | `string[]` | Optional. Groups resources in the command center view. |
85
-
86
- ### contract
87
-
88
- The `contract` block defines the Zod schemas for input and output. The platform validates input against `contract.inputSchema` before passing it to your entry step handler, and validates the final step's return value against `contract.outputSchema`.
89
-
90
- Always use `z.object()` for both schemas. Use `z.infer` to derive TypeScript types -- this keeps types and runtime validation in sync automatically.
91
-
92
- ```typescript
93
- const contract = {
94
- inputSchema: z.object({
95
- userId: z.string().uuid(),
96
- action: z.string(),
97
- }),
98
- outputSchema: z.object({
99
- success: z.boolean(),
100
- message: z.string(),
101
- }),
102
- };
103
- ```
104
-
105
- ### steps
106
-
107
- The `steps` record maps step IDs to step objects. Each step has metadata (`id`, `name`, `description`), a `handler` function, Zod schemas for its own input and output, and a `next` property that controls routing.
108
-
109
- ```typescript
110
- const steps = {
111
- validate: {
112
- id: 'validate',
113
- name: 'Validate',
114
- description: 'Validates the incoming request',
115
- handler: async (input: MyInput) => {
116
- return { validated: true, data: input };
117
- },
118
- inputSchema: myInputSchema,
119
- outputSchema: z.object({ validated: z.boolean(), data: myInputSchema }),
120
- next: { type: 'linear', target: 'process' }, // points to the next step
121
- },
122
- process: {
123
- id: 'process',
124
- name: 'Process',
125
- description: 'Processes the validated data',
126
- handler: async (input: ValidatedData) => {
127
- return { result: 'done' };
128
- },
129
- inputSchema: z.object({ validated: z.boolean(), data: myInputSchema }),
130
- outputSchema: z.object({ result: z.string() }),
131
- next: null, // terminal step
132
- },
133
- };
134
- ```
135
-
136
- ### entryPoint
137
-
138
- `entryPoint` is the name of the first step. For single-step workflows it is always the only step name. For multi-step workflows it is the name of the first step in the chain.
139
-
140
- ```typescript
141
- const workflow: WorkflowDefinition = {
142
- // ...
143
- entryPoint: 'validate', // execution starts here
144
- };
145
- ```
146
-
147
- ---
148
-
149
- ## Multi-Step Workflows
150
-
151
- For workflows with more than one step, import `StepType` from `@elevasis/sdk` to configure step routing.
152
-
153
- ### Linear Steps
154
-
155
- Use `StepType.LINEAR` to connect steps in a fixed sequence. Each step declares a `next` property pointing to the next step name.
156
-
157
- ```typescript
158
- import { z } from 'zod';
159
- import type { WorkflowDefinition, WorkflowStep } from '@elevasis/sdk';
160
-
161
- const fetchStep: WorkflowStep = {
162
- id: 'fetch',
163
- name: 'Fetch',
164
- description: 'Fetches the raw data',
165
- handler: async (input) => {
166
- const data = await fetchSomething((input as { id: string }).id);
167
- return { data };
168
- },
169
- inputSchema: z.object({ id: z.string() }),
170
- outputSchema: z.object({ data: z.unknown() }),
171
- next: { type: 'linear', target: 'process' },
172
- };
173
-
174
- const processStep: WorkflowStep = {
175
- id: 'process',
176
- name: 'Process',
177
- description: 'Transforms the fetched data',
178
- handler: async (input) => {
179
- return { result: transform((input as { data: unknown }).data) };
180
- },
181
- inputSchema: z.object({ data: z.unknown() }),
182
- outputSchema: z.object({ result: z.string() }),
183
- next: null, // terminal step
184
- };
185
-
186
- const pipeline: WorkflowDefinition = {
187
- config: {
188
- resourceId: 'pipeline',
189
- name: 'Pipeline',
190
- type: 'workflow',
191
- description: 'Fetch then process',
192
- version: '1.0.0',
193
- status: 'dev',
194
- },
195
- contract: { inputSchema: pipelineInput, outputSchema: pipelineOutput },
196
- steps: { fetch: fetchStep, process: processStep },
197
- entryPoint: 'fetch',
198
- };
199
- ```
200
-
201
- ### Conditional Branching
202
-
203
- Use `StepType.CONDITIONAL` to route to different steps based on output values. Each route has a `condition` function and a `target` step name. The first condition that returns `true` wins. A `default` fallback step is required.
204
-
205
- ```typescript
206
- import { z } from 'zod';
207
- import type { WorkflowStep } from '@elevasis/sdk';
208
-
209
- const routerStep: WorkflowStep = {
210
- id: 'router',
211
- name: 'Router',
212
- description: 'Scores the input and routes to the appropriate path',
213
- handler: async (input) => {
214
- const score = await evaluate(input);
215
- return { score };
216
- },
217
- inputSchema: z.object({ value: z.unknown() }),
218
- outputSchema: z.object({ score: z.number() }),
219
- next: {
220
- type: 'conditional',
221
- routes: [
222
- {
223
- condition: (output) => (output as { score: number }).score \>= 80,
224
- target: 'highScorePath',
225
- },
226
- {
227
- condition: (output) => (output as { score: number }).score \>= 50,
228
- target: 'mediumScorePath',
229
- },
230
- ],
231
- default: 'lowScorePath',
232
- },
233
- };
234
- ```
235
-
236
- ---
237
-
238
- ## StepContext
239
-
240
- Every step handler can optionally accept a second `context` parameter. TypeScript allows you to omit it if you do not need it -- you can write `handler: async (input) => { ... }` without declaring `context`.
241
-
242
- When you do need it, the context provides runtime metadata:
243
-
244
- ```typescript
245
- import type { StepHandler } from '@elevasis/sdk';
246
-
247
- const myStep: StepHandler = async (input, context) => {
248
- const { executionId, organizationId, resourceId, logger, store } = context;
249
-
250
- logger.info('Starting step', { executionId });
251
-
252
- // store is a simple key-value store scoped to this execution
253
- await store.set('progress', '50%');
254
-
255
- return { done: true };
256
- };
257
- ```
258
-
259
- | Field | Type | Description |
260
- | ---------------- | -------- | -------------------------------------------------------------- |
261
- | `executionId` | `string` | Unique ID for this execution run |
262
- | `organizationId` | `string` | Your organization ID |
263
- | `resourceId` | `string` | ID of the workflow or agent being executed |
264
- | `logger` | `Logger` | Structured logger -- messages appear in the Elevasis dashboard |
265
- | `store` | `Store` | Key-value store scoped to the current execution |
266
-
267
- ---
268
-
269
- ## AgentDefinition
270
-
271
- Agents are autonomous resources that use an LLM and tools to complete a goal. You define them with `AgentDefinition`.
272
-
273
- **Note:** Use `elevasis-sdk exec --async` when executing agents. Agents can run for minutes or longer, and the synchronous execute endpoint will time out for long-running runs. The `--async` flag returns an execution ID immediately and polls for the result.
274
-
275
- ```typescript
276
- import type { AgentDefinition } from '@elevasis/sdk';
277
- import { resourceDescriptors } from '@core/config/organization-model';
278
-
279
- const myAgent: AgentDefinition = {
280
- config: {
281
- resource: resourceDescriptors.myAgent,
282
- resourceId: resourceDescriptors.myAgent.id,
283
- name: 'my-agent',
284
- type: resourceDescriptors.myAgent.kind,
285
- description: 'Answers questions using platform tools',
286
- status: 'dev',
287
- },
288
- agentConfig: {
289
- model: { provider: 'openai', model: 'gpt-4o' },
290
- systemPrompt: 'You are a helpful assistant.',
291
- maxIterations: 10,
292
- },
293
- tools: [],
294
- };
295
- ```
296
-
297
- ---
298
-
299
- ## DeploymentSpec
300
-
301
- All executable resources must be assembled through a `DeploymentSpec` default export from `operations/src/index.ts`. This is the entry point the platform reads when you deploy. Include the Organization Model payload so the validator can compare code-backed resources against OM descriptors.
302
-
303
- ```typescript
304
- import type { DeploymentSpec } from '@elevasis/sdk';
305
- import { resourceGovernanceModel } from '@core/config/organization-model';
306
-
307
- const org: DeploymentSpec = {
308
- version: '0.1.0',
309
- organizationModel: resourceGovernanceModel,
310
- workflows: [echoWorkflow, pipeline],
311
- agents: [
312
- // myAgent,
313
- ],
314
- };
315
-
316
- export default org;
317
- ```
318
-
319
- Each resource's `config.resourceId` is still the deployed runtime identifier. The important authoring rule is that `config.resourceId` derives from the OM descriptor (`resource.id`) instead of being duplicated by hand.
320
-
321
- ### Resource Status
322
-
323
- Set `config.status` to control whether the platform accepts execution requests:
324
-
325
- - `'dev'` - Resource is visible in the dashboard but the platform will not route scheduled or webhook-triggered executions to it. You can still trigger it manually via `elevasis-sdk exec`.
326
- - `'prod'` - Resource is live and accepts all execution sources.
327
-
328
- Use `'dev'` while you are building and testing. Switch to `'prod'` when you are ready to go live.
329
-
330
- You can also set a global default status in `elevasis.config.ts`:
331
-
332
- ```typescript
333
- import type { ElevasConfig } from '@elevasis/sdk';
334
-
335
- const config: ElevasConfig = {
336
- defaultStatus: 'dev',
337
- };
338
-
339
- export default config;
340
- ```
341
-
342
- ## Documentation
343
-
344
- - [SDK Types](types.mdx) - Complete type reference for `@elevasis/sdk` exports, config, and step handler context
345
- - [Common Patterns](patterns.mdx) - Sequential steps, conditional branching, error handling, and resource status patterns
346
-
347
- ---
348
-
349
- **Last Updated:** 2026-02-25
1
+ ---
2
+ title: Writing Resources
3
+ description: Guide to creating descriptor-backed workflows and agents with the Elevasis SDK
4
+ ---
5
+
6
+ Resources are the building blocks of your Elevasis project. Resource identity and governance metadata live in the Organization Model under the id-keyed `organizationModel.resources` map; operations code imports those descriptors, attaches executable workflow or agent behavior, and exports a `DeploymentSpec` for deployment.
7
+
8
+ This page covers how to structure executable resources, derive runtime IDs from OM descriptors, write step handlers, and assemble the deployment spec without creating a second identity catalog.
9
+
10
+ ## WorkflowDefinition
11
+
12
+ A workflow is a series of named steps executed in sequence or branching paths. You define it with a `WorkflowDefinition` object.
13
+
14
+ A complete workflow definition has four required properties:
15
+
16
+ - `config` - metadata about the workflow (name, description, status)
17
+ - `contract` - Zod schemas for input and output validation
18
+ - `steps` - a record of named step handlers
19
+ - `entryPoint` - the name of the first step to execute
20
+
21
+ ### Minimal Example
22
+
23
+ ```typescript
24
+ import { z } from 'zod';
25
+ import type { WorkflowDefinition } from '@elevasis/sdk';
26
+ import { resourceDescriptors } from '@core/config/organization-model';
27
+
28
+ const echoInput = z.object({
29
+ message: z.string(),
30
+ });
31
+
32
+ const echoOutput = z.object({
33
+ result: z.string(),
34
+ });
35
+
36
+ type EchoInput = z.infer<typeof echoInput>;
37
+
38
+ const echoWorkflow: WorkflowDefinition = {
39
+ config: {
40
+ resource: resourceDescriptors.echo,
41
+ resourceId: resourceDescriptors.echo.id,
42
+ name: 'Echo',
43
+ type: resourceDescriptors.echo.kind,
44
+ description: 'Returns the input message unchanged',
45
+ version: '1.0.0',
46
+ status: 'dev',
47
+ },
48
+ contract: {
49
+ inputSchema: echoInput,
50
+ outputSchema: echoOutput,
51
+ },
52
+ steps: {
53
+ run: {
54
+ id: 'run',
55
+ name: 'Run',
56
+ description: 'Returns the input message unchanged',
57
+ handler: async (input) => {
58
+ const { message } = input as EchoInput;
59
+ return { result: message };
60
+ },
61
+ inputSchema: echoInput,
62
+ outputSchema: echoOutput,
63
+ next: null,
64
+ },
65
+ },
66
+ entryPoint: 'run',
67
+ };
68
+ ```
69
+
70
+ ### config
71
+
72
+ The `config` block binds executable behavior to the OM resource descriptor:
73
+
74
+ | Field | Type | Description |
75
+ | ------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
76
+ | `resource` | `ResourceEntry` | OM descriptor from `core/config/organization-model.ts`; owns stable identity, kind, system membership, ownership, and status. |
77
+ | `resourceId` | `string` | Derived from `resource.id`. Used by runtime invocation, CLI targeting, execution logs, and dashboard links. Do not invent it here. |
78
+ | `name` | `string` | Human-readable display name shown in the dashboard. |
79
+ | `type` | `'workflow'` | Derived from `resource.kind` for workflow resources. |
80
+ | `description` | `string` | Summary shown in the dashboard and command center. |
81
+ | `version` | `string` | Semver string (e.g., `'1.0.0'`). Increment when making breaking changes to the contract. |
82
+ | `status` | `'dev' | 'prod'` | Controls runtime availability. Use `'dev'` while building. See [Resource Status](#resource-status). |
83
+ | `domains` | `string[]` | Optional. Groups resources in the command center view. |
84
+
85
+ ### contract
86
+
87
+ The `contract` block defines the Zod schemas for input and output. The platform validates input against `contract.inputSchema` before passing it to your entry step handler, and validates the final step's return value against `contract.outputSchema`.
88
+
89
+ Always use `z.object()` for both schemas. Use `z.infer` to derive TypeScript types -- this keeps types and runtime validation in sync automatically.
90
+
91
+ ```typescript
92
+ const contract = {
93
+ inputSchema: z.object({
94
+ userId: z.string().uuid(),
95
+ action: z.string(),
96
+ }),
97
+ outputSchema: z.object({
98
+ success: z.boolean(),
99
+ message: z.string(),
100
+ }),
101
+ };
102
+ ```
103
+
104
+ ### steps
105
+
106
+ The `steps` record maps step IDs to step objects. Each step has metadata (`id`, `name`, `description`), a `handler` function, Zod schemas for its own input and output, and a `next` property that controls routing.
107
+
108
+ ```typescript
109
+ const steps = {
110
+ validate: {
111
+ id: 'validate',
112
+ name: 'Validate',
113
+ description: 'Validates the incoming request',
114
+ handler: async (input: MyInput) => {
115
+ return { validated: true, data: input };
116
+ },
117
+ inputSchema: myInputSchema,
118
+ outputSchema: z.object({ validated: z.boolean(), data: myInputSchema }),
119
+ next: { type: 'linear', target: 'process' }, // points to the next step
120
+ },
121
+ process: {
122
+ id: 'process',
123
+ name: 'Process',
124
+ description: 'Processes the validated data',
125
+ handler: async (input: ValidatedData) => {
126
+ return { result: 'done' };
127
+ },
128
+ inputSchema: z.object({ validated: z.boolean(), data: myInputSchema }),
129
+ outputSchema: z.object({ result: z.string() }),
130
+ next: null, // terminal step
131
+ },
132
+ };
133
+ ```
134
+
135
+ ### entryPoint
136
+
137
+ `entryPoint` is the name of the first step. For single-step workflows it is always the only step name. For multi-step workflows it is the name of the first step in the chain.
138
+
139
+ ```typescript
140
+ const workflow: WorkflowDefinition = {
141
+ // ...
142
+ entryPoint: 'validate', // execution starts here
143
+ };
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Multi-Step Workflows
149
+
150
+ For workflows with more than one step, import `StepType` from `@elevasis/sdk` to configure step routing.
151
+
152
+ ### Linear Steps
153
+
154
+ Use `StepType.LINEAR` to connect steps in a fixed sequence. Each step declares a `next` property pointing to the next step name.
155
+
156
+ ```typescript
157
+ import { z } from 'zod';
158
+ import type { WorkflowDefinition, WorkflowStep } from '@elevasis/sdk';
159
+
160
+ const fetchStep: WorkflowStep = {
161
+ id: 'fetch',
162
+ name: 'Fetch',
163
+ description: 'Fetches the raw data',
164
+ handler: async (input) => {
165
+ const data = await fetchSomething((input as { id: string }).id);
166
+ return { data };
167
+ },
168
+ inputSchema: z.object({ id: z.string() }),
169
+ outputSchema: z.object({ data: z.unknown() }),
170
+ next: { type: 'linear', target: 'process' },
171
+ };
172
+
173
+ const processStep: WorkflowStep = {
174
+ id: 'process',
175
+ name: 'Process',
176
+ description: 'Transforms the fetched data',
177
+ handler: async (input) => {
178
+ return { result: transform((input as { data: unknown }).data) };
179
+ },
180
+ inputSchema: z.object({ data: z.unknown() }),
181
+ outputSchema: z.object({ result: z.string() }),
182
+ next: null, // terminal step
183
+ };
184
+
185
+ const pipeline: WorkflowDefinition = {
186
+ config: {
187
+ resourceId: 'pipeline',
188
+ name: 'Pipeline',
189
+ type: 'workflow',
190
+ description: 'Fetch then process',
191
+ version: '1.0.0',
192
+ status: 'dev',
193
+ },
194
+ contract: { inputSchema: pipelineInput, outputSchema: pipelineOutput },
195
+ steps: { fetch: fetchStep, process: processStep },
196
+ entryPoint: 'fetch',
197
+ };
198
+ ```
199
+
200
+ ### Conditional Branching
201
+
202
+ Use `StepType.CONDITIONAL` to route to different steps based on output values. Each route has a `condition` function and a `target` step name. The first condition that returns `true` wins. A `default` fallback step is required.
203
+
204
+ ```typescript
205
+ import { z } from 'zod';
206
+ import type { WorkflowStep } from '@elevasis/sdk';
207
+
208
+ const routerStep: WorkflowStep = {
209
+ id: 'router',
210
+ name: 'Router',
211
+ description: 'Scores the input and routes to the appropriate path',
212
+ handler: async (input) => {
213
+ const score = await evaluate(input);
214
+ return { score };
215
+ },
216
+ inputSchema: z.object({ value: z.unknown() }),
217
+ outputSchema: z.object({ score: z.number() }),
218
+ next: {
219
+ type: 'conditional',
220
+ routes: [
221
+ {
222
+ condition: (output) => (output as { score: number }).score \>= 80,
223
+ target: 'highScorePath',
224
+ },
225
+ {
226
+ condition: (output) => (output as { score: number }).score \>= 50,
227
+ target: 'mediumScorePath',
228
+ },
229
+ ],
230
+ default: 'lowScorePath',
231
+ },
232
+ };
233
+ ```
234
+
235
+ ---
236
+
237
+ ## StepContext
238
+
239
+ Every step handler can optionally accept a second `context` parameter. TypeScript allows you to omit it if you do not need it -- you can write `handler: async (input) => { ... }` without declaring `context`.
240
+
241
+ When you do need it, the context provides runtime metadata:
242
+
243
+ ```typescript
244
+ import type { StepHandler } from '@elevasis/sdk';
245
+
246
+ const myStep: StepHandler = async (input, context) => {
247
+ const { executionId, organizationId, resourceId, logger, store } = context;
248
+
249
+ logger.info('Starting step', { executionId });
250
+
251
+ // store is a simple key-value store scoped to this execution
252
+ await store.set('progress', '50%');
253
+
254
+ return { done: true };
255
+ };
256
+ ```
257
+
258
+ | Field | Type | Description |
259
+ | ---------------- | -------- | -------------------------------------------------------------- |
260
+ | `executionId` | `string` | Unique ID for this execution run |
261
+ | `organizationId` | `string` | Your organization ID |
262
+ | `resourceId` | `string` | ID of the workflow or agent being executed |
263
+ | `logger` | `Logger` | Structured logger -- messages appear in the Elevasis dashboard |
264
+ | `store` | `Store` | Key-value store scoped to the current execution |
265
+
266
+ ---
267
+
268
+ ## AgentDefinition
269
+
270
+ Agents are autonomous resources that use an LLM and tools to complete a goal. You define them with `AgentDefinition`.
271
+
272
+ **Note:** Use `elevasis-sdk exec --async` when executing agents. Agents can run for minutes or longer, and the synchronous execute endpoint will time out for long-running runs. The `--async` flag returns an execution ID immediately and polls for the result.
273
+
274
+ ```typescript
275
+ import type { AgentDefinition } from '@elevasis/sdk';
276
+ import { resourceDescriptors } from '@core/config/organization-model';
277
+
278
+ const myAgent: AgentDefinition = {
279
+ config: {
280
+ resource: resourceDescriptors.myAgent,
281
+ resourceId: resourceDescriptors.myAgent.id,
282
+ name: 'my-agent',
283
+ type: resourceDescriptors.myAgent.kind,
284
+ description: 'Answers questions using platform tools',
285
+ status: 'dev',
286
+ },
287
+ agentConfig: {
288
+ model: { provider: 'openai', model: 'gpt-4o' },
289
+ systemPrompt: 'You are a helpful assistant.',
290
+ maxIterations: 10,
291
+ },
292
+ tools: [],
293
+ };
294
+ ```
295
+
296
+ ---
297
+
298
+ ## DeploymentSpec
299
+
300
+ All executable resources must be assembled through a `DeploymentSpec` default export from `operations/src/index.ts`. This is the entry point the platform reads when you deploy. Include the Organization Model payload so the validator can compare code-backed resources against OM descriptors.
301
+
302
+ ```typescript
303
+ import type { DeploymentSpec } from '@elevasis/sdk';
304
+ import { resourceGovernanceModel } from '@core/config/organization-model';
305
+
306
+ const org: DeploymentSpec = {
307
+ version: '0.1.0',
308
+ organizationModel: resourceGovernanceModel,
309
+ workflows: [echoWorkflow, pipeline],
310
+ agents: [
311
+ // myAgent,
312
+ ],
313
+ };
314
+
315
+ export default org;
316
+ ```
317
+
318
+ Each resource's `config.resourceId` is still the deployed runtime identifier. The important authoring rule is that `config.resourceId` derives from the OM descriptor (`resource.id`) instead of being duplicated by hand.
319
+
320
+ ### Resource Status
321
+
322
+ Set `config.status` to control whether the platform accepts execution requests:
323
+
324
+ - `'dev'` - Resource is visible in the dashboard but the platform will not route scheduled or webhook-triggered executions to it. You can still trigger it manually via `elevasis-sdk exec`.
325
+ - `'prod'` - Resource is live and accepts all execution sources.
326
+
327
+ Use `'dev'` while you are building and testing. Switch to `'prod'` when you are ready to go live.
328
+
329
+ You can also set a global default status in `elevasis.config.ts`:
330
+
331
+ ```typescript
332
+ import type { ElevasConfig } from '@elevasis/sdk';
333
+
334
+ const config: ElevasConfig = {
335
+ defaultStatus: 'dev',
336
+ };
337
+
338
+ export default config;
339
+ ```
340
+
341
+ ## Documentation
342
+
343
+ - [SDK Types](types.mdx) - Complete type reference for `@elevasis/sdk` exports, config, and step handler context
344
+ - [Common Patterns](patterns.mdx) - Sequential steps, conditional branching, error handling, and resource status patterns
345
+
346
+ ---
347
+
348
+ **Last Updated:** 2026-02-25