@elevasis/sdk 0.4.9 → 0.4.10

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.
package/dist/templates.js CHANGED
@@ -59,6 +59,7 @@ proactivity -- to their assessed levels.
59
59
  | Credential model | \`reference/security/credentials.mdx\` | Setting up integrations or tool access |
60
60
  | Interaction guidance | \`reference/developer/interaction-guidance.mdx\` | Unsure how to adapt for a skill combination |
61
61
  | Error history | \`.claude/memory/errors/index.md\` | Debugging errors, checking past fixes |
62
+ | Command View model | \`reference/deployment/command-view.mdx\` | Deploying or building resources that invoke other resources |
62
63
  | SDK error reference | \`reference/troubleshooting/common-errors.mdx\` | Unknown error not in workspace memory |
63
64
  | Project resource map | \`docs/navigation.mdx\` | Understanding what's deployed |
64
65
  | Project priorities | \`docs/priorities.mdx\` | Deciding what to work on next |
@@ -78,7 +79,7 @@ All \`reference/\` paths resolve to \`node_modules/@elevasis/sdk/reference/\`.
78
79
  - \`StepType\`, \`ExecutionError\`, \`ToolingError\` are runtime imports from \`'@elevasis/sdk'\`
79
80
  - \`platform\`, \`PlatformToolError\` are runtime imports from \`'@elevasis/sdk/worker'\`
80
81
  - \`.env\` is for CLI authentication only (\`ELEVASIS_API_KEY\`) -- never deployed, never in workers
81
- - Integration credentials are managed via the platform credential system (command center UI)
82
+ - Integration credentials are managed via the \`creds\` skill (auto-triggers when you mention credentials) or the Command Center UI
82
83
  - Documentation goes in \`docs/\` as \`.mdx\` files
83
84
  - \`dist/\` is generated by deploy -- never commit it
84
85
  - \`resourceId\` must be lowercase with hyphens, unique per organization
@@ -112,7 +113,8 @@ For detailed per-dimension adaptation rules, read
112
113
  | Command | Purpose |
113
114
  | --- | --- |
114
115
  | \`/meta\` | Project lifecycle: init, status, update, fix, deploy, health, develop |
115
- | \`/docs\` | Documentation lifecycle: create, checkpoint, cleanup, resume, verify |
116
+ | \`/docs\` | Documentation lifecycle: create, review, verify |
117
+ | \`/work\` | Task tracking: start, save, resume, done, list |
116
118
  | \`/database\` | Database operations: init, browse, query, schema, import |
117
119
  | \`/resource\` | Scaffold a new workflow or agent |
118
120
  | \`/templates\` | Discover and apply workflow templates |
@@ -121,6 +123,14 @@ For detailed per-dimension adaptation rules, read
121
123
  | \`/help\` | Command tree and navigation map |
122
124
  | \`/profile\` | View and update developer profile |
123
125
 
126
+ ## Skills
127
+
128
+ Skills auto-trigger based on conversation context. You do not need to invoke them manually.
129
+
130
+ | Skill | Triggers When |
131
+ | --- | --- |
132
+ | \`creds\` | You mention credentials, API keys, secrets, webhook secrets, or setting up integrations |
133
+
124
134
  ## Maintaining Memory
125
135
 
126
136
  ### What Memory Is
@@ -179,21 +189,6 @@ Populate with content based on the resource definitions in src/.
179
189
  **\`review\`:** Review all docs/ files for accuracy against the actual resource
180
190
  definitions. Flag mismatches between documented schemas and code.
181
191
 
182
- **\`checkpoint\`:** Save current work progress for session resume.
183
- Create or update \`docs/in-progress/<topic>.mdx\` with:
184
- - Current state and decisions made
185
- - Remaining work and blockers
186
- - Update \`docs/priorities.mdx\` with task status
187
-
188
- **\`cleanup\`:** Move completed documents from \`docs/in-progress/\` to their
189
- final location in \`docs/\`. Review each in-progress doc to determine if it's
190
- complete. Incomplete docs remain in \`docs/in-progress/\`.
191
- Also rebuild \`docs/navigation.mdx\` from the current project state.
192
-
193
- **\`resume\`:** Start-of-session command. Review in-progress docs, priorities,
194
- and recent deployment state. Present a summary: what's in progress, what's
195
- blocking, what's next. Offer to continue the highest-priority item.
196
-
197
192
  **\`verify [path]\`:** Cross-reference documentation with the codebase.
198
193
  Read the specified doc (or all docs if no path), compare claims against actual
199
194
  code (resource IDs, schema fields, platform tools used), and report
@@ -247,10 +242,14 @@ cannot specify schemas directly.
247
242
  - Add to \`src/index.ts\` registry
248
243
 
249
244
  **\`tool-step <name>\`:** Create a step that calls a platform tool:
250
- - Import \`{ platform, PlatformToolError }\` from '@elevasis/sdk/worker'
251
- - Use \`await platform.call({ tool, method, params, credential })\`
245
+ - Prefer typed adapters: \`import { createAttioAdapter, scheduler, llm } from '@elevasis/sdk/worker'\`
246
+ - Integration tools: \`const attio = createAttioAdapter('cred'); await attio.listRecords({...})\`
247
+ - Platform singletons: \`await scheduler.createSchedule({...})\`, \`await llm.generate({...})\`
248
+ - Fallback for tools without adapters: \`await platform.call({ tool, method, params, credential })\`
249
+ - Import \`{ PlatformToolError }\` from '@elevasis/sdk/worker' for error handling
252
250
  - Wrap in try/catch for PlatformToolError
253
251
  - Note: 60s timeout per call, credential required for integration tools
252
+ - See reference/platform-tools/adapters.mdx for the full adapter API
254
253
  `;
