@elevasis/sdk 1.23.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/cli.cjs +5927 -6985
  2. package/dist/index.d.ts +4893 -4759
  3. package/dist/index.js +1444 -3870
  4. package/dist/node/index.d.ts +3059 -2
  5. package/dist/node/index.js +163 -1
  6. package/dist/test-utils/index.d.ts +4413 -4439
  7. package/dist/test-utils/index.js +1766 -4753
  8. package/dist/types/worker/index.d.ts +5 -2
  9. package/dist/types/worker/platform.d.ts +2 -2
  10. package/dist/types/worker/utils.d.ts +9 -0
  11. package/dist/worker/index.js +427 -3708
  12. package/package.json +5 -4
  13. package/reference/_navigation.md +1 -0
  14. package/reference/claude-config/rules/active-change-index.md +11 -80
  15. package/reference/claude-config/rules/agent-start-here.md +11 -277
  16. package/reference/claude-config/rules/deployment.md +11 -57
  17. package/reference/claude-config/rules/error-handling.md +11 -56
  18. package/reference/claude-config/rules/execution.md +11 -40
  19. package/reference/claude-config/rules/frontend.md +11 -43
  20. package/reference/claude-config/rules/observability.md +11 -31
  21. package/reference/claude-config/rules/operations.md +11 -80
  22. package/reference/claude-config/rules/organization-model.md +5 -110
  23. package/reference/claude-config/rules/organization-os.md +7 -111
  24. package/reference/claude-config/rules/package-taxonomy.md +11 -33
  25. package/reference/claude-config/rules/platform.md +11 -42
  26. package/reference/claude-config/rules/shared-types.md +10 -48
  27. package/reference/claude-config/rules/task-tracking.md +11 -47
  28. package/reference/claude-config/rules/ui.md +11 -200
  29. package/reference/claude-config/rules/vibe.md +5 -229
  30. package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
  31. package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +2 -2
  32. package/reference/claude-config/sync-notes/2026-05-17-sdk-boundary-consolidation.md +33 -0
  33. package/reference/cli.mdx +1107 -808
  34. package/reference/rules/active-change-index.md +83 -0
  35. package/reference/rules/agent-start-here.md +280 -0
  36. package/reference/rules/deployment.md +60 -0
  37. package/reference/rules/error-handling.md +59 -0
  38. package/reference/rules/execution.md +43 -0
  39. package/reference/rules/frontend.md +46 -0
  40. package/reference/rules/observability.md +34 -0
  41. package/reference/rules/operations.md +85 -0
  42. package/reference/rules/organization-model.md +119 -0
  43. package/reference/rules/organization-os.md +118 -0
  44. package/reference/rules/package-taxonomy.md +36 -0
  45. package/reference/rules/platform.md +45 -0
  46. package/reference/rules/shared-types.md +52 -0
  47. package/reference/rules/task-tracking.md +50 -0
  48. package/reference/rules/ui.md +203 -0
  49. package/reference/rules/vibe.md +238 -0
  50. package/reference/scaffold/core/organization-graph.mdx +4 -5
  51. package/reference/scaffold/core/organization-model.mdx +1 -1
  52. package/reference/scaffold/recipes/customize-crm-actions.md +45 -46
  53. package/reference/scaffold/recipes/extend-crm.md +253 -255
  54. package/reference/scaffold/recipes/index.md +43 -44
  55. package/reference/scaffold/reference/contracts.md +990 -1065
@@ -1,258 +1,256 @@
1
1
  <!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
2
2
  <!-- Regenerate: pnpm scaffold:sync -->
3
3
 
