@elevasis/sdk 0.4.8 → 0.4.9

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/cli.cjs CHANGED
@@ -43781,8 +43781,73 @@ async function apiPost(endpoint, body, apiUrl = resolveApiUrl()) {
43781
43781
  return response.json();
43782
43782
  }
43783
43783
 
43784
+ // package.json
43785
+ var package_default = {
43786
+ name: "@elevasis/sdk",
43787
+ version: "0.4.9",
43788
+ description: "SDK for building Elevasis organization resources",
43789
+ "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.",
43790
+ type: "module",
43791
+ bin: {
43792
+ elevasis: "./dist/cli.cjs",
43793
+ "elevasis-sdk": "./dist/cli.cjs"
43794
+ },
43795
+ exports: {
43796
+ ".": {
43797
+ types: "./dist/index.d.ts",
43798
+ import: "./dist/index.js"
43799
+ },
43800
+ "./worker": {
43801
+ types: "./dist/types/worker/index.d.ts",
43802
+ import: "./dist/worker/index.js"
43803
+ },
43804
+ "./templates": {
43805
+ types: "./dist/types/templates.d.ts",
43806
+ import: "./dist/templates.js"
43807
+ }
43808
+ },
43809
+ files: [
43810
+ "dist/index.js",
43811
+ "dist/index.d.ts",
43812
+ "dist/worker/index.js",
43813
+ "dist/types/worker/index.d.ts",
43814
+ "dist/types/worker/platform.d.ts",
43815
+ "dist/cli.cjs",
43816
+ "dist/templates.js",
43817
+ "dist/types/templates.d.ts",
43818
+ "reference/"
43819
+ ],
43820
+ scripts: {
43821
+ 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`,
43822
+ "check-types": "tsc --noEmit",
43823
+ "test:bundle": "pnpm build && vitest run --config vitest.bundle.config.ts"
43824
+ },
43825
+ dependencies: {
43826
+ esbuild: "^0.25.0",
43827
+ jiti: "^2.0.0"
43828
+ },
43829
+ peerDependencies: {
43830
+ zod: "^4.1.0"
43831
+ },
43832
+ devDependencies: {
43833
+ "@repo/core": "workspace:*",
43834
+ "@repo/typescript-config": "workspace:*",
43835
+ "@types/node": "^22.0.0",
43836
+ chalk: "^5.3.0",
43837
+ commander: "^11.0.0",
43838
+ dotenv: "^16.0.0",
43839
+ "gray-matter": "^4.0.3",
43840
+ ora: "^7.0.1",
43841
+ rollup: "^4.59.0",
43842
+ "rollup-plugin-dts": "^6.3.0",
43843
+ tsup: "^8.0.0",
43844
+ typescript: "5.9.2",
43845
+ zod: "^4.1.0"
43846
+ }
43847
+ };
43848
+
43784
43849
  // src/cli/version.ts
43785
- var SDK_VERSION = "0.4.8";
43850
+ var SDK_VERSION = package_default.version;
43786
43851
 
43787
43852
  // src/cli/commands/deploy.ts
43788
43853
  var import_meta2 = {};
@@ -44433,7 +44498,7 @@ function registerDescribeCommand(program3) {
44433
44498
  // src/cli/commands/init.ts
44434
44499
  var import_path3 = require("path");
44435
44500
  var import_promises2 = require("fs/promises");
44436
- var TEMPLATE_VERSION = 4;
44501
+ var TEMPLATE_VERSION = 5;
44437
44502
  var INIT_ONLY_FILES = [
44438
44503
  "package.json",
44439
44504
  "pnpm-workspace.yaml",
@@ -44442,7 +44507,11 @@ var INIT_ONLY_FILES = [
44442
44507
  ".env.example",
44443
44508
  ".npmrc",
44444
44509
  "src/index.ts",
44445
- "src/workflows/echo.ts",
44510
+ "src/operations/platform-status.ts",
44511
+ "src/operations/index.ts",
44512
+ "src/example/echo.ts",
44513
+ "src/example/index.ts",
44514
+ "src/shared/.gitkeep",
44446
44515
  "docs/index.mdx",
44447
44516
  "docs/in-progress/.gitkeep"
44448
44517
  ];
@@ -44484,7 +44553,9 @@ function registerInitCommand(program3) {
44484
44553
  throw new Error("Scaffold conflict");
44485
44554
  }
44486
44555
  }
44487
- await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/workflows"), { recursive: true });
44556
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/operations"), { recursive: true });
44557
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/example"), { recursive: true });
44558
+ await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "src/shared"), { recursive: true });
44488
44559
  await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, "docs/in-progress"), { recursive: true });
44489
44560
  await (0, import_promises2.mkdir)((0, import_path3.resolve)(targetDir, ".claude/commands"), { recursive: true });
44490
44561
  const files = {
@@ -44497,7 +44568,11 @@ function registerInitCommand(program3) {
44497
44568
  ".npmrc": npmrcTemplate(),
44498
44569
  ".gitignore": gitignoreTemplate(),
44499
44570
  "src/index.ts": starterTemplate(),
44500
- "src/workflows/echo.ts": starterWorkflowTemplate(),
44571
+ "src/operations/platform-status.ts": platformStatusTemplate(),
44572
+ "src/operations/index.ts": operationsBarrelTemplate(),
44573
+ "src/example/echo.ts": starterWorkflowTemplate(),
44574
+ "src/example/index.ts": exampleBarrelTemplate(),
44575
+ "src/shared/.gitkeep": "",
44501
44576
  "docs/index.mdx": docsIndexTemplate(orgSlug),
44502
44577
  "docs/in-progress/.gitkeep": "",
44503
44578
  "CLAUDE.md": claudeMdTemplate(),
@@ -44638,17 +44713,31 @@ elevasis executions <resourceId> # View execution history
44638
44713
  ## Project Structure
44639
44714
 
44640
44715
  - \`elevasis.config.ts\` -- Workspace config (optional settings)
44641
- - \`src/index.ts\` -- Resource registry (imports and exports all workflows)
44642
- - \`src/workflows/\` -- Workflow definitions (one per file)
44716
+ - \`src/index.ts\` -- Resource registry (aggregates from domain barrels)
44717
+ - \`src/operations/\` -- Operations domain (platform-status workflow)
44718
+ - \`src/example/\` -- Example domain (echo workflow -- replace with your own)
44719
+ - \`src/shared/\` -- Cross-domain shared types and utilities
44643
44720
  - \`docs/\` -- Documentation (.mdx files, deployed alongside code)
44644
44721
  - \`.env\` -- API key for CLI authentication
44645
44722
 
44646
44723
  ## Resources
44647
44724
 
44648
- ### Echo Workflow
44725
+ ### Platform Status Workflow (\`src/operations/\`)
44726
+
44727
+ A multi-step workflow that queries platform status and compiles a natural language
44728
+ summary using an LLM. Demonstrates real platform API usage with \`platform.call()\`.
44649
44729
 
44650
- A simple workflow that echoes the input message back. Use it to verify your
44651
- deployment is working:
44730
+ \`\`\`bash
44731
+ elevasis exec platform-status --input '{"timeRange": "24h"}'
44732
+ \`\`\`
44733
+
44734
+ **Input:** \`{ "timeRange": "1h" | "24h" | "7d" }\`
44735
+ **Output:** \`{ "raw": object, "summary": string }\`
44736
+
44737
+ ### Echo Workflow (\`src/example/\`)
44738
+
44739
+ A simple workflow that echoes the input message back. Use it as a starter pattern
44740
+ for new workflows:
44652
44741
 
44653
44742
  \`\`\`bash
44654
44743
  elevasis exec echo --input '{"message": "hello"}'
@@ -44720,6 +44809,9 @@ All \`reference/\` paths resolve to \`node_modules/@elevasis/sdk/reference/\`.
44720
44809
  ## Rules
44721
44810
 
44722
44811
  - All resource definitions must be in \`src/\` and exported via \`src/index.ts\`
44812
+ - Organize resources by business domain (e.g., src/operations/, src/acquisition/)
44813
+ - Each domain exports \`workflows\` and \`agents\` arrays via an index.ts barrel
44814
+ - src/shared/ is for cross-domain utilities; domain-specific shared code goes in <domain>/shared/
44723
44815
  - The default export must be an \`OrganizationResources\` object
44724
44816
  - Do not import from \`@repo/core\` -- use \`@elevasis/sdk\` types only
44725
44817
  - \`StepType\`, \`ExecutionError\`, \`ToolingError\` are runtime imports from \`'@elevasis/sdk'\`
@@ -44812,7 +44904,7 @@ You are a documentation assistant for this Elevasis workspace.
44812
44904
  ## Context
44813
44905
 
44814
44906
  Read the project's CLAUDE.md and all files in docs/ to understand the project.
44815
- Read src/index.ts and src/workflows/ to understand the resource definitions.
44907
+ Read src/index.ts and the domain directories (src/operations/, src/example/, etc.) to understand the resource definitions.
44816
44908
 
44817
44909
  ## Operations
44818
44910
 
@@ -44855,7 +44947,7 @@ You are a resource scaffolding assistant for this Elevasis workspace.
44855
44947
  ## Context
44856
44948
 
44857
44949
  Read CLAUDE.md for navigation to SDK patterns (reference/resources/patterns.mdx).
44858
- Read src/index.ts for the registry and src/workflows/ for existing resources.
44950
+ Read src/index.ts for the registry and domain directories for existing resources.
44859
44951
 
44860
44952
  Before suggesting tools, read \`.claude/memory/profile/identity.md\` if it exists
44861
44953
  to check the user's known integrations and suggest relevant platform tools.
@@ -44877,7 +44969,7 @@ cannot specify schemas directly.
44877
44969
 
44878
44970
  ## Operations
44879
44971
 
44880
- **\`workflow <name>\`:** Create a new workflow in \`src/workflows/<name>.ts\` with:
44972
+ **\`workflow <name>\`:** Create a new workflow in the appropriate domain directory (e.g., \`src/<domain>/<name>.ts\`) with:
44881
44973
  - Zod input/output schemas with \`z.infer\` type aliases
44882
44974
  - Config object (resourceId, name, type, description, version, status)
44883
44975
  - Contract with schemas
@@ -44930,8 +45022,9 @@ Each lesson follows this flow:
44930
45022
  ## Lessons
44931
45023
 
44932
45024
  **Lesson 1: Welcome & Orientation**
44933
- Tour project files: src/index.ts (registry), src/workflows/echo.ts (starter
44934
- workflow), elevasis.config.ts, .env, docs/. Explain the execution model.
45025
+ Tour project files: src/index.ts (registry), src/example/echo.ts (starter
45026
+ workflow), src/operations/platform-status.ts (platform API example),
45027
+ elevasis.config.ts, .env, docs/. Explain the execution model.
44935
45028
  Verify: run \`elevasis resources\`. Observation focus: cloud deployment model.
44936
45029
 
44937
45030
  **Lesson 2: Your First Custom Workflow**
@@ -45066,7 +45159,7 @@ Read \`.claude/memory/profile/skills.md\` to adapt generated code to skill level
45066
45159
 
45067
45160
  **\`/templates apply <name>\`:** Generate a workflow from the template:
45068
45161
  1. Read the template definition from reference/templates/<name>.mdx
45069
- 2. Generate a workflow file in src/workflows/<name>.ts
45162
+ 2. Generate a workflow file in the appropriate domain directory
45070
45163
  3. Add the import to src/index.ts registry
45071
45164
  4. If the template uses platform tools, prompt for credential setup
45072
45165
  5. If the template uses the database, check that /database init has been run
@@ -45356,10 +45449,18 @@ The agent reads current templates from the installed SDK:
45356
45449
  }
45357
45450
  function starterTemplate() {
45358
45451
  return `import type { OrganizationResources } from '@elevasis/sdk'
45359
- import { echo } from './workflows/echo.js'
45452
+ import * as operations from './operations/index.js'
45453
+ import * as example from './example/index.js'
45360
45454
 
45361
45455
  const org: OrganizationResources = {
45362
- workflows: [echo],
45456
+ workflows: [
45457
+ ...operations.workflows,
45458
+ ...example.workflows,
45459
+ ],
45460
+ agents: [
45461
+ ...operations.agents,
45462
+ ...example.agents,
45463
+ ],
45363
45464
  }
45364
45465
  export default org
45365
45466
  `;
@@ -45403,6 +45504,115 @@ export const echo: WorkflowDefinition = {
45403
45504
  }
45404
45505
  `;
45405
45506
  }
45507
+ function platformStatusTemplate() {
45508
+ return `import type { WorkflowDefinition } from '@elevasis/sdk'
45509
+ import { StepType } from '@elevasis/sdk'
45510
+ import { platform } from '@elevasis/sdk/worker'
45511
+ import { z } from 'zod'
45512
+
45513
+ const input = z.object({
45514
+ timeRange: z.enum(['1h', '24h', '7d']).default('24h').describe('Time window for status data'),
45515
+ })
45516
+
45517
+ const statusData = z.object({
45518
+ raw: z.unknown().describe('Raw status overview from platform'),
45519
+ })
45520
+
45521
+ const output = z.object({
45522
+ raw: z.unknown().describe('Raw status overview from platform'),
45523
+ summary: z.string().describe('Natural language status summary'),
45524
+ })
45525
+
45526
+ type Input = z.infer<typeof input>
45527
+
45528
+ export const platformStatus: WorkflowDefinition = {
45529
+ config: {
45530
+ resourceId: 'platform-status',
45531
+ name: 'Platform Status',
45532
+ type: 'workflow',
45533
+ description: 'Gathers cross-system platform status and compiles a natural language summary',
45534
+ version: '1.0.0',
45535
+ status: 'dev',
45536
+ },
45537
+ contract: { inputSchema: input, outputSchema: output },
45538
+ steps: {
45539
+ 'gather-status': {
45540
+ id: 'gather-status',
45541
+ name: 'Gather Status',
45542
+ description: 'Queries platform status overview (executions, pending items, schedules, credentials)',
45543
+ handler: async (rawInput) => {
45544
+ const { timeRange } = rawInput as Input
45545
+ const raw = await platform.call({
45546
+ tool: 'status',
45547
+ method: 'overview',
45548
+ params: { timeRange },
45549
+ })
45550
+ return { raw }
45551
+ },
45552
+ inputSchema: input,
45553
+ outputSchema: statusData,
45554
+ next: { type: StepType.LINEAR, target: 'compile-report' },
45555
+ },
45556
+ 'compile-report': {
45557
+ id: 'compile-report',
45558
+ name: 'Compile Report',
45559
+ description: 'Generates a natural language summary from raw status data',
45560
+ handler: async (rawInput) => {
45561
+ const { raw } = rawInput as z.infer<typeof statusData>
45562
+ const result = await platform.call({
45563
+ tool: 'llm',
45564
+ method: 'generate',
45565
+ params: {
45566
+ provider: 'google',
45567
+ model: 'gemini-3-flash-preview',
45568
+ messages: [
45569
+ {
45570
+ role: 'user',
45571
+ content: [
45572
+ 'Summarize this platform status overview in 3-5 concise bullet points.',
45573
+ 'Focus on: execution health, pending items needing attention, upcoming schedules, and credential coverage.',
45574
+ 'Be specific with numbers. Flag any issues.',
45575
+ '',
45576
+ JSON.stringify(raw, null, 2),
45577
+ ].join('\\n'),
45578
+ },
45579
+ ],
45580
+ responseSchema: {
45581
+ type: 'object',
45582
+ properties: {
45583
+ summary: { type: 'string', description: 'Natural language status summary with bullet points' },
45584
+ },
45585
+ required: ['summary'],
45586
+ },
45587
+ temperature: 0,
45588
+ },
45589
+ })
45590
+ const summary = (result as any)?.summary ?? String(result)
45591
+ return { raw, summary }
45592
+ },
45593
+ inputSchema: statusData,
45594
+ outputSchema: output,
45595
+ next: null,
45596
+ },
45597
+ },
45598
+ entryPoint: 'gather-status',
45599
+ }
45600
+ `;
45601
+ }
45602
+ function operationsBarrelTemplate() {
45603
+ return `import { platformStatus } from './platform-status.js'
45604
+
45605
+ export const workflows = [platformStatus]
45606
+ export const agents = []
45607
+ `;
45608
+ }
45609
+ function exampleBarrelTemplate() {
45610
+ return `import { echo } from './echo.js'
45611
+
45612
+ export const workflows = [echo]
45613
+ export const agents = []
45614
+ `;
45615
+ }
45406
45616
 
45407
45617
  // src/cli/commands/update.ts
45408
45618
  var import_path4 = require("path");
package/dist/index.d.ts CHANGED
@@ -2015,4 +2015,4 @@ declare class ToolingError extends ExecutionError {
2015
2015
  }
2016
2016
 
2017
2017
  export { ExecutionError, RegistryValidationError, ResourceRegistry, StepType, ToolingError };
2018
- export type { AgentConfig, AgentConstraints, AgentDefinition, ConditionalNext, Contract, DomainDefinition, ElevasConfig, EventTriggerConfig, ExecutionContext, ExecutionInterface, ExecutionMetadata, FormField, FormFieldType, FormSchema, IntegrationDefinition, LLMAdapterFactory, LLMModel, LinearNext, ModelConfig, NextConfig, OrganizationResources, ResourceDefinition, ResourceDomain, ResourceMetricsConfig, ResourceStatus, ResourceType, ScheduleTriggerConfig, StepHandler, Tool, ToolExecutionOptions, ToolingErrorType, TriggerConfig, TriggerDefinition, WebhookProviderType, WebhookTriggerConfig, WorkflowConfig, WorkflowDefinition, WorkflowStep };
2018
+ export type { AgentConfig, AgentConstraints, AgentDefinition, AgentMemory, ConditionalNext, Contract, DomainDefinition, ElevasConfig, EventTriggerConfig, ExecutionContext, ExecutionInterface, ExecutionMetadata, FormField, FormFieldType, FormSchema, IntegrationDefinition, LLMAdapterFactory, LLMModel, LinearNext, ModelConfig, NextConfig, OrganizationResources, ResourceDefinition, ResourceDomain, ResourceMetricsConfig, ResourceStatus, ResourceType, ScheduleTriggerConfig, StepHandler, Tool, ToolExecutionOptions, ToolingErrorType, TriggerConfig, TriggerDefinition, WebhookProviderType, WebhookTriggerConfig, WorkflowConfig, WorkflowDefinition, WorkflowStep };
package/dist/templates.js CHANGED
@@ -1,4 +1,4 @@
1
- // src/cli/commands/init.ts
1
+ // package.json
2
2
  function gitignoreTemplate() {
3
3
  return `node_modules/
4
4
  .env
@@ -70,6 +70,9 @@ All \`reference/\` paths resolve to \`node_modules/@elevasis/sdk/reference/\`.
70
70
  ## Rules
71
71
 
72
72
  - All resource definitions must be in \`src/\` and exported via \`src/index.ts\`
73
+ - Organize resources by business domain (e.g., src/operations/, src/acquisition/)
74
+ - Each domain exports \`workflows\` and \`agents\` arrays via an index.ts barrel
75
+ - src/shared/ is for cross-domain utilities; domain-specific shared code goes in <domain>/shared/
73
76
  - The default export must be an \`OrganizationResources\` object
74
77
  - Do not import from \`@repo/core\` -- use \`@elevasis/sdk\` types only
75
78
  - \`StepType\`, \`ExecutionError\`, \`ToolingError\` are runtime imports from \`'@elevasis/sdk'\`
@@ -162,7 +165,7 @@ You are a documentation assistant for this Elevasis workspace.
162
165
  ## Context
163
166
 
164
167
  Read the project's CLAUDE.md and all files in docs/ to understand the project.
165
- Read src/index.ts and src/workflows/ to understand the resource definitions.
168
+ Read src/index.ts and the domain directories (src/operations/, src/example/, etc.) to understand the resource definitions.
166
169
 
167
170
  ## Operations
168
171
 
@@ -205,7 +208,7 @@ You are a resource scaffolding assistant for this Elevasis workspace.
205
208
  ## Context
206
209
 
207
210
  Read CLAUDE.md for navigation to SDK patterns (reference/resources/patterns.mdx).
208
- Read src/index.ts for the registry and src/workflows/ for existing resources.
211
+ Read src/index.ts for the registry and domain directories for existing resources.
209
212
 
210
213
  Before suggesting tools, read \`.claude/memory/profile/identity.md\` if it exists
211
214
  to check the user's known integrations and suggest relevant platform tools.
@@ -227,7 +230,7 @@ cannot specify schemas directly.
227
230
 
228
231
  ## Operations
229
232
 
230
- **\`workflow <name>\`:** Create a new workflow in \`src/workflows/<name>.ts\` with:
233
+ **\`workflow <name>\`:** Create a new workflow in the appropriate domain directory (e.g., \`src/<domain>/<name>.ts\`) with:
231
234
  - Zod input/output schemas with \`z.infer\` type aliases
232
235
  - Config object (resourceId, name, type, description, version, status)
233
236
  - Contract with schemas
@@ -280,8 +283,9 @@ Each lesson follows this flow:
280
283
  ## Lessons
281
284
 
282
285
  **Lesson 1: Welcome & Orientation**
283
- Tour project files: src/index.ts (registry), src/workflows/echo.ts (starter
284
- workflow), elevasis.config.ts, .env, docs/. Explain the execution model.
286
+ Tour project files: src/index.ts (registry), src/example/echo.ts (starter
287
+ workflow), src/operations/platform-status.ts (platform API example),
288
+ elevasis.config.ts, .env, docs/. Explain the execution model.
285
289
  Verify: run \`elevasis resources\`. Observation focus: cloud deployment model.
286
290
 
287
291
  **Lesson 2: Your First Custom Workflow**
@@ -416,7 +420,7 @@ Read \`.claude/memory/profile/skills.md\` to adapt generated code to skill level
416
420
 
417
421
  **\`/templates apply <name>\`:** Generate a workflow from the template:
418
422
  1. Read the template definition from reference/templates/<name>.mdx
419
- 2. Generate a workflow file in src/workflows/<name>.ts
423
+ 2. Generate a workflow file in the appropriate domain directory
420
424
  3. Add the import to src/index.ts registry
421
425
  4. If the template uses platform tools, prompt for credential setup
422
426
  5. If the template uses the database, check that /database init has been run
@@ -743,5 +747,114 @@ export const echo: WorkflowDefinition = {
743
747
  }
744
748
  `;
745
749
  }
750
+ function platformStatusTemplate() {
751
+ return `import type { WorkflowDefinition } from '@elevasis/sdk'
752
+ import { StepType } from '@elevasis/sdk'
753
+ import { platform } from '@elevasis/sdk/worker'
754
+ import { z } from 'zod'
755
+
756
+ const input = z.object({
757
+ timeRange: z.enum(['1h', '24h', '7d']).default('24h').describe('Time window for status data'),
758
+ })
759
+
760
+ const statusData = z.object({
761
+ raw: z.unknown().describe('Raw status overview from platform'),
762
+ })
763
+
764
+ const output = z.object({
765
+ raw: z.unknown().describe('Raw status overview from platform'),
766
+ summary: z.string().describe('Natural language status summary'),
767
+ })
768
+
769
+ type Input = z.infer<typeof input>
770
+
771
+ export const platformStatus: WorkflowDefinition = {
772
+ config: {
773
+ resourceId: 'platform-status',
774
+ name: 'Platform Status',
775
+ type: 'workflow',
776
+ description: 'Gathers cross-system platform status and compiles a natural language summary',
777
+ version: '1.0.0',
778
+ status: 'dev',
779
+ },
780
+ contract: { inputSchema: input, outputSchema: output },
781
+ steps: {
782
+ 'gather-status': {
783
+ id: 'gather-status',
784
+ name: 'Gather Status',
785
+ description: 'Queries platform status overview (executions, pending items, schedules, credentials)',
786
+ handler: async (rawInput) => {
787
+ const { timeRange } = rawInput as Input
788
+ const raw = await platform.call({
789
+ tool: 'status',
790
+ method: 'overview',
791
+ params: { timeRange },
792
+ })
793
+ return { raw }
794
+ },
795
+ inputSchema: input,
796
+ outputSchema: statusData,
797
+ next: { type: StepType.LINEAR, target: 'compile-report' },
798
+ },
799
+ 'compile-report': {
800
+ id: 'compile-report',
801
+ name: 'Compile Report',
802
+ description: 'Generates a natural language summary from raw status data',
803
+ handler: async (rawInput) => {
804
+ 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'],
829
+ },
830
+ temperature: 0,
831
+ },
832
+ })
833
+ const summary = (result as any)?.summary ?? String(result)
834
+ return { raw, summary }
835
+ },
836
+ inputSchema: statusData,
837
+ outputSchema: output,
838
+ next: null,
839
+ },
840
+ },
841
+ entryPoint: 'gather-status',
842
+ }
843
+ `;
844
+ }
845
+ function operationsBarrelTemplate() {
846
+ return `import { platformStatus } from './platform-status.js'
847
+
848
+ export const workflows = [platformStatus]
849
+ export const agents = []
850
+ `;
851
+ }
852
+ function exampleBarrelTemplate() {
853
+ return `import { echo } from './echo.js'
854
+
855
+ export const workflows = [echo]
856
+ export const agents = []
857
+ `;
858
+ }
746
859
 
747
- export { claudeAgentCommandTemplate, claudeDatabaseCommandTemplate, claudeDocsCommandTemplate, claudeHelpCommandTemplate, claudeMdTemplate, claudeMetaCommandTemplate, claudeProfileCommandTemplate, claudeResourceCommandTemplate, claudeSettingsTemplate, claudeTemplatesCommandTemplate, claudeTutorialCommandTemplate, gitignoreTemplate, starterWorkflowTemplate };
860
+ export { claudeAgentCommandTemplate, claudeDatabaseCommandTemplate, claudeDocsCommandTemplate, claudeHelpCommandTemplate, claudeMdTemplate, claudeMetaCommandTemplate, claudeProfileCommandTemplate, claudeResourceCommandTemplate, claudeSettingsTemplate, claudeTemplatesCommandTemplate, claudeTutorialCommandTemplate, exampleBarrelTemplate, gitignoreTemplate, operationsBarrelTemplate, platformStatusTemplate, starterWorkflowTemplate };
@@ -1 +1 @@
1
- export { claudeMdTemplate, claudeMetaCommandTemplate, claudeProfileCommandTemplate, claudeDocsCommandTemplate, claudeResourceCommandTemplate, claudeTutorialCommandTemplate, claudeHelpCommandTemplate, claudeTemplatesCommandTemplate, claudeDatabaseCommandTemplate, claudeAgentCommandTemplate, gitignoreTemplate, claudeSettingsTemplate, starterWorkflowTemplate, } from './cli/commands/init.js';
1
+ export { claudeMdTemplate, claudeMetaCommandTemplate, claudeProfileCommandTemplate, claudeDocsCommandTemplate, claudeResourceCommandTemplate, claudeTutorialCommandTemplate, claudeHelpCommandTemplate, claudeTemplatesCommandTemplate, claudeDatabaseCommandTemplate, claudeAgentCommandTemplate, gitignoreTemplate, claudeSettingsTemplate, starterWorkflowTemplate, platformStatusTemplate, operationsBarrelTemplate, exampleBarrelTemplate, } from './cli/commands/init.js';
@@ -8,8 +8,13 @@
8
8
  * Parent -> Worker: { type: 'manifest' }
9
9
  * Worker -> Parent: { type: 'manifest', workflows: [...], agents: [...] }
10
10
  *
11
- * Parent -> Worker: { type: 'execute', resourceId, executionId, input, organizationId?, organizationName? }
12
- * Worker -> Parent: { type: 'result', status, output?, error?, logs }
11
+ * Parent -> Worker: { type: 'execute', resourceId, executionId, input, organizationId?, organizationName?,
12
+ * sessionId?, sessionTurnNumber?, parentExecutionId?, executionDepth }
13
+ * Worker -> Parent: { type: 'result', status, output?, error?, logs, metrics: { durationMs } }
14
+ *
15
+ * Parent -> Worker: { type: 'abort' } (graceful abort before terminate)
16
+ *
17
+ * Worker -> Parent: { type: 'log', entry: { level, message, timestamp, executionId } }
13
18
  *
14
19
  * Worker -> Parent: { type: 'tool-call', id, tool, method, params, credential? }
15
20
  * Parent -> Worker: { type: 'tool-result', id, result?, error?, code? }
@@ -4755,11 +4755,20 @@ function resolveNext(next, data) {
4755
4755
  }
4756
4756
  async function executeWorkflow(workflow, input, context) {
4757
4757
  const logs = [];
4758
+ const postLog = (level, message) => {
4759
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
4760
+ const entry = { level, message, timestamp };
4761
+ logs.push(entry);
4762
+ parentPort.postMessage({
4763
+ type: "log",
4764
+ entry: { level, message, timestamp, executionId: context.executionId }
4765
+ });
4766
+ };
4758
4767
  const origLog = console.log;
4759
4768
  const origWarn = console.warn;
4760
4769
  const origError = console.error;
4761
4770
  const capture = (level, orig) => (...args) => {
4762
- logs.push({ level, message: args.map(String).join(" ") });
4771
+ postLog(level, args.map(String).join(" "));
4763
4772
  orig(...args);
4764
4773
  };
4765
4774
  console.log = capture("info", origLog);
@@ -4779,7 +4788,10 @@ async function executeWorkflow(workflow, input, context) {
4779
4788
  organizationId: context.organizationId,
4780
4789
  organizationName: context.organizationName,
4781
4790
  resourceId: workflow.config.resourceId,
4782
- executionDepth: 0,
4791
+ sessionId: context.sessionId,
4792
+ sessionTurnNumber: context.sessionTurnNumber,
4793
+ parentExecutionId: context.parentExecutionId,
4794
+ executionDepth: context.executionDepth,
4783
4795
  store: /* @__PURE__ */ new Map(),
4784
4796
  logger: {
4785
4797
  debug: (msg) => console.log(`[debug] ${msg}`),
@@ -4801,20 +4813,41 @@ async function executeWorkflow(workflow, input, context) {
4801
4813
  console.error = origError;
4802
4814
  }
4803
4815
  }
4804
- function buildWorkerExecutionContext(executionId, organizationId, organizationName, resourceId) {
4816
+ function buildWorkerExecutionContext(params) {
4817
+ const { executionId } = params;
4818
+ const postLog = (level, message) => {
4819
+ parentPort.postMessage({
4820
+ type: "log",
4821
+ entry: { level, message, timestamp: (/* @__PURE__ */ new Date()).toISOString(), executionId }
4822
+ });
4823
+ };
4805
4824
  return {
4806
- executionId,
4807
- organizationId,
4808
- organizationName,
4809
- resourceId,
4810
- executionDepth: 0,
4825
+ executionId: params.executionId,
4826
+ organizationId: params.organizationId,
4827
+ organizationName: params.organizationName,
4828
+ resourceId: params.resourceId,
4829
+ sessionId: params.sessionId,
4830
+ sessionTurnNumber: params.sessionTurnNumber,
4831
+ parentExecutionId: params.parentExecutionId,
4832
+ executionDepth: params.executionDepth,
4833
+ signal: params.signal,
4811
4834
  store: /* @__PURE__ */ new Map(),
4812
4835
  logger: {
4813
- debug: (msg) => console.log(`[debug] ${msg}`),
4814
- info: (msg) => console.log(`[info] ${msg}`),
4815
- warn: (msg) => console.warn(`[warn] ${msg}`),
4816
- error: (msg) => console.error(`[error] ${msg}`),
4817
- log: () => {
4836
+ debug: (msg) => {
4837
+ console.log(`[debug] ${msg}`);
4838
+ postLog("info", msg);
4839
+ },
4840
+ info: (msg) => {
4841
+ console.log(`[info] ${msg}`);
4842
+ postLog("info", msg);
4843
+ },
4844
+ warn: (msg) => {
4845
+ console.warn(`[warn] ${msg}`);
4846
+ postLog("warn", msg);
4847
+ },
4848
+ error: (msg) => {
4849
+ console.error(`[error] ${msg}`);
4850
+ postLog("error", msg);
4818
4851
  }
4819
4852
  },
4820
4853
  onMessageEvent: async (event) => {
@@ -4829,6 +4862,7 @@ function startWorker(org) {
4829
4862
  const agents = new Map(
4830
4863
  (org.agents ?? []).map((a) => [a.config.resourceId, a])
4831
4864
  );
4865
+ let localAbortController = new AbortController();
4832
4866
  console.log(`[SDK-WORKER] Worker started with ${workflows.size} workflow(s), ${agents.size} agent(s)`);
4833
4867
  parentPort.on("message", async (msg) => {
4834
4868
  if (msg.type === "manifest") {
@@ -4864,24 +4898,46 @@ function startWorker(org) {
4864
4898
  handleCredentialResult(msg);
4865
4899
  return;
4866
4900
  }
4901
+ if (msg.type === "abort") {
4902
+ console.log("[SDK-WORKER] Abort requested by parent");
4903
+ localAbortController.abort();
4904
+ return;
4905
+ }
4867
4906
  if (msg.type === "execute") {
4868
- const { resourceId, executionId, input, organizationId, organizationName } = msg;
4907
+ const {
4908
+ resourceId,
4909
+ executionId,
4910
+ input,
4911
+ organizationId,
4912
+ organizationName,
4913
+ sessionId,
4914
+ sessionTurnNumber,
4915
+ parentExecutionId,
4916
+ executionDepth
4917
+ } = msg;
4869
4918
  console.log(`[SDK-WORKER] Execute request: resourceId=${resourceId}, executionId=${executionId}`);
4919
+ localAbortController = new AbortController();
4870
4920
  const workflow = workflows.get(resourceId);
4871
4921
  if (workflow) {
4922
+ const startTime = Date.now();
4872
4923
  try {
4873
4924
  console.log(`[SDK-WORKER] Running workflow '${resourceId}' (${Object.keys(workflow.steps).length} steps)`);
4874
- const startTime = Date.now();
4875
4925
  const { output, logs } = await executeWorkflow(workflow, input, {
4876
4926
  executionId,
4877
4927
  organizationId: organizationId ?? "",
4878
- organizationName: organizationName ?? ""
4928
+ organizationName: organizationName ?? "",
4929
+ sessionId,
4930
+ sessionTurnNumber,
4931
+ parentExecutionId,
4932
+ executionDepth: executionDepth ?? 0
4879
4933
  });
4880
- console.log(`[SDK-WORKER] Workflow '${resourceId}' completed (${Date.now() - startTime}ms)`);
4881
- parentPort.postMessage({ type: "result", status: "completed", output, logs });
4934
+ const durationMs = Date.now() - startTime;
4935
+ console.log(`[SDK-WORKER] Workflow '${resourceId}' completed (${durationMs}ms)`);
4936
+ parentPort.postMessage({ type: "result", status: "completed", output, logs, metrics: { durationMs } });
4882
4937
  } catch (err) {
4883
- console.error(`[SDK-WORKER] Workflow '${resourceId}' failed: ${String(err)}`);
4884
- parentPort.postMessage({ type: "result", status: "failed", error: String(err), logs: [] });
4938
+ const durationMs = Date.now() - startTime;
4939
+ console.error(`[SDK-WORKER] Workflow '${resourceId}' failed (${durationMs}ms): ${String(err)}`);
4940
+ parentPort.postMessage({ type: "result", status: "failed", error: String(err), logs: [], metrics: { durationMs } });
4885
4941
  }
4886
4942
  return;
4887
4943
  }
@@ -4891,32 +4947,54 @@ function startWorker(org) {
4891
4947
  const origLog = console.log;
4892
4948
  const origWarn = console.warn;
4893
4949
  const origError = console.error;
4950
+ const postLog = (level, message) => {
4951
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
4952
+ const entry = { level, message, timestamp };
4953
+ logs.push(entry);
4954
+ parentPort.postMessage({
4955
+ type: "log",
4956
+ entry: { level, message, timestamp, executionId }
4957
+ });
4958
+ };
4894
4959
  const capture = (level, orig) => (...args) => {
4895
- logs.push({ level, message: args.map(String).join(" ") });
4960
+ postLog(level, args.map(String).join(" "));
4896
4961
  orig(...args);
4897
4962
  };
4898
4963
  console.log = capture("info", origLog);
4899
4964
  console.warn = capture("warn", origWarn);
4900
4965
  console.error = capture("error", origError);
4966
+ const startTime = Date.now();
4901
4967
  try {
4902
4968
  console.log(`[SDK-WORKER] Running agent '${resourceId}' (${agentDef.tools.length} tools)`);
4903
- const startTime = Date.now();
4904
4969
  const adapterFactory = createPostMessageAdapterFactory();
4905
4970
  const agentInstance = new Agent(agentDef, adapterFactory);
4906
- const context = buildWorkerExecutionContext(executionId, organizationId ?? "", organizationName ?? "", resourceId);
4971
+ const context = buildWorkerExecutionContext({
4972
+ executionId,
4973
+ organizationId: organizationId ?? "",
4974
+ organizationName: organizationName ?? "",
4975
+ resourceId,
4976
+ sessionId,
4977
+ sessionTurnNumber,
4978
+ parentExecutionId,
4979
+ executionDepth: executionDepth ?? 0,
4980
+ signal: localAbortController.signal
4981
+ });
4907
4982
  const output = await agentInstance.execute(input, context);
4908
- console.log(`[SDK-WORKER] Agent '${resourceId}' completed (${Date.now() - startTime}ms)`);
4909
- parentPort.postMessage({ type: "result", status: "completed", output, logs });
4983
+ const durationMs = Date.now() - startTime;
4984
+ console.log(`[SDK-WORKER] Agent '${resourceId}' completed (${durationMs}ms)`);
4985
+ parentPort.postMessage({ type: "result", status: "completed", output, logs, metrics: { durationMs } });
4910
4986
  } catch (err) {
4987
+ const durationMs = Date.now() - startTime;
4911
4988
  const errorMessage = err?.message ?? String(err);
4912
4989
  err?.code ?? "unknown";
4913
4990
  const errorName = err?.name ?? err?.constructor?.name ?? "Error";
4914
- console.error(`[SDK-WORKER] Agent '${resourceId}' failed: [${errorName}] ${errorMessage}`);
4991
+ console.error(`[SDK-WORKER] Agent '${resourceId}' failed (${durationMs}ms): [${errorName}] ${errorMessage}`);
4915
4992
  parentPort.postMessage({
4916
4993
  type: "result",
4917
4994
  status: "failed",
4918
4995
  error: `${errorName}: ${errorMessage}`,
4919
- logs
4996
+ logs,
4997
+ metrics: { durationMs }
4920
4998
  });
4921
4999
  } finally {
4922
5000
  console.log = origLog;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
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,11 +33,6 @@
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
- },
41
36
  "dependencies": {
42
37
  "esbuild": "^0.25.0",
43
38
  "jiti": "^2.0.0"
@@ -46,8 +41,6 @@
46
41
  "zod": "^4.1.0"
47
42
  },
48
43
  "devDependencies": {
49
- "@repo/core": "workspace:*",
50
- "@repo/typescript-config": "workspace:*",
51
44
  "@types/node": "^22.0.0",
52
45
  "chalk": "^5.3.0",
53
46
  "commander": "^11.0.0",
@@ -58,6 +51,13 @@
58
51
  "rollup-plugin-dts": "^6.3.0",
59
52
  "tsup": "^8.0.0",
60
53
  "typescript": "5.9.2",
61
- "zod": "^4.1.0"
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"
62
62
  }
63
- }
63
+ }
@@ -92,4 +92,4 @@ The Growth Log in `memory/profile/skills.md` keeps approximately 20 recent entri
92
92
 
93
93
  ---
94
94
 
95
- **Last Updated:** 2026-02-25
95
+ **Last Updated:** 2026-02-27
@@ -12,23 +12,39 @@ loadWhen: "Understanding scaffolded files or project layout"
12
12
 
13
13
  ### `src/index.ts`
14
14
 
15
- The registry entry point for your workspace. This file imports and re-exports all resources from `src/workflows/` as an `OrganizationResources` default export. It does not contain workflow logic itself -- its sole job is aggregation:
15
+ The registry entry point for your workspace. This file aggregates resources from domain barrel files and re-exports them as an `OrganizationResources` default export. It does not contain workflow logic itself -- its sole job is aggregation:
16
16
 
17
17
  ```ts
18
18
  import type { OrganizationResources } from '@elevasis/sdk'
19
- import { echo } from './workflows/echo.js'
19
+ import * as operations from './operations/index.js'
20
+ import * as example from './example/index.js'
20
21
 
21
22
  const org: OrganizationResources = {
22
- workflows: [echo],
23
+ workflows: [
24
+ ...operations.workflows,
25
+ ...example.workflows,
26
+ ],
27
+ agents: [
28
+ ...operations.agents,
29
+ ...example.agents,
30
+ ],
23
31
  }
24
32
  export default org
25
33
  ```
26
34
 
27
- Every resource you add is wired into this file. The `/resource workflow` command updates it automatically.
35
+ Each domain directory exports `workflows` and `agents` arrays via an `index.ts` barrel. When you add a new domain, import it here and spread its arrays. The `/resource workflow` command updates the appropriate domain barrel automatically.
28
36
 
29
- ### `src/workflows/echo.ts`
37
+ ### `src/operations/platform-status.ts`
30
38
 
31
- The starter workflow, scaffolded to demonstrate the per-file pattern: one workflow per file with its own Zod input/output schemas, config object, contract, and step handler. When you add new workflows, each one gets its own file in `src/workflows/` and is imported into `src/index.ts`.
39
+ A multi-step workflow demonstrating real platform API usage. Calls `platform.call({ tool: 'status', method: 'overview' })` to gather platform status data, then passes it to `platform.call({ tool: 'llm', method: 'generate' })` for a natural language summary. Shows the pattern for workflows that interact with platform tools and chain steps with `StepType.LINEAR`.
40
+
41
+ ### `src/example/echo.ts`
42
+
43
+ The starter workflow, scaffolded to demonstrate the per-file pattern: one workflow per file with its own Zod input/output schemas, config object, contract, and step handler. Replace this domain with your own when you're ready.
44
+
45
+ ### `src/shared/`
46
+
47
+ Cross-domain shared types and utilities. This directory starts empty (`.gitkeep`). Place code here when two or more domains share the same utility -- for example, formatters, shared types, or notification helpers. Domain-specific shared code goes in `<domain>/shared/` instead.
32
48
 
33
49
  ### `elevasis.config.ts`
34
50
 
@@ -38,7 +54,7 @@ Project-level configuration. The scaffolded file includes `templateVersion`, whi
38
54
  import type { ElevasConfig } from '@elevasis/sdk'
39
55
 
40
56
  export default {
41
- templateVersion: 4,
57
+ templateVersion: 5,
42
58
  // defaultStatus: 'dev', // Default status for new resources ('dev' | 'production')
43
59
  // dev: { port: 5170 }, // Local API port (internal development only)
44
60
  } satisfies ElevasConfig
@@ -92,7 +108,9 @@ Only `src/` and `docs/` are scaffolded by `elevasis init`. The following directo
92
108
 
93
109
  | Directory | Created by | When |
94
110
  |-----------|-----------|------|
95
- | `src/workflows/` | `elevasis init` (default) | Always -- starter workflow `echo.ts` lives here |
111
+ | `src/operations/` | `elevasis init` (default) | Always -- platform-status workflow lives here |
112
+ | `src/example/` | `elevasis init` (default) | Always -- echo starter workflow lives here (replace with your own) |
113
+ | `src/shared/` | `elevasis init` (default) | Always -- cross-domain shared utilities (starts empty) |
96
114
  | `docs/` | `elevasis init` (default) | Always |
97
115
  | `docs/in-progress/` | Agent (on first `/docs checkpoint`) | When you save work-in-progress across sessions |
98
116
  | `docs/navigation.mdx` | Agent (on first `/meta deploy`) | Auto-generated and updated on each deploy |
@@ -105,7 +123,7 @@ This structure keeps the initial workspace minimal and adds directories only whe
105
123
 
106
124
  ### `src/lib/`
107
125
 
108
- Shared TypeScript utilities, types, and helpers used by multiple workflows. The agent creates this directory when you have code shared between two or more workflow files -- for example, retry logic, formatters, or shared types. Included in the esbuild bundle alongside workflow code. Not scaffolded by default to avoid premature abstraction.
126
+ Legacy shared code directory. In v5+ projects, use `src/shared/` for cross-domain utilities instead. The agent may still create `src/lib/` in older projects that predate the domain-based organization. Included in the esbuild bundle alongside workflow code.
109
127
 
110
128
  ### `data/`
111
129
 
@@ -250,7 +268,7 @@ Applies pre-built workflow templates to your workspace. Three operations:
250
268
 
251
269
  - **No arguments** -- List available template categories (Data Collection, Data Processing, Communication, CRM, Documents, AI, Scheduling)
252
270
  - **`<category>`** -- Show templates in a category with descriptions
253
- - **`apply <name>`** -- Generate a workflow from a template: writes to `src/workflows/`, wires into `src/index.ts`, prompts for credential setup if needed, and runs `elevasis check` to validate
271
+ - **`apply <name>`** -- Generate a workflow from a template: writes to the appropriate domain directory, wires into the domain barrel, prompts for credential setup if needed, and runs `elevasis check` to validate
254
272
 
255
273
  Templates are documentation files bundled with the SDK, not rigid copy-paste code. The agent reads the template and generates a workflow adapted to your existing schemas, credentials, and naming conventions.
256
274
 
@@ -260,12 +278,13 @@ Templates are documentation files bundled with the SDK, not rigid copy-paste cod
260
278
 
261
279
  Not all scaffolded files participate in template updates. Files fall into two categories:
262
280
 
263
- **SCAFFOLD_FILES total: 23**
281
+ **SCAFFOLD_FILES total: 27**
264
282
 
265
- **INIT_ONLY** (10 files) -- Written once during `elevasis init`, never updated by `elevasis update`:
283
+ **INIT_ONLY** (14 files) -- Written once during `elevasis init`, never updated by `elevasis update`:
266
284
  - `package.json`, `pnpm-workspace.yaml`, `tsconfig.json`
267
285
  - `.env`, `.env.example`, `.npmrc`
268
- - `src/index.ts`, `src/workflows/echo.ts`, `docs/index.mdx`, `.claude/settings.json`
286
+ - `src/index.ts`, `src/operations/platform-status.ts`, `src/operations/index.ts`, `src/example/echo.ts`, `src/example/index.ts`, `src/shared/.gitkeep`
287
+ - `docs/index.mdx`, `docs/in-progress/.gitkeep`
269
288
 
270
289
  **MANAGED** (13 files) -- Written during `elevasis init` and checked/updatable by `elevasis update`:
271
290
  - `elevasis.config.ts`, `.gitignore`, `CLAUDE.md`, `docs/navigation.mdx`
@@ -280,7 +299,7 @@ Run `elevasis update` after installing a new SDK version to bring managed files
280
299
  | File | When You Edit It |
281
300
  |------|-----------------|
282
301
  | `src/index.ts` | Adding or removing resources (the `/resource` command does this automatically) |
283
- | `src/workflows/*.ts` | Writing and modifying workflow logic |
302
+ | `src/<domain>/*.ts` | Writing and modifying workflow logic (organized by business domain) |
284
303
  | `docs/index.mdx` | Updating project documentation |
285
304
  | `docs/navigation.mdx` | Never -- auto-generated by `/meta deploy` |
286
305
  | `docs/priorities.mdx` | When goals or priorities change |
@@ -291,4 +310,4 @@ Run `elevasis update` after installing a new SDK version to bring managed files
291
310
 
292
311
  ---
293
312
 
294
- **Last Updated:** 2026-02-26
313
+ **Last Updated:** 2026-02-27
@@ -29,7 +29,7 @@ elevasis init my-project
29
29
  cd my-project
30
30
  ```
31
31
 
32
- The command scaffolds 23 files covering configuration, source, documentation, and Claude Code integration:
32
+ The command scaffolds 27 files covering configuration, source, documentation, and Claude Code integration:
33
33
 
34
34
  ```
35
35
  my-project/
@@ -47,9 +47,15 @@ my-project/
47
47
  │ ├── tutorial.md # Progressive learning
48
48
  │ └── profile.md # View and update user profile
49
49
  ├── src/
50
- │ ├── index.ts # Registry entry point
51
- └── workflows/
52
- └── echo.ts # Starter workflow
50
+ │ ├── index.ts # Registry entry point (aggregates domain barrels)
51
+ ├── operations/
52
+ │ ├── index.ts # Domain barrel (exports workflows + agents)
53
+ │ │ └── platform-status.ts # Platform status workflow (real API example)
54
+ │ ├── example/
55
+ │ │ ├── index.ts # Domain barrel (exports workflows + agents)
56
+ │ │ └── echo.ts # Starter workflow (replace with your own)
57
+ │ └── shared/
58
+ │ └── .gitkeep # Cross-domain shared utilities
53
59
  ├── docs/
54
60
  │ ├── index.mdx # Starter documentation page
55
61
  │ └── in-progress/
@@ -70,7 +76,7 @@ The scaffolded `elevasis.config.ts` includes a `templateVersion` field that trac
70
76
  import type { ElevasConfig } from '@elevasis/sdk'
71
77
 
72
78
  export default {
73
- templateVersion: 4,
79
+ templateVersion: 5,
74
80
  } satisfies ElevasConfig
75
81
  ```
76
82
 
@@ -145,4 +151,4 @@ When a new SDK version is released, run `elevasis update` to bring your project'
145
151
 
146
152
  ---
147
153
 
148
- **Last Updated:** 2026-02-25
154
+ **Last Updated:** 2026-02-27
@@ -309,26 +309,39 @@ Individual resources that set their own `config.status` override this default.
309
309
 
310
310
  ## Organizing Multiple Resources
311
311
 
312
- As your project grows, split resources into separate files and import them into `src/index.ts`:
312
+ As your project grows, organize resources by business domain. Each domain gets its own directory with an `index.ts` barrel that exports `workflows` and `agents` arrays:
313
313
 
314
314
  ```typescript
315
- // src/workflows/fulfill-order.ts
315
+ // src/orders/fulfill-order.ts
316
316
  export const fulfillOrder: WorkflowDefinition = { ... };
317
317
 
318
- // src/workflows/send-invoice.ts
318
+ // src/billing/send-invoice.ts
319
319
  export const sendInvoice: WorkflowDefinition = { ... };
320
320
 
321
+ // src/orders/index.ts
322
+ import { fulfillOrder } from './fulfill-order.js';
323
+ export const workflows = [fulfillOrder];
324
+ export const agents = [];
325
+
326
+ // src/billing/index.ts
327
+ import { sendInvoice } from './send-invoice.js';
328
+ export const workflows = [sendInvoice];
329
+ export const agents = [];
330
+
321
331
  // src/index.ts
322
- import { fulfillOrder } from './workflows/fulfill-order';
323
- import { sendInvoice } from './workflows/send-invoice';
324
332
  import type { OrganizationResources } from '@elevasis/sdk';
333
+ import * as orders from './orders/index.js';
334
+ import * as billing from './billing/index.js';
325
335
 
326
336
  const org: OrganizationResources = {
327
- workflows: {
328
- 'fulfill-order': fulfillOrder,
329
- 'send-invoice': sendInvoice,
330
- },
331
- agents: {},
337
+ workflows: [
338
+ ...orders.workflows,
339
+ ...billing.workflows,
340
+ ],
341
+ agents: [
342
+ ...orders.agents,
343
+ ...billing.agents,
344
+ ],
332
345
  };
333
346
 
334
347
  export default org;
@@ -45,7 +45,7 @@ This is the static SDK-level error catalog. Check `.claude/memory/errors/` first
45
45
 
46
46
  **Cause:** Two resources in `src/` share the same `resourceId`.
47
47
 
48
- **Fix:** Each resource must have a unique `resourceId` within your organization. Check all files in `src/workflows/` and rename the duplicate.
48
+ **Fix:** Each resource must have a unique `resourceId` within your organization. Check all domain directories in `src/` and rename the duplicate.
49
49
 
50
50
  ### Workflow step references non-existent next step
51
51