@elevasis/core 0.15.1 → 0.16.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 (68) hide show
  1. package/dist/index.d.ts +1662 -23
  2. package/dist/index.js +171 -24
  3. package/dist/organization-model/index.d.ts +1662 -23
  4. package/dist/organization-model/index.js +171 -24
  5. package/dist/test-utils/index.d.ts +711 -10
  6. package/dist/test-utils/index.js +159 -16
  7. package/package.json +7 -3
  8. package/src/__tests__/publish.test.ts +14 -13
  9. package/src/__tests__/template-core-compatibility.test.ts +4 -4
  10. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +305 -201
  11. package/src/auth/multi-tenancy/index.ts +3 -0
  12. package/src/auth/multi-tenancy/theme-presets.ts +45 -0
  13. package/src/auth/multi-tenancy/types.ts +57 -83
  14. package/src/auth/multi-tenancy/users/api-schemas.ts +165 -194
  15. package/src/business/acquisition/activity-events.ts +1 -1
  16. package/src/business/acquisition/api-schemas.ts +1196 -1177
  17. package/src/business/acquisition/crm-state-actions.test.ts +139 -139
  18. package/src/business/acquisition/types.ts +381 -390
  19. package/src/business/crm/api-schemas.ts +40 -0
  20. package/src/business/crm/index.ts +1 -0
  21. package/src/business/deals/api-schemas.ts +79 -0
  22. package/src/business/deals/index.ts +1 -0
  23. package/src/business/projects/types.ts +124 -88
  24. package/src/execution/core/runner-types.ts +61 -80
  25. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -104
  26. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1473
  27. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -102
  28. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -179
  29. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -309
  30. package/src/execution/engine/tools/integration/tool.ts +255 -253
  31. package/src/execution/engine/tools/lead-service-types.ts +895 -894
  32. package/src/execution/engine/tools/messages.ts +43 -0
  33. package/src/execution/engine/tools/platform/acquisition/types.ts +2 -1
  34. package/src/execution/engine/tools/platform/email/types.ts +97 -96
  35. package/src/execution/engine/tools/types.ts +234 -233
  36. package/src/execution/engine/workflow/types.ts +195 -193
  37. package/src/execution/external/api-schemas.ts +40 -0
  38. package/src/execution/external/index.ts +1 -0
  39. package/src/knowledge/README.md +32 -0
  40. package/src/knowledge/__tests__/queries.test.ts +504 -0
  41. package/src/knowledge/format.ts +99 -0
  42. package/src/knowledge/index.ts +5 -0
  43. package/src/knowledge/queries.ts +256 -0
  44. package/src/organization-model/__tests__/defaults.test.ts +172 -172
  45. package/src/organization-model/__tests__/foundation.test.ts +7 -7
  46. package/src/organization-model/__tests__/icons.test.ts +27 -0
  47. package/src/organization-model/__tests__/knowledge.test.ts +214 -0
  48. package/src/organization-model/contracts.ts +17 -15
  49. package/src/organization-model/defaults.ts +74 -19
  50. package/src/organization-model/domains/knowledge.ts +53 -0
  51. package/src/organization-model/domains/navigation.ts +416 -399
  52. package/src/organization-model/domains/shared.ts +6 -5
  53. package/src/organization-model/foundation.ts +10 -6
  54. package/src/organization-model/graph/build.ts +209 -182
  55. package/src/organization-model/graph/schema.ts +37 -34
  56. package/src/organization-model/graph/types.ts +47 -31
  57. package/src/organization-model/icons.ts +81 -0
  58. package/src/organization-model/index.ts +8 -3
  59. package/src/organization-model/organization-model.mdx +1 -1
  60. package/src/organization-model/published.ts +103 -86
  61. package/src/organization-model/schema.ts +90 -85
  62. package/src/organization-model/types.ts +40 -33
  63. package/src/platform/index.ts +23 -27
  64. package/src/platform/registry/index.ts +0 -4
  65. package/src/platform/registry/resource-registry.ts +0 -77
  66. package/src/platform/registry/serialized-types.ts +148 -219
  67. package/src/platform/registry/stats-types.ts +60 -60
  68. package/src/reference/_generated/contracts.md +1265 -1154
