@elevasis/sdk 1.10.0 → 1.11.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 +22 -142
- package/dist/index.d.ts +127 -154
- package/dist/index.js +15 -139
- package/dist/test-utils/index.d.ts +59 -62
- package/dist/worker/index.js +4 -2
- package/package.json +2 -2
- package/reference/deployment/provided-features.mdx +40 -267
- package/reference/examples/organization-model.ts +96 -564
- package/reference/packages/core/src/organization-model/README.md +101 -97
- package/reference/resources/types.mdx +72 -163
- package/reference/scaffold/core/organization-graph.mdx +89 -272
- package/reference/scaffold/core/organization-model.mdx +149 -320
- package/reference/scaffold/recipes/add-a-feature.md +102 -158
- package/reference/scaffold/recipes/add-a-resource.md +85 -158
- package/reference/scaffold/recipes/customize-organization-model.md +141 -400
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +114 -158
- package/reference/scaffold/reference/contracts.md +62 -148
- package/reference/scaffold/reference/feature-registry.md +8 -8
- package/reference/scaffold/reference/glossary.md +71 -105
- package/reference/scaffold/ui/feature-flags-and-gating.md +27 -232
- package/reference/scaffold/ui/feature-shell.mdx +50 -219
- package/reference/scaffold/ui/recipes.md +62 -397
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
// Pure reference file -- NOT imported anywhere.
|
|
2
|
-
// Copy individual examples into organization-model.ts as needed.
|
|
3
|
-
// Each const is a valid `defineOrganizationModel()` override shape. All examples
|
|
4
|
-
// are written against the current @elevasis/core schema (reality-domain expansion)
|
|
5
|
-
// and will type-check once @elevasis/core is updated to the version that includes
|
|
6
|
-
// the new domains (identity, customers, offerings, roles, goals, statuses, operations).
|
|
7
|
-
//
|
|
8
|
-
// Examples are organized by domain. Each section shows the minimal shape a developer
|
|
9
|
-
// would write when answering /configure prompts for that domain.
|
|
10
|
-
import {
|
|
11
|
-
SALES_PIPELINE_SURFACE_ID,
|
|
12
|
-
defineOrganizationModel,
|
|
13
|
-
type OrganizationModelResourceMapping
|
|
14
|
-
} from '@elevasis/core/organization-model'
|
|
2
|
+
// Copy individual examples into core/config/organization-model.ts or resource definitions as needed.
|
|
15
3
|
|
|
16
|
-
|
|
17
|
-
const PROSPECTING_FEATURE_ID = 'lead-gen' as const
|
|
4
|
+
import { defineOrganizationModel } from '@elevasis/core/organization-model'
|
|
18
5
|
|
|
19
6
|
// ---------------------------------------------------------------------------
|
|
20
|
-
//
|
|
7
|
+
// Branding override
|
|
21
8
|
// ---------------------------------------------------------------------------
|
|
22
9
|
export const brandingOverrideExample = defineOrganizationModel({
|
|
23
10
|
branding: {
|
|
@@ -28,9 +15,53 @@ export const brandingOverrideExample = defineOrganizationModel({
|
|
|
28
15
|
})
|
|
29
16
|
|
|
30
17
|
// ---------------------------------------------------------------------------
|
|
31
|
-
//
|
|
18
|
+
// Flat feature hierarchy
|
|
32
19
|
// ---------------------------------------------------------------------------
|
|
33
|
-
export const
|
|
20
|
+
export const featureTreeExample = defineOrganizationModel({
|
|
21
|
+
features: [
|
|
22
|
+
{
|
|
23
|
+
id: 'dashboard',
|
|
24
|
+
label: 'Dashboard',
|
|
25
|
+
enabled: true,
|
|
26
|
+
path: '/',
|
|
27
|
+
icon: 'dashboard',
|
|
28
|
+
uiPosition: 'sidebar-primary'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'sales',
|
|
32
|
+
label: 'Sales',
|
|
33
|
+
enabled: true,
|
|
34
|
+
icon: 'briefcase',
|
|
35
|
+
uiPosition: 'sidebar-primary'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'sales.crm',
|
|
39
|
+
label: 'CRM',
|
|
40
|
+
enabled: true,
|
|
41
|
+
path: '/crm'
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'sales.lead-gen',
|
|
45
|
+
label: 'Lead Gen',
|
|
46
|
+
enabled: true,
|
|
47
|
+
path: '/lead-gen'
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 'admin',
|
|
51
|
+
label: 'Admin',
|
|
52
|
+
enabled: true,
|
|
53
|
+
path: '/admin',
|
|
54
|
+
icon: 'shield',
|
|
55
|
+
uiPosition: 'sidebar-bottom',
|
|
56
|
+
requiresAdmin: true
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Sales customization
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
export const salesCustomizationExample = defineOrganizationModel({
|
|
34
65
|
sales: {
|
|
35
66
|
entityId: 'crm.deal',
|
|
36
67
|
defaultPipelineId: 'sales',
|
|
@@ -40,33 +71,9 @@ export const crmCustomizationExample = defineOrganizationModel({
|
|
|
40
71
|
label: 'Sales Pipeline',
|
|
41
72
|
entityId: 'crm.deal',
|
|
42
73
|
stages: [
|
|
43
|
-
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
color: 'blue',
|
|
47
|
-
order: 1,
|
|
48
|
-
semanticClass: 'open',
|
|
49
|
-
surfaceIds: [SALES_PIPELINE_SURFACE_ID],
|
|
50
|
-
resourceIds: []
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
id: 'negotiating',
|
|
54
|
-
label: 'Negotiating',
|
|
55
|
-
color: 'yellow',
|
|
56
|
-
order: 2,
|
|
57
|
-
semanticClass: 'active',
|
|
58
|
-
surfaceIds: [SALES_PIPELINE_SURFACE_ID],
|
|
59
|
-
resourceIds: []
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
id: 'won',
|
|
63
|
-
label: 'Won',
|
|
64
|
-
color: 'green',
|
|
65
|
-
order: 3,
|
|
66
|
-
semanticClass: 'closed_won',
|
|
67
|
-
surfaceIds: [SALES_PIPELINE_SURFACE_ID],
|
|
68
|
-
resourceIds: []
|
|
69
|
-
}
|
|
74
|
+
{ id: 'qualified', label: 'Qualified', color: 'blue', order: 1, semanticClass: 'open' },
|
|
75
|
+
{ id: 'negotiating', label: 'Negotiating', color: 'yellow', order: 2, semanticClass: 'active' },
|
|
76
|
+
{ id: 'won', label: 'Won', color: 'green', order: 3, semanticClass: 'closed_won' }
|
|
70
77
|
]
|
|
71
78
|
}
|
|
72
79
|
]
|
|
@@ -74,9 +81,9 @@ export const crmCustomizationExample = defineOrganizationModel({
|
|
|
74
81
|
})
|
|
75
82
|
|
|
76
83
|
// ---------------------------------------------------------------------------
|
|
77
|
-
//
|
|
84
|
+
// Prospecting customization
|
|
78
85
|
// ---------------------------------------------------------------------------
|
|
79
|
-
export const
|
|
86
|
+
export const prospectingCustomizationExample = defineOrganizationModel({
|
|
80
87
|
prospecting: {
|
|
81
88
|
listEntityId: 'leadgen.list',
|
|
82
89
|
companyEntityId: 'leadgen.company',
|
|
@@ -95,90 +102,19 @@ export const leadGenCustomizationExample = defineOrganizationModel({
|
|
|
95
102
|
})
|
|
96
103
|
|
|
97
104
|
// ---------------------------------------------------------------------------
|
|
98
|
-
//
|
|
99
|
-
// ---------------------------------------------------------------------------
|
|
100
|
-
const resourceMappingEntries: OrganizationModelResourceMapping[] = [
|
|
101
|
-
{
|
|
102
|
-
id: 'lead-gen-enrichment',
|
|
103
|
-
label: 'Lead Enrichment',
|
|
104
|
-
resourceId: 'my-org/lead-enrichment-workflow',
|
|
105
|
-
resourceType: 'workflow',
|
|
106
|
-
featureIds: [PROSPECTING_FEATURE_ID],
|
|
107
|
-
entityIds: ['leadgen.company'],
|
|
108
|
-
surfaceIds: ['lead-gen.lists'],
|
|
109
|
-
capabilityIds: []
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
id: 'crm-follow-up',
|
|
113
|
-
label: 'CRM Follow-Up Agent',
|
|
114
|
-
resourceId: 'my-org/crm-follow-up-agent',
|
|
115
|
-
resourceType: 'agent',
|
|
116
|
-
featureIds: [SALES_FEATURE_ID],
|
|
117
|
-
entityIds: ['crm.deal'],
|
|
118
|
-
surfaceIds: [SALES_PIPELINE_SURFACE_ID],
|
|
119
|
-
capabilityIds: ['crm.pipeline.manage']
|
|
120
|
-
}
|
|
121
|
-
]
|
|
122
|
-
|
|
123
|
-
export const resourceMappingExample = defineOrganizationModel({
|
|
124
|
-
resourceMappings: resourceMappingEntries
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
// ---------------------------------------------------------------------------
|
|
128
|
-
// 5. Custom feature -- add a project-specific feature
|
|
129
|
-
//
|
|
130
|
-
// NOTE: the `features` field REPLACES the default array on merge (arrays are
|
|
131
|
-
// not deep-merged). To keep the built-in features (CRM, Lead Gen, etc.) while
|
|
132
|
-
// adding a custom one, spread them explicitly:
|
|
133
|
-
//
|
|
134
|
-
// features: [...DEFAULT_ORGANIZATION_MODEL.features, myCustomFeature]
|
|
135
|
-
//
|
|
136
|
-
// The example below shows a standalone override with only the custom feature
|
|
137
|
-
// to illustrate the shape. Import DEFAULT_ORGANIZATION_MODEL from
|
|
138
|
-
// @elevasis/core/organization-model if you need the full set.
|
|
139
|
-
// ---------------------------------------------------------------------------
|
|
140
|
-
export const customFeatureExample = defineOrganizationModel({
|
|
141
|
-
features: [
|
|
142
|
-
{
|
|
143
|
-
id: 'my-custom',
|
|
144
|
-
label: 'My Custom Feature',
|
|
145
|
-
description: 'A project-specific feature outside the standard suite',
|
|
146
|
-
enabled: true,
|
|
147
|
-
color: 'teal',
|
|
148
|
-
entityIds: [],
|
|
149
|
-
surfaceIds: ['my-custom.dashboard'],
|
|
150
|
-
resourceIds: [],
|
|
151
|
-
capabilityIds: []
|
|
152
|
-
}
|
|
153
|
-
]
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
// ---------------------------------------------------------------------------
|
|
157
|
-
// 6. Identity domain -- legal entity, mission/vision, industry/geo anchors
|
|
158
|
-
//
|
|
159
|
-
// Decision #3: identity is distinct from branding. `branding` = display
|
|
160
|
-
// identity (logos, product names). `identity` = legal identity (entity,
|
|
161
|
-
// jurisdiction, mission/vision). Conflating risks branding edits touching
|
|
162
|
-
// compliance fields.
|
|
163
|
-
//
|
|
164
|
-
// Fields: mission, vision, legalName, entityType, jurisdiction,
|
|
165
|
-
// industryCategory, geographicFocus, timeZone, businessHours.
|
|
166
|
-
//
|
|
167
|
-
// businessHours uses HH:MM 24-hour format per day of week.
|
|
168
|
-
// timeZone is an IANA timezone identifier (e.g. "America/Los_Angeles").
|
|
105
|
+
// Identity domain
|
|
169
106
|
// ---------------------------------------------------------------------------
|
|
170
|
-
export const identityExample = {
|
|
107
|
+
export const identityExample = defineOrganizationModel({
|
|
171
108
|
identity: {
|
|
172
|
-
mission: 'Automate the operational work that slows SMBs down
|
|
173
|
-
vision: '
|
|
109
|
+
mission: 'Automate the operational work that slows SMBs down.',
|
|
110
|
+
vision: 'Every small business has the operational leverage of a larger company.',
|
|
174
111
|
legalName: 'Acme Automation, LLC',
|
|
175
112
|
entityType: 'LLC',
|
|
176
|
-
jurisdiction: 'United States
|
|
113
|
+
jurisdiction: 'United States - Delaware',
|
|
177
114
|
industryCategory: 'Software / SaaS',
|
|
178
115
|
geographicFocus: 'North America',
|
|
179
116
|
timeZone: 'America/New_York',
|
|
180
|
-
clientBrief:
|
|
181
|
-
'Acme Automation serves SMBs in the US that are growing past founder-led operations. Primary buyers are ops leads and founders at 10\u201350 person companies. Warm via referral, short sales cycle (~2 weeks), monthly SaaS. The team has no dedicated engineering staff -- we own the full stack from automation design through deployment.',
|
|
117
|
+
clientBrief: 'Acme Automation serves SMBs growing past founder-led operations.',
|
|
182
118
|
businessHours: {
|
|
183
119
|
monday: { open: '09:00', close: '18:00' },
|
|
184
120
|
tuesday: { open: '09:00', close: '18:00' },
|
|
@@ -187,503 +123,99 @@ export const identityExample = {
|
|
|
187
123
|
friday: { open: '09:00', close: '17:00' }
|
|
188
124
|
}
|
|
189
125
|
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Minimal identity -- only mission + timezone filled in; all other fields empty
|
|
193
|
-
export const identityMinimalExample = {
|
|
194
|
-
identity: {
|
|
195
|
-
mission: 'Deliver premium digital marketing results for growth-stage brands.',
|
|
196
|
-
timeZone: 'America/Chicago'
|
|
197
|
-
}
|
|
198
|
-
}
|
|
126
|
+
})
|
|
199
127
|
|
|
200
128
|
// ---------------------------------------------------------------------------
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
// Decision #4 (BMC/VPC shape): each segment declares jobs-to-be-done, pains,
|
|
204
|
-
// gains, firmographics (industry, companySize, region), and a value proposition.
|
|
205
|
-
// Agents use segments for outreach targeting, scoring, and proposal personalization.
|
|
206
|
-
//
|
|
207
|
-
// targetSegmentIds on offerings cross-reference segment ids declared here.
|
|
208
|
-
// Bidirectional validation is enforced via OrganizationModelSchema.superRefine().
|
|
129
|
+
// Customers and offerings
|
|
209
130
|
// ---------------------------------------------------------------------------
|
|
210
|
-
export const
|
|
131
|
+
export const customersAndOfferingsExample = defineOrganizationModel({
|
|
211
132
|
customers: {
|
|
212
133
|
segments: [
|
|
213
134
|
{
|
|
214
135
|
id: 'segment-smb-agencies',
|
|
215
136
|
name: 'SMB Marketing Agencies',
|
|
216
|
-
description:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
pains: [
|
|
221
|
-
'Manual data entry across disconnected tools (Instantly, HubSpot, Notion)',
|
|
222
|
-
'Slow lead qualification that takes hours per batch',
|
|
223
|
-
'Inconsistent follow-up causing deal leakage at the qualification stage'
|
|
224
|
-
],
|
|
225
|
-
gains: [
|
|
226
|
-
'Automated pipelines that run overnight without oversight',
|
|
227
|
-
'Structured HITL handoffs that keep humans in the loop for high-stakes decisions',
|
|
228
|
-
'A unified view of every active client project and deal in one surface'
|
|
229
|
-
],
|
|
137
|
+
description: 'Growth-oriented digital agencies with 5-50 staff.',
|
|
138
|
+
jobsToBeDone: 'Run more client campaigns without growing headcount.',
|
|
139
|
+
pains: ['Manual data entry', 'Slow lead qualification'],
|
|
140
|
+
gains: ['Automated pipelines', 'Structured human review'],
|
|
230
141
|
firmographics: {
|
|
231
142
|
industry: 'Marketing / Digital Agency',
|
|
232
|
-
companySize: '5
|
|
143
|
+
companySize: '5-50',
|
|
233
144
|
region: 'North America'
|
|
234
145
|
},
|
|
235
|
-
valueProp:
|
|
236
|
-
'Elevasis automates the repetitive parts of agency operations so the team focuses on strategy and client relationships \u2014 not spreadsheets.'
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
id: 'segment-ecom-operators',
|
|
240
|
-
name: 'E-Commerce Operators',
|
|
241
|
-
description:
|
|
242
|
-
'Bootstrapped or VC-backed e-commerce brands running on Shopify or WooCommerce with 10\u2013100 SKUs.',
|
|
243
|
-
jobsToBeDone: 'Scale order operations and supplier communication without hiring a large ops team.',
|
|
244
|
-
pains: ['Supplier follow-up is manual and inconsistent', 'Returns processing is slow and error-prone'],
|
|
245
|
-
gains: ['Automated supplier status updates', 'Faster returns processing with fewer manual steps'],
|
|
246
|
-
firmographics: {
|
|
247
|
-
industry: 'E-Commerce / Retail',
|
|
248
|
-
companySize: '1\u201320',
|
|
249
|
-
region: 'Global'
|
|
250
|
-
},
|
|
251
|
-
valueProp:
|
|
252
|
-
'Elevasis turns supplier and returns operations into structured workflows that run without daily oversight.'
|
|
146
|
+
valueProp: 'Automate agency operations so the team focuses on strategy and clients.'
|
|
253
147
|
}
|
|
254
148
|
]
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// ---------------------------------------------------------------------------
|
|
259
|
-
// 8. Offerings domain -- products/services with pricing model and segment targeting
|
|
260
|
-
//
|
|
261
|
-
// Decision #5 (BMC Value Propositions shape): pricingModel enum values are
|
|
262
|
-
// 'one-time' | 'subscription' | 'usage-based' | 'custom'.
|
|
263
|
-
// targetSegmentIds must resolve to declared customers.segments[].id.
|
|
264
|
-
// deliveryFeatureId (optional) must resolve to a declared features[].id.
|
|
265
|
-
//
|
|
266
|
-
// Arrays are NOT deep-merged: if you declare offerings here, include ALL products
|
|
267
|
-
// you want. Do not rely on default products being preserved.
|
|
268
|
-
// ---------------------------------------------------------------------------
|
|
269
|
-
export const offeringsExample = {
|
|
149
|
+
},
|
|
270
150
|
offerings: {
|
|
271
151
|
products: [
|
|
272
152
|
{
|
|
273
153
|
id: 'product-starter',
|
|
274
154
|
name: 'Starter Automation Pack',
|
|
275
|
-
description: '
|
|
276
|
-
pricingModel: 'subscription'
|
|
155
|
+
description: 'Workflow bundle for lead enrichment, CRM follow-up, and project delivery automation.',
|
|
156
|
+
pricingModel: 'subscription',
|
|
277
157
|
price: 299,
|
|
278
158
|
currency: 'USD',
|
|
279
159
|
targetSegmentIds: ['segment-smb-agencies']
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
id: 'product-growth',
|
|
283
|
-
name: 'Growth Plan',
|
|
284
|
-
description:
|
|
285
|
-
'Full platform access including custom workflow builds, unlimited executions, and dedicated onboarding.',
|
|
286
|
-
pricingModel: 'subscription' as const,
|
|
287
|
-
price: 999,
|
|
288
|
-
currency: 'USD',
|
|
289
|
-
targetSegmentIds: ['segment-smb-agencies', 'segment-ecom-operators']
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
id: 'product-custom-build',
|
|
293
|
-
name: 'Custom Build',
|
|
294
|
-
description:
|
|
295
|
-
'Bespoke AI workflow design and deployment for organizations with unique operational requirements.',
|
|
296
|
-
pricingModel: 'custom' as const,
|
|
297
|
-
price: 0,
|
|
298
|
-
currency: 'USD',
|
|
299
|
-
targetSegmentIds: ['segment-smb-agencies']
|
|
300
160
|
}
|
|
301
161
|
]
|
|
302
162
|
}
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// Resource metadata example
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
export const workflowResourceMetadataExample = {
|
|
169
|
+
resourceId: 'lead-enrichment-workflow',
|
|
170
|
+
name: 'Lead Enrichment',
|
|
171
|
+
type: 'workflow' as const,
|
|
172
|
+
version: '1.0.0',
|
|
173
|
+
status: 'prod' as const,
|
|
174
|
+
links: [
|
|
175
|
+
{ nodeId: 'feature:sales.lead-gen', kind: 'operates-on' as const },
|
|
176
|
+
{ nodeId: 'integration:instantly', kind: 'uses' as const }
|
|
177
|
+
],
|
|
178
|
+
category: 'production' as const
|
|
303
179
|
}
|
|
304
180
|
|
|
305
181
|
// ---------------------------------------------------------------------------
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
// Decision #6 (EOS-inspired shape, plain language):
|
|
309
|
-
// Schema fields: id, title, responsibilities[], reportsToId?, heldBy?
|
|
310
|
-
// No EOS jargon: "title" not "seatTitle", "responsibilities" not "accountabilities".
|
|
311
|
-
// reportsToId cross-references another roles[].id; cycle detection is not enforced.
|
|
312
|
-
// heldBy is a free-form string (name or email) -- not validated against any user registry.
|
|
313
|
-
// Absence of reportsToId indicates a top-level role.
|
|
314
|
-
//
|
|
315
|
-
// Agents use roles for HITL routing, escalation, and approval-rights reasoning.
|
|
316
|
-
// "/configure roles" prompts the user to fill in this domain.
|
|
182
|
+
// Roles and goals
|
|
317
183
|
// ---------------------------------------------------------------------------
|
|
318
|
-
export const
|
|
184
|
+
export const rolesAndGoalsExample = defineOrganizationModel({
|
|
319
185
|
roles: {
|
|
320
186
|
roles: [
|
|
321
187
|
{
|
|
322
188
|
id: 'role-ceo',
|
|
323
189
|
title: 'CEO',
|
|
324
|
-
responsibilities: [
|
|
325
|
-
'Set company direction and approve strategic initiatives',
|
|
326
|
-
'Own enterprise-tier client relationships',
|
|
327
|
-
'Final approver for all platform deployments and budget over $5K'
|
|
328
|
-
],
|
|
190
|
+
responsibilities: ['Set company direction', 'Approve strategic initiatives'],
|
|
329
191
|
heldBy: 'Alex Johnson'
|
|
330
192
|
},
|
|
331
193
|
{
|
|
332
194
|
id: 'role-head-of-ops',
|
|
333
195
|
title: 'Head of Operations',
|
|
334
|
-
responsibilities: [
|
|
335
|
-
'Manage day-to-day workflow deployments and execution health',
|
|
336
|
-
'Review and approve items in the HITL queue',
|
|
337
|
-
'Escalate platform failures to CEO within 2 hours'
|
|
338
|
-
],
|
|
196
|
+
responsibilities: ['Manage workflow deployments', 'Review human-in-the-loop queue'],
|
|
339
197
|
reportsToId: 'role-ceo',
|
|
340
198
|
heldBy: 'Jordan Lee'
|
|
341
|
-
},
|
|
342
|
-
{
|
|
343
|
-
id: 'role-sales-lead',
|
|
344
|
-
title: 'Sales Lead',
|
|
345
|
-
responsibilities: [
|
|
346
|
-
'Qualify inbound leads and manage the CRM pipeline',
|
|
347
|
-
'Send proposals and follow up with prospects',
|
|
348
|
-
'Coordinate with ops on client onboarding timelines'
|
|
349
|
-
],
|
|
350
|
-
reportsToId: 'role-ceo',
|
|
351
|
-
heldBy: 'sam@acme.io'
|
|
352
|
-
}
|
|
353
|
-
]
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Minimal roles -- solo founder, no reports-to
|
|
358
|
-
export const rolesSoloFounderExample = {
|
|
359
|
-
roles: {
|
|
360
|
-
roles: [
|
|
361
|
-
{
|
|
362
|
-
id: 'role-founder',
|
|
363
|
-
title: 'Founder',
|
|
364
|
-
responsibilities: ['Own all decisions', 'Review all HITL queue items', 'Approve all client deliverables'],
|
|
365
|
-
heldBy: 'founder@mycompany.io'
|
|
366
199
|
}
|
|
367
200
|
]
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// ---------------------------------------------------------------------------
|
|
372
|
-
// 10. Goals domain -- quarterly objectives with plain-language measurable outcomes
|
|
373
|
-
//
|
|
374
|
-
// Decision #7 (OKR-shaped, plain-language rendering):
|
|
375
|
-
// Schema fields: objectives[].{ id, description, periodStart, periodEnd, keyResults[] }
|
|
376
|
-
// keyResults[].{ id, description, targetMetric, currentValue, targetValue? }
|
|
377
|
-
// periodStart / periodEnd are ISO 8601 date strings (YYYY-MM-DD).
|
|
378
|
-
// periodEnd must be strictly after periodStart (enforced by superRefine).
|
|
379
|
-
//
|
|
380
|
-
// IMPORTANT naming convention: the schema uses "objectives" and "keyResults"
|
|
381
|
-
// internally for OKR-tooling compatibility. All user-facing labels and
|
|
382
|
-
// /configure prompts say "goals" and "measurable outcomes" -- never "OKR",
|
|
383
|
-
// "objective", or "key result".
|
|
384
|
-
// ---------------------------------------------------------------------------
|
|
385
|
-
export const goalsExample = {
|
|
201
|
+
},
|
|
386
202
|
goals: {
|
|
387
203
|
objectives: [
|
|
388
204
|
{
|
|
389
205
|
id: 'goal-grow-arr-q2-2026',
|
|
390
|
-
description: 'Grow monthly recurring revenue
|
|
206
|
+
description: 'Grow monthly recurring revenue by end of Q2 2026.',
|
|
391
207
|
periodStart: '2026-04-01',
|
|
392
208
|
periodEnd: '2026-06-30',
|
|
393
209
|
keyResults: [
|
|
394
210
|
{
|
|
395
211
|
id: 'kr-mrr-10k',
|
|
396
212
|
description: 'Reach $10K MRR',
|
|
397
|
-
targetMetric: 'Monthly recurring revenue
|
|
213
|
+
targetMetric: 'Monthly recurring revenue',
|
|
398
214
|
currentValue: 2800,
|
|
399
215
|
targetValue: 10000
|
|
400
|
-
},
|
|
401
|
-
{
|
|
402
|
-
id: 'kr-customers-15',
|
|
403
|
-
description: 'Acquire 15 paying customers',
|
|
404
|
-
targetMetric: 'Paying customer count',
|
|
405
|
-
currentValue: 4,
|
|
406
|
-
targetValue: 15
|
|
407
|
-
}
|
|
408
|
-
]
|
|
409
|
-
},
|
|
410
|
-
{
|
|
411
|
-
id: 'goal-launch-growth-tier-q2-2026',
|
|
412
|
-
description: 'Launch Growth Plan tier and land 3 customers on it by end of Q2 2026.',
|
|
413
|
-
periodStart: '2026-05-01',
|
|
414
|
-
periodEnd: '2026-06-30',
|
|
415
|
-
keyResults: [
|
|
416
|
-
{
|
|
417
|
-
id: 'kr-growth-launched',
|
|
418
|
-
description: 'Growth Plan live and purchasable',
|
|
419
|
-
targetMetric: 'Launch milestone (binary)',
|
|
420
|
-
currentValue: 0,
|
|
421
|
-
targetValue: 1
|
|
422
|
-
},
|
|
423
|
-
{
|
|
424
|
-
id: 'kr-growth-customers',
|
|
425
|
-
description: '3 customers on Growth tier',
|
|
426
|
-
targetMetric: 'Growth-tier customer count',
|
|
427
|
-
currentValue: 0,
|
|
428
|
-
targetValue: 3
|
|
429
216
|
}
|
|
430
217
|
]
|
|
431
218
|
}
|
|
432
219
|
]
|
|
433
220
|
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Directional goal -- no hard targetValue
|
|
437
|
-
export const goalsDirectionalExample = {
|
|
438
|
-
goals: {
|
|
439
|
-
objectives: [
|
|
440
|
-
{
|
|
441
|
-
id: 'goal-reduce-churn-q3-2026',
|
|
442
|
-
description: 'Reduce monthly churn through better onboarding and proactive success check-ins.',
|
|
443
|
-
periodStart: '2026-07-01',
|
|
444
|
-
periodEnd: '2026-09-30',
|
|
445
|
-
keyResults: [
|
|
446
|
-
{
|
|
447
|
-
id: 'kr-onboarding-nps',
|
|
448
|
-
description: 'Improve onboarding satisfaction',
|
|
449
|
-
targetMetric: 'Onboarding NPS score',
|
|
450
|
-
currentValue: 32
|
|
451
|
-
// targetValue omitted -- directional goal, no hard number yet
|
|
452
|
-
}
|
|
453
|
-
]
|
|
454
|
-
}
|
|
455
|
-
]
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// ---------------------------------------------------------------------------
|
|
460
|
-
// 11. ResourceMappings with techStack extension
|
|
461
|
-
//
|
|
462
|
-
// Decision #4 (org-reality): techStack EXTENDS the resourceMappings subsection.
|
|
463
|
-
// `techStack` is an optional field on each ResourceMapping entry. Fields:
|
|
464
|
-
// platform -- external SaaS name (e.g. "HubSpot", "Stripe", "Notion")
|
|
465
|
-
// purpose -- free-form description of what the integration does
|
|
466
|
-
// credentialStatus -- 'configured' | 'pending' | 'expired' | 'missing'
|
|
467
|
-
// isSystemOfRecord -- boolean; true if this is the primary SoR for its domain
|
|
468
|
-
//
|
|
469
|
-
// ResourceMapping entries with no `techStack` parse cleanly (backward-compat).
|
|
470
|
-
// ---------------------------------------------------------------------------
|
|
471
|
-
export const resourceMappingsWithTechStackExample = {
|
|
472
|
-
resourceMappings: [
|
|
473
|
-
{
|
|
474
|
-
id: 'integration-attio',
|
|
475
|
-
label: 'Attio CRM',
|
|
476
|
-
resourceId: 'my-org/attio-sync',
|
|
477
|
-
resourceType: 'integration' as const,
|
|
478
|
-
featureIds: [],
|
|
479
|
-
entityIds: [],
|
|
480
|
-
surfaceIds: [],
|
|
481
|
-
capabilityIds: [],
|
|
482
|
-
techStack: {
|
|
483
|
-
platform: 'Attio',
|
|
484
|
-
purpose: 'System of record for contacts and deals; synced from the CRM pipeline on stage change',
|
|
485
|
-
credentialStatus: 'configured' as const,
|
|
486
|
-
isSystemOfRecord: true
|
|
487
|
-
}
|
|
488
|
-
},
|
|
489
|
-
{
|
|
490
|
-
id: 'integration-stripe',
|
|
491
|
-
label: 'Stripe',
|
|
492
|
-
resourceId: 'my-org/stripe-billing',
|
|
493
|
-
resourceType: 'integration' as const,
|
|
494
|
-
featureIds: [],
|
|
495
|
-
entityIds: [],
|
|
496
|
-
surfaceIds: [],
|
|
497
|
-
capabilityIds: [],
|
|
498
|
-
techStack: {
|
|
499
|
-
platform: 'Stripe',
|
|
500
|
-
purpose: 'Subscription billing and invoice generation for all products',
|
|
501
|
-
credentialStatus: 'configured' as const,
|
|
502
|
-
isSystemOfRecord: true
|
|
503
|
-
}
|
|
504
|
-
},
|
|
505
|
-
{
|
|
506
|
-
id: 'integration-instantly',
|
|
507
|
-
label: 'Instantly.ai',
|
|
508
|
-
resourceId: 'my-org/instantly-campaigns',
|
|
509
|
-
resourceType: 'integration' as const,
|
|
510
|
-
featureIds: [],
|
|
511
|
-
entityIds: [],
|
|
512
|
-
surfaceIds: [],
|
|
513
|
-
capabilityIds: [],
|
|
514
|
-
techStack: {
|
|
515
|
-
platform: 'Instantly.ai',
|
|
516
|
-
purpose: 'Cold email outreach and campaign management for lead-gen sequences',
|
|
517
|
-
credentialStatus: 'pending' as const,
|
|
518
|
-
isSystemOfRecord: false
|
|
519
|
-
}
|
|
520
|
-
},
|
|
521
|
-
{
|
|
522
|
-
id: 'workflow-lead-enrichment',
|
|
523
|
-
label: 'Lead Enrichment Workflow',
|
|
524
|
-
resourceId: 'my-org/lead-enrichment-workflow',
|
|
525
|
-
resourceType: 'workflow' as const,
|
|
526
|
-
featureIds: [PROSPECTING_FEATURE_ID],
|
|
527
|
-
entityIds: ['leadgen.company'],
|
|
528
|
-
surfaceIds: ['lead-gen.lists'],
|
|
529
|
-
capabilityIds: []
|
|
530
|
-
// No techStack -- this is a platform workflow, not an external SaaS
|
|
531
|
-
}
|
|
532
|
-
]
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
// ---------------------------------------------------------------------------
|
|
536
|
-
// 12. Statuses domain -- per-org label customization of the platform status registry
|
|
537
|
-
//
|
|
538
|
-
// Decision #9 (vibe): statuses shape is { id, label, semanticClass, category? }.
|
|
539
|
-
// semanticClass enum: 'delivery.task' | 'delivery.project' | 'delivery.milestone'
|
|
540
|
-
// | 'queue' | 'execution' | 'schedule' | 'schedule.run' | 'request'
|
|
541
|
-
//
|
|
542
|
-
// The `entries` array REPLACES the default status registry (arrays are not deep-merged).
|
|
543
|
-
// To keep all platform defaults and only relabel a subset, include the full registry.
|
|
544
|
-
// See DEFAULT_ORGANIZATION_MODEL_STATUSES in @elevasis/core/organization-model.
|
|
545
|
-
//
|
|
546
|
-
// Pattern A -- minimal, override only a few labels (spread defaults + your changes):
|
|
547
|
-
// ---------------------------------------------------------------------------
|
|
548
|
-
export const statusesMinimalOverrideExample = {
|
|
549
|
-
// This shape shows only the entries you'd customise; in practice you must include
|
|
550
|
-
// the full DEFAULT_ORGANIZATION_MODEL_STATUSES.entries spread for all other statuses.
|
|
551
|
-
statuses: {
|
|
552
|
-
entries: [
|
|
553
|
-
// Relabeled to match agency vocabulary
|
|
554
|
-
{ id: 'delivery.task.planned', label: 'Queued', semanticClass: 'delivery.task' as const, category: 'delivery' },
|
|
555
|
-
{
|
|
556
|
-
id: 'delivery.task.in_progress',
|
|
557
|
-
label: 'In Progress',
|
|
558
|
-
semanticClass: 'delivery.task' as const,
|
|
559
|
-
category: 'delivery'
|
|
560
|
-
},
|
|
561
|
-
{
|
|
562
|
-
id: 'delivery.task.revision_requested',
|
|
563
|
-
label: 'Needs Rework',
|
|
564
|
-
semanticClass: 'delivery.task' as const,
|
|
565
|
-
category: 'delivery'
|
|
566
|
-
},
|
|
567
|
-
{
|
|
568
|
-
id: 'delivery.task.completed',
|
|
569
|
-
label: 'Done',
|
|
570
|
-
semanticClass: 'delivery.task' as const,
|
|
571
|
-
category: 'delivery'
|
|
572
|
-
},
|
|
573
|
-
// Queue relabeled with client-facing language
|
|
574
|
-
{ id: 'queue.pending', label: 'Awaiting Review', semanticClass: 'queue' as const, category: 'queue' },
|
|
575
|
-
{ id: 'queue.completed', label: 'Resolved', semanticClass: 'queue' as const, category: 'queue' }
|
|
576
|
-
]
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
// ---------------------------------------------------------------------------
|
|
581
|
-
// 13. Operations domain -- runtime entity catalog
|
|
582
|
-
//
|
|
583
|
-
// Decision #10 (vibe): operations catalogs HITL queue, sessions, executions,
|
|
584
|
-
// notifications, schedules as first-class model citizens.
|
|
585
|
-
// semanticClass enum: 'queue' | 'executions' | 'sessions' | 'notifications' | 'schedules'
|
|
586
|
-
// supportedStatusSemanticClass links back to the statuses domain for vibe rendering.
|
|
587
|
-
//
|
|
588
|
-
// Each entry represents one stateful runtime entity the org works with.
|
|
589
|
-
// Agents use this to answer Query intents ("what's pending?", "what's running?")
|
|
590
|
-
// without hardcoding service lookups. The `featureId` field routes the entity
|
|
591
|
-
// to the correct feature surface.
|
|
592
|
-
// ---------------------------------------------------------------------------
|
|
593
|
-
export const operationsExample = {
|
|
594
|
-
operations: {
|
|
595
|
-
entries: [
|
|
596
|
-
{
|
|
597
|
-
id: 'operations.queue',
|
|
598
|
-
label: 'Review Queue',
|
|
599
|
-
semanticClass: 'queue' as const,
|
|
600
|
-
featureId: 'operations',
|
|
601
|
-
supportedStatusSemanticClass: ['queue']
|
|
602
|
-
},
|
|
603
|
-
{
|
|
604
|
-
id: 'operations.executions',
|
|
605
|
-
label: 'Workflow Runs',
|
|
606
|
-
semanticClass: 'executions' as const,
|
|
607
|
-
featureId: 'operations',
|
|
608
|
-
supportedStatusSemanticClass: ['execution']
|
|
609
|
-
},
|
|
610
|
-
{
|
|
611
|
-
id: 'operations.sessions',
|
|
612
|
-
label: 'Agent Sessions',
|
|
613
|
-
semanticClass: 'sessions' as const,
|
|
614
|
-
featureId: 'operations'
|
|
615
|
-
},
|
|
616
|
-
{
|
|
617
|
-
id: 'operations.notifications',
|
|
618
|
-
label: 'Platform Alerts',
|
|
619
|
-
semanticClass: 'notifications' as const,
|
|
620
|
-
featureId: 'monitoring'
|
|
621
|
-
},
|
|
622
|
-
{
|
|
623
|
-
id: 'operations.schedules',
|
|
624
|
-
label: 'Scheduled Tasks',
|
|
625
|
-
semanticClass: 'schedules' as const,
|
|
626
|
-
featureId: 'operations',
|
|
627
|
-
supportedStatusSemanticClass: ['schedule', 'schedule.run']
|
|
628
|
-
}
|
|
629
|
-
]
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// ---------------------------------------------------------------------------
|
|
634
|
-
// 14. Open placement extension -- navigation group with a custom placement ID
|
|
635
|
-
//
|
|
636
|
-
// Decision #12 (vibe): `surfaceType` and `resourceType` are closed enums
|
|
637
|
-
// (UI/runtime invariants). `placement` is open via extension pattern.
|
|
638
|
-
//
|
|
639
|
-
// Core defines three canonical placement values: 'primary', 'secondary', 'bottom'.
|
|
640
|
-
// NavigationGroupSchema uses z.string() for `placement`, so any string is valid
|
|
641
|
-
// at the schema level -- no changes to @elevasis/core required.
|
|
642
|
-
//
|
|
643
|
-
// To introduce a new placement ID:
|
|
644
|
-
// 1. Add a navigation group with the new placement string (shown below).
|
|
645
|
-
// 2. Add matching rendering logic in the UI feature shell.
|
|
646
|
-
// 3. Document the new placement in this file so the vibe agent can narrate it.
|
|
647
|
-
//
|
|
648
|
-
// The UI feature shell renders groups in document order within each placement bucket.
|
|
649
|
-
// A custom placement that the UI doesn't recognize will be silently omitted from
|
|
650
|
-
// the sidebar unless matching render logic is added.
|
|
651
|
-
// ---------------------------------------------------------------------------
|
|
652
|
-
export const openPlacementExample = {
|
|
653
|
-
navigation: {
|
|
654
|
-
// Extend existing groups by spreading DEFAULT_ORGANIZATION_MODEL.navigation.groups
|
|
655
|
-
// and appending the custom group. Example (not runnable here since it needs the import):
|
|
656
|
-
//
|
|
657
|
-
// groups: [
|
|
658
|
-
// ...DEFAULT_ORGANIZATION_MODEL.navigation.groups,
|
|
659
|
-
// {
|
|
660
|
-
// id: 'spotlight-pinned',
|
|
661
|
-
// label: 'Pinned',
|
|
662
|
-
// placement: 'spotlight', // <-- custom placement, open string
|
|
663
|
-
// surfaceIds: ['crm.pipeline']
|
|
664
|
-
// }
|
|
665
|
-
// ]
|
|
666
|
-
//
|
|
667
|
-
// Standalone shape for illustration (single group, no spread):
|
|
668
|
-
groups: [
|
|
669
|
-
{
|
|
670
|
-
id: 'spotlight-pinned',
|
|
671
|
-
label: 'Pinned',
|
|
672
|
-
placement: 'spotlight', // custom placement ID -- valid per schema (z.string())
|
|
673
|
-
surfaceIds: ['crm.pipeline']
|
|
674
|
-
},
|
|
675
|
-
{
|
|
676
|
-
id: 'contextual-tools',
|
|
677
|
-
label: 'Tools',
|
|
678
|
-
placement: 'contextual', // another custom placement
|
|
679
|
-
surfaceIds: ['operations.command-queue', 'operations.task-scheduler']
|
|
680
|
-
}
|
|
681
|
-
]
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
// NOTE on the open-placement example: because this overrides `groups` without
|
|
686
|
-
// spreading DEFAULT_ORGANIZATION_MODEL.navigation.groups, navigation groups from
|
|
687
|
-
// the default model (primary-workspace, primary-operations, etc.) would be lost
|
|
688
|
-
// at runtime. In practice, always spread the defaults unless you are intentionally
|
|
689
|
-
// replacing the entire group list. This example isolates the shape only.
|
|
221
|
+
})
|