4
- ---
5
- title: Build and Extend CRM
6
- description: Map the CRM platform primitives available to SDK projects: shared UI pages, sidebar composition, data hooks, action definitions, workflow adapters, contracts, and org-model extension boundaries.
7
- ---
8
-
9
- # Build and Extend CRM
10
-
11
- Use this recipe when a downstream project wants to build on the shared CRM instead of forking it.
12
-
13
- Good trigger phrases:
14
-
15
- - "Add a CRM reports page."
16
- - "Build a custom deal workspace."
17
- - "Read and update deals from a workflow."
18
- - "Add a Send Quote button."
19
- - "Change the CRM pipeline stages for this business."
20
-
21
- CRM is a layered platform surface, not one component:
22
-
23
- - **Organization OS:** System access, sales pipeline semantics, quick access, and labels live in the organization model.
24
- - **Shared UI:** CRM pages, sidebars, workbench panels, overview widgets, and Kanban/detail components live in `@elevasis/ui`.
25
- - **Headless hooks:** deal, company, contact, note, task, list, transition, and action hooks live under `@elevasis/ui/hooks`.
26
- - **Action system:** `ActionDef`, `DEFAULT_CRM_ACTIONS`, `deriveActions`, and provider-level `crmActions` configure deal actions.
27
- - **Workflow adapters:** `crm` and `acqDb` from `@elevasis/sdk/worker` let workflows read and mutate CRM/acquisition data through platform tools.
28
- - **Contracts:** generated contract docs expose the current CRM shapes in `node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`.
29
-
30
- ## Decision Table
31
-
32
- | User wants | Start here | Notes |
33
- | --- | --- | --- |
34
- | Change CRM System availability, labels, pipeline stages, or resource descriptors | `core/config/organization-model.ts` | Treat this as Organization OS work. Use the project's configure ceremony if available. |
35
- | Add CRM sidebar nav or a CRM route | `@elevasis/ui/features/crm` and `node_modules/@elevasis/sdk/reference/scaffold/ui/customization.md` | Prefer manifest/sidebar composition. Do not fork shared source first. |
36
- | Wrap a shared CRM page with project chrome | `DealsListPage`, `DealDetailPage`, `CrmOverview` from `@elevasis/ui/features/crm` | Keep route files thin and put project-specific logic in local feature modules. |
37
- | Build a custom deal page | `useDealDetail`, `useDealNotes`, `useDealTasks`, `useExecuteAction` from `@elevasis/ui/hooks` | Use hooks for platform data and compose your own UI. |
38
- | Add, hide, or replace deal action buttons | [customize-crm-actions.md](customize-crm-actions.md) | Start with the shared `crmActions` provider path; use project-owned UI when a custom workflow path is outside platform-known/default action dispatch constraints. |
39
- | Read or mutate CRM data inside a workflow | `crm` or `acqDb` from `@elevasis/sdk/worker` | `organizationId` is injected server-side by the platform dispatcher. Do not pass it from workflow code. |
40
- | Add a new persisted CRM column or table | Platform/API migration work, not just scaffold work | Update DB, core schemas/types, API service/handlers, hooks, docs, and scaffold contracts together. |
41
-
42
- ## Published CRM Surfaces
43
-
44
- | Surface | Import from | Use for |
45
- | --- | --- | --- |
46
- | `crmManifest`, `CRM_ITEMS`, `CrmSidebar`, `CrmSidebarTop`, `CrmSidebarMiddle` | `@elevasis/ui/features/crm` | Feature registration and sidebar composition |
47
- | `CrmOverview`, `DealsListPage`, `DealDetailPage`, `CompanyDetailPage` | `@elevasis/ui/features/crm` | Shared CRM pages you can route to or wrap |
48
- | `MyTasksPanel`, `SavedViewsPanel`, `QuickCreateActions` | `@elevasis/ui/features/crm` | Workbench/sidebar panels for custom CRM sidebars |
49
- | `PipelineFunnelWidget`, `ActivityFeedWidget`, `MetricsStrip` | `@elevasis/ui/features/crm` | Overview widgets for custom dashboards |
50
- | `KanbanBoard`, `DealKanbanCard`, `DealDrawer` | `@elevasis/ui/components` | Lower-level CRM deal UI primitives |
51
- | `useDeals`, `useDealDetail`, `useTransitionItem`, `useExecuteAction`, `useDealNotes`, `useDealTasks` | `@elevasis/ui/hooks` | Headless deal and task data access |
52
- | `useCompanies`, `useContacts`, `useLists`, `useBatchTelemetry` | `@elevasis/ui/hooks` | Acquisition substrate data access |
53
- | `ElevasisUIProvider`, `ElevasisCoreProvider`, `useElevasisServices` | `@elevasis/ui/provider` | Provider setup, API access, and organization context |
54
- | `ActionDef`, `DEFAULT_CRM_ACTIONS`, `deriveActions` | `@elevasis/sdk` | Deal action configuration and render-time derivation |
55
- | `crm`, `acqDb` | `@elevasis/sdk/worker` | Workflow-side CRM/acquisition platform adapters |
56
-
57
- Read the generated contracts before changing typed boundaries:
58
-
59
- `node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`
60
-
61
- Look for the **CRM Platform Primitives** section. It includes deal stages, deal rows, task shapes, API schemas, action definitions, and the focused CRM workflow adapter map. The broader acquisition/list adapter maps live under **Lead Gen Platform Primitives**.
62
-
63
- Deal list and detail responses include a server-derived `priority` object. Use `deal.priority.bucketKey`, `rank`, `label`, `reason`, `latestActivityAt`, and `nextActionAt` when composing custom deal workspaces or workflow-side follow-up logic instead of re-deriving priority from `updated_at`.
64
-
65
- ## 1. Extend CRM Navigation or Sidebar
66
-
67
- For a simple nav addition, extend `CRM_ITEMS` and override the CRM system manifest:
68
-
69
- ```tsx
70
- // ui/src/routes/__root.tsx
71
- import { crmManifest, CRM_ITEMS, CrmSidebar, CrmSidebarMiddle } from '@elevasis/ui/features/crm'
72
- import type { SystemModule } from '@elevasis/ui/provider'
73
- import type { NavItem } from '@elevasis/ui/layout'
74
- import { IconFileText } from '@tabler/icons-react'
75
-
76
- const customCrmItems: NavItem[] = [
77
- ...CRM_ITEMS,
78
- { label: 'Reports', to: '/crm/reports', icon: IconFileText, exact: false }
79
- ]
80
-
81
- const CustomCrmSidebar = () => (
82
- <CrmSidebar>
83
- <CrmSidebarMiddle items={customCrmItems} />
84
- </CrmSidebar>
85
- )
86
-
87
- export const customCrmManifest: SystemModule = {
88
- ...crmManifest,
89
- sidebar: CustomCrmSidebar
90
- }
91
- ```
92
-
93
- Then replace `crmManifest` with `customCrmManifest` in the local `SYSTEM_MANIFESTS` array and add the matching route under `ui/src/routes/crm/`.
94
-
95
- For structural changes, compose `CrmSidebarTop`, `SubshellNavList`, `SubshellSidebarSection`, `MyTasksPanel`, and `QuickCreateActions`. The full sidebar decision tree lives in `node_modules/@elevasis/sdk/reference/scaffold/ui/customization.md`.
96
-
97
- ## 2. Wrap Shared CRM Pages
98
-
99
- If the shared page is close, keep it and wrap it:
100
-
101
- ```tsx
102
- // ui/src/routes/crm/deals.index.tsx
103
- import { createFileRoute } from '@tanstack/react-router'
104
- import { DealsListPage } from '@elevasis/ui/features/crm'
105
- import { Stack } from '@mantine/core'
106
- import { ProjectAnnouncementBanner } from '@/lib/components/ProjectAnnouncementBanner'
107
-
108
- export const Route = createFileRoute('/crm/deals/')({
109
- component: DealsRoute
110
- })
111
-
112
- function DealsRoute() {
113
- return (
114
- <Stack gap={0}>
115
- <ProjectAnnouncementBanner context="crm-deals" />
116
- <DealsListPage />
117
- </Stack>
118
- )
119
- }
120
- ```
121
-
122
- Use the same pattern for `CrmOverview`, `DealDetailPage`, and `CompanyDetailPage`.
123
-
124
- ## 3. Build a Custom Deal Page
125
-
126
- When the project needs custom layout or additional workflows, use the hooks directly:
127
-
128
- ```tsx
129
- import { Button, Group, Stack, Textarea } from '@mantine/core'
130
- import { useState } from 'react'
131
- import { useDealDetail, useDealNotes, useCreateDealNote, useExecuteAction } from '@elevasis/ui/hooks'
132
-
133
- export function CustomDealWorkspace({ dealId }: { dealId: string }) {
134
- const { data: deal, isLoading } = useDealDetail(dealId)
135
- const { data: notes = [] } = useDealNotes(dealId)
136
- const createNote = useCreateDealNote()
137
- const executeAction = useExecuteAction({ dealId })
138
- const [body, setBody] = useState('')
139
-
140
- if (isLoading) return null
141
- if (!deal) return <div>Deal not found</div>
142
-
143
- return (
144
- <Stack>
145
- <h1>{deal.contact_email}</h1>
146
- <Group>
147
- <Button onClick={() => executeAction.mutate({ key: 'move_to_proposal' })}>
148
- Move to Proposal
149
- </Button>
150
- </Group>
151
- <Textarea value={body} onChange={(event) => setBody(event.currentTarget.value)} />
152
- <Button onClick={() => createNote.mutate({ dealId, body })}>Add Note</Button>
153
- <pre>{JSON.stringify(notes, null, 2)}</pre>
154
- </Stack>
155
- )
156
- }
157
- ```
158
-
159
- `useExecuteAction` is for platform-known/default action keys. Start custom action UI with the shared `crmActions` provider path; when a project-owned workflow is outside that server-dispatched action set, call `/execute` or `/execute-async` through `useElevasisServices`, or follow [customize-crm-actions.md](customize-crm-actions.md).
160
-
161
- ## 4. Read and Mutate CRM Data in Workflows
162
-
163
- Inside deployed workflows, use worker adapters instead of browser hooks or direct database access:
164
-
165
- ```ts
166
- // operations/src/sales/follow-up-stale-deals.ts
167
- import type { WorkflowDefinition } from '@elevasis/sdk'
168
- import { crm } from '@elevasis/sdk/worker'
169
- import { resourceDescriptors } from '@core/config/organization-model'
170
- import { z } from 'zod'
171
-
172
- const inputSchema = z.object({
173
- stage: z.string().default('proposal')
174
- })
175
-
176
- const outputSchema = z.object({
177
- touched: z.number()
178
- })
179
-
180
- export const followUpStaleDealsWorkflow: WorkflowDefinition = {
181
- config: {
182
- resource: resourceDescriptors.followUpStaleDeals,
183
- resourceId: resourceDescriptors.followUpStaleDeals.id,
184
- name: 'Follow Up Stale Deals',
185
- type: resourceDescriptors.followUpStaleDeals.kind,
186
- version: '1.0.0',
187
- status: 'dev',
188
- },
189
- contract: { inputSchema, outputSchema },
190
- steps: {
191
- followUp: {
192
- id: 'followUp',
193
- name: 'Follow Up',
194
- inputSchema,
195
- outputSchema,
196
- next: null,
197
- handler: async (input) => {
198
- const deals = await crm.listDeals({ stage: input.stage })
199
-
200
- for (const deal of deals) {
201
- if (!['follow_up_due', 'stale'].includes(deal.priority.bucketKey)) continue
202
-
203
- await crm.createDealTask({
204
- dealId: deal.id,
205
- title: 'Follow up',
206
- kind: 'email'
207
- })
208
- await crm.recordActivity({
209
- dealId: deal.id,
210
- type: 'workflow.follow_up_task_created',
211
- title: 'Follow-up task created',
212
- payload: { workflow: 'follow-up-stale-deals' }
213
- })
214
- }
215
-
216
- return { touched: deals.length }
217
- }
218
- }
219
- },
220
- entryPoint: 'followUp'
221
- }
222
- ```
223
-
224
- Use `crm` for focused CRM deal reads, notes, tasks, activity, and cleanup. Use `acqDb` when the workflow needs the broader acquisition substrate: companies, contacts, lists, list-stage transitions, enrichment data, social posts, or lower-level deal sync methods.
225
-
226
- ## 5. Customize Pipeline Semantics
227
-
228
- CRM System identity is `sales.crm`, but the organization-model domain is `sales`.
229
-
230
- For stage labels or stage sets, update the project model:
231
-
232
- `core/config/organization-model.ts`
233
-
234
- Keep these boundaries straight:
235
-
236
- - Org-model sales pipelines describe business semantics.
237
- - `DealStage` and platform action defaults describe the current shared platform deal state vocabulary.
238
- - UI wrappers can relabel and route around shared surfaces, but changing persisted platform stages requires coordinated core/API/UI updates.
239
- - Do not add `sales.actions` to the org model in v1. Deal action customization is covered by [customize-crm-actions.md](customize-crm-actions.md).
240
-
241
- ## Verify
242
-
243
- Run the checks for the surfaces you touched:
244
-
245
- ```bash
246
- pnpm -C ui run check
247
- pnpm -C operations run check
248
- pnpm -C operations exec elevasis-sdk check
249
- ```
250
-
251
- If you changed platform-level CRM contracts in the monorepo, the platform maintainer must also regenerate and verify scaffold output:
252
-
253
- ```bash
254
- pnpm scaffold:sync
255
- pnpm scaffold:verify
256
- ```
257
-
258
-
4
+ ---
5
+ title: Build and Extend CRM
6
+ description: Map the CRM platform primitives available to SDK projects: shared UI pages, sidebar composition, data hooks, action definitions, workflow adapters, contracts, and org-model extension boundaries.
7
+ ---
8
+
9
+ # Build and Extend CRM
10
+
11
+ Use this recipe when a downstream project wants to build on the shared CRM instead of forking it.
12
+
13
+ Good trigger phrases:
14
+
15
+ - "Add a CRM reports page."
16
+ - "Build a custom deal workspace."
17
+ - "Read and update deals from a workflow."
18
+ - "Add a Send Quote button."
19
+ - "Change the CRM pipeline stages for this business."
20
+
21
+ CRM is a layered platform surface, not one component:
22
+
23
+ - **Organization OS:** System access, sales pipeline semantics, quick access, and labels live in the organization model.
24
+ - **Shared UI:** CRM pages, sidebars, workbench panels, overview widgets, and Kanban/detail components live in `@elevasis/ui`.
25
+ - **Headless hooks:** deal, company, contact, note, task, list, transition, and action hooks live under `@elevasis/ui/hooks`.
26
+ - **Action system:** `ActionDef`, `deriveActions`, and the caller-supplied provider-level `crmActions` catalog configure deal actions. The published `@elevasis/sdk` surface ships no default Elevasis action catalog -- projects supply their own `ActionDef[]`.
27
+ - **Workflow adapters:** `crm` and `acqDb` from `@elevasis/sdk/worker` let workflows read and mutate CRM/acquisition data through platform tools.
28
+ - **Contracts:** generated contract docs expose the current CRM shapes in `node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`.
29
+
30
+ ## Decision Table
31
+
32
+ | User wants | Start here | Notes |
33
+ | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
34
+ | Change CRM System availability, labels, pipeline stages, or resource descriptors | `core/config/organization-model.ts` | Treat this as Organization OS work. Use the project's configure ceremony if available. |
35
+ | Add CRM sidebar nav or a CRM route | `@elevasis/ui/features/crm` and `node_modules/@elevasis/sdk/reference/scaffold/ui/customization.md` | Prefer manifest/sidebar composition. Do not fork shared source first. |
36
+ | Wrap a shared CRM page with project chrome | `DealsListPage`, `DealDetailPage`, `CrmOverview` from `@elevasis/ui/features/crm` | Keep route files thin and put project-specific logic in local feature modules. |
37
+ | Build a custom deal page | `useDealDetail`, `useDealNotes`, `useDealTasks`, `useExecuteAction` from `@elevasis/ui/hooks` | Use hooks for platform data and compose your own UI. |
38
+ | Add, hide, or replace deal action buttons | [customize-crm-actions.md](customize-crm-actions.md) | Start with the shared `crmActions` provider path; use project-owned UI when a custom workflow path is outside platform-known/default action dispatch constraints. |
39
+ | Read or mutate CRM data inside a workflow | `crm` or `acqDb` from `@elevasis/sdk/worker` | `organizationId` is injected server-side by the platform dispatcher. Do not pass it from workflow code. |
40
+ | Add a new persisted CRM column or table | Platform/API migration work, not just scaffold work | Update DB, core schemas/types, API service/handlers, hooks, docs, and scaffold contracts together. |
41
+
42
+ ## Published CRM Surfaces
43
+
44
+ | Surface | Import from | Use for |
45
+ | ---------------------------------------------------------------------------------------------------- | --------------------------- | ---------------------------------------------------- |
46
+ | `crmManifest`, `CRM_ITEMS`, `CrmSidebar`, `CrmSidebarTop`, `CrmSidebarMiddle` | `@elevasis/ui/features/crm` | Feature registration and sidebar composition |
47
+ | `CrmOverview`, `DealsListPage`, `DealDetailPage`, `CompanyDetailPage` | `@elevasis/ui/features/crm` | Shared CRM pages you can route to or wrap |
48
+ | `MyTasksPanel`, `SavedViewsPanel`, `QuickCreateActions` | `@elevasis/ui/features/crm` | Workbench/sidebar panels for custom CRM sidebars |
49
+ | `PipelineFunnelWidget`, `ActivityFeedWidget`, `MetricsStrip` | `@elevasis/ui/features/crm` | Overview widgets for custom dashboards |
50
+ | `KanbanBoard`, `DealKanbanCard`, `DealDrawer` | `@elevasis/ui/components` | Lower-level CRM deal UI primitives |
51
+ | `useDeals`, `useDealDetail`, `useTransitionItem`, `useExecuteAction`, `useDealNotes`, `useDealTasks` | `@elevasis/ui/hooks` | Headless deal and task data access |
52
+ | `useCompanies`, `useContacts`, `useLists`, `useBatchTelemetry` | `@elevasis/ui/hooks` | Acquisition substrate data access |
53
+ | `ElevasisUIProvider`, `ElevasisCoreProvider`, `useElevasisServices` | `@elevasis/ui/provider` | Provider setup, API access, and organization context |
54
+ | `ActionDef`, `deriveActions` | `@elevasis/sdk` | Deal action configuration and render-time derivation |
55
+ | `crm`, `acqDb` | `@elevasis/sdk/worker` | Workflow-side CRM/acquisition platform adapters |
56
+
57
+ Read the generated contracts before changing typed boundaries:
58
+
59
+ `node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`
60
+
61
+ Look for the **CRM Platform Primitives** section. It includes deal stages, deal rows, task shapes, API schemas, action definitions, and the focused CRM workflow adapter map. The broader acquisition/list adapter maps live under **Lead Gen Platform Primitives**.
62
+
63
+ Deal list and detail responses include a server-derived `priority` object. Use `deal.priority.bucketKey`, `rank`, `label`, `reason`, `latestActivityAt`, and `nextActionAt` when composing custom deal workspaces or workflow-side follow-up logic instead of re-deriving priority from `updated_at`.
64
+
65
+ ## 1. Extend CRM Navigation or Sidebar
66
+
67
+ For a simple nav addition, extend `CRM_ITEMS` and override the CRM system manifest:
68
+
69
+ ```tsx
70
+ // ui/src/routes/__root.tsx
71
+ import { crmManifest, CRM_ITEMS, CrmSidebar, CrmSidebarMiddle } from '@elevasis/ui/features/crm'
72
+ import type { SystemModule } from '@elevasis/ui/provider'
73
+ import type { NavItem } from '@elevasis/ui/layout'
74
+ import { IconFileText } from '@tabler/icons-react'
75
+
76
+ const customCrmItems: NavItem[] = [
77
+ ...CRM_ITEMS,
78
+ { label: 'Reports', to: '/crm/reports', icon: IconFileText, exact: false }
79
+ ]
80
+
81
+ const CustomCrmSidebar = () => (
82
+ <CrmSidebar>
83
+ <CrmSidebarMiddle items={customCrmItems} />
84
+ </CrmSidebar>
85
+ )
86
+
87
+ export const customCrmManifest: SystemModule = {
88
+ ...crmManifest,
89
+ sidebar: CustomCrmSidebar
90
+ }
91
+ ```
92
+
93
+ Then replace `crmManifest` with `customCrmManifest` in the local `SYSTEM_MANIFESTS` array and add the matching route under `ui/src/routes/crm/`.
94
+
95
+ For structural changes, compose `CrmSidebarTop`, `SubshellNavList`, `SubshellSidebarSection`, `MyTasksPanel`, and `QuickCreateActions`. The full sidebar decision tree lives in `node_modules/@elevasis/sdk/reference/scaffold/ui/customization.md`.
96
+
97
+ ## 2. Wrap Shared CRM Pages
98
+
99
+ If the shared page is close, keep it and wrap it:
100
+
101
+ ```tsx
102
+ // ui/src/routes/crm/deals.index.tsx
103
+ import { createFileRoute } from '@tanstack/react-router'
104
+ import { DealsListPage } from '@elevasis/ui/features/crm'
105
+ import { Stack } from '@mantine/core'
106
+ import { ProjectAnnouncementBanner } from '@/lib/components/ProjectAnnouncementBanner'
107
+
108
+ export const Route = createFileRoute('/crm/deals/')({
109
+ component: DealsRoute
110
+ })
111
+
112
+ function DealsRoute() {
113
+ return (
114
+ <Stack gap={0}>
115
+ <ProjectAnnouncementBanner context="crm-deals" />
116
+ <DealsListPage />
117
+ </Stack>
118
+ )
119
+ }
120
+ ```
121
+
122
+ Use the same pattern for `CrmOverview`, `DealDetailPage`, and `CompanyDetailPage`.
123
+
124
+ ## 3. Build a Custom Deal Page
125
+
126
+ When the project needs custom layout or additional workflows, use the hooks directly:
127
+
128
+ ```tsx
129
+ import { Button, Group, Stack, Textarea } from '@mantine/core'
130
+ import { useState } from 'react'
131
+ import { useDealDetail, useDealNotes, useCreateDealNote, useExecuteAction } from '@elevasis/ui/hooks'
132
+
133
+ export function CustomDealWorkspace({ dealId }: { dealId: string }) {
134
+ const { data: deal, isLoading } = useDealDetail(dealId)
135
+ const { data: notes = [] } = useDealNotes(dealId)
136
+ const createNote = useCreateDealNote()
137
+ const executeAction = useExecuteAction({ dealId })
138
+ const [body, setBody] = useState('')
139
+
140
+ if (isLoading) return null
141
+ if (!deal) return <div>Deal not found</div>
142
+
143
+ return (
144
+ <Stack>
145
+ <h1>{deal.contact_email}</h1>
146
+ <Group>
147
+ <Button onClick={() => executeAction.mutate({ key: 'move_to_proposal' })}>
148
+ Move to Proposal
149
+ </Button>
150
+ </Group>
151
+ <Textarea value={body} onChange={(event) => setBody(event.currentTarget.value)} />
152
+ <Button onClick={() => createNote.mutate({ dealId, body })}>Add Note</Button>
153
+ <pre>{JSON.stringify(notes, null, 2)}</pre>
154
+ </Stack>
155
+ )
156
+ }
157
+ ```
158
+
159
+ `useExecuteAction` is for platform-known/default action keys. Start custom action UI with the shared `crmActions` provider path; when a project-owned workflow is outside that server-dispatched action set, call `/execute` or `/execute-async` through `useElevasisServices`, or follow [customize-crm-actions.md](customize-crm-actions.md).
160
+
161
+ ## 4. Read and Mutate CRM Data in Workflows
162
+
163
+ Inside deployed workflows, use worker adapters instead of browser hooks or direct database access:
164
+
165
+ ```ts
166
+ // operations/src/sales/follow-up-stale-deals.ts
167
+ import type { WorkflowDefinition } from '@elevasis/sdk'
168
+ import { crm } from '@elevasis/sdk/worker'
169
+ import { resourceDescriptors } from '@core/config/organization-model'
170
+ import { z } from 'zod'
171
+
172
+ const inputSchema = z.object({
173
+ stage: z.string().default('proposal')
174
+ })
175
+
176
+ const outputSchema = z.object({
177
+ touched: z.number()
178
+ })
179
+
180
+ export const followUpStaleDealsWorkflow: WorkflowDefinition = {
181
+ config: {
182
+ resource: resourceDescriptors.followUpStaleDeals,
183
+ resourceId: resourceDescriptors.followUpStaleDeals.id,
184
+ name: 'Follow Up Stale Deals',
185
+ type: resourceDescriptors.followUpStaleDeals.kind,
186
+ version: '1.0.0',
187
+ status: 'dev',
188
+ },
189
+ contract: { inputSchema, outputSchema },
190
+ steps: {
191
+ followUp: {
192
+ id: 'followUp',
193
+ name: 'Follow Up',
194
+ inputSchema,
195
+ outputSchema,
196
+ next: null,
197
+ handler: async (input) => {
198
+ const deals = await crm.listDeals({ stage: input.stage })
199
+
200
+ for (const deal of deals) {
201
+ if (!['follow_up_due', 'stale'].includes(deal.priority.bucketKey)) continue
202
+
203
+ await crm.createDealTask({
204
+ dealId: deal.id,
205
+ title: 'Follow up',
206
+ kind: 'email'
207
+ })
208
+ await crm.recordActivity({
209
+ dealId: deal.id,
210
+ type: 'workflow.follow_up_task_created',
211
+ title: 'Follow-up task created',
212
+ payload: { workflow: 'follow-up-stale-deals' }
213
+ })
214
+ }
215
+
216
+ return { touched: deals.length }
217
+ }
218
+ }
219
+ },
220
+ entryPoint: 'followUp'
221
+ }
222
+ ```
223
+
224
+ Use `crm` for focused CRM deal reads, notes, tasks, activity, and cleanup. Use `acqDb` when the workflow needs the broader acquisition substrate: companies, contacts, lists, list-stage transitions, enrichment data, social posts, or lower-level deal sync methods.
225
+
226
+ ## 5. Customize Pipeline Semantics
227
+
228
+ CRM System identity is `sales.crm`, but the organization-model domain is `sales`.
229
+
230
+ For stage labels or stage sets, update the project model:
231
+
232
+ `core/config/organization-model.ts`
233
+
234
+ Keep these boundaries straight:
235
+
236
+ - Org-model sales pipelines describe business semantics.
237
+ - `DealStage` and platform action defaults describe the current shared platform deal state vocabulary.
238
+ - UI wrappers can relabel and route around shared surfaces, but changing persisted platform stages requires coordinated core/API/UI updates.
239
+ - Do not add `sales.actions` to the org model in v1. Deal action customization is covered by [customize-crm-actions.md](customize-crm-actions.md).
240
+
241
+ ## Verify
242
+
243
+ Run the checks for the surfaces you touched:
244
+
245
+ ```bash
246
+ pnpm -C ui run check
247
+ pnpm -C operations run check
248
+ pnpm -C operations exec elevasis-sdk check
249
+ ```
250
+
251
+ If you changed platform-level CRM contracts in the monorepo, the platform maintainer must also regenerate and verify scaffold output:
252
+
253
+ ```bash
254
+ pnpm scaffold:sync
255
+ pnpm scaffold:verify
256
+ ```
@@ -1,51 +1,50 @@
1
1
  <!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