@@ -1,4 +1,5 @@
1
- import { z } from 'zod'
1
+ import { z } from 'zod'
2
+ import { OrganizationModelIconTokenSchema } from '../icons'
2
3
 
3
4
  export const ModelIdSchema = z
4
5
  .string()
@@ -8,10 +9,10 @@ export const ModelIdSchema = z
8
9
  .regex(/^[a-z0-9]+(?:[-._][a-z0-9]+)*$/, 'IDs must be lowercase and use -, _, or . separators')
9
10
 
10
11
  export const LabelSchema = z.string().trim().min(1).max(120)
11
- export const DescriptionSchema = z.string().trim().min(1).max(2000)
12
- export const ColorTokenSchema = z.string().trim().min(1).max(50)
13
- export const IconNameSchema = z.string().trim().min(1).max(80)
14
- export const PathSchema = z.string().trim().startsWith('/').max(300)
12
+ export const DescriptionSchema = z.string().trim().min(1).max(2000)
13
+ export const ColorTokenSchema = z.string().trim().min(1).max(50)
14
+ export const IconNameSchema = OrganizationModelIconTokenSchema
15
+ export const PathSchema = z.string().trim().startsWith('/').max(300)
15
16
 
16
17
  export const ReferenceIdsSchema = z.array(ModelIdSchema).default([])
17
18
 
@@ -1,9 +1,13 @@
1
1
  import { resolveOrganizationModel } from './resolve'
2
+ import type { OrganizationModelBuiltinIconToken } from './icons'
2
3
  import type { DeepPartial, OrganizationModel, OrganizationModelFeature } from './types'
3
4
 
4
5
  export type FoundationSurfaceType = 'page' | 'dashboard' | 'graph' | 'detail' | 'list' | 'settings'
5
6
 
6
- export type FoundationSurfaceIcon = 'dashboard' | 'crm' | 'lead-gen' | 'projects' | 'operations' | 'settings'
7
+ export type FoundationSurfaceIcon = Extract<
8
+ OrganizationModelBuiltinIconToken,
9
+ 'feature.dashboard' | 'feature.crm' | 'feature.lead-gen' | 'feature.projects' | 'feature.operations' | 'feature.settings'
10
+ >
7
11
 
