@elevasis/sdk 1.44.2 → 1.45.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 (245) hide show
  1. package/dist/cli.cjs +1001 -652
  2. package/dist/index.d.ts +1045 -509
  3. package/dist/index.js +748 -690
  4. package/dist/node/index.d.ts +105 -97
  5. package/dist/test-utils/index.d.ts +42 -28
  6. package/dist/test-utils/index.js +549 -732
  7. package/dist/worker/index.d.ts +12112 -0
  8. package/dist/worker/index.js +211 -186
  9. package/package.json +6 -9
  10. package/reference/_navigation.md +151 -21
  11. package/reference/_reference-manifest.json +186 -4
  12. package/reference/claude-config.md +8 -0
  13. package/reference/core/index.mdx +3 -3
  14. package/reference/examples/organization-model.ts +117 -111
  15. package/reference/index.mdx +4 -4
  16. package/reference/rules/active-change-index.md +40 -54
  17. package/reference/rules/agent-runtime.md +81 -0
  18. package/reference/rules/agent-start-here.md +71 -163
  19. package/reference/rules/deployment.md +33 -10
  20. package/reference/rules/error-handling.md +26 -0
  21. package/reference/rules/execution.md +13 -0
  22. package/reference/rules/frontend.md +10 -3
  23. package/reference/rules/observability.md +9 -1
  24. package/reference/rules/operations.md +26 -17
  25. package/reference/rules/organization-model.md +74 -88
  26. package/reference/rules/organization-os.md +71 -88
  27. package/reference/rules/package-taxonomy.md +11 -2
  28. package/reference/rules/platform.md +13 -7
  29. package/reference/rules/shared-types.md +15 -0
  30. package/reference/rules/task-tracking.md +30 -5
  31. package/reference/rules/ui.md +145 -3
  32. package/reference/rules/vibe-intents.md +271 -0
  33. package/reference/rules/vibe.md +17 -243
  34. package/reference/scaffold/core/organization-graph.mdx +111 -97
  35. package/reference/scaffold/core/organization-model.mdx +234 -214
  36. package/reference/scaffold/operations/propagation-pipeline.md +1 -1
  37. package/reference/scaffold/operations/scaffold-maintenance.md +19 -18
  38. package/reference/scaffold/operations/workflow-recipes.md +71 -19
  39. package/reference/scaffold/recipes/add-a-feature.md +156 -146
  40. package/reference/scaffold/recipes/add-a-resource.md +123 -117
  41. package/reference/scaffold/recipes/customize-crm-actions.md +25 -10
  42. package/reference/scaffold/recipes/customize-knowledge-browser.md +52 -117
  43. package/reference/scaffold/recipes/customize-organization-model.md +161 -149
  44. package/reference/scaffold/recipes/extend-a-base-entity.md +156 -140
  45. package/reference/scaffold/recipes/extend-crm.md +16 -11
  46. package/reference/scaffold/recipes/extend-lead-gen.md +25 -7
  47. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +160 -118
  48. package/reference/scaffold/recipes/index.md +2 -2
  49. package/reference/scaffold/recipes/query-the-knowledge-graph.md +23 -23
  50. package/reference/scaffold/reference/contracts.md +12 -1
  51. package/reference/scaffold/reference/glossary.md +3 -3
  52. package/reference/scaffold/reference/system-interface-capabilities.md +5 -4
  53. package/reference/scaffold/ui/composition-extensibility.mdx +271 -232
  54. package/reference/scaffold/ui/feature-flags-and-gating.md +14 -6
  55. package/reference/scaffold/ui/feature-shell.mdx +279 -62
  56. package/reference/scaffold/ui/recipes.md +229 -197
  57. package/reference/sdk/cli-management.mdx +77 -29
  58. package/reference/sdk/concepts.mdx +2 -0
  59. package/reference/sdk/define-builders.mdx +76 -0
  60. package/reference/sdk/deployment/command-center.mdx +6 -2
  61. package/reference/sdk/deployment/execution-reference.mdx +64 -186
  62. package/reference/sdk/deployment/index.mdx +2 -0
  63. package/reference/sdk/exports.mdx +4 -4
  64. package/reference/sdk/framework/agent.mdx +49 -119
  65. package/reference/sdk/framework/index.mdx +46 -65
  66. package/reference/sdk/framework/project-structure.mdx +150 -205
  67. package/reference/sdk/framework/tutorial-system.mdx +2 -2
  68. package/reference/sdk/human-in-the-loop.mdx +152 -0
  69. package/reference/sdk/index.mdx +6 -7
  70. package/reference/sdk/platform-tools/index.mdx +12 -0
  71. package/reference/sdk/platform-tools/type-safety.mdx +4 -0
  72. package/reference/sdk/project-deployment-spec.mdx +131 -0
  73. package/reference/sdk/resources/index.mdx +23 -7
  74. package/reference/sdk/resources/patterns.mdx +54 -24
  75. package/reference/sdk/resources/types.mdx +7 -4
  76. package/reference/sdk/templates/data-enrichment.mdx +7 -3
  77. package/reference/sdk/templates/email-sender.mdx +139 -135
  78. package/reference/sdk/templates/lead-scorer.mdx +5 -1
  79. package/reference/sdk/templates/pdf-generator.mdx +155 -151
  80. package/reference/sdk/templates/recurring-job.mdx +195 -189
  81. package/reference/sdk/templates/text-classifier.mdx +4 -0
  82. package/reference/sdk/templates/web-scraper.mdx +139 -135
  83. package/reference/spine/spine-primer.md +135 -96
  84. package/reference/ui/index.mdx +14 -7
  85. package/dist/types/worker/adapters/anymailfinder.d.ts +0 -14
  86. package/dist/types/worker/adapters/apify.d.ts +0 -14
  87. package/dist/types/worker/adapters/approval.d.ts +0 -23
  88. package/dist/types/worker/adapters/attio.d.ts +0 -22
  89. package/dist/types/worker/adapters/clickup.d.ts +0 -22
  90. package/dist/types/worker/adapters/create-adapter.d.ts +0 -41
  91. package/dist/types/worker/adapters/crm.d.ts +0 -20
  92. package/dist/types/worker/adapters/dropbox.d.ts +0 -14
  93. package/dist/types/worker/adapters/email.d.ts +0 -25
  94. package/dist/types/worker/adapters/execution.d.ts +0 -22
  95. package/dist/types/worker/adapters/gmail.d.ts +0 -14
  96. package/dist/types/worker/adapters/google-sheets.d.ts +0 -14
  97. package/dist/types/worker/adapters/index.d.ts +0 -33
  98. package/dist/types/worker/adapters/instantly.d.ts +0 -14
  99. package/dist/types/worker/adapters/lead.d.ts +0 -28
  100. package/dist/types/worker/adapters/list.d.ts +0 -9
  101. package/dist/types/worker/adapters/llm.d.ts +0 -45
  102. package/dist/types/worker/adapters/millionverifier.d.ts +0 -14
  103. package/dist/types/worker/adapters/notification.d.ts +0 -28
  104. package/dist/types/worker/adapters/pdf.d.ts +0 -22
  105. package/dist/types/worker/adapters/projects.d.ts +0 -20
  106. package/dist/types/worker/adapters/resend.d.ts +0 -14
  107. package/dist/types/worker/adapters/scheduler.d.ts +0 -25
  108. package/dist/types/worker/adapters/signature-api.d.ts +0 -14
  109. package/dist/types/worker/adapters/storage.d.ts +0 -33
  110. package/dist/types/worker/adapters/stripe.d.ts +0 -14
  111. package/dist/types/worker/adapters/tomba.d.ts +0 -14
  112. package/dist/types/worker/index.d.ts +0 -60
  113. package/dist/types/worker/platform.d.ts +0 -90
  114. package/dist/types/worker/utils.d.ts +0 -9
  115. package/reference/claude-config/Overview.md +0 -230
  116. package/reference/claude-config/hooks/post-edit-validate.mjs +0 -98
  117. package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +0 -187
  118. package/reference/claude-config/hooks/tool-failure-recovery.mjs +0 -73
  119. package/reference/claude-config/registries/graph-skills.json +0 -4
  120. package/reference/claude-config/registries/knowledge-flags.json +0 -154
  121. package/reference/claude-config/registries/skill-coverage.json +0 -20
  122. package/reference/claude-config/rules/active-change-index.md +0 -22
  123. package/reference/claude-config/rules/agent-start-here.md +0 -22
  124. package/reference/claude-config/rules/deployment.md +0 -22
  125. package/reference/claude-config/rules/error-handling.md +0 -22
  126. package/reference/claude-config/rules/execution.md +0 -22
  127. package/reference/claude-config/rules/frontend.md +0 -22
  128. package/reference/claude-config/rules/observability.md +0 -22
  129. package/reference/claude-config/rules/operations.md +0 -22
  130. package/reference/claude-config/rules/organization-model.md +0 -22
  131. package/reference/claude-config/rules/organization-os.md +0 -22
  132. package/reference/claude-config/rules/package-taxonomy.md +0 -22
  133. package/reference/claude-config/rules/platform.md +0 -22
  134. package/reference/claude-config/rules/shared-types.md +0 -22
  135. package/reference/claude-config/rules/task-tracking.md +0 -22
  136. package/reference/claude-config/rules/topbar-actions.md +0 -70
  137. package/reference/claude-config/rules/ui.md +0 -22
  138. package/reference/claude-config/rules/vibe.md +0 -22
  139. package/reference/claude-config/scripts/statusline-command.js +0 -18
  140. package/reference/claude-config/settings.json +0 -30
  141. package/reference/claude-config/skills/client/SKILL.md +0 -201
  142. package/reference/claude-config/skills/deploy/SKILL.md +0 -159
  143. package/reference/claude-config/skills/dsp/SKILL.md +0 -66
  144. package/reference/claude-config/skills/elevasis/SKILL.md +0 -251
  145. package/reference/claude-config/skills/explore/SKILL.md +0 -78
  146. package/reference/claude-config/skills/git-sync/SKILL.md +0 -166
  147. package/reference/claude-config/skills/om/SKILL.md +0 -475
  148. package/reference/claude-config/skills/om/operations/build.md +0 -237
  149. package/reference/claude-config/skills/om/operations/codify-level-a.md +0 -109
  150. package/reference/claude-config/skills/om/operations/codify-level-b.md +0 -159
  151. package/reference/claude-config/skills/om/operations/customers.md +0 -114
  152. package/reference/claude-config/skills/om/operations/features.md +0 -88
  153. package/reference/claude-config/skills/om/operations/goals.md +0 -123
  154. package/reference/claude-config/skills/om/operations/identity.md +0 -97
  155. package/reference/claude-config/skills/om/operations/labels.md +0 -110
  156. package/reference/claude-config/skills/om/operations/offerings.md +0 -114
  157. package/reference/claude-config/skills/om/operations/roles.md +0 -104
  158. package/reference/claude-config/skills/om/operations/scaffold.md +0 -163
  159. package/reference/claude-config/skills/om/operations/techStack.md +0 -38
  160. package/reference/claude-config/skills/project/SKILL.md +0 -1114
  161. package/reference/claude-config/skills/run-ui/SKILL.md +0 -73
  162. package/reference/claude-config/skills/save/SKILL.md +0 -183
  163. package/reference/claude-config/skills/setup/SKILL.md +0 -290
  164. package/reference/claude-config/skills/status/SKILL.md +0 -59
  165. package/reference/claude-config/skills/submit-request/SKILL.md +0 -180
  166. package/reference/claude-config/skills/sync/SKILL.md +0 -47
  167. package/reference/claude-config/skills/tutorial/SKILL.md +0 -259
  168. package/reference/claude-config/skills/tutorial/progress-template.md +0 -74
  169. package/reference/claude-config/skills/tutorial/technical.md +0 -1303
  170. package/reference/claude-config/skills/tutorial/vibe-coder.md +0 -890
  171. package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +0 -27
  172. package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +0 -30
  173. package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +0 -73
  174. package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +0 -86
  175. package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +0 -55
  176. package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +0 -97
  177. package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +0 -112
  178. package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +0 -93
  179. package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +0 -58
  180. package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +0 -56
  181. package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +0 -71
  182. package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +0 -83
  183. package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +0 -59
  184. package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +0 -42
  185. package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +0 -60
  186. package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +0 -37
  187. package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +0 -34
  188. package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +0 -38
  189. package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +0 -32
  190. package/reference/claude-config/sync-notes/2026-05-09-command-system.md +0 -33
  191. package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +0 -69
  192. package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +0 -30
  193. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +0 -45
  194. package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +0 -52
  195. package/reference/claude-config/sync-notes/2026-05-17-sdk-boundary-consolidation.md +0 -33
  196. package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +0 -32
  197. package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +0 -43
  198. package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +0 -40
  199. package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +0 -61
  200. package/reference/claude-config/sync-notes/2026-05-23-branding-names-to-identity.md +0 -49
  201. package/reference/claude-config/sync-notes/2026-05-23-lead-gen-manage-access.md +0 -31
  202. package/reference/claude-config/sync-notes/2026-05-23-om-deployment-drift-detection.md +0 -42
  203. package/reference/claude-config/sync-notes/2026-05-23-om-full-model-deploy-contract.md +0 -33
  204. package/reference/claude-config/sync-notes/2026-05-23-ui-sdk-package-fixes.md +0 -37
  205. package/reference/claude-config/sync-notes/2026-05-24-platform-invite-router-core-baseline.md +0 -28
  206. package/reference/claude-config/sync-notes/2026-05-24-system-interface-readiness.md +0 -43
  207. package/reference/claude-config/sync-notes/2026-05-25-invitation-login-loader.md +0 -26
  208. package/reference/claude-config/sync-notes/2026-05-25-om-topbar-requests.md +0 -33
  209. package/reference/claude-config/sync-notes/2026-05-25-system-interface-profile-registry-and-substrate.md +0 -35
  210. package/reference/claude-config/sync-notes/2026-05-25-tenant-om-scaffold-cli.md +0 -49
  211. package/reference/claude-config/sync-notes/2026-05-25-vibe-operate-intent.md +0 -47
  212. package/reference/claude-config/sync-notes/2026-05-28-om-snapshot-sdk-workflow-config.md +0 -33
  213. package/reference/claude-config/sync-notes/2026-05-30-client-source-and-om-profiles.md +0 -39
  214. package/reference/claude-config/sync-notes/2026-06-02-knowledge-nested-group-routing.md +0 -27
  215. package/reference/claude-config/sync-notes/2026-06-02-nest-projects-under-platform.md +0 -45
  216. package/reference/claude-config/sync-notes/2026-06-03-skill-autogen-and-client-skill.md +0 -34
  217. package/reference/claude-config/sync-notes/2026-06-04-scaffold-registry-lane-severity.md +0 -34
  218. package/reference/claude-config/sync-notes/2026-06-05-appearance-app-mode-decouple.md +0 -29
  219. package/reference/claude-config/sync-notes/2026-06-05-ontology-endpoint-rename-and-knowledge-browser-ui.md +0 -86
  220. package/reference/claude-config/sync-notes/2026-06-06-om-build-systems-scaffold.md +0 -47
  221. package/reference/claude-config/sync-notes/2026-06-06-om-item-copy-references.md +0 -50
  222. package/reference/claude-config/sync-notes/2026-06-08-knowledge-base-page-not-found-fix.md +0 -76
  223. package/reference/claude-config/sync-notes/2026-06-09-agent-sessions-public-agent-chat-route.md +0 -75
  224. package/reference/claude-config/sync-notes/2026-06-09-sdk-cli-load-org-model-resolution.md +0 -42
  225. package/reference/claude-config/sync-notes/2026-06-12-agent-grants-visualizer-operations.md +0 -30
  226. package/reference/claude-config/sync-notes/2026-06-14-session-ux-and-project-cli-json.md +0 -33
  227. package/reference/claude-config/sync-notes/2026-06-14-shared-session-conversation-view.md +0 -26
  228. package/reference/claude-config/sync-notes/2026-06-15-session-chat-zero-wiring.md +0 -46
  229. package/reference/claude-config/sync-notes/2026-06-17-agent-session-ux-features.md +0 -34
  230. package/reference/claude-config/sync-notes/2026-06-25-shared-page-scroll-contract-guard.md +0 -52
  231. package/reference/claude-config/sync-notes/2026-06-26-leadgen-overview-om-telemetry.md +0 -47
  232. package/reference/claude-config/sync-notes/2026-07-21-agent-scaffold-hardening.md +0 -75
  233. package/reference/claude-config/sync-notes/2026-07-23-agent-session-memory.md +0 -49
  234. package/reference/claude-config/sync-notes/2026-07-23-workos-org-marker.md +0 -50
  235. package/reference/claude-config/sync-notes/2026-07-24-claude-5-models-and-session-surface-fixes.md +0 -116
  236. package/reference/claude-config/sync-notes/2026-07-27-agent-strict-output-and-turn-drift.md +0 -73
  237. package/reference/claude-config/sync-notes/2026-07-28-agent-reply-is-its-own-field.md +0 -84
  238. package/reference/claude-config/sync-notes/2026-07-30-login-screen-and-member-provisioning-state.md +0 -114
  239. package/reference/claude-config/sync-notes/2026-08-02-auth-guard-defaults-and-truncation-fix.md +0 -122
  240. package/reference/claude-config/sync-notes/2026-08-03-cli-gateway-errors-and-request-timeout.md +0 -120
  241. package/reference/claude-config/sync-notes/README.md +0 -43
  242. package/reference/sdk/framework/interaction-guidance.mdx +0 -182
  243. package/reference/sdk/framework/memory.mdx +0 -326
  244. package/reference/sdk/framework/resource-documentation.mdx +0 -90
  245. package/reference/sdk/roadmap.mdx +0 -164
