@elevasis/sdk 1.48.0 → 1.50.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 (56) hide show
  1. package/dist/chunk-MGZZ4HL4.js +4399 -0
  2. package/dist/chunk-VYWGWJRW.js +130 -0
  3. package/dist/chunk-YJDXRHNP.js +7901 -0
  4. package/dist/cli.cjs +949 -281
  5. package/dist/index.d.ts +1031 -48
  6. package/dist/index.js +2 -7597
  7. package/dist/node/index.d.ts +3 -3675
  8. package/dist/node/index.js +2 -124
  9. package/dist/test-utils/index.d.ts +2 -12051
  10. package/dist/test-utils/index.js +113 -27891
  11. package/dist/worker/index.d.ts +548 -12264
  12. package/dist/worker/index.js +3 -7400
  13. package/package.json +12 -4
  14. package/reference/_navigation.md +4 -4
  15. package/reference/_reference-manifest.json +1 -1
  16. package/reference/core/index.mdx +6 -4
  17. package/reference/index.mdx +11 -5
  18. package/reference/packages/core/src/README.md +46 -44
  19. package/reference/packages/core/src/content/README.md +16 -12
  20. package/reference/rules/agent-start-here.md +1 -1
  21. package/reference/rules/frontend.md +3 -1
  22. package/reference/rules/package-taxonomy.md +7 -5
  23. package/reference/rules/ui.md +31 -5
  24. package/reference/rules/vibe-intents.md +2 -2
  25. package/reference/rules/vibe.md +30 -10
  26. package/reference/scaffold/recipes/extend-content.md +82 -3
  27. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +8 -6
  28. package/reference/scaffold/ui/feature-flags-and-gating.md +11 -1
  29. package/reference/sdk/cli-management.mdx +284 -139
  30. package/reference/sdk/cli.mdx +136 -88
  31. package/reference/sdk/define-builders.mdx +1 -1
  32. package/reference/sdk/deployment/command-center.mdx +2 -2
  33. package/reference/sdk/deployment/index.mdx +24 -7
  34. package/reference/sdk/exports.mdx +4 -4
  35. package/reference/sdk/framework/agent.mdx +4 -3
  36. package/reference/sdk/framework/index.mdx +1 -1
  37. package/reference/sdk/framework/project-structure.mdx +34 -23
  38. package/reference/sdk/framework/tutorial-system.mdx +1 -1
  39. package/reference/sdk/getting-started.mdx +25 -52
  40. package/reference/sdk/index.mdx +3 -3
  41. package/reference/sdk/platform-tools/adapters-integration.mdx +1 -1
  42. package/reference/sdk/platform-tools/adapters-platform.mdx +1 -1
  43. package/reference/sdk/platform-tools/type-safety.mdx +1 -1
  44. package/reference/sdk/resources/patterns.mdx +10 -11
  45. package/reference/sdk/resources/types.mdx +15 -9
  46. package/reference/sdk/templates/data-enrichment.mdx +1 -1
  47. package/reference/sdk/templates/email-sender.mdx +1 -1
  48. package/reference/sdk/templates/index.mdx +47 -47
  49. package/reference/sdk/templates/lead-scorer.mdx +1 -1
  50. package/reference/sdk/templates/pdf-generator.mdx +42 -24
  51. package/reference/sdk/templates/recurring-job.mdx +20 -15
  52. package/reference/sdk/templates/text-classifier.mdx +1 -1
  53. package/reference/sdk/templates/web-scraper.mdx +9 -5
  54. package/reference/sdk/troubleshooting.mdx +72 -1
  55. package/reference/ui/exports.mdx +1 -1
  56. package/reference/ui/index.mdx +2 -2
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "Template: PDF Generator"
3
- description: "PDF generation from structured data with platform storage upload -- render a PDF from a template and upload to platform storage"
3
+ description: "PDF generation from structured data with platform storage upload -- render a PDF from typed content blocks and upload to platform storage"
4
4
  loadWhen: "Applying the pdf-generator workflow template"
5
5
  ---
6
6
 
@@ -16,7 +16,9 @@ loadWhen: "Applying the pdf-generator workflow template"
16
16
 
