@elevasis/sdk 1.4.0 → 1.5.1

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 (31) hide show
  1. package/dist/cli.cjs +100 -12
  2. package/dist/index.d.ts +1464 -749
  3. package/dist/index.js +74 -7
  4. package/dist/types/worker/adapters/crm.d.ts +20 -0
  5. package/dist/types/worker/adapters/index.d.ts +2 -0
  6. package/dist/types/worker/adapters/projects.d.ts +20 -0
  7. package/dist/worker/index.js +41 -1
  8. package/package.json +2 -2
  9. package/reference/_navigation.md +24 -0
  10. package/reference/deployment/provided-features.mdx +64 -25
  11. package/reference/framework/index.mdx +2 -2
  12. package/reference/framework/project-structure.mdx +10 -8
  13. package/reference/index.mdx +3 -3
  14. package/reference/packages/core/src/organization-model/README.md +19 -4
  15. package/reference/resources/patterns.mdx +54 -8
  16. package/reference/scaffold/core/organization-graph.mdx +262 -0
  17. package/reference/scaffold/core/organization-model.mdx +257 -0
  18. package/reference/scaffold/index.mdx +59 -0
  19. package/reference/scaffold/operations/workflow-recipes.md +419 -0
  20. package/reference/scaffold/recipes/add-a-feature.md +142 -0
  21. package/reference/scaffold/recipes/add-a-resource.md +163 -0
  22. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +152 -0
  23. package/reference/scaffold/recipes/index.md +32 -0
  24. package/reference/scaffold/reference/contracts.md +1044 -0
  25. package/reference/scaffold/reference/feature-registry.md +30 -0
  26. package/reference/scaffold/reference/glossary.md +88 -0
  27. package/reference/scaffold/ui/composition-extensibility.mdx +216 -0
  28. package/reference/scaffold/ui/customization.md +239 -0
  29. package/reference/scaffold/ui/feature-flags-and-gating.md +265 -0
  30. package/reference/scaffold/ui/feature-shell.mdx +241 -0
  31. package/reference/scaffold/ui/recipes.md +418 -0
package/dist/index.js CHANGED
@@ -3200,6 +3200,71 @@ var ResourceRegistry = class {
3200
3200
  validateRelationships(orgName, resources);
3201
3201
  }
3202
3202
  }