8
12
  export interface FoundationNavigationSurface extends Omit<OrganizationModelFeature, 'icon' | 'uiPosition'> {
9
13
  icon?: FoundationSurfaceIcon
@@ -50,11 +54,11 @@ export function createFoundationOrganizationModel(override: DeepPartial<Organiza
50
54
  const crmFeature = requireCoreFeature('sales.crm')
51
55
 
52
56
  const navigationSurfaces: FoundationNavigationSurface[] = [
53
- { ...operationsFeature, id: 'operations', path: '/operations', icon: 'operations', surfaceType: 'dashboard' },
54
- { ...projectsFeature, icon: 'projects', surfaceType: 'list' },
55
- { ...leadGenFeature, id: 'lead-gen', icon: 'lead-gen', surfaceType: 'list' },
56
- { ...crmFeature, id: 'crm', icon: 'crm', surfaceType: 'graph' },
57
- { ...requireCoreFeature('settings.account'), id: 'settings', icon: 'settings', surfaceType: 'settings' }
57
+ { ...operationsFeature, id: 'operations', path: '/operations', icon: 'feature.operations', surfaceType: 'dashboard' },
58
+ { ...projectsFeature, icon: 'feature.projects', surfaceType: 'list' },
59
+ { ...leadGenFeature, id: 'lead-gen', icon: 'feature.lead-gen', surfaceType: 'list' },
60
+ { ...crmFeature, id: 'crm', icon: 'feature.crm', surfaceType: 'graph' },
61
+ { ...requireCoreFeature('settings.account'), id: 'settings', icon: 'feature.settings', surfaceType: 'settings' }
58
62
  ]
59
63
 
60
64
  const homeLabel = 'Dashboard'
@@ -1,100 +1,100 @@
1
- import { BuildOrganizationGraphInputSchema, OrganizationGraphSchema } from './schema'
2
- import type { CommandViewData } from '../../platform/registry/command-view'
3
- import type {
4
- BuildOrganizationGraphInput,
5
- OrganizationGraph,
6
- OrganizationGraphEdge,
7
- OrganizationGraphNode,
8
- OrganizationGraphNodeKind
9
- } from './types'
10
-
11
- function nodeId(kind: OrganizationGraphNodeKind, sourceId?: string): string {
12
- return kind === 'organization' ? 'organization-model' : `${kind}:${sourceId ?? ''}`
13
- }
14
-
15
- function edgeId(kind: string, sourceId: string, targetId: string, variant?: string): string {
16
- return variant ? `edge:${kind}:${variant}:${sourceId}:${targetId}` : `edge:${kind}:${sourceId}:${targetId}`
17
- }
18
-
19
- function pushUniqueNode(nodes: OrganizationGraphNode[], seen: Set<string>, node: OrganizationGraphNode): void {
20
- if (seen.has(node.id)) return
21
- seen.add(node.id)
22
- nodes.push(node)
23
- }
24
-
25
- function pushUniqueEdge(edges: OrganizationGraphEdge[], seen: Set<string>, edge: OrganizationGraphEdge): void {
26
- if (seen.has(edge.id)) return
27
- seen.add(edge.id)
28
- edges.push(edge)
29
- }
30
-
31
- function upsertResourceNode(
32
- nodes: OrganizationGraphNode[],
33
- seen: Set<string>,
34
- resourceNodesById: Map<string, OrganizationGraphNode>,
35
- node: OrganizationGraphNode
36
- ): OrganizationGraphNode {
37
- const existing = resourceNodesById.get(node.id)
38
- if (existing) {
39
- if (!existing.label || existing.label === existing.sourceId) {
40
- existing.label = node.label
41
- }
42
- if (!existing.description && node.description) {
43
- existing.description = node.description
44
- }
45
- if (!existing.sourceId && node.sourceId) {
46
- existing.sourceId = node.sourceId
47
- }
48
- if (!existing.resourceType && node.resourceType) {
49
- existing.resourceType = node.resourceType
50
- }
51
- return existing
52
- }
53
-
54
- resourceNodesById.set(node.id, node)
55
- pushUniqueNode(nodes, seen, node)
56
- return node
57
- }
58
-
59
- function ensureResourceNode(
60
- nodes: OrganizationGraphNode[],
61
- seen: Set<string>,
62
- resourceNodesById: Map<string, OrganizationGraphNode>,
63
- resourceId: string
64
- ): OrganizationGraphNode {
65
- const existing = resourceNodesById.get(nodeId('resource', resourceId))
66
- if (existing) return existing
67
-
68
- return upsertResourceNode(nodes, seen, resourceNodesById, {
69
- id: nodeId('resource', resourceId),
70
- kind: 'resource',
71
- label: resourceId,
72
- sourceId: resourceId
73
- })
74
- }
75
-
1
+ import { BuildOrganizationGraphInputSchema, OrganizationGraphSchema } from './schema'
2
+ import type { CommandViewData } from '../../platform/registry/command-view'
3
+ import type {
4
+ BuildOrganizationGraphInput,
5
+ OrganizationGraph,
6
+ OrganizationGraphEdge,
7
+ OrganizationGraphNode,
8
+ OrganizationGraphNodeKind
9
+ } from './types'
10
+
11
+ function nodeId(kind: OrganizationGraphNodeKind, sourceId?: string): string {
12
+ return kind === 'organization' ? 'organization-model' : `${kind}:${sourceId ?? ''}`
13
+ }
14
+
15
+ function edgeId(kind: string, sourceId: string, targetId: string, variant?: string): string {
16
+ return variant ? `edge:${kind}:${variant}:${sourceId}:${targetId}` : `edge:${kind}:${sourceId}:${targetId}`
17
+ }
18
+
19
+ function pushUniqueNode(nodes: OrganizationGraphNode[], seen: Set<string>, node: OrganizationGraphNode): void {
20
+ if (seen.has(node.id)) return
21
+ seen.add(node.id)
22
+ nodes.push(node)
23
+ }
24
+
25
+ function pushUniqueEdge(edges: OrganizationGraphEdge[], seen: Set<string>, edge: OrganizationGraphEdge): void {
26
+ if (seen.has(edge.id)) return
27
+ seen.add(edge.id)
28
+ edges.push(edge)
29
+ }
30
+
31
+ function upsertResourceNode(
32
+ nodes: OrganizationGraphNode[],
33
+ seen: Set<string>,
34
+ resourceNodesById: Map<string, OrganizationGraphNode>,
35
+ node: OrganizationGraphNode
36
+ ): OrganizationGraphNode {
37
+ const existing = resourceNodesById.get(node.id)
38
+ if (existing) {
39
+ if (!existing.label || existing.label === existing.sourceId) {
40
+ existing.label = node.label
41
+ }
42
+ if (!existing.description && node.description) {
43
+ existing.description = node.description
44
+ }
45
+ if (!existing.sourceId && node.sourceId) {
46
+ existing.sourceId = node.sourceId
47
+ }
48
+ if (!existing.resourceType && node.resourceType) {
49
+ existing.resourceType = node.resourceType
50
+ }
51
+ return existing
52
+ }
53
+
54
+ resourceNodesById.set(node.id, node)
55
+ pushUniqueNode(nodes, seen, node)
56
+ return node
57
+ }
58
+
59
+ function ensureResourceNode(
60
+ nodes: OrganizationGraphNode[],
61
+ seen: Set<string>,
62
+ resourceNodesById: Map<string, OrganizationGraphNode>,
63
+ resourceId: string
64
+ ): OrganizationGraphNode {
65
+ const existing = resourceNodesById.get(nodeId('resource', resourceId))
66
+ if (existing) return existing
67
+
68
+ return upsertResourceNode(nodes, seen, resourceNodesById, {
69
+ id: nodeId('resource', resourceId),
70
+ kind: 'resource',
71
+ label: resourceId,
72
+ sourceId: resourceId
73
+ })
74
+ }
75
+
76
76
  type CommandViewResource =
77
- | CommandViewData['workflows'][number]
78
- | CommandViewData['agents'][number]
79
- | CommandViewData['triggers'][number]
80
- | CommandViewData['integrations'][number]
81
- | CommandViewData['externalResources'][number]
82
- | CommandViewData['humanCheckpoints'][number]
83
-
84
- function normalizeCommandViewResourceType(
85
- resourceType: CommandViewResource['type']
86
- ): OrganizationGraphNode['resourceType'] {
87
- return resourceType === 'human' ? 'human_checkpoint' : resourceType
88
- }
89
-
77
+ | CommandViewData['workflows'][number]
78
+ | CommandViewData['agents'][number]
79
+ | CommandViewData['triggers'][number]
80
+ | CommandViewData['integrations'][number]
81
+ | CommandViewData['externalResources'][number]
82
+ | CommandViewData['humanCheckpoints'][number]
83
+
84
+ function normalizeCommandViewResourceType(
85
+ resourceType: CommandViewResource['type']
86
+ ): OrganizationGraphNode['resourceType'] {
87
+ return resourceType === 'human' ? 'human_checkpoint' : resourceType
88
+ }
89
+
90
90
  function collectCommandViewResources(commandViewData: CommandViewData): CommandViewResource[] {
91
- return [
92
- ...commandViewData.workflows,
93
- ...commandViewData.agents,
94
- ...commandViewData.triggers,
95
- ...commandViewData.integrations,
96
- ...commandViewData.externalResources,
97
- ...commandViewData.humanCheckpoints
91
+ return [
92
+ ...commandViewData.workflows,
93
+ ...commandViewData.agents,
94
+ ...commandViewData.triggers,
95
+ ...commandViewData.integrations,
96
+ ...commandViewData.externalResources,
97
+ ...commandViewData.humanCheckpoints
98
98
  ]
99
99
  }
100
100
 
@@ -113,40 +113,41 @@ function pushResourceLinks(
113
113
  })
114
114
  }
115
115
  }