17
17
  ## What This Workflow Does
18
18
 
19
- Receives structured data, renders a PDF using an HTML template, uploads the result to platform storage, and returns a signed URL for download. Suitable for invoices, reports, certificates, contracts, and any document that needs to be generated on demand and delivered as a downloadable file.
19
+ Receives structured content (a title, body text, and an optional data table), renders it to a PDF using the platform's declarative document builder, uploads the result to platform storage, and returns a signed URL for download. Suitable for invoices, reports, certificates, contracts, and any document that needs to be generated on demand and delivered as a downloadable file.
20
+
21
+ The platform's `pdf` tool does not accept raw HTML -- it renders a JSON document tree of typed content blocks (`text`, `metric`, `list`, `table`, `card`, `columns`). This template covers the common `text` + `table` case; adapt the `sections` array for other block types.
20
22
 
21
23
  ---
22
24
 
@@ -26,8 +28,10 @@ Receives structured data, renders a PDF using an HTML template, uploads the resu
26
28
 
27
29
  ```typescript
28
30
  z.object({
29
- templateHtml: z.string(), // HTML template with {variable} placeholders
30
- data: z.record(z.string(), z.unknown()), // Data to inject into the template
31
+ title: z.string(), // Document title, rendered as the page heading
32
+ bodyText: z.string(), // Main body paragraph
33
+ tableHeaders: z.array(z.string()).optional(), // Optional data table column headers
34
+ tableRows: z.array(z.array(z.string())).optional(), // Optional data table rows
31
35
  filename: z.string(), // Output filename (without .pdf extension)
32
36
  expiresInSeconds: z.number().optional(), // Signed URL expiry (default: 3600)
33
37
  })
@@ -56,8 +60,10 @@ import { platform } from '@elevasis/sdk/worker'
56
60
  import { z } from 'zod'
57
61
 
58
62
  const inputSchema = z.object({
59
- templateHtml: z.string(),
60
- data: z.record(z.string(), z.unknown()),
63
+ title: z.string(),
64
+ bodyText: z.string(),
65
+ tableHeaders: z.array(z.string()).optional(),
66
+ tableRows: z.array(z.array(z.string())).optional(),
61
67
  filename: z.string(),
62
68
  expiresInSeconds: z.number().optional(),
63
69
  })
@@ -69,16 +75,12 @@ const outputSchema = z.object({
69
75
 
70
76
  type Input = z.infer<typeof inputSchema>
71
77
 
72
- function renderTemplate(html: string, data: Record<string, unknown>): string {
73
- return html.replace(/\{(\w+)\}/g, (_, key) => String(data[key] ?? ''))
74
- }
75
-
76
78
  export const pdfGenerator: WorkflowDefinition = {
77
79
  config: {
78
- resourceId: 'pdf-generator',
80
+ resourceId: 'pdf-generator-workflow',
79
81
  name: 'PDF Generator',
80
82
  type: 'workflow',
81
- description: 'Generates a PDF from HTML template and uploads to storage',
83
+ description: 'Generates a PDF from structured content blocks and uploads to storage',
82
84
  version: '1.0.0',
83
85
  status: 'dev',
84
86
  },
@@ -87,17 +89,30 @@ export const pdfGenerator: WorkflowDefinition = {
87
89
  render: {
88
90
  id: 'render',
89
91
  name: 'Render PDF',
90
- description: 'Render HTML template to PDF buffer',
92
+ description: 'Render a structured document to a PDF buffer',
91
93
  inputSchema,
92
94
  outputSchema: z.object({ buffer: z.string(), filename: z.string(), expiresInSeconds: z.number() }),
93
95
  handler: async (input) => {
94
- const { templateHtml, data, filename, expiresInSeconds } = input as Input
95
- const html = renderTemplate(templateHtml, data)
96
+ const { title, bodyText, tableHeaders, tableRows, filename, expiresInSeconds } = input as Input
97
+
98
+ const document = {
99
+ pages: [
100
+ {
101
+ sections: [
102
+ { type: 'text' as const, content: title, variant: 'title' as const },
103
+ { type: 'text' as const, content: bodyText, variant: 'body' as const },
104
+ ...(tableHeaders && tableRows
105
+ ? [{ type: 'table' as const, headers: tableHeaders, rows: tableRows }]
106
+ : []),
107
+ ],
108
+ },
109
+ ],
110
+ }
96
111
 
97
112
  const result = await platform.call({
98
113
  tool: 'pdf',
99
114
  method: 'renderToBuffer',
100
- params: { html },
115
+ params: { document },
101
116
  }) as { buffer: string } // base64-encoded buffer
102
117
 
103
118
  return { buffer: result.buffer, filename, expiresInSeconds: expiresInSeconds ?? 3600 }
@@ -112,13 +127,15 @@ export const pdfGenerator: WorkflowDefinition = {
112
127
  outputSchema,
113
128
  handler: async (input, context) => {
114
129
  const { buffer, filename, expiresInSeconds } = input as { buffer: string; filename: string; expiresInSeconds: number }
115
- const key = `documents/${filename}-${Date.now()}.pdf`
130
+ const bucket = 'documents'
131
+ const path = `${filename}-${Date.now()}.pdf`
116
132
 
117
133
  await platform.call({
118
134
  tool: 'storage',
119
135
  method: 'upload',
120
136
  params: {
121
- key,
137
+ bucket,
138
+ path,
122
139
  content: buffer,
123
140
  contentType: 'application/pdf',
124
141
  },
@@ -127,11 +144,11 @@ export const pdfGenerator: WorkflowDefinition = {
127
144
  const urlResult = await platform.call({
128
145
  tool: 'storage',
129
146
  method: 'createSignedUrl',
130
- params: { key, expiresIn: expiresInSeconds },
147
+ params: { bucket, path, expiresIn: expiresInSeconds },
131
148
  }) as { signedUrl: string; expiresAt: string }
132
149
 
133
- context.logger.info(`PDF generated and uploaded: ${filename} at ${key}`)
134
- return { downloadUrl: urlResult.signedUrl, storageKey: key, expiresAt: urlResult.expiresAt }
150
+ context.logger.info(`PDF generated and uploaded: ${filename} at ${bucket}/${path}`)
151
+ return { downloadUrl: urlResult.signedUrl, storageKey: `${bucket}/${path}`, expiresAt: urlResult.expiresAt }
135
152
  },
136
153
  next: null,
137
154
  },
@@ -144,11 +161,12 @@ export const pdfGenerator: WorkflowDefinition = {
144
161
 
145
162
  ## Adaptation Notes
146
163
 
147
- - **Template format:** The simple `{variable}` placeholder system handles most cases. For complex documents, suggest the user write a more complete HTML template with inline CSS.
164
+ - **Content blocks:** The `pdf` tool renders a JSON document tree, not HTML. This template covers `text` and `table` blocks; add `metric`, `list`, `card`, or `columns` blocks to `sections` for richer layouts.
165
+ - **Storage bucket:** The template hardcodes `bucket = 'documents'`. Ask the user what bucket name their organization's platform storage is configured to use.
148
166
  - **Filename:** The template appends a timestamp to avoid collisions. Adapt naming to the user's convention (e.g., `invoice-{invoiceId}`).
149
167
  - **Expiry:** Default is 1 hour. For document delivery workflows, increase to 24-72 hours.
150
- - **Data structure:** Ask the user what fields their document needs before defining the `data` schema. For typed use cases (invoices, reports), define a stricter input schema.
151
- - **Skill adaptation:** For beginners, show a complete example HTML template and explain what "template variables" are.
168
+ - **Data structure:** Ask the user what fields their document needs before defining the input schema and mapping it into `sections`. For typed use cases (invoices, reports), add more input fields and a matching table row or card per field group.
169
+ - **Skill adaptation:** For beginners, walk through the difference between a JSON document tree and an HTML template before generating code.
152
170
 
153
171
  ---
154
172
 
@@ -18,8 +18,8 @@ loadWhen: "Applying the recurring-job workflow template"
18
18
 
19
19
  Two-part pattern for recurring jobs:
20
20
 
21
- 1. **Setup workflow** (`recurring-job-setup`): Creates a schedule entry that triggers the main job workflow on a recurring basis. Run once to activate.
22
- 2. **Main job workflow** (`recurring-job`): The actual work executed on each scheduled trigger.
21
+ 1. **Setup workflow** (`recurring-job-setup-workflow`): Creates a schedule entry that triggers the main job workflow on a recurring basis. Run once to activate.
22
+ 2. **Main job workflow** (`recurring-job-workflow`): The actual work executed on each scheduled trigger.
23
23
 
24
24
  The job workflow and setup workflow share a schedule key for idempotent schedule management.
25
25
 
@@ -43,8 +43,7 @@ z.object({
43
43
 
44
44
  ```typescript