2
2
  <!-- Regenerate: pnpm scaffold:sync -->
3
3
 
4
- ---
5
- title: Pathway Recipes
6
- description: Terse end-to-end walkthroughs for the three most common authoring tasks -- adding a system, adding a resource, and gating access.
7
- ---
8
-
9
- # Pathway Recipes
10
-
11
- Three sequential walkthroughs for common authoring tasks. Each recipe links into the reference docs rather than duplicating them.
12
-
13
- Before starting, read [glossary.md](../reference/glossary.md) to disambiguate overloaded terms (System, Resource, systemId, Settings asymmetry, Topology).
14
-
15
- ---
16
-
17
- ## Recipes
18
-
4
+ ---
5
+ title: Pathway Recipes
6
+ description: Terse end-to-end walkthroughs for the three most common authoring tasks -- adding a system, adding a resource, and gating access.
7
+ ---
8
+
9
+ # Pathway Recipes
10
+
11
+ Three sequential walkthroughs for common authoring tasks. Each recipe links into the reference docs rather than duplicating them.
12
+
13
+ Before starting, read [glossary.md](../reference/glossary.md) to disambiguate overloaded terms (System, Resource, systemId, Settings asymmetry, Topology).
14
+
15
+ ---
16
+
17
+ ## Recipes
18
+
19
19
  **[Add an OM-Backed System](add-a-feature.md)**