116
-
117
- export function buildOrganizationGraph(input: BuildOrganizationGraphInput): OrganizationGraph {
118
- const parsed = BuildOrganizationGraphInputSchema.parse(input)
119
- const organizationModel = parsed.organizationModel
120
- const commandViewData = parsed.commandViewData as CommandViewData | undefined
121
-
122
- const nodes: OrganizationGraphNode[] = []
123
- const edges: OrganizationGraphEdge[] = []
124
- const nodeIds = new Set<string>()
125
- const edgeIds = new Set<string>()
126
- const resourceNodesById = new Map<string, OrganizationGraphNode>()
127
-
128
- const organizationNode: OrganizationGraphNode = {
129
- id: nodeId('organization'),
130
- kind: 'organization',
131
- label: 'Organization Model'
132
- }
133
- pushUniqueNode(nodes, nodeIds, organizationNode)
134
-
116
+
117
+ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): OrganizationGraph {
118
+ const parsed = BuildOrganizationGraphInputSchema.parse(input)
119
+ const organizationModel = parsed.organizationModel
120
+ const commandViewData = parsed.commandViewData as CommandViewData | undefined
121
+
122
+ const nodes: OrganizationGraphNode[] = []
123
+ const edges: OrganizationGraphEdge[] = []
124
+ const nodeIds = new Set<string>()
125
+ const edgeIds = new Set<string>()
126
+ const resourceNodesById = new Map<string, OrganizationGraphNode>()
127
+
128
+ const organizationNode: OrganizationGraphNode = {
129
+ id: nodeId('organization'),
130
+ kind: 'organization',
131
+ label: 'Organization Model'
132
+ }
133
+ pushUniqueNode(nodes, nodeIds, organizationNode)
134
+
135
135
  for (const feature of [...organizationModel.features].sort((a, b) => a.id.localeCompare(b.id))) {
136
136
  const id = nodeId('feature', feature.id)
137
- pushUniqueNode(nodes, nodeIds, {
138
- id,
139
- kind: 'feature',
140
- label: feature.label,
141
- sourceId: feature.id,
142
- description: feature.description,
143
- enabled: feature.enabled,
144
- featureId: feature.id
145
- })
146
- pushUniqueEdge(edges, edgeIds, {
147
- id: edgeId('contains', organizationNode.id, id),
148
- kind: 'contains',
149
- sourceId: organizationNode.id,
137
+ pushUniqueNode(nodes, nodeIds, {
138
+ id,
139
+ kind: 'feature',
140
+ label: feature.label,
141
+ sourceId: feature.id,
142
+ description: feature.description,
143
+ icon: feature.icon,
144
+ enabled: feature.enabled,
145
+ featureId: feature.id
146
+ })
147
+ pushUniqueEdge(edges, edgeIds, {
148
+ id: edgeId('contains', organizationNode.id, id),
149
+ kind: 'contains',
150
+ sourceId: organizationNode.id,
150
151
  targetId: id
151
152
  })
152
153
  const parentId = feature.id.includes('.') ? feature.id.slice(0, feature.id.lastIndexOf('.')) : undefined
@@ -159,23 +160,49 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
159
160
  })
160
161
  }
161
162
  }
