@elevasis/core 0.22.0 → 0.23.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 (112) hide show
  1. package/dist/index.d.ts +2330 -2391
  2. package/dist/index.js +2322 -1147
  3. package/dist/knowledge/index.d.ts +702 -1136
  4. package/dist/knowledge/index.js +9 -9
  5. package/dist/organization-model/index.d.ts +2330 -2391
  6. package/dist/organization-model/index.js +2322 -1147
  7. package/dist/test-utils/index.d.ts +703 -1106
  8. package/dist/test-utils/index.js +1735 -1089
  9. package/package.json +1 -1
  10. package/src/__tests__/template-core-compatibility.test.ts +11 -79
  11. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +360 -98
  12. package/src/business/acquisition/api-schemas.test.ts +2 -2
  13. package/src/business/acquisition/api-schemas.ts +7 -9
  14. package/src/business/acquisition/build-templates.test.ts +4 -4
  15. package/src/business/acquisition/build-templates.ts +72 -30
  16. package/src/business/acquisition/crm-state-actions.test.ts +13 -11
  17. package/src/business/acquisition/types.ts +7 -3
  18. package/src/execution/engine/agent/core/types.ts +1 -1
  19. package/src/execution/engine/workflow/types.ts +2 -2
  20. package/src/knowledge/README.md +8 -7
  21. package/src/knowledge/__tests__/queries.test.ts +74 -73
  22. package/src/knowledge/format.ts +10 -9
  23. package/src/knowledge/index.ts +1 -1
  24. package/src/knowledge/published.ts +1 -1
  25. package/src/knowledge/queries.ts +26 -25
  26. package/src/organization-model/README.md +66 -26
  27. package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -0
  28. package/src/organization-model/__tests__/defaults.test.ts +72 -98
  29. package/src/organization-model/__tests__/domains/actions.test.ts +56 -0
  30. package/src/organization-model/__tests__/domains/customers.test.ts +299 -295
  31. package/src/organization-model/__tests__/domains/entities.test.ts +56 -0
  32. package/src/organization-model/__tests__/domains/goals.test.ts +493 -479
  33. package/src/organization-model/__tests__/domains/identity.test.ts +280 -279
  34. package/src/organization-model/__tests__/domains/navigation.test.ts +268 -212
  35. package/src/organization-model/__tests__/domains/offerings.test.ts +414 -419
  36. package/src/organization-model/__tests__/domains/policies.test.ts +323 -0
  37. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +271 -271
  38. package/src/organization-model/__tests__/domains/resources.test.ts +159 -37
  39. package/src/organization-model/__tests__/domains/roles.test.ts +147 -86
  40. package/src/organization-model/__tests__/domains/statuses.test.ts +246 -243
  41. package/src/organization-model/__tests__/domains/systems.test.ts +67 -51
  42. package/src/organization-model/__tests__/flatten-additive-merge.test.ts +361 -0
  43. package/src/organization-model/__tests__/foundation.test.ts +74 -102
  44. package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -0
  45. package/src/organization-model/__tests__/graph.test.ts +899 -71
  46. package/src/organization-model/__tests__/knowledge.test.ts +173 -52
  47. package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -0
  48. package/src/organization-model/__tests__/migration-helpers.test.ts +591 -0
  49. package/src/organization-model/__tests__/prospecting-ssot.test.ts +36 -27
  50. package/src/organization-model/__tests__/recursive-system-schema.test.ts +520 -0
  51. package/src/organization-model/__tests__/resolve.test.ts +174 -23
  52. package/src/organization-model/__tests__/schema.test.ts +291 -114
  53. package/src/organization-model/__tests__/surface-projection.test.ts +207 -97
  54. package/src/organization-model/catalogs/lead-gen.ts +144 -0
  55. package/src/organization-model/content-kinds/config.ts +36 -0
  56. package/src/organization-model/content-kinds/index.ts +74 -0
  57. package/src/organization-model/content-kinds/pipeline.ts +68 -0
  58. package/src/organization-model/content-kinds/registry.ts +44 -0
  59. package/src/organization-model/content-kinds/status.ts +71 -0
  60. package/src/organization-model/content-kinds/template.ts +83 -0
  61. package/src/organization-model/content-kinds/types.ts +117 -0
  62. package/src/organization-model/contracts.ts +13 -3
  63. package/src/organization-model/defaults.ts +488 -96
  64. package/src/organization-model/domains/actions.ts +239 -0
  65. package/src/organization-model/domains/customers.ts +78 -75
  66. package/src/organization-model/domains/entities.ts +144 -0
  67. package/src/organization-model/domains/goals.ts +83 -80
  68. package/src/organization-model/domains/knowledge.ts +74 -16
  69. package/src/organization-model/domains/navigation.ts +107 -384
  70. package/src/organization-model/domains/offerings.ts +71 -66
  71. package/src/organization-model/domains/policies.ts +102 -0
  72. package/src/organization-model/domains/projects.ts +14 -48
  73. package/src/organization-model/domains/prospecting.ts +62 -181
  74. package/src/organization-model/domains/resources.ts +81 -24
  75. package/src/organization-model/domains/roles.ts +13 -10
  76. package/src/organization-model/domains/sales.ts +10 -219
  77. package/src/organization-model/domains/shared.ts +57 -57
  78. package/src/organization-model/domains/statuses.ts +339 -130
  79. package/src/organization-model/domains/systems.ts +186 -29
  80. package/src/organization-model/foundation.ts +54 -67
  81. package/src/organization-model/graph/build.ts +682 -54
  82. package/src/organization-model/graph/link.ts +1 -1
  83. package/src/organization-model/graph/schema.ts +24 -9
  84. package/src/organization-model/graph/types.ts +20 -7
  85. package/src/organization-model/helpers.ts +231 -26
  86. package/src/organization-model/index.ts +116 -5
  87. package/src/organization-model/migration-helpers.ts +249 -0
  88. package/src/organization-model/organization-graph.mdx +16 -15
  89. package/src/organization-model/organization-model.mdx +89 -41
  90. package/src/organization-model/published.ts +120 -18
  91. package/src/organization-model/resolve.ts +117 -54
  92. package/src/organization-model/schema.ts +561 -140
  93. package/src/organization-model/surface-projection.ts +116 -122
  94. package/src/organization-model/types.ts +102 -21
  95. package/src/platform/constants/versions.ts +1 -1
  96. package/src/platform/registry/__tests__/command-view.test.ts +6 -8
  97. package/src/platform/registry/__tests__/resource-link.test.ts +13 -8
  98. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +16 -31
  99. package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -0
  100. package/src/platform/registry/__tests__/resource-registry.test.ts +9 -7
  101. package/src/platform/registry/__tests__/validation.test.ts +15 -11
  102. package/src/platform/registry/resource-registry.ts +20 -8
  103. package/src/platform/registry/serialization.ts +7 -7
  104. package/src/platform/registry/types.ts +3 -3
  105. package/src/platform/registry/validation.ts +17 -15
  106. package/src/reference/_generated/contracts.md +362 -99
  107. package/src/reference/glossary.md +18 -18
  108. package/src/supabase/database.types.ts +60 -0
  109. package/src/test-utils/test-utils.test.ts +1 -6
  110. package/src/organization-model/__tests__/domains/operations.test.ts +0 -203
  111. package/src/organization-model/domains/features.ts +0 -31
  112. package/src/organization-model/domains/operations.ts +0 -85