3203
+ /**
3204
+ * Get the remote resource IDs currently registered for an organization.
3205
+ * Used to validate redeployments against the post-swap state before any
3206
+ * live registry mutation occurs.
3207
+ */
3208
+ getRemoteResourceIds(orgName) {
3209
+ const prefix = `${orgName}/`;
3210
+ const remoteIds = /* @__PURE__ */ new Set();
3211
+ for (const key of this.remoteResources.keys()) {
3212
+ if (key.startsWith(prefix)) {
3213
+ remoteIds.add(key.slice(prefix.length));
3214
+ }
3215
+ }
3216
+ return remoteIds;
3217
+ }
3218
+ /**
3219
+ * Build the "static + surviving" baseline for registration validation.
3220
+ * On redeploy, this strips the currently remote-owned resources and
3221
+ * deployment-owned metadata so validation reflects the state after swap.
3222
+ */
3223
+ buildRegistrationBase(orgName) {
3224
+ const existingOrg = this.registry[orgName];
3225
+ if (!existingOrg) return void 0;
3226
+ const remoteIds = this.getRemoteResourceIds(orgName);
3227
+ if (remoteIds.size === 0) return existingOrg;
3228
+ const relationships = existingOrg.relationships ? Object.fromEntries(Object.entries(existingOrg.relationships).filter(([resourceId]) => !remoteIds.has(resourceId))) : void 0;
3229
+ return {
3230
+ ...existingOrg,
3231
+ version: existingOrg.version ?? "0.0.0",
3232
+ workflows: (existingOrg.workflows ?? []).filter((w) => !remoteIds.has(w.config.resourceId)),
3233
+ agents: (existingOrg.agents ?? []).filter((a) => !remoteIds.has(a.config.resourceId)),
3234
+ triggers: void 0,
3235
+ integrations: void 0,
3236
+ humanCheckpoints: void 0,
3237
+ externalResources: void 0,
3238
+ relationships: relationships && Object.keys(relationships).length > 0 ? relationships : void 0
3239
+ };
3240
+ }
3241
+ /**
3242
+ * Validate the registry state that would exist after registration succeeds.
3243
+ * This runs before any live mutation so invalid redeploys preserve the
3244
+ * currently active remote resources.
3245
+ */
3246
+ validateRegistrationCandidate(orgName, incoming) {
3247
+ const base = this.buildRegistrationBase(orgName);
3248
+ const candidate = base ? {
3249
+ ...base,
3250
+ version: incoming.version ?? base.version ?? "0.0.0",
3251
+ workflows: [...base.workflows ?? [], ...incoming.workflows ?? []],
3252
+ agents: [...base.agents ?? [], ...incoming.agents ?? []],
3253
+ triggers: incoming.triggers,
3254
+ integrations: incoming.integrations,
3255
+ humanCheckpoints: incoming.humanCheckpoints,
3256
+ externalResources: incoming.externalResources,
3257
+ relationships: incoming.relationships ? {
3258
+ ...base.relationships ?? {},
3259
+ ...incoming.relationships
3260
+ } : base.relationships
3261
+ } : {
3262
+ ...incoming,
3263
+ version: incoming.version ?? "0.0.0"
3264
+ };
3265
+ validateDeploymentSpec(orgName, candidate);
3266
+ validateRelationships(orgName, candidate);
3267
+ }
3203
3268
  /**
3204
3269
  * Get a resource definition by ID
3205
3270
  * Returns full definition (WorkflowDefinition or AgentDefinition)
@@ -3308,13 +3373,10 @@ var ResourceRegistry = class {
3308
3373
  );
3309
3374
  }
3310
3375
  }
3311
- if (this.isRemote(orgName)) {
3312
- this.unregisterOrganization(orgName);
3313
- }
3314
- const existingOrg = this.registry[orgName];
3315
- if (existingOrg) {
3316
- const staticWorkflowIds = new Set((existingOrg.workflows ?? []).map((w) => w.config.resourceId));
3317
- const staticAgentIds = new Set((existingOrg.agents ?? []).map((a) => a.config.resourceId));
3376
+ const validationBase = this.buildRegistrationBase(orgName);
3377
+ if (validationBase) {
3378
+ const staticWorkflowIds = new Set((validationBase.workflows ?? []).map((w) => w.config.resourceId));
3379
+ const staticAgentIds = new Set((validationBase.agents ?? []).map((a) => a.config.resourceId));
3318
3380
  for (const id of incomingIds) {
3319
3381
  if (staticWorkflowIds.has(id) || staticAgentIds.has(id)) {
3320
3382
  throw new Error(
@@ -3323,6 +3385,11 @@ var ResourceRegistry = class {
3323
3385
  }
3324
3386
  }
3325
3387
  }
3388
+ this.validateRegistrationCandidate(orgName, org);
3389
+ if (this.isRemote(orgName)) {
3390
+ this.unregisterOrganization(orgName);
3391
+ }
3392
+ const existingOrg = this.registry[orgName];
3326
3393
  if (existingOrg) {
3327
3394
  existingOrg.workflows = [...existingOrg.workflows ?? [], ...org.workflows ?? []];
3328
3395
  existingOrg.agents = [...existingOrg.agents ?? [], ...org.agents ?? []];
@@ -0,0 +1,20 @@
1
+ /**
2
+ * CRM Platform Tool Adapter
3
+ *
4
+ * Typed wrapper over platform.call() for deal and pipeline operations.
5
+ * Singleton export -- no credential needed (platform tool).
6
+ */
7
+ import { type TypedAdapter } from './create-adapter.js';
8
+ import type { CrmToolMap } from '../../types/index.js';
9
+ /**
10
+ * Typed crm adapter for recent activity, deal reads, stage changes, notes, tasks, and cleanup.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { crm } from '@elevasis/sdk/worker'
15
+ *
16
+ * const deals = await crm.listDeals({ stage: 'proposal' })
17
+ * const activity = await crm.getRecentActivity({ limit: 10 })
18
+ * ```
19
+ */
20
+ export declare const crm: TypedAdapter<CrmToolMap>;
@@ -23,6 +23,8 @@ export { llm } from './llm.js';
23
23
  export { storage } from './storage.js';
24
24
  export { notifications, type NotificationInput } from './notification.js';
25
25
  export { acqDb } from './lead.js';
26
+ export { projects } from './projects.js';
27
+ export { crm } from './crm.js';
26
28
  export { list } from './list.js';
27
29
  export { pdf } from './pdf.js';
28
30
  export { approval } from './approval.js';
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Projects Platform Tool Adapter
3
+ *
4
+ * Typed wrapper over platform.call() for delivery project operations.
5
+ * Singleton export -- no credential needed (platform tool).
6
+ */
7
+ import { type TypedAdapter } from './create-adapter.js';
8
+ import type { ProjectsToolMap } from '../../types/index.js';
9
+ /**
10
+ * Typed projects adapter for project, milestone, task, note, and resume-context operations.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { projects } from '@elevasis/sdk/worker'
15
+ *
16
+ * const activeProjects = await projects.listProjects({ kind: 'internal' })
17
+ * const project = await projects.getProject({ id: '...' })
18
+ * ```
19
+ */
20
+ export declare const projects: TypedAdapter<ProjectsToolMap>;
@@ -5012,6 +5012,46 @@ var acqDb = createAdapter("acqDb", [
5012
5012
  "upsertSocialPosts"
5013
5013
  ]);
