@elevasis/sdk 1.20.2 → 1.22.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.
- package/dist/cli.cjs +4220 -1583
- package/dist/index.d.ts +1035 -481
- package/dist/index.js +7381 -4187
- package/dist/node/index.d.ts +1 -3
- package/dist/node/index.js +40 -49
- package/dist/test-utils/index.d.ts +699 -123
- package/dist/test-utils/index.js +3826 -630
- package/dist/worker/index.js +3616 -442
- package/package.json +3 -3
- package/reference/_navigation.md +9 -7
- package/reference/_reference-manifest.json +1 -1
- package/reference/claude-config/hooks/post-edit-validate.mjs +98 -98
- package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +188 -188
- package/reference/claude-config/hooks/tool-failure-recovery.mjs +73 -73
- package/reference/claude-config/registries/graph-skills.json +4 -4
- package/reference/claude-config/registries/knowledge-flags.json +0 -2
- package/reference/claude-config/rules/active-change-index.md +80 -80
- package/reference/claude-config/rules/agent-start-here.md +277 -273
- package/reference/claude-config/rules/deployment.md +57 -57
- package/reference/claude-config/rules/error-handling.md +56 -56
- package/reference/claude-config/rules/execution.md +40 -40
- package/reference/claude-config/rules/frontend.md +4 -4
- package/reference/claude-config/rules/observability.md +31 -31
- package/reference/claude-config/rules/operations.md +29 -17
- package/reference/claude-config/rules/organization-model.md +108 -40
- package/reference/claude-config/rules/organization-os.md +115 -113
- package/reference/claude-config/rules/package-taxonomy.md +33 -33
- package/reference/claude-config/rules/platform.md +42 -42
- package/reference/claude-config/rules/shared-types.md +49 -46
- package/reference/claude-config/rules/task-tracking.md +47 -47
- package/reference/claude-config/rules/ui.md +200 -200
- package/reference/claude-config/rules/vibe.md +235 -231
- package/reference/claude-config/scripts/statusline-command.js +18 -18
- package/reference/claude-config/settings.json +34 -34
- package/reference/claude-config/skills/deploy/{SKILL.md → skill.md} +156 -156
- package/reference/claude-config/skills/dsp/SKILL.md +66 -66
- package/reference/claude-config/skills/elevasis/SKILL.md +235 -235
- package/reference/claude-config/skills/explore/SKILL.md +6 -6
- package/reference/claude-config/skills/git-sync/SKILL.md +126 -126
- package/reference/claude-config/skills/knowledge/SKILL.md +330 -271
- package/reference/claude-config/skills/knowledge/operations/codify-level-a.md +100 -100
- package/reference/claude-config/skills/knowledge/operations/codify-level-b.md +159 -158
- package/reference/claude-config/skills/knowledge/operations/customers.md +109 -109
- package/reference/claude-config/skills/knowledge/operations/features.md +76 -113
- package/reference/claude-config/skills/knowledge/operations/goals.md +118 -118
- package/reference/claude-config/skills/knowledge/operations/identity.md +93 -93
- package/reference/claude-config/skills/knowledge/operations/labels.md +94 -89
- package/reference/claude-config/skills/knowledge/operations/offerings.md +109 -109
- package/reference/claude-config/skills/knowledge/operations/roles.md +99 -99
- package/reference/claude-config/skills/knowledge/operations/techStack.md +30 -30
- package/reference/claude-config/skills/project/SKILL.md +1088 -1088
- package/reference/claude-config/skills/run-ui/SKILL.md +73 -73
- package/reference/claude-config/skills/save/SKILL.md +3 -3
- package/reference/claude-config/skills/setup/SKILL.md +275 -275
- package/reference/claude-config/skills/status/SKILL.md +59 -59
- package/reference/claude-config/skills/submit-request/SKILL.md +180 -180
- package/reference/claude-config/skills/sync/SKILL.md +47 -47
- package/reference/claude-config/skills/tutorial/SKILL.md +259 -259
- package/reference/claude-config/skills/tutorial/progress-template.md +74 -74
- package/reference/claude-config/skills/tutorial/technical.md +1303 -1306
- package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -890
- package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +27 -27
- package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +30 -30
- package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +73 -73
- package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +86 -86
- package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +55 -55
- package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +97 -97
- package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +112 -112
- package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +93 -93
- package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +58 -58
- package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +56 -56
- package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +71 -71
- package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
- package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +59 -59
- package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +42 -42
- package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +60 -60
- package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +37 -37
- package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +34 -34
- package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +38 -38
- package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +32 -32
- package/reference/claude-config/sync-notes/2026-05-09-command-system.md +33 -33
- package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +69 -69
- package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +30 -0
- package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +42 -0
- package/reference/claude-config/sync-notes/README.md +43 -43
- package/reference/cli.mdx +808 -668
- package/reference/concepts.mdx +146 -146
- package/reference/deployment/api.mdx +297 -297
- package/reference/deployment/command-center.mdx +209 -209
- package/reference/deployment/index.mdx +195 -195
- package/reference/deployment/provided-features.mdx +107 -93
- package/reference/deployment/ui-execution.mdx +250 -250
- package/reference/examples/organization-model.ts +147 -84
- package/reference/framework/agent.mdx +156 -156
- package/reference/framework/index.mdx +195 -195
- package/reference/framework/interaction-guidance.mdx +182 -182
- package/reference/framework/memory.mdx +326 -326
- package/reference/framework/project-structure.mdx +282 -282
- package/reference/framework/tutorial-system.mdx +135 -135
- package/reference/getting-started.mdx +142 -142
- package/reference/index.mdx +106 -106
- package/reference/packages/core/src/README.md +14 -14
- package/reference/packages/core/src/business/README.md +2 -2
- package/reference/packages/core/src/knowledge/README.md +33 -32
- package/reference/packages/core/src/organization-model/README.md +149 -109
- package/reference/packages/core/src/test-utils/README.md +37 -37
- package/reference/packages/ui/src/api/README.md +18 -18
- package/reference/packages/ui/src/app/README.md +24 -24
- package/reference/packages/ui/src/auth/README.md +18 -18
- package/reference/packages/ui/src/components/README.md +24 -24
- package/reference/packages/ui/src/execution/README.md +16 -16
- package/reference/packages/ui/src/features/README.md +28 -28
- package/reference/packages/ui/src/graph/README.md +16 -16
- package/reference/packages/ui/src/hooks/README.md +23 -23
- package/reference/packages/ui/src/initialization/README.md +19 -19
- package/reference/packages/ui/src/knowledge/README.md +31 -31
- package/reference/packages/ui/src/organization/README.md +18 -18
- package/reference/packages/ui/src/profile/README.md +19 -19
- package/reference/packages/ui/src/provider/README.md +32 -32
- package/reference/packages/ui/src/router/README.md +18 -18
- package/reference/packages/ui/src/sse/README.md +13 -13
- package/reference/packages/ui/src/test-utils/README.md +7 -7
- package/reference/packages/ui/src/theme/README.md +23 -23
- package/reference/packages/ui/src/theme/presets/README.md +19 -19
- package/reference/packages/ui/src/types/README.md +16 -16
- package/reference/packages/ui/src/utils/README.md +18 -18
- package/reference/packages/ui/src/zustand/README.md +18 -18
- package/reference/platform-tools/adapters-integration.mdx +301 -301
- package/reference/platform-tools/adapters-platform.mdx +553 -553
- package/reference/platform-tools/index.mdx +217 -217
- package/reference/platform-tools/type-safety.mdx +82 -82
- package/reference/resources/index.mdx +349 -349
- package/reference/resources/patterns.mdx +449 -449
- package/reference/resources/types.mdx +116 -116
- package/reference/roadmap.mdx +165 -165
- package/reference/runtime.mdx +173 -173
- package/reference/scaffold/core/organization-graph.mdx +110 -89
- package/reference/scaffold/core/organization-model.mdx +226 -171
- package/reference/scaffold/index.mdx +67 -67
- package/reference/scaffold/operations/propagation-pipeline.md +77 -77
- package/reference/scaffold/operations/scaffold-maintenance.md +10 -10
- package/reference/scaffold/operations/workflow-recipes.md +138 -138
- package/reference/scaffold/recipes/add-a-feature.md +310 -88
- package/reference/scaffold/recipes/add-a-resource.md +137 -117
- package/reference/scaffold/recipes/customize-crm-actions.md +439 -439
- package/reference/scaffold/recipes/customize-knowledge-browser.md +384 -0
- package/reference/scaffold/recipes/customize-organization-model.md +281 -118
- package/reference/scaffold/recipes/extend-a-base-entity.md +8 -8
- package/reference/scaffold/recipes/extend-crm.md +40 -39
- package/reference/scaffold/recipes/extend-lead-gen.md +400 -401
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +118 -114
- package/reference/scaffold/recipes/index.md +47 -46
- package/reference/scaffold/recipes/query-the-knowledge-graph.md +227 -0
- package/reference/scaffold/reference/contracts.md +2389 -2121
- package/reference/scaffold/reference/feature-registry.md +9 -20
- package/reference/scaffold/reference/glossary.md +76 -76
- package/reference/scaffold/ui/composition-extensibility.mdx +233 -233
- package/reference/scaffold/ui/customization.md +243 -243
- package/reference/scaffold/ui/feature-flags-and-gating.md +46 -46
- package/reference/scaffold/ui/feature-shell.mdx +72 -72
- package/reference/scaffold/ui/recipes.md +221 -213
- package/reference/spine/spine-primer.md +96 -96
- package/reference/templates/index.mdx +47 -47
- package/reference/troubleshooting.mdx +223 -223
|
@@ -1,159 +1,322 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Customize organization-model.ts
|
|
3
|
-
description: Annotated walkthrough for customizing the flat Organization Model in template-derived projects.
|
|
4
|
-
---
|
|
5
1
|
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
2
|
<!-- Regenerate: pnpm scaffold:sync -->
|
|
7
3
|
|
|
4
|
+
---
|
|
5
|
+
title: Customize organization-model.ts
|
|
6
|
+
description: Annotated walkthrough for customizing the System-backed Organization Model in template-derived projects.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Customize organization-model.ts
|
|
10
|
+
|
|
11
|
+
`core/config/organization-model.ts` is the semantic contract between the UI shell and platform operations. The shell reads the id-keyed `systems` map for semantic ownership and access, reads `navigation.sidebar` for shell navigation, and binds resources through the id-keyed `resources` map.
|
|
12
|
+
|
|
13
|
+
## Imports
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import {
|
|
17
|
+
createFoundationOrganizationModel,
|
|
18
|
+
defineOrganizationModel,
|
|
19
|
+
type OrganizationModel
|
|
20
|
+
} from '@elevasis/core/organization-model'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- `defineOrganizationModel` gives a typed override shape.
|
|
24
|
+
- `createFoundationOrganizationModel` resolves defaults and returns the canonical model plus UI-facing helpers.
|
|
25
|
+
- `OrganizationModel` is the fully resolved model type.
|
|
26
|
+
|
|
27
|
+
## Systems
|
|
28
|
+
|
|
29
|
+
The `systems` map is the source of truth for semantic hierarchy, lifecycle, admin visibility, and governed ownership.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const override = defineOrganizationModel({
|
|
33
|
+
systems: {
|
|
34
|
+
dashboard: {
|
|
35
|
+
id: 'dashboard',
|
|
36
|
+
order: 10,
|
|
37
|
+
label: 'Dashboard',
|
|
38
|
+
lifecycle: 'active',
|
|
39
|
+
description: 'Command Center home'
|
|
40
|
+
},
|
|
41
|
+
sales: {
|
|
42
|
+
id: 'sales',
|
|
43
|
+
order: 20,
|
|
44
|
+
label: 'Sales',
|
|
45
|
+
lifecycle: 'active'
|
|
46
|
+
},
|
|
47
|
+
'sales.crm': {
|
|
48
|
+
id: 'sales.crm',
|
|
49
|
+
order: 30,
|
|
50
|
+
label: 'CRM',
|
|
51
|
+
parentSystemId: 'sales',
|
|
52
|
+
lifecycle: 'active',
|
|
53
|
+
description: 'CRM pipeline and deal operations'
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
navigation: {
|
|
57
|
+
sidebar: {
|
|
58
|
+
primary: {
|
|
59
|
+
dashboard: {
|
|
60
|
+
type: 'surface',
|
|
61
|
+
order: 10,
|
|
62
|
+
label: 'Dashboard',
|
|
63
|
+
path: '/',
|
|
64
|
+
surfaceType: 'dashboard',
|
|
65
|
+
icon: 'feature.dashboard',
|
|
66
|
+
targets: { systems: ['dashboard'] }
|
|
67
|
+
},
|
|
68
|
+
business: {
|
|
69
|
+
type: 'group',
|
|
70
|
+
order: 20,
|
|
71
|
+
label: 'Business',
|
|
72
|
+
children: {
|
|
73
|
+
crm: {
|
|
74
|
+
type: 'surface',
|
|
75
|
+
order: 10,
|
|
76
|
+
label: 'CRM',
|
|
77
|
+
path: '/crm',
|
|
78
|
+
surfaceType: 'page',
|
|
79
|
+
targets: { systems: ['sales.crm'] }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
bottom: {}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
System field reference:
|
|
91
|
+
|
|
92
|
+
- `id` -- lowercase dotted path. Parent Systems are inferred from prefix segments or declared through `parentSystemId`.
|
|
93
|
+
- `order` -- deterministic map iteration order. Use multiples of 10 for easy insertion.
|
|
94
|
+
- `label` -- sidebar and breadcrumb label.
|
|
95
|
+
- `description` -- optional settings/help text.
|
|
96
|
+
- `kind` -- product, operational, platform, or diagnostic.
|
|
97
|
+
- `parentSystemId` -- explicit parent System link.
|
|
98
|
+
- `lifecycle` -- draft, beta, active, deprecated, or archived.
|
|
99
|
+
- `ui` -- optional route metadata used by shell matching during migration.
|
|
100
|
+
- `requiresAdmin` -- hides the node for non-admin members; descendants inherit it.
|
|
101
|
+
- `actions` / `policies` -- references to cross-cutting domains.
|
|
102
|
+
- `ontology` -- System-owned object, link, action, catalog, event, surface, interface, value-type, property, or group records.
|
|
103
|
+
- `config` -- JSON-serializable settings local to this System.
|
|
104
|
+
- `systems` -- nested child Systems. Use this for new recursive authoring; `subsystems` is a compatibility alias only.
|
|
8
105
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`core/config/organization-model.ts` is the semantic contract between the UI shell and platform operations. The shell reads one flat feature list, derives hierarchy from dotted IDs, and binds resources through graph links declared on resource metadata.
|
|
106
|
+
## Ontology
|
|
12
107
|
|
|
13
|
-
|
|
108
|
+
Use top-level `ontology` for global/shared primitives and `System.ontology` for owned contracts. The resolved ontology index is compiled from root and System scopes and validated for ID shape, kind mismatch, and duplicate IDs.
|
|
14
109
|
|
|
15
110
|
```ts
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
111
|
+
const override = defineOrganizationModel({
|
|
112
|
+
ontology: {
|
|
113
|
+
valueTypes: {
|
|
114
|
+
'global:value-type/text': {
|
|
115
|
+
id: 'global:value-type/text',
|
|
116
|
+
label: 'Text'
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
systems: {
|
|
121
|
+
sales: {
|
|
122
|
+
id: 'sales',
|
|
123
|
+
order: 20,
|
|
124
|
+
label: 'Sales',
|
|
125
|
+
lifecycle: 'active',
|
|
126
|
+
systems: {
|
|
127
|
+
crm: {
|
|
128
|
+
id: 'sales.crm',
|
|
129
|
+
order: 30,
|
|
130
|
+
label: 'CRM',
|
|
131
|
+
parentSystemId: 'sales',
|
|
132
|
+
lifecycle: 'active',
|
|
133
|
+
ontology: {
|
|
134
|
+
objectTypes: {
|
|
135
|
+
'sales.crm:object/deal': {
|
|
136
|
+
id: 'sales.crm:object/deal',
|
|
137
|
+
label: 'Deal',
|
|
138
|
+
ownerSystemId: 'sales.crm'
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
actionTypes: {
|
|
142
|
+
'sales.crm:action/deal.update-stage': {
|
|
143
|
+
id: 'sales.crm:action/deal.update-stage',
|
|
144
|
+
label: 'Update Deal Stage',
|
|
145
|
+
ownerSystemId: 'sales.crm',
|
|
146
|
+
actsOn: ['sales.crm:object/deal']
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
})
|
|
21
155
|
```
|
|
22
156
|
|
|
23
|
-
- `
|
|
24
|
-
- `createFoundationOrganizationModel` resolves defaults and returns the canonical model plus UI-facing helpers.
|
|
25
|
-
- `OrganizationModel` is the fully resolved model type.
|
|
157
|
+
Top-level `entities`, top-level `actions`, and `System.content kind: "schema"` remain accepted for existing consumers and are projected into compiled ontology indexes. Prefer `System.ontology` for new object/action/catalog contracts.
|
|
26
158
|
|
|
27
|
-
##
|
|
159
|
+
## System Config
|
|
28
160
|
|
|
29
|
-
|
|
161
|
+
Use `systems[*].config` for local settings and defaults that are not semantic contracts:
|
|
30
162
|
|
|
31
163
|
```ts
|
|
32
164
|
const override = defineOrganizationModel({
|
|
33
|
-
|
|
34
|
-
{
|
|
35
|
-
id: 'dashboard',
|
|
36
|
-
label: 'Dashboard',
|
|
37
|
-
enabled: true,
|
|
38
|
-
path: '/',
|
|
39
|
-
icon: 'feature.dashboard',
|
|
40
|
-
uiPosition: 'sidebar-primary'
|
|
41
|
-
},
|
|
42
|
-
{
|
|
165
|
+
systems: {
|
|
166
|
+
sales: {
|
|
43
167
|
id: 'sales',
|
|
168
|
+
order: 20,
|
|
44
169
|
label: 'Sales',
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
170
|
+
lifecycle: 'active',
|
|
171
|
+
systems: {
|
|
172
|
+
crm: {
|
|
173
|
+
id: 'sales.crm',
|
|
174
|
+
order: 30,
|
|
175
|
+
label: 'CRM',
|
|
176
|
+
parentSystemId: 'sales',
|
|
177
|
+
lifecycle: 'active',
|
|
178
|
+
config: {
|
|
179
|
+
defaultPipelineId: 'sales.crm:catalog/pipeline',
|
|
180
|
+
kanban: {
|
|
181
|
+
groupBy: 'stage',
|
|
182
|
+
showProbability: true
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
62
187
|
}
|
|
63
|
-
|
|
188
|
+
}
|
|
64
189
|
})
|
|
65
190
|
```
|
|
66
191
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
Resource identity and governance metadata live in `OrganizationModel` under `resources.entries`. Workflows, agents, and integrations import those descriptors and derive runtime `resourceId` / `type` from them while still declaring semantic graph links in resource metadata.
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
// core/config/organization-model.ts
|
|
85
|
-
import { defineResources } from '@elevasis/core/organization-model'
|
|
86
|
-
|
|
192
|
+
Keep semantic nouns, verbs, relationships, events, catalogs, interfaces, and value types in ontology. Keep secrets, credentials, per-run execution state, logs, and external service state outside the Organization Model.
|
|
193
|
+
|
|
194
|
+
## Sidebar Navigation
|
|
195
|
+
|
|
196
|
+
Author shell navigation under `navigation.sidebar`. Groups can contain nested nodes; routeable surface leaves provide `path`, `surfaceType`, and `targets`. Dashboard should appear before Business, Business is a navigation group only, and `/clients` is the canonical clients route.
|
|
197
|
+
|
|
198
|
+
## Resource Binding
|
|
199
|
+
|
|
200
|
+
Resource identity and governance metadata live in `OrganizationModel` under `resources`. Workflows, agents, integrations, and scripts import those descriptors and derive runtime `resourceId` / `type` from them. The graph derives System membership from `ResourceEntry.systemPath`.
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
// core/config/organization-model.ts
|
|
204
|
+
import { defineResources } from '@elevasis/core/organization-model'
|
|
205
|
+
|
|
87
206
|
export const resourceDescriptors = defineResources({
|
|
88
207
|
leadImport: {
|
|
89
208
|
id: 'lead-import',
|
|
209
|
+
order: 10,
|
|
90
210
|
kind: 'workflow',
|
|
91
|
-
|
|
211
|
+
systemPath: 'sales.crm',
|
|
92
212
|
ownerRoleId: 'role-ops-lead',
|
|
93
|
-
status: 'active'
|
|
213
|
+
status: 'active',
|
|
214
|
+
actionKey: 'sales.crm.deal.update-stage',
|
|
215
|
+
ontology: {
|
|
216
|
+
implements: ['sales.crm:action/deal.update-stage'],
|
|
217
|
+
reads: ['sales.crm:object/deal'],
|
|
218
|
+
writes: ['sales.crm:object/deal'],
|
|
219
|
+
usesCatalogs: ['sales.crm:catalog/pipeline'],
|
|
220
|
+
emits: ['sales.crm:event/deal-stage-updated']
|
|
221
|
+
}
|
|
94
222
|
}
|
|
95
223
|
})
|
|
224
|
+
|
|
225
|
+
// operations/src/lead-import/index.ts
|
|
226
|
+
config: {
|
|
227
|
+
resource: resourceDescriptors.leadImport,
|
|
228
|
+
resourceId: resourceDescriptors.leadImport.id,
|
|
229
|
+
name: 'Lead Import',
|
|
230
|
+
type: resourceDescriptors.leadImport.kind,
|
|
231
|
+
version: '1.0.0',
|
|
232
|
+
status: 'prod',
|
|
233
|
+
category: 'production'
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Use kind-prefixed graph IDs for cross-collection links:
|
|
238
|
+
|
|
239
|
+
- `system:sales.crm`
|
|
240
|
+
- `integration:instantly`
|
|
241
|
+
- `resource:lead-import`
|
|
242
|
+
- `action:operations.queue.review`
|
|
243
|
+
|
|
244
|
+
`category` is one of `production`, `diagnostic`, `internal`, or `testing`.
|
|
96
245
|
|
|
97
|
-
|
|
98
|
-
config: {
|
|
99
|
-
resource: resourceDescriptors.leadImport,
|
|
100
|
-
resourceId: resourceDescriptors.leadImport.id,
|
|
101
|
-
name: 'Lead Import',
|
|
102
|
-
type: resourceDescriptors.leadImport.kind,
|
|
103
|
-
version: '1.0.0',
|
|
104
|
-
status: 'prod',
|
|
105
|
-
links: [{ nodeId: 'feature:sales.lead-gen', kind: 'operates-on' }],
|
|
106
|
-
category: 'production'
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Use kind-prefixed graph IDs for cross-collection links:
|
|
111
|
-
|
|
112
|
-
- `feature:sales.crm`
|
|
113
|
-
- `integration:instantly`
|
|
114
|
-
- `resource:lead-import`
|
|
115
|
-
- `capability:operations.queue.review`
|
|
246
|
+
`actionKey` mirrors a stable runtime action key when the resource has one. Use nested `resource.ontology` bindings to declare which ontology actions, objects, catalogs, and events the resource implements, reads, writes, uses, or emits. Resource event emissions can still be declared through top-level `emits` for older descriptors, but new descriptors should use `resource.ontology.emits`.
|
|
116
247
|
|
|
117
|
-
|
|
248
|
+
## Compatibility Domain Mirrors
|
|
118
249
|
|
|
119
|
-
|
|
250
|
+
The old `sales`, `prospecting`, and `projects` top-level keys are not part of the current primary Organization Model schema. If an older local project still has bridge-era examples for those concepts, migrate the data toward owning Systems:
|
|
120
251
|
|
|
121
|
-
|
|
252
|
+
- durable objects -> `System.ontology.objectTypes`
|
|
253
|
+
- stable verbs -> `System.ontology.actionTypes`
|
|
254
|
+
- pipelines, stages, templates, and status vocabularies -> `System.ontology.catalogTypes`
|
|
255
|
+
- local settings and defaults -> `System.config`
|
|
256
|
+
- existing `System.content kind: "schema"` nodes -> compatibility catalog projections
|
|
122
257
|
|
|
123
258
|
```ts
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
259
|
+
systems: {
|
|
260
|
+
sales: {
|
|
261
|
+
id: 'sales',
|
|
262
|
+
order: 20,
|
|
263
|
+
label: 'Sales',
|
|
264
|
+
lifecycle: 'active',
|
|
265
|
+
systems: {
|
|
266
|
+
crm: {
|
|
267
|
+
id: 'sales.crm',
|
|
268
|
+
order: 30,
|
|
269
|
+
label: 'CRM',
|
|
270
|
+
lifecycle: 'active',
|
|
271
|
+
parentSystemId: 'sales',
|
|
272
|
+
ontology: {
|
|
273
|
+
catalogTypes: {
|
|
274
|
+
'sales.crm:catalog/pipeline': {
|
|
275
|
+
id: 'sales.crm:catalog/pipeline',
|
|
276
|
+
label: 'Default Pipeline',
|
|
277
|
+
kind: 'pipeline',
|
|
278
|
+
ownerSystemId: 'sales.crm',
|
|
279
|
+
entries: {
|
|
280
|
+
interested: { label: 'Interested', color: 'blue', order: 10, semanticClass: 'open' },
|
|
281
|
+
closed_won: { label: 'Closed Won', color: 'green', order: 20, semanticClass: 'closed_won' }
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
136
287
|
}
|
|
137
|
-
|
|
288
|
+
}
|
|
138
289
|
}
|
|
139
290
|
```
|
|
140
|
-
|
|
291
|
+
|
|
141
292
|
Keep `semanticClass` values stable; platform analytics and triggers depend on them.
|
|
142
293
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
export const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
294
|
+
Policy and role integration remains outside ontology in this pass. Use `roles`, `policies`, `responsibleRoleId`, and `ownerRoleId` for accountability and access semantics until a dedicated policy/role ontology design is published.
|
|
295
|
+
|
|
296
|
+
## Export Pattern
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
const foundation = createFoundationOrganizationModel(override)
|
|
300
|
+
|
|
301
|
+
export const canonicalOrganizationModel: OrganizationModel = foundation.canonical
|
|
302
|
+
export const organizationModel = foundation.model
|
|
303
|
+
export const { getOrganizationSurface } = foundation
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Pass `canonicalOrganizationModel` to `ElevasisSystemsProvider` in `ui/src/routes/__root.tsx`.
|
|
307
|
+
|
|
308
|
+
## Resolve Behavior
|
|
309
|
+
|
|
310
|
+
`createFoundationOrganizationModel(override)` resolves defaults, validates System hierarchy, and exposes helper functions used by the shell. Id-keyed domain maps merge additively by key, so tenant overrides can add one System or resource without re-authoring every default entry.
|
|
311
|
+
|
|
312
|
+
Validation catches duplicate System IDs, missing parent Systems, invalid graph IDs, invalid UI paths, invalid ontology IDs, ontology kind mismatches, and duplicate ontology IDs.
|
|
154
313
|
|
|
155
|
-
##
|
|
314
|
+
## Refresh Generated Scaffold Copies
|
|
156
315
|
|
|
157
|
-
|
|
316
|
+
This file is source guidance for generated SDK reference copies. After changing Organization Model scaffold docs, refresh and verify generated outputs from the monorepo root:
|
|
158
317
|
|
|
159
|
-
|
|
318
|
+
```bash
|
|
319
|
+
pnpm scaffold:sync
|
|
320
|
+
pnpm scaffold:verify
|
|
321
|
+
pnpm verify:scaffold-reference
|
|
322
|
+
```
|
|
@@ -10,7 +10,7 @@ description: Add project-specific metadata to the canonical entity shapes (Proje
|
|
|
10
10
|
|
|
11
11
|
Workflows and UI features often operate on domain entities such as projects, deals, companies, or contacts. Rather than each project declaring its own shape from scratch, `@elevasis/core/entities` provides typed base interfaces generic over a `<TMeta>` slot. External projects extend these to add project-specific fields while keeping the canonical shape stable and interoperable with platform tooling.
|
|
12
12
|
|
|
13
|
-
The canonical demo lives in `core/types/entities.ts` of any scaffold project.
|
|
13
|
+
The canonical demo lives in `core/types/entities.ts` of any scaffold project.
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -33,7 +33,7 @@ All imports come from `@elevasis/core/entities`.
|
|
|
33
33
|
|
|
34
34
|
## Recipe 1 -- Extend a base entity with custom metadata
|
|
35
35
|
|
|
36
|
-
Place this in `core/types/entities.ts`. This is the primary pattern -- the scaffold template ships this exact example.
|
|
36
|
+
Place this in `core/types/entities.ts`. This is the primary pattern -- the scaffold template ships this exact example.
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
import { z } from 'zod'
|
|
@@ -59,7 +59,7 @@ Key points:
|
|
|
59
59
|
- `BaseProjectSchema.extend({ metadata: ... })` merges your metadata Zod schema into the validated shape. Zod handles the rest.
|
|
60
60
|
- `BaseProject<ProjectMeta>` infers the TypeScript type with your metadata typed correctly.
|
|
61
61
|
- Only the `metadata` field is extended -- all other base fields (`id`, `organizationId`, `name`, `status`, `createdAt`, `updatedAt`, etc.) are inherited unchanged.
|
|
62
|
-
- This file is the single source of truth for entity shapes across `core/`, `operations/`, and `ui/`.
|
|
62
|
+
- This file is the single source of truth for entity shapes across `core/`, `operations/`, and `ui/`.
|
|
63
63
|
|
|
64
64
|
---
|
|
65
65
|
|
|
@@ -87,7 +87,7 @@ Workflows that operate on projects or deals should reference the project-local e
|
|
|
87
87
|
```ts
|
|
88
88
|
import { z } from 'zod'
|
|
89
89
|
import type { WorkflowDefinition } from '@elevasis/sdk'
|
|
90
|
-
import { ProjectSchema } from '@core/types/entities'
|
|
90
|
+
import { ProjectSchema } from '@core/types/entities'
|
|
91
91
|
|
|
92
92
|
export const myWorkflow: WorkflowDefinition = {
|
|
93
93
|
id: 'my-workflow',
|
|
@@ -99,16 +99,16 @@ export const myWorkflow: WorkflowDefinition = {
|
|
|
99
99
|
}
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
The `@core/*` alias maps to the `core/` workspace package. This keeps entity contracts in one place and ensures the workflow input type matches whatever the UI passes as the execution payload.
|
|
102
|
+
The `@core/*` alias maps to the `core/` workspace package. This keeps entity contracts in one place and ensures the workflow input type matches whatever the UI passes as the execution payload.
|
|
103
103
|
|
|
104
104
|
---
|
|
105
105
|
|
|
106
106
|
## Recipe 4 -- Reference entity types from the UI
|
|
107
107
|
|
|
108
|
-
UI components accept entity types directly in props. The entity type flows from the `core` package through the component into the workflow execution payload:
|
|
108
|
+
UI components accept entity types directly in props. The entity type flows from the `core` package through the component into the workflow execution payload:
|
|
109
109
|
|
|
110
110
|
```tsx
|
|
111
|
-
import type { Project } from '@core/types/entities'
|
|
111
|
+
import type { Project } from '@core/types/entities'
|
|
112
112
|
|
|
113
113
|
interface ProjectCardProps {
|
|
114
114
|
project: Project
|
|
@@ -130,7 +130,7 @@ When wiring this to a `RunResourceButton`, the entity instance becomes the workf
|
|
|
130
130
|
|
|
131
131
|
## Verification
|
|
132
132
|
|
|
133
|
-
- **Test core contracts:** `pnpm -C core test` runs the Vitest suite. The template ships `core/types/entities.test.ts` as a working smoke-check -- it `safeParse`s a valid project (expects success) and an invalid one (expects failure). Run this after any schema change.
|
|
133
|
+
- **Test core contracts:** `pnpm -C core test` runs the Vitest suite. The template ships `core/types/entities.test.ts` as a working smoke-check -- it `safeParse`s a valid project (expects success) and an invalid one (expects failure). Run this after any schema change.
|
|
134
134
|
- **Round-trip safeParse:** Call `ProjectSchema.safeParse(candidateObject)` in a test or REPL to confirm the Zod shape accepts the data your workflows and UI will produce.
|
|
135
135
|
- **Cross-package type check:** `pnpm -C ui build` will surface any TypeScript errors if a UI component or hook passes a mismatched entity type to a workflow input.
|
|
136
136
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Build and Extend CRM
|
|
3
|
-
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.
|
|
4
|
-
---
|
|
5
1
|
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
2
|
<!-- Regenerate: pnpm scaffold:sync -->
|
|
7
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
8
|
|
|
9
9
|
# Build and Extend CRM
|
|
10
10
|
|
|
@@ -20,7 +20,7 @@ Good trigger phrases:
|
|
|
20
20
|
|
|
21
21
|
CRM is a layered platform surface, not one component:
|
|
22
22
|
|
|
23
|
-
- **Organization OS:**
|
|
23
|
+
- **Organization OS:** System access, sales pipeline semantics, quick access, and labels live in the organization model.
|
|
24
24
|
- **Shared UI:** CRM pages, sidebars, workbench panels, overview widgets, and Kanban/detail components live in `@elevasis/ui`.
|
|
25
25
|
- **Headless hooks:** deal, company, contact, note, task, list, transition, and action hooks live under `@elevasis/ui/hooks`.
|
|
26
26
|
- **Action system:** `ActionDef`, `DEFAULT_CRM_ACTIONS`, `deriveActions`, and provider-level `crmActions` configure deal actions.
|
|
@@ -31,7 +31,7 @@ CRM is a layered platform surface, not one component:
|
|
|
31
31
|
|
|
32
32
|
| User wants | Start here | Notes |
|
|
33
33
|
| --- | --- | --- |
|
|
34
|
-
| Change CRM
|
|
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
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
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
37
|
| Build a custom deal page | `useDealDetail`, `useDealNotes`, `useDealTasks`, `useExecuteAction` from `@elevasis/ui/hooks` | Use hooks for platform data and compose your own UI. |
|
|
@@ -58,18 +58,18 @@ Read the generated contracts before changing typed boundaries:
|
|
|
58
58
|
|
|
59
59
|
`node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`
|
|
60
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`.
|
|
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
64
|
|
|
65
65
|
## 1. Extend CRM Navigation or Sidebar
|
|
66
66
|
|
|
67
|
-
For a simple nav addition, extend `CRM_ITEMS` and override the CRM
|
|
67
|
+
For a simple nav addition, extend `CRM_ITEMS` and override the CRM system manifest:
|
|
68
68
|
|
|
69
69
|
```tsx
|
|
70
70
|
// ui/src/routes/__root.tsx
|
|
71
71
|
import { crmManifest, CRM_ITEMS, CrmSidebar, CrmSidebarMiddle } from '@elevasis/ui/features/crm'
|
|
72
|
-
import type {
|
|
72
|
+
import type { SystemModule } from '@elevasis/ui/provider'
|
|
73
73
|
import type { NavItem } from '@elevasis/ui/layout'
|
|
74
74
|
import { IconFileText } from '@tabler/icons-react'
|
|
75
75
|
|
|
@@ -84,13 +84,13 @@ const CustomCrmSidebar = () => (
|
|
|
84
84
|
</CrmSidebar>
|
|
85
85
|
)
|
|
86
86
|
|
|
87
|
-
export const customCrmManifest:
|
|
87
|
+
export const customCrmManifest: SystemModule = {
|
|
88
88
|
...crmManifest,
|
|
89
89
|
sidebar: CustomCrmSidebar
|
|
90
90
|
}
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
Then replace `crmManifest` with `customCrmManifest` in the local `
|
|
93
|
+
Then replace `crmManifest` with `customCrmManifest` in the local `SYSTEM_MANIFESTS` array and add the matching route under `ui/src/routes/crm/`.
|
|
94
94
|
|
|
95
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
96
|
|
|
@@ -164,10 +164,10 @@ Inside deployed workflows, use worker adapters instead of browser hooks or direc
|
|
|
164
164
|
|
|
165
165
|
```ts
|
|
166
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'
|
|
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
171
|
|
|
172
172
|
const inputSchema = z.object({
|
|
173
173
|
stage: z.string().default('proposal')
|
|
@@ -177,15 +177,14 @@ const outputSchema = z.object({
|
|
|
177
177
|
touched: z.number()
|
|
178
178
|
})
|
|
179
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
|
-
links: [{ nodeId: 'feature:sales.crm', kind: 'operates-on' }]
|
|
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',
|
|
189
188
|
},
|
|
190
189
|
contract: { inputSchema, outputSchema },
|
|
191
190
|
steps: {
|
|
@@ -196,15 +195,15 @@ export const followUpStaleDealsWorkflow: WorkflowDefinition = {
|
|
|
196
195
|
outputSchema,
|
|
197
196
|
next: null,
|
|
198
197
|
handler: async (input) => {
|
|
199
|
-
const deals = await crm.listDeals({ stage: input.stage })
|
|
200
|
-
|
|
201
|
-
for (const deal of deals) {
|
|
202
|
-
if (!['follow_up_due', 'stale'].includes(deal.priority.bucketKey)) continue
|
|
203
|
-
|
|
204
|
-
await crm.createDealTask({
|
|
205
|
-
dealId: deal.id,
|
|
206
|
-
title: 'Follow up',
|
|
207
|
-
kind: 'email'
|
|
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'
|
|
208
207
|
})
|
|
209
208
|
await crm.recordActivity({
|
|
210
209
|
dealId: deal.id,
|
|
@@ -226,11 +225,11 @@ Use `crm` for focused CRM deal reads, notes, tasks, activity, and cleanup. Use `
|
|
|
226
225
|
|
|
227
226
|
## 5. Customize Pipeline Semantics
|
|
228
227
|
|
|
229
|
-
CRM
|
|
228
|
+
CRM System identity is `sales.crm`, but the organization-model domain is `sales`.
|
|
230
229
|
|
|
231
|
-
For stage labels or stage sets, update the project model:
|
|
232
|
-
|
|
233
|
-
`core/config/organization-model.ts`
|
|
230
|
+
For stage labels or stage sets, update the project model:
|
|
231
|
+
|
|
232
|
+
`core/config/organization-model.ts`
|
|
234
233
|
|
|
235
234
|
Keep these boundaries straight:
|
|
236
235
|
|
|
@@ -255,3 +254,5 @@ If you changed platform-level CRM contracts in the monorepo, the platform mainta
|
|
|
255
254
|
pnpm scaffold:sync
|
|
256
255
|
pnpm scaffold:verify
|
|
257
256
|
```
|
|
257
|
+
|
|
258
|
+
|