45
45
  z.object({
46
- scheduledAt: z.string(), // ISO timestamp of the scheduled trigger
47
- jobInput: z.record(z.string(), z.unknown()).optional(), // Passed through from schedule creation
46
+ jobInput: z.record(z.string(), z.unknown()).optional(), // Passed through as scheduleConfig.payload at setup time
48
47
  })
49
48
  ```
50
49
 
@@ -72,7 +71,7 @@ import { z } from 'zod'
72
71
  // Setup workflow -- run once to create the schedule
73
72
  export const recurringJobSetup: WorkflowDefinition = {
74
73
  config: {
75
- resourceId: 'recurring-job-setup',
74
+ resourceId: 'recurring-job-setup-workflow',
76
75
  name: 'Recurring Job Setup',
77
76
  type: 'workflow',
78
77
  description: 'Creates or updates the schedule for the recurring job',
@@ -104,10 +103,15 @@ export const recurringJobSetup: WorkflowDefinition = {
104
103
  tool: 'scheduler',
105
104
  method: 'createSchedule',
106
105
  params: {
107
- resourceId: 'recurring-job',
108
- cronExpression,
109
- timezone: timezone ?? 'UTC',
110
- input: { scheduledAt: new Date().toISOString(), jobInput: jobInput ?? {} },
106
+ organizationId: context.organizationId, // ignored -- the platform re-scopes this from execution context
107
+ name: 'Recurring Job Schedule',
108
+ target: { resourceType: 'workflow', resourceId: 'recurring-job-workflow' },
109
+ scheduleConfig: {
110
+ type: 'recurring',
111
+ cron: cronExpression,
112
+ timezone: timezone ?? 'UTC',
113
+ payload: { jobInput: jobInput ?? {} },
114
+ },
111
115
  idempotencyKey: 'recurring-job-schedule',
112
116
  },
113
117
  }) as { id: string }
@@ -124,7 +128,7 @@ export const recurringJobSetup: WorkflowDefinition = {
124
128
  // Main job workflow -- triggered by the scheduler on each run
125
129
  export const recurringJob: WorkflowDefinition = {
126
130
  config: {
127
- resourceId: 'recurring-job',
131
+ resourceId: 'recurring-job-workflow',
128
132
  name: 'Recurring Job',
129
133
  type: 'workflow',
130
134
  description: 'Executes on each scheduled trigger',
@@ -133,7 +137,6 @@ export const recurringJob: WorkflowDefinition = {
133
137
  },
134
138
  contract: {
135
139
  inputSchema: z.object({
136
- scheduledAt: z.string(),
137
140
  jobInput: z.record(z.string(), z.unknown()).optional(),
138
141
  }),
139
142
  outputSchema: z.object({
@@ -147,12 +150,12 @@ export const recurringJob: WorkflowDefinition = {
147
150
  id: 'run',
148
151
  name: 'Run Job',
149
152
  description: 'Execute the recurring job logic',
150
- inputSchema: z.object({ scheduledAt: z.string(), jobInput: z.record(z.string(), z.unknown()).optional() }),
153
+ inputSchema: z.object({ jobInput: z.record(z.string(), z.unknown()).optional() }),
151
154
  outputSchema: z.object({ completed: z.boolean(), processedAt: z.string(), summary: z.string() }),
152
155
  handler: async (input, context) => {
153
- const { scheduledAt, jobInput } = input as { scheduledAt: string; jobInput?: Record<string, unknown> }
156
+ const { jobInput } = input as { jobInput?: Record<string, unknown> }
154
157
 
155
- context.logger.info(`Recurring job started at ${scheduledAt}`)
158
+ context.logger.info(`Recurring job started at ${new Date().toISOString()}`)
156
159
 
157
160
  // === REPLACE THIS SECTION WITH THE ACTUAL JOB LOGIC ===
158
161
  // Example: fetch data, process it, send a report
@@ -186,9 +189,11 @@ export const recurringJob: WorkflowDefinition = {
186
189
  ## Adaptation Notes
187
190
 
188
191
  - **Job logic:** Replace the placeholder comment in the `run` handler with the actual job logic. Ask the user what the job should do before generating the full workflow.
189
- - **Both workflows needed:** Remind the user to add both `recurringJob` and `recurringJobSetup` to their `src/index.ts` registry. Run `setup` once to activate; only `recurring-job` runs automatically thereafter.
192
+ - **Both workflows needed:** Remind the user to add both `recurringJob` and `recurringJobSetup` to their `src/index.ts` registry. Run `setup` once to activate; only `recurring-job-workflow` runs automatically thereafter.
190
193
  - **Idempotency key:** The `recurring-job-schedule` key ensures re-running setup does not create duplicate schedules.
191
194
  - **Timezone:** Always ask the user their preferred timezone. Defaults to UTC which may cause unexpected run times.
195
+ - **`organizationId` in `createSchedule` params:** The platform always re-scopes this from the execution context server-side, so the value passed here is ignored -- it exists only because the field is required by the scheduler's type.
196
+ - **Execution input on each run:** The job workflow receives `scheduleConfig.payload` as its input, with a `_scheduleMetadata` object (`scheduleId`, `scheduleName`, `scheduleStep`) merged in automatically. Extra fields are not part of the validated `inputSchema` and are silently dropped by Zod's default parsing.
192
197
 
193
198
  ---
194
199
 
@@ -70,7 +70,7 @@ type Input = z.infer<typeof inputSchema>
70
70
 
71
71
  export const textClassifier: WorkflowDefinition = {
72
72
  config: {
73
- resourceId: 'text-classifier',
73
+ resourceId: 'text-classifier-workflow',
74
74
  name: 'Text Classifier',
75
75
  type: 'workflow',
76
76
  description: 'Classifies text into predefined categories using an LLM',
@@ -72,7 +72,7 @@ type Input = z.infer<typeof inputSchema>
72
72
 
73
73
  export const webScraper: WorkflowDefinition = {
74
74
  config: {
75
- resourceId: 'web-scraper',
75
+ resourceId: 'web-scraper-workflow',
76
76
  name: 'Web Scraper',
77
77
  type: 'workflow',
78
78
  description: 'Scrapes structured data via Apify and stores in Supabase',
@@ -86,16 +86,20 @@ export const webScraper: WorkflowDefinition = {
86
86
  name: 'Run Apify Actor',
87
87
  description: 'Execute the Apify actor and collect results',
88
88
  inputSchema,
89
- outputSchema: z.object({ items: z.array(z.unknown()), runId: z.string() }),
89
+ outputSchema: z.object({ items: z.array(z.unknown()), runId: z.string(), tableName: z.string() }),
90
90
  handler: async (input) => {
91
- const { actorId, startUrls, maxItems } = input as Input
91
+ const { actorId, startUrls, tableName, maxItems } = input as Input
92
92
  const result = await platform.call({
93
93
  tool: 'apify',
94
94
  method: 'runActor',
95
95
  credential: 'apify',
96
- params: { actorId, input: { startUrls: startUrls.map(url => ({ url })), maxItems: maxItems ?? 100 } },
96
+ params: {
97
+ actorId,
98
+ input: { startUrls: startUrls.map(url => ({ url })) },
99
+ maxItems: maxItems ?? 100,
100
+ },
97
101
  }) as { items: unknown[]; runId: string }
98
- return { items: result.items, runId: result.runId }
102
+ return { items: result.items, runId: result.runId, tableName }
99
103
  },
100
104
  next: { type: StepType.LINEAR, target: 'store' },
101
105
  },
@@ -38,6 +38,42 @@ This is the static SDK-level error catalog. Check `.claude/memory/errors/` first
38
38
 
39
39
  ---
40
40
 
41
+ ## System Readiness Errors (503)
42
+
43
+ ### API request refused (503): `<system>`/`<interface>` is not ready
44
+
45
+ **Message:** starts with `API request refused (503)` and continues `This IS the API rejecting the request -- it is not a gateway hiccup, and re-running it will not help.`
46
+
47
+ **Cause:** The route you called is gated on a System Interface, and your organization's deployed Organization Model has not satisfied it. This is the API deliberately refusing, not a transport fault -- retrying will not help.
48
+
49
+ **Fix:** Read the `Issues:` block in the message. Those entries are the API's own explanation and name the specific missing thing. The guidance line above them tells you the general shape of the fix:
50
+
51
+ - **The System has not been adopted** -- declare it in `core/config/organization-model/systems.ts` with an `apiInterface` block, then deploy. Omitting the block entirely is the supported opt-out; an empty `apiInterface.resourceIds` array is not and will throw.
52
+ - **The interface is declared but disabled** -- set its lifecycle back to active and redeploy.
53
+ - **The `readinessContract` is unsatisfied** -- the issues name the missing `requiredObjects` or `requiredCatalogs` refs. Add them and redeploy.
54
+ - **A cross-System handoff is not ready** -- check the counterpart System as well as the one named.
55
+ - **The deployed snapshot is missing or stale** -- run `elevasis-sdk deploy`. The message already carries this instruction.
56
+ - **The stored snapshot could not be read** -- deploy again first. No field of your declaration is known to be wrong.
57
+
58
+ Then run `elevasis-sdk doctor` to see what else is not ready. Its Systems roster checks every platform-cataloged System, including ones you have not adopted.
59
+
60
+ ### This CLI does not recognize readiness code `{CODE}`
61
+
62
+ **Cause:** The API returned a readiness family your installed `@elevasis/sdk` predates. Tenants run a published SDK that lags the deployed API, so this is expected after a platform release and not a defect.
63
+
64
+ **Fix:**
65
+
66
+ 1. Read the `Issues:` block -- it is family-independent and remains the authoritative part of the message
67
+ 2. Run `pnpm update @elevasis/sdk` and re-run the command for the full guidance
68
+
69
+ ### 503 with "work may still be running server-side"
70
+
71
+ **Cause:** This is the gateway message, not the readiness message. It means a proxy or load balancer returned the `503` with no readiness body -- a genuine transport fault.
72
+
73
+ **Fix:** Retry. Unlike a readiness refusal, this class is transient and the request may have reached the API.
74
+
75
+ ---
76
+
41
77
  ## Validation Errors (elevasis-sdk check)
42
78
 
43
79
  ### Duplicate resource ID
@@ -64,6 +100,41 @@ This is the static SDK-level error catalog. Check `.claude/memory/errors/` first
64
100
 
65
101
  ---
66
102
 
103
+ ## Deploy Errors (elevasis-sdk deploy)
104
+
105
+ ### ORGANIZATION_MODEL_MISSING (400)
106
+
107
+ **Cause:** The deploy carried no organization model, so the platform had nothing to persist as a snapshot.
108
+
109
+ **Fix:** Export an `organizationModel` from your deployment spec and deploy again. This is a hard failure by design -- a deploy without a model used to report success, write no snapshot, and then refuse every subsequent API request with a readiness `503`.
110
+
111
+ ### `sdkVersion` is required (400)
112
+
113
+ **Cause:** The multipart `metadata` part failed schema validation before the deploy pipeline started. `sdkVersion` is the only required field.
114
+
115
+ **Fix:** Deploy through `elevasis-sdk deploy`, which always sends it. A hand-rolled `POST /api/external/deploy` must include it.
116
+
117
+ ### Deploy succeeded but warnings were printed
118
+
119
+ Deploy warnings never block the deploy. Each one names something that will fail later if left alone:
120
+
121
+ - **Workflow graph warnings** -- a dangling `next` target, a missing `entryPoint`, a cycle, or a step unreachable from the entry point. These are warnings at deploy so an existing project carrying a latent invalid graph is not blocked, but the same checks **throw at execution** when the workflow is constructed. Fix them before the workflow next runs.
122
+ - **Missing credential** -- an `IntegrationDefinition.credentialName` you declared has no matching credential in your organization. Create it in the command center; otherwise the first execution fails with a `credentials_missing` tooling error. Only credential names are checked and logged, never values.
123
+ - **Missing `apiInterface` declaration** -- a System with API-backed resources has no `apiInterface` block. Run `elevasis-sdk om:scaffold:fill` for the affected system path.
124
+ - **Unresolvable contract refs** -- contract refs are declared but no `contractRegistry` is exported from your entry.
125
+
126
+ ### Validation reported only one error, but there are more
127
+
128
+ Governance and System Interface readiness failures now report **every** issue in one deploy, not just the first. If you see a single issue, that is the whole list. Set `ELEVASIS_RESOURCE_VALIDATOR=warn-only` to downgrade governance, contract-ref resolution, readiness, and the agent grammar checks to warnings so a deploy can proceed while you work through them -- it never bypasses the structural schema parse or the OM conformance gate.
129
+
130
+ ### The deploy authenticated but the upload was rejected
131
+
132
+ **Cause:** Historically the auth step and the upload step resolved the API key two different ways, so pointing `--api-url` at production with `NODE_ENV=development` set authenticated with one key and uploaded with the other.
133
+
134
+ **Fix:** Update `@elevasis/sdk`. Both steps now derive the key from the URL the request is actually sent to. If you are pinning `NODE_ENV=development` and targeting production, set `ELEVASIS_PLATFORM_KEY` to the production key and use `--prod` or `--api-url`.
135
+
136
+ ---
137
+
67
138
  ## Schema Validation Errors
68
139
 
69
140
  ### Schema validation failed (input)
@@ -219,4 +290,4 @@ Status values: `Resolved` (fixed this session), `Recurring` (seen 2+ times), `Pr
219
290
 