162
-
163
- if (commandViewData) {
164
- const commandViewResources = collectCommandViewResources(commandViewData).sort((a, b) =>
165
- a.resourceId.localeCompare(b.resourceId)
166
- )
167
-
168
- for (const resource of commandViewResources) {
169
- const id = nodeId('resource', resource.resourceId)
170
- const resourceNode = upsertResourceNode(nodes, nodeIds, resourceNodesById, {
171
- id,
172
- kind: 'resource',
173
- label: resource.name,
174
- sourceId: resource.resourceId,
175
- description: resource.description,
176
- resourceType: normalizeCommandViewResourceType(resource.type)
177
- })
178
-
163
+
164
+ for (const node of [...(organizationModel.knowledge?.nodes ?? [])].sort((a, b) => a.id.localeCompare(b.id))) {
165
+ const id = nodeId('knowledge', node.id)
166
+ pushUniqueNode(nodes, nodeIds, {
167
+ id,
168
+ kind: 'knowledge',
169
+ label: node.title,
170
+ sourceId: node.id,
171
+ description: node.summary,
172
+ icon: node.icon
173
+ })
174
+ pushUniqueEdge(edges, edgeIds, {
175
+ id: edgeId('contains', organizationNode.id, id),
176
+ kind: 'contains',
177
+ sourceId: organizationNode.id,
178
+ targetId: id
179
+ })
180
+ for (const link of node.links) {
181
+ pushUniqueEdge(edges, edgeIds, {
182
+ id: edgeId('governs', id, link.nodeId),
183
+ kind: 'governs',
184
+ sourceId: id,
185
+ targetId: link.nodeId
186
+ })
187
+ }
188
+ }
189
+
190
+ if (commandViewData) {
191
+ const commandViewResources = collectCommandViewResources(commandViewData).sort((a, b) =>
192
+ a.resourceId.localeCompare(b.resourceId)
193
+ )
194
+
195
+ for (const resource of commandViewResources) {
196
+ const id = nodeId('resource', resource.resourceId)
197
+ const resourceNode = upsertResourceNode(nodes, nodeIds, resourceNodesById, {
198
+ id,
199
+ kind: 'resource',
200
+ label: resource.name,
201
+ sourceId: resource.resourceId,
202
+ description: resource.description,
203
+ resourceType: normalizeCommandViewResourceType(resource.type)
204
+ })
205
+
179
206
  pushUniqueEdge(edges, edgeIds, {
180
207
  id: edgeId('contains', organizationNode.id, resourceNode.id),
181
208
  kind: 'contains',
@@ -184,41 +211,41 @@ export function buildOrganizationGraph(input: BuildOrganizationGraphInput): Orga
184
211
  })
185
212
  pushResourceLinks(edges, edgeIds, resourceNode.id, resource.links)
186
213
  }
187
-
188
- for (const relationship of [...commandViewData.edges].sort((a, b) => a.id.localeCompare(b.id))) {
189
- const sourceNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.source)
190
- const targetNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.target)
191
-
192
- pushUniqueEdge(edges, edgeIds, {
193
- id: edgeId('contains', organizationNode.id, sourceNode.id),
194
- kind: 'contains',
195
- sourceId: organizationNode.id,
196
- targetId: sourceNode.id
197
- })
198
- pushUniqueEdge(edges, edgeIds, {
199
- id: edgeId('contains', organizationNode.id, targetNode.id),
200
- kind: 'contains',
201
- sourceId: organizationNode.id,
202
- targetId: targetNode.id
203
- })
204
-
205
- pushUniqueEdge(edges, edgeIds, {
206
- id: edgeId('references', sourceNode.id, targetNode.id, relationship.relationship),
207
- kind: 'references',
208
- sourceId: sourceNode.id,
209
- targetId: targetNode.id,
210
- label: relationship.relationship,
211
- relationshipType: relationship.relationship
212
- })
213
- }
214
- }
215
-
216
- const graph: OrganizationGraph = {
217
- version: 1,
218
- organizationModelVersion: organizationModel.version,
219
- nodes,
220
- edges
221
- }
222
-
223
- return OrganizationGraphSchema.parse(graph)
224
- }
214
+
215
+ for (const relationship of [...commandViewData.edges].sort((a, b) => a.id.localeCompare(b.id))) {
216
+ const sourceNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.source)
217
+ const targetNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.target)
218
+
219
+ pushUniqueEdge(edges, edgeIds, {
220
+ id: edgeId('contains', organizationNode.id, sourceNode.id),
221
+ kind: 'contains',
222
+ sourceId: organizationNode.id,
223
+ targetId: sourceNode.id
224
+ })
225
+ pushUniqueEdge(edges, edgeIds, {
226
+ id: edgeId('contains', organizationNode.id, targetNode.id),
227
+ kind: 'contains',
228
+ sourceId: organizationNode.id,
229
+ targetId: targetNode.id
230
+ })
231
+
232
+ pushUniqueEdge(edges, edgeIds, {
233
+ id: edgeId('references', sourceNode.id, targetNode.id, relationship.relationship),
234
+ kind: 'references',
235
+ sourceId: sourceNode.id,
236
+ targetId: targetNode.id,
237
+ label: relationship.relationship,
238
+ relationshipType: relationship.relationship
239
+ })
240
+ }
241
+ }
242
+
243
+ const graph: OrganizationGraph = {
244
+ version: 1,
245
+ organizationModelVersion: organizationModel.version,
246
+ nodes,
247
+ edges
248
+ }
249
+
250
+ return OrganizationGraphSchema.parse(graph)
251
+ }
@@ -1,53 +1,56 @@
1
1
  import { z } from 'zod'