255
254
  }
256
255
  function claudeTutorialCommandTemplate() {
@@ -303,7 +302,10 @@ Observation focus: optional fields, types, suggesting own fields.
303
302
  **Lesson 4: Using Platform Tools**
304
303
  Explain platform tools (concepts page). Browse available tools via
305
304
  reference/platform-tools/index.mdx. Pick a tool based on user's goals.
306
- Build: add a platform.call() step. Explain credential setup.
305
+ Build: add a tool step using typed adapters (preferred) or platform.call().
306
+ Show adapter pattern: \`const attio = createAttioAdapter('cred')\`.
307
+ Show singleton pattern: \`import { scheduler, llm } from '@elevasis/sdk/worker'\`.
308
+ Explain credential setup. See reference/platform-tools/adapters.mdx for full API.
307
309
  Observation focus: credential model, async/await.
308
310
 
309
311
  **Lesson 5: Multi-Step Workflows**
@@ -364,11 +366,17 @@ Available Commands:
364
366
  /docs Documentation lifecycle
365
367
  /docs Show documentation status
366
368
  /docs create Create new documentation page
367
- /docs checkpoint Save progress for session resume
368
- /docs cleanup Move completed docs, rebuild navigation maps
369
- /docs resume Review in-progress work and priorities
369
+ /docs review Review docs for accuracy
370
370
  /docs verify Cross-reference docs with codebase for accuracy
371
371
 
372
+ /work Task tracking
373
+ /work Show current tasks
374
+ /work start Create new task
375
+ /work save Save progress for session resume
376
+ /work resume Resume in-progress work
377
+ /work done Complete and move task
378
+ /work list List all tasks with status
379
+
372
380
  /database Database operations
373
381
  /database init Connect Supabase project
374
382
  /database browse Query and display table contents
@@ -495,14 +503,14 @@ You are an agent development assistant for this Elevasis workspace.
495
503
 
496
504
  Agent definitions are accepted by the SDK and appear in the registry.
497
505
  Autonomous agent execution (multi-turn tool use loops) is deferred.
498
- LLM calls are available via \`platform.call({ tool: 'llm' })\` as a workaround.
506
+ LLM calls are available via the \`llm\` typed adapter: \`import { llm } from '@elevasis/sdk/worker'\`, then \`await llm.generate({ messages: [...] })\`.
499
507
 
500
508
  ## Operations
501
509
 
502
510
  **\`/agent\` (no args):** Explain the current state:
503
511
  - Agent definitions are accepted by the SDK and appear in the registry
504
512
  - Autonomous agent execution (multi-turn tool use loops) is deferred
505
- - LLM calls are available via platform.call({ tool: 'llm' }) as a workaround
513
+ - LLM calls are available via the \`llm\` typed adapter (\`import { llm } from '@elevasis/sdk/worker'\`)
506
514
  - Show the AgentDefinition pattern for future use
507
515
 
508
516
  **\`/agent scaffold <name>\`:** Create an agent definition with:
@@ -659,6 +667,9 @@ Detect and repair drift without a version upgrade:
659
667
 
660
668
  ### \`/meta deploy\` -- Full Deploy Pipeline
661
669
 
670
+ 0. Read \`reference/deployment/command-view.mdx\` -- understand the Command View
671
+ model, relationship declarations, and what deploy-time validation checks.
672
+ This context is essential for diagnosing validation failures in steps 1-2.
662
673
  1. Run \`elevasis check\` (validation)
663
674
  2. Type check if \`tsconfig.json\` exists
664
675
  3. Verify docs reflect current resources
@@ -670,6 +681,8 @@ Detect and repair drift without a version upgrade:
670
681
  9. If git configured and remote exists: optionally push
671
682
 
672
683
  Each step reports its result. Pipeline stops on failure with suggested fix.
684
+ If validation fails with relationship errors, re-read \`reference/deployment/command-view.mdx\`
685
+ for the enforcement model and common fixes.
673
686
 
674
687
  ### \`/meta health\` -- Execution Debugging
675
688
 
@@ -751,6 +764,7 @@ function platformStatusTemplate() {
751
764
  return `import type { WorkflowDefinition } from '@elevasis/sdk'
752
765
  import { StepType } from '@elevasis/sdk'
753
766
  import { platform } from '@elevasis/sdk/worker'
767
+ import { llm } from '@elevasis/sdk/worker'
754
768
  import { z } from 'zod'
755
769
 
756
770
  const input = z.object({
@@ -802,33 +816,29 @@ export const platformStatus: WorkflowDefinition = {
802
816
  description: 'Generates a natural language summary from raw status data',
803
817
  handler: async (rawInput) => {
804
818
  const { raw } = rawInput as z.infer<typeof statusData>
805
- const result = await platform.call({
806
- tool: 'llm',
807
- method: 'generate',
808
- params: {
809
- provider: 'google',
810
- model: 'gemini-3-flash-preview',
811
- messages: [
812
- {
813
- role: 'user',
814
- content: [
815
- 'Summarize this platform status overview in 3-5 concise bullet points.',
816
- 'Focus on: execution health, pending items needing attention, upcoming schedules, and credential coverage.',
817
- 'Be specific with numbers. Flag any issues.',
818
- '',
819
- JSON.stringify(raw, null, 2),
820
- ].join('\\n'),
821
- },
822
- ],
823
- responseSchema: {
824
- type: 'object',
825
- properties: {
826
- summary: { type: 'string', description: 'Natural language status summary with bullet points' },
827
- },
828
- required: ['summary'],
819
+ const result = await llm.generate({
820
+ provider: 'google',
821
+ model: 'gemini-3-flash-preview',
822
+ messages: [
823
+ {
824
+ role: 'user',
825
+ content: [
826
+ 'Summarize this platform status overview in 3-5 concise bullet points.',
827
+ 'Focus on: execution health, pending items needing attention, upcoming schedules, and credential coverage.',
828
+ 'Be specific with numbers. Flag any issues.',
829
+ '',
830
+ JSON.stringify(raw, null, 2),
831
+ ].join('\\n'),
832
+ },
833
+ ],
834
+ responseSchema: {
835
+ type: 'object',
836
+ properties: {
837
+ summary: { type: 'string', description: 'Natural language status summary with bullet points' },
829
838
  },
830
- temperature: 0,
839
+ required: ['summary'],
831
840
  },
841
+ temperature: 0,
832
842
  })
833
843
  const summary = (result as any)?.summary ?? String(result)
834
844
  return { raw, summary }
@@ -27,4 +27,5 @@
27
27
  import type { OrganizationResources } from '../index.js';
28
28
  export { platform, PlatformToolError } from './platform.js';
29
29
  export type { PlatformCredential } from './platform.js';
30
+ export * from './adapters/index.js';
30
31
  export declare function startWorker(org: OrganizationResources): void;
@@ -4744,6 +4744,250 @@ function createPostMessageAdapterFactory() {
4744
4744
  return (config) => new PostMessageLLMAdapter(config.provider, config.model);
4745
4745
  }
4746
4746
 
4747
+ // src/worker/adapters/create-adapter.ts
4748
+ function createAdapter(tool, methods, credential) {
4749
+ const adapter = {};
4750
+ for (const method of methods) {
4751
+ adapter[method] = (params) => platform.call({ tool, method, params: params ?? {}, credential });
4752
+ }
4753
+ return adapter;
4754
+ }
4755
+
4756
+ // src/worker/adapters/attio.ts
4757
+ var METHODS = [
4758
+ "createRecord",
4759
+ "updateRecord",
4760
+ "listRecords",
4761
+ "getRecord",
4762
+ "deleteRecord",
4763
+ "listObjects",
4764
+ "listAttributes",
4765
+ "createAttribute",
4766
+ "updateAttribute",
4767
+ "createNote",
4768
+ "listNotes",
4769
+ "deleteNote"
4770
+ ];
4771
+ function createAttioAdapter(credential) {
4772
+ return createAdapter("attio", METHODS, credential);
4773
+ }
4774
+
4775
+ // src/worker/adapters/apify.ts
4776
+ var METHODS2 = [
4777
+ "runActor"
4778
+ ];
4779
+ function createApifyAdapter(credential) {
4780
+ return createAdapter("apify", METHODS2, credential);
4781
+ }
4782
+
4783
+ // src/worker/adapters/dropbox.ts
4784
+ var METHODS3 = [
4785
+ "uploadFile",
4786
+ "createFolder"
4787
+ ];
4788
+ function createDropboxAdapter(credential) {
4789
+ return createAdapter("dropbox", METHODS3, credential);
4790
+ }
4791
+
4792
+ // src/worker/adapters/gmail.ts
4793
+ var METHODS4 = [
4794
+ "sendEmail"
4795
+ ];
4796
+ function createGmailAdapter(credential) {
4797
+ return createAdapter("gmail", METHODS4, credential);
4798
+ }
4799
+
4800
+ // src/worker/adapters/google-sheets.ts
4801
+ var METHODS5 = [
4802
+ "readSheet",
4803
+ "writeSheet",
4804
+ "appendRows",
4805
+ "clearRange",
4806
+ "getSpreadsheetMetadata",
4807
+ "batchUpdate",
4808
+ "getHeaders",
4809
+ "getLastRow",
4810
+ "getRowByValue",
4811
+ "updateRowByValue",
4812
+ "upsertRow",
4813
+ "filterRows",
4814
+ "deleteRowByValue"
4815
+ ];
4816
+ function createGoogleSheetsAdapter(credential) {
4817
+ return createAdapter("google-sheets", METHODS5, credential);
4818
+ }
4819
+
4820
+ // src/worker/adapters/instantly.ts
4821
+ var METHODS6 = [
4822
+ "sendReply",
4823
+ "removeFromSubsequence",
4824
+ "getEmails",
4825
+ "updateInterestStatus",
4826
+ "addToCampaign"
4827
+ ];
4828
+ function createInstantlyAdapter(credential) {
4829
+ return createAdapter("instantly", METHODS6, credential);
4830
+ }
4831
+
4832
+ // src/worker/adapters/mailso.ts
4833
+ var METHODS7 = [
4834
+ "verifyEmail"
4835
+ ];
4836
+ function createMailsoAdapter(credential) {
4837
+ return createAdapter("mailso", METHODS7, credential);
4838
+ }
4839
+
4840
+ // src/worker/adapters/notion.ts
4841
+ var METHODS8 = [
4842
+ "listAllPages",
4843
+ "readPage",
4844
+ "createPage",
4845
+ "updatePageTitle",
4846
+ "appendBlocks",
4847
+ "updateBlocks",
4848
+ "deletePage",
4849
+ "deleteBlocks"
4850
+ ];
4851
+ function createNotionAdapter(credential) {
4852
+ return createAdapter("notion", METHODS8, credential);
4853
+ }
4854
+
4855
+ // src/worker/adapters/resend.ts
4856
+ var METHODS9 = [
4857
+ "sendEmail",
4858
+ "getEmail"
4859
+ ];
4860
+ function createResendAdapter(credential) {
4861
+ return createAdapter("resend", METHODS9, credential);
4862
+ }
4863
+
4864
+ // src/worker/adapters/signature-api.ts
4865
+ var METHODS10 = [
4866
+ "createEnvelope",
4867
+ "voidEnvelope",
4868
+ "downloadDocument",
4869
+ "getEnvelope"
4870
+ ];
4871
+ function createSignatureApiAdapter(credential) {
4872
+ return createAdapter("signature-api", METHODS10, credential);
4873
+ }
4874
+
4875
+ // src/worker/adapters/stripe.ts
4876
+ var METHODS11 = [
4877
+ "createPaymentLink",
4878
+ "getPaymentLink",
4879
+ "updatePaymentLink",
4880
+ "listPaymentLinks",
4881
+ "createAutoPaymentLink",
4882
+ "createCheckoutSession"
4883
+ ];
4884
+ function createStripeAdapter(credential) {
4885
+ return createAdapter("stripe", METHODS11, credential);
4886
+ }
4887
+
4888
+ // src/worker/adapters/trello.ts
4889
+ var METHODS12 = [
4890
+ "getBoard",
4891
+ "getLists",
4892
+ "getCards",
4893
+ "createCard",
4894
+ "updateCard",
4895
+ "createList",
4896
+ "createChecklist",
4897
+ "addChecklistItem",
4898
+ "updateChecklistItem",
4899
+ "getCardChecklists"
4900
+ ];
4901
+ function createTrelloAdapter(credential) {
4902
+ return createAdapter("trello", METHODS12, credential);
4903
+ }
4904
+
4905
+ // src/worker/adapters/scheduler.ts
4906
+ var scheduler = createAdapter("scheduler", [
4907
+ "createSchedule",
4908
+ "updateAnchor",
4909
+ "deleteSchedule",
4910
+ "findByIdempotencyKey",
4911
+ "deleteScheduleByIdempotencyKey",
4912
+ "listSchedules",
4913
+ "getSchedule",
4914
+ "cancelSchedule",
4915
+ "cancelSchedulesByMetadata"
4916
+ ]);
4917
+
4918
+ // src/worker/adapters/llm.ts
4919
+ var llm = {
4920
+ generate: (params) => platform.call({ tool: "llm", method: "generate", params })
4921
+ };
4922
+
4923
+ // src/worker/adapters/storage.ts
4924
+ var storage = createAdapter("storage", [
4925
+ "upload",
4926
+ "download",
4927
+ "createSignedUrl",
4928
+ "delete",
4929
+ "list"
4930
+ ]);
4931
+
4932
+ // src/worker/adapters/notification.ts
4933
+ var notifications = createAdapter("notification", ["create"]);
4934
+
4935
+ // src/worker/adapters/lead.ts
4936
+ var lead = createAdapter("lead", [
4937
+ // List operations
4938
+ "listLists",
4939
+ "createList",
4940
+ "updateList",
4941
+ "deleteList",
4942
+ // Company operations
4943
+ "createCompany",
4944
+ "upsertCompany",
4945
+ "updateCompany",
4946
+ "getCompany",
4947
+ "listCompanies",
4948
+ "deleteCompany",
4949
+ // Contact operations
4950
+ "createContact",
4951
+ "upsertContact",
4952
+ "updateContact",
4953
+ "getContact",
4954
+ "getContactByEmail",
4955
+ "listContacts",
4956
+ "deleteContact",
4957
+ "bulkImportContacts",
4958
+ // Deal operations
4959
+ "upsertDeal",
4960
+ "getDealByEmail",
4961
+ "getDealByEnvelopeId",
4962
+ "updateDealEnvelopeId",
4963
+ "getDealByAttioId",
4964
+ // Deal-sync operations
4965
+ "updateDiscoveryData",
4966
+ "updateProposalData",
4967
+ "markProposalSent",
4968
+ "markProposalReviewed",
4969
+ "updateCloseLostReason",
4970
+ "updateFees",
4971
+ "syncDealStage",
4972
+ "setContactNurture",
4973
+ "cancelSchedulesAndHitlByEmail",
4974
+ "cancelHitlByDealId",
4975
+ "clearDealFields",
4976
+ "deleteDeal"
4977
+ ]);
4978
+
4979
+ // src/worker/adapters/pdf.ts
4980
+ var pdf = createAdapter("pdf", ["render", "renderToBuffer"]);
4981
+
4982
+ // src/worker/adapters/approval.ts
4983
+ var approval = createAdapter("approval", ["create", "deleteByMetadata"]);
4984
+
4985
+ // src/worker/adapters/execution.ts
4986
+ var execution = createAdapter("execution", ["trigger"]);
4987
+
4988
+ // src/worker/adapters/email.ts
4989
+ var email = createAdapter("email", ["send"]);
4990
+
4747
4991
  // src/worker/index.ts
4748
4992
  function resolveNext(next, data) {
4749
4993
  if (next === null) return null;
@@ -5014,4 +5258,4 @@ function startWorker(org) {
5014
5258
  });
5015
5259
  }
5016
5260
 
5017
- export { PlatformToolError, platform, startWorker };
5261
+ export { PlatformToolError, approval, createAdapter, createApifyAdapter, createAttioAdapter, createDropboxAdapter, createGmailAdapter, createGoogleSheetsAdapter, createInstantlyAdapter, createMailsoAdapter, createNotionAdapter, createResendAdapter, createSignatureApiAdapter, createStripeAdapter, createTrelloAdapter, email, execution, lead, llm, notifications, pdf, platform, scheduler, startWorker, storage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "comment:bin": "IMPORTANT: This package shares the 'elevasis' binary name with @repo/cli. They never conflict because @elevasis/sdk must NEVER be added as a dependency of any workspace package (apps/*, packages/*, organizations/*). Workspace projects use @repo/cli for the 'elevasis' binary. External developers (outside the workspace) get this SDK's binary via npm install.",
6
6
  "type": "module",
@@ -33,6 +33,11 @@
33
33
  "dist/types/templates.d.ts",
34
34
  "reference/"
35
35
  ],
36
+ "scripts": {
37
+ "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.core-dts.json && tsc -p tsconfig.build.json && tsup && rollup -c rollup.dts.config.mjs && esbuild src/cli/index.ts --bundle --platform=node --outfile=dist/cli.cjs --format=cjs --external:esbuild --external:jiti --banner:js=\"#!/usr/bin/env node\" && node scripts/copy-reference-docs.mjs && node scripts/generate-navigation.mjs",
38
+ "check-types": "tsc --noEmit",
39
+ "test:bundle": "pnpm build && vitest run --config vitest.bundle.config.ts"
40
+ },
36
41
  "dependencies": {
37
42
  "esbuild": "^0.25.0",
38
43
  "jiti": "^2.0.0"
@@ -41,6 +46,8 @@
41
46
  "zod": "^4.1.0"
42
47
  },
43
48
  "devDependencies": {
49
+ "@repo/core": "workspace:*",
50
+ "@repo/typescript-config": "workspace:*",
44
51
  "@types/node": "^22.0.0",
45
52
  "chalk": "^5.3.0",
46
53
  "commander": "^11.0.0",
@@ -51,13 +58,6 @@
51
58
  "rollup-plugin-dts": "^6.3.0",
52
59
  "tsup": "^8.0.0",
53
60
  "typescript": "5.9.2",
54
- "zod": "^4.1.0",
55
- "@repo/core": "0.0.0",
56
- "@repo/typescript-config": "0.0.0"
57
- },
58
- "scripts": {
59
- "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.core-dts.json && tsc -p tsconfig.build.json && tsup && rollup -c rollup.dts.config.mjs && esbuild src/cli/index.ts --bundle --platform=node --outfile=dist/cli.cjs --format=cjs --external:esbuild --external:jiti --banner:js=\"#!/usr/bin/env node\" && node scripts/copy-reference-docs.mjs && node scripts/generate-navigation.mjs",
60
- "check-types": "tsc --noEmit",
61
- "test:bundle": "pnpm build && vitest run --config vitest.bundle.config.ts"
61
+ "zod": "^4.1.0"
62
62
  }
63
- }
63
+ }