@elevasis/sdk 0.5.12 → 0.5.13

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 (32) hide show
  1. package/dist/cli.cjs +92 -81
  2. package/dist/index.d.ts +11 -253
  3. package/dist/index.js +5 -9
  4. package/dist/templates.js +26 -23
  5. package/dist/types/worker/adapters/index.d.ts +0 -1
  6. package/dist/worker/index.js +47 -53
  7. package/package.json +1 -1
  8. package/reference/_navigation.md +13 -57
  9. package/reference/concepts.mdx +203 -0
  10. package/reference/deployment/{command-center-ui.mdx → command-center.mdx} +229 -151
  11. package/reference/deployment/index.mdx +158 -153
  12. package/reference/framework/agent.mdx +168 -151
  13. package/reference/framework/index.mdx +182 -103
  14. package/reference/framework/memory.mdx +347 -347
  15. package/reference/framework/tutorial-system.mdx +253 -0
  16. package/reference/{getting-started/index.mdx → getting-started.mdx} +4 -4
  17. package/reference/index.mdx +117 -114
  18. package/reference/platform-tools/adapters.mdx +175 -32
  19. package/reference/platform-tools/index.mdx +354 -195
  20. package/reference/resources/index.mdx +5 -0
  21. package/reference/{roadmap/index.mdx → roadmap.mdx} +1 -1
  22. package/reference/{runtime/index.mdx → runtime.mdx} +196 -141
  23. package/dist/types/worker/adapters/trello.d.ts +0 -14
  24. package/reference/concepts/index.mdx +0 -203
  25. package/reference/deployment/command-view.mdx +0 -154
  26. package/reference/framework/documentation.mdx +0 -92
  27. package/reference/platform-tools/examples.mdx +0 -170
  28. package/reference/runtime/limits.mdx +0 -75
  29. package/reference/security/credentials.mdx +0 -141
  30. /package/reference/{cli/index.mdx → cli.mdx} +0 -0
  31. /package/reference/{developer → framework}/interaction-guidance.mdx +0 -0
  32. /package/reference/{troubleshooting/common-errors.mdx → troubleshooting.mdx} +0 -0