5014
5014
 
5015
+ // src/worker/adapters/projects.ts
5016
+ var projects = createAdapter("projects", [
5017
+ "listProjects",
5018
+ "getProject",
5019
+ "createProject",
5020
+ "updateProject",
5021
+ "deleteProject",
5022
+ "listMilestones",
5023
+ "createMilestone",
5024
+ "updateMilestone",
5025
+ "deleteMilestone",
5026
+ "listTasks",
5027
+ "getTask",
5028
+ "createTask",
5029
+ "updateTask",
5030
+ "deleteTask",
5031
+ "mergeTaskResumeContext",
5032
+ "listNotes",
5033
+ "createNote",
5034
+ "updateNote",
5035
+ "deleteNote"
5036
+ ]);
5037
+
5038
+ // src/worker/adapters/crm.ts
5039
+ var crm = createAdapter("crm", [
5040
+ "getRecentActivity",
5041
+ "listDeals",
5042
+ "getDeal",
5043
+ "getDealByEmail",
5044
+ "updateDealStage",
5045
+ "createDealNote",
5046
+ "listDealNotes",
5047
+ "createDealTask",
5048
+ "listDealTasks",
5049
+ "listDealTasksDue",
5050
+ "completeDealTask",
5051
+ "recordActivity",
5052
+ "deleteDeal"
5053
+ ]);
5054
+
5015
5055
  // src/worker/adapters/list.ts
5016
5056
  var list = createAdapter("list", [
5017
5057
  "getConfig",
@@ -5392,4 +5432,4 @@ function startWorker(org) {
5392
5432
  });
5393
5433
  }
5394
5434
 
5395
- export { PlatformToolError, acqDb, approval, createAdapter, createAnymailfinderAdapter, createApifyAdapter, createAttioAdapter, createDropboxAdapter, createGmailAdapter, createGoogleSheetsAdapter, createInstantlyAdapter, createMillionVerifierAdapter, createResendAdapter, createSignatureApiAdapter, createStripeAdapter, createTombaAdapter, email, execution, list, llm, notifications, pdf, platform, scheduler, startWorker, storage };
5435
+ export { PlatformToolError, acqDb, approval, createAdapter, createAnymailfinderAdapter, createApifyAdapter, createAttioAdapter, createDropboxAdapter, createGmailAdapter, createGoogleSheetsAdapter, createInstantlyAdapter, createMillionVerifierAdapter, createResendAdapter, createSignatureApiAdapter, createStripeAdapter, createTombaAdapter, crm, email, execution, list, llm, notifications, pdf, platform, projects, scheduler, startWorker, storage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -44,7 +44,7 @@
44
44
  "tsup": "^8.0.0",
45
45
  "typescript": "5.9.2",
46
46
  "zod": "^4.1.0",
47
- "@repo/core": "0.1.0",
47
+ "@repo/core": "0.2.0",
48
48
  "@repo/typescript-config": "0.0.0"
49
49
  },