2
- import { DescriptionSchema, LabelSchema } from '../domains/shared'
2
+ import { DescriptionSchema, IconNameSchema, LabelSchema } from '../domains/shared'
3
3
  import { OrganizationModelSchema } from '../schema'
4
-
5
- export const OrganizationGraphNodeKindSchema = z.enum([
6
- 'organization',
7
- 'feature',
8
- 'surface',
9
- 'entity',
10
- 'capability',
11
- 'resource'
12
- ])
13
-
4
+
5
+ export const OrganizationGraphNodeKindSchema = z.enum([
6
+ 'organization',
7
+ 'feature',
8
+ 'surface',
9
+ 'entity',
10
+ 'capability',
11
+ 'resource',
12
+ 'knowledge'
13
+ ])
14
+
14
15
  export const OrganizationGraphEdgeKindSchema = z.enum([
15
16
  'contains',
16
17
  'references',
17
18
  'exposes',
18
19
  'maps_to',
19
20
  'operates-on',
20
- 'uses'
21
+ 'uses',
22
+ 'governs'
21
23
  ])
22
-
24
+
23
25
  export const OrganizationGraphNodeSchema = z.object({
24
26
  id: z.string().trim().min(1).max(200),
25
27
  kind: OrganizationGraphNodeKindSchema,
26
28
  label: LabelSchema,
27
29
  sourceId: z.string().trim().min(1).max(255).optional(),
28
30
  description: DescriptionSchema.optional(),
31
+ icon: IconNameSchema.optional(),
29
32
  enabled: z.boolean().optional(),
30
33
  featureId: z.string().trim().min(1).max(100).optional(),
31
34
  resourceType: z.enum(['workflow', 'agent', 'trigger', 'integration', 'external', 'human_checkpoint']).optional()
32
35
  })
