@elevasis/sdk 1.24.0 → 1.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +1178 -1039
- package/dist/index.d.ts +4760 -4567
- package/dist/index.js +989 -2332
- package/dist/node/index.d.ts +660 -1323
- package/dist/node/index.js +1 -1
- package/dist/test-utils/index.d.ts +4101 -4115
- package/dist/test-utils/index.js +1724 -3471
- package/dist/types/worker/index.d.ts +3 -2
- package/dist/types/worker/platform.d.ts +2 -2
- package/dist/worker/index.js +394 -2448
- package/package.json +2 -2
- package/reference/cli.mdx +1107 -808
- package/reference/scaffold/recipes/customize-crm-actions.md +45 -46
- package/reference/scaffold/recipes/extend-crm.md +253 -255
- package/reference/scaffold/recipes/index.md +43 -44
- package/reference/scaffold/reference/contracts.md +976 -1063
package/dist/index.js
CHANGED
|
@@ -21,670 +21,103 @@ function defineStep(step) {
|
|
|
21
21
|
function defineWorkflow(workflow) {
|
|
22
22
|
return workflow;
|
|
23
23
|
}
|
|
24
|
-
var
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"knowledge",
|
|
36
|
-
"settings",
|
|
37
|
-
"admin",
|
|
38
|
-
"archive",
|
|
39
|
-
"business",
|
|
40
|
-
"finance",
|
|
41
|
-
"platform",
|
|
42
|
-
"seo",
|
|
43
|
-
// Knowledge kinds
|
|
44
|
-
"playbook",
|
|
45
|
-
"strategy",
|
|
46
|
-
"reference",
|
|
47
|
-
// Resource kinds
|
|
48
|
-
"agent",
|
|
49
|
-
"workflow",
|
|
50
|
-
"integration",
|
|
51
|
-
"database",
|
|
52
|
-
"user",
|
|
53
|
-
"team",
|
|
54
|
-
// Integration specifics
|
|
55
|
-
"gmail",
|
|
56
|
-
"google-sheets",
|
|
57
|
-
"attio",
|
|
58
|
-
// Surface / UI views
|
|
59
|
-
"overview",
|
|
60
|
-
"command-view",
|
|
61
|
-
"command-queue",
|
|
62
|
-
"pipeline",
|
|
63
|
-
"lists",
|
|
64
|
-
"resources",
|
|
65
|
-
// Actions
|
|
66
|
-
"approve",
|
|
67
|
-
"reject",
|
|
68
|
-
"retry",
|
|
69
|
-
"edit",
|
|
70
|
-
"view",
|
|
71
|
-
"launch",
|
|
72
|
-
"message",
|
|
73
|
-
"escalate",
|
|
74
|
-
"promote",
|
|
75
|
-
"submit",
|
|
76
|
-
"email",
|
|
77
|
-
// Status
|
|
78
|
-
"success",
|
|
79
|
-
"error",
|
|
80
|
-
"warning",
|
|
81
|
-
"info",
|
|
82
|
-
"pending",
|
|
83
|
-
// OM / UI group icons
|
|
84
|
-
"bolt",
|
|
85
|
-
"building",
|
|
86
|
-
"briefcase",
|
|
87
|
-
"apps",
|
|
88
|
-
"graph",
|
|
89
|
-
"shield",
|
|
90
|
-
"users",
|
|
91
|
-
"chart-bar",
|
|
92
|
-
"search"
|
|
93
|
-
];
|
|
94
|
-
var CustomIconTokenSchema = z.string().trim().max(80).regex(
|
|
95
|
-
/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
|
|
96
|
-
'Custom icon tokens must start with "custom." followed by lowercase alphanumeric segments'
|
|
97
|
-
);
|
|
98
|
-
var OrganizationModelBuiltinIconTokenSchema = z.enum(ORGANIZATION_MODEL_ICON_TOKENS);
|
|
99
|
-
var OrganizationModelIconTokenSchema = z.union([
|
|
100
|
-
OrganizationModelBuiltinIconTokenSchema,
|
|
101
|
-
CustomIconTokenSchema
|
|
24
|
+
var OntologyKindSchema = z.enum([
|
|
25
|
+
"object",
|
|
26
|
+
"link",
|
|
27
|
+
"action",
|
|
28
|
+
"catalog",
|
|
29
|
+
"event",
|
|
30
|
+
"interface",
|
|
31
|
+
"value-type",
|
|
32
|
+
"property",
|
|
33
|
+
"group",
|
|
34
|
+
"surface"
|
|
102
35
|
]);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
var
|
|
106
|
-
var
|
|
107
|
-
var
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
36
|
+
var SYSTEM_PATH_PATTERN = "[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)*";
|
|
37
|
+
var LOCAL_ID_PATTERN = "[a-z0-9][a-z0-9._-]*";
|
|
38
|
+
var ONTOLOGY_ID_PATTERN = `^(global|${SYSTEM_PATH_PATTERN}):(${OntologyKindSchema.options.join("|")})\\/(${LOCAL_ID_PATTERN})$`;
|
|
39
|
+
var ONTOLOGY_ID_REGEX = new RegExp(ONTOLOGY_ID_PATTERN);
|
|
40
|
+
var OntologyIdSchema = z.string().trim().min(1).max(300).regex(
|
|
41
|
+
ONTOLOGY_ID_REGEX,
|
|
42
|
+
"Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
|
|
43
|
+
);
|
|
44
|
+
function parseOntologyId(id) {
|
|
45
|
+
const normalized = OntologyIdSchema.parse(id);
|
|
46
|
+
const match = ONTOLOGY_ID_REGEX.exec(normalized);
|
|
47
|
+
if (match === null) {
|
|
48
|
+
throw new Error(`Invalid ontology ID "${id}"`);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
id: normalized,
|
|
52
|
+
scope: match[1],
|
|
53
|
+
kind: match[2],
|
|
54
|
+
localId: match[3],
|
|
55
|
+
isGlobal: match[1] === "global"
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function formatOntologyId(input) {
|
|
59
|
+
return OntologyIdSchema.parse(`${input.scope}:${input.kind}/${input.localId}`);
|
|
60
|
+
}
|
|
61
|
+
var OntologyReferenceListSchema = z.array(OntologyIdSchema).default([]).optional();
|
|
62
|
+
var OntologyRecordBaseSchema = z.object({
|
|
63
|
+
id: OntologyIdSchema,
|
|
64
|
+
label: z.string().trim().min(1).max(160).optional(),
|
|
65
|
+
description: z.string().trim().min(1).max(2e3).optional(),
|
|
66
|
+
ownerSystemId: z.string().trim().min(1).max(200).optional(),
|
|
67
|
+
aliases: z.array(OntologyIdSchema).optional()
|
|
68
|
+
}).passthrough();
|
|
69
|
+
var OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
|
|
70
|
+
properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
|
|
71
|
+
storage: z.record(z.string(), z.unknown()).optional()
|
|
117
72
|
});
|
|
118
|
-
var
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Health of the credential backing this integration.
|
|
125
|
-
* - configured: credential present and valid
|
|
126
|
-
* - pending: not yet set up
|
|
127
|
-
* - expired: credential existed but has lapsed
|
|
128
|
-
* - missing: expected but not present
|
|
129
|
-
*/
|
|
130
|
-
credentialStatus: z.enum(["configured", "pending", "expired", "missing"]),
|
|
131
|
-
/**
|
|
132
|
-
* Whether this integration is the primary system of record for its domain
|
|
133
|
-
* (e.g. HubSpot is SoR for contacts). Defaults to false.
|
|
134
|
-
*/
|
|
135
|
-
isSystemOfRecord: z.boolean().default(false)
|
|
73
|
+
var OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
|
|
74
|
+
from: OntologyIdSchema,
|
|
75
|
+
to: OntologyIdSchema,
|
|
76
|
+
cardinality: z.string().trim().min(1).max(80).optional(),
|
|
77
|
+
via: z.string().trim().min(1).max(255).optional()
|
|
136
78
|
});
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
systemIds: ReferenceIdsSchema,
|
|
142
|
-
entityIds: ReferenceIdsSchema,
|
|
143
|
-
surfaceIds: ReferenceIdsSchema,
|
|
144
|
-
actionIds: ReferenceIdsSchema,
|
|
145
|
-
/** Optional tech-stack metadata for external-SaaS integrations. */
|
|
146
|
-
techStack: TechStackEntrySchema.optional()
|
|
79
|
+
var OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
|
|
80
|
+
actsOn: OntologyReferenceListSchema,
|
|
81
|
+
input: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
|
|
82
|
+
effects: z.array(z.record(z.string(), z.unknown())).optional()
|
|
147
83
|
});
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
productName: LabelSchema,
|
|
153
|
-
shortName: z.string().trim().min(1).max(40),
|
|
154
|
-
description: DescriptionSchema.optional(),
|
|
155
|
-
logos: z.object({
|
|
156
|
-
light: z.string().trim().min(1).max(2048).optional(),
|
|
157
|
-
dark: z.string().trim().min(1).max(2048).optional()
|
|
158
|
-
}).default({})
|
|
84
|
+
var OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
|
|
85
|
+
kind: z.string().trim().min(1).max(120).optional(),
|
|
86
|
+
appliesTo: OntologyIdSchema.optional(),
|
|
87
|
+
entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
159
88
|
});
|
|
160
|
-
var
|
|
161
|
-
|
|
162
|
-
productName: "Elevasis",
|
|
163
|
-
shortName: "Elevasis",
|
|
164
|
-
logos: {}
|
|
165
|
-
};
|
|
166
|
-
var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]).meta({ label: "Surface type", color: "blue" });
|
|
167
|
-
z.object({
|
|
168
|
-
id: ModelIdSchema,
|
|
169
|
-
label: LabelSchema,
|
|
170
|
-
path: PathSchema,
|
|
171
|
-
surfaceType: SurfaceTypeSchema,
|
|
172
|
-
description: DescriptionSchema.optional(),
|
|
173
|
-
enabled: z.boolean().default(true),
|
|
174
|
-
devOnly: z.boolean().optional(),
|
|
175
|
-
icon: IconNameSchema.optional(),
|
|
176
|
-
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
177
|
-
entityIds: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]),
|
|
178
|
-
resourceIds: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]),
|
|
179
|
-
actionIds: z.array(ModelIdSchema.meta({ ref: "action" })).default([]),
|
|
180
|
-
parentId: ModelIdSchema.meta({ ref: "surface" }).optional()
|
|
89
|
+
var OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
|
|
90
|
+
payload: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
181
91
|
});
|
|
182
|
-
var
|
|
183
|
-
|
|
184
|
-
entities: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]).optional(),
|
|
185
|
-
resources: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]).optional(),
|
|
186
|
-
actions: z.array(ModelIdSchema.meta({ ref: "action" })).default([]).optional()
|
|
187
|
-
}).default({});
|
|
188
|
-
var SidebarNodeSchema = z.lazy(
|
|
189
|
-
() => z.discriminatedUnion("type", [
|
|
190
|
-
z.object({
|
|
191
|
-
type: z.literal("group"),
|
|
192
|
-
label: LabelSchema,
|
|
193
|
-
description: DescriptionSchema.optional(),
|
|
194
|
-
icon: IconNameSchema.optional(),
|
|
195
|
-
order: z.number().int().optional(),
|
|
196
|
-
children: z.record(z.string(), SidebarNodeSchema).default({})
|
|
197
|
-
}),
|
|
198
|
-
z.object({
|
|
199
|
-
type: z.literal("surface"),
|
|
200
|
-
label: LabelSchema,
|
|
201
|
-
path: PathSchema,
|
|
202
|
-
surfaceType: SurfaceTypeSchema,
|
|
203
|
-
description: DescriptionSchema.optional(),
|
|
204
|
-
icon: IconNameSchema.optional(),
|
|
205
|
-
order: z.number().int().optional(),
|
|
206
|
-
targets: SidebarSurfaceTargetsSchema.optional(),
|
|
207
|
-
devOnly: z.boolean().optional(),
|
|
208
|
-
requiresAdmin: z.boolean().optional()
|
|
209
|
-
})
|
|
210
|
-
])
|
|
211
|
-
);
|
|
212
|
-
var SidebarSectionSchema = z.record(z.string(), SidebarNodeSchema).default({});
|
|
213
|
-
var SidebarNavigationSchema = z.object({
|
|
214
|
-
primary: SidebarSectionSchema,
|
|
215
|
-
bottom: SidebarSectionSchema
|
|
216
|
-
}).default({ primary: {}, bottom: {} });
|
|
217
|
-
var OrganizationModelNavigationSchema = z.object({
|
|
218
|
-
sidebar: SidebarNavigationSchema
|
|
219
|
-
}).default({ sidebar: { primary: {}, bottom: {} } });
|
|
220
|
-
z.object({
|
|
221
|
-
id: ModelIdSchema,
|
|
222
|
-
label: LabelSchema,
|
|
223
|
-
placement: z.string().trim().min(1).max(50),
|
|
224
|
-
surfaceIds: z.array(ModelIdSchema.meta({ ref: "surface" })).default([])
|
|
92
|
+
var OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
|
|
93
|
+
properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
225
94
|
});
|
|
226
|
-
var
|
|
227
|
-
|
|
228
|
-
close: z.string().trim().regex(/^\d{2}:\d{2}$/, "Expected HH:MM format")
|
|
95
|
+
var OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
|
|
96
|
+
primitive: z.string().trim().min(1).max(120).optional()
|
|
229
97
|
});
|
|
230
|
-
var
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
thursday: BusinessHoursDaySchema.optional(),
|
|
235
|
-
friday: BusinessHoursDaySchema.optional(),
|
|
236
|
-
saturday: BusinessHoursDaySchema.optional(),
|
|
237
|
-
sunday: BusinessHoursDaySchema.optional()
|
|
238
|
-
}).default({});
|
|
239
|
-
var IdentityDomainSchema = z.object({
|
|
240
|
-
/** Why the organization exists — one or two plain-language sentences. */
|
|
241
|
-
mission: z.string().trim().max(1e3).default(""),
|
|
242
|
-
/** Long-term direction the organization is moving toward. */
|
|
243
|
-
vision: z.string().trim().max(1e3).default(""),
|
|
244
|
-
/** Legal registered name of the entity. */
|
|
245
|
-
legalName: z.string().trim().max(200).default(""),
|
|
246
|
-
/**
|
|
247
|
-
* Type of legal entity (e.g. "LLC", "Corporation", "Sole Proprietor",
|
|
248
|
-
* "Non-profit"). Free-form string so it covers any jurisdiction.
|
|
249
|
-
*/
|
|
250
|
-
entityType: z.string().trim().max(100).default(""),
|
|
251
|
-
/**
|
|
252
|
-
* Primary jurisdiction of registration or operation
|
|
253
|
-
* (e.g. "United States – Delaware", "Canada – Ontario").
|
|
254
|
-
*/
|
|
255
|
-
jurisdiction: z.string().trim().max(200).default(""),
|
|
256
|
-
/**
|
|
257
|
-
* Industry category — broad classification (e.g. "Marketing Agency",
|
|
258
|
-
* "Software / SaaS", "Professional Services").
|
|
259
|
-
*/
|
|
260
|
-
industryCategory: z.string().trim().max(200).default(""),
|
|
261
|
-
/**
|
|
262
|
-
* Geographic focus — where the organization primarily operates or serves
|
|
263
|
-
* (e.g. "North America", "Global", "Southeast Asia").
|
|
264
|
-
*/
|
|
265
|
-
geographicFocus: z.string().trim().max(200).default(""),
|
|
266
|
-
/**
|
|
267
|
-
* IANA timezone identifier for the organization's primary operating timezone
|
|
268
|
-
* (e.g. "America/Los_Angeles", "Europe/London", "UTC").
|
|
269
|
-
*/
|
|
270
|
-
timeZone: z.string().trim().max(100).default("UTC"),
|
|
271
|
-
/** Typical operating hours per day of week. Empty object means not configured. */
|
|
272
|
-
businessHours: BusinessHoursSchema,
|
|
273
|
-
/**
|
|
274
|
-
* Long-form markdown capturing client context, problem narrative, and domain
|
|
275
|
-
* background. Populated by /setup; surfaced to agents as organizational context.
|
|
276
|
-
* Optional — many projects have no external client.
|
|
277
|
-
*/
|
|
278
|
-
clientBrief: z.string().trim().default("")
|
|
98
|
+
var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
|
|
99
|
+
valueType: OntologyIdSchema.optional(),
|
|
100
|
+
searchable: z.boolean().optional(),
|
|
101
|
+
pii: z.boolean().optional()
|
|
279
102
|
});
|
|
280
|
-
var
|
|
281
|
-
|
|
282
|
-
vision: "",
|
|
283
|
-
legalName: "",
|
|
284
|
-
entityType: "",
|
|
285
|
-
jurisdiction: "",
|
|
286
|
-
industryCategory: "",
|
|
287
|
-
geographicFocus: "",
|
|
288
|
-
timeZone: "UTC",
|
|
289
|
-
businessHours: {},
|
|
290
|
-
clientBrief: ""
|
|
291
|
-
};
|
|
292
|
-
var FirmographicsSchema = z.object({
|
|
293
|
-
/** Industry vertical (e.g. "Marketing Agency", "Legal", "Real Estate"). */
|
|
294
|
-
industry: z.string().trim().max(200).optional(),
|
|
295
|
-
/**
|
|
296
|
-
* Company headcount band (e.g. "1–10", "11–50", "51–200", "200+").
|
|
297
|
-
* Free-form string to accommodate any band notation.
|
|
298
|
-
*/
|
|
299
|
-
companySize: z.string().trim().max(100).optional(),
|
|
300
|
-
/**
|
|
301
|
-
* Primary geographic region the segment operates in or is targeted from
|
|
302
|
-
* (e.g. "North America", "Europe", "Global").
|
|
303
|
-
*/
|
|
304
|
-
region: z.string().trim().max(200).optional()
|
|
103
|
+
var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
|
|
104
|
+
members: OntologyReferenceListSchema
|
|
305
105
|
});
|
|
306
|
-
var
|
|
307
|
-
|
|
308
|
-
id: z.string().trim().min(1).max(100),
|
|
309
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
310
|
-
order: z.number(),
|
|
311
|
-
/** Human-readable name shown to agents and in UI (e.g. "SMB Marketing Agencies"). */
|
|
312
|
-
name: z.string().trim().max(200).default(""),
|
|
313
|
-
/** One or two sentences describing who this segment is. */
|
|
314
|
-
description: z.string().trim().max(2e3).default(""),
|
|
315
|
-
/**
|
|
316
|
-
* The primary job(s) this segment is trying to get done — the goal they hire
|
|
317
|
-
* a product/service to accomplish. Plain-language narrative or bullet list.
|
|
318
|
-
*/
|
|
319
|
-
jobsToBeDone: z.string().trim().max(2e3).default(""),
|
|
320
|
-
/**
|
|
321
|
-
* Pains — frustrations, obstacles, and risks the segment experiences
|
|
322
|
-
* when trying to accomplish their jobs-to-be-done.
|
|
323
|
-
*/
|
|
324
|
-
pains: z.array(z.string().trim().max(500)).default([]),
|
|
325
|
-
/**
|
|
326
|
-
* Gains — outcomes and benefits the segment desires; positive motivators
|
|
327
|
-
* beyond merely resolving pains.
|
|
328
|
-
*/
|
|
329
|
-
gains: z.array(z.string().trim().max(500)).default([]),
|
|
330
|
-
/** Firmographic profile for targeting and filtering. */
|
|
331
|
-
firmographics: FirmographicsSchema.default({}),
|
|
332
|
-
/**
|
|
333
|
-
* Value proposition — one or two sentences stating why this organization's
|
|
334
|
-
* offering is uniquely suited for this segment's needs.
|
|
335
|
-
*/
|
|
336
|
-
valueProp: z.string().trim().max(2e3).default("")
|
|
106
|
+
var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
|
|
107
|
+
route: z.string().trim().min(1).max(500).optional()
|
|
337
108
|
});
|
|
338
|
-
var
|
|
339
|
-
|
|
109
|
+
var OntologyScopeSchema = z.object({
|
|
110
|
+
objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
|
|
111
|
+
linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
|
|
112
|
+
actionTypes: z.record(OntologyIdSchema, OntologyActionTypeSchema).default({}).optional(),
|
|
113
|
+
catalogTypes: z.record(OntologyIdSchema, OntologyCatalogTypeSchema).default({}).optional(),
|
|
114
|
+
eventTypes: z.record(OntologyIdSchema, OntologyEventTypeSchema).default({}).optional(),
|
|
115
|
+
interfaceTypes: z.record(OntologyIdSchema, OntologyInterfaceTypeSchema).default({}).optional(),
|
|
116
|
+
valueTypes: z.record(OntologyIdSchema, OntologyValueTypeSchema).default({}).optional(),
|
|
117
|
+
sharedProperties: z.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
|
|
118
|
+
groups: z.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
|
|
119
|
+
surfaces: z.record(OntologyIdSchema, OntologySurfaceTypeSchema).default({}).optional()
|
|
340
120
|
}).default({});
|
|
341
|
-
var DEFAULT_ORGANIZATION_MODEL_CUSTOMERS = {};
|
|
342
|
-
var PricingModelSchema = z.enum(["one-time", "subscription", "usage-based", "custom"]).meta({ label: "Pricing model", color: "green" });
|
|
343
|
-
var ProductSchema = z.object({
|
|
344
|
-
/** Stable unique identifier for the product (e.g. "product-starter-plan"). */
|
|
345
|
-
id: z.string().trim().min(1).max(100),
|
|
346
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
347
|
-
order: z.number(),
|
|
348
|
-
/** Human-readable name shown to agents and in UI (e.g. "Starter Plan"). */
|
|
349
|
-
name: z.string().trim().max(200).default(""),
|
|
350
|
-
/** One or two sentences describing what this product/service delivers. */
|
|
351
|
-
description: z.string().trim().max(2e3).default(""),
|
|
352
|
-
/**
|
|
353
|
-
* How this product is priced:
|
|
354
|
-
* - "one-time" — single purchase (setup fee, project fee)
|
|
355
|
-
* - "subscription" — recurring (monthly/annual SaaS, retainer)
|
|
356
|
-
* - "usage-based" — metered by consumption (API calls, seats)
|
|
357
|
-
* - "custom" — negotiated or bespoke pricing
|
|
358
|
-
*/
|
|
359
|
-
pricingModel: PricingModelSchema.default("custom"),
|
|
360
|
-
/** Base price amount (≥ 0). Currency unit defined by `currency`. */
|
|
361
|
-
price: z.number().min(0).default(0),
|
|
362
|
-
/**
|
|
363
|
-
* ISO 4217 currency code (e.g. "USD", "EUR", "GBP").
|
|
364
|
-
* Free-form string to accommodate any currency; defaults to "USD".
|
|
365
|
-
*/
|
|
366
|
-
currency: z.string().trim().max(10).default("USD"),
|
|
367
|
-
/**
|
|
368
|
-
* IDs of customer segments this product targets.
|
|
369
|
-
* Each id must reference a declared `customers.segments[].id`.
|
|
370
|
-
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
371
|
-
*/
|
|
372
|
-
targetSegmentIds: z.array(z.string().trim().min(1)).default([]),
|
|
373
|
-
/**
|
|
374
|
-
* Optional: ID of the platform system responsible for delivering this product.
|
|
375
|
-
* When present, must reference a declared `systems.systems[].id`.
|
|
376
|
-
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
377
|
-
*/
|
|
378
|
-
deliveryFeatureId: z.string().trim().min(1).optional()
|
|
379
|
-
});
|
|
380
|
-
var OfferingsDomainSchema = z.record(z.string(), ProductSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
381
|
-
message: "Each product entry id must match its map key"
|
|
382
|
-
}).default({});
|
|
383
|
-
var DEFAULT_ORGANIZATION_MODEL_OFFERINGS = {};
|
|
384
|
-
var EntityIdSchema = ModelIdSchema;
|
|
385
|
-
var EntityLinkKindSchema = z.enum(["belongs-to", "has-many", "has-one", "many-to-many"]).meta({ label: "Link kind" });
|
|
386
|
-
var EntityLinkSchema = z.object({
|
|
387
|
-
toEntity: EntityIdSchema.meta({ ref: "entity" }),
|
|
388
|
-
kind: EntityLinkKindSchema,
|
|
389
|
-
via: z.string().trim().min(1).max(255).optional(),
|
|
390
|
-
label: LabelSchema.optional()
|
|
391
|
-
});
|
|
392
|
-
var EntitySchema = z.object({
|
|
393
|
-
id: EntityIdSchema,
|
|
394
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
395
|
-
order: z.number(),
|
|
396
|
-
label: LabelSchema,
|
|
397
|
-
description: DescriptionSchema.optional(),
|
|
398
|
-
ownedBySystemId: ModelIdSchema.meta({ ref: "system" }),
|
|
399
|
-
table: z.string().trim().min(1).max(255).optional(),
|
|
400
|
-
rowSchema: ModelIdSchema.optional(),
|
|
401
|
-
stateCatalogId: ModelIdSchema.optional(),
|
|
402
|
-
links: z.array(EntityLinkSchema).optional()
|
|
403
|
-
});
|
|
404
|
-
var EntitiesDomainSchema = z.record(z.string(), EntitySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
405
|
-
message: "Each entity entry id must match its map key"
|
|
406
|
-
}).default({});
|
|
407
|
-
var ENTITY_ENTRY_INPUTS = [
|
|
408
|
-
{
|
|
409
|
-
id: "crm.deal",
|
|
410
|
-
order: 10,
|
|
411
|
-
label: "Deal",
|
|
412
|
-
description: "A CRM opportunity or sales pipeline record.",
|
|
413
|
-
ownedBySystemId: "sales.crm",
|
|
414
|
-
table: "crm_deals",
|
|
415
|
-
stateCatalogId: "crm.pipeline",
|
|
416
|
-
links: [{ toEntity: "crm.contact", kind: "has-many", via: "deal_contacts", label: "contacts" }]
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
id: "crm.contact",
|
|
420
|
-
order: 20,
|
|
421
|
-
label: "CRM Contact",
|
|
422
|
-
description: "A person associated with a CRM relationship or deal.",
|
|
423
|
-
ownedBySystemId: "sales.crm",
|
|
424
|
-
table: "crm_contacts"
|
|
425
|
-
},
|
|
426
|
-
{
|
|
427
|
-
id: "leadgen.list",
|
|
428
|
-
order: 30,
|
|
429
|
-
label: "Lead List",
|
|
430
|
-
description: "A prospecting list that groups companies and contacts for acquisition workflows.",
|
|
431
|
-
ownedBySystemId: "sales.lead-gen",
|
|
432
|
-
table: "acq_lists",
|
|
433
|
-
links: [
|
|
434
|
-
{ toEntity: "leadgen.company", kind: "has-many", via: "acq_list_companies", label: "companies" },
|
|
435
|
-
{ toEntity: "leadgen.contact", kind: "has-many", via: "acq_list_members", label: "contacts" }
|
|
436
|
-
]
|
|
437
|
-
},
|
|
438
|
-
{
|
|
439
|
-
id: "leadgen.company",
|
|
440
|
-
order: 40,
|
|
441
|
-
label: "Lead Company",
|
|
442
|
-
description: "A company record sourced, enriched, and qualified during prospecting.",
|
|
443
|
-
ownedBySystemId: "sales.lead-gen",
|
|
444
|
-
table: "acq_list_companies",
|
|
445
|
-
stateCatalogId: "lead-gen.company",
|
|
446
|
-
links: [
|
|
447
|
-
{ toEntity: "leadgen.list", kind: "belongs-to", via: "list_id", label: "list" },
|
|
448
|
-
{ toEntity: "leadgen.contact", kind: "has-many", via: "company_id", label: "contacts" }
|
|
449
|
-
]
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
id: "leadgen.contact",
|
|
453
|
-
order: 50,
|
|
454
|
-
label: "Lead Contact",
|
|
455
|
-
description: "A prospect contact discovered or enriched during lead generation.",
|
|
456
|
-
ownedBySystemId: "sales.lead-gen",
|
|
457
|
-
table: "acq_list_members",
|
|
458
|
-
stateCatalogId: "lead-gen.contact",
|
|
459
|
-
links: [
|
|
460
|
-
{ toEntity: "leadgen.list", kind: "belongs-to", via: "list_id", label: "list" },
|
|
461
|
-
{ toEntity: "leadgen.company", kind: "belongs-to", via: "company_id", label: "company" }
|
|
462
|
-
]
|
|
463
|
-
},
|
|
464
|
-
{
|
|
465
|
-
id: "delivery.project",
|
|
466
|
-
order: 60,
|
|
467
|
-
label: "Project",
|
|
468
|
-
description: "A client delivery project.",
|
|
469
|
-
ownedBySystemId: "projects",
|
|
470
|
-
table: "projects",
|
|
471
|
-
links: [
|
|
472
|
-
{ toEntity: "delivery.milestone", kind: "has-many", via: "project_id", label: "milestones" },
|
|
473
|
-
{ toEntity: "delivery.task", kind: "has-many", via: "project_id", label: "tasks" }
|
|
474
|
-
]
|
|
475
|
-
},
|
|
476
|
-
{
|
|
477
|
-
id: "delivery.milestone",
|
|
478
|
-
order: 70,
|
|
479
|
-
label: "Milestone",
|
|
480
|
-
description: "A delivery checkpoint within a project.",
|
|
481
|
-
ownedBySystemId: "projects",
|
|
482
|
-
table: "project_milestones",
|
|
483
|
-
links: [
|
|
484
|
-
{ toEntity: "delivery.project", kind: "belongs-to", via: "project_id", label: "project" },
|
|
485
|
-
{ toEntity: "delivery.task", kind: "has-many", via: "milestone_id", label: "tasks" }
|
|
486
|
-
]
|
|
487
|
-
},
|
|
488
|
-
{
|
|
489
|
-
id: "delivery.task",
|
|
490
|
-
order: 80,
|
|
491
|
-
label: "Task",
|
|
492
|
-
description: "A delivery task that can move through the task status catalog.",
|
|
493
|
-
ownedBySystemId: "projects",
|
|
494
|
-
table: "project_tasks",
|
|
495
|
-
stateCatalogId: "delivery.task",
|
|
496
|
-
links: [
|
|
497
|
-
{ toEntity: "delivery.project", kind: "belongs-to", via: "project_id", label: "project" },
|
|
498
|
-
{ toEntity: "delivery.milestone", kind: "belongs-to", via: "milestone_id", label: "milestone" }
|
|
499
|
-
]
|
|
500
|
-
}
|
|
501
|
-
];
|
|
502
|
-
var DEFAULT_ORGANIZATION_MODEL_ENTITIES = Object.fromEntries(
|
|
503
|
-
ENTITY_ENTRY_INPUTS.map((entity) => {
|
|
504
|
-
const parsed = EntitySchema.parse(entity);
|
|
505
|
-
return [parsed.id, parsed];
|
|
506
|
-
})
|
|
507
|
-
);
|
|
508
|
-
|
|
509
|
-
// ../core/src/organization-model/domains/actions.ts
|
|
510
|
-
var ActionResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
|
|
511
|
-
z.enum(["slash-command", "mcp-tool", "api-endpoint", "script-execution"]).meta({ label: "Invocation kind" });
|
|
512
|
-
var ActionIdSchema = ModelIdSchema;
|
|
513
|
-
var ActionScopeSchema = z.union([
|
|
514
|
-
z.literal("global"),
|
|
515
|
-
z.object({
|
|
516
|
-
domain: ModelIdSchema
|
|
517
|
-
})
|
|
518
|
-
]);
|
|
519
|
-
var ActionRefSchema = z.object({
|
|
520
|
-
actionId: ActionIdSchema.meta({ ref: "action" }),
|
|
521
|
-
intent: z.enum(["exposes", "consumes"]).meta({ label: "Intent" })
|
|
522
|
-
});
|
|
523
|
-
var SlashCommandInvocationSchema = z.object({
|
|
524
|
-
kind: z.literal("slash-command"),
|
|
525
|
-
command: z.string().trim().min(1).max(200).regex(/^\/[^\s].*$/, "Slash commands must start with /"),
|
|
526
|
-
toolFactory: ModelIdSchema.optional()
|
|
527
|
-
});
|
|
528
|
-
var McpToolInvocationSchema = z.object({
|
|
529
|
-
kind: z.literal("mcp-tool"),
|
|
530
|
-
server: ModelIdSchema,
|
|
531
|
-
name: ModelIdSchema
|
|
532
|
-
});
|
|
533
|
-
var ApiEndpointInvocationSchema = z.object({
|
|
534
|
-
kind: z.literal("api-endpoint"),
|
|
535
|
-
method: z.enum(["GET", "POST", "PATCH", "DELETE"]).meta({ label: "HTTP method" }),
|
|
536
|
-
path: z.string().trim().startsWith("/").max(500),
|
|
537
|
-
requestSchema: ModelIdSchema.optional(),
|
|
538
|
-
responseSchema: ModelIdSchema.optional()
|
|
539
|
-
});
|
|
540
|
-
var ScriptExecutionInvocationSchema = z.object({
|
|
541
|
-
kind: z.literal("script-execution"),
|
|
542
|
-
resourceId: ActionResourceIdSchema
|
|
543
|
-
});
|
|
544
|
-
var ActionInvocationSchema = z.discriminatedUnion("kind", [
|
|
545
|
-
SlashCommandInvocationSchema,
|
|
546
|
-
McpToolInvocationSchema,
|
|
547
|
-
ApiEndpointInvocationSchema,
|
|
548
|
-
ScriptExecutionInvocationSchema
|
|
549
|
-
]);
|
|
550
|
-
var ActionSchema = z.object({
|
|
551
|
-
id: ActionIdSchema,
|
|
552
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
553
|
-
order: z.number(),
|
|
554
|
-
label: LabelSchema,
|
|
555
|
-
description: DescriptionSchema.optional(),
|
|
556
|
-
scope: ActionScopeSchema.default("global"),
|
|
557
|
-
resourceId: ActionResourceIdSchema.optional(),
|
|
558
|
-
affects: z.array(EntityIdSchema.meta({ ref: "entity" })).optional(),
|
|
559
|
-
invocations: z.array(ActionInvocationSchema).default([]),
|
|
560
|
-
knowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
|
|
561
|
-
lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
|
|
562
|
-
});
|
|
563
|
-
var ActionsDomainSchema = z.record(z.string(), ActionSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
564
|
-
message: "Each action entry id must match its map key"
|
|
565
|
-
}).default({});
|
|
566
|
-
var DEFAULT_ORGANIZATION_MODEL_ACTIONS = {};
|
|
567
|
-
var OntologyKindSchema = z.enum([
|
|
568
|
-
"object",
|
|
569
|
-
"link",
|
|
570
|
-
"action",
|
|
571
|
-
"catalog",
|
|
572
|
-
"event",
|
|
573
|
-
"interface",
|
|
574
|
-
"value-type",
|
|
575
|
-
"property",
|
|
576
|
-
"group",
|
|
577
|
-
"surface"
|
|
578
|
-
]);
|
|
579
|
-
var SYSTEM_PATH_PATTERN = "[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)*";
|
|
580
|
-
var LOCAL_ID_PATTERN = "[a-z0-9][a-z0-9._-]*";
|
|
581
|
-
var ONTOLOGY_ID_PATTERN = `^(global|${SYSTEM_PATH_PATTERN}):(${OntologyKindSchema.options.join("|")})\\/(${LOCAL_ID_PATTERN})$`;
|
|
582
|
-
var ONTOLOGY_ID_REGEX = new RegExp(ONTOLOGY_ID_PATTERN);
|
|
583
|
-
var OntologyIdSchema = z.string().trim().min(1).max(300).regex(
|
|
584
|
-
ONTOLOGY_ID_REGEX,
|
|
585
|
-
"Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
|
|
586
|
-
);
|
|
587
|
-
function parseOntologyId(id) {
|
|
588
|
-
const normalized = OntologyIdSchema.parse(id);
|
|
589
|
-
const match = ONTOLOGY_ID_REGEX.exec(normalized);
|
|
590
|
-
if (match === null) {
|
|
591
|
-
throw new Error(`Invalid ontology ID "${id}"`);
|
|
592
|
-
}
|
|
593
|
-
return {
|
|
594
|
-
id: normalized,
|
|
595
|
-
scope: match[1],
|
|
596
|
-
kind: match[2],
|
|
597
|
-
localId: match[3],
|
|
598
|
-
isGlobal: match[1] === "global"
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
function formatOntologyId(input) {
|
|
602
|
-
return OntologyIdSchema.parse(`${input.scope}:${input.kind}/${input.localId}`);
|
|
603
|
-
}
|
|
604
|
-
var OntologyReferenceListSchema = z.array(OntologyIdSchema).default([]).optional();
|
|
605
|
-
var OntologyRecordBaseSchema = z.object({
|
|
606
|
-
id: OntologyIdSchema,
|
|
607
|
-
label: z.string().trim().min(1).max(160).optional(),
|
|
608
|
-
description: z.string().trim().min(1).max(2e3).optional(),
|
|
609
|
-
ownerSystemId: z.string().trim().min(1).max(200).optional(),
|
|
610
|
-
aliases: z.array(OntologyIdSchema).optional()
|
|
611
|
-
}).passthrough();
|
|
612
|
-
var OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
|
|
613
|
-
properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
|
|
614
|
-
storage: z.record(z.string(), z.unknown()).optional()
|
|
615
|
-
});
|
|
616
|
-
var OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
|
|
617
|
-
from: OntologyIdSchema,
|
|
618
|
-
to: OntologyIdSchema,
|
|
619
|
-
cardinality: z.string().trim().min(1).max(80).optional(),
|
|
620
|
-
via: z.string().trim().min(1).max(255).optional()
|
|
621
|
-
});
|
|
622
|
-
var OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
|
|
623
|
-
actsOn: OntologyReferenceListSchema,
|
|
624
|
-
input: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
|
|
625
|
-
effects: z.array(z.record(z.string(), z.unknown())).optional()
|
|
626
|
-
});
|
|
627
|
-
var OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
|
|
628
|
-
kind: z.string().trim().min(1).max(120).optional(),
|
|
629
|
-
appliesTo: OntologyIdSchema.optional(),
|
|
630
|
-
entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
631
|
-
});
|
|
632
|
-
var OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
|
|
633
|
-
payload: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
634
|
-
});
|
|
635
|
-
var OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
|
|
636
|
-
properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
637
|
-
});
|
|
638
|
-
var OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
|
|
639
|
-
primitive: z.string().trim().min(1).max(120).optional()
|
|
640
|
-
});
|
|
641
|
-
var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
|
|
642
|
-
valueType: OntologyIdSchema.optional(),
|
|
643
|
-
searchable: z.boolean().optional(),
|
|
644
|
-
pii: z.boolean().optional()
|
|
645
|
-
});
|
|
646
|
-
var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
|
|
647
|
-
members: OntologyReferenceListSchema
|
|
648
|
-
});
|
|
649
|
-
var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
|
|
650
|
-
route: z.string().trim().min(1).max(500).optional()
|
|
651
|
-
});
|
|
652
|
-
var OntologyScopeSchema = z.object({
|
|
653
|
-
objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
|
|
654
|
-
linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
|
|
655
|
-
actionTypes: z.record(OntologyIdSchema, OntologyActionTypeSchema).default({}).optional(),
|
|
656
|
-
catalogTypes: z.record(OntologyIdSchema, OntologyCatalogTypeSchema).default({}).optional(),
|
|
657
|
-
eventTypes: z.record(OntologyIdSchema, OntologyEventTypeSchema).default({}).optional(),
|
|
658
|
-
interfaceTypes: z.record(OntologyIdSchema, OntologyInterfaceTypeSchema).default({}).optional(),
|
|
659
|
-
valueTypes: z.record(OntologyIdSchema, OntologyValueTypeSchema).default({}).optional(),
|
|
660
|
-
sharedProperties: z.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
|
|
661
|
-
groups: z.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
|
|
662
|
-
surfaces: z.record(OntologyIdSchema, OntologySurfaceTypeSchema).default({}).optional()
|
|
663
|
-
}).default({});
|
|
664
|
-
var DEFAULT_ONTOLOGY_SCOPE = {
|
|
665
|
-
valueTypes: {
|
|
666
|
-
"global:value-type/uuid": {
|
|
667
|
-
id: "global:value-type/uuid",
|
|
668
|
-
label: "UUID",
|
|
669
|
-
primitive: "string"
|
|
670
|
-
},
|
|
671
|
-
"global:value-type/text": {
|
|
672
|
-
id: "global:value-type/text",
|
|
673
|
-
label: "Text",
|
|
674
|
-
primitive: "string"
|
|
675
|
-
},
|
|
676
|
-
"global:value-type/url": {
|
|
677
|
-
id: "global:value-type/url",
|
|
678
|
-
label: "URL",
|
|
679
|
-
primitive: "string"
|
|
680
|
-
},
|
|
681
|
-
"global:value-type/email": {
|
|
682
|
-
id: "global:value-type/email",
|
|
683
|
-
label: "Email",
|
|
684
|
-
primitive: "string"
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
};
|
|
688
121
|
var SCOPE_KIND = {
|
|
689
122
|
objectTypes: "object",
|
|
690
123
|
linkTypes: "link",
|
|
@@ -698,16 +131,6 @@ var SCOPE_KIND = {
|
|
|
698
131
|
surfaces: "surface"
|
|
699
132
|
};
|
|
700
133
|
var SCOPE_KEYS = Object.keys(SCOPE_KIND);
|
|
701
|
-
function listResolvedOntologyRecords(index) {
|
|
702
|
-
return SCOPE_KEYS.flatMap((scopeKey) => {
|
|
703
|
-
const kind = SCOPE_KIND[scopeKey];
|
|
704
|
-
return Object.entries(index[scopeKey]).sort(([leftId], [rightId]) => leftId.localeCompare(rightId)).map(([id, record]) => ({
|
|
705
|
-
id,
|
|
706
|
-
kind,
|
|
707
|
-
record
|
|
708
|
-
}));
|
|
709
|
-
});
|
|
710
|
-
}
|
|
711
134
|
function originFromContext(context) {
|
|
712
135
|
return {
|
|
713
136
|
kind: context.kind,
|
|
@@ -905,17 +328,343 @@ function addSystemScopes(index, diagnostics, sourcesById, systems, prefix, schem
|
|
|
905
328
|
system.systems !== void 0 ? "systems" : "subsystems"
|
|
906
329
|
]);
|
|
907
330
|
}
|
|
908
|
-
}
|
|
909
|
-
function compileOrganizationOntology(model) {
|
|
910
|
-
const ontology = createEmptyIndex();
|
|
911
|
-
const diagnostics = [];
|
|
912
|
-
const sourcesById = /* @__PURE__ */ new Map();
|
|
913
|
-
addScope(ontology, diagnostics, sourcesById, model.ontology, "organization.ontology", ["ontology"]);
|
|
914
|
-
addSystemScopes(ontology, diagnostics, sourcesById, model.systems ?? {}, "", ["systems"]);
|
|
915
|
-
addLegacyEntityProjections(ontology, diagnostics, sourcesById, model.entities ?? {});
|
|
916
|
-
addLegacyActionProjections(ontology, diagnostics, sourcesById, model.actions ?? {}, model.entities ?? {});
|
|
917
|
-
return { ontology: sortResolvedOntologyIndex(ontology), diagnostics };
|
|
918
|
-
}
|
|
331
|
+
}
|
|
332
|
+
function compileOrganizationOntology(model) {
|
|
333
|
+
const ontology = createEmptyIndex();
|
|
334
|
+
const diagnostics = [];
|
|
335
|
+
const sourcesById = /* @__PURE__ */ new Map();
|
|
336
|
+
addScope(ontology, diagnostics, sourcesById, model.ontology, "organization.ontology", ["ontology"]);
|
|
337
|
+
addSystemScopes(ontology, diagnostics, sourcesById, model.systems ?? {}, "", ["systems"]);
|
|
338
|
+
addLegacyEntityProjections(ontology, diagnostics, sourcesById, model.entities ?? {});
|
|
339
|
+
addLegacyActionProjections(ontology, diagnostics, sourcesById, model.actions ?? {}, model.entities ?? {});
|
|
340
|
+
return { ontology: sortResolvedOntologyIndex(ontology), diagnostics };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// ../core/src/organization-model/helpers.ts
|
|
344
|
+
function childSystemsOf2(system) {
|
|
345
|
+
return system.systems ?? system.subsystems ?? {};
|
|
346
|
+
}
|
|
347
|
+
function listAllSystems(model) {
|
|
348
|
+
const results = [];
|
|
349
|
+
function walk(map, prefix) {
|
|
350
|
+
for (const [localId, system] of Object.entries(map)) {
|
|
351
|
+
const fullPath = prefix ? `${prefix}.${localId}` : localId;
|
|
352
|
+
results.push({ path: fullPath, system });
|
|
353
|
+
const childSystems = childSystemsOf2(system);
|
|
354
|
+
if (Object.keys(childSystems).length > 0) {
|
|
355
|
+
walk(childSystems, fullPath);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
walk(model.systems, "");
|
|
360
|
+
return results;
|
|
361
|
+
}
|
|
362
|
+
var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
363
|
+
// Navigation / app areas
|
|
364
|
+
"dashboard",
|
|
365
|
+
"calendar",
|
|
366
|
+
"sales",
|
|
367
|
+
"crm",
|
|
368
|
+
"lead-gen",
|
|
369
|
+
"projects",
|
|
370
|
+
"clients",
|
|
371
|
+
"operations",
|
|
372
|
+
"monitoring",
|
|
373
|
+
"knowledge",
|
|
374
|
+
"settings",
|
|
375
|
+
"admin",
|
|
376
|
+
"archive",
|
|
377
|
+
"business",
|
|
378
|
+
"finance",
|
|
379
|
+
"platform",
|
|
380
|
+
"seo",
|
|
381
|
+
// Knowledge kinds
|
|
382
|
+
"playbook",
|
|
383
|
+
"strategy",
|
|
384
|
+
"reference",
|
|
385
|
+
// Resource kinds
|
|
386
|
+
"agent",
|
|
387
|
+
"workflow",
|
|
388
|
+
"integration",
|
|
389
|
+
"database",
|
|
390
|
+
"user",
|
|
391
|
+
"team",
|
|
392
|
+
// Integration specifics
|
|
393
|
+
"gmail",
|
|
394
|
+
"google-sheets",
|
|
395
|
+
"attio",
|
|
396
|
+
// Surface / UI views
|
|
397
|
+
"overview",
|
|
398
|
+
"command-view",
|
|
399
|
+
"command-queue",
|
|
400
|
+
"pipeline",
|
|
401
|
+
"lists",
|
|
402
|
+
"resources",
|
|
403
|
+
// Actions
|
|
404
|
+
"approve",
|
|
405
|
+
"reject",
|
|
406
|
+
"retry",
|
|
407
|
+
"edit",
|
|
408
|
+
"view",
|
|
409
|
+
"launch",
|
|
410
|
+
"message",
|
|
411
|
+
"escalate",
|
|
412
|
+
"promote",
|
|
413
|
+
"submit",
|
|
414
|
+
"email",
|
|
415
|
+
// Status
|
|
416
|
+
"success",
|
|
417
|
+
"error",
|
|
418
|
+
"warning",
|
|
419
|
+
"info",
|
|
420
|
+
"pending",
|
|
421
|
+
// OM / UI group icons
|
|
422
|
+
"bolt",
|
|
423
|
+
"building",
|
|
424
|
+
"briefcase",
|
|
425
|
+
"apps",
|
|
426
|
+
"graph",
|
|
427
|
+
"shield",
|
|
428
|
+
"users",
|
|
429
|
+
"chart-bar",
|
|
430
|
+
"search"
|
|
431
|
+
];
|
|
432
|
+
var CustomIconTokenSchema = z.string().trim().max(80).regex(
|
|
433
|
+
/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
|
|
434
|
+
'Custom icon tokens must start with "custom." followed by lowercase alphanumeric segments'
|
|
435
|
+
);
|
|
436
|
+
var OrganizationModelBuiltinIconTokenSchema = z.enum(ORGANIZATION_MODEL_ICON_TOKENS);
|
|
437
|
+
var OrganizationModelIconTokenSchema = z.union([
|
|
438
|
+
OrganizationModelBuiltinIconTokenSchema,
|
|
439
|
+
CustomIconTokenSchema
|
|
440
|
+
]);
|
|
441
|
+
|
|
442
|
+
// ../core/src/organization-model/domains/shared.ts
|
|
443
|
+
var ModelIdSchema = z.string().trim().min(1).max(100).regex(/^[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "IDs must be lowercase and use -, _, or . separators");
|
|
444
|
+
var LabelSchema = z.string().trim().min(1).max(120);
|
|
445
|
+
var DescriptionSchema = z.string().trim().min(1).max(2e3);
|
|
446
|
+
var ColorTokenSchema = z.string().trim().min(1).max(50);
|
|
447
|
+
var IconNameSchema = OrganizationModelIconTokenSchema;
|
|
448
|
+
var PathSchema = z.string().trim().startsWith("/").max(300);
|
|
449
|
+
var ReferenceIdsSchema = z.array(ModelIdSchema).default([]);
|
|
450
|
+
var DisplayMetadataSchema = z.object({
|
|
451
|
+
label: LabelSchema,
|
|
452
|
+
description: DescriptionSchema.optional(),
|
|
453
|
+
color: ColorTokenSchema.optional(),
|
|
454
|
+
icon: IconNameSchema.optional()
|
|
455
|
+
});
|
|
456
|
+
var TechStackEntrySchema = z.object({
|
|
457
|
+
/** Name of the external platform (e.g. "HubSpot", "Stripe", "Notion"). */
|
|
458
|
+
platform: z.string().trim().min(1).max(200),
|
|
459
|
+
/** Free-form description of what this integration is used for. */
|
|
460
|
+
purpose: z.string().trim().min(1).max(500),
|
|
461
|
+
/**
|
|
462
|
+
* Health of the credential backing this integration.
|
|
463
|
+
* - configured: credential present and valid
|
|
464
|
+
* - pending: not yet set up
|
|
465
|
+
* - expired: credential existed but has lapsed
|
|
466
|
+
* - missing: expected but not present
|
|
467
|
+
*/
|
|
468
|
+
credentialStatus: z.enum(["configured", "pending", "expired", "missing"]),
|
|
469
|
+
/**
|
|
470
|
+
* Whether this integration is the primary system of record for its domain
|
|
471
|
+
* (e.g. HubSpot is SoR for contacts). Defaults to false.
|
|
472
|
+
*/
|
|
473
|
+
isSystemOfRecord: z.boolean().default(false)
|
|
474
|
+
});
|
|
475
|
+
DisplayMetadataSchema.extend({
|
|
476
|
+
id: ModelIdSchema,
|
|
477
|
+
resourceId: z.string().trim().min(1).max(255),
|
|
478
|
+
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
|
|
479
|
+
systemIds: ReferenceIdsSchema,
|
|
480
|
+
entityIds: ReferenceIdsSchema,
|
|
481
|
+
surfaceIds: ReferenceIdsSchema,
|
|
482
|
+
actionIds: ReferenceIdsSchema,
|
|
483
|
+
/** Optional tech-stack metadata for external-SaaS integrations. */
|
|
484
|
+
techStack: TechStackEntrySchema.optional()
|
|
485
|
+
});
|
|
486
|
+
var EntityIdSchema = ModelIdSchema;
|
|
487
|
+
var EntityLinkKindSchema = z.enum(["belongs-to", "has-many", "has-one", "many-to-many"]).meta({ label: "Link kind" });
|
|
488
|
+
var EntityLinkSchema = z.object({
|
|
489
|
+
toEntity: EntityIdSchema.meta({ ref: "entity" }),
|
|
490
|
+
kind: EntityLinkKindSchema,
|
|
491
|
+
via: z.string().trim().min(1).max(255).optional(),
|
|
492
|
+
label: LabelSchema.optional()
|
|
493
|
+
});
|
|
494
|
+
var EntitySchema = z.object({
|
|
495
|
+
id: EntityIdSchema,
|
|
496
|
+
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
497
|
+
order: z.number(),
|
|
498
|
+
label: LabelSchema,
|
|
499
|
+
description: DescriptionSchema.optional(),
|
|
500
|
+
ownedBySystemId: ModelIdSchema.meta({ ref: "system" }),
|
|
501
|
+
table: z.string().trim().min(1).max(255).optional(),
|
|
502
|
+
rowSchema: ModelIdSchema.optional(),
|
|
503
|
+
stateCatalogId: ModelIdSchema.optional(),
|
|
504
|
+
links: z.array(EntityLinkSchema).optional()
|
|
505
|
+
});
|
|
506
|
+
z.record(z.string(), EntitySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
507
|
+
message: "Each entity entry id must match its map key"
|
|
508
|
+
}).default({});
|
|
509
|
+
var ENTITY_ENTRY_INPUTS = [
|
|
510
|
+
{
|
|
511
|
+
id: "crm.deal",
|
|
512
|
+
order: 10,
|
|
513
|
+
label: "Deal",
|
|
514
|
+
description: "A CRM opportunity or sales pipeline record.",
|
|
515
|
+
ownedBySystemId: "sales.crm",
|
|
516
|
+
table: "crm_deals",
|
|
517
|
+
stateCatalogId: "crm.pipeline",
|
|
518
|
+
links: [{ toEntity: "crm.contact", kind: "has-many", via: "deal_contacts", label: "contacts" }]
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
id: "crm.contact",
|
|
522
|
+
order: 20,
|
|
523
|
+
label: "CRM Contact",
|
|
524
|
+
description: "A person associated with a CRM relationship or deal.",
|
|
525
|
+
ownedBySystemId: "sales.crm",
|
|
526
|
+
table: "crm_contacts"
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
id: "leadgen.list",
|
|
530
|
+
order: 30,
|
|
531
|
+
label: "Lead List",
|
|
532
|
+
description: "A prospecting list that groups companies and contacts for acquisition workflows.",
|
|
533
|
+
ownedBySystemId: "sales.lead-gen",
|
|
534
|
+
table: "acq_lists",
|
|
535
|
+
links: [
|
|
536
|
+
{ toEntity: "leadgen.company", kind: "has-many", via: "acq_list_companies", label: "companies" },
|
|
537
|
+
{ toEntity: "leadgen.contact", kind: "has-many", via: "acq_list_members", label: "contacts" }
|
|
538
|
+
]
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
id: "leadgen.company",
|
|
542
|
+
order: 40,
|
|
543
|
+
label: "Lead Company",
|
|
544
|
+
description: "A company record sourced, enriched, and qualified during prospecting.",
|
|
545
|
+
ownedBySystemId: "sales.lead-gen",
|
|
546
|
+
table: "acq_list_companies",
|
|
547
|
+
stateCatalogId: "lead-gen.company",
|
|
548
|
+
links: [
|
|
549
|
+
{ toEntity: "leadgen.list", kind: "belongs-to", via: "list_id", label: "list" },
|
|
550
|
+
{ toEntity: "leadgen.contact", kind: "has-many", via: "company_id", label: "contacts" }
|
|
551
|
+
]
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
id: "leadgen.contact",
|
|
555
|
+
order: 50,
|
|
556
|
+
label: "Lead Contact",
|
|
557
|
+
description: "A prospect contact discovered or enriched during lead generation.",
|
|
558
|
+
ownedBySystemId: "sales.lead-gen",
|
|
559
|
+
table: "acq_list_members",
|
|
560
|
+
stateCatalogId: "lead-gen.contact",
|
|
561
|
+
links: [
|
|
562
|
+
{ toEntity: "leadgen.list", kind: "belongs-to", via: "list_id", label: "list" },
|
|
563
|
+
{ toEntity: "leadgen.company", kind: "belongs-to", via: "company_id", label: "company" }
|
|
564
|
+
]
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
id: "delivery.project",
|
|
568
|
+
order: 60,
|
|
569
|
+
label: "Project",
|
|
570
|
+
description: "A client delivery project.",
|
|
571
|
+
ownedBySystemId: "projects",
|
|
572
|
+
table: "projects",
|
|
573
|
+
links: [
|
|
574
|
+
{ toEntity: "delivery.milestone", kind: "has-many", via: "project_id", label: "milestones" },
|
|
575
|
+
{ toEntity: "delivery.task", kind: "has-many", via: "project_id", label: "tasks" }
|
|
576
|
+
]
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
id: "delivery.milestone",
|
|
580
|
+
order: 70,
|
|
581
|
+
label: "Milestone",
|
|
582
|
+
description: "A delivery checkpoint within a project.",
|
|
583
|
+
ownedBySystemId: "projects",
|
|
584
|
+
table: "project_milestones",
|
|
585
|
+
links: [
|
|
586
|
+
{ toEntity: "delivery.project", kind: "belongs-to", via: "project_id", label: "project" },
|
|
587
|
+
{ toEntity: "delivery.task", kind: "has-many", via: "milestone_id", label: "tasks" }
|
|
588
|
+
]
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
id: "delivery.task",
|
|
592
|
+
order: 80,
|
|
593
|
+
label: "Task",
|
|
594
|
+
description: "A delivery task that can move through the task status catalog.",
|
|
595
|
+
ownedBySystemId: "projects",
|
|
596
|
+
table: "project_tasks",
|
|
597
|
+
stateCatalogId: "delivery.task",
|
|
598
|
+
links: [
|
|
599
|
+
{ toEntity: "delivery.project", kind: "belongs-to", via: "project_id", label: "project" },
|
|
600
|
+
{ toEntity: "delivery.milestone", kind: "belongs-to", via: "milestone_id", label: "milestone" }
|
|
601
|
+
]
|
|
602
|
+
}
|
|
603
|
+
];
|
|
604
|
+
Object.fromEntries(
|
|
605
|
+
ENTITY_ENTRY_INPUTS.map((entity) => {
|
|
606
|
+
const parsed = EntitySchema.parse(entity);
|
|
607
|
+
return [parsed.id, parsed];
|
|
608
|
+
})
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
// ../core/src/organization-model/domains/actions.ts
|
|
612
|
+
var ActionResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
|
|
613
|
+
z.enum(["slash-command", "mcp-tool", "api-endpoint", "script-execution"]).meta({ label: "Invocation kind" });
|
|
614
|
+
var ActionIdSchema = ModelIdSchema;
|
|
615
|
+
var ActionScopeSchema = z.union([
|
|
616
|
+
z.literal("global"),
|
|
617
|
+
z.object({
|
|
618
|
+
domain: ModelIdSchema
|
|
619
|
+
})
|
|
620
|
+
]);
|
|
621
|
+
var ActionRefSchema = z.object({
|
|
622
|
+
actionId: ActionIdSchema.meta({ ref: "action" }),
|
|
623
|
+
intent: z.enum(["exposes", "consumes"]).meta({ label: "Intent" })
|
|
624
|
+
});
|
|
625
|
+
var SlashCommandInvocationSchema = z.object({
|
|
626
|
+
kind: z.literal("slash-command"),
|
|
627
|
+
command: z.string().trim().min(1).max(200).regex(/^\/[^\s].*$/, "Slash commands must start with /"),
|
|
628
|
+
toolFactory: ModelIdSchema.optional()
|
|
629
|
+
});
|
|
630
|
+
var McpToolInvocationSchema = z.object({
|
|
631
|
+
kind: z.literal("mcp-tool"),
|
|
632
|
+
server: ModelIdSchema,
|
|
633
|
+
name: ModelIdSchema
|
|
634
|
+
});
|
|
635
|
+
var ApiEndpointInvocationSchema = z.object({
|
|
636
|
+
kind: z.literal("api-endpoint"),
|
|
637
|
+
method: z.enum(["GET", "POST", "PATCH", "DELETE"]).meta({ label: "HTTP method" }),
|
|
638
|
+
path: z.string().trim().startsWith("/").max(500),
|
|
639
|
+
requestSchema: ModelIdSchema.optional(),
|
|
640
|
+
responseSchema: ModelIdSchema.optional()
|
|
641
|
+
});
|
|
642
|
+
var ScriptExecutionInvocationSchema = z.object({
|
|
643
|
+
kind: z.literal("script-execution"),
|
|
644
|
+
resourceId: ActionResourceIdSchema
|
|
645
|
+
});
|
|
646
|
+
var ActionInvocationSchema = z.discriminatedUnion("kind", [
|
|
647
|
+
SlashCommandInvocationSchema,
|
|
648
|
+
McpToolInvocationSchema,
|
|
649
|
+
ApiEndpointInvocationSchema,
|
|
650
|
+
ScriptExecutionInvocationSchema
|
|
651
|
+
]);
|
|
652
|
+
var ActionSchema = z.object({
|
|
653
|
+
id: ActionIdSchema,
|
|
654
|
+
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
655
|
+
order: z.number(),
|
|
656
|
+
label: LabelSchema,
|
|
657
|
+
description: DescriptionSchema.optional(),
|
|
658
|
+
scope: ActionScopeSchema.default("global"),
|
|
659
|
+
resourceId: ActionResourceIdSchema.optional(),
|
|
660
|
+
affects: z.array(EntityIdSchema.meta({ ref: "entity" })).optional(),
|
|
661
|
+
invocations: z.array(ActionInvocationSchema).default([]),
|
|
662
|
+
knowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
|
|
663
|
+
lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
|
|
664
|
+
});
|
|
665
|
+
z.record(z.string(), ActionSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
666
|
+
message: "Each action entry id must match its map key"
|
|
667
|
+
}).default({});
|
|
919
668
|
|
|
920
669
|
// ../core/src/organization-model/domains/systems.ts
|
|
921
670
|
var SystemKindSchema = z.enum(["product", "operational", "platform", "diagnostic"]).meta({ label: "System kind", color: "blue" });
|
|
@@ -927,7 +676,7 @@ var SystemPathSchema = z.string().trim().min(1).regex(
|
|
|
927
676
|
'must be a dotted lowercase path (e.g. "sales.lead-gen" or "sales.crm")'
|
|
928
677
|
);
|
|
929
678
|
var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]).meta({ label: "UI position" });
|
|
930
|
-
|
|
679
|
+
z.string().trim().min(1).max(200).regex(
|
|
931
680
|
/^[a-z][a-z-]*:([a-z0-9-]+)(\.[a-z0-9-]+)*(:[a-z0-9.-]+)*$/,
|
|
932
681
|
"Node references must use kind:dotted-path (e.g. system:sales.crm or resource:lead-gen.company.qualify)"
|
|
933
682
|
);
|
|
@@ -1022,10 +771,9 @@ var SystemEntrySchema = z.object({
|
|
|
1022
771
|
console.warn("[organization-model] System.status is deprecated; use System.lifecycle instead.");
|
|
1023
772
|
return normalizedSystem.lifecycle === void 0 ? { ...normalizedSystem, lifecycle: normalizedSystem.status } : normalizedSystem;
|
|
1024
773
|
});
|
|
1025
|
-
|
|
774
|
+
z.record(z.string(), SystemEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1026
775
|
message: "Each system entry id must match its map key"
|
|
1027
776
|
}).default({});
|
|
1028
|
-
var DEFAULT_ORGANIZATION_MODEL_SYSTEMS = {};
|
|
1029
777
|
|
|
1030
778
|
// ../core/src/organization-model/domains/resources.ts
|
|
1031
779
|
var ContractRefSchema = z.string().trim().min(1).max(500).regex(
|
|
@@ -1092,1236 +840,264 @@ var ResourceOntologyBindingSchema = z.object({
|
|
|
1092
840
|
}).superRefine((binding, ctx) => {
|
|
1093
841
|
if (binding.primaryAction === void 0) return;
|
|
1094
842
|
if (binding.actions?.includes(binding.primaryAction)) return;
|
|
1095
|
-
ctx.addIssue({
|
|
1096
|
-
code: z.ZodIssueCode.custom,
|
|
1097
|
-
path: ["primaryAction"],
|
|
1098
|
-
message: "Resource ontology primaryAction must be included in actions"
|
|
1099
|
-
});
|
|
1100
|
-
});
|
|
1101
|
-
var CodeReferenceSchema = z.object({
|
|
1102
|
-
path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
|
|
1103
|
-
role: CodeReferenceRoleSchema,
|
|
1104
|
-
symbol: z.string().trim().min(1).max(200).optional(),
|
|
1105
|
-
description: z.string().trim().min(1).max(300).optional()
|
|
1106
|
-
});
|
|
1107
|
-
var ResourceEntryBaseSchema = z.object({
|
|
1108
|
-
/** Canonical resource id; runtime resourceId derives from this value. */
|
|
1109
|
-
id: ResourceIdSchema,
|
|
1110
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
1111
|
-
order: z.number().default(0),
|
|
1112
|
-
/** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
|
|
1113
|
-
systemPath: SystemPathSchema.meta({ ref: "system" }),
|
|
1114
|
-
/** Executable display title owned by the OM Resource descriptor. */
|
|
1115
|
-
title: LabelSchema.optional(),
|
|
1116
|
-
/** Executable display description owned by the OM Resource descriptor. */
|
|
1117
|
-
description: DescriptionSchema.optional(),
|
|
1118
|
-
/** Optional role responsible for maintaining this resource. */
|
|
1119
|
-
ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
1120
|
-
status: ResourceGovernanceStatusSchema,
|
|
1121
|
-
/**
|
|
1122
|
-
* Ontology contract bindings for the semantic work this resource performs.
|
|
1123
|
-
* `emits` stays nested here so top-level resource emits descriptors remain
|
|
1124
|
-
* compatible with graph event projection during the bridge.
|
|
1125
|
-
*/
|
|
1126
|
-
ontology: ResourceOntologyBindingSchema.optional(),
|
|
1127
|
-
/** Repo-relative implementation breadcrumbs for agents and operators. */
|
|
1128
|
-
codeRefs: z.array(CodeReferenceSchema).default([])
|
|
1129
|
-
});
|
|
1130
|
-
var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
1131
|
-
kind: z.literal("workflow"),
|
|
1132
|
-
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
1133
|
-
});
|
|
1134
|
-
var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
1135
|
-
kind: z.literal("agent"),
|
|
1136
|
-
/** Mirrors code-side AgentConfig.kind. */
|
|
1137
|
-
agentKind: AgentKindSchema,
|
|
1138
|
-
/** Role this agent embodies, if any. */
|
|
1139
|
-
actsAsRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
1140
|
-
/** Mirrors AgentConfig.sessionCapable. */
|
|
1141
|
-
sessionCapable: z.boolean(),
|
|
1142
|
-
/** Broad/composite callable entry points orchestrated by this agent. */
|
|
1143
|
-
invocations: z.array(ActionInvocationSchema).default([]),
|
|
1144
|
-
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
1145
|
-
});
|
|
1146
|
-
var IntegrationResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
1147
|
-
kind: z.literal("integration"),
|
|
1148
|
-
provider: z.string().trim().min(1).max(100)
|
|
1149
|
-
});
|
|
1150
|
-
var ScriptResourceSourceSchema = z.union([
|
|
1151
|
-
z.string().trim().min(1).max(5e4),
|
|
1152
|
-
z.object({
|
|
1153
|
-
file: z.string().trim().min(1).max(500)
|
|
1154
|
-
})
|
|
1155
|
-
]);
|
|
1156
|
-
var ScriptResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
1157
|
-
kind: z.literal("script"),
|
|
1158
|
-
language: ScriptResourceLanguageSchema,
|
|
1159
|
-
source: ScriptResourceSourceSchema
|
|
1160
|
-
});
|
|
1161
|
-
var ResourceEntrySchema = z.discriminatedUnion("kind", [
|
|
1162
|
-
WorkflowResourceEntrySchema,
|
|
1163
|
-
AgentResourceEntrySchema,
|
|
1164
|
-
IntegrationResourceEntrySchema,
|
|
1165
|
-
ScriptResourceEntrySchema
|
|
1166
|
-
]);
|
|
1167
|
-
var ResourcesDomainSchema = z.record(z.string(), ResourceEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1168
|
-
message: "Each resource entry id must match its map key"
|
|
1169
|
-
}).default({});
|
|
1170
|
-
var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {};
|
|
1171
|
-
function defineResource(resource) {
|
|
1172
|
-
return ResourceEntrySchema.parse(resource);
|
|
1173
|
-
}
|
|
1174
|
-
function defineResources(resources) {
|
|
1175
|
-
return Object.fromEntries(
|
|
1176
|
-
Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
function ontologyIdFrom(input) {
|
|
1180
|
-
return typeof input === "string" ? input : input.id;
|
|
1181
|
-
}
|
|
1182
|
-
function ontologyIdArrayFrom(input) {
|
|
1183
|
-
return input?.map(ontologyIdFrom);
|
|
1184
|
-
}
|
|
1185
|
-
function defineResourceOntology(input) {
|
|
1186
|
-
return ResourceOntologyBindingSchema.parse({
|
|
1187
|
-
actions: ontologyIdArrayFrom(input.actions),
|
|
1188
|
-
primaryAction: input.primaryAction === void 0 ? void 0 : ontologyIdFrom(input.primaryAction),
|
|
1189
|
-
reads: ontologyIdArrayFrom(input.reads),
|
|
1190
|
-
writes: ontologyIdArrayFrom(input.writes),
|
|
1191
|
-
usesCatalogs: ontologyIdArrayFrom(input.usesCatalogs),
|
|
1192
|
-
emits: ontologyIdArrayFrom(input.emits)
|
|
1193
|
-
});
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
// ../core/src/organization-model/domains/roles.ts
|
|
1197
|
-
var RoleIdSchema = ModelIdSchema;
|
|
1198
|
-
var HumanRoleHolderSchema = z.object({
|
|
1199
|
-
kind: z.literal("human"),
|
|
1200
|
-
userId: z.string().trim().min(1).max(200)
|
|
1201
|
-
});
|
|
1202
|
-
var AgentRoleHolderSchema = z.object({
|
|
1203
|
-
kind: z.literal("agent"),
|
|
1204
|
-
agentId: ResourceIdSchema.meta({ ref: "resource" })
|
|
1205
|
-
});
|
|
1206
|
-
var TeamRoleHolderSchema = z.object({
|
|
1207
|
-
kind: z.literal("team"),
|
|
1208
|
-
memberIds: z.array(z.string().trim().min(1).max(200)).min(1)
|
|
1209
|
-
});
|
|
1210
|
-
var RoleHolderSchema = z.discriminatedUnion("kind", [
|
|
1211
|
-
HumanRoleHolderSchema,
|
|
1212
|
-
AgentRoleHolderSchema,
|
|
1213
|
-
TeamRoleHolderSchema
|
|
1214
|
-
]);
|
|
1215
|
-
var RoleHoldersSchema = z.union([RoleHolderSchema, z.array(RoleHolderSchema).min(1)]);
|
|
1216
|
-
var RoleSchema = z.object({
|
|
1217
|
-
/** Stable unique identifier for the role (e.g. "role-ceo", "role-head-of-sales"). */
|
|
1218
|
-
id: RoleIdSchema,
|
|
1219
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
1220
|
-
order: z.number(),
|
|
1221
|
-
/** Human-readable title shown to agents and in UI (e.g. "CEO", "Head of Sales"). */
|
|
1222
|
-
title: z.string().trim().min(1).max(200),
|
|
1223
|
-
/**
|
|
1224
|
-
* List of responsibilities this role owns - plain-language descriptions of
|
|
1225
|
-
* what the person in this role is accountable for delivering.
|
|
1226
|
-
* Defaults to empty array so minimal role definitions stay concise.
|
|
1227
|
-
*/
|
|
1228
|
-
responsibilities: z.array(z.string().trim().max(500)).default([]),
|
|
1229
|
-
/**
|
|
1230
|
-
* Optional: ID of another role this role reports to.
|
|
1231
|
-
* When present, must reference another `roles[].id` in the same organization.
|
|
1232
|
-
*/
|
|
1233
|
-
reportsToId: RoleIdSchema.meta({ ref: "role" }).optional(),
|
|
1234
|
-
/**
|
|
1235
|
-
* Optional: human, agent, or team holder currently filling this role.
|
|
1236
|
-
* Agent holders reference OM Resource IDs and are validated at the model level.
|
|
1237
|
-
*/
|
|
1238
|
-
heldBy: RoleHoldersSchema.optional(),
|
|
1239
|
-
/**
|
|
1240
|
-
* Optional Systems this role is accountable for.
|
|
1241
|
-
* Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
|
|
1242
|
-
*/
|
|
1243
|
-
responsibleFor: z.array(SystemIdSchema.meta({ ref: "system" })).optional()
|
|
1244
|
-
});
|
|
1245
|
-
var RolesDomainSchema = z.record(z.string(), RoleSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1246
|
-
message: "Each role entry id must match its map key"
|
|
1247
|
-
}).default({});
|
|
1248
|
-
var DEFAULT_ORGANIZATION_MODEL_ROLES = {};
|
|
1249
|
-
var KeyResultSchema = z.object({
|
|
1250
|
-
/** Stable unique identifier for the measurable outcome (e.g. "kr-revenue-q1"). */
|
|
1251
|
-
id: z.string().trim().min(1).max(100),
|
|
1252
|
-
/** Plain-language description of this measurable outcome (e.g. "Increase trial-to-paid conversion"). */
|
|
1253
|
-
description: z.string().trim().min(1).max(500),
|
|
1254
|
-
/**
|
|
1255
|
-
* What is being measured — the metric name (e.g. "monthly revenue", "NPS score",
|
|
1256
|
-
* "trial-to-paid conversion rate"). Free-form string.
|
|
1257
|
-
*/
|
|
1258
|
-
targetMetric: z.string().trim().min(1).max(200),
|
|
1259
|
-
/** Current measured value. Defaults to 0 when not yet tracked. */
|
|
1260
|
-
currentValue: z.number().default(0),
|
|
1261
|
-
/**
|
|
1262
|
-
* Target value to reach for this measurable outcome to be considered achieved.
|
|
1263
|
-
* Optional — omit if the outcome is directional (e.g. "reduce churn") without
|
|
1264
|
-
* a hard numeric target.
|
|
1265
|
-
*/
|
|
1266
|
-
targetValue: z.number().optional()
|
|
1267
|
-
});
|
|
1268
|
-
var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
1269
|
-
var ObjectiveSchema = z.object({
|
|
1270
|
-
/** Stable unique identifier for the goal (e.g. "goal-grow-arr-q1-2026"). */
|
|
1271
|
-
id: z.string().trim().min(1).max(100),
|
|
1272
|
-
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
1273
|
-
order: z.number(),
|
|
1274
|
-
/** Plain-language description of what the organization wants to achieve. */
|
|
1275
|
-
description: z.string().trim().min(1).max(1e3),
|
|
1276
|
-
/**
|
|
1277
|
-
* Start of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
|
|
1278
|
-
* Must be strictly before `periodEnd`.
|
|
1279
|
-
*/
|
|
1280
|
-
periodStart: z.string().regex(ISO_DATE_REGEX, "periodStart must be an ISO date string (YYYY-MM-DD)"),
|
|
1281
|
-
/**
|
|
1282
|
-
* End of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
|
|
1283
|
-
* Must be strictly after `periodStart`.
|
|
1284
|
-
* Enforced via `OrganizationModelSchema.superRefine()`.
|
|
1285
|
-
*/
|
|
1286
|
-
periodEnd: z.string().regex(ISO_DATE_REGEX, "periodEnd must be an ISO date string (YYYY-MM-DD)"),
|
|
1287
|
-
/**
|
|
1288
|
-
* List of measurable outcomes that define success for this goal.
|
|
1289
|
-
* Defaults to empty array so goals can be declared before outcomes are defined.
|
|
1290
|
-
*/
|
|
1291
|
-
keyResults: z.array(KeyResultSchema).default([])
|
|
1292
|
-
});
|
|
1293
|
-
var GoalsDomainSchema = z.record(z.string(), ObjectiveSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1294
|
-
message: "Each objective entry id must match its map key"
|
|
1295
|
-
}).default({});
|
|
1296
|
-
var DEFAULT_ORGANIZATION_MODEL_GOALS = {};
|
|
1297
|
-
var KnowledgeTargetKindSchema = z.enum([
|
|
1298
|
-
"system",
|
|
1299
|
-
"resource",
|
|
1300
|
-
"knowledge",
|
|
1301
|
-
"stage",
|
|
1302
|
-
"action",
|
|
1303
|
-
"role",
|
|
1304
|
-
"goal",
|
|
1305
|
-
"customer-segment",
|
|
1306
|
-
"offering",
|
|
1307
|
-
"ontology"
|
|
1308
|
-
]).meta({ label: "Target kind" });
|
|
1309
|
-
var KnowledgeTargetRefSchema = z.object({
|
|
1310
|
-
kind: KnowledgeTargetKindSchema,
|
|
1311
|
-
// Ontology targets use the canonical '<scope>:<kind>/<local-id>' ontology id format.
|
|
1312
|
-
// Business-logic validation of target existence is done in OrganizationModelSchema.superRefine.
|
|
1313
|
-
id: z.string().trim().min(1).max(300)
|
|
1314
|
-
}).superRefine((target, ctx) => {
|
|
1315
|
-
if (target.kind !== "ontology") return;
|
|
1316
|
-
const result = OntologyIdSchema.safeParse(target.id);
|
|
1317
|
-
if (!result.success) {
|
|
1318
|
-
ctx.addIssue({
|
|
1319
|
-
code: z.ZodIssueCode.custom,
|
|
1320
|
-
path: ["id"],
|
|
1321
|
-
message: "Ontology knowledge targets must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
|
|
1322
|
-
});
|
|
1323
|
-
}
|
|
1324
|
-
});
|
|
1325
|
-
var LegacyKnowledgeLinkSchema = z.object({
|
|
1326
|
-
nodeId: z.union([NodeIdStringSchema, z.templateLiteral(["ontology:", OntologyIdSchema])])
|
|
1327
|
-
}).superRefine((link, ctx) => {
|
|
1328
|
-
const [kind] = link.nodeId.split(":");
|
|
1329
|
-
if (!KnowledgeTargetKindSchema.safeParse(kind).success) {
|
|
1330
|
-
ctx.addIssue({
|
|
1331
|
-
code: z.ZodIssueCode.custom,
|
|
1332
|
-
path: ["nodeId"],
|
|
1333
|
-
message: `Unknown knowledge target kind "${kind}"`
|
|
1334
|
-
});
|
|
1335
|
-
}
|
|
1336
|
-
});
|
|
1337
|
-
var CanonicalKnowledgeLinkSchema = z.object({
|
|
1338
|
-
target: KnowledgeTargetRefSchema
|
|
843
|
+
ctx.addIssue({
|
|
844
|
+
code: z.ZodIssueCode.custom,
|
|
845
|
+
path: ["primaryAction"],
|
|
846
|
+
message: "Resource ontology primaryAction must be included in actions"
|
|
847
|
+
});
|
|
1339
848
|
});
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
return {
|
|
1346
|
-
kind: KnowledgeTargetKindSchema.parse(kind),
|
|
1347
|
-
id: idParts.join(":")
|
|
1348
|
-
};
|
|
1349
|
-
}
|
|
1350
|
-
var KnowledgeLinkSchema = z.union([CanonicalKnowledgeLinkSchema, LegacyKnowledgeLinkSchema]).transform((link) => {
|
|
1351
|
-
const target = "target" in link ? link.target : targetFromNodeId(link.nodeId);
|
|
1352
|
-
return {
|
|
1353
|
-
target,
|
|
1354
|
-
nodeId: nodeIdFromTarget(target)
|
|
1355
|
-
};
|
|
849
|
+
var CodeReferenceSchema = z.object({
|
|
850
|
+
path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
|
|
851
|
+
role: CodeReferenceRoleSchema,
|
|
852
|
+
symbol: z.string().trim().min(1).max(200).optional(),
|
|
853
|
+
description: z.string().trim().min(1).max(300).optional()
|
|
1356
854
|
});
|
|
1357
|
-
var
|
|
1358
|
-
|
|
1359
|
-
id:
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
/**
|
|
1365
|
-
|
|
1366
|
-
/**
|
|
1367
|
-
|
|
1368
|
-
/**
|
|
1369
|
-
|
|
855
|
+
var ResourceEntryBaseSchema = z.object({
|
|
856
|
+
/** Canonical resource id; runtime resourceId derives from this value. */
|
|
857
|
+
id: ResourceIdSchema,
|
|
858
|
+
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
859
|
+
order: z.number().default(0),
|
|
860
|
+
/** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
|
|
861
|
+
systemPath: SystemPathSchema.meta({ ref: "system" }),
|
|
862
|
+
/** Executable display title owned by the OM Resource descriptor. */
|
|
863
|
+
title: LabelSchema.optional(),
|
|
864
|
+
/** Executable display description owned by the OM Resource descriptor. */
|
|
865
|
+
description: DescriptionSchema.optional(),
|
|
866
|
+
/** Optional role responsible for maintaining this resource. */
|
|
867
|
+
ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
868
|
+
status: ResourceGovernanceStatusSchema,
|
|
1370
869
|
/**
|
|
1371
|
-
*
|
|
1372
|
-
*
|
|
870
|
+
* Ontology contract bindings for the semantic work this resource performs.
|
|
871
|
+
* `emits` stays nested here so top-level resource emits descriptors remain
|
|
872
|
+
* compatible with graph event projection during the bridge.
|
|
1373
873
|
*/
|
|
1374
|
-
|
|
1375
|
-
/**
|
|
1376
|
-
|
|
1377
|
-
/** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
|
|
1378
|
-
updatedAt: z.string().trim().min(1).max(50)
|
|
874
|
+
ontology: ResourceOntologyBindingSchema.optional(),
|
|
875
|
+
/** Repo-relative implementation breadcrumbs for agents and operators. */
|
|
876
|
+
codeRefs: z.array(CodeReferenceSchema).default([])
|
|
1379
877
|
});
|
|
1380
|
-
var
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
var OmTopologyNodeKindSchema = z.enum([
|
|
1384
|
-
"system",
|
|
1385
|
-
"resource",
|
|
1386
|
-
"ontology",
|
|
1387
|
-
"policy",
|
|
1388
|
-
"role",
|
|
1389
|
-
"trigger",
|
|
1390
|
-
"humanCheckpoint",
|
|
1391
|
-
"externalResource"
|
|
1392
|
-
]);
|
|
1393
|
-
var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
|
|
1394
|
-
var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
|
|
1395
|
-
z.object({ kind: z.literal("system"), id: ModelIdSchema }),
|
|
1396
|
-
z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
|
|
1397
|
-
z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
|
|
1398
|
-
z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
|
|
1399
|
-
z.object({ kind: z.literal("role"), id: ModelIdSchema }),
|
|
1400
|
-
z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
|
|
1401
|
-
z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
|
|
1402
|
-
z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
|
|
1403
|
-
]);
|
|
1404
|
-
var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
|
|
1405
|
-
function visit(value, path) {
|
|
1406
|
-
if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
|
|
1407
|
-
ctx.addIssue({
|
|
1408
|
-
code: z.ZodIssueCode.custom,
|
|
1409
|
-
path,
|
|
1410
|
-
message: "Topology metadata must not contain secret-like values"
|
|
1411
|
-
});
|
|
1412
|
-
return;
|
|
1413
|
-
}
|
|
1414
|
-
if (Array.isArray(value)) {
|
|
1415
|
-
value.forEach((entry, index) => visit(entry, [...path, index]));
|
|
1416
|
-
return;
|
|
1417
|
-
}
|
|
1418
|
-
if (typeof value !== "object" || value === null) return;
|
|
1419
|
-
Object.entries(value).forEach(([key, entry]) => {
|
|
1420
|
-
if (SecretLikeMetadataKeySchema.test(key)) {
|
|
1421
|
-
ctx.addIssue({
|
|
1422
|
-
code: z.ZodIssueCode.custom,
|
|
1423
|
-
path: [...path, key],
|
|
1424
|
-
message: `Topology metadata key "${key}" looks secret-like`
|
|
1425
|
-
});
|
|
1426
|
-
}
|
|
1427
|
-
visit(entry, [...path, key]);
|
|
1428
|
-
});
|
|
1429
|
-
}
|
|
1430
|
-
visit(metadata, []);
|
|
878
|
+
var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
879
|
+
kind: z.literal("workflow"),
|
|
880
|
+
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
1431
881
|
});
|
|
1432
|
-
var
|
|
1433
|
-
|
|
1434
|
-
kind
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
882
|
+
var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
883
|
+
kind: z.literal("agent"),
|
|
884
|
+
/** Mirrors code-side AgentConfig.kind. */
|
|
885
|
+
agentKind: AgentKindSchema,
|
|
886
|
+
/** Role this agent embodies, if any. */
|
|
887
|
+
actsAsRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
888
|
+
/** Mirrors AgentConfig.sessionCapable. */
|
|
889
|
+
sessionCapable: z.boolean(),
|
|
890
|
+
/** Broad/composite callable entry points orchestrated by this agent. */
|
|
891
|
+
invocations: z.array(ActionInvocationSchema).default([]),
|
|
892
|
+
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
1439
893
|
});
|
|
1440
|
-
var
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
}).default({ version: 1, relationships: {} });
|
|
1444
|
-
var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
|
|
1445
|
-
version: 1,
|
|
1446
|
-
relationships: {}
|
|
1447
|
-
};
|
|
1448
|
-
function idFrom(input) {
|
|
1449
|
-
return typeof input === "string" ? input : input.id;
|
|
1450
|
-
}
|
|
1451
|
-
function parseRef(kind, id) {
|
|
1452
|
-
return OmTopologyNodeRefSchema.parse({ kind, id });
|
|
1453
|
-
}
|
|
1454
|
-
function isNodeRef(input) {
|
|
1455
|
-
return OmTopologyNodeRefSchema.safeParse(input).success;
|
|
1456
|
-
}
|
|
1457
|
-
function isResourceEntry(input) {
|
|
1458
|
-
if (typeof input !== "object" || input === null) return false;
|
|
1459
|
-
const candidate = input;
|
|
1460
|
-
return typeof candidate.id === "string" && typeof candidate.systemPath === "string" && typeof candidate.status === "string" && ["workflow", "agent", "integration", "script"].includes(String(candidate.kind));
|
|
1461
|
-
}
|
|
1462
|
-
var topologyRef = {
|
|
1463
|
-
system: (system) => parseRef("system", idFrom(system)),
|
|
1464
|
-
resource: (resource) => parseRef("resource", idFrom(resource)),
|
|
1465
|
-
ontology: (record) => parseRef("ontology", idFrom(record)),
|
|
1466
|
-
policy: (policy) => parseRef("policy", idFrom(policy)),
|
|
1467
|
-
role: (role) => parseRef("role", idFrom(role)),
|
|
1468
|
-
trigger: (trigger) => parseRef("trigger", idFrom(trigger)),
|
|
1469
|
-
humanCheckpoint: (checkpoint) => parseRef("humanCheckpoint", idFrom(checkpoint)),
|
|
1470
|
-
externalResource: (externalResource) => parseRef("externalResource", idFrom(externalResource))
|
|
1471
|
-
};
|
|
1472
|
-
var topologyRelationship = {
|
|
1473
|
-
triggers: (from, to, options = {}) => defineTopologyRelationship({
|
|
1474
|
-
...options,
|
|
1475
|
-
from,
|
|
1476
|
-
kind: "triggers",
|
|
1477
|
-
to
|
|
1478
|
-
}),
|
|
1479
|
-
uses: (from, to, options = {}) => defineTopologyRelationship({
|
|
1480
|
-
...options,
|
|
1481
|
-
from,
|
|
1482
|
-
kind: "uses",
|
|
1483
|
-
to
|
|
1484
|
-
}),
|
|
1485
|
-
approval: (from, to, options = {}) => defineTopologyRelationship({
|
|
1486
|
-
...options,
|
|
1487
|
-
from,
|
|
1488
|
-
kind: "approval",
|
|
1489
|
-
to
|
|
1490
|
-
}),
|
|
1491
|
-
usesIntegration: (from, integration, options = {}) => defineTopologyRelationship({
|
|
1492
|
-
required: true,
|
|
1493
|
-
...options,
|
|
1494
|
-
from,
|
|
1495
|
-
kind: "uses",
|
|
1496
|
-
to: integration
|
|
1497
|
-
}),
|
|
1498
|
-
requestsApproval: (from, checkpoint, options = {}) => defineTopologyRelationship({
|
|
1499
|
-
required: true,
|
|
1500
|
-
...options,
|
|
1501
|
-
from,
|
|
1502
|
-
kind: "approval",
|
|
1503
|
-
to: topologyRef.humanCheckpoint(checkpoint)
|
|
1504
|
-
}),
|
|
1505
|
-
checkpointRoutesTo: (checkpoint, to, options = {}) => defineTopologyRelationship({
|
|
1506
|
-
required: true,
|
|
1507
|
-
...options,
|
|
1508
|
-
from: topologyRef.humanCheckpoint(checkpoint),
|
|
1509
|
-
kind: "triggers",
|
|
1510
|
-
to
|
|
1511
|
-
})
|
|
1512
|
-
};
|
|
1513
|
-
function compileTopologyNodeRef(input) {
|
|
1514
|
-
if (isNodeRef(input)) return input;
|
|
1515
|
-
if (isResourceEntry(input)) return topologyRef.resource(input);
|
|
1516
|
-
throw new Error("Topology node refs must be typed node objects or serializable { kind, id } refs");
|
|
1517
|
-
}
|
|
1518
|
-
function parseTopologyNodeRef(input) {
|
|
1519
|
-
if (typeof input !== "string") return OmTopologyNodeRefSchema.parse(input);
|
|
1520
|
-
const separatorIndex = input.indexOf(":");
|
|
1521
|
-
if (separatorIndex === -1) {
|
|
1522
|
-
throw new Error(`Topology node ref "${input}" must use <kind>:<id>`);
|
|
1523
|
-
}
|
|
1524
|
-
const kind = input.slice(0, separatorIndex);
|
|
1525
|
-
const id = input.slice(separatorIndex + 1);
|
|
1526
|
-
if (!OmTopologyNodeKindSchema.safeParse(kind).success) {
|
|
1527
|
-
throw new Error(`Topology node ref "${input}" has unsupported kind "${kind}"`);
|
|
1528
|
-
}
|
|
1529
|
-
return OmTopologyNodeRefSchema.parse({ kind, id });
|
|
1530
|
-
}
|
|
1531
|
-
function defineTopologyRelationship(input) {
|
|
1532
|
-
return OmTopologyRelationshipSchema.parse({
|
|
1533
|
-
...input,
|
|
1534
|
-
from: compileTopologyNodeRef(input.from),
|
|
1535
|
-
to: compileTopologyNodeRef(input.to)
|
|
1536
|
-
});
|
|
1537
|
-
}
|
|
1538
|
-
function defineTopology(relationships) {
|
|
1539
|
-
const entries = Array.isArray(relationships) ? relationships.map((relationship, index) => [`relationship-${index + 1}`, relationship]) : Object.entries(relationships);
|
|
1540
|
-
return OmTopologyDomainSchema.parse({
|
|
1541
|
-
version: 1,
|
|
1542
|
-
relationships: Object.fromEntries(entries.map(([key, relationship]) => [key, defineTopologyRelationship(relationship)]))
|
|
1543
|
-
});
|
|
1544
|
-
}
|
|
1545
|
-
var PolicyIdSchema = ModelIdSchema;
|
|
1546
|
-
var PolicyApplicabilitySchema = z.object({
|
|
1547
|
-
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
1548
|
-
actionIds: z.array(ModelIdSchema.meta({ ref: "action" })).default([]),
|
|
1549
|
-
resourceIds: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]),
|
|
1550
|
-
roleIds: z.array(ModelIdSchema.meta({ ref: "role" })).default([])
|
|
894
|
+
var IntegrationResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
895
|
+
kind: z.literal("integration"),
|
|
896
|
+
provider: z.string().trim().min(1).max(100)
|
|
1551
897
|
});
|
|
1552
|
-
var
|
|
1553
|
-
z.
|
|
1554
|
-
kind: z.literal("event"),
|
|
1555
|
-
eventId: EventIdSchema.meta({ ref: "event" })
|
|
1556
|
-
}),
|
|
1557
|
-
z.object({
|
|
1558
|
-
kind: z.literal("action-invocation"),
|
|
1559
|
-
actionId: ModelIdSchema.meta({ ref: "action" })
|
|
1560
|
-
}),
|
|
1561
|
-
z.object({
|
|
1562
|
-
kind: z.literal("schedule"),
|
|
1563
|
-
cron: z.string().trim().min(1).max(120)
|
|
1564
|
-
}),
|
|
1565
|
-
z.object({
|
|
1566
|
-
kind: z.literal("manual")
|
|
1567
|
-
})
|
|
1568
|
-
]);
|
|
1569
|
-
var PolicyPredicateSchema = z.discriminatedUnion("kind", [
|
|
1570
|
-
z.object({
|
|
1571
|
-
kind: z.literal("always")
|
|
1572
|
-
}),
|
|
1573
|
-
z.object({
|
|
1574
|
-
kind: z.literal("expression"),
|
|
1575
|
-
expression: z.string().trim().min(1).max(2e3)
|
|
1576
|
-
}),
|
|
1577
|
-
z.object({
|
|
1578
|
-
kind: z.literal("threshold"),
|
|
1579
|
-
metric: ModelIdSchema,
|
|
1580
|
-
operator: z.enum(["lt", "lte", "eq", "gte", "gt"]).meta({ label: "Operator" }),
|
|
1581
|
-
value: z.number()
|
|
1582
|
-
})
|
|
1583
|
-
]);
|
|
1584
|
-
var PolicyEffectSchema = z.discriminatedUnion("kind", [
|
|
1585
|
-
z.object({
|
|
1586
|
-
kind: z.literal("require-approval"),
|
|
1587
|
-
roleId: ModelIdSchema.meta({ ref: "role" }).optional()
|
|
1588
|
-
}),
|
|
1589
|
-
z.object({
|
|
1590
|
-
kind: z.literal("invoke-action"),
|
|
1591
|
-
actionId: ModelIdSchema.meta({ ref: "action" })
|
|
1592
|
-
}),
|
|
1593
|
-
z.object({
|
|
1594
|
-
kind: z.literal("notify-role"),
|
|
1595
|
-
roleId: ModelIdSchema.meta({ ref: "role" })
|
|
1596
|
-
}),
|
|
898
|
+
var ScriptResourceSourceSchema = z.union([
|
|
899
|
+
z.string().trim().min(1).max(5e4),
|
|
1597
900
|
z.object({
|
|
1598
|
-
|
|
901
|
+
file: z.string().trim().min(1).max(500)
|
|
1599
902
|
})
|
|
1600
903
|
]);
|
|
1601
|
-
var
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
label: LabelSchema,
|
|
1606
|
-
description: DescriptionSchema.optional(),
|
|
1607
|
-
trigger: PolicyTriggerSchema,
|
|
1608
|
-
predicate: PolicyPredicateSchema.default({ kind: "always" }),
|
|
1609
|
-
actions: z.array(PolicyEffectSchema).min(1),
|
|
1610
|
-
appliesTo: PolicyApplicabilitySchema.default({
|
|
1611
|
-
systemIds: [],
|
|
1612
|
-
actionIds: [],
|
|
1613
|
-
resourceIds: [],
|
|
1614
|
-
roleIds: []
|
|
1615
|
-
}),
|
|
1616
|
-
lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
|
|
1617
|
-
});
|
|
1618
|
-
var PoliciesDomainSchema = z.record(z.string(), PolicySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
1619
|
-
message: "Each policy entry id must match its map key"
|
|
1620
|
-
}).default({});
|
|
1621
|
-
var DEFAULT_ORGANIZATION_MODEL_POLICIES = {};
|
|
1622
|
-
|
|
1623
|
-
// ../core/src/organization-model/schema.ts
|
|
1624
|
-
z.enum([
|
|
1625
|
-
"branding",
|
|
1626
|
-
"identity",
|
|
1627
|
-
"customers",
|
|
1628
|
-
"offerings",
|
|
1629
|
-
"roles",
|
|
1630
|
-
"goals",
|
|
1631
|
-
"systems",
|
|
1632
|
-
"ontology",
|
|
1633
|
-
"resources",
|
|
1634
|
-
"topology",
|
|
1635
|
-
"actions",
|
|
1636
|
-
"entities",
|
|
1637
|
-
"policies",
|
|
1638
|
-
"knowledge"
|
|
1639
|
-
]);
|
|
1640
|
-
var OrganizationModelDomainMetadataSchema = z.object({
|
|
1641
|
-
version: z.literal(1).default(1),
|
|
1642
|
-
lastModified: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "lastModified must be an ISO date string (YYYY-MM-DD)")
|
|
1643
|
-
});
|
|
1644
|
-
var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
|
|
1645
|
-
branding: { version: 1, lastModified: "2026-05-10" },
|
|
1646
|
-
identity: { version: 1, lastModified: "2026-05-10" },
|
|
1647
|
-
customers: { version: 1, lastModified: "2026-05-10" },
|
|
1648
|
-
offerings: { version: 1, lastModified: "2026-05-10" },
|
|
1649
|
-
roles: { version: 1, lastModified: "2026-05-10" },
|
|
1650
|
-
goals: { version: 1, lastModified: "2026-05-10" },
|
|
1651
|
-
systems: { version: 1, lastModified: "2026-05-10" },
|
|
1652
|
-
ontology: { version: 1, lastModified: "2026-05-14" },
|
|
1653
|
-
resources: { version: 1, lastModified: "2026-05-10" },
|
|
1654
|
-
topology: { version: 1, lastModified: "2026-05-14" },
|
|
1655
|
-
actions: { version: 1, lastModified: "2026-05-10" },
|
|
1656
|
-
entities: { version: 1, lastModified: "2026-05-10" },
|
|
1657
|
-
policies: { version: 1, lastModified: "2026-05-10" },
|
|
1658
|
-
knowledge: { version: 1, lastModified: "2026-05-10" }
|
|
1659
|
-
};
|
|
1660
|
-
var OrganizationModelDomainMetadataByDomainSchema = z.object({
|
|
1661
|
-
branding: OrganizationModelDomainMetadataSchema,
|
|
1662
|
-
identity: OrganizationModelDomainMetadataSchema,
|
|
1663
|
-
customers: OrganizationModelDomainMetadataSchema,
|
|
1664
|
-
offerings: OrganizationModelDomainMetadataSchema,
|
|
1665
|
-
roles: OrganizationModelDomainMetadataSchema,
|
|
1666
|
-
goals: OrganizationModelDomainMetadataSchema,
|
|
1667
|
-
systems: OrganizationModelDomainMetadataSchema,
|
|
1668
|
-
ontology: OrganizationModelDomainMetadataSchema,
|
|
1669
|
-
resources: OrganizationModelDomainMetadataSchema,
|
|
1670
|
-
topology: OrganizationModelDomainMetadataSchema,
|
|
1671
|
-
actions: OrganizationModelDomainMetadataSchema,
|
|
1672
|
-
entities: OrganizationModelDomainMetadataSchema,
|
|
1673
|
-
policies: OrganizationModelDomainMetadataSchema,
|
|
1674
|
-
knowledge: OrganizationModelDomainMetadataSchema
|
|
1675
|
-
}).partial().default(DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA).transform((metadata) => ({ ...DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA, ...metadata }));
|
|
1676
|
-
var OrganizationModelSchemaBase = z.object({
|
|
1677
|
-
version: z.literal(1).default(1),
|
|
1678
|
-
domainMetadata: OrganizationModelDomainMetadataByDomainSchema,
|
|
1679
|
-
branding: OrganizationModelBrandingSchema,
|
|
1680
|
-
navigation: OrganizationModelNavigationSchema,
|
|
1681
|
-
identity: IdentityDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_IDENTITY),
|
|
1682
|
-
customers: CustomersDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_CUSTOMERS),
|
|
1683
|
-
offerings: OfferingsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_OFFERINGS),
|
|
1684
|
-
roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
|
|
1685
|
-
goals: GoalsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_GOALS),
|
|
1686
|
-
systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
|
|
1687
|
-
ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
|
|
1688
|
-
resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
|
|
1689
|
-
topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
|
|
1690
|
-
actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
|
|
1691
|
-
entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
|
|
1692
|
-
policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
|
|
1693
|
-
// D3: flat Record<id, OrgKnowledgeNode> — no wrapper object
|
|
1694
|
-
knowledge: KnowledgeDomainSchema.default({})
|
|
904
|
+
var ScriptResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
905
|
+
kind: z.literal("script"),
|
|
906
|
+
language: ScriptResourceLanguageSchema,
|
|
907
|
+
source: ScriptResourceSourceSchema
|
|
1695
908
|
});
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
909
|
+
var ResourceEntrySchema = z.discriminatedUnion("kind", [
|
|
910
|
+
WorkflowResourceEntrySchema,
|
|
911
|
+
AgentResourceEntrySchema,
|
|
912
|
+
IntegrationResourceEntrySchema,
|
|
913
|
+
ScriptResourceEntrySchema
|
|
914
|
+
]);
|
|
915
|
+
z.record(z.string(), ResourceEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
916
|
+
message: "Each resource entry id must match its map key"
|
|
917
|
+
}).default({});
|
|
918
|
+
function defineResource(resource) {
|
|
919
|
+
return ResourceEntrySchema.parse(resource);
|
|
1702
920
|
}
|
|
1703
|
-
function
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
}
|
|
1723
|
-
function isRecord(value) {
|
|
1724
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1725
|
-
}
|
|
1726
|
-
OrganizationModelSchemaBase.superRefine((model, ctx) => {
|
|
1727
|
-
function collectAllSystems(systems, prefix = "", schemaPath = ["systems"]) {
|
|
1728
|
-
const result = [];
|
|
1729
|
-
for (const [key, system] of Object.entries(systems)) {
|
|
1730
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
1731
|
-
const currentSchemaPath = [...schemaPath, key];
|
|
1732
|
-
result.push({ path, schemaPath: currentSchemaPath, system });
|
|
1733
|
-
const childSystems = system.systems ?? system.subsystems;
|
|
1734
|
-
if (childSystems !== void 0) {
|
|
1735
|
-
result.push(
|
|
1736
|
-
...collectAllSystems(childSystems, path, [
|
|
1737
|
-
...currentSchemaPath,
|
|
1738
|
-
system.systems !== void 0 ? "systems" : "subsystems"
|
|
1739
|
-
])
|
|
1740
|
-
);
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
return result;
|
|
1744
|
-
}
|
|
1745
|
-
const allSystems = collectAllSystems(model.systems);
|
|
1746
|
-
const systemsById = /* @__PURE__ */ new Map();
|
|
1747
|
-
for (const { path, system } of allSystems) {
|
|
1748
|
-
systemsById.set(path, system);
|
|
1749
|
-
systemsById.set(system.id, system);
|
|
1750
|
-
}
|
|
1751
|
-
const systemIdsByEffectivePath = /* @__PURE__ */ new Map();
|
|
1752
|
-
allSystems.forEach(({ path, schemaPath, system }) => {
|
|
1753
|
-
if (system.parentSystemId !== void 0 && !systemsById.has(system.parentSystemId)) {
|
|
1754
|
-
addIssue(
|
|
1755
|
-
ctx,
|
|
1756
|
-
[...schemaPath, "parentSystemId"],
|
|
1757
|
-
`System "${system.id}" references unknown parent "${system.parentSystemId}"`
|
|
1758
|
-
);
|
|
1759
|
-
}
|
|
1760
|
-
const hasChildren = Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 || allSystems.some(
|
|
1761
|
-
(candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".")
|
|
1762
|
-
);
|
|
1763
|
-
const contributesRoutePath = system.ui?.path !== void 0 || system.path !== void 0 || !hasChildren;
|
|
1764
|
-
if (contributesRoutePath) {
|
|
1765
|
-
const effectivePath = system.ui?.path ?? system.path ?? defaultSystemPathFor(path);
|
|
1766
|
-
const existingSystemId = systemIdsByEffectivePath.get(effectivePath);
|
|
1767
|
-
if (existingSystemId !== void 0) {
|
|
1768
|
-
addIssue(
|
|
1769
|
-
ctx,
|
|
1770
|
-
[...schemaPath, system.ui?.path !== void 0 ? "ui" : "path"],
|
|
1771
|
-
`System "${path}" effective path "${effectivePath}" duplicates system "${existingSystemId}"`
|
|
1772
|
-
);
|
|
1773
|
-
} else {
|
|
1774
|
-
systemIdsByEffectivePath.set(effectivePath, path);
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
if (hasChildren && isLifecycleEnabled(system.lifecycle, system.enabled)) {
|
|
1778
|
-
const hasEnabledDescendant = Object.values(system.systems ?? system.subsystems ?? {}).some(
|
|
1779
|
-
(candidate) => isLifecycleEnabled(candidate.lifecycle, candidate.enabled)
|
|
1780
|
-
) || allSystems.some(
|
|
1781
|
-
(candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".") && isLifecycleEnabled(candidate.system.lifecycle, candidate.system.enabled)
|
|
1782
|
-
);
|
|
1783
|
-
if (!hasEnabledDescendant) {
|
|
1784
|
-
addIssue(ctx, [...schemaPath, "lifecycle"], `System "${path}" is active but has no active descendants`);
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
});
|
|
1788
|
-
allSystems.forEach(({ schemaPath, system }) => {
|
|
1789
|
-
const visited = /* @__PURE__ */ new Set();
|
|
1790
|
-
let currentParentId = system.parentSystemId;
|
|
1791
|
-
while (currentParentId !== void 0) {
|
|
1792
|
-
if (currentParentId === system.id || visited.has(currentParentId)) {
|
|
1793
|
-
addIssue(ctx, [...schemaPath, "parentSystemId"], `System "${system.id}" has a parent cycle`);
|
|
1794
|
-
return;
|
|
1795
|
-
}
|
|
1796
|
-
visited.add(currentParentId);
|
|
1797
|
-
currentParentId = systemsById.get(currentParentId)?.parentSystemId;
|
|
1798
|
-
}
|
|
921
|
+
function defineResources(resources) {
|
|
922
|
+
return Object.fromEntries(
|
|
923
|
+
Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
function ontologyIdFrom(input) {
|
|
927
|
+
return typeof input === "string" ? input : input.id;
|
|
928
|
+
}
|
|
929
|
+
function ontologyIdArrayFrom(input) {
|
|
930
|
+
return input?.map(ontologyIdFrom);
|
|
931
|
+
}
|
|
932
|
+
function defineResourceOntology(input) {
|
|
933
|
+
return ResourceOntologyBindingSchema.parse({
|
|
934
|
+
actions: ontologyIdArrayFrom(input.actions),
|
|
935
|
+
primaryAction: input.primaryAction === void 0 ? void 0 : ontologyIdFrom(input.primaryAction),
|
|
936
|
+
reads: ontologyIdArrayFrom(input.reads),
|
|
937
|
+
writes: ontologyIdArrayFrom(input.writes),
|
|
938
|
+
usesCatalogs: ontologyIdArrayFrom(input.usesCatalogs),
|
|
939
|
+
emits: ontologyIdArrayFrom(input.emits)
|
|
1799
940
|
});
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
node.targets?.systems?.forEach((systemId, systemIndex) => {
|
|
1832
|
-
if (!systemsById.has(systemId)) {
|
|
1833
|
-
addIssue(
|
|
1834
|
-
ctx,
|
|
1835
|
-
[...nodePath, "targets", "systems", systemIndex],
|
|
1836
|
-
`Sidebar surface "${nodeId}" references unknown system "${systemId}"`
|
|
1837
|
-
);
|
|
1838
|
-
}
|
|
941
|
+
}
|
|
942
|
+
var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
|
|
943
|
+
var SecretLikeMetadataValueSchema = /(?:sk-[A-Za-z0-9_-]{12,}|pk_live_[A-Za-z0-9_-]{12,}|eyJ[A-Za-z0-9_-]{20,}|-----BEGIN (?:RSA |OPENSSH |EC )?PRIVATE KEY-----)/;
|
|
944
|
+
var OmTopologyNodeKindSchema = z.enum([
|
|
945
|
+
"system",
|
|
946
|
+
"resource",
|
|
947
|
+
"ontology",
|
|
948
|
+
"policy",
|
|
949
|
+
"role",
|
|
950
|
+
"trigger",
|
|
951
|
+
"humanCheckpoint",
|
|
952
|
+
"externalResource"
|
|
953
|
+
]);
|
|
954
|
+
var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
|
|
955
|
+
var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
|
|
956
|
+
z.object({ kind: z.literal("system"), id: ModelIdSchema }),
|
|
957
|
+
z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
|
|
958
|
+
z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
|
|
959
|
+
z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
|
|
960
|
+
z.object({ kind: z.literal("role"), id: ModelIdSchema }),
|
|
961
|
+
z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
|
|
962
|
+
z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
|
|
963
|
+
z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
|
|
964
|
+
]);
|
|
965
|
+
var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
|
|
966
|
+
function visit(value, path) {
|
|
967
|
+
if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
|
|
968
|
+
ctx.addIssue({
|
|
969
|
+
code: z.ZodIssueCode.custom,
|
|
970
|
+
path,
|
|
971
|
+
message: "Topology metadata must not contain secret-like values"
|
|
1839
972
|
});
|
|
1840
|
-
|
|
1841
|
-
}
|
|
1842
|
-
collectSidebarNodes(model.navigation.sidebar.primary, ["navigation", "sidebar", "primary"]);
|
|
1843
|
-
collectSidebarNodes(model.navigation.sidebar.bottom, ["navigation", "sidebar", "bottom"]);
|
|
1844
|
-
const segmentsById = new Map(Object.entries(model.customers));
|
|
1845
|
-
Object.values(model.offerings).forEach((product) => {
|
|
1846
|
-
product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
|
|
1847
|
-
if (!segmentsById.has(segmentId)) {
|
|
1848
|
-
addIssue(
|
|
1849
|
-
ctx,
|
|
1850
|
-
["offerings", product.id, "targetSegmentIds", segmentIndex],
|
|
1851
|
-
`Product "${product.id}" references unknown customer segment "${segmentId}"`
|
|
1852
|
-
);
|
|
1853
|
-
}
|
|
1854
|
-
});
|
|
1855
|
-
if (product.deliveryFeatureId !== void 0 && !systemsById.has(product.deliveryFeatureId)) {
|
|
1856
|
-
addIssue(
|
|
1857
|
-
ctx,
|
|
1858
|
-
["offerings", product.id, "deliveryFeatureId"],
|
|
1859
|
-
`Product "${product.id}" references unknown delivery system "${product.deliveryFeatureId}"`
|
|
1860
|
-
);
|
|
1861
|
-
}
|
|
1862
|
-
});
|
|
1863
|
-
Object.values(model.goals).forEach((objective) => {
|
|
1864
|
-
if (objective.periodEnd <= objective.periodStart) {
|
|
1865
|
-
addIssue(
|
|
1866
|
-
ctx,
|
|
1867
|
-
["goals", objective.id, "periodEnd"],
|
|
1868
|
-
`Goal "${objective.id}" has periodEnd "${objective.periodEnd}" which must be strictly after periodStart "${objective.periodStart}"`
|
|
1869
|
-
);
|
|
1870
|
-
}
|
|
1871
|
-
});
|
|
1872
|
-
const goalsById = new Map(Object.entries(model.goals));
|
|
1873
|
-
const knowledgeById = new Map(Object.entries(model.knowledge));
|
|
1874
|
-
const actionsById = new Map(Object.entries(model.actions));
|
|
1875
|
-
const entitiesById = new Map(Object.entries(model.entities));
|
|
1876
|
-
const policiesById = new Map(Object.entries(model.policies));
|
|
1877
|
-
sidebarSurfaces.forEach(({ id, node, path }) => {
|
|
1878
|
-
node.targets?.entities?.forEach((entityId, entityIndex) => {
|
|
1879
|
-
if (!entitiesById.has(entityId)) {
|
|
1880
|
-
addIssue(
|
|
1881
|
-
ctx,
|
|
1882
|
-
[...path, "targets", "entities", entityIndex],
|
|
1883
|
-
`Sidebar surface "${id}" references unknown entity "${entityId}"`
|
|
1884
|
-
);
|
|
1885
|
-
}
|
|
1886
|
-
});
|
|
1887
|
-
node.targets?.actions?.forEach((actionId, actionIndex) => {
|
|
1888
|
-
if (!actionsById.has(actionId)) {
|
|
1889
|
-
addIssue(
|
|
1890
|
-
ctx,
|
|
1891
|
-
[...path, "targets", "actions", actionIndex],
|
|
1892
|
-
`Sidebar surface "${id}" references unknown action "${actionId}"`
|
|
1893
|
-
);
|
|
1894
|
-
}
|
|
1895
|
-
});
|
|
1896
|
-
});
|
|
1897
|
-
Object.values(model.entities).forEach((entity) => {
|
|
1898
|
-
if (!systemsById.has(entity.ownedBySystemId)) {
|
|
1899
|
-
addIssue(
|
|
1900
|
-
ctx,
|
|
1901
|
-
["entities", entity.id, "ownedBySystemId"],
|
|
1902
|
-
`Entity "${entity.id}" references unknown ownedBySystemId "${entity.ownedBySystemId}"`
|
|
1903
|
-
);
|
|
1904
|
-
}
|
|
1905
|
-
entity.links?.forEach((link, linkIndex) => {
|
|
1906
|
-
if (!entitiesById.has(link.toEntity)) {
|
|
1907
|
-
addIssue(
|
|
1908
|
-
ctx,
|
|
1909
|
-
["entities", entity.id, "links", linkIndex, "toEntity"],
|
|
1910
|
-
`Entity "${entity.id}" links to unknown entity "${link.toEntity}"`
|
|
1911
|
-
);
|
|
1912
|
-
}
|
|
1913
|
-
});
|
|
1914
|
-
});
|
|
1915
|
-
const rolesById = new Map(Object.entries(model.roles));
|
|
1916
|
-
Object.values(model.roles).forEach((role) => {
|
|
1917
|
-
if (role.reportsToId !== void 0 && !rolesById.has(role.reportsToId)) {
|
|
1918
|
-
addIssue(
|
|
1919
|
-
ctx,
|
|
1920
|
-
["roles", role.id, "reportsToId"],
|
|
1921
|
-
`Role "${role.id}" references unknown reportsToId "${role.reportsToId}"`
|
|
1922
|
-
);
|
|
1923
|
-
}
|
|
1924
|
-
});
|
|
1925
|
-
Object.values(model.roles).forEach((role) => {
|
|
1926
|
-
const visited = /* @__PURE__ */ new Set();
|
|
1927
|
-
let currentReportsToId = role.reportsToId;
|
|
1928
|
-
while (currentReportsToId !== void 0) {
|
|
1929
|
-
if (currentReportsToId === role.id || visited.has(currentReportsToId)) {
|
|
1930
|
-
addIssue(ctx, ["roles", role.id, "reportsToId"], `Role "${role.id}" has a reportsToId cycle`);
|
|
1931
|
-
return;
|
|
1932
|
-
}
|
|
1933
|
-
visited.add(currentReportsToId);
|
|
1934
|
-
currentReportsToId = rolesById.get(currentReportsToId)?.reportsToId;
|
|
1935
|
-
}
|
|
1936
|
-
});
|
|
1937
|
-
Object.values(model.roles).forEach((role) => {
|
|
1938
|
-
role.responsibleFor?.forEach((systemId, systemIndex) => {
|
|
1939
|
-
if (!systemsById.has(systemId)) {
|
|
1940
|
-
addIssue(
|
|
1941
|
-
ctx,
|
|
1942
|
-
["roles", role.id, "responsibleFor", systemIndex],
|
|
1943
|
-
`Role "${role.id}" references unknown responsibleFor system "${systemId}"`
|
|
1944
|
-
);
|
|
1945
|
-
}
|
|
1946
|
-
});
|
|
1947
|
-
});
|
|
1948
|
-
allSystems.forEach(({ schemaPath, system }) => {
|
|
1949
|
-
if (system.responsibleRoleId !== void 0 && !rolesById.has(system.responsibleRoleId)) {
|
|
1950
|
-
addIssue(
|
|
1951
|
-
ctx,
|
|
1952
|
-
[...schemaPath, "responsibleRoleId"],
|
|
1953
|
-
`System "${system.id}" references unknown responsibleRoleId "${system.responsibleRoleId}"`
|
|
1954
|
-
);
|
|
1955
|
-
}
|
|
1956
|
-
system.governedByKnowledge?.forEach((nodeId, nodeIndex) => {
|
|
1957
|
-
if (!knowledgeById.has(nodeId)) {
|
|
1958
|
-
addIssue(
|
|
1959
|
-
ctx,
|
|
1960
|
-
[...schemaPath, "governedByKnowledge", nodeIndex],
|
|
1961
|
-
`System "${system.id}" references unknown knowledge node "${nodeId}"`
|
|
1962
|
-
);
|
|
1963
|
-
}
|
|
1964
|
-
});
|
|
1965
|
-
system.drivesGoals?.forEach((goalId, goalIndex) => {
|
|
1966
|
-
if (!goalsById.has(goalId)) {
|
|
1967
|
-
addIssue(
|
|
1968
|
-
ctx,
|
|
1969
|
-
[...schemaPath, "drivesGoals", goalIndex],
|
|
1970
|
-
`System "${system.id}" references unknown goal "${goalId}"`
|
|
1971
|
-
);
|
|
1972
|
-
}
|
|
1973
|
-
});
|
|
1974
|
-
system.actions?.forEach((actionRef, actionIndex) => {
|
|
1975
|
-
if (!actionsById.has(actionRef.actionId)) {
|
|
1976
|
-
addIssue(
|
|
1977
|
-
ctx,
|
|
1978
|
-
[...schemaPath, "actions", actionIndex, "actionId"],
|
|
1979
|
-
`System "${system.id}" references unknown action "${actionRef.actionId}"`
|
|
1980
|
-
);
|
|
1981
|
-
}
|
|
1982
|
-
});
|
|
1983
|
-
system.policies?.forEach((policyId, policyIndex) => {
|
|
1984
|
-
if (!policiesById.has(policyId)) {
|
|
1985
|
-
addIssue(
|
|
1986
|
-
ctx,
|
|
1987
|
-
[...schemaPath, "policies", policyIndex],
|
|
1988
|
-
`System "${system.id}" references unknown policy "${policyId}"`
|
|
1989
|
-
);
|
|
1990
|
-
}
|
|
1991
|
-
});
|
|
1992
|
-
});
|
|
1993
|
-
Object.values(model.actions).forEach((action) => {
|
|
1994
|
-
action.affects?.forEach((entityId, entityIndex) => {
|
|
1995
|
-
if (!entitiesById.has(entityId)) {
|
|
1996
|
-
addIssue(
|
|
1997
|
-
ctx,
|
|
1998
|
-
["actions", action.id, "affects", entityIndex],
|
|
1999
|
-
`Action "${action.id}" affects unknown entity "${entityId}"`
|
|
2000
|
-
);
|
|
2001
|
-
}
|
|
2002
|
-
});
|
|
2003
|
-
});
|
|
2004
|
-
const resourcesById = new Map(Object.entries(model.resources));
|
|
2005
|
-
sidebarSurfaces.forEach(({ id, node, path }) => {
|
|
2006
|
-
node.targets?.resources?.forEach((resourceId, resourceIndex) => {
|
|
2007
|
-
if (!resourcesById.has(resourceId)) {
|
|
2008
|
-
addIssue(
|
|
2009
|
-
ctx,
|
|
2010
|
-
[...path, "targets", "resources", resourceIndex],
|
|
2011
|
-
`Sidebar surface "${id}" references unknown resource "${resourceId}"`
|
|
2012
|
-
);
|
|
2013
|
-
}
|
|
2014
|
-
});
|
|
2015
|
-
});
|
|
2016
|
-
const actionIds = new Set(Object.keys(model.actions));
|
|
2017
|
-
const offeringsById = new Map(Object.entries(model.offerings));
|
|
2018
|
-
const ontologyCompilation = compileOrganizationOntology(model);
|
|
2019
|
-
const stageIds = /* @__PURE__ */ new Set();
|
|
2020
|
-
for (const catalog of Object.values(ontologyCompilation.ontology.catalogTypes)) {
|
|
2021
|
-
if (catalog.kind !== "stage") continue;
|
|
2022
|
-
for (const stageId of Object.keys(catalog.entries ?? {})) {
|
|
2023
|
-
stageIds.add(stageId);
|
|
973
|
+
return;
|
|
2024
974
|
}
|
|
2025
|
-
}
|
|
2026
|
-
const ontologyIndexByKind = {
|
|
2027
|
-
object: ontologyCompilation.ontology.objectTypes,
|
|
2028
|
-
link: ontologyCompilation.ontology.linkTypes,
|
|
2029
|
-
action: ontologyCompilation.ontology.actionTypes,
|
|
2030
|
-
catalog: ontologyCompilation.ontology.catalogTypes,
|
|
2031
|
-
event: ontologyCompilation.ontology.eventTypes,
|
|
2032
|
-
interface: ontologyCompilation.ontology.interfaceTypes,
|
|
2033
|
-
"value-type": ontologyCompilation.ontology.valueTypes,
|
|
2034
|
-
property: ontologyCompilation.ontology.sharedProperties,
|
|
2035
|
-
group: ontologyCompilation.ontology.groups,
|
|
2036
|
-
surface: ontologyCompilation.ontology.surfaces
|
|
2037
|
-
};
|
|
2038
|
-
const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
|
|
2039
|
-
function topologyTargetExists(ref) {
|
|
2040
|
-
if (ref.kind === "system") return systemsById.has(ref.id);
|
|
2041
|
-
if (ref.kind === "resource") return resourcesById.has(ref.id);
|
|
2042
|
-
if (ref.kind === "ontology") return ontologyIds.has(ref.id);
|
|
2043
|
-
if (ref.kind === "policy") return policiesById.has(ref.id);
|
|
2044
|
-
if (ref.kind === "role") return rolesById.has(ref.id);
|
|
2045
|
-
return true;
|
|
2046
|
-
}
|
|
2047
|
-
Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
|
|
2048
|
-
["from", "to"].forEach((side) => {
|
|
2049
|
-
const ref = relationship[side];
|
|
2050
|
-
if (topologyTargetExists(ref)) return;
|
|
2051
|
-
addIssue(
|
|
2052
|
-
ctx,
|
|
2053
|
-
["topology", "relationships", relationshipId, side],
|
|
2054
|
-
`Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
|
|
2055
|
-
);
|
|
2056
|
-
});
|
|
2057
|
-
});
|
|
2058
|
-
const ontologyReferenceKeyKinds = {
|
|
2059
|
-
valueType: "value-type",
|
|
2060
|
-
catalogType: "catalog",
|
|
2061
|
-
objectType: "object",
|
|
2062
|
-
eventType: "event",
|
|
2063
|
-
actionType: "action",
|
|
2064
|
-
linkType: "link",
|
|
2065
|
-
interfaceType: "interface",
|
|
2066
|
-
propertyType: "property",
|
|
2067
|
-
groupType: "group",
|
|
2068
|
-
surfaceType: "surface",
|
|
2069
|
-
stepCatalog: "catalog"
|
|
2070
|
-
};
|
|
2071
|
-
function validateKnownOntologyReferences(ownerId, value, path, seen = /* @__PURE__ */ new WeakSet()) {
|
|
2072
975
|
if (Array.isArray(value)) {
|
|
2073
|
-
value.forEach((entry, index) =>
|
|
976
|
+
value.forEach((entry, index) => visit(entry, [...path, index]));
|
|
2074
977
|
return;
|
|
2075
978
|
}
|
|
2076
|
-
if (
|
|
2077
|
-
if (seen.has(value)) return;
|
|
2078
|
-
seen.add(value);
|
|
979
|
+
if (typeof value !== "object" || value === null) return;
|
|
2079
980
|
Object.entries(value).forEach(([key, entry]) => {
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
ctx,
|
|
2087
|
-
[...path, key],
|
|
2088
|
-
`Ontology record "${ownerId}" ${key} references unknown ${expectedKind} ontology ID "${entry}"`
|
|
2089
|
-
);
|
|
2090
|
-
}
|
|
2091
|
-
}
|
|
2092
|
-
validateKnownOntologyReferences(ownerId, entry, [...path, key], seen);
|
|
2093
|
-
});
|
|
2094
|
-
}
|
|
2095
|
-
for (const { id, record } of listResolvedOntologyRecords(ontologyCompilation.ontology)) {
|
|
2096
|
-
validateKnownOntologyReferences(id, record, record.origin.path);
|
|
2097
|
-
}
|
|
2098
|
-
Object.values(model.policies).forEach((policy) => {
|
|
2099
|
-
policy.appliesTo.systemIds.forEach((systemId, systemIndex) => {
|
|
2100
|
-
if (!systemsById.has(systemId)) {
|
|
2101
|
-
addIssue(
|
|
2102
|
-
ctx,
|
|
2103
|
-
["policies", policy.id, "appliesTo", "systemIds", systemIndex],
|
|
2104
|
-
`Policy "${policy.id}" applies to unknown system "${systemId}"`
|
|
2105
|
-
);
|
|
2106
|
-
}
|
|
2107
|
-
});
|
|
2108
|
-
policy.appliesTo.actionIds.forEach((actionId, actionIndex) => {
|
|
2109
|
-
if (!actionsById.has(actionId)) {
|
|
2110
|
-
addIssue(
|
|
2111
|
-
ctx,
|
|
2112
|
-
["policies", policy.id, "appliesTo", "actionIds", actionIndex],
|
|
2113
|
-
`Policy "${policy.id}" applies to unknown action "${actionId}"`
|
|
2114
|
-
);
|
|
2115
|
-
}
|
|
2116
|
-
});
|
|
2117
|
-
policy.actions.forEach((action, actionIndex) => {
|
|
2118
|
-
if (action.kind === "invoke-action" && !actionsById.has(action.actionId)) {
|
|
2119
|
-
addIssue(
|
|
2120
|
-
ctx,
|
|
2121
|
-
["policies", policy.id, "actions", actionIndex, "actionId"],
|
|
2122
|
-
`Policy "${policy.id}" invokes unknown action "${action.actionId}"`
|
|
2123
|
-
);
|
|
2124
|
-
}
|
|
2125
|
-
if ((action.kind === "notify-role" || action.kind === "require-approval") && action.roleId !== void 0 && !rolesById.has(action.roleId)) {
|
|
2126
|
-
addIssue(
|
|
2127
|
-
ctx,
|
|
2128
|
-
["policies", policy.id, "actions", actionIndex, "roleId"],
|
|
2129
|
-
`Policy "${policy.id}" references unknown role "${action.roleId}"`
|
|
2130
|
-
);
|
|
2131
|
-
}
|
|
2132
|
-
});
|
|
2133
|
-
if (policy.trigger.kind === "action-invocation" && !actionsById.has(policy.trigger.actionId)) {
|
|
2134
|
-
addIssue(
|
|
2135
|
-
ctx,
|
|
2136
|
-
["policies", policy.id, "trigger", "actionId"],
|
|
2137
|
-
`Policy "${policy.id}" references unknown trigger action "${policy.trigger.actionId}"`
|
|
2138
|
-
);
|
|
2139
|
-
}
|
|
2140
|
-
});
|
|
2141
|
-
function knowledgeTargetExists(kind, id) {
|
|
2142
|
-
if (kind === "system") return systemsById.has(id);
|
|
2143
|
-
if (kind === "resource") return resourcesById.has(id);
|
|
2144
|
-
if (kind === "knowledge") return knowledgeById.has(id);
|
|
2145
|
-
if (kind === "stage") return stageIds.has(id);
|
|
2146
|
-
if (kind === "action") return actionIds.has(id);
|
|
2147
|
-
if (kind === "role") return rolesById.has(id);
|
|
2148
|
-
if (kind === "goal") return goalsById.has(id);
|
|
2149
|
-
if (kind === "customer-segment") return segmentsById.has(id);
|
|
2150
|
-
if (kind === "offering") return offeringsById.has(id);
|
|
2151
|
-
if (kind === "ontology") return ontologyIds.has(id);
|
|
2152
|
-
return false;
|
|
2153
|
-
}
|
|
2154
|
-
Object.entries(model.knowledge).forEach(([nodeId, node]) => {
|
|
2155
|
-
node.links.forEach((link, linkIndex) => {
|
|
2156
|
-
if (!knowledgeTargetExists(link.target.kind, link.target.id)) {
|
|
2157
|
-
addIssue(
|
|
2158
|
-
ctx,
|
|
2159
|
-
["knowledge", nodeId, "links", linkIndex, "target"],
|
|
2160
|
-
`Knowledge node "${node.id}" references unknown ${link.target.kind} target "${link.target.id}"`
|
|
2161
|
-
);
|
|
2162
|
-
}
|
|
2163
|
-
if (!isKnowledgeKindCompatibleWithTarget(node.kind, link.target.kind)) {
|
|
2164
|
-
addIssue(
|
|
2165
|
-
ctx,
|
|
2166
|
-
["knowledge", nodeId, "links", linkIndex, "target", "kind"],
|
|
2167
|
-
`Knowledge node "${node.id}" kind "${node.kind}" cannot govern ${link.target.kind} targets`
|
|
2168
|
-
);
|
|
2169
|
-
}
|
|
2170
|
-
});
|
|
2171
|
-
});
|
|
2172
|
-
Object.values(model.resources).forEach((resource) => {
|
|
2173
|
-
if (!systemsById.has(resource.systemPath)) {
|
|
2174
|
-
addIssue(
|
|
2175
|
-
ctx,
|
|
2176
|
-
["resources", resource.id, "systemPath"],
|
|
2177
|
-
`Resource "${resource.id}" references unknown system path "${resource.systemPath}"`
|
|
2178
|
-
);
|
|
2179
|
-
}
|
|
2180
|
-
if (resource.ownerRoleId !== void 0 && !rolesById.has(resource.ownerRoleId)) {
|
|
2181
|
-
addIssue(
|
|
2182
|
-
ctx,
|
|
2183
|
-
["resources", resource.id, "ownerRoleId"],
|
|
2184
|
-
`Resource "${resource.id}" references unknown ownerRoleId "${resource.ownerRoleId}"`
|
|
2185
|
-
);
|
|
2186
|
-
}
|
|
2187
|
-
if (resource.kind === "agent" && resource.actsAsRoleId !== void 0 && !rolesById.has(resource.actsAsRoleId)) {
|
|
2188
|
-
addIssue(
|
|
2189
|
-
ctx,
|
|
2190
|
-
["resources", resource.id, "actsAsRoleId"],
|
|
2191
|
-
`Agent resource "${resource.id}" references unknown actsAsRoleId "${resource.actsAsRoleId}"`
|
|
2192
|
-
);
|
|
2193
|
-
}
|
|
2194
|
-
});
|
|
2195
|
-
function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
|
|
2196
|
-
const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
|
|
2197
|
-
ontologyIds2.forEach((ontologyId, ontologyIndex) => {
|
|
2198
|
-
if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
|
|
2199
|
-
addIssue(
|
|
2200
|
-
ctx,
|
|
2201
|
-
["resources", resourceId, "ontology", bindingKey, ...Array.isArray(ids) ? [ontologyIndex] : []],
|
|
2202
|
-
`Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
|
|
2203
|
-
);
|
|
2204
|
-
}
|
|
2205
|
-
});
|
|
2206
|
-
}
|
|
2207
|
-
Object.values(model.resources).forEach((resource) => {
|
|
2208
|
-
const binding = resource.ontology;
|
|
2209
|
-
if (binding === void 0) return;
|
|
2210
|
-
validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
|
|
2211
|
-
validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
|
|
2212
|
-
validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
|
|
2213
|
-
validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
|
|
2214
|
-
validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
|
|
2215
|
-
validateResourceOntologyBinding(resource.id, "emits", "event", binding.emits);
|
|
2216
|
-
if (binding.contract !== void 0) {
|
|
2217
|
-
const contractEntries = [
|
|
2218
|
-
["input", binding.contract.input],
|
|
2219
|
-
["output", binding.contract.output]
|
|
2220
|
-
];
|
|
2221
|
-
for (const [side, ref] of contractEntries) {
|
|
2222
|
-
if (ref === void 0) continue;
|
|
2223
|
-
const result = ContractRefSchema.safeParse(ref);
|
|
2224
|
-
if (!result.success) {
|
|
2225
|
-
addIssue(
|
|
2226
|
-
ctx,
|
|
2227
|
-
["resources", resource.id, "ontology", "contract", side],
|
|
2228
|
-
`Resource "${resource.id}" contract.${side} "${ref}" is not a valid ContractRef (expected "package/subpath#ExportName")`
|
|
2229
|
-
);
|
|
2230
|
-
}
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
});
|
|
2234
|
-
Object.values(model.roles).forEach((role) => {
|
|
2235
|
-
if (role.heldBy === void 0) return;
|
|
2236
|
-
asRoleHolderArray(role.heldBy).forEach((holder, holderIndex) => {
|
|
2237
|
-
if (holder.kind !== "agent") return;
|
|
2238
|
-
const resource = resourcesById.get(holder.agentId);
|
|
2239
|
-
if (resource === void 0) {
|
|
2240
|
-
addIssue(
|
|
2241
|
-
ctx,
|
|
2242
|
-
["roles", role.id, "heldBy", Array.isArray(role.heldBy) ? holderIndex : "agentId"],
|
|
2243
|
-
`Role "${role.id}" references unknown agent holder resource "${holder.agentId}"`
|
|
2244
|
-
);
|
|
2245
|
-
return;
|
|
2246
|
-
}
|
|
2247
|
-
if (resource.kind !== "agent") {
|
|
2248
|
-
addIssue(
|
|
2249
|
-
ctx,
|
|
2250
|
-
["roles", role.id, "heldBy", Array.isArray(role.heldBy) ? holderIndex : "agentId"],
|
|
2251
|
-
`Role "${role.id}" agent holder "${holder.agentId}" must reference an agent resource`
|
|
2252
|
-
);
|
|
2253
|
-
}
|
|
2254
|
-
});
|
|
2255
|
-
});
|
|
2256
|
-
Object.entries(model.knowledge).forEach(([nodeId, node]) => {
|
|
2257
|
-
node.ownerIds.forEach((roleId, ownerIndex) => {
|
|
2258
|
-
if (!rolesById.has(roleId)) {
|
|
2259
|
-
addIssue(
|
|
2260
|
-
ctx,
|
|
2261
|
-
["knowledge", nodeId, "ownerIds", ownerIndex],
|
|
2262
|
-
`Knowledge node "${node.id}" references unknown owner role "${roleId}"`
|
|
2263
|
-
);
|
|
981
|
+
if (SecretLikeMetadataKeySchema.test(key)) {
|
|
982
|
+
ctx.addIssue({
|
|
983
|
+
code: z.ZodIssueCode.custom,
|
|
984
|
+
path: [...path, key],
|
|
985
|
+
message: `Topology metadata key "${key}" looks secret-like`
|
|
986
|
+
});
|
|
2264
987
|
}
|
|
988
|
+
visit(entry, [...path, key]);
|
|
2265
989
|
});
|
|
2266
|
-
});
|
|
2267
|
-
for (const diagnostic of ontologyCompilation.diagnostics) {
|
|
2268
|
-
addIssue(ctx, diagnostic.path, diagnostic.message);
|
|
2269
990
|
}
|
|
991
|
+
visit(metadata, []);
|
|
2270
992
|
});
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
993
|
+
var OmTopologyRelationshipSchema = z.object({
|
|
994
|
+
from: OmTopologyNodeRefSchema,
|
|
995
|
+
kind: OmTopologyRelationshipKindSchema,
|
|
996
|
+
to: OmTopologyNodeRefSchema,
|
|
997
|
+
systemPath: SystemPathSchema.optional(),
|
|
998
|
+
required: z.boolean().optional(),
|
|
999
|
+
metadata: OmTopologyMetadataSchema.optional()
|
|
1000
|
+
});
|
|
1001
|
+
var OmTopologyDomainSchema = z.object({
|
|
1002
|
+
version: z.literal(1).default(1),
|
|
1003
|
+
relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
|
|
1004
|
+
}).default({ version: 1, relationships: {} });
|
|
1005
|
+
function idFrom(input) {
|
|
1006
|
+
return typeof input === "string" ? input : input.id;
|
|
1007
|
+
}
|
|
1008
|
+
function parseRef(kind, id) {
|
|
1009
|
+
return OmTopologyNodeRefSchema.parse({ kind, id });
|
|
1010
|
+
}
|
|
1011
|
+
function isNodeRef(input) {
|
|
1012
|
+
return OmTopologyNodeRefSchema.safeParse(input).success;
|
|
1013
|
+
}
|
|
1014
|
+
function isResourceEntry(input) {
|
|
1015
|
+
if (typeof input !== "object" || input === null) return false;
|
|
1016
|
+
const candidate = input;
|
|
1017
|
+
return typeof candidate.id === "string" && typeof candidate.systemPath === "string" && typeof candidate.status === "string" && ["workflow", "agent", "integration", "script"].includes(String(candidate.kind));
|
|
1018
|
+
}
|
|
1019
|
+
var topologyRef = {
|
|
1020
|
+
system: (system) => parseRef("system", idFrom(system)),
|
|
1021
|
+
resource: (resource) => parseRef("resource", idFrom(resource)),
|
|
1022
|
+
ontology: (record) => parseRef("ontology", idFrom(record)),
|
|
1023
|
+
policy: (policy) => parseRef("policy", idFrom(policy)),
|
|
1024
|
+
role: (role) => parseRef("role", idFrom(role)),
|
|
1025
|
+
trigger: (trigger) => parseRef("trigger", idFrom(trigger)),
|
|
1026
|
+
humanCheckpoint: (checkpoint) => parseRef("humanCheckpoint", idFrom(checkpoint)),
|
|
1027
|
+
externalResource: (externalResource) => parseRef("externalResource", idFrom(externalResource))
|
|
2280
1028
|
};
|
|
2281
|
-
var
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
1029
|
+
var topologyRelationship = {
|
|
1030
|
+
triggers: (from, to, options = {}) => defineTopologyRelationship({
|
|
1031
|
+
...options,
|
|
1032
|
+
from,
|
|
1033
|
+
kind: "triggers",
|
|
1034
|
+
to
|
|
1035
|
+
}),
|
|
1036
|
+
uses: (from, to, options = {}) => defineTopologyRelationship({
|
|
1037
|
+
...options,
|
|
1038
|
+
from,
|
|
1039
|
+
kind: "uses",
|
|
1040
|
+
to
|
|
1041
|
+
}),
|
|
1042
|
+
approval: (from, to, options = {}) => defineTopologyRelationship({
|
|
1043
|
+
...options,
|
|
1044
|
+
from,
|
|
1045
|
+
kind: "approval",
|
|
1046
|
+
to
|
|
1047
|
+
}),
|
|
1048
|
+
usesIntegration: (from, integration, options = {}) => defineTopologyRelationship({
|
|
1049
|
+
required: true,
|
|
1050
|
+
...options,
|
|
1051
|
+
from,
|
|
1052
|
+
kind: "uses",
|
|
1053
|
+
to: integration
|
|
1054
|
+
}),
|
|
1055
|
+
requestsApproval: (from, checkpoint, options = {}) => defineTopologyRelationship({
|
|
1056
|
+
required: true,
|
|
1057
|
+
...options,
|
|
1058
|
+
from,
|
|
1059
|
+
kind: "approval",
|
|
1060
|
+
to: topologyRef.humanCheckpoint(checkpoint)
|
|
1061
|
+
}),
|
|
1062
|
+
checkpointRoutesTo: (checkpoint, to, options = {}) => defineTopologyRelationship({
|
|
1063
|
+
required: true,
|
|
1064
|
+
...options,
|
|
1065
|
+
from: topologyRef.humanCheckpoint(checkpoint),
|
|
1066
|
+
kind: "triggers",
|
|
1067
|
+
to
|
|
1068
|
+
})
|
|
2305
1069
|
};
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
1070
|
+
function compileTopologyNodeRef(input) {
|
|
1071
|
+
if (isNodeRef(input)) return input;
|
|
1072
|
+
if (isResourceEntry(input)) return topologyRef.resource(input);
|
|
1073
|
+
throw new Error("Topology node refs must be typed node objects or serializable { kind, id } refs");
|
|
2310
1074
|
}
|
|
2311
|
-
function
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
results.push({ path: fullPath, system });
|
|
2317
|
-
const childSystems = childSystemsOf2(system);
|
|
2318
|
-
if (Object.keys(childSystems).length > 0) {
|
|
2319
|
-
walk(childSystems, fullPath);
|
|
2320
|
-
}
|
|
2321
|
-
}
|
|
1075
|
+
function parseTopologyNodeRef(input) {
|
|
1076
|
+
if (typeof input !== "string") return OmTopologyNodeRefSchema.parse(input);
|
|
1077
|
+
const separatorIndex = input.indexOf(":");
|
|
1078
|
+
if (separatorIndex === -1) {
|
|
1079
|
+
throw new Error(`Topology node ref "${input}" must use <kind>:<id>`);
|
|
2322
1080
|
}
|
|
2323
|
-
|
|
2324
|
-
|
|
1081
|
+
const kind = input.slice(0, separatorIndex);
|
|
1082
|
+
const id = input.slice(separatorIndex + 1);
|
|
1083
|
+
if (!OmTopologyNodeKindSchema.safeParse(kind).success) {
|
|
1084
|
+
throw new Error(`Topology node ref "${input}" has unsupported kind "${kind}"`);
|
|
1085
|
+
}
|
|
1086
|
+
return OmTopologyNodeRefSchema.parse({ kind, id });
|
|
1087
|
+
}
|
|
1088
|
+
function defineTopologyRelationship(input) {
|
|
1089
|
+
return OmTopologyRelationshipSchema.parse({
|
|
1090
|
+
...input,
|
|
1091
|
+
from: compileTopologyNodeRef(input.from),
|
|
1092
|
+
to: compileTopologyNodeRef(input.to)
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
function defineTopology(relationships) {
|
|
1096
|
+
const entries = Array.isArray(relationships) ? relationships.map((relationship, index) => [`relationship-${index + 1}`, relationship]) : Object.entries(relationships);
|
|
1097
|
+
return OmTopologyDomainSchema.parse({
|
|
1098
|
+
version: 1,
|
|
1099
|
+
relationships: Object.fromEntries(entries.map(([key, relationship]) => [key, defineTopologyRelationship(relationship)]))
|
|
1100
|
+
});
|
|
2325
1101
|
}
|
|
2326
1102
|
|
|
2327
1103
|
// ../core/src/organization-model/migration-helpers.ts
|
|
@@ -2387,80 +1163,6 @@ function getLeadGenStageCatalog(model) {
|
|
|
2387
1163
|
Object.entries(results).sort(([, a], [, b]) => a.order - b.order || a.key.localeCompare(b.key))
|
|
2388
1164
|
);
|
|
2389
1165
|
}
|
|
2390
|
-
var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
|
|
2391
|
-
var SalesStageSchema = DisplayMetadataSchema.extend({
|
|
2392
|
-
id: ModelIdSchema,
|
|
2393
|
-
order: z.number().int().min(0),
|
|
2394
|
-
semanticClass: SalesStageSemanticClassSchema,
|
|
2395
|
-
surfaceIds: ReferenceIdsSchema,
|
|
2396
|
-
resourceIds: ReferenceIdsSchema
|
|
2397
|
-
});
|
|
2398
|
-
z.object({
|
|
2399
|
-
id: ModelIdSchema,
|
|
2400
|
-
label: z.string().trim().min(1).max(120),
|
|
2401
|
-
description: DescriptionSchema.optional(),
|
|
2402
|
-
entityId: ModelIdSchema,
|
|
2403
|
-
stages: z.array(SalesStageSchema).min(1)
|
|
2404
|
-
});
|
|
2405
|
-
var CRM_DISCOVERY_REPLIED_STATE = {
|
|
2406
|
-
stateKey: "discovery_replied",
|
|
2407
|
-
label: "Discovery Replied"
|
|
2408
|
-
};
|
|
2409
|
-
var CRM_DISCOVERY_LINK_SENT_STATE = {
|
|
2410
|
-
stateKey: "discovery_link_sent",
|
|
2411
|
-
label: "Discovery Link Sent"
|
|
2412
|
-
};
|
|
2413
|
-
var CRM_DISCOVERY_NUDGING_STATE = {
|
|
2414
|
-
stateKey: "discovery_nudging",
|
|
2415
|
-
label: "Discovery Nudging"
|
|
2416
|
-
};
|
|
2417
|
-
var CRM_DISCOVERY_BOOKING_CANCELLED_STATE = {
|
|
2418
|
-
stateKey: "discovery_booking_cancelled",
|
|
2419
|
-
label: "Discovery Booking Cancelled"
|
|
2420
|
-
};
|
|
2421
|
-
var CRM_REPLY_SENT_STATE = {
|
|
2422
|
-
stateKey: "reply_sent",
|
|
2423
|
-
label: "Reply Sent"
|
|
2424
|
-
};
|
|
2425
|
-
var CRM_FOLLOWUP_1_SENT_STATE = {
|
|
2426
|
-
stateKey: "followup_1_sent",
|
|
2427
|
-
label: "Follow-up 1 Sent"
|
|
2428
|
-
};
|
|
2429
|
-
var CRM_FOLLOWUP_2_SENT_STATE = {
|
|
2430
|
-
stateKey: "followup_2_sent",
|
|
2431
|
-
label: "Follow-up 2 Sent"
|
|
2432
|
-
};
|
|
2433
|
-
var CRM_FOLLOWUP_3_SENT_STATE = {
|
|
2434
|
-
stateKey: "followup_3_sent",
|
|
2435
|
-
label: "Follow-up 3 Sent"
|
|
2436
|
-
};
|
|
2437
|
-
var CRM_PIPELINE_DEFINITION = {
|
|
2438
|
-
pipelineKey: "crm",
|
|
2439
|
-
label: "CRM",
|
|
2440
|
-
entityKey: "crm.deal",
|
|
2441
|
-
stages: [
|
|
2442
|
-
{
|
|
2443
|
-
stageKey: "interested",
|
|
2444
|
-
label: "Interested",
|
|
2445
|
-
color: "blue",
|
|
2446
|
-
states: [
|
|
2447
|
-
CRM_DISCOVERY_REPLIED_STATE,
|
|
2448
|
-
CRM_DISCOVERY_LINK_SENT_STATE,
|
|
2449
|
-
CRM_DISCOVERY_NUDGING_STATE,
|
|
2450
|
-
CRM_DISCOVERY_BOOKING_CANCELLED_STATE,
|
|
2451
|
-
CRM_REPLY_SENT_STATE,
|
|
2452
|
-
CRM_FOLLOWUP_1_SENT_STATE,
|
|
2453
|
-
CRM_FOLLOWUP_2_SENT_STATE,
|
|
2454
|
-
CRM_FOLLOWUP_3_SENT_STATE
|
|
2455
|
-
]
|
|
2456
|
-
},
|
|
2457
|
-
{ stageKey: "proposal", label: "Proposal", color: "yellow", states: [] },
|
|
2458
|
-
{ stageKey: "closing", label: "Closing", color: "orange", states: [] },
|
|
2459
|
-
{ stageKey: "closed_won", label: "Closed Won", color: "green", states: [] },
|
|
2460
|
-
{ stageKey: "closed_lost", label: "Closed Lost", color: "red", states: [] },
|
|
2461
|
-
{ stageKey: "nurturing", label: "Nurturing", color: "grape", states: [] }
|
|
2462
|
-
]
|
|
2463
|
-
};
|
|
2464
1166
|
DisplayMetadataSchema.extend({
|
|
2465
1167
|
id: ModelIdSchema,
|
|
2466
1168
|
order: z.number().min(0)
|
|
@@ -6856,298 +5558,89 @@ var ResourceRegistry = class {
|
|
|
6856
5558
|
* @param organizationName - Organization name
|
|
6857
5559
|
* @param resourceId - Resource ID
|
|
6858
5560
|
* @returns Serialized definition or null if not found
|
|
6859
|
-
*/
|
|
6860
|
-
getSerializedDefinition(organizationName, resourceId) {
|
|
6861
|
-
const cache = this.serializedCache.get(organizationName);
|
|
6862
|
-
if (!cache) return null;
|
|
6863
|
-
return cache.definitions.agents.get(resourceId) ?? cache.definitions.workflows.get(resourceId) ?? null;
|
|
6864
|
-
}
|
|
6865
|
-
/**
|
|
6866
|
-
* Get resource list for organization (instant lookup)
|
|
6867
|
-
* Use for /resources endpoint - returns pre-computed ResourceDefinition array
|
|
6868
|
-
*
|
|
6869
|
-
* @param organizationName - Organization name
|
|
6870
|
-
* @returns Resource list with workflows, agents, and total count
|
|
6871
|
-
*/
|
|
6872
|
-
getResourceList(organizationName) {
|
|
6873
|
-
const cache = this.serializedCache.get(organizationName);
|
|
6874
|
-
if (!cache) {
|
|
6875
|
-
return { workflows: [], agents: [], total: 0 };
|
|
6876
|
-
}
|
|
6877
|
-
return cache.resources;
|
|
6878
|
-
}
|
|
6879
|
-
/**
|
|
6880
|
-
* Get Command View data for organization (instant lookup)
|
|
6881
|
-
* Use for /command-view endpoint - returns complete graph data
|
|
6882
|
-
*
|
|
6883
|
-
* @param organizationName - Organization name
|
|
6884
|
-
* @returns Command View data with nodes and edges
|
|
6885
|
-
*/
|
|
6886
|
-
getCommandViewData(organizationName) {
|
|
6887
|
-
const cache = this.serializedCache.get(organizationName);
|
|
6888
|
-
if (!cache) {
|
|
6889
|
-
return {
|
|
6890
|
-
workflows: [],
|
|
6891
|
-
agents: [],
|
|
6892
|
-
triggers: [],
|
|
6893
|
-
integrations: [],
|
|
6894
|
-
externalResources: [],
|
|
6895
|
-
humanCheckpoints: [],
|
|
6896
|
-
edges: []
|
|
6897
|
-
};
|
|
6898
|
-
}
|
|
6899
|
-
return cache.commandView;
|
|
6900
|
-
}
|
|
6901
|
-
};
|
|
6902
|
-
|
|
6903
|
-
// ../core/src/platform/registry/types.ts
|
|
6904
|
-
function bindResourceDescriptor(definition) {
|
|
6905
|
-
const { resource, ...rest } = definition;
|
|
6906
|
-
return {
|
|
6907
|
-
...rest,
|
|
6908
|
-
resource,
|
|
6909
|
-
resourceId: resource.id,
|
|
6910
|
-
type: resource.kind
|
|
6911
|
-
};
|
|
6912
|
-
}
|
|
6913
|
-
|
|
6914
|
-
// ../core/src/business/acquisition/build-templates.ts
|
|
6915
|
-
var BUILD_TEMPLATE_CATALOG = [
|
|
6916
|
-
{
|
|
6917
|
-
id: "local-services",
|
|
6918
|
-
label: "Local Services",
|
|
6919
|
-
description: "Source, analyze, qualify, and personalize local service businesses for outreach.",
|
|
6920
|
-
steps: Object.values(PROSPECTING_STEPS.localServices)
|
|
6921
|
-
},
|
|
6922
|
-
{
|
|
6923
|
-
id: "dtc-subscription-apollo-clickup",
|
|
6924
|
-
label: "DTC Subscription (Apollo + ClickUp)",
|
|
6925
|
-
description: "Import DTC brand leads from Apollo, crawl their websites, score fit, enrich contacts, and export via ClickUp.",
|
|
6926
|
-
steps: Object.values(PROSPECTING_STEPS.dtcApolloClickup)
|
|
6927
|
-
}
|
|
6928
|
-
];
|
|
6929
|
-
var PROSPECTING_BUILD_TEMPLATE_OPTIONS = BUILD_TEMPLATE_CATALOG.map(({ id, label, description }) => ({
|
|
6930
|
-
id,
|
|
6931
|
-
label,
|
|
6932
|
-
description
|
|
6933
|
-
}));
|
|
6934
|
-
function isProspectingBuildTemplateId(value) {
|
|
6935
|
-
return PROSPECTING_BUILD_TEMPLATE_OPTIONS.some((template) => template.id === value);
|
|
6936
|
-
}
|
|
6937
|
-
|
|
6938
|
-
// ../core/src/business/acquisition/ontology-validation.ts
|
|
6939
|
-
var CRM_PIPELINE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
6940
|
-
scope: "sales.crm",
|
|
6941
|
-
kind: "catalog",
|
|
6942
|
-
localId: "crm.pipeline"
|
|
6943
|
-
});
|
|
6944
|
-
var LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
6945
|
-
scope: "sales.lead-gen",
|
|
6946
|
-
kind: "catalog",
|
|
6947
|
-
localId: "lead-gen.stage-catalog"
|
|
6948
|
-
});
|
|
6949
|
-
var CRM_DEAL_OBJECT_ONTOLOGY_ID = formatOntologyId({
|
|
6950
|
-
scope: "sales.crm",
|
|
6951
|
-
kind: "object",
|
|
6952
|
-
localId: "crm.deal"
|
|
6953
|
-
});
|
|
6954
|
-
function createCrmPipelineCatalog() {
|
|
6955
|
-
return {
|
|
6956
|
-
id: CRM_PIPELINE_CATALOG_ONTOLOGY_ID,
|
|
6957
|
-
label: CRM_PIPELINE_DEFINITION.label,
|
|
6958
|
-
ownerSystemId: "sales.crm",
|
|
6959
|
-
kind: "pipeline",
|
|
6960
|
-
appliesTo: CRM_DEAL_OBJECT_ONTOLOGY_ID,
|
|
6961
|
-
entries: Object.fromEntries(
|
|
6962
|
-
CRM_PIPELINE_DEFINITION.stages.map((stage, index) => [
|
|
6963
|
-
stage.stageKey,
|
|
6964
|
-
{
|
|
6965
|
-
key: stage.stageKey,
|
|
6966
|
-
label: stage.label,
|
|
6967
|
-
order: (index + 1) * 10,
|
|
6968
|
-
...stage.color !== void 0 ? { color: stage.color } : {},
|
|
6969
|
-
states: stage.states.map((state) => ({ ...state }))
|
|
6970
|
-
}
|
|
6971
|
-
])
|
|
6972
|
-
),
|
|
6973
|
-
legacyPipelineKey: CRM_PIPELINE_DEFINITION.pipelineKey,
|
|
6974
|
-
legacyEntityKey: CRM_PIPELINE_DEFINITION.entityKey
|
|
6975
|
-
};
|
|
6976
|
-
}
|
|
6977
|
-
function createLeadGenStageCatalog(model) {
|
|
6978
|
-
return {
|
|
6979
|
-
id: LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID,
|
|
6980
|
-
label: "Lead Gen Processing Stages",
|
|
6981
|
-
ownerSystemId: "sales.lead-gen",
|
|
6982
|
-
kind: "processing-stage-catalog",
|
|
6983
|
-
entries: Object.fromEntries(
|
|
6984
|
-
Object.entries(getLeadGenStageCatalog(model)).map(([key, entry]) => [
|
|
6985
|
-
key,
|
|
6986
|
-
{
|
|
6987
|
-
...entry
|
|
6988
|
-
}
|
|
6989
|
-
])
|
|
6990
|
-
),
|
|
6991
|
-
legacyCatalogKey: "LEAD_GEN_STAGE_CATALOG"
|
|
6992
|
-
};
|
|
6993
|
-
}
|
|
6994
|
-
function isPlainRecord(value) {
|
|
6995
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6996
|
-
}
|
|
6997
|
-
function mergeBridgeCatalogs(model) {
|
|
6998
|
-
const baseCatalogTypes = model.ontology?.catalogTypes ?? {};
|
|
6999
|
-
const bridgeCatalogTypes = {};
|
|
7000
|
-
if (baseCatalogTypes[CRM_PIPELINE_CATALOG_ONTOLOGY_ID] === void 0) {
|
|
7001
|
-
bridgeCatalogTypes[CRM_PIPELINE_CATALOG_ONTOLOGY_ID] = createCrmPipelineCatalog();
|
|
7002
|
-
}
|
|
7003
|
-
if (baseCatalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID] === void 0) {
|
|
7004
|
-
bridgeCatalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID] = createLeadGenStageCatalog(model);
|
|
7005
|
-
}
|
|
7006
|
-
if (Object.keys(bridgeCatalogTypes).length === 0) return model;
|
|
7007
|
-
return {
|
|
7008
|
-
...model,
|
|
7009
|
-
ontology: {
|
|
7010
|
-
...model.ontology ?? {},
|
|
7011
|
-
catalogTypes: {
|
|
7012
|
-
...baseCatalogTypes,
|
|
7013
|
-
...bridgeCatalogTypes
|
|
7014
|
-
}
|
|
7015
|
-
}
|
|
7016
|
-
};
|
|
7017
|
-
}
|
|
7018
|
-
function compileBusinessOntologyValidationIndex(model = DEFAULT_ORGANIZATION_MODEL) {
|
|
7019
|
-
const compilation = compileOrganizationOntology(mergeBridgeCatalogs(model));
|
|
7020
|
-
if (compilation.diagnostics.length > 0) {
|
|
7021
|
-
const summary = compilation.diagnostics.map((diagnostic) => diagnostic.message).join("; ");
|
|
7022
|
-
throw new Error(`Business ontology validation index failed to compile: ${summary}`);
|
|
5561
|
+
*/
|
|
5562
|
+
getSerializedDefinition(organizationName, resourceId) {
|
|
5563
|
+
const cache = this.serializedCache.get(organizationName);
|
|
5564
|
+
if (!cache) return null;
|
|
5565
|
+
return cache.definitions.agents.get(resourceId) ?? cache.definitions.workflows.get(resourceId) ?? null;
|
|
7023
5566
|
}
|
|
7024
|
-
|
|
7025
|
-
|
|
7026
|
-
|
|
7027
|
-
|
|
5567
|
+
/**
|
|
5568
|
+
* Get resource list for organization (instant lookup)
|
|
5569
|
+
* Use for /resources endpoint - returns pre-computed ResourceDefinition array
|
|
5570
|
+
*
|
|
5571
|
+
* @param organizationName - Organization name
|
|
5572
|
+
* @returns Resource list with workflows, agents, and total count
|
|
5573
|
+
*/
|
|
5574
|
+
getResourceList(organizationName) {
|
|
5575
|
+
const cache = this.serializedCache.get(organizationName);
|
|
5576
|
+
if (!cache) {
|
|
5577
|
+
return { workflows: [], agents: [], total: 0 };
|
|
5578
|
+
}
|
|
5579
|
+
return cache.resources;
|
|
7028
5580
|
}
|
|
7029
|
-
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
7036
|
-
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
5581
|
+
/**
|
|
5582
|
+
* Get Command View data for organization (instant lookup)
|
|
5583
|
+
* Use for /command-view endpoint - returns complete graph data
|
|
5584
|
+
*
|
|
5585
|
+
* @param organizationName - Organization name
|
|
5586
|
+
* @returns Command View data with nodes and edges
|
|
5587
|
+
*/
|
|
5588
|
+
getCommandViewData(organizationName) {
|
|
5589
|
+
const cache = this.serializedCache.get(organizationName);
|
|
5590
|
+
if (!cache) {
|
|
5591
|
+
return {
|
|
5592
|
+
workflows: [],
|
|
5593
|
+
agents: [],
|
|
5594
|
+
triggers: [],
|
|
5595
|
+
integrations: [],
|
|
5596
|
+
externalResources: [],
|
|
5597
|
+
humanCheckpoints: [],
|
|
5598
|
+
edges: []
|
|
5599
|
+
};
|
|
7042
5600
|
}
|
|
5601
|
+
return cache.commandView;
|
|
7043
5602
|
}
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
function
|
|
7048
|
-
|
|
7049
|
-
}
|
|
7050
|
-
function asCrmStageEntry(key, value) {
|
|
7051
|
-
const record = isPlainRecord(value) ? value : {};
|
|
7052
|
-
const label = typeof record.label === "string" ? record.label : key;
|
|
7053
|
-
const order = typeof record.order === "number" ? record.order : 0;
|
|
7054
|
-
const color = typeof record.color === "string" ? record.color : void 0;
|
|
7055
|
-
const rawStates = Array.isArray(record.states) ? record.states : [];
|
|
7056
|
-
const states = rawStates.flatMap((state) => {
|
|
7057
|
-
if (!isPlainRecord(state) || typeof state.stateKey !== "string") return [];
|
|
7058
|
-
return [
|
|
7059
|
-
{
|
|
7060
|
-
stateKey: state.stateKey,
|
|
7061
|
-
label: typeof state.label === "string" ? state.label : state.stateKey
|
|
7062
|
-
}
|
|
7063
|
-
];
|
|
7064
|
-
});
|
|
5603
|
+
};
|
|
5604
|
+
|
|
5605
|
+
// ../core/src/platform/registry/types.ts
|
|
5606
|
+
function bindResourceDescriptor(definition) {
|
|
5607
|
+
const { resource, ...rest } = definition;
|
|
7065
5608
|
return {
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
states
|
|
5609
|
+
...rest,
|
|
5610
|
+
resource,
|
|
5611
|
+
resourceId: resource.id,
|
|
5612
|
+
type: resource.kind
|
|
7071
5613
|
};
|
|
7072
5614
|
}
|
|
7073
|
-
var CRM_STAGE_KEYS_FROM_ONTOLOGY = Object.keys(
|
|
7074
|
-
getCatalogEntries(BUSINESS_ONTOLOGY_VALIDATION_INDEX.crmPipelineCatalog)
|
|
7075
|
-
);
|
|
7076
|
-
var CRM_STATE_KEYS_FROM_ONTOLOGY = Object.values(
|
|
7077
|
-
getCatalogEntries(BUSINESS_ONTOLOGY_VALIDATION_INDEX.crmPipelineCatalog)
|
|
7078
|
-
).flatMap((entry, index) => {
|
|
7079
|
-
const stageKey = CRM_STAGE_KEYS_FROM_ONTOLOGY[index];
|
|
7080
|
-
if (stageKey === void 0) return [];
|
|
7081
|
-
return asCrmStageEntry(stageKey, entry).states.map((state) => state.stateKey);
|
|
7082
|
-
});
|
|
7083
|
-
Object.keys(
|
|
7084
|
-
getCatalogEntries(BUSINESS_ONTOLOGY_VALIDATION_INDEX.leadGenStageCatalog)
|
|
7085
|
-
);
|
|
7086
5615
|
|
|
7087
|
-
// ../core/src/business/acquisition/
|
|
7088
|
-
var
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
function getDealOwnership(deal) {
|
|
7101
|
-
if (deal.state_key === "closed_won" || deal.state_key === "closed_lost") {
|
|
7102
|
-
return null;
|
|
7103
|
-
}
|
|
7104
|
-
if (!Array.isArray(deal.activity_log)) return null;
|
|
7105
|
-
let latestInboundMs = null;
|
|
7106
|
-
let latestOutboundMs = null;
|
|
7107
|
-
for (const entry of deal.activity_log) {
|
|
7108
|
-
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
7109
|
-
const record = entry;
|
|
7110
|
-
const type = typeof record.type === "string" ? record.type : null;
|
|
7111
|
-
if (!type) continue;
|
|
7112
|
-
const isInbound = INBOUND_SET.has(type);
|
|
7113
|
-
const isOutbound = OUTBOUND_SET.has(type);
|
|
7114
|
-
if (!isInbound && !isOutbound) continue;
|
|
7115
|
-
const occurredAt = resolveTimestamp(record);
|
|
7116
|
-
if (occurredAt === null) continue;
|
|
7117
|
-
if (isInbound && (latestInboundMs === null || occurredAt > latestInboundMs)) {
|
|
7118
|
-
latestInboundMs = occurredAt;
|
|
7119
|
-
}
|
|
7120
|
-
if (isOutbound && (latestOutboundMs === null || occurredAt > latestOutboundMs)) {
|
|
7121
|
-
latestOutboundMs = occurredAt;
|
|
7122
|
-
}
|
|
7123
|
-
}
|
|
7124
|
-
if (latestInboundMs === null && latestOutboundMs === null) return null;
|
|
7125
|
-
if (latestOutboundMs !== null && (latestInboundMs === null || latestOutboundMs >= latestInboundMs)) {
|
|
7126
|
-
return "them";
|
|
7127
|
-
}
|
|
7128
|
-
return "us";
|
|
7129
|
-
}
|
|
7130
|
-
function resolveTimestamp(record) {
|
|
7131
|
-
return parseMs(record.timestamp) ?? parseMs(record.occurredAt) ?? parseMs(record.createdAt) ?? parseMs(record.updatedAt) ?? parseMs(record.sentAt) ?? null;
|
|
7132
|
-
}
|
|
7133
|
-
function parseMs(value) {
|
|
7134
|
-
if (value instanceof Date) {
|
|
7135
|
-
const ms2 = value.getTime();
|
|
7136
|
-
return Number.isNaN(ms2) ? null : ms2;
|
|
5616
|
+
// ../core/src/business/acquisition/build-templates.ts
|
|
5617
|
+
var BUILD_TEMPLATE_CATALOG = [
|
|
5618
|
+
{
|
|
5619
|
+
id: "local-services",
|
|
5620
|
+
label: "Local Services",
|
|
5621
|
+
description: "Source, analyze, qualify, and personalize local service businesses for outreach.",
|
|
5622
|
+
steps: Object.values(PROSPECTING_STEPS.localServices)
|
|
5623
|
+
},
|
|
5624
|
+
{
|
|
5625
|
+
id: "dtc-subscription-apollo-clickup",
|
|
5626
|
+
label: "DTC Subscription (Apollo + ClickUp)",
|
|
5627
|
+
description: "Import DTC brand leads from Apollo, crawl their websites, score fit, enrich contacts, and export via ClickUp.",
|
|
5628
|
+
steps: Object.values(PROSPECTING_STEPS.dtcApolloClickup)
|
|
7137
5629
|
}
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
5630
|
+
];
|
|
5631
|
+
var PROSPECTING_BUILD_TEMPLATE_OPTIONS = BUILD_TEMPLATE_CATALOG.map(({ id, label, description }) => ({
|
|
5632
|
+
id,
|
|
5633
|
+
label,
|
|
5634
|
+
description
|
|
5635
|
+
}));
|
|
5636
|
+
function isProspectingBuildTemplateId(value) {
|
|
5637
|
+
return PROSPECTING_BUILD_TEMPLATE_OPTIONS.some((template) => template.id === value);
|
|
7141
5638
|
}
|
|
7142
|
-
|
|
7143
|
-
// ../core/src/business/acquisition/api-schemas.ts
|
|
7144
5639
|
var ProcessingStageStatusSchema = z.enum(["success", "no_result", "skipped", "error"]);
|
|
7145
5640
|
var LeadGenStageKeySchema = z.string().trim().min(1);
|
|
7146
5641
|
var LeadGenActionKeySchema = z.string().trim().min(1);
|
|
7147
|
-
var
|
|
7148
|
-
var
|
|
7149
|
-
var CrmStageKeySchema = z.enum(crmStageKeys);
|
|
7150
|
-
var CrmStateKeySchema = z.enum(crmStateKeys);
|
|
5642
|
+
var CrmStageKeySchema = z.string().trim().min(1);
|
|
5643
|
+
var CrmStateKeySchema = z.string().trim().min(1);
|
|
7151
5644
|
var ProcessingStateEntrySchema = z.object({
|
|
7152
5645
|
status: ProcessingStageStatusSchema,
|
|
7153
5646
|
data: z.unknown().optional()
|
|
@@ -8044,116 +6537,280 @@ var ActivityEventSchema = z.discriminatedUnion("type", [
|
|
|
8044
6537
|
DealCreatedEventSchema,
|
|
8045
6538
|
ActionFailedEventSchema
|
|
8046
6539
|
]);
|
|
8047
|
-
|
|
6540
|
+
z.object({
|
|
8048
6541
|
replyBody: z.string().trim().min(1).max(1e4)
|
|
8049
6542
|
}).strict();
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
label: "
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
}
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
},
|
|
8091
|
-
rebook: {
|
|
8092
|
-
key: "rebook",
|
|
8093
|
-
label: "Rebook",
|
|
8094
|
-
workflowId: "crm-rebook-workflow"
|
|
6543
|
+
function deriveActions(deal, actions = []) {
|
|
6544
|
+
return actions.filter((a) => a.isAvailableFor(deal)).map(({ key, label, payloadSchema }) => ({ key, label, payloadSchema }));
|
|
6545
|
+
}
|
|
6546
|
+
|
|
6547
|
+
// ../core/src/business/acquisition/ontology-validation.ts
|
|
6548
|
+
var CRM_PIPELINE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
6549
|
+
scope: "sales.crm",
|
|
6550
|
+
kind: "catalog",
|
|
6551
|
+
localId: "crm.pipeline"
|
|
6552
|
+
});
|
|
6553
|
+
var LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID = formatOntologyId({
|
|
6554
|
+
scope: "sales.lead-gen",
|
|
6555
|
+
kind: "catalog",
|
|
6556
|
+
localId: "lead-gen.stage-catalog"
|
|
6557
|
+
});
|
|
6558
|
+
function createLeadGenStageCatalog(model) {
|
|
6559
|
+
return {
|
|
6560
|
+
id: LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID,
|
|
6561
|
+
label: "Lead Gen Processing Stages",
|
|
6562
|
+
ownerSystemId: "sales.lead-gen",
|
|
6563
|
+
kind: "processing-stage-catalog",
|
|
6564
|
+
entries: Object.fromEntries(
|
|
6565
|
+
Object.entries(getLeadGenStageCatalog(model)).map(([key, entry]) => [
|
|
6566
|
+
key,
|
|
6567
|
+
{
|
|
6568
|
+
...entry
|
|
6569
|
+
}
|
|
6570
|
+
])
|
|
6571
|
+
),
|
|
6572
|
+
legacyCatalogKey: "LEAD_GEN_STAGE_CATALOG"
|
|
6573
|
+
};
|
|
6574
|
+
}
|
|
6575
|
+
function isPlainRecord(value) {
|
|
6576
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6577
|
+
}
|
|
6578
|
+
function mergeBridgeCatalogs(model) {
|
|
6579
|
+
const baseCatalogTypes = model.ontology?.catalogTypes ?? {};
|
|
6580
|
+
const bridgeCatalogTypes = {};
|
|
6581
|
+
if (baseCatalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID] === void 0) {
|
|
6582
|
+
bridgeCatalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID] = createLeadGenStageCatalog(model);
|
|
8095
6583
|
}
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
6584
|
+
if (Object.keys(bridgeCatalogTypes).length === 0) return model;
|
|
6585
|
+
return {
|
|
6586
|
+
...model,
|
|
6587
|
+
ontology: {
|
|
6588
|
+
...model.ontology ?? {},
|
|
6589
|
+
catalogTypes: {
|
|
6590
|
+
...baseCatalogTypes,
|
|
6591
|
+
...bridgeCatalogTypes
|
|
6592
|
+
}
|
|
6593
|
+
}
|
|
6594
|
+
};
|
|
6595
|
+
}
|
|
6596
|
+
function compileBusinessOntologyValidationIndex(model) {
|
|
6597
|
+
const compilation = compileOrganizationOntology(mergeBridgeCatalogs(model));
|
|
6598
|
+
if (compilation.diagnostics.length > 0) {
|
|
6599
|
+
const summary = compilation.diagnostics.map((diagnostic) => diagnostic.message).join("; ");
|
|
6600
|
+
throw new Error(`Business ontology validation index failed to compile: ${summary}`);
|
|
6601
|
+
}
|
|
6602
|
+
const crmPipelineCatalog = compilation.ontology.catalogTypes[CRM_PIPELINE_CATALOG_ONTOLOGY_ID];
|
|
6603
|
+
const leadGenStageCatalog = compilation.ontology.catalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID];
|
|
6604
|
+
if (crmPipelineCatalog === void 0 || leadGenStageCatalog === void 0) {
|
|
6605
|
+
throw new Error("Business ontology validation index is missing CRM or lead-gen catalog bridge records");
|
|
8101
6606
|
}
|
|
8102
6607
|
return {
|
|
8103
|
-
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
6608
|
+
ontology: compilation.ontology,
|
|
6609
|
+
crmPipelineCatalog,
|
|
6610
|
+
leadGenStageCatalog,
|
|
6611
|
+
actionTypesByLegacyId: indexActionTypesByLegacyId(compilation.ontology.actionTypes)
|
|
8107
6612
|
};
|
|
8108
6613
|
}
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
return
|
|
6614
|
+
function indexActionTypesByLegacyId(actionTypes) {
|
|
6615
|
+
const byLegacyId = {};
|
|
6616
|
+
for (const actionType of Object.values(actionTypes)) {
|
|
6617
|
+
const legacyActionId = actionType["legacyActionId"];
|
|
6618
|
+
if (typeof legacyActionId === "string") {
|
|
6619
|
+
byLegacyId[legacyActionId] = actionType;
|
|
6620
|
+
}
|
|
6621
|
+
}
|
|
6622
|
+
return byLegacyId;
|
|
6623
|
+
}
|
|
6624
|
+
function getCatalogEntries(catalog) {
|
|
6625
|
+
return isPlainRecord(catalog.entries) ? catalog.entries : {};
|
|
6626
|
+
}
|
|
6627
|
+
function asLeadGenStageEntry(key, value) {
|
|
6628
|
+
const record = isPlainRecord(value) ? value : {};
|
|
6629
|
+
const entity = record.entity === "contact" ? "contact" : "company";
|
|
6630
|
+
const additionalEntities = Array.isArray(record.additionalEntities) ? record.additionalEntities.filter(
|
|
6631
|
+
(item) => item === "company" || item === "contact"
|
|
6632
|
+
) : void 0;
|
|
6633
|
+
const recordEntity = record.recordEntity === "company" || record.recordEntity === "contact" ? record.recordEntity : void 0;
|
|
6634
|
+
const recordStageKey = typeof record.recordStageKey === "string" ? record.recordStageKey : void 0;
|
|
6635
|
+
return {
|
|
6636
|
+
key: typeof record.key === "string" ? record.key : key,
|
|
6637
|
+
label: typeof record.label === "string" ? record.label : key,
|
|
6638
|
+
description: typeof record.description === "string" ? record.description : "",
|
|
6639
|
+
order: typeof record.order === "number" ? record.order : 0,
|
|
6640
|
+
entity,
|
|
6641
|
+
...additionalEntities !== void 0 ? { additionalEntities } : {},
|
|
6642
|
+
...recordEntity !== void 0 ? { recordEntity } : {},
|
|
6643
|
+
...recordStageKey !== void 0 ? { recordStageKey } : {}
|
|
6644
|
+
};
|
|
6645
|
+
}
|
|
6646
|
+
function createLeadGenStageValidators(index) {
|
|
6647
|
+
const getCatalog = () => Object.fromEntries(
|
|
6648
|
+
Object.entries(getCatalogEntries(index.leadGenStageCatalog)).map(([key, value]) => [
|
|
6649
|
+
key,
|
|
6650
|
+
asLeadGenStageEntry(key, value)
|
|
6651
|
+
])
|
|
6652
|
+
);
|
|
6653
|
+
const getEntry = (stageKey) => getCatalog()[stageKey];
|
|
6654
|
+
return {
|
|
6655
|
+
getLeadGenStageCatalog: getCatalog,
|
|
6656
|
+
getLeadGenStageEntry: getEntry,
|
|
6657
|
+
isLeadGenStageKey: (stageKey) => getEntry(stageKey) !== void 0,
|
|
6658
|
+
isLeadGenStageValidForEntity: (stageKey, entity) => {
|
|
6659
|
+
const stage = getEntry(stageKey);
|
|
6660
|
+
return stage !== void 0 && (stage.entity === entity || stage.additionalEntities?.includes(entity) === true);
|
|
6661
|
+
},
|
|
6662
|
+
isLeadGenRecordStageValidForEntity: (stageKey, entity) => {
|
|
6663
|
+
const stage = getEntry(stageKey);
|
|
6664
|
+
return stage !== void 0 && (stage.entity === entity || stage.additionalEntities?.includes(entity) === true || stage.recordEntity === entity);
|
|
6665
|
+
},
|
|
6666
|
+
resolveLeadGenRecordStageKey: (stageKey, entity) => {
|
|
6667
|
+
const stage = getEntry(stageKey);
|
|
6668
|
+
return stage?.recordEntity === entity && stage.recordStageKey ? stage.recordStageKey : stageKey;
|
|
6669
|
+
}
|
|
6670
|
+
};
|
|
6671
|
+
}
|
|
6672
|
+
|
|
6673
|
+
// src/project-deployment-spec.ts
|
|
6674
|
+
function toSdkResourceDescriptor(resource, getResourceOntologyBinding) {
|
|
6675
|
+
const ontologyBinding = getResourceOntologyBinding?.(resource.id);
|
|
6676
|
+
return {
|
|
6677
|
+
...resource,
|
|
6678
|
+
...ontologyBinding ?? {},
|
|
6679
|
+
systemId: resource.systemPath
|
|
6680
|
+
};
|
|
6681
|
+
}
|
|
6682
|
+
function withPlatformResourceDescriptor(workflow, getWorkflowResourceDescriptor, getResourceOntologyBinding) {
|
|
6683
|
+
const resource = getWorkflowResourceDescriptor(workflow.config.resourceId);
|
|
6684
|
+
const sdkResource = toSdkResourceDescriptor(resource, getResourceOntologyBinding);
|
|
6685
|
+
return {
|
|
6686
|
+
...workflow,
|
|
6687
|
+
config: {
|
|
6688
|
+
...workflow.config,
|
|
6689
|
+
resource: sdkResource,
|
|
6690
|
+
resourceId: sdkResource.id,
|
|
6691
|
+
type: sdkResource.kind
|
|
6692
|
+
}
|
|
6693
|
+
};
|
|
6694
|
+
}
|
|
6695
|
+
function withPlatformResourceDescriptors(workflows, getWorkflowResourceDescriptor, getResourceOntologyBinding) {
|
|
6696
|
+
return workflows.map(
|
|
6697
|
+
(workflow) => withPlatformResourceDescriptor(workflow, getWorkflowResourceDescriptor, getResourceOntologyBinding)
|
|
6698
|
+
);
|
|
6699
|
+
}
|
|
6700
|
+
function withPlatformIntegrationResourceDescriptor(integration, getIntegrationResourceDescriptor, getResourceOntologyBinding) {
|
|
6701
|
+
const resource = getIntegrationResourceDescriptor(integration.resourceId);
|
|
6702
|
+
const sdkResource = toSdkResourceDescriptor(resource, getResourceOntologyBinding);
|
|
6703
|
+
return {
|
|
6704
|
+
...integration,
|
|
6705
|
+
resource: sdkResource,
|
|
6706
|
+
resourceId: sdkResource.id,
|
|
6707
|
+
type: sdkResource.kind
|
|
6708
|
+
};
|
|
6709
|
+
}
|
|
6710
|
+
function withPlatformIntegrationResourceDescriptors(integrations, getIntegrationResourceDescriptor, getResourceOntologyBinding) {
|
|
6711
|
+
return integrations.map(
|
|
6712
|
+
(integration) => withPlatformIntegrationResourceDescriptor(integration, getIntegrationResourceDescriptor, getResourceOntologyBinding)
|
|
6713
|
+
);
|
|
8150
6714
|
}
|
|
8151
|
-
function
|
|
8152
|
-
|
|
8153
|
-
|
|
6715
|
+
function projectTopologyRelationships(model) {
|
|
6716
|
+
const projected = {};
|
|
6717
|
+
function ensure(sourceId) {
|
|
6718
|
+
projected[sourceId] ??= {};
|
|
6719
|
+
return projected[sourceId];
|
|
6720
|
+
}
|
|
6721
|
+
for (const relationship of Object.values(model.topology.relationships)) {
|
|
6722
|
+
if (relationship.from.kind === "humanCheckpoint") continue;
|
|
6723
|
+
if (relationship.kind === "triggers" && relationship.to.kind === "resource") {
|
|
6724
|
+
const target = model.resources[relationship.to.id];
|
|
6725
|
+
if (target?.kind !== "workflow" && target?.kind !== "agent") continue;
|
|
6726
|
+
const source = ensure(relationship.from.id);
|
|
6727
|
+
source.triggers ??= {};
|
|
6728
|
+
if (target.kind === "workflow") {
|
|
6729
|
+
source.triggers.workflows ??= [];
|
|
6730
|
+
source.triggers.workflows.push(target.id);
|
|
6731
|
+
} else {
|
|
6732
|
+
source.triggers.agents ??= [];
|
|
6733
|
+
source.triggers.agents.push(target.id);
|
|
6734
|
+
}
|
|
6735
|
+
continue;
|
|
6736
|
+
}
|
|
6737
|
+
if (relationship.kind === "uses" && relationship.from.kind === "resource" && relationship.to.kind === "resource") {
|
|
6738
|
+
const target = model.resources[relationship.to.id];
|
|
6739
|
+
if (target?.kind !== "integration") continue;
|
|
6740
|
+
const source = ensure(relationship.from.id);
|
|
6741
|
+
source.uses ??= {};
|
|
6742
|
+
source.uses.integrations ??= [];
|
|
6743
|
+
source.uses.integrations.push(target.id);
|
|
6744
|
+
}
|
|
8154
6745
|
}
|
|
8155
|
-
return
|
|
6746
|
+
return projected;
|
|
6747
|
+
}
|
|
6748
|
+
function projectDeploymentSpec(options) {
|
|
6749
|
+
const workflows = withPlatformResourceDescriptors(
|
|
6750
|
+
options.workflows,
|
|
6751
|
+
options.getWorkflowResourceDescriptor,
|
|
6752
|
+
options.getResourceOntologyBinding
|
|
6753
|
+
);
|
|
6754
|
+
const integrations = withPlatformIntegrationResourceDescriptors(
|
|
6755
|
+
options.integrations ?? [],
|
|
6756
|
+
options.getIntegrationResourceDescriptor,
|
|
6757
|
+
options.getResourceOntologyBinding
|
|
6758
|
+
);
|
|
6759
|
+
const workflowResourceIds = new Set(workflows.map((workflow) => workflow.config.resourceId));
|
|
6760
|
+
const integrationResourceIds = new Set(integrations.map((integration) => integration.resourceId));
|
|
6761
|
+
const resources = projectDeploymentResources(
|
|
6762
|
+
options.organizationModel.resources,
|
|
6763
|
+
workflowResourceIds,
|
|
6764
|
+
integrationResourceIds,
|
|
6765
|
+
options.getResourceOntologyBinding
|
|
6766
|
+
);
|
|
6767
|
+
return {
|
|
6768
|
+
version: options.version,
|
|
6769
|
+
organizationModel: {
|
|
6770
|
+
systems: projectDeploymentSystems(options.organizationModel),
|
|
6771
|
+
resources
|
|
6772
|
+
},
|
|
6773
|
+
workflows,
|
|
6774
|
+
agents: options.agents ?? [],
|
|
6775
|
+
triggers: options.triggers,
|
|
6776
|
+
integrations,
|
|
6777
|
+
humanCheckpoints: options.humanCheckpoints,
|
|
6778
|
+
relationships: projectTopologyRelationships(options.organizationModel),
|
|
6779
|
+
...options.externalResources ? { externalResources: options.externalResources } : {}
|
|
6780
|
+
};
|
|
6781
|
+
}
|
|
6782
|
+
function projectDeploymentResources(resources, workflowResourceIds, integrationResourceIds, getResourceOntologyBinding) {
|
|
6783
|
+
return Object.fromEntries(
|
|
6784
|
+
Object.values(resources).filter((resource) => workflowResourceIds.has(resource.id) || integrationResourceIds.has(resource.id)).map((resource) => {
|
|
6785
|
+
const sdkResource = toSdkResourceDescriptor(resource, getResourceOntologyBinding);
|
|
6786
|
+
return [sdkResource.id, sdkResource];
|
|
6787
|
+
})
|
|
6788
|
+
);
|
|
6789
|
+
}
|
|
6790
|
+
function projectDeploymentSystems(model) {
|
|
6791
|
+
return Object.fromEntries(
|
|
6792
|
+
listAllSystems(model).map(({ path, system }, index) => {
|
|
6793
|
+
const lifecycle = system.lifecycle === "archived" ? "archived" : system.lifecycle === "deprecated" ? "deprecated" : "active";
|
|
6794
|
+
return [
|
|
6795
|
+
system.id,
|
|
6796
|
+
{
|
|
6797
|
+
id: system.id,
|
|
6798
|
+
order: system.order ?? (index + 1) * 10,
|
|
6799
|
+
title: system.label ?? system.title ?? system.id,
|
|
6800
|
+
description: system.description ?? "",
|
|
6801
|
+
kind: system.kind ?? "product",
|
|
6802
|
+
...system.parentSystemId ? { parentSystemId: system.parentSystemId } : {},
|
|
6803
|
+
...path !== system.id ? { systemPath: path } : {},
|
|
6804
|
+
governedByKnowledge: system.governedByKnowledge ?? [],
|
|
6805
|
+
drivesGoals: system.drivesGoals ?? [],
|
|
6806
|
+
lifecycle,
|
|
6807
|
+
status: lifecycle,
|
|
6808
|
+
...system.responsibleRoleId ? { responsibleRoleId: system.responsibleRoleId } : {}
|
|
6809
|
+
}
|
|
6810
|
+
];
|
|
6811
|
+
})
|
|
6812
|
+
);
|
|
8156
6813
|
}
|
|
8157
6814
|
var ListBuilderStageKeySchema = z.string().min(1);
|
|
8158
6815
|
|
|
8159
|
-
export { ActivityEventSchema, BuildPlanSnapshotStepSchema, ProspectingBuildTemplateSchema as BuildTemplateSchema, ContractRefResolutionError, CrmStageKeySchema, CrmStateKeySchema,
|
|
6816
|
+
export { ActivityEventSchema, BuildPlanSnapshotStepSchema, ProspectingBuildTemplateSchema as BuildTemplateSchema, ContractRefResolutionError, CrmStageKeySchema, CrmStateKeySchema, EmailSchema, ExecutionError, ListBuilderStageKeySchema, ProcessingStageStatusSchema, RegistryValidationError, ResourceRegistry, StepType, ToolingError, bindResourceDescriptor, compileBusinessOntologyValidationIndex, concurrentPool, createLeadGenStageValidators, defineContract, defineResource, defineResourceOntology, defineResources, defineStep, defineTopology, defineTopologyRelationship, defineWorkflow, deriveActions, diagnosticOutput, integrationInput, isZodType, parseTopologyNodeRef, projectDeploymentSpec, projectTopologyRelationships, resolveContractRef, runDiagnostic, splitName, toSdkResourceDescriptor, topologyRef, topologyRelationship, validateResourceGovernance, withPlatformIntegrationResourceDescriptor, withPlatformIntegrationResourceDescriptors, withPlatformResourceDescriptor, withPlatformResourceDescriptors };
|