20
20
  You want a new system with cohesive Organization Model semantics, executable resources, and optional UI. Covers Systems, System-owned ontology and config, Resource descriptors with `title`, `description`, `resource.ontology.actions`, `primaryAction`, `codeRefs`, OM topology, runtime assembly, manifests, routes, guards, tests, and compatibility notes for old `System.content` consumers.
21
-
22
- **[Add a Resource](add-a-resource.md)**
23
- You want a new workflow or agent deployed to the platform. Covers OM Resource descriptor authoring, descriptor-backed `WorkflowDefinition` binding, `DeploymentSpec` assembly, relationship declarations, and CLI verification.
24
-
25
- **[Gate by System or Admin](gate-by-feature-or-admin.md)**
26
- You want to restrict a route, nav item, or UI element by system flag or admin role. Covers the decision table, `SystemGuard`, `AdminGuard`, nav-entry visibility fields, per-member system overrides, and the settings-asymmetry gotcha.
27
-
28
- **[Build and Extend CRM](extend-crm.md)**
29
- You want to build on the shared CRM without forking it: add CRM routes, compose sidebars/pages, use deal/company/contact hooks, mutate CRM data from workflows, or understand which contracts and adapters form the extension surface.
30
-
31
- **[Build and Extend Lead Gen](extend-lead-gen.md)**
32
- You want to build on the shared lead-gen system without forking it: add lead-gen routes, compose sidebars/pages, use list/company/contact/artifact hooks, mutate list data from workflows, or understand which contracts and adapters form the extension surface.
33
-
34
- **[Customize CRM Actions](customize-crm-actions.md)**
35
- You want to add, hide, or replace CRM deal action buttons, configure the shared `crmActions` provider path, or call a project-owned workflow from custom UI when server-side action dispatch constraints require it. Covers `ActionDef`, `DEFAULT_CRM_ACTIONS`, provider wiring, and the current v1 boundary for custom action dispatch.
36
-
37
- **[Customize Knowledge Browser](customize-knowledge-browser.md)**
38
- You want to mount, extend, or replace the default Knowledge Browser. Covers the three customization tiers (default manifest mount, sidebar composition via `KnowledgeSidebarMiddle` + `KNOWLEDGE_ITEMS`, and direct query access via `@elevasis/core/knowledge`), the one-line `vite.config.ts` plugin add (`knowledgePlugin()` from `@elevasis/ui/vite-plugin-knowledge`), and the CSS import requirement.
39
-
21
+
22
+ **[Add a Resource](add-a-resource.md)**
23
+ You want a new workflow or agent deployed to the platform. Covers OM Resource descriptor authoring, descriptor-backed `WorkflowDefinition` binding, `DeploymentSpec` assembly, relationship declarations, and CLI verification.
24
+
25
+ **[Gate by System or Admin](gate-by-feature-or-admin.md)**
26
+ You want to restrict a route, nav item, or UI element by system flag or admin role. Covers the decision table, `SystemGuard`, `AdminGuard`, nav-entry visibility fields, per-member system overrides, and the settings-asymmetry gotcha.
27
+
28
+ **[Build and Extend CRM](extend-crm.md)**
29
+ You want to build on the shared CRM without forking it: add CRM routes, compose sidebars/pages, use deal/company/contact hooks, mutate CRM data from workflows, or understand which contracts and adapters form the extension surface.
30
+
31
+ **[Build and Extend Lead Gen](extend-lead-gen.md)**
32
+ You want to build on the shared lead-gen system without forking it: add lead-gen routes, compose sidebars/pages, use list/company/contact/artifact hooks, mutate list data from workflows, or understand which contracts and adapters form the extension surface.
33
+
34
+ **[Customize CRM Actions](customize-crm-actions.md)**
35
+ You want to add, hide, or replace CRM deal action buttons, configure the shared `crmActions` provider path, or call a project-owned workflow from custom UI when server-side action dispatch constraints require it. Covers `ActionDef`, the caller-supplied `crmActions` catalog, provider wiring, and the current v1 boundary for custom action dispatch.
36
+
37
+ **[Customize Knowledge Browser](customize-knowledge-browser.md)**
38
+ You want to mount, extend, or replace the default Knowledge Browser. Covers the three customization tiers (default manifest mount, sidebar composition via `KnowledgeSidebarMiddle` + `KNOWLEDGE_ITEMS`, and direct query access via `@elevasis/core/knowledge`), the one-line `vite.config.ts` plugin add (`knowledgePlugin()` from `@elevasis/ui/vite-plugin-knowledge`), and the CSS import requirement.
39
+
40
40
  **[Query the Knowledge Graph](query-the-knowledge-graph.md)**
