@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,553 +1,553 @@
1
- ---
2
- title: Platform Adapters
3
- description: Type-safe singleton adapters for built-in platform services -- scheduler, storage, LLM, PDF, approval, notifications, acqDb, list, execution, and email -- no credentials required
4
- loadWhen: "Using platform service adapters (scheduler, storage, llm, pdf, approval, notifications, acqDb, list, execution, email)"
5
- ---
6
-
7
- Platform adapters are singleton objects imported directly from `@elevasis/sdk/worker`. They require no credential argument because the platform injects context server-side. For integration adapters (Attio, Stripe, etc.), see [Integration Adapters](adapters-integration.mdx).
8
-
9
- ```typescript
10
- import {
11
- acqDb, scheduler, storage, pdf, approval,
12
- notifications, llm, list, execution, email,
13
- } from '@elevasis/sdk/worker'
14
- ```
15
-
16
- ---
17
-
18
- ## Quick Reference
19
-
20
- | Import | Methods | Purpose |
21
- | --------------- | ------- | ------------------------------------ |
22
- | `acqDb` | 49 | Acquisition database CRUD and sync |
23
- | `scheduler` | 9 | Task schedule management |
24
- | `storage` | 5 | File upload, download, signed URLs |
25
- | `pdf` | 2 | PDF rendering to storage or buffer |
26
- | `approval` | 2 | Human-in-the-loop approval gates |
27
- | `notifications` | 1 | In-app team notifications |
28
- | `llm` | 1 | LLM inference with structured output |
29
- | `list` | 4 | List-scoped execution and stage ops |
30
- | `execution` | 1 | Trigger nested child executions |
31
- | `email` | 1 | Send email to org members |
32
-
33
- ---
34
-
35
- ## Scheduler Adapter
36
-
37
- Singleton -- 9 methods for task schedule management.
38
-
39
- ```typescript
40
- import { scheduler } from '@elevasis/sdk/worker'
41
- ```
42
-
43
- ### Methods
44
-
45
- | Method | Params | Returns |
46
- | -------------------------------- | ------------------------------ | ---------------------- |
47
- | `createSchedule` | `CreateScheduleInput` | `TaskSchedule` |
48
- | `updateAnchor` | `{ scheduleId, anchorAt }` | `TaskSchedule` |
49
- | `deleteSchedule` | `{ scheduleId }` | `void` |
50
- | `findByIdempotencyKey` | `{ idempotencyKey }` | `TaskSchedule | null` |
51
- | `deleteScheduleByIdempotencyKey` | `{ idempotencyKey }` | `void` |
52
- | `listSchedules` | `{ status?, limit?, offset? }` | `TaskSchedule[]` |
53
- | `getSchedule` | `{ scheduleId }` | `TaskSchedule` |
54
- | `cancelSchedule` | `{ scheduleId }` | `void` |
55
- | `cancelSchedulesByMetadata` | `{ metadata }` | `{ cancelledCount }` |
56
-
57
- ### Examples
58
-
59
- ```typescript
60
- // Create a relative schedule (follow-up sequence)
61
- const schedule = await scheduler.createSchedule({
62
- organizationId: context.organizationId,
63
- name: 'Proposal follow-up',
64
- target: { resourceType: 'workflow', resourceId: 'send-followup' },
65
- scheduleConfig: {
66
- type: 'relative',
67
- anchorAt: '2026-03-15T10:00:00Z',
68
- anchorLabel: 'proposal_sent_date',
69
- items: [
70
- { offset: '+3d', payload: { step: 'first-followup' }, label: 'First follow-up' },
71
- { offset: '+7d', payload: { step: 'second-followup' }, label: 'Second follow-up' },
72
- ],
73
- },
74
- metadata: { dealId: 'deal-123', contactEmail: 'jane@acme.com' },
75
- idempotencyKey: 'proposal-followup-deal-123',
76
- })
77
-
78
- // Reschedule (update anchor)
79
- await scheduler.updateAnchor({
80
- scheduleId: schedule.id,
81
- anchorAt: '2026-03-20T10:00:00Z',
82
- })
83
-
84
- // Cancel all schedules matching metadata
85
- await scheduler.cancelSchedulesByMetadata({
86
- metadata: { dealId: 'deal-123' },
87
- })
88
- ```
89
-
90
- ---
91
-
92
- ## Storage Adapter
93
-
94
- Singleton -- 5 methods for file storage operations. All paths are relative to the organization's storage prefix (injected server-side).
95
-
96
- ```typescript
97
- import { storage } from '@elevasis/sdk/worker'
98
- ```
99
-
100
- ### Methods
101
-
102
- | Method | Params | Returns |
103
- | ----------------- | ----------------------- | ------------------------ |
104
- | `upload` | `StorageUploadInput` | `StorageUploadOutput` |
105
- | `download` | `StorageDownloadInput` | `StorageDownloadOutput` |
106
- | `createSignedUrl` | `StorageSignedUrlInput` | `StorageSignedUrlOutput` |
107
- | `delete` | `StorageDeleteInput` | `StorageDeleteOutput` |
108
- | `list` | `StorageListInput` | `StorageListOutput` |
109
-
110
- ### Examples
111
-
112
- ```typescript
113
- // Upload a PDF
114
- await storage.upload({
115
- bucket: 'acquisition',
116
- path: 'proposals/deal-123/proposal.pdf',
117
- content: base64PdfContent,
118
- contentType: 'application/pdf',
119
- })
120
-
121
- // Generate a signed URL (temporary access)
122
- const { signedUrl } = await storage.createSignedUrl({
123
- bucket: 'acquisition',
124
- path: 'proposals/deal-123/proposal.pdf',
125
- })
126
-
127
- // List files under a prefix
128
- const files = await storage.list({
129
- bucket: 'acquisition',
130
- path: 'proposals/deal-123/',
131
- })
132
- ```
133
-
134
- ---
135
-
136
- ## LLM Adapter
137
-
138
- Singleton -- 1 method with a generic `<T>` for typed structured output. No API keys needed -- keys are resolved server-side from environment variables.
139
-
140
- ```typescript
141
- import { llm } from '@elevasis/sdk/worker'
142
- ```
143
-
144
- ### Method
145
-
146
- | Method | Params | Returns |
147
- | --------------- | -------------------------------------- | -------------------------- |
148
- | `generate<T>` | `Omit<LLMGenerateRequest, 'signal'>` | `LLMGenerateResponse<T>` |
149
-
150
- The `signal` property (AbortSignal) is not serializable over the postMessage boundary. Abort is handled at the worker level.
151
-
152
- ### Example
153
-
154
- ```typescript
155
- interface Classification {
156
- category: 'interested' | 'not-interested' | 'bounced'
157
- confidence: number
158
- summary: string
159
- }
160
-
161
- const response = await llm.generate<Classification>({
162
- provider: 'anthropic',
163
- model: 'claude-sonnet-4-5',
164
- messages: [
165
- { role: 'system', content: 'Classify this email reply.' },
166
- { role: 'user', content: emailText },
167
- ],
168
- responseSchema: {
169
- type: 'object',
170
- properties: {
171
- category: { type: 'string', enum: ['interested', 'not-interested', 'bounced'] },
172
- confidence: { type: 'number', minimum: 0, maximum: 1 },
173
- summary: { type: 'string' },
174
- },
175
- required: ['category', 'confidence', 'summary'],
176
- },
177
- temperature: 0.1,
178
- })
179
-
180
- // response.output is typed as Classification
181
- const { category, confidence, summary } = response.output
182
- ```
183
-
184
- **Supported models:** See the full model table in [Platform Tools](index.mdx#llm-tool).
185
-
186
- See [Adapter Type Safety](type-safety.mdx) for required field enforcement and design rationale.
187
-
188
- ---
189
-
190
- ## PDF Adapter
191
-
192
- Singleton -- 2 methods for rendering PDFDocument structures to files or buffers. No credential required.
193
-
194
- ```typescript
195
- import { pdf } from '@elevasis/sdk/worker'
196
- ```
197
-
198
- ### Methods
199
-
200
- | Method | Params | Returns |
201
- | ---------------- | ------------------------------------------------- | --------------------------- |
202
- | `render` | `{ document, theme?, storage: { bucket, path } }` | `{ success, pdfUrl, size }` |
203
- | `renderToBuffer` | `{ document, theme? }` | `{ buffer }` |
204
-
205
- ### Example
206
-
207
- ```typescript
208
- // Render to storage (returns a URL)
209
- const result = await pdf.render({
210
- document: proposalDocument,
211
- storage: { bucket: 'acquisition', path: 'proposals/deal-123/proposal.pdf' },
212
- })
213
- console.log(result.pdfUrl)
214
-
215
- // Render to buffer (for inline processing)
216
- const { buffer } = await pdf.renderToBuffer({ document: proposalDocument })
217
- ```
218
-
219
- ---
220
-
221
- ## Approval Adapter
222
-
223
- Singleton -- 2 methods for creating and managing human-in-the-loop (HITL) approval tasks. No credential required.
224
-
225
- ```typescript
226
- import { approval } from '@elevasis/sdk/worker'
227
- ```
228
-
229
- ### Methods
230
-
231
- | Method | Params | Returns |
232
- | ------------------ | ---------------------------------------------------------------------------------------- | ------------- |
233
- | `create` | `{ actions, context, description?, priority?, humanCheckpoint?, metadata?, expiresAt? }` | `{ id }` |
234
- | `deleteByMetadata` | `{ metadata, status? }` | `{ deleted }` |
235
-
236
- ### Example
237
-
238
- ```typescript
239
- // Create an approval gate
240
- const task = await approval.create({
241
- actions: [
242
- { id: 'approve', label: 'Approve', type: 'primary' },
243
- { id: 'reject', label: 'Reject', type: 'danger' },
244
- ],
245
- context: { dealId: 'deal-123', proposalUrl: 'https://...' },
246
- description: 'Review proposal for Acme Corp',
247
- humanCheckpoint: 'proposal-review',
248
- metadata: { dealId: 'deal-123' },
249
- })
250
-
251
- // Clean up stale tasks
252
- await approval.deleteByMetadata({
253
- metadata: { dealId: 'deal-123' },
254
- status: 'pending',
255
- })
256
- ```
257
-
258
- ---
259
-
260
- ## Notifications Adapter
261
-
262
- Singleton -- 1 method for sending in-app team notifications. `userId` and `organizationId` are injected server-side.
263
-
264
- ```typescript
265
- import { notifications } from '@elevasis/sdk/worker'
266
- ```
267
-
268
- ### Method
269
-
270
- | Method | Params | Returns |
271
- | -------- | ---------------------- | ------- |
272
- | `create` | `NotificationSDKInput` | `void` |
273
-
274
- `NotificationSDKInput` fields: `category`, `title`, `message`, `actionUrl?`, `metadata?`
275
-
276
- ### Example
277
-
278
- ```typescript
279
- await notifications.create({
280
- category: 'acquisition',
281
- title: 'New lead qualified',
282
- message: 'Acme Corp has been qualified and moved to proposal stage.',
283
- actionUrl: '/deals/deal-123',
284
- })
285
- ```
286
-
287
- ---
288
-
289
- ## AcqDb Adapter
290
-
291
- Singleton -- 41 methods for acquisition database management (lists, companies, contacts, deals, deal-sync, enrichment, social monitoring). `organizationId` is injected server-side -- never pass it.
292
-
293
- ```typescript
294
- import { acqDb } from '@elevasis/sdk/worker'
295
- ```
296
-
297
- ### Methods
298
-
299
- **List operations:**
300
-
301
- | Method | Params | Returns |
302
- | ------------------- | --------------------------------------------------- | ------------------------- |
303
- | `listLists` | none | `AcqList[]` |
304
- | `createList` | `Omit<CreateListParams, 'organizationId'>` | `AcqList` |
305
- | `updateList` | `{ id } & UpdateListParams` | `AcqList` |
306
- | `deleteList` | `{ id }` | `void` |
307
- | `addContactsToList` | `Omit<AddContactsToListParams, 'organizationId'>` | `AddContactsToListResult` |
308
-
309
- **Company operations:**
310
-
311
- | Method | Params | Returns |
312
- | --------------- | ----------------------------------------------- | -------------------- |
313
- | `createCompany` | `Omit<CreateCompanyParams, 'organizationId'>` | `AcqCompany` |
314
- | `upsertCompany` | `Omit<UpsertCompanyParams, 'organizationId'>` | `AcqCompany` |
315
- | `updateCompany` | `{ id } & UpdateCompanyParams` | `AcqCompany` |
316
- | `getCompany` | `{ id }` | `AcqCompany | null` |
317
- | `listCompanies` | `{ filters? }` | `AcqCompany[]` |
318
- | `deleteCompany` | `{ id }` | `void` |
319
-
320
- **Contact operations:**
321
-
322
- | Method | Params | Returns |
323
- | ----------------------------- | ----------------------------------------------------- | ------------------------------- |
324
- | `createContact` | `Omit<CreateContactParams, 'organizationId'>` | `AcqContact` |
325
- | `upsertContact` | `Omit<UpsertContactParams, 'organizationId'>` | `AcqContact` |
326
- | `updateContact` | `{ id } & UpdateContactParams` | `AcqContact` |
327
- | `getContact` | `{ id }` | `AcqContact | null` |
328
- | `getContactByEmail` | `{ email }` | `AcqContact | null` |
329
- | `listContacts` | `{ filters?, pagination? }` | `PaginatedResult<AcqContact>` |
330
- | `deleteContact` | `{ id }` | `void` |
331
- | `bulkImportContacts` | `Omit<BulkImportParams, 'organizationId'>` | `BulkImportResult` |
332
- | `bulkImportCompanies` | `Omit<BulkImportCompaniesParams, 'organizationId'>` | `BulkImportCompaniesResult` |
333
- | `deactivateContactsByCompany` | `{ companyId }` | `{ deactivated: number }` |
334
-
335
- **Deal operations:**
336
-
337
- | Method | Params | Returns |
338
- | ---------------------- | -------------------------------------------- | ----------------- |
339
- | `upsertDeal` | `Omit<UpsertDealParams, 'organizationId'>` | `AcqDeal` |
340
- | `getDealByEmail` | `{ email }` | `AcqDeal | null` |
341
- | `getDealByEnvelopeId` | `{ envelopeId }` | `AcqDeal | null` |
342
- | `updateDealEnvelopeId` | `{ attioDealId, envelopeId }` | `AcqDeal | null` |
343
- | `getDealByAttioId` | `{ attioDealId }` | `AcqDeal | null` |
344
-
345
- **Deal-sync operations:**
346
-
347
- | Method | Params | Returns |
348
- | ------------------------------- | ----------------------------------------------------------- | ------------------------------------- |
349
- | `updateDiscoveryData` | `Omit<UpdateDiscoveryDataParams, 'organizationId'>` | `void` |
350
- | `updateProposalData` | `Omit<UpdateProposalDataParams, 'organizationId'>` | `void` |
351
- | `markProposalSent` | `Omit<MarkProposalSentParams, 'organizationId'>` | `void` |
352
- | `markProposalReviewed` | `Omit<MarkProposalReviewedParams, 'organizationId'>` | `void` |
353
- | `updateCloseLostReason` | `Omit<UpdateCloseLostReasonParams, 'organizationId'>` | `void` |
354
- | `updateFees` | `Omit<UpdateFeesParams, 'organizationId'>` | `void` |
355
- | `syncDealStage` | `Omit<SyncDealStageParams, 'organizationId'>` | `void` |
356
- | `setContactNurture` | `Omit<SetContactNurtureParams, 'organizationId'>` | `void` |
357
- | `cancelSchedulesAndHitlByEmail` | `Omit<..., 'organizationId'>` | `{ schedulesCancelled, hitlDeleted }` |
358
- | `cancelHitlByDealId` | `Omit<..., 'organizationId'>` | `{ hitlDeleted }` |
359
- | `clearDealFields` | `Omit<ClearDealFieldsParams, 'organizationId'>` | `void` |
360
- | `deleteDeal` | `Omit<DeleteDealParams, 'organizationId'>` | `void` |
361
- | `recordReply` | `{ contactEmail, replyText, replySubject?, campaignName? }` | `void` |
362
- | `recordDealActivity` | `{ attioDealId?, contactEmail?, type, ... }` | `void` |
363
-
364
- **Enrichment operations:**
365
-
366
- | Method | Params | Returns |
367
- | --------------------- | -------------------------------------------------------- | ------- |
368
- | `mergeEnrichmentData` | `{ id, table: 'acq_companies' | 'acq_contacts', data }` | `void` |
369
-
370
- **Social monitoring operations:**
371
-
372
- | Method | Params | Returns |
373
- | ------------------- | --------------------------------------------------------------- | ------------------------- |
374
- | `upsertSocialPosts` | `{ posts: Omit<UpsertSocialPostParams, 'organizationId'>[] }` | `UpsertSocialPostsResult` |
375
-
376
- ### Example
377
-
378
- ```typescript
379
- const deal = await acqDb.getDealByEmail({ email: 'jane@acme.com' })
380
- if (!deal) {
381
- await acqDb.upsertDeal({
382
- attioDealId: 'deal-123',
383
- contactEmail: 'jane@acme.com',
384
- })
385
- }
386
-
387
- // Bulk import contacts
388
- await acqDb.bulkImportContacts({
389
- listId: 'list-abc',
390
- contacts: [
391
- { email: 'a@example.com', firstName: 'Alice' },
392
- { email: 'b@example.com', firstName: 'Bob' },
393
- ],
394
- })
395
- ```
396
-
397
- ---
398
-
399
- ## Execution Adapter
400
-
401
- Singleton -- 1 method for triggering another resource (workflow or agent) as a nested child execution. Maximum depth: 5 levels.
402
-
403
- ```typescript
404
- import { execution } from '@elevasis/sdk/worker'
405
- ```
406
-
407
- ### Method
408
-
409
- | Method | Params | Returns |
410
- | --------- | ------------------------ | ------------------------------------------ |
411
- | `trigger` | `{ resourceId, input? }` | `{ success, executionId, output, error? }` |
412
-
413
- ### Example
414
-
415
- ```typescript
416
- const result = await execution.trigger({
417
- resourceId: 'send-welcome-sequence',
418
- input: { userId: newUser.id, email: newUser.email },
419
- })
420
-
421
- if (!result.success) {
422
- throw new Error(`Child workflow failed: ${result.error}`)
423
- }
424
- ```
425
-
426
- ---
427
-
428
- ## List Adapter
429
-
430
- Singleton -- 4 methods for list-scoped lead-gen runtime operations. This is the focused companion to `acqDb` for list-oriented workflows.
431
-
432
- ```typescript
433
- import { list } from '@elevasis/sdk/worker'
434
- ```
435
-
436
- ### Methods
437
-
438
- | Method | Params | Returns |
439
- | ------ | ------ | ------- |
440
- | `getConfig` | `{ listId }` | `ListConfig` |
441
- | `recordExecution` | `{ listId, executionId, payload? }` | `void` |
442
- | `updateCompanyStage` | `{ listId, companyId, stage, metadata? }` | `void` |
443
- | `updateContactStage` | `{ listId, contactId, stage, metadata? }` | `void` |
444
-
445
- ### Example
446
-
447
- ```typescript
448
- const config = await list.getConfig({ listId })
449
-
450
- await list.recordExecution({
451
- listId,
452
- executionId: context.executionId,
453
- payload: { resourceId: context.resourceId, step: 'qualification' },
454
- })
455
-
456
- await list.updateCompanyStage({
457
- listId,
458
- companyId,
459
- stage: 'qualified',
460
- })
461
- ```
462
-
463
- Use `list` when the workflow is explicitly operating on a list pipeline run. Use `acqDb` when you need broader list, company, contact, or deal CRUD.
464
-
465
- ---
466
-
467
- ## Email Adapter
468
-
469
- Singleton -- 1 method for sending platform emails to organization members (from `notifications@elevasis.io`). For client-facing emails, use the Resend or Instantly integration adapters instead.
470
-
471
- ```typescript
472
- import { email } from '@elevasis/sdk/worker'
473
- ```
474
-
475
- ### Method
476
-
477
- | Method | Params | Returns |
478
- | ------ | ------------------------------------------------------------------------------- | --------------------------- |
479
- | `send` | `{ subject, html?, text?, userIds?, targetRole?, targetAll?, replyTo?, tags? }` | `{ sent, failed, errors? }` |
480
-
481
- ### Example
482
-
483
- ```typescript
484
- // Notify all org members
485
- await email.send({
486
- subject: 'New deal closed',
487
- text: 'Acme Corp has signed the contract.',
488
- targetAll: true,
489
- })
490
-
491
- // Notify specific users
492
- await email.send({
493
- subject: 'Action required',
494
- html: '\<p\>Please review the proposal.\</p\>',
495
- userIds: ['user-abc', 'user-def'],
496
- })
497
- ```
498
-
499
- ---
500
-
501
- ## Custom Adapters with `createAdapter`
502
-
503
- The generic `createAdapter` factory is exported for building adapters for any tool not already covered. Define a type map and call the factory.
504
-
505
- ```typescript
506
- import { createAdapter } from '@elevasis/sdk/worker'
507
-
508
- // 1. Define a type map
509
- type MyToolMap = {
510
- doSomething: { params: { input: string }; result: { output: string } }
511
- listItems: { params: { limit?: number }; result: { items: string[] } }
512
- getStatus: { params: Record<string, never>; result: { healthy: boolean } }
513
- }
514
-
515
- // 2. Create the adapter
516
- const myTool = createAdapter<MyToolMap>('my-tool', [
517
- 'doSomething', 'listItems', 'getStatus',
518
- ], 'my-credential') // credential is optional
519
-
520
- // 3. Use it (fully typed)
521
- const result = await myTool.doSomething({ input: 'hello' })
522
- // ^-- { output: string }
523
- ```
524
-
525
- Method names are compile-time checked against the type map keys.
526
-
527
- ---
528
-
529
- ## Error Handling
530
-
531
- All adapter calls throw `PlatformToolError` on failure, with a `code` field and `retryable` flag:
532
-
533
- ```typescript
534
- import { PlatformToolError } from '@elevasis/sdk/worker'
535
-
536
- try {
537
- await scheduler.listSchedules({ status: 'active' })
538
- } catch (err) {
539
- if (err instanceof PlatformToolError) {
540
- console.log(err.message) // Human-readable error
541
- console.log(err.code) // e.g., 'rate_limit_exceeded', 'service_unavailable'
542
- console.log(err.retryable) // true for transient errors
543
- }
544
- }
545
- ```
546
-
547
- Retryable error codes: `rate_limit_exceeded`, `network_error`, `timeout_error`, `api_error`, `service_unavailable`, `server_unavailable`.
548
-
549
- **Timeouts:** LLM calls have a 120s timeout. All other tool calls have a 60s timeout.
550
-
551
- ---
552
-
553
- **Last Updated:** 2026-04-15
1
+ ---
2
+ title: Platform Adapters
3
+ description: Type-safe singleton adapters for built-in platform services -- scheduler, storage, LLM, PDF, approval, notifications, acqDb, list, execution, and email -- no credentials required
4
+ loadWhen: "Using platform service adapters (scheduler, storage, llm, pdf, approval, notifications, acqDb, list, execution, email)"
5
+ ---
6
+
7
+ Platform adapters are singleton objects imported directly from `@elevasis/sdk/worker`. They require no credential argument because the platform injects context server-side. For integration adapters (Attio, Stripe, etc.), see [Integration Adapters](adapters-integration.mdx).
8
+
9
+ ```typescript
10
+ import {
11
+ acqDb, scheduler, storage, pdf, approval,
12
+ notifications, llm, list, execution, email,
13
+ } from '@elevasis/sdk/worker'
14
+ ```
15
+
16
+ ---
17
+
18
+ ## Quick Reference
19
+
20
+ | Import | Methods | Purpose |
21
+ | --------------- | ------- | ------------------------------------ |
22
+ | `acqDb` | 49 | Acquisition database CRUD and sync |
23
+ | `scheduler` | 9 | Task schedule management |
24
+ | `storage` | 5 | File upload, download, signed URLs |
25
+ | `pdf` | 2 | PDF rendering to storage or buffer |
26
+ | `approval` | 2 | Human-in-the-loop approval gates |
27
+ | `notifications` | 1 | In-app team notifications |
28
+ | `llm` | 1 | LLM inference with structured output |
29
+ | `list` | 4 | List-scoped execution and stage ops |
30
+ | `execution` | 1 | Trigger nested child executions |
31
+ | `email` | 1 | Send email to org members |
32
+
33
+ ---
34
+
35
+ ## Scheduler Adapter
36
+
37
+ Singleton -- 9 methods for task schedule management.
38
+
39
+ ```typescript
40
+ import { scheduler } from '@elevasis/sdk/worker'
41
+ ```
42
+
43
+ ### Methods
44
+
45
+ | Method | Params | Returns |
46
+ | -------------------------------- | ------------------------------ | ---------------------- |
47
+ | `createSchedule` | `CreateScheduleInput` | `TaskSchedule` |
48
+ | `updateAnchor` | `{ scheduleId, anchorAt }` | `TaskSchedule` |
49
+ | `deleteSchedule` | `{ scheduleId }` | `void` |
50
+ | `findByIdempotencyKey` | `{ idempotencyKey }` | `TaskSchedule | null` |
51
+ | `deleteScheduleByIdempotencyKey` | `{ idempotencyKey }` | `void` |
52
+ | `listSchedules` | `{ status?, limit?, offset? }` | `TaskSchedule[]` |
53
+ | `getSchedule` | `{ scheduleId }` | `TaskSchedule` |
54
+ | `cancelSchedule` | `{ scheduleId }` | `void` |
55
+ | `cancelSchedulesByMetadata` | `{ metadata }` | `{ cancelledCount }` |
56
+
57
+ ### Examples
58
+
59
+ ```typescript
60
+ // Create a relative schedule (follow-up sequence)
61
+ const schedule = await scheduler.createSchedule({
62
+ organizationId: context.organizationId,
63
+ name: 'Proposal follow-up',
64
+ target: { resourceType: 'workflow', resourceId: 'send-followup' },
65
+ scheduleConfig: {
66
+ type: 'relative',
67
+ anchorAt: '2026-03-15T10:00:00Z',
68
+ anchorLabel: 'proposal_sent_date',
69
+ items: [
70
+ { offset: '+3d', payload: { step: 'first-followup' }, label: 'First follow-up' },
71
+ { offset: '+7d', payload: { step: 'second-followup' }, label: 'Second follow-up' },
72
+ ],
73
+ },
74
+ metadata: { dealId: 'deal-123', contactEmail: 'jane@acme.com' },
75
+ idempotencyKey: 'proposal-followup-deal-123',
76
+ })
77
+
78
+ // Reschedule (update anchor)
79
+ await scheduler.updateAnchor({
80
+ scheduleId: schedule.id,
81
+ anchorAt: '2026-03-20T10:00:00Z',
82
+ })
83
+
84
+ // Cancel all schedules matching metadata
85
+ await scheduler.cancelSchedulesByMetadata({
86
+ metadata: { dealId: 'deal-123' },
87
+ })
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Storage Adapter
93
+
94
+ Singleton -- 5 methods for file storage operations. All paths are relative to the organization's storage prefix (injected server-side).
95
+
96
+ ```typescript
97
+ import { storage } from '@elevasis/sdk/worker'
98
+ ```
99
+
100
+ ### Methods
101
+
102
+ | Method | Params | Returns |
103
+ | ----------------- | ----------------------- | ------------------------ |
104
+ | `upload` | `StorageUploadInput` | `StorageUploadOutput` |
105
+ | `download` | `StorageDownloadInput` | `StorageDownloadOutput` |
106
+ | `createSignedUrl` | `StorageSignedUrlInput` | `StorageSignedUrlOutput` |
107
+ | `delete` | `StorageDeleteInput` | `StorageDeleteOutput` |
108
+ | `list` | `StorageListInput` | `StorageListOutput` |
109
+
110
+ ### Examples
111
+
112
+ ```typescript
113
+ // Upload a PDF
114
+ await storage.upload({
115
+ bucket: 'acquisition',
116
+ path: 'proposals/deal-123/proposal.pdf',
117
+ content: base64PdfContent,
118
+ contentType: 'application/pdf',
119
+ })
120
+
121
+ // Generate a signed URL (temporary access)
122
+ const { signedUrl } = await storage.createSignedUrl({
123
+ bucket: 'acquisition',
124
+ path: 'proposals/deal-123/proposal.pdf',
125
+ })
126
+
127
+ // List files under a prefix
128
+ const files = await storage.list({
129
+ bucket: 'acquisition',
130
+ path: 'proposals/deal-123/',
131
+ })
132
+ ```
133
+
134
+ ---
135
+
136
+ ## LLM Adapter
137
+
138
+ Singleton -- 1 method with a generic `<T>` for typed structured output. No API keys needed -- keys are resolved server-side from environment variables.
139
+
140
+ ```typescript
141
+ import { llm } from '@elevasis/sdk/worker'
142
+ ```
143
+
144
+ ### Method
145
+
146
+ | Method | Params | Returns |
147
+ | --------------- | -------------------------------------- | -------------------------- |
148
+ | `generate<T>` | `Omit<LLMGenerateRequest, 'signal'>` | `LLMGenerateResponse<T>` |
149
+
150
+ The `signal` property (AbortSignal) is not serializable over the postMessage boundary. Abort is handled at the worker level.
151
+
152
+ ### Example
153
+
154
+ ```typescript
155
+ interface Classification {
156
+ category: 'interested' | 'not-interested' | 'bounced'
157
+ confidence: number
158
+ summary: string
159
+ }
160
+
161
+ const response = await llm.generate<Classification>({
162
+ provider: 'anthropic',
163
+ model: 'claude-sonnet-4-5',
164
+ messages: [
165
+ { role: 'system', content: 'Classify this email reply.' },
166
+ { role: 'user', content: emailText },
167
+ ],
168
+ responseSchema: {
169
+ type: 'object',
170
+ properties: {
171
+ category: { type: 'string', enum: ['interested', 'not-interested', 'bounced'] },
172
+ confidence: { type: 'number', minimum: 0, maximum: 1 },
173
+ summary: { type: 'string' },
174
+ },
175
+ required: ['category', 'confidence', 'summary'],
176
+ },
177
+ temperature: 0.1,
178
+ })
179
+
180
+ // response.output is typed as Classification
181
+ const { category, confidence, summary } = response.output
182
+ ```
183
+
184
+ **Supported models:** See the full model table in [Platform Tools](index.mdx#llm-tool).
185
+
186
+ See [Adapter Type Safety](type-safety.mdx) for required field enforcement and design rationale.
187
+
188
+ ---
189
+
190
+ ## PDF Adapter
191
+
192
+ Singleton -- 2 methods for rendering PDFDocument structures to files or buffers. No credential required.
193
+
194
+ ```typescript
195
+ import { pdf } from '@elevasis/sdk/worker'
196
+ ```
197
+
198
+ ### Methods
199
+
200
+ | Method | Params | Returns |
201
+ | ---------------- | ------------------------------------------------- | --------------------------- |
202
+ | `render` | `{ document, theme?, storage: { bucket, path } }` | `{ success, pdfUrl, size }` |
203
+ | `renderToBuffer` | `{ document, theme? }` | `{ buffer }` |
204
+
205
+ ### Example
206
+
207
+ ```typescript
208
+ // Render to storage (returns a URL)
209
+ const result = await pdf.render({
210
+ document: proposalDocument,
211
+ storage: { bucket: 'acquisition', path: 'proposals/deal-123/proposal.pdf' },
212
+ })
213
+ console.log(result.pdfUrl)
214
+
215
+ // Render to buffer (for inline processing)
216
+ const { buffer } = await pdf.renderToBuffer({ document: proposalDocument })
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Approval Adapter
222
+
223
+ Singleton -- 2 methods for creating and managing human-in-the-loop (HITL) approval tasks. No credential required.
224
+
225
+ ```typescript
226
+ import { approval } from '@elevasis/sdk/worker'
227
+ ```
228
+
229
+ ### Methods
230
+
231
+ | Method | Params | Returns |
232
+ | ------------------ | ---------------------------------------------------------------------------------------- | ------------- |
233
+ | `create` | `{ actions, context, description?, priority?, humanCheckpoint?, metadata?, expiresAt? }` | `{ id }` |
234
+ | `deleteByMetadata` | `{ metadata, status? }` | `{ deleted }` |
235
+
236
+ ### Example
237
+
238
+ ```typescript
239
+ // Create an approval gate
240
+ const task = await approval.create({
241
+ actions: [
242
+ { id: 'approve', label: 'Approve', type: 'primary' },
243
+ { id: 'reject', label: 'Reject', type: 'danger' },
244
+ ],
245
+ context: { dealId: 'deal-123', proposalUrl: 'https://...' },
246
+ description: 'Review proposal for Acme Corp',
247
+ humanCheckpoint: 'proposal-review',
248
+ metadata: { dealId: 'deal-123' },
249
+ })
250
+
251
+ // Clean up stale tasks
252
+ await approval.deleteByMetadata({
253
+ metadata: { dealId: 'deal-123' },
254
+ status: 'pending',
255
+ })
256
+ ```
257
+
258
+ ---
259
+
260
+ ## Notifications Adapter
261
+
262
+ Singleton -- 1 method for sending in-app team notifications. `userId` and `organizationId` are injected server-side.
263
+
264
+ ```typescript
265
+ import { notifications } from '@elevasis/sdk/worker'
266
+ ```
267
+
268
+ ### Method
269
+
270
+ | Method | Params | Returns |
271
+ | -------- | ---------------------- | ------- |
272
+ | `create` | `NotificationSDKInput` | `void` |
273
+
274
+ `NotificationSDKInput` fields: `category`, `title`, `message`, `actionUrl?`, `metadata?`
275
+
276
+ ### Example
277
+
278
+ ```typescript
279
+ await notifications.create({
280
+ category: 'acquisition',
281
+ title: 'New lead qualified',
282
+ message: 'Acme Corp has been qualified and moved to proposal stage.',
283
+ actionUrl: '/deals/deal-123',
284
+ })
285
+ ```
286
+
287
+ ---
288
+
289
+ ## AcqDb Adapter
290
+
291
+ Singleton -- 41 methods for acquisition database management (lists, companies, contacts, deals, deal-sync, enrichment, social monitoring). `organizationId` is injected server-side -- never pass it.
292
+
293
+ ```typescript
294
+ import { acqDb } from '@elevasis/sdk/worker'
295
+ ```
296
+
297
+ ### Methods
298
+
299
+ **List operations:**
300
+
301
+ | Method | Params | Returns |
302
+ | ------------------- | --------------------------------------------------- | ------------------------- |
303
+ | `listLists` | none | `AcqList[]` |
304
+ | `createList` | `Omit<CreateListParams, 'organizationId'>` | `AcqList` |
305
+ | `updateList` | `{ id } & UpdateListParams` | `AcqList` |
306
+ | `deleteList` | `{ id }` | `void` |
307
+ | `addContactsToList` | `Omit<AddContactsToListParams, 'organizationId'>` | `AddContactsToListResult` |
308
+
309
+ **Company operations:**
310
+
311
+ | Method | Params | Returns |
312
+ | --------------- | ----------------------------------------------- | -------------------- |
313
+ | `createCompany` | `Omit<CreateCompanyParams, 'organizationId'>` | `AcqCompany` |
314
+ | `upsertCompany` | `Omit<UpsertCompanyParams, 'organizationId'>` | `AcqCompany` |
315
+ | `updateCompany` | `{ id } & UpdateCompanyParams` | `AcqCompany` |
316
+ | `getCompany` | `{ id }` | `AcqCompany | null` |
317
+ | `listCompanies` | `{ filters? }` | `AcqCompany[]` |
318
+ | `deleteCompany` | `{ id }` | `void` |
319
+
320
+ **Contact operations:**
321
+
322
+ | Method | Params | Returns |
323
+ | ----------------------------- | ----------------------------------------------------- | ------------------------------- |
324
+ | `createContact` | `Omit<CreateContactParams, 'organizationId'>` | `AcqContact` |
325
+ | `upsertContact` | `Omit<UpsertContactParams, 'organizationId'>` | `AcqContact` |
326
+ | `updateContact` | `{ id } & UpdateContactParams` | `AcqContact` |
327
+ | `getContact` | `{ id }` | `AcqContact | null` |
328
+ | `getContactByEmail` | `{ email }` | `AcqContact | null` |
329
+ | `listContacts` | `{ filters?, pagination? }` | `PaginatedResult<AcqContact>` |
330
+ | `deleteContact` | `{ id }` | `void` |
331
+ | `bulkImportContacts` | `Omit<BulkImportParams, 'organizationId'>` | `BulkImportResult` |
332
+ | `bulkImportCompanies` | `Omit<BulkImportCompaniesParams, 'organizationId'>` | `BulkImportCompaniesResult` |
333
+ | `deactivateContactsByCompany` | `{ companyId }` | `{ deactivated: number }` |
334
+
335
+ **Deal operations:**
336
+
337
+ | Method | Params | Returns |
338
+ | ---------------------- | -------------------------------------------- | ----------------- |
339
+ | `upsertDeal` | `Omit<UpsertDealParams, 'organizationId'>` | `AcqDeal` |
340
+ | `getDealByEmail` | `{ email }` | `AcqDeal | null` |
341
+ | `getDealByEnvelopeId` | `{ envelopeId }` | `AcqDeal | null` |
342
+ | `updateDealEnvelopeId` | `{ attioDealId, envelopeId }` | `AcqDeal | null` |
343
+ | `getDealByAttioId` | `{ attioDealId }` | `AcqDeal | null` |
344
+
345
+ **Deal-sync operations:**
346
+
347
+ | Method | Params | Returns |
348
+ | ------------------------------- | ----------------------------------------------------------- | ------------------------------------- |
349
+ | `updateDiscoveryData` | `Omit<UpdateDiscoveryDataParams, 'organizationId'>` | `void` |
350
+ | `updateProposalData` | `Omit<UpdateProposalDataParams, 'organizationId'>` | `void` |
351
+ | `markProposalSent` | `Omit<MarkProposalSentParams, 'organizationId'>` | `void` |
352
+ | `markProposalReviewed` | `Omit<MarkProposalReviewedParams, 'organizationId'>` | `void` |
353
+ | `updateCloseLostReason` | `Omit<UpdateCloseLostReasonParams, 'organizationId'>` | `void` |
354
+ | `updateFees` | `Omit<UpdateFeesParams, 'organizationId'>` | `void` |
355
+ | `syncDealStage` | `Omit<SyncDealStageParams, 'organizationId'>` | `void` |
356
+ | `setContactNurture` | `Omit<SetContactNurtureParams, 'organizationId'>` | `void` |
357
+ | `cancelSchedulesAndHitlByEmail` | `Omit<..., 'organizationId'>` | `{ schedulesCancelled, hitlDeleted }` |
358
+ | `cancelHitlByDealId` | `Omit<..., 'organizationId'>` | `{ hitlDeleted }` |
359
+ | `clearDealFields` | `Omit<ClearDealFieldsParams, 'organizationId'>` | `void` |
360
+ | `deleteDeal` | `Omit<DeleteDealParams, 'organizationId'>` | `void` |
361
+ | `recordReply` | `{ contactEmail, replyText, replySubject?, campaignName? }` | `void` |
362
+ | `recordDealActivity` | `{ attioDealId?, contactEmail?, type, ... }` | `void` |
363
+
364
+ **Enrichment operations:**
365
+
366
+ | Method | Params | Returns |
367
+ | --------------------- | -------------------------------------------------------- | ------- |
368
+ | `mergeEnrichmentData` | `{ id, table: 'acq_companies' | 'acq_contacts', data }` | `void` |
369
+
370
+ **Social monitoring operations:**
371
+
372
+ | Method | Params | Returns |
373
+ | ------------------- | --------------------------------------------------------------- | ------------------------- |
374
+ | `upsertSocialPosts` | `{ posts: Omit<UpsertSocialPostParams, 'organizationId'>[] }` | `UpsertSocialPostsResult` |
375
+
376
+ ### Example
377
+
378
+ ```typescript
379
+ const deal = await acqDb.getDealByEmail({ email: 'jane@acme.com' })
380
+ if (!deal) {
381
+ await acqDb.upsertDeal({
382
+ attioDealId: 'deal-123',
383
+ contactEmail: 'jane@acme.com',
384
+ })
385
+ }
386
+
387
+ // Bulk import contacts
388
+ await acqDb.bulkImportContacts({
389
+ listId: 'list-abc',
390
+ contacts: [
391
+ { email: 'a@example.com', firstName: 'Alice' },
392
+ { email: 'b@example.com', firstName: 'Bob' },
393
+ ],
394
+ })
395
+ ```
396
+
397
+ ---
398
+
399
+ ## Execution Adapter
400
+
401
+ Singleton -- 1 method for triggering another resource (workflow or agent) as a nested child execution. Maximum depth: 5 levels.
402
+
403
+ ```typescript
404
+ import { execution } from '@elevasis/sdk/worker'
405
+ ```
406
+
407
+ ### Method
408
+
409
+ | Method | Params | Returns |
410
+ | --------- | ------------------------ | ------------------------------------------ |
411
+ | `trigger` | `{ resourceId, input? }` | `{ success, executionId, output, error? }` |
412
+
413
+ ### Example
414
+
415
+ ```typescript
416
+ const result = await execution.trigger({
417
+ resourceId: 'send-welcome-sequence',
418
+ input: { userId: newUser.id, email: newUser.email },
419
+ })
420
+
421
+ if (!result.success) {
422
+ throw new Error(`Child workflow failed: ${result.error}`)
423
+ }
424
+ ```
425
+
426
+ ---
427
+
428
+ ## List Adapter
429
+
430
+ Singleton -- 4 methods for list-scoped lead-gen runtime operations. This is the focused companion to `acqDb` for list-oriented workflows.
431
+
432
+ ```typescript
433
+ import { list } from '@elevasis/sdk/worker'
434
+ ```
435
+
436
+ ### Methods
437
+
438
+ | Method | Params | Returns |
439
+ | ------ | ------ | ------- |
440
+ | `getConfig` | `{ listId }` | `ListConfig` |
441
+ | `recordExecution` | `{ listId, executionId, payload? }` | `void` |
442
+ | `updateCompanyStage` | `{ listId, companyId, stage, metadata? }` | `void` |
443
+ | `updateContactStage` | `{ listId, contactId, stage, metadata? }` | `void` |
444
+
445
+ ### Example
446
+
447
+ ```typescript
448
+ const config = await list.getConfig({ listId })
449
+
450
+ await list.recordExecution({
451
+ listId,
452
+ executionId: context.executionId,
453
+ payload: { resourceId: context.resourceId, step: 'qualification' },
454
+ })
455
+
456
+ await list.updateCompanyStage({
457
+ listId,
458
+ companyId,
459
+ stage: 'qualified',
460
+ })
461
+ ```
462
+
463
+ Use `list` when the workflow is explicitly operating on a list pipeline run. Use `acqDb` when you need broader list, company, contact, or deal CRUD.
464
+
465
+ ---
466
+
467
+ ## Email Adapter
468
+
469
+ Singleton -- 1 method for sending platform emails to organization members (from `notifications@elevasis.io`). For client-facing emails, use the Resend or Instantly integration adapters instead.
470
+
471
+ ```typescript
472
+ import { email } from '@elevasis/sdk/worker'
473
+ ```
474
+
475
+ ### Method
476
+
477
+ | Method | Params | Returns |
478
+ | ------ | ------------------------------------------------------------------------------- | --------------------------- |
479
+ | `send` | `{ subject, html?, text?, userIds?, targetRole?, targetAll?, replyTo?, tags? }` | `{ sent, failed, errors? }` |
480
+
481
+ ### Example
482
+
483
+ ```typescript
484
+ // Notify all org members
485
+ await email.send({
486
+ subject: 'New deal closed',
487
+ text: 'Acme Corp has signed the contract.',
488
+ targetAll: true,
489
+ })
490
+
491
+ // Notify specific users
492
+ await email.send({
493
+ subject: 'Action required',
494
+ html: '\<p\>Please review the proposal.\</p\>',
495
+ userIds: ['user-abc', 'user-def'],
496
+ })
497
+ ```
498
+
499
+ ---
500
+
501
+ ## Custom Adapters with `createAdapter`
502
+
503
+ The generic `createAdapter` factory is exported for building adapters for any tool not already covered. Define a type map and call the factory.
504
+
505
+ ```typescript
506
+ import { createAdapter } from '@elevasis/sdk/worker'
507
+
508
+ // 1. Define a type map
509
+ type MyToolMap = {
510
+ doSomething: { params: { input: string }; result: { output: string } }
511
+ listItems: { params: { limit?: number }; result: { items: string[] } }
512
+ getStatus: { params: Record<string, never>; result: { healthy: boolean } }
513
+ }
514
+
515
+ // 2. Create the adapter
516
+ const myTool = createAdapter<MyToolMap>('my-tool', [
517
+ 'doSomething', 'listItems', 'getStatus',
518
+ ], 'my-credential') // credential is optional
519
+
520
+ // 3. Use it (fully typed)
521
+ const result = await myTool.doSomething({ input: 'hello' })
522
+ // ^-- { output: string }
523
+ ```
524
+
525
+ Method names are compile-time checked against the type map keys.
526
+
527
+ ---
528
+
529
+ ## Error Handling
530
+
531
+ All adapter calls throw `PlatformToolError` on failure, with a `code` field and `retryable` flag:
532
+
533
+ ```typescript
534
+ import { PlatformToolError } from '@elevasis/sdk/worker'
535
+
536
+ try {
537
+ await scheduler.listSchedules({ status: 'active' })
538
+ } catch (err) {
539
+ if (err instanceof PlatformToolError) {
540
+ console.log(err.message) // Human-readable error
541
+ console.log(err.code) // e.g., 'rate_limit_exceeded', 'service_unavailable'
542
+ console.log(err.retryable) // true for transient errors
543
+ }
544
+ }
545
+ ```
546
+
547
+ Retryable error codes: `rate_limit_exceeded`, `network_error`, `timeout_error`, `api_error`, `service_unavailable`, `server_unavailable`.
548
+
549
+ **Timeouts:** LLM calls have a 120s timeout. All other tool calls have a 60s timeout.
550
+
551
+ ---
552
+
553
+ **Last Updated:** 2026-04-15