33
-
34
- export const OrganizationGraphEdgeSchema = z.object({
35
- id: z.string().trim().min(1).max(250),
36
- kind: OrganizationGraphEdgeKindSchema,
37
- sourceId: z.string().trim().min(1).max(200),
38
- targetId: z.string().trim().min(1).max(200),
39
- label: z.string().trim().min(1).max(120).optional(),
40
- relationshipType: z.enum(['triggers', 'uses', 'approval']).optional()
41
- })
42
-
43
- export const OrganizationGraphSchema = z.object({
44
- version: z.literal(1),
45
- organizationModelVersion: OrganizationModelSchema.shape.version,
46
- nodes: z.array(OrganizationGraphNodeSchema),
47
- edges: z.array(OrganizationGraphEdgeSchema)
48
- })
49
-
50
- export const BuildOrganizationGraphInputSchema = z.object({
51
- organizationModel: OrganizationModelSchema,
52
- commandViewData: z.unknown().optional()
53
- })
36
+
37
+ export const OrganizationGraphEdgeSchema = z.object({
38
+ id: z.string().trim().min(1).max(250),
39
+ kind: OrganizationGraphEdgeKindSchema,
40
+ sourceId: z.string().trim().min(1).max(200),
41
+ targetId: z.string().trim().min(1).max(200),
42
+ label: z.string().trim().min(1).max(120).optional(),
43
+ relationshipType: z.enum(['triggers', 'uses', 'approval']).optional()
44
+ })
45
+
46
+ export const OrganizationGraphSchema = z.object({
47
+ version: z.literal(1),
48
+ organizationModelVersion: OrganizationModelSchema.shape.version,
49
+ nodes: z.array(OrganizationGraphNodeSchema),
50
+ edges: z.array(OrganizationGraphEdgeSchema)
51
+ })
52
+
53
+ export const BuildOrganizationGraphInputSchema = z.object({
54
+ organizationModel: OrganizationModelSchema,
55
+ commandViewData: z.unknown().optional()
56
+ })
@@ -1,40 +1,56 @@
1
1
  import type { CommandViewData } from '../../platform/registry/command-view'