@@ -1,154 +0,0 @@
1
- ---
2
- title: Command View
3
- description: How the Command View graph works -- node types, relationships, what is enforced vs decorative, and what the platform needs to render your resource graph
4
- loadWhen: "Deploying resources or building resources that invoke other resources"
5
- ---
6
-
7
- The Command View is a visual graph in the Elevasis command center that shows how your organization's resources connect. Nodes are resources (workflows, agents, integrations). Edges are relationships you declare between them. The graph helps operators understand how automation flows through the system at a glance.
8
-
9
- ---
10
-
11
- ## Node Types
12
-
13
- Every resource you deploy becomes a node in the Command View. Some nodes are executable (the platform runs them); others are visual-only (they exist for the graph but have no runtime behavior).
14
-
15
- ### Executable Nodes
16
-
17
- | Type | What It Does | Deployed By |
18
- | ---- | ------------ | ----------- |
19
- | Workflow | Runs step handlers in sequence or branching paths | `elevasis-sdk deploy` |
20
- | Agent | Autonomous LLM-powered resource with tools | `elevasis-sdk deploy` |
21
-
22
- ### Visual-Only Nodes
23
-
24
- These exist solely for the Command View graph. They have no runtime behavior -- the platform does not execute them.
25
-
26
- | Type | What It Represents | Why It Exists |
27
- | ---- | ------------------ | ------------- |
28
- | Trigger | A webhook or schedule that starts a workflow | Shows how executions begin |
29
- | Integration | A credential reference (provider + credential name) | Shows which external services a resource uses |
30
- | External Resource | A third-party automation (n8n, Make, Zapier) | Documents automations outside the platform |
31
- | Human Checkpoint | A point where a human makes a decision | Shows where HITL approval gates exist |
32
-
33
- Visual-only nodes are declarations. A `TriggerDefinition` does not set up actual trigger routing -- the webhook gateway routes independently. An `IntegrationDefinition` does not configure or connect to anything -- it is a visual node referencing a credential.
34
-
35
- ---
36
-
37
- ## Relationships
38
-
39
- Relationships are edges in the Command View graph. You declare them in `OrganizationResources` to tell the platform how resources connect.
40
-
41
- ### Declaring Relationships
42
-
43
- ```typescript
44
- const org: OrganizationResources = {
45
- workflows: {
46
- 'score-lead': scoreLeadWorkflow,
47
- 'send-proposal': sendProposalWorkflow,
48
- },
49
- agents: {
50
- 'research-agent': researchAgent,
51
- },
52
- relationships: {
53
- 'score-lead': {
54
- triggers: {
55
- workflows: ['send-proposal'], // score-lead triggers send-proposal
56
- agents: ['research-agent'], // score-lead triggers research-agent
57
- },
58
- uses: {
59
- integrations: ['attio-integration'], // score-lead uses Attio
60
- },
61
- },
62
- },
63
- };
64
- ```
65
-
66
- ### Relationship Fields
67
-
68
- | Field | Type | Meaning |
69
- | ----- | ---- | ------- |
70
- | `triggers.workflows` | `string[]` | Workflows this resource starts |
71
- | `triggers.agents` | `string[]` | Agents this resource starts |
72
- | `uses.integrations` | `string[]` | Integrations this resource depends on |
73
-
74
- All referenced IDs must exist in the same organization. Missing targets cause a validation error at deploy time.
75
-
76
- ### Relationships Are Declarations, Not Routing
77
-
78
- Relationships tell the Command View what edges to draw. They do **not** create execution paths. If you declare that workflow A triggers workflow B, the platform does not automatically route A's output to B. Your handler code must explicitly invoke B using the `execution` adapter or `platform.call()`.
79
-
80
- This means the graph can drift from reality:
81
-
82
- - If your code invokes resource B but you forgot to declare the relationship, the edge is **missing** from the graph
83
- - If you declared a relationship to resource B but your code never invokes it, the edge is **stale** in the graph
84
-
85
- ---
86
-
87
- ## What Is Enforced vs Decorative
88
-
89
- | Category | Validated at Deploy | Matches Runtime | Status |
90
- | -------- | ------------------- | --------------- | ------ |
91
- | Resource IDs unique | Yes | Yes | **Enforced** |
92
- | Input schema matches execution interface | Yes | Yes | **Enforced** |
93
- | Relationship targets exist | Yes | No -- invocations are hardcoded strings in handlers | **Decorative** |
94
- | Trigger routing | No | No -- webhook handlers route independently | **Decorative** |
95
- | Tool availability per agent | No | No -- tools built dynamically at runtime | **Decorative** |
96
- | Model config | Yes (provider + model valid) | No -- runtime uses environment config | **Decorative** |
97
- | Integration usage | Partial (IDs checked) | No -- credentials resolved at runtime | **Decorative** |
98
-
99
- **Enforced** means the platform rejects invalid state. **Decorative** means the platform trusts your declaration but does not verify it matches what the code actually does.
100
-
101
- ### What This Means for You
102
-
103
- - Keep relationships in sync with your handler code. When you add an `execution.trigger('other-resource')` call, add the corresponding relationship declaration.
104
- - When you remove an invocation, remove the relationship.
105
- - The Command View is only as accurate as your declarations.
106
-
107
- ---
108
-
109
- ## Deploy-Time Validation
110
-
111
- When you run `elevasis-sdk deploy` or `elevasis-sdk check`, the SDK validates your resource definitions locally using the same `ResourceRegistry` the platform uses.
112
-
113
- ### What Gets Checked
114
-
115
- - **Duplicate resource IDs** -- two resources with the same key in `workflows` or `agents`
116
- - **Relationship targets exist** -- every ID in `triggers` and `uses` must match a resource or integration in the same `OrganizationResources`
117
- - **Model configuration** -- agent model params (provider, model name, temperature bounds) are valid
118
- - **Step chains** -- `next.target` values in multi-step workflows point to existing step names
119
-
120
- ### What Does Not Get Checked
121
-
122
- - Whether your handler code actually invokes the resources you declared in relationships
123
- - Whether your handler code invokes resources you did **not** declare in relationships
124
- - Whether triggers route to the workflows you declared
125
- - Whether agents use the tools you expect
126
-
127
- These are the decorative gaps listed above. The graph is a best-effort representation that depends on you keeping declarations in sync with code.
128
-
129
- ### Validation Error Examples
130
-
131
- ```
132
- ERROR Relationship target 'send-proposal' not found in organization resources
133
- Resource: score-lead
134
- Field: relationships.triggers.workflows
135
-
136
- ERROR Duplicate resource ID 'score-lead' in organization
137
- ```
138
-
139
- Fix relationship errors by checking that the target resource ID is spelled correctly and exists in your `OrganizationResources` export. If the resource was renamed or removed, update the relationship to match.
140
-
141
- ---
142
-
143
- ## Graph Serialization
144
-
145
- The platform converts your resource definitions and relationships into a visual graph using two data structures:
146
-
147
- - **`CommandViewNode`** -- one per resource (workflow, agent, trigger, integration, etc.). Contains the resource ID, type, name, status, and metadata.
148
- - **`CommandViewEdge`** -- one per relationship. Contains source node, target node, and edge type (triggers, uses).
149
-
150
- The `buildEdges()` function in the platform registry reads your `relationships` declarations and produces `CommandViewEdge[]`. This is a pure transformation -- it does not add or remove edges based on runtime behavior.
151
-
152
- ---
153
-
154
- **Last Updated:** 2026-03-02
@@ -1,92 +0,0 @@
1
- ---
2
- title: Resource Documentation
3
- description: Write and deploy MDX documentation alongside your Elevasis resources
4
- loadWhen: "Writing or updating project documentation"
5
- ---
6
-
7
- `elevasis-sdk deploy` ships your code and your documentation atomically -- one command, no version drift. Documentation files live in a `docs/` directory at your project root and render in the Elevasis platform UI for operators using your resources.
8
-
9
- ## Directory Structure
10
-
11
- Create `.mdx` files inside a `docs/` directory at your project root. `elevasis-sdk init` scaffolds a starter structure:
12
-
13
- ```
14
- my-project/
15
- ├── docs/
16
- │ └── index.mdx # Resource overview (scaffolded by init)
17
- ├── src/
18
- │ └── index.ts # Resource definitions
19
- ├── elevasis.config.ts
20
- └── ...
21
- ```
22
-
23
- A missing `docs/` directory is silently ignored -- documentation is optional. If the directory exists, its contents are included in the deploy payload alongside resource schemas.
24
-
25
- ## Frontmatter Schema
26
-
27
- Every documentation file supports a frontmatter block at the top:
28
-
29
- ```yaml
30
- ---
31
- title: string # Page title (required)
32
- description: string # Short description (optional)
33
- order: number # Sort order within directory (optional, default: 0)
34
- ---
35
- ```
36
-
37
- ## Naming Conventions
38
-
39
- - `docs/index.mdx` is the root documentation page and is always rendered first
40
- - Nested directories create sections: `docs/guides/getting-started.mdx`
41
- - File names become URL slugs: `setup-guide.mdx` renders at `/docs/setup-guide`
42
- - Arbitrary nesting is supported -- there is no depth limit
43
-
44
- ## Size Limits
45
-
46
- - 100KB per file
47
- - 1MB total across all files in a deployment
48
-
49
- These limits are enforced by the CLI before the deploy request is sent. Validation errors include the file name and size.
50
-
51
- ## Starter Template
52
-
53
- `elevasis-sdk init` writes this starter file to `docs/index.mdx`:
54
-
55
- ```mdx
56
- ---
57
- title: Overview
58
- description: Documentation for this Elevasis project
59
- ---
60
-
61
- # Overview
62
-
63
- Welcome to the documentation for this project.
64
-
65
- ## Resources
66
-
67
- Describe your workflows and agents here. This documentation is deployed alongside your
68
- code and rendered in the Elevasis platform UI.
69
-
70
- ## Getting Started
71
-
72
- \`\`\`bash
73
- elevasis-sdk check # Validate resources
74
- elevasis-sdk deploy # Deploy to platform
75
- elevasis-sdk exec <resourceId> --input '{"key": "value"}'
76
- \`\`\`
77
- ```
78
-
79
- ## Deploy Behavior
80
-
81
- When you run `elevasis-sdk deploy`:
82
-
83
- 1. The CLI scans `docs/` recursively for `.mdx` files
84
- 2. Each file's frontmatter (title, description, order) is parsed and stripped from the content
85
- 3. Total size is validated against the 1MB limit and individual files against 100KB
86
- 4. The documentation array is included in the deploy metadata alongside your resource schemas
87
-
88
- Documentation and code ship in the same transaction. There is no separate upload step and no way for documentation to drift out of sync with the deployed version.
89
-
90
- ---
91
-
92
- **Last Updated:** 2026-02-25
@@ -1,170 +0,0 @@
1
- ---
2
- title: Integration Examples
3
- description: Working code examples for email, CRM, PDF, LLM inference, resource triggering, and storage using typed adapters and platform.call()
4
- loadWhen: "Implementing a platform tool call in a workflow step"
5
- ---
6
-
7
- Working code examples for common tool integrations. All tools shown here have [typed adapters](adapters.mdx) that provide full autocomplete and compile-time checking -- prefer adapters in new code. The `platform.call()` patterns below are kept as reference and for tools without adapters yet (supabase).
8
-
9
- ## Sending Email via Resend
10
-
11
- Send a transactional email through your Resend account. Store your Resend API key as a credential named `resend` using the [Elevasis CLI](../cli/index.mdx).
12
-
13
- ```typescript
14
- import { createResendAdapter } from '@elevasis/sdk/worker'
15
-
16
- const resend = createResendAdapter('resend')
17
- const result = await resend.sendEmail({
18
- from: 'hello@yourapp.com',
19
- to: 'customer@example.com',
20
- subject: 'Your order is confirmed',
21
- html: '\<p\>Thank you for your order!\</p\>',
22
- })
23
- ```
24
-
25
- The `credential` value must match the name you used when storing the API key. Resend supports `{ apiKey }` as its credential shape.
26
-
27
- ## Creating a CRM Record via Attio
28
-
29
- Create a contact or company record in Attio. Store your Attio API key as a credential named `attio`.
30
-
31
- ```typescript
32
- import { createAttioAdapter } from '@elevasis/sdk/worker'
33
-
34
- const attio = createAttioAdapter('attio')
35
- const result = await attio.createRecord({
36
- object: 'people',
37
- values: {
38
- name: [{ full_name: 'Jane Smith' }],
39
- email_addresses: [{ email_address: 'jane@example.com' }],
40
- },
41
- })
42
-
43
- const recordId = result.data.id
44
- ```
45
-
46
- Attio exposes 12 methods covering CRUD operations, schema inspection, and notes. See the [typed adapter reference](adapters.mdx#attio-crm-adapter) for the full method list.
47
-
48
- ## Generating a PDF
49
-
50
- Render a PDF from a document structure or template. No credential required -- PDF generation is a built-in platform service.
51
-
52
- ```typescript
53
- import { pdf, storage } from '@elevasis/sdk/worker'
54
-
55
- // Render to storage directly
56
- const result = await pdf.render({
57
- document: proposalDocument,
58
- storage: { bucket: 'invoices', path: 'invoice-1042.pdf' },
59
- })
60
- console.log(result.pdfUrl)
61
-
62
- // Or render to buffer for inline processing
63
- const { buffer } = await pdf.renderToBuffer({
64
- document: proposalDocument,
65
- })
66
-
67
- // Then upload manually if needed
68
- await storage.upload({
69
- bucket: 'invoices',
70
- path: 'invoice-1042.pdf',
71
- content: buffer,
72
- contentType: 'application/pdf',
73
- })
74
- ```
75
-
76
- ## Making an LLM Call with Structured Output
77
-
78
- Use the `llm` adapter to call any supported model with a JSON Schema for structured output. No API keys are needed in your code -- keys are resolved server-side.
79
-
80
- ```typescript
81
- import { llm } from '@elevasis/sdk/worker'
82
-
83
- interface TicketClassification {
84
- priority: 'low' | 'medium' | 'high' | 'critical'
85
- category: 'billing' | 'technical' | 'account' | 'other'
86
- sentiment: 'positive' | 'neutral' | 'negative'
87
- summary: string
88
- }
89
-
90
- const response = await llm.generate\<TicketClassification\>({
91
- provider: 'anthropic',
92
- model: 'claude-sonnet-4-5',
93
- messages: [
94
- { role: 'system', content: 'You extract structured data from support tickets.' },
95
- { role: 'user', content: ticketText },
96
- ],
97
- responseSchema: {
98
- type: 'object',
99
- properties: {
100
- priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
101
- category: { type: 'string', enum: ['billing', 'technical', 'account', 'other'] },
102
- sentiment: { type: 'string', enum: ['positive', 'neutral', 'negative'] },
103
- summary: { type: 'string' },
104
- },
105
- required: ['priority', 'category', 'sentiment', 'summary'],
106
- },
107
- temperature: 0.1,
108
- })
109
-
110
- // response.output is typed as TicketClassification
111
- const { priority, category, summary } = response.output
112
- ```
113
-
114
- Supported providers: `google`, `openai`, `anthropic`, `openrouter`. See [Platform Tools](index.mdx) for the full model list.
115
-
116
- ## Triggering Another Resource
117
-
118
- Trigger a separate workflow or agent as a nested child execution. The call is synchronous -- your workflow waits for the child to complete and receives its output.
119
-
120
- ```typescript
121
- import { execution } from '@elevasis/sdk/worker'
122
-
123
- const outcome = await execution.trigger({
124
- resourceId: 'send-welcome-sequence',
125
- input: {
126
- userId: newUser.id,
127
- email: newUser.email,
128
- plan: 'pro',
129
- },
130
- })
131
-
132
- if (!outcome.success) {
133
- throw new Error(`Child workflow failed: ${outcome.error}`)
134
- }
135
-
136
- // outcome = { success: true, executionId: '...', output: { emailsSent: 3 }, error: undefined }
137
- ```
138
-
139
- Nested executions are tracked with depth up to a maximum of 5 levels. Both the calling workflow and the child must belong to the same organization.
140
-
141
- ## Uploading to Storage
142
-
143
- Upload a file to Elevasis-managed storage and generate a signed URL for temporary access. No credential required.
144
-
145
- ```typescript
146
- import { storage } from '@elevasis/sdk/worker'
147
-
148
- // Upload a processed file
149
- const reportPath = `exports/report-${Date.now()}.csv`
150
- await storage.upload({
151
- bucket: 'exports',
152
- path: reportPath,
153
- content: csvContent,
154
- contentType: 'text/csv',
155
- })
156
-
157
- // Generate a signed URL valid for 1 hour (3600 seconds)
158
- const { signedUrl } = await storage.createSignedUrl({
159
- bucket: 'exports',
160
- path: reportPath,
161
- })
162
-
163
- // Share signedUrl with the user or include in an email
164
- ```
165
-
166
- Storage also supports `download`, `delete`, and `list` operations. Use `list` to enumerate files under a path prefix.
167
-
168
- ---
169
-
170
- **Last Updated:** 2026-03-02
@@ -1,75 +0,0 @@
1
- ---
2
- title: Resource Limits & Quotas
3
- description: Memory limits, execution timeouts, scale quotas, networking constraints, and v1 platform limitations for SDK resources
4
- loadWhen: "Hitting resource limits or planning for scale"
5
- ---
6
-
7
- This page documents the hard limits enforced on all SDK resources running on the Elevasis platform. These limits exist to ensure platform stability and fair resource usage across all organizations.
8
-
9
- ---
10
-
11
- ## Resource Limits
12
-
13
- Limits enforced per worker thread at runtime:
14
-
15
- | Resource | Value |
16
- | -------- | ----- |
17
- | Memory (V8 heap) | 256MB per worker |
18
- | Disk | Bundle file only (ephemeral, not persistent across deploys) |
19
-
20
- - **Memory:** Enforced by the platform. Exceeding 256MB crashes the worker. The platform catches the error; other tenants are unaffected. If your workflow processes large datasets, consider streaming or batching to stay within the limit.
21
- - **Disk:** Your bundle is written to disk during deploy and available to the worker at execution time. It is not a persistent write surface -- do not write files to disk from within your handler expecting them to persist.
22
-
23
- ---
24
-
25
- ## Scale Limits & Quotas
26
-
27
- Hard limits to prevent abuse and ensure platform stability:
28
-
29
- | Limit | Value |
30
- | ----- | ----- |
31
- | Max execution duration (workflows) | 300s (5 min) |
32
- | Max execution duration (agents) | 600s (10 min) |
33
- | Max log volume | 100MB/day |
34
- | Max deploy frequency | 60/day |
35
-
36
- - **Execution duration:** Executions exceeding the timeout are terminated by the platform. The execution is marked failed with a timeout reason.
37
- - **Log volume:** Total log output across all executions is capped at 100MB per day. Logs beyond this threshold may be truncated.
38
- - **Deploy frequency:** 60 deploys per day is generous for normal development. This limit prevents accidental deploy loops (for example, a CI pipeline misconfigured to deploy on every commit).
39
-
40
- ---
41
-
42
- ## Networking
43
-
44
- - **Outbound:** Unrestricted. Your handlers can call any external API (OpenAI, Twilio, Stripe, etc.) from within the worker.
45
- - **Inbound:** Workers receive input from the platform coordinator via internal message passing -- they are not exposed to the network directly.
46
- - **No ports:** Workers communicate with the platform via zero-network-overhead message passing. No port allocation occurs.
47
- - **Isolation:** Workers have no access to other organizations' data or platform credentials by default. Supabase credentials are not present in the worker environment.
48
-
49
- ---
50
-
51
- ## Platform Maintenance
52
-
53
- - **Rolling updates:** Platform upgrades re-register all active deployments on startup. No executions are lost.
54
- - **Node.js updates:** When the server's Node.js version is updated, worker threads pick up the new version on the next execution with no action required from you.
55
- - **Advance notice:** 24-hour advance notice is provided for breaking maintenance windows. These are rare and reserved for major infrastructure changes.
56
-
57
- ---
58
-
59
- ## v1 Limitations
60
-
61
- | Limitation | Reason | Future path |
62
- | ---------- | ------ | ----------- |
63
- | **No nested execution from external resources** | External resources cannot call back to the platform's execution coordinator to trigger other resources as sub-executions. | A callback API endpoint that external processes can call to trigger nested executions (requires auth token forwarding). |
64
- | **No streaming logs** | Execution logs are returned in the response body after completion. There is no real-time SSE streaming from within the worker. | SSE/WebSocket push from external processes to the platform log system. |
65
- | **Static resource priority conflicts** | If your organization has a static (monorepo) resource with the same ID as a resource in your SDK bundle, the deploy will fail. Static definitions always take priority and cannot be overridden. | Conflict detection is surfaced in the CLI with a clear error message. |
66
-
67
- ---
68
-
69
- ## Organization Provisioning
70
-
71
- Organization creation is currently admin-only. If you need a new organization provisioned for SDK access, contact the Elevasis team. Self-serve organization creation and API key generation is on the roadmap.
72
-
73
- ---
74
-
75
- **Last Updated:** 2026-03-03
@@ -1,141 +0,0 @@
1
- ---
2
- title: "Credential Security"
3
- description: "Three-layer credential model: platform tools (server-side injection), http tool (arbitrary APIs), getCredential() (explicit opt-in raw access) -- .env scope and security boundaries"
4
- loadWhen: "Setting up integrations or configuring tool access"
5
- ---
6
-
7
- This reference covers the Elevasis credential security model. Read it when helping a user connect to an external service, set up platform tools, or understand why environment variables are not used in workflows.
8
-
9
- ---
10
-
11
- ## The Core Rule
12
-
13
- Integration credentials are never stored in `.env` and never available via `process.env` inside worker threads.
14
-
15
- Credentials live in the platform credential system, created via the command center UI. Worker threads access credentials only through controlled channels: `platform.call()` (server-side injection) or `platform.getCredential()` (explicit opt-in).
16
-
17
- `.env` contains only `ELEVASIS_API_KEY`, used by the CLI for authentication. It is never uploaded to the platform and never injected into workers.
18
-
19
- ---
20
-
21
- ## Three-Layer Model
22
-
23
- ### Layer 1: Platform Tools (Default)
24
-
25
- All platform tools resolve credentials server-side. The tool dispatcher in the API process looks up the credential by name, injects it into the service call, and returns only the result. Credential values never cross the postMessage boundary into the worker.
26
-
27
- ```typescript
28
- // Credential 'my-gmail' is resolved server-side -- value never enters worker memory
29
- const result = await platform.call({
30
- tool: 'gmail',
31
- method: 'sendEmail',
32
- credential: 'my-gmail',
33
- params: { to: '...', subject: '...', body: '...' },
34
- })
35
- ```
36
-
37
- This is the default pattern for all integrations that have a platform adapter (Gmail, Attio, Stripe, Resend, etc.).
38
-
39
- ### Layer 2: HTTP Platform Tool
40
-
41
- For APIs without a dedicated platform adapter, use the `http` platform tool. Credentials are resolved and injected server-side before the outgoing HTTP request.
42
-
43
- ```typescript
44
- const result = await platform.call({
45
- tool: 'http',
46
- method: 'request',
47
- credential: 'my-custom-api',
48
- params: {
49
- url: 'https://api.example.com/v1/data',
50
- method: 'GET',
51
- headers: { 'Content-Type': 'application/json' },
52
- },
53
- })
54
- // result = { status: 200, headers: {...}, body: {...} }
55
- ```
56
-
57
- **Supported credential injection patterns:**
58
-
59
- | Pattern | Credential Config | How Injected |
60
- | --- | --- | --- |
61
- | Bearer token | `{ type: 'bearer', token: 'sk_...' }` | `Authorization: Bearer sk_...` header |
62
- | API key header | `{ type: 'api-key-header', header: 'X-API-Key', key: 'ak_...' }` | Custom header with key value |
63
- | Basic auth | `{ type: 'basic', username: '...', password: '...' }` | `Authorization: Basic base64(user:pass)` header |
64
- | Query parameter | `{ type: 'query-param', param: 'api_key', value: 'ak_...' }` | Appended to URL query string |
65
- | Body field | `{ type: 'body-field', field: 'apiKey', value: 'ak_...' }` | Merged into JSON request body |
66
- | Custom header | `{ type: 'custom-header', header: 'X-Custom', value: '...' }` | Arbitrary header with value |
67
-
68
- The credential type is selected when creating the credential in the command center UI.
69
-
70
- ### Layer 3: getCredential() (Explicit Opt-In)
71
-
72
- For cases where a third-party SDK must be initialized with a raw key (e.g., `new Stripe(key)`), use `platform.getCredential()`. This is an explicit opt-in that causes the credential value to enter worker memory.
73
-
74
- ```typescript
75
- import { platform } from '@elevasis/sdk/worker'
76
-
77
- // Explicit opt-in -- secret enters worker memory for duration of execution
78
- const cred = await platform.getCredential('my-stripe-key')
79
- const stripe = new Stripe(cred.credentials.secretKey)
80
- ```
81
-
82
- `getCredential()` returns `{ provider: string, credentials: Record<string, string> }`. The fields in `credentials` depend on the credential type stored in the command center.
83
-
84
- **Security guardrails:**
85
-
86
- - All `getCredential()` calls are logged with credential name, deployment ID, and execution ID
87
- - Workers are ephemeral (destroyed after each execution) -- no credential persistence
88
- - Use `platform.call()` with the `http` tool instead when possible
89
-
90
- ---
91
-
92
- ## Credential Setup
93
-
94
- Credentials are created in the command center UI:
95
-
96
- 1. Open the Elevasis command center
97
- 2. Navigate to Credentials
98
- 3. Click "Add Credential"
99
- 4. Enter a name (e.g., `my-gmail`, `production-attio`, `custom-api`)
100
- 5. Select the credential type (bearer, api-key-header, basic, etc.)
101
- 6. Enter the secret values
102
- 7. Save
103
-
104
- The credential name is what you pass as `credential: 'my-gmail'` in `platform.call()`.
105
-
106
- Credential names are case-sensitive. A mismatch causes a `PlatformToolError` with the message "credential not found."
107
-
108
- ---
109
-
110
- ## .env Scope
111
-
112
- `.env` in your workspace contains only:
113
-
114
- ```
115
- ELEVASIS_API_KEY=sk_your_key_here
116
- ```
117
-
118
- This key authenticates CLI operations (`elevasis-sdk deploy`, `elevasis-sdk check`, `elevasis-sdk exec`). It is never uploaded to the platform and never injected into workers.
119
-
120
- Do not put integration API keys in `.env`. They will not be available inside workflows.
121
-
122
- ---
123
-
124
- ## Choosing a Credential Pattern
125
-
126
- | Situation | Pattern |
127
- | --- | --- |
128
- | Using a supported platform tool (Gmail, Attio, Stripe, etc.) | `platform.call()` with the tool name |
129
- | Calling an API not in the tool catalog | `platform.call()` with `tool: 'http'` |
130
- | Third-party SDK that requires a raw key | `platform.getCredential()` |
131
- | CLI authentication | `ELEVASIS_API_KEY` in `.env` only |
132
-
133
- ---
134
-
135
- ## Migrating from elevasis-sdk env
136
-
137
- If you previously set integration credentials via `elevasis-sdk env set`, that command no longer exists. Use `elevasis-sdk env list` to see what was set, then recreate each entry as a platform credential in the command center. Update workflow code from `process.env.KEY` to `platform.call({ tool: 'http', credential: '...', ... })` or `platform.getCredential('...')`, then redeploy. The `.env` file remains but is scoped to `ELEVASIS_API_KEY` only.
138
-
139
- ---
140
-
141
- **Last Updated:** 2026-02-26
File without changes