50
50
  "scripts": {
@@ -89,3 +89,27 @@ Package entries indexed: 36.
89
89
  | --- | --- | --- | --- |
90
90
  | Theme | `packages/ui/src/theme/README.md` | Published theme entry for downstream applications. | (not specified) |
91
91
  | Graph | `packages/ui/src/graph/README.md` | Published graph helper and visualization entry. | (not specified) |
92
+
93
+ ---
94
+
95
+ ## Scaffold Reference
96
+
97
+ Universal scaffold documentation for all SDK projects. Source locations are co-located with owning packages; the SDK build copies everything into `reference/scaffold/`.
98
+
99
+ | Document | Bundle Path | Description |
100
+ | --- | --- | --- |
101
+ | Scaffold Index | `scaffold/index.mdx` | Discovery entry point and navigation map |
102
+ | Add a Feature | `scaffold/recipes/add-a-feature.md` | End-to-end feature addition recipe |
103
+ | Add a Resource | `scaffold/recipes/add-a-resource.md` | Workflow/agent authoring recipe |
104
+ | Gate by Feature/Admin | `scaffold/recipes/gate-by-feature-or-admin.md` | Access control patterns |
105
+ | UI Recipes | `scaffold/ui/recipes.md` | Copy-paste UI recipes |
106
+ | Feature Flags & Gating | `scaffold/ui/feature-flags-and-gating.md` | Three-concept gating model |
107
+ | Customizing Features | `scaffold/ui/customization.md` | Sidebar composition patterns |
108
+ | Feature Shell | `scaffold/ui/feature-shell.mdx` | FeatureModule manifest and provider |
109
+ | Composition & Extensibility | `scaffold/ui/composition-extensibility.mdx` | Layout primitives and overrides |
110
+ | Organization Model | `scaffold/core/organization-model.mdx` | Semantic contract and schema |
111
+ | Organization Graph | `scaffold/core/organization-graph.mdx` | Graph derivation and Cytoscape |
112
+ | Workflow Recipes | `scaffold/operations/workflow-recipes.md` | Workflow anatomy and adapters |
113
+ | Glossary | `scaffold/reference/glossary.md` | Term definitions |
114
+ | Contracts | `scaffold/reference/contracts.md` | Auto-generated type contracts |
115
+ | Feature Registry | `scaffold/reference/feature-registry.md` | Auto-generated feature catalog |
@@ -4,28 +4,61 @@ description: Shared UI and API surfaces for packaged business systems like Lead
4
4
  loadWhen: "Building against packaged app features, list-oriented lead gen, CRM, or project-management surfaces"
5
5
  ---
6
6
 
7
- The SDK now covers more than raw workflow execution. `@elevasis/ui` publishes packaged business surfaces through `@elevasis/ui/features/<name>`, while `@elevasis/ui/components` stays available for generic UI primitives and short-lived compatibility aliases during the rollout. `elevasis-sdk` still exposes CLI commands for project-management surfaces that user agents can operate directly.
7
+ The SDK now covers more than raw workflow execution. The published `@elevasis/ui@2.7.0` package includes:
8
8
 
9
- Use this page when you need to understand how the shared feature system is wired, which routes and hooks back each area, and which API or CLI surface to reach for.
9
+ - manifest-backed shared features under `@elevasis/ui/features/<name>`
10
+ - headless shell/provider exports under `@elevasis/ui/provider`
11
+ - compatibility re-exports from `@elevasis/ui/components` for existing consumers
12
+
13
+ Use this page to understand what the shared shell actually owns, which surfaces are still host-owned, and which API or CLI surface to reach for.
10
14
 
11
15
  ---
12
16
 
13
- ## Feature Shell
17
+ ## Shared Shell Contract
18
+
19
+ `ElevasisFeaturesProvider` and `FeatureShell` give you a shared manifest-driven shell layer, not a full application shell. In `2.7.0` they handle:
20
+
21
+ - feature registration
22
+ - feature-gated nav contribution
23
+ - route-to-sidebar subshell dispatch when a manifest includes a shared sidebar
24
+ - shared provider context such as `timeRange` and operations runtime inputs
14
25
 
15
- Shared application features are mounted through `@elevasis/ui/provider` and feature manifests exported from `@elevasis/ui/features/<name>`.
26
+ Your host app still owns:
27
+
28
+ - TanStack route registration
29
+ - top-level app nav, topbar, branding, and auth wiring
30
+ - app-specific assistant/admin behavior
31
+ - any dashboard or landing page experience that is not backed by a published manifest
16
32
 
17
33
  ```tsx
18
34
  import { Outlet } from '@tanstack/react-router'
19
- import { ElevasisFeaturesProvider, FeatureShell } from '@elevasis/ui/provider'
35
+ import { IconLayoutDashboard } from '@tabler/icons-react'
36
+ import {
37
+ ElevasisFeaturesProvider,
38
+ FeatureShell,
39
+ type AppShellOverrides
40
+ } from '@elevasis/ui/provider'
20
41
  import { leadGenManifest } from '@elevasis/ui/features/lead-gen'
21
42
  import { crmManifest } from '@elevasis/ui/features/crm'
22
43
  import { deliveryManifest } from '@elevasis/ui/features/delivery'
23
-
24
- const features = [leadGenManifest, crmManifest, deliveryManifest]
44
+ import { monitoringManifest } from '@elevasis/ui/features/monitoring'
45
+ import { settingsManifest } from '@elevasis/ui/features/settings'
46
+
47
+ const features = [
48
+ leadGenManifest,
49
+ crmManifest,
50
+ deliveryManifest,
51
+ monitoringManifest,
52
+ settingsManifest,
53
+ ]
54
+
55
+ const appShellOverrides: AppShellOverrides = {
56
+ primaryNavItems: [{ label: 'Dashboard', icon: IconLayoutDashboard, link: '/' }],
57
+ }
25
58
 
26
59
  export function AppShell() {
27
60
  return (
28
- <ElevasisFeaturesProvider features={features}>
61
+ <ElevasisFeaturesProvider features={features} appShellOverrides={appShellOverrides}>
29
62
  <FeatureShell>
30
63
  <Outlet />
31
64
  </FeatureShell>
@@ -36,33 +69,37 @@ export function AppShell() {
36
69
 
37
70
  What this gives you:
38
71
 
39
- - feature-gated top-level nav entries
40
- - automatic subshell sidebar dispatch by route prefix
41
- - shared pages and hooks without copying route/sidebar boilerplate into each app
72
+ - manifest-backed nav items merged with app-owned nav
73
+ - automatic shared sidebar dispatch for manifests that define both routes and a sidebar
74
+ - shared pages and hooks without copying the same subshell wiring into each app
42
75
 
43
- Current packaged feature subpaths include Lead Gen, CRM, Projects, Operations, Monitoring, Dashboard, Settings, and SEO. During rollout, some symbols may still be aliased from `@elevasis/ui/components`, but new imports should prefer `@elevasis/ui/features/<name>`.
76
+ Dashboard is not part of that shared manifest shell by default. `@elevasis/ui/features/dashboard` exports reusable dashboard components, but it does not publish a `dashboardManifest`.
44
77
 
45
78
  ---
46
79
 
47
80
  ## Contract Matrix
48
81
 
49
- This is the actual contract split today, not an idealized one:
82
+ This is the published contract split in `@elevasis/ui@2.7.0`:
50
83
 
51
- | System | Primary UI import | API | SDK CLI | Runtime tools |
52
- | ------ | ----------------- | --- | ------- | ------------- |
53
- | Lead Gen | `@elevasis/ui/features/lead-gen` | Yes | No first-class `elevasis-sdk` surface | Yes |
54
- | CRM | `@elevasis/ui/features/crm` | Yes, but thinner than Lead Gen and Projects | No | Indirectly, through acquisition/deal surfaces |
55
- | Projects | `@elevasis/ui/features/delivery` | Yes | Yes | No dedicated runtime adapter |
84
+ | Contract type | What is published | Current examples |
85
+ | ------------- | ----------------- | ---------------- |
86
+ | Manifest-backed shared subshell features | Feature manifest plus shared sidebar/pages, mounted through `@elevasis/ui/provider` | Lead Gen, CRM, Projects, Operations, SEO |
87
+ | Manifest-backed nav/app sections | Feature manifest contributes gated nav and route metadata, but the host still owns the route pages or shell chrome | Monitoring, Settings |
88
+ | Exported compatibility components | Reusable components exported without a manifest-backed shell contract | Dashboard components such as `Dashboard`, `OperationsOverview`, `ResourceOverview`, `RecentExecutionsByResource`, `UnresolvedErrorsTeaser` |
89
+ | Compatibility barrel | Existing imports remain available from `@elevasis/ui/components`, but new host integrations should prefer feature/provider subpaths | Manifests, sidebars, and page components re-exported for compatibility |
56
90
 
57
- Projects is currently the only one with a first-class `elevasis-sdk project:*` CLI family. Lead Gen and CRM are still primarily UI + API + workflow/runtime surfaces.
91
+ Projects is currently the only packaged system with a first-class `elevasis-sdk project:*` CLI family. Lead Gen and CRM are still primarily UI + API + workflow/runtime surfaces, and browser-facing interactions remain REST-driven even when runtime tools exist.
58
92
 
59
93
  ## System Map
60
94
 
61
95
  | System | Primary route space | Shared UI surface | Main data surface | Best SDK entry point |
62
96
  | ------ | ------------------- | ----------------- | ----------------- | -------------------- |
63
97
  | Lead Gen | `/lead-gen/*` | Lead Gen pages, sidebars, list detail page, run dialogs | Acquisition list APIs + list/acqDb platform tools | `@elevasis/ui/features/lead-gen`, `@elevasis/ui/hooks`, `@elevasis/sdk/worker` |
64
- | CRM | `/crm/*` | CRM sidebar, overview widgets, deal/detail pages, workbench panels | Deal APIs, recent-activity API, and acquisition-backed hooks | `@elevasis/ui/features/crm`, `@elevasis/ui/hooks` |
98
+ | CRM | `/crm/*` | CRM sidebar, overview widgets, deal/detail pages, workbench panels | Deal APIs, recent-activity API, acquisition-backed hooks, and the `crm` runtime adapter | `@elevasis/ui/features/crm`, `@elevasis/ui/hooks`, `@elevasis/sdk/worker` |
65
99
  | Projects | `/projects/*` | Projects list page, milestones/tasks/notes sidebars and pages | Project, milestone, task, note REST endpoints + CLI | `@elevasis/ui/features/delivery`, `@elevasis/ui/hooks/delivery`, `elevasis-sdk project:*` |
100
+ | Dashboard | host-owned | Dashboard and overview components only; no shared manifest-backed nav contract | Host-chosen API composition | `@elevasis/ui/features/dashboard` |
101
+ | Monitoring | `/monitoring/*` | Monitoring nav metadata plus exported pages/components; no shared `FeatureShell` sidebar today | Monitoring REST APIs | `@elevasis/ui/features/monitoring` |
102
+ | Settings | `/settings/*` | Settings nav metadata plus exported settings components; no shared `FeatureShell` sidebar today | Settings/account/org REST APIs | `@elevasis/ui/features/settings` |
66
103
 
67
104
  ---
68
105
 
@@ -173,27 +210,28 @@ The CRM manifest is `crmManifest`, with the route prefix `/crm` and feature-key
173
210
 
174
211
  ### API Surface
175
212
 
176
- CRM is not CLI-first today, but it does have real API-backed behavior.
213
+ CRM is not CLI-first today, but it does have real API-backed behavior and a dedicated runtime adapter for agent/workflow use.
177
214
 
178
215
  Shared CRM pages and hooks currently rely on:
179
216
 
180
217
  - deal list/detail surfaces through the acquisition/deal APIs
181
218
  - `GET /crm/recent-activity` for the overview activity feed
219
+ - the `crm` platform tool for runtime access to deal, task, note, stage, and activity operations
182
220
 
183
- That means downstream users can build against CRM with shared UI and API contracts, but there is not yet a dedicated `elevasis-sdk crm:*` CLI family.
221
+ That means downstream users can build against CRM with shared UI, API, and runtime contracts, but there is not yet a dedicated `elevasis-sdk crm:*` CLI family.
184
222
 
185
223
  ### Practical Guidance
186
224
 
187
225
  - Use the shared CRM pages first; do not rebuild sidebar and overview chrome locally unless the app truly diverges.
188
226
  - Treat CRM overview/workbench components as the canonical packaged surface for downstream apps.
189
227
  - When CRM actions depend on acquisition or delivery state, keep the route shell local and compose the shared packaged widgets inside it.
190
- - Treat CRM as UI + API today, not UI + API + CLI.
228
+ - Treat CRM as UI + API + runtime tools today, with browser interactivity still driven primarily by REST endpoints rather than the platform adapter.
191
229
 
192
230
  ---
193
231
 
194
232
  ## Projects
195
233
 
196
- Projects is the packaged delivery/project-management system. It has both a shared UI surface and a first-class CLI surface in `elevasis-sdk`.
234
+ Projects is the packaged delivery/project-management system. It has both a shared UI surface and a first-class CLI surface in `elevasis-sdk`, plus a dedicated runtime adapter for workflow and agent use.
197
235
 
198
236
  ### Shared UI Surface
199
237
 
@@ -243,7 +281,8 @@ This matters for downstream user agents because project tasks now have a resumab
243
281
 
244
282
  ## Choosing The Right Surface
245
283
 
246
- - Need packaged app navigation or subshell routing? Use `ElevasisFeaturesProvider`, `FeatureShell`, and manifests from `@elevasis/ui/features/<name>`.
284
+ - Need packaged nav contribution or shared subshell routing? Use `ElevasisFeaturesProvider`, `FeatureShell`, and manifests from `@elevasis/ui/features/<name>`.
285
+ - Need a dashboard or landing page in the app root? Keep that route host-owned and compose exported components from `@elevasis/ui/features/dashboard` or `@elevasis/ui/components`.
247
286
  - Need list-scoped lead-gen runtime behavior? Use the `list` adapter, then `acqDb` for broader acquisition CRUD.
248
287
  - Need a custom React page against an existing system? Start with the shared `@elevasis/ui` pages and hooks before writing app-local fetch logic.
249
288
  - Need project/task automation from an agent or terminal workflow? Use `elevasis-sdk project:*`.
@@ -67,7 +67,7 @@ See [Memory System](memory.mdx) for architecture, error tracking format, scaling
67
67
 
68
68
  ### Project Structure
69
69
 
70
- The scaffolded project separates concerns clearly: `src/` for resources, `docs/` for platform documentation, `.claude/` for agent infrastructure, and config files at the root. Understanding which files are gitignored, which are committed, and why matters for collaborating on projects.
70
+ The scaffolded project separates concerns clearly: `src/` for resources, `docs/` for platform documentation, `.claude/` for agent infrastructure, and config files at the root. In the current full-stack template that becomes a small workspace with `ui/`, `operations/`, and `foundations/` packages plus a root `docs/index.md`. Understanding which files are gitignored, which are committed, and why matters for collaborating on projects.
71
71
 
72
72
  See [Project Structure](project-structure.mdx) for a file-by-file walkthrough of the scaffolded project.
73
73
 
@@ -125,7 +125,7 @@ order: number # Sort order within directory (optional, default: 0)
125
125
 
126
126
  ### Naming Conventions
127
127
 
128
- - `docs/index.mdx` is the root page and is always rendered first
128
+ - `docs/index.md` is the root page and is always rendered first
129
129
  - Nested directories create sections: `docs/guides/getting-started.mdx`
130
130
  - File names become URL slugs: `setup-guide.mdx` renders at `/docs/setup-guide`
131
131
  - Arbitrary nesting is supported -- no depth limit
@@ -6,6 +6,8 @@ loadWhen: "Understanding scaffolded files or project layout"
6
6
 
7
7
  `elevasis-sdk init` creates a complete workspace structure. This page explains what each file does and when you will interact with it.
8
8
 
9
+ The current full-stack scaffold uses a workspace layout with `ui/`, `operations/`, `foundations/`, and a root `docs/` directory. When older examples refer to `src/shared/`, read that as the current `foundations/` package for cross-runtime types, schemas, and organization-model configuration.
10
+
9
11
  ---
10
12
 
11
13
  ## Source Files
@@ -42,9 +44,9 @@ A multi-step workflow demonstrating real platform API usage. Calls `platform.cal
42
44
 
43
45
  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
46
 
45
- ### `src/shared/`
47
+ ### `foundations/`
46
48
 
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.
49
+ Cross-runtime types, schemas, constants, and organization-model configuration shared between the UI and operations packages. Put contracts here when both runtimes need the same validation or labels without depending on app-specific code.
48
50
 
49
51
  ### `elevasis.config.ts`
50
52
 
@@ -65,7 +67,7 @@ Leave this file minimal -- the platform provides sensible defaults.
65
67
 
66
68
  ## Documentation
67
69
 
68
- ### `docs/index.mdx`
70
+ ### `docs/index.md`
69
71
 
70
72
  The entry point for your workspace's documentation. Documentation files in `docs/` are deployed alongside your code during `elevasis-sdk deploy` and rendered in the Elevasis platform UI.
71
73
 
@@ -109,7 +111,7 @@ Only `src/` and `docs/` are scaffolded by `elevasis-sdk init`. The following dir
109
111
  | ---------------------- | -------------------------------- | ------------------------------------------------------------------ |
110
112
  | `src/operations/` | `elevasis-sdk init` (default) | Always -- platform-status workflow lives here |
111
113
  | `src/example/` | `elevasis-sdk init` (default) | Always -- echo starter workflow lives here (replace with your own) |
112
- | `src/shared/` | `elevasis-sdk init` (default) | Always -- cross-domain shared utilities (starts empty) |
114
+ | `foundations/` | `elevasis-sdk init` (default) | Always -- cross-runtime contracts, schemas, and organization model |
113
115
  | `docs/` | `elevasis-sdk init` (default) | Always |
114
116
  | `docs/in-progress/` | Agent (on first `/work`) | When you create a task doc for in-progress work |
115
117
  | `docs/project-map.mdx` | `elevasis-sdk deploy` | Auto-generated on every deploy |
@@ -122,7 +124,7 @@ This structure keeps the initial workspace minimal and adds directories only whe
122
124
 
123
125
  ### `src/lib/`
124
126
 
125
- 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.
127
+ Legacy shared code directory. In the current workspace scaffold, prefer the top-level `foundations/` package for cross-runtime contracts. The agent may still create `src/lib/` in older projects that predate the workspace-based layout. Included in the esbuild bundle alongside workflow code.
126
128
 
127
129
  ### `data/`
128
130
 
@@ -240,8 +242,8 @@ Not all scaffolded files participate in template updates. Files fall into two ca
240
242
 
241
243
  - `package.json`, `pnpm-workspace.yaml`, `tsconfig.json`
242
244
  - `.env`, `.npmrc`
243
- - `src/index.ts`, `src/operations/platform-status.ts`, `src/operations/index.ts`, `src/example/echo.ts`, `src/example/index.ts`, `src/shared/.gitkeep`
244
- - `docs/index.mdx`, `docs/in-progress/.gitkeep`
245
+ - `src/index.ts`, `src/operations/platform-status.ts`, `src/operations/index.ts`, `src/example/echo.ts`, `src/example/index.ts`, `foundations/types/index.ts`
246
+ - `docs/index.md`, `docs/in-progress/.gitkeep`
245
247
  - `.claude/rules/workspace-patterns.md`
246
248
 
247
249
  **MANAGED** (18 files) -- Written during `elevasis-sdk init` and checked/updatable by `elevasis-sdk update`:
@@ -263,7 +265,7 @@ Run `elevasis-sdk update` after installing a new SDK version to bring managed fi
263
265
  | ----------------------- | ------------------------------------------------------------------------------ |
264
266
  | `src/index.ts` | Adding or removing resources (the `/resource` command does this automatically) |
265
267
  | `src/<domain>/*.ts` | Writing and modifying workflow logic (organized by business domain) |
266
- | `docs/index.mdx` | Updating project documentation |
268
+ | `docs/index.md` | Updating project documentation |
267
269
  | `docs/project-map.mdx` | Never -- auto-generated by `elevasis-sdk deploy` |
268
270
  | `docs/priorities.mdx` | When goals or priorities change |
269
271
  | `elevasis.config.ts` | Changing project-level settings |
@@ -25,7 +25,7 @@ After `pnpm dlx @elevasis/sdk init`, your project is scaffolded with a working e
25
25
 
26
26
  - **Workflows** -- Step-based automation with typed inputs and outputs. Steps can be linear, conditional, or branching. Each step is a plain async function. See [Resources](resources/index.mdx) for the complete definition API.
27
27
  - **Agents** -- Autonomous AI resources with access to platform tools. Agents run in the worker runtime with full LLM access and platform tool support. Use `--async` when executing agents to avoid HTTP timeout limits on long-running runs.
28
- - **Feature-driven apps** -- Shared Lead Gen, CRM, Projects, Operations, Monitoring, Dashboard, and Settings surfaces are available through `@elevasis/ui`. See [Provided Features](deployment/provided-features.mdx).
28
+ - **Feature-driven apps** -- The published `@elevasis/ui@2.7.0` surface includes manifest-backed shared features for Lead Gen, CRM, Projects, Operations, Monitoring, Settings, and SEO, plus dashboard-oriented compatibility components for host-owned shells. See [Provided Features](deployment/provided-features.mdx).
29
29
 
30
30
  ## Platform Tools
31
31
 
@@ -92,7 +92,7 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog.
92
92
  ### Deployment Subpages
93
93
 
94
94
  - [Command Center](deployment/command-center.mdx) - Resource graph, relationships, node types, and post-deployment UI reference
95
- - [Provided Features](deployment/provided-features.mdx) - Shared Lead Gen, CRM, Projects, feature manifests, and downstream app wiring
95
+ - [Provided Features](deployment/provided-features.mdx) - Manifest-backed shared features, compatibility components, and host shell wiring
96
96
  - [Execution API](deployment/api.mdx) - REST endpoints for executing resources and managing deployments
97
97
 
98
98
  ### More
@@ -102,4 +102,4 @@ See [Platform Tools](platform-tools/index.mdx) for the full catalog.
102
102
 
103
103
  ---
104
104
 
105
- **Last Updated:** 2026-04-15
105
+ **Last Updated:** 2026-04-16
@@ -33,7 +33,7 @@ Top-level fields:
33
33
 
34
34
  - `domains` - semantic domain entries that bind entity IDs, surface IDs, resource IDs, and capability IDs.
35
35
  - `branding` - organization branding defaults and overrides.
36
- - `features` - feature flags and labels for the shell.
36
+ - `features` - grouped shell-level feature flags and labels.
37
37
  - `navigation` - navigation model for the product shell.
38
38
  - `crm` - CRM-specific contract data.
39
39
  - `leadGen` - lead generation contract data.
@@ -51,29 +51,44 @@ The default model includes four semantic domains:
51
51
 
52
52
  ## Feature Keys
53
53
 
54
- The current feature keys are:
54
+ The current canonical feature keys are grouped shell features:
55
55
 
56
56
  - `acquisition`
57
57
  - `delivery`
58
58
  - `operations`
59
59
  - `monitoring`
60
60
  - `settings`
61
- - `seo`
62
61
  - `calibration`
62
+ - `seo`
63
63
 
64
64
  Each feature can carry an enabled flag and an optional label override.
65
65
 
66
+ This is intentionally different from the domain and surface vocabulary:
67
+
68
+ - domains and surface IDs still use IDs such as `crm`, `lead-gen`, and `projects.index`
69
+ - navigation surfaces point those routes at grouped `featureKey` values such as `acquisition` and `delivery`
70
+ - downstream apps may still carry compatibility aliases for legacy route-level keys, but the published organization-model contract does not
71
+
66
72
  ## Resolution Semantics
67
73
 
68
74
  - `defineOrganizationModel()` is a typed helper. It does not validate or merge anything by itself.
69
75
  - `resolveOrganizationModel()` deep-merges a partial override into the default model, then validates the result with `OrganizationModelSchema`.
70
76
  - Plain objects merge recursively.
71
77
  - Arrays replace the default value instead of merging element-by-element.
78
+ - If `navigation.surfaces` is replaced without also supplying `navigation.groups`, inherited default groups are dropped when they no longer point at declared surfaces.
72
79
  - Missing fields fall back to `DEFAULT_ORGANIZATION_MODEL`.
73
80
 
81
+ ## Referential Integrity
82
+
83
+ - `navigation.defaultSurfaceId` must point at a declared navigation surface.
84
+ - Every navigation group `surfaceId` must resolve to a declared surface.
85
+ - Domain, surface, and resource-mapping IDs must resolve to declared counterparts; dangling references fail validation.
86
+ - Domain-to-surface and domain/surface-to-resource links are validated in both directions so one-sided declarations fail during resolution.
87
+ - Feature-bearing surfaces validate `featureKey` against the canonical grouped feature set.
88
+
74
89
  ## Practical Guidance
75
90
 
76
91
  - Use `resolveOrganizationModel()` when you need a runtime-safe model for rendering or policy checks.
77
92
  - Use `defineOrganizationModel()` when authoring a static partial model in source.
93
+ - Treat `features.enabled` and `features.labels` as the shell-level contract; do not use `crm`, `lead-gen`, or `projects` as canonical feature keys in new organization-model authoring.
78
94
  - Keep domain IDs, surface IDs, and capability IDs stable because downstream UI and policy code depend on them.
79
-