@@ -48,6 +48,9 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog, adapter ref
48
48
  - [Resources](resources/index.mdx) - Workflow and agent definition patterns, Zod schemas, step types, and routing
49
49
  - [Platform Tools](platform-tools/index.mdx) - Full catalog of 25 adapters (13 integration + 12 platform), integration adapters, and credential management
50
50
  - [Credential Security](platform-tools/index.mdx#credential-security) - Three-layer credential model, HTTP tool patterns, and credential management
51
+ - [Human-in-the-Loop Workflows](human-in-the-loop.mdx) - The full HITL story: approval adapter, checkpoint metadata, and queue resolution
52
+ - [The Deployment Spec Pattern](project-deployment-spec.mdx) - projectDeploymentSpec and defineWorkflowConfig, the shape the template actually ships
53
+ - [When to Reach for the define\* Builders](define-builders.mdx) - Judgment guide for defineWorkflow, defineResource, defineTopology, and friends
51
54
 
52
55
  ### Reference
53
56
 
@@ -65,13 +68,10 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog, adapter ref
65
68
 
66
69
  ### Framework
67
70
 
68
- - [Development Framework](framework/index.mdx) - How Claude Code helps you build: project structure, agent integration, memory, and documentation
71
+ - [Development Framework](framework/index.mdx) - How Claude Code helps you build: project structure, agent integration, and the skill surface
69
72
  - [Project Structure](framework/project-structure.mdx) - Scaffolded file layout, domain barrels, src/index.ts entry point, and config files
70
- - [Agent Configuration](framework/agent.mdx) - Agent capabilities, tool access, model config, and Claude Code integration patterns
71
- - [Memory](framework/memory.mdx) - Agent memory system, session state, developer profiles, and workspace conventions
72
- - [Interaction Guidance](framework/interaction-guidance.mdx) - Skill dimension adaptation rules for platform navigation, API integration, and automation concepts
73
- - [Tutorial System](framework/tutorial-system.mdx) - Two-track onboarding (8 vibe-coder + 19 technical lessons), skill-adaptive lesson variants, progress tracking, and module contents
74
- - [Resource Documentation](framework/resource-documentation.mdx) - Docs directory structure, frontmatter schema, size limits, deploy behavior, and /docs command reference
73
+ - [Agent Configuration](framework/agent.mdx) - The shipped skill inventory, project context via `project:*`, upgrades via `/git-sync`, and the ambient vibe layer
74
+ - [Tutorial System](framework/tutorial-system.mdx) - Two-track onboarding: 8 vibe-coder lessons and 19 technical lessons across 5 sections, with track choice persisted to `profile.md`
75
75
 
76
76
  ### Resources Subpages
77
77
 
@@ -87,7 +87,6 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog, adapter ref
87
87
 
88
88
  - [Export Catalog](exports.mdx) - Auto-generated catalog of all published @elevasis/sdk subpath exports
89
89
  - [Troubleshooting](troubleshooting.mdx) - Static error catalog for CLI, deployment, schema, and runtime failures
90
- - [Roadmap](roadmap.mdx) - Planned features including error taxonomy, retry semantics, circuit breaker, and metrics
91
90
 
92
91
  ---
93
92
 
@@ -11,6 +11,8 @@ Your SDK workflows have access to 25 adapters (13 integration + 12 platform) --
11
11
 
12
12
  **Preferred: Typed adapters** (available for all integration tools + key platform services)
13
13
 
14
+ {/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
15
+
14
16
  ```typescript
15
17
  import { createResendAdapter, scheduler, llm } from '@elevasis/sdk/worker'
16
18
 
@@ -25,6 +27,8 @@ const result = await llm.generate({ messages: [...] })
25
27
 
26
28
  **Fallback: `platform.call()`** (for tools without typed adapters)
27
29
 
30
+ {/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
31
+
28
32
  ```typescript
29
33
  import { platform } from '@elevasis/sdk/worker'
30
34
 
@@ -51,6 +55,8 @@ Integration credentials are never stored in `.env` and never available via `proc
51
55
 
52
56
  All platform tools resolve credentials server-side. The credential value never crosses the postMessage boundary into the worker.
53
57
 
58
+ {/* doc-snippet:skip: continues from the `import { platform } from '@elevasis/sdk/worker'` shown in Usage above */}
59
+
54
60
  ```typescript
55
61
  // Credential 'my-gmail' is resolved server-side -- value never enters worker memory
56
62
  const result = await platform.call({
@@ -65,6 +71,8 @@ const result = await platform.call({
65
71
 
66
72
  For APIs without a dedicated adapter, use the `http` platform tool. Credentials are injected server-side before the outgoing request.
67
73
 
74
+ {/* doc-snippet:skip: continues from the `import { platform } from '@elevasis/sdk/worker'` shown in Usage above */}
75
+
68
76
  ```typescript
69
77
  const result = await platform.call({
70
78
  tool: 'http',
@@ -93,6 +101,8 @@ const result = await platform.call({
93
101
 
94
102
  For third-party SDKs that require a raw key (e.g., `new Stripe(key)`), use `platform.getCredential()`. This explicitly causes the credential value to enter worker memory.
95
103
 
104
+ {/* doc-snippet:skip: illustrative composition with the third-party `stripe` npm package -- that package is not installed in this doc-check project and is not an @elevasis import */}
105
+
96
106
  ```typescript
97
107
  import { platform } from '@elevasis/sdk/worker'
98
108
 
@@ -152,6 +162,8 @@ Supabase is a first-class integration adapter for persistent storage. Pass the `
152
162
 
153
163
  **Methods:** `insert`, `select`, `update`, `delete`, `upsert`, `rpc`, `count`
154
164
 
165
+ {/* doc-snippet:skip: continues from the `import { platform } from '@elevasis/sdk/worker'` shown in Usage above */}
166
+
155
167
  ```typescript
156
168
  const qualified = await platform.call({
157
169
  tool: 'supabase',
@@ -15,6 +15,8 @@ The approach: tighten types where misconfiguration is a realistic foot-gun, and
15
15
 
16
16
  `provider` and `model` are required on `SDKLLMGenerateParams` in `packages/sdk/src/worker/adapters/llm.ts`. They were previously optional because the server-side `modelConfig` fallback in `tool-dispatcher.ts` would fill them in -- but that fallback is a foot-gun, not a feature. Omitting them silently selects a default model that may not be appropriate for the call site.
17
17
 
18
+ {/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
19
+
18
20
  ```typescript
19
21
  // Required -- both fields must be specified inline
20
22
  await llm.generate({
@@ -54,6 +56,8 @@ The `never` pattern on sibling fields causes TypeScript to error if you pass two
54
56
 
55
57
  `ApprovalToolMap.create.params` uses `context: Record<string, unknown>` instead of `context: unknown`. This prevents passing primitives (strings, numbers) as context -- approval tasks always expect a structured key-value object.
56
58
 
59
+ {/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
60
+
57
61
  ```typescript
58
62
  // Correct
59
63
  await approval.create({
@@ -0,0 +1,131 @@
1
+ ---
2
+ title: The Deployment Spec Pattern
3
+ description: How projectDeploymentSpec and defineWorkflowConfig assemble the DeploymentSpec a scaffolded project actually ships, using operations/src/index.ts as the reference.
4
+ ---
5
+
6
+ [Resources](resources/index.mdx#deploymentspec) shows the minimal shape of a `DeploymentSpec`: a hand-built object literal with `version`, `organizationModel`, `workflows`, and `agents`. That shape type-checks, but it is not what a scaffolded project ships. The real `operations/src/index.ts` -- the file every agent is pointed at to register a new resource -- is built on two exports this bundle otherwise only mentions in passing: `projectDeploymentSpec` and `defineWorkflowConfig`. This page teaches that shape, using the shipped file as the reference point.
7
+
8
+ ## The Real File
9
+
10
+ `external/_template/operations/src/index.ts` (the file `pnpm dlx @elevasis/sdk init` scaffolds for you) looks like this, trimmed to the parts that matter:
11
+
12
+ {/* doc-snippet:skip: real-file excerpt with project-local path aliases, not a standalone compilable file */}
13
+
14
+ ```typescript
15
+ import { projectDeploymentSpec, type DeploymentSpec } from '@elevasis/sdk'
16
+ import {
17
+ canonicalOrganizationModel,
18
+ getTemplateAgentResourceDescriptor,
19
+ getTemplateWorkflowResourceDescriptor
20
+ } from '@core/config/organization-model'
21
+ import * as example from './example/index.js'
22
+ import * as emailNotification from './email-notification/exports.js'
23
+ import { triggers, integrations, humanCheckpoints } from './metadata.js'
24
+
25
+ function getTemplateIntegrationResourceDescriptor(resourceId: string): never {
26
+ throw new Error(`No integration OM Resource descriptor for "${resourceId}".`)
27
+ }
28
+
29
+ type TemplateDeploymentSpec = DeploymentSpec & {
30
+ organizationModel: typeof canonicalOrganizationModel
31
+ }
32
+
33
+ const deploymentSpec: TemplateDeploymentSpec = {
34
+ ...projectDeploymentSpec({
35
+ version: '0.1.0',
36
+ organizationModel: canonicalOrganizationModel,
37
+ workflows: [...example.workflows, ...emailNotification.workflows],
38
+ agents: [...example.agents, ...emailNotification.agents],
39
+ triggers,
40
+ integrations,
41
+ humanCheckpoints,
42
+ getWorkflowResourceDescriptor: getTemplateWorkflowResourceDescriptor,
43
+ getAgentResourceDescriptor: getTemplateAgentResourceDescriptor,
44
+ getIntegrationResourceDescriptor: getTemplateIntegrationResourceDescriptor
45
+ }),
46
+ organizationModel: canonicalOrganizationModel
47
+ }
48
+ export default deploymentSpec
49
+ ```
50
+
51
+ Four things are doing work here that the minimal literal example does not show: `projectDeploymentSpec` itself, the descriptor resolver functions passed into it, the feature-group `exports.ts` files being spread into `workflows`/`agents`, and `metadata.ts` supplying `triggers`/`integrations`/`humanCheckpoints`. Each is below.
52
+
53
+ ## `projectDeploymentSpec`: What It Actually Does
54
+
55
+ `projectDeploymentSpec` takes your bare `WorkflowDefinition[]` / `AgentDefinition[]` / `IntegrationDefinition[]` arrays and, for every entry, injects `config.resource`, `config.resourceId`, and `config.type` from the matching Organization Model resource descriptor -- looked up through the resolver functions you pass in. You never write those three fields into a workflow's `config` by hand under this pattern; the workflow file only needs a `resourceId` that exists in the OM.
56
+
57
+ It also computes `relationships` for you, by projecting `organizationModel.topology.relationships` into the `triggers` / `uses` edges the Command Center graph reads. The minimal `DeploymentSpec` recipe has you author `relationships` manually; under `projectDeploymentSpec`, that field is derived, not authored -- edit topology in the OM (via `/om`) rather than adding a `relationships` entry to `index.ts` by hand.
58
+
59
+ The three resolver functions are required or optional depending on what you're deploying:
60
+
61
+ - `getWorkflowResourceDescriptor` -- required. Looks up a workflow's `resourceId` in the OM `resources` map and throws if it is missing or not `kind: 'workflow'`.
62
+ - `getIntegrationResourceDescriptor` -- required by the function signature, even if you have zero integrations. The template satisfies this with a function that always throws, since `integrations` starts empty -- it is never invoked while the array stays empty, and it fails loudly the moment someone wires an integration without first adding its OM descriptor.
63
+ - `getAgentResourceDescriptor` -- optional. Omit it and your `agents` array passes through unresolved.
64
+
65
+ These resolvers are why a workflow you write must have a matching OM resource descriptor before it deploys -- `projectDeploymentSpec` is the point where that requirement is enforced, not a validation step bolted on afterward.
66
+
67
+ ## Feature-Group Exports
68
+
69
+ Each feature folder under `operations/src/` owns an `exports.ts` (or, for a single-workflow group, folds the same two arrays into its `index.ts`) that lists its own workflows and agents:
70
+
71
+ {/* doc-snippet:skip: real-file excerpt with a relative import, not a standalone compilable file */}
72
+
73
+ ```typescript
74
+ // email-notification/exports.ts
75
+ import { emailNotification } from './index.js'
76
+ import type { WorkflowDefinition } from '@elevasis/sdk'
77
+
78
+ export const workflows: WorkflowDefinition[] = [emailNotification]
79
+ export const agents: never[] = []
80
+ ```
81
+
82
+ `index.ts` at the project root spreads every group's arrays together: `workflows: [...example.workflows, ...emailNotification.workflows]`. Adding a new workflow to an existing feature means adding it to that feature's array; adding a new feature means adding a new `import * as myFeature from './my-feature/exports.js'` line and spreading its arrays alongside the others.
83
+
84
+ ## `defineWorkflowConfig`: Deriving `config` From One OM Descriptor
85
+
86
+ `defineWorkflowConfig(resourceId, descriptors, actionRegistry?)` is a second, smaller helper for the common case where a workflow's `config.name`, `config.description`, `config.actions`, and `config.primaryAction` should all come from the same OM resource descriptor instead of being retyped by hand. `echo.ts` uses it:
87
+
88
+ {/* doc-snippet:skip: real-file excerpt with project-local path aliases, not a standalone compilable file */}
89
+
90
+ ```typescript
91
+ import { defineWorkflowConfig, type WorkflowDefinition } from '@elevasis/sdk'
92
+ import { templateResourceDescriptors } from '@core/config/organization-model'
93
+ import { echoInputSchema, echoOutputSchema } from '@core/types'
94
+
95
+ export const echo: WorkflowDefinition = {
96
+ config: {
97
+ ...defineWorkflowConfig('echo', templateResourceDescriptors),
98
+ type: 'workflow',
99
+ version: '1.0.0',
100
+ status: 'dev'
101
+ },
102
+ contract: { inputSchema: echoInputSchema, outputSchema: echoOutputSchema },
103
+ steps: {
104
+ /* ... */
105
+ },
106
+ entryPoint: 'echo'
107
+ }
108
+ ```
109
+
110
+ It throws if the descriptor is missing, if it is not `kind: 'workflow'`, or if the descriptor's `ontology.primaryAction` is unset -- `defineWorkflowConfig` requires a resource that has already been given an ontology binding. A workflow whose OM descriptor has no `ontology.primaryAction` yet cannot use this helper. `email-notification.ts`, in the same shipped template, is that case: it reads `templateResourceDescriptors['email-notification']` directly and builds `config.resourceId` / `config.name` / `config.type` / `config.description` off the descriptor's own fields by hand, because that resource's ontology binding was not authored. Both are valid, verified-shipping patterns -- reach for `defineWorkflowConfig` once the descriptor has a `primaryAction`, and fall back to manual descriptor field access until it does.
111
+
112
+ Note that `config.resource` and the final `config.resourceId` / `config.type` are still overwritten by `projectDeploymentSpec` at assembly time regardless of which of the two you use here -- `defineWorkflowConfig` and the manual fallback both only save you from retyping `name` and `description`, not from the resolver-injection step above.
113
+
114
+ ## `triggers`, `integrations`, `humanCheckpoints`: `metadata.ts`
115
+
116
+ These three arrays are deployment mechanics, not OM identity, and live in `operations/src/metadata.ts`. All three start empty in a freshly scaffolded project -- add entries as you adopt webhook triggers, third-party credentials, or HITL checkpoints. See [Human-in-the-Loop Workflows](human-in-the-loop.mdx) for the `humanCheckpoints` shape in context.
117
+
118
+ ## Adding a Workflow Under This Pattern
119
+
120
+ 1. Write the workflow file (`config`, `contract`, `steps`, `entryPoint`), using `defineWorkflowConfig` if the resource already has an `ontology.primaryAction`, otherwise deriving `config` fields from the descriptor by hand.
121
+ 2. Make sure the resource exists in your OM -- for a tenant project this goes through the `/om` ceremony, not a direct edit to `core/config/organization-model.ts`.
122
+ 3. Export it from its feature group's `workflows` array (`exports.ts` or `index.ts`).
123
+ 4. Confirm the top-level `operations/src/index.ts` spreads that group into the `workflows` list passed to `projectDeploymentSpec` -- existing groups already do; a brand-new group needs the import and spread added once.
124
+ 5. Run `pnpm -C operations run check` (not `deploy` without `run` -- `pnpm -C operations deploy` without the `run` keyword is parsed as pnpm's own builtin `deploy` command, not your project's `deploy` script).
125
+ 6. Deploy with `pnpm -C operations run deploy`.
126
+
127
+ ## Documentation
128
+
129
+ - [Resources](resources/index.mdx) -- the `WorkflowDefinition` / `AgentDefinition` shape these helpers assemble
130
+ - [Human-in-the-Loop Workflows](human-in-the-loop.mdx) -- the `humanCheckpoints` entry in `metadata.ts`, in context
131
+ - [Deployment](deployment/index.mdx) -- what happens after `deploy` runs
@@ -23,7 +23,7 @@ A complete workflow definition has four required properties:
23
23
  ```typescript
24
24
  import { z } from 'zod';
25
25
  import type { WorkflowDefinition } from '@elevasis/sdk';
26
- import { resourceDescriptors } from '@core/config/organization-model';
26
+ import { templateResourceDescriptors } from '@core/config/organization-model';
27
27
 
28
28
  const echoInput = z.object({
29
29
  message: z.string(),
@@ -37,10 +37,10 @@ type EchoInput = z.infer<typeof echoInput>;
37
37
 
38
38
  const echoWorkflow: WorkflowDefinition = {
39
39
  config: {
40
- resource: resourceDescriptors.echo,
41
- resourceId: resourceDescriptors.echo.id,
40
+ resource: templateResourceDescriptors.echo,
41
+ resourceId: templateResourceDescriptors.echo.id,
42
42
  name: 'Echo',
43
- type: resourceDescriptors.echo.kind,
43
+ type: templateResourceDescriptors.echo.kind,
44
44
  description: 'Returns the input message unchanged',
45
45
  version: '1.0.0',
46
46
  status: 'dev',
@@ -88,6 +88,8 @@ The `contract` block defines the Zod schemas for input and output. The platform
88
88
 
89
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
90
 
91
+ {/* doc-snippet:skip: illustrative excerpt -- shows the contract shape in isolation, omits the `import { z } from 'zod'` shown in the Minimal Example above */}
92
+
91
93
  ```typescript
92
94
  const contract = {
93
95
  inputSchema: z.object({
@@ -105,6 +107,8 @@ const contract = {
105
107
 
106
108
  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
109
 
110
+ {/* doc-snippet:skip: illustrative excerpt -- MyInput/myInputSchema/ValidatedData are placeholder names for types you define yourself, not a standalone compilable file */}
111
+
108
112
  ```typescript
109
113
  const steps = {
110
114
  validate: {
@@ -136,6 +140,8 @@ const steps = {
136
140
 
137
141
  `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
142
 
143
+ {/* doc-snippet:skip: illustrative excerpt with a `// ...` elision, not a standalone compilable file */}
144
+
139
145
  ```typescript
140
146
  const workflow: WorkflowDefinition = {
141
147
  // ...
@@ -153,6 +159,8 @@ For workflows with more than one step, import `StepType` from `@elevasis/sdk` to
153
159
 
154
160
  Use `StepType.LINEAR` to connect steps in a fixed sequence. Each step declares a `next` property pointing to the next step name.
155
161
 
162
+ {/* doc-snippet:skip: illustrative excerpt -- fetchSomething/transform/pipelineInput/pipelineOutput are placeholder names for your own helpers and schemas, not a standalone compilable file */}
163
+
156
164
  ```typescript
157
165
  import { z } from 'zod';
158
166
  import type { WorkflowDefinition, WorkflowStep } from '@elevasis/sdk';
@@ -201,6 +209,8 @@ const pipeline: WorkflowDefinition = {
201
209
 
202
210
  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
211
 
212
+ {/* doc-snippet:skip: illustrative excerpt -- `evaluate` is a placeholder name for your own scoring logic, not a standalone compilable file */}
213
+
204
214
  ```typescript
205
215
  import { z } from 'zod';
206
216
  import type { WorkflowStep } from '@elevasis/sdk';
@@ -246,7 +256,7 @@ import type { StepHandler } from '@elevasis/sdk';
246
256
  const myStep: StepHandler = async (input, context) => {
247
257
  const { executionId, organizationId, resourceId, logger, store } = context;
248
258
 
249
- logger.info('Starting step', { executionId });
259
+ logger.info(`Starting step for execution ${executionId}`);
250
260
 
251
261
  // store is a simple key-value store scoped to this execution
252
262
  await store.set('progress', '50%');
@@ -328,19 +338,25 @@ const myAgent: AgentDefinition = {
328
338
 
329
339
  `contract.inputSchema` is required, same as a workflow. `contract.outputSchema` is what a **non-session** (single-shot) agent like the example above returns — there is no conversational reply to read a structured answer from otherwise. A `sessionCapable: true` agent typically omits `outputSchema` and speaks through its conversational `message` instead.
330
340
 
341
+ The framework normalizes literal escape sequences out of that conversational `message`, out of `reasoning`, and out of session-memory values before any of them are persisted, streamed, or replayed. A model sometimes writes the two characters backslash-n where a line break belongs; the result is valid JSON that satisfies the response schema, so nothing upstream can catch it, and the operator ends up reading those characters mid-sentence. Nothing is required of you — no agent definition field changes — but two consequences are worth knowing. An agent that legitimately wants to show an escape sequence in prose (explaining a regex, say) will have it converted, because the normalizer is not markdown-aware. And a memory value that is itself JSON is skipped entirely, so a stored JSON blob keeps its internal escaping intact.
342
+
331
343
  ---
332
344
 
333
345
  ## DeploymentSpec
334
346
 
335
347
  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.
336
348
 
349
+ Use the canonical (resolved) organization model here, not the `organizationModel` convenience export used for navigation/UI code -- that export reshapes the `navigation` field into a template-facing surface list and is not assignable to `DeploymentSpec['organizationModel']`.
350
+
351
+ {/* doc-snippet:skip: illustrative excerpt -- echoWorkflow and pipeline continue from the Minimal Example and Linear Steps examples earlier on this page, not a standalone compilable file */}
352
+
337
353
  ```typescript
338
354
  import type { DeploymentSpec } from '@elevasis/sdk';
339
- import { organizationModel } from '@core/config/organization-model';
355
+ import { canonicalOrganizationModel } from '@core/config/organization-model';
340
356
 
341
357
  const org: DeploymentSpec = {
342
358
  version: '0.1.0',
343
- organizationModel,
359
+ organizationModel: canonicalOrganizationModel,
344
360
  workflows: [echoWorkflow, pipeline],
345
361
  agents: [
346
362
  // myAgent,
@@ -13,6 +13,10 @@ The simplest pattern: a chain of steps where each step feeds its output into the
13
13
 
14
14
  Each `WorkflowStep` requires `id`, `name`, `description`, `handler`, `inputSchema`, `outputSchema`, and `next`. There is no `type` field on a step -- `StepType` (`LINEAR` / `CONDITIONAL`) is a label for `next.type` only, not a step property.
15
15
 
16
+ A step's `handler` is typed `(input: unknown, context) => Promise<unknown>` -- narrowing the parameter itself (`async (input: Input) => ...`) breaks assignability under `strictFunctionTypes`. Cast inside the handler body instead, as shown below.
17
+
18
+ {/* doc-snippet:skip: illustrative excerpt -- getOrder/createShipment are placeholder names for your own domain logic, not a standalone compilable file */}
19
+
16
20
  ```typescript
17
21
  import { z } from 'zod';
18
22
  import type { WorkflowDefinition, WorkflowStep } from '@elevasis/sdk';
@@ -28,9 +32,10 @@ const validateStep: WorkflowStep = {
28
32
  description: 'Checks the order exists before shipping',
29
33
  inputSchema: z.object({ orderId: z.string() }),
30
34
  outputSchema: z.object({ order: z.unknown() }),
31
- handler: async (input: Input) => {
32
- const order = await getOrder(input.orderId);
33
- if (!order) throw new Error(`Order ${input.orderId} not found`);
35
+ handler: async (input) => {
36
+ const { orderId } = input as Input;
37
+ const order = await getOrder(orderId);
38
+ if (!order) throw new Error(`Order ${orderId} not found`);
34
39
  return { order };
35
40
  },
36
41
  next: { type: 'linear', target: 'ship' },
@@ -43,7 +48,8 @@ const shipStep: WorkflowStep = {
43
48
  inputSchema: z.object({ order: z.unknown() }),
44
49
  outputSchema: z.object({ shipped: z.boolean(), trackingNumber: z.string() }),
45
50
  handler: async (input) => {
46
- const tracking = await createShipment(input.order);
51
+ const { order } = input as { order: unknown };
52
+ const tracking = await createShipment(order);
47
53
  return { shipped: true, trackingNumber: tracking.number };
48
54
  },
49
55
  next: null, // terminal -- no further steps
@@ -72,6 +78,8 @@ const fulfillOrder: WorkflowDefinition = {
72
78
 
73
79
  Use a `next.type` of `'conditional'` when the next step depends on the output of the current step. The step itself still has no `type` field -- the routing decision lives entirely in `next`.
74
80
 
81
+ {/* doc-snippet:skip: illustrative excerpt, not a standalone compilable file */}
82
+
75
83
  ```typescript
76
84
  import { z } from 'zod';
77
85
  import type { WorkflowStep } from '@elevasis/sdk';
@@ -128,18 +136,20 @@ const sendEmailStep: WorkflowStep = {
128
136
  inputSchema: z.object({ recipientEmail: z.string(), subject: z.string(), body: z.string() }),
129
137
  outputSchema: z.object({ sent: z.boolean(), messageId: z.string() }),
130
138
  handler: async (input, context) => {
131
- const result = await platform.call({
139
+ const { recipientEmail, subject, body } = input as {
140
+ recipientEmail: string;
141
+ subject: string;
142
+ body: string;
143
+ };
144
+
145
+ const result = (await platform.call({
132
146
  tool: 'email',
133
147
  method: 'send',
134
- params: {
135
- to: input.recipientEmail,
136
- subject: input.subject,
137
- body: input.body,
138
- },
148
+ params: { to: recipientEmail, subject, body },
139
149
  credential: 'sendgrid', // name of the stored credential
140
- });
150
+ })) as { messageId: string };
141
151
 
142
- context.logger.info('Email sent', { messageId: result.messageId });
152
+ context.logger.info(`Email sent: ${result.messageId}`);
143
153
  return { sent: true, messageId: result.messageId };
144
154
  },
145
155
  next: null,
@@ -149,7 +159,7 @@ const sendEmailStep: WorkflowStep = {
149
159
  **Key points:**
150
160
 
151
161
  - `platform.call()` is async and times out after 30 minutes (a worker-side safety net; real enforcement is server-side)
152
- - `credential` is the name of a platform environment variable set via `elevasis-sdk env set` when the tool needs one
162
+ - `credential` is the name of a platform environment variable created via `elevasis-sdk creds create` when the tool needs one
153
163
  - On failure, `platform.call()` throws `PlatformToolError` (not `ToolingError`)
154
164
  - Always log success so executions are easy to debug in the dashboard
155
165
 
@@ -164,20 +174,20 @@ Use `PlatformToolError` (from `@elevasis/sdk/worker`) to handle tool-specific fa
164
174
  ```typescript
165
175
  import { platform, PlatformToolError } from '@elevasis/sdk/worker';
166
176
 
167
- const step = async (input) => {
177
+ const step = async (input: { followUpAt?: string }) => {
168
178
  try {
169
- const deals = await platform.call({
179
+ const deals = (await platform.call({
170
180
  tool: 'crm',
171
181
  method: 'listDeals',
172
182
  params: { stage: 'proposal', limit: 10 },
173
- });
183
+ })) as Array<{ id: string }>;
174
184
 
175
185
  const deal = deals[0]
176
- ? await platform.call({
186
+ ? ((await platform.call({
177
187
  tool: 'crm',
178
188
  method: 'getDeal',
179
189
  params: { dealId: deals[0].id },
180
- })
190
+ })) as { id: string })
181
191
  : null;
182
192
 
183
193
  if (deal) {
@@ -234,6 +244,8 @@ const step = async (input) => {
234
244
 
235
245
  Use `ExecutionError` when your step detects a condition that should mark the entire execution as failed:
236
246
 
247
+ {/* doc-snippet:skip: illustrative excerpt, not a standalone compilable file */}
248
+
237
249
  ```typescript
238
250
  import { ExecutionError } from '@elevasis/sdk';
239
251
 
@@ -254,10 +266,12 @@ const validateStep = async (input) => {
254
266
 
255
267
  `ToolingError` is thrown by lower-level platform operations (not `platform.call()` directly). You may encounter it in advanced scenarios:
256
268
 
269
+ {/* doc-snippet:skip: illustrative excerpt -- `doSomething` is a placeholder name for your own logic, not a standalone compilable file */}
270
+
257
271
  ```typescript
258
272
  import { ToolingError } from '@elevasis/sdk';
259
273
 
260
- const step = async (input) => {
274
+ const step = async (input: unknown) => {
261
275
  try {
262
276
  return await doSomething(input);
263
277
  } catch (err) {
@@ -274,17 +288,20 @@ const step = async (input) => {
274
288
 
275
289
  ## Logging in Steps
276
290
 
277
- The `context.logger` writes structured logs attached to the execution. Use it instead of `console.log` so logs appear in the dashboard alongside the execution record.
291
+ The `context.logger` writes structured logs attached to the execution. Use it instead of `console.log` so logs appear in the dashboard alongside the execution record. `logger.info()`'s optional second parameter is an internal engine-only context type, not a place for arbitrary metadata -- interpolate values into the message string instead.
292
+
293
+ {/* doc-snippet:skip: illustrative excerpt -- `doWork` is a placeholder name for your own logic, not a standalone compilable file */}
278
294
 
279
295
  ```typescript
280
296
  import type { StepHandler } from '@elevasis/sdk';
281
297
 
282
298
  const processStep: StepHandler = async (input, context) => {
283
- context.logger.info('Starting process', { userId: input.userId });
299
+ const { userId } = input as { userId: string };
300
+ context.logger.info(`Starting process for user ${userId}`);
284
301
 
285
- const result = await doWork(input);
302
+ const result = (await doWork(input)) as { id: string };
286
303
 
287
- context.logger.info('Process complete', { resultId: result.id });
304
+ context.logger.info(`Process complete: ${result.id}`);
288
305
  return result;
289
306
  };
290
307
  ```
@@ -297,9 +314,14 @@ Avoid logging sensitive values (API keys, passwords, PII) since logs are stored
297
314
 
298
315
  `context.store` is a simple key-value store scoped to the current execution. Use it to pass data between steps without coupling step interfaces, or to checkpoint long-running work.
299
316
 
317
+ {/* doc-snippet:skip: illustrative excerpt -- fetchExpensiveData/transform are placeholder names for your own logic, not a standalone compilable file */}
318
+
300
319
  ```typescript
320
+ import type { StepHandler } from '@elevasis/sdk';
321
+
301
322
  const firstStep: StepHandler = async (input, context) => {
302
- const data = await fetchExpensiveData(input.id);
323
+ const { id } = input as { id: string };
324
+ const data = await fetchExpensiveData(id);
303
325
 
304
326
  // Save for use by later steps
305
327
  await context.store.set('fetchedData', JSON.stringify(data));
@@ -325,6 +347,8 @@ Store values are strings. Serialize objects with `JSON.stringify` and parse with
325
347
 
326
348
  While building a resource, set `config.status` to `'dev'`:
327
349
 
350
+ {/* doc-snippet:skip: illustrative excerpt with a `// ...` elision, not a standalone compilable file */}
351
+
328
352
  ```typescript
329
353
  const myWorkflow: WorkflowDefinition = {
330
354
  config: {
@@ -345,6 +369,8 @@ Dev resources:
345
369
 
346
370
  When you are ready to go live, change to `'prod'` and redeploy:
347
371
 
372
+ {/* doc-snippet:skip: illustrative excerpt, not a standalone compilable file */}
373
+
348
374
  ```typescript
349
375
  config: {
350
376
  name: 'my-workflow',
@@ -375,6 +401,8 @@ Individual resources that set their own `config.status` override this default.
375
401
 
376
402
  As your project grows, organize resources by business domain. Each domain gets its own directory with an `index.ts` barrel that exports `workflows` and `agents` arrays:
377
403
 
404
+ {/* doc-snippet:skip: illustrative excerpt with `...` elisions, not a standalone compilable file */}
405
+
378
406
  ```typescript
379
407
  // src/orders/fulfill-order.ts
380
408
  export const fulfillOrder: WorkflowDefinition = { ... };
@@ -423,6 +451,8 @@ The platform's HITL mechanism works in two parts: your workflow code creates an
423
451
 
424
452
  Call `approval.create()` from any workflow step to pause execution and emit a task to the Command Queue:
425
453
 
454
+ {/* doc-snippet:skip: illustrative excerpt -- dealId/proposalUrl are shorthand for values from the enclosing step handler's input, not a standalone compilable file */}
455
+
426
456
  ```typescript
427
457
  import { approval } from '@elevasis/sdk/worker'
428
458
 
@@ -45,6 +45,8 @@ Zod is a peer dependency.
45
45
 
46
46
  Resource metadata uses graph links:
47
47
 
48
+ {/* doc-snippet:skip: illustrative excerpt, not a standalone compilable file */}
49
+
48
50
  ```ts
49
51
  config: {
50
52
  resourceId: 'lead-import',
@@ -77,6 +79,8 @@ config: {
77
79
  ## ElevasConfig
78
80
 
79
81
  ```ts
82
+ import type { ResourceStatus } from '@elevasis/sdk'
83
+
80
84
  export interface ElevasConfig {
81
85
  defaultStatus?: ResourceStatus
82
86
  dev?: { port?: number }
@@ -90,14 +94,13 @@ export interface ElevasConfig {
90
94
 
91
95
  ## StepHandler Context
92
96
 
97
+ `logger`'s optional second parameter is an internal engine-only context type, not a place for arbitrary metadata -- interpolate values into the message string instead.
98
+
93
99
  ```ts
94
100
  import type { StepHandler, ExecutionContext } from '@elevasis/sdk'
95
101
 
96
102
  const handler: StepHandler = async (input, context: ExecutionContext) => {
97
- context.logger.info('Processing', {
98
- executionId: context.executionId,
99
- resourceId: context.resourceId
100
- })
103
+ context.logger.info(`Processing execution ${context.executionId} for resource ${context.resourceId}`)
101
104
 
102
105
  await context.store.set('checkpoint', JSON.stringify({ step: 'started' }))
103
106
  return { done: true }
@@ -23,10 +23,12 @@ Fetches records from a Supabase table that need enrichment, sends each record to
23
23
 
24
24
  ## Input Schema
25
25
 
26
+ {/* doc-snippet:skip: illustrative excerpt -- shows the schema shape in isolation, omits the `import { z } from 'zod'` shown in Workflow Code Pattern below */}
27
+
26
28
  ```typescript
27
29
  z.object({
28
30
  table: z.string(), // Supabase table to enrich
29
- filter: z.record(z.string()).optional(), // Filter rows to enrich (PostgREST format)
31
+ filter: z.record(z.string(), z.string()).optional(), // Filter rows to enrich (PostgREST format)
30
32
  sourceField: z.string(), // Field to send to the LLM as input
31
33
  targetField: z.string(), // Field to write enriched output to
32
34
  prompt: z.string(), // LLM prompt template (use {value} as placeholder)
@@ -36,6 +38,8 @@ z.object({
36
38
 
37
39
  ## Output Schema
38
40
 
41
+ {/* doc-snippet:skip: illustrative excerpt -- shows the schema shape in isolation, omits the `import { z } from 'zod'` shown in Workflow Code Pattern below */}
42
+
39
43
  ```typescript
40
44
  z.object({
41
45
  processed: z.number(), // Rows successfully enriched
@@ -55,7 +59,7 @@ import { z } from 'zod'
55
59
 
56
60
  const inputSchema = z.object({
57
61
  table: z.string(),
58
- filter: z.record(z.string()).optional(),
62
+ filter: z.record(z.string(), z.string()).optional(),
59
63
  sourceField: z.string(),
60
64
  targetField: z.string(),
61
65
  prompt: z.string(),
@@ -130,7 +134,7 @@ export const dataEnrichment: WorkflowDefinition = {
130
134
  },
131
135
  })
132
136
 
133
- context.logger.info('Enriched row', { id: row.id })
137
+ context.logger.info(`Enriched row ${String(row.id)}`)
134
138
  processed++
135
139
  } catch (err) {
136
140
  const msg = err instanceof Error ? err.message : String(err)