220
291
  ---
221
292
 
222
- **Last Updated:** 2026-02-26
293
+ **Last Updated:** 2026-08-20
@@ -44,7 +44,7 @@ description: "Auto-generated catalog of all published @elevasis/ui subpath expor
44
44
  | `@elevasis/ui/layout` | Layout | Components | Published layout component entry for downstream applications. |
45
45
  | `@elevasis/ui/charts` | Charts | Components | Published chart component entry for downstream applications. |
46
46
  | `@elevasis/ui/theme` | Theme | Visual | Published theme entry for downstream applications. |
47
- | `@elevasis/ui/theme/presets` | Theme Presets | Visual | Re-exports the canonical THEME_PRESETS tuple, ThemePresetName union, and ThemePresetEnum Zod enum from @repo/core. Single source of truth for preset names across UI, schemas, and Zustand state. |
47
+ | `@elevasis/ui/theme/presets` | Theme Presets | Visual | Published THEME_PRESETS tuple, ThemePresetName union, and ThemePresetEnum Zod enum, defined locally and kept manually aligned with the canonical list in packages/core/src/auth/multi-tenancy/theme-presets.ts. |
48
48
  | `@elevasis/ui/api` | API | Foundation | Published API client entry for downstream applications. |
49
49
  | `@elevasis/ui/utils` | Utils | Foundation | Published utility entry for downstream applications. |
50
50
  | `@elevasis/ui/graph` | Graph | Visual | Published graph helper and visualization entry. |
@@ -77,6 +77,6 @@ You do not need `@elevasis/ui` if you are only writing backend workflows and age
77
77
 
78
78
  `@elevasis/ui` uses `@elevasis/core` internally for entity schemas, org-model types, and auth contracts. Installing `@elevasis/ui` will pull in `@elevasis/core` as a dependency. You do not need to install `@elevasis/core` separately unless you need direct access to its subpaths.
79
79
 
80
- ## Export Catalog
80
+ ## Documentation
81
81
 
82
- See [Export Catalog](exports.mdx) for a generated table of all published subpath exports derived from the reference manifest.
82
+ - [Export Catalog](exports.mdx) - Generated table of all published subpath exports derived from the reference manifest