2
2
  import type { OrganizationModel } from '../types'
3
3
  import type { RelationshipType } from '../../platform/registry/command-view'
4
-
5
- export type OrganizationGraphNodeKind = 'organization' | 'feature' | 'surface' | 'entity' | 'capability' | 'resource'
6
-
7
- export type OrganizationGraphEdgeKind = 'contains' | 'references' | 'exposes' | 'maps_to' | 'operates-on' | 'uses'
4
+ import type { OrganizationModelIconToken } from '../icons'
5
+
6
+ export type OrganizationGraphNodeKind =
7
+ | 'organization'
8
+ | 'feature'
9
+ | 'surface'
10
+ | 'entity'
11
+ | 'capability'
12
+ | 'resource'
13
+ | 'knowledge'
14
+
15
+ export type OrganizationGraphEdgeKind =
16
+ | 'contains'
17
+ | 'references'
18
+ | 'exposes'
19
+ | 'maps_to'
20
+ | 'operates-on'
21
+ | 'uses'
22
+ | 'governs'
8
23
  export type { Link } from './link'
9
-
10
- export interface OrganizationGraphNode {
11
- id: string
12
- kind: OrganizationGraphNodeKind
13
- label: string
14
- sourceId?: string
24
+
25
+ export interface OrganizationGraphNode {
26
+ id: string
27
+ kind: OrganizationGraphNodeKind
28
+ label: string
29
+ sourceId?: string
15
30
  description?: string
31
+ icon?: OrganizationModelIconToken
16
32
  enabled?: boolean
17
33
  featureId?: string
18
34
  resourceType?: 'workflow' | 'agent' | 'trigger' | 'integration' | 'external' | 'human_checkpoint'
19
35
  }
20
-
21
- export interface OrganizationGraphEdge {
22
- id: string
23
- kind: OrganizationGraphEdgeKind
24
- sourceId: string
25
- targetId: string
26
- label?: string
27
- relationshipType?: RelationshipType
28
- }
29
-
30
- export interface OrganizationGraph {
31
- version: 1
32
- organizationModelVersion: OrganizationModel['version']
33
- nodes: OrganizationGraphNode[]
34
- edges: OrganizationGraphEdge[]
35
- }
36
-
37
- export interface BuildOrganizationGraphInput {
38
- organizationModel: OrganizationModel
39
- commandViewData?: CommandViewData
40
- }
36
+
37
+ export interface OrganizationGraphEdge {
38
+ id: string
39
+ kind: OrganizationGraphEdgeKind
40
+ sourceId: string
41
+ targetId: string
42
+ label?: string
43
+ relationshipType?: RelationshipType
44
+ }
45
+
46
+ export interface OrganizationGraph {
47
+ version: 1
48
+ organizationModelVersion: OrganizationModel['version']
49
+ nodes: OrganizationGraphNode[]
50
+ edges: OrganizationGraphEdge[]
51
+ }
52
+
53
+ export interface BuildOrganizationGraphInput {
54
+ organizationModel: OrganizationModel
55
+ commandViewData?: CommandViewData
56
+ }