@@ -1,7 +1,9 @@
1
1
  import { describe, expect, it } from 'vitest'
2
+ import { ZodError } from 'zod'
2
3
  import { bindResourceDescriptor } from '../../../platform/registry/types'
3
4
  import {
4
5
  DEFAULT_ORGANIZATION_MODEL_RESOURCES,
6
+ EventIdSchema,
5
7
  ResourceEntrySchema,
6
8
  ResourceKindSchema,
7
9
  ResourcesDomainSchema,
@@ -12,6 +14,7 @@ import { resolveOrganizationModel } from '../../resolve'
12
14
 
13
15
  const VALID_SYSTEM = {
14
16
  id: 'sys.lead-gen',
17
+ order: 10,
15
18
  title: 'Lead Generation Pipeline',
16
19
  description: 'Coordinates prospecting, enrichment, qualification, and outreach preparation.',
17
20
  kind: 'operational' as const,
@@ -20,55 +23,81 @@ const VALID_SYSTEM = {
20
23
 
21
24
  const VALID_ROLE = {
22
25
  id: 'role.sales-ops',
26
+ order: 10,
23
27
  title: 'Sales Ops'
24
28
  }
25
29
 
26
30
  const WORKFLOW_RESOURCE = {
27
31
  id: 'LGN-01-company-scrape',
32
+ order: 10,
28
33
  kind: 'workflow' as const,
29
- systemId: 'sys.lead-gen',
34
+ systemPath: 'sys.lead-gen',
30
35
  ownerRoleId: 'role.sales-ops',
31
36
  status: 'active' as const,
32
- capabilityKey: 'lead-gen.company.scrape'
37
+ actionKey: 'lead-gen.company.scrape'
38
+ }
39
+
40
+ const WORKFLOW_EVENT_EMISSION = {
41
+ eventKey: 'processed',
42
+ label: 'Processed',
43
+ payloadSchema: 'leadgen.company.processed',
44
+ lifecycle: 'active' as const
33
45
  }
34
46
 
35
47
  const AGENT_RESOURCE = {
36
48
  id: 'command-center-assistant',
49
+ order: 20,
37
50
  kind: 'agent' as const,
38
- systemId: 'sys.lead-gen',
51
+ systemPath: 'sys.lead-gen',
39
52
  ownerRoleId: 'role.sales-ops',
40
53
  status: 'active' as const,
41
- agentKind: 'system' as const,
54
+ agentKind: 'platform' as const,
42
55
  actsAsRoleId: 'role.sales-ops',
43
- sessionCapable: true
56
+ sessionCapable: true,
57
+ invocations: [{ kind: 'slash-command' as const, command: '/work handoff' }]
44
58
  }
45
59
 
46
60
  const INTEGRATION_RESOURCE = {
47
61
  id: 'attio-crm',
62
+ order: 30,
48
63
  kind: 'integration' as const,
49
- systemId: 'sys.lead-gen',
64
+ systemPath: 'sys.lead-gen',
50
65
  ownerRoleId: 'role.sales-ops',
51
66
  status: 'active' as const,
52
67
  provider: 'attio'
53
68
  }
54
69
 
55
- function resolveWithResources(resources: unknown[]) {
70
+ const SCRIPT_RESOURCE = {
71
+ id: 'leadgen-backfill-script',
72
+ order: 40,
73
+ kind: 'script' as const,
74
+ systemPath: 'sys.lead-gen',
75
+ ownerRoleId: 'role.sales-ops',
76
+ status: 'active' as const,
77
+ language: 'typescript' as const,
78
+ source: {
79
+ file: 'scripts/leadgen/backfill.ts'
80
+ }
81
+ }
82
+
83
+ function resolveWithResources(resources: Record<string, unknown>) {
56
84
  return resolveOrganizationModel({
57
- roles: { roles: [VALID_ROLE] },
58
- systems: { systems: [VALID_SYSTEM] },
59
- resources: { entries: resources }
85
+ roles: { 'role.sales-ops': VALID_ROLE },
86
+ systems: { 'sys.lead-gen': VALID_SYSTEM },
87
+ resources: resources as Record<string, typeof WORKFLOW_RESOURCE>
60
88
  })
61
89
  }
62
90
 
63
91
  describe('ResourceEntrySchema', () => {
64
- it('accepts workflow, agent, and integration descriptors with required systemId', () => {
92
+ it('accepts workflow, agent, integration, and script descriptors with required systemPath', () => {
65
93
  expect(ResourceEntrySchema.safeParse(WORKFLOW_RESOURCE).success).toBe(true)
66
94
  expect(ResourceEntrySchema.safeParse(AGENT_RESOURCE).success).toBe(true)
67
95
  expect(ResourceEntrySchema.safeParse(INTEGRATION_RESOURCE).success).toBe(true)
96
+ expect(ResourceEntrySchema.safeParse(SCRIPT_RESOURCE).success).toBe(true)
68
97
  })
69
98
 
70
- it('rejects resources without a systemId', () => {
71
- const { systemId: _systemId, ...resourceWithoutSystem } = WORKFLOW_RESOURCE
99
+ it('rejects resources without a systemPath', () => {
100
+ const { systemPath: _systemPath, ...resourceWithoutSystem } = WORKFLOW_RESOURCE
72
101
 
73
102
  expect(ResourceEntrySchema.safeParse(resourceWithoutSystem).success).toBe(false)
74
103
  })
@@ -77,7 +106,7 @@ describe('ResourceEntrySchema', () => {
77
106
  expect(
78
107
  ResourceEntrySchema.safeParse({
79
108
  ...WORKFLOW_RESOURCE,
80
- systemId: ['sys.lead-gen', 'sys.crm']
109
+ systemPath: ['sys.lead-gen', 'sys.crm']
81
110
  }).success
82
111
  ).toBe(false)
83
112
  })
@@ -90,10 +119,70 @@ describe('ResourceEntrySchema', () => {
90
119
  }).success
91
120
  ).toBe(false)
92
121
  })
122
+
123
+ it('defaults agent invocations and accepts slash-command orchestration entries', () => {
124
+ const result = ResourceEntrySchema.safeParse({
125
+ ...AGENT_RESOURCE,
126
+ invocations: undefined
127
+ })
128
+
129
+ expect(result.success).toBe(true)
130
+ if (result.success) {
131
+ expect(result.data.kind).toBe('agent')
132
+ if (result.data.kind === 'agent') {
133
+ expect(result.data.invocations).toEqual([])
134
+ }
135
+ }
136
+
137
+ expect(ResourceEntrySchema.safeParse(AGENT_RESOURCE).success).toBe(true)
138
+ })
139
+
140
+ it('rejects malformed agent invocation entries', () => {
141
+ expect(
142
+ ResourceEntrySchema.safeParse({
143
+ ...AGENT_RESOURCE,
144
+ invocations: [{ kind: 'slash-command', command: 'work handoff' }]
145
+ }).success
146
+ ).toBe(false)
147
+ })
148
+
149
+ it('accepts event emissions on workflow and agent resources only', () => {
150
+ const workflowResult = ResourceEntrySchema.safeParse({
151
+ ...WORKFLOW_RESOURCE,
152
+ emits: [WORKFLOW_EVENT_EMISSION]
153
+ })
154
+ const agentResult = ResourceEntrySchema.safeParse({
155
+ ...AGENT_RESOURCE,
156
+ emits: [{ eventKey: 'approved', label: 'Approved' }]
157
+ })
158
+ const integrationResult = ResourceEntrySchema.safeParse({
159
+ ...INTEGRATION_RESOURCE,
160
+ emits: [{ eventKey: 'received', label: 'Received' }]
161
+ })
162
+
163
+ expect(workflowResult.success).toBe(true)
164
+ expect(agentResult.success).toBe(true)
165
+ expect(integrationResult.success).toBe(true)
166
+ if (workflowResult.success && workflowResult.data.kind === 'workflow') {
167
+ expect(workflowResult.data.emits).toEqual([WORKFLOW_EVENT_EMISSION])
168
+ }
169
+ if (agentResult.success && agentResult.data.kind === 'agent') {
170
+ expect(agentResult.data.emits).toEqual([{ eventKey: 'approved', label: 'Approved' }])
171
+ }
172
+ if (integrationResult.success && integrationResult.data.kind === 'integration') {
173
+ expect('emits' in integrationResult.data).toBe(false)
174
+ }
175
+ })
176
+
177
+ it('validates derived event id format', () => {
178
+ expect(EventIdSchema.parse('crm.deal:won')).toBe('crm.deal:won')
179
+ expect(EventIdSchema.parse('LGN-01-company-scrape:processed')).toBe('LGN-01-company-scrape:processed')
180
+ expect(() => EventIdSchema.parse('crm.deal.won')).toThrow()
181
+ })
93
182
  })
94
183
 
95
184
  describe('ResourcesDomainSchema', () => {
96
- it('defaults resources to an empty array when omitted', () => {
185
+ it('defaults resources to an empty record when omitted', () => {
97
186
  const result = ResourcesDomainSchema.safeParse({})
98
187
 
99
188
  expect(result.success).toBe(true)
@@ -102,60 +191,93 @@ describe('ResourcesDomainSchema', () => {
102
191
  }
103
192
  })
104
193
 
105
- it.each(['workflow', 'agent', 'integration'] as const)('accepts kind "%s"', (kind) => {
194
+ it.each(['workflow', 'agent', 'integration', 'script'] as const)('accepts kind "%s"', (kind) => {
106
195
  expect(ResourceKindSchema.safeParse(kind).success).toBe(true)
107
196
  })
108
197
  })
109
198
 
110
199
  describe('resolveOrganizationModel - resources domain integration', () => {
111
200
  it('accepts valid resources with system and role references', () => {
112
- const model = resolveWithResources([WORKFLOW_RESOURCE, AGENT_RESOURCE, INTEGRATION_RESOURCE])
201
+ const model = resolveWithResources({
202
+ 'LGN-01-company-scrape': WORKFLOW_RESOURCE,
203
+ 'command-center-assistant': AGENT_RESOURCE,
204
+ 'attio-crm': INTEGRATION_RESOURCE,
205
+ 'leadgen-backfill-script': SCRIPT_RESOURCE
206
+ })
113
207
 
114
- expect(model.resources.entries).toHaveLength(3)
208
+ expect(Object.keys(model.resources)).toHaveLength(4)
115
209
  })
116
210
 
117
- it('throws when resource IDs are duplicated', () => {
211
+ it('throws when a resource entry id does not match its map key', () => {
118
212
  expect(() =>
119
- resolveWithResources([
120
- WORKFLOW_RESOURCE,
121
- {
213
+ resolveWithResources({
214
+ 'LGN-01-company-scrape': WORKFLOW_RESOURCE,
215
+ 'wrong-key': {
122
216
  ...WORKFLOW_RESOURCE,
123
- capabilityKey: 'lead-gen.company.scrape-duplicate'
217
+ id: 'LGN-01-company-scrape'
124
218
  }
125
- ])
126
- ).toThrow(/Resource id \\"LGN-01-company-scrape\\" must be unique/)
219
+ })
220
+ ).toThrow()
127
221
  })
128
222
 
129
- it('throws when systemId references an unknown system', () => {
223
+ it('throws when systemPath references an unknown system', () => {
130
224
  expect(() =>
131
- resolveWithResources([
132
- {
225
+ resolveWithResources({
226
+ 'LGN-01-company-scrape': {
133
227
  ...WORKFLOW_RESOURCE,
134
- systemId: 'sys.missing'
228
+ systemPath: 'sys.missing'
135
229
  }
230
+ })
231
+ ).toThrow(/unknown system path \\"sys\.missing\\"/)
232
+ })
233
+
234
+ it('reports a dangling resource systemPath on the resource systemPath issue path', () => {
235
+ let error: unknown
236
+
237
+ try {
238
+ resolveWithResources({
239
+ 'LGN-01-company-scrape': {
240
+ ...WORKFLOW_RESOURCE,
241
+ systemPath: 'sys.missing'
242
+ }
243
+ })
244
+ } catch (caught) {
245
+ error = caught
246
+ }
247
+
248
+ expect(error).toBeInstanceOf(ZodError)
249
+ if (!(error instanceof ZodError)) {
250
+ throw new Error('Expected resolveOrganizationModel to throw a ZodError')
251
+ }
252
+
253
+ expect(error.issues).toEqual(
254
+ expect.arrayContaining([
255
+ expect.objectContaining({
256
+ path: ['resources', 'LGN-01-company-scrape', 'systemPath']
257
+ })
136
258
  ])
137
- ).toThrow(/unknown systemId \\"sys\.missing\\"/)
259
+ )
138
260
  })
139
261
 
140
262
  it('throws when ownerRoleId references an unknown role', () => {
141
263
  expect(() =>
142
- resolveWithResources([
143
- {
264
+ resolveWithResources({
265
+ 'LGN-01-company-scrape': {
144
266
  ...WORKFLOW_RESOURCE,
145
267
  ownerRoleId: 'role.missing'
146
268
  }
147
- ])
269
+ })
148
270
  ).toThrow(/unknown ownerRoleId \\"role\.missing\\"/)
149
271
  })
150
272
 
151
273
  it('throws when agent actsAsRoleId references an unknown role', () => {
152
274
  expect(() =>
153
- resolveWithResources([
154
- {
275
+ resolveWithResources({
276
+ 'command-center-assistant': {
155
277
  ...AGENT_RESOURCE,
156
278
  actsAsRoleId: 'role.missing'
157
279
  }
158
- ])
280
+ })
159
281
  ).toThrow(/unknown actsAsRoleId \\"role\.missing\\"/)
160
282
  })
161
283
  })
@@ -169,7 +291,7 @@ describe('descriptor helper contract', () => {
169
291
  })
170
292
 
171
293
  expect(workflow.id).toBe('LGN-01-company-scrape')
172
- expect(resources.commandCenterAssistant.agentKind).toBe('system')
294
+ expect(resources.commandCenterAssistant.agentKind).toBe('platform')
173
295
  })
174
296
 
175
297
  it('derives runtime resourceId and type from the descriptor', () => {