41
41
  You want to browse, inspect, or traverse the OrganizationModel knowledge graph from the command line. Covers the three verbs (`knowledge:ls`, `knowledge:cat`, `knowledge:graph`), all six mount axes (`/by-system/`, `/by-ontology/`, `/by-kind/`, `/by-owner/`, `/graph/.../governs/`, `/graph/.../governed-by/`), dual-CLI invocation patterns (`elevasis-sdk` for external projects, `elevasis` for the monorepo), JSON output shapes, and the Windows/MSYS PowerShell gotcha.
42
-
43
- ---
44
-
45
- ## Reference docs these recipes link into
46
-
47
- - [glossary.md](../reference/glossary.md) -- term disambiguation for System, Resource, systemId, Topology, Settings asymmetry
48
- - [contracts.md](../reference/contracts.md) -- TypeScript shapes: `SystemModule`, `OrganizationModel`, CRM deal types, lead-gen list/member/artifact types, `CrmToolMap`, `LeadToolMap`, `ListToolMap`, `ActionDef`
49
- - [feature-flags-and-gating.md](../ui/feature-flags-and-gating.md) -- full three-concept gating model
50
- - [workflow-recipes.md](../operations/workflow-recipes.md) -- workflow anatomy, adapters, trigger patterns
51
-
42
+
43
+ ---
44
+
45
+ ## Reference docs these recipes link into
46
+
47
+ - [glossary.md](../reference/glossary.md) -- term disambiguation for System, Resource, systemId, Topology, Settings asymmetry
48
+ - [contracts.md](../reference/contracts.md) -- TypeScript shapes: `SystemModule`, `OrganizationModel`, CRM deal types, lead-gen list/member/artifact types, `CrmToolMap`, `LeadToolMap`, `ListToolMap`, `ActionDef`
49
+ - [feature-flags-and-gating.md](../ui/feature-flags-and-gating.md) -- full three-concept gating model
50
+ - [workflow-recipes.md](../operations/workflow-recipes.md) -- workflow anatomy, adapters, trigger patterns